Fix review findings and remove Uncategorized from sidebar
Backend: cache Google access tokens (drop dead access_token_expires_at, migration 0007), handle MeTube cleared/canceled events by URL, return email from /auth/status only when authenticated, move Google base URLs into settings, run container as non-root. Frontend: include local feed filters in the query key, remove dead Saved page and unused assets, drop stale CategoryNav props and classes, send Content-Type only with a body, remove Uncategorized from sidebar.
This commit is contained in:
parent
6c704cac97
commit
fde9a439df
25 changed files with 420 additions and 174 deletions
|
|
@ -117,6 +117,26 @@ def _find_job_by_payload(db: Session, payload: dict) -> DownloadJob | None:
|
|||
return None
|
||||
|
||||
|
||||
def _find_job_by_key(db: Session, key: str) -> DownloadJob | None:
|
||||
"""Match a bare MeTube store key (its 'canceled'/'cleared' events carry
|
||||
just one key, JSON-string-encoded) to our latest job for it. The key is
|
||||
the URL the download was enqueued under; matching the metube job id first
|
||||
keeps us tolerant of both shapes."""
|
||||
job = (
|
||||
db.query(DownloadJob)
|
||||
.filter(DownloadJob.metube_job_id == key)
|
||||
.order_by(DownloadJob.id.desc())
|
||||
.first()
|
||||
)
|
||||
if job is not None:
|
||||
return job
|
||||
|
||||
video = db.query(Video).filter(Video.youtube_url == key).one_or_none()
|
||||
if video is not None:
|
||||
return get_latest_job(db, video.id)
|
||||
return None
|
||||
|
||||
|
||||
async def handle_metube_event(db: Session, event_name: str, raw_payload) -> None:
|
||||
try:
|
||||
payload = json.loads(raw_payload) if isinstance(raw_payload, str) else raw_payload
|
||||
|
|
@ -124,21 +144,34 @@ async def handle_metube_event(db: Session, event_name: str, raw_payload) -> None
|
|||
logger.warning("Could not parse MeTube event payload for %s: %r", event_name, raw_payload)
|
||||
return
|
||||
|
||||
if event_name in ("canceled", "cleared"):
|
||||
if event_name == "canceled":
|
||||
if not isinstance(payload, str):
|
||||
return
|
||||
job = (
|
||||
db.query(DownloadJob)
|
||||
.filter(DownloadJob.metube_job_id == payload)
|
||||
.order_by(DownloadJob.id.desc())
|
||||
.first()
|
||||
)
|
||||
if job is not None and event_name == "canceled" and job.status in ACTIVE_STATUSES:
|
||||
job = _find_job_by_key(db, payload)
|
||||
if job is not None and job.status in ACTIVE_STATUSES:
|
||||
job.status = "failed"
|
||||
job.error_message = "Отменено в MeTube"
|
||||
db.commit()
|
||||
return
|
||||
|
||||
if event_name == "cleared":
|
||||
# MeTube emits 'cleared' ONLY when a *done* entry is deleted (trash
|
||||
# via /delete?where=done, or CLEAR_COMPLETED_AFTER): the payload is
|
||||
# that entry's key (its URL) as a JSON string, one event per item.
|
||||
# Clearing the queue emits 'canceled' instead. The removed entry is
|
||||
# usually a download MeTube had before we existed (AGENTS.md rule 10)
|
||||
# or one we already completed, so an unmatched/empty payload must not
|
||||
# touch anything: failing all active jobs here would wrongly mark
|
||||
# downloads MeTube is still running.
|
||||
if not isinstance(payload, str) or not payload:
|
||||
return
|
||||
job = _find_job_by_key(db, payload)
|
||||
if job is not None and job.status in ACTIVE_STATUSES:
|
||||
job.status = "failed"
|
||||
job.error_message = "Очищено в MeTube"
|
||||
db.commit()
|
||||
return
|
||||
|
||||
if not isinstance(payload, dict):
|
||||
return
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue