Spaces:
Running
Running
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import sys
|
3 |
+
import urllib.request
|
4 |
+
import subprocess
|
5 |
+
import argparse
|
6 |
+
|
7 |
+
def convert_to_bool(in_bool):
|
8 |
+
# Convert the input to string and lower case, then check against true values
|
9 |
+
return str(in_bool).lower() in ('true', 'on', '1', 'y', 'yes')
|
10 |
+
|
11 |
+
def install_packages_from_requirements(requirements_file):
|
12 |
+
try:
|
13 |
+
# Try installing with pip3
|
14 |
+
subprocess.run(['pip3', 'install', '-r', requirements_file, '--upgrade'], check=True)
|
15 |
+
print("Packages installed successfully using pip3.")
|
16 |
+
except subprocess.CalledProcessError:
|
17 |
+
try:
|
18 |
+
# If pip3 fails, try installing with pip
|
19 |
+
subprocess.run(['pip', 'install', '-r', requirements_file, '--upgrade'], check=True)
|
20 |
+
print("Packages installed successfully using pip.")
|
21 |
+
except subprocess.CalledProcessError:
|
22 |
+
print("Failed to install packages using both pip3 and pip.")
|
23 |
+
|
24 |
+
def download_from_github(url, output_file):
|
25 |
+
try:
|
26 |
+
with urllib.request.urlopen(url) as response, open(output_file, 'wb') as out_file:
|
27 |
+
data = response.read() # a `bytes` object
|
28 |
+
out_file.write(data)
|
29 |
+
print(f"File downloaded successfully to {output_file}")
|
30 |
+
except urllib.error.HTTPError as e:
|
31 |
+
print(f"Failed to download file from {url}. HTTP Error Code: {e.code}")
|
32 |
+
except urllib.error.URLError as e:
|
33 |
+
print(f"URL Error: {e.reason}")
|
34 |
+
except Exception as e:
|
35 |
+
print(f"An error occurred: {e}")
|
36 |
+
|
37 |
+
def prompt_and_save_bazarr_env_variables():
|
38 |
+
"""
|
39 |
+
Prompts the user for Bazarr related environment variables with descriptions and saves them to a file.
|
40 |
+
If the user does not input anything, default values are used.
|
41 |
+
"""
|
42 |
+
# Instructions for the user
|
43 |
+
instructions = (
|
44 |
+
"You will be prompted for several configuration values.\n"
|
45 |
+
"If you wish to use the default value for any of them, simply press Enter without typing anything.\n"
|
46 |
+
"The default values are shown in brackets [] next to the prompts.\n"
|
47 |
+
"Items can be the value of true, on, 1, y, yes, false, off, 0, n, no, or an appropriate text response.\n"
|
48 |
+
)
|
49 |
+
print(instructions)
|
50 |
+
env_vars = {
|
51 |
+
'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'),
|
52 |
+
'WEBHOOKPORT': ('Webhook Port', 'Default listening port for subgen.py', '9000'),
|
53 |
+
'TRANSCRIBE_DEVICE': ('Transcribe Device', 'Set as cpu or gpu', 'gpu'),
|
54 |
+
'DEBUG': ('Debug', 'Enable debug logging', 'True'),
|
55 |
+
'CLEAR_VRAM_ON_COMPLETE': ('Clear VRAM', 'Attempt to clear VRAM when complete (Windows users may need to set this to False)', 'False'),
|
56 |
+
'APPEND': ('Append', 'Append \'Transcribed by whisper\' to generated subtitle', 'False'),
|
57 |
+
}
|
58 |
+
|
59 |
+
# Dictionary to hold the user's input
|
60 |
+
user_input = {}
|
61 |
+
|
62 |
+
# Prompt the user for each environment variable and write to .env file
|
63 |
+
with open('subgen.env', 'w') as file:
|
64 |
+
for var, (description, prompt, default) in env_vars.items():
|
65 |
+
value = input(f"{prompt} [{default}]: ") or default
|
66 |
+
file.write(f"{var}={value}\n")
|
67 |
+
|
68 |
+
print("Environment variables have been saved to subgen.env")
|
69 |
+
|
70 |
+
def load_env_variables(env_filename='subgen.env'):
|
71 |
+
"""
|
72 |
+
Loads environment variables from a specified .env file and sets them.
|
73 |
+
"""
|
74 |
+
try:
|
75 |
+
with open(env_filename, 'r') as file:
|
76 |
+
for line in file:
|
77 |
+
var, value = line.strip().split('=', 1)
|
78 |
+
os.environ[var] = value
|
79 |
+
|
80 |
+
print(f"Environment variables have been loaded from {env_filename}")
|
81 |
+
|
82 |
+
except FileNotFoundError:
|
83 |
+
print(f"{env_filename} file not found. Please run prompt_and_save_env_variables() first.")
|
84 |
+
|
85 |
+
def main():
|
86 |
+
# Check if the script is run with 'python' or 'python3'
|
87 |
+
if 'python3' in sys.executable:
|
88 |
+
python_cmd = 'python3'
|
89 |
+
elif 'python' in sys.executable:
|
90 |
+
python_cmd = 'python'
|
91 |
+
else:
|
92 |
+
print("Script started with an unknown command")
|
93 |
+
sys.exit(1)
|
94 |
+
if sys.version_info[0] < 3:
|
95 |
+
print(f"This script requires Python 3 or higher, you are running {sys.version}")
|
96 |
+
sys.exit(1) # Terminate the script
|
97 |
+
|
98 |
+
#Make sure we're saving subgen.py and subgen.env in the right folder
|
99 |
+
os.chdir(os.path.dirname(os.path.abspath(__file__)))
|
100 |
+
|
101 |
+
# Construct the argument parser
|
102 |
+
parser = argparse.ArgumentParser(prog="python launcher.py", formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
103 |
+
parser.add_argument('-d', '--debug', default=False, action='store_true', help="Enable console debugging")
|
104 |
+
parser.add_argument('-i', '--install', default=False, action='store_true', help="Install/update all necessary packages")
|
105 |
+
parser.add_argument('-a', '--append', default=False, action='store_true', help="Append 'Transcribed by whisper' to generated subtitle")
|
106 |
+
parser.add_argument('-u', '--update', default=False, action='store_true', help="Update Subgen")
|
107 |
+
parser.add_argument('-x', '--exit-early', default=False, action='store_true', help="Exit without running subgen.py")
|
108 |
+
parser.add_argument('-s', '--setup-bazarr', default=False, action='store_true', help="Prompt for common Bazarr setup parameters and save them for future runs")
|
109 |
+
parser.add_argument('-b', '--branch', type=str, default='main', help='Specify the branch to download from')
|
110 |
+
parser.add_argument('-l', '--launcher-update', default=False, action='store_true', help="Update launcher.py and re-launch")
|
111 |
+
|
112 |
+
args = parser.parse_args()
|
113 |
+
|
114 |
+
# Get the branch name from the BRANCH environment variable or default to 'main'
|
115 |
+
branch_name = args.branch if args.branch != 'main' else os.getenv('BRANCH', 'main')
|
116 |
+
# Determine the script name based on the branch name
|
117 |
+
script_name = f"-{branch_name}.py" if branch_name != "main" else ".py"
|
118 |
+
# Check we need to update the launcher
|
119 |
+
|
120 |
+
if args.launcher_update or convert_to_bool(os.getenv('LAUNCHER_UPDATE')):
|
121 |
+
print(f"Updating launcher.py from GitHub branch {branch_name}...")
|
122 |
+
download_from_github(f"https://raw.githubusercontent.com/McCloudS/subgen/{branch_name}/launcher.py", f'launcher{script_name}')
|
123 |
+
|
124 |
+
# Prepare the arguments to exclude update triggers
|
125 |
+
excluded_args = ['--launcher-update', '-l']
|
126 |
+
new_args = [arg for arg in sys.argv[1:] if arg not in excluded_args]
|
127 |
+
if branch_name == 'main' and args.launcher_update:
|
128 |
+
print("Running launcher.py for the 'main' branch.")
|
129 |
+
os.execl(sys.executable, sys.executable, "launcher.py", *new_args)
|
130 |
+
elif args.launcher_update:
|
131 |
+
print(f"Running launcher-{branch_name}.py for the '{branch_name}' branch.")
|
132 |
+
os.execl(sys.executable, sys.executable, f"launcher{script_name}", *new_args)
|
133 |
+
|
134 |
+
# Set environment variables based on the parsed arguments
|
135 |
+
os.environ['DEBUG'] = str(args.debug)
|
136 |
+
os.environ['APPEND'] = str(args.append)
|
137 |
+
|
138 |
+
if args.setup_bazarr:
|
139 |
+
prompt_and_save_bazarr_env_variables()
|
140 |
+
load_env_variables()
|
141 |
+
|
142 |
+
# URL to the requirements.txt file on GitHub
|
143 |
+
requirements_url = "https://raw.githubusercontent.com/McCloudS/subgen/main/requirements.txt"
|
144 |
+
requirements_file = "requirements.txt"
|
145 |
+
|
146 |
+
# Install packages from requirements.txt if the install or packageupdate argument is True
|
147 |
+
if args.install:
|
148 |
+
download_from_github(requirements_url, requirements_file)
|
149 |
+
install_packages_from_requirements(requirements_file)
|
150 |
+
|
151 |
+
# Check if the script exists or if the UPDATE environment variable is set to True
|
152 |
+
if not os.path.exists(f'subgen{script_name}') or args.update or convert_to_bool(os.getenv('UPDATE')):
|
153 |
+
print(f"Downloading subgen.py from GitHub branch {branch_name}...")
|
154 |
+
download_from_github(f"https://raw.githubusercontent.com/McCloudS/subgen/{branch_name}/subgen.py", f'subgen{script_name}')
|
155 |
+
else:
|
156 |
+
print("subgen.py exists and UPDATE is set to False, skipping download.")
|
157 |
+
|
158 |
+
if not args.exit_early:
|
159 |
+
print(f'Launching subgen{script_name}')
|
160 |
+
if branch_name != 'main':
|
161 |
+
subprocess.run([f'{python_cmd}', '-u', f'subgen{script_name}'], check=True)
|
162 |
+
else:
|
163 |
+
subprocess.run([f'{python_cmd}', '-u', 'subgen.py'], check=True)
|
164 |
+
else:
|
165 |
+
print("Not running subgen.py: -x or --exit-early set")
|
166 |
+
|
167 |
+
if __name__ == "__main__":
|
168 |
+
main()
|