Passed
Pull Request — master (#751)
by Matias
07:33 queued 04:51
created

ClusterController::findIgnored()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 43
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
cc 6
eloc 30
c 0
b 0
f 0
nc 6
nop 0
dl 0
loc 43
ccs 0
cts 31
cp 0
crap 42
rs 8.8177
1
<?php
2
/**
3
 * @copyright Copyright (c) 2018-2021 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\File;
28
29
use OCP\AppFramework\Http;
30
use OCP\AppFramework\Http\DataResponse;
31
use OCP\AppFramework\Http\JSONResponse;
32
use OCP\AppFramework\Http\DataDisplayResponse;
33
use OCP\AppFramework\Controller;
34
35
use OCA\FaceRecognition\Db\Face;
36
use OCA\FaceRecognition\Db\FaceMapper;
37
38
use OCA\FaceRecognition\Db\Image;
39
use OCA\FaceRecognition\Db\ImageMapper;
40
41
use OCA\FaceRecognition\Db\Person;
42
use OCA\FaceRecognition\Db\PersonMapper;
43
44
use OCA\FaceRecognition\Service\SettingsService;
45
use OCA\FaceRecognition\Service\UrlService;
46
47
48
class ClusterController extends Controller {
49
50
	/** @var FaceMapper */
51
	private $faceMapper;
52
53
	/** @var ImageMapper */
54
	private $imageMapper;
55
56
	/** @var PersonMapper */
57
	private $personMapper;
58
59
	/** @var SettingsService */
60
	private $settingsService;
61
62
	/** @var UrlService */
63
	private $urlService;
64
65
	/** @var string */
66
	private $userId;
67
68
	public function __construct($AppName,
69
	                            IRequest        $request,
70
	                            FaceMapper      $faceMapper,
71
	                            ImageMapper     $imageMapper,
72
	                            PersonMapper    $personmapper,
73
	                            SettingsService $settingsService,
74
	                            UrlService      $urlService,
75
	                            $UserId)
76
	{
77
		parent::__construct($AppName, $request);
78
79
		$this->faceMapper      = $faceMapper;
80
		$this->imageMapper     = $imageMapper;
81
		$this->personMapper    = $personmapper;
82
		$this->settingsService = $settingsService;
83
		$this->urlService      = $urlService;
84
		$this->userId          = $UserId;
85
	}
86
87
	/**
88
	 * @NoAdminRequired
89
	 *
90
	 * @return DataResponse
91
	 */
92
	public function find(int $id): DataResponse {
93
		$person = $this->personMapper->find($this->userId, $id);
94
95
		$resp = [];
96
		$faces = [];
97
		$personFaces = $this->faceMapper->findFromCluster($this->userId, $person->getId(), $this->settingsService->getCurrentFaceModel());
98
		foreach ($personFaces as $personFace) {
99
			$image = $this->imageMapper->find($this->userId, $personFace->getImage());
100
101
			$file =  $this->urlService->getFileNode($image->getFile());
102
			if ($file === null) continue;
103
104
			$face = [];
105
			$face['thumbUrl'] = $this->urlService->getThumbUrl($personFace->getId(), 50);
106
			$face['fileUrl'] = $this->urlService->getRedirectToFileUrl($file);
107
			$faces[] = $face;
108
		}
109
		$resp['name'] = $person->getName();
110
		$resp['id'] = $person->getId();
111
		$resp['faces'] = $faces;
112
113
		return new DataResponse($resp);
114
	}
115
116
	/**
117
	 * @NoAdminRequired
118
	 *
119
	 * @return DataResponse
120
	 */
121
	public function findByName(string $personName): DataResponse {
122
		$userEnabled = $this->settingsService->getUserEnabled($this->userId);
123
124
		$resp = array();
125
		$resp['enabled'] = $userEnabled;
126
		$resp['clusters'] = array();
127
128
		if (!$userEnabled)
129
			return new DataResponse($resp);
130
131
		$modelId = $this->settingsService->getCurrentFaceModel();
132
133
		$persons = $this->personMapper->findByName($this->userId, $modelId, $personName);
134
		foreach ($persons as $person) {
135
			$personFaces = $this->faceMapper->findFromCluster($this->userId, $person->getId(), $modelId);
136
137
			$faces = [];
138
			foreach ($personFaces as $personFace) {
139
				$image = $this->imageMapper->find($this->userId, $personFace->getImage());
140
141
				$file = $this->urlService->getFileNode($image->getFile());
142
				if ($file === null) continue;
143
144
				$face = [];
145
				$face['thumbUrl'] = $this->urlService->getThumbUrl($personFace->getId(), 50);
146
				$face['fileUrl'] = $this->urlService->getRedirectToFileUrl($file);
147
				$faces[] = $face;
148
			}
149
150
			$cluster = [];
151
			$cluster['name'] = $person->getName();
152
			$cluster['count'] = count($personFaces);
153
			$cluster['id'] = $person->getId();
154
			$cluster['faces'] = $faces;
155
			$resp['clusters'][] = $cluster;
156
		}
157
158
		return new DataResponse($resp);
159
	}
160
161
	/**
162
	 * @NoAdminRequired
163
	 *
164
	 * @return DataResponse
165
	 */
166
	public function findUnassigned(): DataResponse {
167
		$userEnabled = $this->settingsService->getUserEnabled($this->userId);
168
169
		$resp = array();
170
		$resp['enabled'] = $userEnabled;
171
		$resp['clusters'] = array();
172
173
		if (!$userEnabled)
174
			return new DataResponse($resp);
175
176
		$modelId = $this->settingsService->getCurrentFaceModel();
177
		$minClusterSize = $this->settingsService->getMinimumFacesInCluster();
178
179
		$clusters = $this->personMapper->findUnassigned($this->userId, $modelId);
180
		foreach ($clusters as $cluster) {
181
			$clusterSize = $this->personMapper->countClusterFaces($cluster->getId());
182
			if ($clusterSize < $minClusterSize)
183
				continue;
184
185
			$personFaces = $this->faceMapper->findFromCluster($this->userId, $cluster->getId(), $modelId, 40);
186
			$faces = [];
187
			foreach ($personFaces as $personFace) {
188
				$image = $this->imageMapper->find($this->userId, $personFace->getImage());
189
190
				$file = $this->urlService->getFileNode($image->getFile());
191
				if ($file === null) continue;
192
193
				$face = [];
194
				$face['thumbUrl'] = $this->urlService->getThumbUrl($personFace->getId(), 50);
195
				$face['fileUrl'] = $this->urlService->getRedirectToFileUrl($file);
196
197
				$faces[] = $face;
198
			}
199
200
			$entry = [];
201
			$entry['count'] = $clusterSize;
202
			$entry['id'] = $cluster->getId();
203
			$entry['faces'] = $faces;
204
			$resp['clusters'][] = $entry;
205
		}
206
207
		return new DataResponse($resp);
208
	}
209
210
	/**
211
	 * @NoAdminRequired
212
	 *
213
	 * @return DataResponse
214
	 */
215
	Public function findIgnored(): DataResponse {
216
		sleep(1); // button "Review ignored people" should be created delayed (after "Review people found" button)
217
		$userEnabled = $this->settingsService->getUserEnabled($this->userId);
218
219
		$resp = array();
220
		$resp['enabled'] = $userEnabled;
221
		$resp['clusters'] = array();
222
223
		if (!$userEnabled)
224
			return new DataResponse($resp);
225
226
		$modelId = $this->settingsService->getCurrentFaceModel();
227
		$minClusterSize = $this->settingsService->getMinimumFacesInCluster();
228
229
		$clusters = $this->personMapper->findIgnored($this->userId, $modelId);
230
		foreach ($clusters as $cluster) {
231
			$clusterSize = $this->personMapper->countClusterFaces($cluster->getId());
232
			if ($clusterSize < $minClusterSize)
233
				continue;
234
235
			$personFaces = $this->faceMapper->findFromCluster($this->userId, $cluster->getId(), $modelId, 40);
236
			$faces = [];
237
			foreach ($personFaces as $personFace) {
238
				$image = $this->imageMapper->find($this->userId, $personFace->getImage());
239
240
				$file = $this->urlService->getFileNode($image->getFile());
241
				if ($file === null) continue;
242
243
				$face = [];
244
				$face['thumbUrl'] = $this->urlService->getThumbUrl($personFace->getId(), 50);
245
				$face['fileUrl'] = $this->urlService->getRedirectToFileUrl($file);
246
247
				$faces[] = $face;
248
			}
249
250
			$entry = [];
251
			$entry['count'] = $clusterSize;
252
			$entry['id'] = $cluster->getId();
253
			$entry['faces'] = $faces;
254
			$resp['clusters'][] = $entry;
255
		}
256
257
		return new DataResponse($resp);
258
	}
259
260
	/**
261
	 * @NoAdminRequired
262
	 *
263
	 * @param int $id
264
	 * @param bool $visible
265
	 *
266
	 * @return DataResponse
267
	 */
268
	public function setVisibility (int $id, bool $visible): DataResponse {
269
		$resp = array();
270
		$this->personMapper->setVisibility($id, $visible);
271
		return new DataResponse($resp);
272
	}
273
274
	/**
275
	 * @NoAdminRequired
276
	 *
277
	 * @param int $id if of cluster
278
	 * @param int $face id of face.
279
	 * @param string|null $name optional name to rename it.
280
	 *
281
	 * @return DataResponse
282
	 */
283
	public function detachFace (int $id, int $face, $name = null): DataResponse {
284
		$person = $this->personMapper->detachFace($id, $face, $name);
285
		return new DataResponse($person);
286
	}
287
288
	/**
289
	 * @NoAdminRequired
290
	 *
291
	 * @param int $id of cluster
292
	 * @param string $name to rename them.
293
	 * @param int|null $face_id optional face id if you just want to name that face
294
	 *
295
	 * @return DataResponse new person with that update.
296
	 */
297
	public function updateName($id, $name, $face_id = null): DataResponse {
298
		if (is_null($face_id)) {
299
			$person = $this->personMapper->find($this->userId, $id);
300
			$person->setName($name);
301
			$this->personMapper->update($person);
302
		} else {
303
			$person = $this->personMapper->detachFace($id, $face_id, $name);
304
		}
305
		return new DataResponse($person);
306
	}
307
308
}
309