move to anther profile

This commit is contained in:
Mateusz Gruszczyński
2026-06-20 17:01:48 +02:00
parent e6733d6a27
commit fc03b7755b
12 changed files with 201 additions and 14 deletions
+19 -1
View File
@@ -2,6 +2,7 @@ from __future__ import annotations
from ._shared import *
from ..services.rtorrent.diagnostics import profile_diagnostics
from ..services import auth
from ..utils import human_size
@bp.get("/profiles")
def profiles_list():
@@ -10,6 +11,13 @@ def profiles_list():
item = dict(row)
# Note: Frontend actions can hide write-only operations without trusting this flag; backend still enforces permissions.
item["can_write"] = auth.can_write_profile(int(item.get("id") or 0), auth.current_user_id() or default_user_id())
stats = preferences.get_profile_runtime_stats(int(item.get("id") or 0))
if stats:
stats["total_size_h"] = human_size(stats.get("total_size_bytes"))
stats["completed_h"] = human_size(stats.get("completed_bytes"))
stats["downloaded_h"] = human_size(stats.get("downloaded_bytes"))
stats["uploaded_h"] = human_size(stats.get("uploaded_bytes"))
item["runtime_stats"] = stats
settings = backup_service.get_auto_backup_settings(default_user_id(), "profile", int(item.get("id") or 0))
item["profile_backup_enabled"] = bool(settings.get("enabled"))
item["profile_backup_interval_hours"] = settings.get("interval_hours")
@@ -46,7 +54,17 @@ def profiles_delete(profile_id: int):
@bp.post("/profiles/<int:profile_id>/activate")
def profiles_activate(profile_id: int):
try:
return ok({"profile": preferences.activate_profile(profile_id)})
profile = preferences.activate_profile(profile_id)
stats_error = ""
try:
# Note: Profile overview metrics are cached only on user-initiated profile switch, not on every profile list render.
preferences.save_profile_runtime_stats(profile, rtorrent.list_torrents(profile), user_id=auth.current_user_id() or default_user_id())
except Exception as exc:
stats_error = str(exc)
response = {"profile": profile}
if stats_error:
response["stats_error"] = stats_error
return ok(response)
except Exception as exc:
return jsonify({"ok": False, "error": str(exc)}), 404
+3 -1
View File
@@ -578,7 +578,9 @@ def _profile_transfer_payload(source_profile: dict, data: dict, *, require_hashe
target_path = _clean_remote_transfer_path(requested_target_path or default_target_path)
inside_allowed_root = bool(roots and any(_path_inside_root(target_path, root) for root in roots))
if not inside_allowed_root:
# Note: A metadata-only profile transfer does not require source-user write access, but it still uses a safe target default.
# Note: A chosen target path must stay inside the target profile roots even for metadata-only transfers.
if requested_target_path:
raise ValueError("Target path is outside the target profile download roots")
target_path = default_target_path
inside_allowed_root = bool(roots and any(_path_inside_root(target_path, root) for root in roots))