Passed
Push — master ( ec0dd3...615970 )
by Pauli
02:15
created

RadioApiController::get()   A

Complexity

Conditions 2
Paths 3

Size

Total Lines 6
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 6
rs 10
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, 2021
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
use OCP\AppFramework\Http\DataResponse;
19
20
use OCP\Files\Folder;
21
use OCP\IRequest;
22
23
use OCA\Music\AppFramework\BusinessLayer\BusinessLayerException;
24
use OCA\Music\AppFramework\Core\Logger;
25
use OCA\Music\BusinessLayer\RadioStationBusinessLayer;
26
use OCA\Music\Http\ErrorResponse;
27
use OCA\Music\Utility\PlaylistFileService;
28
use OCA\Music\Utility\Util;
29
use OCA\Music\Utility\RadioMetadata;
30
31
class RadioApiController extends Controller {
32
	private $businessLayer;
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
								PlaylistFileService $playlistFileService,
42
								?string $userId,
43
								?Folder $userFolder,
44
								Logger $logger) {
45
		parent::__construct($appname, $request);
46
		$this->businessLayer = $businessLayer;
47
		$this->playlistFileService = $playlistFileService;
48
		$this->userId = $userId ?? ''; // ensure non-null to satisfy Scrutinizer; the null case should happen only when the user has already logged out
49
		$this->userFolder = $userFolder;
50
		$this->logger = $logger;
51
	}
52
53
	/**
54
	 * lists all radio stations
55
	 *
56
	 * @NoAdminRequired
57
	 * @NoCSRFRequired
58
	 */
59
	public function getAll() {
60
		$stations = $this->businessLayer->findAll($this->userId);
61
		return Util::arrayMapMethod($stations, 'toApi');
62
	}
63
64
	/**
65
	 * creates a station
66
	 *
67
	 * @NoAdminRequired
68
	 * @NoCSRFRequired
69
	 */
70
	public function create($name, $streamUrl, $homeUrl) {
71
		if ($streamUrl === null) {
72
			return new ErrorResponse(Http::STATUS_BAD_REQUEST, "Mandatory argument 'streamUrl' not given");
73
		} else {
74
			$station = $this->businessLayer->create($this->userId, $name, $streamUrl, $homeUrl);
75
			return $station->toApi();
76
		}
77
	}
78
79
	/**
80
	 * deletes a station
81
	 *
82
	 * @NoAdminRequired
83
	 * @NoCSRFRequired
84
	 */
85
	public function delete(int $id) {
86
		try {
87
			$this->businessLayer->delete($id, $this->userId);
88
			return [];
89
		} catch (BusinessLayerException $ex) {
90
			return new ErrorResponse(Http::STATUS_NOT_FOUND, $ex->getMessage());
91
		}
92
	}
93
94
	/**
95
	 * get a single radio station
96
	 *
97
	 * @NoAdminRequired
98
	 * @NoCSRFRequired
99
	 */
100
	public function get(int $id) {
101
		try {
102
			$station = $this->businessLayer->find($id, $this->userId);
103
			return $station->toAPI();
104
		} catch (BusinessLayerException $ex) {
105
			return new ErrorResponse(Http::STATUS_NOT_FOUND, $ex->getMessage());
106
		}
107
	}
108
109
	/**
110
	 * update a station
111
	 *
112
	 * @NoAdminRequired
113
	 * @NoCSRFRequired
114
	 */
115
	public function update(int $id, string $name = null, string $streamUrl = null, string $homeUrl = null) {
116
		if ($name === null && $streamUrl === null && $homeUrl === null) {
117
			return new ErrorResponse(Http::STATUS_BAD_REQUEST, "at least one of the args ['name', 'streamUrl', 'homrUrl'] must be given");
118
		}
119
120
		try {
121
			$station = $this->businessLayer->find($id, $this->userId);
122
			if ($name !== null) {
123
				$station->setName($name);
124
			}
125
			if ($streamUrl !== null) {
126
				$station->setStreamUrl($streamUrl);
127
			}
128
			if ($homeUrl !== null) {
129
				$station->setHomeUrl($homeUrl);
130
			}
131
			$this->businessLayer->update($station);
132
133
			return new JSONResponse($station->toApi());
134
		} catch (BusinessLayerException $ex) {
135
			return new ErrorResponse(Http::STATUS_NOT_FOUND, $ex->getMessage());
136
		}
137
	}
