Passed
Push — split-cluster-person ( bb4f7f...7f7263 )
by Matias
05:36
created

SettingsService   A

Complexity

Total Complexity 36

Size/Duplication

Total Lines 253
Duplicated Lines 0 %

Test Coverage

Coverage 65.52%

Importance

Changes 15
Bugs 0 Features 0
Metric Value
eloc 93
dl 0
loc 253
ccs 57
cts 87
cp 0.6552
rs 9.52
c 15
b 0
f 0
wmc 36

29 Methods

Rating   Name   Duplication   Size   Complexity  
A setObfuscateFaces() 0 2 2
A isAllowedMimetype() 0 10 2
A getMaximumImageArea() 0 2 1
A getObfuscateFaces() 0 3 1
A getSensitivity() 0 2 1
A setSensitivity() 0 2 1
A getCurrentFaceModel() 0 2 1
A getAnalysisImageArea() 0 2 1
A _setForceCreateClusters() 0 2 2
A getUserEnabled() 0 3 1
A getMinimumConfidence() 0 2 1
A getLastStaleImageChecked() 0 2 1
A getHandleExternalFiles() 0 3 1
A setUserFullScanDone() 0 2 2
A setNeedRecreateClusters() 0 2 2
A setLastStaleImageChecked() 0 2 1
A setMinimumConfidence() 0 2 1
A _getForceCreateClusters() 0 3 1
A getMinimumImageSize() 0 2 1
A getNeedRemoveStaleImages() 0 3 1
A getHandleSharedFiles() 0 3 1
A setCurrentFaceModel() 0 2 1
A getMinimumFaceSize() 0 5 1
A setNeedRemoveStaleImages() 0 2 2
A __construct() 0 5 1
A setAnalysisImageArea() 0 2 1
A getNeedRecreateClusters() 0 3 1
A getUserFullScanDone() 0 3 1
A setUserEnabled() 0 2 2
1
<?php
2
declare(strict_types=1);
3
/**
4
 * @copyright Copyright (c) 2020 Matias De lellis <[email protected]>
5
 *
6
 * @author Matias De lellis <[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 OCA\FaceRecognition\AppInfo\Application;
28
29
use OCA\FaceRecognition\Model\ModelManager;
30
31
use OCP\IConfig;
32
33
class SettingsService {
34
35
	/*
36
	 * System
37
	 */
38
	const MINIMUM_SYSTEM_MEMORY_REQUIREMENTS = 1 * 1024 * 1024 * 1024;
39
40
	/*
41
	 * Settings keys and default values.
42
	 */
43
44
	/** Current Model used to analyze */
45
	const CURRENT_MODEL_KEY = 'model';
46
	const FALLBACK_CURRENT_MODEL = -1;
47
48
	/** Image area that used used for analysis */
49
	const ANALYSIS_IMAGE_AREA_KEY = 'analysis_image_area';
50
	const MINIMUM_ANALYSIS_IMAGE_AREA = 640*480;
51
	const DEFAULT_ANALYSIS_IMAGE_AREA = -1; // It is dynamically configured according to hardware
52
	const MAXIMUM_ANALYSIS_IMAGE_AREA = 3840*2160;
53
54
	/** Sensitivity used to clustering */
55
	const SENSITIVITY_KEY = 'sensitivity';
56
	const MINIMUM_SENSITIVITY = '0.2';
57
	const DEFAULT_SENSITIVITY = '0.4';
58
	const MAXIMUM_SENSITIVITY = '0.6';
59
60
	/** Minimum confidence used to try to clustring faces */
61
	const MINIMUM_CONFIDENCE_KEY = 'min_confidence';
62
	const MINIMUM_MINIMUM_CONFIDENCE = '0.0';
63
	const DEFAULT_MINIMUM_CONFIDENCE = '0.99';
64
	const MAXIMUM_MINIMUM_CONFIDENCE = '1.1';
65
66
	/** Minimum face size used to try to clustring faces */
67
	const MINIMUM_FACE_SIZE_KEY = 'min_face_size';
68
	const MINIMUM_MINIMUM_FACE_SIZE = '0';
69
	const DEFAULT_MINIMUM_FACE_SIZE = '40';
