Passed
Push — find-similar ( 493fd2...333d64 )
by Matias
04:44
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
class PersonController extends Controller {
50
51
	/** @var IRootFolder */
52
	private $rootFolder;
53
54
	/** @var IUserSession */
55
	private $userSession;
56
57
	/** @var IURLGenerator */
58
	private $urlGenerator;
59
60
	/** @var FaceMapper */
61
	private $faceMapper;
62
63
	/** @var ImageMapper */
64
	private $imageMapper;
65
66
	/** @var PersonMapper */
67
	private $personMapper;
68
69
	/** @var SettingsService */
70
	private $settingsService;
71
72
	/** @var string */
73
	private $userId;
74
75
	public function __construct($AppName,
76
	                            IRequest        $request,
77
	                            IRootFolder     $rootFolder,
78
	                            IUserSession    $userSession,
79
	                            IURLGenerator   $urlGenerator,
80
	                            FaceMapper      $faceMapper,
81
	                            ImageMapper     $imageMapper,
82
	                            PersonMapper    $personmapper,
83
	                            SettingsService $settingsService,
84
	                            $UserId)
85
	{
86
		parent::__construct($AppName, $request);
87
88
		$this->rootFolder      = $rootFolder;
89
		$this->userSession     = $userSession;
90
		$this->urlGenerator    = $urlGenerator;
91
		$this->faceMapper      = $faceMapper;
92
		$this->imageMapper     = $imageMapper;
93
		$this->personMapper    = $personmapper;
94
		$this->settingsService = $settingsService;
95
		$this->userId          = $UserId;
96
	}
97
98
	/**
99
	 * @NoAdminRequired
100
	 */
101
	public function index() {
102
		$notGrouped = $this->settingsService->getShowNotGrouped();
103
		$userEnabled = $this->settingsService->getUserEnabled($this->userId);
104
105
		$resp = array();
106
		$resp['enabled'] = $userEnabled;
107
		$resp['clusters'] = array();
108
109
		if (!$userEnabled)
110
			return new DataResponse($resp);
111
112
		$modelId = $this->settingsService->getCurrentFaceModel();
113
114
		$persons = $this->personMapper->findAll($this->userId, $modelId);
115
		foreach ($persons as $person) {
116
			$personFaces = $this->faceMapper->findFacesFromPerson($this->userId, $person->getId(), $modelId);
117
			if ($notGrouped === false && count($personFaces) <= 1)
118
				continue;
119
120
			$limit = 14;
121
			$faces = [];
122
			foreach ($personFaces as $personFace) {
123
				$image = $this->imageMapper->find($this->userId, $personFace->getImage());
124
				$fileUrl = $this->getRedirectToFileUrl($image->getFile());
0 ignored issues
show
Bug introduced by
It seems like $image->getFile() can also be of type null; however, parameter $fileId of OCA\FaceRecognition\Cont...:getRedirectToFileUrl() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

124
				$fileUrl = $this->getRedirectToFileUrl(/** @scrutinizer ignore-type */ $image->getFile());
Loading history...
125
				if (NULL === $fileUrl)
126
					continue;
127
128
				$face = [];
129
				$face['thumb-url'] = $this->getThumbUrl($personFace->getId());
130
				$face['file-url'] = $fileUrl;
131
				$faces[] = $face;
132
133
				if (--$limit === 0)
134
					break;
135
			}
136
137
			$cluster = [];
138
			$cluster['name'] = $person->getName();
139
			$cluster['count'] = count($personFaces);
140
			$cluster['id'] = $person->getId();
141
			$cluster['faces'] = $faces;
142
143
			$resp['clusters'][] = $cluster;
144
		}
145
		return new DataResponse($resp);
146
	}
147
148
	/**
149
	 * @NoAdminRequired
150
	 */
151
	public function find(int $id) {
152
		$person = $this->personMapper->find($this->userId, $id);
153
154
		$resp = [];
155
		$faces = [];
156
		$personFaces = $this->faceMapper->findFacesFromPerson($this->userId, $person->getId(), $this->settingsService->getCurrentFaceModel());
157
		foreach ($personFaces as $personFace) {
158
			$image = $this->imageMapper->find($this->userId, $personFace->getImage());
159
			$fileUrl = $this->getRedirectToFileUrl($image->getFile());
0 ignored issues
show
Bug introduced by
It seems like $image->getFile() can also be of type null; however, parameter $fileId of OCA\FaceRecognition\Cont...:getRedirectToFileUrl() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

159
			$fileUrl = $this->getRedirectToFileUrl(/** @scrutinizer ignore-type */ $image->getFile());
Loading history...
160
			if (NULL === $fileUrl)
161
				continue;
162
			$face = [];
163
			$face['thumb-url'] = $this->getThumbUrl($personFace->getId());
164
			$face['file-url'] = $fileUrl;
165
			$faces[] = $face;
166
		}
167
		$resp['name'] = $person->getName();
168
		$resp['id'] = $person->getId();
169
		$resp['faces'] = $faces;
170
171
		return new DataResponse($resp);
172
	}
173
174
	/**
175
	 * @NoAdminRequired
176
	 */
177
	public function findSimilar(int $id) {
178
		$deviation = $this->settingsService->getDeviation();
179
		if (!version_compare(phpversion('pdlib'), '1.0.2', '>=') || ($deviation === 0.0))
180
			return new DataResponse(array());
181
182
		$sensitivity = $this->settingsService->getSensitivity();
183
		$modelId = $this->settingsService->getCurrentFaceModel();
184
185
		$mainPerson = $this->personMapper->find($this->userId, $id);
186
		$mainFace = $this->faceMapper->findRepresentativeFromPerson($this->userId, $id, $sensitivity, $modelId);
187
188
		$resp = array();
189
		$persons = $this->personMapper->findAll($this->userId, $modelId);
190
		foreach ($persons as $cmpPerson) {
191
			if ($mainPerson->getName() === $cmpPerson->getName())
192
				continue;
193
194
			$cmpFace = $this->faceMapper->findRepresentativeFromPerson($this->userId, $cmpPerson->getId(), $sensitivity, $modelId);
195
			$distance = dlib_vector_length($mainFace->descriptor, $cmpFace->descriptor);
0 ignored issues
show
Bug introduced by
The function dlib_vector_length was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

195
			$distance = /** @scrutinizer ignore-call */ dlib_vector_length($mainFace->descriptor, $cmpFace->descriptor);
Loading history...
196
			if ($distance < ($sensitivity + $deviation)) {
197
				$similar = array();
198
				$similar['id'] = $cmpPerson->getId();
199
				$similar['name'] = $cmpPerson->getName();
200
				$similar['thumb-url'] = $this->getThumbUrl($cmpFace->getId());
201
				$resp[] = $similar;
202
			}
203
		}
204
205
		return new DataResponse($resp);
206
	}
207
208
	/**
209
	 * @NoAdminRequired
210
	 */
211
	public function findByName(string $personName) {
212
		$userEnabled = $this->settingsService->getUserEnabled($this->userId);
213
214
		$resp = array();
215
		$resp['enabled'] = $userEnabled;
216
		$resp['clusters'] = array();
217
218
		if (!$userEnabled)
219
			return new DataResponse($resp);
220
221
		$modelId = $this->settingsService->getCurrentFaceModel();
222
223
		$persons = $this->personMapper->findByName($this->userId, $modelId, $personName);
224
		foreach ($persons as $person) {
225
			$personFaces = $this->faceMapper->findFacesFromPerson($this->userId, $person->getId(), $modelId);
226
227
			$faces = [];
228
			foreach ($personFaces as $personFace) {
229
				$image = $this->imageMapper->find($this->userId, $personFace->getImage());
230
				$fileUrl = $this->getRedirectToFileUrl($image->getFile());
0 ignored issues
show
Bug introduced by
It seems like $image->getFile() can also be of type null; however, parameter $fileId of OCA\FaceRecognition\Cont...:getRedirectToFileUrl() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

230
				$fileUrl = $this->getRedirectToFileUrl(/** @scrutinizer ignore-type */ $image->getFile());
Loading history...
231
				if (NULL === $fileUrl)
232
					continue;
233
234
				$face = [];
235
				$face['thumb-url'] = $this->getThumbUrl($personFace->getId());
236
				$face['file-url'] = $fileUrl;
237
				$faces[] = $face;
238
			}
239
240
			$cluster = [];
241
			$cluster['name'] = $person->getName();
242
			$cluster['count'] = count($personFaces);
243
			$cluster['id'] = $person->getId();
244
			$cluster['faces'] = $faces;
245
			$resp['clusters'][] = $cluster;
246
		}
247
248
		return new DataResponse($resp);
249
	}
250
251
	/**
252
	 * @NoAdminRequired
253
	 *
254
	 * @param int $id
255
	 * @param string $name
256
	 */
257
	public function updateName($id, $name) {
258
		$person = $this->personMapper->find ($this->userId, $id);
259
		$person->setName($name);
260
		$this->personMapper->update($person);
261
262
		$newPerson = $this->personMapper->find($this->userId, $id);
263
		return new DataResponse($newPerson);
264
	}
265
266
	/**
267
	 * Url to thumb face
268
	 *
269
	 * @param string $faceId face id to show
270
	 */
271
	private function getThumbUrl($faceId) {
272
		$params = [];
273
		$params['id'] = $faceId;
274
		$params['size'] = 50;
275
		return $this->urlGenerator->linkToRoute('facerecognition.face.getThumb', $params);
276
	}
277
278
	/**
279
	 * Redirects to the file list and highlight the given file id
280
	 *
281
	 * @param int $fileId file id to show
282
	 */
283
	private function getRedirectToFileUrl(int $fileId) {
284
		$uid        = $this->userSession->getUser()->getUID();
285
		$baseFolder = $this->rootFolder->getUserFolder($uid);
286
		$files      = $baseFolder->getById($fileId);
287
		$file       = current($files);
288
289
		if(!($file instanceof File)) {
290
			// If we cannot find a file probably it was deleted out of our control and we must clean our tables.
291
			$this->settingsService->setNeedRemoveStaleImages(true, $this->userId);
292
			return NULL;
293
		}
294
295
		$params = [];
296
		$params['dir'] = $baseFolder->getRelativePath($file->getParent()->getPath());
297
		$params['scrollto'] = $file->getName();
298
299
		return $this->urlGenerator->linkToRoute('files.view.index', $params);
300
	}
301
302
}
303