You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: app/api/qbittorrent/torrents.py
+19-2Lines changed: 19 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -37,7 +37,24 @@ def torrents_add(
37
37
paused: Optional[bool] =Form(default=False),
38
38
tags: Optional[str] =Form(default=None),
39
39
):
40
-
"""Sonarr posts magnet URL(s) here. We accept the first one."""
40
+
"""
41
+
Accept a Sonarr POST of magnet URL(s), schedule the download for the first magnet, and record a ClientTask.
42
+
43
+
Parses the first magnet line from `urls`, extracts metadata (slug, season, episode, language, site, name, and torrent hash), schedules a download job, and upserts a ClientTask with the job and save path. If `savepath` is not provided, the configured download directory is used; if a public save path is configured it is stored as the task's save path.
44
+
45
+
Parameters:
46
+
urls (str): One or more magnet URLs separated by newlines; only the first line is processed.
47
+
savepath (Optional[str]): Optional explicit save directory for the torrent. If omitted, the configured DOWNLOAD_DIR is used; a configured QBIT_PUBLIC_SAVE_PATH will be preferred when stored.
48
+
category (Optional[str]): Optional category to record with the task.
49
+
paused (Optional[bool]): If true, the created task is marked as queued instead of downloading.
50
+
tags (Optional[str]): Optional tags provided by the caller (accepted but not otherwise interpreted here).
51
+
52
+
Returns:
53
+
PlainTextResponse: A plain-text response with the body "Ok." on success.
54
+
55
+
Raises:
56
+
HTTPException: Raised with status 400 when `urls` is empty or missing.
57
+
"""
41
58
logger.info(f"Received request to add torrent(s): {urls}")
42
59
ifnoturls:
43
60
logger.warning("No URLs provided in torrents_add.")
@@ -333,4 +350,4 @@ def torrents_delete(
333
350
logger.warning(f"Exception during file deletion for hash {h}: {e}")
334
351
delete_client_task(session, h)
335
352
logger.success(f"Deleted client task for hash {h}")
Copy file name to clipboardExpand all lines: app/api/torznab/api.py
+27-1Lines changed: 27 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -37,6 +37,32 @@ def torznab_api(
37
37
limit: int=Query(default=50),
38
38
session: Session=Depends(get_session),
39
39
) ->Response:
40
+
"""
41
+
Handle torznab-compatible API requests and return the corresponding XML response.
42
+
43
+
Supports three request modes determined by `t`:
44
+
- "caps": return the server capabilities XML.
45
+
- "search": perform a generic/preview search and return an RSS feed with zero or more synthetic or discovered items.
46
+
- "tvsearch": search for a specific TV episode (requires `q` and `season`; `ep` defaults to 1 if omitted) and return an RSS feed of available releases.
47
+
48
+
Parameters:
49
+
request: FastAPI Request object for the incoming HTTP request.
50
+
t (str): One of "caps", "search", or "tvsearch", selecting the API mode.
51
+
apikey (Optional[str]): API key for access control; presence/validity is required.
52
+
q (Optional[str]): Query string identifying a series or search terms.
53
+
season (Optional[int]): Season number for TV episode searches; required for "tvsearch".
54
+
ep (Optional[int]): Episode number for TV episode searches; defaults to 1 for previews when omitted.
55
+
cat (Optional[str]): Category filter (passed through but not required).
56
+
offset (int): Result offset for paging.
57
+
limit (int): Maximum number of RSS items to include.
58
+
session: Database session (provided via dependency injection; omitted from docs for common DI services).
59
+
60
+
Returns:
61
+
Response: A FastAPI Response containing XML:
62
+
- application/xml; charset=utf-8 for "caps"
63
+
- application/rss+xml; charset=utf-8 for "search" and "tvsearch"
64
+
- HTTP 400 is raised for unknown `t` values; empty RSS feeds are returned when required parameters or slug resolution are missing.
Download an episode to the specified directory, resolving a direct stream URL with provider fallback and proxy-aware retry logic.
328
+
329
+
This function builds an Episode from the provided identifiers, attempts to resolve a direct download URL (optionally preferring a provider), downloads the media via yt-dlp with progress callbacks and cancellation support, and renames the downloaded file into the repository's release naming schema. If extraction or download fails, controlled fallback attempts are performed (no-proxy re-resolution and alternate providers) before failing.
330
+
331
+
Parameters:
332
+
link (Optional[str]): Direct episode page URL; if provided, used instead of slug/season/episode.
333
+
slug (Optional[str]): Series identifier used to construct an Episode when `link` is not given.
334
+
season (Optional[int]): Season number to construct an Episode when `link` is not given.
335
+
episode (Optional[int]): Episode number to construct an Episode when `link` is not given.
336
+
provider (Optional[Provider]): Preferred provider name to try first when resolving a direct URL.
337
+
language (str): Desired language label (will be normalized); used when resolving available streams.
338
+
dest_dir (Path): Destination directory where the temporary download will be written.
339
+
title_hint (Optional[str]): Hint for the temporary output filename; if omitted and slug/season/episode are given, a default is generated.
340
+
cookiefile (Optional[Path]): Path to a cookies file passed to yt-dlp, if required by the provider/site.
341
+
progress_cb (Optional[ProgressCb]): Optional callback that receives yt-dlp progress dictionaries.
342
+
stop_event (Optional[threading.Event]): Optional event that, when set, requests download cancellation.
343
+
site (str): Site identifier to use when constructing the Episode (defaults to "aniworld.to").
344
+
345
+
Returns:
346
+
Path: Final path to the renamed release file.
347
+
348
+
Raises:
349
+
DownloadError: When URL resolution or download ultimately fails after all fallback attempts.
0 commit comments