forked from flathunters/flathunter
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature flathunters#472: filter based on GMaps distance
This PR involves some refactoring. The problem is that previously, filters ran before making any calls to external APIs. Therefore, just adding another filter for the distance doesn't actually work: the distance information is not yet available when we apply the filters. We can't just run the filters later, because then we would run the Google Maps API calls before we filtered out any properties, meaning that we would incur Google Maps API calls for all properties that we find in our search, including those that we later filter out anyway based on price, size, etc. - and we actually have to pay for those requests! My solution is to group the filters in two chains, and then run one chain before and one after external API calls have been made. This way, we can run the distance filter after the API calls are made, but keep everything else the same.
- Loading branch information
1 parent
1c5f36b
commit 8a85d82
Showing
11 changed files
with
249 additions
and
100 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
from dataclasses import dataclass | ||
from enum import Enum | ||
from typing import Optional | ||
|
||
|
||
class TransportationModes(Enum): | ||
"""The transportation mode for Google Maps distance calculation.""" | ||
TRANSIT = 'transit' | ||
BICYCLING = 'bicycling' | ||
DRIVING = 'driving' | ||
WALKING = 'walking' | ||
|
||
|
||
@dataclass | ||
class DistanceValueTuple: | ||
"""We want to keep both the numeric value of a distance, and its string representation.""" | ||
meters: float | ||
text: str | ||
|
||
|
||
@dataclass | ||
class DurationValueTuple: | ||
"""We want to keep both the numeric value of a duration, and its string representation.""" | ||
seconds: float | ||
text: str | ||
|
||
|
||
@dataclass | ||
class DistanceElement: | ||
"""Represents the distance from a property to some location.""" | ||
duration: DurationValueTuple | ||
distance: DistanceValueTuple | ||
mode: TransportationModes | ||
|
||
|
||
@dataclass | ||
class DistanceConfig: | ||
"""Represents distance filter information in the configuration file. | ||
location_name must refer to the location name used to identify the location | ||
in the durations section of the config file, and the transport_mode must be | ||
configured in the durations section for that location name, lest no information | ||
is available to actually filter on.""" | ||
location_name: str | ||
transport_mode: TransportationModes | ||
max_distance_meters: Optional[float] | ||
max_duration_seconds: Optional[float] | ||
|
||
|
||
class FilterChainName(Enum): | ||
"""Identifies the filter chain that a filter acts on | ||
Preprocess filters will be run before the expose is processed by any further actions. | ||
Use this chain to filter exposes that can be excluded based on information scraped | ||
from the expose website alone (such as based on price or size). | ||
Postprocess filters will be run after other actions have completed. Use this if you | ||
require additional information from other steps, such as information from the Google | ||
Maps API, to make a decision on this expose. | ||
We separate the filter chains to avoid making expensive (literally!) calls to the | ||
Google Maps API for exposes that we already know we aren't interested in anyway.""" | ||
preprocess = 'PREPROCESS' | ||
postprocess = 'POSTPROCESS' |
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
Oops, something went wrong.