Geführtes Update: "Anwendung ersetzen" im Update-Hinweis

Der Update-Hinweis bietet neben "Update Ordner öffnen" nun den Button
"Anwendung ersetzen". Er kopiert das ZIP vom SMB-Laufwerk lokal, prüft es,
entpackt es in einen eigenen Ordner neben der aktuellen Installation,
übernimmt input/, output/ und eigene Templates und startet die neue EXE.
Die alte Installation bleibt als Rückfallebene erhalten; eine angepasste
settings.ini wird als settings.vorherige-version.ini aufbewahrt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
RobandClaude Opus 5.5 committed 2026-11-03 12:55:12 +01:00
1 parent 5e2fab7fd3
commit cb059ac20d
7 files changed
+315 -5

No files matched your search

+33 -4
View File
@@ -30,6 +30,7 @@ from src.parser import parse_input_file, group_by_employee, get_unique_antragsnu
from src.validator import validate_input_file, validate_template
from src.writer import generate_activity_reports
from version_check import UPDATE_DIR, get_latest_version
from update_installer import can_replace_application, install_update, start_application
def open_input_folder(directory: Path):
@@ -91,7 +92,7 @@ try:
local_version, latest_version = get_latest_version()
current_version_text = f"v{'.'.join(map(str, local_version))}"
if latest_version:
available_version, _ = latest_version
available_version, update_path = latest_version
version_text = ".".join(map(str, available_version))
st.html(
f'''<style>
@@ -105,7 +106,7 @@ try:
#update-notice-dismiss:checked + .update-notice {{ display:none; }}
body:has(#update-notice-dismiss:checked) div.st-key-update_notice_open {{ display:none!important; }}
.update-notice__actions {{ display:flex; justify-content:flex-end; gap:8px; margin-top:8px; }}
.update-notice__actions--footer {{ min-height:26px; }}
.update-notice__actions--footer {{ min-height:60px; }}
.update-notice__button {{
display:inline-flex; align-items:center; justify-content:center;
width:26px; height:26px; color:#5f4700; background:#fffdf3;
@@ -114,11 +115,12 @@ try:
}}
.update-notice__button:hover {{ background:#f6e7b2; }}
div.st-key-update_notice_open {{
position:fixed; top:8.5rem; right:3.75rem; z-index:10001; width:26px;
position:fixed; top:8.5rem; right:calc(1rem + 13px); z-index:10001;
width:264px; gap:6px;
}}
div.st-key-update_notice_open div[data-testid="stButton"] {{ margin:0; }}
div.st-key-update_notice_open div[data-testid="stButton"] button {{
min-width:200px; min-height:26px; height:26px; padding:0; color:#5f4700;
width:100%; min-height:26px; height:26px; padding:0; color:#5f4700;
background:#fffdf3; border:1px solid #d9bd66; border-radius:5px;
}}
</style>
@@ -136,6 +138,33 @@ try:
if st.button("Update Ordner öffnen 📁", key="open_update_directory", help="Update-Ordner öffnen"):
if sys.platform == "win32":
os.startfile(str(UPDATE_DIR))
replace_supported = can_replace_application()
replace_clicked = st.button(
"Anwendung ersetzen 🔄", key="replace_application",
disabled=not replace_supported or st.session_state.get("update_started", False),
help=("Neue Version neben der aktuellen einrichten, input/ und output/ übernehmen "
"und starten. Die aktuelle Version bleibt als Ordner erhalten."
if replace_supported else "Nur in der installierten Windows-Anwendung verfügbar."))
if replace_clicked:
try:
with st.spinner(f"Version v{version_text} wird eingerichtet …"):
result = install_update(update_path, PROJECT_ROOT)
start_application(result.target_dir)
except Exception as exc: # Der umgebende Block verschluckt sonst jeden Fehler.
st.error(f"Update fehlgeschlagen: {exc}\n\n"
"Alternativ das Update manuell aus dem Update-Ordner einrichten.")
else:
st.session_state.update_started = True
details = [f"Neuer Programmordner: `{result.target_dir}`"]
if result.already_installed:
details.append("Die Version war dort bereits eingerichtet und wurde nur gestartet.")
else:
details.append("Die Ordner input/ und output/ wurden übernommen.")
if result.previous_settings:
details.append(f"Die bisherige settings.ini wurde als `{result.previous_settings.name}` aufbewahrt.")
details.append("Bitte im folgenden Fenster bestätigen, dass die alte Version beendet wird. "
"Desktop-Verknüpfungen zeigen noch auf den alten Ordner.")
st.success(f"Version v{version_text} wird gestartet.\n\n" + "\n\n".join(details))
except Exception:
pass