This commit is contained in:
2026-01-31 21:32:51 -08:00
parent bc3dbf28e8
commit ed44d69ef1
4 changed files with 75 additions and 4 deletions

View File

@@ -800,6 +800,15 @@ def save_config_and_verify(config: Dict[str, Any], retries: int = 3, delay: floa
store_key = None store_key = None
if prov_key == expected_key or store_key == expected_key: if prov_key == expected_key or store_key == expected_key:
try:
# Log a short, masked fingerprint to aid debugging without exposing the key itself
import hashlib
fp = hashlib.sha256(expected_key.encode("utf-8")).hexdigest()[:8]
log(f"Verified AllDebrid API key persisted (fingerprint={fp})")
except Exception:
# If hashing/logging fails, don't abort the save
pass
return saved return saved
# Not yet persisted; log and retry # Not yet persisted; log and retry

View File

@@ -10,7 +10,7 @@ from textual.screen import ModalScreen
from textual.widgets import Static, Button, Input, Label, ListView, ListItem, Rule, Select, Checkbox from textual.widgets import Static, Button, Input, Label, ListView, ListItem, Rule, Select, Checkbox
from pathlib import Path from pathlib import Path
from SYS.config import load_config, save_config, reload_config, global_config, count_changed_entries, ConfigSaveConflict from SYS.config import load_config, save_config, save_config_and_verify, reload_config, global_config, count_changed_entries, ConfigSaveConflict
from SYS.database import db from SYS.database import db
from SYS.logger import log, debug from SYS.logger import log, debug
from Store.registry import _discover_store_classes, _required_keys_for from Store.registry import _discover_store_classes, _required_keys_for
@@ -1739,7 +1739,10 @@ class ConfigModal(ModalScreen):
@work(thread=True) @work(thread=True)
def _save_background(self, cfg: Dict[str, Any], changed: int) -> None: def _save_background(self, cfg: Dict[str, Any], changed: int) -> None:
try: try:
saved_entries = save_config(cfg) # Use the verified save path which will check that crucial keys
# (like AllDebrid API keys) persisted to disk. This ensures the UI
# surface reports a failure immediately if post-save verification fails.
saved_entries = save_config_and_verify(cfg)
try: try:
appobj = self.app appobj = self.app
except Exception: except Exception:
@@ -1758,6 +1761,17 @@ class ConfigModal(ModalScreen):
appobj.call_from_thread(self._on_save_complete, False, str(exc), changed, 0) appobj.call_from_thread(self._on_save_complete, False, str(exc), changed, 0)
else: else:
self._on_save_complete(False, str(exc), changed, 0) self._on_save_complete(False, str(exc), changed, 0)
except Exception as exc:
# Bubble up verification/other save errors back to the UI so the
# user knows persistent storage failed.
try:
appobj = self.app
except Exception:
appobj = None
if appobj and hasattr(appobj, 'call_from_thread'):
appobj.call_from_thread(self._on_save_complete, False, str(exc), changed, 0)
else:
self._on_save_complete(False, str(exc), changed, 0)
except Exception as exc: except Exception as exc:
try: try:
appobj = self.app appobj = self.app

View File

@@ -1,7 +1,7 @@
from typing import List, Dict, Any, Optional, Sequence from typing import List, Dict, Any, Optional, Sequence
from cmdlet._shared import Cmdlet, CmdletArg from cmdlet._shared import Cmdlet, CmdletArg
from SYS.config import load_config, save_config from SYS.config import load_config, save_config, save_config_and_verify
from SYS import pipeline as ctx from SYS import pipeline as ctx
from SYS.result_table import Table from SYS.result_table import Table
@@ -200,6 +200,19 @@ def _run(piped_result: Any, args: List[str], config: Dict[str, Any]) -> int:
new_value = _strip_value_quotes(new_value) new_value = _strip_value_quotes(new_value)
try: try:
set_nested_config(current_config, selection_key, new_value) set_nested_config(current_config, selection_key, new_value)
# For AllDebrid API changes, use the verified save path to ensure
# the new API key persisted to disk; otherwise fall back to normal save.
try:
key_l = str(selection_key or "").lower()
except Exception:
key_l = ""
if "alldebrid" in key_l or "all-debrid" in key_l:
try:
save_config_and_verify(current_config)
except Exception as exc:
print(f"Error saving configuration (verification failed): {exc}")
return 1
else:
save_config(current_config) save_config(current_config)
print(f"Updated '{selection_key}' to '{new_value}'") print(f"Updated '{selection_key}' to '{new_value}'")
return 0 return 0

View File

@@ -572,3 +572,38 @@ http://10.162.158.28:45899/get_files/file?hash=5c7296f1a5544522e3d118f60080e0389
2026-02-01T04:23:19.808488Z [DEBUG] logger.debug: DEBUG: [Store] Unknown store type 'debrid' 2026-02-01T04:23:19.808488Z [DEBUG] logger.debug: DEBUG: [Store] Unknown store type 'debrid'
2026-02-01T04:23:36.282589Z [DEBUG] search_file.run: Backend all-debrid search failed: "Unknown store backend: all-debrid. Available: ['rpi', 'local']" 2026-02-01T04:23:36.282589Z [DEBUG] search_file.run: Backend all-debrid search failed: "Unknown store backend: all-debrid. Available: ['rpi', 'local']"
2026-02-01T04:23:52.712154Z [DEBUG] logger.debug: DEBUG: [search-file] Searching 'local' 2026-02-01T04:23:52.712154Z [DEBUG] logger.debug: DEBUG: [search-file] Searching 'local'
2026-02-01T04:40:52.223912Z [DEBUG] logger.debug: DEBUG: [search-file] Calling alldebrid.search(filters={})
2026-02-01T04:41:09.154528Z [DEBUG] logger.debug: DEBUG: <rich.panel.Panel object at 0x000001DF0A29D190>
2026-02-01T04:41:26.087564Z [DEBUG] logger.debug: DEBUG: <rich.panel.Panel object at 0x000001DF0A29D190>
2026-02-01T04:41:43.108223Z [DEBUG] logger.debug: DEBUG: [search-file] alldebrid -> 50 result(s)
2026-02-01T04:42:00.084311Z [DEBUG] logger.debug: DEBUG: [search-file] Calling alldebrid.search(filters={})
2026-02-01T04:42:17.153684Z [DEBUG] logger.debug: DEBUG: <rich.panel.Panel object at 0x000001DF0A29DB50>
2026-02-01T04:42:33.940496Z [DEBUG] logger.debug: DEBUG: <rich.panel.Panel object at 0x000001DF0A29DB50>
2026-02-01T04:42:50.766611Z [DEBUG] logger.debug: DEBUG: [search-file] alldebrid -> 50 result(s)
2026-02-01T04:43:07.583583Z [DEBUG] logger.debug: DEBUG: [search-file] Calling alldebrid.search(filters={})
2026-02-01T04:43:24.248810Z [DEBUG] logger.debug: DEBUG: <rich.panel.Panel object at 0x000001DF0A29D010>
2026-02-01T04:43:40.777131Z [DEBUG] logger.debug: DEBUG: <rich.panel.Panel object at 0x000001DF0A29D010>
2026-02-01T04:43:57.669799Z [DEBUG] logger.debug: DEBUG: [search-file] alldebrid -> 50 result(s)
2026-02-01T04:45:05.508224Z [DEBUG] logger.debug: DEBUG: [download-file] run invoked with args: ['magnet:?xt=urn:btih:RO3NJTH7KWG3YIZM6ACTLJOFMF4IXK64']
2026-02-01T04:45:22.402282Z [DEBUG] logger.debug: DEBUG: Starting download-file
2026-02-01T04:45:39.392199Z [DEBUG] alldebrid.url_patterns: [alldebrid] url_patterns loaded 0 cached host domains; total patterns=2
2026-02-01T04:45:56.042183Z [DEBUG] alldebrid.url_patterns: [alldebrid] url_patterns loaded 0 cached host domains; total patterns=2
2026-02-01T04:46:12.642265Z [DEBUG] alldebrid.url_patterns: [alldebrid] url_patterns loaded 0 cached host domains; total patterns=2
2026-02-01T04:46:29.352428Z [DEBUG] logger.debug: DEBUG: Output directory: C:\Users\Admin\AppData\Local\Temp\Medios-Macina
2026-02-01T04:46:46.014474Z [DEBUG] logger.debug: DEBUG: Processing URL: magnet:?xt=urn:btih:RO3NJTH7KWG3YIZM6ACTLJOFMF4IXK64
2026-02-01T04:47:02.617436Z [DEBUG] alldebrid.url_patterns: [alldebrid] url_patterns loaded 0 cached host domains; total patterns=2
2026-02-01T04:47:19.322141Z [DEBUG] logger.debug: DEBUG: Provider alldebrid claimed magnet:?xt=urn:btih:RO3NJTH7KWG3YIZM6ACTLJOFMF4IXK64
2026-02-01T04:47:35.912588Z [DEBUG] logger.debug: DEBUG: <rich.panel.Panel object at 0x000001DF0A29DFD0>
2026-02-01T04:47:52.591623Z [DEBUG] logger.debug: DEBUG: <rich.panel.Panel object at 0x000001DF0A29DFD0>
2026-02-01T04:48:09.205544Z [DEBUG] logger.debug: DEBUG: [search-file] Calling alldebrid.search(filters={})
2026-02-01T04:48:25.895487Z [DEBUG] logger.debug: DEBUG: <rich.panel.Panel object at 0x000001DF0A29DFD0>
2026-02-01T04:48:42.505354Z [DEBUG] logger.debug: DEBUG: <rich.panel.Panel object at 0x000001DF0A29DFD0>
2026-02-01T04:48:59.158923Z [DEBUG] logger.debug: DEBUG: [search-file] alldebrid -> 1 result(s)
2026-02-01T04:49:15.817590Z [DEBUG] logger.debug: DEBUG: [alldebrid] Sent magnet 453036517 to AllDebrid for download
2026-02-01T04:49:32.492568Z [DEBUG] logger.debug: DEBUG: Provider alldebrid handled URL without file output
2026-02-01T04:49:49.187120Z [DEBUG] logger.debug: DEBUG: [download-file] Processing 0 piped item(s)...
2026-02-01T04:50:05.787087Z [DEBUG] download_file._run_impl: No downloads completed
2026-02-01T04:50:22.440968Z [DEBUG] logger.debug: DEBUG: [search-file] Calling alldebrid.search(filters={})
2026-02-01T04:50:39.033859Z [DEBUG] logger.debug: DEBUG: <rich.panel.Panel object at 0x000001DF0A29EC90>
2026-02-01T04:50:55.684809Z [DEBUG] logger.debug: DEBUG: <rich.panel.Panel object at 0x000001DF0A29EC90>
2026-02-01T04:51:12.287393Z [DEBUG] logger.debug: DEBUG: [search-file] alldebrid -> 50 result(s)