o „9i—Bã@sdZddlmZmZmZmZmZmZmZm Z m Z m Z m Z m Z mZmZddlmZddlmZddlZddlmZddlmZGdd „d eƒZdS) z@ Job Editor Dialog Form for creating and editing scheduled jobs é)ÚQDialogÚ QVBoxLayoutÚ QHBoxLayoutÚ QFormLayoutÚ QGroupBoxÚ QLineEditÚ QTextEditÚ QComboBoxÚQSpinBoxÚ QCheckBoxÚ QPushButtonÚ QFileDialogÚQLabelÚ QMessageBox)ÚQt)ÚloggerN)ÚPath)ÚSchedulerDatabasecsxeZdZdZddedef‡fdd„ Zdd„Zd efd d „Z d d „Z dd„Z dd„Z de fdd„Zdd„Zdd„Z‡ZS)ÚJobEditorDialogz Dialog for creating/editing jobsNÚdbÚjob_idcshtƒ |¡||_||_|du|_| |jrdnd¡| d¡| d¡| ¡|jr2|  ¡dSdS)NzEdit JobzNew JobTiX) ÚsuperÚ__init__rrÚ is_edit_modeÚsetWindowTitleZsetModalZsetMinimumWidthÚ _setup_uiÚ_load_job_data)ÚselfÚparentrr©Ú __class__©ú,c:\PYTHON\Scheduler\gui\job_editor_dialog.pyrs     ÿzJobEditorDialog.__init__c Cs|tƒ}tdƒ}tƒ}tƒ|_|j d¡| d|j¡tƒ|_|j  d¡|j d¡| d|j¡|  |¡|  |¡tdƒ}tƒ}t ƒ|_ |j  gd¢¡| d |j ¡tƒ}tƒ|_|j d ¡|  |j¡td ƒ|_|jj |j¡|  |j¡| d |¡tƒ|_|j d ¡| d|j¡tƒ}tƒ|_|j d¡|  |j¡td ƒ|_|jj |j¡|  |j¡| d|¡|  |¡|  |¡tdƒ}tƒ} t ƒ|_|j gd¢¡|jj |j¡|  d|j¡tƒ|_|j d¡|  d|j¡tdƒ|_|j  d¡|j !d¡|  d|j¡t"ƒ|_#|j# $d¡|j# %d¡|  d|j#¡t"ƒ|_&|j& $d¡|j& %d¡|  d|j&¡t"ƒ|_'|j' $d¡|j' %d¡|  d |j'¡t"ƒ|_(|j( $d¡|j( %d!¡|  d"|j(¡t"ƒ|_)|j) $d¡|j) %d!¡|  d#|j)¡|j# *d$¡|j& *d$¡|j' *d$¡|j( *d$¡|j) *d$¡|  | ¡|  |¡td%ƒ} tƒ} t+d&ƒ|_,|j, -d¡|  d|j,¡t+d'ƒ|_.|j. /d(¡|  d|j.¡t"ƒ|_0|j0 1dd)¡|j0 2d*¡|j0 3d+¡|  d,|j0¡t"ƒ|_4|j4 1dd-¡|j4 2d¡|  d.|j4¡t"ƒ|_5|j5 1dd*¡|j5 2d¡|j5 3d+¡|  d/|j5¡t ƒ|_6|j6 gd0¢¡|j6 7d1¡|  d2|j6¡tƒ|_8|j8 d3¡|  d4|j8¡|   | ¡|  | ¡tƒ} |  9¡|j:r€td5ƒ|_;|j;j |j<¡|   |j;¡t|j:r‡d6nd7ƒ|_=|j= >d¡|j=j |j?¡|   |j=¡td8ƒ|_@|j@j |jA¡|   |j@¡| B| ¡|  |¡d9S):zSetup dialog UIzBasic Informationze.g., DataHub Daily Refreshz Job Name:*é<z$Description of what this job does...z Description:zExecution Settings)ÚbatchZscriptZ python_modulez Job Type:*zC:\path\to\script.batz Browse...z Executable:*zOptional command line argumentsz Arguments:zC:\path\to\working\directoryz Working Dir:zSchedule Settings)ÚcronÚintervalÚmanualzSchedule Type:*z$e.g., 0 7 * * mon-fri (7am weekdays)zCron Expression:zTCron Help | Format: minute hour day month weekdayTzcolor: gray; font-size: 10pt;Úré4zWeeks:imzDays:ézHours:é;zMinutes:zSeconds:FzAdvanced SettingszJob is enabledz Show Console Window (Debug Mode)zhDisplay a visible CMD window during job execution. Useful for debugging. Output is still logged to file.i€Qiz secondszTimeout:é z Retry Count:z Retry Delay:)ÚnormalZ importantÚcriticalr-z Criticality:z,production, daily, datahub (comma-separated)zTags:úTest RunZSaveZCreateZCancelN)CrrrrÚ name_inputÚsetPlaceholderTextZaddRowrÚdescription_inputÚsetMaximumHeightÚ setLayoutÚ addWidgetr Újob_type_comboZaddItemsrÚexecutable_inputr Z browse_buttonÚclickedÚconnectÚ_browse_executableÚarguments_inputÚworking_dir_inputZbrowse_dir_buttonÚ_browse_directoryÚschedule_type_comboZcurrentTextChangedÚ_on_schedule_type_changedÚ cron_inputrÚ cron_helpZsetOpenExternalLinksÚ setStyleSheetr Úinterval_weeksZ setMinimumZ setMaximumÚ interval_daysÚinterval_hoursÚinterval_minutesÚinterval_secondsÚ setVisibler Úenabled_checkboxÚ setCheckedÚshow_console_checkboxÚ setToolTipÚ timeout_inputZsetRangeÚsetValueZ setSuffixÚretry_count_inputÚretry_delay_inputÚcriticality_comboÚsetCurrentTextÚ tags_inputÚ addStretchrZ test_buttonÚ _test_runZ save_buttonZ setDefaultÚ _save_jobZ cancel_buttonÚrejectÚ addLayout) rÚlayoutZ basic_groupZ basic_layoutZ exec_groupÚ exec_layoutZexec_path_layoutZworkdir_layoutZschedule_groupZschedule_layoutZadvanced_groupZadvanced_layoutZ button_layoutr!r!r"r%s                   ÿ                      ÿ                zJobEditorDialog._setup_uiÚ schedule_typecCsŒ|dk}|dk}|j |¡|j |¡|j |¡|j |¡|j |¡|j |¡|j |¡|dkr>|j d¡dS|j d¡dS)zHandle schedule type changer%r&r'zManual execution onlyze.g., 0 7 * * mon-friN) r@rHrArCrDrErFrGr1)rr[Zis_cronZ is_intervalr!r!r"r?Ýs       z)JobEditorDialog._on_schedule_type_changedcCsPt |ddd¡\}}|r$|j |¡|j ¡s&|j tt|ƒjƒ¡dSdSdS)zOpen file picker for executablezSelect Executabler(zgAll Files (*.bat *.cmd *.py *.exe);;Batch Files (*.bat *.cmd);;Python Files (*.py);;Executables (*.exe)N) r ZgetOpenFileNamer7ÚsetTextr<ÚtextÚstrrr)rZ file_pathÚ_r!r!r"r:ôsü  ûz"JobEditorDialog._browse_executablecCs&t |dd¡}|r|j |¡dSdS)z(Open folder picker for working directoryzSelect Working Directoryr(N)r ZgetExistingDirectoryr<r\)rZdir_pathr!r!r"r=sýÿz!JobEditorDialog._browse_directoryc CsZz|j |j¡}|st |dd|j›d¡| ¡WdS|j |d¡|j  |dp.d¡|j   |d¡|j  |d ¡|j  |d pHd¡|j |d pRd¡|j  |d ¡t |d ¡}|d dkrt|j | dd¡¡n8|d dkr¬|j | dd¡¡|j | dd¡¡|j | dd¡¡|j | dd¡¡|j | dd¡¡|j t|dƒ¡|j |d¡|j |d¡|j |d¡|j   |d¡|drát |d¡ng}|j! d "|¡¡|j# | dd¡¡t$ %d|j›d ¡WdSt&y,}zt$ 'd!|›¡t (|dd"|›¡| ¡WYd}~dSd}~ww)#z"Load existing job data for editingÚErrorzJob ID z not foundNÚnameÚ descriptionr(Újob_typeÚexecutable_pathÚ argumentsÚworking_directoryr[Úschedule_configr%r&ÚweeksrÚdaysÚhoursÚminutesÚsecondsÚenabledÚtimeout_secondsÚ retry_countÚretry_delay_secondsÚ criticalityÚtagsz, Ú show_consoleFz Loaded job z for editingzError loading job data: zFailed to load job: ))rÚget_jobrrÚwarningrWr0r\r2Z setPlainTextr6rRr7r;r<r>ÚjsonÚloadsr@ÚgetrCrNrDrErFrGrIrJÚboolrMrOrPrQrSÚjoinrKrÚinfoÚ ExceptionÚerrorr.)rÚjobrgrrÚer!r!r"r sJ  €ýzJobEditorDialog._load_job_dataÚreturncCs|j ¡ ¡st |dd¡|j ¡dS|j ¡ ¡s*t |dd¡|j ¡dS|j ¡dkrF|j  ¡ ¡sFt |dd¡|j  ¡dSdS)zValidate form inputszValidation ErrorzJob name is requiredFzExecutable path is requiredr%z2Cron expression is required for cron schedule typeT) r0r]ÚstriprruZsetFocusr7r>Ú currentTextr@)rr!r!r"Ú_validate_inputs:s   z JobEditorDialog._validate_inputscCs6| ¡sdSzî|j ¡}i}|dkr|j ¡ ¡|d<n'|dkrC|j ¡|d<|j ¡|d<|j  ¡|d<|j  ¡|d<|j  ¡|d<|j  ¡ ¡}|rVd d „|  d ¡Dƒng}|j ¡ ¡|j ¡ ¡pfd|j ¡|j ¡ ¡|j ¡ ¡pxd|j ¡ ¡p€d|||j ¡|j ¡|j ¡|j ¡|j ¡||j ¡d œ}|jrÈ|jj|jfi|¤Žt  !d |j›d|d›¡t" #|dd|d›d¡n&|jj$di|¤Ž}t  !d|›d|d›¡t" #|dd|d›d|›d¡| %¡WdSt&y}zt  'd|›¡t" (|dd|›¡WYd}~dSd}~ww)zSave job to databaseNr%r&rhrirjrkrlcSsg|] }| ¡r| ¡‘qSr!)r)Ú.0Útr!r!r"Ú bsz-JobEditorDialog._save_job..ú,)rarbrcrdrerfr[rgrmrnrorprqrrrsz Updated job z: raÚSuccesszJob 'z' updated successfullyz Created job z' created successfully (ID: ú)zError saving job: r`zFailed to save job: r!))rƒr>r‚r@r]rrCÚvaluerDrErFrGrSÚsplitr0r2Z toPlainTextr6r7r;r<rIZ isCheckedrMrOrPrQrKrrÚ update_jobrrr{rÚ informationÚ create_jobÚacceptr|r}r.)rr[rgZ tags_textrrZjob_datarrr!r!r"rVNsX   ñ "€þzJobEditorDialog._save_jobc Csþ|jsdSt |dd|j ¡›dtjjtjjB¡}|tjjkr}z7ddlm }ddl m }|ƒ}||j |ƒ}|j |jdd }t |d d |›d ¡t d |j›d|›¡WdSty|}zt d|›¡t |dd|›¡WYd}~dSd}~wwdS)zExecute test run of the jobNr/z Execute job 'z' now?r)Ú JobExecutor)ÚSchedulerConfigZ manual_test)Ú triggered_byzTest Run StartedzJob execution started (ID: z!) Check History tab for results.zTest run started for job z , execution zError starting test run: r`zFailed to start test run: )rrÚquestionr0r]ÚStandardButtonÚYesÚNoÚdaemon.job_executorrÚ core.configr‘rÚ execute_jobrrr{r|r}r.)rÚreplyrr‘ÚconfigÚexecutorÚ execution_idrr!r!r"rUˆs6ü     ý"€þðzJobEditorDialog._test_run)N)Ú__name__Ú __module__Ú __qualname__Ú__doc__rÚintrrr^r?r:r=rryrƒrVrUÚ __classcell__r!r!rr"rs9 -:r)r¡ÚPyQt6.QtWidgetsrrrrrrrr r r r r rrÚ PyQt6.QtCorerÚlogururrvÚpathlibrÚ core.databaserrr!r!r!r"Ús@