Passed
Push — split-cluster-person ( 71fbb4...a0dc73 )
by Matias
07:16
created

PersonController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 21
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 9
c 1
b 0
f 0
nc 1
nop 10
dl 0
loc 21
ccs 0
cts 20
cp 0
crap 2
rs 9.9666

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/**
3
 * @copyright Copyright (c) 2018-2020 Matias De lellis <[email protected]>
4
 *
5
 * @author Matias De lellis <[email protected]>
6
 *
7
 * @license GNU AGPL version 3 or any later version
8
 *
9
 * This program is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Affero General Public License as
11
 * published by the Free Software Foundation, either version 3 of the
12
 * License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU Affero General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Affero General Public License
20
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 */
23
24
namespace OCA\FaceRecognition\Controller;
25
26
use OCP\IRequest;
27
use OCP\Files\IRootFolder;
28
use OCP\Files\File;
29
use OCP\IUserSession;
30
use OCP\IURLGenerator;
31
32
use OCP\AppFramework\Http;
33
use OCP\AppFramework\Http\DataResponse;
34
use OCP\AppFramework\Http\JSONResponse;
35
use OCP\AppFramework\Http\DataDisplayResponse;
36
use OCP\AppFramework\Controller;
37
38
use OCA\FaceRecognition\Db\Face;
39
use OCA\FaceRecognition\Db\FaceMapper;
40
41
use OCA\FaceRecognition\Db\Image;
42
use OCA\FaceRecognition\Db\ImageMapper;
43
44
use OCA\FaceRecognition\Db\Person;
45
use OCA\FaceRecognition\Db\PersonMapper;
46
47
use OCA\FaceRecognition\Service\SettingsService;
48
49
50
class PersonController extends Controller {
51
52
	/** @var IRootFolder */
53
	private $rootFolder;
54
55
	/** @var IUserSession */
56
	private $userSession;
57
58
	/** @var IURLGenerator */
59
	private $urlGenerator;
60
61
	/** @var FaceMapper */
62
	private $faceMapper;
63
64
	/** @var ImageMapper */
65
	private $imageMapper;
66
67
	/** @var PersonMapper */
68
	private $personMapper;
69
70
	/** @var SettingsService */
71
	private $settingsService;
72
73
	/** @var string */
74
	private $userId;
75
76
	public function __construct($AppName,
77
	                            IRequest        $request,
78
	                            IRootFolder     $rootFolder,
79
	                            IUserSession    $userSession,
80
	                            IURLGenerator   $urlGenerator,
81
	                            FaceMapper      $faceMapper,
82
	                            ImageMapper     $imageMapper,
83
	                            PersonMapper    $personmapper,
84
	                            SettingsService $settingsService,
85
	                            $UserId)
86
	{
87
		parent::__construct($AppName, $request);
88
89
		$this->rootFolder      = $rootFolder;
90
		$this->userSession     = $userSession;
91
		$this->urlGenerator    = $urlGenerator;
92
		$this->faceMapper      = $faceMapper;
93
		$this->imageMapper     = $imageMapper;
94
		$this->personMapper    = $personmapper;
95
		$this->settingsService = $settingsService;
96
		$this->userId          = $UserId;
97
	}
98
99
	/**
100
	 * @NoAdminRequired
101
	 */
102
	public function index() {
103
		$userEnabled = $this->settingsService->getUserEnabled($this->userId);
104
105
		$resp = array();
106
		$resp['enabled'] = $userEnabled;
107
		$resp['persons'] = array();
108
109
		if (!$userEnabled)
110
			return new DataResponse($resp);
111
112
		$modelId = $this->settingsService->getCurrentFaceModel();
113
114
		$personsNames = $this->personMapper->findDistinctNames($this->userId, $modelId);
115
		foreach ($personsNames as $personNamed) {
116
			$facesCount = 0;
117
			$faceUrl = null;
118
			$faces = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $faces is dead and can be removed.
Loading history...
119
			$persons = $this->personMapper->findByName($this->userId, $modelId, $personNamed->getName());
120
			foreach ($persons as $person) {
121
				$personFaces = $this->faceMapper->findFacesFromPerson($this->userId, $person->getId(), $modelId);
122
				if (is_null($faceUrl)) {
123
					$faceUrl = $this->getThumbUrl($personFaces[0]->getId(), 128);
124
				}
125
				$facesCount += count($personFaces);
126
			}
127
128
			$person = [];
129
			$person['name'] = $personNamed->getName();
130
			$person['thumb-url'] = $faceUrl;
131
			$person['count'] = $facesCount;
132
133
			$resp['persons'][] = $person;
134
		}
135
		return new DataResponse($resp);
136
	}
137
138
	/**
139
	 * @NoAdminRequired
140
	 */
141
	public function find(int $id) {
142
		$person = $this->personMapper->find($this->userId, $id);
143
144
		$resp = [];
145
		$faces = [];
146
		$personFaces = $this->faceMapper->findFacesFromPerson($this->userId, $person->getId(), $this->settingsService->getCurrentFaceModel());
147
		foreach ($personFaces as $personFace) {
148
			$image = $this->imageMapper->find($this->userId, $personFace->getImage());
149
			$fileId = $image->getFile();
150
			if ($fileId === null) continue;
151
152
			$fileUrl = $this->getRedirectToFileUrl($fileId);
153
			if ($fileUrl === null) continue;
154
155
			$face = [];
156
			$face['thumb-url'] = $this->getThumbUrl($personFace->getId());
0 ignored issues
show
Bug introduced by
The call to OCA\FaceRecognition\Cont...ntroller::getThumbUrl() has too few arguments starting with size. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

156
			/** @scrutinizer ignore-call */ 
157
   $face['thumb-url'] = $this->getThumbUrl($personFace->getId());

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
157
			$face['file-url'] = $fileUrl;
158
			$faces[] = $face;
159
		}
160
		$resp['name'] = $person->getName();
161
		$resp['id'] = $person->getId();
162
		$resp['faces'] = $faces;
163
164
		return new DataResponse($resp);
165
	}
166
167
	/**
168
	 * @NoAdminRequired
169
	 */
170
	public function findByName(string $personName) {
171
		$userEnabled = $this->settingsService->getUserEnabled($this->userId);
172
173
		$resp = array();
174
		$resp['enabled'] = $userEnabled;
175
		$resp['name'] = $personName;
176
		$resp['clusters'] = 0;
177
		$resp['images'] = array();
178
179
		if (!$userEnabled)
180
			return new DataResponse($resp);
181
182
		$modelId = $this->settingsService->getCurrentFaceModel();
183
184
		$clusters = $this->personMapper->findByName($this->userId, $modelId, $personName);
185
		foreach ($clusters as $cluster) {
186
			$resp['clusters']++;
187
188
			$faces = $this->faceMapper->findFacesFromPerson($this->userId, $cluster->getId(), $modelId);
189
			foreach ($faces as $face) {
190
				$image = $this->imageMapper->find($this->userId, $face->getImage());
191
192
				$fileId = $image->getFile();
193
				if ($fileId === null) continue;
194
195
				$fileUrl = $this->getRedirectToFileUrl($fileId);
196
				if ($fileUrl === null) continue;
197
198
				$thumbUrl = $this->getPreviewUrl($fileId, 128);
199
				if ($thumbUrl === null) continue;
200
201
				$image = [];
202
				$image['thumb-url'] = $thumbUrl;
203
				$image['file-url'] = $fileUrl;
204
205
				$resp['images'][] = $image;
206
			}
207
		}
208
209
		return new DataResponse($resp);
210
	}
211
212
213
214
	/**
215
	 * @NoAdminRequired
216
	 */
217
	public function findClustersByName(string $personName) {
218
		$userEnabled = $this->settingsService->getUserEnabled($this->userId);
219
220
		$resp = array();
221
		$resp['enabled'] = $userEnabled;
222
		$resp['clusters'] = array();
223
224
		if (!$userEnabled)
225
			return new DataResponse($resp);
226
227
		$modelId = $this->settingsService->getCurrentFaceModel();
228
229
		$persons = $this->personMapper->findByName($this->userId, $modelId, $personName);
230
		foreach ($persons as $person) {
231
			$personFaces = $this->faceMapper->findFacesFromPerson($this->userId, $person->getId(), $modelId);
232
233
			$faces = [];
234
			foreach ($personFaces as $personFace) {
235
				$image = $this->imageMapper->find($this->userId, $personFace->getImage());
236
				$fileId = $image->getFile();
237
				if ($fileId === null) continue;
238
239
				$fileUrl = $this->getRedirectToFileUrl($fileId);
240
				if ($fileUrl === null) continue;
241
242
				$face = [];
243
				$face['thumb-url'] = $this->getThumbUrl($personFace->getId(), 50);
244
				$face['file-url'] = $fileUrl;
245
				$faces[] = $face;
246
			}
247
248
			$cluster = [];
249
			$cluster['name'] = $person->getName();
250
			$cluster['count'] = count($personFaces);
251
			$cluster['id'] = $person->getId();
252
			$cluster['faces'] = $faces;
253
			$resp['clusters'][] = $cluster;
254
		}
255
256
		return new DataResponse($resp);
257
	}
258
259
	/**
260
	 * @NoAdminRequired
261
	 *
262
	 * @param int $id
263
	 * @param string $name
264
	 */
265
	public function updateName($id, $name) {
266
		$person = $this->personMapper->find ($this->userId, $id);
267
		$person->setName($name);
268
		$this->personMapper->update($person);
269
270
		$newPerson = $this->personMapper->find($this->userId, $id);
271
		return new DataResponse($newPerson);
272
	}
273
274
	/**
275
	 * Url to thumb face
276
	 *
277
	 * @param int $faceId face id to show
278
	 * @param int $size Size of face thumbnails
279
	 */
280
	private function getThumbUrl(int $faceId, int $size) {
281
		$params = [];
282
		$params['id'] = $faceId;
283
		$params['size'] = $size;
284
		return $this->urlGenerator->linkToRoute('facerecognition.face.getThumb', $params);
285
	}
286
287
	/**
288
	 * Get thumbnail of the give file id
289
	 *
290
	 * @param int $fileId file id to show
291
	 * @param int $sideSize side lenght to show
292
	 */
293
	public function getPreviewUrl(int $fileId, int $sideSize): ?string {
294
		$userFolder = $this->rootFolder->getUserFolder($this->userId);
295
		$file = current($userFolder->getById($fileId));
296
297
		if (!($file instanceof File)) {
298
			// If we cannot find a file probably it was deleted out of our control and we must clean our tables.
299
			$this->settingsService->setNeedRemoveStaleImages(true, $this->userId);
300
			return null;
301
		}
302
303
		return $this->urlGenerator->linkToRouteAbsolute('core.Preview.getPreview', [
304
			'file' => $userFolder->getRelativePath($file->getPath()),
305
			'x' => $sideSize,
306
			'y' => $sideSize
307
		]);
308
	}
309
310
	/**
311
	 * Redirects to the file list and highlight the given file id
312
	 *
313
	 * @param int $fileId file id to show
314
	 */
315
	private function getRedirectToFileUrl(int $fileId) {
316
		$uid        = $this->userSession->getUser()->getUID();
317
		$baseFolder = $this->rootFolder->getUserFolder($uid);
318
		$files      = $baseFolder->getById($fileId);
319
		$file       = current($files);
320
321
		if(!($file instanceof File)) {
322
			// If we cannot find a file probably it was deleted out of our control and we must clean our tables.
323
			$this->settingsService->setNeedRemoveStaleImages(true, $this->userId);
324
			return null;
325
		}
326
327
		$params = [];
328
		$params['dir'] = $baseFolder->getRelativePath($file->getParent()->getPath());
329
		$params['scrollto'] = $file->getName();
330
331
		return $this->urlGenerator->linkToRoute('files.view.index', $params);
332
	}
333
334
}
335