From 00000d9ad81c6d42b7bdd2cff4325e8f6db425a3 Mon Sep 17 00:00:00 2001 From: doms9 <96013514+doms9@users.noreply.github.com> Date: Wed, 13 May 2026 21:41:14 -0400 Subject: [PATCH] e - add dami.py --- M3U8/fetch.py | 3 ++ M3U8/scrapers/dami.py | 80 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 M3U8/scrapers/dami.py diff --git a/M3U8/fetch.py b/M3U8/fetch.py index d332d533..6d72ffe5 100644 --- a/M3U8/fetch.py +++ b/M3U8/fetch.py @@ -6,6 +6,7 @@ from pathlib import Path from playwright.async_api import async_playwright from scrapers import ( cdnlivetv, + dami, embedhd, fawa, fsports, @@ -65,6 +66,7 @@ async def main() -> None: ] httpx_tasks = [ + asyncio.create_task(dami.scrape()), asyncio.create_task(fawa.scrape()), asyncio.create_task(istreameast.scrape()), asyncio.create_task(mainportal.scrape()), @@ -93,6 +95,7 @@ async def main() -> None: additions = ( cdnlivetv.urls + | dami.urls | embedhd.urls | fawa.urls | fsports.urls diff --git a/M3U8/scrapers/dami.py b/M3U8/scrapers/dami.py new file mode 100644 index 00000000..78b01586 --- /dev/null +++ b/M3U8/scrapers/dami.py @@ -0,0 +1,80 @@ +from .utils import Cache, Time, get_logger, leagues, network + +log = get_logger(__name__) + +urls: dict[str, dict[str, str | float]] = {} + +TAG = "DAMI" + +CACHE_FILE = Cache(TAG, exp=28_800) + +API_URL = "https://api.ppv.to/api/streams" +# "https://api.ppv.cx/api/streams" +# "https://api.ppv.sh/api/streams" + + +async def get_events() -> dict[str, dict[str, str | float]]: + now = Time.clean(Time.now()) + + events = {} + + if not (r := await network.request(API_URL, log=log)): + return events + + api_data: dict[str, dict] = r.json() + + for stream_group in api_data.get("streams", []): + sport = stream_group["category"] + + if sport == "24/7 Streams": + continue + + for event in stream_group.get("streams", []): + name = event.get("name") + + start_ts = event.get("starts_at") + + logo = event.get("poster") + + uri_name = event.get("uri_name") + + if not (name and start_ts and uri_name): + continue + + event_dt = Time.from_ts(start_ts) + + if event_dt.date() != now.date(): + continue + + key = f"[{sport}] {name} ({TAG})" + + tvg_id, pic = leagues.get_tvg_info(sport, name) + + events[key] = { + "url": f"https://dami-tv.pro/live-hls/channel/{uri_name}/playlist.m3u8", + "logo": logo or pic, + "base": f"https://dami-tv.pro/player/auto/?match={uri_name}", + "timestamp": now.timestamp(), + "id": tvg_id or "Live.Event.us", + } + + return events + + +async def scrape() -> None: + if cached_urls := CACHE_FILE.load(): + urls.update(cached_urls) + + log.info(f"Loaded {len(urls)} event(s) from cache") + + return + + log.info(f'Scraping from "{API_URL}"') + + events = await get_events() + + urls.update(events) + + log.info(f"Collected and cached {len(urls)} event(s)") + + CACHE_FILE.write(urls)