This commit is contained in:
2026-01-23 18:40:00 -08:00
parent 883ac2a283
commit b79e3b309b
4 changed files with 57 additions and 37 deletions

View File

@@ -2,13 +2,12 @@
from __future__ import annotations
import re
import tempfile
import json
import sqlite3
import time
from copy import deepcopy
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.utils import expand_path
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
_CONFIG_CACHE: Dict[str, Any] = {}
_LAST_SAVED_CONFIG: Dict[str, Any] = {}
_CONFIG_SAVE_MAX_RETRIES = 5
_CONFIG_SAVE_RETRY_DELAY = 0.15
@@ -39,9 +39,10 @@ def global_config() -> List[Dict[str, Any]]:
def clear_config_cache() -> None:
"""Clear the configuration cache."""
global _CONFIG_CACHE
"""Clear the configuration cache and baseline snapshot."""
global _CONFIG_CACHE, _LAST_SAVED_CONFIG
_CONFIG_CACHE = {}
_LAST_SAVED_CONFIG = {}
def get_hydrus_instance(
@@ -334,8 +335,37 @@ def resolve_debug_log(config: Dict[str, Any]) -> Optional[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]:
global _CONFIG_CACHE
global _CONFIG_CACHE, _LAST_SAVED_CONFIG
if _CONFIG_CACHE:
return _CONFIG_CACHE
@@ -343,8 +373,10 @@ def load_config() -> Dict[str, Any]:
db_config = get_config_all()
if db_config:
_CONFIG_CACHE = db_config
_LAST_SAVED_CONFIG = deepcopy(db_config)
return db_config
_LAST_SAVED_CONFIG = {}
return {}
@@ -354,6 +386,10 @@ def reload_config() -> Dict[str, Any]:
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:
count = 0
with db.transaction():
@@ -384,7 +420,10 @@ def save_config(config: Dict[str, Any]) -> int:
while True:
try:
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
except sqlite3.OperationalError as exc:
attempts += 1
@@ -400,8 +439,8 @@ def save_config(config: Dict[str, Any]) -> int:
raise
clear_config_cache()
global _CONFIG_CACHE
_CONFIG_CACHE = config
_LAST_SAVED_CONFIG = deepcopy(config)
return saved_entries