PhotoAlbums   A
last analyzed

Complexity

Total Complexity 31

Size/Duplication

Total Lines 223
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 3
Bugs 1 Features 1
Metric Value
eloc 112
c 3
b 1
f 1
dl 0
loc 223
ccs 0
cts 112
cp 0
rs 9.92
wmc 31

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getPersonsImages() 0 7 2
A syncUserPersonNamesSelected() 0 35 6
B syncUserPersonNamesCombinedAlbum() 0 51 7
A getPersonsNamesSelected() 0 7 2
B syncUser() 0 38 6
A __construct() 0 9 1
A getPersonsNames() 0 7 2
A getMultiPersonsImages() 0 21 5
1
<?php
2
/**
3
 * @copyright Copyright (c) 2022 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
namespace OCA\FaceRecognition\Helper;
24
25
use OCP\IUser;
26
27
use Symfony\Component\Console\Output\OutputInterface;
28
29
use OCA\FaceRecognition\Db\ImageMapper;
30
use OCA\FaceRecognition\Db\PersonMapper;
31
use OCA\FaceRecognition\Album\AlbumMapper;
32
33
use OCA\FaceRecognition\Service\SettingsService;
34
35
class PhotoAlbums {
36
37
	/** @var PersonMapper Person mapper*/
38
	private $personMapper;
39
40
	/** @var ImageMapper Image mapper*/
41
	private $imageMapper;
42
43
	/** @var AlbumMapper Album mapper */
44
	private $albumMapper;
45
46
	/** @var SettingsService Settings service*/
47
	private $settingsService;
48
49
	/**
50
	 * @param PersonMapper $personMapper
51
	 * @param ImageMapper $imageMapper
52
	 * @param AlbumMapper $albumMapper
53
	 * @param SettingsService $settingsService
54
	 */
55
	public function __construct(PersonMapper    $personMapper,
56
	                            ImageMapper     $imageMapper,
57
	                            AlbumMapper     $albumMapper,
58
	                            SettingsService $settingsService)
59
	{
60
		$this->personMapper    = $personMapper;
61
		$this->imageMapper     = $imageMapper;
62
		$this->albumMapper     = $albumMapper;
63
		$this->settingsService = $settingsService;
64
	}
65
66
	/**
67
	 * @return void
68
	 */
69
	public function syncUser (string $userId) {
70
		$modelId = $this->settingsService->getCurrentFaceModel();
71
72
		/* Get current albums and persons to sync */
73
		$personNames = $this->getPersonsNames($userId, $modelId);
74
		$albumNames = $this->albumMapper->getAll($userId);
75
76
		/* Create albums for new persons */
77
		$albumsToCreate = array_diff ($personNames, $albumNames);
78
		foreach ($albumsToCreate as $albumToCreate) {
79
			$this->albumMapper->create($userId, $albumToCreate);
80
		}
81
82
		/* Remove albums for old persons */
83
		$albumsToDelete = array_diff ($albumNames, $personNames);
84
		foreach ($albumsToDelete as $albumToDelete) {
85
			$albumId = $this->albumMapper->get($userId, $albumToDelete);
86
			$this->albumMapper->delete($albumId);
87
		}
88
89
		/* Find person's images and sync */
90
		foreach ($personNames as $albumName) {
91
			$albumId = $this->albumMapper->get($userId, $albumName);
92
93
			/* Get images within albums and person's to compare and sync */
94
			$albumImages = $this->albumMapper->getFiles($albumId);
95
			$personImages = $this->getPersonsImages($userId, $modelId, $albumName);
96
97
			/* Delete old photos. Maybe corrections. */
98
			$imagesToDelete = array_diff ($albumImages, $personImages);
99
			foreach ($imagesToDelete as $image) {
100
				$this->albumMapper->removeFile($albumId, $image);
101
			}
102
103
			/* Add new photos to the person's album */
104
			$imagesToAdd = array_diff ($personImages, $albumImages);
105
			foreach ($imagesToAdd as $image) {
106
				$this->albumMapper->addFile($albumId, $image, $userId);
107
			}
108
		}
109
	}
110
111
	/**
112
	 * @return void
113
	 */
114
	public function syncUserPersonNamesSelected (string $userId, string $personNames, OutputInterface $output) {
115
		$modelId = $this->settingsService->getCurrentFaceModel();
116
117
		/* Get current albums and persons to sync */
118
		$personsNames = $this->getPersonsNamesSelected($userId, $modelId, $personNames);
119
		if ( count($personsNames) === 0 ){
120
			$output->writeln("Person name $personNames invalid - skipping");
121
			return;
122
		}
123
		$albumNames = $this->albumMapper->getAll($userId);
124
125
		/* Create albums for new persons */
126
		$albumsToCreate = array_diff ($personsNames, $albumNames);
127
		foreach ($albumsToCreate as $albumToCreate) {
128
			$this->albumMapper->create($userId, $albumToCreate);
129
		}
130
131
		/* Find person's images and sync */
132
		foreach ($personsNames as $albumName) {
133
			$albumId = $this->albumMapper->get($userId, $albumName);
134
135
			/* Get images within albums and person's to compare and sync */
136
			$albumImages = $this->albumMapper->getFiles($albumId);
137
			$personImages = $this->getPersonsImages($userId, $modelId, $albumName);
138
139
			/* Delete old photos. Maybe corrections. */
140
			$imagesToDelete = array_diff ($albumImages, $personImages);
141
			foreach ($imagesToDelete as $image) {
142
				$this->albumMapper->removeFile($albumId, $image);
143
			}
144
145
			/* Add new photos to the person's album */
146
			$imagesToAdd = array_diff ($personImages, $albumImages);
147
			foreach ($imagesToAdd as $image) {
148
				$this->albumMapper->addFile($albumId, $image, $userId);
149
			}
150
		}
151
	}
