89 lines
4.1 KiB
Python
89 lines
4.1 KiB
Python
import datetime
|
|
import json
|
|
import logging
|
|
|
|
from bs4 import BeautifulSoup
|
|
|
|
from gallery.sketch.schedule.api import ScheduleApi
|
|
from gallery.sketch.schedule.model import Channel, Schedule, ScheduleValue
|
|
from gallery.sketch.source import ApiSource
|
|
|
|
logger = logging.getLogger("matchtv")
|
|
|
|
|
|
class MatchTvApi(ScheduleApi):
|
|
PROVIDER = "matchtv"
|
|
SOURCE = ApiSource("https://matchtv.ru")
|
|
|
|
async def find_channels(self, query: str) -> list[Channel]:
|
|
endpoint = "api/v1/channels"
|
|
data = json.loads(await self.SOURCE.request(endpoint))
|
|
result = []
|
|
query = query.lower()
|
|
for item in data["result"]:
|
|
if query in item["name"].lower() or query in item["alias"]:
|
|
channel_id = item["alias"]
|
|
name = item["name"].split("|")[0].strip()
|
|
result.append(Channel(id=channel_id, name=name, provider=self.provider))
|
|
return result
|
|
|
|
async def get_schedule(self, channel_id: str, date: datetime.date) -> Schedule:
|
|
endpoint = f"api/v1/channels/{channel_id}/tv-schedule?date={date:%Y%m%d}"
|
|
data = json.loads(await self.SOURCE.request(endpoint))
|
|
channel_data = data["result"]["channels"][0]
|
|
channel = Channel(id=channel_data["alias"], name=channel_data["name"], provider=self.provider)
|
|
values = []
|
|
current_day = datetime.datetime.combine(date.today(), datetime.datetime.min.time())
|
|
end = current_day + datetime.timedelta(days=1, hours=6)
|
|
prev_value: ScheduleValue | None = None
|
|
for item in channel_data["schedule"]:
|
|
title = item["title"]
|
|
time_str = item["time"]
|
|
hours, minutes = map(int, time_str.split(":"))
|
|
item_date = current_day.replace(hour=hours, minute=minutes)
|
|
if prev_value is not None and item_date.hour < prev_value.start.hour:
|
|
current_day += datetime.timedelta(days=1)
|
|
item_date += datetime.timedelta(days=1)
|
|
live = "Прямая трансляция" in title
|
|
value = ScheduleValue(start=item_date, end=end, label=title, live=live)
|
|
values.append(value)
|
|
if prev_value is not None:
|
|
prev_value.end = item_date
|
|
prev_value = value
|
|
return Schedule(
|
|
channel=channel,
|
|
date=date,
|
|
values=values,
|
|
)
|
|
|
|
async def get_schedule_legacy(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")
|
|
values = []
|
|
channel_name = soup.select_one(".p-tv-guide-header__title").text.replace("Телепрограмма ", "").strip()
|
|
current_day = datetime.datetime.combine(date.today(), datetime.datetime.min.time())
|
|
end = current_day + datetime.timedelta(days=1, hours=6)
|
|
prev_value: ScheduleValue | None = None
|
|
for item in soup.select(
|
|
".p-tv-guide-schedule-channel-carcass__transmissions .p-tv-guide-schedule-channel-transmission"
|
|
):
|
|
title = item.select_one(".p-tv-guide-schedule-channel-transmission__title").text.strip()
|
|
time_str = item.select_one(".p-tv-guide-schedule-channel-transmission__time-block").text.strip()
|
|
hours, minutes = map(int, time_str.split(":"))
|
|
item_date = current_day.replace(hour=hours, minute=minutes)
|
|
if prev_value is not None and item_date.hour < prev_value.start.hour:
|
|
current_day += datetime.timedelta(days=1)
|
|
item_date += datetime.timedelta(days=1)
|
|
live = "Прямая трансляция" in title
|
|
value = ScheduleValue(start=item_date, end=end, label=title, live=live)
|
|
values.append(value)
|
|
if prev_value is not None:
|
|
prev_value.end = item_date
|
|
prev_value = value
|
|
return Schedule(
|
|
channel=Channel(id=channel_id, name=channel_name, provider=self.provider),
|
|
date=date,
|
|
values=values,
|
|
)
|