diff --git a/README.md b/README.md index 71d53f6..5548992 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,20 @@ This little script allows simple interaction between `taskwarrior` and a `jrnl` file. It parses the `jrnl` file and logs accomplished tasks in `taskwarrior`. -To accomplish this it borrows a little from the [todotxt](http://todotxt.org/) syntax --- +To accomplish this it borrows a little from the [todo.txt](http://todotxt.org/) syntax --- namely the idea of (A) (B) (C) prioritization and `x task done syntax` (i.e. starting a line with `x ` means it represents an accomplished task). +## Usage + +Point the file to your `jrnl` file (ideally it needs to be a single file) and +set the syntax which declares a `todo` entry within it. + +```bash +./open-todo-txt.py -f ~/.local/share/jrnl/journal.txt -b 'todotxt' +``` + +The commandline above sets the script to work on a specific `jrnl` file +and only work on entries which have exactly `todotxt` as their title. +The settings above are also the default settings of the script. + diff --git a/open-todo-txt.py b/open-todo-txt.py index 28aa165..2a9d629 100755 --- a/open-todo-txt.py +++ b/open-todo-txt.py @@ -9,60 +9,33 @@ import re import os import sys import subprocess -import argparse - -TODOTXT_FILE = "/home/marty/documents/records/todo.md" -TODO_BLOCK_TITLE = "todotxt" - -parser = argparse.ArgumentParser() -parser.add_argument( - "-n", "--dryrun", help="only simulate and print changes", action="store_true" -) -parser.add_argument( - "-L", - "--nologging", - help="don't log done todo items to taskwarrior", - action="store_true", -) -args = parser.parse_args() - -# set options -def is_dryrun(): - if args.dryrun: - return True - return False +import options -def is_logging_done_to_tw(): - if args.nologging: - return False - return True - - -def get_todo_block_date(line): +def get_todo_block_date(line, todo_block_title): result = re.search( - rf"^\[(\d{{4}}-\d{{2}}-\d{{2}}).*\] ({re.escape(TODO_BLOCK_TITLE)}$)?", + rf"^\[(\d{{4}}-\d{{2}}-\d{{2}}).*\] ({re.escape(todo_block_title)}$)?", line, ) # we are entering todotxt data block if result and result[2]: return result[1] - # we are in block but not one for todotxt + # we enter block but not one for todotxt elif result and not result[2]: return False # nothing changed, we didn't cross a date line return "same" -def parse_file(fname): - curdate = "1970-01-01" +def parse_file(options): + fname = options.jrnl_fname lines_to_delete = [] with open(fname) as file: line_number = 0 for line in file: line_number += 1 - todo_block = get_todo_block_date(line) + todo_block = get_todo_block_date(line, options.todo_block_title) if todo_block == False: continue if todo_block != "same": @@ -70,12 +43,12 @@ def parse_file(fname): continue completed_task = re.search(r"^x ((?:\([A-D]\))? ?.*)$", line) - if completed_task and is_logging_done_to_tw(): - log_done_to_taskwarrior(completed_task[1], curdate) + if completed_task and options.taskwarrior_log_done: + log_done_to_taskwarrior(completed_task[1], curdate, options.dryrun) lines_to_delete.append(line_number) if lines_to_delete: - delete_logged_tasks_from_file(TODOTXT_FILE, lines_to_delete) + delete_logged_tasks_from_file(fname, lines_to_delete, options.dryrun) def get_prio_string(task_string): @@ -92,7 +65,7 @@ def get_prio_string(task_string): return prio_string -def log_done_to_taskwarrior(task_string, date): +def log_done_to_taskwarrior(task_string, date, dryrun): overrides = ["rc.context=none", "rc.verbose=nothing", "rc.hooks=0"] cmd = [ @@ -105,15 +78,15 @@ def log_done_to_taskwarrior(task_string, date): get_prio_string(task_string), ] - if is_dryrun(): + if dryrun: print(cmd) return subprocess.Popen(cmd) -def delete_logged_tasks_from_file(fname, lines): - if is_dryrun(): +def delete_logged_tasks_from_file(fname, lines, dryrun): + if dryrun: print(f"deleting lines: {lines}") return @@ -129,5 +102,6 @@ def delete_logged_tasks_from_file(fname, lines): os.rename(repl_file, fname) -parse_file(TODOTXT_FILE) -sys.exit(0) +if __name__ == "__main__": + parse_file(options.init()) + sys.exit(0) diff --git a/options.py b/options.py new file mode 100644 index 0000000..edf0755 --- /dev/null +++ b/options.py @@ -0,0 +1,49 @@ +import os +import argparse +from dataclasses import dataclass + + +@dataclass +class Options: + jrnl_fname: str = f"{os.path.expanduser('~')}/documents/records/todo.md" + todo_block_title: str = "todotxt" + dryrun: bool = False + taskwarrior_log_done: bool = True + + +def init(): + opt = Options() + parse_cmdline_args(opt) + print_dryrun(opt) + return opt + + +def print_dryrun(options): + print(options) + + +def parse_cmdline_args(options): + parser = argparse.ArgumentParser() + parser.add_argument( + "-n", "--dryrun", help="only simulate and print changes", action="store_true" + ) + parser.add_argument("-f", "--file", help="the jrnl file to ingest") + parser.add_argument("-b", "--blocktitle", help="the jrnl file to ingest") + parser.add_argument( + "-L", + "--nologging", + help="don't log done 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 + if args.file: + options.jrnl_fname = args.file + if args.blocktitle: + options.todo_block_title = args.blocktitle + + return options