Files
Py-Backup/pyimage_ui/header_frame.py
Désiré Werner Menrath e1b12227d0 feat: Improve encrypted backup management and UI feedback
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.
2025-09-06 15:39:59 +02:00

104 lines
3.7 KiB
Python

import tkinter as tk
import os
from core.pbp_app_config import Msg
from shared_libs.common_tools import IconManager
class HeaderFrame(tk.Frame):
def __init__(self, container, image_manager, encryption_manager, app, **kwargs):
super().__init__(container, bg="#455A64", **kwargs)
self.image_manager = image_manager
self.encryption_manager = encryption_manager
self.app = app
# Configure grid weights for internal layout
self.columnconfigure(1, weight=1) # Make the middle column expand
self.rowconfigure(0, weight=1) # Make the top row expand
# Left side: Icon and Main Title/Subtitle
left_frame = tk.Frame(self, bg="#455A64")
left_frame.grid(row=0, column=0, rowspan=2, sticky="nsew")
left_frame.columnconfigure(0, weight=1)
left_frame.rowconfigure(0, weight=1)
icon_label = tk.Label(
left_frame,
image=self.image_manager.get_icon(
"backup_extralarge"), # Using a generic backup icon
bg="#455A64",
)
icon_label.grid(row=0, column=0, sticky="e", padx=10, pady=5)
title_label = tk.Label(
self,
text=Msg.STR["header_title"],
font=("Helvetica", 16, "bold"),
fg="#ffffff",
bg="#455A64",
)
title_label.grid(row=0, column=1, sticky="w",
padx=(5, 20), pady=(15, 5))
subtitle_label = tk.Label(
self,
text=Msg.STR["header_subtitle"],
font=("Helvetica", 10),
fg="#bdc3c7",
bg="#455A64",
)
subtitle_label.grid(row=1, column=1, sticky="w",
padx=(5, 20), pady=(0, 10))
# Right side: Keyring status
right_frame = tk.Frame(self, bg="#455A64")
right_frame.grid(row=0, column=2, rowspan=2, sticky="nsew")
right_frame.columnconfigure(0, weight=1)
right_frame.rowconfigure(0, weight=1)
self.keyring_status_label = tk.Label(
right_frame,
text="",
font=("Helvetica", 10, "bold"),
bg="#455A64",
)
self.keyring_status_label.grid(row=0, column=0, sticky="ne", padx=(10, 10), pady=(10, 0))
self.refresh_status()
def refresh_status(self):
"""Checks the keyring status based on the current destination and updates the label."""
dest_path = self.app.destination_path
if not dest_path or not self.encryption_manager.is_encrypted(dest_path):
self.keyring_status_label.config(text="") # Clear status if not encrypted
return
username = os.path.basename(dest_path.rstrip('/'))
if self.encryption_manager.is_mounted(dest_path):
status_text = "Key: In Use"
auth_method = getattr(self.encryption_manager, 'auth_method', None)
if auth_method == 'keyring':
status_text += " (Keyring)"
elif auth_method == 'keyfile':
status_text += " (Keyfile)"
self.keyring_status_label.config(
text=status_text,
fg="#2E8B57" # SeaGreen
)
elif self.encryption_manager.is_key_in_keyring(username):
self.keyring_status_label.config(
text="Key: Available (Keyring)",
fg="#FFD700" # Gold
)
elif os.path.exists(self.encryption_manager.get_key_file_path(dest_path)):
self.keyring_status_label.config(
text="Key: Available (Keyfile)",
fg="#FFD700" # Gold
)
else:
self.keyring_status_label.config(
text="Key: Not Available",
fg="#A9A9A9" # DarkGray
)