reworked version by chatgpt

main
oscar 3 months ago
parent 7580320366
commit ea7d8a4635

@ -1,12 +1,8 @@
# app.py DB-powered version
import os, time, json, zlib, math, hashlib, subprocess
# app.py — Streamaster, DB-Only, Clean
import os, time, json, math, hashlib, subprocess
from concurrent.futures import ThreadPoolExecutor
import psycopg2.extras
from flask import (
Flask, render_template, request, jsonify, send_file
)
from flask import Flask, render_template, request, jsonify, send_file
from config import get_local_db_connection
# ───────── CONFIG ───────── #
@ -21,21 +17,21 @@ FF_QUALITY = "80"
os.makedirs(THUMB_DIR, exist_ok=True)
# ───────── DB HELPER ───────── #
def db_get_videos():
conn, cur = get_local_db_connection()
cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
cur.execute("""
SELECT
video_id, username, site AS platform,
filepath, size, duration, gender, created_at, updated_at
filepath, size, duration, gender,
created_at, updated_at
FROM videos
""")
rows = cur.fetchall()
cur.close(); conn.close()
return [dict(r) for r in rows]
# ───────── THUMB UTILS ───────── #
# ───────── THUMBNAIL HELPERS ───────── #
def _hashed_thumb_path(video_id: str):
h = hashlib.md5(video_id.encode()).hexdigest()
sub1, sub2 = h[:2], h[2:4]
@ -53,62 +49,60 @@ def _gen_thumb_cmd(src: str, dest: str):
dest
]
def generate_thumbnail(task):
src, dest = task
if not os.path.exists(dest):
subprocess.run(_gen_thumb_cmd(src, dest), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
def generate_thumbnails_for_videos(videos):
tasks = []
for v in videos:
video_id = v["video_id"]
thumb_path = _hashed_thumb_path(video_id)
if not os.path.exists(thumb_path):
tasks.append((v["filepath"], thumb_path))
v["thumbnail"] = thumb_path
if tasks:
with ThreadPoolExecutor(max_workers=os.cpu_count() * 2) as exe:
list(exe.map(lambda t: subprocess.run(_gen_thumb_cmd(*t), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL), tasks))
# ───────── CACHE BUILDER ───────── #
def build_cache():
videos = db_get_videos()
# group by (username, platform)
grouped = {}
for v in videos:
key = (v["username"], v["platform"])
grouped.setdefault(key, []).append(v)
storage_usage, avg_sizes, video_map = {}, {}, {}
thumb_tasks = []
for (username, platform), vids in grouped.items():
key = f"{username}::{platform}"
total_gb = 0
for v in vids:
try:
size_mb = float(v.get("size", 0) or 0)
total_gb += float(v.get("size", 0) or 0) / 1024
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] = {
"total_size": total_gb,
"video_count": len(vids)
}
avg_sizes[key] = total_gb / len(vids) if vids else 0
for v in vids:
video_id = v["video_id"]
thumb_path = _hashed_thumb_path(video_id)
if not os.path.exists(thumb_path):
thumb_tasks.append((v["filepath"], thumb_path))
v["thumbnail"] = thumb_path
video_map[key] = vids
if thumb_tasks:
with ThreadPoolExecutor(max_workers=os.cpu_count()*2) as exe:
list(exe.map(generate_thumbnail, thumb_tasks))
generate_thumbnails_for_videos(videos)
return {
"timestamp" : time.time(),
"videos" : video_map,
"storage_usage" : storage_usage,
"avg_sizes" : avg_sizes
"timestamp": time.time(),
"videos": video_map,
"storage_usage": storage_usage,
"avg_sizes": avg_sizes
}
# ───────── ROUTES (unchanged logic) ───────── #
# ───────── ROUTES ───────── #
@app.route("/")
def dashboard():
cache = build_cache()
@ -129,26 +123,25 @@ def dashboard():
return render_template(
"analytics.html",
storage_usage = paginated,
avg_sizes = cache["avg_sizes"],
page = page,
total_pages = total_pages,
query = query
storage_usage=paginated,
avg_sizes=cache["avg_sizes"],
page=page,
total_pages=total_pages,
query=query
)
@app.route("/refresh")
def refresh():
cache = build_cache()
return jsonify({
"status" : "ok",
"videos" : sum(x["video_count"] for x in cache["storage_usage"].values()),
"updated" : time.ctime(cache["timestamp"])
"status": "ok",
"videos": sum(x["video_count"] for x in cache["storage_usage"].values()),
"updated": time.ctime(cache["timestamp"])
})
@app.route("/user/<username>")
def user_page(username):
cache = build_cache()
videos = [
v | {"platform": key.split("::")[1]}
for key, vids in cache["videos"].items()
@ -163,10 +156,10 @@ def user_page(username):
return render_template(
"user_page.html",
username = username,
videos = paginated,
page = page,
total_pages = total_pages
username=username,
videos=paginated,
page=page,
total_pages=total_pages
)
@app.route("/video/stream/<video_id>")

Loading…
Cancel
Save