mobile ux

This commit is contained in:
Mateusz Gruszczyński
2026-05-08 19:00:26 +02:00
parent 80cea1dbc3
commit f245f082d5
5 changed files with 354 additions and 34 deletions

View File

@@ -13,11 +13,11 @@ import socket
import json
import psutil
import xml.etree.ElementTree as ET
from flask import Blueprint, jsonify, request, abort
from flask import Blueprint, jsonify, request, abort, send_file
from ..config import DB_PATH, JOBS_RETENTION_DAYS, SMART_QUEUE_HISTORY_RETENTION_DAYS, WORKERS
from ..db import connect, utcnow
from ..services.auth import current_user_id as default_user_id, current_user, list_users, save_user, delete_user, login_user, logout_user, enabled as auth_enabled, require_profile_write
from ..services import preferences, rtorrent, torrent_stats, speed_peaks
from ..services import preferences, rtorrent, torrent_stats, speed_peaks, tracker_cache
from ..services.torrent_cache import torrent_cache
from ..services.torrent_summary import cached_summary
from ..services.workers import enqueue, list_jobs, cancel_job, retry_job, clear_jobs, emergency_clear_jobs
@@ -489,16 +489,25 @@ def torrents():
def trackers_summary():
profile = preferences.active_profile()
if not profile:
return ok({"summary": {"hashes": {}, "trackers": [], "errors": [], "scanned": 0}, "error": "No profile"})
limit = min(2000, max(1, int(request.args.get("limit") or 1000)))
hashes = request.args.getlist("hash")
return ok({"summary": {"hashes": {}, "trackers": [], "errors": [], "scanned": 0, "pending": 0}, "error": "No profile"})
try:
# Note: This endpoint powers only the sidebar tracker filter and never mutates torrents.
if not hashes:
hashes = [t.get("hash") for t in torrent_cache.snapshot(profile["id"]) if t.get("hash")]
return ok({"summary": rtorrent.tracker_summary(profile, hashes, limit=limit)})
# Note: Tracker summary uses the local torrent snapshot and refreshes only a small cache batch per request.
scan_limit = min(250, max(0, int(request.args.get("scan_limit") or 80)))
hashes = [t.get("hash") for t in torrent_cache.snapshot(profile["id"]) if t.get("hash")]
summary = tracker_cache.summary(profile, hashes, lambda h: rtorrent.torrent_trackers(profile, h), scan_limit=scan_limit)
return ok({"summary": summary})
except Exception as exc:
return jsonify({"ok": False, "error": str(exc)}), 500
return ok({"summary": {"hashes": {}, "trackers": [], "errors": [{"error": str(exc)}], "scanned": 0, "pending": 0}, "error": str(exc)})
@bp.get("/trackers/favicon/<path:domain>")
def tracker_favicon(domain: str):
prefs = preferences.get_preferences()
enabled = bool(prefs and prefs.get("tracker_favicons_enabled"))
path, mime = tracker_cache.favicon_path(domain, enabled=enabled)
if not path:
abort(404)
return send_file(path, mimetype=mime or "image/x-icon", max_age=7 * 24 * 60 * 60)
@bp.get("/torrent-stats")
def torrent_stats_get():