feat(weather): add weather location search

This commit is contained in:
2026-04-22 12:58:56 +03:00
parent 3dd0a5410c
commit 94870a5c86
32 changed files with 550 additions and 152 deletions

View File

@@ -1,13 +1,13 @@
import datetime
import json
import logging
from typing import Any, Dict, List
from typing import Any
from bs4 import BeautifulSoup
from gallery.sketch.source import ApiSource
from gallery.sketch.weather.api import WeatherApi
from gallery.sketch.weather.catalog import LocationId
from gallery.sketch.weather.model import WeatherResponse, WeatherValue
from gallery.sketch.weather.model import Location, WeatherResponse, WeatherValue
from . import datehelp
from .parser import DAYS_PARSER, LOCATION_PARSER, ONE_DAY_PARSER, ROW_PARSERS
@@ -34,7 +34,7 @@ class GismeteoApi(WeatherApi):
)
def _parse_oneday(self, date: datetime.date, data: str) -> WeatherResponse:
result: List[Dict[str, Any]] = []
result: list[dict[str, Any]] = []
soup = BeautifulSoup(data, features="html.parser")
location = LOCATION_PARSER.parse_location(data)
widget = ONE_DAY_PARSER.parse_widget(soup)
@@ -52,7 +52,7 @@ class GismeteoApi(WeatherApi):
)
def _parse_manydays(self, data: str) -> WeatherResponse:
result: List[Dict[str, Any]] = []
result: list[dict[str, Any]] = []
soup = BeautifulSoup(data, features="html.parser")
location = LOCATION_PARSER.parse_location(data)
widget = DAYS_PARSER.parse_widget(soup)
@@ -69,11 +69,29 @@ class GismeteoApi(WeatherApi):
values=values,
)
async def get_locations(self) -> list[str]:
return [
LocationId.OREL,
LocationId.ZMIYEVKA,
]
async def find_locations(self, query: str) -> list[Location]:
geo = "ru"
latitude = 52.968498
longitude = 36.0695
data = json.loads(
await self.SOURCE.request(
f"mq/city/q/?q={query}&geo={geo}&latitude={latitude}&longitude={longitude}&limit=10"
)
)
result = []
for item in data["data"]:
result.append(
Location(
id=f"{item['slug']}-{item['id']}",
name=item["translations"]["kk"]["city"]["name"],
lat=item["coordinates"]["latitude"],
lon=item["coordinates"]["longitude"],
country=item["translations"]["kk"]["country"]["name"],
district=item["translations"]["kk"]["district"]["name"],
subdistrict=item["translations"]["kk"]["subdistrict"]["name"],
)
)
return result
async def get_day(self, location_id: str, date: datetime.date) -> WeatherResponse:
data = await self.SOURCE.request(f"weather-{location_id}/{datehelp.dump(date)}")