diff --git a/antidrift.py b/antidrift.py index d989b85..df2761b 100644 --- a/antidrift.py +++ b/antidrift.py @@ -4,13 +4,17 @@ import logging import shutil import sys +import signal from pathlib import Path import antidrift.client as client from antidrift.config import Config from antidrift.daemon import AntiDriftDaemon +from dbus.mainloop.glib import DBusGMainLoop +DBusGMainLoop(set_as_default=True) +signal.signal(signal.SIGINT, signal.SIG_DFL) -def init_logging(log_file: Path): +def init_logging(log_file: Path, mode: str): class DuplicateFilter(logging.Filter): def filter(self, record) -> bool: current_log = (record.module, record.levelno, record.msg) @@ -18,8 +22,9 @@ def init_logging(log_file: Path): self.last_log = current_log return True return False + format_str = f'%(asctime)s | %(levelname)-8s | {mode} | %(message)s' logging.basicConfig(filename=log_file, - format='%(asctime)s | %(levelname)-8s | %(message)s', + format=format_str, datefmt='%H:%M:%S', encoding='utf-8', level=logging.DEBUG) @@ -35,14 +40,33 @@ def check_for_xdotool(): sys.exit(1) +def tailf(config): + import time + from rich import print + with open(config.log_file, 'r') as f: + f.seek(0, 2) + while True: + line = f.readline() + if not line: + time.sleep(0.1) + else: + print(line.strip()) + + def main() -> None: """ Main routine that dispatches to client or daemon """ - check_for_xdotool() config = Config.load("config.yaml") - init_logging(config.log_file) + + if len(sys.argv) > 1 and sys.argv[1] == "tailf": + tailf(config) + return + + check_for_xdotool() if client.antidrift_is_running(): + init_logging(config.log_file, "[blue]client[/blue]") client.client_mode(config) else: + init_logging(config.log_file, "[red]server[/red]") add = AntiDriftDaemon(config) add.run() diff --git a/antidrift/client.py b/antidrift/client.py index b86f8d2..bfcf7cb 100644 --- a/antidrift/client.py +++ b/antidrift/client.py @@ -2,8 +2,6 @@ from antidrift.config import Config from antidrift.daemon import DaemonStatus import dbus import dbus.service -from dbus.mainloop.glib import DBusGMainLoop -DBusGMainLoop(set_as_default=True) def antidrift_is_running() -> bool: diff --git a/antidrift/daemon.py b/antidrift/daemon.py index 13da75b..daffd73 100644 --- a/antidrift/daemon.py +++ b/antidrift/daemon.py @@ -1,8 +1,10 @@ import logging import time +import os +import sys import antidrift.xwindow as xwindow from antidrift.config import Config -from gi.repository import GLib +from gi.repository import GLib, Gio from enum import Enum import dbus import dbus.service @@ -17,6 +19,12 @@ class DaemonStatus(Enum): ERROR = "error" +def reload_callback(m, f, o, event): + # Without this check, multiple 'ok's will be printed for each file change + logging.warning("[bold green]Restart.[/bold green]") + os.execv(sys.executable, ['python3'] + sys.argv) + + class AntiDriftDaemon(dbus.service.Object): def __init__(self, config: Config): bus = dbus.SessionBus() @@ -31,12 +39,20 @@ class AntiDriftDaemon(dbus.service.Object): return DaemonStatus.RUNNING.value def run(self): - def _enforce(): enforce(self.config) GLib.timeout_add(self.config.check_delay, _enforce) - logging.info("AntiDriftDaemon run") + # autorestart on file change for development + monitors = [] + files = ["antidrift.py", "antidrift/daemon.py", "antidrift/client.py"] + 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("AntiDriftDaemon run.") _enforce() mainloop = GLib.MainLoop() mainloop.run() @@ -62,7 +78,8 @@ def window_is_blocked(config: Config) -> bool: for w in whiteblocks: for k in w.keywords: if k in window.keywords: - logging.debug(f"{window.name[:30]} allowed by {w.name}.") + logging.debug(f"[green]{window.name[:30]}[/green] " + f"allowed by [blue]{w.name}[/blue].") return False xwindow.notify(f"{window.name[:30]} not on any whitelist.") return True diff --git a/antidrift/xwindow.py b/antidrift/xwindow.py index ae3fa7d..b1b933b 100644 --- a/antidrift/xwindow.py +++ b/antidrift/xwindow.py @@ -33,7 +33,7 @@ class XWindow: def notify(message: str) -> None: """ Notify user via the Xorg notify-send command. """ - logging.debug(f"notify: {message}") + logging.debug(f"[yellow]notify[/yellow] {message}") env = { **os.environ, "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus"