Log windows and intention (aka whiteblocks if active)

This commit is contained in:
2023-05-26 16:55:46 -04:00
parent 311cd49c06
commit 1a99219851
4 changed files with 32 additions and 17 deletions

View File

@@ -18,6 +18,7 @@ class Block(BaseModel):
class Config(BaseModel): class Config(BaseModel):
blackblocks: List[Block] blackblocks: List[Block]
whiteblocks: List[Block] whiteblocks: List[Block]
window_log_file: Path = Path("/home/felixm/tmp/antidrift/history.log")
daemon_log_file: Path = Path() daemon_log_file: Path = Path()
client_log_file: Path = Path() client_log_file: Path = Path()
config_file: Path = Path() config_file: Path = Path()

View File

@@ -1,12 +1,13 @@
import dbus
import dbus.service
import logging import logging
import os import os
import pwd import pwd
import re import re
import sys import sys
import antidrift.xwindow as xwindow import time
import dbus
import dbus.service
from antidrift.xwindow import XWindow
from antidrift.config import Config, State, Block from antidrift.config import Config, State, Block
from gi.repository import GLib, Gio from gi.repository import GLib, Gio
from typing import List, Optional 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." m = f"Blackblock [sky_blue3]{blackblock.name}[/sky_blue3] is now allowed."
logging.info(m) 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 run(self, debug: bool = False):
def _enforce(): def _enforce():
self.enforce() self.enforce()
GLib.timeout_add(self.config.polling_cycle_ms, _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 # autorestart on file change for development
monitors = [] monitors = []
files = [ files = [
@@ -156,20 +172,22 @@ class AntiDriftDaemon(dbus.service.Object):
"antidrift/config.py", "antidrift/config.py",
] ]
if debug: if debug:
logging.warning("[red]Running in debug mode.[/red]")
for filename in files: for filename in files:
gio_file = Gio.File.new_for_path(filename) gio_file = Gio.File.new_for_path(filename)
monitor = gio_file.monitor_file(Gio.FileMonitorFlags.NONE, None) monitor = gio_file.monitor_file(Gio.FileMonitorFlags.NONE, None)
monitor.connect("changed", reload_callback) monitor.connect("changed", reload_callback)
monitors.append(monitor) monitors.append(monitor)
logging.info("[rosy_brown]Start.[/rosy_brown]")
_enforce() _enforce()
_log()
mainloop = GLib.MainLoop() mainloop = GLib.MainLoop()
mainloop.run() mainloop.run()
xwindow.notify(f"AntiDrift running.")
def enforce(self): def enforce(self):
if self.enforce_count >= self.enforce_value: if self.enforce_count >= self.enforce_value:
window = xwindow.XWindow() window = XWindow()
xwindow.notify(f"Minimize {window.name[:30]}.") xwindow.notify(f"Minimize {window.name[:30]}.")
window.minimize() window.minimize()
self.enforce_count = 0 self.enforce_count = 0
@@ -188,11 +206,11 @@ def window_is_blocked(state: State, silent: bool = False) -> bool:
blackblocks = state.active_blackblocks blackblocks = state.active_blackblocks
whiteblocks = state.active_whiteblocks whiteblocks = state.active_whiteblocks
window = xwindow.XWindow() window = XWindow()
if not window.keywords: if not window.keywords:
return False 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("/"): if keyword.startswith("/") and keyword.endswith("/"):
try: try:
r = re.compile(keyword[1:-1], re.IGNORECASE) 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: if not silent:
xwindow.notify(f"'{window.name[:30]}' not on any whiteblock.") xwindow.notify(f"'{window.name[:30]}' not on any whiteblock.")
return True return True
def run(config: Config):
add = AntiDriftDaemon(config)
xwindow.notify(f"AntiDrift.run()")
add.run()

View File

@@ -18,6 +18,9 @@ class XWindow:
self.pid = self._run(["getwindowpid", self.window]) self.pid = self._run(["getwindowpid", self.window])
self.keywords = list(re.findall(r"\w+", self.name.lower())) self.keywords = list(re.findall(r"\w+", self.name.lower()))
def __repr__(self):
return f"<XWindow '{self.name[:20]}' '{self.cls[:20]}'>"
def _run(self, cmd) -> str: def _run(self, cmd) -> str:
cmd = ["xdotool"] + cmd cmd = ["xdotool"] + cmd
p = subprocess.run(cmd, capture_output=True) p = subprocess.run(cmd, capture_output=True)

View File

@@ -10,7 +10,7 @@ from rich.logging import RichHandler
from pathlib import Path from pathlib import Path
import antidrift.client import antidrift.client
import antidrift.daemon from antidrift.daemon import AntiDriftDaemon
from antidrift.config import Config from antidrift.config import Config
from dbus.mainloop.glib import DBusGMainLoop from dbus.mainloop.glib import DBusGMainLoop
@@ -81,15 +81,14 @@ def main_daemon(config):
newpid = os.fork() newpid = os.fork()
if newpid == 0: if newpid == 0:
init_logging(config.daemon_log_file) init_logging(config.daemon_log_file)
antidrift.daemon.run(config) AntiDriftDaemon(config).run()
else: else:
if sys.argv[0] == "antidrift": if sys.argv[0] == "antidrift":
cmd = ["sudo", "antidrift", "--daemon"] cmd = ["sudo", "antidrift", "--daemon"]
subprocess.Popen(cmd) subprocess.Popen(cmd)
else: else:
init_logging(config.daemon_log_file, dev_mode=True) init_logging(config.daemon_log_file, dev_mode=True)
logging.warning("[red]Running in development mode.[/red]") AntiDriftDaemon(config).run(debug=True)
antidrift.daemon.run(config)
def main() -> None: def main() -> None: