mirror of
https://github.com/doms9/iptv.git
synced 2026-03-07 11:18:25 +01:00
e
edit typing move epg fetching into M3U8 folder edit workflows
This commit is contained in:
parent
00000d9638
commit
00000d98e3
16 changed files with 376740 additions and 377279 deletions
12
.github/workflows/epg.yml
vendored
12
.github/workflows/epg.yml
vendored
|
|
@ -14,14 +14,6 @@ jobs:
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Cache venv
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: .venv
|
|
||||||
key: shared-venv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
|
|
||||||
restore-keys: |
|
|
||||||
shared-venv-${{ runner.os }}-
|
|
||||||
|
|
||||||
- name: Install uv
|
- name: Install uv
|
||||||
uses: astral-sh/setup-uv@v6
|
uses: astral-sh/setup-uv@v6
|
||||||
with:
|
with:
|
||||||
|
|
@ -36,13 +28,13 @@ jobs:
|
||||||
python-version-file: "pyproject.toml"
|
python-version-file: "pyproject.toml"
|
||||||
|
|
||||||
- name: Fetch EPG
|
- name: Fetch EPG
|
||||||
run: uv run EPG/fetch.py
|
run: uv run M3U8/epg-fetch.py
|
||||||
|
|
||||||
- name: Push changes
|
- name: Push changes
|
||||||
uses: stefanzweifel/git-auto-commit-action@v6
|
uses: stefanzweifel/git-auto-commit-action@v6
|
||||||
with:
|
with:
|
||||||
commit_message: "update EPG"
|
commit_message: "update EPG"
|
||||||
file_pattern: "EPG/TV.xml"
|
file_pattern: "M3U8/TV.xml"
|
||||||
commit_author: "GitHub Actions Bot <actions@github.com>"
|
commit_author: "GitHub Actions Bot <actions@github.com>"
|
||||||
commit_user_name: "GitHub Actions Bot"
|
commit_user_name: "GitHub Actions Bot"
|
||||||
commit_user_email: "actions@github.com"
|
commit_user_email: "actions@github.com"
|
||||||
|
|
|
||||||
17
.github/workflows/m3u8.yml
vendored
17
.github/workflows/m3u8.yml
vendored
|
|
@ -22,23 +22,6 @@ jobs:
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Cache venv
|
|
||||||
if: steps.check_time.outputs.run == 'true'
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: .venv
|
|
||||||
key: shared-venv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
|
|
||||||
restore-keys: |
|
|
||||||
shared-venv-${{ runner.os }}-
|
|
||||||
|
|
||||||
- name: Cache cert
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: M3U8/scrape/utils/cached-ca.pem
|
|
||||||
key: cert-cache-${{ runner.os }}-${{ hashFiles('M3U8/scrape/utils/cached-ca.pem') }}
|
|
||||||
restore-keys: |
|
|
||||||
cert-cache-${{ runner.os }}-
|
|
||||||
|
|
||||||
- name: Install uv
|
- name: Install uv
|
||||||
if: steps.check_time.outputs.run == 'true'
|
if: steps.check_time.outputs.run == 'true'
|
||||||
uses: astral-sh/setup-uv@v6
|
uses: astral-sh/setup-uv@v6
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -5,15 +5,18 @@ import re
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from xml.etree import ElementTree as ET
|
from xml.etree import ElementTree as ET
|
||||||
|
|
||||||
import httpx
|
from scrapers.utils import get_logger, network
|
||||||
|
|
||||||
epg_file = Path(__file__).parent / "TV.xml"
|
log = get_logger(__name__)
|
||||||
|
|
||||||
epg_urls = [
|
BASE_M3U8 = Path(__file__).parent / "base.m3u8"
|
||||||
|
|
||||||
|
EPG_FILE = Path(__file__).parent / "TV.xml"
|
||||||
|
|
||||||
|
EPG_URLS = [
|
||||||
"https://epgshare01.online/epgshare01/epg_ripper_CA2.xml.gz",
|
"https://epgshare01.online/epgshare01/epg_ripper_CA2.xml.gz",
|
||||||
"https://epgshare01.online/epgshare01/epg_ripper_DUMMY_CHANNELS.xml.gz",
|
"https://epgshare01.online/epgshare01/epg_ripper_DUMMY_CHANNELS.xml.gz",
|
||||||
"https://epgshare01.online/epgshare01/epg_ripper_FANDUEL1.xml.gz",
|
"https://epgshare01.online/epgshare01/epg_ripper_FANDUEL1.xml.gz",
|
||||||
"https://epgshare01.online/epgshare01/epg_ripper_MY1.xml.gz",
|
|
||||||
"https://epgshare01.online/epgshare01/epg_ripper_PLEX1.xml.gz",
|
"https://epgshare01.online/epgshare01/epg_ripper_PLEX1.xml.gz",
|
||||||
"https://epgshare01.online/epgshare01/epg_ripper_UK1.xml.gz",
|
"https://epgshare01.online/epgshare01/epg_ripper_UK1.xml.gz",
|
||||||
"https://epgshare01.online/epgshare01/epg_ripper_US2.xml.gz",
|
"https://epgshare01.online/epgshare01/epg_ripper_US2.xml.gz",
|
||||||
|
|
@ -21,44 +24,31 @@ epg_urls = [
|
||||||
"https://i.mjh.nz/Roku/all.xml.gz",
|
"https://i.mjh.nz/Roku/all.xml.gz",
|
||||||
]
|
]
|
||||||
|
|
||||||
client = httpx.AsyncClient(
|
LIVE_IMG = "https://i.gyazo.com/978f2eb4a199ca5b56b447aded0cb9e3.png"
|
||||||
timeout=httpx.Timeout(5.0),
|
|
||||||
follow_redirects=True,
|
|
||||||
http2=True,
|
|
||||||
headers={
|
|
||||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0"
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
live_img = "https://i.gyazo.com/978f2eb4a199ca5b56b447aded0cb9e3.png"
|
DUMMIES = {
|
||||||
|
"Basketball.Dummy.us": LIVE_IMG,
|
||||||
dummies = {
|
"Golf.Dummy.us": LIVE_IMG,
|
||||||
"Basketball.Dummy.us": live_img,
|
"Live.Event.us": LIVE_IMG,
|
||||||
"Golf.Dummy.us": live_img,
|
|
||||||
"Live.Event.us": live_img,
|
|
||||||
"MLB.Baseball.Dummy.us": None,
|
"MLB.Baseball.Dummy.us": None,
|
||||||
"NBA.Basketball.Dummy.us": None,
|
"NBA.Basketball.Dummy.us": None,
|
||||||
"NFL.Dummy.us": None,
|
"NFL.Dummy.us": None,
|
||||||
"NHL.Hockey.Dummy.us": None,
|
"NHL.Hockey.Dummy.us": None,
|
||||||
"PPV.EVENTS.Dummy.us": live_img,
|
"PPV.EVENTS.Dummy.us": LIVE_IMG,
|
||||||
"Racing.Dummy.us": live_img,
|
"Racing.Dummy.us": LIVE_IMG,
|
||||||
"Soccer.Dummy.us": live_img,
|
"Soccer.Dummy.us": LIVE_IMG,
|
||||||
"Tennis.Dummy.us": live_img,
|
"Tennis.Dummy.us": LIVE_IMG,
|
||||||
"WNBA.dummy.us": None,
|
"WNBA.dummy.us": None,
|
||||||
}
|
}
|
||||||
|
|
||||||
replace_ids = {
|
REPLACE_IDs = {
|
||||||
"NCAA Sports": {"old": "Sports.Dummy.us", "new": "NCAA.Sports.Dummy.us"},
|
"NCAA Sports": {"old": "Sports.Dummy.us", "new": "NCAA.Sports.Dummy.us"},
|
||||||
"UFC": {"old": "UFC.247.Dummy.us", "new": "UFC.Dummy.us"},
|
"UFC": {"old": "UFC.247.Dummy.us", "new": "UFC.Dummy.us"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def get_tvg_ids() -> dict[str, str]:
|
def get_tvg_ids() -> dict[str, str]:
|
||||||
base_m3u8 = (
|
base_m3u8 = BASE_M3U8.read_text(encoding="utf-8").splitlines()
|
||||||
(Path(__file__).parent.parent / "M3U8" / "base.m3u8")
|
|
||||||
.read_text(encoding="utf-8")
|
|
||||||
.splitlines()
|
|
||||||
)
|
|
||||||
|
|
||||||
tvg = {}
|
tvg = {}
|
||||||
|
|
||||||
|
|
@ -73,20 +63,17 @@ def get_tvg_ids() -> dict[str, str]:
|
||||||
|
|
||||||
|
|
||||||
async def fetch_xml(url: str) -> ET.Element | None:
|
async def fetch_xml(url: str) -> ET.Element | None:
|
||||||
try:
|
if not (html_data := await network.request(url, log=log)):
|
||||||
r = await client.get(url)
|
|
||||||
r.raise_for_status()
|
|
||||||
except Exception as e:
|
|
||||||
print(f'Failed to fetch "{url}": {e}')
|
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
decompressed_data = gzip.decompress(r.content)
|
decompressed_data = gzip.decompress(html_data.content)
|
||||||
|
|
||||||
return ET.fromstring(decompressed_data)
|
return ET.fromstring(decompressed_data)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f'Failed to decompress and parse XML from "{url}": {e}')
|
log.error(f'Failed to decompress and parse XML from "{url}": {e}')
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
def hijack_id(
|
def hijack_id(
|
||||||
|
|
@ -138,13 +125,15 @@ def hijack_id(
|
||||||
|
|
||||||
|
|
||||||
async def main() -> None:
|
async def main() -> None:
|
||||||
|
log.info(f"{'=' * 10} Fetching EPG {'=' * 10}")
|
||||||
|
|
||||||
tvg_ids = get_tvg_ids()
|
tvg_ids = get_tvg_ids()
|
||||||
|
|
||||||
tvg_ids |= dummies | {v["old"]: live_img for v in replace_ids.values()}
|
tvg_ids |= DUMMIES | {v["old"]: LIVE_IMG for v in REPLACE_IDs.values()}
|
||||||
|
|
||||||
root = ET.Element("tv")
|
root = ET.Element("tv")
|
||||||
|
|
||||||
tasks = [fetch_xml(url) for url in epg_urls]
|
tasks = [fetch_xml(url) for url in EPG_URLS]
|
||||||
|
|
||||||
results = await asyncio.gather(*tasks)
|
results = await asyncio.gather(*tasks)
|
||||||
|
|
||||||
|
|
@ -176,20 +165,24 @@ async def main() -> None:
|
||||||
|
|
||||||
root.append(program)
|
root.append(program)
|
||||||
|
|
||||||
for k, v in replace_ids.items():
|
for k, v in REPLACE_IDs.items():
|
||||||
hijack_id(**v, text=k, root=root)
|
hijack_id(**v, text=k, root=root)
|
||||||
|
|
||||||
tree = ET.ElementTree(root)
|
tree = ET.ElementTree(root)
|
||||||
|
|
||||||
tree.write(epg_file, encoding="utf-8", xml_declaration=True)
|
tree.write(EPG_FILE, encoding="utf-8", xml_declaration=True)
|
||||||
|
|
||||||
print(f"EPG saved to {epg_file.resolve()}")
|
log.info(f"EPG saved to {EPG_FILE.resolve()}")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
asyncio.run(main())
|
asyncio.run(main())
|
||||||
|
|
||||||
|
for hndlr in log.handlers:
|
||||||
|
hndlr.flush()
|
||||||
|
hndlr.stream.write("\n")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
asyncio.run(client.aclose())
|
asyncio.run(network.client.aclose())
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
@ -162,10 +162,10 @@ async def main() -> None:
|
||||||
|
|
||||||
log.info(f"Events saved to {EVENTS_FILE.resolve()}")
|
log.info(f"Events saved to {EVENTS_FILE.resolve()}")
|
||||||
|
|
||||||
for hndlr in log.handlers:
|
|
||||||
hndlr.flush()
|
|
||||||
hndlr.stream.write("\n")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
asyncio.run(main())
|
asyncio.run(main())
|
||||||
|
|
||||||
|
for hndlr in log.handlers:
|
||||||
|
hndlr.flush()
|
||||||
|
hndlr.stream.write("\n")
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from playwright.async_api import BrowserContext
|
from playwright.async_api import Browser
|
||||||
|
|
||||||
from .utils import Cache, Time, get_logger, leagues, network
|
from .utils import Cache, Time, get_logger, leagues, network
|
||||||
|
|
||||||
|
|
@ -85,7 +85,7 @@ async def get_events(cached_keys: list[str]) -> list[dict[str, str]]:
|
||||||
return events
|
return events
|
||||||
|
|
||||||
|
|
||||||
async def scrape(browser: BrowserContext) -> None:
|
async def scrape(browser: Browser) -> None:
|
||||||
cached_urls = CACHE_FILE.load()
|
cached_urls = CACHE_FILE.load()
|
||||||
|
|
||||||
cached_count = len(cached_urls)
|
cached_count = len(cached_urls)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from playwright.async_api import BrowserContext
|
from playwright.async_api import Browser
|
||||||
|
|
||||||
from .utils import Cache, Time, get_logger, leagues, network
|
from .utils import Cache, Time, get_logger, leagues, network
|
||||||
|
|
||||||
|
|
@ -75,7 +75,7 @@ async def get_events(cached_keys: list[str]) -> list[dict[str, str]]:
|
||||||
return events
|
return events
|
||||||
|
|
||||||
|
|
||||||
async def scrape(browser: BrowserContext) -> None:
|
async def scrape(browser: Browser) -> None:
|
||||||
cached_urls = CACHE_FILE.load()
|
cached_urls = CACHE_FILE.load()
|
||||||
|
|
||||||
cached_count = len(cached_urls)
|
cached_count = len(cached_urls)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import json
|
import json
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from playwright.async_api import BrowserContext, Page
|
from playwright.async_api import Browser, Page
|
||||||
|
|
||||||
from .utils import Cache, Time, get_logger, leagues, network
|
from .utils import Cache, Time, get_logger, leagues, network
|
||||||
|
|
||||||
|
|
@ -73,7 +73,7 @@ async def get_events(page: Page) -> dict[str, dict[str, str | float]]:
|
||||||
return events
|
return events
|
||||||
|
|
||||||
|
|
||||||
async def scrape(browser: BrowserContext) -> None:
|
async def scrape(browser: Browser) -> None:
|
||||||
if cached := CACHE_FILE.load():
|
if cached := CACHE_FILE.load():
|
||||||
urls.update(cached)
|
urls.update(cached)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from playwright.async_api import BrowserContext
|
from playwright.async_api import Browser
|
||||||
|
|
||||||
from .utils import Cache, Time, get_logger, leagues, network
|
from .utils import Cache, Time, get_logger, leagues, network
|
||||||
|
|
||||||
|
|
@ -78,7 +78,7 @@ async def get_events(url: str, cached_keys: list[str]) -> list[dict[str, str]]:
|
||||||
return events
|
return events
|
||||||
|
|
||||||
|
|
||||||
async def scrape(browser: BrowserContext) -> None:
|
async def scrape(browser: Browser) -> None:
|
||||||
cached_urls = CACHE_FILE.load()
|
cached_urls = CACHE_FILE.load()
|
||||||
|
|
||||||
cached_count = len(cached_urls)
|
cached_count = len(cached_urls)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import asyncio
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from urllib.parse import urljoin
|
from urllib.parse import urljoin
|
||||||
|
|
||||||
from playwright.async_api import BrowserContext
|
from playwright.async_api import Browser
|
||||||
from selectolax.parser import HTMLParser
|
from selectolax.parser import HTMLParser
|
||||||
|
|
||||||
from .utils import Cache, Time, get_logger, leagues, network
|
from .utils import Cache, Time, get_logger, leagues, network
|
||||||
|
|
@ -88,7 +88,7 @@ async def get_events(cached_keys: list[str]) -> list[dict[str, str]]:
|
||||||
return events
|
return events
|
||||||
|
|
||||||
|
|
||||||
async def scrape(browser: BrowserContext) -> None:
|
async def scrape(browser: Browser) -> None:
|
||||||
cached_urls = CACHE_FILE.load()
|
cached_urls = CACHE_FILE.load()
|
||||||
|
|
||||||
cached_count = len(cached_urls)
|
cached_count = len(cached_urls)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from playwright.async_api import BrowserContext
|
from playwright.async_api import Browser
|
||||||
|
|
||||||
from .utils import Cache, Time, get_logger, leagues, network
|
from .utils import Cache, Time, get_logger, leagues, network
|
||||||
|
|
||||||
|
|
@ -90,7 +90,7 @@ async def get_events(cached_keys: list[str]) -> list[dict[str, str]]:
|
||||||
return events
|
return events
|
||||||
|
|
||||||
|
|
||||||
async def scrape(browser: BrowserContext) -> None:
|
async def scrape(browser: Browser) -> None:
|
||||||
cached_urls = CACHE_FILE.load()
|
cached_urls = CACHE_FILE.load()
|
||||||
|
|
||||||
cached_count = len(cached_urls)
|
cached_count = len(cached_urls)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import asyncio
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from urllib.parse import urljoin
|
from urllib.parse import urljoin
|
||||||
|
|
||||||
from playwright.async_api import BrowserContext
|
from playwright.async_api import Browser
|
||||||
from selectolax.parser import HTMLParser
|
from selectolax.parser import HTMLParser
|
||||||
|
|
||||||
from .utils import Cache, Time, get_logger, leagues, network
|
from .utils import Cache, Time, get_logger, leagues, network
|
||||||
|
|
@ -132,7 +132,7 @@ async def get_events(cached_keys: list[str]) -> list[dict[str, str]]:
|
||||||
return live
|
return live
|
||||||
|
|
||||||
|
|
||||||
async def scrape(browser: BrowserContext) -> None:
|
async def scrape(browser: Browser) -> None:
|
||||||
cached_urls = CACHE_FILE.load()
|
cached_urls = CACHE_FILE.load()
|
||||||
|
|
||||||
valid_urls = {k: v for k, v in cached_urls.items() if v["url"]}
|
valid_urls = {k: v for k, v in cached_urls.items() if v["url"]}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ from itertools import chain
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from urllib.parse import urljoin
|
from urllib.parse import urljoin
|
||||||
|
|
||||||
from playwright.async_api import BrowserContext
|
from playwright.async_api import Browser
|
||||||
|
|
||||||
from .utils import Cache, Time, get_logger, leagues, network
|
from .utils import Cache, Time, get_logger, leagues, network
|
||||||
|
|
||||||
|
|
@ -120,7 +120,7 @@ async def get_events(cached_keys: list[str]) -> list[dict[str, str]]:
|
||||||
return events
|
return events
|
||||||
|
|
||||||
|
|
||||||
async def scrape(browser: BrowserContext) -> None:
|
async def scrape(browser: Browser) -> None:
|
||||||
cached_urls = CACHE_FILE.load()
|
cached_urls = CACHE_FILE.load()
|
||||||
|
|
||||||
cached_count = len(cached_urls)
|
cached_count = len(cached_urls)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ from functools import partial
|
||||||
from urllib.parse import urljoin
|
from urllib.parse import urljoin
|
||||||
|
|
||||||
import feedparser
|
import feedparser
|
||||||
from playwright.async_api import BrowserContext, Error, Page, TimeoutError
|
from playwright.async_api import Browser, Error, Page, TimeoutError
|
||||||
|
|
||||||
from .utils import Cache, Time, get_logger, leagues, network
|
from .utils import Cache, Time, get_logger, leagues, network
|
||||||
|
|
||||||
|
|
@ -161,7 +161,7 @@ async def get_events(cached_keys: list[str]) -> list[dict[str, str]]:
|
||||||
return events
|
return events
|
||||||
|
|
||||||
|
|
||||||
async def scrape(browser: BrowserContext) -> None:
|
async def scrape(browser: Browser) -> None:
|
||||||
cached_urls = CACHE_FILE.load()
|
cached_urls = CACHE_FILE.load()
|
||||||
|
|
||||||
valid_urls = {k: v for k, v in cached_urls.items() if v["url"]}
|
valid_urls = {k: v for k, v in cached_urls.items() if v["url"]}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ from itertools import chain
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from urllib.parse import urljoin
|
from urllib.parse import urljoin
|
||||||
|
|
||||||
from playwright.async_api import BrowserContext, Page, TimeoutError
|
from playwright.async_api import Browser, Page, TimeoutError
|
||||||
|
|
||||||
from .utils import Cache, Time, get_logger, leagues, network
|
from .utils import Cache, Time, get_logger, leagues, network
|
||||||
|
|
||||||
|
|
@ -232,7 +232,7 @@ async def get_events(base_url: str, cached_keys: list[str]) -> list[dict[str, st
|
||||||
return events
|
return events
|
||||||
|
|
||||||
|
|
||||||
async def scrape(browser: BrowserContext) -> None:
|
async def scrape(browser: Browser) -> None:
|
||||||
cached_urls = CACHE_FILE.load()
|
cached_urls = CACHE_FILE.load()
|
||||||
|
|
||||||
valid_urls = {k: v for k, v in cached_urls.items() if v["url"]}
|
valid_urls = {k: v for k, v in cached_urls.items() if v["url"]}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from playwright.async_api import BrowserContext
|
from playwright.async_api import Browser
|
||||||
from selectolax.parser import HTMLParser
|
from selectolax.parser import HTMLParser
|
||||||
|
|
||||||
from .utils import Cache, Time, get_logger, leagues, network
|
from .utils import Cache, Time, get_logger, leagues, network
|
||||||
|
|
@ -110,7 +110,7 @@ async def get_events(cached_keys: list[str]) -> list[dict[str, str]]:
|
||||||
return live
|
return live
|
||||||
|
|
||||||
|
|
||||||
async def scrape(browser: BrowserContext) -> None:
|
async def scrape(browser: Browser) -> None:
|
||||||
cached_urls = CACHE_FILE.load()
|
cached_urls = CACHE_FILE.load()
|
||||||
|
|
||||||
cached_count = len(cached_urls)
|
cached_count = len(cached_urls)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue