#!/usr/bin/env python3 import sys import subprocess import os import logging import argparse # Configure logging log_path = '/tmp/convertions.log' logging.basicConfig( filename=log_path, level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s' ) VERSION = "0.0.1" def display_version(): """Display the current version.""" print(f"Convertions version: {VERSION}") # Mapping of commands to utility scripts SCRIPT_MAP = { "csvtoexcel": "csvtoexcel.py", "csvtojson": "csvtojson.py", "docxtomd": "docxtomd.py", "exceltocsv": "exceltocsv.py", "htmltomd": "htmltomd.py", "jsontocsv": "jsontocsv.py", "mdtohtml": "mdtohtml.py", "yamltomd": "yamltomd.py", "pngtojpg": "pngtojpg.py", "jpgtopng": "jpgtopng.py", "pdftojpg": "pdftojpg.py", "imagetomd": "imagetomd.py", "jpgstopdf": "jpgstopdf.py", "pdftomd": "pdftomd.py", "csvmerge": "csvmerge.py", "mdtabletocsv": "mdtabletocsv.py", "yamlttojson": "yamlttojson.py", "jsontoyaml": "jsontoyaml.py", "audiototext": "audiototext.py", "texttospeech": "texttospeech.py", "videotoaudio": "videotoaudio.py", "pdftoexcel": "pdftoexcel.py", "mergepdfs": "mergepdfs.py" } # Display help for all commands def display_help(): help_text = """ Usage: convertions [args...] Available commands: csvtoexcel csvtojson exceltocsv htmltomd jsontocsv mdtohtml yamltomd pngtojpg jpgtopng pdftojpg imagetomd jpgstopdf ... pdftomd csvmerge ... mdtabletocsv yamlttojson jsontoyaml audiototext texttospeech videotoaudio pdftoexcel docxtomd mergepdfs ... """ print(help_text) def expand_path(path): """ Expand ~ to the user's home directory """ return os.path.expanduser(path) # Adjust script path to locate `utils` correctly in binary or development mode def get_script_path(script_name): # When running as a PyInstaller binary, locate utils in the `_MEIPASS` path if getattr(sys, 'frozen', False): script_path = os.path.join(sys._MEIPASS, 'utils', script_name) else: # In development, locate utils relative to the script script_path = os.path.join(os.path.dirname(__file__), 'utils', script_name) return script_path def validate_paths(command, args): """Validate paths for commands with specific argument requirements.""" if command in ["jpgstopdf", "csvmerge", "mergepdfs"]: output_path = expand_path(args[0]) input_paths = [expand_path(path) for path in args[1:]] if len(input_paths) < 2: raise ValueError(f"Command '{command}' requires at least two input files.") if not all(os.path.isfile(path) for path in input_paths): raise FileNotFoundError("One or more input paths do not exist.") else: if len(args) < 2: raise ValueError(f"Command '{command}' requires an input and an output path.") input_path, output_path = expand_path(args[0]), expand_path(args[1]) if not os.path.isfile(input_path): raise FileNotFoundError(f"Input file '{input_path}' does not exist.") return output_path def run_command(command, args): """Run the specified command by calling the appropriate script.""" if command not in SCRIPT_MAP: raise ValueError(f"Unknown command: {command}") # Validate paths and get output path output_path = validate_paths(command, args) # Locate the correct path for the utility script script_path = get_script_path(SCRIPT_MAP[command]) try: result = subprocess.run([sys.executable, script_path] + args, check=True) logging.info(f"Successfully executed {command} on {args}.") print(f"Conversion completed successfully. Output saved to '{output_path}'.") except subprocess.CalledProcessError as e: logging.error(f"Error executing {command} on {args}: {e}") print(f"Error: Conversion failed. Check the log file at {log_path} for details.") def main(): parser = argparse.ArgumentParser( description="Convertions: A tool for various file format conversions." ) parser.add_argument('--version', '-v', action='store_true', help="Display the program version and exit.") parser.add_argument('command', type=str, nargs='?', help="The command to run (e.g., csvtoexcel, htmltomd).") parser.add_argument('args', nargs=argparse.REMAINDER, help="Arguments for the specified command.") args = parser.parse_args() # Display version and exit if --version or -v is specified if args.version: display_version() sys.exit(0) # If no command is provided, display help and exit if not args.command: display_help() sys.exit(1) # If help is requested, display help and exit if args.command in ["help", "-h", "--help"]: display_help() sys.exit(0) # Run the command try: run_command(args.command, args.args) except (ValueError, FileNotFoundError) as e: print(f"Error: {e}") logging.error(e) display_help() sys.exit(1) if __name__ == "__main__": main()