Passed
Pull Request — master (#751)
by Matias
11:11 queued 08:36
created

PhotoAlbums::syncUserPersonNamesCombinedAlbum()   B

Complexity

Conditions 7
Paths 33

Size

Total Lines 51
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 7
eloc 34
c 1
b 0
f 1
nc 33
nop 3
dl 0
loc 51
ccs 0
cts 33
cp 0
crap 56
rs 8.4426

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
		$multiPersonMatchingImages = array();
248
		for ( $i = 1 ;  $i < count($multiPersonImages) ; ++$i){
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
249
			if ( $i === 1 ){
250
				$multiPersonMatchingImages = array_intersect($multiPersonImages[$i-1],$multiPersonImages[$i]);
251
			}else{
252
				$multiPersonMatchingImages = array_intersect($multiPersonMatchingImages,$multiPersonImages[$i]);
253
			}
254
		}
255
		return array_unique($multiPersonMatchingImages);
256
	}
257
258
}
259