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 @@

{% if response.period == 'day' %} ⬅️ + href="../tag/{{tag_util.create_tag('day', response.date, -1)}}">⬅️ ⬆️ + href="../tag/days-10">⬆️ {{response.location}} | {{response.date.strftime('%a, %d %B %Y')}} ➡️ + href="../tag/{{tag_util.create_tag('day', response.date, 1)}}">➡️ {% endif %} {% if response.period == 'days' %} {{response.location}} | {{response.date.strftime('%a, %d %B %Y')}} @@ -42,9 +42,12 @@ {% endif %} {% if response.period == 'days' %} - - {{value.date.strftime('%a %d')}} + + + + {{value.date.strftime('%a %d')}} + + {% endif %} {% endfor %} diff --git a/weather/util.py b/weather/util.py new file mode 100644 index 0000000..f4d9896 --- /dev/null +++ b/weather/util.py @@ -0,0 +1,22 @@ +import datetime + +from weather.model import Cloudness, Precipitation, Sky, WeatherValue, WindDirection + + +def build_weather_value(date: datetime.datetime) -> WeatherValue: + return WeatherValue( + date=date, + sky=Sky( + cloudness=Cloudness.CLEAR, + precipitation=Precipitation.NO, + thunder=False, + fog=False, + ), + temperature=[], + wind_speed=0, + wind_gust=0, + wind_direction=WindDirection.CALM, + precipitation=0, + pressure=[], + humidity=0, + )