From ece1a58a27de8fc28bbc9d0ebb08d26bd1d5ac24 Mon Sep 17 00:00:00 2001 From: shmyga Date: Thu, 17 Sep 2026 16:39:07 +0300 Subject: [PATCH] refactor(gismeteo): add gismeteo location parser --- gallery/painting/gismeteo/api.py | 40 +++++++---------------------- gallery/painting/gismeteo/parser.py | 32 ++++++++++++++++++++++- 2 files changed, 40 insertions(+), 32 deletions(-) diff --git a/gallery/painting/gismeteo/api.py b/gallery/painting/gismeteo/api.py index b052c77..a0a6c5a 100644 --- a/gallery/painting/gismeteo/api.py +++ b/gallery/painting/gismeteo/api.py @@ -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( - f"mq/city/q/?q={query}&geo={geo}&latitude={latitude}&longitude={longitude}&limit=10" - ) + 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) diff --git a/gallery/painting/gismeteo/parser.py b/gallery/painting/gismeteo/parser.py index 9769c2a..248b320 100644 --- a/gallery/painting/gismeteo/parser.py +++ b/gallery/painting/gismeteo/parser.py @@ -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