add fallback_locations for via_ip

This commit is contained in:
Sean Breckenridge 2023-01-27 11:46:22 -08:00
parent f2c9715dbc
commit 31981b8f34
3 changed files with 62 additions and 10 deletions

View file

@ -10,16 +10,16 @@ class FallbackLocation:
lat: float
lon: float
dt: datetime
duration: int # time in seconds for how long this is valid
duration: float # time in seconds for how long this is valid
accuracy: Optional[float] = None
elevation: Optional[float] = None
datasource: Optional[str] = None # which module provided this, useful for debugging
def to_location(self, end: bool = False) -> Location:
"""
'''
by default the start date is used for the location
If end is True, the start date + duration is used
"""
'''
dt: datetime = self.dt
if end:
dt += timedelta(self.duration)
@ -31,3 +31,33 @@ class FallbackLocation:
elevation=self.elevation,
datasource=self.datasource,
)
@classmethod
def from_end_date(
cls,
lat: float,
lon: float,
dt: datetime,
end_dt: datetime,
accuracy: Optional[float] = None,
elevation: Optional[float] = None,
datasource: Optional[str] = None,
) -> 'FallbackLocation':
'''
Create FallbackLocation from a start date and an end date
'''
if end_dt < dt:
raise ValueError('end_date must be after dt')
duration = (end_dt - dt).total_seconds()
return cls(
lat=lat,
lon=lon,
dt=dt,
duration=duration,
accuracy=accuracy,
elevation=elevation,
datasource=datasource,
)
# TODO: create estimate location which uses other fallback_locations to estimate a location

View file

@ -6,6 +6,8 @@ REQUIRES = ["git+https://github.com/seanbreckenridge/ipgeocache"]
from my.core import dataclass, Stats
from my.config import location
from my.core.warnings import medium
from datetime import datetime
@dataclass
@ -13,26 +15,40 @@ class config(location.via_ip):
# no real science to this, just a guess of ~15km accuracy for IP addresses
accuracy: float = 15_000.0
for_duration: float = 60 * 10 # default to being accurate for ~10 minutes
from typing import Iterator
from ..common import Location
from .common import FallbackLocation
from my.ip.all import ips
def locations() -> Iterator[Location]:
def fallback_locations() -> Iterator[FallbackLocation]:
for ip in ips():
loc: str = ip.ipgeocache()["loc"]
lat, _, lon = loc.partition(",")
yield Location(
lat=float(lat),
lon=float(lon),
lat, lon = ip.latlon
yield FallbackLocation(
lat=lat,
lon=lon,
dt=ip.dt,
accuracy=config.accuracy,
duration=config.for_duration,
elevation=None,
datasource="ip",
)
# for compatibility with my.location.via_ip, this shouldnt be used by other modules
def locations() -> Iterator[Location]:
medium("via_ip.locations is deprecated, use via_ip.fallback_locations instead")
yield from map(FallbackLocation.to_location, fallback_locations())
def estimate_location(dt: datetime) -> Location:
raise NotImplementedError("not implemented yet")
def stats() -> Stats:
from my.core import stat