《新闻联播》每日抓取入库:全链路 + 可移植化 + 定时任务
从 CCTV 主页抓取《新闻联播》,下载 → 转 MP3/WAV → 静音切分 → ASR 识别 → LLM 校对 → 切分为单条新闻 → 入库 MySQL。 主要内容: - 全链路:getVideo5 抓取下载、audioRead 转写、deepseek 校对与切分、newsProcess 入库 - 可移植化:配置分层,.env 只放密钥、config.yml 放模型/接入点/路由/参数 - 可换供应商:endpoints(kind/base_url/api_key_env/extra_body)+ routes 按环节选路 - 数据保真:数值事实守卫,校对改动数字/年份/届次则整片回退 ASR 原文; 识别不完整不发布该日精编,避免半天内容被当成完整一天 - 定时任务:systemd 每天 21:00,失败 21:30 / 22:00 重试; 只缺切分时只重跑切分(省掉全部 ASR),用 state/.asr_complete_* 标记判定阶段 - 隧道自愈:13306 不通时自动执行 autossh.sh(所有入口共用,systemd 托管时只等待) - 中间产物每日清理;97 项离线自检(配置/清理/事实守卫/解析/隧道)
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
"""敏感配置加载器(.env)
|
||||
|
||||
职责边界(2026-09-25 重构):
|
||||
- 本文件只负责**加载**敏感配置:数据库口令、各供应商 API Key。
|
||||
- 校验(缺哪些、密钥变量叫什么)在 `config.required_secrets()` / `config.check_secrets()`,
|
||||
因为密钥变量名由 config.yml 的 `endpoints.*.api_key_env` 决定(换供应商时会变)。
|
||||
- 非敏感配置(数据库地址、目录、模型名、**base url 接入点**、参数、清理开关)见 config.yml / config.py。
|
||||
|
||||
`.env` 查找顺序:XWLB_ENV_FILE → 项目目录内 .env → 上一级 / 上两级 .env(兼容旧 djapi 布局)。
|
||||
已存在的进程环境变量优先,不会被 .env 覆盖。
|
||||
"""
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# 本文件所在目录即项目根(xwlb/)
|
||||
BASE_DIR = Path(__file__).resolve().parent
|
||||
|
||||
|
||||
def _candidate_env_files():
|
||||
"""按优先级返回候选 .env 路径"""
|
||||
override = os.getenv('XWLB_ENV_FILE')
|
||||
if override:
|
||||
yield Path(override).expanduser()
|
||||
return
|
||||
yield BASE_DIR / '.env'
|
||||
# 兼容旧布局:xwlb/ 的上一级或上两级
|
||||
yield BASE_DIR.parent / '.env'
|
||||
yield BASE_DIR.parent.parent / '.env'
|
||||
|
||||
|
||||
def _load_dotenv():
|
||||
"""从候选路径中第一个存在的 .env 加载环境变量(不覆盖已有)"""
|
||||
for dotenv_path in _candidate_env_files():
|
||||
if not dotenv_path.is_file():
|
||||
continue
|
||||
count = 0
|
||||
with open(dotenv_path, encoding='utf-8') as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line or line.startswith('#') or '=' not in line:
|
||||
continue
|
||||
key, _, value = line.partition('=')
|
||||
key = key.strip()
|
||||
value = value.strip().strip('"').strip("'")
|
||||
if key and key not in os.environ:
|
||||
os.environ[key] = value
|
||||
count += 1
|
||||
logger.info("已加载敏感配置 %s(注入 %d 个变量)", dotenv_path, count)
|
||||
return dotenv_path
|
||||
logger.debug("未找到 .env 文件,仅使用进程环境变量")
|
||||
return None
|
||||
|
||||
|
||||
LOADED_ENV_FILE = _load_dotenv()
|
||||
|
||||
|
||||
def env_file() -> Path:
|
||||
"""当前使用的 .env 路径(不存在时返回期望路径)"""
|
||||
return LOADED_ENV_FILE or (BASE_DIR / '.env')
|
||||
Reference in New Issue
Block a user