import datetime from pathlib import Path from fastapi import FastAPI, Request from fastapi.responses import HTMLResponse, RedirectResponse from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates from gismeteo.location import LOCATION_BUNDLE from gismeteo.mock import MOCK_DATA from weather.api import WeatherApi from weather.app.route.util import TagType, TagUtil from weather.model import WeatherResponse from .filters import cloudness_icon, wind_direction_icon def mount(app: FastAPI): base_dir = Path(__file__).parent app.mount("/static", StaticFiles(directory=base_dir / "static"), name="static") templates = Jinja2Templates(directory=base_dir / "templates") templates.env.filters["wind_direction_icon"] = wind_direction_icon templates.env.filters["cloudness_icon"] = cloudness_icon def build_weather_response(request: Request, response: WeatherResponse): return templates.TemplateResponse( request=request, name="weather.html", context={ "tag_util": TagUtil, "datetime": datetime, "response": response, }, ) @app.get("/", response_class=RedirectResponse) async def get_weather_root(): return RedirectResponse("weather") @app.get("/weather", response_class=HTMLResponse) async def get_weather_list(request: Request): return templates.TemplateResponse( request=request, name="index.html", context={ "locations": LOCATION_BUNDLE._values, }, ) @app.get("/weather/{location}", response_class=RedirectResponse) async def get_weather_default(location: str): return RedirectResponse(f"{location}/tag/today") @app.get("/weather/{location}/day/mock", response_class=HTMLResponse) async def get_weather_day_mock(request: Request): response = MOCK_DATA.get_response("day") return build_weather_response(request, response) @app.get("/weather/{location}/days/mock", response_class=HTMLResponse) async def get_weather_days_mock(request: Request): response = MOCK_DATA.get_response("days") return build_weather_response(request, response) @app.get("/weather/{location}/day/{date}", response_class=HTMLResponse) async def get_weather_day(request: Request, location: str, date: datetime.date): weather_api: WeatherApi = request.app.state.weather_api response = await weather_api.get_day(location, date) return build_weather_response(request, response) @app.get("/weather/{location}/days/{days}", response_class=HTMLResponse) async def get_weather_days(request: Request, location: str, days: int): weather_api: WeatherApi = request.app.state.weather_api response = await weather_api.get_days(location, days) return build_weather_response(request, response) @app.get("/weather/{location}/tag/{tag}", response_class=HTMLResponse) async def get_weather_tag(request: Request, location: str, tag: str): tag_value = TagUtil.parse_tag(tag) weather_api: WeatherApi = request.app.state.weather_api 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)