o n¡9iÏ#ã@s€dZddlmZmZmZmZmZmZmZddl m Z m Z ddl m Z mZddlmZddlmZddlmZGdd „d eƒZd S) z\ Real-time Log Monitor Window - PyQt6 Shows job execution log in real-time with auto-scroll é)ÚQDialogÚ QVBoxLayoutÚ QTextEditÚQLabelÚ QPushButtonÚ QHBoxLayoutÚ QMessageBox)ÚQTimerÚQt)ÚQFontÚ QTextCursor)ÚPath)ÚOptional)ÚSchedulerDatabasecszeZdZdZddedef‡fdd„ Zdd„Zd d „Zd d „Z d d„Z dd„Z dd„Z de fdd„Zdd„Zdd„Z‡ZS)ÚLogMonitorWindowz3Window that displays job execution log in real-timeNÚ execution_idÚdbcsLtƒ |¡||_||_d|_d|_d|_d|_| ¡|  ¡|  ¡dS)NrT) ÚsuperÚ__init__rrÚ log_file_pathÚlog_fileÚ last_positionÚ is_monitoringÚ _setup_uiÚ_load_execution_infoÚ_start_monitoring)ÚselfrrÚparent©Ú __class__©ú-c:\PYTHON\Scheduler\gui\log_monitor_window.pyrs  zLogMonitorWindow.__init__cCsš| d|j›¡| dd¡t|ƒ}tdƒ|_|j d¡| |j¡tdƒ|_|j d¡| |j¡t ƒ|_ |j   d¡|j   t j j¡td d ƒ}| ¡sUtd d ƒ}|j  |¡|j  d ¡| |j ¡tƒ}td ƒ|_|j d¡|j d¡|jj |j¡| |j¡tdƒ|_|jj |j¡| |j¡| ¡tdƒ|_|jj |j¡| |j¡| |¡t |ƒ|_!|j!j" |j#¡|j! $d¡dS)z Setup the UIzJob Monitor - Execution #i„iXz Loading...zØ QLabel { background-color: #2c3e50; color: white; padding: 10px; font-weight: bold; font-size: 12pt; } zStatus: Initializing...z• QLabel { background-color: #34495e; color: #ecf0f1; padding: 5px; } TZConsolasé z Courier Newz¥ QTextEdit { background-color: #1e1e1e; color: #d4d4d4; border: 1px solid #3e3e3e; } zAuto-scroll: ONz Refresh NowÚCloseédN)%ÚsetWindowTitlerÚsetMinimumSizerrÚ header_labelÚ setStyleSheetÚ addWidgetÚ status_labelrÚlog_textZ setReadOnlyZsetLineWrapModeZ LineWrapModeZNoWrapr Z exactMatchÚsetFontrrÚauto_scroll_btnZ setCheckableÚ setCheckedÚclickedÚconnectÚ_toggle_auto_scrollÚ refresh_btnÚ_manual_refreshÚ addStretchZ close_btnÚcloseÚ addLayoutr Ú update_timerÚtimeoutÚ _update_logZ setInterval)rÚlayoutÚfontÚ button_layoutr r r!rsF                      zLogMonitorWindow._setup_uicCsþ|j |j¡}|st |dd|j›d¡| ¡dS|j |d¡}|r)|dnd|d›}| d|›¡|j  d |›d |j›¡t |d ƒ|_ |d }d dddddœ}|  |d¡}|j   d| ¡›d|d›d|j j›¡|j  d|›d¡dS)z(Load execution information from databaseÚErrorz Execution ID z not foundNÚjob_idÚnamezJob ID zJob Monitor - zJob: z | Execution ID: rÚstatusz#3498dbz#27ae60z#e74c3cz#e67e22z#95a5a6)ÚrunningÚ completedÚfailedr8ÚpendingzStatus: z | Started: Ú start_timez | Log: z8 QLabel { background-color: zw; color: white; padding: 5px; font-weight: bold; } )rÚ get_executionrrÚcriticalr5Úget_jobr%r'ÚsetTextr rÚgetr*Úupperr?r()rÚ executionÚjobÚjob_namer@Z status_colorsÚcolorr r r!rls< ÿû  ÿþÿþz%LogMonitorWindow._load_execution_infoc Cs¼|jr|j ¡s|j d¡t d|j¡dSz)t|jdddd|_|j  ¡}|r3|j  |¡|  ¡|j  ¡|_ |j ¡WdSty]}z|j d|›d ¡WYd}~dSd}~ww) zStart monitoring the log filez&Waiting for log file to be created... éèNÚrzutf-8Úreplace)ÚencodingÚerrorsz ERROR opening log file: Ú )rÚexistsr+Úappendr Ú singleShotÚ_check_log_file_existsÚopenrÚreadÚ setPlainTextÚ_scroll_to_bottomÚtellrr7ÚstartÚ Exception)rÚcontentÚer r r!ršs     "€ÿz"LogMonitorWindow._start_monitoringcCs.|jr|j ¡r| ¡dSt d|j¡dS)z.Check if log file exists (called periodically)rPN)rrVrr rXrY©rr r r!rY´s z'LogMonitorWindow._check_log_file_existsc Csx|jr|jsdSz‘|j |j¡}|ddvrv|j |j¡|j ¡}|r.|j  |¡|  ¡|j   ¡d|_|  ¡|d}|d}|d}dd›d}|d | ¡›d7}|d |›d |d ›d 7}|d›d7}|j  |¡|  ¡WdS|j |j¡|j ¡}|r—|j  |¡|j ¡|_|  ¡WdSWdSty»}z|j  d|›d¡|j   ¡WYd}~dSd}~ww)zUpdate log content from fileNr@)rBrCr8FÚ exit_codeÚduration_secondsrUzP================================================================================zJOB FINISHED - Status: z Exit Code: z | Duration: z.1fzs z ERROR reading log: )rrrrFrÚseekrr[r+rWr]r7ÚstoprrKr^r`) rrLZ remainingr@rdÚdurationZcompletion_msgZ new_contentrbr r r!r9¼sF          ý€þzLogMonitorWindow._update_logcCs6|j ¡r|j ¡}| tjj¡|j |¡dSdS)z*Scroll to bottom if auto-scroll is enabledN) r-Ú isCheckedr+Z textCursorZ movePositionr Z MoveOperationZEndZ setTextCursor)rÚcursorr r r!r]îs  ýz"LogMonitorWindow._scroll_to_bottomÚcheckedcCs.|j d|rdnd›¡|r| ¡dSdS)zToggle auto-scrollz Auto-scroll: ZONZOFFN)r-rIr])rrkr r r!r1õs ÿz$LogMonitorWindow._toggle_auto_scrollcCs | ¡dS)zManually refresh log contentN)r9rcr r r!r3ûs z LogMonitorWindow._manual_refreshcCsV|jr|j ¡|jr%t |ddtjjtjjB¡}|tjjkr%| ¡dS|  ¡dS)zClean up when window closesz Close MonitorzMJob is still running. Close monitor window? (Job will continue in background)N) rr5rrÚquestionÚStandardButtonÚYesÚNoÚignoreÚaccept)rÚeventÚreplyr r r!Ú closeEventÿs ü  zLogMonitorWindow.closeEvent)N)Ú__name__Ú __module__Ú __qualname__Ú__doc__ÚintrrrrrrYr9r]Úboolr1r3rtÚ __classcell__r r rr!rsM.2rN)rxÚPyQt6.QtWidgetsrrrrrrrÚ PyQt6.QtCorer r Ú PyQt6.QtGuir r Úpathlibr ÚtypingrÚ core.databaserrr r r r!Ús$