o æº)i?ã@s dZddlmZmZmZmZmZmZmZm Z m Z m Z m Z m Z ddlmZmZddlmZmZddlmZddlmZddlmZddlmZGd d „d eƒZd S) z@ Backup Widget for GUI - Manages backup profiles and operations é) ÚQWidgetÚ QVBoxLayoutÚ QHBoxLayoutÚ QPushButtonÚ QTableWidgetÚQTableWidgetItemÚQLabelÚ QMessageBoxÚ QGroupBoxÚ QTextEditÚ QHeaderViewÚQAbstractItemView)ÚQtÚ pyqtSignal)ÚQFontÚQColor)Úlogger)Údatetime)ÚDatabase)ÚSchedulerConfigcsˆeZdZdZeƒZdedef‡fdd„ Zdd„Z dd „Z d d „Z d d „Z dd„Z dd„Zdd„Zdd„Zdd„Zdd„Zdd„Z‡ZS)Ú BackupWidgetz2Widget for managing backup profiles and operationsÚdbÚconfigcs*tƒ ¡||_||_| ¡| ¡dS)N)ÚsuperÚ__init__rrÚ _setup_uiÚrefresh)Úselfrr©Ú __class__©ú(c:\PYTHON\Scheduler\gui\backup_widget.pyrs  zBackupWidget.__init__c Cs:t|ƒ}| dddd¡| d¡tƒ}tdƒ}tƒ}| d¡| d¡| |¡|  |¡|  ¡t dƒ|_ |j j  |j¡|  |j ¡t dƒ|_|jj  |j¡|j d¡|  |j¡t dƒ|_|jj  |j¡|j d¡|  |j¡t d ƒ|_|jj  |j¡|j d¡|  |j¡| |¡td ƒ}t|ƒ}tƒ|_|j d ¡|j gd ¢¡|j ¡ tj j!¡|j ¡ "d¡|j #t$j%j&¡|j 't$j(j)¡|j *t$j+j,¡|jj- |j.¡|jj/ |j0¡|j 1d d¡|j 1dd¡|j 1dd¡|j 1dd¡|j 1dd¡|j 1dd¡|  |j¡|j |ddtdƒ}t|ƒ}tƒ|_2|j2 d¡|j2 gd¢¡|j2 ¡ tj j!¡|j2 ¡ "d¡|j2 #t$j%j&¡|j2 *t$j+j,¡|j2 1d d¡|j2 1dd¡|j2 1dd¡|j2 1dd¡|j2 1dd¡|j2 1dd¡|j2 1d d¡|  |j2¡|j |dddS)zSetup backup UI componentséu💾 Backup ProfileséTuâž• New Profileuâ–¶ Run BackupFu 📅 Scheduleu 🗑 DeletezBackup Profilesé)ÚIDÚNamez Backup RootZSourceszRetention (days)ÚEnabledré2ééÈééúéé–ééxééP)ZstretchzRecent Backup Operationsé)r%ZProfileÚTypeÚStatusz Start TimeÚDurationZFilesédN)3rÚsetContentsMarginsÚ setSpacingrrrÚ setPointSizeÚsetBoldÚsetFontÚ addWidgetÚ addStretchrZnew_btnÚclickedÚconnectÚ_create_profileÚrun_btnÚ _run_backupÚ setEnabledÚ schedule_btnÚ_schedule_backupÚ delete_btnÚ_delete_profileÚ addLayoutr rÚprofiles_tableÚsetColumnCountÚsetHorizontalHeaderLabelsÚhorizontalHeaderÚsetSectionResizeModer Ú ResizeModeÚ InteractiveZsetStretchLastSectionÚsetSelectionBehaviorr ÚSelectionBehaviorÚ SelectRowsÚsetSelectionModeÚ SelectionModeZSingleSelectionÚsetEditTriggersÚ EditTriggerÚNoEditTriggersÚitemSelectionChangedÚ_on_profile_selectedZ doubleClickedÚ _edit_profileZsetColumnWidthÚoperations_table) rÚlayoutÚ header_layoutÚ title_labelÚ title_fontZprofiles_groupZprofiles_layoutZoperations_groupZoperations_layoutr r r!r s‚                     zBackupWidget._setup_uicCs| ¡| ¡dS)zRefresh all dataN)Ú_load_profilesÚ_load_operations)rr r r!r|s zBackupWidget.refreshc CsàzÊ|j ¡}|j t|ƒ¡t|ƒD]µ\}}tt|dƒƒ}| t j j ¡|j  |d|¡t|dƒ}|j  |d|¡t|dƒ}|j  |d|¡ddl }zt|dtƒr\| |d¡n|d}t|ƒ} Wnd} Yt| ›d ƒ} |  t j j ¡|j  |d | ¡tt|d ƒƒ} |  t j j ¡|j  |d | ¡|d rŸdnd} t| ƒ} |  t j j ¡|d r¸|  tdƒ¡n|  tdƒ¡|j  |d| ¡qWdStyï}zt d|›¡t |dd|›¡WYd}~dSd}~ww)z"Load backup profiles from databaseÚidrÚnamer)Ú backup_rootr+NÚsourcesz source(s)r-Úretention_daysr/Úenabledu✓ Yesu✗ NoÚgreenÚredr1zError loading backup profiles: ÚErrorz Failed to load backup profiles: )rÚget_all_backup_profilesrJÚ setRowCountÚlenÚ enumeraterÚstrÚsetTextAlignmentrÚ AlignmentFlagÚ AlignCenterÚsetItemÚjsonÚ isinstanceÚloadsÚ setForegroundrÚ ExceptionrÚerrorr Úcritical)rÚprofilesÚrowÚprofileÚid_itemÚ name_itemZ root_itemrurfZ sources_countZ sources_itemZretention_itemÚ enabled_textÚ enabled_itemÚer r r!rasH   $ Ú("€þzBackupWidget._load_profilesc CsàzR|jjdd}|j t|ƒ¡t|ƒD]:\}}tt|dƒƒ}| t j j ¡|j  |d|¡|j  |d¡}|r?|dnd|d›}t|ƒ}|j  |d|¡t|d ƒ}|j  |d |¡|d } t| ƒ} |  t j j ¡|d d kr}|  td ƒ¡n|d dkr‹|  tdƒ¡n |d dkr˜|  tdƒ¡|j  |d| ¡|d} | rÆz t | ¡} |  d¡} Wnt| ƒdkrÂ| dd…n| } Ynd} t| ƒ}|j  |d|¡| d¡r| d¡rzt |d¡}t |d¡}|| ¡}|d›d}Wnd}Yn |d dkr dnd}t|ƒ}| t j j ¡|j  |d|¡| dd¡}| dd¡}|dkr;|›d |›d!nd}t|ƒ}| t j j ¡|j  |d"|¡qWdStyo}zt d#|›¡WYd}~dSd}~ww)$zLoad recent backup operationsé)ÚlimitrcrÚ profile_idrdúProfile r)Úoperation_typer+ÚstatusÚ completedriÚfailedrjÚrunningZoranger-Ú start_timez%Y-%m-%d %H:%M:%SéNzN/Ar/Úend_timez.1fÚsz Running...r1Ú files_totalÚ files_linkedz (z links)r$z!Error loading backup operations: )rÚget_recent_backup_operationsr\rmrnrorrprqrrrrsrtÚget_backup_profilerxrrÚ fromisoformatÚstrftimeÚgetÚ total_secondsryrrz)rZ operationsr}Úoprr~Z profile_nameZ profile_itemZ type_itemÚ status_textÚ status_itemrÚdtÚtime_strZ time_itemÚstartÚendÚdurationÚ duration_strZ duration_itemr‘r’Z files_strZ files_itemrƒr r r!rb´sp         ¿C€ÿzBackupWidget._load_operationscCs:t|j ¡ƒdk}|j |¡|j |¡|j |¡dS)zHandle profile selectionrN)rnrJÚ selectedItemsrBrDrErG)rÚ has_selectionr r r!rZs  z!BackupWidget._on_profile_selectedcCs4|j ¡}|s dS|d ¡}t|j |d¡ ¡ƒS)zGet selected profile IDNr)rJr¢r}ÚintÚitemÚtext)rÚselectedr}r r r!Ú_get_selected_profile_ids  z%BackupWidget._get_selected_profile_idcCsXddlm}ddlm}|||jƒ}| ¡|jjkr*t  d¡|  ¡|j   ¡dSdS)zCreate new backup profiler©ÚBackupProfileDialog©ÚQDialogzNew backup profile createdN) Úgui.backup_profile_dialogrªÚPyQt6.QtWidgetsr¬rÚexecÚ DialogCodeÚAcceptedrÚinforÚprofile_changedÚemit)rrªr¬Údialogr r r!rAs    ýzBackupWidget._create_profilecCs€ddlm}ddlm}| ¡}|st |dd¡dS|||j|ƒ}| ¡|j j kr>t   d|›d¡|  ¡|j ¡dSdS) zEdit selected backup profilerr©r«z No SelectionzPlease select a profile to editNzBackup profile z updated)r­rªr®r¬r¨r Úwarningrr¯r°r±rr²rr³r´)rrªr¬r†rµr r r!r[s  ýzBackupWidget._edit_profilec Cs¾| ¡}|sdSt |dd|›dtjjtjjB¡}|tjjkr]zt |dd|›d¡| ¡|j  ¡WdSt y\}zt   d|›¡t  |d d |›¡WYd}~dSd}~wwdS) zRun backup for selected profileNz Run Backupz#Start backup operation for profile ú?zBackup Startedz$Backup operation queued for profile zD. Full integration with daemon will be completed in the next phase.zError running backup: rkzFailed to run backup: )r¨r ÚquestionÚStandardButtonÚYesÚNoÚ informationrr³r´ryrrzr{©rr†Úreplyrƒr r r!rC,s0 ü  ý"€þôzBackupWidget._run_backupc CsL| ¡}|sdSzxddlm}ddlm}|j |¡}|s+t |dd|›d¡WdS|||j|j ƒ}|j   d¡t |j  ¡ƒD]}|j  |¡|krR|j  |¡nq@|j d |d ›¡| ¡|jjkr~t d |›¡t |d d |d ›d¡WdSWdSty¥}zt d|›¡t |dd|›¡WYd}~dSd}~ww)z0Open schedule dialog for selected backup profileNr)ÚScheduleEditorDialogr«rkr‡z not foundTzScheduled Backup: rdz$Created schedule for backup profile zSchedule Createdz#Schedule created successfully for 'z2'. Check the Schedules tab to view and manage it.zError scheduling backup: z Failed to open schedule dialog: )r¨Úgui.schedule_editor_dialogr¿r®r¬rr”r r¶rÚ backup_radioÚ setCheckedÚrangeÚ backup_comboÚcountZitemDataÚsetCurrentIndexÚ name_inputÚsetTextr¯r°r±rr²r¼ryrzr{)rr†r¿r¬r~rµÚirƒr r r!rFIs>     þ ýþ "€þzBackupWidget._schedule_backupc CsÄ| ¡}|sdSt |dd|›dtjjtjjB¡}|tjjkr`z|j |¡t  d|›¡|  ¡|j   ¡WdSt y_}zt d|›¡t |dd|›¡WYd}~dSd}~wwdS) zDelete selected backup profileNzDelete Profilez(Are you sure you want to delete profile z:? This will also delete all associated backup operations.zDeleted backup profile zError deleting profile: rkzFailed to delete profile: )r¨r r¸r¹rºr»rÚdelete_backup_profilerr²rr³r´ryrzr{r½r r r!rHus* û  "€þùzBackupWidget._delete_profile)Ú__name__Ú __module__Ú __qualname__Ú__doc__rr³rrrrrrarbrZr¨rAr[rCrFrHÚ __classcell__r r rr!rs\3M  ,rN)rÎr®rrrrrrrr r r r r Ú PyQt6.QtCorerrÚ PyQt6.QtGuirrÚlogururrÚ core.databaserÚ core.configrrr r r r!Ús8