v1.0.1 updates and polish

This commit is contained in:
2026-01-24 18:29:10 +02:00
parent de64610a90
commit 19831656dc
11 changed files with 342 additions and 72 deletions

View File

@@ -259,48 +259,72 @@ class Bootstrapper:
process.wait()
def refresh_app_source(self):
"""Refresh app source files. Skips if already exists to save time."""
# Optimization: If app/main.py exists, skip update to improve startup speed.
# The user can delete the 'runtime' folder to force an update.
if (self.app_path / "main.py").exists():
log("App already exists. Skipping update.")
return True
if self.ui: self.ui.set_status("Updating app files...")
"""
Smartly updates app source files by only copying changed files.
Preserves user settings and reduces disk I/O.
"""
if self.ui: self.ui.set_status("Checking for updates...")
try:
# Preserve settings.json if it exists
settings_path = self.app_path / "settings.json"
temp_settings = None
if settings_path.exists():
try:
temp_settings = settings_path.read_bytes()
except:
log("Failed to backup settings.json, it involves risk of data loss.")
if self.app_path.exists():
shutil.rmtree(self.app_path, ignore_errors=True)
# 1. Ensure destination exists
if not self.app_path.exists():
self.app_path.mkdir(parents=True, exist_ok=True)
shutil.copytree(
self.source_path,
self.app_path,
ignore=shutil.ignore_patterns(
'__pycache__', '*.pyc', '.git', 'venv',
'build', 'dist', '*.egg-info', 'runtime'
)
)
# Restore settings.json
if temp_settings:
try:
settings_path.write_bytes(temp_settings)
log("Restored settings.json")
except:
log("Failed to restore settings.json")
# 2. Walk source and sync
# source_path is the temporary bundled folder
# app_path is the persistent runtime folder
changes_made = 0
for src_dir, dirs, files in os.walk(self.source_path):
# Determine relative path from source root
rel_path = Path(src_dir).relative_to(self.source_path)
dst_dir = self.app_path / rel_path
# Ensure directory exists
if not dst_dir.exists():
dst_dir.mkdir(parents=True, exist_ok=True)
for file in files:
# Skip ignored files
if file in ['__pycache__', '.git', 'settings.json'] or file.endswith('.pyc'):
continue
src_file = Path(src_dir) / file
dst_file = dst_dir / file
# Check if update needed
should_copy = False
if not dst_file.exists():
should_copy = True
else:
# Compare size first (fast)
if src_file.stat().st_size != dst_file.stat().st_size:
should_copy = True
else:
# Compare content (slower but accurate)
# Only read if size matches to verify diff
if src_file.read_bytes() != dst_file.read_bytes():
should_copy = True
if should_copy:
shutil.copy2(src_file, dst_file)
changes_made += 1
if self.ui: self.ui.set_detail(f"Updated: {file}")
# 3. Cleanup logic (Optional: remove files in dest that are not in source)
# For now, we only add/update to prevent deleting generated user files (logs, etc)
if changes_made > 0:
log(f"Update complete. {changes_made} files changed.")
else:
log("App is up to date.")
return True
except Exception as e:
log(f"Error refreshing app source: {e}")
# Fallback to nuclear option if sync fails completely?
# No, 'smart_sync' failing might mean permissions, nuclear wouldn't help.
return False
def run_app(self):