Compare commits

..

6 commits

Author SHA1 Message Date
9bb2e2f8f1
Update doitlive 2024-11-12 00:40:28 -05:00
1a0461eded
Small improvements 2024-11-12 00:40:27 -05:00
3021ab1cf0
Fix doitlive echo 2024-11-12 00:39:49 -05:00
950aa8920a
Add doitlive 2024-11-12 00:26:19 -05:00
aa09137df6
Create a python todo utility 2024-11-11 16:42:06 -05:00
4510216590
Change todo.txt -> todo.md 2024-11-11 14:13:37 -05:00
5 changed files with 195 additions and 0 deletions

3
README.md Normal file
View file

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

11
breakitlive.sh Normal file
View file

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

29
doitlive.sh Normal file
View file

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

View file

152
todo.py Executable file
View file

@ -0,0 +1,152 @@
#!/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()