Files
kadence/desktop/kadence_desktop/__main__.py
T
timka123andClaude Opus 5 ec7eedbc66 style: say which lint rules this repo keeps, then keep them
`[tool.ruff]` set a line length and a target version and nothing else, so which
rules ran depended on the installed ruff's defaults — fine while nobody ran it,
not fine for a CI job that can turn a push red because a tool changed its mind.

The set is named explicitly (E, F, I, UP, SIM, B, RUF) with three ignores that
are each a real decision rather than a shrug: B008, because FastAPI's whole
dependency idiom is a call in a default argument; E501, because wrapping prose
is a formatter's business; and RUF001, because the reports and the bot speak
Russian and "ambiguous character" is the wrong complaint about a string the
user is meant to read.

The 73 findings that remained are fixed — mostly `datetime.timezone.utc` →
`datetime.UTC`, `typing.Callable` → `collections.abc.Callable`, import order,
and unused `noqa` markers — plus seven by hand: `contextlib.suppress` for two
try/except/pass pairs, unpacking instead of list concatenation, one negated
return.

`ruff format` is deliberately *not* adopted: it would reformat 51 files, and
some of the layout here is hand-set (the comment tables, the DNS wire-format
structs) in ways a formatter flattens.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-22 17:28:57 +03:00

90 lines
2.8 KiB
Python

"""Entry point.
Run with no arguments to open the app. The verbs (`--toggle`, `--status`, …)
talk to a *running* instance over D-Bus instead of starting a second one, which
is what makes them usable as global shortcuts:
kadence-desktop --toggle # bind this to a key in System Settings
kadence-desktop --mini # show/hide the floating mini timer
kadence-desktop --status # prints "Focus 18:42 · Write the docs · 3/8 today"
"""
from __future__ import annotations
import argparse
import logging
import os
import sys
REMOTE_VERBS = {
"toggle": "Toggle",
"start": "StartWork",
"break": "StartBreak",
"pause": "Pause",
"resume": "Resume",
"complete": "Complete",
"stop": "Stop",
"extend": "Extend",
"interrupt": "Interrupt",
"status": "Status",
"report": "SendReport",
"mini": "ToggleMini",
"show": "Raise",
}
def _remote(verb: str) -> int:
"""Call the running instance. Returns a process exit code."""
from PyQt6.QtCore import QCoreApplication
from PyQt6.QtDBus import QDBusConnection, QDBusInterface
_app = QCoreApplication(sys.argv)
interface = QDBusInterface(
"org.kadence.Desktop", "/Timer", "org.kadence.Timer", QDBusConnection.sessionBus()
)
if not interface.isValid():
print("Kadence is not running.", file=sys.stderr)
return 1
reply = interface.call(REMOTE_VERBS[verb])
arguments = reply.arguments()
if arguments:
print(arguments[0])
return 0
def main() -> int:
parser = argparse.ArgumentParser(prog="kadence-desktop", description=__doc__)
parser.add_argument("--minimized", action="store_true", help="start in the tray only")
parser.add_argument(
"--view-only", action="store_true", help="start in view-only mode with timer turned off"
)
parser.add_argument("--verbose", action="store_true")
for verb in REMOTE_VERBS:
parser.add_argument(
f"--{verb}", action="store_true", help=f"ask the running instance to {verb}"
)
args = parser.parse_args()
logging.basicConfig(
level=logging.DEBUG if args.verbose else os.environ.get("KADENCE_LOG", "INFO").upper(),
format="%(asctime)s %(levelname)-7s %(name)s: %(message)s",
)
for verb in REMOTE_VERBS:
if getattr(args, verb):
return _remote(verb)
from kadence_desktop.app import KadenceApp
from kadence_desktop.integrations.dbus_service import call_existing
# Single instance: if somebody already owns the name, just raise their window.
if call_existing("Raise"):
print("Kadence is already running — raised its window.")
return 0
return KadenceApp(sys.argv, minimized=args.minimized, view_only=args.view_only).run()
if __name__ == "__main__":
raise SystemExit(main())