feat: M3 — automatic channel tagging (language + topic system tags)

- Tag and ChannelTag models + migration 0003 (partial unique indexes split
  system vs per-user tag names)
- Offline language detection (py3langid) constrained to a curated language set,
  with the channel's declared default language as a strong prior
- Topic tags mapped from YouTube topicDetails + dominant video category; the
  generic "Lifestyle" catch-all is intentionally dropped
- System (auto) tags are regenerated idempotently and never touch user tags;
  orphaned system tags are cleaned up
- GET /api/tags and admin POST /api/tags/recompute; scheduled autotag job
This commit is contained in:
npeter83 2026-06-11 01:57:19 +02:00
parent 64b18b3cc1
commit 68dad91e8a
9 changed files with 482 additions and 1 deletions

View file

@ -48,6 +48,14 @@ class Settings(BaseSettings):
# interactive syncs / enrichment of fresh videos.
backfill_quota_reserve: int = 2000
# --- Auto-tagging / feed defaults ---
# Number of recent video titles sampled per channel for language detection.
autotag_title_sample: int = 40
autotag_interval_minutes: int = 30
# live_status values hidden from the feed by default. Completed-stream VODs
# ("was_live") are real watchable content and stay visible.
feed_default_hidden_live: str = "live,upcoming"
@property
def allowed_email_set(self) -> set[str]:
return {e.strip().lower() for e in self.allowed_emails.split(",") if e.strip()}