jrnlwarrior/open-todo-txt.py

137 lines
3.4 KiB
Python
Raw Normal View History

2021-10-30 17:49:08 +00:00
#!/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"
)
2021-10-31 10:40:36 +00:00
parser.add_argument(
"-L",
"--nologging",
help="don't log done todo items to taskwarrior",
action="store_true",
)
2021-10-30 17:49:08 +00:00
args = parser.parse_args()
2021-10-31 10:40:36 +00:00
# set options
def is_dryrun():
if args.dryrun:
return True
return False
def is_logging_done_to_tw():
if args.nologging:
return False
return True
2021-10-30 17:49:08 +00:00
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)
2021-10-31 10:40:36 +00:00
if completed_task and is_logging_done_to_tw():
log_done_to_taskwarrior(completed_task[1], curdate)
2021-10-30 17:49:08 +00:00
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
2021-10-31 10:40:36 +00:00
def log_done_to_taskwarrior(task_string, date):
2021-10-30 17:49:08 +00:00
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),
]
2021-10-31 10:40:36 +00:00
if is_dryrun():
2021-10-30 17:49:08 +00:00
print(cmd)
return
subprocess.Popen(cmd)
def delete_logged_tasks_from_file(fname, lines):
2021-10-31 10:40:36 +00:00
if is_dryrun():
print(f"deleting lines: {lines}")
2021-10-30 17:49:08 +00:00
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)
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