Autoupdates
All checks were successful
Build and Upload Release (Windows EXE) / Build Windows EXE (release) Successful in 42s

This commit is contained in:
2026-01-24 01:55:54 -05:00
parent 49ba0a4602
commit f1cd7eadb9
2 changed files with 174 additions and 21 deletions

View File

@@ -2808,7 +2808,7 @@ def show_blocking_update_dialog(root, update_checker, release_info):
# Calculate window size and center it
window_width = 600
window_height = 500
window_height = 600 # Increased height to accommodate buttons
# Get screen dimensions
screen_width = update_window.winfo_screenwidth()
@@ -2825,7 +2825,7 @@ def show_blocking_update_dialog(root, update_checker, release_info):
text="🔄 Update Required",
fg='#ff6b6b', bg='#2b2b2b',
font=('Arial', 20, 'bold'))
title_label.pack(pady=30)
title_label.pack(pady=20)
# Message
message_label = tk.Label(update_window,
@@ -2836,7 +2836,7 @@ def show_blocking_update_dialog(root, update_checker, release_info):
# Version info
version_frame = tk.Frame(update_window, bg='#2b2b2b')
version_frame.pack(pady=20)
version_frame.pack(pady=15)
current_label = tk.Label(version_frame,
text=f"Current Version: {update_checker.current_version}",
@@ -2856,14 +2856,14 @@ def show_blocking_update_dialog(root, update_checker, release_info):
text="What's New:",
fg='white', bg='#2b2b2b',
font=('Arial', 14, 'bold'))
notes_label.pack(pady=(30, 10))
notes_label.pack(pady=(20, 10))
# Create scrollable text widget for release notes
notes_frame = tk.Frame(update_window, bg='#2b2b2b')
notes_frame.pack(fill='both', expand=True, padx=40, pady=(0, 20))
notes_frame.pack(fill='both', expand=True, padx=40, pady=(0, 10))
notes_text = tk.Text(notes_frame,
height=8,
height=6, # Reduced height to make room for buttons
bg='#404040', fg='#ffffff',
font=('Arial', 11),
wrap=tk.WORD,
@@ -2883,14 +2883,154 @@ def show_blocking_update_dialog(root, update_checker, release_info):
notes_text.insert('1.0', release_info['body'])
notes_text.config(state='disabled')
# Buttons
# Buttons - fixed at bottom
button_frame = tk.Frame(update_window, bg='#2b2b2b')
button_frame.pack(pady=30)
button_frame.pack(side='bottom', pady=20) # Pack at bottom with padding
def download_and_exit():
"""Open download page and exit the application"""
def auto_update():
"""Download and install the update automatically"""
try:
# Disable buttons during download
auto_btn.config(state='disabled', text='Downloading...')
download_btn.config(state='disabled')
exit_btn.config(state='disabled')
# Update the window to show progress
update_window.update()
# Start download in a separate thread
import threading
threading.Thread(target=perform_auto_update, daemon=True).start()
except Exception as e:
print(f"Auto update failed: {e}")
# Re-enable buttons on error
auto_btn.config(state='normal', text='Auto Update')
download_btn.config(state='normal')
exit_btn.config(state='normal')
def perform_auto_update():
"""Perform the actual auto update process"""
try:
import requests
import tempfile
import shutil
import subprocess
import sys
# Find the EXE asset in the release
exe_asset = None
for asset in release_info.get('assets', []):
if asset.get('name', '').endswith('.exe'):
exe_asset = asset
break
if not exe_asset:
raise Exception("No EXE file found in release assets")
download_url = exe_asset.get('browser_download_url')
if not download_url:
raise Exception("No download URL found for EXE asset")
# Update status
root.after(0, lambda: auto_btn.config(text='Downloading...'))
# Download the new EXE
response = requests.get(download_url, stream=True)
response.raise_for_status()
# Save to temporary file
with tempfile.NamedTemporaryFile(delete=False, suffix='.exe') as temp_file:
temp_path = temp_file.name
for chunk in response.iter_content(chunk_size=8192):
temp_file.write(chunk)
# Get current executable path
if getattr(sys, 'frozen', False):
# Running as PyInstaller bundle
current_exe = sys.executable
else:
# Running as script - for testing
current_exe = sys.argv[0]
# Update status
root.after(0, lambda: auto_btn.config(text='Installing...'))
# Get configuration
from update_config import get_update_config
config = get_update_config()
auto_restart = config.get("auto_restart_after_update", True)
# Create a batch script to replace the executable and optionally restart
if auto_restart:
restart_command = f'start "" /B "{current_exe}"'
restart_message = "Starting new version..."
else:
restart_command = 'echo Please manually start the application.'
restart_message = "Please manually start the updated application."
batch_script = f'''@echo off
echo Updating Progression Loader...
timeout /t 3 /nobreak >nul
REM Replace the executable
move "{temp_path}" "{current_exe}"
if errorlevel 1 (
echo Failed to replace executable
pause
exit /b 1
)
echo Update complete! {restart_message}
timeout /t 1 /nobreak >nul
REM Start the new executable (if configured)
{restart_command}
REM Clean up this batch file
timeout /t 2 /nobreak >nul
del "%~f0"
'''
# Write batch script to temp file
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.bat') as batch_file:
batch_file.write(batch_script)
batch_path = batch_file.name
# Update status
root.after(0, lambda: auto_btn.config(text='Restarting...'))
# Show success message
root.after(0, lambda: tk.messagebox.showinfo(
"Update Complete",
"Update downloaded successfully!\nThe application will restart automatically.",
parent=update_window
))
# Execute the batch script and exit
subprocess.Popen([batch_path], shell=True)
# Exit the current application
root.after(2000, root.quit)
except Exception as e:
print(f"Auto update failed: {e}")
# Re-enable buttons on error
root.after(0, lambda: auto_btn.config(state='normal', text='Auto Update'))
root.after(0, lambda: download_btn.config(state='normal'))
root.after(0, lambda: exit_btn.config(state='normal'))
# Show error message
root.after(0, lambda: tk.messagebox.showerror(
"Auto Update Failed",
f"Failed to automatically update:\n{str(e)}\n\nPlease use 'Download Page' to update manually.",
parent=update_window
))
def download_page():
"""Open the release download page"""
webbrowser.open(release_info['html_url'])
print("Please download and install the update, then restart the application.")
print("Please download and install the update manually, then restart the application.")
root.quit() # Exit the entire application
def exit_app():
@@ -2898,17 +3038,27 @@ def show_blocking_update_dialog(root, update_checker, release_info):
print("Application cannot continue without updating.")
root.quit()
# Download Update button (primary action)
# Auto Update button (primary action)
auto_btn = tk.Button(button_frame,
text="Auto Update",
command=auto_update,
bg='#4ecdc4', fg='white',
font=('Arial', 14, 'bold'),
padx=30, pady=10,
cursor='hand2')
auto_btn.pack(side='left', padx=10)
# Download Page button (secondary action)
download_btn = tk.Button(button_frame,
text="Download Update & Exit",
command=download_and_exit,
bg='#4ecdc4', fg='white',
font=('Arial', 14, 'bold'),
padx=30, pady=10,
text="Download Page",
command=download_page,
bg='#45b7d1', fg='white',
font=('Arial', 12),
padx=20, pady=10,
cursor='hand2')
download_btn.pack(side='left', padx=10)
# Exit button (secondary action)
# Exit button (tertiary action)
exit_btn = tk.Button(button_frame,
text="Exit Application",
command=exit_app,
@@ -2921,8 +3071,8 @@ def show_blocking_update_dialog(root, update_checker, release_info):
# Handle window close (same as exit)
update_window.protocol("WM_DELETE_WINDOW", exit_app)
# Focus on the download button
download_btn.focus_set()
# Focus on the auto update button
auto_btn.focus_set()
print("Blocking update dialog shown - app will not continue until user updates")

View File

@@ -5,7 +5,7 @@ Configuration settings for the update checker
# Update checker configuration
UPDATE_CONFIG = {
# Current version of the application
"current_version": "0.0.1",
"current_version": "0.0.3",
# Repository information
"repo_owner": "HRiggs",
@@ -21,6 +21,9 @@ UPDATE_CONFIG = {
# Whether updates are required (blocks app if true)
"updates_required": True,
# Whether to auto-restart after successful update
"auto_restart_after_update": True,
# Whether to include pre-releases in update checks
"include_prereleases": True,