Skip to content

Commit 2b304f2

Browse files
committed
Safe UI Updates & fixes
1 parent 1bfe6fb commit 2b304f2

17 files changed

+679
-418
lines changed

src/switchcraft/assets/lang/de.json

Lines changed: 125 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,21 @@
3636
"drag_drop": "Installer hier ablegen\n(EXE / MSI)",
3737
"analyzing": "Analysiere",
3838
"analysis_complete": "Analyse abgeschlossen",
39+
"none_detected": "Keine erkannt",
40+
"click_to_browse": "Klicken zum Durchsuchen",
3941
"ai_helper": "KI Helfer",
4042
"ai_stub_greeting": "Hallo! Ich bin dein lokaler KI-Assistent. Ich kann dir bei Paketierungsfragen helfen, auch wenn du keinen API-Key konfiguriert hast.",
4143
"ai_stub_welcome": "Hallo! Ich bin der lokale SwitchCraft KI-Helfer. Ich laufe derzeit im eingeschränkten Modus, da das KI-Addon nicht installiert ist, aber ich kann dir trotzdem einige grundlegende Tipps geben!",
4244
"error": "Fehler",
45+
"crash_title": "Etwas ist schiefgelaufen",
46+
"crash_subtitle": "Ein unerwarteter Fehler ist beim Laden dieser Ansicht aufgetreten.",
47+
"btn_copy_error": "Fehler kopieren",
48+
"btn_close_app": "App schließen",
49+
"btn_reload_app": "App neu laden",
50+
"error_copied": "Fehlerdetails in die Zwischenablage kopiert",
51+
"error_copy_failed": "Fehler beim Kopieren in die Zwischenablage",
52+
"closing": "Schließe...",
53+
"reloading": "Neu laden...",
4354
"file_not_found": "Datei nicht gefunden.",
4455
"unknown_installer": "Installer-Typ konnte nicht erkannt werden.",
4556
"silent_install": "Silent Installation",
@@ -49,6 +60,27 @@
4960
"search_online": "Online nach Switches suchen",
5061
"lang_change_refresh": "Sprache geändert. Die Ansicht wird automatisch aktualisiert.",
5162
"view_winget": "Auf Winget GitHub ansehen",
63+
"winget_match_at": "Entspricht Winget-Paket: {id} aufgrund von {reason}",
64+
"det_type": "Erkennungstyp",
65+
"det_file": "Dateipfad",
66+
"det_reg": "Registry-Schlüssel",
67+
"det_msi": "MSI-Produktcode",
68+
"det_ver": "Dateiversion",
69+
"det_ps": "PowerShell-Skript",
70+
"lbl_path_key_code": "Pfad / Schlüssel / Code",
71+
"lbl_val_name": "Wertname (Optional für Registry)",
72+
"lbl_expected_val": "Erwarteter Wert (Optional)",
73+
"lbl_operator": "Operator",
74+
"lbl_ps_script_desc": "PowerShell-Skript (Return 0 = Erkannt, Nicht-0 = Nicht erkannt)",
75+
"btn_test_det": "Erkennung testen",
76+
"title_det_tester": "Live Erkennungstester",
77+
"win_only_feature": "Diese Funktion ist nur unter Windows verfügbar.",
78+
"det_tester_desc": "Überprüfe deine Intune-Erkennungsregeln lokal vor dem Hochladen.",
79+
"lbl_target_ver": "Zielversion",
80+
"msg_detected": "ERKANNT",
81+
"msg_not_detected": "NICHT ERKANNT",
82+
"err_path_required": "Pfad/Schlüssel ist erforderlich",
83+
"err_script_required": "Skriptinhalt ist erforderlich",
5284
"settings_theme": "Design",
5385
"settings_lang": "Sprache",
5486
"settings_debug": "Debug-Protokollierung",
@@ -236,7 +268,7 @@
236268
"create_intunewin_pkg": "📦 .intunewin Paket erstellen",
237269
"test_install_local": "▶ Test Installation (Lokal)",
238270
"extract_archive_btn": "📦 Archiv entpacken",
239-
"view_full_params": "Detaillierte Analysedaten anzeigen",
271+
"view_full_params": "Detaillierte Analysedaten",
240272
"confirm_automation": "Automatisierung bestätigen",
241273
"confirm_automation_msg": "Dies wird versuchen:\n1. Skript generieren & signieren\n2. Lokalen Install/Uninstall Test ausführen (Admin benötigt)\n3. IntuneWin Paket erstellen\n4. Nach Intune hochladen\n\nFortfahren?",
242274
"config_warning": "Konfigurations-Warnung",
@@ -642,6 +674,97 @@
642674
"stat_packaged": "Paketiert",
643675
"stat_deployed": "Bereitgestellt",
644676
"stat_errors": "Fehler",
677+
"mail_flow_test_title": "Mail-Flow-Test starten",
678+
"mail_flow_test_msg": "Sende eine Test-E-Mail, um den Mail-Flow zu überprüfen.",
679+
"lbl_sender": "Absender (UPN)",
680+
"lbl_recipient": "Empfänger",
681+
"mail_flow_started": "Mail-Flow gestartet: {sender} -> {recipient} (Mock)",
682+
"ex_lbl_scheduled": "Geplant",
683+
"ex_msg_no_results": "Keine Nachrichten gefunden.",
684+
"ex_err_enter_mailbox": "Bitte gib eine Postfach-SMTP-Adresse ein.",
685+
"ex_msg_from": "Von: {sender} | {received}",
686+
"ex_oof_saved": "OOF-Einstellungen aktualisiert!",
687+
"ex_no_delegates": "Keine Delegierten gefunden oder unzureichende Berechtigungen.",
688+
"ex_stat_sent": "Gesendet",
689+
"ex_stat_recv": "Empfangen",
690+
"ex_stat_blocked": "Blockiert",
691+
"ex_err_prefix": "Exchange-Fehler: {message}",
692+
"group_name": "Gruppenname",
693+
"group_desc": "Beschreibung",
694+
"group_name_required": "Gruppenname ist erforderlich",
695+
"not_connected_intune": "Nicht mit Intune verbunden",
696+
"create_new_group": "Neue Gruppe erstellen",
697+
"confirm_deletion": "Löschen bestätigen",
698+
"confirm_delete_group": "Bist du sicher, dass du '{group_name}' löschen möchtest? Dies kann nicht rückgängig gemacht werden.",
699+
"select_group_first": "Bitte wähle zuerst eine Gruppe aus.",
700+
"member_removed": "Mitglied entfernt",
701+
"no_members": "Keine Mitglieder gefunden.",
702+
"remove_member": "Mitglied entfernen",
703+
"error_loading_members": "Fehler beim Laden der Mitglieder: {error}",
704+
"search_user_hint": "Benutzer suchen (Name oder E-Mail)",
705+
"no_users_found": "Keine Benutzer gefunden.",
706+
"member_added": "Mitglied erfolgreich hinzugefügt",
707+
"ai_typing": "KI schreibt...",
708+
"ai_you": "Du",
709+
"ai_assistant": "KI",
710+
"ai_error": "KI Fehler",
711+
"ai_btn_send": "Nachricht senden",
712+
"col_filename": "Dateiname",
713+
"col_product": "Produkt",
714+
"col_date": "Datum",
715+
"col_action": "Aktion",
716+
"no_history": "Kein Verlauf gefunden.",
717+
"unknown": "Unbekannt",
718+
"btn_clear_all": "Alle löschen",
719+
"btn_refresh": "Aktualisieren",
720+
"msg_group_deleted": "Gruppe gelöscht.",
721+
"msg_creation_failed": "Erstellung fehlgeschlagen: {error}",
722+
"msg_deletion_failed": "Löschen fehlgeschlagen: {error}",
723+
"msg_member_add_failed": "Mitglied konnte nicht hinzugefügt werden: {error}",
724+
"msg_search_failed": "Suche fehlgeschlagen: {error}",
725+
"msg_group_created": "Gruppe '{name}' wurde erstellt!",
726+
"err_intunewin_not_found": "IntuneWinAppUtil wurde nicht gefunden.",
727+
"msg_intunewin_req": "Dieses Tool ist erforderlich, um Anwendungen zu paketieren.",
728+
"msg_downloading": "Wird heruntergeladen...",
729+
"err_download_failed": "Download fehlgeschlagen. Überprüfen Sie die Logs.",
730+
"status_connecting": "Wird verbunden...",
731+
"err_missing_creds": "Fehlende Anmeldedaten (in den Einstellungen prüfen)",
732+
"status_connected": "Verbunden",
733+
"err_conn_failed": "Verbindung fehlgeschlagen: {error}",
734+
"msg_searching": "Suche...",
735+
"msg_no_apps_found": "Keine Apps gefunden",
736+
"msg_found_apps": "{count} Apps gefunden",
737+
"err_search_error": "Suchfehler: {error}",
738+
"msg_fetching_details": "Details werden abgerufen...",
739+
"msg_metadata_copied": "Metadaten kopiert!",
740+
"msg_metadata_copied_from": "Metadaten von {name} kopiert",
741+
"msg_starting_creation": "Erstellung gestartet...",
742+
"msg_creation_done": "FERTIG! Paket erfolgreich erstellt.",
743+
"err_invalid_file": "Ungültige Datei",
744+
"status_uploading": "Wird hochgeladen...",
745+
"status_upload_done": "Upload abgeschlossen!",
746+
"err_upload_failed": "Upload fehlgeschlagen: {error}",
747+
"msg_app_id": "App-ID: {id}",
748+
"msg_supersede_config": "Ersetzung konfiguriert, falls ausgewählt.",
749+
"msg_save_success": "Änderungen erfolgreich gespeichert!",
750+
"msg_save_failed": "Speichern fehlgeschlagen: {error}",
751+
"msg_no_changes": "Keine Änderungen erkannt.",
752+
"msg_saving": "Wird gespeichert...",
753+
"winget_search_timeout": "Die Suche dauert zu lange...",
754+
"winget_search_timeout_hint": "Versuchen Sie einen spezifischeren Suchbegriff oder prüfen Sie Ihre Internetverbindung.",
755+
"btn_download_installer": "Installer herunterladen",
756+
"winget_tip_autoupdate": "Tipp: Nutze Winget-AutoUpdate, um Apps aktuell zu halten!",
757+
"msg_assigning_app": "App wird {group} zugewiesen...",
758+
"msg_assign_success": "Erfolgreich als {intent} zugewiesen!",
759+
"err_assign_failed": "Zuweisung fehlgeschlagen: {error}",
760+
"msg_search_taking_long": "Suche dauert zu lange...",
761+
"msg_try_specific": "Versuchen Sie einen genaueren Suchbegriff.",
762+
"msg_check_settings_creds": "Bitte prüfen Sie Verbindung und Anmeldedaten.",
763+
"msg_not_assigned": "Nicht zugewiesen.",
764+
"lbl_command_install": "Installationsbefehl",
765+
"lbl_command_uninstall": "Deinstallationsbefehl",
766+
"lbl_release_date": "Veröffentlichungsdatum",
767+
"lbl_location": "Speicherort",
645768
"chart_activity_title": "Aktivität (Letzte 5 Tage)",
646769
"recent_actions": "Letzte Aktionen",
647770
"status_analyzed": "Analysiert",
@@ -676,7 +799,7 @@
676799
"btn_winget_manifest": "Winget Manifest",
677800
"btn_gen_intune_script": "Intune Script generieren",
678801
"btn_create_intunewin": ".intunewin erstellen",
679-
"btn_manual_cmds": "Manuelle Befehle",
802+
"btn_manual_cmds": "Installationsbefehle",
680803
"winget_explorer_title": "Winget Explorer",
681804
"app_found": "1 App gefunden",
682805
"apps_found": "{0} Apps gefunden",

