Files
daily-paper/app/utils.py
T
Rain-Bus 0d293422ac feat: enhance UI, refactor services, improve templates and tests
- Replace image_extractor with pdf_image_extractor service
- Enhance pi_client with expanded API capabilities
- Improve summarizer service with additional features
- Update admin routes with more endpoints
- Add login page template
- Enhance detail page with comprehensive layout
- Improve search and trends pages
- Update base template with additional elements
- Refactor tests for better coverage
- Add validate_summary script
- Update project configuration and dependencies
2026-06-07 19:38:58 +08:00

86 lines
3.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""公共工具 — 消除各模块间的重复代码。"""
from __future__ import annotations
from datetime import datetime, timezone
from pathlib import Path
from zoneinfo import ZoneInfo
import httpx
from fastapi.templating import Jinja2Templates
from app.config import settings
# ── 路径常量 ──────────────────────────────────────────────────────────
DATA_DIR = Path("data")
PAPERS_DIR = DATA_DIR / "papers"
TMP_DIR = DATA_DIR / "tmp"
# ── 模板单例 ──────────────────────────────────────────────────────────
class _Templates(Jinja2Templates):
"""自动注入 is_admin 到模板上下文的 Jinja2Templates 子类。"""
def TemplateResponse(self, request, name, context=None, **kwargs):
context = context or {}
context.setdefault("is_admin", request.session.get("is_admin", False))
return super().TemplateResponse(request, name, context, **kwargs)
templates = _Templates(directory="app/templates")
# ── 时区工具 ──────────────────────────────────────────────────────────
def today_str() -> str:
"""当前日期字符串(按 APP_TIMEZONE)。"""
tz = ZoneInfo(settings.APP_TIMEZONE)
return datetime.now(tz).strftime("%Y-%m-%d")
# ── 锁释放 ────────────────────────────────────────────────────────────
def release_lock(db, lock) -> None:
"""释放 TaskLock。"""
try:
lock.status = "finished"
lock.released_at = datetime.now(timezone.utc)
db.commit()
except Exception:
db.rollback()
# ── HTTP 客户端工厂 ───────────────────────────────────────────────────
def make_http_client(
*, sync: bool = False, follow_redirects: bool = False, **kwargs
) -> httpx.AsyncClient | httpx.Client:
"""创建带 proxy 和默认配置的 httpx 客户端。
Args:
sync: True 返回同步 ClientFalse 返回 AsyncClient
follow_redirects: 是否跟随重定向
**kwargs: 覆盖默认参数
"""
defaults: dict = {
"timeout": settings.HTTP_TIMEOUT_SECONDS,
"headers": {"User-Agent": settings.HTTP_USER_AGENT},
"follow_redirects": follow_redirects,
}
if settings.http_proxy:
defaults["transport"] = (
httpx.HTTPTransport(proxy=settings.http_proxy)
if sync
else httpx.AsyncHTTPTransport(proxy=settings.http_proxy)
)
defaults.update(kwargs)
if sync:
return httpx.Client(**defaults)
return httpx.AsyncClient(**defaults)