70
	const MAXIMUM_MINIMUM_FACE_SIZE = '250';
71
72
	/** User setting what indicates if has the analysis enabled */
73
	const USER_ENABLED_KEY = 'enabled';
74
	const DEFAULT_USER_ENABLED = 'false';
75
76
	/** User setting that remember last images checked */
77
	const STALE_IMAGES_LAST_CHECKED_KEY = 'stale_images_last_checked';
78
	const DEFAULT_STALE_IMAGES_LAST_CHECKED = '0';
79
80
	/** Define if for some reason need remove old images */
81
	const STALE_IMAGES_REMOVAL_NEEDED_KEY = 'stale_images_removal_needed';
82
	const DEFAULT_STALE_IMAGES_REMOVAL_NEEDED = 'false';
83
84
	/** User setting that indicate when scan finished */
85
	const FULL_IMAGE_SCAN_DONE_KEY = 'full_image_scan_done';
86
	const DEFAULT_FULL_IMAGE_SCAN_DONE = 'false';
87
88
	/** User setting that indicate that need to recreate clusters */
89
	const USER_RECREATE_CLUSTERS_KEY = 'recreate_clusters';
90
	const DEFAULT_USER_RECREATE_CLUSTERS = 'false';
91
92
	/** User setting that indicate that is forced to create clusters */
93
	const FORCE_CREATE_CLUSTERS_KEY = 'force_create_clusters';
94
	const DEFAULT_FORCE_CREATE_CLUSTERS = 'false';
95
96
	/** Hidden setting that allows to analyze shared files */
97
	const HANDLE_SHARED_FILES_KEY = 'handle_shared_files';
98
	const DEFAULT_HANDLE_SHARED_FILES = 'false';
99
100
	/** Hidden setting that allows to analyze external files */
101
	const HANDLE_EXTERNAL_FILES_KEY = 'handle_external_files';
102
	const DEFAULT_HANDLE_EXTERNAL_FILES = 'false';
103
104
	/** Hidden setting that indicate minimum large of image to analyze */
105
	const MINIMUM_IMAGE_SIZE_KEY = 'min_image_size';
106
	const DEFAULT_MINIMUM_IMAGE_SIZE = '512';
107
108
	/** Hidden setting that indicate maximum area of image to analyze */
109
	const MAXIMUM_IMAGE_AREA_KEY = 'max_image_area';
110
	const DEFAULT_MAXIMUM_IMAGE_AREA = '-1';
111
112
	/** Hidden setting that allows obfuscate that faces for security */
113
	const OBFUSCATE_FACE_THUMBS_KEY = 'obfuscate_faces';
114
	const DEFAULT_OBFUSCATE_FACE_THUMBS = 'false';
115
116
	/** System setting to enable mimetypes */
117
	const SYSTEM_ENABLED_MIMETYPES = 'enabledFaceRecognitionMimetype';
118
	private $allowedMimetypes = ['image/jpeg', 'image/png'];
119
	private $cachedAllowedMimetypes = false;
120
121
	/**
122
	 * SettingsService
123
	 */
124
125
	/** @var IConfig Config */
126
	private $config;
127
128
	/**  @var string|null */
129
	private $userId;
130
131
	/**
132
	 * @param IConfig $config
133
	 * @param string $userId
134
	 */
135 1
	public function __construct(IConfig $config,
136
	                            $userId)
137
	{
138 1
		$this->config = $config;
139 1
		$this->userId = $userId;
140 1
	}
141
142
	/*
143
	 * User settings.
144
	 */
145 10
	public function getUserEnabled ($userId = null): bool {
146 10
		$enabled = $this->config->getUserValue($userId ?? $this->userId, Application::APP_NAME, self::USER_ENABLED_KEY, self::DEFAULT_USER_ENABLED);
147 10
		return ($enabled === 'true');
148
	}
149
150
	public function setUserEnabled (bool $enabled, $userId = null) {
151
		$this->config->setUserValue($userId ?? $this->userId, Application::APP_NAME, self::USER_ENABLED_KEY, $enabled ? "true" : "false");
152
	}
