chore(downloads): C3-C6 — DRY the source-URL, filename, and serialize helpers

- C3: `_reference_url` (downloads.py) and public.py's inline source-URL block were
  the same rule → extract `service.reference_url(job, asset)`; both surfaces now
  share it so the "downloaded from" link can't drift between them.
- C4: Content-Disposition filename derivation (ext pick + doubled-ext strip + join)
  was duplicated in download_file and watch_file → extract
  `storage.download_filename(display_name, container, path)`.
- C5: inline the one-line `_clean_basename` passthrough (folded into C4).
- C6: the `db.get(MediaAsset, job.asset_id) if job.asset_id else None; _serialize(...)`
  resolve-then-serialize dance was repeated across 6 single-job handlers → fold into
  `_serialize_job(db, job)`. (File-serving handlers that use the asset for their own
  checks keep their explicit resolve.)

Behavior-neutral; ruff/parse clean, localdev boots, downloads routes load.
This commit is contained in:
npeter83 2026-07-11 05:47:51 +02:00
parent 2a44db04d8
commit cac5526399
5 changed files with 44 additions and 49 deletions

View file

@ -32,6 +32,20 @@ def source_url(source_kind: str, source_ref: str) -> str:
return source_ref
def reference_url(job, asset) -> str | None:
"""The clean "downloaded from" URL for a job — shared by the private Downloads page and the public
watch page so both surfaces always agree. None for edit derivatives (a clip's source is the user's
own earlier download, not a web page); else the canonical page URL yt-dlp recorded; else one derived
from source_kind+source_ref (covers queued/older rows before the worker fills it)."""
if job is None or job.job_kind == "edit":
return None
if asset is not None and asset.source_webpage_url:
return asset.source_webpage_url
if job.source_kind in ("youtube", "url"):
return source_url(job.source_kind, job.source_ref)
return None
def get_or_create_asset(
db: Session, source_kind: str, source_ref: str, format_sig: str
) -> MediaAsset: