FOSSology  4.7.1
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  SPDX-FileCopyrightText: © Fossology contributors
7  Author: Shaheem Azmal<shaheem.azmal@siemens.com>,
8  Anupam Ghosh <anupam.ghosh@siemens.com>
9 
10  SPDX-License-Identifier: GPL-2.0-only
11 */
12 
17 namespace Fossology\UI\Ajax;
18 
24 use Symfony\Component\HttpFoundation\JsonResponse;
25 
26 define("TITLE_AJAXSHOWJOBS", _("ShowJobs"));
27 
34 class AjaxShowJobs extends \FO_Plugin
35 {
36  const MAX_LOG_OUTPUT = 32768;
37 
39  private $dbManager;
40 
42  private $showJobsDao;
43 
45  private $userDao;
46 
48  private $clearingDao;
49 
50  function __construct()
51  {
52  $this->Name = "ajaxShowJobs";
53  $this->Title = TITLE_AJAXSHOWJOBS;
54  $this->DBaccess = PLUGIN_DB_WRITE;
55  $this->LoginFlag = 0;
56  $this->NoMenu = 0;
57  $this->OutputType = 'JSON';
58  $this->OutputToStdout = true;
59 
60  global $container;
61  $this->showJobsDao = $container->get('dao.show_jobs');
62  $this->userDao = $container->get('dao.user');
63  $this->clearingDao = $container->get('dao.clearing');
64  $this->dbManager = $container->get('db.manager');
65 
66  parent::__construct();
67  }
68 
69  function OutputOpen()
70  {
71  if ($this->State != PLUGIN_STATE_READY) {
72  return null;
73  }
74  $uploadId = GetParm("upload", PARM_INTEGER);
75  if (empty($uploadId)) {
76  return null;
77  }
78  }
79 
86  protected function compareJobsInfo($JobsInfo1, $JobsInfo2)
87  {
88  $job_pk1 = $JobsInfo1["job"]["job_pk"];
89  $job_pk2 = $JobsInfo2["job"]["job_pk"];
90 
91  return $job_pk2 - $job_pk1;
92  }
93 
99  protected function getGeekyScanDetailsForJob($job_pk)
100  {
101  $i=0;
102  $fields=array('jq_pk'=>'jq_pk',
103  'job_pk'=>'jq_job_fk',
104  'Job Name'=> 'job_name',
105  'Agent Name'=>'jq_type',
106  'Priority'=>'job_priority',
107  'Args'=>'jq_args',
108  'jq_runonpfile'=>'jq_runonpfile',
109  'Queued'=>'job_queued',
110  'Started'=>'jq_starttime',
111  'Ended'=>'jq_endtime',
112  'Elapsed HH:MM:SS'=>'elapsed',
113  'Status'=>'jq_end_bits',
114  'Items processed'=>'jq_itemsprocessed',
115  'Submitter'=>'job_user_fk',
116  'Upload'=>'job_upload_fk',
117  'Log'=>'jq_log');
118  $uri = Traceback_uri() . "?mod=showjobs&upload=";
119 
120  $row = $this->showJobsDao->getDataForASingleJob($job_pk);
121 
122  $table = array();
123  foreach ($fields as $labelKey=>$field) {
124  $value ="";
125  $label = $labelKey;
126  switch ($field) {
127  case 'job_queued':
128  case 'jq_starttime':
129  case 'jq_endtime':
130  if (! empty($row[$field])) {
131  $value = Convert2BrowserTime($row[$field]);
132  }
133  break;
134  case 'jq_itemsprocessed':
135  $value = number_format($row[$field]);
136  break;
137  case 'jq_end_bits':
138  $value = $this->jobqueueStatus($row);
139  break;
140  case 'jq_pk':
141  if (!empty($row['job_upload_fk'])) {
142  $value = "<a href='$uri" . $row['job_upload_fk'] . "'>" . htmlentities($row[$field]) . "</a>"." (" . _("Click to view jobs for this upload") . ")";
143  } else {
144  $uri2 = Traceback_uri() . "?mod=showjobs";
145  $back = "(" . _("Click to return to Show Jobs") . ")";
146  $value = "<a href='$uri2'>$row[$field] $back</a>";
147  }
148  break;
149  case 'job_upload_fk':
150  if (!empty($row[$field])) {
151  $browse = Traceback_uri() . "?mod=browse&upload=" . htmlentities($row[$field]);
152  $value = "<a href='$browse'>" . htmlentities($row[$field]) . "</a>"." (" . _("Click to browse upload") . ")";
153  }
154  break;
155  case 'jq_log':
156  if (empty($row[$field]) || $row[$field] == 'removed' || !file_exists($row[$field])) {
157  break;
158  }
159  if (filesize($row[$field]) > self::MAX_LOG_OUTPUT) {
160  $value = "<pre>" .file_get_contents($row[$field],false,null,-1,self::MAX_LOG_OUTPUT)."</pre>"
161  .'<a href="'.Traceback_uri() . '?mod=download&log=' . $row['jq_pk'] . '">Download full log</a>';
162  } else {
163  $value = "<pre>" . file_get_contents($row[$field]). "</pre>";
164  }
165  break;
166  case 'job_user_fk':
167  if (!empty($row[$field])) {
168  $value = $this->userDao->getUserName($row[$field]);
169  }
170  break;
171  case 'jq_args':
172  $jq_args_temp = $row[$field];
173  $jq_args_show = $jq_args_temp;
174  if (! empty($jq_args_temp)) {
175  $pos = strpos($jq_args_temp, ' SVN ');
176  if ($pos) {
177  $jq_args_show = substr($jq_args_temp, 0, $pos + 4);
178  }
179  $pos = strpos($jq_args_temp, ' CVS ');
180  if ($pos) {
181  $jq_args_show = substr($jq_args_temp, 0, $pos + 4);
182  }
183  $pos = strpos($jq_args_temp, ' Git ');
184  if ($pos) {
185  $jq_args_show = substr($jq_args_temp, 0, $pos + 4);
186  }
187  $value = $jq_args_show;
188  }
189  break;
190  default:
191  if (array_key_exists($field, $row)) {
192  $value = htmlentities($row[$field]);
193  }
194  break;
195  }
196  $table[] = array('DT_RowId' => $i++,
197  '0'=>$label,
198  '1'=> $value);
199  }
200  $tableData = array_values($table);
201  return new JsonResponse(array('sEcho' => intval($_GET['sEcho']),
202  'aaData' => $tableData,
203  'iTotalRecords' => count($tableData),
204  'iTotalDisplayRecords' => count($tableData)));
205 
206  } /* getGeekyScanDetailsForJob() */
207 
214  public function getShowJobsForEachJob($jobData, $forApi = false)
215  {
216  if (count($jobData) == 0) {
217  return array('showJobsData' => "There are no jobs to display");
218  }
219  $returnData = [];
220  foreach ($jobData as $jobId => $jobs) {
221  $jobArr = array(
222  'jobId' => $jobs['job']['job_pk'],
223  'jobName' => $jobs['job']['job_name'],
224  'jobQueue' => $jobs['jobqueue']
225  );
226  foreach ($jobArr['jobQueue'] as $key => $singleJobQueue) {
227  if (! $forApi) {
228  if (! empty($jobArr['jobQueue'][$key]['jq_starttime'])) {
229  $jobArr['jobQueue'][$key]['jq_starttime'] = Convert2BrowserTime(
230  $jobArr['jobQueue'][$key]['jq_starttime']);
231  }
232  if (! empty($jobArr['jobQueue'][$key]['jq_endtime'])) {
233  $jobArr['jobQueue'][$key]['jq_endtime'] = Convert2BrowserTime(
234  $jobArr['jobQueue'][$key]['jq_endtime']) ;
235  }
236  }
237  if (! empty($singleJobQueue["jq_endtime"])) {
238  $numSecs = strtotime($singleJobQueue['jq_endtime']) -
239  strtotime($singleJobQueue['jq_starttime']);
240  $numSecs = ($numSecs == 0) ? 1 : $numSecs; // If difference is in milliseconds
241  } else {
242  $numSecs = time() - strtotime($singleJobQueue['jq_starttime']);
243  }
244 
245  $jobArr['jobQueue'][$key]['itemsPerSec'] = $itemsPerSec = 0;
246  if ($singleJobQueue['jq_starttime']) {
247  $itemsPerSec = $this->showJobsDao->getNumItemsPerSec(
248  $singleJobQueue['jq_itemsprocessed'], $numSecs);
249  $jobArr['jobQueue'][$key]['itemsPerSec'] = $itemsPerSec;
250  }
251  if (empty($singleJobQueue['jq_endtime'])) {
252  $jobArr['jobQueue'][$key]['eta'] = $this->showJobsDao->getEstimatedTime(
253  $singleJobQueue['jq_job_fk'], $singleJobQueue['jq_type'],
254  $itemsPerSec, $jobs['job']['job_upload_fk']);
255  if ($singleJobQueue['jq_type'] === 'monkbulk' ||
256  $singleJobQueue['jq_type'] === 'deciderjob') {
257  $noOfMonkBulk = $this->showJobsDao->getItemsProcessedForDecider(
258  'decider', $singleJobQueue['jq_job_fk']);
259  if (! empty($noOfMonkBulk)) {
260  $totalCountOfMb = $this->clearingDao->getPreviousBulkIds(
261  $noOfMonkBulk[1], Auth::getGroupId(), Auth::getUserId(),
262  $onlyCount = 1);
263  }
264  if (! empty($totalCountOfMb)) {
265  $jobArr['jobQueue'][$key]['isNoOfMonkBulk'] = $noOfMonkBulk[0] .
266  "/" . $totalCountOfMb;
267  }
268  }
269  }
270 
271  $jobArr['jobQueue'][$key]['canDoActions'] = ($_SESSION[Auth::USER_LEVEL] ==
272  PLUGIN_DB_ADMIN) || (Auth::getUserId() == $jobs['job']['job_user_fk']);
273  $jobArr['jobQueue'][$key]['isInProgress'] = ($singleJobQueue['jq_end_bits'] ==
274  0);
275  $jobArr['jobQueue'][$key]['isReady'] = ($singleJobQueue['jq_end_bits'] ==
276  1);
277 
278  $reportName = "";
279  if ($this->showJobsDao->isJobIdPresentInReportGen($singleJobQueue['jq_job_fk'])) {
280  switch ($singleJobQueue['jq_type']) {
281  case 'readmeoss':
282  $reportName = "ReadMeOss";
283  break;
284  case 'spdx2':
285  $reportName = "SPDX2 report";
286  break;
287  case 'spdx2tv':
288  $reportName = "SPDX2 tag/value report";
289  break;
290  case 'spdx2csv':
291  $reportName = "SPDX2 CSV report";
292  break;
293  case 'spdx3jsonld':
294  $reportName = "SPDX3 JSON-LD report";
295  break;
296  case 'spdx3json':
297  $reportName = "SPDX3 JSON report";
298  break;
299  case 'spdx3rdf':
300  $reportName = "SPDX3 RDF report";
301  break;
302  case 'spdx3tv':
303  $reportName = "SPDX3 tag/value report";
304  break;
305  case 'dep5':
306  $reportName = "DEP5 copyright file";
307  break;
308  case 'reportImport':
309  $reportName = "uploaded SPDX2 report";
310  break;
311  case 'unifiedreport':
312  $reportName = "Unified Report";
313  break;
314  case 'clixml':
315  $reportName = "Clixml Report";
316  break;
317  case 'cyclonedx':
318  $reportName = "CycloneDX json Report";
319  break;
320  case 'decisionexporter':
321  $reportName = "FOSSology Decisions";
322  break;
323  }
324  }
325  $jobArr['jobQueue'][$key]['download'] = $reportName;
326  }
327  if (! empty($jobs['upload'])) {
328  $uploadArr = array(
329  'uploadName' => $jobs['upload']['upload_filename'],
330  'uploadId' => $jobs['upload']['upload_pk'],
331  'uploadDesc' => $jobs['upload']['upload_desc'],
332  'uploadItem' => empty($jobs['uploadtree']) ? -1 : $jobs['uploadtree']['uploadtree_pk'],
333  'uploadEta' => $this->showJobsDao->getEstimatedTime($jobs['job']['job_pk'], '', 0, $jobs['upload']['upload_pk'])
334  );
335  } else {
336  $uploadArr = null;
337  }
338  $returnData[] = array(
339  'job' => $jobArr,
340  'upload' => $uploadArr,
341  );
342  }
343  return $returnData;
344  } /* getShowJobsForEachJob() */
345 
351  protected function isUnfinishedJob($job)
352  {
353  foreach ($job['jobqueue'] as $jobqueueRec) {
354  if ($jobqueueRec['jq_end_bits'] === 0) {
355  return true;
356  }
357  }
358  return false;
359  }
360 
361  /* isUnfinishedJob() */
362 
367  protected function getClass($jobqueueRec)
368  {
369  if ($jobqueueRec['jq_end_bits'] > 1) {
370  return 'jobFailed';
371  } else if (! empty($jobqueueRec['jq_starttime']) &&
372  empty($jobqueueRec['jq_endtime'])) {
373  return 'jobScheduled';
374  } else if (!empty($jobqueueRec['jq_starttime']) && !empty($jobqueueRec['jq_endtime'])) {
375  return 'jobFinished';
376  } else {
377  return 'jobQueued';
378  }
379  }
380 
381 
389  protected function jobqueueStatus($jobqueueRec)
390  {
391  $status = "";
392 
393  /*
394  * check the jobqueue status. If the job is finished, return the status.
395  */
396  if (! empty($jobqueueRec['jq_endtext'])) {
397  $status .= "$jobqueueRec[jq_endtext]";
398  }
399 
400  if (! strstr($status, "Success") && ! strstr($status, "Fail") &&
401  $jobqueueRec["jq_end_bits"]) {
402  $status .= "<br>";
403  if ($jobqueueRec["jq_end_bits"] == 0x1) {
404  $status .= _("Success");
405  } else if ($jobqueueRec["jq_end_bits"] == 0x2) {
406  $status .= _("Failure");
407  } else if ($jobqueueRec["jq_end_bits"] == 0x4) {
408  $status .= _("Nonfatal");
409  }
410  }
411  return $status;
412  }
413 
414  /* jobqueueStatus() */
415 
420  protected function getJobs($uploadPk)
421  {
422  $page = GetParm('page', PARM_INTEGER);
423  $allusers = GetParm("allusers", PARM_INTEGER);
424  $uri = "?mod=showjobs";
425  if (!empty($allusers) && $allusers > 0) {
426  $uri .= "&allusers=$allusers";
427  }
428  if ($uploadPk > 0) {
429  $uri .= "&upload=$uploadPk";
430  }
431 
432  if (empty($allusers)) {
433  $allusers = 0;
434  }
435  $totalPages = 0;
436  if ($uploadPk > 0) {
437  $upload_pks = array($uploadPk);
438  list($jobs, $totalPages) = $this->showJobsDao->uploads2Jobs($upload_pks, $page);
439  } else {
440  list($jobs, $totalPages) = $this->showJobsDao->myJobs($allusers, $page);
441  }
442  $jobsInfo = $this->showJobsDao->getJobInfo($jobs);
443  usort($jobsInfo, array($this,"compareJobsInfo"));
444 
445  $pagination = ($totalPages > 0 ? MenuPage($page, $totalPages, $uri) : "");
446 
447  $showJobData = $this->getShowJobsForEachJob($jobsInfo, false);
448  return new JsonResponse(
449  array(
450  'showJobsData' => $showJobData,
451  'pagination' => $pagination
452  ));
453  } /* getJobs()*/
454 
455  public function Output()
456  {
457  if ($this->State != PLUGIN_STATE_READY) {
458  return 0;
459  }
460  $output = $this->jsonContent();
461  if (!$this->OutputToStdout) {
462  return;
463  }
464  return $output;
465  }
466 
467  protected function jsonContent()
468  {
469  $action = GetParm("do", PARM_STRING);
470  switch ($action) {
471  case "showjb":
472  $uploadPk = GetParm('upload', PARM_INTEGER);
473  if (! empty($uploadPk)) {
474  return $this->getJobs($uploadPk);
475  }
476  break;
477  case "showSingleJob":
478  $job_pk1 = GetParm('jobId', PARM_INTEGER);
479  return $this->getGeekyScanDetailsForJob($job_pk1);
480  }
481  }
482 }
483 
484 $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