153
154 10
	public function getUserFullScanDone ($userId = null): bool {
155 10
		$fullScanDone = $this->config->getUserValue($userId ?? $this->userId, Application::APP_NAME, self::FULL_IMAGE_SCAN_DONE_KEY, self::DEFAULT_FULL_IMAGE_SCAN_DONE);
156 10
		return ($fullScanDone === 'true');
157
	}
158
159 28
	public function setUserFullScanDone (bool $fullScanDone, $userId = null) {
160 28
		$this->config->setUserValue($userId ?? $this->userId, Application::APP_NAME, self::FULL_IMAGE_SCAN_DONE_KEY, $fullScanDone ? "true" : "false");
161 28
	}
162
163 3
	public function getNeedRemoveStaleImages ($userId = null): bool {
164 3
		$needRemoval = $this->config->getUserValue($userId ?? $this->userId, Application::APP_NAME, self::STALE_IMAGES_REMOVAL_NEEDED_KEY, self::DEFAULT_STALE_IMAGES_REMOVAL_NEEDED);
165 3
		return ($needRemoval === 'true');
166
	}
167
168 2
	public function setNeedRemoveStaleImages (bool $needRemoval, $userId = null) {
169 2
		$this->config->setUserValue($userId ?? $this->userId, Application::APP_NAME, self::STALE_IMAGES_REMOVAL_NEEDED_KEY, $needRemoval ? "true" : "false");
170 2
	}
171
172 2
	public function getLastStaleImageChecked ($userId = null): int {
173 2
		return intval($this->config->getUserValue($userId ?? $this->userId, Application::APP_NAME, self::STALE_IMAGES_LAST_CHECKED_KEY, self::DEFAULT_STALE_IMAGES_LAST_CHECKED));
174
	}
175
176 2
	public function setLastStaleImageChecked (int $lastCheck, $userId = null) {
177 2
		$this->config->setUserValue($userId ?? $this->userId, Application::APP_NAME, self::STALE_IMAGES_LAST_CHECKED_KEY, $lastCheck);
178 2
	}
179
180
	public function getNeedRecreateClusters ($userId = null): bool {
181
		$needRecreate = $this->config->getUserValue($userId ?? $this->userId, Application::APP_NAME, self::USER_RECREATE_CLUSTERS_KEY, self::DEFAULT_USER_RECREATE_CLUSTERS);
182
		return ($needRecreate === 'true');
183
	}
184
185 1
	public function setNeedRecreateClusters (bool $needRecreate, $userId = null) {
186 1
		$this->config->setUserValue($userId ?? $this->userId, Application::APP_NAME, self::USER_RECREATE_CLUSTERS_KEY, $needRecreate ? "true" : "false");
187 1
	}
188
189
	// Private function used only on tests
190 1
	public function _getForceCreateClusters ($userId = null): bool {
191 1
		$forceCreate = $this->config->getUserValue($userId ?? $this->userId, Application::APP_NAME, self::FORCE_CREATE_CLUSTERS_KEY, self::DEFAULT_FORCE_CREATE_CLUSTERS);
192 1
		return ($forceCreate === 'true');
193
	}
194
195
	// Private function used only on tests
196 1
	public function _setForceCreateClusters (bool $forceCreate, $userId = null) {
197 1
		$this->config->setUserValue($userId ?? $this->userId, Application::APP_NAME, self::FORCE_CREATE_CLUSTERS_KEY, $forceCreate ? "true" : "false");
198 1
	}
199
200
	/*
201
	 * Admin and process settings.
202
	 */
203 12
	public function getCurrentFaceModel(): int {
204 12
		return intval($this->config->getAppValue(Application::APP_NAME, self::CURRENT_MODEL_KEY, self::FALLBACK_CURRENT_MODEL));
205
	}
206
207
	public function setCurrentFaceModel(int $model) {
208
		$this->config->setAppValue(Application::APP_NAME, self::CURRENT_MODEL_KEY, strval($model));
209
	}
210
211 4
	public function getAnalysisImageArea(): int {
212 4
		return intval($this->config->getAppValue(Application::APP_NAME, self::ANALYSIS_IMAGE_AREA_KEY, self::DEFAULT_ANALYSIS_IMAGE_AREA));
213
	}
214
215
	public function setAnalysisImageArea(int $imageArea) {
216
		$this->config->setAppValue(Application::APP_NAME, self::ANALYSIS_IMAGE_AREA_KEY, strval($imageArea));
217
	}
