Passed
Push — split-cluster-person ( 2a9d8c...7ada7e )
by Matias
05:23
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['thumbUrl'] = $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['thumbUrl'] = $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['thumbUrl'] = $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['fileUrl'] = $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, 256);
199
				if ($thumbUrl === null) continue;
200
201
				$image = [];
202
				$image['thumbUrl'] = $thumbUrl;
203
				$image['fileUrl'] = $fileUrl;
204
205
				$resp['images'][] = $image;
206
			}
207
		}
208
209
		return new DataResponse($resp);
210
	}
211
212
	/**
213
	 * @NoAdminRequired
214
	 */
215
	public function findClustersByName(string $personName) {
216
		$userEnabled = $this->settingsService->getUserEnabled($this->userId);
217
218
		$resp = array();
219
		$resp['enabled'] = $userEnabled;
220
		$resp['clusters'] = array();
221
222
		if (!$userEnabled)
223
			return new DataResponse($resp);
224
225
		$modelId = $this->settingsService->getCurrentFaceModel();
226
227
		$persons = $this->personMapper->findByName($this->userId, $modelId, $personName);
228
		foreach ($persons as $person) {
229
			$personFaces = $this->faceMapper->findFacesFromPerson($this->userId, $person->getId(), $modelId);
230
231
			$faces = [];
232
			foreach ($personFaces as $personFace) {
233
				$image = $this->imageMapper->find($this->userId, $personFace->getImage());
234
				$fileId = $image->getFile();
235
				if ($fileId === null) continue;
236
237
				$fileUrl = $this->getRedirectToFileUrl($fileId);
238
				if ($fileUrl === null) continue;
239
240
				$face = [];
241
				$face['thumbUrl'] = $this->getThumbUrl($personFace->getId(), 50);
242
				$face['fileUrl'] = $fileUrl;
243
				$faces[] = $face;
244
			}
245
246
			$cluster = [];
247
			$cluster['name'] = $person->getName();
248
			$cluster['count'] = count($personFaces);
249
			$cluster['id'] = $person->getId();
250
			$cluster['faces'] = $faces;
251
			$resp['clusters'][] = $cluster;
252
		}
253
254
		return new DataResponse($resp);
255
	}
256
257
	/**
258
	 * @NoAdminRequired
259
	 *
260
	 * @param string $personName
261
	 * @param string $name
262
	 */
263
	public function updatePerson($personName, $name) {
264
		$modelId = $this->settingsService->getCurrentFaceModel();
265
		$clusters = $this->personMapper->findByName($this->userId, $modelId, $personName);
266
		foreach ($clusters as $person) {
267
			$person->setName($name);
268
			$this->personMapper->update($person);
269
		}
270
		return $this->findByName($name);
271
	}
272
273
	/**
274
	 * @NoAdminRequired
275
	 *
276
	 * @param int $id
277
	 * @param string $name
278
	 */
279
	public function updateName($id, $name) {
280
		$person = $this->personMapper->find ($this->userId, $id);
281
		$person->setName($name);
282
		$this->personMapper->update($person);
283
284
		$newPerson = $this->personMapper->find($this->userId, $id);
285
		return new DataResponse($newPerson);
286
	}
287
288
	/**
289
	 * Url to thumb face
290
	 *
291
	 * @param int $faceId face id to show
292
	 * @param int $size Size of face thumbnails
293
	 */
294
	private function getThumbUrl(int $faceId, int $size) {
295
		$params = [];
296
		$params['id'] = $faceId;
297
		$params['size'] = $size;
298
		return $this->urlGenerator->linkToRoute('facerecognition.face.getThumb', $params);
299
	}
300
301
	/**
302
	 * Get thumbnail of the give file id
303
	 *
304
	 * @param int $fileId file id to show
305
	 * @param int $sideSize side lenght to show
306
	 */
307
	public function getPreviewUrl(int $fileId, int $sideSize): ?string {
308
		$userFolder = $this->rootFolder->getUserFolder($this->userId);
309
		$file = current($userFolder->getById($fileId));
310
311
		if (!($file instanceof File)) {
312
			// If we cannot find a file probably it was deleted out of our control and we must clean our tables.
313
			$this->settingsService->setNeedRemoveStaleImages(true, $this->userId);
314
			return null;
315
		}
316
317
		return '/core/preview?fileId=' . $fileId .'&x=' . $sideSize . '&y=' . $sideSize . '&a=false&v=' . $file->getETag();
318
	}
319
320
	/**
321
	 * Redirects to the file list and highlight the given file id
322
	 *
323
	 * @param int $fileId file id to show
324
	 */
325
	private function getRedirectToFileUrl(int $fileId) {
326
		$uid        = $this->userSession->getUser()->getUID();
327
		$baseFolder = $this->rootFolder->getUserFolder($uid);
328
		$files      = $baseFolder->getById($fileId);
329
		$file       = current($files);
330
331
		if(!($file instanceof File)) {
332
			// If we cannot find a file probably it was deleted out of our control and we must clean our tables.
333
			$this->settingsService->setNeedRemoveStaleImages(true, $this->userId);
334
			return null;
335
		}
336
337
		$params = [];
338
		$params['dir'] = $baseFolder->getRelativePath($file->getParent()->getPath());
339
		$params['scrollto'] = $file->getName();
340
341
		return $this->urlGenerator->linkToRoute('files.view.index', $params);
342
	}
343
344
}
345