#2i^SrSSKrSSKJrJr SSKJrJrJrJrJ r J r J r J r J r JrJrJr SSKJr SSKJrJrJr SSKJr SSKJr SS KJr SS KJr SS KJ r SS K!J"r" SS K#J$r$ "SS\5r%g)zu Dashboard Widget for Python Scheduler Control panel style with critical jobs, active executions, and recent history N)datetime timedelta) QWidget QVBoxLayout QHBoxLayoutQLabelQFrame QScrollArea QGroupBox QGridLayout QTableWidgetQTableWidgetItem QPushButton QHeaderView)Qt)QFontQColorQPalette) CronTrigger)IntervalTrigger) DateTrigger)logger)SchedulerDatabase)SchedulerConfig)convert_unix_to_iso_dayofweekc^\rSrSrSrS\S\4U4SjjrSrS\ S\ S \ 4S jr S r S r S rSrSrSrSrSrSrSrSrSrS\ S\4SjrS\ S\S \ 4SjrS\S \ 4SjrS\ S \ 4SjrSrS rU=r$)!DashboardWidgetz"Dashboard with control panel styledbconfigc>[TU]5 XlX lUR [ R "55UlUR5 UR5 g)N) super__init__rr _get_week_startrnowcurrent_week_start _setup_uirefresh)selfrr __class__s +c:\PYTHON\Scheduler\gui\dashboard_widget.pyr#DashboardWidget.__init__sD  "&"6"6x||~"F  c*[U5nURSSSS5 URS5 [5nUR SS5Ul[5UlUR RUR 5 URUR S5 UR SS5Ul [5Ul URRUR5 URURS5 URU5 UR SS5Ul [5nURS 5 UR[ R"R$5 UR'S 5 [)5n[5UlURUR*5 UR-U5 [5nURU5 URRU5 URURS5 UR S S 5Ul[5UlUR.RUR05 URUR.S 5 UR35 g)zSetup dashboard UIu🔴 CRITICAL JOBSz#ffebeeu▶️ ACTIVE NOWz#e8f5e9u📊 RECENT EXECUTIONSz#e3f2fdTi,u📅 WEEKLY TIMELINEz#fff3e0N)rsetContentsMargins setSpacingr _create_panelcritical_panelcritical_content setLayout addWidget active_panelactive_content addLayout recent_panelr setWidgetResizable setFrameShaper ShapeNoFramesetMaximumHeightrrecent_content setWidgettimeline_paneltimeline_content addStretch)r) main_layouttop_row recent_scrollrecent_container panel_layouts r+r'DashboardWidget._setup_ui&s!$' &&r2r26r"-#001EyQ +  %%d&;&;<$--q1!../BIN)m ##D$7$78$++Q/g&!../GS$ ((.##FLL$8$89&&s+#9)m""4#6#67 01#} }- ##L1d//3#001GS +  %%d&;&;<d1115 r-titlebg_colorreturncF[U5nURSUS35 U$)zCreate a styled panela  QGroupBox { font-size: 14px; font-weight: bold; border: 2px solid #ccc; border-radius: 8px; margin-top: 10px; padding: 15px; background-color: z; } QGroupBox::title { subcontrol-origin: margin; left: 10px; padding: 0 5px; } )r setStyleSheet)r)rMrNpanels r+r4DashboardWidget._create_panel[s9%  !#$,*-   " r-cUR5 UR5 UR5 UR5 g![a#n[ R "SU35 SnAgSnAff=f)zRefresh dashboard datazError refreshing dashboard: N)_refresh_critical_jobs_refresh_active_jobs_refresh_recent_executions_refresh_weekly_timeline Exceptionrerror)r)es r+r(DashboardWidget.refreshss^ =  ' ' )  % % '  + + -  ) ) + = LL7s; < < =sAA A0 A++A0cURUR5 URRSS9nUVs/sHo"SS:XdM UPM nnU(d8[ S5nUR S5 URR U5 OFUH@n[ SUS35nUR S 5 URR U5 MB URR5 g s snf) zRefresh critical jobs sectionT enabled_only criticalitycriticalzNo critical jobs configured color: #666; font-style: italic;u● namez3font-size: 12px; color: #c62828; font-weight: bold;N) _clear_layoutr6r get_all_jobsrrQr8rF)r)all_jobsj critical_jobslabeljob job_labels r+rU&DashboardWidget._refresh_critical_jobs}s 400177''T':$,OHq-0@J0NH O89E    B C  ! ! + +E 2$"T#f+#78 ''(]^%%// :% ((*Ps C1 C1c&URUR5 URR5nU(d8[ S5nUR S5 URR U5 OUH}n[ SUS35nUR S5 URR U5 [ SUS35nUR S5 URR U5 M URR5 g ) zRefresh active jobs sectionzNo jobs runningrbu▶ job_namez3font-size: 12px; color: #2e7d32; font-weight: bold;z Status: statuszfont-size: 10px; color: #666;N)rdr:rget_active_executionsrrQr8rF)r)activeri executionrk status_labels r+rV$DashboardWidget._refresh_active_jobss 4../..0,-E    B C    ) )% 0# "T)J*?)@#AB ''(]^##--i8 & Ih4G3H&IJ **+JK##--l;$ &&(r-cDURUR5 URRSS5nURR US9nU(d9[ S5nURS5 URRU5 GOvUGHon[5nUR[RR[RR-5 URS5 URS5 [!U5nUR#SS SS 5 US (aUS S S OS n[ U5nUR%S5 URS5 URU5 UR'US5n [ U 5n U R%S5 URU 5 [ US5n U RS5 URU S5 US(a USSS3n OS n [ U 5n U R%S5 U R)[*R,R.5 U RS5 URU 5 USb[1US5OS n[ SU35nUR%S5 UR)[*R,R.5 URS5 URU5 URRU5 GMr URR35 g )z!Refresh recent executions sectionzgui.dashboard_recent_jobsr/)limitzNo recent executionsrbr0z:background-color: white; border-radius: 4px; padding: 5px;  start_timeNN/Az(font-family: monospace; font-size: 11px;rornz#font-size: 11px; font-weight: bold;duration_secondsz.1fs< exit_codezExit: )rdrBr getrget_recent_executionsrrQr8r setFrameStyler?BoxShadowPlain setLineWidthrr2 setFixedWidth_get_status_icon setAlignmentr AlignmentFlag AlignRightstrrF)r)rvrecentrirr exec_frame exec_layouttime_str time_label status_iconrs name_label duration_strduration_label exit_code_str exit_labels r+rW*DashboardWidget._refresh_recent_executionss 4../  ;R@..U.;12E    B C    ) )% 0$ #X (()9)9FMM>@I)\22&88:@@B  4001!] z*r"  1X&**YA->>t66??HIXM^M^_iMjLklm  0 0 < <=  !FGZ+( #!!$"="=>Y'z*r"  1X& '' 3 Q "6 ''0 9C*DAg^F :Qvcl3J  ' '-=j-I J ..0  %%eZ8 %%d+ l66EEF |99EEF E" ##L$;$;$J$JK %%l&=&=&L&LM !!,"?"?"["[\ S! R^^334 44R8 ))$/8C  " " $ 9 9#{?U?U?]?] ^ ''.  !  # # % . .z : "r-cVU[UR5S9- RSSSSS9$)z%Get Monday of the week for given daterr)rrsecond microsecond)rweekdayreplace)r)dates r+r$DashboardWidget._get_week_startKs.ydlln55>>AaXYgh>iir-c\U=R[SS9-slUR5 g)zNavigate to previous weekrNr&rrXr)s r+rDashboardWidget._prev_weekO$ 9!#44 %%'r-c\U=R[SS9- slUR5 g)zNavigate to next weekrrNrrs r+rDashboardWidget._next_weekTrr-cvUR[R"55UlUR 5 g)zReset to current weekN)r$rr%r&rXrs r+r&DashboardWidget._reset_to_current_weekYs'"&"6"6x||~"F %%'r-c SSKnURS5nURUR5nU[ SS9-nUR R SS9n/nUHnUSS :XaMUS S :XaMURS 5cM-[US [5(a[R"US 5OUS nURUSU5n U (dMSn Un Sn SnX:dMU R!X5nU(aX:aMUR#UUSUSUS US S.5 Un U[ SS9-n US- nX:aM]M U$![a+n [R"SUSSU 35 Sn A GM$Sn A ff=f![a+n [R"SUSSU 35 Sn A GM\Sn A ff=f![a$n [R"SU 3SS9 /sSn A $Sn A ff=f)z2Calculate all schedule executions for current weekrN Europe/RomerrTr^ schedule_typemanual target_type sync_profile target_nameschedule_configz-Failed to parse schedule config for schedule id: iz(Error calculating next_run for schedule rc)r schedule_id schedule_namerrr0)secondszError in _get_week_executions: )exc_info)pytztimezonelocalizer&rrget_all_schedulesrrrjsonloadsrYrrZ_build_trigger_for_timelineget_next_fire_timeappend)r)r tz week_startr schedulesrscheduler r[triggerpreviousr%max_iterations iterationsnext_runs r+r$DashboardWidget._get_week_executions^s@E  }-BT%<%<=J!I1$55H11t1DIJ%O,8M*n<<< .6HRS[\mSnpsHtHtTZZ1B(CD{CDU{VF ::8O;TV\]  !%  1#*#=#=h#L $x';%%$,'/~)1&)9'/ '>'/ '> ' (H"Yq%99C!OJ)!1A&l M!LL#PQYZ^Q_P``bcdbe!fg&% 'OPXY]P^O__abcad%ef(  LL:1#> NI syBF? 6E?)F?-F>A F? F? FE?8F??FF? F<F70F?7F<<F?? G- G("G-(G-c\SnUS:Xa8URS5nU(dg[U5n[R"XSS9$US:Xa [ S SU0UD6$US:Xa"URS5nU(dg[ XcS 9$g![ a#n[R"S U35 SnAgSnAff=f) z3Build APScheduler trigger for timeline calculationsrcronNr intervalr rrun_dater r zCould not build trigger: ) rrr from_crontabrrrYrwarning)r)rr r cron_expr cron_expr_isor r[s r+r+DashboardWidget._build_trigger_for_timelines B&"JJv.   =i H "// KK*,&==f==&(!::j1"HBB  NN6qc: ; s. A>A>A>A>4A>> B+B&&B+c 0nUHnUSnUR(aUR5RSS9nUR5nURnUR nUS:dUS:dUS:XaUS:dUS:aM~US- S-US :aS OS-n U n Un X4n X;a/X<'X<R U5 M UR5GHuupn [U 5nUS :Xa[U SS SS 5nO[US 35n/nU H7nUSRS5nUR USUS SUSS35 M9 URSRU55 UR[RR 5 [#SU 55n[#SU 55n[#SU 55nUS:a'US:Xa!US:XaUR%['S55 OtUS:a'US:Xa!US:XaUR%['S55 OGUS:a'US:Xa!US:XaUR%['S55 OUR%['S55 UR)XU5 GM [+S5HFn [+S5H4n UR-X5bM[S5nUR)XU5 M6 MH g)z'Populate timeline table with executionsrN)tzinforrrxr1r}r0rz schedulesz%H:%Mrz (r) c3:# UHoSS:XdM Sv M g7f)rbackup_profiler0Nr".0exs r+ ;DashboardWidget._populate_timeline_table..sZ5R}4EIY4Yqq5  c3:# UHoSS:XdM Sv M g7f)rrjr0Nr"r0s r+r3r4sL"M1Be1KAAr5c3:# UHoSS:XdM Sv M g7f)rgroupr0Nr"r0s r+r3r4sP%Bm3D3Oaa%r5z#bbdefbz#c8e6c9z#e1bee7z#fff9c4rz)r) astimezonerrrrritemslenrr setToolTipjoinsetTextAlignmentrrrsum setBackgroundrsetItemritem)r)rrslotsrrexec_dt day_of_weekrr slot_indexrrkeyexecsrrC tooltip_linesr2r backup_count job_count group_counts r+r(DashboardWidget._populate_timeline_tables#I +G~~!,,.66d6C"//+K<227;$$zR5H4IB}L]K^^_%`a OODIIm4 5  ! !""2"2">"> ?Z5ZZLLLLIP%PPKaIN{a7G""6)#45Q<1#49I""6)#45q\Q%69>""6)#45""6)#45 MM#D )O"/T9CQx::c'/+B/DMM#D1 r-rrc SnUS:Xa.URS5nU(dg[R"XCS9nOjUS:Xa[S SU0UD6nOVUS:XaOURS5nU(dg[ U[ 5(a[ R"U5n[XcS 9nOgURS[ R"UR5S 9$![a NEf=f![a#n[R"S U35 SnAgSnAff=f) z*Calculate next run datetime for a schedulerrNrrr rr r!)previous_fire_timer%zCould not compute next run: r")rrr#rrrr fromisoformatrYrrr%r rr$)r)rrrr%rr excs r+_calculate_next_run#DashboardWidget._calculate_next_runs B&+//7  %229J*,)I2II&(*..z:h,,#+#9#9(#C&xE--8<r)r)rrpartsrHrs r+_format_schedule_text%DashboardWidget._format_schedule_text-s F "O//>?@ @ J &EG'++C05LLE7!C5!12H38VDIIe,-. P=P P F " 3 3J FGH H H $%=!!r-rcURS5=(d SURS53nSSSS.nURURS5URSS 55nUS U3$) zLabel target with its typerzID target_idJobGroupBackup)rjr8r/rTargetrr)r)rrtype_mapprefixs r+_format_targetDashboardWidget._format_target>snll=1Vs8<< ;T:U5V &  hll=98<< W_;`aK=))r-roc8SSSSSSS.nURUS5$) zGet status icon for executionu✅u❌u▶️u⏱️u⛔u⏳) completedfailedrunningtimeout cancelledqueuedu❓rc)r)roiconss r+r DashboardWidget._get_status_iconIs0  yy''r-cPUR5(aURS5nUR5(aUR5R5 O4UR 5(aUR UR 55 UR5(aMgg)zClear all widgets from layoutrN)rtakeAtr deleteLaterlayoutrd)r)rtrCs r+rdDashboardWidget._clear_layoutUsdllnn==#D{{}} ))+""4;;=1 llnnr-) r:r9r r6r5r&rrBr<rErD) __name__ __module__ __qualname____firstlineno____doc__rrr#r'rr r4r(rUrVrWrXr$rrrrrrdictrSr[rfrrd__static_attributes__ __classcell__)r*s@r+rrs,,o3!j3#)0=+*)2?)B];~j( ( ( GR0O2bt:"3""RU"" *t * * (s (s (22r-r)&rzr rrPyQt6.QtWidgetsrrrrr r r r r rrr PyQt6.QtCorer PyQt6.QtGuirrrapscheduler.triggers.cronrapscheduler.triggers.intervalrapscheduler.triggers.daterlogurur core.databaser core.configrcore.cron_utilsrrr"r-r+rsT  ( //191+'9B 2gB 2r-