import datetime from pathlib import Path from fastapi import APIRouter from fastapi.responses import HTMLResponse, RedirectResponse from gallery.easel.core import AppRequest from gallery.easel.depends.api import api_resolver from gallery.easel.depends.weather import WeatherApiDepends from gallery.sketch.weather.api import WeatherApi from gallery.sketch.weather.model import WeatherResponse from ..common.utils.tag import TagType, TagUtil from ..common.utils.template import build_templates from .filters import cloudness_icon, wind_direction_icon def context_procesor(request: AppRequest) -> dict: return { "providers": request.app.state.api.get_api_providers(WeatherApi), } templates = build_templates( Path(__file__).parent / "templates", { "wind_direction_icon": wind_direction_icon, "cloudness_icon": cloudness_icon, }, context_procesor, ) def build_weather_response(request: AppRequest, response: WeatherResponse): return templates.TemplateResponse( request=request, name="weather.html", context={ "response": response, }, ) router = APIRouter(prefix="/weather") @router.get("/", response_class=HTMLResponse) async def get_weather_index(request: AppRequest, provider: str | None = None, query: str | None = None): if query and provider: weather_api = api_resolver(WeatherApi)(request, provider) locations = await weather_api.find_locations(query) else: locations = [] return templates.TemplateResponse( request=request, name="index.html", context={ "locations": locations, }, ) @router.get("/{provider}/{location}", response_class=RedirectResponse) async def get_weather(location: str): return RedirectResponse(f"{location}/tag/today") @router.get("/{provider}/{location}/day/{date}", response_class=HTMLResponse) async def get_weather_day( request: AppRequest, weather_api: WeatherApiDepends, location: str, date: datetime.date, ): response = await weather_api.get_day(location, date) return build_weather_response(request, response) @router.get("/{provider}/{location}/days/{days}", response_class=HTMLResponse) async def get_weather_days(request: AppRequest, weather_api: WeatherApiDepends, location: str, days: int): response = await weather_api.get_days(location, days) return build_weather_response(request, response) @router.get("/{provider}/{location}/tag/{tag}", response_class=HTMLResponse) async def get_weather_tag(request: AppRequest, weather_api: WeatherApiDepends, location: str, tag: str): tag_value = TagUtil.parse_tag(tag) if tag_value.type == TagType.DAY: response = await weather_api.get_day(location, tag_value.date) elif tag_value.type == TagType.DAYS: response = await weather_api.get_days(location, tag_value.days) else: raise ValueError(tag) return build_weather_response(request, response) @router.get("/zmiyevka-184640/tag/{tag}", response_class=RedirectResponse) async def get_zmiyevka_weather_compat(request: AppRequest): path_parts = request.url.path.split("/") path_parts.insert(2, "gismeteo") return RedirectResponse("/".join(path_parts))