218
219 1
	public function getSensitivity(): float {
220 1
		return floatval($this->config->getAppValue(Application::APP_NAME, self::SENSITIVITY_KEY, self::DEFAULT_SENSITIVITY));
221
	}
222
223
	public function setSensitivity($sensitivity) {
224
		$this->config->setAppValue(Application::APP_NAME, self::SENSITIVITY_KEY, $sensitivity);
225
	}
226
227 1
	public function getMinimumConfidence(): float {
228 1
		return floatval($this->config->getAppValue(Application::APP_NAME, self::MINIMUM_CONFIDENCE_KEY, self::DEFAULT_MINIMUM_CONFIDENCE));
229
	}
230
231
	public function setMinimumConfidence($confidence) {
232
		$this->config->setAppValue(Application::APP_NAME, self::MINIMUM_CONFIDENCE_KEY, $confidence);
233
	}
234
235
	/**
236
	 * The next settings are advanced preferences that are not available in gui.
237
	 * See: https://github.com/matiasdelellis/facerecognition/wiki/Settings#hidden-settings
238
	 */
239
	public function getHandleSharedFiles(): bool {
240
		$handle = $this->config->getAppValue(Application::APP_NAME, self::HANDLE_SHARED_FILES_KEY, self::DEFAULT_HANDLE_SHARED_FILES);
241
		return ($handle === 'true');
242
	}
243
244
	public function getHandleExternalFiles(): bool {
245
		$handle = $this->config->getAppValue(Application::APP_NAME, self::HANDLE_EXTERNAL_FILES_KEY, self::DEFAULT_HANDLE_EXTERNAL_FILES);
246
		return ($handle === 'true');
247
	}
248
249 4
	public function getMinimumImageSize(): int {
250 4
		return intval($this->config->getAppValue(Application::APP_NAME, self::MINIMUM_IMAGE_SIZE_KEY, self::DEFAULT_MINIMUM_IMAGE_SIZE));
251
	}
252
253 1
	public function getMinimumFaceSize(): int {
254 1
		$minFaceSize = intval($this->config->getAppValue(Application::APP_NAME, self::MINIMUM_FACE_SIZE_KEY, self::DEFAULT_MINIMUM_FACE_SIZE));
255 1
		$minFaceSize = max(self::MINIMUM_MINIMUM_FACE_SIZE, $minFaceSize);
256 1
		$minFaceSize = min($minFaceSize, self::MAXIMUM_MINIMUM_FACE_SIZE);
257 1
		return intval($minFaceSize);
258
	}
259
260 4
	public function getMaximumImageArea(): int {
261 4
		return intval($this->config->getAppValue(Application::APP_NAME, self::MAXIMUM_IMAGE_AREA_KEY, self::DEFAULT_MAXIMUM_IMAGE_AREA));
262
	}
263
264
	public function getObfuscateFaces(): bool {
265
		$obfuscate = $this->config->getAppValue(Application::APP_NAME, self::OBFUSCATE_FACE_THUMBS_KEY, self::DEFAULT_OBFUSCATE_FACE_THUMBS);
266
		return ($obfuscate === 'true');
267
	}
268
269
	public function setObfuscateFaces(bool $obfuscate) {
270
		$this->config->setAppValue(Application::APP_NAME, self::OBFUSCATE_FACE_THUMBS_KEY, $obfuscate ? 'true' : 'false');
271
	}
272
273
	/**
274
	 * System settings that must be configured according to the server configuration.
275
	 */
276 8
	public function isAllowedMimetype(string $mimetype): bool {
277 8
		if (!$this->cachedAllowedMimetypes) {
278 1
			$systemMimetypes = $this->config->getSystemValue(self::SYSTEM_ENABLED_MIMETYPES, $this->allowedMimetypes);
279 1
			$this->allowedMimetypes = array_merge($this->allowedMimetypes, $systemMimetypes);
280 1
			$this->allowedMimetypes = array_unique($this->allowedMimetypes);
281
282 1
			$this->cachedAllowedMimetypes = true;
283
		}
284
285 8
		return in_array($mimetype, $this->allowedMimetypes);
286
	}
287
288
}
289