|
|
#!/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()
|
|
|
|