diff --git a/gallery/easel/__init__.py b/gallery/easel/__init__.py index 055baf2..901c16e 100644 --- a/gallery/easel/__init__.py +++ b/gallery/easel/__init__.py @@ -1,10 +1,11 @@ from fastapi import FastAPI +from fastapi.responses import RedirectResponse from fastapi.staticfiles import StaticFiles from gallery.sketch.bundle import ApiBundle from gallery.util import root_path -from .route import api, doc, view +from .route import api, view def build_app(api_bundle: ApiBundle) -> FastAPI: @@ -15,8 +16,12 @@ def build_app(api_bundle: ApiBundle) -> FastAPI: ) app.state.api = api_bundle app.mount("/static", StaticFiles(directory=root_path / "static/dist")) - doc.mount(app) api.app.state.api = api_bundle app.mount("/api", api.app) app.include_router(view.router) + + @app.get("/docs") + def get_docs(): + return RedirectResponse("/api/docs") + return app diff --git a/gallery/easel/depends/schedule.py b/gallery/easel/depends/schedule.py index 132cafe..baa7682 100644 --- a/gallery/easel/depends/schedule.py +++ b/gallery/easel/depends/schedule.py @@ -1,4 +1,4 @@ -from typing import Annotated +from typing import Annotated, NamedTuple from fastapi import Depends @@ -7,3 +7,35 @@ from gallery.sketch.schedule.api import ScheduleApi from .api import api_resolver ScheduleApiDepends = Annotated[ScheduleApi, Depends(api_resolver(ScheduleApi))] + + +class ChannelDef(NamedTuple): + provider: str + id: str + + +GROUP_CANNELS_MAP: dict[str, list[ChannelDef]] = { + "central": [ + ChannelDef("yandextv", "pervyy-16"), + ChannelDef("yandextv", "rossiya-1-31"), + ChannelDef("yandextv", "ntv-11"), + ChannelDef("yandextv", "sts-8"), + ], + "sport": [ + ChannelDef("matchtv", "matchtv"), + ChannelDef("matchtv", "igra"), + ChannelDef("matchtv", "arena"), + ChannelDef("matchtv", "futbol-1"), + ChannelDef("matchtv", "futbol-2"), + ChannelDef("matchtv", "futbol-3"), + ChannelDef("matchtv", "strana"), + ChannelDef("yandextv", "start-103"), + ], +} + + +def resolve_group_channels(group_id: str) -> list[ChannelDef]: + return GROUP_CANNELS_MAP.get(group_id) or [ChannelDef(*item.split(":")) for item in group_id.split(",")] + + +ScheduleGroupChannelsDepends = Annotated[list[ChannelDef], Depends(resolve_group_channels)] diff --git a/gallery/easel/route/api/__init__.py b/gallery/easel/route/api/__init__.py index 33200b8..4dd5ceb 100644 --- a/gallery/easel/route/api/__init__.py +++ b/gallery/easel/route/api/__init__.py @@ -1,9 +1,14 @@ from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware +from gallery.easel.route import doc + from . import schedule, weather -app = FastAPI(openapi_prefix="/api") +app = FastAPI( + docs_url=None, + redoc_url=None, +) app.add_middleware( CORSMiddleware, allow_origins=["*"], @@ -13,3 +18,4 @@ app.add_middleware( ) app.include_router(weather.router) app.include_router(schedule.router) +doc.mount(app, "/api") diff --git a/gallery/easel/route/api/schedule.py b/gallery/easel/route/api/schedule.py index 93f3af9..e55cc56 100644 --- a/gallery/easel/route/api/schedule.py +++ b/gallery/easel/route/api/schedule.py @@ -1,7 +1,11 @@ from fastapi import APIRouter from gallery.easel.core import AppRequest -from gallery.easel.depends.schedule import ScheduleApiDepends +from gallery.easel.depends.schedule import ( + GROUP_CANNELS_MAP, + ScheduleApiDepends, + ScheduleGroupChannelsDepends, +) from gallery.sketch.schedule.api import ScheduleApi from gallery.sketch.schedule.model import Channel, Schedule @@ -10,6 +14,19 @@ from ...depends.date import DateDepends router = APIRouter(prefix="/schedule", tags=["Schedule"]) +@router.get("/groups") +async def get_api_schedule_groups(): + return list(GROUP_CANNELS_MAP.keys()) + + +@router.get("/group/{group_id}/{date}") +async def get_api_schedule_group_schedule( + request: AppRequest, channels: ScheduleGroupChannelsDepends, date: DateDepends +) -> list[Schedule]: + api = request.app.state.api + return [await api.get_api(ScheduleApi, channel.provider).get_schedule(channel.id, date) for channel in channels] + + @router.get("/providers") async def get_api_weather_providers(request: AppRequest) -> list[str]: return request.app.state.api.get_api_providers(ScheduleApi) diff --git a/gallery/easel/route/doc/__init__.py b/gallery/easel/route/doc/__init__.py index fdba2b2..b4eda22 100644 --- a/gallery/easel/route/doc/__init__.py +++ b/gallery/easel/route/doc/__init__.py @@ -8,7 +8,8 @@ from fastapi.openapi.docs import ( from fastapi.staticfiles import StaticFiles -def mount(app: FastAPI): +def mount(app: FastAPI, prefix: str | None = None): + openapi_url = prefix + app.openapi_url if prefix else app.openapi_url app.mount( "/docs/static", StaticFiles(directory=Path(__file__).parent / "static"), @@ -17,7 +18,7 @@ def mount(app: FastAPI): @app.get("/docs", include_in_schema=False) async def custom_swagger_ui_html(): return get_swagger_ui_html( - openapi_url=app.openapi_url, + openapi_url=openapi_url, title=app.title + " - Swagger UI", oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url, swagger_js_url="docs/static/swagger-ui-bundle.js", @@ -31,7 +32,7 @@ def mount(app: FastAPI): @app.get("/redoc", include_in_schema=False) async def redoc_html(): return get_redoc_html( - openapi_url=app.openapi_url, + openapi_url=openapi_url, title=app.title + " - ReDoc", redoc_js_url="docs/static/redoc.standalone.js", ) diff --git a/gallery/easel/route/view/root/templates/root_index.html b/gallery/easel/route/view/root/templates/root_index.html index 12f0fd9..396c88a 100644 --- a/gallery/easel/route/view/root/templates/root_index.html +++ b/gallery/easel/route/view/root/templates/root_index.html @@ -17,13 +17,13 @@