FaceManagementService::resetImageErrors()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 5
ccs 0
cts 5
cp 0
crap 6
rs 10
c 1
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2020, Matias De lellis <[email protected]>
4
 * @copyright Copyright (c) 2019, Branko Kokanovic <[email protected]>
5
 *
6
 * @author Branko Kokanovic <[email protected]>
7
 *
8
 * @license GNU AGPL version 3 or any later version
9
 *
10
 * This program is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU Affero General Public License as
12
 * published by the Free Software Foundation, either version 3 of the
13
 * License, or (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU Affero General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Affero General Public License
21
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
 *
23
 */
24
25
namespace OCA\FaceRecognition\Service;
26
27
use OCP\IUser;
28
use OCP\IUserManager;
29
30
use OCA\FaceRecognition\Db\FaceMapper;
31
use OCA\FaceRecognition\Db\ImageMapper;
32
use OCA\FaceRecognition\Db\PersonMapper;
33
34
use OCA\FaceRecognition\Service\SettingsService;
35
36
/**
37
 * Background service. Both command and cron job are calling this service for long-running background operations.
38
 * Background processing for face recognition is comprised of several steps, called tasks. Each task is independent,
39
 * idempotent, DI-aware logic unit that yields. Since tasks are non-preemptive, they should yield from time to time, so we son't end up
40
 * working for more than given timeout.
41
 *
42
 * Tasks can be seen as normal sequential functions, but they are easier to work with,
43
 * reason about them and test them independently. Other than that, they are really glorified functions.
44
 */
45
class FaceManagementService {
46
47
	/** @var IUserManager */
48
	private $userManager;
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 2
	public function __construct(IUserManager    $userManager,
63
	                            FaceMapper      $faceMapper,
64
	                            ImageMapper     $imageMapper,
65
	                            PersonMapper    $personMapper,
66
	                            SettingsService $settingsService)
67
	{
68 2
		$this->userManager     = $userManager;
69 2
		$this->faceMapper      = $faceMapper;
70 2
		$this->imageMapper     = $imageMapper;
71 2
		$this->personMapper    = $personMapper;
72 2
		$this->settingsService = $settingsService;
73
	}
74
75
	/**
76
	 * Check if the current model has data on db
77
	 *
78
	 * @param IUser|null $user Optional user to check
79
	 * @param Int $modelId Optional model to check
80
	 *
81
	 * @return bool
82
	 */
83
	public function hasData(IUser $user = null, int $modelId = -1): bool {
84
		if ($modelId === -1) {
85
			$modelId = $this->settingsService->getCurrentFaceModel();
86
		}
87
		$eligible_users = $this->getEligiblesUserId($user);
88
		foreach ($eligible_users as $userId) {
89
			if ($this->hasDataForUser($userId, $modelId)) {
90
				return true;
91
			}
92
		}
93
		return false;
94
	}
95
96
	/**
97
	 * Check if the current model has data on db for user
98
	 *
99
	 * @param string $user ID of user to check
100
	 * @param Int $modelId model to check
101
	 *
102
	 * @return bool
103
	 */
104
	public function hasDataForUser(string $userId, int $modelId): bool {
105
		$facesCount = $this->faceMapper->countFaces($userId, $modelId);
106
		return ($facesCount > 0);
107
	}
108
109
	/**
110
	 * Deletes all faces, images and persons found. IF no user is given, resetting is executed for all users.
111
	 *
112
	 * @param IUser|null $user Optional user to execute resetting for
113
	 *
114
	 * @return void
115
	 */
116
	public function resetAll(IUser $user = null): void {
117
		$eligible_users = $this->getEligiblesUserId($user);
118
		foreach($eligible_users as $user) {
119
			$this->resetAllForUser($user);
120
		}
121
	}
122
123
	/**
124
	 * Deletes all faces, images and persons found for a given user.
125
	 *
126
	 * @param string $user ID of user to execute resetting for
127
	 *
128
	 * @return void
129
	 */
130 28
	public function resetAllForUser(string $userId): void {
131 28
		$this->faceMapper->deleteUserFaces($userId);
132 28
		$this->personMapper->deleteUserPersons($userId);
133 28
		$this->imageMapper->deleteUserImages($userId);
134
135 28
		$this->settingsService->setUserFullScanDone(false, $userId);
136
	}
137
138
	/**
139
	 * Deletes all faces, images and persons found. If no user is given, resetting is executed for all users.
140
	 *
141
	 * @param IUser|null $user Optional user to execute resetting for
142
	 * @param Int $modelId Optional model to clean
143
	 *
144
	 * @return void
145
	 */
146
	public function resetModel(IUser $user = null, int $modelId = -1): void {
147
		if ($modelId === -1) {
148
			$modelId = $this->settingsService->getCurrentFaceModel();
149
		}
150
		$eligible_users = $this->getEligiblesUserId($user);
151
		foreach($eligible_users as $userId) {
152
			$this->resetModelForUser($userId, $modelId);
153
		}
154
	}
155
156
	/**
157
	 * Deletes all faces, images and persons found for a given user.
158
	 *
159
	 * @param string $user ID of user to execute resetting for
160
	 * @param Int $modelId model to clean
161
	 *
162
	 * @return void
163
	 */
164
	public function resetModelForUser(string $userId, $modelId): void {
165
		$this->personMapper->deleteUserModel($userId, $modelId);
166
		$this->faceMapper->deleteUserModel($userId, $modelId);
167
		$this->imageMapper->deleteUserModel($userId, $modelId);
168
169
		$this->settingsService->setUserFullScanDone(false, $userId);
170
	}
171
172
	/**
173
	 * Reset error in images in order to re-analyze again.
174
	 * If no user is given, resetting is executed for all users.
175
	 *
176
	 * @param IUser|null $user Optional user to execute resetting for
177
	 *
178
	 * @return void
179
	 */
180
	public function resetImageErrors(IUser $user = null): void {
181
		$eligible_users = $this->getEligiblesUserId($user);
182
		foreach($eligible_users as $userId) {
183
			$this->imageMapper->resetErrors($userId);
184
			$this->settingsService->setUserFullScanDone(false, $userId);
185
		}
186
	}
187
188
	/**
189
	 * Eliminate all faces relations with person.
190
	 * If no user is given, resetting is executed for all users.
191
	 *
192
	 * @param IUser|null $user Optional user to execute resetting for
193
	 *
194
	 * @return void
195
	 */
196
	public function resetClusters(IUser $user = null): void {
197
		$eligible_users = $this->getEligiblesUserId($user);
198
		foreach($eligible_users as $user) {
199
			$this->resetClustersForUser($user);
200
		}
201
	}
202
203
	/**
204
	 * Eliminate all faces relations with person.
205
	 *
206
	 * @param string $user ID of user to execute resetting for
207
	 *
208
	 * @return void
209
	 */
210
	public function resetClustersForUser(string $userId): void {
211
		$model = $this->settingsService->getCurrentFaceModel();
212
213
		$this->faceMapper->unsetPersonsRelationForUser($userId, $model);
214
		$this->personMapper->deleteUserPersons($userId);
215
	}
216
217
	/**
218
	 * Get an array with the eligibles users taking into account the user argument,
219
	 * or all users.
220
	 *
221
	 * @param IUser|null $user Optional user to get specific user.
222
	 */
223
	private function getEligiblesUserId(IUser $user = null): array {
224
		$eligible_users = array();
225
		if (is_null($user)) {
226
			$this->userManager->callForAllUsers(function (IUser $user) use (&$eligible_users) {
227
				$eligible_users[] = $user->getUID();
228
			});
229
		} else {
230
			$eligible_users[] = $user->getUID();
231
		}
232
		return $eligible_users;
233
	}
234
235
}