src/switchcraft/assets/lang/en.json

Lines changed: 124 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,49 @@
3636
"drag_drop": "Drag & Drop Installer Here\n(EXE / MSI)",
3737
"analyzing": "Analyzing",
3838
"analysis_complete": "Analysis Complete",
39+
"none_detected": "None detected",
40+
"click_to_browse": "Click to browse",
3941
"ai_helper": "AI Helper",
4042
"ai_stub_greeting": "Hello! I am your local AI assistant. I can help you with packaging questions even when you don't have an API key configured.",
4143
"ai_stub_welcome": "Hello! I am the local SwitchCraft AI helper. I'm currently running in limited mode because the AI addon is not installed, but I can still give you some basic tips!",
4244
"error": "Error",
45+
"crash_title": "Something went wrong",
46+
"crash_subtitle": "An unexpected error occurred while loading this view.",
47+
"btn_copy_error": "Copy Error",
48+
"btn_close_app": "Close App",
49+
"btn_reload_app": "Reload App",
50+
"error_copied": "Error details copied to clipboard",
51+
"error_copy_failed": "Failed to copy to clipboard",
52+
"closing": "Closing...",
53+
"reloading": "Reloading...",
4354
"file_not_found": "File not found.",
4455
"unknown_installer": "Could not identify installer type.",
4556
"silent_install": "Silent Install",
4657
"silent_uninstall": "Silent Uninstall",
4758
"no_switches": "No automatic switches found.",
4859
"brute_force_help": "Brute Force Help",
49-
"search_online": "Search Online for Switches",
5060
"view_winget": "View on Winget GitHub",
61+
"winget_match_at": "Matches Winget Package: {id} due to {reason}",
62+
"det_type": "Detection Type",
63+
"det_file": "File Path",
64+
"det_reg": "Registry Key",
65+
"det_msi": "MSI Product Code",
66+
"det_ver": "File Version",
67+
"det_ps": "PowerShell Script",
68+
"lbl_path_key_code": "Path / Key / Code",
69+
"lbl_val_name": "Value Name (Optional for Registry)",
70+
"lbl_expected_val": "Expected Value (Optional)",
71+
"lbl_operator": "Operator",
72+
"lbl_ps_script_desc": "PowerShell Script (Return 0 = Detected, Non-0 = Not Detected)",
73+
"btn_test_det": "Test Detection",
74+
"title_det_tester": "Live Detection Tester",
75+
"win_only_feature": "This feature is only available on Windows.",
76+
"det_tester_desc": "Verify your Intune detection rules locally before uploading.",
77+
"lbl_target_ver": "Target Version",
78+
"msg_detected": "DETECTED",
79+
"msg_not_detected": "NOT DETECTED",
80+
"err_path_required": "Path/Key is required",
81+
"err_script_required": "Script content is required",
5182
"settings_theme": "Theme",
5283
"settings_lang": "Language",
5384
"lang_change_refresh": "Language changed. Please restart the app (Ctrl+R).",
@@ -642,6 +673,97 @@
642673
"stat_packaged": "Packaged",
643674
"stat_deployed": "Deployed",
644675
"stat_errors": "Errors",
676+
"mail_flow_test_title": "Start Mail Flow Test",
677+
"mail_flow_test_msg": "Send a test email to verify mail flow.",
678+
"lbl_sender": "Sender (UPN)",
679+
"lbl_recipient": "Recipient",
680+
"mail_flow_started": "Mail flow started: {sender} -> {recipient} (Mock)",
681+
"ex_lbl_scheduled": "Scheduled",
682+
"ex_msg_no_results": "No messages found.",
683+
"ex_err_enter_mailbox": "Please enter a mailbox SMTP address.",
684+
"ex_msg_from": "From: {sender} | {received}",
685+
"ex_oof_saved": "OOF settings updated!",
686+
"ex_no_delegates": "No delegates found or permissions insufficient.",
687+
"ex_stat_sent": "Sent",
688+
"ex_stat_recv": "Recv",
689+
"ex_stat_blocked": "Blocked",
690+
"ex_err_prefix": "Exchange Error: {message}",
691+
"group_name": "Group Name",
692+
"group_desc": "Description",
693+
"group_name_required": "Group name is required",
694+
"not_connected_intune": "Not connected to Intune",
695+
"create_new_group": "Create New Group",
696+
"confirm_deletion": "Confirm Deletion",
697+
"confirm_delete_group": "Are you sure you want to delete '{group_name}'? This cannot be undone.",
698+
"select_group_first": "Please select a group first.",
699+
"member_removed": "Member removed",
700+
"no_members": "No members found.",
701+
"remove_member": "Remove Member",
702+
"error_loading_members": "Error loading members: {error}",
703+
"search_user_hint": "Search User (Name or Email)",
704+
"no_users_found": "No users found.",
705+
"member_added": "Member added successfully",
706+
"ai_typing": "AI is typing...",
707+
"ai_you": "You",
708+
"ai_assistant": "AI",
709+
"ai_error": "AI Error",
710+
"ai_btn_send": "Send message",
711+
"col_filename": "File",
712+
"col_product": "Product",
713+
"col_date": "Date",
714+
"col_action": "Action",
715+
"no_history": "No history found.",
716+
"unknown": "Unknown",
717+
"btn_clear_all": "Clear All",
718+
"btn_refresh": "Refresh",
719+
"msg_group_deleted": "Group deleted.",
720+
"msg_creation_failed": "Creation failed: {error}",
721+
"msg_deletion_failed": "Deletion failed: {error}",
722+
"msg_member_add_failed": "Failed to add member: {error}",
723+
"msg_search_failed": "Search failed: {error}",
724+
"msg_group_created": "Group '{name}' created!",
725+
"err_intunewin_not_found": "IntuneWinAppUtil not found.",
726+
"msg_intunewin_req": "This tool is required to package applications.",
727+
"msg_downloading": "Downloading...",
728+
"err_download_failed": "Download failed. Check logs.",
729+
"status_connecting": "Connecting...",
730+
"err_missing_creds": "Missing Credentials (check Settings)",
731+
"status_connected": "Connected",
732+
"err_conn_failed": "Connection Failed: {error}",
733+
"msg_searching": "Searching...",
734+
"msg_no_apps_found": "No apps found",
735+
"msg_found_apps": "Found {count} apps",
736+
"err_search_error": "Search Error: {error}",
737+
"msg_fetching_details": "Fetching details...",
738+
"msg_metadata_copied": "Metadata copied!",
739+
"msg_metadata_copied_from": "Metadata copied from {name}",
740+
"msg_starting_creation": "Starting creation...",
741+
"msg_creation_done": "DONE! Package created successfully.",
742+
"err_invalid_file": "Invalid File",
743+
"status_uploading": "Uploading...",
744+
"status_upload_done": "Upload Complete!",
745+
"err_upload_failed": "Upload failed: {error}",
746+
"msg_app_id": "App ID: {id}",
747+
"msg_supersede_config": "Supersedence configured if selected.",
748+
"msg_save_success": "Changes saved successfully!",
749+
"msg_save_failed": "Failed to save: {error}",
750+
"msg_no_changes": "No changes detected.",
751+
"msg_saving": "Saving...",
752+
"winget_search_timeout": "Search is taking too long...",
753+
"winget_search_timeout_hint": "Try a more specific search term or check your internet connection.",
754+
"btn_download_installer": "Download Installer",
755+
"winget_tip_autoupdate": "Tip: Use Winget-AutoUpdate to keep apps fresh!",
756+
"msg_assigning_app": "Assigning app to {group}...",
757+
"msg_assign_success": "Successfully assigned as {intent}!",
758+
"err_assign_failed": "Assignment failed: {error}",
759+
"msg_search_taking_long": "Search is taking too long...",
760+
"msg_try_specific": "Try a more specific search term.",
761+
"msg_check_settings_creds": "Please check your connection and credentials.",
762+
"msg_not_assigned": "Not assigned.",
763+
"lbl_command_install": "Install Command",
764+
"lbl_command_uninstall": "Uninstall Command",
765+
"lbl_release_date": "Release Date",
766+
"lbl_location": "Location",
645767
"chart_activity_title": "Activity (Last 5 Days)",
646768
"recent_actions": "Recent Actions",
647769
"status_analyzed": "Analyzed",
@@ -674,7 +796,7 @@
674796
"btn_winget_manifest": "Winget Manifest",
675797
"btn_gen_intune_script": "Generate Intune Script",
676798
"btn_create_intunewin": "Create .intunewin",
677-
"btn_manual_cmds": "Manual Commands",
799+
"btn_manual_cmds": "Install Commands",
678800
"winget_explorer_title": "Winget Explorer",
679801
"app_found": "1 app found",
680802
"apps_found": "{0} apps found",

