diff --git a/gallery/easel/route/api/weather.py b/gallery/easel/route/api/weather.py index c763927..4c7e1f7 100644 --- a/gallery/easel/route/api/weather.py +++ b/gallery/easel/route/api/weather.py @@ -8,6 +8,11 @@ from gallery.sketch.weather.model import Location, WeatherResponse router = APIRouter(prefix="/weather") +@router.get("/providers") +async def get_api_weather_providers(request: AppRequest) -> list[str]: + return request.app.state.api.get_api_providers("weather") + + @router.get("/locations") async def get_api_weather_locations(request: AppRequest, query: str) -> list[Location]: weather_api = request.app.state.api.weather diff --git a/gallery/easel/route/view/common/utils/template.py b/gallery/easel/route/view/common/utils/template.py index c12f377..df85b6a 100644 --- a/gallery/easel/route/view/common/utils/template.py +++ b/gallery/easel/route/view/common/utils/template.py @@ -1,15 +1,19 @@ import datetime +import typing from pathlib import Path from babel.dates import format_date from fastapi import Request from fastapi.templating import Jinja2Templates +from gallery.easel.core import AppRequest from gallery.version import __version__ from ...translation import _ from .tag import TagUtil +ContextProcessor = typing.Callable[[AppRequest], dict[str, typing.Any]] + def is_widget(request: Request) -> bool: return (request.url.hostname and request.url.hostname.startswith("weather")) or ( @@ -17,17 +21,23 @@ def is_widget(request: Request) -> bool: ) -def context_processor(request: Request) -> dict: +def base_context_processor(request: Request) -> dict: return { "is_widget": is_widget(request), + "provider": request.query_params.get("provider"), } -def build_templates(templates_dir: Path | None = None, filters: dict | None = None) -> Jinja2Templates: +def build_templates( + templates_dir: Path | None = None, filters: dict | None = None, context_processor: ContextProcessor | None = None +) -> Jinja2Templates: directory = [Path(__file__).parent.parent / "templates"] if templates_dir: directory.append(templates_dir) - templates = Jinja2Templates(directory=directory, context_processors=[context_processor]) + context_processors: list[ContextProcessor] = [base_context_processor] + if context_processor: + context_processors.append(context_processor) + templates = Jinja2Templates(directory=directory, context_processors=context_processors) templates.env.globals.update( { "_": _, diff --git a/gallery/easel/route/view/schedule/__init__.py b/gallery/easel/route/view/schedule/__init__.py index a2c5737..13c64a9 100644 --- a/gallery/easel/route/view/schedule/__init__.py +++ b/gallery/easel/route/view/schedule/__init__.py @@ -1,16 +1,32 @@ 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.schedule.api import ScheduleApi from gallery.sketch.schedule.catalog import BUNDLE from ..common.utils.tag import TagType, TagUtil from ..common.utils.template import build_templates from .filters import timedelta_format + +async def get_schedule_api(request: AppRequest, provider: str | None = None) -> ScheduleApi: + return request.app.state.api.get_schedule(provider) + + +ScheduleApiDepends = Annotated[ScheduleApi, Depends(get_schedule_api)] + + +def context_procesor(request: AppRequest) -> dict: + return { + "providers": request.app.state.api.get_api_providers(ScheduleApi.TYPE), + } + + templates = build_templates( Path(__file__).parent / "templates", { @@ -18,12 +34,11 @@ templates = build_templates( }, ) -router = APIRouter() +router = APIRouter(prefix="/schedule") -@router.get("/schedule", response_class=HTMLResponse) -async def get_schedule_list(request: AppRequest): - schedule_api = request.app.state.api.schedule +@router.get("/", response_class=HTMLResponse) +async def get_schedule_list(request: AppRequest, schedule_api: ScheduleApiDepends): channels = await schedule_api.get_channels() channels_data = BUNDLE.select_items(channels) return templates.TemplateResponse( @@ -35,10 +50,9 @@ async def get_schedule_list(request: AppRequest): ) -@router.get("/schedule/tag/{tag}", response_class=HTMLResponse) -async def get_schedule_tag(request: AppRequest, tag: str, live: bool = False): +@router.get("/tag/{tag}", response_class=HTMLResponse) +async def get_schedule_tag(request: AppRequest, schedule_api: ScheduleApiDepends, tag: str, live: bool = False): tag_value = TagUtil.parse_tag(tag) - schedule_api = request.app.state.api.schedule results = await schedule_api.get_all_schedules(tag_value.date) return templates.TemplateResponse( request=request, @@ -53,15 +67,14 @@ async def get_schedule_tag(request: AppRequest, tag: str, live: bool = False): ) -@router.get("/schedule/{channel}", response_class=RedirectResponse) +@router.get("/{channel}", response_class=RedirectResponse) async def get_channel_default(channel: str): return RedirectResponse(f"{channel}/tag/today") -@router.get("/schedule/{channel}/tag/{tag}", response_class=HTMLResponse) -async def get_channel_tag(request: AppRequest, channel: str, tag: str): +@router.get("/{channel}/tag/{tag}", response_class=HTMLResponse) +async def get_channel_tag(request: AppRequest, schedule_api: ScheduleApiDepends, channel: str, tag: str): tag_value = TagUtil.parse_tag(tag) - 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: diff --git a/gallery/easel/route/view/schedule/templates/index.html b/gallery/easel/route/view/schedule/templates/index.html index 4763633..0a93198 100644 --- a/gallery/easel/route/view/schedule/templates/index.html +++ b/gallery/easel/route/view/schedule/templates/index.html @@ -4,12 +4,12 @@ {% block content %}