o ¿«2i™7ã@sœdZddlmZmZmZmZmZmZmZm Z m Z m Z m Z ddl mZmZddlmZmZddlmZddlmZddlmZddlmZGd d „d eƒZd S) z< Sync Widget for GUI - Manages sync profiles and operations é) ÚQWidgetÚ QVBoxLayoutÚ QHBoxLayoutÚ QPushButtonÚ QTableWidgetÚQTableWidgetItemÚQLabelÚ QMessageBoxÚ QGroupBoxÚ 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„Z‡ZS)Ú SyncWidgetz0Widget for managing sync profiles and operationsÚdbÚconfigcs*tƒ ¡||_||_| ¡| ¡dS)N)ÚsuperÚ__init__rrÚ _setup_uiÚrefresh)Úselfrr©Ú __class__©ú&c:\PYTHON\Scheduler\gui\sync_widget.pyrs  zSyncWidget.__init__c CsRt|ƒ}| 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¡t d ƒ|_|jj  |j¡|  |j¡| |¡td ƒ}t|ƒ}tƒ|_|j d ¡|j gd ¢¡|j ¡  t!j"j#¡|j ¡ $d¡|j %t&j'j(¡|j )t&j*j+¡|j ,t&j-j.¡|jj/ |j0¡|jj1 |j¡|j 2dd¡|j 2dd¡|j 2dd¡|j 2dd¡|j 2dd¡|  |j¡|j |ddtdƒ}t|ƒ}tƒ|_3|j3 d¡|j3 gd¢¡|j3 ¡  t!j"j#¡|j3 ¡ $d¡|j3 %t&j'j(¡|j3 ,t&j-j.¡|j3 2dd¡|j3 2dd¡|j3 2dd¡|j3 2dd¡|j3 2dd¡|j3 2d d¡|j3 2dd¡|  |j3¡|j |dddS)zSetup sync UI componentséu📠Directory Sync ProfileséTuâž• New Profileu✠EditFu 📅 Scheduleu 🗑 Deleteu 🔄 Refreshz Sync Profilesé)ÚIDÚNameZSourceZ DestinationÚEnabledré2ééÈéi,éééP)ÚstretchzRecent Sync Operationsé)r$ÚProfileÚStatusz Start TimeÚDurationZCopiedZDeletedé–édéN)4rÚsetContentsMarginsÚ setSpacingrrrÚ setPointSizeÚsetBoldÚsetFontÚ addWidgetÚ addStretchrÚnew_btnÚclickedÚconnectÚ_create_profileÚedit_btnÚ _edit_profileÚ setEnabledÚ schedule_btnÚ_schedule_syncÚ delete_btnÚ_delete_profileÚ refresh_btnrÚ addLayoutr rÚprofiles_tableÚsetColumnCountÚsetHorizontalHeaderLabelsÚhorizontalHeaderÚsetSectionResizeModer Ú ResizeModeÚ InteractiveÚsetStretchLastSectionÚsetSelectionBehaviorr ÚSelectionBehaviorÚ SelectRowsÚsetSelectionModeÚ SelectionModeÚSingleSelectionÚsetEditTriggersÚ EditTriggerÚNoEditTriggersÚitemSelectionChangedÚ_on_profile_selectedÚ doubleClickedÚsetColumnWidthÚoperations_table) rÚlayoutÚ header_layoutÚ title_labelÚ title_fontÚprofiles_groupÚprofiles_layoutÚoperations_groupÚoperations_layoutrrr r s†                       zSyncWidget._setup_uicCs| ¡| ¡dS)zRefresh all dataN)Ú_load_profilesÚ_load_operations)rrrr rs zSyncWidget.refreshc Cs\zˆ|j ¡}|j t|ƒ¡t|ƒD]s\}}tt|dƒƒ}| t j j ¡|j  |d|¡t|dƒ}|j  |d|¡t|dƒ}|j  |d|¡t|dƒ}|j  |d|¡|d r]d nd }t|ƒ} |  t j j ¡|d rv|   td ƒ¡n|   td ƒ¡|j  |d| ¡qWdSty­} zt d| ›¡t |dd| ›¡WYd} ~ dSd} ~ ww)z Load sync profiles from databaseÚidrÚnamer(Ú source_pathr*Údestination_pathr+Úenabledu✓ Yesu✗ NoÚgreenÚredr,zError loading sync profiles: ÚErrorzFailed to load sync profiles: N)rÚget_all_sync_profilesrJÚ setRowCountÚlenÚ enumeraterÚstrÚsetTextAlignmentr Ú AlignmentFlagÚ AlignCenterÚsetItemÚ setForegroundrÚ ExceptionrÚerrorr Úcritical) rÚprofilesÚrowÚprofileÚid_itemÚ name_itemZ source_itemZ dest_itemÚ enabled_textÚ enabled_itemÚerrr rh„s4    æ"€þzSyncWidget._load_profilesc CsðzZ|jjdd}|j t|ƒ¡t|ƒD]B\}}tt|dƒƒ}| t j j ¡|j  |d|¡|j  |d¡}|r?|dnd|d›}t|ƒ}|j  |d|¡|d }t|ƒ} |  t j j ¡|d d kro|  td ƒ¡n)|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¡}tt|ƒƒ}| t j j ¡|j  |d|¡| d d¡}tt|ƒƒ}| t j j ¡|j  |d!|¡qWdStyw}zt d"|›¡WYd}~dSd}~ww)#zLoad recent sync operationsé)ÚlimitrjrÚ profile_idrkúProfile r(ÚstatusÚ completedroÚfailedrpÚrunningÚorangeZcompleted_with_errorsZ darkoranger*Ú start_timez%Y-%m-%d %H:%M:%SéNzN/Ar+Úend_timez.1fÚsz Running...r,Ú files_copiedr#Ú files_deletedr5zError loading sync operations: )rÚget_recent_sync_operationsr_rsrtrurrvrwr rxryrzÚget_sync_profiler{rrÚ fromisoformatÚstrftimeÚgetÚ total_secondsr|rr})rÚ operationsr€Úopr‚rÚ profile_nameÚ profile_itemÚ status_textÚ status_itemrÚdtÚtime_strÚ time_itemÚstartÚendÚdurationÚ duration_strÚ duration_itemr”Z copied_itemr•Z deleted_itemr†rrr ri«st           ½E€ÿzSyncWidget._load_operationscCs:t|j ¡ƒdk}|j |¡|j |¡|j |¡dS)zHandle profile selectionrN)rtrJÚ selectedItemsrArCrDrF)rÚ has_selectionrrr r\ús  zSyncWidget._on_profile_selectedcCs4|j ¡}|s dS|d ¡}t|j |d¡ ¡ƒS)zGet selected profile IDNr)rJrªr€ÚintÚitemÚtext)rÚselectedr€rrr Ú_get_selected_profile_ids  z#SyncWidget._get_selected_profile_idcCsXddlm}ddlm}|||jƒ}| ¡|jjkr*t  d¡|  ¡|j   ¡dSdS)zCreate new sync profiler©ÚSyncProfileDialog©ÚQDialogzNew sync profile createdN) Úgui.sync_profile_dialogr²ÚPyQt6.QtWidgetsr´rÚexecÚ DialogCodeÚAcceptedrÚinforÚprofile_changedÚemit)rr²r´Údialogrrr r@ s    ýzSyncWidget._create_profilecCs€ddlm}ddlm}| ¡}|st |dd¡dS|||j|ƒ}| ¡|j j kr>t   d|›d¡|  ¡|j ¡dSdS) zEdit selected sync profilerr±r³ú No SelectionzPlease select a profile to editNz Sync profile z updated)rµr²r¶r´r°r Úwarningrr·r¸r¹rrºrr»r¼)rr²r´r‰r½rrr rBs  ýzSyncWidget._edit_profilecCsôddlm}ddlm}| ¡}|st |dd¡dS|j |¡}|s0t |dd|›d ¡dS|||j|j ƒ}|j   d |d ›¡|j   d ¡|j |¡}|dkrY|j |¡| ¡|jjkrxt d |›¡t |dd|d ›d¡dSdS)z.Open schedule dialog for selected sync profiler)ÚScheduleEditorDialogr³r¾z#Please select a profile to scheduleNrqrŠz not foundzSync: rkTz"Created schedule for sync profile ÚSuccessz#Schedule created successfully for 'z2'. Check the Schedules tab to view and manage it.)Úgui.schedule_editor_dialogrÀr¶r´r°r r¿rr—rÚ name_inputÚsetTextÚ sync_radioÚ setCheckedÚ sync_comboÚfindDataÚsetCurrentIndexr·r¸r¹rrºÚ information)rrÀr´r‰rr½Úindexrrr rE%s0      ýþzSyncWidget._schedule_syncc Cs¼| ¡}|sdSt |ddtjjtjjB¡}|tjjkr\z|j |¡t  d|›¡|  ¡|j   ¡WdSt y[}zt d|›¡t |dd|›¡WYd}~dSd}~wwdS)zDelete selected sync profileNzDelete ProfileziAre you sure you want to delete this sync profile? This will also delete all associated sync operations.zDeleted sync profile zError deleting profile: rqzFailed to delete profile: )r°r ÚquestionÚStandardButtonÚYesÚNorÚdelete_sync_profilerrºrr»r¼r|r}r~)rr‰Úreplyr†rrr rGIs*û  "€þùzSyncWidget._delete_profile)Ú__name__Ú __module__Ú __qualname__Ú__doc__rr»rrrrrrhrir\r°r@rBrErGÚ __classcell__rrrr rs_'O  $rN)rÕr¶rrrrrrrr r r r Ú PyQt6.QtCorer rÚ PyQt6.QtGuirrÚlogururrÚ core.databaserÚ core.configrrrrrr Ús4