000x's picture
Upload 13 files
78c8669 verified
Raw History Blame Contribute Delete
3.73 kB
"""
SQLite storage for tasks and settings.
The DB file lives at DATA_DIR/uploader.db so it persists across
requests in the same running container.
DATA_DIR defaults to a "data" folder next to this file, which is
writable in an ordinary Docker container. If you attach a persistent
storage volume on Hugging Face, set the DATA_DIR env var / secret to
its mount path (e.g. /data) so the database survives a Space rebuild.
"""
import sqlite3
import os
import time
from contextlib import contextmanager
_DEFAULT_DATA_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data")
DATA_DIR = os.environ.get("DATA_DIR") or _DEFAULT_DATA_DIR
try:
os.makedirs(DATA_DIR, exist_ok=True)
except PermissionError:
DATA_DIR = "/tmp/fb-uploader-data"
os.makedirs(DATA_DIR, exist_ok=True)
DB_PATH = os.path.join(DATA_DIR, "uploader.db")
SCHEMA = """
CREATE TABLE IF NOT EXISTS tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
video_url TEXT NOT NULL,
title TEXT NOT NULL,
description TEXT,
privacy TEXT NOT NULL DEFAULT 'SELF',
status TEXT NOT NULL DEFAULT 'pending',
video_id TEXT,
cdn_url TEXT,
error_message TEXT,
attempts INTEGER NOT NULL DEFAULT 0,
created_at REAL NOT NULL,
updated_at REAL NOT NULL
);
CREATE TABLE IF NOT EXISTS settings (
key TEXT PRIMARY KEY,
value TEXT
);
"""
# status values: pending -> uploading -> processing -> completed
# any of the above -> failed
@contextmanager
def get_conn():
conn = sqlite3.connect(DB_PATH, timeout=30)
conn.row_factory = sqlite3.Row
conn.execute("PRAGMA journal_mode=WAL;")
try:
yield conn
conn.commit()
finally:
conn.close()
def init_db():
with get_conn() as conn:
conn.executescript(SCHEMA)
# ---------- settings ----------
def set_setting(key: str, value: str):
with get_conn() as conn:
conn.execute(
"INSERT INTO settings (key, value) VALUES (?, ?) "
"ON CONFLICT(key) DO UPDATE SET value=excluded.value",
(key, value),
)
def get_setting(key: str, default=None):
with get_conn() as conn:
row = conn.execute("SELECT value FROM settings WHERE key=?", (key,)).fetchone()
return row["value"] if row else default
# ---------- tasks ----------
def create_task(video_url: str, title: str, description: str, privacy: str = "SELF") -> int:
now = time.time()
with get_conn() as conn:
cur = conn.execute(
"INSERT INTO tasks (video_url, title, description, privacy, status, "
"created_at, updated_at) VALUES (?, ?, ?, ?, 'pending', ?, ?)",
(video_url, title, description, privacy, now, now),
)
return cur.lastrowid
def list_tasks():
with get_conn() as conn:
rows = conn.execute("SELECT * FROM tasks ORDER BY id DESC").fetchall()
return [dict(r) for r in rows]
def get_task(task_id: int):
with get_conn() as conn:
row = conn.execute("SELECT * FROM tasks WHERE id=?", (task_id,)).fetchone()
return dict(row) if row else None
def get_tasks_by_status(status: str):
with get_conn() as conn:
rows = conn.execute("SELECT * FROM tasks WHERE status=?", (status,)).fetchall()
return [dict(r) for r in rows]
def update_task(task_id: int, **fields):
if not fields:
return
fields["updated_at"] = time.time()
cols = ", ".join(f"{k}=?" for k in fields)
values = list(fields.values()) + [task_id]
with get_conn() as conn:
conn.execute(f"UPDATE tasks SET {cols} WHERE id=?", values)
def delete_task(task_id: int):
with get_conn() as conn:
conn.execute("DELETE FROM tasks WHERE id=?", (task_id,))