-
Notifications
You must be signed in to change notification settings - Fork 64
Description
Am just posting/ideating this here to see if its something you're interested in adding, since this is a bit more state-ful than HPI typically is (this would include a CLI which saves data to disk based on prompting the user). I thought about making this a separate project but I think dealing with all this messy data is sort of HPI is good for, so it would be nice to have an interface thats easily extendible in here
Ive been creating something similar for my where_db CLI and we already have home locations as fallback, so I thought it would be nice to formalize it into an API thats easier to extend, like:
my/location/fallback/all.py
my/location/fallback/via_home.py (rename locations/homes.py to here)
my/location/fallback/common.py
my/location/fallback/via_prompt.py
my/location/fallback/via_photos.py
my/location/fallback/via_ip.py
via_photos
because I have lots of photos on disk but not all of them I actually want to use for location, so this would let me confirm which ones to do that for (could also maybe improve on photos.py
somehow)
via_prompt
being a manual entry of the namedtuple described below
Namedtuple would be something like:
class FallbackLocation(NamedTuple):
lat: float
lon: float
dt: datetime
accuracy: Optional[float]
elevation: Optional[float]
duration: Optional[timedelta]
end_dt: Optional[datetime]
def to_location(self) -> Location:
return Location(...)
Either duration
(how long this location is valid for) or end_dt
(when this location is no longer valid) has to be set.
And then all would call some function that prioritizes/picks which source to use, based on the order theyre returned in, like:
def estimate_location(dt: time) -> FallbackLocation:
return estimate_from(
dt,
fallbacks=(via_prompt, via_photos, via_ip, via_home)
)
It would call each fallback function, and then use the one with the closest accuracy
(which typically would be entered or estimated through a config block in each module)
This would require the user to prompt the user, so could probably just have a main function and run this like python3 -m my.location.fallback.via_prompt
? Or could hook it into the CLI, either way.
Strategy in general Ive thought of:
- sort all valid locations by some accuracy threshold, find dates which dont have accurate locations
- use other sources (ips, manual entry (via_prompt), homes) as fallbacks for each of those days
- pick the one with the highest accuracy
The choices the user picks would cached (so they arent re-prompted), so this would need to save to a JSON file or something, e.g. to ~/data/locations/via_prompt.json, ~/data/locations/via_ip.json
Im a bit split between actually saving data, or saving a 'sourcemap/transform' of sorts -- I recently did something similar for my scramble_history project, which lets me define keys to look for on any object, and then it defines a mapping file which converts one model into another -- that way were not actually duplicating data, its a bit more programatic, and you can sort of define 'behavior' to transform one piece of data (e.g. IPs) into locations
Not heavily attached to any of these ideas
--
As a sidenote, I had another idea for sorted locations as we discussed in #237 -- I had an idea to create a custom class which just yields the iterator, but then in the merge in all.py
, we can just do an isinstance check on the iterator itself to check if its the class, like
class SortedLocationIterator:
def __init__(self, sorted_locations):
self.location = iter(sorted_locations)
def __iter__(self):
return self
def __next__(self):
return next(self.location)
In [1]: import test
In [2]: x = test.SortedLocationIterator(range(5))
In [3]: x.__class__
Out[3]: test.SortedLocationIterator
In [4]: next(x)
Out[4]: 0
That way its still all backwards compatible and only if all sources are SortedLocationIterator
do we do a mergesort of sorts.
This could all be added behind a flag as well, but would really speed up sorting locations
Then in tz.via_location
for example, if all.py
return type is a SortedLocationIterator
, we know its been sorted by the user and we dont have to sort it ourself