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