138
139
	/**
140
	 * export all radio stations to a file
141
	 *
142
	 * @param string $name target file name without the file extension
143
	 * @param string $path parent folder path
144
	 * @param string $oncollision action to take on file name collision,
145
	 *								supported values:
146
	 *								- 'overwrite' The existing file will be overwritten
147
	 *								- 'keepboth' The new file is named with a suffix to make it unique
148
	 *								- 'abort' (default) The operation will fail
149
	 *
150
	 * @NoAdminRequired
151
	 * @NoCSRFRequired
152
	 */
153
	public function exportAllToFile(string $name, string $path, string $oncollision) {
154
		if ($this->userFolder === null) {
155
			// This shouldn't get actually run. The folder may be null in case the user has already logged out.
156
			// But in that case, the framework should block the execution before it reaches here.
157
			return new ErrorResponse(Http::STATUS_UNAUTHORIZED, 'no valid user folder got');
158
		}
159
		try {
160
			$exportedFilePath = $this->playlistFileService->exportRadioStationsToFile(
161
					$this->userId, $this->userFolder, $path, $name . '.m3u8', $oncollision);
162
			return new JSONResponse(['wrote_to_file' => $exportedFilePath]);
163
		} catch (\OCP\Files\NotFoundException $ex) {
164
			return new ErrorResponse(Http::STATUS_NOT_FOUND, 'folder not found');
165
		} catch (\RuntimeException $ex) {
166
			return new ErrorResponse(Http::STATUS_CONFLICT, $ex->getMessage());
167
		} catch (\OCP\Files\NotPermittedException $ex) {
168
			return new ErrorResponse(Http::STATUS_FORBIDDEN, 'user is not allowed to write to the target file');
169
		}
170
	}
171
172
	/**
173
	 * import radio stations from a file
174
	 * @param string $filePath path of the file to import
175
	 *
176
	 * @NoAdminRequired
177
	 * @NoCSRFRequired
178
	 */
179
	public function importFromFile(string $filePath) {
180
		if ($this->userFolder === null) {
181
			// This shouldn't get actually run. The folder may be null in case the user has already logged out.
182
			// But in that case, the framework should block the execution before it reaches here.
183
			return new ErrorResponse(Http::STATUS_UNAUTHORIZED, 'no valid user folder got');
184
		}
185
		try {
186
			$result = $this->playlistFileService->importRadioStationsFromFile($this->userId, $this->userFolder, $filePath);
187
			$result['stations'] = Util::arrayMapMethod($result['stations'], 'toApi');
188
			return $result;
189
		} catch (\OCP\Files\NotFoundException $ex) {
190
			return new ErrorResponse(Http::STATUS_NOT_FOUND, 'playlist file not found');
191
		} catch (\UnexpectedValueException $ex) {
192
			return new ErrorResponse(Http::STATUS_UNSUPPORTED_MEDIA_TYPE, $ex->getMessage());
193
		}
194
	}
195
196
	/**
197
	 * reset all the radio stations of the user
198
	 *
199
	 * @NoAdminRequired
200
	 * @NoCSRFRequired
201
	 */
202
	public function resetAll() {
203
		$this->businessLayer->deleteAll($this->userId);
204
		return new JSONResponse(['success' => true]);
205
	}
206
207
	/**
208
	* get radio metadata from stream
209
	*
210
	* @NoAdminRequired
211
	* @NoCSRFRequired
212
	*/
213
214
	public function getRadioStreamData(int $id) {
215
		try {
216
			$response = "";
0 ignored issues
show
Unused Code introduced by
The assignment to $response is dead and can be removed.
Loading history...
217
			$station = $this->businessLayer->find($id, $this->userId);
218
			$response = RadioMetadata::fetchStreamData($station->getStreamUrl(), 1, 1);
219
			return new DataResponse([ 'title' => $response ]);
220
221
		} catch (BusinessLayerException $ex) {
222
			return new ErrorResponse(Http::STATUS_NOT_FOUND, $ex->getMessage());
223
		}
224
	}
225
}
226