commit f9f3422387bedbf34c233f85c13cfe1a62f2b173 Author: Robert Date: Thu Mar 26 17:29:57 2026 -0400 Remember INIT diff --git a/README.md b/README.md new file mode 100644 index 0000000..3f9f0c3 --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +# Remember Commands with Python +## remember.py + +## Make Symbolic Link +``` +sudo ln -s $(pwd)/remember.py /usr/local/bin/rem +``` +# Add entry +``` +rem add "ls -la" -p "List all files with details" -k "linux,files,list" +``` +-p = purpose +-k = keywords + +# List entries +``` +rem list +``` + +# Search +``` +rem search -t KEYWORK or PURPOSE or COMMAND +``` + +# Edit entry +``` +rem edit -i 1 -c "ls -lah" -k "linux,files,detailed" +``` +-i = ID# +-c = command + +# Delete entry +``` +rem delete -i 1 +``` diff --git a/remember.py b/remember.py new file mode 100755 index 0000000..4e31ef2 --- /dev/null +++ b/remember.py @@ -0,0 +1,272 @@ +#!/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()