feat(app/view): add tag routing

This commit is contained in:
2024-08-04 23:54:24 +03:00
parent 891869c58c
commit 217ba7e46c
4 changed files with 103 additions and 8 deletions

57
weather/app/route/util.py Normal file
View File

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

View File

@@ -6,10 +6,10 @@ from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates from fastapi.templating import Jinja2Templates
from gismeteo import datehelp
from gismeteo.location import LOCATION_BUNDLE from gismeteo.location import LOCATION_BUNDLE
from gismeteo.mock import MOCK_DATA from gismeteo.mock import MOCK_DATA
from weather.api import WeatherApi from weather.api import WeatherApi
from weather.app.route.util import TagType, TagUtil
from weather.model import WeatherResponse from weather.model import WeatherResponse
from .filters import cloudness_icon, wind_direction_icon from .filters import cloudness_icon, wind_direction_icon
@@ -27,6 +27,7 @@ def mount(app: FastAPI):
request=request, request=request,
name="weather.html", name="weather.html",
context={ context={
"tag_util": TagUtil,
"datetime": datetime, "datetime": datetime,
"response": response, "response": response,
}, },
@@ -48,7 +49,7 @@ def mount(app: FastAPI):
@app.get("/weather/{location}", response_class=RedirectResponse) @app.get("/weather/{location}", response_class=RedirectResponse)
async def get_weather_default(location: str): 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) @app.get("/weather/{location}/day/mock", response_class=HTMLResponse)
async def get_weather_day_mock(request: Request): async def get_weather_day_mock(request: Request):
@@ -71,3 +72,15 @@ def mount(app: FastAPI):
weather_api: WeatherApi = request.app.state.weather_api weather_api: WeatherApi = request.app.state.weather_api
response = await weather_api.get_days(location, days) response = await weather_api.get_days(location, days)
return build_weather_response(request, response) 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)

View File

@@ -19,12 +19,12 @@
<h3> <h3>
{% if response.period == 'day' %} {% if response.period == 'day' %}
<a class="button {{'disabled' if response.date == datetime.date.today() else ''}}" <a class="button {{'disabled' if response.date == datetime.date.today() else ''}}"
href="{{response.date - datetime.timedelta(days=1)}}">⬅️</a> href="../tag/{{tag_util.create_tag('day', response.date, -1)}}">⬅️</a>
<a class="button" <a class="button"
href="../days/10">⬆️</a> href="../tag/days-10">⬆️</a>
<span>{{response.location}} | {{response.date.strftime('%a, %d %B %Y')}}</span> <span>{{response.location}} | {{response.date.strftime('%a, %d %B %Y')}}</span>
<a class="button" <a class="button"
href="{{response.date + datetime.timedelta(days=1)}}">➡️</a> href="../tag/{{tag_util.create_tag('day', response.date, 1)}}">➡️</a>
{% endif %} {% endif %}
{% if response.period == 'days' %} {% if response.period == 'days' %}
<span>{{response.location}} | {{response.date.strftime('%a, %d %B %Y')}}</span> <span>{{response.location}} | {{response.date.strftime('%a, %d %B %Y')}}</span>
@@ -42,9 +42,12 @@
</td> </td>
{% endif %} {% endif %}
{% if response.period == 'days' %} {% if response.period == 'days' %}
<td <td class="date {{'now' if value.date.date() == datetime.date.today() else ''}}">
class="date {{'now' if value.date.date() == datetime.date.today() else ''}}"> <span class="value">
<span class="value"><a href="../day/{{value.date.date()}}">{{value.date.strftime('%a %d')}}</a></span> <a href="../tag/{{tag_util.create_tag('day', value.date.date())}}">
{{value.date.strftime('%a %d')}}
</a>
</span>
</td> </td>
{% endif %} {% endif %}
{% endfor %} {% endfor %}

22
weather/util.py Normal file
View File

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