otb-cloud secure encrypted backups
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

144 lines
3.9 KiB

from app.db import get_db
from pathlib import Path
def get_tenant_row(db, tenant):
cur = db.cursor()
cur.execute(
"SELECT id, storage_root FROM tenants WHERE slug = %s LIMIT 1",
(tenant,)
)
row = cur.fetchone()
if not row:
return None
return row
def get_device_row(db, device_id):
cur = db.cursor()
cur.execute(
"SELECT id, device_name, relative_path FROM devices WHERE id = %s LIMIT 1",
(device_id,)
)
row = cur.fetchone()
if not row:
return None
return row
def resolve_source_relative_path(storage_root, device_relative_path, input_filename):
base = Path(storage_root) / device_relative_path
if not base.exists():
raise FileNotFoundError(f"Device base path not found: {base}")
candidates = []
for p in base.rglob("*"):
if not p.is_file():
continue
name = p.name
if name == input_filename or name.endswith("__" + input_filename):
candidates.append(p)
if not candidates:
raise FileNotFoundError(
f"Could not locate source file for {input_filename} under {base}"
)
candidates.sort(key=lambda p: p.stat().st_mtime, reverse=True)
chosen = candidates[0]
rel = chosen.relative_to(Path(storage_root))
return str(rel)
def create_video_job(tenant, device_id, input_filename, profile="default"):
db = get_db()
tenant_row = get_tenant_row(db, tenant)
if not tenant_row:
raise Exception(f"Tenant not found: {tenant}")
device_row = get_device_row(db, device_id)
if not device_row:
raise Exception(f"Device not found: {device_id}")
tenant_id = tenant_row["id"]
storage_root = tenant_row["storage_root"]
device_relative_path = device_row["relative_path"]
source_relative_path = resolve_source_relative_path(
storage_root,
device_relative_path,
input_filename
)
cur = db.cursor()
cur.execute(
"""
INSERT INTO video_jobs (
tenant_id,
device_id,
source_file_id,
source_relative_path,
source_original_filename,
requested_profile,
requested_gpu_preference,
status,
progress_percent
) VALUES (%s, %s, NULL, %s, %s, %s, 'auto', 'queued', 0)
""",
(tenant_id, device_id, source_relative_path, input_filename, profile)
)
db.commit()
return cur.lastrowid
def list_jobs_for_tenant(tenant):
db = get_db()
tenant_row = get_tenant_row(db, tenant)
if not tenant_row:
return []
tenant_id = tenant_row["id"]
cur = db.cursor()
cur.execute(
"""
SELECT
id,
device_id,
source_original_filename,
requested_profile,
status,
progress_percent,
assigned_processor,
output_relative_path,
error_message,
created_at,
started_at,
completed_at
FROM video_jobs
WHERE tenant_id = %s
ORDER BY id DESC
LIMIT 100
""",
(tenant_id,)
)
rows = cur.fetchall()
out = []
for r in rows:
out.append({
"id": r["id"],
"device_id": r["device_id"],
"filename": r["source_original_filename"],
"profile": r["requested_profile"],
"status": r["status"],
"progress_percent": r["progress_percent"],
"assigned_processor": r["assigned_processor"],
"output_relative_path": r["output_relative_path"],
"error_message": r["error_message"],
"created_at": str(r["created_at"]) if r["created_at"] is not None else None,
"started_at": str(r["started_at"]) if r["started_at"] is not None else None,
"completed_at": str(r["completed_at"]) if r["completed_at"] is not None else None,
})
return out