File size: 9,679 Bytes
9daddd6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
569af75
9daddd6
569af75
9daddd6
569af75
 
9daddd6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
import os
import sys
import urllib.request
import subprocess
import argparse

def convert_to_bool(in_bool):
    # Convert the input to string and lower case, then check against true values
    return str(in_bool).lower() in ('true', 'on', '1', 'y', 'yes')

def install_packages_from_requirements(requirements_file):
    try:
        subprocess.run(['pip3', 'install', '-r', requirements_file, '--upgrade'], check=True)
        print("Packages installed successfully using pip3.")
    except subprocess.CalledProcessError:
        try:
            subprocess.run(['pip', 'install', '-r', requirements_file, '--upgrade'], check=True)
            print("Packages installed successfully using pip.")
        except subprocess.CalledProcessError:
            print("Failed to install packages using both pip3 and pip.")

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()
            out_file.write(data)
        print(f"File downloaded successfully to {output_file}")
    except urllib.error.HTTPError as e:
        print(f"Failed to download file from {url}. HTTP Error Code: {e.code}")
    except urllib.error.URLError as e:
        print(f"URL Error: {e.reason}")
    except Exception as e:
        print(f"An error occurred: {e}")

def prompt_and_save_bazarr_env_variables():
    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"
        "The default values are shown in brackets [] next to the prompts.\n"
        "Items can be the value of true, on, 1, y, yes, false, off, 0, n, no, or an appropriate text response.\n"
    )
    print(instructions)
    env_vars = {
        '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', 'distil-large-v3.5'),
        'WEBHOOKPORT': ('Webhook Port', 'Default listening port for subgen.py', '9000'),
        'TRANSCRIBE_DEVICE': ('Transcribe Device', 'Set as cpu or gpu', 'cpu'),
        # Defaulting to False here for the prompt, user can change
        'DEBUG': ('Debug', 'Enable debug logging (true/false)', 'true'),
        'CLEAR_VRAM_ON_COMPLETE': ('Clear VRAM', 'Attempt to clear VRAM when complete (Windows users may need to set this to False)', 'true'),
        'APPEND': ('Append', 'Append \'Transcribed by whisper\' to generated subtitle (true/false)', 'False'),
    }

    user_input = {}
    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'):
    try:
        with open(env_filename, 'r') as file:
            for line in file:
                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. Consider running with --setup-bazarr or creating it manually.")

def main():
    if 'python3' in sys.executable:
        python_cmd = 'python3'
    elif 'python' in sys.executable:
        python_cmd = 'python'
    else:
        print("Script started with an unknown command")
        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)

    os.chdir(os.path.dirname(os.path.abspath(__file__)))

    parser = argparse.ArgumentParser(prog="python launcher.py", formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    # 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()

    branch_name = args.branch if args.branch != 'main' else os.getenv('BRANCH', 'main')
    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_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

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


    requirements_url = "https://raw.githubusercontent.com/McCloudS/subgen/main/requirements.txt"
    requirements_file = "requirements.txt"

    if args.install:
        download_from_github(requirements_url, requirements_file)
        install_packages_from_requirements(requirements_file)

    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(f"{subgen_script_to_run} exists and UPDATE is set to False, skipping download.")

    if not args.exit_early:
        #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")

if __name__ == "__main__":
    main()