feat(easel): add api provider
This commit is contained in:
@@ -1,22 +1,39 @@
|
||||
import datetime
|
||||
from pathlib import Path
|
||||
from typing import Annotated
|
||||
|
||||
from fastapi import APIRouter
|
||||
from fastapi import APIRouter, Depends
|
||||
from fastapi.responses import HTMLResponse, RedirectResponse
|
||||
|
||||
from gallery.easel.core import AppRequest
|
||||
from gallery.sketch.weather.api import WeatherApi
|
||||
from gallery.sketch.weather.model import WeatherResponse
|
||||
|
||||
from ..common.utils.tag import TagType, TagUtil
|
||||
from ..common.utils.template import build_templates
|
||||
from .filters import cloudness_icon, wind_direction_icon
|
||||
|
||||
|
||||
async def get_weather_api(request: AppRequest, provider: str | None = None) -> WeatherApi:
|
||||
return request.app.state.api.get_weather(provider)
|
||||
|
||||
|
||||
WeatherApiDepends = Annotated[WeatherApi, Depends(get_weather_api)]
|
||||
|
||||
|
||||
def context_procesor(request: AppRequest) -> dict:
|
||||
return {
|
||||
"providers": request.app.state.api.get_api_providers(WeatherApi.TYPE),
|
||||
}
|
||||
|
||||
|
||||
templates = build_templates(
|
||||
Path(__file__).parent / "templates",
|
||||
{
|
||||
"wind_direction_icon": wind_direction_icon,
|
||||
"cloudness_icon": cloudness_icon,
|
||||
},
|
||||
context_procesor,
|
||||
)
|
||||
|
||||
|
||||
@@ -30,12 +47,11 @@ def build_weather_response(request: AppRequest, response: WeatherResponse):
|
||||
)
|
||||
|
||||
|
||||
router = APIRouter()
|
||||
router = APIRouter(prefix="/weather")
|
||||
|
||||
|
||||
@router.get("/weather", response_class=HTMLResponse)
|
||||
async def get_weather_index(request: AppRequest, query: str | None = None):
|
||||
weather_api = request.app.state.api.weather
|
||||
@router.get("/", response_class=HTMLResponse)
|
||||
async def get_weather_index(request: AppRequest, weather_api: WeatherApiDepends, query: str | None = None):
|
||||
locations = (await weather_api.find_locations(query)) if query else []
|
||||
return templates.TemplateResponse(
|
||||
request=request,
|
||||
@@ -46,29 +62,31 @@ async def get_weather_index(request: AppRequest, query: str | None = None):
|
||||
)
|
||||
|
||||
|
||||
@router.get("/weather/{location}", response_class=RedirectResponse)
|
||||
@router.get("/{location}", response_class=RedirectResponse)
|
||||
async def get_weather_default(location: str):
|
||||
return RedirectResponse(f"{location}/tag/today")
|
||||
|
||||
|
||||
@router.get("/weather/{location}/day/{date}", response_class=HTMLResponse)
|
||||
async def get_weather_day(request: AppRequest, location: str, date: datetime.date):
|
||||
weather_api = request.app.state.api.weather
|
||||
@router.get("/{location}/day/{date}", response_class=HTMLResponse)
|
||||
async def get_weather_day(
|
||||
request: AppRequest,
|
||||
weather_api: WeatherApiDepends,
|
||||
location: str,
|
||||
date: datetime.date,
|
||||
):
|
||||
response = await weather_api.get_day(location, date)
|
||||
return build_weather_response(request, response)
|
||||
|
||||
|
||||
@router.get("/weather/{location}/days/{days}", response_class=HTMLResponse)
|
||||
async def get_weather_days(request: AppRequest, location: str, days: int):
|
||||
weather_api = request.app.state.api.weather
|
||||
@router.get("/{location}/days/{days}", response_class=HTMLResponse)
|
||||
async def get_weather_days(request: AppRequest, weather_api: WeatherApiDepends, location: str, days: int):
|
||||
response = await weather_api.get_days(location, days)
|
||||
return build_weather_response(request, response)
|
||||
|
||||
|
||||
@router.get("/weather/{location}/tag/{tag}", response_class=HTMLResponse)
|
||||
async def get_weather_tag(request: AppRequest, location: str, tag: str):
|
||||
@router.get("/{location}/tag/{tag}", response_class=HTMLResponse)
|
||||
async def get_weather_tag(request: AppRequest, weather_api: WeatherApiDepends, location: str, tag: str):
|
||||
tag_value = TagUtil.parse_tag(tag)
|
||||
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:
|
||||
|
||||
@@ -1,6 +1,23 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}{{_("Weather")}}{% endblock %}
|
||||
|
||||
{# {% block header %}
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-secondary dropdown-toggle"
|
||||
type="button"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-expanded="false">
|
||||
{{provider or providers[0]}}
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
{% for provider in providers %}
|
||||
<li><a class="dropdown-item"
|
||||
href="{{ url_for('get_weather_index').include_query_params(provider=provider) }}">{{provider}}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %} #}
|
||||
|
||||
{% block content %}
|
||||
<h1>{{_("Weather")}}</h1>
|
||||
<form action=""
|
||||
@@ -19,7 +36,7 @@
|
||||
<ul id="locations"
|
||||
class="list-group mb-5">
|
||||
{% for location in locations %}
|
||||
<a href="weather/{{location.id}}"
|
||||
<a href="{{location.id}}"
|
||||
class="list-group-item list-group-item-action px-4"
|
||||
onclick="saveLocation({id:'{{location.id}}', name:'{{location.name}}'});">
|
||||
<span class="fi fi-{{location.country_code}} me-1"></span>
|
||||
@@ -39,7 +56,7 @@
|
||||
container.innerHTML = '';
|
||||
for (const [id, name] of Object.entries(locations)) {
|
||||
const element = document.createElement('a');
|
||||
element.href = `weather/${id}`;
|
||||
element.href = `${id}`;
|
||||
element.className = 'list-group-item list-group-item-action px-4 d-flex justify-content-between align-items-start';
|
||||
element.innerHTML = `
|
||||
<span class="text-primary me-auto">${name}</span>
|
||||
|
||||
Reference in New Issue
Block a user