#!/usr/bin/env python3 import argparse import glob import os from cli import opt_generate_keypair from cli import opt_save_private_key from cli import opt_load_private_key from cli import opt_save_public_key from cli import opt_mine_block from cli import opt_generate_transaction from cli import opt_view_deck from cli import msg_array from cli import get_private_key_from_file from cli import fetch_cards_json DEFAULT_FILENAME: str = "privatekey"; def resolve_path(path: str | None) -> str | None: if not path or path.strip() == "": return None; path = path.strip(); if not path.endswith(".pem"): path += ".pem"; if os.path.exists(path) and os.path.isfile(path): return path; return None; def resolve_path_for_key_creation(filename:str | None) -> str: default_name = "privatekey.pem"; if not filename or filename.strip() == "": return default_name; filename = filename.strip(); if os.path.isdir(filename): return os.path.join(filename, default_name); if not filename.endswith(".pem"): filename += ".pem"; dir_path = os.path.dirname(filename); if dir_path and not os.path.exists(dir_path): os.makedirs(dir_path); return filename; def get_first_pem_file(): pem_files = glob.glob("*.pem"); if pem_files: first_pem = min(pem_files, key=os.path.getmtime); return first_pem; else: return None; def handle_createkey(args): rsa_key = opt_generate_keypair(); filepath = resolve_path_for_key_creation(args.output); opt_save_private_key(rsa_key, filepath); print(msg_array[0]); public_path = f"pub_{filepath}" opt_save_public_key(rsa_key, public_path); def handle_mine(args): file = resolve_path(args.use); if not file: file = get_first_pem_file(); if not file: msg_array[0] = "No valid private key found"; return; opt_mine_block(file); def handle_tx(args): file = resolve_path(args.use); if not file: file = get_first_pem_file(); if not file: msg_array[0] = "No valid private key found"; return; recv = resolve_path(args.receiver); if args.receiver and not recv: msg_array[0] = "No valid public key found (receiver)"; return; opt_generate_transaction(file, recv); def handle_deck(args): file = resolve_path(args.use); if not file: file = get_first_pem_file(); if not file: msg_array[0] = "No valid private key found"; return; rsa = get_private_key_from_file(file); if rsa is None: return; cards = fetch_cards_json(rsa); if len(cards) < 1: msg_array[0] = "You have no cards to view"; return; for i, card in enumerate(cards): print(f"{i+1}. Card ID: {card['cardId']}, Page ID: {card['pageId']}"); def build_parser(): parser = argparse.ArgumentParser(description="Wikideck CLI"); subparsers = parser.add_subparsers(dest="command", required=True); #createkey p_create = subparsers.add_parser("createkey",aliases=["ck"], help="Create an RSA keypair and save it to the current directory"); p_create.add_argument("-O", "--output", help="Optional custom filename (.pem)"); p_create.set_defaults(func=handle_createkey); #mine p_mine = subparsers.add_parser("mine", help="Mine a block, using the first ./*.pem by default."); p_mine.add_argument("-u", "--use", help="Use specified keypair (path to .pem file)"); p_mine.set_defaults(func=handle_mine); #transaction p_transaction = subparsers.add_parser("transaction", aliases=["tx"], help="Generate a transaction, using the first ./*.pem by default."); p_transaction.add_argument("-u", "--use", help="Use specified keypair (path to .pem file)"); p_transaction.add_argument("-to", "--receiver", help="Send to specified public key (path to .pem file)"); p_transaction.set_defaults(func=handle_tx); #deck p_deck = subparsers.add_parser("deck", help="Show all cards tied to the private key, using the first ./*.pem by default."); p_deck.add_argument("-u", "--use", help="Use specified keypair (path to .pem file)"); p_deck.set_defaults(func=handle_deck); return parser; def main(): parser = build_parser(); args = parser.parse_args(); args.func(args); print(msg_array[0]); if __name__ == "__main__": main();