feat(app/view): add tag routing
This commit is contained in:
57
weather/app/route/util.py
Normal file
57
weather/app/route/util.py
Normal 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)
|
||||
@@ -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)
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
<h3>
|
||||
{% if response.period == 'day' %}
|
||||
<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"
|
||||
href="../days/10">⬆️</a>
|
||||
href="../tag/days-10">⬆️</a>
|
||||
<span>{{response.location}} | {{response.date.strftime('%a, %d %B %Y')}}</span>
|
||||
<a class="button"
|
||||
href="{{response.date + datetime.timedelta(days=1)}}">➡️</a>
|
||||
href="../tag/{{tag_util.create_tag('day', response.date, 1)}}">➡️</a>
|
||||
{% endif %}
|
||||
{% if response.period == 'days' %}
|
||||
<span>{{response.location}} | {{response.date.strftime('%a, %d %B %Y')}}</span>
|
||||
@@ -42,9 +42,12 @@
|
||||
</td>
|
||||
{% endif %}
|
||||
{% if response.period == 'days' %}
|
||||
<td
|
||||
class="date {{'now' if value.date.date() == datetime.date.today() else ''}}">
|
||||
<span class="value"><a href="../day/{{value.date.date()}}">{{value.date.strftime('%a %d')}}</a></span>
|
||||
<td class="date {{'now' if value.date.date() == datetime.date.today() else ''}}">
|
||||
<span class="value">
|
||||
<a href="../tag/{{tag_util.create_tag('day', value.date.date())}}">
|
||||
{{value.date.strftime('%a %d')}}
|
||||
</a>
|
||||
</span>
|
||||
</td>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
Reference in New Issue
Block a user