Issues (125)

lib/Command/SetupCommand.php (2 issues)

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
37
use OCA\FaceRecognition\Helper\CommandLock;
38
use OCA\FaceRecognition\Helper\MemoryLimits;
39
40
use OCP\Util as OCP_Util;
41
42
class SetupCommand extends Command {
43
44
	/** @var ModelManager */
45
	protected $modelManager;
46
47
	/** @var SettingsService */
48
	private $settingsService;
49
50
	/** @var OutputInterface */
51
	protected $logger;
52
53
	/**
54
	 * @param ModelManager $modelManager
55
	 * @param SettingsService $settingsService
56
	 */
57
	public function __construct(ModelManager    $modelManager,
58
	                            SettingsService $settingsService)
59
	{
60
		parent::__construct();
61
62
		$this->modelManager    = $modelManager;
63
		$this->settingsService = $settingsService;
64
	}
65
66
	/**
67
	 * @return void
68
	 */
69
	protected function configure() {
70
		$this
71
			->setName('face:setup')
72
			->setDescription('Basic application settings, such as maximum memory, and the model used.')
73
			->addOption(
74
				'memory',
75
				'M',
76
				InputOption::VALUE_REQUIRED,
77
				'The maximum memory assigned for image processing',
78
				-1
79
			)
80
			->addOption(
81
				'model',
82
				'm',
83
				InputOption::VALUE_REQUIRED,
84
				'The identifier number of the model to install',
85
				-1
86
			);
87
	}
88
89
	/**
90
	 * @param InputInterface $input
91
	 * @param OutputInterface $output
92
	 * @return int
93
	 */
94
	protected function execute(InputInterface $input, OutputInterface $output) {
95
		$this->logger = $output;
96
97
		$assignMemory = $input->getOption('memory');
98
		$modelId = $input->getOption('model');
99
100
		if ($assignMemory < 0 && $modelId < 0) {
101
			$this->dumpCurrentSetup();
102
			return 0;
103
		}
104
105
		// Get lock to avoid potential errors.
106
		//
107
		$lock = CommandLock::Lock("face:setup");
0 ignored issues
show
Are you sure the assignment to $lock is correct as OCA\FaceRecognition\Help...ock::Lock('face:setup') targeting OCA\FaceRecognition\Helper\CommandLock::lock() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
108
		if (!$lock) {
0 ignored issues
show
$lock is of type null, thus it always evaluated to false.
Loading history...
109
			$output->writeln("Another command ('". CommandLock::IsLockedBy().  "') is already running that prevents it from continuing.");
110
			return 1;
111
		}
112
113
		if ($assignMemory > 0) {
114
			$ret = $this->setupAssignedMemory(OCP_Util::computerFileSize($assignMemory));
115
			if ($ret > 0) {
116
				CommandLock::Unlock($lock);
117
				return $ret;
118
			}
119
		}
120
121
		if ($modelId > 0) {
122
			$ret = $this->setupModel($modelId);
123
			if ($ret > 0) {
124
				CommandLock::Unlock($lock);
125
				return $ret;
126
			}
127
		}
128
129
		// Release obtained lock
130
		//
131
		CommandLock::Unlock($lock);
132
133
		return 0;
134
	}
135
136
	private function setupAssignedMemory ($assignMemory): int {
137
		$systemMemory = MemoryLimits::getSystemMemory();
138
		$this->logger->writeln("System memory: " . ($systemMemory > 0 ? $this->getHumanMemory($systemMemory) : "Unknown"));
139
		$phpMemory = MemoryLimits::getPhpMemory();
140
		$this->logger->writeln("Memory assigned to PHP: " . ($phpMemory > 0 ? $this->getHumanMemory($phpMemory) : "Unlimited"));
141
142
		$this->logger->writeln("");
143
		$availableMemory = MemoryLimits::getAvailableMemory();
144
		$this->logger->writeln("Minimum value to assign to image processing.: " . $this->getHumanMemory(SettingsService::MINIMUM_ASSIGNED_MEMORY));
145
		$this->logger->writeln("Maximum value to assign to image processing.: " . ($availableMemory > 0 ? $this->getHumanMemory($availableMemory) : "Unknown"));
146
147
		$this->logger->writeln("");
148
		if ($assignMemory > $availableMemory) {
149
			$this->logger->writeln("Cannot assign more memory than the maximum...");
150
			return 1;
151
		}
152
153
		if ($assignMemory < SettingsService::MINIMUM_ASSIGNED_MEMORY) {
154
			$this->logger->writeln("Cannot assign less memory than the minimum...");
155
			return 1;
156
		}
157
158
		$this->settingsService->setAssignedMemory ($assignMemory);
159
		$this->logger->writeln("Maximum memory assigned for image processing: " . $this->getHumanMemory($assignMemory));
160
161
		return 0;
162
	}
163
164
	private function setupModel (int $modelId): int {
165
		$this->logger->writeln("");
166
167
		$model = $this->modelManager->getModel($modelId);
168
		if (is_null($model)) {
169
			$this->logger->writeln('Invalid model Id');
170
			return 1;
171
		}
172
173
		$modelDescription = $model->getId() . ' (' . $model->getName(). ')';
174
175
		$error_message = "";
176
		if (!$model->meetDependencies($error_message)) {
177
			$this->logger->writeln('You do not meet the dependencies to install the model ' . $modelDescription);
178
			$this->logger->writeln('Summary: ' . $error_message);
179
			$this->logger->writeln('Please read the documentation for this model to continue: ' .$model->getDocumentation());
180
			return 1;
181
		}
182
183
		if ($model->isInstalled()) {
184
			$this->logger->writeln('The files of model ' . $modelDescription . ' are already installed');
185
			$this->modelManager->setDefault($modelId);
186
			$this->logger->writeln('The model ' . $modelDescription . ' was configured as default');
187
188
			return 0;
189
		}
190
191
		$this->logger->writeln('The model ' . $modelDescription . ' will be installed');
192
		$model->install();
193
		$this->logger->writeln('Install model ' . $modelDescription . ' successfully done');
194
195
		$this->modelManager->setDefault($modelId);
196
		$this->logger->writeln('The model ' . $modelDescription . ' was configured as default');
197
198
		return 0;
199
	}
200
201
	private function dumpCurrentSetup (): void {
202
		$this->logger->writeln("Current setup:");
203
		$this->logger->writeln('');
204
		$this->logger->writeln("Minimum value to assign to image processing.: " . $this->getHumanMemory(SettingsService::MINIMUM_ASSIGNED_MEMORY));
205
		$availableMemory = MemoryLimits::getAvailableMemory();
206
		$this->logger->writeln("Maximum value to assign to image processing.: " . ($availableMemory > 0 ? $this->getHumanMemory($availableMemory) : "Unknown"));
207
		$assignedMemory = $this->settingsService->getAssignedMemory();
208
		$this->logger->writeln("Maximum memory assigned for image processing: " . ($assignedMemory > 0 ? $this->getHumanMemory($assignedMemory) : "Pending configuration"));
209
210
		$this->logger->writeln('');
211
		$this->logger->writeln("Available models:");
212
		$table = new Table($this->logger);
213
		$table->setHeaders(['Id', 'Enabled', 'Name', 'Description']);
214
215
		$currentModel = $this->modelManager->getCurrentModel();
216
		$modelId = (!is_null($currentModel)) ? $currentModel->getId() : -1;
217
218
		$models = $this->modelManager->getAllModels();
219
		foreach ($models as $model) {
220
			$table->addRow([
221
				$model->getId(),
222
				($model->getId() === $modelId) ? '*' : '',
223
				$model->getName(),
224
				$model->getDescription()
225
			]);
226
		}
227
		$table->render();
228
	}
229
230
	private function getHumanMemory ($memory): string {
231
		return OCP_Util::humanFileSize($memory) . " (" . intval($memory) . "B)";
232
	}
233
234
}
235