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

160 lines
5.0 KiB
Python

from flask import Blueprint, render_template, request, send_file, jsonify
import math, time
from helpers.db import db_get_videos, db_get_video, db_get_recent
from helpers.favorites import mark_favorites, db_get_favorites, db_get_fav_set
from helpers.cache import build_cache
from config import VIDEOS_PER_PAGE, DASHBOARD_PER_PAGE
web = Blueprint("web", __name__)
from datetime import date, datetime, timedelta
def _parse_dates(timeframe: str, start_str: str | None, end_str: str | None):
"""Return (start, end) as date objects or (None, None). End inclusive by day."""
today = date.today()
if timeframe == "week":
# This week = last 7 days ending today
return (today - timedelta(days=6)), today
if timeframe == "month":
# Last 30 days
return (today - timedelta(days=29)), today
if timeframe == "year":
# Last 365 days
return (today - timedelta(days=364)), today
if timeframe == "custom":
try:
s = datetime.strptime(start_str, "%Y-%m-%d").date() if start_str else None
e = datetime.strptime(end_str, "%Y-%m-%d").date() if end_str else None
if s and e and s > e: s, e = e, s
return s, e
except ValueError:
return None, None
# "all" or unknown → no filter
return None, None
@web.route("/")
def dashboard():
# ---- read filters ----
query = request.args.get("q", "").lower().strip()
sort = request.args.get("sort", "total_size")
dir_ = request.args.get("dir", "desc")
timeframe = request.args.get("timeframe", "all")
start_str = request.args.get("start")
end_str = request.args.get("end")
reverse = (dir_ == "desc")
start, end = _parse_dates(timeframe, start_str, end_str)
# ---- build cache over timeframe ----
cache = build_cache(start=start, end=end)
items = list(cache["storage_usage"].items())
# ---- search ----
if query:
items = [e for e in items if query in e[0].split("::")[0].lower()]
# ---- sort ----
def k_user(x): return x[0].split("::")[0].lower()
def k_platform(x): return x[0].split("::")[1].lower()
def k_total(x): return x[1]["total_size"]
def k_count(x): return x[1]["video_count"]
def k_avg(x): return cache["avg_sizes"][x[0]]
key_map = {
"user": k_user,
"platform": k_platform,
"total_size": k_total,
"video_count": k_count,
"avg_size": k_avg,
}
items.sort(key=key_map.get(sort, k_total), reverse=reverse)
# ---- paginate ----
page = max(1, int(request.args.get("page", 1)))
total_pages = max(1, math.ceil(len(items) / DASHBOARD_PER_PAGE))
start_idx = (page - 1) * DASHBOARD_PER_PAGE
paginated = items[start_idx:start_idx + DASHBOARD_PER_PAGE]
return render_template(
"main.html",
storage_usage=paginated,
avg_sizes=cache["avg_sizes"],
page=page,
total_pages=total_pages,
query=query,
sort=sort,
dir=dir_,
timeframe=timeframe,
start_date=start_str,
end_date=end_str
)
@web.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"])
})
@web.route("/user/<username>")
def user_page(username):
videos = db_get_videos(username=username)
page = max(1, int(request.args.get("page", 1)))
total_pages = max(1, math.ceil(len(videos) / VIDEOS_PER_PAGE))
start = (page - 1) * VIDEOS_PER_PAGE
paginated = videos[start:start + VIDEOS_PER_PAGE]
mark_favorites(paginated)
return render_template(
"user_page.html",
username=username,
videos=paginated,
page=page,
total_pages=total_pages
)
@web.route("/video/stream/<video_id>")
def stream_video(video_id):
video = db_get_video(video_id)
if video:
return send_file(video["filepath"], mimetype="video/mp4")
return "Video not found", 404
@web.route("/video/<video_id>")
def view_video(video_id):
video = db_get_video(video_id)
if video:
video["is_favorite"] = (video["video_id"] in db_get_fav_set())
return render_template("video_view.html", video=video)
return "Video not found", 404
@web.route("/recent")
def recent():
page = max(1, int(request.args.get("page", 1)))
per_page = VIDEOS_PER_PAGE
videos, total = db_get_recent(page, per_page)
total_pages = max(1, math.ceil(total / per_page))
mark_favorites(videos)
return render_template(
"recent.html",
videos=videos,
page=page,
total_pages=total_pages
)
@web.route("/favorites")
def favorites_page():
page = max(1, int(request.args.get("page", 1)))
per_page = VIDEOS_PER_PAGE
videos, total = db_get_favorites(page, per_page)
total_pages = max(1, math.ceil(total / per_page))
mark_favorites(videos)
return render_template(
"favorites.html",
videos=videos,
page=page,
total_pages=total_pages
)