56 lines
1.9 KiB
Python
56 lines
1.9 KiB
Python
import datetime
|
|
from os import environ
|
|
|
|
from gallery.sketch.source import ApiSource
|
|
from gallery.sketch.weather.api import WeatherApi
|
|
from gallery.sketch.weather.model import Location, WeatherResponse
|
|
|
|
from . import PROVIDER
|
|
from .parser import ForecastData, GismeteoForecastParser, GismeteoLocationParser
|
|
|
|
|
|
def format_date(date: datetime.date) -> str:
|
|
today = datetime.date.today()
|
|
days = (date - today).days
|
|
if days == 0:
|
|
return "today"
|
|
elif days == 1:
|
|
return "tomorrow"
|
|
else:
|
|
return f"{days + 1}-day"
|
|
|
|
|
|
class GismeteoApi(WeatherApi):
|
|
PROVIDER = PROVIDER
|
|
|
|
forecast_parser = GismeteoForecastParser()
|
|
location_parser = GismeteoLocationParser()
|
|
|
|
def _build_source(self) -> ApiSource:
|
|
return ApiSource(
|
|
"https://www.gismeteo.ru",
|
|
cookies={"xauth": auth} if (auth := environ.get("GISMETEO_AUTH")) else None,
|
|
)
|
|
|
|
async def find_locations(self, query: str) -> list[Location]:
|
|
geo = "ru"
|
|
latitude = 52.968498
|
|
longitude = 36.0695
|
|
data = await self.source.request(
|
|
f"mq/city/q/?q={query}&geo={geo}&latitude={latitude}&longitude={longitude}&limit=10"
|
|
)
|
|
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)
|
|
if date > max_date:
|
|
raise ValueError(f"Invalid date: {date}, max: {max_date}")
|
|
data = await self.source.request(f"weather-{location_id}/{format_date(date)}")
|
|
context = ForecastData(date, "day", data, 8)
|
|
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 = ForecastData(datetime.date.today(), "days", data)
|
|
return self.forecast_parser.parse(context)
|