Files
gallery/gallery/painting/gismeteo/api.py
T

84 lines
2.9 KiB
Python

import datetime
import json
import logging
from os import environ
from fastapi import HTTPException, status
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
logger = logging.getLogger("gismeteo")
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 = "gismeteo"
parser = GismeteoParser()
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 = 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"],
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
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 HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail={"max_date": max_date.strftime("%Y-%m-%d")}
)
data = await self.source.request(f"weather-{location_id}/{format_date(date)}")
context = Context(date, "day", data, 8)
return self.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)