'bkgSearch-treeRootNode', 'request' => 'bkgPlot-treeRootNode', 'download' => 'bkgDown-treeRootNode'); protected $resRootNode = array('condition' => 'resSearch-treeRootNode', 'request' => 'resPlot-treeRootNode', 'download' => 'resDown-treeRootNode'); /* * @brief Constructor */ function __construct() { } /* * @brief Load jobs file and create it if needed */ private function init() { $this->jobXmlName = IHMConfigClass::getUserJobsFile(); $this->jobXml = new DomDocument("1.0"); if (!file_exists($this->jobXmlName)) { $res = $this->createJobsFile(); if (!$res['success']) return $res; } $res = $this->jobXml->load($this->jobXmlName); if (!$res) return array( "success" => false, "message" => "Cannot load jobs file"); return array("success" => true); } /* * @brief Create a new jobs file */ private function createJobsFile() { $rootElement = $this->jobXml->createElement('jobs'); $jobsInProgress = $this->jobXml->createElement('jobsInProgress'); foreach ($this->bkgRootNode as $key => $value) { $element = $this->jobXml->createElement("$key"); $element->setAttribute('xml:id',$value); $jobsInProgress->appendChild($element); } $jobsFinished = $this->jobXml->createElement('jobsFinished'); foreach ($this->resRootNode as $key => $value) { $element = $this->jobXml->createElement("$key"); $element->setAttribute('xml:id',"$value"); $jobsFinished->appendChild($element); } $rootElement->appendChild($jobsInProgress); $rootElement->appendChild($jobsFinished); $this->jobXml->appendChild($rootElement); $res = $this->jobXml->save($this->jobXmlName); if (!$res) return array( "success" => false, "message" => "Cannot create new jobs file"); return array("success" => true); } /* * @brief Get the path of the request object file */ protected function getRequestObjectFilePath($id) { return IHMConfigClass::getUserJobsPath().$id.".request"; } /* * @brief Save a request object file */ protected function saveRequestObjectFile($obj, $id) { $file = fopen($this->getRequestObjectFilePath($id), 'w'); fwrite($file, json_encode($obj)); fclose($file); } /* * @brief Decode a request object file */ protected function getRequestObjectFile($id) { if (!file_exists($this->getRequestObjectFilePath($id))) return NULL; return json_decode(file_get_contents($this->getRequestObjectFilePath($id))); } /* * @brief Delete a request object file */ protected function deleteRequestObjectFile($id) { if (file_exists($this->getRequestObjectFilePath($id))) unlink($this->getRequestObjectFilePath($id)); } /* * @brief get a job status from process info */ protected function getJobStatus($running,$exitcode) { if ($running) return 'in_progress'; if ($exitcode == 0) return 'done'; return 'error'; } /* * @brief delete a job */ public function deleteJob($id) { $res = $this->init(); if (!$res['success']) return $res; $job = $this->jobXml->getElementById($id); //delete job if (!$job) return array('success' => false, 'message' => "Job not reachable"); $folder = $job->getAttribute('folder'); //be sure that it's an AMDA working dir before deletion... $fullFolderPath = IHMConfigClass::getRequestPath().$folder.'/'; if ((isset($folder)) && ($folder != "") && is_dir($fullFolderPath) && (preg_match("/DD[0-9A-Za-z]*_/",$folder) || preg_match("/Plot[0-9]*_/",$folder))) { foreach (glob($fullFolderPath.'*') as $filename) { if (is_dir($filename) && (basename($filename) == 'params')) { //recursive deletion only for "params" dir (a full recursive deletion is probably too dangerous...) foreach (glob($filename.'/*') as $paramname) unlink($paramname); rmdir($filename); } else unlink($filename); } rmdir($fullFolderPath); } $this->deleteRequestObjectFile($id); $job->parentNode->removeChild($job); $res = $this->jobXml->save($this->jobXmlName); if (!$res) return array( 'success' => false, 'message' => "Cannot save jobs file"); return array('success' => true, 'id' => $id); } /* * @brief get job info about a job */ public function getJobInfo($id) { $res = $this->init(); if (!$res['success']) return $res; $job = $this->jobXml->getElementById($id); $format = 'unknown'; $compression = 'unknown'; if($job) { $name = $job->getAttribute('name'); $status = $job->getAttribute('status'); $jobType = $job->getAttribute('jobType'); $info = $job->getAttribute('info'); $start = $job->getAttribute('start'); $stop = $job->getAttribute('stop'); $result = $job->getAttribute('result'); $folder = $job->getAttribute('folder'); $request_obj = $this->getRequestObjectFile($id); if (isset($request_obj)) { if (isset($request_obj->format)) { $format = strtolower($request_obj->format); if (($format == "pdf") || ($format == "ps")) //auto compression for plot request $compression = ".tar.gz"; } if (isset($request_obj->compression)) $compression = strtolower($request_obj->compression); } } return array( 'success' => true, 'id' => $id, 'name' => $name, 'status' => $status, 'jobType' => $jobType, 'info' => $info, 'start' => $start, 'stop' => $stop, 'folder' => $folder, 'result' => $result, 'format' => $format, 'compression' => $compression); } /* * @brief Add a new job */ public function addJob($obj, $id, $folder, $running, $start, $result, $exitcode) { $res = $this->init(); if (!$res['success']) return $res; $newJob = $this->jobXml->createElement('job'); $newJob->setAttribute('xml:id', $id); $newJob->setAttribute('jobType', $obj->nodeType); switch ($obj->nodeType) { case 'condition' : $name = 'datamining_'.time(); $info = $obj->expression; break; case 'download' : if ($obj->downloadSrc == '2') //fits image $name = "download_fits_".time(); else $name = "download_data_".time(); $info = ''; foreach ($obj->list as $param) { if ($obj->downloadSrc == '2') //fits image $info = $info.' '.$param->url; else $info = $info.' '.$param; //data } break; case 'request' : $name = "request_".time(); $info = ''; for ($i=0; $i < count($obj->children); $i++) { for ($j=0; $j < count($obj->children[$i]->children); $j++) { $info = $info.' '.$obj->children[$i]->children[$j]->name; } } break; default: $name = "unknown_".time(); $info = ''; } $newJob->setAttribute('name', $name); $newJob->setAttribute('info', $info); $newJob->setAttribute('folder', $folder); $newJob->setAttribute('result', $result); $newJob->setAttribute('start', date('d-m-Y H:i:s', $start)); $newJob->setAttribute('result', $result); //to know if know if it's an immediate job or not $newJob->setAttribute('immediate', !$running); if ($running) { $rootJobNode = $this->jobXml->getElementById($this->bkgRootNode[$obj->nodeType]); if (!$rootJobNode) { $key = $obj->nodeType; $rootJobNode = $this->jobXml->createElement("$key"); $rootJobNode->setAttribute('xml:id', $this->bkgRootNode[$obj->nodeType]); $jobsInProgress = $this->jobXml->getElementsByTagName('jobsInProgress')->item(0); $jobsInProgress->appendChild($rootJobNode); } } else { $rootJobNode = $this->jobXml->getElementById($this->resRootNode[$obj->nodeType]); if (!$rootJobNode) { $key = $obj->nodeType; $rootJobNode = $this->jobXml->createElement("$key"); $rootJobNode->setAttribute('xml:id', $this->resRootNode[$obj->nodeType]); $jobsFinished = $this->jobXml->getElementsByTagName('jobsFinished')->item(0); $jobsFinished->appendChild($rootJobNode); } } $rootJobNode->appendChild($newJob); if (!$this->jobXml->save($this->jobXmlName)) return array("success" => false, "message" => "Cannot save job manager file"); $this->saveRequestObjectFile($obj, $id); $this->updateJobStatus($id, $running, $exitcode); return $this->getJobInfo($id); } /* * @brief Update the status of a job */ public function updateJobStatus($id, $running, $exitcode) { $res = $this->init(); if (!$res['success']) return $res; $job = $this->jobXml->getElementById($id); if (!isset($job)) return array("success" => false, "message" => "Cannot found job"); $jobstatus = $this->getJobStatus($running,$exitcode); $job->setAttribute('status', $jobstatus); if ($running) $job->setAttribute('stop', 'unknown'); else if ($job->getAttribute('stop') == '' || $job->getAttribute('stop') == 'unknown') { $job->setAttribute('stop', date('d-m-Y H:i:s', time())); $this->jobXml->getElementById($this->resRootNode[$job->getAttribute('jobType')])->appendChild($job); } $res = $this->jobXml->save($this->jobXmlName); if (!$res) return array( 'success' => false, 'message' => "Cannot save jobs status file"); return $this->getJobInfo($id); } /* * @brief Get the list of jobs with a specific status */ public function getJobsByStatus($status) { $res = $this->init(); if (!$res['success']) return $res; $xp = new domxpath($this->jobXml); $jobs = $xp->query("//job[@status='".$status."']"); $jobsId = array(); foreach ($jobs as $job) $jobsId[] = $job->getAttribute('xml:id'); return array('success' => true, 'jobs' => $jobsId); } /* * @brief Get jobs that use a specific working dir */ public function getJobsByWorkingDir($folder) { $res = $this->init(); if (!$res['success']) return $res; $xp = new domxpath($this->jobXml); $jobs = $xp->query("//job[@folder='".$folder."']"); $jobsId = array(); foreach ($jobs as $job) $jobsId[] = $job->getAttribute('xml:id'); return array('success' => true, 'jobs' => $jobsId); } /* * @brief Get all jobs to clean (immediate result jobs) */ public function getJobsToClean() { $res = $this->init(); if (!$res['success']) return $res; // Get immediate jobs $xp = new domxpath($this->jobXml); $jobs = $xp->query("//job[@immediate='1']"); $jobsId = array(); foreach ($jobs as $job) $jobsId[] = $job->getAttribute('xml:id'); return array("success" => true, "jobs" => $jobsId); } } ?>