obsidian-vault/ligbox-ops-platform/api/app/modules/store.py
2026-06-19 17:26:42 +00:00

93 lines
2.6 KiB
Python

"""Persistência e consulta de módulos activos."""
from __future__ import annotations
import json
import os
from pathlib import Path
from app.modules.registry import MODULE_BY_ID, MODULES
MODULES_PATH = Path(os.getenv("DESK_MODULES_PATH", "/data/desk_modules.json"))
def _disabled_from_env() -> set[str]:
raw = os.getenv("DESK_MODULES_DISABLED", "").strip()
if not raw:
return set()
return {part.strip() for part in raw.split(",") if part.strip()}
def _load_overrides() -> dict[str, bool]:
if not MODULES_PATH.exists():
return {}
try:
data = json.loads(MODULES_PATH.read_text(encoding="utf-8"))
except (json.JSONDecodeError, OSError):
return {}
overrides: dict[str, bool] = {}
for key, val in data.items():
if isinstance(val, dict) and "enabled" in val:
overrides[key] = bool(val["enabled"])
elif isinstance(val, bool):
overrides[key] = val
return overrides
def _save_overrides(overrides: dict[str, bool]) -> None:
MODULES_PATH.parent.mkdir(parents=True, exist_ok=True)
payload = {mid: {"enabled": overrides[mid]} for mid in overrides if mid in MODULE_BY_ID}
MODULES_PATH.write_text(json.dumps(payload, indent=2), encoding="utf-8")
def is_module_enabled(module_id: str) -> bool:
mod = MODULE_BY_ID.get(module_id)
if not mod:
return False
if mod.locked:
return True
env_disabled = _disabled_from_env()
if module_id in env_disabled:
return False
overrides = _load_overrides()
if module_id in overrides:
return overrides[module_id]
return mod.default_enabled
def set_module_enabled(module_id: str, enabled: bool) -> None:
mod = MODULE_BY_ID.get(module_id)
if not mod:
raise KeyError(f"unknown module: {module_id}")
if mod.locked:
raise ValueError(f"module {module_id} is locked")
overrides = _load_overrides()
for m in MODULES:
if m.id not in overrides:
overrides[m.id] = is_module_enabled(m.id)
overrides[module_id] = enabled
_save_overrides(overrides)
def list_modules() -> list[dict]:
items = []
for mod in MODULES:
items.append(
{
"id": mod.id,
"label": mod.label,
"description": mod.description,
"locked": mod.locked,
"nav_views": list(mod.nav_views),
"enabled": is_module_enabled(mod.id),
}
)
return items
def enabled_nav_views() -> set[str]:
views: set[str] = set()
for mod in MODULES:
if is_module_enabled(mod.id):
views.update(mod.nav_views)
return views