Use coordinate-based timezone lookup for trip destinations
This commit is contained in:
parent
ec413ac310
commit
1ee1f38a99
2 changed files with 40 additions and 0 deletions
|
|
@ -10,3 +10,4 @@ ephem
|
||||||
flask
|
flask
|
||||||
requests
|
requests
|
||||||
emoji
|
emoji
|
||||||
|
timezonefinder
|
||||||
|
|
|
||||||
39
web_view.py
39
web_view.py
|
|
@ -3,7 +3,9 @@
|
||||||
"""Web page to show upcoming events."""
|
"""Web page to show upcoming events."""
|
||||||
|
|
||||||
import decimal
|
import decimal
|
||||||
|
import functools
|
||||||
import hashlib
|
import hashlib
|
||||||
|
import importlib
|
||||||
import inspect
|
import inspect
|
||||||
import json
|
import json
|
||||||
import operator
|
import operator
|
||||||
|
|
@ -789,9 +791,35 @@ def _format_offset_from_bristol(offset_minutes: int) -> str:
|
||||||
return f"{sign}{hours:02d}:{mins:02d} vs Bristol"
|
return f"{sign}{hours:02d}:{mins:02d} vs Bristol"
|
||||||
|
|
||||||
|
|
||||||
|
def _timezone_from_coordinates(latitude: float, longitude: float) -> str | None:
|
||||||
|
"""Resolve IANA timezone name from coordinates."""
|
||||||
|
timezone_finder = _get_timezone_finder()
|
||||||
|
if timezone_finder is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
tz_name = timezone_finder.timezone_at(lng=longitude, lat=latitude)
|
||||||
|
return tz_name if isinstance(tz_name, str) else None
|
||||||
|
|
||||||
|
|
||||||
|
@functools.lru_cache(maxsize=1)
|
||||||
|
def _get_timezone_finder() -> typing.Any:
|
||||||
|
"""Get timezone finder instance if dependency is available."""
|
||||||
|
try:
|
||||||
|
timezonefinder_module = importlib.import_module("timezonefinder")
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
timezone_finder_cls = getattr(timezonefinder_module, "TimezoneFinder", None)
|
||||||
|
if timezone_finder_cls is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return timezone_finder_cls()
|
||||||
|
|
||||||
|
|
||||||
def get_destination_timezones(trip: Trip) -> list[StrDict]:
|
def get_destination_timezones(trip: Trip) -> list[StrDict]:
|
||||||
"""Build destination timezone metadata for the trip page."""
|
"""Build destination timezone metadata for the trip page."""
|
||||||
per_location: dict[tuple[str, str], list[str]] = defaultdict(list)
|
per_location: dict[tuple[str, str], list[str]] = defaultdict(list)
|
||||||
|
location_coords: dict[tuple[str, str], tuple[float, float]] = {}
|
||||||
for item in trip.accommodation + trip.conferences + trip.events:
|
for item in trip.accommodation + trip.conferences + trip.events:
|
||||||
location = item.get("location")
|
location = item.get("location")
|
||||||
country = item.get("country")
|
country = item.get("country")
|
||||||
|
|
@ -803,6 +831,11 @@ def get_destination_timezones(trip: Trip) -> list[StrDict]:
|
||||||
if isinstance(timezone_name, str):
|
if isinstance(timezone_name, str):
|
||||||
per_location[key].append(timezone_name)
|
per_location[key].append(timezone_name)
|
||||||
|
|
||||||
|
latitude = item.get("latitude")
|
||||||
|
longitude = item.get("longitude")
|
||||||
|
if isinstance(latitude, (int, float)) and isinstance(longitude, (int, float)):
|
||||||
|
location_coords[key] = (float(latitude), float(longitude))
|
||||||
|
|
||||||
for field in (
|
for field in (
|
||||||
"from",
|
"from",
|
||||||
"to",
|
"to",
|
||||||
|
|
@ -832,6 +865,12 @@ def get_destination_timezones(trip: Trip) -> list[StrDict]:
|
||||||
except Exception:
|
except Exception:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if not timezone_name and key in location_coords:
|
||||||
|
latitude, longitude = location_coords[key]
|
||||||
|
coordinate_timezone = _timezone_from_coordinates(latitude, longitude)
|
||||||
|
if coordinate_timezone:
|
||||||
|
timezone_name = coordinate_timezone
|
||||||
|
|
||||||
if not timezone_name:
|
if not timezone_name:
|
||||||
country_timezones = pytz.country_timezones.get(country_code, [])
|
country_timezones = pytz.country_timezones.get(country_code, [])
|
||||||
if len(country_timezones) == 1:
|
if len(country_timezones) == 1:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue