Skip to content

Commit

Permalink
Adding ability to filter by date. Now aisgrep has --after and --befor…
Browse files Browse the repository at this point in the history
…e options.
  • Loading branch information
wpietri committed Jun 17, 2016
1 parent 1655b6b commit d9fd9dc
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 4 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from setuptools import setup, find_packages

setup(name='simpleais',
version='0.6.4',
version='0.6.5',
description='a simple ais parser',
url='https://github.com/wpietri/simpleais',
author='William Pietri',
Expand Down
23 changes: 20 additions & 3 deletions simpleais/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import click
import numpy
from dateutil.parser import parse as dateutil_parse

from simpleais import sentences_from_source

Expand Down Expand Up @@ -71,14 +72,16 @@ class Taster(object):
pass

def __init__(self, mmsi=None, sentence_type=None, vessel_class=None, lon=None, lat=None, field=None, value=None,
mode='and', checksum=None, invert_match=False):
before=None, after=None, mode='and', checksum=None, invert_match=False):
self.mmsi = mmsi
self.sentence_type = sentence_type
self.vessel_class = vessel_class
self.lon = lon
self.lat = lat
self.field = field
self.value = value
self.before = before
self.after = after
if mode == 'and' or mode is None:
self.default_result = [True]
self.reducer = lambda x, y: x and y
Expand Down Expand Up @@ -113,6 +116,10 @@ def likes(self, sentence):
if self.value:
for f, v in self.value:
factors.append(sentence[f] == v or str(sentence[f]) == str(v))
if self.before:
factors.append(sentence.time <= self.before)
if self.after:
factors.append(self.after <= sentence.time)
if self.checksum is not None:
factors.append(sentence.check() == self.checksum)
result = functools.reduce(self.reducer, factors)
Expand All @@ -122,6 +129,13 @@ def likes(self, sentence):
return result


def parse_date(string):
if string:
return int(dateutil_parse(string).strftime("%s"))
else:
return None


@click.command()
@click.argument('sources', nargs=-1)
@click.option('--mmsi', '-m', multiple=True)
Expand All @@ -132,12 +146,14 @@ def likes(self, sentence):
@click.option('--latitude', '--lat', nargs=2, type=float)
@click.option('--field', '-f', multiple=True)
@click.option('--value', type=(str, str), multiple=True)
@click.option('--before')
@click.option('--after')
@click.option('--checksum', type=click.Choice(['valid', 'invalid']))
@click.option('--mode', type=click.Choice(['and', 'or']))
@click.option('--invert-match', '-v', is_flag=True)
@click.option('--verbose', is_flag=True)
def grep(sources, mmsi=None, mmsi_file=None, sentence_type=None, vessel_class=None, lon=None, lat=None,
value=None, field=None, checksum=None,
value=None, before=None, after=None, field=None, checksum=None,
mode='and', invert_match=False, verbose=False):
""" Filters AIS transmissions. """
if not mmsi:
Expand All @@ -149,7 +165,8 @@ def grep(sources, mmsi=None, mmsi_file=None, sentence_type=None, vessel_class=No
checksum_desire = None
else:
checksum_desire = checksum == "valid"
taster = Taster(mmsi, sentence_type, vessel_class, lon, lat, field, value, mode, checksum_desire, invert_match)
taster = Taster(mmsi, sentence_type, vessel_class, lon, lat, field, value, parse_date(before), parse_date(after),
mode, checksum_desire, invert_match)
with wild_disregard_for(BrokenPipeError):
for sentence in sentences_from_sources(sources, log_errors=verbose):
if taster.likes(sentence):
Expand Down
12 changes: 12 additions & 0 deletions tests/test_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,18 @@ def test_checksum_filter(self):
self.assertFalse(taster.likes(good))
self.assertTrue(taster.likes(bad))

def test_time_filter(self):
early, late = parse(["1456572038.584 !AIVDM,1,1,,A,35DQ`v100211@E:GFlh=6To<P000pJw>`<,0*59",
"1463812839.417 !AIVDM,1,1,,A,15DQ`v001P005W4EqMD`DVW>0>`<,0*62"])

taster = Taster(before=1460000000)
self.assertTrue(taster.likes(early))
self.assertFalse(taster.likes(late))

taster = Taster(after=1460000000)
self.assertFalse(taster.likes(early))
self.assertTrue(taster.likes(late))

def test_invert_match(self):
taster = Taster(lat=(32, 35), invert_match=True) # LA
self.assertFalse(taster.likes(self.type_1_la))
Expand Down

0 comments on commit d9fd9dc

Please sign in to comment.