From 26cb264179c1385ab0e181239079782cdec54a2b Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Sat, 30 Oct 2021 19:49:08 +0200 Subject: [PATCH] initial commit --- open-todo-txt.py | 123 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100755 open-todo-txt.py diff --git a/open-todo-txt.py b/open-todo-txt.py new file mode 100755 index 0000000..7943fd0 --- /dev/null +++ b/open-todo-txt.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python3 + +# From: https://gist.github.com/varunagrawal/2b93c5dc721520ff6876e940c420ab05 +# This hooks script logs any finished tasks currently in the todo.txt file +# pointed to by its settings. +# The on-exit event is triggered once, after all processing is complete. + +import re +import os +import sys +import subprocess +import argparse + +TODOTXT_FILE = "/home/marty/documents/records/todo.md" + +parser = argparse.ArgumentParser() +parser.add_argument( + "-n", "--dryrun", help="only simulate and print changes", action="store_true" +) +args = parser.parse_args() + + +def extract_tw_data(fname): + curdate = "1970-01-01" + lines_to_delete = [] + in_todotxt_block = False + with open(fname) as file: + line_number = 0 + for line in file: + line_number += 1 + newdate = re.search(r"^\[(\d{4}-\d{2}-\d{2}).*\] (todotxt$)?", line) + # we are entering todotxt data block + if newdate and newdate[2]: + curdate = newdate[1] + in_todotxt_block = True + continue + # we are in block but not one for todotxt + elif newdate and not newdate[2]: + in_todotxt_block = False + continue + + if not in_todotxt_block: + continue + + completed_task = re.search(r"^x ((?:\([A-D]\))? ?.*)$", line) + if completed_task: + log_to_taskwarrior(completed_task[1], curdate) + lines_to_delete.append(line_number) + + if lines_to_delete: + delete_logged_tasks_from_file(TODOTXT_FILE, lines_to_delete) + + +def get_prio_string(task_string): + prio = re.search(r"^\(([ABC])\) (.*)$", task_string) + prio_string = "" + if prio: + task_string = prio[2] + if prio[1] == "A": + prio_string = "prio:H" + elif prio[1] == "B": + prio_string = "prio:M" + elif prio[1] == "C": + prio_string = "prio:L" + return prio_string + + +def log_to_taskwarrior(task_string, date): + overrides = "rc.context=none rc.hooks=0" + + cmd = [ + "task", + overrides, + "log", + f'"{task_string}"', + f"entry:{date}", + f"end:{date}", + get_prio_string(task_string), + ] + + if is_dryrun: + print(cmd) + return + + subprocess.Popen(cmd) + + +def delete_logged_tasks_from_file(fname, lines): + if is_dryrun: + return + + cur_line = 0 + repl_file = fname + ".bak" + with open(fname) as read_file, open(repl_file, "w") as write_file: + for line in read_file: + cur_line += 1 + if lines and cur_line == lines[0]: + lines.pop(0) + continue + write_file.write(line) + os.rename(repl_file, fname) + + +def is_dryrun(): + if args.dryrun: + return True + return False + + +extract_tw_data(TODOTXT_FILE) +sys.exit(0) + +# The on-launch event is triggered once, after initialization, before any +# processing occurs. This hooks script has no effect on processing. + +# Output: +# - Optional feedback/error. +# echo 'on-launch' + +# Status: +# - 0: JSON ignored, non-JSON is feedback. +# - non-0: JSON ignored, non-JSON is error. +# exit 0