From c80b5db14d88de1a15c07a14f79b47c2e295ce45 Mon Sep 17 00:00:00 2001 From: McCloudS <64094529+McCloudS@users.noreply.github.com> Date: Wed, 14 May 2025 09:57:43 -0600 Subject: [PATCH] Fix terrible hierarchy of environment/external variables DEBUG should be respected now. --- launcher.py | 159 ++++++++++++++++++++++++++++------------------------ 1 file changed, 85 insertions(+), 74 deletions(-) diff --git a/launcher.py b/launcher.py index 42ddfc2..8a1567c 100644 --- a/launcher.py +++ b/launcher.py @@ -10,12 +10,10 @@ def convert_to_bool(in_bool): def install_packages_from_requirements(requirements_file): try: - # Try installing with pip3 subprocess.run(['pip3', 'install', '-r', requirements_file, '--upgrade'], check=True) print("Packages installed successfully using pip3.") except subprocess.CalledProcessError: try: - # If pip3 fails, try installing with pip subprocess.run(['pip', 'install', '-r', requirements_file, '--upgrade'], check=True) print("Packages installed successfully using pip.") except subprocess.CalledProcessError: @@ -24,7 +22,7 @@ def install_packages_from_requirements(requirements_file): def download_from_github(url, output_file): try: with urllib.request.urlopen(url) as response, open(output_file, 'wb') as out_file: - data = response.read() # a `bytes` object + data = response.read() out_file.write(data) print(f"File downloaded successfully to {output_file}") except urllib.error.HTTPError as e: @@ -35,11 +33,6 @@ def download_from_github(url, output_file): print(f"An error occurred: {e}") def prompt_and_save_bazarr_env_variables(): - """ - Prompts the user for Bazarr related environment variables with descriptions and saves them to a file. - If the user does not input anything, default values are used. - """ - # Instructions for the user instructions = ( "You will be prompted for several configuration values.\n" "If you wish to use the default value for any of them, simply press Enter without typing anything.\n" @@ -51,39 +44,35 @@ def prompt_and_save_bazarr_env_variables(): 'WHISPER_MODEL': ('Whisper Model', 'Enter the Whisper model you want to run: tiny, tiny.en, base, base.en, small, small.en, medium, medium.en, large, distil-large-v2, distil-medium.en, distil-small.en', 'medium'), 'WEBHOOKPORT': ('Webhook Port', 'Default listening port for subgen.py', '9000'), 'TRANSCRIBE_DEVICE': ('Transcribe Device', 'Set as cpu or gpu', 'gpu'), - 'DEBUG': ('Debug', 'Enable debug logging', 'True'), + # Defaulting to False here for the prompt, user can change + 'DEBUG': ('Debug', 'Enable debug logging (true/false)', 'False'), 'CLEAR_VRAM_ON_COMPLETE': ('Clear VRAM', 'Attempt to clear VRAM when complete (Windows users may need to set this to False)', 'False'), - 'APPEND': ('Append', 'Append \'Transcribed by whisper\' to generated subtitle', 'False'), + 'APPEND': ('Append', 'Append \'Transcribed by whisper\' to generated subtitle (true/false)', 'False'), } - # Dictionary to hold the user's input user_input = {} - - # Prompt the user for each environment variable and write to .env file with open('subgen.env', 'w') as file: for var, (description, prompt, default) in env_vars.items(): value = input(f"{prompt} [{default}]: ") or default file.write(f"{var}={value}\n") - print("Environment variables have been saved to subgen.env") def load_env_variables(env_filename='subgen.env'): - """ - Loads environment variables from a specified .env file and sets them. - """ try: with open(env_filename, 'r') as file: for line in file: - var, value = line.strip().split('=', 1) - os.environ[var] = value - + line = line.strip() + if line and not line.startswith('#') and '=' in line: + var, value = line.split('=', 1) + # Only set if not already set by a higher priority mechanism (like external env var) + # For this simple loader, we'll let it overwrite, + # and CLI args will overwrite these later if specified. + os.environ[var] = value print(f"Environment variables have been loaded from {env_filename}") - except FileNotFoundError: - print(f"{env_filename} file not found. Please run prompt_and_save_env_variables() first.") + print(f"{env_filename} file not found. Consider running with --setup-bazarr or creating it manually.") def main(): - # Check if the script is run with 'python' or 'python3' if 'python3' in sys.executable: python_cmd = 'python3' elif 'python' in sys.executable: @@ -93,77 +82,99 @@ def main(): sys.exit(1) if sys.version_info[0] < 3: print(f"This script requires Python 3 or higher, you are running {sys.version}") - sys.exit(1) # Terminate the script - - #Make sure we're saving subgen.py and subgen.env in the right folder + sys.exit(1) + os.chdir(os.path.dirname(os.path.abspath(__file__))) - - # Construct the argument parser + parser = argparse.ArgumentParser(prog="python launcher.py", formatter_class=argparse.ArgumentDefaultsHelpFormatter) - parser.add_argument('-d', '--debug', default=True, action='store_true', help="Enable console debugging") - parser.add_argument('-i', '--install', default=False, action='store_true', help="Install/update all necessary packages") - parser.add_argument('-a', '--append', default=False, action='store_true', help="Append 'Transcribed by whisper' to generated subtitle") - parser.add_argument('-u', '--update', default=False, action='store_true', help="Update Subgen") - parser.add_argument('-x', '--exit-early', default=False, action='store_true', help="Exit without running subgen.py") - parser.add_argument('-s', '--setup-bazarr', default=False, action='store_true', help="Prompt for common Bazarr setup parameters and save them for future runs") - parser.add_argument('-b', '--branch', type=str, default='main', help='Specify the branch to download from') - parser.add_argument('-l', '--launcher-update', default=False, action='store_true', help="Update launcher.py and re-launch") + # Changed: action='store_true' means it's False by default, True if flag is present + parser.add_argument('-d', '--debug', action='store_true', help="Enable console debugging (overrides .env and external ENV)") + parser.add_argument('-i', '--install', action='store_true', help="Install/update all necessary packages") + # Changed: action='store_true' + parser.add_argument('-a', '--append', action='store_true', help="Append 'Transcribed by whisper' (overrides .env and external ENV)") + parser.add_argument('-u', '--update', action='store_true', help="Update Subgen") + parser.add_argument('-x', '--exit-early', action='store_true', help="Exit without running subgen.py") + parser.add_argument('-s', '--setup-bazarr', action='store_true', help="Prompt for common Bazarr setup parameters and save them for future runs") + parser.add_argument('-b', '--branch', type=str, default='main', help='Specify the branch to download from') + parser.add_argument('-l', '--launcher-update', action='store_true', help="Update launcher.py and re-launch") args = parser.parse_args() - # Get the branch name from the BRANCH environment variable or default to 'main' branch_name = args.branch if args.branch != 'main' else os.getenv('BRANCH', 'main') - # Determine the script name based on the branch name - script_name = f"-{branch_name}.py" if branch_name != "main" else ".py" - # Check we need to update the launcher - + script_name_suffix = f"-{branch_name}.py" if branch_name != "main" else ".py" + subgen_script_to_run = f"subgen{script_name_suffix}" + language_code_script_to_download = f"language_code{script_name_suffix}" + + if args.launcher_update or convert_to_bool(os.getenv('LAUNCHER_UPDATE')): print(f"Updating launcher.py from GitHub branch {branch_name}...") - download_from_github(f"https://raw.githubusercontent.com/McCloudS/subgen/{branch_name}/launcher.py", f'launcher{script_name}') + download_from_github(f"https://raw.githubusercontent.com/McCloudS/subgen/{branch_name}/launcher.py", f'launcher{script_name_suffix}') + excluded_args = ['--launcher-update', '-l'] + new_args = [arg for arg in sys.argv[1:] if arg not in excluded_args] + print(f"Relaunching updated launcher: launcher{script_name_suffix}") + os.execl(sys.executable, sys.executable, f"launcher{script_name_suffix}", *new_args) + # The script will not continue past os.execl - # Prepare the arguments to exclude update triggers - excluded_args = ['--launcher-update', '-l'] - new_args = [arg for arg in sys.argv[1:] if arg not in excluded_args] - if branch_name == 'main' and args.launcher_update: - print("Running launcher.py for the 'main' branch.") - os.execl(sys.executable, sys.executable, "launcher.py", *new_args) - elif args.launcher_update: - print(f"Running launcher-{branch_name}.py for the '{branch_name}' branch.") - os.execl(sys.executable, sys.executable, f"launcher{script_name}", *new_args) - - # Set environment variables based on the parsed arguments - if not convert_to_bool(os.environ.get('DEBUG', '')): - os.environ['DEBUG'] = str(args.debug) - if not convert_to_bool(os.environ.get('APPEND', '')): - os.environ['APPEND'] = str(args.append) - - if args.setup_bazarr: + # --- Environment Variable Handling --- + # 1. Load from .env file first. This sets a baseline. + # External environment variables (set before launcher.py) will already be in os.environ + # and won't be overwritten by load_env_variables IF load_env_variables checked for existence. + # For simplicity, this version of load_env_variables *will* overwrite. + # If you need to preserve external env vars over .env, load_env_variables needs adjustment. + if args.setup_bazarr: prompt_and_save_bazarr_env_variables() - load_env_variables() + # After saving, load them immediately for this run + load_env_variables() + else: + # Load if not setting up, assuming subgen.env might exist + load_env_variables() + + + # 2. Override with command-line arguments (highest priority for these specific flags) + if args.debug: # If -d or --debug was passed + os.environ['DEBUG'] = 'True' + print("Launcher CLI: DEBUG set to True") + elif 'DEBUG' not in os.environ: # If not set by CLI and not by .env or external + os.environ['DEBUG'] = 'False' # Default to False if nothing else specified it + print("Launcher: DEBUG defaulted to False (no prior setting)") + + + if args.append: # If -a or --append was passed + os.environ['APPEND'] = 'True' + print("Launcher CLI: APPEND set to True") + elif 'APPEND' not in os.environ: # If not set by CLI and not by .env or external + os.environ['APPEND'] = 'False' # Default to False if nothing else specified it + #print("Launcher: APPEND defaulted to False (no prior setting)") + # --- End Environment Variable Handling --- + - # URL to the requirements.txt file on GitHub requirements_url = "https://raw.githubusercontent.com/McCloudS/subgen/main/requirements.txt" requirements_file = "requirements.txt" - # Install packages from requirements.txt if the install or packageupdate argument is True if args.install: download_from_github(requirements_url, requirements_file) install_packages_from_requirements(requirements_file) - # Check if the script exists or if the UPDATE environment variable is set to True - if not os.path.exists(f'subgen{script_name}') or args.update or convert_to_bool(os.getenv('UPDATE')): - print(f"Downloading subgen.py from GitHub branch {branch_name}...") - download_from_github(f"https://raw.githubusercontent.com/McCloudS/subgen/{branch_name}/subgen.py", f'subgen{script_name}') - download_from_github(f"https://raw.githubusercontent.com/McCloudS/subgen/{branch_name}/language_code.py", f'language_code{script_name}') + if not os.path.exists(subgen_script_to_run) or args.update or convert_to_bool(os.getenv('UPDATE')): + print(f"Downloading {subgen_script_to_run} from GitHub branch {branch_name}...") + download_from_github(f"https://raw.githubusercontent.com/McCloudS/subgen/{branch_name}/subgen.py", subgen_script_to_run) + print(f"Downloading {language_code_script_to_download} from GitHub branch {branch_name}...") + download_from_github(f"https://raw.githubusercontent.com/McCloudS/subgen/{branch_name}/language_code.py", language_code_script_to_download) + else: - print("subgen.py exists and UPDATE is set to False, skipping download.") - + print(f"{subgen_script_to_run} exists and UPDATE is set to False, skipping download.") + if not args.exit_early: - print(f'Launching subgen{script_name}') - if branch_name != 'main': - subprocess.run([f'{python_cmd}', '-u', f'subgen{script_name}'], check=True) - else: - subprocess.run([f'{python_cmd}', '-u', 'subgen.py'], check=True) + #print(f"DEBUG environment variable for subgen.py: {os.getenv('DEBUG')}") + #print(f"APPEND environment variable for subgen.py: {os.getenv('APPEND')}") + print(f'Launching {subgen_script_to_run}') + try: + subprocess.run([python_cmd, '-u', subgen_script_to_run], check=True) + except FileNotFoundError: + print(f"Error: Could not find {subgen_script_to_run}. Make sure it was downloaded correctly.") + except subprocess.CalledProcessError as e: + print(f"Error running {subgen_script_to_run}: {e}") + else: print("Not running subgen.py: -x or --exit-early set")