update attempt

main
oscar 3 months ago
parent 61e6079372
commit 7580320366

@ -1,20 +1,17 @@
# app.py DB-powered version # app.py DB-powered version
import os, time, json, zlib, math, hashlib, subprocess import os, time, json, zlib, math, hashlib, subprocess
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
from datetime import datetime import psycopg2.extras
from flask import ( from flask import (
Flask, render_template, request, jsonify, send_file Flask, render_template, request, jsonify, send_file
) )
from config import connect_redis, get_local_db_connection from config import get_local_db_connection
# ───────── CONFIG ───────── # # ───────── CONFIG ───────── #
app = Flask(__name__) app = Flask(__name__)
redis = connect_redis()
CACHE_KEY = "video_cache_v3" # bumped because source changed
META_HASH = "video_meta_v3"
THUMB_DIR = "static/thumbnails" THUMB_DIR = "static/thumbnails"
VIDEOS_PER_PAGE = 40 VIDEOS_PER_PAGE = 40
DASHBOARD_PER_PAGE = 100 DASHBOARD_PER_PAGE = 100
@ -24,25 +21,19 @@ FF_QUALITY = "80"
os.makedirs(THUMB_DIR, exist_ok=True) os.makedirs(THUMB_DIR, exist_ok=True)
# ───────── DB HELPER ───────── # # ───────── DB HELPER ───────── #
def db_get_videos(): def db_get_videos():
"""Return list of dicts exactly like the old parser produced."""
conn, cur = get_local_db_connection() conn, cur = get_local_db_connection()
cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
cur.execute(""" cur.execute("""
SELECT SELECT
video_id, username, site AS platform, video_id, username, site AS platform,
filepath, size_mb AS size, filepath, size, duration, gender, created_at, updated_at
duration,
gender,
created_at,
updated_at
FROM videos FROM videos
""") """)
rows = cur.fetchall() rows = cur.fetchall()
# Convert psycopg rows → list[dict]
cols = [desc[0] for desc in cur.description]
videos = [dict(zip(cols, row)) for row in rows]
cur.close(); conn.close() cur.close(); conn.close()
return videos return [dict(r) for r in rows]
# ───────── THUMB UTILS ───────── # # ───────── THUMB UTILS ───────── #
def _hashed_thumb_path(video_id: str): def _hashed_thumb_path(video_id: str):
@ -65,11 +56,8 @@ def _gen_thumb_cmd(src: str, dest: str):
def generate_thumbnail(task): def generate_thumbnail(task):
src, dest = task src, dest = task
if not os.path.exists(dest): if not os.path.exists(dest):
subprocess.run(_gen_thumb_cmd(src, dest), subprocess.run(_gen_thumb_cmd(src, dest), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
# ───────── CACHE BUILDER ───────── #
def build_cache(): def build_cache():
videos = db_get_videos() videos = db_get_videos()
@ -84,7 +72,14 @@ def build_cache():
for (username, platform), vids in grouped.items(): for (username, platform), vids in grouped.items():
key = f"{username}::{platform}" key = f"{username}::{platform}"
total_gb = sum(v["size"] for v in vids) / 1024 total_gb = 0
for v in vids:
try:
size_mb = float(v.get("size", 0) or 0)
except ValueError:
print(f"⚠️ Invalid size for video {v.get('video_id')}: {v.get('size')}")
size_mb = 0
total_gb += size_mb / 1024
storage_usage[key] = { storage_usage[key] = {
"total_size": total_gb, "total_size": total_gb,
"video_count": len(vids) "video_count": len(vids)
@ -95,13 +90,9 @@ def build_cache():
video_id = v["video_id"] video_id = v["video_id"]
thumb_path = _hashed_thumb_path(video_id) thumb_path = _hashed_thumb_path(video_id)
# Meta-cache use DB updated_at as mtime surrogate if not os.path.exists(thumb_path):
meta = redis.hget(META_HASH, video_id)
if not meta or json.loads(meta)["updated_at"] != str(v["updated_at"]):
thumb_tasks.append((v["filepath"], thumb_path)) thumb_tasks.append((v["filepath"], thumb_path))
redis.hset(META_HASH, video_id,
json.dumps({"updated_at": str(v["updated_at"]),
"thumb" : thumb_path}))
v["thumbnail"] = thumb_path v["thumbnail"] = thumb_path
video_map[key] = vids video_map[key] = vids
@ -110,33 +101,17 @@ def build_cache():
with ThreadPoolExecutor(max_workers=os.cpu_count()*2) as exe: with ThreadPoolExecutor(max_workers=os.cpu_count()*2) as exe:
list(exe.map(generate_thumbnail, thumb_tasks)) list(exe.map(generate_thumbnail, thumb_tasks))
cache = { return {
"timestamp" : time.time(), "timestamp" : time.time(),
"videos" : video_map, "videos" : video_map,
"storage_usage" : storage_usage, "storage_usage" : storage_usage,
"avg_sizes" : avg_sizes "avg_sizes" : avg_sizes
} }
blob = zlib.compress(json.dumps(cache).encode())
redis.set(CACHE_KEY, blob)
with open("video_cache.json.gz", "wb") as f:
f.write(blob)
return cache
def get_cached_data():
blob = redis.get(CACHE_KEY)
if blob:
return json.loads(zlib.decompress(blob).decode())
if os.path.exists("video_cache.json.gz"):
with open("video_cache.json.gz", "rb") as f:
return json.loads(zlib.decompress(f.read()).decode())
return build_cache()
# ───────── ROUTES (unchanged logic) ───────── # # ───────── ROUTES (unchanged logic) ───────── #
@app.route("/") @app.route("/")
def dashboard(): def dashboard():
cache = get_cached_data() cache = build_cache()
query = request.args.get("q", "").lower().strip() query = request.args.get("q", "").lower().strip()
sorted_usage = sorted( sorted_usage = sorted(
@ -172,7 +147,7 @@ def refresh():
@app.route("/user/<username>") @app.route("/user/<username>")
def user_page(username): def user_page(username):
cache = get_cached_data() cache = build_cache()
videos = [ videos = [
v | {"platform": key.split("::")[1]} v | {"platform": key.split("::")[1]}
@ -196,7 +171,7 @@ def user_page(username):
@app.route("/video/stream/<video_id>") @app.route("/video/stream/<video_id>")
def stream_video(video_id): def stream_video(video_id):
cache = get_cached_data() cache = build_cache()
for vids in cache["videos"].values(): for vids in cache["videos"].values():
for v in vids: for v in vids:
if v["video_id"] == video_id: if v["video_id"] == video_id:
@ -205,7 +180,7 @@ def stream_video(video_id):
@app.route("/video/<video_id>") @app.route("/video/<video_id>")
def view_video(video_id): def view_video(video_id):
cache = get_cached_data() cache = build_cache()
for vids in cache["videos"].values(): for vids in cache["videos"].values():
for v in vids: for v in vids:
if v["video_id"] == video_id: if v["video_id"] == video_id:
@ -213,4 +188,4 @@ def view_video(video_id):
return "Video not found", 404 return "Video not found", 404
if __name__ == "__main__": if __name__ == "__main__":
app.run(debug=True) app.run(debug=True)
Loading…
Cancel
Save