35 lines
2.4 KiB
Python
35 lines
2.4 KiB
Python
"""Authenticated per-video download acknowledgements. No bulk deletion endpoint."""
|
|
import json,re,sqlite3,time
|
|
from contextlib import closing
|
|
from fastapi import Depends,HTTPException
|
|
|
|
def install_video_cleanup(app,auth,db_path):
|
|
with closing(sqlite3.connect(db_path)) as db,db:
|
|
db.execute('''CREATE TABLE IF NOT EXISTS video_cleanup_acks (
|
|
id TEXT PRIMARY KEY, output_index INTEGER NOT NULL, sha256 TEXT NOT NULL,
|
|
bytes INTEGER NOT NULL, status TEXT NOT NULL DEFAULT 'pending',
|
|
manifest TEXT, attempts INTEGER NOT NULL DEFAULT 0, next_attempt REAL NOT NULL DEFAULT 0,
|
|
error TEXT, created REAL NOT NULL, updated REAL NOT NULL)''')
|
|
|
|
@app.post('/v2/video_generation/{jid}/cleanup',dependencies=[Depends(auth)])
|
|
async def acknowledge_video(jid:str,body:dict):
|
|
if set(body)!={'version','index','sha256','bytes'} or type(body.get('version')) is not int or body['version']!=1:
|
|
raise HTTPException(400,'Invalid download acknowledgement')
|
|
if type(body.get('index')) is not int or not 0<=body['index']<=64:
|
|
raise HTTPException(400,'Invalid video output index')
|
|
if type(body.get('bytes')) is not int or not 0<body['bytes']<=512*1024*1024 or not re.fullmatch('[0-9a-f]{64}',str(body.get('sha256',''))):
|
|
raise HTTPException(400,'Invalid video checksum receipt')
|
|
with closing(sqlite3.connect(db_path)) as db,db:
|
|
db.row_factory=sqlite3.Row
|
|
if not db.execute('SELECT 1 FROM jobs WHERE id=?',(jid,)).fetchone():
|
|
raise HTTPException(404,'Unknown bridge video task')
|
|
existing=db.execute('SELECT * FROM video_cleanup_acks WHERE id=?',(jid,)).fetchone()
|
|
if existing and (existing['output_index'],existing['sha256'],existing['bytes'])!=(body['index'],body['sha256'],body['bytes']):
|
|
raise HTTPException(409,'A different receipt already exists for this video')
|
|
if not existing:
|
|
ts=time.time()
|
|
db.execute('INSERT INTO video_cleanup_acks(id,output_index,sha256,bytes,created,updated) VALUES(?,?,?,?,?,?)',(jid,body['index'],body['sha256'],body['bytes'],ts,ts))
|
|
row=db.execute('SELECT * FROM video_cleanup_acks WHERE id=?',(jid,)).fetchone()
|
|
return {'status':'cleaned' if row['status']=='cleaned' else 'pending','index':row['output_index'],
|
|
'sha256':row['sha256'],'bytes':row['bytes'],'retrying':bool(row['error'])}
|