FOSSology  3.2.0rc1
Open Source License Compliance by Open Source Software
AjaxShowJobs.php
Go to the documentation of this file.
1 <?php
2 /*
3  Copyright (C) 2015-2019, Siemens AG
4  Author: Shaheem Azmal<shaheem.azmal@siemens.com>,
5  Anupam Ghosh <anupam.ghosh@siemens.com>
6  Copyright (C) 2020 Robert Bosch GmbH, Dineshkumar Devarajan <Devarajan.Dineshkumar@in.bosch.com>
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License
10  version 2 as published by the Free Software Foundation.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License along
18  with this program; if not, write to the Free Software Foundation, Inc.,
19  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  */
21 
26 namespace Fossology\UI\Ajax;
27 
34 
35 define("TITLE_AJAXSHOWJOBS", _("ShowJobs"));
36 
43 class AjaxShowJobs extends \FO_Plugin
44 {
45  const MAX_LOG_OUTPUT = 32768;
46 
48  private $dbManager;
49 
51  private $showJobsDao;
52 
54  private $userDao;
55 
57  private $clearingDao;
58 
59  function __construct()
60  {
61  $this->Name = "ajaxShowJobs";
62  $this->Title = TITLE_AJAXSHOWJOBS;
63  $this->DBaccess = PLUGIN_DB_WRITE;
64  $this->LoginFlag = 0;
65  $this->NoMenu = 0;
66  $this->OutputType = 'JSON';
67  $this->OutputToStdout = true;
68 
69  global $container;
70  $this->showJobsDao = $container->get('dao.show_jobs');
71  $this->userDao = $container->get('dao.user');
72  $this->clearingDao = $container->get('dao.clearing');
73  $this->dbManager = $container->get('db.manager');
74 
75  parent::__construct();
76  }
77 
78  function OutputOpen()
79  {
80  if ($this->State != PLUGIN_STATE_READY) {
81  return null;
82  }
83  $uploadId = GetParm("upload", PARM_INTEGER);
84  if (empty($uploadId)) {
85  return null;
86  }
87  }
88 
95  protected function compareJobsInfo($JobsInfo1, $JobsInfo2)
96  {
97  $job_pk1 = $JobsInfo1["job"]["job_pk"];
98  $job_pk2 = $JobsInfo2["job"]["job_pk"];
99 
100  return $job_pk2 - $job_pk1;
101  }
102 
108  protected function getGeekyScanDetailsForJob($job_pk)
109  {
110  $i=0;
111  $fields=array('jq_pk'=>'jq_pk',
112  'job_pk'=>'jq_job_fk',
113  'Job Name'=> 'job_name',
114  'Agent Name'=>'jq_type',
115  'Priority'=>'job_priority',
116  'Args'=>'jq_args',
117  'jq_runonpfile'=>'jq_runonpfile',
118  'Queued'=>'job_queued',
119  'Started'=>'jq_starttime',
120  'Ended'=>'jq_endtime',
121  'Elapsed HH:MM:SS'=>'elapsed',
122  'Status'=>'jq_end_bits',
123  'Items processed'=>'jq_itemsprocessed',
124  'Submitter'=>'job_user_fk',
125  'Upload'=>'job_upload_fk',
126  'Log'=>'jq_log');
127  $uri = Traceback_uri() . "?mod=showjobs&upload=";
128 
129  $row = $this->showJobsDao->getDataForASingleJob($job_pk);
130 
131  $table = array();
132  foreach ($fields as $labelKey=>$field) {
133  $value ="";
134  $label = $labelKey;
135  switch ($field) {
136  case 'job_queued':
137  case 'jq_starttime':
138  case 'jq_endtime':
139  $value = Convert2BrowserTime($row[$field]);
140  break;
141  case 'jq_itemsprocessed':
142  $value = number_format($row[$field]);
143  break;
144  case 'jq_end_bits':
145  $value = $this->jobqueueStatus($row);
146  break;
147  case 'jq_pk':
148  if (!empty($row['job_upload_fk'])) {
149  $value = "<a href='$uri" . $row['job_upload_fk'] . "'>" . htmlentities($row[$field]) . "</a>"." (" . _("Click to view jobs for this upload") . ")";
150  } else {
151  $uri2 = Traceback_uri() . "?mod=showjobs";
152  $back = "(" . _("Click to return to Show Jobs") . ")";
153  $value = "<a href='$uri2'>$row[$field] $back</a>";
154  }
155  break;
156  case 'job_upload_fk':
157  if (!empty($row[$field])) {
158  $browse = Traceback_uri() . "?mod=browse&upload=" . htmlentities($row[$field]);
159  $value = "<a href='$browse'>" . htmlentities($row[$field]) . "</a>"." (" . _("Click to browse upload") . ")";
160  }
161  break;
162  case 'jq_log':
163  if (empty($row[$field]) || $row[$field] == 'removed' || !file_exists($row[$field])) {
164  break;
165  }
166  if (filesize($row[$field]) > self::MAX_LOG_OUTPUT) {
167  $value = "<pre>" .file_get_contents($row[$field],false,null,-1,self::MAX_LOG_OUTPUT)."</pre>"
168  .'<a href="'.Traceback_uri() . '?mod=download&log=' . $row['jq_pk'] . '">Download full log</a>';
169  } else {
170  $value = "<pre>" . file_get_contents($row[$field]). "</pre>";
171  }
172  break;
173  case 'job_user_fk':
174  if (!empty($row[$field])) {
175  $value = $this->userDao->getUserName($row[$field]);
176  }
177  break;
178  case 'jq_args':
179  $jq_args_temp = $row[$field];
180  $jq_args_show = $jq_args_temp;
181  if (! empty($jq_args_temp)) {
182  $pos = strpos($jq_args_temp, ' SVN ');
183  if ($pos) {
184  $jq_args_show = substr($jq_args_temp, 0, $pos + 4);
185  }
186  $pos = strpos($jq_args_temp, ' CVS ');
187  if ($pos) {
188  $jq_args_show = substr($jq_args_temp, 0, $pos + 4);
189  }
190  $pos = strpos($jq_args_temp, ' Git ');
191  if ($pos) {
192  $jq_args_show = substr($jq_args_temp, 0, $pos + 4);
193  }
194  $value = $jq_args_show;
195  }
196  break;
197  default:
198  if (array_key_exists($field, $row)) {
199  $value = htmlentities($row[$field]);
200  }
201  break;
202  }
203  $table[] = array('DT_RowId' => $i++,
204  '0'=>$label,
205  '1'=> $value);
206  }
207  $tableData = array_values($table);
208  return new JsonResponse(array('sEcho' => intval($_GET['sEcho']),
209  'aaData' => $tableData,
210  'iTotalRecords' => count($tableData),
211  'iTotalDisplayRecords' => count($tableData)));
212 
213  } /* getGeekyScanDetailsForJob() */
214 
220  protected function getShowJobsForEachJob($jobData)
221  {
222  if (count($jobData) == 0) {
223  return array('showJobsData' => "There are no jobs to display");
224  }
225  $returnData = [];
226  foreach ($jobData as $jobId => $jobs) {
227  $jobArr = array(
228  'jobId' => $jobs['job']['job_pk'],
229  'jobName' => $jobs['job']['job_name'],
230  'jobQueue' => $jobs['jobqueue']
231  );
232  foreach ($jobArr['jobQueue'] as $key => $singleJobQueue) {
233  $jobArr['jobQueue'][$key]['jq_starttime'] = Convert2BrowserTime($jobArr['jobQueue'][$key]['jq_starttime']);
234  $jobArr['jobQueue'][$key]['jq_endtime'] = Convert2BrowserTime($jobArr['jobQueue'][$key]['jq_endtime']) ;
235  if (! empty($singleJobQueue["jq_endtime"])) {
236  $numSecs = strtotime($singleJobQueue['jq_endtime']) -
237  strtotime($singleJobQueue['jq_starttime']);
238  $numSecs = ($numSecs == 0) ? 1 : $numSecs; // If difference is in milliseconds
239  } else {
240  $numSecs = time() - strtotime($singleJobQueue['jq_starttime']);
241  }
242 
243  $jobArr['jobQueue'][$key]['itemsPerSec'] = $itemsPerSec = 0;
244  if ($singleJobQueue['jq_starttime']) {
245  $itemsPerSec = $this->showJobsDao->getNumItemsPerSec(
246  $singleJobQueue['jq_itemsprocessed'], $numSecs);
247  $jobArr['jobQueue'][$key]['itemsPerSec'] = $itemsPerSec;
248  }
249  if (empty($singleJobQueue['jq_endtime'])) {
250  $jobArr['jobQueue'][$key]['eta'] = $this->showJobsDao->getEstimatedTime(
251  $singleJobQueue['jq_job_fk'], $singleJobQueue['jq_type'],
252  $itemsPerSec, $jobs['job']['job_upload_fk']);
253  if ($singleJobQueue['jq_type'] === 'monkbulk' ||
254  $singleJobQueue['jq_type'] === 'deciderjob') {
255  $noOfMonkBulk = $this->showJobsDao->getItemsProcessedForDecider(
256  'decider', $singleJobQueue['jq_job_fk']);
257  if (! empty($noOfMonkBulk)) {
258  $totalCountOfMb = $this->clearingDao->getPreviousBulkIds(
259  $noOfMonkBulk[1], Auth::getGroupId(), Auth::getUserId(),
260  $onlyCount = 1);
261  }
262  if (! empty($totalCountOfMb)) {
263  $jobArr['jobQueue'][$key]['isNoOfMonkBulk'] = $noOfMonkBulk[0] .
264  "/" . $totalCountOfMb;
265  }
266  }
267  }
268 
269  $jobArr['jobQueue'][$key]['canDoActions'] = ($_SESSION[Auth::USER_LEVEL] ==
270  PLUGIN_DB_ADMIN) || (Auth::getUserId() == $jobs['job']['job_user_fk']);
271  $jobArr['jobQueue'][$key]['isInProgress'] = ($singleJobQueue['jq_end_bits'] ==
272  0);
273  $jobArr['jobQueue'][$key]['isReady'] = ($singleJobQueue['jq_end_bits'] ==
274  1);
275 
276  switch ($singleJobQueue['jq_type']) {
277  case 'readmeoss':
278  $jobArr['jobQueue'][$key]['download'] = "ReadMeOss";
279  break;
280  case 'spdx2':
281  $jobArr['jobQueue'][$key]['download'] = "SPDX2 report";
282  break;
283  case 'spdx2tv':
284  $jobArr['jobQueue'][$key]['download'] = "SPDX2 tag/value report";
285  break;
286  case 'dep5':
287  $jobArr['jobQueue'][$key]['download'] = "DEP5 copyright file";
288  break;
289  case 'reportImport':
290  $jobArr['jobQueue'][$key]['download'] = "uploaded SPDX2 report";
291  break;
292  case 'unifiedreport':
293  $jobArr['jobQueue'][$key]['download'] = "Unified Report";
294  break;
295  default:
296  $jobArr['jobQueue'][$key]['download'] = "";
297  }
298  }
299  if (! empty($jobs['upload'])) {
300  $uploadArr = array(
301  'uploadName' => $jobs['upload']['upload_filename'],
302  'uploadId' => $jobs['upload']['upload_pk'],
303  'uploadDesc' => $jobs['upload']['upload_desc'],
304  'uploadItem' => empty($jobs['uploadtree']) ? -1 : $jobs['uploadtree']['uploadtree_pk'],
305  'uploadEta' => $this->showJobsDao->getEstimatedTime($jobs['job']['job_pk'], '', 0, $jobs['upload']['upload_pk'])
306  );
307  } else {
308  $uploadArr = null;
309  }
310  $returnData[] = array(
311  'job' => $jobArr,
312  'upload' => $uploadArr,
313  );
314  }
315  return $returnData;
316  } /* getShowJobsForEachJob() */
317 
323  protected function isUnfinishedJob($job)
324  {
325  foreach ($job['jobqueue'] as $jobqueueRec) {
326  if ($jobqueueRec['jq_end_bits'] === 0) {
327  return true;
328  }
329  }
330  return false;
331  }
332 
333  /* isUnfinishedJob() */
334 
339  protected function getClass($jobqueueRec)
340  {
341  if ($jobqueueRec['jq_end_bits'] > 1) {
342  return 'jobFailed';
343  } else if (! empty($jobqueueRec['jq_starttime']) &&
344  empty($jobqueueRec['jq_endtime'])) {
345  return 'jobScheduled';
346  } else if (!empty($jobqueueRec['jq_starttime']) && !empty($jobqueueRec['jq_endtime'])) {
347  return 'jobFinished';
348  } else {
349  return 'jobQueued';
350  }
351  }
352 
353 
361  protected function jobqueueStatus($jobqueueRec)
362  {
363  $status = "";
364 
365  /*
366  * check the jobqueue status. If the job is finished, return the status.
367  */
368  if (! empty($jobqueueRec['jq_endtext'])) {
369  $status .= "$jobqueueRec[jq_endtext]";
370  }
371 
372  if (! strstr($status, "Success") && ! strstr($status, "Fail") &&
373  $jobqueueRec["jq_end_bits"]) {
374  $status .= "<br>";
375  if ($jobqueueRec["jq_end_bits"] == 0x1) {
376  $status .= _("Success");
377  } else if ($jobqueueRec["jq_end_bits"] == 0x2) {
378  $status .= _("Failure");
379  } else if ($jobqueueRec["jq_end_bits"] == 0x4) {
380  $status .= _("Nonfatal");
381  }
382  }
383  return $status;
384  }
385 
386  /* jobqueueStatus() */
387 
392  protected function getJobs($uploadPk)
393  {
394  $page = GetParm('page', PARM_INTEGER);
395  $allusers = GetParm("allusers", PARM_INTEGER);
396  $uri = "?mod=showjobs";
397  if (!empty($allusers) && $allusers > 0) {
398  $uri .= "&allusers=$allusers";
399  }
400  if ($uploadPk > 0) {
401  $uri .= "&upload=$uploadPk";
402  }
403 
404  if (empty($allusers)) {
405  $allusers = 0;
406  }
407  $totalPages = 0;
408  if ($uploadPk > 0) {
409  $upload_pks = array($uploadPk);
410  list($jobs, $totalPages) = $this->showJobsDao->uploads2Jobs($upload_pks, $page);
411  } else {
412  list($jobs, $totalPages) = $this->showJobsDao->myJobs($allusers, $page);
413  }
414  $jobsInfo = $this->showJobsDao->getJobInfo($jobs);
415  usort($jobsInfo, array($this,"compareJobsInfo"));
416 
417  $pagination = ($totalPages > 1 ? MenuPage($page, $totalPages, $uri) : "");
418 
419  $showJobData = $this->getShowJobsForEachJob($jobsInfo);
420  return new JsonResponse(
421  array(
422  'showJobsData' => $showJobData,
423  'pagination' => $pagination
424  ));
425  } /* getJobs()*/
426 
427  public function Output()
428  {
429  if ($this->State != PLUGIN_STATE_READY) {
430  return 0;
431  }
432  $output = $this->jsonContent();
433  if (!$this->OutputToStdout) {
434  return;
435  }
436  return $output;
437  }
438 
439  protected function jsonContent()
440  {
441  $action = GetParm("do", PARM_STRING);
442  switch ($action) {
443  case "showjb":
444  $uploadPk = GetParm('upload', PARM_INTEGER);
445  if (! empty($uploadPk)) {
446  return $this->getJobs($uploadPk);
447  }
448  break;
449  case "showSingleJob":
450  $job_pk1 = GetParm('jobId', PARM_INTEGER);
451  return $this->getGeekyScanDetailsForJob($job_pk1);
452  }
453  }
454 }
455 
456 $NewPlugin = new AjaxShowJobs();
Traceback_uri()
Get the URI without query to this location.
static getUserId()
Get the current user&#39;s id.
Definition: Auth.php:69
getClass($jobqueueRec)
array $jobqueueRec get the jobqueue row color
#define PLUGIN_DB_ADMIN
Plugin requires admin level permission on DB.
Definition: libfossology.h:51
Convert2BrowserTime($server_time)
Convert the server time to browser time.
Definition: common-ui.php:298
isUnfinishedJob($job)
Are there any unfinished jobqueues in this job?
MenuPage($Page, $TotalPage, $Uri= '')
Create a "First Prev 1 2 ... Next Last" page links for paged output.
Definition: common-menu.php:71
getJobs($uploadPk)
get data of all jobs using uploadpk
compareJobsInfo($JobsInfo1, $JobsInfo2)
Sort compare function to order $JobsInfo by job_pk.
jobqueueStatus($jobqueueRec)
Get the status of a jobqueue item If the job isn&#39;t known to the scheduler, then report the status bas...
getShowJobsForEachJob($jobData)
Returns an upload job status in array.
getGeekyScanDetailsForJob($job_pk)
Returns geeky scan details about the jobqueue item.
Provide data for jobs table.
Definition: state.hpp:26
GetParm($parameterName, $parameterType)
This function will retrieve the variables and check data types.
Definition: common-parm.php:57
const PARM_STRING
Definition: common-parm.php:29
#define PLUGIN_DB_WRITE
Plugin requires write permission on DB.
Definition: libfossology.h:50
const PARM_INTEGER
Definition: common-parm.php:25
fo_dbManager * dbManager
fo_dbManager object
Definition: process.c:28
This is the Plugin class. All plugins should:
Definition: FO_Plugin.php:67
list_t type structure used to keep various lists. (e.g. there are multiple lists).
Definition: nomos.h:321
static getGroupId()
Get the current user&#39;s group id.
Definition: Auth.php:78