Issues (125)

lib/Helper/Imaginary.php (4 issues)

1
<?php
2
/**
3
 * @copyright Copyright (c) 2022-2023, Matias De lellis
4
 *
5
 * @author Matias De lellis <[email protected]>
6
 *
7
 * @license AGPL-3.0-or-later
8
 *
9
 * This code is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Affero General Public License, version 3,
11
 * as published by the Free Software Foundation.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
 * GNU Affero General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Affero General Public License, version 3,
19
 * along with this program. If not, see <http://www.gnu.org/licenses/>
20
 *
21
 */
22
23
namespace OCA\FaceRecognition\Helper;
24
25
use OCP\Files\File;
26
use OCP\Http\Client\IClientService;
27
use OCP\IConfig;
28
use OCP\IImage;
29
30
use OC\StreamImage;
0 ignored issues
show
The type OC\StreamImage was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
31
32
class Imaginary {
33
34
	/** @var IConfig */
35
	private $config;
36
37
	/** @var IClientService */
38
	private $service;
39
40 5
	public function __construct() {
41 5
		$this->config = \OC::$server->get(IConfig::class);
42 5
		$this->service = \OC::$server->get(IClientService::class);
43
	}
44
45 5
	public function isEnabled(): bool {
46 5
		$imaginaryUrl = $this->config->getSystemValueString('preview_imaginary_url', 'invalid');
47 5
		return ($imaginaryUrl !== 'invalid');
48
	}
49
50
	public function getUrl(): ?string {
51
		$imaginaryUrl = $this->config->getSystemValueString('preview_imaginary_url', 'invalid');
52
		if ($imaginaryUrl === 'invalid')
53
			return null;
54
55
		return rtrim($imaginaryUrl, '/');
56
	}
57
58
	public function hasKey(): bool {
59
		$imaginaryKey = $this->config->getSystemValueString('preview_imaginary_key', 'invalid');
60
		return ($imaginaryKey !== 'invalid');
61
	}
62
63
	public function getKey(): ?string {
64
		$imaginaryKey = $this->config->getSystemValueString('preview_imaginary_key', 'invalid');
65
		if ($imaginaryKey === 'invalid')
66
			return null;
67
               
68
		return $imaginaryKey;
69
	}
70
71
	/**
72
	 * @return string imaginary version
73
	 */
74
	public function getVersion(): ?string {
75
		$imaginaryUrl = $this->getUrl();
76
		if (!$imaginaryUrl) {
77
			throw new \RuntimeException('Try to use imaginary without valid url');
78
		}
79
80
		$httpClient = $this->service->newClient();
81
82
		try {
83
			$options = [];
84
			if ($this->hasKey()) {
85
				$options['query'] = [
86
					'key' => $this->getKey(),
87
				];
88
			}
89
			$response = $httpClient->get($imaginaryUrl . '/', $options);
90
		} catch (\Exception $e) {
91
			return null;
92
		}
93
94
		if ($response->getStatusCode() !== 200) {
95
			return null;
96
		}
97
98
		$info = json_decode($response->getBody(), true);
0 ignored issues
show
It seems like $response->getBody() can also be of type resource; however, parameter $json of json_decode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

98
		$info = json_decode(/** @scrutinizer ignore-type */ $response->getBody(), true);
Loading history...
99
100
		return $info['imaginary'];
101
	}
102
103
	/**
104
	 * @return array Returns the array with the size of image.
105
	 */
106
	public function getInfo(string $filepath): array {
107
		$imaginaryUrl = $this->getUrl();
108
		if (!$imaginaryUrl) {
109
			throw new \RuntimeException('Try to use imaginary without valid url');
110
		}
111
112
		$httpClient = $this->service->newClient();
113
114
		$options = [];
115
		$options['multipart'] = [[
116
			'name' => 'file',
117
			'contents' => file_get_contents($filepath),
118
			'filename' => basename($filepath),
119
		]];
120
121
		if ($this->hasKey()) {
122
			$options['query'] = [
123
				'key' => $this->getKey(),
124
			];
125
		}
126
127
		$response = $httpClient->post($imaginaryUrl . '/info', $options);
128
129
		if ($response->getStatusCode() !== 200) {
130
			throw new \RuntimeException('Error getting image information in Imaginary: ' . json_decode($response->getBody())['message']);
0 ignored issues
show
It seems like $response->getBody() can also be of type resource; however, parameter $json of json_decode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

130
			throw new \RuntimeException('Error getting image information in Imaginary: ' . json_decode(/** @scrutinizer ignore-type */ $response->getBody())['message']);
Loading history...
131
		}
132
133
		$info = json_decode($response->getBody(), true);
134
135
		$type = $info['type'];
136
		//NOTE: Imaginary has problems rorating heic images. Issue #662
137
		$autorotate = ($info['orientation'] > 4 && $type != 'heif');
138
139
		return [
140
			'type'   => $type,
141
			'autorotate' => $autorotate,
142
			// Rotates the size, since it is important and Imaginary do not do that.
143
			'width'  => $autorotate ? $info['height'] : $info['width'],
144
			'height' => $autorotate ? $info['width'] :  $info['height']
145
		];
146
	}
147
148
	/**
149
	 * @return string|resource Returns the resized image
150
	 */
151
	public function getResized(string $filepath, int $width, int $height, bool $autorotate, string $mimeType) {
152
153
		$imaginaryUrl = $this->getUrl();
154
		if (!$imaginaryUrl) {
155
			throw new \RuntimeException('Try to use imaginary without valid url');
156
		}
157
158
		$httpClient = $this->service->newClient();
159
160
		switch ($mimeType) {
161
			case 'image/png':
162
				$type = 'png';
163
				break;
164
			default:
165
				$type = 'jpeg';
166
		}
167
168
		$operations = [];
169
170
		if ($autorotate) {
171
			$operations[] = [
172
				'operation' => 'autorotate',
173
			];
174
		}
175
176
		$operations[] = [
177
			'operation' => 'resize',
178
			'params' => [
179
				'width' => $width,
180
				'height' => $height,
181
				'stripmeta' => 'true',
182
				'type' => $type,
183
				'norotation' => 'true',
184
				'force' => 'true'
185
			]
186
		];
187
188
		$query = [];
189
		$query['operations'] = json_encode($operations);
190
		if ($this->hasKey()) {
191
			$query['key'] = $this->getKey();
192
		}
193
194
		$response = $httpClient->post(
195
			$imaginaryUrl . '/pipeline', [
196
				'query' => $query,
197
				'body' => file_get_contents($filepath),
198
				'nextcloud' => ['allow_local_address' => true],
199
			]);
200
201
		if ($response->getStatusCode() !== 200) {
202
			throw new \RuntimeException('Error generating temporary image in Imaginary: ' . json_decode($response->getBody())['message']);
0 ignored issues
show
It seems like $response->getBody() can also be of type resource; however, parameter $json of json_decode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

202
			throw new \RuntimeException('Error generating temporary image in Imaginary: ' . json_decode(/** @scrutinizer ignore-type */ $response->getBody())['message']);
Loading history...
203
		}
204
205
		return $response->getBody();
206
	}
207
208
}
209