footer imrpove
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
|
||||
from ..db import connect, utcnow, default_user_id
|
||||
|
||||
BOOTSTRAP_THEMES = {
|
||||
@@ -157,6 +159,7 @@ def save_preferences(data: dict, user_id: int | None = None):
|
||||
table_columns_json = data.get("table_columns_json")
|
||||
peers_refresh_seconds = data.get("peers_refresh_seconds")
|
||||
port_check_enabled = data.get("port_check_enabled")
|
||||
footer_items_json = data.get("footer_items_json")
|
||||
with connect() as conn:
|
||||
now = utcnow()
|
||||
if allowed_theme:
|
||||
@@ -173,4 +176,11 @@ def save_preferences(data: dict, user_id: int | None = None):
|
||||
conn.execute("UPDATE user_preferences SET peers_refresh_seconds=?, updated_at=? WHERE user_id=?", (sec, now, user_id))
|
||||
if port_check_enabled is not None:
|
||||
conn.execute("UPDATE user_preferences SET port_check_enabled=?, updated_at=? WHERE user_id=?", (1 if port_check_enabled else 0, now, user_id))
|
||||
if footer_items_json is not None:
|
||||
# Note: Store only JSON objects so footer visibility can be extended without schema churn.
|
||||
value = footer_items_json if isinstance(footer_items_json, str) else json.dumps(footer_items_json)
|
||||
parsed = json.loads(value or "{}")
|
||||
if not isinstance(parsed, dict):
|
||||
parsed = {}
|
||||
conn.execute("UPDATE user_preferences SET footer_items_json=?, updated_at=? WHERE user_id=?", (json.dumps(parsed), now, user_id))
|
||||
return get_preferences(user_id)
|
||||
|
||||
@@ -435,6 +435,28 @@ def disk_usage_for_default_path(profile: dict) -> dict:
|
||||
return usage
|
||||
|
||||
|
||||
|
||||
def _safe_rtorrent_int(callable_obj, default=None):
|
||||
"""Return an integer rTorrent metric without failing the whole status poll."""
|
||||
try:
|
||||
value = callable_obj()
|
||||
return int(value)
|
||||
except Exception:
|
||||
return default
|
||||
|
||||
|
||||
def _safe_rtorrent_time(c):
|
||||
"""Read rTorrent server time when supported; otherwise let the browser clock remain authoritative."""
|
||||
candidates = (
|
||||
lambda: c.system.time_seconds(),
|
||||
lambda: c.system.time(),
|
||||
)
|
||||
for candidate in candidates:
|
||||
value = _safe_rtorrent_int(candidate)
|
||||
if value:
|
||||
return value
|
||||
return None
|
||||
|
||||
def system_status(profile: dict) -> dict:
|
||||
c = client_for(profile)
|
||||
version = str(c.system.client_version())
|
||||
@@ -447,13 +469,19 @@ def system_status(profile: dict) -> dict:
|
||||
except Exception:
|
||||
up_limit = 0
|
||||
rows = list_torrents(profile)
|
||||
# Note: ruTorrent-style footer metrics. Missing XMLRPC methods are shown as unavailable instead of breaking polling.
|
||||
open_sockets = _safe_rtorrent_int(lambda: c.network.open_sockets())
|
||||
max_open_sockets = _safe_rtorrent_int(lambda: c.network.max_open_sockets())
|
||||
rtorrent_time = _safe_rtorrent_time(c)
|
||||
checking_count = sum(1 for t in rows if t.get("status") == "Checking" or int(t.get("hashing") or 0) > 0)
|
||||
return {
|
||||
"ok": True,
|
||||
"version": version,
|
||||
"total": len(rows),
|
||||
"active": sum(1 for t in rows if t["state"]),
|
||||
"seeding": sum(1 for t in rows if t["complete"] and t["state"] and not t.get("paused")),
|
||||
"leeching": sum(1 for t in rows if not t["complete"] and t["state"] and not t.get("paused")),
|
||||
"leeching": sum(1 for t in rows if not t["complete"] and t["state"] and not t.get("paused") and t.get("status") != "Checking"),
|
||||
"checking": checking_count,
|
||||
"paused": sum(1 for t in rows if t.get("paused")),
|
||||
"stopped": sum(1 for t in rows if not t["state"]),
|
||||
"down_rate": sum(t["down_rate"] for t in rows),
|
||||
@@ -468,6 +496,9 @@ def system_status(profile: dict) -> dict:
|
||||
"total_up": sum(t["up_total"] for t in rows),
|
||||
"total_down_h": human_size(sum(t["down_total"] for t in rows)),
|
||||
"total_up_h": human_size(sum(t["up_total"] for t in rows)),
|
||||
"open_sockets": open_sockets,
|
||||
"max_open_sockets": max_open_sockets,
|
||||
"rtorrent_time": rtorrent_time,
|
||||
"disk": disk_usage_for_default_path(profile),
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user