fix(downloads): a signed-in Facebook reel keeps its title, and an mp3 stays an mp3

Since a Facebook cookie was added on prod, every reel came down titled
"Video": measured on dev, a signed-in read gives yt-dlp the placeholder
"Video" (an 18+ reel read as Chrome gives "Facebook") while the post's text
is still in the description. A new SourceAdapter.title hook takes the whole
first line of the description in that case, and both title writes (the early
fill and the finished download) go through it, so the row, the file name and
the share preview carry the post's text again. The line is not cut with an
ellipsis: normalize_title's NFKC turns "…" into "..." and collapses it to
".", which read as a finished sentence (seen in dev UAT).

The "Audio (MP3)" profile's extracted .mp3 was remuxed into an .mp4 by the
browser-safe step (the audio spec is clamped to container mp4 too) and served
as video/mp4, which iPad's WebKit will not play (prod job 268). Audio mode now
skips that step, so an .mp3 is served as audio/mpeg and an .m4a as audio/mp4.
Audio downloads version their cache identity on their own (v5), so a cached
remuxed audio re-derives without re-downloading every cached video.
This commit is contained in:
2026-09-14 17:46:46 +02:00
parent 90523284ab
commit 6169e32ca5
6 changed files with 160 additions and 6 deletions
+26
View File
@@ -1,6 +1,7 @@
"""Per-source adapter selection + the source-specific policy each one carries. These lock the
behaviour that used to live inline in worker.build_uploader_url / backfill._should_refetch."""
from app.titles import normalize_title
from app.downloads.adapters import (
FacebookAdapter,
RedditAdapter,
@@ -139,3 +140,28 @@ def test_wants_metadata_backfill_matches_old_should_refetch():
def test_nfo_uniqueid_type_is_the_adapter_key():
assert YouTubeAdapter().nfo_uniqueid_type() == "youtube"
assert SourceAdapter().nfo_uniqueid_type() == "generic"
def test_title_is_yt_dlps_for_a_source_without_placeholders():
assert SourceAdapter().title({"title": "Video", "description": "text"}) == "Video"
assert SourceAdapter().title({}) is None
def test_facebook_placeholder_title_takes_the_posts_text():
# Measured: signed in, yt-dlp titles every reel "Video" (an 18+ reel read as Chrome: "Facebook"),
# while the post's text is still in the description.
a = FacebookAdapter()
info = {"title": "Video", "description": "\n Tune of The Day\nsecond line"}
assert a.title(info) == "Tune of The Day"
assert a.title({**info, "title": "Facebook"}) == "Tune of The Day"
# A real title (signed out) is left for normalize_title, engagement prefix and all.
assert a.title({**info, "title": "456K views | Tune"}) == "456K views | Tune"
# Nothing better on the page: keep what yt-dlp gave.
assert a.title({"title": "Facebook", "description": None}) == "Facebook"
def test_facebook_title_from_a_long_description_is_the_whole_line_after_cleaning():
# Dev UAT: a cut with "…" came out of normalize_title as "… live at." (NFKC "..." collapsed to "."),
# a sentence that seemed to end. The whole first line survives the cleaning intact instead.
line = 'Tune of The Day, Argy playing his version of the classic "Resurrection" with Paul Oakenfold live at Space'
assert normalize_title(FacebookAdapter().title({"title": "Video", "description": line})) == line