src/switchcraft/controllers/analysis_controller.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
class AnalysisResult:
2020
info: InstallerInfo
2121
winget_url: Optional[str] = None
22+
winget_id: Optional[str] = None
23+
winget_reason: Optional[str] = None
2224
brute_force_data: Optional[str] = None
2325
nested_data: Optional[Dict] = None
2426
silent_disabled_info: Optional[Dict] = None
@@ -172,7 +174,12 @@ def nested_progress_handler(pct, message, _=None):
172174
winget_mod = addon_service.import_addon_module("winget", "utils.winget")
173175
if winget_mod and info.product_name:
174176
winget = winget_mod.WingetHelper()
175-
winget_url = winget.search_by_name(info.product_name)
177+
results = winget.search_packages(info.product_name)
178+
if results:
179+
first = results[0]
180+
winget_id = first.get("Id")
181+
winget_url = winget.search_by_name(info.product_name)
182+
winget_reason = f"matched by name '{info.product_name}'"
176183
except Exception as e:
177184
logger.error(f"Winget search failed: {e}")
178185
else:
@@ -197,6 +204,8 @@ def nested_progress_handler(pct, message, _=None):
197204
return AnalysisResult(
198205
info=info,
199206
winget_url=winget_url,
207+
winget_id=winget_id,
208+
winget_reason=winget_reason,
200209
brute_force_data=brute_force_data,
201210
nested_data=nested_data,
202211
silent_disabled_info=silent_disabled,

src/switchcraft/gui_modern/utils/view_utils.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,23 @@ def wrapped_handler(e):
106106
self._show_error_view(ex, error_context)
107107
return wrapped_handler
108108

109+
def _safe_update(self, control=None, *args):
110+
"""
111+
Safely update the control/view or a specific child control.
112+
Checks if the control is actually on a page to avoid RuntimeError.
113+
"""
114+
try:
115+
target = control if control else self
116+
# Some controls might not have .page attribute exposed directly or correctly when detached
117+
# But the standard Flet check is usually checking if it's on page.
118+
if getattr(target, "page", None):
119+
target.update()
120+
except Exception:
121+
# Control not added to page, or already removed, or updated in bad state
122+
pass
123+
except Exception as e:
124+
logger.debug(f"Safe update failed (non-critical): {e}")
125+
109126
def _show_snack(self, msg, color="GREEN"):
110127
"""Show a snackbar message on the page using modern API."""
111128
try:

0 commit comments

Comments
 (0)