This commit is contained in:
2026-01-31 16:11:25 -08:00
parent c854f8c6a8
commit dcf16e0cc4
6 changed files with 112 additions and 43 deletions

3
.gitignore vendored
View File

@@ -245,4 +245,5 @@ mypy.
medios.db medios.db
medios* medios*
mypy.ini mypy.ini
\logs\* \logs\*
logs

View File

@@ -100,8 +100,8 @@ def _resolve_verify_value(verify_ssl: bool) -> Union[bool, str]:
pass pass
return None return None
# Prefer pip_system_certs if available # Prefer helpful modules if available (use safe checks to avoid first-chance import errors)
for mod_name in ("pip_system_certs",): for mod_name in ("pip_system_certs", "certifi_win32"):
path = _try_module_bundle(mod_name) path = _try_module_bundle(mod_name)
if path: if path:
try: try:
@@ -111,29 +111,18 @@ def _resolve_verify_value(verify_ssl: bool) -> Union[bool, str]:
logger.info(f"SSL_CERT_FILE not set; using bundle from {mod_name}: {path}") logger.info(f"SSL_CERT_FILE not set; using bundle from {mod_name}: {path}")
return path return path
# Special-case helpers that merge system certs (eg. certifi_win32) # Fallback to certifi
try: try:
import certifi_win32 as _cw # type: ignore import certifi # type: ignore
if hasattr(_cw, "add_windows_store_certs") and callable(_cw.add_windows_store_certs):
try:
_cw.add_windows_store_certs()
except Exception:
pass
try:
import certifi # type: ignore
path = certifi.where() path = certifi.where()
if path: if path:
try: try:
os.environ["SSL_CERT_FILE"] = path os.environ["SSL_CERT_FILE"] = path
except Exception:
pass
logger.info(
f"SSL_CERT_FILE not set; using certifi bundle after certifi_win32: {path}"
)
return path
except Exception: except Exception:
pass pass
logger.info(f"SSL_CERT_FILE not set; using certifi bundle: {path}")
return path
except Exception: except Exception:
pass pass

View File

