move to anther profile
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user