Passed
Pull Request — master (#534)
by Matias
07:20 queued 04:42
created

SetupCommand::getHumanMemory()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 2
ccs 0
cts 2
cp 0
crap 2
rs 10
1
<?php
2
/**
3
 * @copyright Copyright (c) 2019-2020 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\Command;
24
25
use Symfony\Component\Console\Command\Command;
26
use Symfony\Component\Console\Helper\Table;
27
use Symfony\Component\Console\Input\InputOption;
28
use Symfony\Component\Console\Input\InputInterface;
29
use Symfony\Component\Console\Output\OutputInterface;
30
31
use OCA\FaceRecognition\Model\IModel;
32
33
use OCA\FaceRecognition\Model\ModelManager;
34
35
use OCA\FaceRecognition\Service\SettingsService;
36
use OCA\FaceRecognition\Helper\MemoryLimits;
37
38
use OCP\Util as OCP_Util;
39
40
class SetupCommand extends Command {
41
42
	/** @var ModelManager */
43
	protected $modelManager;
44
45
	/** @var SettingsService */
46
	private $settingsService;
47
48
	/** @var OutputInterface */
49
	protected $logger;
50
51
	/**
52
	 * @param ModelManager $modelManager
53
	 * @param SettingsService $settingsService
54
	 */
55
	public function __construct(ModelManager    $modelManager,
56
	                            SettingsService $settingsService)
57
	{
58
		parent::__construct();
59
60
		$this->modelManager    = $modelManager;
61
		$this->settingsService = $settingsService;
62
	}
63
64
	/**
65
	 * @return void
66
	 */
67
	protected function configure() {
68
		$this
69
			->setName('face:setup')
70
			->setDescription('Basic application settings, such as maximum memory, and the model used.')
71
			->addOption(
72
				'memory',
73
				'M',
74
				InputOption::VALUE_REQUIRED,
75
				'The maximum memory assigned for image processing',
76
				-1
77
			)
78
			->addOption(
79
				'model',
80
				'm',
81
				InputOption::VALUE_OPTIONAL,
82
				'The identifier number of the model to install',
83
				-1
84
			);
85
	}
86
87
	/**
88
	 * @param InputInterface $input
89
	 * @param OutputInterface $output
90
	 * @return int
91
	 */
92
	protected function execute(InputInterface $input, OutputInterface $output) {
93
		$this->logger = $output;
94
95
		$assignMemory = $input->getOption('memory');
96
		if ($assignMemory > 0) {
97
			return $this->setupAssignedMemory(OCP_Util::computerFileSize($assignMemory));
98
		}
99
100
		$modelId = $input->getOption('model');
101
		if ($modelId > 0) {
102
			return $this->setupModel($modelId);
103
		}
104
		else {
105
			$this->logger->writeln('You must indicate the ID of the model to install...');
106
			$this->dumpModels();
107
			return 0;
108
		}
109
110
		return 0;
0 ignored issues
show
Unused Code introduced by
return 0 is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
111
	}
112
113
	private function setupAssignedMemory ($assignMemory): int {
114
		$systemMemory = MemoryLimits::getSystemMemory();
115
		$this->logger->writeln("System memory: " . ($systemMemory > 0 ? $this->getHumanMemory($systemMemory) : "Unknown"));
0 ignored issues
show
Bug introduced by
$systemMemory of type double is incompatible with the type integer expected by parameter $memory of OCA\FaceRecognition\Comm...mmand::getHumanMemory(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

115
		$this->logger->writeln("System memory: " . ($systemMemory > 0 ? $this->getHumanMemory(/** @scrutinizer ignore-type */ $systemMemory) : "Unknown"));
Loading history...
116
		$phpMemory = MemoryLimits::getPhpMemory();
117
		$this->logger->writeln("Memory assigned to PHP: " . ($phpMemory > 0 ? $this->getHumanMemory($phpMemory) : "Unlimited"));
118
119
		$this->logger->writeln("");
120
		$availableMemory = MemoryLimits::getAvailableMemory();
121
		$this->logger->writeln("Minimum value to assign to image processing.: " . $this->getHumanMemory(SettingsService::MINIMUM_ASSIGNED_MEMORY));
122
		$this->logger->writeln("Maximum value to assign to image processing.: " . ($availableMemory > 0 ? $this->getHumanMemory($availableMemory) : "Unknown"));
123
124
		$this->logger->writeln("");
125
		if ($assignMemory > $availableMemory) {
126
			$this->logger->writeln("Cannot assign more memory than the maximum...");
127
			return 1;
128
		}
129
130
		if ($assignMemory < SettingsService::MINIMUM_ASSIGNED_MEMORY) {
131
			$this->logger->writeln("Cannot assign less memory than the minimum...");
132
			return 1;
133
		}
134
135
		$this->settingsService->setAssignedMemory ($assignMemory);
136
		$this->logger->writeln("Maximum memory assigned for image processing: " . $this->getHumanMemory($assignMemory));
137
138
		return 0;
139
	}
140
141
	private function setupModel (int $modelId): int {
142
		$model = $this->modelManager->getModel($modelId);
143
		if (is_null($model)) {
144
			$this->logger->writeln('Invalid model Id');
145
			return 1;
146
		}
147
148
		$modelDescription = $model->getId() . ' (' . $model->getName(). ')';
149
150
		$error_message = "";
151
		if (!$model->meetDependencies($error_message)) {
152
			$this->logger->writeln('You do not meet the dependencies to install the model ' . $modelDescription);
153
			$this->logger->writeln('Summary: ' . $error_message);
154
			$this->logger->writeln('Please read the documentation for this model to continue: ' .$model->getDocumentation());
155
			return 1;
156
		}
157
158
		if ($model->isInstalled()) {
159
			$this->logger->writeln('The files of model ' . $modelDescription . ' are already installed');
160
			$this->modelManager->setDefault($modelId);
161
			$this->logger->writeln('The model ' . $modelDescription . ' was configured as default');
162
163
			return 0;
164
		}
165
166
		$this->logger->writeln('The model ' . $modelDescription . ' will be installed');
167
		$model->install();
168
		$this->logger->writeln('Install model ' . $modelDescription . ' successfully done');
169
170
		$this->modelManager->setDefault($modelId);
171
		$this->logger->writeln('The model ' . $modelDescription . ' was configured as default');
172
173
		return 0;
174
	}
175
176
	/**
177
	 * Print list of models
178
	 *
179
	 * @return void
180
	 */
181
	private function dumpModels(): void {
182
		$this->logger->writeln('');
183
		$table = new Table($this->logger);
184
		$table->setHeaders(['Id', 'Enabled', 'Name', 'Description']);
185
186
		$currentModel = $this->modelManager->getCurrentModel();
187
		$modelId = (!is_null($currentModel)) ? $currentModel->getId() : -1;
188
189
		$models = $this->modelManager->getAllModels();
190
		foreach ($models as $model) {
191
			$table->addRow([
192
				$model->getId(),
193
				($model->getId() === $modelId) ? '*' : '',
194
				$model->getName(),
195
				$model->getDescription()
196
			]);
197
		}
198
		$table->render();
199
	}
200
201
	private function getHumanMemory (int $memory): string {
202
		return OCP_Util::humanFileSize($memory) . " (" . $memory . "B)";
203
	}
204
205
}
206