@@ -234,7 +234,7 @@
"ddl\\.to/([0-9a-zA-Z]{12})" "ddl\\.to/([0-9a-zA-Z]{12})"
], ],
"regexp": "((ddownload\\.com/[0-9a-zA-Z]{12}))|(ddl\\.to/([0-9a-zA-Z]{12}))", "regexp": "((ddownload\\.com/[0-9a-zA-Z]{12}))|(ddl\\.to/([0-9a-zA-Z]{12}))",
"status": false "status": true
}, },
"dropapk": { "dropapk": {
"name": "dropapk", "name": "dropapk",
@@ -622,7 +622,7 @@
"(simfileshare\\.net/download/[0-9]+/)" "(simfileshare\\.net/download/[0-9]+/)"
], ],
"regexp": "(simfileshare\\.net/download/[0-9]+/)", "regexp": "(simfileshare\\.net/download/[0-9]+/)",
"status": true "status": false
}, },
"streamtape": { "streamtape": {
"name": "streamtape", "name": "streamtape",
@@ -4759,6 +4759,17 @@
], ],
"regexp": "(https?://(?:www\\.)?eroprofile\\.com/m/videos/album/([^/]+))|(https?://(?:www\\.)?eroprofile\\.com/m/videos/view/([^/]+))" "regexp": "(https?://(?:www\\.)?eroprofile\\.com/m/videos/album/([^/]+))|(https?://(?:www\\.)?eroprofile\\.com/m/videos/view/([^/]+))"
}, },
"errarhiiv": {
"name": "errarhiiv",
"type": "free",
"domains": [
"arhiiv.err.ee"
],
"regexps": [
"https://arhiiv\\.err\\.ee/video/(?:vaata/)?([^/?#]+)"
],
"regexp": "https://arhiiv\\.err\\.ee/video/(?:vaata/)?([^/?#]+)"
},
"errjupiter": { "errjupiter": {
"name": "errjupiter", "name": "errjupiter",
"type": "free", "type": "free",
@@ -5315,6 +5326,19 @@
], ],
"regexp": "https?://(?:www\\.)?radiofrance\\.fr/(?:franceculture|franceinfo|franceinter|francemusique|fip|mouv)/podcasts/(?:[^?#]+/)?([^?#]+)-(\\d{6,})(?:$|[?#])" "regexp": "https?://(?:www\\.)?radiofrance\\.fr/(?:franceculture|franceinfo|franceinter|francemusique|fip|mouv)/podcasts/(?:[^?#]+/)?([^?#]+)-(\\d{6,})(?:$|[?#])"
}, },
"franceinfo": {
"name": "franceinfo",
"type": "free",
"domains": [
"francetvinfo.fr",
"france3-regions.francetvinfo.fr",
"franceinfo.fr"
],
"regexps": [
"https?://(?:www|mobile|france3-regions)\\.france(?:tv)?info.fr/(?:[^/?#]+/)*([^/?#&.]+)"
],
"regexp": "https?://(?:www|mobile|france3-regions)\\.france(?:tv)?info.fr/(?:[^/?#]+/)*([^/?#&.]+)"
},
"franceinter": { "franceinter": {
"name": "franceinter", "name": "franceinter",
"type": "free", "type": "free",
@@ -5337,18 +5361,6 @@
], ],
"regexp": "(francetv:([^@#]+))|(https?://(?:(?:www\\.)?france\\.tv|mobile\\.france\\.tv)/(?:[^/]+/)*([^/]+)\\.html)" "regexp": "(francetv:([^@#]+))|(https?://(?:(?:www\\.)?france\\.tv|mobile\\.france\\.tv)/(?:[^/]+/)*([^/]+)\\.html)"
}, },
"francetvinfo.fr": {
"name": "francetvinfo.fr",
"type": "free",
"domains": [
"francetvinfo.fr",
"france3-regions.francetvinfo.fr"
],
"regexps": [
"https?://(?:www|mobile|france3-regions)\\.francetvinfo\\.fr/(?:[^/]+/)*([^/?#&.]+)"
],
"regexp": "https?://(?:www|mobile|france3-regions)\\.francetvinfo\\.fr/(?:[^/]+/)*([^/?#&.]+)"
},
"freesound": { "freesound": {
"name": "freesound", "name": "freesound",
"type": "free", "type": "free",
@@ -9760,7 +9772,7 @@
"name": "nitter", "name": "nitter",
"type": "free", "type": "free",
"domains": [ "domains": [
"nitter.projectsegfau.lt" "nitter.fdn.fr"
], ],
"regexps": [ "regexps": [
"https?://(?:3nzoldnxplag42gqjs23xvghtzf6t6yzssrtytnntc6ppc7xxuoneoad\\.onion|nitter\\.l4qlywnpwqsluw65ts7md3khrivpirse744un3x7mlskqauz5pyuzgqd\\.onion|nitter7bryz3jv7e3uekphigvmoyoem4al3fynerxkj22dmoxoq553qd\\.onion|npf37k3mtzwxreiw52ccs5ay4e6qt2fkcs2ndieurdyn2cuzzsfyfvid\\.onion|nitter\\.v6vgyqpa7yefkorazmg5d5fimstmvm2vtbirt6676mt7qmllrcnwycqd\\.onion|i23nv6w3juvzlw32xzoxcqzktegd4i4fu3nmnc2ewv4ggiu4ledwklad\\.onion|26oq3gioiwcmfojub37nz5gzbkdiqp7fue5kvye7d4txv4ny6fb4wwid\\.onion|vfaomgh4jxphpbdfizkm5gbtjahmei234giqj4facbwhrfjtcldauqad\\.onion|iwgu3cv7ywf3gssed5iqtavmrlszgsxazkmwwnt4h2kdait75thdyrqd\\.onion|erpnncl5nhyji3c32dcfmztujtl3xaddqb457jsbkulq24zqq7ifdgad\\.onion|ckzuw5misyahmg7j5t5xwwuj3bwy62jfolxyux4brfflramzsvvd3syd\\.onion|jebqj47jgxleaiosfcxfibx2xdahjettuydlxbg64azd4khsxv6kawid\\.onion|nttr2iupbb6fazdpr2rgbooon2tzbbsvvkagkgkwohhodjzj43stxhad\\.onion|nitraeju2mipeziu2wtcrqsxg7h62v5y4eqgwi75uprynkj74gevvuqd\\.onion|nitter\\.lqs5fjmajyp7rvp4qvyubwofzi6d4imua7vs237rkc4m5qogitqwrgyd\\.onion|ibsboeui2im5o7dxnik3s5yghufumgy5abevtij5nbizequfpu4qi4ad\\.onion|ec5nvbycpfa5k6ro77blxgkyrzbkv7uy6r5cngcbkadtjj2733nm3uyd\\.onion|nitter\\.i2p|u6ikd6zndl3c4dsdq4mmujpntgeevdk5qzkfb57r4tnfeccrn2qa\\.b32\\.i2p|nitterlgj3n5fgwesu3vxc5h67ruku33nqaoeoocae2mvlzhsu6k7fqd\\.onion|nitter\\.lacontrevoie\\.fr|nitter\\.fdn\\.fr|nitter\\.1d4\\.us|nitter\\.kavin\\.rocks|nitter\\.unixfox\\.eu|nitter\\.domain\\.glass|nitter\\.namazso\\.eu|birdsite\\.xanny\\.family|nitter\\.moomoo\\.me|bird\\.trom\\.tf|nitter\\.it|twitter\\.censors\\.us|nitter\\.grimneko\\.de|twitter\\.076\\.ne\\.jp|nitter\\.fly\\.dev|notabird\\.site|nitter\\.weiler\\.rocks|nitter\\.sethforprivacy\\.com|nitter\\.cutelab\\.space|nitter\\.nl|nitter\\.mint\\.lgbt|nitter\\.bus\\-hit\\.me|nitter\\.esmailelbob\\.xyz|tw\\.artemislena\\.eu|nitter\\.winscloud\\.net|nitter\\.tiekoetter\\.com|nitter\\.spaceint\\.fr|nitter\\.privacy\\.com\\.de|nitter\\.poast\\.org|nitter\\.bird\\.froth\\.zone|nitter\\.dcs0\\.hu|twitter\\.dr460nf1r3\\.org|nitter\\.garudalinux\\.org|twitter\\.femboy\\.hu|nitter\\.cz|nitter\\.privacydev\\.net|nitter\\.evil\\.site|tweet\\.lambda\\.dance|nitter\\.kylrth\\.com|nitter\\.foss\\.wtf|nitter\\.priv\\.pw|nitter\\.tokhmi\\.xyz|nitter\\.catalyst\\.sx|unofficialbird\\.com|nitter\\.projectsegfau\\.lt|nitter\\.eu\\.projectsegfau\\.lt|singapore\\.unofficialbird\\.com|canada\\.unofficialbird\\.com|india\\.unofficialbird\\.com|nederland\\.unofficialbird\\.com|uk\\.unofficialbird\\.com|n\\.l5\\.ca|nitter\\.slipfox\\.xyz|nitter\\.soopy\\.moe|nitter\\.qwik\\.space|read\\.whatever\\.social|nitter\\.rawbit\\.ninja|nt\\.vern\\.cc|ntr\\.odyssey346\\.dev|nitter\\.ir|nitter\\.privacytools\\.io|nitter\\.sneed\\.network|n\\.sneed\\.network|nitter\\.manasiwibi\\.com|nitter\\.smnz\\.de|nitter\\.twei\\.space|nitter\\.inpt\\.fr|nitter\\.d420\\.de|nitter\\.caioalonso\\.com|nitter\\.at|nitter\\.drivet\\.xyz|nitter\\.pw|nitter\\.nicfab\\.eu|bird\\.habedieeh\\.re|nitter\\.hostux\\.net|nitter\\.adminforge\\.de|nitter\\.platypush\\.tech|nitter\\.mask\\.sh|nitter\\.pufe\\.org|nitter\\.us\\.projectsegfau\\.lt|nitter\\.arcticfoxes\\.net|t\\.com\\.sb|nitter\\.kling\\.gg|nitter\\.ktachibana\\.party|nitter\\.riverside\\.rocks|nitter\\.girlboss\\.ceo|nitter\\.lunar\\.icu|twitter\\.moe\\.ngo|nitter\\.freedit\\.eu|ntr\\.frail\\.duckdns\\.org|nitter\\.librenode\\.org|n\\.opnxng\\.com|nitter\\.plus\\.st|nitter\\.ethibox\\.fr|nitter\\.net|is\\-nitter\\.resolv\\.ee|lu\\-nitter\\.resolv\\.ee|nitter\\.13ad\\.de|nitter\\.40two\\.app|nitter\\.cattube\\.org|nitter\\.cc|nitter\\.dark\\.fail|nitter\\.himiko\\.cloud|nitter\\.koyu\\.space|nitter\\.mailstation\\.de|nitter\\.mastodont\\.cat|nitter\\.tedomum\\.net|nitter\\.tokhmi\\.xyz|nitter\\.weaponizedhumiliation\\.com|nitter\\.vxempire\\.xyz|tweet\\.lambda\\.dance|nitter\\.ca|nitter\\.42l\\.fr|nitter\\.pussthecat\\.org|nitter\\.nixnet\\.services|nitter\\.eu|nitter\\.actionsack\\.com|nitter\\.hu|twitr\\.gq|nittereu\\.moomoo\\.me|bird\\.from\\.tf|twitter\\.grimneko\\.de|nitter\\.alefvanoon\\.xyz|n\\.hyperborea\\.cloud|twitter\\.mstdn\\.social|nitter\\.silkky\\.cloud|nttr\\.stream|fuckthesacklers\\.network|nitter\\.govt\\.land|nitter\\.datatunnel\\.xyz|de\\.nttr\\.stream|twtr\\.bch\\.bar|nitter\\.exonip\\.de|nitter\\.mastodon\\.pro|nitter\\.notraxx\\.ch|nitter\\.skrep\\.in|nitter\\.snopyta\\.org)/(.+)/status/([0-9]+)(#.)?" "https?://(?:3nzoldnxplag42gqjs23xvghtzf6t6yzssrtytnntc6ppc7xxuoneoad\\.onion|nitter\\.l4qlywnpwqsluw65ts7md3khrivpirse744un3x7mlskqauz5pyuzgqd\\.onion|nitter7bryz3jv7e3uekphigvmoyoem4al3fynerxkj22dmoxoq553qd\\.onion|npf37k3mtzwxreiw52ccs5ay4e6qt2fkcs2ndieurdyn2cuzzsfyfvid\\.onion|nitter\\.v6vgyqpa7yefkorazmg5d5fimstmvm2vtbirt6676mt7qmllrcnwycqd\\.onion|i23nv6w3juvzlw32xzoxcqzktegd4i4fu3nmnc2ewv4ggiu4ledwklad\\.onion|26oq3gioiwcmfojub37nz5gzbkdiqp7fue5kvye7d4txv4ny6fb4wwid\\.onion|vfaomgh4jxphpbdfizkm5gbtjahmei234giqj4facbwhrfjtcldauqad\\.onion|iwgu3cv7ywf3gssed5iqtavmrlszgsxazkmwwnt4h2kdait75thdyrqd\\.onion|erpnncl5nhyji3c32dcfmztujtl3xaddqb457jsbkulq24zqq7ifdgad\\.onion|ckzuw5misyahmg7j5t5xwwuj3bwy62jfolxyux4brfflramzsvvd3syd\\.onion|jebqj47jgxleaiosfcxfibx2xdahjettuydlxbg64azd4khsxv6kawid\\.onion|nttr2iupbb6fazdpr2rgbooon2tzbbsvvkagkgkwohhodjzj43stxhad\\.onion|nitraeju2mipeziu2wtcrqsxg7h62v5y4eqgwi75uprynkj74gevvuqd\\.onion|nitter\\.lqs5fjmajyp7rvp4qvyubwofzi6d4imua7vs237rkc4m5qogitqwrgyd\\.onion|ibsboeui2im5o7dxnik3s5yghufumgy5abevtij5nbizequfpu4qi4ad\\.onion|ec5nvbycpfa5k6ro77blxgkyrzbkv7uy6r5cngcbkadtjj2733nm3uyd\\.onion|nitter\\.i2p|u6ikd6zndl3c4dsdq4mmujpntgeevdk5qzkfb57r4tnfeccrn2qa\\.b32\\.i2p|nitterlgj3n5fgwesu3vxc5h67ruku33nqaoeoocae2mvlzhsu6k7fqd\\.onion|nitter\\.lacontrevoie\\.fr|nitter\\.fdn\\.fr|nitter\\.1d4\\.us|nitter\\.kavin\\.rocks|nitter\\.unixfox\\.eu|nitter\\.domain\\.glass|nitter\\.namazso\\.eu|birdsite\\.xanny\\.family|nitter\\.moomoo\\.me|bird\\.trom\\.tf|nitter\\.it|twitter\\.censors\\.us|nitter\\.grimneko\\.de|twitter\\.076\\.ne\\.jp|nitter\\.fly\\.dev|notabird\\.site|nitter\\.weiler\\.rocks|nitter\\.sethforprivacy\\.com|nitter\\.cutelab\\.space|nitter\\.nl|nitter\\.mint\\.lgbt|nitter\\.bus\\-hit\\.me|nitter\\.esmailelbob\\.xyz|tw\\.artemislena\\.eu|nitter\\.winscloud\\.net|nitter\\.tiekoetter\\.com|nitter\\.spaceint\\.fr|nitter\\.privacy\\.com\\.de|nitter\\.poast\\.org|nitter\\.bird\\.froth\\.zone|nitter\\.dcs0\\.hu|twitter\\.dr460nf1r3\\.org|nitter\\.garudalinux\\.org|twitter\\.femboy\\.hu|nitter\\.cz|nitter\\.privacydev\\.net|nitter\\.evil\\.site|tweet\\.lambda\\.dance|nitter\\.kylrth\\.com|nitter\\.foss\\.wtf|nitter\\.priv\\.pw|nitter\\.tokhmi\\.xyz|nitter\\.catalyst\\.sx|unofficialbird\\.com|nitter\\.projectsegfau\\.lt|nitter\\.eu\\.projectsegfau\\.lt|singapore\\.unofficialbird\\.com|canada\\.unofficialbird\\.com|india\\.unofficialbird\\.com|nederland\\.unofficialbird\\.com|uk\\.unofficialbird\\.com|n\\.l5\\.ca|nitter\\.slipfox\\.xyz|nitter\\.soopy\\.moe|nitter\\.qwik\\.space|read\\.whatever\\.social|nitter\\.rawbit\\.ninja|nt\\.vern\\.cc|ntr\\.odyssey346\\.dev|nitter\\.ir|nitter\\.privacytools\\.io|nitter\\.sneed\\.network|n\\.sneed\\.network|nitter\\.manasiwibi\\.com|nitter\\.smnz\\.de|nitter\\.twei\\.space|nitter\\.inpt\\.fr|nitter\\.d420\\.de|nitter\\.caioalonso\\.com|nitter\\.at|nitter\\.drivet\\.xyz|nitter\\.pw|nitter\\.nicfab\\.eu|bird\\.habedieeh\\.re|nitter\\.hostux\\.net|nitter\\.adminforge\\.de|nitter\\.platypush\\.tech|nitter\\.mask\\.sh|nitter\\.pufe\\.org|nitter\\.us\\.projectsegfau\\.lt|nitter\\.arcticfoxes\\.net|t\\.com\\.sb|nitter\\.kling\\.gg|nitter\\.ktachibana\\.party|nitter\\.riverside\\.rocks|nitter\\.girlboss\\.ceo|nitter\\.lunar\\.icu|twitter\\.moe\\.ngo|nitter\\.freedit\\.eu|ntr\\.frail\\.duckdns\\.org|nitter\\.librenode\\.org|n\\.opnxng\\.com|nitter\\.plus\\.st|nitter\\.ethibox\\.fr|nitter\\.net|is\\-nitter\\.resolv\\.ee|lu\\-nitter\\.resolv\\.ee|nitter\\.13ad\\.de|nitter\\.40two\\.app|nitter\\.cattube\\.org|nitter\\.cc|nitter\\.dark\\.fail|nitter\\.himiko\\.cloud|nitter\\.koyu\\.space|nitter\\.mailstation\\.de|nitter\\.mastodont\\.cat|nitter\\.tedomum\\.net|nitter\\.tokhmi\\.xyz|nitter\\.weaponizedhumiliation\\.com|nitter\\.vxempire\\.xyz|tweet\\.lambda\\.dance|nitter\\.ca|nitter\\.42l\\.fr|nitter\\.pussthecat\\.org|nitter\\.nixnet\\.services|nitter\\.eu|nitter\\.actionsack\\.com|nitter\\.hu|twitr\\.gq|nittereu\\.moomoo\\.me|bird\\.from\\.tf|twitter\\.grimneko\\.de|nitter\\.alefvanoon\\.xyz|n\\.hyperborea\\.cloud|twitter\\.mstdn\\.social|nitter\\.silkky\\.cloud|nttr\\.stream|fuckthesacklers\\.network|nitter\\.govt\\.land|nitter\\.datatunnel\\.xyz|de\\.nttr\\.stream|twtr\\.bch\\.bar|nitter\\.exonip\\.de|nitter\\.mastodon\\.pro|nitter\\.notraxx\\.ch|nitter\\.skrep\\.in|nitter\\.snopyta\\.org)/(.+)/status/([0-9]+)(#.)?"
@@ -14557,9 +14569,9 @@
"watch.thechosen.tv" "watch.thechosen.tv"
], ],
"regexps": [ "regexps": [
"https?://(?:www\\.)?watch\\.thechosen\\.tv/video/([0-9]+)" "https?://(?:www\\.)?watch\\.thechosen\\.tv/watch/([0-9]+)"
], ],
"regexp": "https?://(?:www\\.)?watch\\.thechosen\\.tv/video/([0-9]+)" "regexp": "https?://(?:www\\.)?watch\\.thechosen\\.tv/watch/([0-9]+)"
}, },
"thechosengroup": { "thechosengroup": {
"name": "thechosengroup", "name": "thechosengroup",
@@ -16353,9 +16365,11 @@
"volej.tv" "volej.tv"
], ],
"regexps": [ "regexps": [
"https?://volej\\.tv/video/(\\d+)" "https?://volej\\.tv/kategorie/([^/$?]+)",
"https?://volej\\.tv/klub/(\\d+)",
"https?://volej\\.tv/match/(\\d+)"
], ],
"regexp": "https?://volej\\.tv/video/(\\d+)" "regexp": "(https?://volej\\.tv/kategorie/([^/$?]+))|(https?://volej\\.tv/klub/(\\d+))|(https?://volej\\.tv/match/(\\d+))"
}, },
"voxmedia": { "voxmedia": {
"name": "voxmedia", "name": "voxmedia",

View File

@@ -2,6 +2,7 @@ from __future__ import annotations
import sqlite3 import sqlite3
import json import json
import ast
import threading import threading
import os import os
from queue import Queue from queue import Queue
@@ -396,6 +397,9 @@ def rows_to_config(rows) -> Dict[str, Any]:
# Conservative JSON parsing: only attempt to decode when the value # Conservative JSON parsing: only attempt to decode when the value
# looks like JSON (object/array/quoted string/true/false/null/number). # looks like JSON (object/array/quoted string/true/false/null/number).
# If JSON decoding fails, also attempt Python literal parsing (e.g., single-quoted
# dict/list reprs) using ast.literal_eval as a safe fallback. If both
# attempts fail, use the raw string value.
parsed_val = val parsed_val = val
try: try:
if isinstance(val, str): if isinstance(val, str):
@@ -409,14 +413,26 @@ def rows_to_config(rows) -> Dict[str, Any]:
try: try:
parsed_val = json.loads(val) parsed_val = json.loads(val)
except Exception: except Exception:
parsed_val = val # Try parsing Python literal formats (single-quoted dicts/lists)
try:
parsed_val = ast.literal_eval(val)
debug(f"Parsed config value for key '{key}' using ast.literal_eval (non-JSON literal)")
except Exception:
parsed_val = val
else: else:
parsed_val = val parsed_val = val
else: else:
try: try:
parsed_val = json.loads(val) parsed_val = json.loads(val)
except Exception: except Exception:
parsed_val = val # Non-string values can sometimes be bytes or Python literals; try decoding when appropriate
try:
if isinstance(val, (bytes, bytearray)):
parsed_val = json.loads(val.decode('utf-8', errors='replace'))
else:
parsed_val = val
except Exception:
parsed_val = val
except Exception: except Exception:
parsed_val = val parsed_val = val

View File

@@ -586,6 +586,52 @@ class search_file(Cmdlet):
if store_filter and not storage_backend: if store_filter and not storage_backend:
storage_backend = store_filter storage_backend = store_filter
# If the user accidentally used `-store <provider>` or `store:<provider>`,
# prefer to treat it as a provider search (providers like 'alldebrid' are not store backends).
try:
from Store.registry import list_configured_backend_names
providers_map = list_search_providers(config)
configured = list_configured_backend_names(config or {})
if storage_backend:
matched = None
for p in (providers_map or {}):
if str(p).strip().lower() == str(storage_backend).strip().lower():
matched = p
break
if matched and str(storage_backend) not in configured:
log(f"Note: Treating '-store {storage_backend}' as provider search for '{matched}'", file=sys.stderr)
return self._run_provider_search(
provider_name=matched,
query=query,
limit=limit,
limit_set=limit_set,
open_id=open_id,
args_list=args_list,
refresh_mode=refresh_mode,
config=config,
)
elif store_filter:
matched = None
for p in (providers_map or {}):
if str(p).strip().lower() == str(store_filter).strip().lower():
matched = p
break
if matched and str(store_filter) not in configured:
log(f"Note: Treating 'store:{store_filter}' as provider search for '{matched}'", file=sys.stderr)
return self._run_provider_search(
provider_name=matched,
query=query,
limit=limit,
limit_set=limit_set,
open_id=open_id,
args_list=args_list,
refresh_mode=refresh_mode,
config=config,
)
except Exception:
# Be conservative: if provider detection fails, fall back to store behaviour
pass
hash_query = parse_hash_query(query) hash_query = parse_hash_query(query)
if not query: if not query:
@@ -644,6 +690,8 @@ class search_file(Cmdlet):
from Store._base import Store as BaseStore from Store._base import Store as BaseStore
backend_to_search = storage_backend or None backend_to_search = storage_backend or None
if hash_query: if hash_query:
# Explicit hash list search: build rows from backend metadata. # Explicit hash list search: build rows from backend metadata.
backends_to_try: List[str] = [] backends_to_try: List[str] = []

View File

@@ -567,3 +567,4 @@ http://10.162.158.28:45899/get_files/file?hash=5c7296f1a5544522e3d118f60080e0389
2026-01-31T03:13:05.258091Z [DEBUG] logger.debug: DEBUG: <rich.panel.Panel object at 0x00000161B7383D10> 2026-01-31T03:13:05.258091Z [DEBUG] logger.debug: DEBUG: <rich.panel.Panel object at 0x00000161B7383D10>
2026-01-31T03:13:22.207331Z [DEBUG] logger.debug: DEBUG: <rich.panel.Panel object at 0x00000161B7383D10> 2026-01-31T03:13:22.207331Z [DEBUG] logger.debug: DEBUG: <rich.panel.Panel object at 0x00000161B7383D10>
2026-01-31T03:13:39.166965Z [DEBUG] alldebrid.search: [alldebrid] Failed to list account magnets: AllDebrid API error: The auth apikey is invalid 2026-01-31T03:13:39.166965Z [DEBUG] alldebrid.search: [alldebrid] Failed to list account magnets: AllDebrid API error: The auth apikey is invalid
2026-02-01T00:05:13.728816Z [DEBUG] logger.debug: DEBUG: [Store] Unknown store type 'debrid'