feat(db): add video pages and up follower snapshot schema

This commit is contained in:
kairee committed 2026-11-01 11:14:36 +08:00
1 parent 707ed7d7d7
commit 4942d1d161
10 files changed
+521 -13

No files matched your search

+45
View File
@@ -38,6 +38,13 @@ DEFAULT_HEAT_WEIGHTS: dict[str, float] = {
"danmaku": 0.02,
}
DEFAULT_ANALYTICS: dict[str, Any] = {
"min_duration_seconds": 600,
"maturity_days": 14,
"min_view_for_efficiency": 0,
"shrink_minutes": None,
}
DEFAULT_CONFIG: dict[str, Any] = {
"bilibili": {
"read": {"mid": 0, "csrf": "", "cookie": ""},
@@ -73,6 +80,7 @@ DEFAULT_CONFIG: dict[str, Any] = {
"notify": {"min_score": 2, "max_items_per_message": 10},
"classify": DEFAULT_CLASSIFY,
"heat_weights": DEFAULT_HEAT_WEIGHTS,
"analytics": DEFAULT_ANALYTICS,
}
# 环境变量只作为 CI / 临时调试的覆盖入口,不作为主路径。
@@ -161,6 +169,14 @@ class DiscoverConfig:
window_days: int
@dataclass(frozen=True)
class AnalyticsConfig:
min_duration_seconds: int
maturity_days: int
min_view_for_efficiency: int
shrink_minutes: int | None
@dataclass(frozen=True)
class AppConfig:
path: Path
@@ -176,6 +192,7 @@ class AppConfig:
discover: DiscoverConfig
classify: Mapping[str, Any]
heat_weights: Mapping[str, float]
analytics: AnalyticsConfig
raw: Mapping[str, Any] = field(repr=False, compare=False)
def folder_for_year(self, year: int) -> FolderConfig | None:
@@ -431,6 +448,33 @@ def _build_config(data: Mapping[str, Any], path: Path) -> AppConfig:
raise ConfigError(f"heat_weights.{metric} 必须是非负数字")
heat[metric] = float(value)
analytics_raw = data["analytics"]
if not isinstance(analytics_raw, Mapping):
raise ConfigError("analytics 必须是对象")
shrink_raw = analytics_raw.get("shrink_minutes")
analytics = AnalyticsConfig(
min_duration_seconds=_as_int(
analytics_raw.get("min_duration_seconds", 600),
"analytics.min_duration_seconds",
minimum=0,
),
maturity_days=_as_int(
analytics_raw.get("maturity_days", 14),
"analytics.maturity_days",
minimum=0,
),
min_view_for_efficiency=_as_int(
analytics_raw.get("min_view_for_efficiency", 0),
"analytics.min_view_for_efficiency",
minimum=0,
),
shrink_minutes=(
None if shrink_raw is None else _as_int(
shrink_raw, "analytics.shrink_minutes", minimum=1
)
),
)
return AppConfig(
path=path,
bilibili=bilibili,
@@ -445,6 +489,7 @@ def _build_config(data: Mapping[str, Any], path: Path) -> AppConfig:
discover=discover,
classify=classify,
heat_weights=heat,
analytics=analytics,
raw=data,
)