inital v4
This commit is contained in:
112
v4/server/app/store.py
Normal file
112
v4/server/app/store.py
Normal file
@@ -0,0 +1,112 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import threading
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from .config import Config
|
||||
from .models import UpdateManifest
|
||||
|
||||
DEFAULT_SETTINGS: dict[str, Any] = {
|
||||
"app_name": "NotifyPulse",
|
||||
"active_usecase": "",
|
||||
"paused": False,
|
||||
"hotkey": "F13",
|
||||
"startup_toast": True,
|
||||
"notify_sound": True,
|
||||
"auto_open_browser": True,
|
||||
"minimize_to_tray": True,
|
||||
"run_on_startup": False,
|
||||
"confirm_delete": True,
|
||||
"entry_display_mode": "percent",
|
||||
"notification_duration": 5,
|
||||
"overlay_opacity": 0.4,
|
||||
"overlay_duration": 6,
|
||||
"overlay_stretch": False,
|
||||
"overlay_monitor": 0,
|
||||
"wallpaper_fit": "fill",
|
||||
"pwa_bg_blur": 18,
|
||||
"pwa_bg_opacity": 0.72,
|
||||
"log_max_entries": 100,
|
||||
"webui_refresh_ms": 1000,
|
||||
}
|
||||
|
||||
DEFAULT_USECASES: list[dict[str, Any]] = []
|
||||
|
||||
DEFAULT_UPDATE_MANIFEST: dict[str, Any] = {
|
||||
"windows": UpdateManifest().model_dump(),
|
||||
}
|
||||
|
||||
|
||||
class JsonStore:
|
||||
def __init__(self, data_dir: Path):
|
||||
self._data_dir = data_dir
|
||||
self._lock = threading.RLock()
|
||||
self._settings_file = data_dir / "settings.json"
|
||||
self._usecases_file = data_dir / "usecases.json"
|
||||
self._update_file = data_dir / "update_manifest.json"
|
||||
self._init_defaults()
|
||||
|
||||
def _init_defaults(self) -> None:
|
||||
with self._lock:
|
||||
self._ensure_file(self._settings_file, DEFAULT_SETTINGS)
|
||||
self._ensure_file(self._usecases_file, DEFAULT_USECASES)
|
||||
self._ensure_file(self._update_file, DEFAULT_UPDATE_MANIFEST)
|
||||
|
||||
@staticmethod
|
||||
def _write_json(path: Path, payload: Any) -> None:
|
||||
path.write_text(json.dumps(payload, indent=2), encoding="utf-8")
|
||||
|
||||
def _ensure_file(self, path: Path, payload: Any) -> None:
|
||||
if not path.exists():
|
||||
self._write_json(path, payload)
|
||||
|
||||
@staticmethod
|
||||
def _read_json(path: Path, fallback: Any) -> Any:
|
||||
try:
|
||||
return json.loads(path.read_text(encoding="utf-8"))
|
||||
except Exception:
|
||||
return fallback
|
||||
|
||||
def get_settings(self) -> dict[str, Any]:
|
||||
with self._lock:
|
||||
raw = self._read_json(self._settings_file, {})
|
||||
return {**DEFAULT_SETTINGS, **raw}
|
||||
|
||||
def update_settings(self, patch: dict[str, Any]) -> dict[str, Any]:
|
||||
with self._lock:
|
||||
current = self.get_settings()
|
||||
current.update(patch)
|
||||
self._write_json(self._settings_file, current)
|
||||
return current
|
||||
|
||||
def get_usecases(self) -> list[dict[str, Any]]:
|
||||
with self._lock:
|
||||
raw = self._read_json(self._usecases_file, DEFAULT_USECASES)
|
||||
return raw if isinstance(raw, list) else []
|
||||
|
||||
def set_usecases(self, payload: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
||||
with self._lock:
|
||||
self._write_json(self._usecases_file, payload)
|
||||
return payload
|
||||
|
||||
def get_update_manifest(self, platform: str) -> UpdateManifest:
|
||||
with self._lock:
|
||||
raw = self._read_json(self._update_file, DEFAULT_UPDATE_MANIFEST)
|
||||
platform_raw = raw.get(platform) if isinstance(raw, dict) else None
|
||||
if not isinstance(platform_raw, dict):
|
||||
return UpdateManifest()
|
||||
return UpdateManifest.model_validate(platform_raw)
|
||||
|
||||
def set_update_manifest(self, platform: str, manifest: UpdateManifest) -> None:
|
||||
with self._lock:
|
||||
raw = self._read_json(self._update_file, DEFAULT_UPDATE_MANIFEST)
|
||||
if not isinstance(raw, dict):
|
||||
raw = {}
|
||||
raw[platform] = manifest.model_dump()
|
||||
self._write_json(self._update_file, raw)
|
||||
|
||||
|
||||
Config.ensure_dirs()
|
||||
store = JsonStore(Config.data_dir)
|
||||
Reference in New Issue
Block a user