diff --git a/weather/app/route/util.py b/weather/app/route/util.py new file mode 100644 index 0000000..f3308c1 --- /dev/null +++ b/weather/app/route/util.py @@ -0,0 +1,57 @@ +import datetime +from enum import Enum +from typing import NamedTuple, Optional + + +class TagType(str, Enum): + DAY = "day" + DAYS = "days" + + +class Tag(NamedTuple): + type: TagType + date: datetime.date + days: int = 1 + + def __str__(self) -> str: + if self.type == TagType.DAY: + today = datetime.date.today() + day = (self.date - today).days + return f"day-{day}" + elif self.type == TagType.DAYS: + return f"days-{self.days}" + else: + raise ValueError(self.type) + + +class TagUtil: + @classmethod + def parse_tag(cls, tag: str) -> Tag: + if tag == "today": + return Tag(TagType.DAY, datetime.date.today()) + elif tag == "tomorrow": + return Tag(TagType.DAY, datetime.date.today() + datetime.timedelta(days=1)) + elif tag.startswith("day-"): + days = int(tag.split("-")[-1]) + return Tag( + TagType.DAY, + datetime.date.today() + datetime.timedelta(days=days), + ) + elif tag.startswith("days-"): + days = int(tag.split("-")[-1]) + return Tag(TagType.DAYS, datetime.date.today(), days) + raise ValueError(tag) + + @classmethod + def create_tag( + cls, + tag_type: TagType, + date: datetime.date, + day: int = 0, + days: int = 10, + ) -> Tag: + if tag_type == TagType.DAY: + return Tag(tag_type, date + datetime.timedelta(days=day)) + if tag_type == TagType.DAYS: + return Tag(tag_type, date, days) + raise ValueError(tag_type) diff --git a/weather/app/route/view/__init__.py b/weather/app/route/view/__init__.py index bff7afd..aa7f262 100644 --- a/weather/app/route/view/__init__.py +++ b/weather/app/route/view/__init__.py @@ -6,10 +6,10 @@ from fastapi.responses import HTMLResponse, RedirectResponse from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates -from gismeteo import datehelp 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 @@ -27,6 +27,7 @@ def mount(app: FastAPI): request=request, name="weather.html", context={ + "tag_util": TagUtil, "datetime": datetime, "response": response, }, @@ -48,7 +49,7 @@ def mount(app: FastAPI): @app.get("/weather/{location}", response_class=RedirectResponse) async def get_weather_default(location: str): - return RedirectResponse(f"{location}/day/{datetime.date.today()}") + return RedirectResponse(f"{location}/tag/today") @app.get("/weather/{location}/day/mock", response_class=HTMLResponse) async def get_weather_day_mock(request: Request): @@ -71,3 +72,15 @@ def mount(app: FastAPI): 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) diff --git a/weather/app/route/view/templates/weather.html b/weather/app/route/view/templates/weather.html index 34422fd..849cd89 100644 --- a/weather/app/route/view/templates/weather.html +++ b/weather/app/route/view/templates/weather.html @@ -19,12 +19,12 @@