diff --git a/open-todo-txt.py b/open-todo-txt.py index def4b3b..daee1af 100755 --- a/open-todo-txt.py +++ b/open-todo-txt.py @@ -48,8 +48,11 @@ def process_file(options): if handle_completed_tasks(line, curdate, options): lines_to_delete.append(line_number) + if handle_open_tasks(line, curdate, options): + lines_to_delete.append(line_number) + if lines_to_delete: - delete_logged_tasks_from_file(fname, lines_to_delete, options.dryrun) + delete_lines_from_file(fname, lines_to_delete, options.dryrun) def handle_completed_tasks(line, date, options): @@ -63,20 +66,6 @@ def handle_completed_tasks(line, date, options): return False -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_completed_to_taskwarrior(task_string, date, options): overrides = options.taskwarrior_overrides cmd = [ @@ -94,7 +83,49 @@ def log_completed_to_taskwarrior(task_string, date, options): subprocess.Popen(cmd) -def delete_logged_tasks_from_file(fname, lines, dryrun): +def handle_open_tasks(line, date, options): + completed_task = re.search( + rf"^{options.regex_task_incomplete} ((?:\([A-D]\))? ?.*)$", + line, + ) + if completed_task and options.taskwarrior_add_incomplete: + add_incomplete_to_taskwarrior(completed_task[1], date, options) + return True + return False + + +def add_incomplete_to_taskwarrior(task_string, date, options): + overrides = options.taskwarrior_overrides + cmd = [ + "task", + *overrides, + "add", + f'"{task_string}"', + f"entry:{date}", + f"scheduled:{date}", + get_prio_string(task_string), + ] + if options.dryrun: + print(cmd) + return + subprocess.Popen(cmd) + + +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 delete_lines_from_file(fname, lines, dryrun): if dryrun: print(f"deleting lines: {lines}") return diff --git a/options.py b/options.py index b491d7b..b194e3e 100644 --- a/options.py +++ b/options.py @@ -1,6 +1,7 @@ import os import argparse -from dataclasses import dataclass +from dataclasses import dataclass, field +from typing import List @dataclass @@ -10,25 +11,28 @@ class Options: todo_block_title: str = "todotxt" dryrun: bool = False taskwarrior_log_completed: bool = True + taskwarrior_add_incomplete: bool = True # can not yet be changed - taskwarrior_overrides: list = [ - "rc.context=none", - "rc.verbose=nothing", - "rc.hooks=0", - ] - regex_task_completed: str = r"(?:x|[x])" - regex_task_incomplete: str = r"[ ]" + taskwarrior_overrides: List = field( + default_factory=lambda: [ + "rc.context=none", + "rc.verbose=nothing", + "rc.hooks=0", + ] + ) + regex_task_completed: str = r"(?:x|\[x\])" + regex_task_incomplete: str = r"\[ \]" def init(): opt = Options() parse_cmdline_args(opt) - print_dryrun(opt) + dryrun_show_options(opt) return opt -def print_dryrun(options): +def dryrun_show_options(options): print(options) @@ -45,12 +49,20 @@ def parse_cmdline_args(options): help="don't log done todo items to taskwarrior", action="store_true", ) + parser.add_argument( + "-I", + "--noincomplete", + help="don't add incomplete todo items to taskwarrior", + action="store_true", + ) args = parser.parse_args() if args.dryrun: options.dryrun = True if args.nologging: - options.taskwarrior_log_done = False + options.taskwarrior_log_completed = False + if args.noincomplete: + options.taskwarrior_add_incomplete = False if args.file: options.jrnl_fname = args.file if args.blocktitle: