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 
212  public function getShowJobsForEachJob($jobData)
213  {
214  if (count($jobData) == 0) {
215  return array('showJobsData' => "There are no jobs to display");
216  }
217  $returnData = [];
218  foreach ($jobData as $jobId => $jobs) {
219  $jobArr = array(
220  'jobId' => $jobs['job']['job_pk'],
221  'jobName' => $jobs['job']['job_name'],
222  'jobQueue' => $jobs['jobqueue']
223  );
224  foreach ($jobArr['jobQueue'] as $key => $singleJobQueue) {
225  if (! empty($jobArr['jobQueue'][$key]['jq_starttime'])) {
226  $jobArr['jobQueue'][$key]['jq_starttime'] = Convert2BrowserTime(
227  $jobArr['jobQueue'][$key]['jq_starttime']);
228  }
229  if (! empty($jobArr['jobQueue'][$key]['jq_endtime'])) {
230  $jobArr['jobQueue'][$key]['jq_endtime'] = Convert2BrowserTime(
231  $jobArr['jobQueue'][$key]['jq_endtime']) ;
232  }
233  if (! empty($singleJobQueue["jq_endtime"])) {
234  $numSecs = strtotime($singleJobQueue['jq_endtime']) -
235  strtotime($singleJobQueue['jq_starttime']);
236  $numSecs = ($numSecs == 0) ? 1 : $numSecs; // If difference is in milliseconds
237  } else {
238  $numSecs = time() - strtotime($singleJobQueue['jq_starttime']);
239  }
240 
241  $jobArr['jobQueue'][$key]['itemsPerSec'] = $itemsPerSec = 0;
242  if ($singleJobQueue['jq_starttime']) {
243  $itemsPerSec = $this->showJobsDao->getNumItemsPerSec(
244  $singleJobQueue['jq_itemsprocessed'], $numSecs);
245  $jobArr['jobQueue'][$key]['itemsPerSec'] = $itemsPerSec;
246  }
247  if (empty($singleJobQueue['jq_endtime'])) {
248  $jobArr['jobQueue'][$key]['eta'] = $this->showJobsDao->getEstimatedTime(
249  $singleJobQueue['jq_job_fk'], $singleJobQueue['jq_type'],
250  $itemsPerSec, $jobs['job']['job_upload_fk']);
251  if ($singleJobQueue['jq_type'] === 'monkbulk' ||
252  $singleJobQueue['jq_type'] === 'deciderjob') {
253  $noOfMonkBulk = $this->showJobsDao->getItemsProcessedForDecider(
254  'decider', $singleJobQueue['jq_job_fk']);
255  if (! empty($noOfMonkBulk)) {
256  $totalCountOfMb = $this->clearingDao->getPreviousBulkIds(
257  $noOfMonkBulk[1], Auth::getGroupId(), Auth::getUserId(),
258  $onlyCount = 1);
259  }
260  if (! empty($totalCountOfMb)) {
261  $jobArr['jobQueue'][$key]['isNoOfMonkBulk'] = $noOfMonkBulk[0] .
262  "/" . $totalCountOfMb;
263  }
264  }
265  }
266 
267  $jobArr['jobQueue'][$key]['canDoActions'] = ($_SESSION[Auth::USER_LEVEL] ==
268  PLUGIN_DB_ADMIN) || (Auth::getUserId() == $jobs['job']['job_user_fk']);
269  $jobArr['jobQueue'][$key]['isInProgress'] = ($singleJobQueue['jq_end_bits'] ==
270  0);
271  $jobArr['jobQueue'][$key]['isReady'] = ($singleJobQueue['jq_end_bits'] ==
272  1);
273 
274  switch ($singleJobQueue['jq_type']) {
275  case 'readmeoss':
276  $jobArr['jobQueue'][$key]['download'] = "ReadMeOss";
277  break;
278  case 'spdx2':
279  $jobArr['jobQueue'][$key]['download'] = "SPDX2 report";
280  break;
281  case 'spdx2tv':
282  $jobArr['jobQueue'][$key]['download'] = "SPDX2 tag/value report";
283  break;
284  case 'spdx2csv':
285  $jobArr['jobQueue'][$key]['download'] = "SPDX2 CSV report";
286  break;
287  case 'dep5':
288  $jobArr['jobQueue'][$key]['download'] = "DEP5 copyright file";
289  break;
290  case 'reportImport':
291  $jobArr['jobQueue'][$key]['download'] = "uploaded SPDX2 report";
292  break;
293  case 'unifiedreport':
294  $jobArr['jobQueue'][$key]['download'] = "Unified Report";
295  break;
296  case 'clixml':
297  $jobArr['jobQueue'][$key]['download'] = "Clixml Report";
298  break;
299  case 'cyclonedx':
300  $jobArr['jobQueue'][$key]['download'] = "CycloneDX json Report";
301  break;
302  case 'decisionexporter':
303  $jobArr['jobQueue'][$key]['download'] = "FOSSology Decisions";
304  break;
305  default:
306  $jobArr['jobQueue'][$key]['download'] = "";
307  }
308  }
309  if (! empty($jobs['upload'])) {
310  $uploadArr = array(
311  'uploadName' => $jobs['upload']['upload_filename'],
312  'uploadId' => $jobs['upload']['upload_pk'],
313  'uploadDesc' => $jobs['upload']['upload_desc'],
314  'uploadItem' => empty($jobs['uploadtree']) ? -1 : $jobs['uploadtree']['uploadtree_pk'],
315  'uploadEta' => $this->showJobsDao->getEstimatedTime($jobs['job']['job_pk'], '', 0, $jobs['upload']['upload_pk'])
316  );
317  } else {
318  $uploadArr = null;
319  }
320  $returnData[] = array(
321  'job' => $jobArr,
322  'upload' => $uploadArr,
323  );
324  }
325  return $returnData;
326  } /* getShowJobsForEachJob() */
327 
333  protected function isUnfinishedJob($job)
334  {
335  foreach ($job['jobqueue'] as $jobqueueRec) {
336  if ($jobqueueRec['jq_end_bits'] === 0) {
337  return true;
338  }
339  }
340  return false;
341  }
342 
343  /* isUnfinishedJob() */
344 
349  protected function getClass($jobqueueRec)
350  {
351  if ($jobqueueRec['jq_end_bits'] > 1) {
352  return 'jobFailed';
353  } else if (! empty($jobqueueRec['jq_starttime']) &&
354  empty($jobqueueRec['jq_endtime'])) {
355  return 'jobScheduled';
356  } else if (!empty($jobqueueRec['jq_starttime']) && !empty($jobqueueRec['jq_endtime'])) {
357  return 'jobFinished';
358  } else {
359  return 'jobQueued';
360  }
361  }
362 
363 
371  protected function jobqueueStatus($jobqueueRec)
372  {
373  $status = "";
374 
375  /*
376  * check the jobqueue status. If the job is finished, return the status.
377  */
378  if (! empty($jobqueueRec['jq_endtext'])) {
379  $status .= "$jobqueueRec[jq_endtext]";
380  }
381 
382  if (! strstr($status, "Success") && ! strstr($status, "Fail") &&
383  $jobqueueRec["jq_end_bits"]) {
384  $status .= "<br>";
385  if ($jobqueueRec["jq_end_bits"] == 0x1) {
386  $status .= _("Success");
387  } else if ($jobqueueRec["jq_end_bits"] == 0x2) {
388  $status .= _("Failure");
389  } else if ($jobqueueRec["jq_end_bits"] == 0x4) {
390  $status .= _("Nonfatal");
391  }
392  }
393  return $status;
394  }
395 
396  /* jobqueueStatus() */
397 
402  protected function getJobs($uploadPk)
403  {
404  $page = GetParm('page', PARM_INTEGER);
405  $allusers = GetParm("allusers", PARM_INTEGER);
406  $uri = "?mod=showjobs";
407  if (!empty($allusers) && $allusers > 0) {
408  $uri .= "&allusers=$allusers";
409  }
410  if ($uploadPk > 0) {
411  $uri .= "&upload=$uploadPk";
412  }
413 
414  if (empty($allusers)) {
415  $allusers = 0;
416  }
417  $totalPages = 0;
418  if ($uploadPk > 0) {
419  $upload_pks = array($uploadPk);
420  list($jobs, $totalPages) = $this->showJobsDao->uploads2Jobs($upload_pks, $page);
421  } else {
422  list($jobs, $totalPages) = $this->showJobsDao->myJobs($allusers, $page);
423  }
424  $jobsInfo = $this->showJobsDao->getJobInfo($jobs);
425  usort($jobsInfo, array($this,"compareJobsInfo"));
426 
427  $pagination = ($totalPages > 1 ? MenuPage($page, $totalPages, $uri) : "");
428 
429  $showJobData = $this->getShowJobsForEachJob($jobsInfo);
430  return new JsonResponse(
431  array(
432  'showJobsData' => $showJobData,
433  'pagination' => $pagination
434  ));
435  } /* getJobs()*/
436 
437  public function Output()
438  {
439  if ($this->State != PLUGIN_STATE_READY) {
440  return 0;
441  }
442  $output = $this->jsonContent();
443  if (!$this->OutputToStdout) {
444  return;
445  }
446  return $output;
447  }
448 
449  protected function jsonContent()
450  {
451  $action = GetParm("do", PARM_STRING);
452  switch ($action) {
453  case "showjb":
454  $uploadPk = GetParm('upload', PARM_INTEGER);
455  if (! empty($uploadPk)) {
456  return $this->getJobs($uploadPk);
457  }
458  break;
459  case "showSingleJob":
460  $job_pk1 = GetParm('jobId', PARM_INTEGER);
461  return $this->getGeekyScanDetailsForJob($job_pk1);
462  }
463  }
464 }
465 
466 $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.
OutputOpen()
This function is called when user output is requested. This function is responsible for assigning hea...
getShowJobsForEachJob($jobData)
Returns an upload job status in array.
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