This repository was archived by the owner on Mar 8, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathInstallerAutoUpdater.py
More file actions
169 lines (149 loc) · 6.49 KB
/
InstallerAutoUpdater.py
File metadata and controls
169 lines (149 loc) · 6.49 KB
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
import os
import sys
import json
import shutil
import subprocess
import requests
from datetime import datetime
from dulwich import porcelain
import atexit
import time
if hasattr(sys, '_MEIPASS'):
temp_dir = sys._MEIPASS
@atexit.register
def cleanup_temp_dir():
for _ in range(5): # Retry cleanup up to 5 times
try:
shutil.rmtree(temp_dir, ignore_errors=True)
print(f"Successfully cleaned up temporary directory: {temp_dir}")
break
except Exception as e:
print(f"Failed to clean up temporary directory {temp_dir}: {e}")
time.sleep(1) # Wait before retrying
class InstallerAutoUpdater:
def __init__(self):
self.base_path = os.path.join(os.environ['USERPROFILE'], 'OpenWebUI')
self.config_file = os.path.join(self.base_path, 'config.json')
self.exe_name = "InstallerAutoUpdater.exe"
self.repo_url = "https://github.com/BrainDriveAI/OpenWebUI_CondaInstaller"
self.release_url = "https://api.github.com/repos/BrainDriveAI/OpenWebUI_CondaInstaller/releases/latest"
self.exe_path = os.path.join(self.base_path, self.exe_name)
self.current_version = None
self.load_config()
def load_config(self):
"""Load or initialize the configuration file."""
if not os.path.exists(self.config_file):
self.initialize_config()
with open(self.config_file, 'r') as f:
config = json.load(f)
self.base_path = config['install_dir']
self.current_version = config['current_version']
def initialize_config(self):
"""Initialize the config file with default values."""
os.makedirs(self.base_path, exist_ok=True)
default_config = {
"install_dir": self.base_path,
"current_version": None,
"last_checked": None,
}
with open(self.config_file, 'w') as f:
json.dump(default_config, f, indent=4)
def save_config(self, key, value):
"""Save a key-value pair in the configuration."""
with open(self.config_file, 'r') as f:
config = json.load(f)
config[key] = value
with open(self.config_file, 'w') as f:
json.dump(config, f, indent=4)
def get_latest_release(self):
"""Fetch the latest release information from GitHub."""
response = requests.get(self.release_url)
response.raise_for_status()
release_data = response.json()
return release_data
def download_file(self, url, dest_path):
"""Download a file from a URL to the specified destination."""
try:
response = requests.get(url, stream=True, timeout=10)
response.raise_for_status()
with open(dest_path, 'wb') as f:
for chunk in response.iter_content(chunk_size=1024):
f.write(chunk)
except requests.ConnectionError:
print("No internet connection. Unable to download the file.")
return False
except requests.Timeout:
print("The download request timed out. Please try again.")
return False
except requests.RequestException as e:
print(f"An error occurred while downloading the file: {e}")
return False
return True
def check_and_update(self):
"""Check for updates and update if necessary."""
latest_release = self.get_latest_release()
if not latest_release:
print("Update check failed. Please ensure you are connected to the internet.")
return
latest_version = latest_release['tag_name']
download_url = next(
(asset['browser_download_url'] for asset in latest_release['assets']
if asset['name'] == "OpenWebUIInstaller.exe"), None
)
if not download_url:
print("Failed to find the installer in the release assets.")
return
installer_path = os.path.join(self.base_path, "OpenWebUIInstaller.exe")
if self.current_version == latest_version:
self.save_config('last_checked', datetime.now().isoformat())
print("You already have the latest version.")
self.run_exe(installer_path)
else:
print(f"Downloading latest version ({latest_version})...")
if self.download_file(download_url, installer_path):
self.save_config('current_version', latest_version)
self.save_config('last_checked', datetime.now().isoformat())
self.run_exe(installer_path)
else:
print("Download failed. Please try again when you have a stable internet connection.")
def run_exe(self, exe_path):
"""Run the specified executable from the correct location."""
if not os.path.exists(exe_path):
print(f"Error: The executable '{exe_path}' does not exist. Please ensure it has been downloaded successfully.")
return
try:
print(f"Running {exe_path}...")
subprocess.Popen([exe_path], cwd=self.base_path)
except FileNotFoundError:
print(f"Error: Unable to find the executable '{exe_path}'.")
except PermissionError:
print(f"Error: Permission denied while trying to run '{exe_path}'. Ensure you have the necessary permissions.")
except subprocess.CalledProcessError as e:
print(f"Executable returned an error: {e}")
except Exception as e:
print(f"An unexpected error occurred while trying to run the executable: {e}")
finally:
# Ensure cleanup happens here
if hasattr(sys, '_MEIPASS'):
try:
shutil.rmtree(sys._MEIPASS, ignore_errors=True)
except Exception as cleanup_err:
print(f"Failed to remove temporary directory: {cleanup_err}")
sys.exit()
def verify_install(self):
"""Verify the install directory and executable."""
if not os.path.exists(self.base_path):
os.makedirs(self.base_path, exist_ok=True)
if not os.path.exists(self.exe_path):
shutil.copy2(sys.argv[0], self.exe_path)
def main(self):
"""Main execution flow."""
self.verify_install()
self.check_and_update()
if __name__ == "__main__":
try:
updater = InstallerAutoUpdater()
updater.main()
except Exception as e:
print(f"An error occurred: {e}")
sys.exit(1)