refactor(gismeteo): add gismeteo location parser

This commit is contained in:
2026-09-17 16:39:07 +03:00
parent a12a81e26d
commit ece1a58a27
2 changed files with 40 additions and 32 deletions
+8 -30
View File
@@ -1,5 +1,4 @@
import datetime
import json
import logging
from os import environ
@@ -9,7 +8,7 @@ from gallery.sketch.source import ApiSource
from gallery.sketch.weather.api import WeatherApi
from gallery.sketch.weather.model import Location, WeatherResponse
from .parser import Context, GismeteoParser
from .parser import Context, GismeteoForecastParser, GismeteoLocationParser
logger = logging.getLogger("gismeteo")
@@ -27,7 +26,9 @@ def format_date(date: datetime.date) -> str:
class GismeteoApi(WeatherApi):
PROVIDER = "gismeteo"
parser = GismeteoParser()
forecast_parser = GismeteoForecastParser()
location_parser = GismeteoLocationParser()
def _build_source(self) -> ApiSource:
return ApiSource(
@@ -39,33 +40,10 @@ class GismeteoApi(WeatherApi):
geo = "ru"
latitude = 52.968498
longitude = 36.0695
data = json.loads(
await self.source.request(
data = 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"],
provider=self.provider,
lat=item["coordinates"]["latitude"],
lon=item["coordinates"]["longitude"],
country=item["translations"]["kk"]["country"]["name"],
country_code=item["country"]["code"].lower(),
district=(
item["translations"]["kk"]["district"]["name"] if item["translations"]["kk"]["district"] else ""
),
subdistrict=(
item["translations"]["kk"]["subdistrict"]["name"]
if "subdistrict" in item["translations"]["kk"]
else ""
),
)
)
return result
return self.location_parser.parse(data)
async def get_day(self, location_id: str, date: datetime.date) -> WeatherResponse:
max_date = datetime.date.today() + datetime.timedelta(days=9)
@@ -75,9 +53,9 @@ class GismeteoApi(WeatherApi):
)
data = await self.source.request(f"weather-{location_id}/{format_date(date)}")
context = Context(date, "day", data, 8)
return self.parser.parse(context)
return self.forecast_parser.parse(context)
async def get_days(self, location_id: str, days: int) -> WeatherResponse:
data = await self.source.request(f"weather-{location_id}/{days}-days")
context = Context(datetime.date.today(), "days", data)
return self.parser.parse(context)
return self.forecast_parser.parse(context)
+31 -1
View File
@@ -1,4 +1,5 @@
import datetime
import json
import logging
import re
from typing import Literal, NamedTuple
@@ -10,6 +11,7 @@ from gallery.sketch.parse.date import parse_date
from gallery.sketch.parse.html import TableParser, TableValueParser
from gallery.sketch.weather.model import (
Cloudness,
Location,
Precipitation,
Sky,
WeatherResponse,
@@ -201,7 +203,7 @@ class Context(NamedTuple):
values: int | None = None
class GismeteoParser(Parser[Context, WeatherResponse]):
class GismeteoForecastParser(Parser[Context, WeatherResponse]):
location_parser = LocationNameParser()
table_parser = GismeteoTableParser()
@@ -222,3 +224,31 @@ class GismeteoParser(Parser[Context, WeatherResponse]):
period=data.period,
values=values,
)
class GismeteoLocationParser(Parser[str, list[Location]]):
def parse(self, data: str) -> list[Location]:
content = json.loads(data)
result = []
for item in content["data"]:
result.append(
Location(
id=f"{item['slug']}-{item['id']}",
name=item["translations"]["kk"]["city"]["name"],
provider="gismeteo", # TODO: provider module const
lat=item["coordinates"]["latitude"],
lon=item["coordinates"]["longitude"],
country=item["translations"]["kk"]["country"]["name"],
country_code=item["country"]["code"].lower(),
district=(
item["translations"]["kk"]["district"]["name"] if item["translations"]["kk"]["district"] else ""
),
subdistrict=(
item["translations"]["kk"]["subdistrict"]["name"]
if "subdistrict" in item["translations"]["kk"]
else ""
),
)
)
return result