Fix lock when trying to stop while enforce sequence is active.

This commit is contained in:
2022-07-02 21:09:50 -04:00
parent 73a5585b3c
commit b69d426d85
5 changed files with 63 additions and 63 deletions

View File

@@ -14,7 +14,7 @@ DBusGMainLoop(set_as_default=True)
signal.signal(signal.SIGINT, signal.SIG_DFL) signal.signal(signal.SIGINT, signal.SIG_DFL)
def init_logging(log_file: Path, mode: str): def init_logging(log_file: Path):
class DuplicateFilter(logging.Filter): class DuplicateFilter(logging.Filter):
def filter(self, record) -> bool: def filter(self, record) -> bool:
current_log = (record.module, record.levelno, record.msg) current_log = (record.module, record.levelno, record.msg)
@@ -22,10 +22,12 @@ def init_logging(log_file: Path, mode: str):
self.last_log = current_log self.last_log = current_log
return True return True
return False return False
format_str = f'%(asctime)s | %(levelname)-8s | {mode} | %(message)s' format_str = '[bold pale_green3]%(asctime)s[/bold pale_green3] | ' \
'[light_steel_blue]%(levelname)-8s[/light_steel_blue] | ' \
'%(message)s'
logging.basicConfig(filename=log_file, logging.basicConfig(filename=log_file,
format=format_str, format=format_str,
datefmt='%H:%M:%S', datefmt='%a %H:%M:%S',
encoding='utf-8', encoding='utf-8',
level=logging.DEBUG) level=logging.DEBUG)
logger = logging.getLogger() logger = logging.getLogger()
@@ -40,33 +42,16 @@ def check_for_xdotool():
sys.exit(1) 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: def main() -> None:
""" Main routine that dispatches to client or daemon """ """ Main routine that dispatches to client or daemon """
config = Config.load("config.yaml") config = Config.load("config.yaml")
if len(sys.argv) > 1 and sys.argv[1] == "tailf":
tailf(config)
return
check_for_xdotool() check_for_xdotool()
if client.antidrift_daemon_is_running(): if client.antidrift_daemon_is_running():
init_logging(config.log_file, "[blue]client[/blue]") init_logging(config.client_log_file)
client.client_mode(config) client.client_mode(config)
else: else:
init_logging(config.log_file, "[red]server[/red]") init_logging(config.daemon_log_file)
add = AntiDriftDaemon(config) add = AntiDriftDaemon(config)
add.run() add.run()

View File

