#!/usr/bin/env python3 import sqlite3 from pathlib import Path import os import sys home = Path.home() DB_NAME = os.path.join(str(home), "CommandsToRemember.db") VALID_ACTIONS = {"add", "list", "search", "edit", "delete"} def init_db(db): conn = sqlite3.connect(db) cur = conn.cursor() cur.execute(""" CREATE TABLE IF NOT EXISTS commands ( id INTEGER PRIMARY KEY AUTOINCREMENT, command TEXT NOT NULL, purpose TEXT, keywords TEXT ) """) conn.commit() conn.close() def add_command(db, command, purpose, keywords): conn = sqlite3.connect(db) cur = conn.cursor() cur.execute( "INSERT INTO commands (command, purpose, keywords) VALUES (?, ?, ?)", (command, purpose, keywords) ) conn.commit() conn.close() print("✅ Command saved.") def list_commands(db): conn = sqlite3.connect(db) cur = conn.cursor() cur.execute("SELECT id, command, purpose, keywords FROM commands") rows = cur.fetchall() if not rows: print("No commands stored.") return for row in rows: print(f"\nID: {row[0]}") print(f"Command: {row[1]}") print(f"Purpose: {row[2]}") print(f"Keywords: {row[3]}") conn.close() def search_commands(db, term): conn = sqlite3.connect(db) cur = conn.cursor() like_term = f"%{term}%" cur.execute(""" SELECT id, command, purpose, keywords FROM commands WHERE command LIKE ? OR purpose LIKE ? OR keywords LIKE ? """, (like_term, like_term, like_term)) rows = cur.fetchall() if not rows: print("No matches found.") return for row in rows: print(f"\nID: {row[0]}") print(f"Command: {row[1]}") print(f"Purpose: {row[2]}") print(f"Keywords: {row[3]}") conn.close() def delete_command(db, cmd_id): conn = sqlite3.connect(db) cur = conn.cursor() cur.execute("SELECT * FROM commands WHERE id = ?", (cmd_id,)) row = cur.fetchone() if not row: print("❌ Command not found.") conn.close() return confirm = input(f"Delete command '{row[1]}'? (y/N): ").strip().lower() if confirm == "y": cur.execute("DELETE FROM commands WHERE id = ?", (cmd_id,)) conn.commit() print("🗑️ Command deleted.") else: print("Canceled.") conn.close() def edit_command(db, cmd_id, command, purpose, keywords): conn = sqlite3.connect(db) cur = conn.cursor() cur.execute("SELECT command, purpose, keywords FROM commands WHERE id = ?", (cmd_id,)) row = cur.fetchone() if not row: print("❌ Command not found.") conn.close() return # Keep existing values if not provided new_command = command if command else row[0] new_purpose = purpose if purpose else row[1] new_keywords = keywords if keywords else row[2] cur.execute(""" UPDATE commands SET command = ?, purpose = ?, keywords = ? WHERE id = ? """, (new_command, new_purpose, new_keywords, cmd_id)) conn.commit() conn.close() print("✏️ Command updated.") def parse_args(argv): if len(argv) < 2: raise ValueError("Missing action (add, list, search, edit, delete)") # First positional argument action = argv[1] if action not in VALID_ACTIONS: raise ValueError(f"Invalid action: {action}") args = { "database": DB_NAME, "action": action, "id": None, "command": None, "purpose": None, "keywords": None, "term": None } i = 2 while i < len(argv): arg = argv[i] num = i + 1 size = len(argv) i += 2 if num < size: value = argv[num] else: value = "" if arg == "-c": if value == "": raise ValueError("Missing value -c") else: args["command"] = value elif arg == "-d": if value == "": args["database"] = DB_NAME else: args["database"] = value elif arg == "-p": if value == "": raise ValueError("Missing value -p") else: args["purpose"] = value elif arg == "-k": if value == "": raise ValueError("Missing value -k") else: args["keywords"] = value elif arg == "-t": if value == "": raise ValueError("Missing value -t") else: args["term"] = value elif arg == "-i": if value == "": raise ValueError("Missing value -i") else: try: args["id"] = int(value) except ValueError: raise ValueError("ID must be a number") return args def validate_args(args): # print("Parsed Arguments:") # print(f" Action : {args['action']}") # print(f" Command: {args['command']}") # print(f" Purpose: {args['purpose']}") action = args["action"] # Only require flags for certain actions if action in {"add"}: if args["command"] is None: raise ValueError("'-c' (command) is required for add/edit") if args["purpose"] is None: raise ValueError("'-p' (purpose) is required for add/edit") if action in {"edit", "delete"}: if args["id"] is None: raise ValueError("'-i' (id) is required for edit/delete") return args def main(): try: parsed = parse_args(sys.argv) validated = validate_args(parsed) db = validated['database'] init_db(db) if validated['action'] == "add": add_command(db, validated['command'], validated['purpose'], validated['keywords']) elif validated['action'] == "list": list_commands(db) elif validated['action'] == "search": search_commands(db, validated['term']) elif validated['action'] == "delete": delete_command(db, validated['id']) elif validated['action'] == "edit": edit_command(db, validated['id'], validated['command'], validated['purpose'], validated['keywords']) except ValueError as e: print(f"Error: {e}") print_usage() sys.exit(1) def print_usage(): print("\nUsage:") print("\n Add entry: rem add -c \"ls -la\" -p \"List all files with details\" -k \"linux,files,list\"") print("\t -p = purpose, -k = keywords") print("\n List entries: rem list") print("\n Search: rem search -t KEYWORD or COMMAND or PURPOSE") print("\n Edit entry: rem edit -i 1 -c \"ls -lah\" -k \"linux,files,detailed\"") print("\t -c = command") print("\n Delete entry: rem delete -i 1") if __name__ == "__main__": main()