forked from Zaunei/flathunter
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request NodyHub#11 from codders/feat/processor-pipelines
Add processing pipelines
- Loading branch information
Showing
17 changed files
with
408 additions
and
155 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
class Processor: | ||
|
||
def process_exposes(self, exposes): | ||
return map(lambda e: self.process_expose(e), exposes) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import re | ||
import logging | ||
from flathunter.abstract_processor import Processor | ||
|
||
class Filter(Processor): | ||
|
||
def __init__(self, config, filter): | ||
self.config = config | ||
self.filter = filter | ||
|
||
def process_exposes(self, exposes): | ||
return self.filter.filter(exposes) | ||
|
||
class AddressResolver(Processor): | ||
__log__ = logging.getLogger(__name__) | ||
|
||
def __init__(self, config): | ||
self.config = config | ||
|
||
def process_expose(self, expose): | ||
if expose['address'].startswith('http'): | ||
url = expose['address'] | ||
for searcher in self.config.searchers(): | ||
if re.search(searcher.URL_PATTERN, url): | ||
expose['address'] = searcher.load_address(url) | ||
self.__log__.debug("Loaded address %s for url %s" % (expose['address'], url)) | ||
break | ||
return expose | ||
|
||
class LambdaProcessor(Processor): | ||
|
||
def __init__(self, config, func): | ||
self.func = func | ||
|
||
def process_expose(self, expose): | ||
res = self.func(expose) | ||
return expose |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import logging | ||
import datetime | ||
import time | ||
import urllib | ||
import requests | ||
|
||
from flathunter.abstract_processor import Processor | ||
|
||
class GMapsDurationProcessor(Processor): | ||
|
||
GM_MODE_TRANSIT = 'transit' | ||
GM_MODE_BICYCLE = 'bicycling' | ||
GM_MODE_DRIVING = 'driving' | ||
|
||
__log__ = logging.getLogger(__name__) | ||
|
||
def __init__(self, config): | ||
self.config = config | ||
|
||
def process_expose(self, expose): | ||
expose['durations'] = self.get_formatted_durations(expose['address']).strip() | ||
return expose | ||
|
||
def get_formatted_durations(self, address): | ||
out = "" | ||
for duration in self.config.get('durations', list()): | ||
if 'destination' in duration and 'name' in duration: | ||
dest = duration.get('destination') | ||
name = duration.get('name') | ||
for mode in duration.get('modes', list()): | ||
if 'gm_id' in mode and 'title' in mode and 'key' in self.config.get('google_maps_api', dict()): | ||
duration = self.get_gmaps_distance(address, dest, mode['gm_id']) | ||
out += "> %s (%s): %s\n" % (name, mode['title'], duration) | ||
|
||
return out.strip() | ||
|
||
def get_gmaps_distance(self, address, dest, mode): | ||
# get timestamp for next monday at 9:00:00 o'clock | ||
now = datetime.datetime.today().replace(hour=9, minute=0, second=0) | ||
next_monday = now + datetime.timedelta(days=(7 - now.weekday())) | ||
arrival_time = str(int(time.mktime(next_monday.timetuple()))) | ||
|
||
# decode from unicode and url encode addresses | ||
address = urllib.parse.quote_plus(address.strip().encode('utf8')) | ||
dest = urllib.parse.quote_plus(dest.strip().encode('utf8')) | ||
self.__log__.debug("Got address: %s" % address) | ||
|
||
# get google maps config stuff | ||
base_url = self.config.get('google_maps_api', dict()).get('url') | ||
gm_key = self.config.get('google_maps_api', dict()).get('key') | ||
|
||
if not gm_key and mode != self.GM_MODE_DRIVING: | ||
self.__log__.warning("No Google Maps API key configured and without using a mode different from " | ||
"'driving' is not allowed. Downgrading to mode 'drinving' thus. ") | ||
mode = 'driving' | ||
base_url = base_url.replace('&key={key}', '') | ||
|
||
# retrieve the result | ||
url = base_url.format(dest=dest, mode=mode, origin=address, key=gm_key, arrival=arrival_time) | ||
result = requests.get(url).json() | ||
if result['status'] != 'OK': | ||
self.__log__.error("Failed retrieving distance to address %s: " % address, result) | ||
return None | ||
|
||
# get the fastest route | ||
distances = dict() | ||
for row in result['rows']: | ||
for element in row['elements']: | ||
if 'status' in element and element['status'] != 'OK': | ||
self.__log__.warning("For address %s we got the status message: %s" % (address, element['status'])) | ||
self.__log__.debug("We got this result: %s" % repr(result)) | ||
continue | ||
self.__log__.debug("Got distance and duration: %s / %s (%i seconds)" | ||
% (element['distance']['text'], element['duration']['text'], | ||
element['duration']['value']) | ||
) | ||
distances[element['duration']['value']] = '%s (%s)' % \ | ||
(element['duration']['text'], element['distance']['text']) | ||
return distances[min(distances.keys())] if distances else None |
Oops, something went wrong.