feat(downloads): edit + remove actions on shared-with-me items (no re-share)
A shared-with-me item only had a download button. Add two actions (Share is intentionally NOT
offered — no chain re-sharing of someone else's file):
- Edit: the editor now accepts an accessible (owned OR shared) source, so editing a shared video
produces the editor's OWN clip in their library (counts against their quota, fully theirs
including share); the source file is only read. Route uses _accessible_job.
- Remove from my list: DELETE /api/downloads/shared/{job_id} deletes only the recipient's share
grant — the owner's job and physical file are untouched (per-user dismissal).
i18n en/hu/de. Verified in a real browser (edit a shared 70-min video → own 2:31 clip; remove
confirm shows 'won't delete the owner's file').
This commit is contained in:
parent
b7f365dd5a
commit
1e3fad9a8f
6 changed files with 66 additions and 8 deletions
|
|
@ -258,8 +258,12 @@ def enqueue_download(
|
|||
def enqueue_edit(
|
||||
payload: dict, user: User = Depends(require_human), db: Session = Depends(get_db)
|
||||
) -> dict:
|
||||
"""Queue a phase-2 editor derivative (trim/crop) of one of the user's finished downloads."""
|
||||
source_job = _own_job(db, user, int(payload.get("source_job_id") or 0))
|
||||
"""Queue a phase-2 editor derivative (trim/crop) of a download this user can access.
|
||||
|
||||
The source may be the user's own download OR one shared with them — either way the resulting
|
||||
clip is a NEW per-user derivative in the editor's own library (counts against their quota); the
|
||||
source file is only read, never modified, so editing a shared video is safe."""
|
||||
source_job = _accessible_job(db, user, int(payload.get("source_job_id") or 0))
|
||||
if source_job.status != "done" or source_job.asset_id is None:
|
||||
raise HTTPException(status_code=409, detail="You can only edit a finished download.")
|
||||
spec = payload.get("edit_spec")
|
||||
|
|
@ -619,6 +623,24 @@ def unshare_download(
|
|||
return {"ok": True}
|
||||
|
||||
|
||||
@router.delete("/shared/{job_id}")
|
||||
def remove_shared_with_me(
|
||||
job_id: int, user: User = Depends(require_human), db: Session = Depends(get_db)
|
||||
) -> dict:
|
||||
"""Remove a download that was shared WITH this user from their 'Shared with me' list. Deletes
|
||||
only the recipient's share grant — the owner's job and the physical file are untouched (this is
|
||||
a per-user dismissal, not a delete)."""
|
||||
row = db.execute(
|
||||
select(DownloadShare).where(
|
||||
DownloadShare.job_id == job_id, DownloadShare.to_user_id == user.id
|
||||
)
|
||||
).scalar_one_or_none()
|
||||
if row is not None:
|
||||
db.delete(row)
|
||||
db.commit()
|
||||
return {"removed": job_id}
|
||||
|
||||
|
||||
# --- recipients (for the internal "share with a user" picker) ------------------------------
|
||||
|
||||
@router.get("/recipients")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue