h
This commit is contained in:
@@ -339,7 +339,7 @@
|
|||||||
"(file\\.al/[0-9a-zA-Z]{12})"
|
"(file\\.al/[0-9a-zA-Z]{12})"
|
||||||
],
|
],
|
||||||
"regexp": "(file\\.al/[0-9a-zA-Z]{12})",
|
"regexp": "(file\\.al/[0-9a-zA-Z]{12})",
|
||||||
"status": true
|
"status": false
|
||||||
},
|
},
|
||||||
"filedot": {
|
"filedot": {
|
||||||
"name": "filedot",
|
"name": "filedot",
|
||||||
@@ -477,7 +477,7 @@
|
|||||||
"isra\\.cloud/\\?op=report_file&id=([0-9a-zA-Z]{12})"
|
"isra\\.cloud/\\?op=report_file&id=([0-9a-zA-Z]{12})"
|
||||||
],
|
],
|
||||||
"regexp": "((isra\\.cloud/[0-9a-zA-Z]{12}))|(isra\\.cloud/\\?op=report_file&id=([0-9a-zA-Z]{12}))",
|
"regexp": "((isra\\.cloud/[0-9a-zA-Z]{12}))|(isra\\.cloud/\\?op=report_file&id=([0-9a-zA-Z]{12}))",
|
||||||
"status": true,
|
"status": false,
|
||||||
"hardRedirect": [
|
"hardRedirect": [
|
||||||
"isra\\.cloud/([0-9a-zA-Z]{12})"
|
"isra\\.cloud/([0-9a-zA-Z]{12})"
|
||||||
]
|
]
|
||||||
@@ -507,7 +507,7 @@
|
|||||||
"mediafire\\.com/(\\?|download/|file/|download\\.php\\?)([0-9a-z]{15})"
|
"mediafire\\.com/(\\?|download/|file/|download\\.php\\?)([0-9a-z]{15})"
|
||||||
],
|
],
|
||||||
"regexp": "mediafire\\.com/(\\?|download/|file/|download\\.php\\?)([0-9a-z]{15})",
|
"regexp": "mediafire\\.com/(\\?|download/|file/|download\\.php\\?)([0-9a-z]{15})",
|
||||||
"status": false
|
"status": true
|
||||||
},
|
},
|
||||||
"mexashare": {
|
"mexashare": {
|
||||||
"name": "mexashare",
|
"name": "mexashare",
|
||||||
|
|||||||
19
MPV/lyric.py
19
MPV/lyric.py
@@ -557,24 +557,7 @@ def _load_config_best_effort() -> dict:
|
|||||||
try:
|
try:
|
||||||
from SYS.config import load_config
|
from SYS.config import load_config
|
||||||
|
|
||||||
# `SYS.config.load_config()` defaults to loading `config.conf` from the
|
cfg = load_config()
|
||||||
# SYS/ directory, but this repo keeps `config.conf` at the repo root.
|
|
||||||
# MPV.lyric is often spawned from mpv (not the CLI), so we must locate
|
|
||||||
# the repo root ourselves.
|
|
||||||
try:
|
|
||||||
repo_root = Path(__file__).resolve().parent.parent
|
|
||||||
except Exception:
|
|
||||||
repo_root = None
|
|
||||||
|
|
||||||
cfg = None
|
|
||||||
if repo_root is not None:
|
|
||||||
try:
|
|
||||||
cfg = load_config(config_dir=repo_root)
|
|
||||||
except Exception:
|
|
||||||
cfg = None
|
|
||||||
|
|
||||||
if cfg is None:
|
|
||||||
cfg = load_config()
|
|
||||||
|
|
||||||
return cfg if isinstance(cfg, dict) else {}
|
return cfg if isinstance(cfg, dict) else {}
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|||||||
@@ -2,13 +2,12 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import re
|
|
||||||
import tempfile
|
|
||||||
import json
|
import json
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import time
|
import time
|
||||||
|
from copy import deepcopy
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Dict, Optional, List
|
from typing import Any, Dict, List, Optional, Tuple
|
||||||
from SYS.logger import log
|
from SYS.logger import log
|
||||||
from SYS.utils import expand_path
|
from SYS.utils import expand_path
|
||||||
from SYS.database import db, get_config_all, save_config_value
|
from SYS.database import db, get_config_all, save_config_value
|
||||||
@@ -16,6 +15,7 @@ from SYS.database import db, get_config_all, save_config_value
|
|||||||
SCRIPT_DIR = Path(__file__).resolve().parent
|
SCRIPT_DIR = Path(__file__).resolve().parent
|
||||||
|
|
||||||
_CONFIG_CACHE: Dict[str, Any] = {}
|
_CONFIG_CACHE: Dict[str, Any] = {}
|
||||||
|
_LAST_SAVED_CONFIG: Dict[str, Any] = {}
|
||||||
_CONFIG_SAVE_MAX_RETRIES = 5
|
_CONFIG_SAVE_MAX_RETRIES = 5
|
||||||
_CONFIG_SAVE_RETRY_DELAY = 0.15
|
_CONFIG_SAVE_RETRY_DELAY = 0.15
|
||||||
|
|
||||||
@@ -39,9 +39,10 @@ def global_config() -> List[Dict[str, Any]]:
|
|||||||
|
|
||||||
|
|
||||||
def clear_config_cache() -> None:
|
def clear_config_cache() -> None:
|
||||||
"""Clear the configuration cache."""
|
"""Clear the configuration cache and baseline snapshot."""
|
||||||
global _CONFIG_CACHE
|
global _CONFIG_CACHE, _LAST_SAVED_CONFIG
|
||||||
_CONFIG_CACHE = {}
|
_CONFIG_CACHE = {}
|
||||||
|
_LAST_SAVED_CONFIG = {}
|
||||||
|
|
||||||
|
|
||||||
def get_hydrus_instance(
|
def get_hydrus_instance(
|
||||||
@@ -334,8 +335,37 @@ def resolve_debug_log(config: Dict[str, Any]) -> Optional[Path]:
|
|||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
def _flatten_config_entries(config: Dict[str, Any]) -> Dict[Tuple[str, str, str, str], Any]:
|
||||||
|
entries: Dict[Tuple[str, str, str, str], Any] = {}
|
||||||
|
for key, value in config.items():
|
||||||
|
if key in ('store', 'provider', 'tool') and isinstance(value, dict):
|
||||||
|
for subtype, instances in value.items():
|
||||||
|
if not isinstance(instances, dict):
|
||||||
|
continue
|
||||||
|
if key == 'store':
|
||||||
|
for name, settings in instances.items():
|
||||||
|
if not isinstance(settings, dict):
|
||||||
|
continue
|
||||||
|
for k, v in settings.items():
|
||||||
|
entries[(key, subtype, name, k)] = v
|
||||||
|
else:
|
||||||
|
for k, v in instances.items():
|
||||||
|
entries[(key, subtype, 'default', k)] = v
|
||||||
|
elif not key.startswith('_') and value is not None:
|
||||||
|
entries[('global', 'none', 'none', key)] = value
|
||||||
|
return entries
|
||||||
|
|
||||||
|
|
||||||
|
def _count_changed_entries(old_config: Dict[str, Any], new_config: Dict[str, Any]) -> int:
|
||||||
|
old_entries = _flatten_config_entries(old_config or {})
|
||||||
|
new_entries = _flatten_config_entries(new_config or {})
|
||||||
|
changed = {k for k, v in new_entries.items() if old_entries.get(k) != v}
|
||||||
|
removed = {k for k in old_entries if k not in new_entries}
|
||||||
|
return len(changed) + len(removed)
|
||||||
|
|
||||||
|
|
||||||
def load_config() -> Dict[str, Any]:
|
def load_config() -> Dict[str, Any]:
|
||||||
global _CONFIG_CACHE
|
global _CONFIG_CACHE, _LAST_SAVED_CONFIG
|
||||||
if _CONFIG_CACHE:
|
if _CONFIG_CACHE:
|
||||||
return _CONFIG_CACHE
|
return _CONFIG_CACHE
|
||||||
|
|
||||||
@@ -343,8 +373,10 @@ def load_config() -> Dict[str, Any]:
|
|||||||
db_config = get_config_all()
|
db_config = get_config_all()
|
||||||
if db_config:
|
if db_config:
|
||||||
_CONFIG_CACHE = db_config
|
_CONFIG_CACHE = db_config
|
||||||
|
_LAST_SAVED_CONFIG = deepcopy(db_config)
|
||||||
return db_config
|
return db_config
|
||||||
|
|
||||||
|
_LAST_SAVED_CONFIG = {}
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
@@ -354,6 +386,10 @@ def reload_config() -> Dict[str, Any]:
|
|||||||
|
|
||||||
|
|
||||||
def save_config(config: Dict[str, Any]) -> int:
|
def save_config(config: Dict[str, Any]) -> int:
|
||||||
|
global _CONFIG_CACHE, _LAST_SAVED_CONFIG
|
||||||
|
previous_config = deepcopy(_LAST_SAVED_CONFIG)
|
||||||
|
changed_count = _count_changed_entries(previous_config, config)
|
||||||
|
|
||||||
def _write_entries() -> int:
|
def _write_entries() -> int:
|
||||||
count = 0
|
count = 0
|
||||||
with db.transaction():
|
with db.transaction():
|
||||||
@@ -384,7 +420,10 @@ def save_config(config: Dict[str, Any]) -> int:
|
|||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
saved_entries = _write_entries()
|
saved_entries = _write_entries()
|
||||||
log(f"Synced {saved_entries} entries to {db.db_path}")
|
log(
|
||||||
|
f"Synced {saved_entries} entries to {db.db_path} "
|
||||||
|
f"({changed_count} changed entries)"
|
||||||
|
)
|
||||||
break
|
break
|
||||||
except sqlite3.OperationalError as exc:
|
except sqlite3.OperationalError as exc:
|
||||||
attempts += 1
|
attempts += 1
|
||||||
@@ -400,8 +439,8 @@ def save_config(config: Dict[str, Any]) -> int:
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
clear_config_cache()
|
clear_config_cache()
|
||||||
global _CONFIG_CACHE
|
|
||||||
_CONFIG_CACHE = config
|
_CONFIG_CACHE = config
|
||||||
|
_LAST_SAVED_CONFIG = deepcopy(config)
|
||||||
return saved_entries
|
return saved_entries
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -182,11 +182,9 @@ def _strip_value_quotes(value: str) -> str:
|
|||||||
|
|
||||||
def _run(piped_result: Any, args: List[str], config: Dict[str, Any]) -> int:
|
def _run(piped_result: Any, args: List[str], config: Dict[str, Any]) -> int:
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
|
||||||
|
# Load configuration from the database
|
||||||
# Load from workspace root, not SYS directory
|
current_config = load_config()
|
||||||
workspace_root = Path(__file__).resolve().parent.parent
|
|
||||||
current_config = load_config(config_dir=workspace_root)
|
|
||||||
|
|
||||||
selection_key = _get_selected_config_key()
|
selection_key = _get_selected_config_key()
|
||||||
value_from_args = _extract_value_arg(args) if selection_key else None
|
value_from_args = _extract_value_arg(args) if selection_key else None
|
||||||
@@ -202,7 +200,7 @@ 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)
|
||||||
save_config(current_config, config_dir=workspace_root)
|
save_config(current_config)
|
||||||
print(f"Updated '{selection_key}' to '{new_value}'")
|
print(f"Updated '{selection_key}' to '{new_value}'")
|
||||||
return 0
|
return 0
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
@@ -235,7 +233,7 @@ def _run(piped_result: Any, args: List[str], config: Dict[str, Any]) -> int:
|
|||||||
from cmdlet._shared import SharedArgs
|
from cmdlet._shared import SharedArgs
|
||||||
from cmdnat.status import CMDLET as STATUS_CMDLET
|
from cmdnat.status import CMDLET as STATUS_CMDLET
|
||||||
# We reload the config one more time because it might have changed on disk
|
# We reload the config one more time because it might have changed on disk
|
||||||
fresh_config = load_config(config_dir=workspace_root)
|
fresh_config = load_config()
|
||||||
|
|
||||||
# Force refresh of shared caches (especially stores)
|
# Force refresh of shared caches (especially stores)
|
||||||
SharedArgs._refresh_store_choices_cache(fresh_config)
|
SharedArgs._refresh_store_choices_cache(fresh_config)
|
||||||
@@ -261,7 +259,7 @@ def _run(piped_result: Any, args: List[str], config: Dict[str, Any]) -> int:
|
|||||||
value = _strip_value_quotes(" ".join(args[1:]))
|
value = _strip_value_quotes(" ".join(args[1:]))
|
||||||
try:
|
try:
|
||||||
set_nested_config(current_config, key, value)
|
set_nested_config(current_config, key, value)
|
||||||
save_config(current_config, config_dir=workspace_root)
|
save_config(current_config)
|
||||||
print(f"Updated '{key}' to '{value}'")
|
print(f"Updated '{key}' to '{value}'")
|
||||||
return 0
|
return 0
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
|
|||||||
Reference in New Issue
Block a user