feat(weather): add openweather api

This commit is contained in:
2024-08-25 23:28:49 +03:00
parent d3ef03a6a0
commit 3e80ccb0df
25 changed files with 1636 additions and 75 deletions

View File

@@ -0,0 +1,9 @@
from fastapi import FastAPI
from . import common, schedule, weather
def mount(app: FastAPI):
common.mount(app)
weather.mount(app)
schedule.mount(app)

View File

@@ -1,12 +1,12 @@
import datetime
from pathlib import Path
from fastapi import FastAPI, Request
from fastapi import FastAPI
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from gallery.sketch.schedule.api import ScheduleApi
from gallery.easel.core import AppRequest
from gallery.sketch.schedule.catalog import BUNDLE
from gallery.version import __version__
@@ -21,8 +21,8 @@ def mount(app: FastAPI):
templates.env.filters["timedelta_format"] = timedelta_format
@app.get("/schedule", response_class=HTMLResponse)
async def get_schedule_list(request: Request):
schedule_api: ScheduleApi = request.app.state.schedule_api
async def get_schedule_list(request: AppRequest):
schedule_api = request.app.state.api.schedule
channels = await schedule_api.get_channels()
channels_data = BUNDLE.select_items(channels)
return templates.TemplateResponse(
@@ -35,9 +35,9 @@ def mount(app: FastAPI):
)
@app.get("/schedule/tag/{tag}", response_class=HTMLResponse)
async def get_schedule_tag(request: Request, tag: str, live: bool = False):
async def get_schedule_tag(request: AppRequest, tag: str, live: bool = False):
tag_value = TagUtil.parse_tag(tag)
schedule_api: ScheduleApi = request.app.state.schedule_api
schedule_api = request.app.state.api.schedule
channels = await schedule_api.get_channels()
responses = [
await schedule_api.get_channel_schedule(channel, tag_value.date)
@@ -62,9 +62,9 @@ def mount(app: FastAPI):
return RedirectResponse(f"{channel}/tag/today")
@app.get("/schedule/{channel}/tag/{tag}", response_class=HTMLResponse)
async def get_channel_tag(request: Request, channel: str, tag: str):
async def get_channel_tag(request: AppRequest, channel: str, tag: str):
tag_value = TagUtil.parse_tag(tag)
schedule_api: ScheduleApi = request.app.state.schedule_api
schedule_api = request.app.state.api.schedule
if tag_value.type == TagType.DAY:
response = await schedule_api.get_channel_schedule(channel, tag_value.date)
else:

View File

@@ -1,12 +1,12 @@
import datetime
from pathlib import Path
from fastapi import FastAPI, Request
from fastapi import FastAPI
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from gallery.sketch.weather.api import WeatherApi
from gallery.easel.core import AppRequest
from gallery.sketch.weather.catalog import BUNDLE
from gallery.sketch.weather.mock import WEATHER_MOCK_DATA
from gallery.sketch.weather.model import WeatherResponse
@@ -23,7 +23,7 @@ def mount(app: FastAPI):
templates.env.filters["wind_direction_icon"] = wind_direction_icon
templates.env.filters["cloudness_icon"] = cloudness_icon
def build_weather_response(request: Request, response: WeatherResponse):
def build_weather_response(request: AppRequest, response: WeatherResponse):
return templates.TemplateResponse(
request=request,
name="weather.html",
@@ -36,8 +36,8 @@ def mount(app: FastAPI):
)
@app.get("/weather", response_class=HTMLResponse)
async def get_weather_list(request: Request):
weather_api: WeatherApi = request.app.state.weather_api
async def get_weather_list(request: AppRequest):
weather_api = request.app.state.api.weather
locations = await weather_api.get_locations()
locations_data = BUNDLE.select_items(locations)
return templates.TemplateResponse(
@@ -54,31 +54,31 @@ def mount(app: FastAPI):
return RedirectResponse(f"{location}/tag/today")
@app.get("/weather/{location}/day/mock", response_class=HTMLResponse)
async def get_weather_day_mock(request: Request):
async def get_weather_day_mock(request: AppRequest):
response = WEATHER_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):
async def get_weather_days_mock(request: AppRequest):
response = WEATHER_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
async def get_weather_day(request: AppRequest, location: str, date: datetime.date):
weather_api = request.app.state.api.weather
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
async def get_weather_days(request: AppRequest, location: str, days: int):
weather_api = request.app.state.api.weather
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):
async def get_weather_tag(request: AppRequest, location: str, tag: str):
tag_value = TagUtil.parse_tag(tag)
weather_api: WeatherApi = request.app.state.weather_api
weather_api = request.app.state.api.weather
if tag_value.type == TagType.DAY:
response = await weather_api.get_day(location, tag_value.date)
elif tag_value.type == TagType.DAYS:

View File

@@ -1,12 +1,19 @@
from gallery.sketch.weather.model import Cloudness, Precipitation, Sky, WindDirection
from gallery.sketch.weather.model import (
Cloudness,
Precipitation,
Sky,
WindDirection,
WindDirectionDeg,
)
def wind_direction_icon(wind_direction: WindDirection) -> str:
def wind_direction_icon(wind_direction_deg: float) -> str:
wind_direction = WindDirectionDeg(wind_direction_deg).direction
return {
WindDirection.N: "⬇️",
WindDirection.NO: "↙️",
WindDirection.O: "⬅️",
WindDirection.SO: "↖️",
WindDirection.NE: "↙️",
WindDirection.E: "⬅️",
WindDirection.SE: "↖️",
WindDirection.S: "⬆️",
WindDirection.SW: "↗️",
WindDirection.W: "➡️",