|
|
|
|
@ -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() |