From 76c85c66f4417af8bbca311292f957fa69f72b0d Mon Sep 17 00:00:00 2001 From: Ignacio Perez <67933444+BasileusErwin@users.noreply.github.com> Date: Mon, 13 May 2024 10:29:25 -0300 Subject: [PATCH] feat: add `exclude_titles` config & CLI option for excluding window titles by regex (#99) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add `exclude_titles` feature for enhanced window title exclusion This commit introduces the `--exclude-titles` argument to the aw-watcher-window module, allowing users to specify a list of window titles or regular expression patterns to exclude from tracking. This new feature is designed to complement the existing `--exclude-title` flag, providing enhanced flexibility for users who need to exclude multiple window titles without breaking compatibility with existing configurations. Key Changes: - Added the `--exclude-titles` argument to the argparse configuration in `config.py`, enabling the specification of multiple exclusion patterns. - Updated the `heartbeat_loop` function in `main.py` to support both `exclude_title` and `exclude_titles`, with `exclude_titles` allowing for an array of titles to be excluded. - Utilized the `re` module for regex pattern matching against window titles, ensuring case-insensitive comparisons. This enhancement ensures that users can now more precisely control which window titles are excluded from tracking, making the aw-watcher-window module more versatile and user-friendly. * Added exclude-titles in default config * Update aw_watcher_window/main.py Co-authored-by: Erik Bjäreholt * Changed the helper message and changed how regex is compiled * Changed patterns to pass by parameter to heartbeat_loop * Change compile regex * Apply suggestions from code review --------- Co-authored-by: Erik Bjäreholt --- aw_watcher_window/config.py | 9 +++++++++ aw_watcher_window/main.py | 15 ++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/aw_watcher_window/config.py b/aw_watcher_window/config.py index cfa2c7b..81eabc2 100644 --- a/aw_watcher_window/config.py +++ b/aw_watcher_window/config.py @@ -5,6 +5,7 @@ default_config = """ [aw-watcher-window] exclude_title = false +exclude_titles = [] poll_time = 1.0 strategy_macos = "swift" """.strip() @@ -19,6 +20,7 @@ def parse_args(): default_poll_time = config["poll_time"] default_exclude_title = config["exclude_title"] + default_exclude_titles = config["exclude_titles"] default_strategy_macos = config["strategy_macos"] parser = argparse.ArgumentParser( @@ -33,6 +35,13 @@ def parse_args(): action="store_true", default=default_exclude_title, ) + parser.add_argument( + "--exclude-titles", + dest="exclude_titles", + nargs='+', + default=default_exclude_titles, + help="Exclude window titles by regular expression. Can specify multiple times." + ) parser.add_argument("--verbose", dest="verbose", action="store_true") parser.add_argument( "--poll-time", dest="poll_time", type=float, default=default_poll_time diff --git a/aw_watcher_window/main.py b/aw_watcher_window/main.py index 79b23bd..8d954d5 100644 --- a/aw_watcher_window/main.py +++ b/aw_watcher_window/main.py @@ -1,5 +1,6 @@ import logging import os +import re import signal import subprocess import sys @@ -30,6 +31,13 @@ def kill_process(pid): except ProcessLookupError: logger.info("Process {} already dead".format(pid)) +def try_compile_title_regex(title): + try: + return re.compile(title, re.IGNORECASE) + except re.error: + logger.error(f"Invalid regex pattern: {title}") + exit(1) + def main(): args = parse_args() @@ -92,10 +100,11 @@ def main(): poll_time=args.poll_time, strategy=args.strategy, exclude_title=args.exclude_title, + exclude_titles=[try_compile_title_regex(title) for title in args.exclude_titles if title is not None] ) -def heartbeat_loop(client, bucket_id, poll_time, strategy, exclude_title=False): +def heartbeat_loop(client, bucket_id, poll_time, strategy, exclude_title=False, exclude_titles=[]): while True: if os.getppid() == 1: logger.info("window-watcher stopped because parent process died") @@ -128,6 +137,10 @@ def heartbeat_loop(client, bucket_id, poll_time, strategy, exclude_title=False): if current_window is None: logger.debug("Unable to fetch window, trying again on next poll") else: + for pattern in exclude_titles: + if pattern.search(current_window["title"]): + current_window["title"] = "excluded" + if exclude_title: current_window["title"] = "excluded"