init
This commit is contained in:
121 files changed
+17641
No files matched your search
@@ -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()
|
||||
Reference in new issue
Block a user