e
This commit is contained in:
parent
dece752803
commit
00000d9440
12 changed files with 371 additions and 133 deletions
3
M3U8/scrape/utils/__init__.py
Normal file
3
M3U8/scrape/utils/__init__.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
from .config import LOGOS, TZ, get_base, get_logger, safe_process_event
|
||||
|
||||
__all__ = ["LOGOS", "TZ", "get_base", "get_logger", "safe_process_event"]
|
||||
106
M3U8/scrape/utils/config.py
Normal file
106
M3U8/scrape/utils/config.py
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
import asyncio
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
import httpx
|
||||
import pytz
|
||||
|
||||
TZ = pytz.timezone("America/New_York")
|
||||
|
||||
LOGOS = {
|
||||
"MLB": "https://i.gyazo.com/0fe7865ef2f06c9507791b24f04dbca8.png",
|
||||
"NBA": "https://i.gyazo.com/773c23570f095a5d549c23b9401d83f4.png",
|
||||
"NCAAF": "https://i.gyazo.com/ca63b40c86e757436de9d34d369b24f8.png",
|
||||
"NCAAB": "https://i.gyazo.com/ca63b40c86e757436de9d34d369b24f8.png",
|
||||
"NFL": "https://i.gyazo.com/fb4956d7a2fe54a1bac54cd81e1b3f11.png",
|
||||
"NHL": "https://i.gyazo.com/526607d4e886d5ed1fecca4bff3115e2.png",
|
||||
"WNBA": "https://i.gyazo.com/02d665a5704118d195dbcd5fa20d5462.png",
|
||||
}
|
||||
|
||||
LOG_FMT = (
|
||||
"[%(asctime)s] "
|
||||
"%(levelname)-8s "
|
||||
"[%(name)s] "
|
||||
"%(message)-70s "
|
||||
"(%(filename)s:%(lineno)d)"
|
||||
)
|
||||
|
||||
COLORS = {
|
||||
"DEBUG": "\033[37m",
|
||||
"INFO": "\033[32m",
|
||||
"WARNING": "\033[33m",
|
||||
"ERROR": "\033[31m",
|
||||
"CRITICAL": "\033[41m",
|
||||
"reset": "\033[0m",
|
||||
}
|
||||
|
||||
|
||||
class ColorFormatter(logging.Formatter):
|
||||
def format(self, record) -> str:
|
||||
color = COLORS.get(record.levelname, "")
|
||||
levelname = record.levelname
|
||||
record.levelname = f"{color}{levelname}{COLORS['reset']}"
|
||||
formatted = super().format(record)
|
||||
record.levelname = levelname
|
||||
return formatted
|
||||
|
||||
|
||||
def get_logger(name: str | None = None) -> logging.Logger:
|
||||
if not name:
|
||||
name = Path(__file__).stem
|
||||
|
||||
logger = logging.getLogger(name)
|
||||
|
||||
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)
|
||||
|
||||
return logger
|
||||
|
||||
|
||||
async def safe_process_event(
|
||||
fn,
|
||||
url_num: int,
|
||||
timeout=20,
|
||||
log: logging.Logger | None = None,
|
||||
) -> Any | None:
|
||||
|
||||
if not log:
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
task = asyncio.create_task(fn())
|
||||
|
||||
try:
|
||||
return await asyncio.wait_for(task, timeout=timeout)
|
||||
except asyncio.TimeoutError:
|
||||
log.warning(f"URL {url_num}) Timed out after {timeout}s, skipping event")
|
||||
|
||||
task.cancel()
|
||||
|
||||
try:
|
||||
await task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
except Exception as e:
|
||||
log.debug(f"URL {url_num}) Ignore exception after timeout: {e}")
|
||||
|
||||
|
||||
async def check_status(client: httpx.AsyncClient, url: str) -> bool:
|
||||
try:
|
||||
r = await client.get(url)
|
||||
r.raise_for_status()
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
return r.status_code == 200
|
||||
|
||||
|
||||
async def get_base(client: httpx.AsyncClient, mirrors: list[str]) -> str:
|
||||
tasks = [check_status(client, link) for link in mirrors]
|
||||
results = await asyncio.gather(*tasks)
|
||||
|
||||
return [url for url, ok in zip(mirrors, results) if ok][0]
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
import logging
|
||||
|
||||
log_format = "[%(asctime)s] %(levelname)-8s %(message)-70s %(filename)s:%(lineno)d"
|
||||
|
||||
colors = {
|
||||
"DEBUG": "\033[37m",
|
||||
"INFO": "\033[32m",
|
||||
"WARNING": "\033[33m",
|
||||
"ERROR": "\033[31m",
|
||||
"CRITICAL": "\033[41m",
|
||||
"reset": "\033[0m",
|
||||
}
|
||||
|
||||
|
||||
class ColorFormatter(logging.Formatter):
|
||||
def format(self, record) -> str:
|
||||
color = colors.get(record.levelname, "")
|
||||
|
||||
record.levelname = f"{color}{record.levelname}{colors['reset']}"
|
||||
|
||||
return super().format(record)
|
||||
|
||||
|
||||
def get_logger(name: str = __name__) -> logging.Logger:
|
||||
logger = logging.getLogger(name)
|
||||
|
||||
if not logger.hasHandlers():
|
||||
handler = logging.StreamHandler()
|
||||
|
||||
formatter = ColorFormatter(log_format, datefmt="%Y-%m-%d | %H:%M:%S")
|
||||
|
||||
handler.setFormatter(formatter)
|
||||
|
||||
logger.addHandler(handler)
|
||||
|
||||
logger.setLevel(logging.INFO)
|
||||
|
||||
return logger
|
||||
Loading…
Add table
Add a link
Reference in a new issue