df
Some checks failed
smoke-mm / Install & smoke test mm --help (push) Has been cancelled
Some checks failed
smoke-mm / Install & smoke test mm --help (push) Has been cancelled
This commit is contained in:
90
config.py
90
config.py
@@ -1,6 +1,5 @@
|
||||
""" """
|
||||
|
||||
"""
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
@@ -76,7 +75,9 @@ def _merge_dict_inplace(base: Dict[str, Any], patch: Dict[str, Any]) -> Dict[str
|
||||
return base
|
||||
|
||||
|
||||
def _apply_conf_block(config: Dict[str, Any], kind: str, subtype: str, block: Dict[str, Any]) -> None:
|
||||
def _apply_conf_block(
|
||||
config: Dict[str, Any], kind: str, subtype: str, block: Dict[str, Any]
|
||||
) -> None:
|
||||
kind_l = str(kind).strip().lower()
|
||||
subtype_l = str(subtype).strip().lower()
|
||||
|
||||
@@ -290,23 +291,24 @@ def _serialize_conf(config: Dict[str, Any]) -> str:
|
||||
def _make_cache_key(config_dir: Optional[Path], filename: str, actual_path: Optional[Path]) -> str:
|
||||
if actual_path:
|
||||
return str(actual_path.resolve())
|
||||
base_dir = (config_dir or SCRIPT_DIR)
|
||||
base_dir = config_dir or SCRIPT_DIR
|
||||
return str((base_dir / filename).resolve())
|
||||
|
||||
|
||||
|
||||
def get_hydrus_instance(config: Dict[str, Any], instance_name: str = "home") -> Optional[Dict[str, Any]]:
|
||||
def get_hydrus_instance(
|
||||
config: Dict[str, Any], instance_name: str = "home"
|
||||
) -> Optional[Dict[str, Any]]:
|
||||
"""Get a specific Hydrus instance config by name.
|
||||
|
||||
|
||||
Supports multiple formats:
|
||||
- Current: config["store"]["hydrusnetwork"][instance_name]
|
||||
- Legacy: config["storage"]["hydrus"][instance_name]
|
||||
- Old: config["HydrusNetwork"][instance_name]
|
||||
|
||||
|
||||
Args:
|
||||
config: Configuration dict
|
||||
instance_name: Name of the Hydrus instance (default: "home")
|
||||
|
||||
|
||||
Returns:
|
||||
Dict with access key and URL, or None if not found
|
||||
"""
|
||||
@@ -323,14 +325,14 @@ def get_hydrus_instance(config: Dict[str, Any], instance_name: str = "home") ->
|
||||
|
||||
def get_hydrus_access_key(config: Dict[str, Any], instance_name: str = "home") -> Optional[str]:
|
||||
"""Get Hydrus access key for an instance.
|
||||
|
||||
|
||||
Config format:
|
||||
- config["store"]["hydrusnetwork"][name]["API"]
|
||||
|
||||
|
||||
Args:
|
||||
config: Configuration dict
|
||||
instance_name: Name of the Hydrus instance (default: "home")
|
||||
|
||||
|
||||
Returns:
|
||||
Access key string, or None if not found
|
||||
"""
|
||||
@@ -344,14 +346,14 @@ def get_hydrus_access_key(config: Dict[str, Any], instance_name: str = "home") -
|
||||
|
||||
def get_hydrus_url(config: Dict[str, Any], instance_name: str = "home") -> Optional[str]:
|
||||
"""Get Hydrus URL for an instance.
|
||||
|
||||
|
||||
Config format:
|
||||
- config["store"]["hydrusnetwork"][name]["URL"]
|
||||
|
||||
|
||||
Args:
|
||||
config: Configuration dict
|
||||
instance_name: Name of the Hydrus instance (default: "home")
|
||||
|
||||
|
||||
Returns:
|
||||
URL string, or None if not found
|
||||
"""
|
||||
@@ -380,15 +382,14 @@ def get_soulseek_password(config: Dict[str, Any]) -> Optional[str]:
|
||||
return str(val).strip() if val else None
|
||||
|
||||
|
||||
|
||||
def resolve_output_dir(config: Dict[str, Any]) -> Path:
|
||||
"""Resolve output directory from config with single source of truth.
|
||||
|
||||
|
||||
Priority:
|
||||
1. config["temp"] - explicitly set temp/output directory
|
||||
2. config["outfile"] - fallback to outfile setting
|
||||
3. Home/Videos - safe user directory fallback
|
||||
|
||||
|
||||
Returns:
|
||||
Path to output directory
|
||||
"""
|
||||
@@ -402,7 +403,7 @@ def resolve_output_dir(config: Dict[str, Any]) -> Path:
|
||||
return path
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
# Then try outfile setting
|
||||
outfile_value = config.get("outfile")
|
||||
if outfile_value:
|
||||
@@ -410,22 +411,22 @@ def resolve_output_dir(config: Dict[str, Any]) -> Path:
|
||||
return Path(str(outfile_value)).expanduser()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
# Fallback to user's Videos directory
|
||||
return Path.home() / "Videos"
|
||||
|
||||
|
||||
def get_local_storage_path(config: Dict[str, Any]) -> Optional[Path]:
|
||||
"""Get local storage path from config.
|
||||
|
||||
|
||||
Supports multiple formats:
|
||||
- New: config["store"]["folder"]["default"]["path"]
|
||||
- Old: config["storage"]["local"]["path"]
|
||||
- Old: config["Local"]["path"]
|
||||
|
||||
|
||||
Args:
|
||||
config: Configuration dict
|
||||
|
||||
|
||||
Returns:
|
||||
Path object if found, None otherwise
|
||||
"""
|
||||
@@ -439,7 +440,7 @@ def get_local_storage_path(config: Dict[str, Any]) -> Optional[Path]:
|
||||
path_str = default_config.get("path")
|
||||
if path_str:
|
||||
return Path(str(path_str)).expanduser()
|
||||
|
||||
|
||||
# Fall back to storage.local.path format
|
||||
storage = config.get("storage", {})
|
||||
if isinstance(storage, dict):
|
||||
@@ -448,14 +449,14 @@ def get_local_storage_path(config: Dict[str, Any]) -> Optional[Path]:
|
||||
path_str = local_config.get("path")
|
||||
if path_str:
|
||||
return Path(str(path_str)).expanduser()
|
||||
|
||||
|
||||
# Fall back to old Local format
|
||||
local_config = config.get("Local", {})
|
||||
if isinstance(local_config, dict):
|
||||
path_str = local_config.get("path")
|
||||
if path_str:
|
||||
return Path(str(path_str)).expanduser()
|
||||
|
||||
|
||||
return None
|
||||
|
||||
|
||||
@@ -465,11 +466,11 @@ def get_debrid_api_key(config: Dict[str, Any], service: str = "All-debrid") -> O
|
||||
Config format:
|
||||
- config["store"]["debrid"][<name>]["api_key"]
|
||||
where <name> is the store name (e.g. "all-debrid")
|
||||
|
||||
|
||||
Args:
|
||||
config: Configuration dict
|
||||
service: Service name (default: "All-debrid")
|
||||
|
||||
|
||||
Returns:
|
||||
API key string if found, None otherwise
|
||||
"""
|
||||
@@ -490,21 +491,21 @@ def get_debrid_api_key(config: Dict[str, Any], service: str = "All-debrid") -> O
|
||||
|
||||
if isinstance(entry, str):
|
||||
return entry.strip() or None
|
||||
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def get_provider_credentials(config: Dict[str, Any], provider: str) -> Optional[Dict[str, str]]:
|
||||
"""Get provider credentials (email/password) from config.
|
||||
|
||||
|
||||
Supports both formats:
|
||||
- New: config["provider"][provider] = {"email": "...", "password": "..."}
|
||||
- Old: config[provider.capitalize()] = {"email": "...", "password": "..."}
|
||||
|
||||
|
||||
Args:
|
||||
config: Configuration dict
|
||||
provider: Provider name (e.g., "openlibrary", "soulseek")
|
||||
|
||||
|
||||
Returns:
|
||||
Dict with credentials if found, None otherwise
|
||||
"""
|
||||
@@ -514,7 +515,7 @@ def get_provider_credentials(config: Dict[str, Any], provider: str) -> Optional[
|
||||
creds = provider_config.get(provider.lower(), {})
|
||||
if isinstance(creds, dict) and creds:
|
||||
return creds
|
||||
|
||||
|
||||
# Fall back to old format (capitalized key)
|
||||
old_key_map = {
|
||||
"openlibrary": "OpenLibrary",
|
||||
@@ -526,11 +527,13 @@ def get_provider_credentials(config: Dict[str, Any], provider: str) -> Optional[
|
||||
creds = config.get(old_key, {})
|
||||
if isinstance(creds, dict) and creds:
|
||||
return creds
|
||||
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def resolve_cookies_path(config: Dict[str, Any], script_dir: Optional[Path] = None) -> Optional[Path]:
|
||||
def resolve_cookies_path(
|
||||
config: Dict[str, Any], script_dir: Optional[Path] = None
|
||||
) -> Optional[Path]:
|
||||
# Support both legacy top-level `cookies=...` and the modular conf style:
|
||||
# [tool=ytdlp]
|
||||
# cookies="C:\\path\\cookies.txt"
|
||||
@@ -573,6 +576,7 @@ def resolve_cookies_path(config: Dict[str, Any], script_dir: Optional[Path] = No
|
||||
return default_path
|
||||
return None
|
||||
|
||||
|
||||
def resolve_debug_log(config: Dict[str, Any]) -> Optional[Path]:
|
||||
value = config.get("download_debug_log")
|
||||
if not value:
|
||||
@@ -582,7 +586,10 @@ def resolve_debug_log(config: Dict[str, Any]) -> Optional[Path]:
|
||||
path = Path.cwd() / path
|
||||
return path
|
||||
|
||||
def load_config(config_dir: Optional[Path] = None, filename: str = DEFAULT_CONFIG_FILENAME) -> Dict[str, Any]:
|
||||
|
||||
def load_config(
|
||||
config_dir: Optional[Path] = None, filename: str = DEFAULT_CONFIG_FILENAME
|
||||
) -> Dict[str, Any]:
|
||||
base_dir = config_dir or SCRIPT_DIR
|
||||
config_path = base_dir / filename
|
||||
cache_key = _make_cache_key(config_dir, filename, config_path)
|
||||
@@ -608,7 +615,9 @@ def load_config(config_dir: Optional[Path] = None, filename: str = DEFAULT_CONFI
|
||||
return data
|
||||
|
||||
|
||||
def reload_config(config_dir: Optional[Path] = None, filename: str = DEFAULT_CONFIG_FILENAME) -> Dict[str, Any]:
|
||||
def reload_config(
|
||||
config_dir: Optional[Path] = None, filename: str = DEFAULT_CONFIG_FILENAME
|
||||
) -> Dict[str, Any]:
|
||||
cache_key = _make_cache_key(config_dir, filename, None)
|
||||
_CONFIG_CACHE.pop(cache_key, None)
|
||||
return load_config(config_dir=config_dir, filename=filename)
|
||||
@@ -617,6 +626,7 @@ def reload_config(config_dir: Optional[Path] = None, filename: str = DEFAULT_CON
|
||||
def clear_config_cache() -> None:
|
||||
_CONFIG_CACHE.clear()
|
||||
|
||||
|
||||
def save_config(
|
||||
config: Dict[str, Any],
|
||||
config_dir: Optional[Path] = None,
|
||||
@@ -626,7 +636,9 @@ def save_config(
|
||||
config_path = base_dir / filename
|
||||
|
||||
if config_path.suffix.lower() != ".conf":
|
||||
raise RuntimeError(f"Unsupported config format: {config_path.name} (only .conf is supported)")
|
||||
raise RuntimeError(
|
||||
f"Unsupported config format: {config_path.name} (only .conf is supported)"
|
||||
)
|
||||
|
||||
try:
|
||||
config_path.write_text(_serialize_conf(config), encoding="utf-8")
|
||||
@@ -636,10 +648,12 @@ def save_config(
|
||||
cache_key = _make_cache_key(config_dir, filename, config_path)
|
||||
_CONFIG_CACHE[cache_key] = config
|
||||
|
||||
|
||||
def load() -> Dict[str, Any]:
|
||||
"""Return the parsed downlow configuration."""
|
||||
return load_config()
|
||||
|
||||
|
||||
def save(config: Dict[str, Any]) -> None:
|
||||
"""Persist *config* back to disk."""
|
||||
save_config(config)
|
||||
|
||||
Reference in New Issue
Block a user