This commit is contained in:
timka123 committed 2026-10-18 18:02:05 +03:00
commit 17a0a3c4c9
121 files changed
+17641

No files matched your search

+97
View File
@@ -0,0 +1,97 @@
"""Desktop-local configuration.
Only what is *about this machine* lives here — where the backend is, and which
system integrations this box may use. Everything else (timer lengths, block
lists, Telegram) is server-side, so the phone, the web UI and this app always
agree.
Stored as JSON in `$XDG_CONFIG_HOME/kadence/desktop.json`.
"""
from __future__ import annotations
import json
import os
from dataclasses import asdict, dataclass, field
from pathlib import Path
def config_dir() -> Path:
base = os.environ.get("XDG_CONFIG_HOME") or str(Path.home() / ".config")
path = Path(base) / "kadence"
path.mkdir(parents=True, exist_ok=True)
return path
CONFIG_PATH = config_dir() / "desktop.json"
@dataclass
class DesktopConfig:
"""What this machine needs to know."""
server_url: str = "http://localhost:8000"
api_token: str = ""
poll_seconds: int = 5
"""How often to ask the backend for the timer state and the block policy."""
start_minimized: bool = False
close_to_tray: bool = True
# ---- system integration (each one is a real desktop feature) -----------
tray_icon: bool = True
notifications: bool = True
notification_actions: bool = True
"""Buttons on the notification itself: "Start break", "Skip", "+5 min"."""
inhibit_screensaver: bool = True
"""Keep the screen awake while a work interval runs."""
do_not_disturb: bool = True
"""Silence other apps' notifications during a work interval."""
taskbar_progress: bool = True
"""Progress on the dock/taskbar icon (Unity LauncherEntry — KDE honours it)."""
pause_media: bool = True
"""Pause whatever is playing (MPRIS) when focus starts."""
pause_on_lock: bool = True
"""Pause the timer when the session locks, resume when you come back."""
pause_on_idle_minutes: int = 0
"""Pause after this many idle minutes. 0 = never."""
dbus_service: bool = True
"""Expose org.kadence.Desktop so shortcuts and scripts can drive it."""
# ---- blocking (enforcement; the rules themselves are server-side) ------
enforce_blocking: bool = True
block_hosts_file: bool = True
block_apps: bool = True
helper_path: str = "/usr/local/bin/kadence-helper"
window: dict = field(default_factory=lambda: {"width": 1100, "height": 760})
@classmethod
def load(cls) -> "DesktopConfig":
if not CONFIG_PATH.exists():
config = cls()
config.save()
return config
try:
data = json.loads(CONFIG_PATH.read_text("utf-8"))
except (OSError, json.JSONDecodeError):
return cls()
known = {key: value for key, value in data.items() if key in cls.__dataclass_fields__}
return cls(**known)
def save(self) -> None:
CONFIG_PATH.write_text(json.dumps(asdict(self), indent=2), "utf-8")
def update(self, **changes: object) -> None:
for key, value in changes.items():
if key in self.__dataclass_fields__:
setattr(self, key, value)
self.save()