fix(downloads): a converted upload too big says so, and a suspended owner's waiting rebuild is not "preparing"

- A converted upload over the space left (not zero) fails with CONVERTED_TOO_BIG_MESSAGE, not
  "storage is full"; it classifies as quota_exceeded by the phrase it shares with the clip's.
- The public watch page says "preparing" only for a job a worker will take: a suspended owner's
  queued job waits for as long as the suspension lasts, so the link says the video is gone, as
  for a paused rebuild.
- The worker's claim docstring names the restart case: a running job put back in the queue waits.
This commit is contained in:
2026-10-10 21:29:55 +02:00
parent c27cfdcb9c
commit 89d18b46a6
6 changed files with 57 additions and 8 deletions
+13 -2
View File
@@ -17,7 +17,7 @@ from app.db import get_db
from app.downloads import links as linksmod
from app.downloads import storage
from app.downloads.status import JobStatus
from app.models import DownloadJob, DownloadLink, MediaAsset
from app.models import DownloadJob, DownloadLink, MediaAsset, User
from app.ratelimit import RateLimiter, client_key
from app.security import verify_password
from app.refusal import refused
@@ -44,6 +44,17 @@ def _link_or_404(db: Session, token: str) -> DownloadLink:
return link
def _being_made(db: Session, job: DownloadJob) -> bool:
"""The job is running, or queued for a worker that will take it: the worker leaves a suspended
owner's queued jobs where they are (`worker._claim_job`), as long as the suspension lasts."""
if job.status == JobStatus.RUNNING:
return True
if job.status != JobStatus.QUEUED:
return False
owner = db.get(User, job.user_id)
return owner is not None and not owner.is_suspended
def _ready_target(db: Session, link: DownloadLink) -> tuple[DownloadJob, MediaAsset]:
job = db.get(DownloadJob, link.job_id)
asset = db.get(MediaAsset, job.asset_id) if job and job.asset_id else None
@@ -51,7 +62,7 @@ def _ready_target(db: Session, link: DownloadLink) -> tuple[DownloadJob, MediaAs
job is not None
and asset is not None
and asset.status in ("pending", "downloading")
and job.status in (JobStatus.QUEUED, JobStatus.RUNNING)
and _being_made(db, job)
):
# Being (re)made — a re-download, or a conversion — so the link works again once it is ready:
# its own reason, so the page can say "try again shortly" rather than "this link is gone".