diff --git a/M3U8/fetch.py b/M3U8/fetch.py index 9324b17..38264c0 100644 --- a/M3U8/fetch.py +++ b/M3U8/fetch.py @@ -11,8 +11,8 @@ from scrapers import ( roxie, streambtw, streameast, + streamfree, strmd, - strmfree, tvpass, watchfooty, ) @@ -50,8 +50,8 @@ async def main() -> None: asyncio.create_task(roxie.scrape(network.client)), asyncio.create_task(streambtw.scrape(network.client)), asyncio.create_task(streameast.scrape(network.client)), + asyncio.create_task(streamfree.scrape(network.client)), asyncio.create_task(strmd.scrape(network.client)), - asyncio.create_task(strmfree.scrape(network.client)), asyncio.create_task(tvpass.scrape(network.client)), asyncio.create_task(watchfooty.scrape(network.client)), ] @@ -67,7 +67,7 @@ async def main() -> None: | streambtw.urls | streameast.urls | strmd.urls - | strmfree.urls + | streamfree.urls | tvpass.urls | watchfooty.urls ) diff --git a/M3U8/scrapers/fawa.py b/M3U8/scrapers/fawa.py index 7420247..31e1196 100644 --- a/M3U8/scrapers/fawa.py +++ b/M3U8/scrapers/fawa.py @@ -1,6 +1,5 @@ import re from functools import partial -from pathlib import Path from urllib.parse import quote, urljoin import httpx @@ -10,12 +9,12 @@ from .utils import Cache, Time, get_logger, leagues, network log = get_logger(__name__) -urls: dict[str, dict[str, str]] = {} +urls: dict[str, dict[str, str | float]] = {} + +CACHE_FILE = Cache("fawa.json", exp=10_800) BASE_URL = "http://www.fawanews.sc/" -CACHE_FILE = Cache(Path(__file__).parent / "caches" / "fawa.json", exp=10_800) - async def process_event( client: httpx.AsyncClient, diff --git a/M3U8/scrapers/lotus.py b/M3U8/scrapers/lotus.py index f513454..8df3fa7 100644 --- a/M3U8/scrapers/lotus.py +++ b/M3U8/scrapers/lotus.py @@ -1,5 +1,4 @@ from functools import partial -from pathlib import Path import httpx from playwright.async_api import async_playwright @@ -10,9 +9,9 @@ log = get_logger(__name__) urls: dict[str, dict[str, str | float]] = {} -CACHE_FILE = Cache(Path(__file__).parent / "caches" / "lotus.json", exp=3_600) +CACHE_FILE = Cache("lotus.json", exp=3_600) -API_CACHE = Cache(Path(__file__).parent / "caches" / "lotus_api.json", exp=28_800) +API_CACHE = Cache("lotus-api.json", exp=28_800) BASE_URL = "https://lotusgamehd.xyz/api-event.php" @@ -33,6 +32,7 @@ async def refresh_api_cache( r.raise_for_status() except Exception as e: log.error(f'Failed to fetch "{url}": {e}') + return {} data = r.json() @@ -58,7 +58,7 @@ async def get_events( API_CACHE.write(api_data) - events: list[dict[str, str]] = [] + events = [] for info in api_data["days"]: day = Time.from_str(info["day_et"]) diff --git a/M3U8/scrapers/old/fstv.py b/M3U8/scrapers/old/fstv.py index 48013f1..2367391 100644 --- a/M3U8/scrapers/old/fstv.py +++ b/M3U8/scrapers/old/fstv.py @@ -1,5 +1,4 @@ from functools import partial -from pathlib import Path from urllib.parse import unquote, urljoin import httpx @@ -9,7 +8,9 @@ from .utils import Cache, Time, get_logger, leagues, network log = get_logger(__name__) -urls: dict[str, dict[str, str]] = {} +urls: dict[str, dict[str, str | float]] = {} + +CACHE_FILE = Cache("fstv.json", exp=10_800) MIRRORS = [ "https://fstv.online", @@ -18,8 +19,6 @@ MIRRORS = [ "https://fstv.us", ] -CACHE_FILE = Cache(Path(__file__).parent / "caches" / "fstv.json", exp=10_800) - async def process_event( client: httpx.AsyncClient, @@ -179,3 +178,6 @@ async def scrape(client: httpx.AsyncClient) -> None: log.info("No new events found") CACHE_FILE.write(cached_urls) + + +# cloudflare bot check added diff --git a/M3U8/scrapers/pixel.py b/M3U8/scrapers/pixel.py index 297d25d..717b4ee 100644 --- a/M3U8/scrapers/pixel.py +++ b/M3U8/scrapers/pixel.py @@ -1,5 +1,4 @@ import re -from pathlib import Path import httpx @@ -9,9 +8,9 @@ log = get_logger(__name__) urls: dict[str, dict[str, str | float]] = {} -API_FILE = Cache(Path(__file__).parent / "caches" / "pixel_api.json", exp=28_800) +CACHE_FILE = Cache("pixel.json", exp=10_800) -CACHE_FILE = Cache(Path(__file__).parent / "caches" / "pixel.json", exp=10_800) +API_FILE = Cache("pixel-api.json", exp=28_800) BASE_URL = "https://pixelsport.tv/backend/livetv/events" @@ -28,6 +27,7 @@ async def refresh_api_cache( r.raise_for_status() except Exception as e: log.error(f'Failed to fetch "{url}": {e}') + return {} data = r.json() @@ -63,7 +63,7 @@ async def get_events( end_dt = now.delta(minutes=30) for event in api_data["events"]: - event_dt = Time.from_str(f'{event["date"]}', timezone="UTC") + event_dt = Time.from_str(event["date"], timezone="UTC") if now.date() != event_dt.date(): continue diff --git a/M3U8/scrapers/ppv.py b/M3U8/scrapers/ppv.py index 3e5ad6b..12cfe07 100644 --- a/M3U8/scrapers/ppv.py +++ b/M3U8/scrapers/ppv.py @@ -1,5 +1,4 @@ from functools import partial -from pathlib import Path from urllib.parse import urljoin import httpx @@ -11,9 +10,9 @@ log = get_logger(__name__) urls: dict[str, dict[str, str | float]] = {} -API_FILE = Cache(Path(__file__).parent / "caches" / "ppv_api.json", exp=28_800) +CACHE_FILE = Cache("ppv.json", exp=10_800) -CACHE_FILE = Cache(Path(__file__).parent / "caches" / "ppv.json", exp=10_800) +API_FILE = Cache("ppv-api.json", exp=28_800) BASE_URL = "https://ppv.to" @@ -29,6 +28,7 @@ async def refresh_api_cache( r.raise_for_status() except Exception as e: log.error(f'Failed to fetch "{url}": {e}') + return {} return r.json() @@ -49,7 +49,7 @@ async def get_events( API_FILE.write(api_data) - events: list[dict[str, str]] = [] + events = [] now = Time.clean(Time.now()) start_dt = now.delta(minutes=-30) diff --git a/M3U8/scrapers/roxie.py b/M3U8/scrapers/roxie.py index 1e2275b..623e24e 100644 --- a/M3U8/scrapers/roxie.py +++ b/M3U8/scrapers/roxie.py @@ -1,7 +1,6 @@ import asyncio import re from functools import partial -from pathlib import Path from urllib.parse import urljoin import httpx @@ -11,14 +10,14 @@ from .utils import Cache, Time, get_logger, leagues, network log = get_logger(__name__) -urls: dict[str, dict[str, str]] = {} +urls: dict[str, dict[str, str | float]] = {} + +CACHE_FILE = Cache("roxie.json", exp=10_800) + +HTML_CACHE = Cache("roxie-html.json", exp=28_800) MIRRORS = ["https://roxiestreams.live", "https://roxiestreams.cc"] -CACHE_FILE = Cache(Path(__file__).parent / "caches" / "roxie.json", exp=10_800) - -HTML_CACHE = Cache(Path(__file__).parent / "caches" / "roxie_html.json", exp=28_800) - async def process_event( client: httpx.AsyncClient, @@ -80,7 +79,7 @@ async def refresh_html_cache( data_start = span.attributes["data-start"].rsplit(":", 1)[0] - event_dt = Time.from_str(f"{data_start}", timezone="PST") + event_dt = Time.from_str(data_start, timezone="PST") key = f"[{sport}] {event} (ROXIE)" diff --git a/M3U8/scrapers/streambtw.py b/M3U8/scrapers/streambtw.py index 865b956..d28f51c 100644 --- a/M3U8/scrapers/streambtw.py +++ b/M3U8/scrapers/streambtw.py @@ -1,6 +1,5 @@ import re from functools import partial -from pathlib import Path from urllib.parse import urljoin import httpx @@ -10,12 +9,12 @@ from .utils import Cache, Time, get_logger, leagues, network log = get_logger(__name__) -urls: dict[str, dict[str, str]] = {} +urls: dict[str, dict[str, str | float]] = {} + +CACHE_FILE = Cache("streambtw.json", exp=3_600) BASE_URL = "https://streambtw.com" -CACHE_FILE = Cache(Path(__file__).parent / "caches" / "streambtw.json", exp=3_600) - async def process_event( client: httpx.AsyncClient, diff --git a/M3U8/scrapers/streameast.py b/M3U8/scrapers/streameast.py index d60cc56..8853c56 100644 --- a/M3U8/scrapers/streameast.py +++ b/M3U8/scrapers/streameast.py @@ -1,5 +1,4 @@ from functools import partial -from pathlib import Path from urllib.parse import urljoin import httpx @@ -12,9 +11,9 @@ log = get_logger(__name__) urls: dict[str, dict[str, str | float]] = {} -CACHE_FILE = Cache(Path(__file__).parent / "caches" / "streameast.json", exp=10_800) +CACHE_FILE = Cache("streameast.json", exp=10_800) -prefix = { +prefixes = { "ch": None, "sg": None, "tw": None, @@ -33,8 +32,8 @@ prefix = { } MIRRORS = [ - *[f"https://streameast.{ext}" for ext in prefix if not prefix[ext]], - *[f"https://thestreameast.{ext}" for ext in prefix if prefix[ext] == "the"], + *[f"https://streameast.{ext}" for ext in prefixes if not prefixes[ext]], + *[f"https://thestreameast.{ext}" for ext in prefixes if prefixes[ext] == "the"], ] @@ -52,6 +51,7 @@ async def get_events( return [] soup = HTMLParser(r.text) + events = [] now = Time.clean(Time.now()) diff --git a/M3U8/scrapers/strmfree.py b/M3U8/scrapers/streamfree.py similarity index 94% rename from M3U8/scrapers/strmfree.py rename to M3U8/scrapers/streamfree.py index 3ab2604..1fbba70 100644 --- a/M3U8/scrapers/strmfree.py +++ b/M3U8/scrapers/streamfree.py @@ -1,5 +1,4 @@ from functools import partial -from pathlib import Path from urllib.parse import urljoin import httpx @@ -11,9 +10,9 @@ log = get_logger(__name__) urls: dict[str, dict[str, str | float]] = {} -API_FILE = Cache(Path(__file__).parent / "caches" / "strmfree_api.json", exp=28_800) +CACHE_FILE = Cache("streamfree.json", exp=10_800) -CACHE_FILE = Cache(Path(__file__).parent / "caches" / "strmfree.json", exp=10_800) +API_FILE = Cache("streamfree-api.json", exp=28_800) BASE_URL = "https://streamfree.to" @@ -29,6 +28,7 @@ async def refresh_api_cache( r.raise_for_status() except Exception as e: log.error(f'Failed to fetch "{url}": {e}') + return {} data = r.json() @@ -52,7 +52,7 @@ async def get_events( API_FILE.write(api_data) - events: list[dict[str, str]] = [] + events = [] now = Time.clean(Time.now()) start_dt = now.delta(hours=-1) diff --git a/M3U8/scrapers/strmd.py b/M3U8/scrapers/strmd.py index 2e67b97..129931d 100644 --- a/M3U8/scrapers/strmd.py +++ b/M3U8/scrapers/strmd.py @@ -1,7 +1,6 @@ import asyncio import re from functools import partial -from pathlib import Path from typing import Any from urllib.parse import urljoin @@ -14,9 +13,9 @@ log = get_logger(__name__) urls: dict[str, dict[str, str | float]] = {} -API_FILE = Cache(Path(__file__).parent / "caches" / "strmd_api.json", exp=28_800) +CACHE_FILE = Cache("strmd.json", exp=10_800) -CACHE_FILE = Cache(Path(__file__).parent / "caches" / "strmd.json", exp=10_800) +API_FILE = Cache("strmd-api.json", exp=28_800) MIRRORS = ["https://streamed.pk", "https://streami.su", "https://streamed.st"] @@ -41,6 +40,7 @@ async def refresh_api_cache( r.raise_for_status() except Exception as e: log.error(f'Failed to fetch "{url}": {e}') + return {} data = r.json() @@ -130,7 +130,7 @@ async def get_events( API_FILE.write(api_data) - events: list[dict[str, str]] = [] + events = [] now = Time.clean(Time.now()) start_dt = now.delta(minutes=-30) diff --git a/M3U8/scrapers/tvpass.py b/M3U8/scrapers/tvpass.py index 5bbebb2..27a0001 100644 --- a/M3U8/scrapers/tvpass.py +++ b/M3U8/scrapers/tvpass.py @@ -1,5 +1,4 @@ import re -from pathlib import Path import httpx @@ -7,12 +6,12 @@ from .utils import Cache, Time, get_logger, leagues log = get_logger(__name__) -urls: dict[str, dict[str, str]] = {} +urls: dict[str, dict[str, str | float]] = {} + +CACHE_FILE = Cache("tvpass.json", exp=86_400) BASE_URL = "https://tvpass.org/playlist/m3u" -CACHE_FILE = Cache(Path(__file__).parent / "caches" / "tvpass.json", exp=86_400) - async def fetch_m3u8(client: httpx.AsyncClient) -> list[str]: try: @@ -20,6 +19,7 @@ async def fetch_m3u8(client: httpx.AsyncClient) -> list[str]: r.raise_for_status() except Exception as e: log.error(f'Failed to fetch "{BASE_URL}": {e}') + return [] return r.text.splitlines() diff --git a/M3U8/scrapers/utils/caching.py b/M3U8/scrapers/utils/caching.py index 1026cb2..0da3521 100644 --- a/M3U8/scrapers/utils/caching.py +++ b/M3U8/scrapers/utils/caching.py @@ -5,8 +5,8 @@ from .config import Time class Cache: - def __init__(self, file: Path, exp: int | float) -> None: - self.file = file + def __init__(self, file: str, exp: int | float) -> None: + self.file = Path(__file__).parent.parent / "caches" / file self.exp = exp self.now_ts = Time.now().timestamp() @@ -17,6 +17,18 @@ class Cache: return self.now_ts - dt_ts < self.exp + def write(self, data: dict) -> None: + self.file.parent.mkdir(parents=True, exist_ok=True) + + self.file.write_text( + json.dumps( + data, + indent=2, + ensure_ascii=False, + ), + encoding="utf-8", + ) + def load( self, per_entry: bool = True, @@ -41,17 +53,5 @@ class Cache: return data if self.is_fresh({"timestamp": dt_ts}) else {} - def write(self, data: dict) -> None: - self.file.parent.mkdir(parents=True, exist_ok=True) - - self.file.write_text( - json.dumps( - data, - indent=2, - ensure_ascii=False, - ), - encoding="utf-8", - ) - __all__ = ["Cache"] diff --git a/M3U8/scrapers/utils/config.py b/M3U8/scrapers/utils/config.py index 69c6ea2..bddb5c7 100644 --- a/M3U8/scrapers/utils/config.py +++ b/M3U8/scrapers/utils/config.py @@ -170,8 +170,6 @@ class Leagues: elif self.is_valid(event, "WNBA"): return self.info("WNBA") - # NCAA - else: return self.info("Basketball") diff --git a/M3U8/scrapers/watchfooty.py b/M3U8/scrapers/watchfooty.py index 2d89be3..2bd9bff 100644 --- a/M3U8/scrapers/watchfooty.py +++ b/M3U8/scrapers/watchfooty.py @@ -2,7 +2,6 @@ import asyncio import re from functools import partial from itertools import chain -from pathlib import Path from typing import Any from urllib.parse import urljoin @@ -15,9 +14,9 @@ log = get_logger(__name__) urls: dict[str, dict[str, str | float]] = {} -API_FILE = Cache(Path(__file__).parent / "caches" / "watchfty_api.json", exp=28_800) +CACHE_FILE = Cache("watchfty.json", exp=10_800) -CACHE_FILE = Cache(Path(__file__).parent / "caches" / "watchfty.json", exp=10_800) +API_FILE = Cache("watchfty-api.json", exp=28_800) MIRRORS = [ "https://www.watchfooty.cc", @@ -26,23 +25,30 @@ MIRRORS = [ ] SPORT_ENDPOINTS = [ - "football", "american-football", - "hockey", - "basketball", + "australian-football", "baseball", - "racing", + "basketball", + "cricket", + "darts", "fighting", + "football", "golf", + "hockey", + "racing", + "rugby", + "tennis", + "volleyball", ] async def get_api_data(client: httpx.AsyncClient, url: str) -> list[dict[str, Any]]: try: - r = await client.get(url, timeout=10) + r = await client.get(url, timeout=5) r.raise_for_status() except Exception as e: log.error(f'Failed to fetch "{url}": {e}') + return [] return r.json() @@ -85,7 +91,11 @@ async def process_event( got_one = asyncio.Event() - handler = partial(network.capture_req, captured=captured, got_one=got_one) + handler = partial( + network.capture_req, + captured=captured, + got_one=got_one, + ) page.on("request", handler) @@ -159,7 +169,7 @@ async def get_events( API_FILE.write(api_data) - events: list[dict[str, str]] = [] + events = [] now = Time.clean(Time.now()) start_dt = now.delta(hours=-1) diff --git a/uv.lock b/uv.lock index 932fe75..0a1c575 100644 --- a/uv.lock +++ b/uv.lock @@ -19,11 +19,11 @@ wheels = [ [[package]] name = "certifi" -version = "2025.10.5" +version = "2025.11.12" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4c/5b/b6ce21586237c77ce67d01dc5507039d444b630dd76611bbca2d8e5dcd91/certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43", size = 164519, upload-time = "2025-10-05T04:12:15.808Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/8c/58f469717fa48465e4a50c014a0400602d3c437d7c0c468e17ada824da3a/certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316", size = 160538, upload-time = "2025-11-12T02:54:51.517Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e4/37/af0d2ef3967ac0d6113837b44a4f0bfe1328c2b9763bd5b1744520e5cfed/certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", size = 163286, upload-time = "2025-10-05T04:12:14.03Z" }, + { url = "https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b", size = 159438, upload-time = "2025-11-12T02:54:49.735Z" }, ] [[package]] @@ -52,6 +52,8 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7f/91/ae2eb6b7979e2f9b035a9f612cf70f1bf54aad4e1d125129bef1eae96f19/greenlet-3.2.4-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c2ca18a03a8cfb5b25bc1cbe20f3d9a4c80d8c3b13ba3df49ac3961af0b1018d", size = 584358, upload-time = "2025-08-07T13:18:23.708Z" }, { url = "https://files.pythonhosted.org/packages/f7/85/433de0c9c0252b22b16d413c9407e6cb3b41df7389afc366ca204dbc1393/greenlet-3.2.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9fe0a28a7b952a21e2c062cd5756d34354117796c6d9215a87f55e38d15402c5", size = 1113550, upload-time = "2025-08-07T13:42:37.467Z" }, { url = "https://files.pythonhosted.org/packages/a1/8d/88f3ebd2bc96bf7747093696f4335a0a8a4c5acfcf1b757717c0d2474ba3/greenlet-3.2.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8854167e06950ca75b898b104b63cc646573aa5fef1353d4508ecdd1ee76254f", size = 1137126, upload-time = "2025-08-07T13:18:20.239Z" }, + { url = "https://files.pythonhosted.org/packages/f1/29/74242b7d72385e29bcc5563fba67dad94943d7cd03552bac320d597f29b2/greenlet-3.2.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f47617f698838ba98f4ff4189aef02e7343952df3a615f847bb575c3feb177a7", size = 1544904, upload-time = "2025-11-04T12:42:04.763Z" }, + { url = "https://files.pythonhosted.org/packages/c8/e2/1572b8eeab0f77df5f6729d6ab6b141e4a84ee8eb9bc8c1e7918f94eda6d/greenlet-3.2.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:af41be48a4f60429d5cad9d22175217805098a9ef7c40bfef44f7669fb9d74d8", size = 1611228, upload-time = "2025-11-04T12:42:08.423Z" }, { url = "https://files.pythonhosted.org/packages/d6/6f/b60b0291d9623c496638c582297ead61f43c4b72eef5e9c926ef4565ec13/greenlet-3.2.4-cp310-cp310-win_amd64.whl", hash = "sha256:73f49b5368b5359d04e18d15828eecc1806033db5233397748f4ca813ff1056c", size = 298654, upload-time = "2025-08-07T13:50:00.469Z" }, { url = "https://files.pythonhosted.org/packages/a4/de/f28ced0a67749cac23fecb02b694f6473f47686dff6afaa211d186e2ef9c/greenlet-3.2.4-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:96378df1de302bc38e99c3a9aa311967b7dc80ced1dcc6f171e99842987882a2", size = 272305, upload-time = "2025-08-07T13:15:41.288Z" }, { url = "https://files.pythonhosted.org/packages/09/16/2c3792cba130000bf2a31c5272999113f4764fd9d874fb257ff588ac779a/greenlet-3.2.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1ee8fae0519a337f2329cb78bd7a8e128ec0f881073d43f023c7b8d4831d5246", size = 632472, upload-time = "2025-08-07T13:42:55.044Z" }, @@ -61,6 +63,8 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1f/8e/abdd3f14d735b2929290a018ecf133c901be4874b858dd1c604b9319f064/greenlet-3.2.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2523e5246274f54fdadbce8494458a2ebdcdbc7b802318466ac5606d3cded1f8", size = 587684, upload-time = "2025-08-07T13:18:25.164Z" }, { url = "https://files.pythonhosted.org/packages/5d/65/deb2a69c3e5996439b0176f6651e0052542bb6c8f8ec2e3fba97c9768805/greenlet-3.2.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1987de92fec508535687fb807a5cea1560f6196285a4cde35c100b8cd632cc52", size = 1116647, upload-time = "2025-08-07T13:42:38.655Z" }, { url = "https://files.pythonhosted.org/packages/3f/cc/b07000438a29ac5cfb2194bfc128151d52f333cee74dd7dfe3fb733fc16c/greenlet-3.2.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:55e9c5affaa6775e2c6b67659f3a71684de4c549b3dd9afca3bc773533d284fa", size = 1142073, upload-time = "2025-08-07T13:18:21.737Z" }, + { url = "https://files.pythonhosted.org/packages/67/24/28a5b2fa42d12b3d7e5614145f0bd89714c34c08be6aabe39c14dd52db34/greenlet-3.2.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c9c6de1940a7d828635fbd254d69db79e54619f165ee7ce32fda763a9cb6a58c", size = 1548385, upload-time = "2025-11-04T12:42:11.067Z" }, + { url = "https://files.pythonhosted.org/packages/6a/05/03f2f0bdd0b0ff9a4f7b99333d57b53a7709c27723ec8123056b084e69cd/greenlet-3.2.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:03c5136e7be905045160b1b9fdca93dd6727b180feeafda6818e6496434ed8c5", size = 1613329, upload-time = "2025-11-04T12:42:12.928Z" }, { url = "https://files.pythonhosted.org/packages/d8/0f/30aef242fcab550b0b3520b8e3561156857c94288f0332a79928c31a52cf/greenlet-3.2.4-cp311-cp311-win_amd64.whl", hash = "sha256:9c40adce87eaa9ddb593ccb0fa6a07caf34015a29bf8d344811665b573138db9", size = 299100, upload-time = "2025-08-07T13:44:12.287Z" }, { url = "https://files.pythonhosted.org/packages/44/69/9b804adb5fd0671f367781560eb5eb586c4d495277c93bde4307b9e28068/greenlet-3.2.4-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3b67ca49f54cede0186854a008109d6ee71f66bd57bb36abd6d0a0267b540cdd", size = 274079, upload-time = "2025-08-07T13:15:45.033Z" }, { url = "https://files.pythonhosted.org/packages/46/e9/d2a80c99f19a153eff70bc451ab78615583b8dac0754cfb942223d2c1a0d/greenlet-3.2.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ddf9164e7a5b08e9d22511526865780a576f19ddd00d62f8a665949327fde8bb", size = 640997, upload-time = "2025-08-07T13:42:56.234Z" }, @@ -70,6 +74,8 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/19/0d/6660d55f7373b2ff8152401a83e02084956da23ae58cddbfb0b330978fe9/greenlet-3.2.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b3812d8d0c9579967815af437d96623f45c0f2ae5f04e366de62a12d83a8fb0", size = 607586, upload-time = "2025-08-07T13:18:28.544Z" }, { url = "https://files.pythonhosted.org/packages/8e/1a/c953fdedd22d81ee4629afbb38d2f9d71e37d23caace44775a3a969147d4/greenlet-3.2.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:abbf57b5a870d30c4675928c37278493044d7c14378350b3aa5d484fa65575f0", size = 1123281, upload-time = "2025-08-07T13:42:39.858Z" }, { url = "https://files.pythonhosted.org/packages/3f/c7/12381b18e21aef2c6bd3a636da1088b888b97b7a0362fac2e4de92405f97/greenlet-3.2.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:20fb936b4652b6e307b8f347665e2c615540d4b42b3b4c8a321d8286da7e520f", size = 1151142, upload-time = "2025-08-07T13:18:22.981Z" }, + { url = "https://files.pythonhosted.org/packages/27/45/80935968b53cfd3f33cf99ea5f08227f2646e044568c9b1555b58ffd61c2/greenlet-3.2.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ee7a6ec486883397d70eec05059353b8e83eca9168b9f3f9a361971e77e0bcd0", size = 1564846, upload-time = "2025-11-04T12:42:15.191Z" }, + { url = "https://files.pythonhosted.org/packages/69/02/b7c30e5e04752cb4db6202a3858b149c0710e5453b71a3b2aec5d78a1aab/greenlet-3.2.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:326d234cbf337c9c3def0676412eb7040a35a768efc92504b947b3e9cfc7543d", size = 1633814, upload-time = "2025-11-04T12:42:17.175Z" }, { url = "https://files.pythonhosted.org/packages/e9/08/b0814846b79399e585f974bbeebf5580fbe59e258ea7be64d9dfb253c84f/greenlet-3.2.4-cp312-cp312-win_amd64.whl", hash = "sha256:a7d4e128405eea3814a12cc2605e0e6aedb4035bf32697f72deca74de4105e02", size = 299899, upload-time = "2025-08-07T13:38:53.448Z" }, { url = "https://files.pythonhosted.org/packages/49/e8/58c7f85958bda41dafea50497cbd59738c5c43dbbea5ee83d651234398f4/greenlet-3.2.4-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:1a921e542453fe531144e91e1feedf12e07351b1cf6c9e8a3325ea600a715a31", size = 272814, upload-time = "2025-08-07T13:15:50.011Z" }, { url = "https://files.pythonhosted.org/packages/62/dd/b9f59862e9e257a16e4e610480cfffd29e3fae018a68c2332090b53aac3d/greenlet-3.2.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd3c8e693bff0fff6ba55f140bf390fa92c994083f838fece0f63be121334945", size = 641073, upload-time = "2025-08-07T13:42:57.23Z" }, @@ -79,6 +85,8 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ee/43/3cecdc0349359e1a527cbf2e3e28e5f8f06d3343aaf82ca13437a9aa290f/greenlet-3.2.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23768528f2911bcd7e475210822ffb5254ed10d71f4028387e5a99b4c6699671", size = 610497, upload-time = "2025-08-07T13:18:31.636Z" }, { url = "https://files.pythonhosted.org/packages/b8/19/06b6cf5d604e2c382a6f31cafafd6f33d5dea706f4db7bdab184bad2b21d/greenlet-3.2.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:00fadb3fedccc447f517ee0d3fd8fe49eae949e1cd0f6a611818f4f6fb7dc83b", size = 1121662, upload-time = "2025-08-07T13:42:41.117Z" }, { url = "https://files.pythonhosted.org/packages/a2/15/0d5e4e1a66fab130d98168fe984c509249c833c1a3c16806b90f253ce7b9/greenlet-3.2.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d25c5091190f2dc0eaa3f950252122edbbadbb682aa7b1ef2f8af0f8c0afefae", size = 1149210, upload-time = "2025-08-07T13:18:24.072Z" }, + { url = "https://files.pythonhosted.org/packages/1c/53/f9c440463b3057485b8594d7a638bed53ba531165ef0ca0e6c364b5cc807/greenlet-3.2.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e343822feb58ac4d0a1211bd9399de2b3a04963ddeec21530fc426cc121f19b", size = 1564759, upload-time = "2025-11-04T12:42:19.395Z" }, + { url = "https://files.pythonhosted.org/packages/47/e4/3bb4240abdd0a8d23f4f88adec746a3099f0d86bfedb623f063b2e3b4df0/greenlet-3.2.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca7f6f1f2649b89ce02f6f229d7c19f680a6238af656f61e0115b24857917929", size = 1634288, upload-time = "2025-11-04T12:42:21.174Z" }, { url = "https://files.pythonhosted.org/packages/0b/55/2321e43595e6801e105fcfdee02b34c0f996eb71e6ddffca6b10b7e1d771/greenlet-3.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:554b03b6e73aaabec3745364d6239e9e012d64c68ccd0b8430c64ccc14939a8b", size = 299685, upload-time = "2025-08-07T13:24:38.824Z" }, { url = "https://files.pythonhosted.org/packages/22/5c/85273fd7cc388285632b0498dbbab97596e04b154933dfe0f3e68156c68c/greenlet-3.2.4-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:49a30d5fda2507ae77be16479bdb62a660fa51b1eb4928b524975b3bde77b3c0", size = 273586, upload-time = "2025-08-07T13:16:08.004Z" }, { url = "https://files.pythonhosted.org/packages/d1/75/10aeeaa3da9332c2e761e4c50d4c3556c21113ee3f0afa2cf5769946f7a3/greenlet-3.2.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:299fd615cd8fc86267b47597123e3f43ad79c9d8a22bebdce535e53550763e2f", size = 686346, upload-time = "2025-08-07T13:42:59.944Z" }, @@ -86,6 +94,8 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/dc/8b/29aae55436521f1d6f8ff4e12fb676f3400de7fcf27fccd1d4d17fd8fecd/greenlet-3.2.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b4a1870c51720687af7fa3e7cda6d08d801dae660f75a76f3845b642b4da6ee1", size = 694659, upload-time = "2025-08-07T13:53:17.759Z" }, { url = "https://files.pythonhosted.org/packages/92/2e/ea25914b1ebfde93b6fc4ff46d6864564fba59024e928bdc7de475affc25/greenlet-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:061dc4cf2c34852b052a8620d40f36324554bc192be474b9e9770e8c042fd735", size = 695355, upload-time = "2025-08-07T13:18:34.517Z" }, { url = "https://files.pythonhosted.org/packages/72/60/fc56c62046ec17f6b0d3060564562c64c862948c9d4bc8aa807cf5bd74f4/greenlet-3.2.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44358b9bf66c8576a9f57a590d5f5d6e72fa4228b763d0e43fee6d3b06d3a337", size = 657512, upload-time = "2025-08-07T13:18:33.969Z" }, + { url = "https://files.pythonhosted.org/packages/23/6e/74407aed965a4ab6ddd93a7ded3180b730d281c77b765788419484cdfeef/greenlet-3.2.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2917bdf657f5859fbf3386b12d68ede4cf1f04c90c3a6bc1f013dd68a22e2269", size = 1612508, upload-time = "2025-11-04T12:42:23.427Z" }, + { url = "https://files.pythonhosted.org/packages/0d/da/343cd760ab2f92bac1845ca07ee3faea9fe52bee65f7bcb19f16ad7de08b/greenlet-3.2.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:015d48959d4add5d6c9f6c5210ee3803a830dce46356e3bc326d6776bde54681", size = 1680760, upload-time = "2025-11-04T12:42:25.341Z" }, { url = "https://files.pythonhosted.org/packages/e3/a5/6ddab2b4c112be95601c13428db1d8b6608a8b6039816f2ba09c346c08fc/greenlet-3.2.4-cp314-cp314-win_amd64.whl", hash = "sha256:e37ab26028f12dbb0ff65f29a8d3d44a765c61e729647bf2ddfbbed621726f01", size = 303425, upload-time = "2025-08-07T13:32:27.59Z" }, ] @@ -192,21 +202,21 @@ requires-dist = [ [[package]] name = "playwright" -version = "1.55.0" +version = "1.56.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "greenlet" }, { name = "pyee" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/80/3a/c81ff76df266c62e24f19718df9c168f49af93cabdbc4608ae29656a9986/playwright-1.55.0-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:d7da108a95001e412effca4f7610de79da1637ccdf670b1ae3fdc08b9694c034", size = 40428109, upload-time = "2025-08-28T15:46:20.357Z" }, - { url = "https://files.pythonhosted.org/packages/cf/f5/bdb61553b20e907196a38d864602a9b4a461660c3a111c67a35179b636fa/playwright-1.55.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:8290cf27a5d542e2682ac274da423941f879d07b001f6575a5a3a257b1d4ba1c", size = 38687254, upload-time = "2025-08-28T15:46:23.925Z" }, - { url = "https://files.pythonhosted.org/packages/4a/64/48b2837ef396487807e5ab53c76465747e34c7143fac4a084ef349c293a8/playwright-1.55.0-py3-none-macosx_11_0_universal2.whl", hash = "sha256:25b0d6b3fd991c315cca33c802cf617d52980108ab8431e3e1d37b5de755c10e", size = 40428108, upload-time = "2025-08-28T15:46:27.119Z" }, - { url = "https://files.pythonhosted.org/packages/08/33/858312628aa16a6de97839adc2ca28031ebc5391f96b6fb8fdf1fcb15d6c/playwright-1.55.0-py3-none-manylinux1_x86_64.whl", hash = "sha256:c6d4d8f6f8c66c483b0835569c7f0caa03230820af8e500c181c93509c92d831", size = 45905643, upload-time = "2025-08-28T15:46:30.312Z" }, - { url = "https://files.pythonhosted.org/packages/83/83/b8d06a5b5721931aa6d5916b83168e28bd891f38ff56fe92af7bdee9860f/playwright-1.55.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29a0777c4ce1273acf90c87e4ae2fe0130182100d99bcd2ae5bf486093044838", size = 45296647, upload-time = "2025-08-28T15:46:33.221Z" }, - { url = "https://files.pythonhosted.org/packages/06/2e/9db64518aebcb3d6ef6cd6d4d01da741aff912c3f0314dadb61226c6a96a/playwright-1.55.0-py3-none-win32.whl", hash = "sha256:29e6d1558ad9d5b5c19cbec0a72f6a2e35e6353cd9f262e22148685b86759f90", size = 35476046, upload-time = "2025-08-28T15:46:36.184Z" }, - { url = "https://files.pythonhosted.org/packages/46/4f/9ba607fa94bb9cee3d4beb1c7b32c16efbfc9d69d5037fa85d10cafc618b/playwright-1.55.0-py3-none-win_amd64.whl", hash = "sha256:7eb5956473ca1951abb51537e6a0da55257bb2e25fc37c2b75af094a5c93736c", size = 35476048, upload-time = "2025-08-28T15:46:38.867Z" }, - { url = "https://files.pythonhosted.org/packages/21/98/5ca173c8ec906abde26c28e1ecb34887343fd71cc4136261b90036841323/playwright-1.55.0-py3-none-win_arm64.whl", hash = "sha256:012dc89ccdcbd774cdde8aeee14c08e0dd52ddb9135bf10e9db040527386bd76", size = 31225543, upload-time = "2025-08-28T15:46:41.613Z" }, + { url = "https://files.pythonhosted.org/packages/6b/31/a5362cee43f844509f1f10d8a27c9cc0e2f7bdce5353d304d93b2151c1b1/playwright-1.56.0-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:b33eb89c516cbc6723f2e3523bada4a4eb0984a9c411325c02d7016a5d625e9c", size = 40611424, upload-time = "2025-11-11T18:39:10.175Z" }, + { url = "https://files.pythonhosted.org/packages/ef/95/347eef596d8778fb53590dc326c344d427fa19ba3d42b646fce2a4572eb3/playwright-1.56.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:b228b3395212b9472a4ee5f1afe40d376eef9568eb039fcb3e563de8f4f4657b", size = 39400228, upload-time = "2025-11-11T18:39:13.915Z" }, + { url = "https://files.pythonhosted.org/packages/b9/54/6ad97b08b2ca1dfcb4fbde4536c4f45c0d9d8b1857a2d20e7bbfdf43bf15/playwright-1.56.0-py3-none-macosx_11_0_universal2.whl", hash = "sha256:0ef7e6fd653267798a8a968ff7aa2dcac14398b7dd7440ef57524e01e0fbbd65", size = 40611424, upload-time = "2025-11-11T18:39:17.093Z" }, + { url = "https://files.pythonhosted.org/packages/e4/76/6d409e37e82cdd5dda3df1ab958130ae32b46e42458bd4fc93d7eb8749cb/playwright-1.56.0-py3-none-manylinux1_x86_64.whl", hash = "sha256:404be089b49d94bc4c1fe0dfb07664bda5ffe87789034a03bffb884489bdfb5c", size = 46263122, upload-time = "2025-11-11T18:39:20.619Z" }, + { url = "https://files.pythonhosted.org/packages/4f/84/fb292cc5d45f3252e255ea39066cd1d2385c61c6c1596548dfbf59c88605/playwright-1.56.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64cda7cf4e51c0d35dab55190841bfcdfb5871685ec22cb722cd0ad2df183e34", size = 46110645, upload-time = "2025-11-11T18:39:24.005Z" }, + { url = "https://files.pythonhosted.org/packages/61/bd/8c02c3388ae14edc374ac9f22cbe4e14826c6a51b2d8eaf86e89fabee264/playwright-1.56.0-py3-none-win32.whl", hash = "sha256:d87b79bcb082092d916a332c27ec9732e0418c319755d235d93cc6be13bdd721", size = 35639837, upload-time = "2025-11-11T18:39:27.174Z" }, + { url = "https://files.pythonhosted.org/packages/64/27/f13b538fbc6b7a00152f4379054a49f6abc0bf55ac86f677ae54bc49fb82/playwright-1.56.0-py3-none-win_amd64.whl", hash = "sha256:3c7fc49bb9e673489bf2622855f9486d41c5101bbed964638552b864c4591f94", size = 35639843, upload-time = "2025-11-11T18:39:30.851Z" }, + { url = "https://files.pythonhosted.org/packages/f2/c7/3ee8b556107995846576b4fe42a08ed49b8677619421f2afacf6ee421138/playwright-1.56.0-py3-none-win_arm64.whl", hash = "sha256:2745490ae8dd58d27e5ea4d9aa28402e8e2991eb84fb4b2fd5fbde2106716f6f", size = 31248959, upload-time = "2025-11-11T18:39:33.998Z" }, ] [[package]]