From 124f88ba59c2e93646875bf0221223b4e271b8d0 Mon Sep 17 00:00:00 2001 From: Thomas Schneider Date: Mon, 27 Jul 2026 19:29:20 +0200 Subject: nm-tagger: Port to notmuch2 bindings; use tqdm for progress bar --- dot.local-bin-nm--tagger | 93 +++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 49 deletions(-) (limited to 'dot.local-bin-nm--tagger') diff --git a/dot.local-bin-nm--tagger b/dot.local-bin-nm--tagger index c23c277..5c07f6d 100755 --- a/dot.local-bin-nm--tagger +++ b/dot.local-bin-nm--tagger @@ -22,8 +22,10 @@ See :py:func:`read_config` for configuration details. import json import logging as log +from os import environ from pathlib import Path -import notmuch +from tqdm import tqdm +import notmuch2 DEFAULT_CONFIG = { "folder_separator": ".", @@ -67,15 +69,8 @@ def read_config(): config_path_base = Path(BaseDirectory.load_first_config("nm-tagger")) except ImportError: - from os import environ - - config_path_base = environ["XDG_CONFIG_HOME"] - if config_path_base != "": - config_path_base = Path(config_path_base) - else: - config_path_base = Path.home() / ".config" / "nm-tagger" - except KeyError: - config_path_base = Path.home() / ".config" / "nm-tagger" + config_home = environ.get("XDG_CONFIG_HOME", Path.home() / ".config") + config_path_base = Path(config_home) / "nm-tagger" config_path = config_path_base / "config.json" @@ -92,48 +87,48 @@ def read_config(): def main(): """Entry point""" - log.basicConfig(format="%(asctime)s %(levelname)s: %(message)s", level=log.DEBUG) + log.basicConfig( + format="%(asctime)s %(levelname)s: %(message)s", + level=environ.get("NM_TAGGER_LOG_LEVEL", log.INFO), + ) config = read_config() - with notmuch.Database(mode=notmuch.Database.MODE.READ_WRITE) as db: - top = Path(db.get_path()) - log.info("Opened notmuch db at %s", top) - new_messages_query = notmuch.Query(db, "tag:new") - log.info("Found %d messages to process", new_messages_query.count_messages()) - new_messages = set(new_messages_query.search_messages()) - - db.begin_atomic() - - for m in new_messages: - mid = m.get_message_id() - _paths = {Path(p).relative_to(top) for p in m.get_filenames()} - if config["folder_separator"] == "#FILESYSTEM#": - paths = {p.parts[:-2] for p in _paths} - else: - paths = { - p.parent.parent.as_posix().split(config["folder_separator"]) - for p in _paths - } - log.debug("paths of %s: (%d) %s", mid, len(paths), str(paths)) - tags = set() - for _p in paths: - p = tuple(map(lambda c: config["transforms"].get(c, c), _p)) - tags.add(p[0]) - tags.add(p[-1]) - for c in p[1:-1]: - if c in config["keep"]: - tags.add(c) - log.debug("tags for %s: %s", mid, str(tags)) - try: - m.freeze() - for t in tags: - m.add_tag(t) - m.remove_tag("new") - finally: - m.thaw() - - db.end_atomic() + with notmuch2.Database(mode=notmuch2.Database.MODE.READ_WRITE) as db: + top = db.path + mail_root = Path(db.config.get("database.mail_root", top)) + log.info("Opened notmuch db at %s for mail root %s", top, mail_root) + new_messages = db.messages("tag:new", omit_excluded=db.EXCLUDE.FALSE) + count = db.count_messages("tag:new", omit_excluded=db.EXCLUDE.FALSE) + log.info("Found %d messages to process", count) + + with db.atomic(): + for m in tqdm(new_messages, total=count): + mid = m.messageid + _paths = {p.relative_to(mail_root) for p in m.filenames()} + if config["folder_separator"] == "#FILESYSTEM#": + paths = {p.parts[:-2] for p in _paths} + else: + paths = { + tuple( + p.parent.parent.as_posix().split(config["folder_separator"]) + ) + for p in _paths + } + log.debug("paths of %s: (%d) %s", mid, len(paths), str(paths)) + tags = set() + for _p in paths: + p = tuple(map(lambda c: config["transforms"].get(c, c), _p)) + tags.add(p[0]) + tags.add(p[-1]) + for c in p[1:-1]: + if c in config["keep"]: + tags.add(c) + log.debug("tags for %s: %s", mid, str(tags)) + with m.frozen(): + for t in tags: + m.tags.add(t) + m.tags.discard("new") if __name__ == "__main__": -- cgit v1.2.3