ForcePilot/backend/package/yuxi/channels/adapters/urbit/media.py
Kris 49ecd949e8 feat(urbit): 实现完整的Urbit聊天适配器模块
新增了从错误定义、客户端实现到功能完整的Urbit适配器全套代码,包括认证、消息处理、目录查询、邀请管理、媒体处理、速率限制等核心功能模块
2026-05-12 00:50:27 +08:00

58 lines
1.4 KiB
Python

from __future__ import annotations
from typing import TYPE_CHECKING
from yuxi.utils.logging_config import logger
if TYPE_CHECKING:
from .client import UrbitClient
async def download_media(
client: UrbitClient,
file_url: str,
timeout: float = 30.0,
*,
allow_private: bool = False,
) -> tuple[bytes, str]:
from .probe import validate_urbit_url
is_valid, warnings = validate_urbit_url(file_url, allow_private=allow_private)
if not is_valid:
raise ValueError(f"SSRF blocked: {'; '.join(warnings)}")
import httpx
try:
r = await client.http.get(
file_url,
timeout=httpx.Timeout(timeout),
follow_redirects=True,
)
r.raise_for_status()
content_type = r.headers.get("content-type", "application/octet-stream")
return r.content, content_type
except Exception as e:
logger.warning(f"[Urbit] Media download failed from {file_url}: {e}")
raise
_MEDIA_EXTENSIONS: dict[str, str] = {
"image/jpeg": ".jpg",
"image/png": ".png",
"image/gif": ".gif",
"image/webp": ".webp",
"image/svg+xml": ".svg",
"image/heic": ".heic",
"image/heif": ".heif",
"video/mp4": ".mp4",
"video/webm": ".webm",
"audio/mpeg": ".mp3",
"audio/ogg": ".ogg",
"audio/wav": ".wav",
}
def get_media_extension(content_type: str) -> str:
return _MEDIA_EXTENSIONS.get(content_type, ".bin")