from __future__ import annotations import re from typing import Any from yuxi.utils.logging_config import logger _URL_RE = re.compile( r"https?://[^\s]+\.(?:png|jpg|jpeg|gif|webp|svg)(?:\?[^\s]*)?", re.IGNORECASE, ) def extract_media_urls(text: str) -> list[str]: return _URL_RE.findall(text) def has_media_url(text: str) -> bool: return bool(_URL_RE.search(text)) async def download_media( url: str, timeout: float = 15.0, ) -> bytes | None: import aiohttp try: async with aiohttp.ClientSession() as session: async with session.get(url, timeout=aiohttp.ClientTimeout(total=timeout)) as resp: if resp.status != 200: logger.warning(f"IRC media download failed: {url} (status {resp.status})") return None content_length = resp.headers.get("Content-Length") if content_length and int(content_length) > 50 * 1024 * 1024: logger.warning(f"IRC media too large: {url} ({int(content_length) // 1024 // 1024}MB)") return None return await resp.read() except TimeoutError: logger.warning(f"IRC media download timeout: {url}") return None except Exception as e: logger.warning(f"IRC media download error: {url} - {e}") return None def analyze_urls(text: str) -> list[dict[str, Any]]: urls = extract_media_urls(text) result: list[dict[str, Any]] = [] for url in urls: ext = url.rsplit(".", 1)[-1].split("?")[0].lower() result.append( { "url": url, "type": "image", "format": ext, "size_bytes": None, } ) return result