diff --git a/tasks/cli.py b/tasks/cli.py new file mode 100644 index 0000000..363a36d --- /dev/null +++ b/tasks/cli.py @@ -0,0 +1,61 @@ +import argparse +import sys +from db import init_db, add_task, list_tasks, update_task, delete_task + +def main(): + init_db() + + parser = argparse.ArgumentParser(description="Plexus Task Tracker") + subparsers = parser.add_subparsers(dest="command") + + # Add task + add_parser = subparsers.add_parser("add", help="Add a new task") + add_parser.add_argument("title", help="Task title") + + # List tasks + list_parser = subparsers.add_parser("list", help="List tasks") + list_parser.add_argument("--status", help="Filter by status") + + # Update task + update_parser = subparsers.add_parser("update", help="Update task status") + update_parser.add_argument("id", type=int, help="Task ID") + update_parser.add_argument("status", help="New status") + + # Done task + done_parser = subparsers.add_parser("done", help="Mark task as done") + done_parser.add_argument("id", type=int, help="Task ID") + + # Delete task + delete_parser = subparsers.add_parser("delete", help="Delete a task") + delete_parser.add_argument("id", type=int, help="Task ID") + + args = parser.parse_args() + + if args.command == "add": + add_task(args.title) + print(f"Task added: {args.title}") + + elif args.command == "list": + tasks = list_tasks(args.status) + print(f"{'ID':<5} {'Status':<15} {'Title'}") + print("-" * 40) + for t in tasks: + print(f"{t[0]:<5} {t[2]:<15} {t[1]}") + + elif args.command == "update": + update_task(args.id, args.status) + print(f"Task {args.id} updated to {args.status}") + + elif args.command == "done": + update_task(args.id, "done") + print(f"Task {args.id} marked as done") + + elif args.command == "delete": + delete_task(args.id) + print(f"Task {args.id} deleted") + + else: + parser.print_help() + +if __name__ == "__main__": + main() diff --git a/tasks/db.py b/tasks/db.py new file mode 100644 index 0000000..6ca5d35 --- /dev/null +++ b/tasks/db.py @@ -0,0 +1,48 @@ +import duckdb +import os + +DB_PATH = "data/tasks.duckdb" + +def init_db(): + if not os.path.exists("data"): + os.makedirs("data") + + con = duckdb.connect(DB_PATH) + con.execute(""" + CREATE TABLE IF NOT EXISTS tasks ( + id INTEGER PRIMARY KEY, + title VARCHAR, + status VARCHAR DEFAULT 'todo', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ) + """) + con.execute("CREATE SEQUENCE IF NOT EXISTS seq_task_id START 1") + con.close() + +def get_connection(): + return duckdb.connect(DB_PATH) + +def add_task(title): + con = get_connection() + con.execute("INSERT INTO tasks (id, title) VALUES (nextval('seq_task_id'), ?)", [title]) + con.close() + +def list_tasks(status=None): + con = get_connection() + if status: + res = con.execute("SELECT * FROM tasks WHERE status = ? ORDER BY id", [status]).fetchall() + else: + res = con.execute("SELECT * FROM tasks ORDER BY id").fetchall() + con.close() + return res + +def update_task(task_id, status): + con = get_connection() + con.execute("UPDATE tasks SET status = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?", [status, task_id]) + con.close() + +def delete_task(task_id): + con = get_connection() + con.execute("DELETE FROM tasks WHERE id = ?", [task_id]) + con.close()