新增IRC协议相关的全套工具模块,包括: - 核心协议解析与CTCP处理 - 消息发送缓存与文本 sanitize - 账号配置管理与运行时状态 - 命令处理与权限控制 - 服务发现与诊断工具 - 多账号网关与配置加载
61 lines
1.7 KiB
Python
61 lines
1.7 KiB
Python
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
|