jkj
This commit is contained in:
74
config.py
74
config.py
@@ -1,11 +1,5 @@
|
||||
|
||||
"""Unified configuration helpers.
|
||||
|
||||
Configuration is defined exclusively via the modular `.conf` format.
|
||||
|
||||
- Required: `temp`
|
||||
- Optional: stores, providers, and other settings
|
||||
- Modular: optional fragments in `config.d/*.conf` are merged in lexicographic order
|
||||
"""
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -130,6 +124,21 @@ def _apply_conf_block(config: Dict[str, Any], kind: str, subtype: str, block: Di
|
||||
provider[provider_name] = dict(block)
|
||||
return
|
||||
|
||||
if kind_l == "tool":
|
||||
tool_name = str(subtype).strip().lower()
|
||||
if not tool_name:
|
||||
return
|
||||
tool = config.setdefault("tool", {})
|
||||
if not isinstance(tool, dict):
|
||||
config["tool"] = {}
|
||||
tool = config["tool"]
|
||||
existing = tool.get(tool_name)
|
||||
if isinstance(existing, dict):
|
||||
_merge_dict_inplace(existing, block)
|
||||
else:
|
||||
tool[tool_name] = dict(block)
|
||||
return
|
||||
|
||||
|
||||
def parse_conf_text(text: str, *, base: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
|
||||
"""Parse a lightweight .conf format into the app's config dict.
|
||||
@@ -227,7 +236,7 @@ def _serialize_conf(config: Dict[str, Any]) -> str:
|
||||
|
||||
# Top-level scalars first
|
||||
for key in sorted(config.keys()):
|
||||
if key in {"store", "provider"}:
|
||||
if key in {"store", "provider", "tool"}:
|
||||
continue
|
||||
value = config.get(key)
|
||||
if isinstance(value, dict):
|
||||
@@ -263,6 +272,18 @@ def _serialize_conf(config: Dict[str, Any]) -> str:
|
||||
for k in sorted(block.keys()):
|
||||
lines.append(f"{k}={_format_conf_value(block.get(k))}")
|
||||
|
||||
# Tool blocks
|
||||
tool = config.get("tool")
|
||||
if isinstance(tool, dict):
|
||||
for name in sorted(tool.keys()):
|
||||
block = tool.get(name)
|
||||
if not isinstance(block, dict):
|
||||
continue
|
||||
lines.append("")
|
||||
lines.append(f"[tool={name}]")
|
||||
for k in sorted(block.keys()):
|
||||
lines.append(f"{k}={_format_conf_value(block.get(k))}")
|
||||
|
||||
return "\n".join(lines).rstrip() + "\n"
|
||||
|
||||
|
||||
@@ -510,12 +531,43 @@ def get_provider_credentials(config: Dict[str, Any], provider: str) -> Optional[
|
||||
|
||||
|
||||
def resolve_cookies_path(config: Dict[str, Any], script_dir: Optional[Path] = None) -> Optional[Path]:
|
||||
value = config.get("cookies")
|
||||
if value:
|
||||
# Support both legacy top-level `cookies=...` and the modular conf style:
|
||||
# [tool=ytdlp]
|
||||
# cookies="C:\\path\\cookies.txt"
|
||||
values: list[Any] = []
|
||||
try:
|
||||
values.append(config.get("cookies"))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
tool = config.get("tool")
|
||||
if isinstance(tool, dict):
|
||||
ytdlp = tool.get("ytdlp")
|
||||
if isinstance(ytdlp, dict):
|
||||
values.append(ytdlp.get("cookies"))
|
||||
values.append(ytdlp.get("cookiefile"))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
ytdlp_block = config.get("ytdlp")
|
||||
if isinstance(ytdlp_block, dict):
|
||||
values.append(ytdlp_block.get("cookies"))
|
||||
values.append(ytdlp_block.get("cookiefile"))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
base_dir = script_dir or SCRIPT_DIR
|
||||
for value in values:
|
||||
if not value:
|
||||
continue
|
||||
candidate = Path(str(value)).expanduser()
|
||||
if not candidate.is_absolute():
|
||||
candidate = (base_dir / candidate).expanduser()
|
||||
if candidate.is_file():
|
||||
return candidate
|
||||
base_dir = script_dir or SCRIPT_DIR
|
||||
|
||||
default_path = base_dir / "cookies.txt"
|
||||
if default_path.is_file():
|
||||
return default_path
|
||||
|
||||
Reference in New Issue
Block a user