Unify feature checks; simplify station routes.
This commit is contained in:
parent
6529a92e58
commit
6e9af6f1f4
|
@ -3,6 +3,7 @@
|
|||
* Administrative dashboard configuration.
|
||||
*/
|
||||
|
||||
use App\Enums\StationFeatures;
|
||||
use App\Enums\StationPermissions;
|
||||
use App\Radio\Enums\AudioProcessingMethods;
|
||||
|
||||
|
@ -13,8 +14,6 @@ return function (App\Event\BuildStationMenu $e) {
|
|||
$backendConfig = $station->getBackendConfig();
|
||||
|
||||
$router = $request->getRouter();
|
||||
|
||||
$backendEnum = $station->getBackendTypeEnum();
|
||||
$frontendEnum = $station->getFrontendTypeEnum();
|
||||
|
||||
$willDisconnectMessage = __('Restart broadcasting? This will disconnect any current listeners.');
|
||||
|
@ -63,33 +62,30 @@ return function (App\Event\BuildStationMenu $e) {
|
|||
'media' => [
|
||||
'label' => __('Media'),
|
||||
'icon' => 'library_music',
|
||||
'visible' => StationFeatures::Media->supportedForStation($station),
|
||||
'items' => [
|
||||
'files' => [
|
||||
'label' => __('Music Files'),
|
||||
'icon' => 'library_music',
|
||||
'url' => (string)$router->fromHere('stations:files:index'),
|
||||
'visible' => $backendEnum->isEnabled(),
|
||||
'permission' => StationPermissions::Media,
|
||||
],
|
||||
'reports_duplicates' => [
|
||||
'label' => __('Duplicate Songs'),
|
||||
'class' => 'text-muted',
|
||||
'url' => (string)$router->fromHere('stations:files:index') . '#special:duplicates',
|
||||
'visible' => $backendEnum->isEnabled(),
|
||||
'permission' => StationPermissions::Media,
|
||||
],
|
||||
'reports_unprocessable' => [
|
||||
'label' => __('Unprocessable Files'),
|
||||
'class' => 'text-muted',
|
||||
'url' => (string)$router->fromHere('stations:files:index') . '#special:unprocessable',
|
||||
'visible' => $backendEnum->isEnabled(),
|
||||
'permission' => StationPermissions::Media,
|
||||
],
|
||||
'reports_unassigned' => [
|
||||
'label' => __('Unassigned Files'),
|
||||
'class' => 'text-muted',
|
||||
'url' => (string)$router->fromHere('stations:files:index') . '#special:unassigned',
|
||||
'visible' => $backendEnum->isEnabled(),
|
||||
'permission' => StationPermissions::Media,
|
||||
],
|
||||
'ondemand' => [
|
||||
|
@ -111,7 +107,6 @@ return function (App\Event\BuildStationMenu $e) {
|
|||
'label' => __('Bulk Media Import/Export'),
|
||||
'class' => 'text-muted',
|
||||
'url' => (string)$router->fromHere('stations:bulk-media'),
|
||||
'visible' => $backendEnum->isEnabled(),
|
||||
'permission' => StationPermissions::Media,
|
||||
],
|
||||
],
|
||||
|
@ -121,7 +116,7 @@ return function (App\Event\BuildStationMenu $e) {
|
|||
'label' => __('Playlists'),
|
||||
'icon' => 'queue_music',
|
||||
'url' => (string)$router->fromHere('stations:playlists:index'),
|
||||
'visible' => $backendEnum->isEnabled(),
|
||||
'visible' => StationFeatures::Media->supportedForStation($station),
|
||||
'permission' => StationPermissions::Media,
|
||||
],
|
||||
|
||||
|
@ -129,18 +124,19 @@ return function (App\Event\BuildStationMenu $e) {
|
|||
'label' => __('Podcasts'),
|
||||
'icon' => 'cast',
|
||||
'url' => (string)$router->fromHere('stations:podcasts:index'),
|
||||
'visible' => StationFeatures::Podcasts->supportedForStation($station),
|
||||
'permission' => StationPermissions::Podcasts,
|
||||
],
|
||||
|
||||
'live_streaming' => [
|
||||
'label' => __('Live Streaming'),
|
||||
'icon' => 'mic',
|
||||
'visible' => StationFeatures::Streamers->supportedForStation($station),
|
||||
'items' => [
|
||||
'streamers' => [
|
||||
'label' => __('Streamer/DJ Accounts'),
|
||||
'icon' => 'mic',
|
||||
'url' => (string)$router->fromHere('stations:streamers:index'),
|
||||
'visible' => $backendEnum->isEnabled() && $station->getEnableStreamers(),
|
||||
'permission' => StationPermissions::Streamers,
|
||||
],
|
||||
|
||||
|
@ -154,7 +150,7 @@ return function (App\Event\BuildStationMenu $e) {
|
|||
true
|
||||
)
|
||||
->withScheme('https'),
|
||||
'visible' => $station->getEnablePublicPage() && $station->getEnableStreamers(),
|
||||
'visible' => $station->getEnablePublicPage(),
|
||||
'external' => true,
|
||||
],
|
||||
],
|
||||
|
@ -164,6 +160,7 @@ return function (App\Event\BuildStationMenu $e) {
|
|||
'label' => __('Web Hooks'),
|
||||
'icon' => 'code',
|
||||
'url' => (string)$router->fromHere('stations:webhooks:index'),
|
||||
'visible' => StationFeatures::Webhooks->supportedForStation($station),
|
||||
'permission' => StationPermissions::WebHooks,
|
||||
],
|
||||
|
||||
|
@ -204,32 +201,34 @@ return function (App\Event\BuildStationMenu $e) {
|
|||
'label' => __('Mount Points'),
|
||||
'icon' => 'wifi_tethering',
|
||||
'url' => (string)$router->fromHere('stations:mounts:index'),
|
||||
'visible' => $frontendEnum->supportsMounts(),
|
||||
'visible' => StationFeatures::MountPoints->supportedForStation($station),
|
||||
'permission' => StationPermissions::MountPoints,
|
||||
],
|
||||
'hls_streams' => [
|
||||
'label' => __('HLS Streams'),
|
||||
'url' => (string)$router->fromHere('stations:hls_streams:index'),
|
||||
'visible' => $backendEnum->isEnabled() && $station->getEnableHls(),
|
||||
'visible' => StationFeatures::HlsStreams->supportedForStation($station),
|
||||
'permission' => StationPermissions::MountPoints,
|
||||
],
|
||||
'remotes' => [
|
||||
'label' => __('Remote Relays'),
|
||||
'icon' => 'router',
|
||||
'url' => (string)$router->fromHere('stations:remotes:index'),
|
||||
'visible' => StationFeatures::RemoteRelays->supportedForStation($station),
|
||||
'permission' => StationPermissions::RemoteRelays,
|
||||
],
|
||||
'fallback' => [
|
||||
'label' => __('Custom Fallback File'),
|
||||
'class' => 'text-muted',
|
||||
'url' => (string)$router->fromHere('stations:fallback'),
|
||||
'visible' => StationFeatures::Media->supportedForStation($station),
|
||||
'permission' => StationPermissions::Broadcasting,
|
||||
],
|
||||
'ls_config' => [
|
||||
'label' => __('Edit Liquidsoap Configuration'),
|
||||
'class' => 'text-muted',
|
||||
'url' => (string)$router->fromHere('stations:util:ls_config'),
|
||||
'visible' => $settings->getEnableAdvancedFeatures() && $backendEnum->isEnabled(),
|
||||
'visible' => StationFeatures::CustomLiquidsoapConfig->supportedForStation($station),
|
||||
'permission' => StationPermissions::Broadcasting,
|
||||
],
|
||||
'stations:stereo_tool_config' => [
|
||||
|
@ -237,7 +236,7 @@ return function (App\Event\BuildStationMenu $e) {
|
|||
'class' => 'text-muted',
|
||||
'url' => (string)$router->fromHere('stations:stereo_tool_config'),
|
||||
'visible' => $settings->getEnableAdvancedFeatures()
|
||||
&& App\Radio\Enums\BackendAdapters::Liquidsoap === $backendEnum
|
||||
&& StationFeatures::Media->supportedForStation($station)
|
||||
&& AudioProcessingMethods::StereoTool === $backendConfig->getAudioProcessingMethodEnum(),
|
||||
'permission' => StationPermissions::Broadcasting,
|
||||
],
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
use App\Controller;
|
||||
use App\Enums\StationFeatures;
|
||||
use App\Enums\StationPermissions;
|
||||
use App\Middleware;
|
||||
use Slim\Routing\RouteCollectorProxy;
|
||||
|
@ -87,8 +88,7 @@ return static function (RouteCollectorProxy $group) {
|
|||
$group->get(
|
||||
'/waveform/{media_id:[a-zA-Z0-9\-]+}.json',
|
||||
Controller\Api\Stations\Waveform\GetWaveformAction::class
|
||||
)
|
||||
->setName('api:stations:media:waveform');
|
||||
)->setName('api:stations:media:waveform');
|
||||
|
||||
$group->get('/art/{media_id:[a-zA-Z0-9\-]+}.jpg', Controller\Api\Stations\Art\GetArtAction::class)
|
||||
->setName('api:stations:media:art');
|
||||
|
@ -102,42 +102,9 @@ return static function (RouteCollectorProxy $group) {
|
|||
$group->delete('/art/{media_id:[a-zA-Z0-9]+}', Controller\Api\Stations\Art\DeleteArtAction::class)
|
||||
->add(new Middleware\Permissions(StationPermissions::Media, true));
|
||||
|
||||
$group->group(
|
||||
'/liquidsoap-config',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'',
|
||||
Controller\Api\Stations\LiquidsoapConfig\GetAction::class
|
||||
)->setName('api:stations:liquidsoap-config');
|
||||
|
||||
$group->put(
|
||||
'',
|
||||
Controller\Api\Stations\LiquidsoapConfig\PutAction::class
|
||||
);
|
||||
}
|
||||
)->add(new Middleware\Permissions(StationPermissions::Broadcasting, true));
|
||||
|
||||
$group->group(
|
||||
'/stereo_tool_config',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'',
|
||||
Controller\Api\Stations\StereoTool\GetStereoToolConfigurationAction::class
|
||||
)->setName('api:stations:stereo_tool_config');
|
||||
|
||||
$group->post(
|
||||
'',
|
||||
Controller\Api\Stations\StereoTool\PostStereoToolConfigurationAction::class
|
||||
);
|
||||
|
||||
$group->delete(
|
||||
'',
|
||||
Controller\Api\Stations\StereoTool\DeleteStereoToolConfigurationAction::class
|
||||
);
|
||||
}
|
||||
)->add(new Middleware\Permissions(StationPermissions::Broadcasting, true));
|
||||
|
||||
// Public and private podcast pages
|
||||
/*
|
||||
* Podcast Public Pages
|
||||
*/
|
||||
$group->group(
|
||||
'/podcast/{podcast_id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
|
@ -176,304 +143,424 @@ return static function (RouteCollectorProxy $group) {
|
|||
}
|
||||
)->add(Middleware\RequirePublishedPodcastEpisodeMiddleware::class);
|
||||
|
||||
// Private-only podcast pages
|
||||
/*
|
||||
* Podcast Private Pates
|
||||
*/
|
||||
$group->group(
|
||||
'/podcasts',
|
||||
'',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Api\Stations\PodcastsController::class . ':listAction')
|
||||
$group->get('/podcasts', Controller\Api\Stations\PodcastsController::class . ':listAction')
|
||||
->setName('api:stations:podcasts');
|
||||
|
||||
$group->post('', Controller\Api\Stations\PodcastsController::class . ':createAction');
|
||||
$group->post('/podcasts', Controller\Api\Stations\PodcastsController::class . ':createAction');
|
||||
|
||||
$group->post('/art', Controller\Api\Stations\Podcasts\Art\PostArtAction::class)
|
||||
$group->post('/podcasts/art', Controller\Api\Stations\Podcasts\Art\PostArtAction::class)
|
||||
->setName('api:stations:podcasts:new-art');
|
||||
}
|
||||
)->add(new Middleware\Permissions(StationPermissions::Podcasts, true));
|
||||
|
||||
$group->group(
|
||||
'/podcast/{podcast_id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->put('', Controller\Api\Stations\PodcastsController::class . ':editAction');
|
||||
|
||||
$group->delete('', Controller\Api\Stations\PodcastsController::class . ':deleteAction');
|
||||
|
||||
$group->post(
|
||||
'/art',
|
||||
Controller\Api\Stations\Podcasts\Art\PostArtAction::class
|
||||
)->setName('api:stations:podcast:art-internal');
|
||||
|
||||
$group->delete(
|
||||
'/art',
|
||||
Controller\Api\Stations\Podcasts\Art\DeleteArtAction::class
|
||||
);
|
||||
|
||||
$group->post(
|
||||
'/episodes',
|
||||
Controller\Api\Stations\PodcastEpisodesController::class . ':createAction'
|
||||
);
|
||||
|
||||
$group->post(
|
||||
'/episodes/art',
|
||||
Controller\Api\Stations\Podcasts\Episodes\Art\PostArtAction::class
|
||||
)->setName('api:stations:podcast:episodes:new-art');
|
||||
|
||||
$group->post(
|
||||
'/episodes/media',
|
||||
Controller\Api\Stations\Podcasts\Episodes\Media\PostMediaAction::class
|
||||
)->setName('api:stations:podcast:episodes:new-media');
|
||||
|
||||
$group->group(
|
||||
'/episode/{episode_id}',
|
||||
'/podcast/{podcast_id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->put(
|
||||
'',
|
||||
Controller\Api\Stations\PodcastEpisodesController::class . ':editAction'
|
||||
);
|
||||
$group->put('', Controller\Api\Stations\PodcastsController::class . ':editAction');
|
||||
|
||||
$group->delete(
|
||||
'',
|
||||
Controller\Api\Stations\PodcastEpisodesController::class . ':deleteAction'
|
||||
);
|
||||
$group->delete('', Controller\Api\Stations\PodcastsController::class . ':deleteAction');
|
||||
|
||||
$group->post(
|
||||
'/art',
|
||||
Controller\Api\Stations\Podcasts\Art\PostArtAction::class
|
||||
)->setName('api:stations:podcast:art-internal');
|
||||
|
||||
$group->delete(
|
||||
'/art',
|
||||
Controller\Api\Stations\Podcasts\Art\DeleteArtAction::class
|
||||
);
|
||||
|
||||
$group->post(
|
||||
'/episodes',
|
||||
Controller\Api\Stations\PodcastEpisodesController::class . ':createAction'
|
||||
);
|
||||
|
||||
$group->post(
|
||||
'/episodes/art',
|
||||
Controller\Api\Stations\Podcasts\Episodes\Art\PostArtAction::class
|
||||
)->setName('api:stations:podcast:episode:art-internal');
|
||||
|
||||
$group->delete(
|
||||
'/art',
|
||||
Controller\Api\Stations\Podcasts\Episodes\Art\DeleteArtAction::class
|
||||
);
|
||||
)->setName('api:stations:podcast:episodes:new-art');
|
||||
|
||||
$group->post(
|
||||
'/media',
|
||||
'/episodes/media',
|
||||
Controller\Api\Stations\Podcasts\Episodes\Media\PostMediaAction::class
|
||||
)->setName('api:stations:podcast:episode:media-internal');
|
||||
)->setName('api:stations:podcast:episodes:new-media');
|
||||
|
||||
$group->delete(
|
||||
'/media',
|
||||
Controller\Api\Stations\Podcasts\Episodes\Media\DeleteMediaAction::class
|
||||
$group->group(
|
||||
'/episode/{episode_id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->put(
|
||||
'',
|
||||
Controller\Api\Stations\PodcastEpisodesController::class . ':editAction'
|
||||
);
|
||||
|
||||
$group->delete(
|
||||
'',
|
||||
Controller\Api\Stations\PodcastEpisodesController::class . ':deleteAction'
|
||||
);
|
||||
|
||||
$group->post(
|
||||
'/art',
|
||||
Controller\Api\Stations\Podcasts\Episodes\Art\PostArtAction::class
|
||||
)->setName('api:stations:podcast:episode:art-internal');
|
||||
|
||||
$group->delete(
|
||||
'/art',
|
||||
Controller\Api\Stations\Podcasts\Episodes\Art\DeleteArtAction::class
|
||||
);
|
||||
|
||||
$group->post(
|
||||
'/media',
|
||||
Controller\Api\Stations\Podcasts\Episodes\Media\PostMediaAction::class
|
||||
)->setName('api:stations:podcast:episode:media-internal');
|
||||
|
||||
$group->delete(
|
||||
'/media',
|
||||
Controller\Api\Stations\Podcasts\Episodes\Media\DeleteMediaAction::class
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
)->add(new Middleware\Permissions(StationPermissions::Podcasts, true));
|
||||
|
||||
// Streamers public pages
|
||||
$group->get(
|
||||
'/streamer/{streamer_id}/art',
|
||||
Controller\Api\Stations\Streamers\Art\GetArtAction::class
|
||||
)->setName('api:stations:streamer:art');
|
||||
|
||||
// Streamers internal pages
|
||||
$group->post('/streamers/art', Controller\Api\Stations\Streamers\Art\PostArtAction::class)
|
||||
->setName('api:stations:streamers:new-art')
|
||||
->add(new Middleware\Permissions(StationPermissions::Streamers, true));
|
||||
|
||||
/*
|
||||
* Files/Media
|
||||
*/
|
||||
$group->group(
|
||||
'/streamer/{streamer_id}',
|
||||
'',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->post(
|
||||
'/art',
|
||||
Controller\Api\Stations\Streamers\Art\PostArtAction::class
|
||||
)->setName('api:stations:streamer:art-internal');
|
||||
$group->group(
|
||||
'/files',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'',
|
||||
Controller\Api\Stations\FilesController::class . ':listAction'
|
||||
)->setName('api:stations:files');
|
||||
|
||||
$group->delete(
|
||||
'/art',
|
||||
Controller\Api\Stations\Streamers\Art\DeleteArtAction::class
|
||||
$group->post(
|
||||
'',
|
||||
Controller\Api\Stations\FilesController::class . ':createAction'
|
||||
);
|
||||
|
||||
$group->get('/list', Controller\Api\Stations\Files\ListAction::class)
|
||||
->setName('api:stations:files:list');
|
||||
|
||||
$group->get('/directories', Controller\Api\Stations\Files\ListDirectoriesAction::class)
|
||||
->setName('api:stations:files:directories');
|
||||
|
||||
$group->put('/rename', Controller\Api\Stations\Files\RenameAction::class)
|
||||
->setName('api:stations:files:rename');
|
||||
|
||||
$group->put('/batch', Controller\Api\Stations\Files\BatchAction::class)
|
||||
->setName('api:stations:files:batch');
|
||||
|
||||
$group->post('/mkdir', Controller\Api\Stations\Files\MakeDirectoryAction::class)
|
||||
->setName('api:stations:files:mkdir');
|
||||
|
||||
$group->get('/bulk', Controller\Api\Stations\BulkMedia\DownloadAction::class)
|
||||
->setName('api:stations:files:bulk');
|
||||
|
||||
$group->post('/bulk', Controller\Api\Stations\BulkMedia\UploadAction::class);
|
||||
|
||||
$group->get('/download', Controller\Api\Stations\Files\DownloadAction::class)
|
||||
->setName('api:stations:files:download');
|
||||
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/upload',
|
||||
Controller\Api\Stations\Files\FlowUploadAction::class
|
||||
)->setName('api:stations:files:upload');
|
||||
}
|
||||
);
|
||||
|
||||
$group->group(
|
||||
'/file/{id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'',
|
||||
Controller\Api\Stations\FilesController::class . ':getAction'
|
||||
)->setName('api:stations:file');
|
||||
|
||||
$group->put(
|
||||
'',
|
||||
Controller\Api\Stations\FilesController::class . ':editAction'
|
||||
);
|
||||
|
||||
$group->delete(
|
||||
'',
|
||||
Controller\Api\Stations\FilesController::class . ':deleteAction'
|
||||
);
|
||||
|
||||
$group->get('/play', Controller\Api\Stations\Files\PlayAction::class)
|
||||
->setName('api:stations:files:play');
|
||||
}
|
||||
);
|
||||
}
|
||||
)->add(new Middleware\Permissions(StationPermissions::Streamers, true));
|
||||
|
||||
$station_api_endpoints = [
|
||||
[
|
||||
'file',
|
||||
'files',
|
||||
Controller\Api\Stations\FilesController::class,
|
||||
StationPermissions::Media,
|
||||
],
|
||||
[
|
||||
'hls_stream',
|
||||
'hls_streams',
|
||||
Controller\Api\Stations\HlsStreamsController::class,
|
||||
StationPermissions::MountPoints,
|
||||
],
|
||||
[
|
||||
'mount',
|
||||
'mounts',
|
||||
Controller\Api\Stations\MountsController::class,
|
||||
StationPermissions::MountPoints,
|
||||
],
|
||||
[
|
||||
'playlist',
|
||||
'playlists',
|
||||
Controller\Api\Stations\PlaylistsController::class,
|
||||
StationPermissions::Media,
|
||||
],
|
||||
[
|
||||
'remote',
|
||||
'remotes',
|
||||
Controller\Api\Stations\RemotesController::class,
|
||||
StationPermissions::RemoteRelays,
|
||||
],
|
||||
[
|
||||
'sftp-user',
|
||||
'sftp-users',
|
||||
Controller\Api\Stations\SftpUsersController::class,
|
||||
StationPermissions::Media,
|
||||
],
|
||||
[
|
||||
'streamer',
|
||||
'streamers',
|
||||
Controller\Api\Stations\StreamersController::class,
|
||||
StationPermissions::Streamers,
|
||||
],
|
||||
[
|
||||
'webhook',
|
||||
'webhooks',
|
||||
Controller\Api\Stations\WebhooksController::class,
|
||||
StationPermissions::WebHooks,
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($station_api_endpoints as [$singular, $plural, $class, $permission]) {
|
||||
$group->group(
|
||||
'',
|
||||
function (RouteCollectorProxy $group) use ($singular, $plural, $class) {
|
||||
$group->get('/' . $plural, $class . ':listAction')
|
||||
->setName('api:stations:' . $plural);
|
||||
$group->post('/' . $plural, $class . ':createAction');
|
||||
|
||||
$group->get('/' . $singular . '/{id}', $class . ':getAction')
|
||||
->setName('api:stations:' . $singular);
|
||||
$group->put('/' . $singular . '/{id}', $class . ':editAction');
|
||||
$group->delete('/' . $singular . '/{id}', $class . ':deleteAction');
|
||||
}
|
||||
)->add(new Middleware\Permissions($permission, true));
|
||||
}
|
||||
|
||||
$group->group(
|
||||
'/files',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('/list', Controller\Api\Stations\Files\ListAction::class)
|
||||
->setName('api:stations:files:list');
|
||||
|
||||
$group->get('/directories', Controller\Api\Stations\Files\ListDirectoriesAction::class)
|
||||
->setName('api:stations:files:directories');
|
||||
|
||||
$group->put('/rename', Controller\Api\Stations\Files\RenameAction::class)
|
||||
->setName('api:stations:files:rename');
|
||||
|
||||
$group->put('/batch', Controller\Api\Stations\Files\BatchAction::class)
|
||||
->setName('api:stations:files:batch');
|
||||
|
||||
$group->post('/mkdir', Controller\Api\Stations\Files\MakeDirectoryAction::class)
|
||||
->setName('api:stations:files:mkdir');
|
||||
|
||||
$group->get('/play/{id}', Controller\Api\Stations\Files\PlayAction::class)
|
||||
->setName('api:stations:files:play');
|
||||
|
||||
$group->get('/download', Controller\Api\Stations\Files\DownloadAction::class)
|
||||
->setName('api:stations:files:download');
|
||||
|
||||
$group->get('/bulk', Controller\Api\Stations\BulkMedia\DownloadAction::class)
|
||||
->setName('api:stations:files:bulk');
|
||||
|
||||
$group->post('/bulk', Controller\Api\Stations\BulkMedia\UploadAction::class);
|
||||
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/upload',
|
||||
Controller\Api\Stations\Files\FlowUploadAction::class
|
||||
)->setName('api:stations:files:upload');
|
||||
}
|
||||
)
|
||||
->add(Middleware\Module\StationFiles::class)
|
||||
)->add(new Middleware\StationSupportsFeature(StationFeatures::Media))
|
||||
->add(new Middleware\Permissions(StationPermissions::Media, true));
|
||||
|
||||
$group->post(
|
||||
'/mounts/intro',
|
||||
Controller\Api\Stations\Mounts\Intro\PostIntroAction::class
|
||||
)->setName('api:stations:mounts:new-intro')
|
||||
/*
|
||||
* SFTP Users
|
||||
*/
|
||||
$group->group(
|
||||
'',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'/sftp-users',
|
||||
Controller\Api\Stations\SftpUsersController::class . ':listAction'
|
||||
)->setName('api:stations:sftp-users');
|
||||
|
||||
$group->post(
|
||||
'/sftp-users',
|
||||
Controller\Api\Stations\SftpUsersController::class . ':createAction'
|
||||
);
|
||||
|
||||
$group->get(
|
||||
'/sftp-user/{id}',
|
||||
Controller\Api\Stations\SftpUsersController::class . ':getAction'
|
||||
)->setName('api:stations:sftp-user');
|
||||
|
||||
$group->put(
|
||||
'/sftp-user/{id}',
|
||||
Controller\Api\Stations\SftpUsersController::class . ':editAction'
|
||||
);
|
||||
$group->delete(
|
||||
'/sftp-user/{id}',
|
||||
Controller\Api\Stations\SftpUsersController::class . ':deleteAction'
|
||||
);
|
||||
}
|
||||
)->add(new Middleware\StationSupportsFeature(StationFeatures::Sftp))
|
||||
->add(new Middleware\Permissions(StationPermissions::Media, true));
|
||||
|
||||
/*
|
||||
* Mount Points
|
||||
*/
|
||||
$group->group(
|
||||
'',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->group(
|
||||
'/mounts',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'',
|
||||
Controller\Api\Stations\MountsController::class . ':listAction'
|
||||
)->setName('api:stations:mounts');
|
||||
|
||||
$group->post(
|
||||
'',
|
||||
Controller\Api\Stations\MountsController::class . ':createAction'
|
||||
);
|
||||
|
||||
$group->post(
|
||||
'/intro',
|
||||
Controller\Api\Stations\Mounts\Intro\PostIntroAction::class
|
||||
)->setName('api:stations:mounts:new-intro');
|
||||
}
|
||||
);
|
||||
|
||||
$group->group(
|
||||
'/mount/{id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'',
|
||||
Controller\Api\Stations\MountsController::class . ':getAction'
|
||||
)->setName('api:stations:mount');
|
||||
|
||||
$group->put(
|
||||
'',
|
||||
Controller\Api\Stations\MountsController::class . ':editAction'
|
||||
);
|
||||
|
||||
$group->delete(
|
||||
'',
|
||||
Controller\Api\Stations\MountsController::class . ':deleteAction'
|
||||
);
|
||||
|
||||
$group->get(
|
||||
'/intro',
|
||||
Controller\Api\Stations\Mounts\Intro\GetIntroAction::class
|
||||
)->setName('api:stations:mounts:intro');
|
||||
|
||||
$group->post(
|
||||
'/intro',
|
||||
Controller\Api\Stations\Mounts\Intro\PostIntroAction::class
|
||||
);
|
||||
|
||||
$group->delete(
|
||||
'/intro',
|
||||
Controller\Api\Stations\Mounts\Intro\DeleteIntroAction::class
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
)->add(new Middleware\StationSupportsFeature(StationFeatures::MountPoints))
|
||||
->add(new Middleware\Permissions(StationPermissions::MountPoints, true));
|
||||
|
||||
/*
|
||||
* Remote Relays
|
||||
*/
|
||||
$group->group(
|
||||
'/mount/{id}',
|
||||
'',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'/intro',
|
||||
Controller\Api\Stations\Mounts\Intro\GetIntroAction::class
|
||||
)->setName('api:stations:mounts:intro');
|
||||
'/remotes',
|
||||
Controller\Api\Stations\RemotesController::class . ':listAction'
|
||||
)->setName('api:stations:remotes');
|
||||
|
||||
$group->post(
|
||||
'/intro',
|
||||
Controller\Api\Stations\Mounts\Intro\PostIntroAction::class
|
||||
'/remotes',
|
||||
Controller\Api\Stations\RemotesController::class . ':createAction'
|
||||
);
|
||||
|
||||
$group->get(
|
||||
'/remote/{id}',
|
||||
Controller\Api\Stations\RemotesController::class . ':getAction'
|
||||
)->setName('api:stations:remote');
|
||||
|
||||
$group->put(
|
||||
'/remote/{id}',
|
||||
Controller\Api\Stations\RemotesController::class . ':editAction'
|
||||
);
|
||||
|
||||
$group->delete(
|
||||
'/intro',
|
||||
Controller\Api\Stations\Mounts\Intro\DeleteIntroAction::class
|
||||
'/remote/{id}',
|
||||
Controller\Api\Stations\RemotesController::class . ':deleteAction'
|
||||
);
|
||||
}
|
||||
)->add(new Middleware\Permissions(StationPermissions::MountPoints, true));
|
||||
)->add(new Middleware\StationSupportsFeature(StationFeatures::RemoteRelays))
|
||||
->add(new Middleware\Permissions(StationPermissions::RemoteRelays, true));
|
||||
|
||||
$group->get(
|
||||
'/playlists/schedule',
|
||||
Controller\Api\Stations\PlaylistsController::class . ':scheduleAction'
|
||||
)
|
||||
->setName('api:stations:playlists:schedule')
|
||||
/*
|
||||
* HLS Streams
|
||||
*/
|
||||
$group->group(
|
||||
'',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'/hls_streams',
|
||||
Controller\Api\Stations\HlsStreamsController::class . ':listAction'
|
||||
)->setName('api:stations:hls_streams');
|
||||
|
||||
$group->post(
|
||||
'/hls_streams',
|
||||
Controller\Api\Stations\HlsStreamsController::class . ':createAction'
|
||||
);
|
||||
|
||||
$group->get(
|
||||
'/hls_stream/{id}',
|
||||
Controller\Api\Stations\HlsStreamsController::class . ':getAction'
|
||||
)->setName('api:stations:hls_stream');
|
||||
|
||||
$group->put(
|
||||
'/hls_stream/{id}',
|
||||
Controller\Api\Stations\HlsStreamsController::class . ':editAction'
|
||||
);
|
||||
|
||||
$group->delete(
|
||||
'/hls_stream/{id}',
|
||||
Controller\Api\Stations\HlsStreamsController::class . ':deleteAction'
|
||||
);
|
||||
}
|
||||
)->add(new Middleware\StationSupportsFeature(StationFeatures::HlsStreams))
|
||||
->add(new Middleware\Permissions(StationPermissions::MountPoints, true));
|
||||
|
||||
/*
|
||||
* Playlist
|
||||
*/
|
||||
$group->group(
|
||||
'',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'/playlists',
|
||||
Controller\Api\Stations\PlaylistsController::class . ':listAction'
|
||||
)->setName('api:stations:playlists');
|
||||
|
||||
$group->post(
|
||||
'/playlists',
|
||||
Controller\Api\Stations\PlaylistsController::class . ':createAction'
|
||||
);
|
||||
|
||||
$group->get(
|
||||
'/playlists/schedule',
|
||||
Controller\Api\Stations\PlaylistsController::class . ':scheduleAction'
|
||||
)->setName('api:stations:playlists:schedule');
|
||||
|
||||
$group->group(
|
||||
'/playlist/{id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'',
|
||||
Controller\Api\Stations\PlaylistsController::class . ':getAction'
|
||||
)->setName('api:stations:playlist');
|
||||
|
||||
$group->put(
|
||||
'',
|
||||
Controller\Api\Stations\PlaylistsController::class . ':editAction'
|
||||
);
|
||||
|
||||
$group->delete(
|
||||
'',
|
||||
Controller\Api\Stations\PlaylistsController::class . ':deleteAction'
|
||||
);
|
||||
|
||||
$group->put(
|
||||
'/toggle',
|
||||
Controller\Api\Stations\Playlists\ToggleAction::class
|
||||
)->setName('api:stations:playlist:toggle');
|
||||
|
||||
$group->put(
|
||||
'/reshuffle',
|
||||
Controller\Api\Stations\Playlists\ReshuffleAction::class
|
||||
)->setName('api:stations:playlist:reshuffle');
|
||||
|
||||
$group->get(
|
||||
'/order',
|
||||
Controller\Api\Stations\Playlists\GetOrderAction::class
|
||||
)->setName('api:stations:playlist:order');
|
||||
|
||||
$group->put(
|
||||
'/order',
|
||||
Controller\Api\Stations\Playlists\PutOrderAction::class
|
||||
);
|
||||
|
||||
$group->get(
|
||||
'/queue',
|
||||
Controller\Api\Stations\Playlists\GetQueueAction::class
|
||||
)->setName('api:stations:playlist:queue');
|
||||
|
||||
$group->delete(
|
||||
'/queue',
|
||||
Controller\Api\Stations\Playlists\DeleteQueueAction::class
|
||||
);
|
||||
|
||||
$group->post(
|
||||
'/clone',
|
||||
Controller\Api\Stations\Playlists\CloneAction::class
|
||||
)->setName('api:stations:playlist:clone');
|
||||
|
||||
$group->post(
|
||||
'/import',
|
||||
Controller\Api\Stations\Playlists\ImportAction::class
|
||||
)->setName('api:stations:playlist:import');
|
||||
|
||||
$group->get(
|
||||
'/export[/{format}]',
|
||||
Controller\Api\Stations\Playlists\ExportAction::class
|
||||
)->setName('api:stations:playlist:export');
|
||||
}
|
||||
);
|
||||
}
|
||||
)->add(new Middleware\StationSupportsFeature(StationFeatures::Media))
|
||||
->add(new Middleware\Permissions(StationPermissions::Media, true));
|
||||
|
||||
$group->group(
|
||||
'/playlist/{id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->put(
|
||||
'/toggle',
|
||||
Controller\Api\Stations\Playlists\ToggleAction::class
|
||||
)->setName('api:stations:playlist:toggle');
|
||||
|
||||
$group->put(
|
||||
'/reshuffle',
|
||||
Controller\Api\Stations\Playlists\ReshuffleAction::class
|
||||
)->setName('api:stations:playlist:reshuffle');
|
||||
|
||||
$group->get(
|
||||
'/order',
|
||||
Controller\Api\Stations\Playlists\GetOrderAction::class
|
||||
)->setName('api:stations:playlist:order');
|
||||
|
||||
$group->put(
|
||||
'/order',
|
||||
Controller\Api\Stations\Playlists\PutOrderAction::class
|
||||
);
|
||||
|
||||
$group->get(
|
||||
'/queue',
|
||||
Controller\Api\Stations\Playlists\GetQueueAction::class
|
||||
)->setName('api:stations:playlist:queue');
|
||||
|
||||
$group->delete(
|
||||
'/queue',
|
||||
Controller\Api\Stations\Playlists\DeleteQueueAction::class
|
||||
);
|
||||
|
||||
$group->post(
|
||||
'/clone',
|
||||
Controller\Api\Stations\Playlists\CloneAction::class
|
||||
)->setName('api:stations:playlist:clone');
|
||||
|
||||
$group->post(
|
||||
'/import',
|
||||
Controller\Api\Stations\Playlists\ImportAction::class
|
||||
)->setName('api:stations:playlist:import');
|
||||
|
||||
$group->get(
|
||||
'/export[/{format}]',
|
||||
Controller\Api\Stations\Playlists\ExportAction::class
|
||||
)->setName('api:stations:playlist:export');
|
||||
}
|
||||
)->add(new Middleware\Permissions(StationPermissions::Media, true));
|
||||
|
||||
/*
|
||||
* Reports
|
||||
*/
|
||||
$group->group(
|
||||
'/reports',
|
||||
function (RouteCollectorProxy $group) {
|
||||
|
@ -539,40 +626,94 @@ return static function (RouteCollectorProxy $group) {
|
|||
}
|
||||
)->add(new Middleware\Permissions(StationPermissions::Reports, true));
|
||||
|
||||
/*
|
||||
* Streamers Extras
|
||||
*/
|
||||
$group->get(
|
||||
'/streamers/schedule',
|
||||
Controller\Api\Stations\StreamersController::class . ':scheduleAction'
|
||||
)
|
||||
->setName('api:stations:streamers:schedule')
|
||||
->add(new Middleware\Permissions(StationPermissions::Streamers, true));
|
||||
|
||||
$group->get(
|
||||
'/streamers/broadcasts',
|
||||
Controller\Api\Stations\Streamers\BroadcastsController::class . ':listAction'
|
||||
)
|
||||
->setName('api:stations:streamers:broadcasts')
|
||||
->add(new Middleware\Permissions(StationPermissions::Streamers, true));
|
||||
'/streamer/{id}/art',
|
||||
Controller\Api\Stations\Streamers\Art\GetArtAction::class
|
||||
)->setName('api:stations:streamer:art');
|
||||
|
||||
$group->group(
|
||||
'/streamer/{streamer_id}',
|
||||
'',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'/broadcasts',
|
||||
Controller\Api\Stations\Streamers\BroadcastsController::class . ':listAction'
|
||||
)->setName('api:stations:streamer:broadcasts');
|
||||
$group->group(
|
||||
'/streamers',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'',
|
||||
Controller\Api\Stations\StreamersController::class . ':listAction'
|
||||
)->setName('api:stations:streamers');
|
||||
|
||||
$group->get(
|
||||
'/broadcast/{broadcast_id}/download',
|
||||
Controller\Api\Stations\Streamers\BroadcastsController::class . ':downloadAction'
|
||||
)->setName('api:stations:streamer:broadcast:download');
|
||||
$group->post(
|
||||
'',
|
||||
Controller\Api\Stations\StreamersController::class . ':createAction'
|
||||
);
|
||||
|
||||
$group->delete(
|
||||
'/broadcast/{broadcast_id}',
|
||||
Controller\Api\Stations\Streamers\BroadcastsController::class . ':deleteAction'
|
||||
)
|
||||
->setName('api:stations:streamer:broadcast:delete');
|
||||
$group->get(
|
||||
'/schedule',
|
||||
Controller\Api\Stations\StreamersController::class . ':scheduleAction'
|
||||
)->setName('api:stations:streamers:schedule');
|
||||
|
||||
$group->get(
|
||||
'/broadcasts',
|
||||
Controller\Api\Stations\Streamers\BroadcastsController::class . ':listAction'
|
||||
)->setName('api:stations:streamers:broadcasts');
|
||||
|
||||
$group->post(
|
||||
'/art',
|
||||
Controller\Api\Stations\Streamers\Art\PostArtAction::class
|
||||
)->setName('api:stations:streamers:new-art');
|
||||
}
|
||||
);
|
||||
|
||||
$group->group(
|
||||
'/streamer/{id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'',
|
||||
Controller\Api\Stations\StreamersController::class . ':getAction'
|
||||
)->setName('api:stations:streamer');
|
||||
|
||||
$group->put(
|
||||
'',
|
||||
Controller\Api\Stations\StreamersController::class . ':editAction'
|
||||
);
|
||||
|
||||
$group->delete(
|
||||
'',
|
||||
Controller\Api\Stations\StreamersController::class . ':deleteAction'
|
||||
);
|
||||
|
||||
$group->get(
|
||||
'/broadcasts',
|
||||
Controller\Api\Stations\Streamers\BroadcastsController::class . ':listAction'
|
||||
)->setName('api:stations:streamer:broadcasts');
|
||||
|
||||
$group->get(
|
||||
'/broadcast/{broadcast_id}/download',
|
||||
Controller\Api\Stations\Streamers\BroadcastsController::class . ':downloadAction'
|
||||
)->setName('api:stations:streamer:broadcast:download');
|
||||
|
||||
$group->delete(
|
||||
'/broadcast/{broadcast_id}',
|
||||
Controller\Api\Stations\Streamers\BroadcastsController::class . ':deleteAction'
|
||||
)->setName('api:stations:streamer:broadcast:delete');
|
||||
|
||||
$group->post(
|
||||
'/art',
|
||||
Controller\Api\Stations\Streamers\Art\PostArtAction::class
|
||||
)->setName('api:stations:streamer:art-internal');
|
||||
|
||||
$group->delete(
|
||||
'/art',
|
||||
Controller\Api\Stations\Streamers\Art\DeleteArtAction::class
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
)->add(new Middleware\Permissions(StationPermissions::Streamers, true));
|
||||
)->add(new Middleware\StationSupportsFeature(StationFeatures::Streamers))
|
||||
->add(new Middleware\Permissions(StationPermissions::Streamers, true));
|
||||
|
||||
$group->get('/restart-status', Controller\Api\Stations\GetRestartStatusAction::class)
|
||||
->setName('api:stations:restart-status')
|
||||
|
@ -589,8 +730,7 @@ return static function (RouteCollectorProxy $group) {
|
|||
$group->post(
|
||||
'/frontend/{do}',
|
||||
Controller\Api\Stations\ServicesController::class . ':frontendAction'
|
||||
)
|
||||
->setName('api:stations:frontend')
|
||||
)->setName('api:stations:frontend')
|
||||
->add(new Middleware\Permissions(StationPermissions::Broadcasting, true));
|
||||
|
||||
$group->post('/reload', Controller\Api\Stations\ServicesController::class . ':reloadAction')
|
||||
|
@ -601,6 +741,9 @@ return static function (RouteCollectorProxy $group) {
|
|||
->setName('api:stations:restart')
|
||||
->add(new Middleware\Permissions(StationPermissions::Broadcasting, true));
|
||||
|
||||
/*
|
||||
* Custom Fallback File
|
||||
*/
|
||||
$group->group(
|
||||
'/fallback',
|
||||
function (RouteCollectorProxy $group) {
|
||||
|
@ -621,26 +764,104 @@ return static function (RouteCollectorProxy $group) {
|
|||
}
|
||||
)->add(new Middleware\Permissions(StationPermissions::Broadcasting, true));
|
||||
|
||||
/*
|
||||
* Webhook Extras
|
||||
*/
|
||||
$group->group(
|
||||
'/webhook/{id}',
|
||||
'',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->put(
|
||||
'/toggle',
|
||||
Controller\Api\Stations\Webhooks\ToggleAction::class
|
||||
)->setName('api:stations:webhook:toggle');
|
||||
|
||||
$group->put(
|
||||
'/test',
|
||||
Controller\Api\Stations\Webhooks\TestAction::class
|
||||
)->setName('api:stations:webhook:test');
|
||||
|
||||
$group->get(
|
||||
'/test-log/{path}',
|
||||
Controller\Api\Stations\Webhooks\TestLogAction::class
|
||||
)->setName('api:stations:webhook:test-log');
|
||||
}
|
||||
)->add(new Middleware\Permissions(StationPermissions::WebHooks, true));
|
||||
'/webhooks',
|
||||
Controller\Api\Stations\WebhooksController::class . ':listAction'
|
||||
)->setName('api:stations:webhooks');
|
||||
|
||||
$group->post(
|
||||
'/webhooks',
|
||||
Controller\Api\Stations\WebhooksController::class . ':createAction'
|
||||
);
|
||||
|
||||
$group->group(
|
||||
'/webhook/{id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'',
|
||||
Controller\Api\Stations\WebhooksController::class . ':getAction'
|
||||
)->setName('api:stations:webhook');
|
||||
|
||||
$group->put(
|
||||
'',
|
||||
Controller\Api\Stations\WebhooksController::class . ':editAction'
|
||||
);
|
||||
|
||||
$group->delete(
|
||||
'',
|
||||
Controller\Api\Stations\WebhooksController::class . ':deleteAction'
|
||||
);
|
||||
|
||||
$group->put(
|
||||
'/toggle',
|
||||
Controller\Api\Stations\Webhooks\ToggleAction::class
|
||||
)->setName('api:stations:webhook:toggle');
|
||||
|
||||
$group->put(
|
||||
'/test',
|
||||
Controller\Api\Stations\Webhooks\TestAction::class
|
||||
)->setName('api:stations:webhook:test');
|
||||
|
||||
$group->get(
|
||||
'/test-log/{path}',
|
||||
Controller\Api\Stations\Webhooks\TestLogAction::class
|
||||
)->setName('api:stations:webhook:test-log');
|
||||
}
|
||||
);
|
||||
}
|
||||
)->add(new Middleware\StationSupportsFeature(StationFeatures::Webhooks))
|
||||
->add(new Middleware\Permissions(StationPermissions::WebHooks, true));
|
||||
|
||||
/*
|
||||
* Custom Liquidsoap Configuration
|
||||
*/
|
||||
$group->group(
|
||||
'/liquidsoap-config',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'',
|
||||
Controller\Api\Stations\LiquidsoapConfig\GetAction::class
|
||||
)->setName('api:stations:liquidsoap-config');
|
||||
|
||||
$group->put(
|
||||
'',
|
||||
Controller\Api\Stations\LiquidsoapConfig\PutAction::class
|
||||
);
|
||||
}
|
||||
)->add(new Middleware\Permissions(StationPermissions::Broadcasting, true));
|
||||
|
||||
/*
|
||||
* StereoTool Configuration
|
||||
*/
|
||||
$group->group(
|
||||
'/stereo_tool_config',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'',
|
||||
Controller\Api\Stations\StereoTool\GetStereoToolConfigurationAction::class
|
||||
)->setName('api:stations:stereo_tool_config');
|
||||
|
||||
$group->post(
|
||||
'',
|
||||
Controller\Api\Stations\StereoTool\PostStereoToolConfigurationAction::class
|
||||
);
|
||||
|
||||
$group->delete(
|
||||
'',
|
||||
Controller\Api\Stations\StereoTool\DeleteStereoToolConfigurationAction::class
|
||||
);
|
||||
}
|
||||
)->add(new Middleware\Permissions(StationPermissions::Broadcasting, true));
|
||||
|
||||
/*
|
||||
* Logs
|
||||
*/
|
||||
$group->group(
|
||||
'',
|
||||
function (RouteCollectorProxy $group) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
use App\Controller;
|
||||
use App\Enums\StationFeatures;
|
||||
use App\Enums\StationPermissions;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
|
@ -30,14 +31,17 @@ return static function (RouteCollectorProxy $app) {
|
|||
|
||||
$group->get('/files', Controller\Stations\FilesAction::class)
|
||||
->setName('stations:files:index')
|
||||
->add(new Middleware\StationSupportsFeature(StationFeatures::Media))
|
||||
->add(new Middleware\Permissions(StationPermissions::Media, true));
|
||||
|
||||
$group->get('/hls_streams', Controller\Stations\HlsStreamsAction::class)
|
||||
->setName('stations:hls_streams:index')
|
||||
->add(new Middleware\StationSupportsFeature(StationFeatures::HlsStreams))
|
||||
->add(new Middleware\Permissions(StationPermissions::MountPoints, true));
|
||||
|
||||
$group->get('/ls_config', Controller\Stations\EditLiquidsoapConfigAction::class)
|
||||
->setName('stations:util:ls_config')
|
||||
->add(new Middleware\StationSupportsFeature(StationFeatures::CustomLiquidsoapConfig))
|
||||
->add(new Middleware\Permissions(StationPermissions::Broadcasting, true));
|
||||
|
||||
$group->get('/stereo_tool_config', Controller\Stations\UploadStereoToolConfigAction::class)
|
||||
|
@ -50,14 +54,17 @@ return static function (RouteCollectorProxy $app) {
|
|||
|
||||
$group->get('/playlists', Controller\Stations\PlaylistsAction::class)
|
||||
->setName('stations:playlists:index')
|
||||
->add(new Middleware\StationSupportsFeature(StationFeatures::Media))
|
||||
->add(new Middleware\Permissions(StationPermissions::Media, true));
|
||||
|
||||
$group->get('/podcasts', Controller\Stations\PodcastsAction::class)
|
||||
->setName('stations:podcasts:index')
|
||||
->add(new Middleware\StationSupportsFeature(StationFeatures::Podcasts))
|
||||
->add(new Middleware\Permissions(StationPermissions::Podcasts, true));
|
||||
|
||||
$group->get('/mounts', Controller\Stations\MountsAction::class)
|
||||
->setName('stations:mounts:index')
|
||||
->add(new Middleware\StationSupportsFeature(StationFeatures::MountPoints))
|
||||
->add(new Middleware\Permissions(StationPermissions::MountPoints, true));
|
||||
|
||||
$group->get('/profile', Controller\Stations\ProfileController::class)
|
||||
|
@ -76,10 +83,12 @@ return static function (RouteCollectorProxy $app) {
|
|||
|
||||
$group->get('/queue', Controller\Stations\QueueAction::class)
|
||||
->setName('stations:queue:index')
|
||||
->add(new Middleware\StationSupportsFeature(StationFeatures::Media))
|
||||
->add(new Middleware\Permissions(StationPermissions::Broadcasting, true));
|
||||
|
||||
$group->get('/remotes', Controller\Stations\RemotesAction::class)
|
||||
->setName('stations:remotes:index')
|
||||
->add(new Middleware\StationSupportsFeature(StationFeatures::RemoteRelays))
|
||||
->add(new Middleware\Permissions(StationPermissions::RemoteRelays, true));
|
||||
|
||||
$group->group(
|
||||
|
@ -108,14 +117,17 @@ return static function (RouteCollectorProxy $app) {
|
|||
|
||||
$group->get('/sftp_users', Controller\Stations\SftpUsersAction::class)
|
||||
->setName('stations:sftp_users:index')
|
||||
->add(new Middleware\StationSupportsFeature(StationFeatures::Sftp))
|
||||
->add(new Middleware\Permissions(StationPermissions::Media, true));
|
||||
|
||||
$group->get('/streamers', Controller\Stations\StreamersAction::class)
|
||||
->setName('stations:streamers:index')
|
||||
->add(new Middleware\StationSupportsFeature(StationFeatures::Streamers))
|
||||
->add(new Middleware\Permissions(StationPermissions::Streamers, true));
|
||||
|
||||
$group->get('/webhooks', Controller\Stations\WebhooksAction::class)
|
||||
->setName('stations:webhooks:index')
|
||||
->add(new Middleware\StationSupportsFeature(StationFeatures::Webhooks))
|
||||
->add(new Middleware\Permissions(StationPermissions::WebHooks, true));
|
||||
}
|
||||
)
|
||||
|
|
|
@ -5,8 +5,6 @@ declare(strict_types=1);
|
|||
namespace App\Controller\Api\Stations;
|
||||
|
||||
use App\Entity;
|
||||
use App\Exception\StationUnsupportedException;
|
||||
use App\Http\ServerRequest;
|
||||
use App\OpenApi;
|
||||
use OpenApi\Attributes as OA;
|
||||
|
||||
|
@ -137,18 +135,4 @@ final class HlsStreamsController extends AbstractStationApiCrudController
|
|||
{
|
||||
protected string $entityClass = Entity\StationHlsStream::class;
|
||||
protected string $resourceRouteName = 'api:stations:hls_stream';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function getStation(ServerRequest $request): Entity\Station
|
||||
{
|
||||
$station = parent::getStation($request);
|
||||
|
||||
if (!$station->getBackendTypeEnum()->isEnabled()) {
|
||||
throw new StationUnsupportedException();
|
||||
}
|
||||
|
||||
return $station;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ namespace App\Controller\Api\Stations;
|
|||
use App\Controller\Api\Traits\CanSortResults;
|
||||
use App\Doctrine\ReloadableEntityManagerInterface;
|
||||
use App\Entity;
|
||||
use App\Exception\StationUnsupportedException;
|
||||
use App\Http\Response;
|
||||
use App\Http\Router;
|
||||
use App\Http\ServerRequest;
|
||||
|
@ -256,18 +255,4 @@ final class MountsController extends AbstractStationApiCrudController
|
|||
|
||||
return $response->withJson(Entity\Api\Status::deleted());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function getStation(ServerRequest $request): Entity\Station
|
||||
{
|
||||
$station = parent::getStation($request);
|
||||
|
||||
if (!$station->getFrontendTypeEnum()->supportsMounts()) {
|
||||
throw new StationUnsupportedException();
|
||||
}
|
||||
|
||||
return $station;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,11 +21,11 @@ final class DeleteArtAction
|
|||
ServerRequest $request,
|
||||
Response $response,
|
||||
string $station_id,
|
||||
string $streamer_id
|
||||
string $id
|
||||
): ResponseInterface {
|
||||
$station = $request->getStation();
|
||||
|
||||
$streamer = $this->streamerRepo->requireForStation($streamer_id, $station);
|
||||
$streamer = $this->streamerRepo->requireForStation($id, $station);
|
||||
|
||||
$this->streamerRepo->removeArtwork($streamer);
|
||||
$this->streamerRepo->getEntityManager()
|
||||
|
|
|
@ -21,14 +21,14 @@ final class GetArtAction
|
|||
ServerRequest $request,
|
||||
Response $response,
|
||||
string $station_id,
|
||||
string $streamer_id
|
||||
string $id
|
||||
): ResponseInterface {
|
||||
// If a timestamp delimiter is added, strip it automatically.
|
||||
$streamer_id = explode('|', $streamer_id, 2)[0];
|
||||
$id = explode('|', $id, 2)[0];
|
||||
|
||||
$station = $request->getStation();
|
||||
|
||||
$artworkPath = Entity\StationStreamer::getArtworkPath($streamer_id);
|
||||
$artworkPath = Entity\StationStreamer::getArtworkPath($id);
|
||||
|
||||
$fsConfig = (new StationFilesystems($station))->getConfigFilesystem();
|
||||
if ($fsConfig->fileExists($artworkPath)) {
|
||||
|
|
|
@ -21,7 +21,7 @@ final class PostArtAction
|
|||
ServerRequest $request,
|
||||
Response $response,
|
||||
string $station_id,
|
||||
?string $streamer_id = null
|
||||
?string $id = null
|
||||
): ResponseInterface {
|
||||
$station = $request->getStation();
|
||||
|
||||
|
@ -30,8 +30,8 @@ final class PostArtAction
|
|||
return $flowResponse;
|
||||
}
|
||||
|
||||
if (null !== $streamer_id) {
|
||||
$streamer = $this->streamerRepo->requireForStation($streamer_id, $station);
|
||||
if (null !== $id) {
|
||||
$streamer = $this->streamerRepo->requireForStation($id, $station);
|
||||
|
||||
$this->streamerRepo->writeArtwork(
|
||||
$streamer,
|
||||
|
|
|
@ -25,12 +25,12 @@ final class BroadcastsController extends AbstractApiCrudController
|
|||
ServerRequest $request,
|
||||
Response $response,
|
||||
string $station_id,
|
||||
?string $streamer_id = null
|
||||
?string $id = null
|
||||
): ResponseInterface {
|
||||
$station = $request->getStation();
|
||||
|
||||
if (null !== $streamer_id) {
|
||||
$streamer = $this->getStreamer($station, $streamer_id);
|
||||
if (null !== $id) {
|
||||
$streamer = $this->getStreamer($station, $id);
|
||||
|
||||
if (null === $streamer) {
|
||||
return $response->withStatus(404)
|
||||
|
@ -66,13 +66,13 @@ final class BroadcastsController extends AbstractApiCrudController
|
|||
$fsRecordings = (new StationFilesystems($station))->getRecordingsFilesystem();
|
||||
|
||||
$paginator->setPostprocessor(
|
||||
function ($row) use ($streamer_id, $is_bootgrid, $router, $fsRecordings) {
|
||||
function ($row) use ($id, $is_bootgrid, $router, $fsRecordings) {
|
||||
$return = $this->toArray($row);
|
||||
|
||||
unset($return['recordingPath']);
|
||||
$recordingPath = $row->getRecordingPath();
|
||||
|
||||
if (null === $streamer_id) {
|
||||
if (null === $id) {
|
||||
$streamer = $row->getStreamer();
|
||||
$return['streamer'] = [
|
||||
'id' => $streamer->getId(),
|
||||
|
@ -85,7 +85,7 @@ final class BroadcastsController extends AbstractApiCrudController
|
|||
$routeParams = [
|
||||
'broadcast_id' => $row->getId(),
|
||||
];
|
||||
if (null === $streamer_id) {
|
||||
if (null === $id) {
|
||||
$routeParams['id'] = $row->getStreamer()->getId();
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,7 @@ final class BroadcastsController extends AbstractApiCrudController
|
|||
ServerRequest $request,
|
||||
Response $response,
|
||||
string $station_id,
|
||||
string $streamer_id,
|
||||
string $id,
|
||||
string $broadcast_id
|
||||
): ResponseInterface {
|
||||
$station = $request->getStation();
|
||||
|
@ -159,7 +159,7 @@ final class BroadcastsController extends AbstractApiCrudController
|
|||
ServerRequest $request,
|
||||
Response $response,
|
||||
string $station_id,
|
||||
string $streamer_id,
|
||||
string $id,
|
||||
string $broadcast_id
|
||||
): ResponseInterface {
|
||||
$station = $request->getStation();
|
||||
|
|
|
@ -7,7 +7,6 @@ namespace App\Controller\Api\Stations;
|
|||
use App\Controller\Api\Traits\CanSortResults;
|
||||
use App\Doctrine\ReloadableEntityManagerInterface;
|
||||
use App\Entity;
|
||||
use App\Exception\StationUnsupportedException;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\OpenApi;
|
||||
|
@ -286,38 +285,24 @@ final class StreamersController extends AbstractScheduledEntityController
|
|||
$return['has_custom_art'] = (0 !== $record->getArtUpdatedAt());
|
||||
$return['art'] = (string)$router->fromHere(
|
||||
route_name: 'api:stations:streamer:art',
|
||||
route_params: ['streamer_id' => $record->getIdRequired() . '|' . $record->getArtUpdatedAt()],
|
||||
route_params: ['id' => $record->getIdRequired() . '|' . $record->getArtUpdatedAt()],
|
||||
absolute: !$isInternal
|
||||
);
|
||||
|
||||
$return['links']['broadcasts'] = (string)$router->fromHere(
|
||||
route_name: 'api:stations:streamer:broadcasts',
|
||||
route_params: ['streamer_id' => $record->getId()],
|
||||
route_params: ['id' => $record->getId()],
|
||||
absolute: !$isInternal
|
||||
);
|
||||
$return['links']['art'] = (string)$router->fromHere(
|
||||
route_name: 'api:stations:streamer:art-internal',
|
||||
route_params: ['streamer_id' => $record->getId()],
|
||||
route_params: ['id' => $record->getId()],
|
||||
absolute: !$isInternal
|
||||
);
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function getStation(ServerRequest $request): Entity\Station
|
||||
{
|
||||
$station = parent::getStation($request);
|
||||
|
||||
if (!$station->getBackendTypeEnum()->isEnabled()) {
|
||||
throw new StationUnsupportedException();
|
||||
}
|
||||
|
||||
return $station;
|
||||
}
|
||||
|
||||
protected function deleteRecord(object $record): void
|
||||
{
|
||||
if (!($record instanceof Entity\StationStreamer)) {
|
||||
|
|
|
@ -6,7 +6,6 @@ namespace App\Controller\Stations;
|
|||
|
||||
use App\Entity\StationBackendConfiguration;
|
||||
use App\Event\Radio\WriteLiquidsoapConfiguration;
|
||||
use App\Exception\StationUnsupportedException;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Radio\Backend\Liquidsoap;
|
||||
|
@ -27,10 +26,6 @@ final class EditLiquidsoapConfigAction
|
|||
): ResponseInterface {
|
||||
$station = $request->getStation();
|
||||
|
||||
if (!$station->getBackendTypeEnum()->isEnabled()) {
|
||||
throw new StationUnsupportedException();
|
||||
}
|
||||
|
||||
$configSections = StationBackendConfiguration::getCustomConfigurationSections();
|
||||
$tokens = Liquidsoap\ConfigWriter::getDividerString();
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace App\Controller\Stations;
|
||||
|
||||
use App\Exception\StationUnsupportedException;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
@ -16,12 +15,6 @@ final class HlsStreamsAction
|
|||
Response $response,
|
||||
string $station_id
|
||||
): ResponseInterface {
|
||||
$station = $request->getStation();
|
||||
|
||||
if (!$station->getBackendTypeEnum()->isEnabled() || !$station->getEnableHls()) {
|
||||
throw new StationUnsupportedException();
|
||||
}
|
||||
|
||||
$router = $request->getRouter();
|
||||
return $request->getView()->renderVuePage(
|
||||
response: $response,
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use App\Entity\Station;
|
||||
|
||||
enum StationFeatures
|
||||
{
|
||||
case CustomLiquidsoapConfig;
|
||||
case Media;
|
||||
case Sftp;
|
||||
case MountPoints;
|
||||
case RemoteRelays;
|
||||
case HlsStreams;
|
||||
case Streamers;
|
||||
case Webhooks;
|
||||
case Podcasts;
|
||||
|
||||
public function supportedForStation(Station $station): bool
|
||||
{
|
||||
$backendEnabled = $station->getBackendTypeEnum()->isEnabled();
|
||||
|
||||
return match ($this) {
|
||||
self::Media, self::RemoteRelays, self::CustomLiquidsoapConfig => $backendEnabled,
|
||||
self::Streamers => $backendEnabled && $station->getEnableStreamers(),
|
||||
self::Sftp => $backendEnabled && $station->getMediaStorageLocation()->isLocal(),
|
||||
self::MountPoints => $station->getFrontendTypeEnum()->supportsMounts(),
|
||||
self::HlsStreams => $backendEnabled && $station->getEnableHls(),
|
||||
self::Webhooks, self::Podcasts => true,
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Middleware;
|
||||
|
||||
use App\Enums\StationFeatures;
|
||||
use App\Exception;
|
||||
use App\Http\ServerRequest;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
|
||||
final class StationSupportsFeature
|
||||
{
|
||||
public function __construct(
|
||||
private readonly StationFeatures $feature
|
||||
) {
|
||||
}
|
||||
|
||||
public function __invoke(ServerRequest $request, RequestHandlerInterface $handler): ResponseInterface
|
||||
{
|
||||
if (!$this->feature->supportedForStation($request->getStation())) {
|
||||
throw new Exception\StationUnsupportedException();
|
||||
}
|
||||
|
||||
return $handler->handle($request);
|
||||
}
|
||||
}
|
|
@ -14,6 +14,10 @@ class Api_Stations_StreamersCest extends CestAbstract
|
|||
|
||||
// Create new record
|
||||
$station = $this->getTestStation();
|
||||
$station->setEnableStreamers(true);
|
||||
$this->em->persist($station);
|
||||
$this->em->flush();
|
||||
|
||||
$listUrl = '/api/station/' . $station->getId() . '/streamers';
|
||||
|
||||
$I->sendPOST(
|
||||
|
|
Loading…
Reference in New Issue