Since 2026-10-28 a signed-in read of a reel gives the placeholder title and no description, so the adapter had nothing to fall back on and every such download (and its name) read "Facebook". A placeholder with nothing behind it now gets one signed-out, metadata-only read of the page. The backfill retitles the downloads already made, and every name that only repeated the placeholder; a name its owner gave stays.
181 lines
6.2 KiB
Python
181 lines
6.2 KiB
Python
"""A Facebook download's title when the signed-in read gives only a placeholder.
|
|
|
|
Measured on prod (2026-11-01): every Facebook download since 2026-10-28 is titled "Facebook" — the
|
|
signed-in read (the owner's cookie) now gives that placeholder and NO description, so the adapter had
|
|
no post text to fall back on, and the download name copied the placeholder too. A signed-out read of
|
|
the same reel (yt-dlp 2026.08.19, as on prod) still carries the post's text in its description.
|
|
"""
|
|
|
|
from app.config import settings
|
|
from app.downloads import adapters, backfill, pipeline
|
|
from app.downloads.models import DownloadJob, MediaAsset
|
|
|
|
_URL = "https://www.facebook.com/reel/1860682468422402/"
|
|
# The measured signed-out read of that reel.
|
|
_PUBLIC = {
|
|
"title": "163K reactions · 14K shares | sorry not helping #workhumor #officelife | Work dot exe",
|
|
"description": "sorry not helping\n\n#workhumor #officelife",
|
|
"uploader": "Work dot exe",
|
|
}
|
|
|
|
|
|
def _fake_ydl(monkeypatch, outcome):
|
|
"""yt-dlp faked at its `YoutubeDL` boundary: records each read's options, answers `outcome`."""
|
|
seen: list[dict] = []
|
|
|
|
class FakeYDL:
|
|
def __init__(self, opts):
|
|
seen.append(opts)
|
|
|
|
def __enter__(self):
|
|
return self
|
|
|
|
def __exit__(self, *exc):
|
|
return False
|
|
|
|
def extract_info(self, url, download):
|
|
return outcome
|
|
|
|
monkeypatch.setattr(backfill.yt_dlp, "YoutubeDL", FakeYDL)
|
|
return seen
|
|
|
|
|
|
def test_a_placeholder_with_nothing_behind_it_takes_the_signed_out_pages_text(monkeypatch):
|
|
seen = _fake_ydl(monkeypatch, _PUBLIC)
|
|
fb = adapters.FacebookAdapter()
|
|
|
|
info = backfill.public_title_info({"title": "Facebook", "description": None}, _URL, fb, 7)
|
|
|
|
assert fb.title(info) == "sorry not helping"
|
|
# One metadata-only read, and signed out: no cookie goes with it.
|
|
assert len(seen) == 1
|
|
assert seen[0]["skip_download"] is True
|
|
assert not seen[0].get("cookiefile")
|
|
|
|
|
|
def test_a_real_title_reads_nothing_more(monkeypatch):
|
|
seen = _fake_ydl(monkeypatch, _PUBLIC)
|
|
info = {"title": "Funny Dark Humor Dad Joke!", "description": None}
|
|
|
|
assert backfill.public_title_info(info, _URL, adapters.FacebookAdapter(), 7) is info
|
|
assert seen == []
|
|
|
|
|
|
def test_a_placeholder_the_signed_out_page_cannot_better_stays(monkeypatch):
|
|
_fake_ydl(monkeypatch, {"title": "Facebook", "description": None})
|
|
fb = adapters.FacebookAdapter()
|
|
|
|
info = backfill.public_title_info({"title": "Facebook", "description": None}, _URL, fb, 7)
|
|
|
|
assert fb.title(info) == "Facebook"
|
|
|
|
|
|
def test_another_source_is_never_read_again(monkeypatch):
|
|
seen = _fake_ydl(monkeypatch, _PUBLIC)
|
|
info = {"title": "Video", "description": None}
|
|
|
|
assert backfill.public_title_info(info, _URL, adapters.SourceAdapter(), 7) is info
|
|
assert seen == []
|
|
|
|
|
|
def test_the_backfill_retitles_a_placeholder_download_and_the_names_that_repeated_it(
|
|
db, make_user, monkeypatch
|
|
):
|
|
_fake_ydl(monkeypatch, _PUBLIC)
|
|
owner, other = make_user(), make_user()
|
|
asset = MediaAsset(
|
|
source_kind="url",
|
|
source_ref=_URL,
|
|
format_sig="fb",
|
|
status="ready",
|
|
rel_path="facebook/x.mp4",
|
|
poster_path="facebook/x.jpg",
|
|
uploader_url="https://www.facebook.com/1",
|
|
title="Facebook",
|
|
ref_count=2,
|
|
)
|
|
db.add(asset)
|
|
db.flush()
|
|
copied = DownloadJob(
|
|
user_id=owner.id,
|
|
asset_id=asset.id,
|
|
source_kind="url",
|
|
source_ref=_URL,
|
|
status="done",
|
|
queue_pos=0,
|
|
profile_snapshot={},
|
|
display_name="Facebook",
|
|
)
|
|
renamed = DownloadJob(
|
|
user_id=other.id,
|
|
asset_id=asset.id,
|
|
source_kind="url",
|
|
source_ref=_URL,
|
|
status="done",
|
|
queue_pos=0,
|
|
profile_snapshot={},
|
|
display_name="Office jokes",
|
|
)
|
|
db.add_all([copied, renamed])
|
|
db.commit()
|
|
|
|
assert backfill.run()["retitled"] == 1
|
|
|
|
db.expire_all()
|
|
assert db.get(MediaAsset, asset.id).title == "sorry not helping"
|
|
assert db.get(DownloadJob, copied.id).display_name == "sorry not helping"
|
|
assert db.get(DownloadJob, renamed.id).display_name == "Office jokes"
|
|
# Run again: nothing left to retitle, and no page read for it.
|
|
assert backfill.run()["retitled"] == 0
|
|
|
|
|
|
def test_a_download_titled_facebook_is_named_from_the_signed_out_page(
|
|
db, make_user, monkeypatch, tmp_path
|
|
):
|
|
# The whole download path with yt-dlp and the media tools faked: the signed-in read gives only
|
|
# the placeholder, and the file and the download's name get the post's text.
|
|
_fake_ydl(monkeypatch, _PUBLIC)
|
|
monkeypatch.setattr(settings, "files_root", str(tmp_path))
|
|
monkeypatch.setattr(pipeline.urlguard, "check_url", lambda url: None)
|
|
monkeypatch.setattr(pipeline, "_ensure_phone_safe", lambda _j, produced, *_a: produced)
|
|
monkeypatch.setattr(
|
|
pipeline.probe, "resolve_media_facts", lambda produced, info: ("h264", "aac", 720, 1280, 9)
|
|
)
|
|
monkeypatch.setattr(pipeline.editmod, "thumbnail_to_jpg", lambda *a: None)
|
|
monkeypatch.setattr(pipeline.editmod, "ensure_poster", lambda *a: None)
|
|
owner = make_user()
|
|
asset = MediaAsset(
|
|
source_kind="url", source_ref=_URL, format_sig="fb", status="downloading", ref_count=1
|
|
)
|
|
db.add(asset)
|
|
db.flush()
|
|
job = DownloadJob(
|
|
user_id=owner.id,
|
|
asset_id=asset.id,
|
|
source_kind="url",
|
|
source_ref=_URL,
|
|
status="running",
|
|
queue_pos=0,
|
|
profile_snapshot={},
|
|
)
|
|
db.add(job)
|
|
db.commit()
|
|
|
|
def signed_in_read(job_id, asset_id, url, spec, staging, adapter, **kw):
|
|
f = staging / "1860682468422402.mp4"
|
|
f.write_bytes(b"v" * 100)
|
|
return {
|
|
"id": "1860682468422402",
|
|
"title": "Facebook",
|
|
"uploader": "Work dot exe",
|
|
"requested_downloads": [{"filepath": str(f)}],
|
|
}
|
|
|
|
monkeypatch.setattr(pipeline, "_extract_with_fallback", signed_in_read)
|
|
pipeline._download(job.id, asset.id, "url", _URL, {}, owner.id)
|
|
|
|
db.expire_all()
|
|
assert db.get(DownloadJob, job.id).status == "done"
|
|
assert db.get(MediaAsset, asset.id).title == "sorry not helping"
|
|
assert db.get(DownloadJob, job.id).display_name == "sorry not helping"
|