n9i#SrSSKJrJrJrJrJrJrJr SSK J r J r SSK J r Jr SSKJr SSKJr SSKJr "SS \5rg ) z\ Real-time Log Monitor Window - PyQt6 Shows job execution log in real-time with auto-scroll )QDialog QVBoxLayout QTextEditQLabel QPushButton QHBoxLayout QMessageBox)QTimerQt)QFont QTextCursor)Path)Optional)SchedulerDatabasecz^\rSrSrSrSS\S\4U4SjjjrSrSr Sr S r S r S r S \4S jrSrSrSrU=r$)LogMonitorWindowz3Window that displays job execution log in real-time execution_iddbc>[TU]U5 XlX lSUlSUlSUlSUlUR5 UR5 UR5 g)NrT) super__init__rr log_file_pathlog_file last_position is_monitoring _setup_ui_load_execution_info_start_monitoring)selfrrparent __class__s -c:\PYTHON\Scheduler\gui\log_monitor_window.pyrLogMonitorWindow.__init__s\  (-1 !  !!#  cURSUR35 URSS5 [U5n[ S5UlUR R S5 URUR 5 [ S5UlURR S5 URUR5 [5Ul URRS5 URR[RR5 [S S 5nUR!5(d [S S 5nURR#U5 URR S 5 URUR5 [%5n['S 5UlUR(R+S5 UR(R-S5 UR(R.R1UR25 URUR(5 ['S5UlUR4R.R1UR65 URUR45 UR95 ['S5UlUR:R.R1UR<5 URUR:5 UR?U5 [AU5Ul!URBRDR1URF5 URBRIS5 g)z Setup the UIzJob Monitor - Execution #iiXz 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; } TConsolas z Courier Newz QTextEdit { background-color: #1e1e1e; color: #d4d4d4; border: 1px solid #3e3e3e; } zAuto-scroll: ONz Refresh NowClosedN)%setWindowTitlersetMinimumSizerr header_label setStyleSheet addWidget status_labelrlog_text setReadOnlysetLineWrapMode LineWrapModeNoWrapr exactMatchsetFontrrauto_scroll_btn setCheckable setCheckedclickedconnect_toggle_auto_scroll refresh_btn_manual_refresh addStretch close_btnclose addLayoutr update_timertimeout _update_log setInterval)r layoutfont button_layouts r#rLogMonitorWindow._setup_uis 78I8I7JKL C%T"#<0 '')   **+##<= '')   **+"   !!$' %%i&<&<&C&CDZ#  *D d# ##%   '$ *+<= ))$/ ''- $$,,T-E-EF 4 45&}5   (()=)=> 0 01  "$W- &&tzz2/'#4L !!))$*:*:; %%c*r%cURRUR5nU(d7[R"USSURS35 UR 5 gURR US5nU(aUSOSUS3nURSU35 URRS US UR35 [US 5Ul US nS SSSSS.nURUS5nURRSUR5SUSSURR35 URR!SUS35 g)z(Load execution information from databaseErrorz Execution ID z not foundNjob_idnamezJob ID zJob Monitor - zJob: z | Execution ID: rstatusz#3498dbz#27ae60z#e74c3cz#e67e22z#95a5a6)running completedfailedrEpendingzStatus: z | Started: start_timez | Log: z8 QLabel { background-color: zw; color: white; padding: 5px; font-weight: bold; } )r get_executionrr criticalrBget_jobr+r-setTextrrgetr0upperrOr.)r executionjobjob_namerP status_colorscolors r#r%LogMonitorWindow._load_execution_infolsGG))$*;*;<   w"/0A0A/B* M O JJL ggooi12"%3v;WYx5H4I+J nXJ78 !!E(3DTEVEVDW"XY")J"788$ "   !!&)4 !!v||~&'!,/01&&++, . ''-##('* )  r%cUR(aURR5(d=URRS5 [R "SUR 5 g[URSSSS9UlURR5nU(a+URRU5 UR5 URR5Ul URR5 g![ a)nURRSUS 35 SnAgSnAff=f) zStart monitoring the log filez&Waiting for log file to be created... Nrzutf-8replace)encodingerrorsz ERROR opening log file:  )rexistsr1appendr singleShot_check_log_file_existsopenrread setPlainText_scroll_to_bottomtellrrDstart Exception)r contentes r#r"LogMonitorWindow._start_monitorings!!););)B)B)D)D MM !J K   dD$?$? @  E !3!3S7S\]DMmm((*G **73&&(!%!3!3!5D     # # % E MM #=aS!C D D Es/B D ED>>EcUR(a0URR5(aUR5 g[R"SUR 5 g)z.Check if log file exists (called periodically)rcN)rrirr rkrlr s r#rl'LogMonitorWindow._check_log_file_existssC   $"4"4";";"="=  " " $   dD$?$? @r%cUR(aUR(dgURRUR5nUSS;GaURR UR 5 URR5nU(a+URRU5 UR5 URR5 SUlUR5 USnUSnUSnSSS3nUS UR5S3- nUS US US S 3- nUSS3- nURRU5 UR5 gURR UR 5 URR5nU(aKURRU5 URR5UlUR5 gg![ aCnURRSUS35 URR5 SnAgSnAff=f)zUpdate log content from fileNrP)rRrSrEF exit_codeduration_secondsrhzP================================================================================zJOB FINISHED - Status: z Exit Code: z | Duration: z.1fzs z ERROR reading log: )rrrrVrseekrrnr1rjrprDstoprr[rqrs) r r\ remainingrPr{durationcompletion_msg new_contentrus r#rFLogMonitorWindow._update_logs}}D$6$6 + %--d.?.?@I"&HH ""4#5#56 MM..0 MM((3**,!!&&(%*"))+#8,%k2 $%78#%fXR$;FLLN;K2"NNK {-QT~UX"YYVHB-/ $$^4&&( MM  t11 2--,,.K $$[1%)]]%7%7%9"&&(  % MM #82!> ?    " " $ $ %sD=G5#BG55 I?9H==IcURR5(a_URR5nUR [ R R5 URRU5 gg)z*Scroll to bottom if auto-scroll is enabledN) r8 isCheckedr1 textCursor movePositionr MoveOperationEnd setTextCursor)r cursors r#rp"LogMonitorWindow._scroll_to_bottomsZ    ) ) + +]]--/F    9 9 = = > MM ' ' / ,r%checkedcURRSU(aSOS35 U(aUR5 gg)zToggle auto-scrollz Auto-scroll: ONOFFN)r8rYrp)r rs r#r=$LogMonitorWindow._toggle_auto_scrolls6 $$}WT%4P%QR   " " $ r%c$UR5 g)zManually refresh log contentN)rFrxs r#r? LogMonitorWindow._manual_refreshs r%cUR(aURR5 UR(a{[R"USS[R R [R R-5nU[R R:XaUR5 gUR5 g)zClean up when window closesz Close MonitorzMJob is still running. Close monitor window? (Job will continue in background)N) rrBrr questionStandardButtonYesNoignoreaccept)r eventreplys r# closeEventLogMonitorWindow.closeEvents == MM   !   ((`**..1K1K1N1NN E 22555  r%) r8rArrr-rrrrr1r>r0rD)N)__name__ __module__ __qualname____firstlineno____doc__intrrrrrrlrFrpboolr=r?r__static_attributes__ __classcell__)r"s@r#rrs^= !S !.? ! !K+Z, \E4A0%d0%4% r%rN)rPyQt6.QtWidgetsrrrrrrr PyQt6.QtCorer r PyQt6.QtGuir r pathlibrtypingr core.databaserrr%r#rs9EEE#*+BwBr%