diff --git a/gallery/easel/depends/api.py b/gallery/easel/depends/api.py
new file mode 100644
index 0000000..3d6b291
--- /dev/null
+++ b/gallery/easel/depends/api.py
@@ -0,0 +1,9 @@
+from gallery.easel.core import AppRequest
+from gallery.sketch.api import API
+
+
+def api_resolver(api_type: type[API]):
+ def get_api(request: AppRequest, provider: str | None = None) -> API:
+ return request.app.state.api.get_api(api_type, provider)
+
+ return get_api
diff --git a/gallery/easel/depends/schedule.py b/gallery/easel/depends/schedule.py
new file mode 100644
index 0000000..132cafe
--- /dev/null
+++ b/gallery/easel/depends/schedule.py
@@ -0,0 +1,9 @@
+from typing import Annotated
+
+from fastapi import Depends
+
+from gallery.sketch.schedule.api import ScheduleApi
+
+from .api import api_resolver
+
+ScheduleApiDepends = Annotated[ScheduleApi, Depends(api_resolver(ScheduleApi))]
diff --git a/gallery/easel/depends/weather.py b/gallery/easel/depends/weather.py
index e0db605..2fb3c14 100644
--- a/gallery/easel/depends/weather.py
+++ b/gallery/easel/depends/weather.py
@@ -2,12 +2,8 @@ from typing import Annotated
from fastapi import Depends
-from gallery.easel.core import AppRequest
from gallery.sketch.weather.api import WeatherApi
+from .api import api_resolver
-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)]
+WeatherApiDepends = Annotated[WeatherApi, Depends(api_resolver(WeatherApi))]
diff --git a/gallery/easel/route/api/schedule.py b/gallery/easel/route/api/schedule.py
index ea9d39a..e276a1a 100644
--- a/gallery/easel/route/api/schedule.py
+++ b/gallery/easel/route/api/schedule.py
@@ -3,13 +3,13 @@ import datetime
from fastapi import APIRouter
from gallery.easel.core import AppRequest
-from gallery.sketch.schedule.model import ChannelId, Schedule
+from gallery.sketch.schedule.model import Channel, Schedule
router = APIRouter(prefix="/schedule")
@router.get("/channels")
-async def get_api_schedule_channels(request: AppRequest) -> list[ChannelId]:
+async def get_api_schedule_channels(request: AppRequest) -> list[Channel]:
schedule_api = request.app.state.api.schedule
return await schedule_api.get_channels()
diff --git a/gallery/easel/route/view/schedule/__init__.py b/gallery/easel/route/view/schedule/__init__.py
index 13c64a9..8b6b057 100644
--- a/gallery/easel/route/view/schedule/__init__.py
+++ b/gallery/easel/route/view/schedule/__init__.py
@@ -1,26 +1,18 @@
import datetime
from pathlib import Path
-from typing import Annotated
-from fastapi import APIRouter, Depends
+from fastapi import APIRouter
from fastapi.responses import HTMLResponse, RedirectResponse
from gallery.easel.core import AppRequest
+from gallery.easel.depends.schedule import ScheduleApiDepends
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),
@@ -32,20 +24,20 @@ templates = build_templates(
{
"timedelta_format": timedelta_format,
},
+ context_procesor,
)
router = APIRouter(prefix="/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)
+async def get_schedule_index(request: AppRequest, schedule_api: ScheduleApiDepends, query: str | None = None):
+ channels = (await schedule_api.find_channels(query)) if query else []
return templates.TemplateResponse(
request=request,
name="index.html",
context={
- "channels": channels_data,
+ "channels": channels,
},
)
@@ -53,15 +45,15 @@ async def get_schedule_list(request: AppRequest, schedule_api: ScheduleApiDepend
@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)
- results = await schedule_api.get_all_schedules(tag_value.date)
+ # results = await schedule_api.get_all_schedules(tag_value.date)
return templates.TemplateResponse(
request=request,
name="schedule.html",
context={
"tag_util": TagUtil,
"datetime": datetime,
- "response": results[0],
- "responses": results,
+ # "response": results[0],
+ # "responses": results,
"live": live,
},
)
@@ -72,11 +64,11 @@ async def get_channel_default(channel: str):
return RedirectResponse(f"{channel}/tag/today")
-@router.get("/{channel}/tag/{tag}", response_class=HTMLResponse)
+@router.get("/{provider}/{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)
if tag_value.type == TagType.DAY:
- response = await schedule_api.get_channel_schedule(channel, tag_value.date)
+ response = await schedule_api.get_schedule(channel, tag_value.date)
else:
raise ValueError(tag)
return templates.TemplateResponse(
diff --git a/gallery/easel/route/view/schedule/templates/index.html b/gallery/easel/route/view/schedule/templates/index.html
index 0a93198..f88fe85 100644
--- a/gallery/easel/route/view/schedule/templates/index.html
+++ b/gallery/easel/route/view/schedule/templates/index.html
@@ -3,16 +3,60 @@
{% block content %}
{{_("TV program")}}
-
+
+
+{% endif %}
+
+
{% endblock %}
\ No newline at end of file
diff --git a/gallery/painting/matchtv/api.py b/gallery/painting/matchtv/api.py
index 7075f3a..2031f9e 100644
--- a/gallery/painting/matchtv/api.py
+++ b/gallery/painting/matchtv/api.py
@@ -4,7 +4,7 @@ import logging
from bs4 import BeautifulSoup
from gallery.sketch.schedule.api import ScheduleApi
-from gallery.sketch.schedule.model import Channel, ChannelId, Schedule, ScheduleValue
+from gallery.sketch.schedule.model import Channel, Schedule, ScheduleValue
from gallery.sketch.source import ApiSource
logger = logging.getLogger("matchtv")
@@ -14,18 +14,10 @@ class MatchTvApi(ScheduleApi):
PROVIDER = "matchtv"
SOURCE = ApiSource("https://matchtv.ru")
- async def get_channels(self) -> list[ChannelId]:
- 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,
- ]
+ async def find_channels(self, query: str) -> list[Channel]:
+ raise NotImplementedError
- async def get_channel_schedule(self, channel_id: ChannelId, date: datetime.date) -> Schedule:
+ async def get_channel_schedule(self, channel_id: str, date: datetime.date) -> Schedule:
endpoint = f"tvguide/{channel_id}?date={date:%Y%m%d}"
data = await self.SOURCE.request(endpoint)
soup = BeautifulSoup(data, features="html.parser")
@@ -50,4 +42,8 @@ class MatchTvApi(ScheduleApi):
if prev_value is not None:
prev_value.end = item_date
prev_value = value
- return Schedule(channel=Channel(id=channel_id, name=channel_name), date=date, values=values)
+ return Schedule(
+ channel=Channel(id=channel_id, name=channel_name, provider=self.provider),
+ date=date,
+ values=values,
+ )
diff --git a/gallery/painting/yandextv/api.py b/gallery/painting/yandextv/api.py
index f3c66b4..39267ce 100644
--- a/gallery/painting/yandextv/api.py
+++ b/gallery/painting/yandextv/api.py
@@ -1,27 +1,15 @@
import datetime
+import json
import logging
from bs4 import BeautifulSoup
from gallery.sketch.schedule.api import ScheduleApi
-from gallery.sketch.schedule.model import Channel, ChannelId, Schedule, ScheduleValue
+from gallery.sketch.schedule.model import Channel, Schedule, ScheduleValue
from gallery.sketch.source import ApiSource
logger = logging.getLogger("matchtv")
-CHANNELS_MAP: dict[ChannelId, str] = {
- ChannelId.MATCH_TV: "match-tv-49",
- ChannelId.MATCH_IGRA: "match-igra-1174",
- ChannelId.MATCH_ARENA: "match-arena-1173",
- ChannelId.MATCH_FUTBOL_1: "match-futbol-1-646",
- ChannelId.MATCH_FUTBOL_2: "match-futbol-2-593",
- ChannelId.MATCH_FUTBOL_3: "match-futbol-3-797",
- ChannelId.MATCH_STRANA: "match-strana-1356",
- ChannelId.MATCH_PLANETA: "match-planeta-1177",
- # ChannelId.EUROSPORT: "eurosport-677",
- # ChannelId.EUROSPORT_2: "eurosport-2-720",
- ChannelId.START: "start-103",
-}
HEADERS: dict[str, str] = {
"Accept": (
@@ -57,11 +45,17 @@ class YandexTvApi(ScheduleApi):
PROVIDER = "yandextv"
SOURCE = ApiSource("https://tv.yandex.ru", headers=HEADERS)
- async def get_channels(self) -> list[ChannelId]:
- return list(CHANNELS_MAP.keys())
+ async def find_channels(self, query: str) -> list[Channel]:
+ url = f"https://suggest-multi.yandex.ru/suggest-tv2?v=4&uil=ru&lr=10&count_channels=4&count_programs=4&sn=50&part={query}"
+ _, values = json.loads(await self.SOURCE.request(url))
+ result = []
+ for _, name, content in values[:-1]:
+ channel_id = content["url"].split("/")[-1]
+ result.append(Channel(id=channel_id, name=name, provider=self.provider))
+ return result
- async def get_channel_schedule(self, channel_id: ChannelId, date: datetime.date) -> Schedule:
- endpoint = f"channel/{CHANNELS_MAP[channel_id]}?date={date:%Y-%m-%d}"
+ async def get_channel_schedule(self, channel_id: str, date: datetime.date) -> Schedule:
+ endpoint = f"channel/{channel_id}?date={date:%Y-%m-%d}"
data = await self.SOURCE.request(endpoint)
soup = BeautifulSoup(data, features="html.parser")
if soup.select_one(".CheckboxCaptcha") is not None:
@@ -85,4 +79,8 @@ class YandexTvApi(ScheduleApi):
if prev_value is not None:
prev_value.end = item_date
prev_value = value
- return Schedule(channel=Channel(id=channel_id, name=channel_name), date=date, values=values)
+ return Schedule(
+ channel=Channel(id=channel_id, name=channel_name, provider=self.provider),
+ date=date,
+ values=values,
+ )
diff --git a/gallery/sketch/bundle.py b/gallery/sketch/bundle.py
index 70356d0..f2f49c0 100644
--- a/gallery/sketch/bundle.py
+++ b/gallery/sketch/bundle.py
@@ -1,6 +1,4 @@
from .api import API, Api
-from .schedule.api import ScheduleApi
-from .weather.api import WeatherApi
class ApiBundle:
@@ -21,9 +19,3 @@ class ApiBundle:
if provider is None or provider == value.provider:
return value
raise ValueError(api_type, provider)
-
- def get_weather(self, provider: str | None = None) -> WeatherApi:
- return self.get_api(WeatherApi, provider)
-
- def get_schedule(self, provider: str | None = None) -> ScheduleApi:
- return self.get_api(ScheduleApi, provider)
diff --git a/gallery/sketch/catalog.py b/gallery/sketch/catalog.py
deleted file mode 100644
index c0d9afc..0000000
--- a/gallery/sketch/catalog.py
+++ /dev/null
@@ -1,14 +0,0 @@
-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 get_item(self, item_id: str) -> T:
- return self._items_by_id[item_id]
-
- 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/api.py b/gallery/sketch/schedule/api.py
index 11abe2a..b6a3884 100644
--- a/gallery/sketch/schedule/api.py
+++ b/gallery/sketch/schedule/api.py
@@ -1,25 +1,15 @@
-import asyncio
import datetime
from ..api import Api
-from .model import ChannelId, Schedule
+from .model import Channel, Schedule
class ScheduleApi(Api):
TYPE = "schedule"
INTERVAL: float = 0.5
- async def get_channels(self) -> list[ChannelId]:
+ async def find_channels(self, query: str) -> list[Channel]:
raise NotImplementedError
- async def get_channel_schedule(self, channel_id: ChannelId, date: datetime.date) -> Schedule:
+ async def get_schedule(self, channel_id: str, date: datetime.date) -> Schedule:
raise NotImplementedError
-
- async def get_all_schedules(self, date: datetime.date) -> list[Schedule]:
- channels = await self.get_channels()
- results = []
- for channel in channels:
- results.append(await self.get_channel_schedule(channel_id=channel, date=date))
- if self.INTERVAL > 0:
- await asyncio.sleep(self.INTERVAL)
- return results
diff --git a/gallery/sketch/schedule/cached.py b/gallery/sketch/schedule/cached.py
index ec36150..8563d36 100644
--- a/gallery/sketch/schedule/cached.py
+++ b/gallery/sketch/schedule/cached.py
@@ -6,7 +6,7 @@ from gallery.sketch.cached import CachedApi, CachePreset
from gallery.util import TimeUnit
from .api import ScheduleApi
-from .model import ChannelId, Schedule
+from .model import Channel, Schedule
CACHE_PRESET = CachePreset(ttl=TimeUnit.HOUR * 6)
@@ -15,11 +15,11 @@ class CachedScheduleApi(ScheduleApi, CachedApi[ScheduleApi]):
CACHE_KEY = ScheduleApi.TYPE
@cached(
- key_builder=lambda fun, self: f"api.{self.CACHE_KEY}.{self.provider}.channels",
+ key_builder=lambda fun, self, query: f"api.{self.CACHE_KEY}.{self.provider}.find.{query}",
**CACHE_PRESET._asdict(),
)
- async def get_channels(self) -> list[ChannelId]:
- return await self._api.get_channels()
+ async def find_channels(self, query: str) -> list[Channel]:
+ return await self._api.find_channels(query)
@cached(
key_builder=lambda fun, self, channel_id, date: (
@@ -27,12 +27,5 @@ class CachedScheduleApi(ScheduleApi, CachedApi[ScheduleApi]):
),
**CACHE_PRESET._asdict(),
)
- async def get_channel_schedule(self, channel_id: ChannelId, date: datetime.date) -> Schedule:
+ async def get_channel_schedule(self, channel_id: str, date: datetime.date) -> Schedule:
return await self._api.get_channel_schedule(channel_id, date)
-
- @cached(
- key_builder=lambda fun, self, date: (f"api.{self.CACHE_KEY}.{self.provider}.all.{date}"),
- **CACHE_PRESET._asdict(),
- )
- async def get_all_schedules(self, date: datetime.date) -> list[Schedule]:
- return await self._api.get_all_schedules(date)
diff --git a/gallery/sketch/schedule/catalog.py b/gallery/sketch/schedule/catalog.py
deleted file mode 100644
index 6ed8afd..0000000
--- a/gallery/sketch/schedule/catalog.py
+++ /dev/null
@@ -1,21 +0,0 @@
-from gallery.sketch.catalog import CatalogBundle
-
-from .model import Channel, ChannelId
-
-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="Матч! Страна"),
- Channel(id=ChannelId.MATCH_PLANETA, name="Матч! Планета"),
- Channel(id=ChannelId.MATCH_PLANETA, name="Матч! Планета"),
- Channel(id=ChannelId.EUROSPORT, name="Europsort"),
- Channel(id=ChannelId.EUROSPORT_2, name="Europsort 2"),
- Channel(id=ChannelId.START, name="Старт!"),
- Channel(id=ChannelId.TEST, name="Тест"),
- ]
-)
diff --git a/gallery/sketch/schedule/model.py b/gallery/sketch/schedule/model.py
index 790c22b..533c3c2 100644
--- a/gallery/sketch/schedule/model.py
+++ b/gallery/sketch/schedule/model.py
@@ -1,5 +1,4 @@
import datetime
-from enum import StrEnum
from pydantic import BaseModel
@@ -9,27 +8,10 @@ class Model(BaseModel):
use_enum_values = True
-class ChannelId(StrEnum):
- 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"
- MATCH_PLANETA = "planeta"
- EUROSPORT = "eurosport"
- EUROSPORT_2 = "eurosport-2"
- START = "start"
- TEST = "test"
-
- def __str__(self) -> str:
- return self.value
-
-
class Channel(Model):
- id: ChannelId
+ id: str
name: str
+ provider: str
class ScheduleValue(Model):
diff --git a/gallery/sketch/source.py b/gallery/sketch/source.py
index f2d602f..1b716c1 100644
--- a/gallery/sketch/source.py
+++ b/gallery/sketch/source.py
@@ -26,7 +26,10 @@ class ApiSource:
self._headers = headers
async def request(self, endpoint: str) -> str:
- url = f"{self._base_url}/{endpoint}"
+ if endpoint.startswith("https:"):
+ url = endpoint
+ else:
+ url = f"{self._base_url}/{endpoint}"
logger.info(url)
headers = {"User-Agent": self._user_agent, **(self._headers or {})}
async with aiohttp.ClientSession(
diff --git a/static/src/index.ts b/static/src/index.ts
index f0b971c..6c0de69 100644
--- a/static/src/index.ts
+++ b/static/src/index.ts
@@ -4,6 +4,7 @@ import "./language";
import "./main.scss";
import "./theme";
import "./weather/weather";
+import "./schedule/schedule";
document.addEventListener("DOMContentLoaded", (event) => {
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]');
diff --git a/static/src/schedule/schedule.ts b/static/src/schedule/schedule.ts
new file mode 100644
index 0000000..c53de76
--- /dev/null
+++ b/static/src/schedule/schedule.ts
@@ -0,0 +1,109 @@
+export interface Channel {
+ id: string;
+ name: string;
+ provider: string;
+}
+
+export class ScheduleChannelStorage {
+ private storageKey: string = "schedule:channels";
+
+ getAll(): Channel[] {
+ const objects = JSON.parse(window.localStorage.getItem(this.storageKey) || "{}");
+ return Object.values(objects);
+ }
+
+ add(object: Channel) {
+ const objects = JSON.parse(window.localStorage.getItem(this.storageKey) || "{}");
+ objects[object.id] = object;
+ window.localStorage.setItem(this.storageKey, JSON.stringify(objects));
+ }
+
+ remove(id: string) {
+ const objects = JSON.parse(window.localStorage.getItem(this.storageKey) || "{}");
+ delete objects[id];
+ window.localStorage.setItem(this.storageKey, JSON.stringify(objects));
+ }
+}
+
+export class ScheduleChannelManager {
+ loadChannels(selector: string) {
+ const channels = window.scheduleChannelStorage.getAll();
+ const container = document.querySelector(selector);
+ if (container) {
+ container.innerHTML = "";
+ for (const channel of channels) {
+ const element = new ScheduleChannelElement();
+ element.setAttribute("channel", JSON.stringify(channel));
+ element.setAttribute("removable", "");
+ container.appendChild(element);
+ }
+ }
+ }
+}
+
+class ScheduleChannelElement extends HTMLElement {
+ static observedAttributes = ["channel", "removable"];
+
+ channel: Channel | null = null;
+
+ constructor() {
+ super();
+ this.handleClick = this.handleClick.bind(this);
+ this.handleRemoveClick = this.handleRemoveClick.bind(this);
+ }
+
+ connectedCallback() {
+ this.channel = JSON.parse(this.getAttribute("channel") || "{}");
+ this.innerHTML = `
+
+
+ ${this.channel?.name}
+
+
+ ${this.channel?.provider}
+
+ ✕
+
+
+ `;
+ this.addEventListener("click", this.handleClick);
+ if (this.hasAttribute("removable")) {
+ this.querySelector("[data-remove]")?.addEventListener("click", this.handleRemoveClick);
+ } else {
+ this.querySelector("[data-remove]")?.remove();
+ }
+ }
+
+ disconnectedCallback() {
+ this.removeEventListener("click", this.handleClick);
+ this.querySelector("[data-remove]")?.removeEventListener("click", this.handleRemoveClick);
+ }
+
+ handleClick(event: MouseEvent) {
+ if (this.channel) {
+ window.scheduleChannelStorage.add(this.channel);
+ }
+ }
+
+ handleRemoveClick(event: MouseEvent) {
+ event.preventDefault();
+ event.stopPropagation();
+ if (this.channel) {
+ window.scheduleChannelStorage.remove(this.channel.id);
+ }
+ this.remove();
+ }
+}
+
+customElements.define("schedule-channel", ScheduleChannelElement);
+
+declare global {
+ interface Window {
+ scheduleChannelStorage: ScheduleChannelStorage;
+ scheduleChannelManager: ScheduleChannelManager;
+ }
+}
+
+window.scheduleChannelStorage = new ScheduleChannelStorage();
+window.scheduleChannelManager = new ScheduleChannelManager();
diff --git a/tests/data/yandextv/__init__.py b/tests/data/yandextv/__init__.py
index 39ecdc9..a8f99bf 100644
--- a/tests/data/yandextv/__init__.py
+++ b/tests/data/yandextv/__init__.py
@@ -6,5 +6,6 @@ YANDEXTV_MOCK_SOURCE = MockSource(
Path(__file__).parent,
{
"test": "test.html",
+ "suggest-tv2": "suggest-tv2.json",
},
)
diff --git a/tests/data/yandextv/suggest-tv2.json b/tests/data/yandextv/suggest-tv2.json
new file mode 100644
index 0000000..03549e6
--- /dev/null
+++ b/tests/data/yandextv/suggest-tv2.json
@@ -0,0 +1,423 @@
+[
+ "матч",
+ [
+ [
+ "bemjson",
+ "Матч!",
+ {
+ "url": "https:\/\/tv.yandex.ru\/channels\/1593",
+ "target": "_self",
+ "bemjson": [
+ {
+ "elem": "icon",
+ "elemMods": {
+ "size": "l"
+ },
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/square",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/square",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/small",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/small",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/40x30",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/40x30",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/48x72",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/48x68",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/48x72",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/48x68",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/60x45",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/60x45",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/64x36",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/alice_64_48",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/64x36",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/alice_64_48",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/x",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/x",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/80x60",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/80x45",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/80x60",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/80x45",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/114x80",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/114x80",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/120x90",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/middle",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/120x90",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/middle",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/130x80",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/130x80",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/y",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/y",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/214x121",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/368x280",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/184x140",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/428x280",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/z",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/170x100",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/340x200",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/260x160",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/160x90",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/160x120",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/160x160",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/214x121",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/368x280",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/184x140",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/428x280",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/z",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/170x100",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/340x200",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/260x160",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/160x90",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/160x120",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/160x160",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016e2603ad95657bcd08dc16bad081\/orig",
+ "attrs": {
+ "style": "margin-right: 5px;"
+ }
+ },
+ {
+ "elem": "text",
+ "content": "Матч!"
+ }
+ ],
+ "label": "Каналы"
+ }
+ ],
+ [
+ "bemjson",
+ "Матч Премьер",
+ {
+ "url": "https:\/\/tv.yandex.ru\/channels\/1861",
+ "target": "_self",
+ "bemjson": [
+ {
+ "elem": "icon",
+ "elemMods": {
+ "size": "l"
+ },
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/square",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/square",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/small",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/small",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/40x30",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/40x30",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/60x45",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/60x45",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/alice_64_48",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/alice_64_48",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/x",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/x",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/80x60",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/80x60",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/114x80",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/114x80",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/120x90",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/middle",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/120x90",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/middle",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/130x80",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/130x80",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/y",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/y",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/184x140",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/160x120",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/160x90",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/260x160",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/428x280",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/340x200",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/z",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/214x121",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/160x160",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/368x280",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/170x100",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/184x140",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/160x120",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/160x90",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/260x160",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/428x280",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/340x200",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/z",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/214x121",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/160x160",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/368x280",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/170x100",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/28884\/2a00000164ea55a8e4e47294c57caf3f249c\/orig",
+ "attrs": {
+ "style": "margin-right: 5px;"
+ }
+ },
+ {
+ "elem": "text",
+ "content": "Матч Премьер"
+ }
+ ],
+ "label": "Каналы"
+ }
+ ],
+ [
+ "bemjson",
+ "Матч! Арена",
+ {
+ "url": "https:\/\/tv.yandex.ru\/channels\/1667",
+ "target": "_self",
+ "bemjson": [
+ {
+ "elem": "icon",
+ "elemMods": {
+ "size": "l"
+ },
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/27485\/2a000001600802507cc14a8dfebd96835e47\/square",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/27485\/2a000001600802507cc14a8dfebd96835e47\/square",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/27485\/2a000001600802507cc14a8dfebd96835e47\/small",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/27485\/2a000001600802507cc14a8dfebd96835e47\/small",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/27485\/2a000001600802507cc14a8dfebd96835e47\/40x30",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/27485\/2a000001600802507cc14a8dfebd96835e47\/40x30",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/27485\/2a000001600802507cc14a8dfebd96835e47\/60x45",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/27485\/2a000001600802507cc14a8dfebd96835e47\/60x45",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/27485\/2a000001600802507cc14a8dfebd96835e47\/alice_64_48",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/27485\/2a000001600802507cc14a8dfebd96835e47\/alice_64_48",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/27485\/2a000001600802507cc14a8dfebd96835e47\/x",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/27485\/2a000001600802507cc14a8dfebd96835e47\/x",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a00000160080262b3c5f1b231e9c1a50c16\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a00000160080262b3c5f1b231e9c1a50c16\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/27485\/2a000001600802507cc14a8dfebd96835e47\/114x80",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/27485\/2a000001600802507cc14a8dfebd96835e47\/114x80",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/27485\/2a000001600802507cc14a8dfebd96835e47\/middle",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/30303\/2a0000016008026461f08cb3fdd86e3a2457\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/27485\/2a000001600802507cc14a8dfebd96835e47\/middle",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/30303\/2a0000016008026461f08cb3fdd86e3a2457\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/27485\/2a000001600802507cc14a8dfebd96835e47\/y",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/27485\/2a000001600802507cc14a8dfebd96835e47\/y",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/51763\/2a0000016008026771d2f3c7dac0e8d437f9\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802686dbbbed380ec99afc655\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/51763\/2a000001600802653c391d2e32075819e8f6\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016008026696804b8c4e42f226e439\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/27485\/2a000001600802507cc14a8dfebd96835e47\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/51763\/2a0000016008026771d2f3c7dac0e8d437f9\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802686dbbbed380ec99afc655\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/51763\/2a000001600802653c391d2e32075819e8f6\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a0000016008026696804b8c4e42f226e439\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/27485\/2a000001600802507cc14a8dfebd96835e47\/orig",
+ "attrs": {
+ "style": "margin-right: 5px;"
+ }
+ },
+ {
+ "elem": "text",
+ "content": "Матч! Арена"
+ }
+ ],
+ "label": "Каналы"
+ }
+ ],
+ [
+ "bemjson",
+ "Матч! Боец",
+ {
+ "url": "https:\/\/tv.yandex.ru\/channels\/454",
+ "target": "_self",
+ "bemjson": [
+ {
+ "elem": "icon",
+ "elemMods": {
+ "size": "l"
+ },
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802bf4bc9e92d4f31f4a9878b\/square",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802bf4bc9e92d4f31f4a9878b\/square",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802bf4bc9e92d4f31f4a9878b\/small",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802bf4bc9e92d4f31f4a9878b\/small",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802bf4bc9e92d4f31f4a9878b\/40x30",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802bf4bc9e92d4f31f4a9878b\/40x30",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802bf4bc9e92d4f31f4a9878b\/60x45",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802bf4bc9e92d4f31f4a9878b\/60x45",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802bf4bc9e92d4f31f4a9878b\/alice_64_48",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802bf4bc9e92d4f31f4a9878b\/alice_64_48",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802bf4bc9e92d4f31f4a9878b\/x",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802bf4bc9e92d4f31f4a9878b\/x",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/27485\/2a000001600802e5ce16abfff4ef6582314b\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/27485\/2a000001600802e5ce16abfff4ef6582314b\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802bf4bc9e92d4f31f4a9878b\/114x80",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802bf4bc9e92d4f31f4a9878b\/114x80",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/27485\/2a000001600802ed550b3e50934bd9590a8d\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802bf4bc9e92d4f31f4a9878b\/middle",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/27485\/2a000001600802ed550b3e50934bd9590a8d\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802bf4bc9e92d4f31f4a9878b\/middle",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802bf4bc9e92d4f31f4a9878b\/y",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802bf4bc9e92d4f31f4a9878b\/y",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802fb1f6c51e988763d812c9a\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a000001600803041768d758a55eb7e2badb\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/30303\/2a0000016008030a3439b27b50315e0282d5\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802f430b56de4f7f74fa9d062\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802bf4bc9e92d4f31f4a9878b\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802fb1f6c51e988763d812c9a\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/70787\/2a000001600803041768d758a55eb7e2badb\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/30303\/2a0000016008030a3439b27b50315e0282d5\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802f430b56de4f7f74fa9d062\/orig",
+ "png": "\/\/avatars.mds.yandex.net\/get-tv-channel-logos\/69315\/2a000001600802bf4bc9e92d4f31f4a9878b\/orig",
+ "attrs": {
+ "style": "margin-right: 5px;"
+ }
+ },
+ {
+ "elem": "text",
+ "content": "Матч! Боец"
+ }
+ ],
+ "label": "Каналы"
+ }
+ ],
+ [
+ "bemjson",
+ "Матч Поинт",
+ {
+ "url": "https:\/\/tv.yandex.ru\/program\/8975707?eventId=258920426",
+ "target": "_self",
+ "label": "Передачи",
+ "bemjson": [
+ {
+ "elem": "info",
+ "content": [
+ {
+ "elem": "img",
+ "elemMods": {
+ "size": "m"
+ },
+ "src": "\/\/avatars.mds.yandex.net\/get-tv-shows\/28313\/2a0000019e1b8bb6911cbc36699f5e382156\/120x90"
+ },
+ {
+ "elem": "text",
+ "elemMods": {
+ "type": "title-url"
+ },
+ "content": "Матч Поинт"
+ },
+ {
+ "elem": "desc",
+ "content": "КИНОМАН, сегодня, 18:00"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ [
+ "bemjson",
+ "Матч",
+ {
+ "url": "https:\/\/tv.yandex.ru\/program\/9094736?eventId=258988710",
+ "target": "_self",
+ "label": "Передачи",
+ "bemjson": [
+ {
+ "elem": "info",
+ "content": [
+ {
+ "elem": "img",
+ "elemMods": {
+ "size": "m"
+ },
+ "src": "\/\/avatars.mds.yandex.net\/get-tv-shows\/27487\/2a0000019ee0cfaf7272900dc66e5da38072\/120x90"
+ },
+ {
+ "elem": "text",
+ "elemMods": {
+ "type": "title-url"
+ },
+ "content": "Матч"
+ },
+ {
+ "elem": "desc",
+ "content": "Союзный, завтра, 19:00"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ [
+ "bemjson",
+ "Матч-реванш",
+ {
+ "url": "https:\/\/tv.yandex.ru\/program\/8045748?eventId=258901794",
+ "target": "_self",
+ "label": "Передачи",
+ "bemjson": [
+ {
+ "elem": "info",
+ "content": [
+ {
+ "elem": "img",
+ "elemMods": {
+ "size": "m"
+ },
+ "src": "\/\/avatars.mds.yandex.net\/get-tv-shows\/28886\/2a0000019590a3a76b641bcec6df9bb179cc\/120x90"
+ },
+ {
+ "elem": "text",
+ "elemMods": {
+ "type": "title-url"
+ },
+ "content": "Матч-реванш"
+ },
+ {
+ "elem": "desc",
+ "content": "Советские мультфильмы, сегодня, 20:04"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ [
+ "bemjson",
+ "Матч-реванш",
+ {
+ "url": "https:\/\/tv.yandex.ru\/program\/7398398?eventId=258967472",
+ "target": "_self",
+ "label": "Передачи",
+ "bemjson": [
+ {
+ "elem": "info",
+ "content": [
+ {
+ "elem": "img",
+ "elemMods": {
+ "size": "m"
+ },
+ "src": "\/\/avatars.mds.yandex.net\/get-tv-shows\/26422\/2a0000019409646c1723839178f3274f0a03\/120x90"
+ },
+ {
+ "elem": "text",
+ "elemMods": {
+ "type": "title-url"
+ },
+ "content": "Матч-реванш"
+ },
+ {
+ "elem": "desc",
+ "content": "Чижик, завтра, 07:55"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ [
+ "bemjson",
+ "Все результаты",
+ {
+ "url": "https:\/\/tv.yandex.ru\/search?text=%D0%BC%D0%B0%D1%82%D1%87",
+ "target": "_self",
+ "label": "Другое",
+ "bemjson": [
+ {
+ "elem": "info",
+ "elemMods": {
+ "type": "title_url"
+ },
+ "content": "Все результаты"
+ }
+ ]
+ }
+ ]
+ ]
+]
\ No newline at end of file
diff --git a/tests/test_yandextv_api.py b/tests/test_yandextv_api.py
index caf3d5b..1a7a73f 100644
--- a/tests/test_yandextv_api.py
+++ b/tests/test_yandextv_api.py
@@ -2,8 +2,7 @@ import datetime
import pytest
-from gallery.painting.yandextv.api import CHANNELS_MAP, YandexTvApi
-from gallery.sketch.schedule.model import ChannelId
+from gallery.painting.yandextv.api import YandexTvApi
from tests.data.yandextv import YANDEXTV_MOCK_SOURCE
@@ -11,13 +10,16 @@ from tests.data.yandextv import YANDEXTV_MOCK_SOURCE
def yandextv_api_fixture() -> YandexTvApi:
api = YandexTvApi()
api.SOURCE = YANDEXTV_MOCK_SOURCE
- CHANNELS_MAP[ChannelId("test")] = "test"
return api
+async def test_search(yandextv_api: YandexTvApi):
+ result = await yandextv_api.find_channels("матч")
+ print(result)
+ assert len(result) == 8
+
+
async def test_channel(yandextv_api: YandexTvApi):
- result = await yandextv_api.get_channel_schedule(
- ChannelId.TEST, datetime.date.today()
- )
+ result = await yandextv_api.get_channel_schedule("test", datetime.date.today())
assert result is not None
assert len(result.values) > 0