#!/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(): conn = sqlite3.connect(DB_NAME) 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(command, purpose, keywords): conn = sqlite3.connect(DB_NAME) 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(): conn = sqlite3.connect(DB_NAME) 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(term): conn = sqlite3.connect(DB_NAME) 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(cmd_id): conn = sqlite3.connect(DB_NAME) 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(cmd_id, command, purpose, keywords): conn = sqlite3.connect(DB_NAME) 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 = { "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 == "-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(): init_db() try: parsed = parse_args(sys.argv) validated = validate_args(parsed) if validated['action'] == "add": add_command(validated['command'], validated['purpose'], validated['keywords']) elif validated['action'] == "list": list_commands() elif validated['action'] == "search": search_commands(validated['term']) elif validated['action'] == "delete": delete_command(validated['id']) elif validated['action'] == "edit": edit_command(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: remember.sh add \"ls -la\" -p \"List all files with details\" -k \"linux,files,list\"") print("\t -p = purpose, -k = keywords") print("\n List entries: remember.sh list") print("\n Search: remember.sh search -t KEYWORD or COMMAND or PURPOSE") print("\n Edit entry: remember.sh edit -i 1 -c \"ls -lah\" -k \"linux,files,detailed\"") print("\t -c = command") print("\n Delete entry: remember.sh delete -i 1") if __name__ == "__main__": main()