Commit 8720c98967213d1a94c0a3c6f796a21c386b2b3c

Authored by Myriam Bouchemit
2 parents 91c2a59a 8fc77945

Merge branch 'tooltipJobs' into 'master'

Tooltip jobs

Improve tooltips in jobs tab in Workspace explorer.

Issue: https://projects.irap.omp.eu/issues/4861

See merge request !1
.gitignore
1 1 .project
  2 +.idea
... ...
src/InputOutput/IHMImpl/Process/IHMInputOutputRunningInfoProcessClass.php
... ... @@ -39,6 +39,8 @@ class IHMInputOutputRunningInfoProcessClass extends IHMInputOutputInfoProcessAbs
39 39 if (!$jobInfo['success'])
40 40 continue;
41 41  
  42 + $jobInfo['runningPath'] = $d->getRunningPath();
  43 +
42 44 switch ($jobInfo['status'])
43 45 {
44 46 case 'in_progress' :
... ...
src/InputOutput/IHMImpl/Tools/IHMJobsManagerClass.php
... ... @@ -199,6 +199,12 @@ class IHMJobsManagerClass {
199 199 return $res;
200 200  
201 201 $job = $this->jobXml->getElementById($id);
  202 +
  203 + $attributes = [];
  204 + foreach( $job->attributes as $attrName => $attrNode) {
  205 + $attributes[$attrName] = $attrNode->nodeValue;
  206 + }
  207 +
202 208 $format = 'unknown';
203 209 $compression = 'unknown';
204 210 if($job)
... ... @@ -252,95 +258,157 @@ class IHMJobsManagerClass {
252 258 /*
253 259 * @brief Add a new job
254 260 */
255   - public function addJob($obj, $id, $folder,
256   - $running, $start, $result, $exitcode)
  261 + public function addJob($obj, $id, $folder, $running, $start, $result, $exitcode)
257 262 {
  263 + $obj = get_object_vars($obj); // Allow access to elements where the key is in dash-separated form.
258 264 $res = $this->init();
259 265 if (!$res['success'])
260 266 return $res;
261 267  
262   - $newJob = $this->jobXml->createElement('job');
263   -
264   - $newJob->setAttribute('xml:id', $id);
265   - $newJob->setAttribute('jobType', $obj->nodeType);
266   -
267   - switch ($obj->nodeType)
268   - {
269   - case 'condition' :
  268 + $infos = [];
  269 + switch ($obj['nodeType']) {
  270 + // Data mining
  271 + case 'condition':
270 272 $name = 'datamining_'.time();
271   - $info = $obj->expression;
  273 + if($obj['name'] != '') {
  274 + $infos['Name'] = $obj['name'];
  275 + }
  276 + $infos['Condition'] = $obj['expression'];
  277 + $infos['Start date'] = $obj['startDate'];
  278 + $infos['Stop date'] = $obj['stopDate'];
272 279 break;
273   - case 'statistics' :
  280 +
  281 + case 'statistics':
274 282 $name = 'statistics_'.time();
275   - $info = isset($obj->expression) ? $obj->expression : "";
  283 + $infos['Name'] = $obj['name']; // TODO: name toujours รฉgal ร  'test' (?)
  284 +
  285 + // TODO : lire data/user/TT/tt_0.xml -> trouver ttname + nbIntervals
  286 +
  287 + if(array_key_exists('timeTables', $obj)) {
  288 + $ttXml = new DomDocument();
  289 + $ttXml->load(USERWSDIR . 'Tt.xml');
  290 +
  291 + $ttIntervals = [];
  292 + foreach ($ttXml->getElementsByTagName('timetab') as $tt) {
  293 + $ttIntervals[$tt->getAttribute('name')] = $tt->getAttribute('intervals');
  294 + }
  295 +
  296 + if(count($obj['timeTables']) == 1) {
  297 + $infos['Time table'] = $obj['timeTables'][0]->timeTableName;
  298 + $infos['Nb Intervals'] = $ttIntervals[$infos['Time table']];
  299 + } else {
  300 + foreach ($obj['timeTables'] as $tt) {
  301 + if($tt === reset($obj['timeTables'])) {
  302 + $infos['Time tables'] = $tt->timeTableName . '(' . $ttIntervals[$tt->timeTableName] . ' int.)';
  303 + } else {
  304 + $infos['Time tables'] .= ', ' . $tt->timeTableName . '(' . $ttIntervals[$tt->timeTableName] . ' int.)';
  305 + }
  306 + }
  307 + }
  308 + } else {
  309 + $infos['Start date'] = $obj['startDate'];
  310 + $infos['Stop date'] = $obj['stopDate'];
  311 + }
  312 +
  313 + if(array_key_exists('expression', $obj)) {
  314 + $infos['Expression'] = $obj['expression'];
  315 + }
  316 + $params = [];
  317 + foreach ($obj['parameter'] as $param) {
  318 + $params[] = $param->function . '(' . $param->paramid . ')';
  319 + }
  320 + if(count($params) == 1) {
  321 + $infos['Parameter'] = $params[0];
  322 + } else {
  323 + $infos['Parameters'] = '<ul><li>' . join('</li><li>', $params) . '</li></ul>';
  324 + }
276 325 break;
277   - case 'download' :
278   - if ($obj->downloadSrc == '2') //fits image
279   - $name = "download_fits_".time();
280   - else
281   - $name = "download_data_".time();
282   - $info = '';
283   - foreach ($obj->list as $param)
284   - {
285   - if ($obj->downloadSrc == '2') //fits image
286   - $info = $info.' '.$param->url;
287   - else
288   - $info = $info.' '.$param->name; //data
  326 +
  327 + case 'download':
  328 + $name = $obj['downloadSrc'] == '2' ? "download_fits_".time() : "download_data_".time();
  329 + $params = [];
  330 + foreach ($obj['list'] as $param) {
  331 + $params[] = $param->paramid;
  332 + }
  333 + if(count($params) == 1) {
  334 + $infos['Parameter'] = $params[0];
  335 + } else {
  336 + $infos['Parameters'] = join(', ', $params);
289 337 }
  338 + $infos['Start date'] = $obj['startDate'];
  339 + $infos['Stop date'] = $obj['stopDate'];
290 340 break;
291   - case 'request' :
  341 +
  342 + // Plot
  343 + case 'request':
292 344 $name = "request_".time();
293   - $info = '';
294   - for ($i=0; $i < count($obj->children); $i++) {
295   - for ($j=0; $j < count($obj->children[$i]->children); $j++) {
296   - $info = $info.' '.$obj->children[$i]->children[$j]->name;
  345 +
  346 + $infos['Output'] = strtolower($obj['file-format']) . ' (' . strtolower($obj['file-output']) . ')';
  347 + foreach ($obj['tabs'] as $tab) {
  348 + if($tab->id == $obj['last-plotted-tab']) {
  349 + $infos['Start date'] = $tab->startDate;
  350 + $infos['Stop date'] = $tab->stopDate;
  351 +
  352 + $strPanels = [];
  353 +
  354 + foreach ($tab->panels as $panel) {
  355 + $strParams = '';
  356 + foreach ($panel->params as $param) {
  357 + $strParams .= $param->paramid . ($param === end($panel->params) ? '' : ', ');
  358 + }
  359 + $infos['โ€ข Panel ' . $panel->id] = $strParams;
  360 + }
  361 +
  362 + continue;
297 363 }
298 364 }
299 365 break;
  366 +
300 367 default:
301 368 $name = "unknown_".time();
302   - $info = '';
303 369 }
  370 + $infos['Started at'] = gmdate("Y-m-d H:i:s", $start);
304 371  
305   - $newJob->setAttribute('name', $name);
306   - $newJob->setAttribute('info', $info);
  372 + $strInfo = '';
  373 + foreach ($infos as $key => $info) {
  374 + $strInfo .= ($key == 'Started at' ? '<hr/>' : '') . '<b>' . $key . '</b>: ' . $info . '<br/>';
  375 + }
307 376  
  377 + $newJob = $this->jobXml->createElement('job');
  378 + $newJob->setAttribute('xml:id', $id);
  379 + $newJob->setAttribute('jobType', $obj['nodeType']);
  380 + $newJob->setAttribute('name', $name);
  381 + $newJob->setAttribute('info', $strInfo);
308 382 $newJob->setAttribute('folder', $folder);
309   -
310 383 $newJob->setAttribute('result', $result);
311   -
312 384 $newJob->setAttribute('start', date('d-m-Y H:i:s', $start));
313   -
314   - $newJob->setAttribute('result', $result);
315   -
316 385 //to know if know if it's an immediate job or not
317 386 $newJob->setAttribute('immediate', !$running);
318 387  
319   - $sendToSamp = isset($obj->sendToSamp) ? $obj->sendToSamp : FALSE;
  388 + $sendToSamp = isset($obj['sendToSamp']) ? $obj['sendToSamp'] : FALSE;
320 389 if ($sendToSamp) {
321 390 $newJob->setAttribute('sendToSamp', "true");
322 391 }
323 392  
  393 + $key = $obj['nodeType'];
324 394 if ($running)
325 395 {
326   - $rootJobNode = $this->jobXml->getElementById($this->bkgRootNode[$obj->nodeType]);
  396 + $rootJobNode = $this->jobXml->getElementById($this->bkgRootNode[$key]);
327 397 if (!$rootJobNode)
328 398 {
329   - $key = $obj->nodeType;
330 399 $rootJobNode = $this->jobXml->createElement("$key");
331   - $rootJobNode->setAttribute('xml:id', $this->bkgRootNode[$obj->nodeType]);
  400 + $rootJobNode->setAttribute('xml:id', $this->bkgRootNode[$key]);
332 401 $jobsInProgress = $this->jobXml->getElementsByTagName('jobsInProgress')->item(0);
333 402 $jobsInProgress->appendChild($rootJobNode);
334 403 }
335 404 }
336 405 else
337 406 {
338   - $rootJobNode = $this->jobXml->getElementById($this->resRootNode[$obj->nodeType]);
  407 + $rootJobNode = $this->jobXml->getElementById($this->resRootNode[$key]);
339 408 if (!$rootJobNode)
340 409 {
341   - $key = $obj->nodeType;
342 410 $rootJobNode = $this->jobXml->createElement("$key");
343   - $rootJobNode->setAttribute('xml:id', $this->resRootNode[$obj->nodeType]);
  411 + $rootJobNode->setAttribute('xml:id', $this->resRootNode[$key]);
344 412 $jobsFinished = $this->jobXml->getElementsByTagName('jobsFinished')->item(0);
345 413 $jobsFinished->appendChild($rootJobNode);
346 414 }
... ... @@ -369,20 +437,58 @@ class IHMJobsManagerClass {
369 437  
370 438 $job = $this->jobXml->getElementById($id);
371 439  
372   - if (!isset($job))
  440 + if (!isset($job)) {
373 441 return array("success" => false, "message" => "Cannot found job");
374   -
  442 + }
  443 +
375 444 $jobstatus = $this->getJobStatus($running,$exitcode);
376 445 $job->setAttribute('status', $jobstatus);
377 446  
378   - if ($running)
  447 + $infos = [];
  448 +
  449 + if ($running) {
379 450 $job->setAttribute('stop', 'unknown');
380   - else if ($job->getAttribute('stop') == '' || $job->getAttribute('stop') == 'unknown')
381   - {
  451 + } else if ($job->getAttribute('stop') == '' || $job->getAttribute('stop') == 'unknown') {
382 452 $job->setAttribute('stop', date('d-m-Y H:i:s', time()));
  453 +
  454 + $start = new DateTime($job->getAttribute('start'));
  455 + $interval = (new DateTime('now'))->diff($start);
  456 + $infos['Job duration'] = $interval->format('%Hh %Im %Ss');
  457 +
  458 + $resPath = glob(USERWORKINGDIR . $job->getAttribute('folder') . '/' . $job->getAttribute('result') . '*')[0];
  459 +
  460 + if($job->getAttribute('jobType') == 'condition') {
  461 + error_log('resPath: ' . $resPath);
  462 + $resXml = new DomDocument();
  463 + $resXml->load($resPath);
  464 + $infos['nb intervals'] = $resXml->getElementsByTagName('nbIntervals')->item(0)->nodeValue;
  465 + }
  466 +
  467 + $fileSize = filesize($resPath);
  468 + if ($fileSize < 1024) {
  469 + $strSize = number_format($fileSize, 2, '.', ' ') . 'b';
  470 + } else if($fileSize < 1024*1024) {
  471 + $strSize = number_format($fileSize/1024, 2, '.', ' ') . 'kb';
  472 + } else if($fileSize < 1024*1024*1024) {
  473 + $strSize = number_format($fileSize/(1024*1024), 2, '.', ' ') . 'mb';
  474 + } else {
  475 + $strSize = number_format($fileSize/(1024*1024*1024), 2, '.', ' ') . 'gb';
  476 + }
  477 + $infos['File size'] = $strSize;
  478 +
383 479 $this->jobXml->getElementById($this->resRootNode[$job->getAttribute('jobType')])->appendChild($job);
384 480 }
385   -
  481 +
  482 + if($exitcode != 0) {
  483 + $infos['Error code'] = $exitcode;
  484 + }
  485 +
  486 + $strInfo = $job->getAttribute('info');
  487 + foreach ($infos as $key => $info) {
  488 + $strInfo .= '<b>' . $key . '</b>: ' . $info . '<br/>';
  489 + }
  490 + $job->setAttribute('info', $strInfo);
  491 +
386 492 $res = $this->jobXml->save($this->jobXmlName);
387 493  
388 494 if (!$res)
... ...
src/Request/ProcessRequestImpl/ProcessRequestClass.php
... ... @@ -76,6 +76,8 @@ class ProcessRequestClass extends RequestAbstractClass
76 76 */
77 77 private function updateProcess($processInfo)
78 78 {
  79 + $this->requestData->setRunningPath($processInfo['runningpath']);
  80 +
79 81 $this->requestData->setId($processInfo['id']);
80 82 if ($processInfo['isrunning'])
81 83 $this->requestData->setStatus(ProcessStatusEnumClass::RUNNING);
... ...
src/Request/ProcessRequestImpl/ProcessRequestDataClass.php
... ... @@ -46,6 +46,7 @@ class ProcessRequestDataClass extends RequestDataClass
46 46 private $status = ProcessStatusEnumClass::UNKNOWN;
47 47 private $exitCode = 0;
48 48 private $start = 0;
  49 + private $runningPath = "";
49 50  
50 51 public function getManagerFilePath()
51 52 {
... ... @@ -107,6 +108,16 @@ class ProcessRequestDataClass extends RequestDataClass
107 108 $this->id = $id;
108 109 }
109 110  
  111 + public function getRunningPath()
  112 + {
  113 + return $this->runningPath;
  114 + }
  115 +
  116 + public function setRunningPath($runningPath)
  117 + {
  118 + $this->runningPath = $runningPath;
  119 + }
  120 +
110 121 public function getType()
111 122 {
112 123 return $this->type;
... ... @@ -117,14 +128,14 @@ class ProcessRequestDataClass extends RequestDataClass
117 128 $this->type = $type;
118 129 }
119 130  
120   - public function getBatchEnable()
121   - {
122   - return $this->batchEnable;
123   - }
124   -
125   - public function setBatchEnable($batchEnable)
126   - {
127   - $this->batchEnable = $batchEnable;
  131 + public function getBatchEnable()
  132 + {
  133 + return $this->batchEnable;
  134 + }
  135 +
  136 + public function setBatchEnable($batchEnable)
  137 + {
  138 + $this->batchEnable = $batchEnable;
128 139 }
129 140  
130 141 public function getStatus()
... ...