Passed
Push — master ( 1723b5...d7de35 )
by Pauli
11:26
created

RadioApiController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 7
c 1
b 0
f 0
dl 0
loc 15
rs 10
cc 1
nc 1
nop 8

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php declare(strict_types=1);
2
3
/**
4
 * ownCloud - Music app
5
 *
6
 * This file is licensed under the Affero General Public License version 3 or
7
 * later. See the COPYING file.
8
 *
9
 * @author Pauli Järvinen <[email protected]>
10
 * @copyright Pauli Järvinen 2020 - 2022
11
 */
12
13
namespace OCA\Music\Controller;
14
15
use OCP\AppFramework\Controller;
16
use OCP\AppFramework\Http;
17
use OCP\AppFramework\Http\JSONResponse;
18
19
use OCP\Files\Folder;
20
use OCP\IRequest;
21
22
use OCA\Music\AppFramework\BusinessLayer\BusinessLayerException;
23
use OCA\Music\AppFramework\Core\Logger;
24
use OCA\Music\BusinessLayer\RadioStationBusinessLayer;
25
use OCA\Music\Http\ErrorResponse;
26
use OCA\Music\Utility\PlaylistFileService;
27
use OCA\Music\Utility\Util;
28
use OCA\Music\Utility\RadioMetadata;
29
30
class RadioApiController extends Controller {
31
	private $businessLayer;
32
	private $metadata;
33
	private $playlistFileService;
34
	private $userId;
35
	private $userFolder;
36
	private $logger;
37
38
	public function __construct(string $appname,
39
								IRequest $request,
40
								RadioStationBusinessLayer $businessLayer,
41
								RadioMetadata $metadata,
42
								PlaylistFileService $playlistFileService,
43
								?string $userId,
44
								?Folder $userFolder,
45
								Logger $logger) {
46
		parent::__construct($appname, $request);
47
		$this->businessLayer = $businessLayer;
48
		$this->metadata = $metadata;
49
		$this->playlistFileService = $playlistFileService;
50
		$this->userId = $userId ?? ''; // ensure non-null to satisfy Scrutinizer; the null case should happen only when the user has already logged out
51
		$this->userFolder = $userFolder;
52
		$this->logger = $logger;
53
	}
54
55
	/**
56
	 * lists all radio stations
57
	 *
58
	 * @NoAdminRequired
59
	 * @NoCSRFRequired
60
	 */
61
	public function getAll() {
62
		$stations = $this->businessLayer->findAll($this->userId);
63
		return Util::arrayMapMethod($stations, 'toApi');
64
	}
65
66
	/**
67
	 * creates a station
68
	 *
69
	 * @NoAdminRequired
70
	 * @NoCSRFRequired
71
	 */
72
	public function create($name, $streamUrl, $homeUrl) {
73
		if ($streamUrl === null) {
74
			return new ErrorResponse(Http::STATUS_BAD_REQUEST, "Mandatory argument 'streamUrl' not given");
75
		} else {
76
			$station = $this->businessLayer->create($this->userId, $name, $streamUrl, $homeUrl);
77
			return $station->toApi();
78
		}
79
	}
80
81
	/**
82
	 * deletes a station
83
	 *
84
	 * @NoAdminRequired
85
	 * @NoCSRFRequired
86
	 */
87
	public function delete(int $id) {
88
		try {
89
			$this->businessLayer->delete($id, $this->userId);
90
			return [];
91
		} catch (BusinessLayerException $ex) {
92
			return new ErrorResponse(Http::STATUS_NOT_FOUND, $ex->getMessage());
93
		}
94
	}
95
96
	/**
97
	 * get a single radio station
98
	 *
99
	 * @NoAdminRequired
100
	 * @NoCSRFRequired
101
	 */
102
	public function get(int $id) {
103
		try {
104
			$station = $this->businessLayer->find($id, $this->userId);
105
			return $station->toAPI();
106
		} catch (BusinessLayerException $ex) {
107
			return new ErrorResponse(Http::STATUS_NOT_FOUND, $ex->getMessage());
108
		}
109
	}
110
111
	/**
112
	 * update a station
113
	 *
114
	 * @NoAdminRequired
115
	 * @NoCSRFRequired
116
	 */
117
	public function update(int $id, string $name = null, string $streamUrl = null, string $homeUrl = null) {
118
		if ($name === null && $streamUrl === null && $homeUrl === null) {
119
			return new ErrorResponse(Http::STATUS_BAD_REQUEST, "at least one of the args ['name', 'streamUrl', 'homrUrl'] must be given");
120
		}
121
122
		try {
123
			$station = $this->businessLayer->find($id, $this->userId);
124
			if ($name !== null) {
125
				$station->setName($name);
126
			}
127
			if ($streamUrl !== null) {
128
				$station->setStreamUrl($streamUrl);
129
			}
130
			if ($homeUrl !== null) {
131
				$station->setHomeUrl($homeUrl);
132
			}
133
			$this->businessLayer->update($station);
134
135
			return new JSONResponse($station->toApi());
136
		} catch (BusinessLayerException $ex) {
137
			return new ErrorResponse(Http::STATUS_NOT_FOUND, $ex->getMessage());
138
		}
139
	}
140
141
	/**
142
	 * export all radio stations to a file
143
	 *
144
	 * @param string $name target file name without the file extension
145
	 * @param string $path parent folder path
146
	 * @param string $oncollision action to take on file name collision,
147
	 *								supported values:
148
	 *								- 'overwrite' The existing file will be overwritten
149
	 *								- 'keepboth' The new file is named with a suffix to make it unique
150
	 *								- 'abort' (default) The operation will fail
151
	 *
152
	 * @NoAdminRequired
153
	 * @NoCSRFRequired
154
	 */
155
	public function exportAllToFile(string $name, string $path, string $oncollision) {
156
		if ($this->userFolder === null) {
157
			// This shouldn't get actually run. The folder may be null in case the user has already logged out.
158
			// But in that case, the framework should block the execution before it reaches here.
159
			return new ErrorResponse(Http::STATUS_UNAUTHORIZED, 'no valid user folder got');
160
		}
161
		try {
162
			$exportedFilePath = $this->playlistFileService->exportRadioStationsToFile(
163
					$this->userId, $this->userFolder, $path, $name . '.m3u8', $oncollision);
164
			return new JSONResponse(['wrote_to_file' => $exportedFilePath]);
165
		} catch (\OCP\Files\NotFoundException $ex) {
166
			return new ErrorResponse(Http::STATUS_NOT_FOUND, 'folder not found');
167
		} catch (\RuntimeException $ex) {
168
			return new ErrorResponse(Http::STATUS_CONFLICT, $ex->getMessage());
169
		} catch (\OCP\Files\NotPermittedException $ex) {
170
			return new ErrorResponse(Http::STATUS_FORBIDDEN, 'user is not allowed to write to the target file');
171
		}
172
	}
173
174
	/**
175
	 * import radio stations from a file
176
	 * @param string $filePath path of the file to import
177
	 *
178
	 * @NoAdminRequired
179
	 * @NoCSRFRequired
180
	 */
181
	public function importFromFile(string $filePath) {
182
		if ($this->userFolder === null) {
183
			// This shouldn't get actually run. The folder may be null in case the user has already logged out.
184
			// But in that case, the framework should block the execution before it reaches here.
185
			return new ErrorResponse(Http::STATUS_UNAUTHORIZED, 'no valid user folder got');
186
		}
187
		try {
188
			$result = $this->playlistFileService->importRadioStationsFromFile($this->userId, $this->userFolder, $filePath);
189
			$result['stations'] = Util::arrayMapMethod($result['stations'], 'toApi');
190
			return $result;
191
		} catch (\OCP\Files\NotFoundException $ex) {
192
			return new ErrorResponse(Http::STATUS_NOT_FOUND, 'playlist file not found');
193
		} catch (\UnexpectedValueException $ex) {
194
			return new ErrorResponse(Http::STATUS_UNSUPPORTED_MEDIA_TYPE, $ex->getMessage());
195
		}
196
	}
197
198
	/**
199
	 * reset all the radio stations of the user
200
	 *
201
	 * @NoAdminRequired
202
	 * @NoCSRFRequired
203
	 */
204
	public function resetAll() {
205
		$this->businessLayer->deleteAll($this->userId);
206
		return new JSONResponse(['success' => true]);
207
	}
208
209
	/**
210
	* get radio metadata from stream
211
	*
212
	* @NoAdminRequired
213
	* @NoCSRFRequired
214
	*/
215
	public function getChannelInfo(int $id, ?string $type=null) {
216
		try {
217
			$station = $this->businessLayer->find($id, $this->userId);
218
			$streamUrl = $station->getStreamUrl();
219
220
			switch ($type) {
221
				case 'icy':
222
					$metadata = $this->metadata->readIcyMetadata($streamUrl, 1, 1);
223
					break;
224
				case 'shoutcast-v1':
225
					$metadata = $this->metadata->readShoutcastV1Metadata($streamUrl);
226
					break;
227
				case 'shoutcast-v2':
228
					$metadata = $this->metadata->readShoutcastV2Metadata($streamUrl);
229
					break;
230
				case 'icecast':
231
					$metadata = $this->metadata->readIcecastMetadata($streamUrl);
232
					break;
233
				default:
234
					$metadata = $this->metadata->readIcyMetadata($streamUrl, 1, 1)
235
							?? $this->metadata->readShoutcastV2Metadata($streamUrl)
236
							?? $this->metadata->readIcecastMetadata($streamUrl)
237
							?? $this->metadata->readShoutcastV1Metadata($streamUrl);
238
					break;
239
			}
240
241
			return new JSONResponse($metadata);
242
		} catch (BusinessLayerException $ex) {
243
			return new ErrorResponse(Http::STATUS_NOT_FOUND, $ex->getMessage());
244
		}
245
	}
246
}
247