f
This commit is contained in:
@@ -266,6 +266,22 @@ def _fetch_torrent_bytes(target: str) -> Optional[bytes]:
|
||||
return None
|
||||
|
||||
|
||||
_ALD_MAGNET_PREFIX = "alldebrid:magnet:"
|
||||
|
||||
|
||||
def _parse_alldebrid_magnet_id(target: str) -> Optional[int]:
|
||||
candidate = str(target or "").strip()
|
||||
if not candidate:
|
||||
return None
|
||||
if not candidate.lower().startswith(_ALD_MAGNET_PREFIX):
|
||||
return None
|
||||
try:
|
||||
magnet_id_raw = candidate[len(_ALD_MAGNET_PREFIX):].strip()
|
||||
return int(magnet_id_raw)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def resolve_magnet_spec(target: str) -> Optional[str]:
|
||||
"""Resolve a magnet/hash/torrent URL into a magnet/hash string."""
|
||||
candidate = str(target or "").strip()
|
||||
@@ -558,14 +574,14 @@ class AllDebrid(TableProviderMixin, Provider):
|
||||
1. User runs: search-file -provider alldebrid "ubuntu"
|
||||
2. Results show magnet folders and (optionally) files
|
||||
3. User selects a row: @1
|
||||
4. Selection metadata routes to download-file with -magnet-id
|
||||
5. download-file calls provider.download_items() with magnet_id
|
||||
4. Selection metadata routes to download-file with -url alldebrid:magnet:<id>
|
||||
5. download-file invokes provider.download_items() via provider URL handling
|
||||
6. Provider fetches files, unlocks locked URLs, and downloads
|
||||
"""
|
||||
# Magnet URIs should be routed through this provider.
|
||||
TABLE_AUTO_STAGES = {"alldebrid": ["download-file"]}
|
||||
AUTO_STAGE_USE_SELECTION_ARGS = True
|
||||
URL = ("magnet:",)
|
||||
URL = ("magnet:", "alldebrid:magnet:")
|
||||
URL_DOMAINS = ()
|
||||
|
||||
@classmethod
|
||||
@@ -631,6 +647,19 @@ class AllDebrid(TableProviderMixin, Provider):
|
||||
return resolve_magnet_spec(str(target)) if isinstance(target, str) else None
|
||||
|
||||
def handle_url(self, url: str, *, output_dir: Optional[Path] = None) -> Tuple[bool, Optional[Path]]:
|
||||
magnet_id = _parse_alldebrid_magnet_id(url)
|
||||
if magnet_id is not None:
|
||||
return True, {
|
||||
"action": "download_items",
|
||||
"path": f"{_ALD_MAGNET_PREFIX}{magnet_id}",
|
||||
"title": f"magnet-{magnet_id}",
|
||||
"metadata": {
|
||||
"magnet_id": magnet_id,
|
||||
"provider": "alldebrid",
|
||||
"provider_view": "files",
|
||||
},
|
||||
}
|
||||
|
||||
spec = resolve_magnet_spec(url)
|
||||
if not spec:
|
||||
return False, None
|
||||
@@ -1180,8 +1209,8 @@ class AllDebrid(TableProviderMixin, Provider):
|
||||
"provider": "alldebrid",
|
||||
"provider_view": "files",
|
||||
# Selection metadata for table system
|
||||
"_selection_args": ["-magnet-id", str(magnet_id)],
|
||||
"_selection_action": ["download-file", "-provider", "alldebrid", "-magnet-id", str(magnet_id)],
|
||||
"_selection_args": ["-url", f"{_ALD_MAGNET_PREFIX}{magnet_id}"],
|
||||
"_selection_action": ["download-file", "-provider", "alldebrid", "-url", f"{_ALD_MAGNET_PREFIX}{magnet_id}"],
|
||||
}
|
||||
|
||||
results.append(
|
||||
@@ -1295,8 +1324,8 @@ class AllDebrid(TableProviderMixin, Provider):
|
||||
"provider_view": "folders",
|
||||
"magnet_name": magnet_name,
|
||||
# Selection metadata: allow @N expansion to drive downloads directly
|
||||
"_selection_args": ["-magnet-id", str(magnet_id)],
|
||||
"_selection_action": ["download-file", "-provider", "alldebrid", "-magnet-id", str(magnet_id)],
|
||||
"_selection_args": ["-url", f"{_ALD_MAGNET_PREFIX}{magnet_id}"],
|
||||
"_selection_action": ["download-file", "-provider", "alldebrid", "-url", f"{_ALD_MAGNET_PREFIX}{magnet_id}"],
|
||||
},
|
||||
)
|
||||
)
|
||||
@@ -1585,7 +1614,7 @@ try:
|
||||
1. Explicit _selection_action (full command args)
|
||||
2. Explicit _selection_args (URL-specific args)
|
||||
3. Magic routing based on provider_view (files vs folders)
|
||||
4. Magnet ID routing for folder-type rows
|
||||
4. Magnet ID routing for folder-type rows (via alldebrid:magnet:<id>)
|
||||
5. Direct URL for file rows
|
||||
|
||||
This ensures that selector overrides all pre-codes and gives users full power.
|
||||
@@ -1612,7 +1641,7 @@ try:
|
||||
# Folder rows: use magnet_id to fetch and download all files
|
||||
magnet_id = metadata.get("magnet_id")
|
||||
if magnet_id is not None:
|
||||
return ["-magnet-id", str(magnet_id)]
|
||||
return ["-url", f"{_ALD_MAGNET_PREFIX}{magnet_id}"]
|
||||
|
||||
# Fallback: try direct URL
|
||||
if row.path:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
When a URL is passed through download-file, this provider displays available formats
|
||||
in a table and routes format selection back to download-file with the chosen format
|
||||
already specified via -format, skipping the format table on the second invocation.
|
||||
already specified via -query "format:<id>", skipping the format table on the second invocation.
|
||||
|
||||
This keeps format selection logic in ytdlp and leaves add-file plug-and-play.
|
||||
"""
|
||||
@@ -31,8 +31,8 @@ class ytdlp(TableProviderMixin, Provider):
|
||||
- User runs: download-file "https://example.com/video"
|
||||
- If URL is ytdlp-supported and no format specified, displays format table
|
||||
- User selects @N (e.g., @3 for format index 3)
|
||||
- Selection args include -format <format_id>, re-invoking download-file
|
||||
- Second download-file call sees -format and skips table, downloads directly
|
||||
- Selection args include -query "format:<format_id>", re-invoking download-file
|
||||
- Second download-file call sees the format query and skips the table, downloads directly
|
||||
|
||||
SEARCH USAGE:
|
||||
- User runs: search-file -provider ytdlp "linux tutorial"
|
||||
@@ -41,12 +41,12 @@ class ytdlp(TableProviderMixin, Provider):
|
||||
- Selection args route to download-file for streaming download
|
||||
|
||||
SELECTION FLOW (Format):
|
||||
1. download-file receives URL without -format
|
||||
1. download-file receives URL without a format query
|
||||
2. Calls ytdlp to list formats
|
||||
3. Returns formats as ResultTable (from this provider)
|
||||
4. User selects @N
|
||||
5. Selection args: ["-format", "<format_id>"] route back to download-file
|
||||
6. Second download-file invocation with -format skips table
|
||||
5. Selection args: ["-query", "format:<format_id>"] route back to download-file
|
||||
6. Second download-file invocation with format query skips table
|
||||
|
||||
SELECTION FLOW (Search):
|
||||
1. search-file lists YouTube videos via yt_dlp
|
||||
@@ -56,7 +56,7 @@ class ytdlp(TableProviderMixin, Provider):
|
||||
5. download-file downloads the selected video
|
||||
|
||||
TABLE AUTO-STAGES:
|
||||
- Format selection: ytdlp.formatlist -> download-file (with -format)
|
||||
- Format selection: ytdlp.formatlist -> download-file (with -query format:<id>)
|
||||
- Video search: ytdlp.search -> download-file (with -url)
|
||||
|
||||
SUPPORTED URLS:
|
||||
@@ -106,7 +106,7 @@ class ytdlp(TableProviderMixin, Provider):
|
||||
"ytdlp.formatlist": ["download-file"],
|
||||
"ytdlp.search": ["download-file"],
|
||||
}
|
||||
# Forward selection args (including -format or -url) to the next stage
|
||||
# Forward selection args (including -query format:... or -url) to the next stage
|
||||
AUTO_STAGE_USE_SELECTION_ARGS = True
|
||||
|
||||
def search(
|
||||
@@ -277,7 +277,7 @@ try:
|
||||
"""Return selection args for format selection.
|
||||
|
||||
When user selects @N, these args are passed to download-file which sees
|
||||
the -format specifier and skips the format table, downloading directly.
|
||||
the format query and skips the format table, downloading directly.
|
||||
"""
|
||||
metadata = row.metadata or {}
|
||||
|
||||
@@ -291,7 +291,7 @@ try:
|
||||
# Fallback: use format_id
|
||||
format_id = metadata.get("format_id") or metadata.get("id")
|
||||
if format_id:
|
||||
result_args = ["-format", str(format_id)]
|
||||
result_args = ["-query", f"format:{format_id}"]
|
||||
debug(f"[ytdlp] Selection routed with format_id: {format_id}")
|
||||
return result_args
|
||||
|
||||
|
||||
Reference in New Issue
Block a user