From aa09137df616fb533f0e8758d46bd7b6d6770cc3 Mon Sep 17 00:00:00 2001 From: Yehuda Deutsch Date: Mon, 11 Nov 2024 16:06:27 -0500 Subject: [PATCH 1/3] Create a python todo utility --- README.md | 3 ++ todo.py | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 README.md create mode 100755 todo.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..86dabed --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Ajal Todo CLI + +A todo utility diff --git a/todo.py b/todo.py new file mode 100755 index 0000000..fa26f2a --- /dev/null +++ b/todo.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python3 +import os +import re +import sys + +base_dir = os.path.abspath(os.path.dirname(__file__)) +todo_file = os.path.join(base_dir, "todo.md") + + +def add_task(task: str, parent=None): + print(f"Adding task '{task}' to '{parent if parent else 'root'}'") + todo = parse_todo() + if parent and parent not in todo: + print(f"Could not find parent task '{parent}' in root task list") + exit(1) + if parent: + todo[parent]["sub_tasks"][task] = {"completed": False} + else: + todo[task] = {"completed": False, "sub_tasks": {}} + write_todo(todo) + + +def list_tasks(parent=None): + print(f"Listing tasks in '{parent if parent else 'root'}'") + todo = parse_todo() + if parent and parent not in todo: + print(f"Could not find parent task '{parent}' in root task list") + exit(1) + if parent: + todo = {parent: todo[parent]} + print(render_todo(todo)) + + +def complete_task(task, parent=None): + print(f"Marking task '{task}' in '{parent if parent else 'root'}' as completed") + todo = parse_todo() + if parent: + if parent not in todo: + print(f"Could not find parent task '{parent}' in root task list") + exit(1) + if task not in todo[parent]["sub_tasks"]: + print(f"Could not find task '{task}' in parent task '{parent}'") + exit(1) + if task not in todo: + print(f"Could not find task '{task}' in root task list") + exit(1) + if parent: + task = todo[parent]["sub_tasks"][task] + else: + task = todo[task] + task["completed"] = True + write_todo(todo) + + +def remove_task(task, parent=None): + print(f"Removing task '{task}' from '{parent if parent else 'root'}'") + todo = parse_todo() + if parent: + if parent not in todo: + print(f"Could not find parent task '{parent}' in root task list") + exit(1) + if task not in todo[parent]["sub_tasks"]: + print(f"Could not find task '{task}' in parent task '{parent}'") + exit(1) + if task not in todo: + print(f"Could not find task '{task}' in root task list") + exit(1) + if parent: + del todo[parent]["sub_tasks"][task] + else: + del todo[task] + write_todo(todo) + + +def print_help(): + print("""Usage: todo.py [add|complete|remove] TASK [PARENT] + todo.py list [PARENT] + + Manages todo.md file as a ToDo file""") + + +def parse_todo() -> dict[str, dict]: + todo = {} + with open(todo_file, "r") as f: + lines = f.readlines() + root_task = None + for line in lines: + if matches := re.match(r"^-\s+(\[(?P[x ])]\s+)?(?P.*)$", line.rstrip()): + root_task_name = matches.group("task") + root_task = { + "completed": matches.group("status") == "x", + "sub_tasks": {}, + } + todo[root_task_name] = root_task + elif matches := re.match(r"^\s+-\s+(\[(?P[x ])]\s+)?(?P.*)$", line.rstrip()): + leaf_task = matches.group("task") + root_task["sub_tasks"][leaf_task] = { + "completed": matches.group("status") == "x", + } + return todo + + +def render_todo(todo: dict[str, dict]) -> str: + lines = ["# A ToDo list", ""] + for task, task_data in todo.items(): # type: str, dict + lines.append(f"- [{'x' if task_data["completed"] else ' '}] {task}") + for leaf_task, leaf_task_data in task_data["sub_tasks"].items(): + lines.append(f" - [{'x' if leaf_task_data["completed"] else ' '}] {leaf_task}") + lines += [""] + return "\n".join(lines) + + +def write_todo(todo: dict[str, dict]): + with open(todo_file, "w") as f: + f.write(render_todo(todo)) + + +def main(): + if len(sys.argv) < 2: + print_help() + exit(1) + + match sys.argv[1]: + case "help" | "--help" | "h" | "-h": + print_help() + case "list": + match sys.argv[2:]: + case [parent]: + list_tasks(parent) + case _: + list_tasks() + case "add" | "complete" | "remove" as task_name: + task_func = f"{task_name}_task" + match sys.argv[2:]: + case [task]: + globals()[task_func](task) + case [task, parent]: + globals()[task_func](task, parent) + case _: + print_help() + exit(1) + case _: + print_help() + exit(1) + + +if __name__ == "__main__": + main() -- 2.45.3 From 950aa8920aa331de346d47c418e8f04518e4924b Mon Sep 17 00:00:00 2001 From: Yehuda Deutsch Date: Tue, 12 Nov 2024 00:26:19 -0500 Subject: [PATCH 2/3] Add doitlive --- breakitlive.sh | 8 ++++++++ doitlive.sh | 31 +++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 breakitlive.sh create mode 100644 doitlive.sh diff --git a/breakitlive.sh b/breakitlive.sh new file mode 100644 index 0000000..c9afb70 --- /dev/null +++ b/breakitlive.sh @@ -0,0 +1,8 @@ +#doitlive speed: 3 +#doitlive prompt: sorin + +python3 todo.py add Test +python3 todo.py list Test +python3 todo.py list Test Test + +python3 todo.py add test1 Test Test diff --git a/doitlive.sh b/doitlive.sh new file mode 100644 index 0000000..67e7059 --- /dev/null +++ b/doitlive.sh @@ -0,0 +1,31 @@ +#doitlive speed: 3 +#doitlive prompt: sorin + +python3 todo.py --help +python3 todo.py help +python3 todo.py -h +python3 todo.py h +echo $? +python3 todo.py asdf +echo $? + +python3 todo.py list + +python3 todo.py add Test +python3 todo.py list +python3 todo.py list Test +python3 todo.py add test Test +python3 todo.py list Test +python3 todo.py list + +python3 todo.py complete test Test +python3 todo.py list Test +python3 todo.py list +python3 todo.py complete Test +python3 todo.py list + +python3 todo.py remove test Test +python3 todo.py list Test +python3 todo.py list +python3 todo.py remove Test +python3 todo.py list -- 2.45.3 From 3021ab1cf093fea338f450a0072dfc016ee7cb3b Mon Sep 17 00:00:00 2001 From: Yehuda Deutsch Date: Tue, 12 Nov 2024 00:39:49 -0500 Subject: [PATCH 3/3] Fix doitlive echo --- doitlive.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/doitlive.sh b/doitlive.sh index 67e7059..e8e2fba 100644 --- a/doitlive.sh +++ b/doitlive.sh @@ -4,10 +4,8 @@ python3 todo.py --help python3 todo.py help python3 todo.py -h -python3 todo.py h -echo $? -python3 todo.py asdf -echo $? +python3 todo.py h; echo $? +python3 todo.py asdf; echo $? python3 todo.py list -- 2.45.3