This commit is contained in:
Benjamin Harder
2025-05-29 16:38:24 +02:00
parent e69c9a4af6
commit 6fe5bb763f
5 changed files with 56 additions and 39 deletions

View File

@@ -41,13 +41,11 @@ class RemovalHandler:
async def _remove_download(self, queue_item, blocklist):
queue_id = queue_item["id"]
logger.info(f">>> Job '{self.job_name}' triggered removal: {queue_item['title']}")
if not self.settings.general.test_run:
await self.arr.remove_queue_item(queue_id=queue_id, blocklist=blocklist)
await self.arr.remove_queue_item(queue_id=queue_id, blocklist=blocklist)
async def _tag_as_obsolete(self, queue_item, download_id):
logger.info(f">>> Job'{self.job_name}' triggered obsolete-tagging: {queue_item['title']}")
if not self.settings.general.test_run:
for qbit in self.settings.download_clients.qbittorrent:
for qbit in self.settings.download_clients.qbittorrent:
await qbit.set_tag(tags=[self.settings.general.obsolete_tag], hashes=[download_id])

View File

@@ -201,8 +201,7 @@ class RemoveBadFiles(RemovalJob):
async def _mark_files_as_stopped(self, qbit_client, torrent_hash, stoppable_files):
"""Mark specific files as 'Do Not Download' in qBittorrent."""
for file, _ in stoppable_files:
if not self.settings.general.test_run:
await qbit_client.set_torrent_file_priority(torrent_hash, file['index'], 0)
await qbit_client.set_torrent_file_priority(torrent_hash, file['index'], 0)
def _all_files_stopped(self, torrent_files, stoppable_files):
"""Check if all files are either stopped (priority 0) or in the stoppable files list."""

View File

@@ -68,9 +68,8 @@ class SearchHandler:
return [item for item in wanted_items if item["id"] not in queue_ids]
async def _trigger_search(self, items):
if not self.settings.general.test_run:
ids = [item["id"] for item in items]
await self.wanted_manager.search_items(ids)
ids = [item["id"] for item in items]
await self.wanted_manager.search_items(ids)
def _filter_recent_searches(self, items):
now = datetime.now(timezone.utc)

View File

@@ -76,7 +76,7 @@ class QbitClient:
data = {"username": getattr(self, 'username', ''), "password": getattr(self, 'password', '')}
headers = {"content-type": "application/x-www-form-urlencoded"}
response = await make_request(
"post", endpoint, self.settings, data=data, headers=headers
"post", endpoint, self.settings, data=data, headers=headers, ignore_test_run=True
)
if response.text == "Fails.":
@@ -124,15 +124,14 @@ class QbitClient:
current_tags = response.json()
if self.settings.general.protected_tag not in current_tags:
logger.verbose(f"Creating protection tag: {self.settings.general.protected_tag}")
if not self.settings.general.test_run:
data = {"tags": self.settings.general.protected_tag}
await make_request(
"post",
self.api_url + "/torrents/createTags",
self.settings,
data=data,
cookies=self.cookie,
)
data = {"tags": self.settings.general.protected_tag}
await make_request(
"post",
self.api_url + "/torrents/createTags",
self.settings,
data=data,
cookies=self.cookie,
)
if (
self.settings.general.public_tracker_handling == "tag_as_obsolete"
@@ -140,15 +139,14 @@ class QbitClient:
):
if self.settings.general.obsolete_tag not in current_tags:
logger.verbose(f"Creating obsolete tag: {self.settings.general.obsolete_tag}")
if not self.settings.general.test_run:
data = {"tags": self.settings.general.obsolete_tag}
await make_request(
"post",
self.api_url + "/torrents/createTags",
self.settings,
data=data,
cookies=self.cookie,
)
data = {"tags": self.settings.general.obsolete_tag}
await make_request(
"post",
self.api_url + "/torrents/createTags",
self.settings,
data=data,
cookies=self.cookie,
)
async def set_unwanted_folder(self):
"""Set the 'unwanted folder' setting in qBittorrent if needed."""
@@ -163,15 +161,14 @@ class QbitClient:
logger.info(
"Enabling 'Keep unselected files in .unwanted folder' in qBittorrent."
)
if not self.settings.general.test_run:
data = {"json": '{"use_unwanted_folder": true}'}
await make_request(
"post",
self.api_url + "/app/setPreferences",
self.settings,
data=data,
cookies=self.cookie,
)
data = {"json": '{"use_unwanted_folder": true}'}
await make_request(
"post",
self.api_url + "/app/setPreferences",
self.settings,
data=data,
cookies=self.cookie,
)
async def check_qbit_reachability(self):
@@ -181,7 +178,7 @@ class QbitClient:
data = {"username": getattr(self, 'username', ''), "password": getattr(self, 'password', '')}
headers = {"content-type": "application/x-www-form-urlencoded"}
await make_request(
"post", endpoint, self.settings, data=data, headers=headers, log_error=False
"post", endpoint, self.settings, data=data, headers=headers, log_error=False, ignore_test_run=True
)
except Exception as e:

View File

@@ -6,6 +6,17 @@ import copy
import requests
from src.utils.log_setup import logger
class DummyResponse:
def __init__(self, text="", status_code=200):
self.text = text
self.status_code = status_code
def raise_for_status(self):
if self.status_code >= 400:
raise requests.HTTPError(f"Status code: {self.status_code}")
def sanitize_kwargs(data):
"""Recursively redact sensitive values in kwargs for safe logging."""
if isinstance(data, dict):
@@ -20,19 +31,32 @@ def sanitize_kwargs(data):
return [sanitize_kwargs(item) for item in data]
return data
async def make_request(
method: str, endpoint: str, settings, timeout: int = 15, log_error = True, **kwargs
) -> requests.Response:
"""
A utility function to make HTTP requests (GET, POST, DELETE, PUT).
"""
ignore_test_run = kwargs.pop("ignore_test_run", False)
if settings.general.test_run and not ignore_test_run:
if method.lower() in ("put", "post","delete"):
if logger.isEnabledFor(logging.DEBUG):
sanitized_kwargs = sanitize_kwargs(copy.deepcopy(kwargs))
logger.debug(
f"common.py/make_request: [Test Run] Simulating {method.upper()} request to {endpoint} with kwargs={sanitized_kwargs}"
)
return DummyResponse(text="Test run - no actual call made", status_code=200)
try:
if logger.isEnabledFor(logging.DEBUG):
sanitized_kwargs = sanitize_kwargs(copy.deepcopy(kwargs))
logger.debug(
f"common.py/make_request: Making {method.upper()} request to {endpoint} with kwargs={sanitized_kwargs}"
)
# Make the request using the method passed (get, post, etc.)
response = await asyncio.to_thread(
getattr(requests, method.lower()),