urgent fixes
This commit is contained in:
@@ -117,6 +117,9 @@ def bypass_user_id() -> int:
|
||||
def current_user_id() -> int:
|
||||
if not enabled():
|
||||
return default_user_id()
|
||||
if not has_request_context():
|
||||
# Note: Background jobs and schedulers do not have Flask request/session state.
|
||||
return 0
|
||||
if auth_bypassed_request():
|
||||
return bypass_user_id()
|
||||
api_user_id = getattr(g, "api_user_id", None)
|
||||
|
||||
@@ -6,6 +6,7 @@ import json
|
||||
import psutil
|
||||
from flask_socketio import emit, join_room, leave_room, disconnect
|
||||
from .preferences import active_profile, get_profile
|
||||
from ..db import default_user_id
|
||||
from .torrent_cache import torrent_cache
|
||||
from .torrent_summary import cached_summary
|
||||
from . import rtorrent, smart_queue, traffic_history, automation_rules, torrent_stats, auth, speed_peaks, poller_control, download_planner
|
||||
@@ -38,13 +39,15 @@ def _emit_profile(socketio, event: str, payload: dict, profile_id: int) -> None:
|
||||
|
||||
def _run_slow_profile_tasks(socketio, profile: dict, profile_id: int) -> None:
|
||||
state = poller_control.state_for(profile_id)
|
||||
# Note: Background checks keep the profile owner so bypass/admin profiles do not enqueue jobs as the fallback user.
|
||||
profile_user_id = int(profile.get("user_id") or default_user_id())
|
||||
try:
|
||||
try:
|
||||
torrent_stats.queue_refresh(socketio, profile, force=False, room=_profile_room(profile_id) if auth.enabled() else None)
|
||||
except Exception as exc:
|
||||
_emit_profile(socketio, "torrent_stats_update", {"ok": False, "profile_id": profile_id, "error": str(exc)}, profile_id)
|
||||
try:
|
||||
result = smart_queue.check(profile, force=False)
|
||||
result = smart_queue.check(profile, user_id=profile_user_id, force=False)
|
||||
if result.get("enabled"):
|
||||
_emit_profile(socketio, "smart_queue_update", result, profile_id)
|
||||
if result.get("stopped") or result.get("started") or result.get("start_requested") or result.get("paused") or result.get("resumed"):
|
||||
@@ -55,7 +58,7 @@ def _run_slow_profile_tasks(socketio, profile: dict, profile_id: int) -> None:
|
||||
except Exception as exc:
|
||||
_emit_profile(socketio, "smart_queue_update", {"ok": False, "profile_id": profile_id, "error": str(exc)}, profile_id)
|
||||
try:
|
||||
auto_result = automation_rules.check(profile, force=False)
|
||||
auto_result = automation_rules.check(profile, user_id=profile_user_id, force=False)
|
||||
if auto_result.get("applied"):
|
||||
_emit_profile(socketio, "automation_update", auto_result, profile_id)
|
||||
except Exception as exc:
|
||||
|
||||
@@ -9,6 +9,8 @@ from . import rtorrent, auth, disk_guard, operation_logs
|
||||
from .preferences import get_profile
|
||||
from ..config import WORKERS
|
||||
from ..db import connect, utcnow, default_user_id
|
||||
from .torrent_cache import torrent_cache
|
||||
from .torrent_summary import cached_summary
|
||||
|
||||
LIGHT_ACTIONS = {"start", "stop", "pause", "resume", "unpause", "set_label", "set_ratio_group", "reannounce", "set_limits"}
|
||||
WATCHDOG_INTERVAL_SECONDS = 30
|
||||
@@ -216,10 +218,11 @@ def _job_event_meta(payload: dict) -> dict:
|
||||
return meta
|
||||
|
||||
|
||||
def _execute(profile: dict, action_name: str, payload: dict):
|
||||
def _execute(profile: dict, action_name: str, payload: dict, user_id: int | None = None):
|
||||
if action_name == "smart_queue_check":
|
||||
from . import smart_queue
|
||||
return smart_queue.check(profile, user_id=auth.current_user_id() or default_user_id(), force=True)
|
||||
# Note: Worker execution uses the job owner instead of Flask session state.
|
||||
return smart_queue.check(profile, user_id=user_id or default_user_id(), force=True)
|
||||
if action_name == "add_magnet":
|
||||
if bool(payload.get("start", True)):
|
||||
disk_guard.assert_can_start_download(profile)
|
||||
@@ -268,6 +271,22 @@ def _mark_running(job_id: str, attempts: int) -> bool:
|
||||
return int(cur.rowcount or 0) == 1
|
||||
|
||||
|
||||
def _emit_torrent_refresh(profile: dict, action_name: str) -> None:
|
||||
if action_name not in {"add_magnet", "add_torrent_raw", "remove", "move", "start", "stop", "pause", "resume", "unpause", "set_label", "set_ratio_group", "recheck"}:
|
||||
return
|
||||
try:
|
||||
diff = torrent_cache.refresh(profile)
|
||||
profile_id = int(profile["id"])
|
||||
if diff.get("ok"):
|
||||
rows = torrent_cache.snapshot(profile_id)
|
||||
_emit("torrent_patch", {**diff, "summary": cached_summary(profile_id, rows, force=True)})
|
||||
else:
|
||||
_emit("rtorrent_error", diff)
|
||||
except Exception as exc:
|
||||
# Note: A failed live refresh must not change the already completed job result.
|
||||
_emit("rtorrent_error", {"profile_id": int(profile.get("id") or 0), "error": str(exc)})
|
||||
|
||||
|
||||
def _run(job_id: str):
|
||||
if not _claim_runner(job_id):
|
||||
return
|
||||
@@ -303,7 +322,7 @@ def _run(job_id: str):
|
||||
operation_logs.record_job_event(profile["id"], job["action"], "started", payload, job_id=job_id, user_id=int(job.get("user_id") or 0))
|
||||
_emit("operation_started", {"job_id": job_id, "action": job["action"], "profile_id": profile["id"], "hashes": payload.get("hashes") or [], "hash_count": len(payload.get("hashes") or []), "bulk": len(payload.get("hashes") or []) > 1, **event_meta})
|
||||
_emit("job_update", {"id": job_id, "profile_id": profile["id"], "status": "running", "attempts": attempts})
|
||||
result = _execute(profile, job["action"], payload)
|
||||
result = _execute(profile, job["action"], payload, user_id=int(job.get("user_id") or 0))
|
||||
fresh = _job_row(job_id)
|
||||
# Note: Emergency cancel and watchdog timeout keep late work from overwriting a terminal state.
|
||||
if fresh and fresh["status"] != "running":
|
||||
|
||||
Reference in New Issue
Block a user