diff --git a/antidrift/config.py b/antidrift/config.py index 53a09bd..8ec4df6 100644 --- a/antidrift/config.py +++ b/antidrift/config.py @@ -18,6 +18,7 @@ class Block(BaseModel): class Config(BaseModel): blackblocks: List[Block] whiteblocks: List[Block] + window_log_file: Path = Path("/home/felixm/tmp/antidrift/history.log") daemon_log_file: Path = Path() client_log_file: Path = Path() config_file: Path = Path() diff --git a/antidrift/daemon.py b/antidrift/daemon.py index a259d67..86dcf92 100644 --- a/antidrift/daemon.py +++ b/antidrift/daemon.py @@ -1,12 +1,13 @@ +import dbus +import dbus.service import logging import os import pwd import re import sys -import antidrift.xwindow as xwindow -import dbus -import dbus.service +import time +from antidrift.xwindow import XWindow from antidrift.config import Config, State, Block from gi.repository import GLib, Gio from typing import List, Optional @@ -142,11 +143,26 @@ class AntiDriftDaemon(dbus.service.Object): m = f"Blackblock [sky_blue3]{blackblock.name}[/sky_blue3] is now allowed." logging.info(m) + def get_intention(self) -> str: + s = " ".join(map(lambda b: b.name, self.state.active_whiteblocks)) + return f"intention is {s} work" if s else "no intention" + def run(self, debug: bool = False): def _enforce(): self.enforce() GLib.timeout_add(self.config.polling_cycle_ms, _enforce) + def _log(): + self.config.window_log_file.parent.mkdir(parents=True, exist_ok=True) + window = XWindow() + ts = int(time.time()) + intention = self.get_intention() + log_line = f"{ts}, {window.name}, {window.cls}, {intention}\n" + with self.config.window_log_file.open('a') as f: + f.write(log_line) + ONE_MINUTE_IN_MS = 60 * 1000 + GLib.timeout_add(ONE_MINUTE_IN_MS, _log) + # autorestart on file change for development monitors = [] files = [ @@ -156,20 +172,22 @@ class AntiDriftDaemon(dbus.service.Object): "antidrift/config.py", ] if debug: + logging.warning("[red]Running in debug mode.[/red]") for filename in files: gio_file = Gio.File.new_for_path(filename) monitor = gio_file.monitor_file(Gio.FileMonitorFlags.NONE, None) monitor.connect("changed", reload_callback) monitors.append(monitor) - logging.info("[rosy_brown]Start.[/rosy_brown]") _enforce() + _log() mainloop = GLib.MainLoop() mainloop.run() + xwindow.notify(f"AntiDrift running.") def enforce(self): if self.enforce_count >= self.enforce_value: - window = xwindow.XWindow() + window = XWindow() xwindow.notify(f"Minimize {window.name[:30]}.") window.minimize() self.enforce_count = 0 @@ -188,11 +206,11 @@ def window_is_blocked(state: State, silent: bool = False) -> bool: blackblocks = state.active_blackblocks whiteblocks = state.active_whiteblocks - window = xwindow.XWindow() + window = XWindow() if not window.keywords: return False - def keyword_matches_window(keyword: str, window: xwindow.XWindow): + def keyword_matches_window(keyword: str, window: XWindow): if keyword.startswith("/") and keyword.endswith("/"): try: r = re.compile(keyword[1:-1], re.IGNORECASE) @@ -240,9 +258,3 @@ def window_is_blocked(state: State, silent: bool = False) -> bool: if not silent: xwindow.notify(f"'{window.name[:30]}…' not on any whiteblock.") return True - - -def run(config: Config): - add = AntiDriftDaemon(config) - xwindow.notify(f"AntiDrift.run()") - add.run() diff --git a/antidrift/xwindow.py b/antidrift/xwindow.py index e8fe4df..6526594 100644 --- a/antidrift/xwindow.py +++ b/antidrift/xwindow.py @@ -18,6 +18,9 @@ class XWindow: self.pid = self._run(["getwindowpid", self.window]) self.keywords = list(re.findall(r"\w+", self.name.lower())) + def __repr__(self): + return f"" + def _run(self, cmd) -> str: cmd = ["xdotool"] + cmd p = subprocess.run(cmd, capture_output=True) diff --git a/main.py b/main.py index 25f3974..ada8f4b 100644 --- a/main.py +++ b/main.py @@ -10,7 +10,7 @@ from rich.logging import RichHandler from pathlib import Path import antidrift.client -import antidrift.daemon +from antidrift.daemon import AntiDriftDaemon from antidrift.config import Config from dbus.mainloop.glib import DBusGMainLoop @@ -81,15 +81,14 @@ def main_daemon(config): newpid = os.fork() if newpid == 0: init_logging(config.daemon_log_file) - antidrift.daemon.run(config) + AntiDriftDaemon(config).run() else: if sys.argv[0] == "antidrift": cmd = ["sudo", "antidrift", "--daemon"] subprocess.Popen(cmd) else: init_logging(config.daemon_log_file, dev_mode=True) - logging.warning("[red]Running in development mode.[/red]") - antidrift.daemon.run(config) + AntiDriftDaemon(config).run(debug=True) def main() -> None: