diff --git a/gallery/easel/route/view/schedule/__init__.py b/gallery/easel/route/view/schedule/__init__.py index 83f671b..b208bb8 100644 --- a/gallery/easel/route/view/schedule/__init__.py +++ b/gallery/easel/route/view/schedule/__init__.py @@ -7,6 +7,7 @@ from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates from gallery.sketch.schedule.api import ScheduleApi +from gallery.sketch.schedule.catalog import BUNDLE from gallery.version import __version__ from ..common.util import TagType, TagUtil @@ -23,12 +24,13 @@ def mount(app: FastAPI): async def get_schedule_list(request: Request): schedule_api: ScheduleApi = request.app.state.schedule_api channels = await schedule_api.get_channels() + channels_data = BUNDLE.select_items(channels) return templates.TemplateResponse( request=request, name="index.html", context={ "version": __version__, - "channels": channels, + "channels": channels_data, }, ) diff --git a/gallery/easel/route/view/schedule/templates/index.html b/gallery/easel/route/view/schedule/templates/index.html index 45a3e0e..2414898 100644 --- a/gallery/easel/route/view/schedule/templates/index.html +++ b/gallery/easel/route/view/schedule/templates/index.html @@ -28,9 +28,9 @@ diff --git a/gallery/easel/route/view/weather/__init__.py b/gallery/easel/route/view/weather/__init__.py index a5e7788..4be51d0 100644 --- a/gallery/easel/route/view/weather/__init__.py +++ b/gallery/easel/route/view/weather/__init__.py @@ -7,6 +7,7 @@ from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates from gallery.sketch.weather.api import WeatherApi +from gallery.sketch.weather.catalog import BUNDLE from gallery.sketch.weather.mock import WEATHER_MOCK_DATA from gallery.sketch.weather.model import WeatherResponse from gallery.version import __version__ @@ -38,12 +39,13 @@ def mount(app: FastAPI): async def get_weather_list(request: Request): weather_api: WeatherApi = request.app.state.weather_api locations = await weather_api.get_locations() + locations_data = BUNDLE.select_items(locations) return templates.TemplateResponse( request=request, name="index.html", context={ "version": __version__, - "locations": locations, + "locations": locations_data, }, ) diff --git a/gallery/easel/route/view/weather/templates/index.html b/gallery/easel/route/view/weather/templates/index.html index 512d05a..d0dea15 100644 --- a/gallery/easel/route/view/weather/templates/index.html +++ b/gallery/easel/route/view/weather/templates/index.html @@ -29,7 +29,7 @@ diff --git a/gallery/painting/gismeteo/api.py b/gallery/painting/gismeteo/api.py index 73280f8..713d263 100644 --- a/gallery/painting/gismeteo/api.py +++ b/gallery/painting/gismeteo/api.py @@ -7,6 +7,7 @@ from aiocache import cached from bs4 import BeautifulSoup from gallery.sketch.weather.api import WeatherApi +from gallery.sketch.weather.catalog import LocationId from gallery.sketch.weather.model import WeatherResponse, WeatherValue from . import datehelp @@ -81,8 +82,8 @@ class GismeteoApi(WeatherApi): async def get_locations(self) -> list[str]: return [ - "orel-4432", - "zmiyevka-184640", + LocationId.OREL, + LocationId.ZMIYEVKA, ] @cached(ttl=CACHE_TTL) diff --git a/gallery/painting/matchtv/api.py b/gallery/painting/matchtv/api.py index d5d5275..2ae35c6 100644 --- a/gallery/painting/matchtv/api.py +++ b/gallery/painting/matchtv/api.py @@ -6,23 +6,12 @@ from aiocache import cached from bs4 import BeautifulSoup from gallery.sketch.schedule.api import ScheduleApi +from gallery.sketch.schedule.catalog import ChannelId from gallery.sketch.schedule.model import Channel, Schedule, ScheduleValue logger = logging.getLogger("matchtv") -CHANNEL_LIST = [ - "matchtv", - "igra", - "arena", - "futbol-1", - "futbol-2", - "futbol-3", - "strana", - # "planeta", -] - - class MatchTvApi(ScheduleApi): BASE_URL = "https://matchtv.ru" CACHE_TTL = 30 * 60 @@ -46,7 +35,15 @@ class MatchTvApi(ScheduleApi): return await response.text() async def get_channels(self) -> list[str]: - return CHANNEL_LIST + return [ + ChannelId.MATCH_TV, + ChannelId.MATCH_IGRA, + ChannelId.MATCH_ARENA, + ChannelId.MATCH_FUTBOL_1, + ChannelId.MATCH_FUTBOL_2, + ChannelId.MATCH_FUTBOL_3, + ChannelId.MATCH_STRANA, + ] @cached(ttl=CACHE_TTL) async def get_channel_schedule( diff --git a/gallery/sketch/catalog.py b/gallery/sketch/catalog.py new file mode 100644 index 0000000..e4f519f --- /dev/null +++ b/gallery/sketch/catalog.py @@ -0,0 +1,11 @@ +from typing import Generic, TypeVar + +T = TypeVar("T") + + +class CatalogBundle(Generic[T]): + def __init__(self, items: list[T]) -> None: + self._items_by_id = {item.id: item for item in items} + + def select_items(self, ids: list[str]) -> list[T]: + return [self._items_by_id[id_] for id_ in ids] diff --git a/gallery/sketch/schedule/catalog.py b/gallery/sketch/schedule/catalog.py new file mode 100644 index 0000000..2538f17 --- /dev/null +++ b/gallery/sketch/schedule/catalog.py @@ -0,0 +1,31 @@ +from enum import Enum + +from gallery.sketch.catalog import CatalogBundle + +from .model import Channel + + +class ChannelId(str, Enum): + MATCH_TV = "matchtv" + MATCH_IGRA = "igra" + MATCH_ARENA = "arena" + MATCH_FUTBOL_1 = "futbol-1" + MATCH_FUTBOL_2 = "futbol-2" + MATCH_FUTBOL_3 = "futbol-3" + MATCH_STRANA = "strana" + + def __str__(self) -> str: + return self.value + + +BUNDLE = CatalogBundle( + [ + Channel(id=ChannelId.MATCH_TV, name="Матч ТВ"), + Channel(id=ChannelId.MATCH_IGRA, name="Матч! Игра"), + Channel(id=ChannelId.MATCH_ARENA, name="Матч! Арена"), + Channel(id=ChannelId.MATCH_FUTBOL_1, name="Футбол 1"), + Channel(id=ChannelId.MATCH_FUTBOL_2, name="Футбол 2"), + Channel(id=ChannelId.MATCH_FUTBOL_3, name="Футбол 3"), + Channel(id=ChannelId.MATCH_STRANA, name="Матч! Страна"), + ] +) diff --git a/gallery/sketch/weather/catalog.py b/gallery/sketch/weather/catalog.py new file mode 100644 index 0000000..97aa74d --- /dev/null +++ b/gallery/sketch/weather/catalog.py @@ -0,0 +1,21 @@ +from enum import Enum + +from gallery.sketch.catalog import CatalogBundle + +from .model import Location + + +class LocationId(str, Enum): + OREL = "orel-4432" + ZMIYEVKA = "zmiyevka-184640" + + def __str__(self) -> str: + return self.value + + +BUNDLE = CatalogBundle( + [ + Location(id=LocationId.OREL, name="Орёл"), + Location(id=LocationId.ZMIYEVKA, name="Змиёвка"), + ] +) diff --git a/gallery/sketch/weather/model.py b/gallery/sketch/weather/model.py index d8532ff..c786fa6 100644 --- a/gallery/sketch/weather/model.py +++ b/gallery/sketch/weather/model.py @@ -9,6 +9,11 @@ class Model(BaseModel): use_enum_values = True +class Location(Model): + id: str + name: str + + class Cloudness(str, Enum): CLEAR = "clear" PARTLY_CLOUDY = "party_cloudy" diff --git a/tests/test_matchtv_api.py b/tests/test_matchtv_api.py index c66388f..f234a82 100644 --- a/tests/test_matchtv_api.py +++ b/tests/test_matchtv_api.py @@ -20,5 +20,4 @@ def matchtv_api_fixture() -> MatchTvApi: async def test_channel(matchtv_api: MatchTvApi): result = await matchtv_api.get_channel_schedule("matchtv", datetime.date.today()) assert result is not None - assert len(result.items) > 0 - print(">>", "\n".join(map(str, result.items))) + assert len(result.values) > 0