The global handle in web_server.py was named soulseek_client for historical reasons but the type has long been DownloadOrchestrator, not SoulseekClient. Renamed the global plus every parameter/attribute that carried the legacy name. - web_server.py: global var renamed; all 99 references updated. - api/, core/downloads/*, core/search/*, core/streaming/*, services/sync_service.py: parameter names, dataclass fields, and init() arg names renamed. - Test fixtures (CandidatesDeps, MasterDeps, SearchDeps, etc.) and the _build_deps helpers updated accordingly. The core.soulseek_client module path and SoulseekClient class name (the actual soulseek-only client) are unchanged — only the orchestrator handle renamed. Module imports of TrackResult/AlbumResult/DownloadStatus from core.soulseek_client preserved.
101 lines
3.4 KiB
Python
101 lines
3.4 KiB
Python
"""
|
|
System endpoints — status, activity feed, stats.
|
|
"""
|
|
|
|
import time
|
|
|
|
from flask import current_app
|
|
from .auth import require_api_key
|
|
from .helpers import api_success, api_error
|
|
|
|
|
|
def register_routes(bp):
|
|
|
|
@bp.route("/system/status", methods=["GET"])
|
|
@require_api_key
|
|
def system_status():
|
|
"""Server status including uptime and service connectivity."""
|
|
try:
|
|
app = current_app._get_current_object()
|
|
ctx = app.soulsync
|
|
|
|
uptime_seconds = time.time() - getattr(app, "start_time", time.time())
|
|
hours, remainder = divmod(int(uptime_seconds), 3600)
|
|
minutes, seconds = divmod(remainder, 60)
|
|
|
|
spotify = ctx.get("spotify_client")
|
|
spotify_ok = bool(spotify and spotify.is_authenticated())
|
|
|
|
soulseek = ctx.get("download_orchestrator")
|
|
soulseek_ok = bool(soulseek)
|
|
|
|
hydrabase = ctx.get("hydrabase_client")
|
|
hydrabase_ok = False
|
|
if hydrabase:
|
|
try:
|
|
ws, _ = hydrabase.get_ws_and_lock()
|
|
hydrabase_ok = ws is not None and ws.connected
|
|
except Exception:
|
|
pass
|
|
|
|
return api_success({
|
|
"uptime": f"{hours}h {minutes}m {seconds}s",
|
|
"uptime_seconds": int(uptime_seconds),
|
|
"services": {
|
|
"spotify": spotify_ok,
|
|
"soulseek": soulseek_ok,
|
|
"hydrabase": hydrabase_ok,
|
|
},
|
|
})
|
|
except Exception as e:
|
|
return api_error("SYSTEM_ERROR", str(e), 500)
|
|
|
|
@bp.route("/system/activity", methods=["GET"])
|
|
@require_api_key
|
|
def system_activity():
|
|
"""Recent activity feed."""
|
|
try:
|
|
from core.runtime_state import activity_feed
|
|
items = list(activity_feed) if activity_feed else []
|
|
return api_success({"activities": items})
|
|
except Exception as e:
|
|
return api_error("SYSTEM_ERROR", str(e), 500)
|
|
|
|
@bp.route("/system/stats", methods=["GET"])
|
|
@require_api_key
|
|
def system_stats():
|
|
"""Combined library + download statistics."""
|
|
try:
|
|
from database.music_database import get_database
|
|
db = get_database()
|
|
lib_stats = db.get_statistics_for_server()
|
|
db_info = db.get_database_info_for_server()
|
|
|
|
# Active download count
|
|
download_count = 0
|
|
try:
|
|
from core.runtime_state import download_tasks, tasks_lock
|
|
with tasks_lock:
|
|
download_count = sum(
|
|
1 for t in download_tasks.values()
|
|
if t.get("status") in ("downloading", "queued", "searching")
|
|
)
|
|
except ImportError:
|
|
pass
|
|
|
|
return api_success({
|
|
"library": {
|
|
"artists": lib_stats.get("artists", 0),
|
|
"albums": lib_stats.get("albums", 0),
|
|
"tracks": lib_stats.get("tracks", 0),
|
|
},
|
|
"database": {
|
|
"size_mb": db_info.get("database_size_mb"),
|
|
"last_update": db_info.get("last_update"),
|
|
},
|
|
"downloads": {
|
|
"active": download_count,
|
|
},
|
|
})
|
|
except Exception as e:
|
|
return api_error("SYSTEM_ERROR", str(e), 500)
|