From f2de819f5829b2c73f012911e8e87abf1ea66635 Mon Sep 17 00:00:00 2001 From: oscar <> Date: Thu, 16 Oct 2025 15:16:24 +0300 Subject: [PATCH] added favorite streamers feature --- helpers/favorites.py | 9 ++++++++- routes/api.py | 15 +++++++++++++++ routes/web.py | 5 ++++- static/styles.css | 10 ++++++++++ templates/main.html | 42 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 79 insertions(+), 2 deletions(-) diff --git a/helpers/favorites.py b/helpers/favorites.py index b85b4fb..df1f0aa 100644 --- a/helpers/favorites.py +++ b/helpers/favorites.py @@ -70,4 +70,11 @@ def db_get_favorites(page: int, per_page: int): total = cur.fetchone()[0] cur.close(); conn.close() - return rows, total \ No newline at end of file + return rows, total + +def db_get_favorite_users(): + conn, cur = get_local_db_connection() + cur.execute("SELECT username FROM favorite_users") + favorite_users = [r['username'] for r in cur.fetchall()] + cur.close(); conn.close() + return favorite_users \ No newline at end of file diff --git a/routes/api.py b/routes/api.py index e2ebeac..a40d4f0 100644 --- a/routes/api.py +++ b/routes/api.py @@ -91,3 +91,18 @@ def get_online(): for s in streamers: s["is_online"] = (s.get("status") == "Channel online") return jsonify(streamers) + +@api.route("/api/favorite_user", methods=["POST"]) +def favorite_user(): + data = request.get_json(force=True) + username = data.get("username") + fav = bool(data.get("favorite")) + + conn, cur = get_local_db_connection() + if fav: + cur.execute("INSERT INTO favorite_users (username) VALUES (%s) ON CONFLICT DO NOTHING", (username,)) + else: + cur.execute("DELETE FROM favorite_users WHERE username = %s", (username,)) + conn.commit() + cur.close(); conn.close() + return {"ok": True} diff --git a/routes/web.py b/routes/web.py index ba1cf85..a1191b2 100644 --- a/routes/web.py +++ b/routes/web.py @@ -1,7 +1,7 @@ from flask import Blueprint, render_template, request, send_file, jsonify import math 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.favorites import mark_favorites, db_get_favorites, db_get_fav_set, db_get_favorite_users from helpers.cache import build_cache from config import VIDEOS_PER_PAGE, DASHBOARD_PER_PAGE, get_local_db_connection from datetime import date, datetime, timedelta @@ -120,6 +120,8 @@ def dashboard(): start_idx = (page - 1) * DASHBOARD_PER_PAGE paginated = items[start_idx:start_idx + DASHBOARD_PER_PAGE] + favorite_users = db_get_favorite_users() + return render_template( "main.html", storage_usage=paginated, @@ -134,6 +136,7 @@ def dashboard(): end_date=end_str, online_set=online_usernames, recording_offline_set=recording_offline_usernames, + favorite_users=favorite_users, ) @web.route("/user/") diff --git a/static/styles.css b/static/styles.css index 31e2dd5..a866cc4 100644 --- a/static/styles.css +++ b/static/styles.css @@ -172,6 +172,16 @@ tr:nth-child(even){background:#181818} .fav-btn[aria-pressed="true"]{color:gold} .fav-btn:hover{transform:scale(1.05)} +.user-fav { + position: static; /* no absolute positioning */ + background: none; + padding: 0; + margin-right: 6px; /* little gap before username */ + font-size: 16px; + backdrop-filter: none; +} + + /* ========================= Responsive tweaks ========================= */ diff --git a/templates/main.html b/templates/main.html index 9798fd3..f28fd2d 100644 --- a/templates/main.html +++ b/templates/main.html @@ -51,7 +51,15 @@ {% for key, stats in storage_usage %} {% set user, platform = key.split("::") %} + + + + {{ user }} {% set uname = user.lower() %} {% if uname in online_set %} @@ -62,10 +70,15 @@ {% endif %} + {{ platform }} + {{ "%.2f"|format(stats.total_size) }} + {{ stats.video_count }} + {{ "%.2f"|format(avg_sizes[key]) }} + {% if stats.last_online %} {{ stats.last_online.strftime('%Y-%m-%d') }} @@ -73,6 +86,7 @@ — {% endif %} + {% endfor %} @@ -104,4 +118,32 @@ async function refreshStatusDots() { } refreshStatusDots(); setInterval(refreshStatusDots, 20000); + + + {% endblock %}