This commit is contained in:
doms9 2025-12-18 04:14:54 -05:00
parent 8b2d8cc1fc
commit 00000d939c
20 changed files with 119 additions and 12 deletions

View file

@ -7,7 +7,9 @@ from .config import Time
class Cache:
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()
def is_fresh(self, entry: dict) -> bool:

View file

@ -45,11 +45,13 @@ class Time(datetime):
def to_tz(self, tzone: str) -> "Time":
dt = self.astimezone(self.ZONES[tzone])
return self.__class__.fromtimestamp(dt.timestamp(), tz=self.ZONES[tzone])
@classmethod
def _to_class_tz(cls, dt) -> "Time":
dt = dt.astimezone(cls.TZ)
return cls.fromtimestamp(dt.timestamp(), tz=cls.TZ)
@classmethod

View file

@ -22,9 +22,13 @@ COLORS = {
class ColorFormatter(logging.Formatter):
def format(self, record) -> str:
color = COLORS.get(record.levelname, COLORS["reset"])
levelname = record.levelname
record.levelname = f"{color}{levelname:<8}{COLORS['reset']}"
formatted = super().format(record)
record.levelname = levelname
return formatted
@ -38,10 +42,15 @@ def get_logger(name: str | None = None) -> logging.Logger:
if not logger.hasHandlers():
handler = logging.StreamHandler()
formatter = ColorFormatter(LOG_FMT, datefmt="%Y-%m-%d | %H:%M:%S")
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.INFO)
logger.propagate = False
return logger

View file

@ -12,6 +12,8 @@ from playwright.async_api import Browser, BrowserContext, Playwright, Request
from .logger import get_logger
logger = get_logger(__name__)
T = TypeVar("T")
@ -32,8 +34,6 @@ class Network:
http2=True,
)
self._logger = get_logger("network")
@staticmethod
def build_proxy_url(
tag: str,
@ -58,16 +58,18 @@ class Network:
**kwargs,
) -> httpx.Response | None:
log = log or self._logger
log = log or logger
try:
r = await self.client.get(url, **kwargs)
r.raise_for_status()
except Exception as e:
log.error(f'Failed to fetch "{url}": {e}\n{kwargs = }')
return ""
return r
r.raise_for_status()
return r
except (httpx.HTTPError, httpx.TimeoutException) as e:
log.error(f'Failed to fetch "{url}": {e}')
return ""
async def get_base(self, mirrors: list[str]) -> str | None:
random.shuffle(mirrors)
@ -89,7 +91,7 @@ class Network:
log: logging.Logger | None = None,
) -> T | None:
log = log or get_logger("network")
log = log or logger
task = asyncio.create_task(fn())
@ -104,13 +106,15 @@ class Network:
await task
except asyncio.CancelledError:
pass
except Exception as e:
log.debug(f"URL {url_num}) Ignore exception after timeout: {e}")
return None
return
except Exception as e:
log.error(f"URL {url_num}) Unexpected error: {e}")
return None
return
@staticmethod
def capture_req(
@ -141,7 +145,7 @@ class Network:
log: logging.Logger | None = None,
) -> str | None:
log = log or self._logger
log = log or logger
page = await context.new_page()
@ -170,6 +174,7 @@ class Network:
await asyncio.wait_for(wait_task, timeout=timeout)
except asyncio.TimeoutError:
log.warning(f"URL {url_num}) Timed out waiting for M3U8.")
return
finally:
@ -183,17 +188,21 @@ class Network:
if captured:
log.info(f"URL {url_num}) Captured M3U8")
return captured[0]
log.warning(f"URL {url_num}) No M3U8 captured after waiting.")
return
except Exception as e:
log.warning(f"URL {url_num}) Exception while processing: {e}")
return
finally:
page.remove_listener("request", handler)
await page.close()
@staticmethod
@ -205,7 +214,9 @@ class Network:
if browser == "brave":
brwsr = await playwright.chromium.connect_over_cdp("http://localhost:9222")
context = brwsr.contexts[0]
else:
brwsr = await playwright.firefox.launch(headless=True)