File size: 3,118 Bytes
d0c18f0 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | """
URL输入处理器 - 供所有插件复用
支持 Base64 和 URL 两种输入方式
"""
import base64
import httpx
from typing import Optional, Tuple
from urllib.parse import urlparse
from .http_client import get_http_client
MAX_FILE_SIZE = 50 * 1024 * 1024 # 50MB
async def resolve_content(
content_base64: Optional[str],
content_url: Optional[str],
) -> Tuple[bytes, str]:
"""
统一解析输入内容
Args:
content_base64: Base64编码的内容(优先使用)
content_url: 文件URL地址(备选方式)
Returns:
(原始bytes, 来源说明)
Raises:
ValueError: 输入无效或下载失败
"""
if content_base64:
try:
return base64.b64decode(content_base64), "base64"
except Exception as e:
raise ValueError(f"Base64解码失败: {e}")
if content_url:
parsed = urlparse(content_url)
if parsed.scheme not in ("http", "https"):
raise ValueError(f"不支持的URL协议: {parsed.scheme}")
if not parsed.netloc:
raise ValueError(f"无效的URL: {content_url}")
try:
client = get_http_client()
resp = await client.get(content_url)
if resp.status_code != 200:
raise ValueError(f"下载失败: HTTP {resp.status_code}")
content_length = len(resp.content)
if content_length > MAX_FILE_SIZE:
raise ValueError(f"文件过大: {content_length} bytes (上限 {MAX_FILE_SIZE})")
return resp.content, f"url:{content_url}"
except httpx.TimeoutException:
raise ValueError(f"下载超时")
except httpx.RequestError as e:
raise ValueError(f"网络请求失败: {e}")
raise ValueError("必须提供 content_base64 或 content_url")
async def resolve_text_content(
content_base64: Optional[str],
content_url: Optional[str],
encoding: str = "utf-8",
) -> Tuple[str, str]:
"""
解析文本内容(自动解码)
Args:
content_base64: Base64编码的内容
content_url: 文件URL地址
encoding: 文本编码(默认utf-8)
Returns:
(解码后的文本, 来源说明)
"""
content, source = await resolve_content(content_base64, content_url)
try:
return content.decode(encoding), source
except UnicodeDecodeError as e:
raise ValueError(f"文本解码失败 ({encoding}): {e}")
def encode_bytes_to_base64(data: bytes) -> str:
"""将字节数据编码为 Base64"""
return base64.b64encode(data).decode("utf-8")
def encode_text_to_base64(text: str, encoding: str = "utf-8") -> str:
"""将文本编码为 Base64"""
return base64.b64encode(text.encode(encoding)).decode("utf-8")
def decode_base64_to_bytes(base64_str: str) -> bytes:
"""将 Base64 解码为字节"""
return base64.b64decode(base64_str)
def decode_base64_to_text(base64_str: str, encoding: str = "utf-8") -> str:
"""将 Base64 解码为文本"""
return base64.b64decode(base64_str).decode(encoding) |