Compare commits

..

No commits in common. "03-fault-tolerance" and "master" have entirely different histories.

5 changed files with 0 additions and 195 deletions

View file

@ -1,3 +0,0 @@
# Ajal Todo CLI
A todo utility

View file

@ -1,11 +0,0 @@
#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 Test test1 test2
python3 todo.py add Test test1 test3
python3 todo.py complete Test test1 test3
python3 todo.py remove Test test1 test3

View file

@ -1,29 +0,0 @@
#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

152
todo.py
View file

@ -1,152 +0,0 @@
#!/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):
todo = parse_todo()
if parent and parent not in todo:
print(f"Could not find parent task '{parent}' in root task list")
exit(1)
print(f"Adding task '{task}' to '{parent if parent else 'root'}'")
if parent:
todo[parent]["sub_tasks"][task] = {"completed": False}
else:
todo[task] = {"completed": False, "sub_tasks": {}}
write_todo(todo)
def list_tasks(parent=None):
todo = parse_todo()
if parent and parent not in todo:
print(f"Could not find parent task '{parent}' in root task list")
exit(1)
print(f"Listing tasks in '{parent if parent else 'root'}'")
if parent:
todo = {parent: todo[parent]}
print(render_todo(todo))
def complete_task(task, parent=None):
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)
print(f"Marking task '{task}' in '{parent if parent else 'root'}' as completed")
if parent:
task = todo[parent]["sub_tasks"][task]
else:
task = todo[task]
task["completed"] = True
write_todo(todo)
def remove_task(task, parent=None):
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)
print(f"Removing task '{task}' from '{parent if parent else 'root'}'")
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<status>[x ])]\s+)?(?P<task>.+)$", 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<status>[x ])]\s+)?(?P<task>.+)$", 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 [parent, task, *_]:
globals()[task_func](task, parent)
case _:
print_help()
exit(1)
case _:
print_help()
exit(1)
if __name__ == "__main__":
main()

View file