@@ -1,9 +1,8 @@
from antidrift.config import Config from antidrift.config import Config
from typing import Optional, List from typing import Optional
from rich import print from rich import print
import argparse import argparse
import sys import time
import logging
import dbus import dbus
import dbus.service import dbus.service
@@ -25,21 +24,37 @@ def antidrift_daemon_is_running() -> bool:
return False return False
reply = interface.status() reply = interface.status()
if reply: if reply:
logging.info(reply)
return True return True
return False return False
def client_mode(_config: Config): def tailf(config):
with open(config.daemon_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 client_mode(config: Config):
parser = argparse.ArgumentParser(description='AntiDrift CLI.') parser = argparse.ArgumentParser(description='AntiDrift CLI.')
parser.add_argument('--start', metavar='whiteblock', nargs='+', parser.add_argument('--start', metavar='whiteblock', nargs='+',
help='start session with whiteblocks') help='start session with whiteblocks')
parser.add_argument('--stop', action='store_true', parser.add_argument('--stop', action='store_true',
help='stop session') help='stop session')
parser.add_argument('--tailf', action='store_true',
help='tail -f log file')
args = parser.parse_args() args = parser.parse_args()
interface = get_dbus_interface() interface = get_dbus_interface()
if args.start: if args.start:
reply = interface.start(args.start) reply = interface.start(args.start)
elif args.stop: elif args.stop:
reply = interface.stop() reply = interface.stop()
elif args.tailf:
tailf(config)
else:
reply = '[red]no command[/red]'
print(reply) print(reply)

View File

@@ -15,10 +15,11 @@ class Config(BaseModel):
whiteblocks: List[Block] whiteblocks: List[Block]
active_blackblocks: List[Block] = [] active_blackblocks: List[Block] = []
active_whiteblocks: List[Block] = [] active_whiteblocks: List[Block] = []
log_file: Path = Path() daemon_log_file: Path = Path()
client_log_file: Path = Path()
config_file: Path = Path() config_file: Path = Path()
check_delay: int = 1000 polling_cycle_ms: int = 500
minimize_delay: int = 5 enforce_delay_ms: int = 10000
class Config: class Config:
extra = 'forbid' extra = 'forbid'

View File

@@ -1,12 +1,9 @@
import logging import logging
import time
import os import os
import sys import sys
import argparse
import antidrift.xwindow as xwindow import antidrift.xwindow as xwindow
from antidrift.config import Config from antidrift.config import Config
from gi.repository import GLib, Gio from gi.repository import GLib, Gio
from enum import Enum
from typing import List from typing import List
import dbus import dbus
import dbus.service import dbus.service
@@ -17,8 +14,9 @@ OPATH = "/com/antidrift"
def reload_callback(m, f, o, event): def reload_callback(m, f, o, event):
# Without this check, multiple 'ok's will be printed for each file change filename = f.get_basename()
logging.warning("[bold green]Restart.[/bold green]") m = f"[dark_orange3]Restart after change in '{filename}'.[/dark_orange3]"
logging.warning(m)
os.execv(sys.executable, ['python3'] + sys.argv) os.execv(sys.executable, ['python3'] + sys.argv)
@@ -31,13 +29,14 @@ class AntiDriftDaemon(dbus.service.Object):
self.config = config self.config = config
self.config.active_whiteblocks = [] self.config.active_whiteblocks = []
self.config.active_blackblocks = self.config.blackblocks self.config.active_blackblocks = self.config.blackblocks
self.enforce_count = 0
self.enforce_value = int(config.enforce_delay_ms / config.polling_cycle_ms)
@dbus.service.method(dbus_interface=IFACE, @dbus.service.method(dbus_interface=IFACE,
in_signature="", out_signature="s") in_signature="", out_signature="s")
def status(self) -> str: def status(self) -> str:
return "active" return "active"
@dbus.service.method(dbus_interface=IFACE, @dbus.service.method(dbus_interface=IFACE,
in_signature="as", out_signature="s") in_signature="as", out_signature="s")
def start(self, whiteblocks: List[str]) -> str: def start(self, whiteblocks: List[str]) -> str:
@@ -52,7 +51,8 @@ class AntiDriftDaemon(dbus.service.Object):
else: else:
fail_wbs.append(wb_name) fail_wbs.append(wb_name)
if success_wbs: if success_wbs:
r = f"Start whiteblocks [blue]{', '.join(success_wbs)}[/blue]." wbs = ', '.join(success_wbs)
r = f"Start whiteblocks [sky_blue3]{wbs}[/sky_blue3]."
logging.info(r) logging.info(r)
else: else:
r = "No whiteblocks started." r = "No whiteblocks started."
@@ -70,26 +70,45 @@ class AntiDriftDaemon(dbus.service.Object):
logging.info(m) logging.info(m)
return m return m
def run(self): def run(self):
def _enforce(): def _enforce():
enforce(self.config) self.enforce()
GLib.timeout_add(self.config.check_delay, _enforce) GLib.timeout_add(self.config.polling_cycle_ms, _enforce)
# autorestart on file change for development # autorestart on file change for development
monitors = [] monitors = []
files = ["antidrift.py", "antidrift/daemon.py", "antidrift/client.py"] files = ["antidrift.py", "antidrift/daemon.py", "antidrift/client.py",
"antidrift/config.py"]
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("Start AntiDriftDaemon.") logging.info("[rosy_brown]Start.[/rosy_brown]")
_enforce() _enforce()
mainloop = GLib.MainLoop() mainloop = GLib.MainLoop()
mainloop.run() mainloop.run()
def enforce(self):
config = self.config
# logging.debug(f"{self.enforce_count=} {self.enforce_value=}")
if self.enforce_count >= self.enforce_value:
window = xwindow.XWindow()
xwindow.notify(f"Minimize {window.name[:30]}.")
window.minimize()
self.enforce_count = 0
elif self.enforce_count > 0 and window_is_blocked(config, True):
self.enforce_count += 1
elif self.enforce_count == 0 and window_is_blocked(config):
self.enforce_count += 1
delay = config.enforce_delay_ms
xwindow.notify(f"AntiDrift will minimize in {delay} ms.")
elif self.enforce_count > 0:
xwindow.notify("We are gucci again.")
self.enforce_count = 0
def window_is_blocked(config: Config, silent: bool = False) -> bool: def window_is_blocked(config: Config, silent: bool = False) -> bool:
# These should be selectable in the future (not all at the same time) # These should be selectable in the future (not all at the same time)
@@ -121,23 +140,3 @@ def window_is_blocked(config: Config, silent: bool = False) -> bool:
if not silent: if not silent:
xwindow.notify(f"[red]{window.name[:30]}[/red] not on any whiteblock.") xwindow.notify(f"[red]{window.name[:30]}[/red] not on any whiteblock.")
return True return True
def enforce(config: Config):
if not window_is_blocked(config):
return
delay = config.minimize_delay
xwindow.notify(f"AntiDrift will minimize in {delay} seconds.")
timer, timer_step = 0.0, 0.5
while timer < config.minimize_delay:
time.sleep(timer_step)
timer += timer_step
if not window_is_blocked(config, True):
break
window = xwindow.XWindow()
if window_is_blocked(config):
window = xwindow.XWindow()
xwindow.notify(f"Minimize {window.name[:30]}.")
window.minimize()
else:
xwindow.notify("We are gucci again.")

View File

@@ -33,7 +33,7 @@ class XWindow:
def notify(message: str) -> None: def notify(message: str) -> None:
""" Notify user via the Xorg notify-send command. """ """ Notify user via the Xorg notify-send command. """
logging.debug(f"[yellow]notify[/yellow] {message}") logging.debug(f"{message} - [grey]notify[/grey]")
env = { env = {
**os.environ, **os.environ,
"DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus" "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus"