feat(titles): normalize video titles for display (feed, search, downloads)
Noisy YouTube titles are cleaned for display + storage, raw kept in videos.original_title: - app/titles.normalize_title: strip emoji/symbols (keep accents), remove trailing SEO hashtag clusters (keep numeric #3 episode markers), context-aware de-shout (mostly-ALL-CAPS titles -> Title Case with an acronym whitelist + function-word lowercasing; otherwise only long all-caps words), collapse repeated punctuation - applied at enrichment (sync/videos.py) and in the download worker (ad-hoc yt-dlp titles); catalog downloads inherit the normalized title automatically - migration 0039: add original_title, preserve raw, rewrite title (generated search_vector regenerates); reversible via original_title Backfill on localdev: 122115/273417 titles normalized in ~2 min. Verified in the feed + on real messy samples (emoji/de-shout/hashtags), accents + acronyms (PS5/AI/USA/PC) preserved.
This commit is contained in:
parent
b200f61642
commit
d55799cbc1
5 changed files with 140 additions and 4 deletions
|
|
@ -11,6 +11,7 @@ from sqlalchemy.orm import Session
|
|||
|
||||
from app import progress, sysconfig
|
||||
from app.models import Channel, Video
|
||||
from app.titles import normalize_title
|
||||
from app.youtube.client import YouTubeClient, best_thumbnail
|
||||
from app.youtube.rss import fetch_channel_feed
|
||||
from app.youtube.shorts import make_client, probe_is_short
|
||||
|
|
@ -225,7 +226,11 @@ def apply_video_details(video: Video, item: dict) -> None:
|
|||
live = item.get("liveStreamingDetails")
|
||||
status = item.get("status", {})
|
||||
|
||||
video.title = snippet.get("title") or video.title
|
||||
raw_title = snippet.get("title")
|
||||
if raw_title:
|
||||
# Store the raw title and a normalized one for display (feed/search/downloads).
|
||||
video.original_title = raw_title
|
||||
video.title = normalize_title(raw_title)
|
||||
video.description = snippet.get("description")
|
||||
if not video.published_at:
|
||||
video.published_at = parse_dt(snippet.get("publishedAt"))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue