|
1 | 1 | from packaging import version |
| 2 | +from requests.cookies import RequestsCookieJar |
2 | 3 |
|
3 | 4 | from src.settings._constants import ApiEndpoints, MinVersions |
4 | 5 | from src.utils.common import extract_json_from_response, make_request, wait_and_exit |
@@ -102,12 +103,28 @@ def _connection_error(): |
102 | 103 | if response.text == "Fails.": |
103 | 104 | _connection_error() |
104 | 105 |
|
105 | | - self.cookie = {"SID": response.cookies["SID"]} |
| 106 | + self.cookie = self.extract_sid(response.cookies) |
106 | 107 | except Exception as e: |
107 | 108 | logger.error(f"Error refreshing qBit cookie: {e}") |
108 | 109 | self.cookie = {} |
109 | 110 | raise QbitError(e) from e |
110 | 111 |
|
| 112 | + @staticmethod |
| 113 | + def extract_sid(cookie_jar: RequestsCookieJar) -> dict[str, str]: |
| 114 | + """ |
| 115 | + Extract the SID or dynamic QBIT_SID_<WEB_UI_PORT>. |
| 116 | +
|
| 117 | + This supports the legacy 'SID' key and the dynamic port-based |
| 118 | + naming introduced in qBit 5.2_x. |
| 119 | + """ |
| 120 | + for cookie in cookie_jar: |
| 121 | + # Simple, fast, and covers both legacy and new dynamic ports |
| 122 | + if cookie.name == "SID" or cookie.name.startswith("QBIT_SID_"): |
| 123 | + return {cookie.name: cookie.value} |
| 124 | + |
| 125 | + error = "No qBit cookie found" |
| 126 | + raise QbitError(error) |
| 127 | + |
111 | 128 | async def fetch_version(self): |
112 | 129 | """Fetch the current qBittorrent version.""" |
113 | 130 | logger.debug("_download_clients_qBit.py/fetch_version: Getting qBit Version") |
@@ -292,7 +309,9 @@ async def get_protected_and_private(self): |
292 | 309 | logger.debug( |
293 | 310 | "_download_clients_qBit/get_protected_and_private: Checking if torrents are private (only done for old qbit versions)", |
294 | 311 | ) |
295 | | - qbit_item_props = await self.get_torrent_properties(qbit_item["hash"]) |
| 312 | + qbit_item_props = await self.get_torrent_properties( |
| 313 | + qbit_item["hash"] |
| 314 | + ) |
296 | 315 |
|
297 | 316 | if not qbit_item_props: |
298 | 317 | logger.error( |
@@ -376,15 +395,14 @@ async def get_qbit_items(self, hashes: list[str] | str | None = None) -> list[di |
376 | 395 | async def get_torrent_properties(self, qbit_hash): |
377 | 396 | params = {"hash": qbit_hash.lower()} |
378 | 397 | response = await make_request( |
379 | | - "get", |
380 | | - self.api_url + "/torrents/properties", |
381 | | - self.settings, |
382 | | - params=params, |
383 | | - cookies=self.cookie, |
384 | | - ) |
| 398 | + "get", |
| 399 | + self.api_url + "/torrents/properties", |
| 400 | + self.settings, |
| 401 | + params=params, |
| 402 | + cookies=self.cookie, |
| 403 | + ) |
385 | 404 | return response.json() |
386 | 405 |
|
387 | | - |
388 | 406 | async def get_torrent_files(self, download_id): |
389 | 407 | # this may not work if the wrong qbit |
390 | 408 | logger.debug("_download_clients_qBit/get_torrent_files: Getting torrent files") |
|
0 commit comments