This commit addresses several issues related to encrypted drive handling during application shutdown and provides better user feedback.
- **Fix(GUI):** Prevent `bgerror` by cancelling pending `_process_queue` calls when the application is closing.
- **Feat(Unmount):** Implement logic to prevent application closure if encrypted drives fail to unmount gracefully. A `MessageDialog` is now displayed to the user in such cases.
- **Feat(UI):** Enhance `HeaderFrame` to display the current mount status of encrypted drives, providing immediate visual feedback.
- **Fix(Syntax):** Correct `SyntaxError: unterminated f-string literal` in `encryption_manager.py` by using triple-quoted f-strings for multi-line content.
- **Fix(Translation):** Add missing translation strings (`unmount_failed_title`, `unmount_failed_message`) to `core/pbp_app_config.py`.
- **Fix(Unmount):** Remove `|| true` from shell commands in `unmount_and_reset_owner` to ensure actual unmount failures are correctly reported and handled by the application logic.
This commit introduces a new "Hard Reset" functionality in the settings, allowing users to reset the application to its initial state by deleting the configuration directory.
Key changes include:
- Added a "Hard Reset" button and a dedicated confirmation frame in `settings_frame.py`.
- Implemented the logic to delete the `.config/py_backup` directory and restart the application.
- Enhanced the hard reset process to unmount encrypted drives if they are mounted, prompting for a password if necessary.
To improve modularity and maintainability, the PasswordDialog class has been refactored:
- Moved PasswordDialog from `pyimage_ui/password_dialog.py` to `shared_libs/message.py`.
- Updated all references and imports to the new location.
- Externalized all user-facing strings in PasswordDialog for translation support.
Additionally, several bug fixes and improvements were made:
- Corrected object access hierarchy in `settings_frame.py` and `advanced_settings_frame.py` by passing manager instances directly.
- Handled `FileNotFoundError` in `actions.py` when selecting remote backup destinations, preventing crashes and displaying "N/A" for disk usage.
- Replaced incorrect `calculating_animation` reference with `animated_icon` in `actions.py`.
- Added missing translation keys in `pbp_app_config.py`.
Der Button für den Testlauf wurde nicht freigegeben, wenn die inkrementelle Berechnung abgeschlossen war. Dies wurde behoben, indem der Status des Buttons in der UI-Refresh-Funktion korrekt gesetzt wird.
fix(logging): Logger früher initialisieren
Der Logger wurde zu spät initialisiert, was dazu führte, dass einige Log-Meldungen auf der Konsole statt im Log-Fenster ausgegeben wurden. Die Initialisierung wurde vorgezogen, um alle Meldungen abzufangen.
refactor: Variablen umbenennen
Einige Variablen wurden für eine bessere Lesbarkeit und Konsistenz im gesamten Code umbenannt (z.B. `testlauf_var` zu `test_run_var`).
Dieses Commit ersetzt die meisten ttk.Checkbutton- und ttk.Radiobutton-Widgets in der gesamten Anwendung durch einen benutzerdefinierten "Switch"-Stil, um ein moderneres Erscheinungsbild zu erzielen.
Die Änderungen umfassen:
- **Hauptfenster**:
- Umwandlung der Backup-Optionen (Voll, Inkrementell, Komprimiert, Verschlüsselt) in Switches.
- Ersetzung der "Genaue Grössenberechnung"-Checkbox durch einen normalen Button.
- Verschiebung der "Testlauf"- und "Sicherheit umgehen"-Switches in die Seitenleiste unter "Einstellungen".
- **Scheduler**:
- Ersetzung aller Radio-Buttons und Checkboxen durch Switches, mit implementierter Logik zur Gewährleistung der exklusiven Auswahl für Backup-Typ und Frequenz.
- **Erweiterte Einstellungen**:
- Umwandlung aller Checkboxen im Abschnitt "Backup-Standards" in Switches.
- **Styling**:
- Hinzufügen eines neuen Stils `Switch2.TCheckbutton` für die Switches in der Seitenleiste, um sie an das dunkle Thema der Seitenleiste anzupassen. Die Konfiguration erfolgt direkt in `main_app.py`.
- **Fehlerbehebungen**:
- Behebung eines `AttributeError`-Absturzes, der durch die Verschiebung der Switches vor der Deklaration ihrer `tk.BooleanVar`-Variablen verursacht wurde.
- Anpassung der zugehörigen Logik in `pyimage_ui/actions.py` an den neuen Button.
This commit introduces the following changes:
- Enhanced Backup Option Logic:
- Implemented mutual exclusivity between 'Compressed' and 'Incremental' backups:
- If 'Compressed' is selected, 'Incremental' is deselected and disabled, and 'Full' is automatically selected.
- Implemented mutual exclusivity between 'Compressed' and 'Encrypted' backups:
- If 'Compressed' is selected, 'Encrypted' is deselected and disabled.
- If 'Encrypted' is selected, 'Compressed' is deselected and disabled.
- If 'Incremental' is selected, 'Compressed' is deselected and disabled.
- These rules are applied consistently across the main backup window, advanced settings, and scheduler.
- UI Improvements:
- Added 'Full', 'Incremental', 'Compressed', and 'Encrypted' checkboxes to the scheduler view.
- Adjusted the layout in the scheduler view to place 'Backup Options' next to 'Folders to back up'.
- Added missing string definitions for new UI elements in core/pbp_app_config.py.
- Refactoring:
- Updated _refresh_backup_options_ui in pyimage_ui/actions.py to handle the new logic.
- Modified _on_compression_toggle in pyimage_ui/advanced_settings_frame.py and _on_compression_toggle_scheduler in pyimage_ui/scheduler_frame.py to reflect the updated exclusivity rules.
- Adjusted _save_job and _load_scheduled_jobs in pyimage_ui/scheduler_frame.py to include and parse the new backup options.
- Updated _parse_job_comment in core/backup_manager.py to correctly parse new backup options from cron job comments.
This commit implements several UI/UX improvements for the "Backup Content" list view based on user feedback.
- feat(ui): User backups are now grouped by their full/incremental chains, similar to system backups, for a more logical and organized view.
- feat(ui): The color scheme for backup chains has been simplified. Each chain (a full backup and its incrementals) now shares a single color to improve visual grouping.
- feat(ui): Incremental backups are now denoted by a ▲ icon in the Type column instead of a different color or font style, providing a clear and clean indicator.
- fix(ui): Adjusted all column widths in the backup lists to ensure all data (especially Date and Time) is fully visible without truncation.
This commit refactors the backup size calculation logic and fixes several bugs related to rsync argument passing and UI actions.
- refactor(core): Centralized all incremental backup size calculation logic within the BackupManager class. This removes duplicated and buggy code from the DataProcessing class and ensures both post-backup reporting and pre-backup estimation use a single, robust implementation.
- fix(backup): The pre-backup "accurate size calculation" now works correctly for all backup types. It uses an `rsync --dry-run` with a proper temporary directory and correctly handles root permissions for system backups.
- fix(backup): The post-backup size reporting for incremental system backups is now accurate. It uses a root-privileged command to inspect file links and calculate the true disk usage, avoiding permission errors.
- fix(backup): Corrected multiple quoting issues with rsync arguments (`--link-dest`, `--exclude-from`) that caused backups to fail or misbehave.
- fix(ui): Fixed a TypeError that occurred when deleting a system backup from the "Backup Content" view.
- feat(backup): Added the `-v` (verbose) flag to rsync for user backups to provide better feedback in the UI.
Implements a more intuitive default view for the "Backup Content" screen based on user context.
- After a backup is completed, the "Backup Content" view will now automatically open the tab corresponding to the type of backup just performed (System or User).
- On a fresh application start, the "Backup Content" view will now always default to showing the "System" backups tab.
- This is achieved by adding state variables to the main app and modifying the navigation logic, while removing the previous behavior of saving the last-viewed tab to the config.
This commit addresses several bugs and improves the logic of the settings panels.
- fix(settings): The "Reset to default settings" action no longer deletes the user-defined file/folder exclusion list.
- fix(settings): Corrected a bug in the "Add to exclude list" function where new entries were not being written correctly. The logic is now more robust and prevents duplicate entries.
- fix(ui): Fixed a TclError crash in Advanced Settings caused by mixing `grid` and `pack` geometry managers.
- feat(settings): Implemented mutual exclusivity for the "trash bin" and "compression/encryption" checkboxes to prevent invalid configurations.
- i18n: Improved and clarified the English text for the trash bin feature descriptions to enable better translation.
Refactor the core backup and encryption logic to use a new, consistent directory structure. This new structure separates encrypted and unencrypted backups and centralizes metadata, making the system more robust and easier to manage.
Key changes:
- Implemented a new directory scheme:
/pybackup/
├── unencrypted/{system,user}/<source>/
├── encrypted/{system,user}/<source>/ (mount point)
├── metadata/
└── pybackup_encrypted.luks
- Reworked path generation logic in BackupManager and EncryptionManager to support the new structure.
- All backup, restore, and listing operations now correctly resolve paths based on the new scheme.
This also includes several bug fixes identified during the refactoring:
- fix(backup): Correctly quote rsync paths for user backups to prevent "No such file or directory" errors.
- fix(encryption): Change key lookup order to Keyring -> Keyfile -> Password Prompt, as requested.
- fix(ui): Remove eager auto-mount on startup to prevent unexpected password prompts. The app now only mounts when required by a user action.
This commit introduces several UI enhancements and bug fixes based on user feedback.
- **Backup Content View:**
- The "Folder" column is now displayed before the "Comment" column for user backups.
- The "Folder" column now shows the simple source name (e.g., "Dokumente") instead of the full backup name.
- Column alignment and widths have been adjusted in both system and user backup views for better readability.
- A timing issue causing progress bars to be missing after unlocking an encrypted volume has been resolved.
- **Advanced Settings:**
- New options have been added to control file deletion behavior (use trash or delete directly).
- The layout of the advanced settings panel has been refined.
- **Encryption:**
- Introduces a keyfile-based authentication mechanism for LUKS containers, reducing the need for password prompts.
- Replaces temporary script files with a dedicated runner script (`privileged_script_runner.sh`) for executing root commands, improving security and robustness.
This commit refactors the encrypted container management to significantly improve usability and robustness.
- **Reduced Password Prompts:** The entire resize operation (unmount, truncate, check, resize, mount) is now consolidated into a single script. This reduces the maximum number of password prompts during a backup with resize from four down to two.
- **Fix "No Space Left" Error:** The resize script is now more robust, including a filesystem check (`e2fsck`) before resizing to prevent the filesystem from failing to expand. This resolves the critical "No space left on device" error.
- **Session-wide Password Cache:** A simple in-memory cache for the LUKS password has been introduced. This prevents further password prompts when unmounting containers, for example, when the application is closed.
- **Improved Logging:** Privileged script execution now logs stderr output even on success, aiding future diagnostics.
This commit addresses several bugs related to the mounting, unmounting, and deletion of encrypted backups, as well as a crash when listing backups.
The key changes are:
- **Fix Double Mount on View:** Removed redundant mount operation when viewing encrypted backup contents. The mount is now handled by a single, centralized function.
- **Fix Deletion of Encrypted Backups:**
- The container is no longer re-mounted if already open, preventing a second password prompt.
- Deletion of encrypted *user* backups is now performed with user-level permissions, removing the need for a third password prompt via pkexec.
- **Fix UI Refresh after Deletion:** The backup list now correctly refreshes after a backup is deleted.
- **Fix Crash on Empty Backup List:** Resolved an `UnboundLocalError` that occurred when listing backups from an empty or non-existent backup directory.
- **Improve Mount Detection:** The `is_mounted` check is now more robust to prevent race conditions or other OS-level inconsistencies.
Replaced the LVM-on-a-file implementation with a more robust, industry-standard LUKS-on-a-file approach.
This change was motivated by persistent and hard-to-debug errors related to LVM state management and duplicate loop device detection during repeated mount/unmount cycles.
The new implementation provides several key benefits:
- **Robustness:** Eliminates the entire LVM layer, which was the root cause of the mount/unmount failures.
- **Improved UX:** Drastically reduces the number of password prompts for encrypted user backups. By changing ownership of the mountpoint, rsync can run with user privileges.
- **Enhanced Security:** The file transfer process (rsync) for user backups no longer runs with root privileges.
- **Better Usability:** Encrypted containers are now left mounted during the application's lifecycle and are only unmounted on exit, improving workflow for consecutive operations.
This commit introduces the core logic for handling incremental user backups.
Changes include:
- Updated `core/backup_manager.py`:
- Modified `_list_user_backups_from_path` to parse new naming convention for user backups (including `_full` and `_incremental`).
- Enhanced `_find_latest_backup` to filter by source name for user backups.
- Adjusted `_run_backup_path` to dynamically determine backup mode (full/incremental) for user backups and apply `--link-dest` accordingly.
- Updated `pyimage_ui/user_backup_content_frame.py`:
- Added `tag_colors` attribute for visual differentiation.
- Included 'type' column in the Treeview.
- Modified `_load_backup_content` to apply coloring based on backup type.
This commit introduces significant improvements to how encrypted backups are handled,
focusing on user experience and system integration.
- Persistent Mounts: Encrypted backup containers now remain mounted across UI view changes,
eliminating repeated password prompts when navigating the application. The container is
automatically unmounted when the destination changes or the application closes.
- Key Management Fallback: The mounting process now intelligently falls back from
keyring to keyfile, and finally to a user password prompt if previous methods fail.
- Enhanced UI Status: The header now provides detailed feedback on the encryption key
status, indicating whether a key is available (via keyring or keyfile) and if the
container is currently in use.
- Reduced pkexec Prompts: By keeping containers mounted, the number of system-level
pkexec authentication prompts is drastically reduced, improving workflow.
- Bug Fixes:
- Corrected a SyntaxError in encryption_manager.py related to string escaping.
- Fixed an AttributeError in header_frame.py by restoring the is_key_in_keyring method.
- Addressed a TclError on application shutdown by safely destroying Tkinter widgets.
Adds logic to prevent the screensaver or screen lock from activating while a backup is in progress.
- Uses a D-Bus call to `org.freedesktop.ScreenSaver.Inhibit` to request a lock.
- The lock is activated when a backup starts.
- The lock is reliably released when the backup finishes, fails, or is cancelled.
Refactors the encryption mechanism to use a flexible LVM-on-a-loop-device backend instead of a fixed-size file. This resolves issues with containers running out of space.
- Implements auto-resizing of the container when a backup fails due to lack of space.
- Implements transparent inspection of encrypted containers, allowing the UI to display their contents (full/incremental backups) just like unencrypted ones.
- Fixes deletion of encrypted backups by ensuring the container is unlocked before deletion.
- Fixes a bug where deleting unencrypted user backups incorrectly required root privileges.
- Fixes a UI freeze caused by calling a password dialog from a non-UI thread during deletion.
- Simplifies the UI by removing the now-obsolete "Show Encrypted Backups" button.
- Changes the default directory for encrypted user backups to `user_encrypt`.
Die Logik zur Erkennung von vollständigen Backups wurde verbessert.
Das Programm prüft nun korrekt, ob bereits ein vollständiges Backup
vorhanden ist und schlägt in diesem Fall automatisch ein inkrementelles
Backup vor. Dies funktioniert jetzt auch für verschlüsselte Backups.
- Introduces `pybackup-cli.py` as a command-line interface for non-interactive backups.
- Adds support for LUKS key files in `EncryptionManager` for passwordless container operations.
- Updates `BackupManager` to pass key file arguments to encryption routines.
- Modifies `AdvancedSettingsFrame` to provide a GUI for creating and managing key files.
- Integrates `pybackup-cli.py` and key file options into `schedule_job_dialog.py` for cronjob generation.
- Fixes a bug where the backup list would not display "orphan" incremental backups in the encrypted view.
- Fixes a bug where system backups were incorrectly shown in the user backup list.
- Prevents the app from asking for system permissions to lock an encrypted container on exit if it is not currently mounted.
- Fixes pathing inconsistencies for the encryption manager to ensure mapper names are created consistently.
- Adds debug logging to the backup list functions to help diagnose future issues.
- Centralizes backup content view logic into a single BackupContentFrame.
- Removes the separate, now obsolete EncryptedBackupContentFrame.
- Adds a toggle button within the BackupContentFrame to switch between viewing normal and encrypted backups.
- Centralizes the Restore, Delete, and Edit Comment buttons into a single button bar in BackupContentFrame.
- Corrects the path resolution logic to find backups and encrypted containers within the /pybackup subdirectory.
- Fixes UI bugs where action buttons would disappear when switching tabs.
- Improves the backup list display with chronological sorting, colored grouping for full/incremental backups, and dedicated time column.
- Changes backup folder naming to a consistent dd-mm-yyyy_HH:MM:SS format.
- Fixes bug where backup size was not displayed.
- Adds detection for encrypted backup containers, showing them correctly in the list.
- Hardens destination space check:
- Considers extra space needed for compressed backups.
- Disables start button if projected usage is > 95% or exceeds total disk space.