FOSSology  4.4.0
Open Source License Compliance by Open Source Software
oneshot.php
1 <?php
2 /*
3  SPDX-FileCopyrightText: © 2014 Siemens AG
4 
5  SPDX-License-Identifier: GPL-2.0-only
6 */
7 
8 
9 namespace Fossology\Monk\UI;
10 
20 use Symfony\Component\HttpFoundation\File\UploadedFile;
21 use Symfony\Component\HttpFoundation\Request;
22 use Symfony\Component\HttpFoundation\Response;
23 
24 class OneShot extends DefaultPlugin
25 {
26  const NAME = "oneshot-monk";
27 
29  private $highlightProcessor;
31  private $highlightRenderer;
33  private $textRenderer;
34 
35  function __construct()
36  {
37  parent::__construct(self::NAME, array(
38  self::TITLE => "One-Shot Monk",
39  self::MENU_LIST => "Upload::One-Shot Monk Analysis",
40  self::PERMISSION => Auth::PERM_WRITE,
41  self::REQUIRES_LOGIN => true
42  ));
43 
44  $this->highlightProcessor = $this->getObject('view.highlight_processor');
45  $this->highlightRenderer = $this->getObject('view.highlight_renderer');
46  $this->textRenderer = $this->getObject('view.text_renderer');
47  }
48 
53  protected function handle(Request $request)
54  {
56  $uploadFile = $request->files->get('file_input');
57  if ($uploadFile === null) {
58  return $this->render('oneshot-upload.html.twig', $this->getDefaultVars());
59  }
60  $fullpath = $uploadFile->getPath().'/'.$uploadFile->getFilename();
61 
62  list($licenseIds, $rendered) = $this->scanMonkFileRendered($fullpath);
63  $vars = $this->mergeWithDefault(array('content' => $this->renderLicenseList($licenseIds).$rendered));
64  $vars['styles'] .= "<link rel='stylesheet' href='css/highlights.css'>\n";
65  return $this->render('include/base.html.twig', $vars);
66  }
67 
68  public function scanMonkRendered($text, $fromRest = false)
69  {
70  $tmpFileName = tempnam("/tmp", "monk");
71  if (!$tmpFileName) {
72  throw new \Exception("cannot create temporary file");
73  }
74  $handle = fopen($tmpFileName, "w");
75  fwrite($handle, $text);
76  fclose($handle);
77  list($licenseIds, $highlights) = $this->scanMonk($tmpFileName);
78  unlink($tmpFileName);
79 
80  $this->highlightProcessor->addReferenceTexts($highlights);
81  if ($fromRest) {
82  return array($licenseIds, $highlights);
83  }
84 
85  $splitPositions = $this->highlightProcessor->calculateSplitPositions($highlights);
86  $textFragment = new TextFragment(0, $text);
87 
88  $rendered = $this->textRenderer->renderText($textFragment, $splitPositions);
89  return array($licenseIds, $rendered);
90  }
91 
92 
93  public function scanMonkFileRendered($tmpfname)
94  {
95  list($licenseIds, $highlights) = $this->scanMonk($tmpfname);
96 
97  $text = file_get_contents($tmpfname);
98 
99  $this->highlightProcessor->addReferenceTexts($highlights);
100  $splitPositions = $this->highlightProcessor->calculateSplitPositions($highlights);
101  $textFragment = new TextFragment(0, $text);
102 
103  $rendered = $this->textRenderer->renderText($textFragment, $splitPositions);
104 
105  return array($licenseIds, $rendered);
106  }
107 
108 
109  public function scanMonk($fileName)
110  {
111  global $SYSCONFDIR;
112  $cmd = dirname(__DIR__).'/agent/monk -c '.$SYSCONFDIR.' '.$fileName;
113  exec($cmd, $output, $returnVar);
114  if ($returnVar != 0) {
115  throw new \Exception("scan failed with $returnVar");
116  }
117 
118  $qFileName = preg_quote($fileName, "/");
119  $licenseIds = array();
120  $highlights = array();
121  foreach ($output as $line) {
122  $lineMatches = array();
123  if (preg_match('/found diff match between "'.$qFileName.'" and "[^"]*" \‍(rf_pk=(?P<rf>[0-9]+)\‍); rank (?P<rank>[0-9]{1,3}); diffs: \{(?P<diff>[st\[\]0-9, MR+-]+)}/', $line, $lineMatches)) {
124  $licenseId = $lineMatches['rf'];
125  $licenseIds[] = $licenseId;
126  $this->addDiffsToHighlights($licenseId, $lineMatches, $highlights);
127  }
128  if (preg_match('/found full match between "'.$qFileName.'" and "[^"]*" \‍(rf_pk=(?P<rf>[0-9]+)\‍); matched: (?P<start>[0-9]*)\+?(?P<len>[0-9]*)?/', $line, $lineMatches)) {
129  $licenseId = $lineMatches['rf'];
130  $licenseIds[] = $licenseId;
131 
132  $start = $lineMatches['start'];
133  $end = $start + $lineMatches['len'];
134 
135  $type = Highlight::MATCH;
136 
137  $highlight = new Highlight($start, $end, $type);
138  $highlight->setLicenseId($licenseId);
139 
140  $highlights[] = $highlight;
141  }
142  }
143 
144  return array($licenseIds, $highlights);
145  }
146 
147  private function addDiffsToHighlights($licenseId, $lineMatches, &$highlights)
148  {
149  foreach (explode(',', $lineMatches['diff']) as $diff) {
150  // t[0+4798] M0 s[0+4834]
151  if (preg_match('/t\[(?P<start>[0-9]*)\+?(?P<len>[0-9]*)?\] M(?P<type>.?) s\[(?P<rf_start>[0-9]*)\+?(?P<rf_len>[0-9]*)?\]/', $diff, $diffMatches)) {
152  $start = intval($diffMatches['start']);
153  $end = $start + intval($diffMatches['len']);
154  $rfStart = intval($diffMatches['rf_start']);
155  $rfEnd = $rfStart + intval($diffMatches['rf_len']);
156 
157  switch ($diffMatches['type']) {
158  case '0':
159  $type = Highlight::MATCH;
160  break;
161  case 'R':
162  $type = Highlight::CHANGED;
163  break;
164  case '-':
165  $type = Highlight::DELETED;
166  break;
167  case '+':
168  $type = Highlight::ADDED;
169  break;
170  default:
171  throw new \Exception('unrecognized diff type');
172  }
173  $highlight = new Highlight($start, $end, $type, $rfStart, $rfEnd);
174  $highlight->setLicenseId($licenseId);
175 
176  $highlights[] = $highlight;
177  } else {
178  throw new \Exception('failed parsing diff element: '.$diff);
179  }
180  }
181  }
182 
183 
184  public function renderLicenseList($licenseIds)
185  {
186  $content = '';
187  global $container;
189  $licenseDao = $container->get('dao.license');
190  $isLoggedIn = $this->isLoggedIn();
191  foreach ($licenseIds as $licenseId) {
193  $license = $licenseDao->getLicenseById($licenseId);
194  if ($isLoggedIn) {
195  $js = "javascript:window.open('?mod=popup-license&rf=" . $license->getId() . "','License text','width=600,height=400,toolbar=no,scrollbars=yes,resizable=yes');";
196  $content .= '<li><a onclick="' . $js . '" href="javascript:;">' . $license->getShortName() . '</a></li>';
197  } else {
198  $content .= '<li>' . $license->getShortName() . '</li>';
199  }
200  }
201  return $content ? _('Possible licenses').":<ul>$content</ul>" : _('No match found').'<hr/>';
202  }
203 }
204 
205 register_plugin(new OneShot());
Contains the constants and helpers for authentication of user.
Definition: Auth.php:24
render($templateName, $vars=null, $headers=null)