'bkgSearch-treeRootNode', 'request' => 'bkgPlot-treeRootNode', 'download' => 'bkgDown-treeRootNode'); protected $resRootNode = array('condition' => 'resSearch-treeRootNode', 'request' => 'resPlot-treeRootNode', 'download' => 'resDown-treeRootNode'); protected $jobPrefix = array( 'condition' => 'bkgrd_cond_', 'request' => 'bkgrd_req_', 'download' => 'bkgrd_down_'); public $success = true; function __construct() { $this->jobXmlName = USERJOBDIR."jobs.xml"; $this->jobXml = new DomDocument("1.0"); if (!file_exists($this->jobXmlName)){ $status = $this->generateXml(); if (!$status) { error_log('Cannot create jobs.xml: Fatal Error',1,email); $this->success = false; } } else { $status = $this->jobXml->load($this->jobXmlName); if (!$status) { $status = $this->generateXml(); $msg = $status ? 'Cannot load jobs.xml. New jobs.xml was created' : 'Cannot load jobs.xml. Cannot create jobs.xml: Fatal Error'; error_log($msg,1,email); if (!$status) $this->success = false; } } } /* * Create jobs.xml if it doesn't exist or in case of loading problems */ private function generateXml() { $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); $status = $this->jobXml->save($this->jobXmlName); return $status; } //TODO procedure to estimate STATUS protected function getStatus($pid) { return '20'; } /* * */ protected function updateJobStatus($pid) { if ($this->isFinished($pid)) return 'done'; $status = $this -> getStatus($pid); return $status; } /* * */ protected function saveResource($obj, $name) { $file = fopen(USERJOBDIR.$name, 'w'); //TODO change id and name to job ones? fwrite($file, json_encode($obj)); fclose($file); } // $obj => XML tag protected function deleteResource($obj) { // Delete request $request_name = $obj->getAttribute('xml:id'); if (file_exists(USERJOBDIR.$request_name)) unlink(USERJOBDIR.$request_name); // Delete result Time Table if ($obj->getAttribute('jobType') == 'condition') { foreach (glob(USERTTDIR.'*'.$obj->getAttribute('name').'*.xml') as $filename) unlink($filename); } // Delete result PLOT : PDF and PS if ($obj->getAttribute('jobType') == 'request' || $obj->getAttribute('jobType') == 'download') { $resultDir = USERWORKINGDIR.$obj->getAttribute('rawname').'_/'; if (is_dir($resultDir)) { foreach (glob($resultDir.'*') as $filename) unlink($filename); rmdir($resultDir); } } } // $obj => XML tag protected function updateResultName($obj) { switch ($obj->getAttribute('jobType')) { case 'condition': //TODO temporary dir? $old_tt = USERTTDIR.$obj->getAttribute('rawname').'.xml'; $new_tt = USERTTDIR.$obj->getAttribute('name').'.xml'; if (file_exists($old_tt)) rename($old_tt, $new_tt); $old_tt = USERTTDIR.'Gaps_'.$obj->getAttribute('rawname').'.xml'; $new_tt = USERTTDIR.'Gaps_'.$obj->getAttribute('name').'.xml'; if (file_exists($old_tt)) rename($old_tt, $new_tt); break; case 'request' : $resultDir = USERWORKINGDIR.$obj->getAttribute('rawname').'_/'; $reqFile = USERJOBDIR.$obj->getAttribute('xml:id'); if (file_exists($reqFile)) { $object = json_decode(file_get_contents($reqFile)); $format = strtolower($object->format); $newName = $obj->getAttribute('name'); switch ($format) { case 'ps': if (file_exists($resultDir.'idl.ps')){ rename($resultDir.'idl.ps',$resultDir.$newName.'.ps'); exec('gzip '.$resultDir.$newName.'.ps'); } //PS for time table else { $filenames = glob($resultDir."*.ps.gz"); if ($filenames && count($filenames) == 1) { rename($filenames[0],$resultDir.$newName.'.ps.gz'); } } break; case 'pdf': if (file_exists($resultDir.'idl.ps')){ exec('ps2pdf '.$resultDir.'idl.ps '.$resultDir.'idl.pdf'); unlink($resultDir.'idl.ps'); rename($resultDir.'idl.pdf',$resultDir.$newName.'.pdf'); } // PDF for time tables if (file_exists($resultDir.'idl.pdf')){ rename($resultDir.'idl.pdf',$resultDir.$newName.'.pdf'); } break; case 'png' : rename($resultDir.$obj->getAttribute('rawname').'.png', $resultDir.$newName.'.png'); break; default : } } break; case 'download' : $rawId = $obj->getAttribute('rawname'); $name = $obj->getAttribute('name'); $reqMgr = new RequestMgr('download'); $resultDir = USERWORKINGDIR.$rawId.'_/'; $res = $reqMgr->initResDir($rawId); if (!$res['success']) return $res; $resultDir = $res['resdir']; //get options $opts = $reqMgr->getPrintOptions($rawId); // Start PostProcessing - lock dir from Client Requests if (!file_exists($resultDir."/POSTPROCESSING")) touch($resultDir."/POSTPROCESSING"); // Is still PostProcessing - return else return true; $reqMgr->postProcessing($rawId,$name); if (file_exists($resultDir."/POSTPROCESSING")) unlink($resultDir."/POSTPROCESSING"); break; default : } return false; } /***************************************************************** * PUBLIC FUNCTIONS *****************************************************************/ public function isFinished($PID){ exec("ps $PID", $ProcessState); if (count($ProcessState) >= 2 ) return false; return true; } /* * */ public function addJob($obj, $pid, $tmpname, $newname) { /* [id] => cond_2 [name] => longtest [sampling] => 60 [gap] => 5 [expression] => imf(0) > 0 [startDate] => 2000-09-27T13:50:51 [durationDay] => 0665 [durationHour] => 12 [durationMin] => 00 [durationSec] => 00 [leaf] => 1 [nodeType] => condition */ $newJob = $this->jobXml->createElement('job'); $newJob->setAttribute('jobType', $obj->nodeType); $newJob->setAttribute('pid', $pid); $newJob->setAttribute('start', date('d-m-Y H:i:s')); if ($pid) { $newJob->setAttribute('status', $this->getStatus($pid)); $newJob->setAttribute('name', 'job_'.$pid); } else { $newJob->setAttribute('status', 'done'); $newJob->setAttribute('name', $newname); } $newJob->setAttribute('rawname', $tmpname); switch ($obj->nodeType) { case 'condition': $newJob->setAttribute('info', $obj->expression); break; case 'download' : $info = ''; foreach ($obj->list as $param) { if ($obj->downloadSrc == '2') //fits image $info = $info.' '.$param->url; else $info = $info.' '.$param; //data } $newJob->setAttribute('info', $info); break; case 'request' : $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; } } $newJob->setAttribute('info', $info); break; default: } if ($pid) { $newJob->setAttribute('xml:id',$this->jobPrefix[$obj->nodeType].$pid); $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 { $newJob->setAttribute('xml:id', $tmpname); $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]); $jobsInProgress = $this->jobXml->getElementsByTagName('jobsFinished')->item(0); $jobsInProgress->appendChild($rootJobNode); } } //TODO if status 'error'... $rootJobNode->appendChild($newJob); $ok = $this->jobXml->save($this->jobXmlName); if ($pid) $this->saveResource($obj, $newJob->getAttribute('xml:id')); return $newJob->getAttribute('xml:id'); } /* * object : id, leaf, nodeType */ public function deleteObject($obj) { $job = $this->jobXml->getElementById($obj->id); if (!$job) return array('id' => $obj->id); $pid = $job->getAttribute('pid'); // Check if it is temporary result if ($pid == '0') { $resultDir = USERWORKINGDIR.$obj->id.'_'; if (is_dir($resultDir)) { foreach (glob($resultDir.'/*') as $filename) unlink($filename); rmdir($resultDir); } //TT temporary foreach (glob(USERTTDIR.'*'.$obj->id.'*.xml') as $filename) unlink($filename); $job->parentNode->removeChild($job); $this->jobXml->save($this->jobXmlName); return array('id' => $obj->id); } if (!$this->isFinished($pid)) { $cmd = 'kill -9 '.$pid; exec($cmd); } $this->deleteResource($job); $job->parentNode->removeChild($job); $this->jobXml->save($this->jobXmlName); return array('id' => $obj->id); } /* * */ public function getObject($id) { $job = $this->jobXml->getElementById($id); $format = 'unknown'; $compression = 'unknown'; if($job) { $rawname = $job->getAttribute('rawname'); if ($job->getAttribute('jobType') == 'request') { if (file_exists(USERJOBDIR.$id)) { $obj = json_decode(file_get_contents(USERJOBDIR.$id)); $format = strtolower($obj->format); }; } if ($job->getAttribute('jobType') == 'download') { if (file_exists(USERJOBDIR.$id)) { $obj = json_decode(file_get_contents(USERJOBDIR.$id)); $compression = strtolower($obj->compression); }; } } return array('id' => $id, 'name' => $rawname, 'format' => $format, 'compression' => $compression); } /* * Real Update */ public function getCurrentJobsStatus() { $jobs = $this->jobXml->getElementsByTagName('job'); foreach ($jobs as $job) { $pid = $job->getAttribute('pid'); $status = $job->getAttribute('status'); // Already in Result => do not process if ($status == 'error' || $status == 'done') { $stop = $job->getAttribute('stop'); $jobType = $job->getAttribute('jobType'); $status = 'old'; } else { $status = $this -> updateJobStatus($pid); $stop = 'unknown'; $job->setAttribute('status',$status); $jobType = $job->getAttribute('jobType'); if ($status == 'error' || $status == 'done') { $stop = date('d-m-Y H:i:s'); $job->setAttribute('stop', $stop); // new array !!! otherwise $jobs array decreased if ($jobType != null) { $jobsToMove[] = $job; } if ($status == 'done') { // Could take long time - special truck to avoid interference of TaskMgr requests // check if ResDir is locked $postProccesing = $this->updateResultName($job); if ($postProccesing) { // is already PostProcessing -> return something not-used return array('id' => 'postprocessing'); } } } } $allJobs[] = array('name' => $job->getAttribute('name'), 'id' => $job->getAttribute('xml:id'), 'nodeType' => 'bkgWorks', 'leaf' => true, 'pid' => $pid, 'status' => $status, 'start' => $job->getAttribute('start'), 'stop' => $stop, 'jobType' => $jobType); } foreach ($jobsToMove as $job) $this->jobXml->getElementById($this->resRootNode[$job->getAttribute('jobType')])->appendChild($job); $this->jobXml->save($this->jobXmlName); return $allJobs; } /* * Delete all temporary products */ public function deleteTmp() { // Clean up temporary directory if (is_dir(USERTEMPDIR)) foreach ( glob(USERTEMPDIR.'*') as $filename ) unlink($filename); // Clean up immediate jobs $xp = new domxpath($this->jobXml); $tmps = $xp->query("//job[@pid='0']"); if ($tmps->length == 0) return; foreach ($tmps as $tmp) { $this->deleteResource($tmp); $tmp->parentNode->removeChild($tmp); } $this->jobXml->save($this->jobXmlName); return; } } ?>