Files
param-hub-python/utils.py

106 lines
3.2 KiB
Python

"""
ParamHub 工具函数
"""
import json
import base64
from pathlib import Path
from datetime import datetime
from werkzeug.utils import secure_filename
from config import (
ALLOWED_EXTENSIONS, DEFAULT_CONFIG, CONFIG_FILE, IMAGES_DIR, DATA_DIR
)
def allowed_file(filename: str) -> bool:
"""检查文件扩展名是否允许"""
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
def load_data(file_path: Path):
"""加载JSON数据文件"""
if file_path.exists():
return json.loads(file_path.read_text(encoding='utf-8'))
return []
def save_data(file_path: Path, data):
"""保存JSON数据到文件"""
file_path.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding='utf-8')
def load_config() -> dict:
"""加载网站配置,合并默认值"""
if CONFIG_FILE.exists():
loaded = json.loads(CONFIG_FILE.read_text(encoding='utf-8'))
result = DEFAULT_CONFIG.copy()
result.update(loaded)
return result
return DEFAULT_CONFIG.copy()
def save_config(config: dict):
"""保存网站配置"""
CONFIG_FILE.write_text(json.dumps(config, ensure_ascii=False, indent=2), encoding='utf-8')
def get_items_file(category_id: str) -> Path:
"""获取动态分类的数据文件路径"""
return DATA_DIR / f'items_{category_id}.json'
def get_llm_config() -> dict:
"""从 config.json 动态读取 LLM 配置"""
config = load_config()
return {
'base_url': config.get('llm_base_url', DEFAULT_CONFIG['llm_base_url']),
'api_key': config.get('llm_api_key', DEFAULT_CONFIG['llm_api_key']),
'model': config.get('llm_model', DEFAULT_CONFIG['llm_model']),
'vision_model': config.get('llm_vision_model', DEFAULT_CONFIG['llm_vision_model']),
}
def parse_date_to_timestamp(date_str: str) -> float | None:
"""将日期字符串转换为 Unix 时间戳"""
if not date_str:
return None
for fmt in ['%Y-%m-%d', '%Y-%m-%d %H:%M:%S', '%Y/%m/%d']:
try:
return datetime.strptime(date_str, fmt).timestamp()
except (ValueError, TypeError):
pass
return None
def safe_sort_key(x: dict, key: str):
"""排序时安全获取字段值,缺失时返回合理默认值"""
val = x.get(key)
if val is None:
if key in ['parameters', 'context_length', 'mmlu', 'views']:
return 0
elif key in ['publish_date', 'created_at', 'updated_at']:
return ''
return ''
return val
def read_image_base64(img_src: str) -> str | None:
"""将图片路径/base64/URL转换为base64 data URI"""
import base64 as b64
if img_src.startswith('data:'):
return img_src
if img_src.startswith('http'):
return img_src # URL 直接传给 LLM
# 本地路径
try:
img_path = IMAGES_DIR / img_src.replace('/static/uploads/', '')
if img_path.exists():
with open(img_path, 'rb') as f:
img_data = b64.b64encode(f.read()).decode()
ext = img_path.suffix.lower().lstrip('.')
mime = f'image/{"jpeg" if ext == "jpg" else ext}'
return f'data:{mime};base64,{img_data}'
except Exception:
pass
return None