152
153
	/**
154
	 * @return void
155
	 */
156
	public function syncUserPersonNamesCombinedAlbum (string $userId, array $personList, OutputInterface $output) {
157
		$modelId = $this->settingsService->getCurrentFaceModel();
158
159
		/* Get current albums and persons to sync */
160
		$albumToCreateCombined = "";
161
		$albumTodo = array();
162
		$personNames = array();
163
		foreach ($personList as $person) {
164
			$personName = $this->getPersonsNamesSelected($userId, $modelId, $person);
165
			if ( $personName[0] === $person ){
166
				array_push($personNames, $personName[0]);
167
				$albumToCreateCombined .= $personName[0] . "+";
168
			}else{
169
				$output->writeln("Person name $person invalid - exit without creating combined album");
170
				return;
171
			}
172
		}
173
		$albumToCreateCombined = rtrim($albumToCreateCombined, "+");
174
		array_push($albumTodo, $albumToCreateCombined);
175
		$albumNames = $this->albumMapper->getAll($userId);
176
177
		/* Create albums for new persons */
178
		$albumsToCreate = array_diff ($albumTodo, $albumNames);
179
		$countAlbumsToCreate = count($albumsToCreate);
180
		if ($countAlbumsToCreate === 1) {
181
			$albumToCreate = $albumsToCreate[0];
182
			$this->albumMapper->create($userId, $albumToCreate);
183
		}
184
185
		if ($countAlbumsToCreate === 1) {
186
			$albumToCreate = $albumsToCreate[0];
187
			$albumId = $this->albumMapper->get($userId, $albumToCreate);
188
		} else {
189
			$albumToCreate = $albumTodo[0];
190
			$albumId = $this->albumMapper->get($userId, $albumToCreate);
191
		}
192
193
		/* Get images within albums and person's to compare and sync */
194
		$albumImages = $this->albumMapper->getFiles($albumId);
195
		$personImages = $this->getMultiPersonsImages($userId, $modelId, $personNames);
196
197
		/* Delete old photos. Maybe corrections. */
198
		$imagesToDelete = array_diff ($albumImages, $personImages);
199
		foreach ($imagesToDelete as $image) {
200
			$this->albumMapper->removeFile($albumId, $image);
201
		}
202
203
		/* Add new photos to the person's album */
204
		$imagesToAdd = array_diff ($personImages, $albumImages);
205
		foreach ($imagesToAdd as $image) {
206
			$this->albumMapper->addFile($albumId, $image, $userId);
207
		}
208
	}
209
210
	private function getPersonsNames(string $userId, int $modelId): array {
211
		$distintNames = $this->personMapper->findDistinctNames($userId, $modelId);
212
		$names = [];
213
		foreach ($distintNames as $distintName) {
214
			$names[] = $distintName->getName();
215
		}
216
		return $names;
217
	}
218
219
	private function getPersonsNamesSelected(string $userId, int $modelId, string $faceNames): array {
220
		$distintNames = $this->personMapper->findDistinctNamesSelected($userId, $modelId, $faceNames);
221
		$names = [];
222
		foreach ($distintNames as $distintName) {
223
			$names[] = $distintName->getName();
224
		}
225
		return $names;
226
	}
227
228
	private function getPersonsImages(string $userId, int $modelId, string $personName): array {
229
		$personImages = $this->imageMapper->findFromPerson($userId, $modelId, $personName);
230
		$images = [];
231
		foreach ($personImages as $image) {
232
			$images[] = $image->getFile();
233
		}
234
		return array_unique($images);
235
	}
236
237
	private function getMultiPersonsImages(string $userId, int $modelId, array $personNames): array {
238
		$multiPersonImages = array();
239
		foreach ($personNames as $personName){
240
			$personImages = $this->imageMapper->findFromPerson($userId, $modelId, $personName);
241
			$images = [];
242
			foreach ($personImages as $image) {
243
				$images[] = $image->getFile();
244
			}
245
			array_push($multiPersonImages, $images);
246
		}
247
248
		$noPersons = count($multiPersonImages);
249
		$multiPersonMatchingImages = array();
250
		for ($i = 1 ;  $i < $noPersons ; ++$i) {
251
			if ($i === 1) {
252
				$multiPersonMatchingImages = array_intersect($multiPersonImages[$i-1], $multiPersonImages[$i]);
253
			} else {
254
				$multiPersonMatchingImages = array_intersect($multiPersonMatchingImages, $multiPersonImages[$i]);
255
			}
256
		}
257
		return array_unique($multiPersonMatchingImages);
258
	}
259
260
}
261