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  $reportName = "";
278  if ($this->showJobsDao->isJobIdPresentInReportGen($singleJobQueue['jq_job_fk'])) {
279  switch ($singleJobQueue['jq_type']) {
280  case 'readmeoss':
281  $reportName = "ReadMeOss";
282  break;
283  case 'spdx2':
284  $reportName = "SPDX2 report";
285  break;
286  case 'spdx2tv':
287  $reportName = "SPDX2 tag/value report";
288  break;
289  case 'spdx2csv':
290  $reportName = "SPDX2 CSV report";
291  break;
292  case 'dep5':
293  $reportName = "DEP5 copyright file";
294  break;
295  case 'reportImport':
296  $reportName = "uploaded SPDX2 report";
297  break;
298  case 'unifiedreport':
299  $reportName = "Unified Report";
300  break;
301  case 'clixml':
302  $reportName = "Clixml Report";
303  break;
304  case 'cyclonedx':
305  $reportName = "CycloneDX json Report";
306  break;
307  case 'decisionexporter':
308  $reportName = "FOSSology Decisions";
309  break;
310  }
311  }
312  $jobArr['jobQueue'][$key]['download'] = $reportName;
313  }
314  if (! empty($jobs['upload'])) {
315  $uploadArr = array(
316  'uploadName' => $jobs['upload']['upload_filename'],
317  'uploadId' => $jobs['upload']['upload_pk'],
318  'uploadDesc' => $jobs['upload']['upload_desc'],
319  'uploadItem' => empty($jobs['uploadtree']) ? -1 : $jobs['uploadtree']['uploadtree_pk'],
320  'uploadEta' => $this->showJobsDao->getEstimatedTime($jobs['job']['job_pk'], '', 0, $jobs['upload']['upload_pk'])
321  );
322  } else {
323  $uploadArr = null;
324  }
325  $returnData[] = array(
326  'job' => $jobArr,
327  'upload' => $uploadArr,
328  );
329  }
330  return $returnData;
331  } /* getShowJobsForEachJob() */
332 
338  protected function isUnfinishedJob($job)
339  {
340  foreach ($job['jobqueue'] as $jobqueueRec) {
341  if ($jobqueueRec['jq_end_bits'] === 0) {
342  return true;
343  }
344  }
345  return false;
346  }
347 
348  /* isUnfinishedJob() */
349 
354  protected function getClass($jobqueueRec)
355  {
356  if ($jobqueueRec['jq_end_bits'] > 1) {
357  return 'jobFailed';
358  } else if (! empty($jobqueueRec['jq_starttime']) &&
359  empty($jobqueueRec['jq_endtime'])) {
360  return 'jobScheduled';
361  } else if (!empty($jobqueueRec['jq_starttime']) && !empty($jobqueueRec['jq_endtime'])) {
362  return 'jobFinished';
363  } else {
364  return 'jobQueued';
365  }
366  }
367 
368 
376  protected function jobqueueStatus($jobqueueRec)
377  {
378  $status = "";
379 
380  /*
381  * check the jobqueue status. If the job is finished, return the status.
382  */
383  if (! empty($jobqueueRec['jq_endtext'])) {
384  $status .= "$jobqueueRec[jq_endtext]";
385  }
386 
387  if (! strstr($status, "Success") && ! strstr($status, "Fail") &&
388  $jobqueueRec["jq_end_bits"]) {
389  $status .= "<br>";
390  if ($jobqueueRec["jq_end_bits"] == 0x1) {
391  $status .= _("Success");
392  } else if ($jobqueueRec["jq_end_bits"] == 0x2) {
393  $status .= _("Failure");
394  } else if ($jobqueueRec["jq_end_bits"] == 0x4) {
395  $status .= _("Nonfatal");
396  }
397  }
398  return $status;
399  }
400 
401  /* jobqueueStatus() */
402 
407  protected function getJobs($uploadPk)
408  {
409  $page = GetParm('page', PARM_INTEGER);
410  $allusers = GetParm("allusers", PARM_INTEGER);
411  $uri = "?mod=showjobs";
412  if (!empty($allusers) && $allusers > 0) {
413  $uri .= "&allusers=$allusers";
414  }
415  if ($uploadPk > 0) {
416  $uri .= "&upload=$uploadPk";
417  }
418 
419  if (empty($allusers)) {
420  $allusers = 0;
421  }
422  $totalPages = 0;
423  if ($uploadPk > 0) {
424  $upload_pks = array($uploadPk);
425  list($jobs, $totalPages) = $this->showJobsDao->uploads2Jobs($upload_pks, $page);
426  } else {
427  list($jobs, $totalPages) = $this->showJobsDao->myJobs($allusers, $page);
428  }
429  $jobsInfo = $this->showJobsDao->getJobInfo($jobs);
430  usort($jobsInfo, array($this,"compareJobsInfo"));
431 
432  $pagination = ($totalPages > 1 ? MenuPage($page, $totalPages, $uri) : "");
433 
434  $showJobData = $this->getShowJobsForEachJob($jobsInfo, false);
435  return new JsonResponse(
436  array(
437  'showJobsData' => $showJobData,
438  'pagination' => $pagination
439  ));
440  } /* getJobs()*/
441 
442  public function Output()
443  {
444  if ($this->State != PLUGIN_STATE_READY) {
445  return 0;
446  }
447  $output = $this->jsonContent();
448  if (!$this->OutputToStdout) {
449  return;
450  }
451  return $output;
452  }
453 
454  protected function jsonContent()
455  {
456  $action = GetParm("do", PARM_STRING);
457  switch ($action) {
458  case "showjb":
459  $uploadPk = GetParm('upload', PARM_INTEGER);
460  if (! empty($uploadPk)) {
461  return $this->getJobs($uploadPk);
462  }
463  break;
464  case "showSingleJob":
465  $job_pk1 = GetParm('jobId', PARM_INTEGER);
466  return $this->getGeekyScanDetailsForJob($job_pk1);
467  }
468  }
469 }
470 
471 $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