Vuetify Liquidsoap config; other app cleanup.
This commit is contained in:
parent
5caa21ba33
commit
87ea336a12
|
@ -176,7 +176,7 @@ return function (CallableEventDispatcherInterface $dispatcher) {
|
|||
App\Radio\AutoDJ\Annotations::class,
|
||||
App\Radio\Backend\Liquidsoap\ConfigWriter::class,
|
||||
App\Sync\Task\NowPlayingTask::class,
|
||||
App\Controller\Api\NowplayingController::class,
|
||||
App\Controller\Api\NowPlayingAction::class,
|
||||
]
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<?php
|
||||
|
||||
use App\Acl;
|
||||
use App\Controller;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
|
@ -27,7 +26,7 @@ return static function (RouteCollectorProxy $app) {
|
|||
$group->get('', Controller\Api\IndexController::class . ':indexAction')
|
||||
->setName('api:index:index');
|
||||
|
||||
$group->get('/openapi.yml', Controller\Api\OpenApiController::class)
|
||||
$group->get('/openapi.yml', Controller\Api\OpenApiAction::class)
|
||||
->setName('api:openapi');
|
||||
|
||||
$group->get('/status', Controller\Api\IndexController::class . ':statusAction')
|
||||
|
@ -36,65 +35,6 @@ return static function (RouteCollectorProxy $app) {
|
|||
$group->get('/time', Controller\Api\IndexController::class . ':timeAction')
|
||||
->setName('api:index:time');
|
||||
|
||||
$group->group(
|
||||
'/frontend',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->group(
|
||||
'/account',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('/me', Controller\Api\Frontend\Account\GetMeAction::class)
|
||||
->setName('api:frontend:account:me');
|
||||
|
||||
$group->put('/me', Controller\Api\Frontend\Account\PutMeAction::class);
|
||||
|
||||
$group->put('/password', Controller\Api\Frontend\Account\PutPasswordAction::class)
|
||||
->setName('api:frontend:account:password');
|
||||
|
||||
$group->get('/two-factor', Controller\Api\Frontend\Account\GetTwoFactorAction::class)
|
||||
->setName('api:frontend:account:two-factor');
|
||||
|
||||
$group->put('/two-factor', Controller\Api\Frontend\Account\PutTwoFactorAction::class);
|
||||
|
||||
$group->delete('/two-factor', Controller\Api\Frontend\Account\DeleteTwoFactorAction::class);
|
||||
|
||||
$group->get(
|
||||
'/api-keys',
|
||||
Controller\Api\Frontend\Account\ApiKeysController::class . ':listAction'
|
||||
)->setName('api:frontend:api-keys');
|
||||
|
||||
$group->post(
|
||||
'/api-keys',
|
||||
Controller\Api\Frontend\Account\ApiKeysController::class . ':createAction'
|
||||
);
|
||||
|
||||
$group->get(
|
||||
'/api-key/{id}',
|
||||
Controller\Api\Frontend\Account\ApiKeysController::class . ':getAction'
|
||||
)->setName('api:frontend:api-key');
|
||||
|
||||
$group->delete(
|
||||
'/api-key/{id}',
|
||||
Controller\Api\Frontend\Account\ApiKeysController::class . ':deleteAction'
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
$group->group(
|
||||
'/dashboard',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('/charts', Controller\Api\Frontend\Dashboard\ChartsAction::class)
|
||||
->setName('api:frontend:dashboard:charts');
|
||||
|
||||
$group->get('/notifications', Controller\Api\Frontend\Dashboard\NotificationsAction::class)
|
||||
->setName('api:frontend:dashboard:notifications');
|
||||
|
||||
$group->get('/stations', Controller\Api\Frontend\Dashboard\StationsAction::class)
|
||||
->setName('api:frontend:dashboard:stations');
|
||||
}
|
||||
);
|
||||
}
|
||||
)->add(Middleware\RequireLogin::class);
|
||||
|
||||
$group->group(
|
||||
'/internal',
|
||||
function (RouteCollectorProxy $group) {
|
||||
|
@ -150,693 +90,16 @@ return static function (RouteCollectorProxy $app) {
|
|||
}
|
||||
);
|
||||
|
||||
$group->get('/nowplaying[/{station_id}]', Controller\Api\NowplayingController::class)
|
||||
$group->get('/nowplaying[/{station_id}]', Controller\Api\NowPlayingAction::class)
|
||||
->setName('api:nowplaying:index');
|
||||
|
||||
$group->get('/stations', Controller\Api\Stations\IndexController::class . ':listAction')
|
||||
->setName('api:stations:list')
|
||||
->add(new Middleware\RateLimit('api'));
|
||||
|
||||
$group->group(
|
||||
'/admin',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->group(
|
||||
'',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'/api-keys',
|
||||
Controller\Api\Admin\ApiKeysController::class . ':listAction'
|
||||
)->setName('api:admin:api-keys');
|
||||
|
||||
$group->get(
|
||||
'/api-key/{id}',
|
||||
Controller\Api\Admin\ApiKeysController::class . ':getAction'
|
||||
)->setName('api:admin:api-key');
|
||||
|
||||
$group->delete(
|
||||
'/api-key/{id}',
|
||||
Controller\Api\Admin\ApiKeysController::class . ':deleteAction'
|
||||
);
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::GLOBAL_API_KEYS));
|
||||
|
||||
$group->get('/auditlog', Controller\Api\Admin\AuditLogAction::class)
|
||||
->setName('api:admin:auditlog')
|
||||
->add(new Middleware\Permissions(Acl::GLOBAL_LOGS));
|
||||
|
||||
$group->group(
|
||||
'/backups',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Api\Admin\Backups\GetAction::class)
|
||||
->setName('api:admin:backups');
|
||||
|
||||
$group->post('/run', Controller\Api\Admin\Backups\RunAction::class)
|
||||
->setName('api:admin:backups:run');
|
||||
|
||||
$group->get('/log/{path}', Controller\Api\Admin\Backups\GetLogAction::class)
|
||||
->setName('api:admin:backups:log');
|
||||
|
||||
$group->get('/download/{path}', Controller\Api\Admin\Backups\DownloadAction::class)
|
||||
->setName('api:admin:backups:download');
|
||||
|
||||
$group->delete('/delete/{path}', Controller\Api\Admin\Backups\DeleteAction::class)
|
||||
->setName('api:admin:backups:delete');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::GLOBAL_BACKUPS));
|
||||
|
||||
$group->get('/permissions', Controller\Api\Admin\PermissionsController::class)
|
||||
->add(new Middleware\Permissions(Acl::GLOBAL_ALL));
|
||||
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/relays',
|
||||
function (ServerRequest $request, Response $response) {
|
||||
return $response->withRedirect(
|
||||
(string)$request->getRouter()->fromHere('api:internal:relays')
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
$group->group(
|
||||
'',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'/settings[/{group}]',
|
||||
Controller\Api\Admin\SettingsController::class . ':listAction'
|
||||
)->setName('api:admin:settings');
|
||||
|
||||
$group->put(
|
||||
'/settings[/{group}]',
|
||||
Controller\Api\Admin\SettingsController::class . ':updateAction'
|
||||
);
|
||||
|
||||
$group->get(
|
||||
'/custom_assets/{type}',
|
||||
Controller\Api\Admin\CustomAssets\GetCustomAssetAction::class
|
||||
)->setName('api:admin:custom_assets');
|
||||
|
||||
$group->post(
|
||||
'/custom_assets/{type}',
|
||||
Controller\Api\Admin\CustomAssets\PostCustomAssetAction::class
|
||||
);
|
||||
$group->delete(
|
||||
'/custom_assets/{type}',
|
||||
Controller\Api\Admin\CustomAssets\DeleteCustomAssetAction::class
|
||||
);
|
||||
|
||||
$group->get(
|
||||
'/geolite',
|
||||
Controller\Api\Admin\GeoLite\GetAction::class
|
||||
)->setName('api:admin:geolite');
|
||||
|
||||
$group->post(
|
||||
'/geolite',
|
||||
Controller\Api\Admin\GeoLite\PostAction::class
|
||||
);
|
||||
|
||||
$group->get(
|
||||
'/shoutcast',
|
||||
Controller\Api\Admin\Shoutcast\GetAction::class
|
||||
)->setName('api:admin:shoutcast');
|
||||
|
||||
$group->post(
|
||||
'/shoutcast',
|
||||
Controller\Api\Admin\Shoutcast\PostAction::class
|
||||
);
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::GLOBAL_SETTINGS));
|
||||
|
||||
$admin_api_endpoints = [
|
||||
[
|
||||
'custom_field',
|
||||
'custom_fields',
|
||||
Controller\Api\Admin\CustomFieldsController::class,
|
||||
Acl::GLOBAL_CUSTOM_FIELDS,
|
||||
],
|
||||
['role', 'roles', Controller\Api\Admin\RolesController::class, Acl::GLOBAL_ALL],
|
||||
['station', 'stations', Controller\Api\Admin\StationsController::class, Acl::GLOBAL_STATIONS],
|
||||
['user', 'users', Controller\Api\Admin\UsersController::class, Acl::GLOBAL_ALL],
|
||||
[
|
||||
'storage_location',
|
||||
'storage_locations',
|
||||
Controller\Api\Admin\StorageLocationsController::class,
|
||||
Acl::GLOBAL_STORAGE_LOCATIONS,
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($admin_api_endpoints as [$singular, $plural, $class, $permission]) {
|
||||
$group->group(
|
||||
'',
|
||||
function (RouteCollectorProxy $group) use ($singular, $plural, $class) {
|
||||
$group->get('/' . $plural, $class . ':listAction')
|
||||
->setName('api:admin:' . $plural);
|
||||
$group->post('/' . $plural, $class . ':createAction');
|
||||
|
||||
$group->get('/' . $singular . '/{id}', $class . ':getAction')
|
||||
->setName('api:admin:' . $singular);
|
||||
$group->put('/' . $singular . '/{id}', $class . ':editAction');
|
||||
$group->delete('/' . $singular . '/{id}', $class . ':deleteAction');
|
||||
}
|
||||
)->add(new Middleware\Permissions($permission));
|
||||
}
|
||||
|
||||
$group->post('/station/{id}/clone', Controller\Api\Admin\Stations\CloneAction::class)
|
||||
->setName('api:admin:station:clone')
|
||||
->add(new Middleware\Permissions(Acl::GLOBAL_STATIONS));
|
||||
|
||||
$group->get(
|
||||
'/stations/storage-locations',
|
||||
Controller\Api\Admin\Stations\StorageLocationsAction::class
|
||||
)->setName('api:admin:stations:storage-locations')
|
||||
->add(new Middleware\Permissions(Acl::GLOBAL_STATIONS));
|
||||
}
|
||||
);
|
||||
|
||||
$group->group(
|
||||
'/station/{station_id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Api\Stations\IndexController::class . ':indexAction')
|
||||
->setName('api:stations:index')
|
||||
->add(new Middleware\RateLimit('api', 5, 2));
|
||||
|
||||
$group->group(
|
||||
'/automation',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'/settings',
|
||||
Controller\Api\Stations\Automation\GetSettingsAction::class
|
||||
)->setName('api:stations:automation:settings');
|
||||
|
||||
$group->put(
|
||||
'/settings',
|
||||
Controller\Api\Stations\Automation\PutSettingsAction::class
|
||||
);
|
||||
|
||||
$group->put(
|
||||
'/run',
|
||||
Controller\Api\Stations\Automation\RunAction::class
|
||||
)->setName('api:stations:automation:run');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::STATION_AUTOMATION, true));
|
||||
|
||||
$group->get('/nowplaying', Controller\Api\NowplayingController::class . ':indexAction');
|
||||
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/nowplaying/update',
|
||||
Controller\Api\Stations\UpdateMetadataController::class
|
||||
)
|
||||
->add(new Middleware\Permissions(Acl::STATION_BROADCASTING, true));
|
||||
|
||||
$group->get('/profile', Controller\Api\Stations\ProfileController::class)
|
||||
->setName('api:stations:profile')
|
||||
->add(new Middleware\Permissions(Acl::STATION_VIEW, true));
|
||||
|
||||
$group->get(
|
||||
'/profile/edit',
|
||||
Controller\Api\Stations\ProfileEditController::class . ':getProfileAction'
|
||||
)->setName('api:stations:profile:edit')
|
||||
->add(new Middleware\Permissions(Acl::STATION_PROFILE, true));
|
||||
|
||||
$group->put(
|
||||
'/profile/edit',
|
||||
Controller\Api\Stations\ProfileEditController::class . ':putProfileAction'
|
||||
)->add(new Middleware\Permissions(Acl::STATION_PROFILE, true));
|
||||
|
||||
$group->get('/schedule', Controller\Api\Stations\ScheduleAction::class)
|
||||
->setName('api:stations:schedule');
|
||||
|
||||
$group->get('/history', Controller\Api\Stations\HistoryController::class)
|
||||
->setName('api:stations:history')
|
||||
->add(new Middleware\Permissions(Acl::STATION_REPORTS, true));
|
||||
|
||||
$group->group(
|
||||
'/queue',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Api\Stations\QueueController::class . ':listAction')
|
||||
->setName('api:stations:queue');
|
||||
|
||||
$group->post('/clear', Controller\Api\Stations\QueueController::class . ':clearAction')
|
||||
->setName('api:stations:queue:clear');
|
||||
|
||||
$group->delete('/{id}', Controller\Api\Stations\QueueController::class . ':deleteAction')
|
||||
->setName('api:stations:queue:record');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::STATION_BROADCASTING, true));
|
||||
|
||||
$group->get('/requests', Controller\Api\Stations\RequestsController::class . ':listAction')
|
||||
->setName('api:requests:list');
|
||||
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/request/{media_id}',
|
||||
Controller\Api\Stations\RequestsController::class . ':submitAction'
|
||||
)
|
||||
->setName('api:requests:submit')
|
||||
->add(new Middleware\RateLimit('api', 5, 2));
|
||||
|
||||
$group->get('/ondemand', Controller\Api\Stations\OnDemand\ListAction::class)
|
||||
->setName('api:stations:ondemand:list');
|
||||
|
||||
$group->get('/ondemand/download/{media_id}', Controller\Api\Stations\OnDemand\DownloadAction::class)
|
||||
->setName('api:stations:ondemand:download')
|
||||
->add(new Middleware\RateLimit('ondemand', 1, 2));
|
||||
|
||||
$group->get('/listeners', Controller\Api\Stations\ListenersAction::class)
|
||||
->setName('api:listeners:index')
|
||||
->add(new Middleware\Permissions(Acl::STATION_REPORTS, true));
|
||||
|
||||
$group->get(
|
||||
'/waveform/{media_id:[a-zA-Z0-9\-]+}.json',
|
||||
Controller\Api\Stations\Waveform\GetWaveformAction::class
|
||||
)
|
||||
->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');
|
||||
|
||||
$group->get('/art/{media_id:[a-zA-Z0-9\-]+}', Controller\Api\Stations\Art\GetArtAction::class)
|
||||
->setName('api:stations:media:art-internal');
|
||||
|
||||
$group->post('/art/{media_id:[a-zA-Z0-9]+}', Controller\Api\Stations\Art\PostArtAction::class)
|
||||
->add(new Middleware\Permissions(Acl::STATION_MEDIA, true));
|
||||
|
||||
$group->delete('/art/{media_id:[a-zA-Z0-9]+}', Controller\Api\Stations\Art\DeleteArtAction::class)
|
||||
->add(new Middleware\Permissions(Acl::STATION_MEDIA, true));
|
||||
|
||||
// Public and private podcast pages
|
||||
$group->group(
|
||||
'/podcast/{podcast_id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Api\Stations\PodcastsController::class . ':getAction')
|
||||
->setName('api:stations:podcast');
|
||||
|
||||
$group->get(
|
||||
'/art',
|
||||
Controller\Api\Stations\Podcasts\Art\GetArtAction::class
|
||||
)->setName('api:stations:podcast:art');
|
||||
|
||||
$group->get(
|
||||
'/episodes',
|
||||
Controller\Api\Stations\PodcastEpisodesController::class . ':listAction'
|
||||
)->setName('api:stations:podcast:episodes');
|
||||
|
||||
$group->group(
|
||||
'/episode/{episode_id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'',
|
||||
Controller\Api\Stations\PodcastEpisodesController::class . ':getAction'
|
||||
)->setName('api:stations:podcast:episode');
|
||||
|
||||
$group->get(
|
||||
'/art',
|
||||
Controller\Api\Stations\Podcasts\Episodes\Art\GetArtAction::class
|
||||
)->setName('api:stations:podcast:episode:art');
|
||||
|
||||
$group->get(
|
||||
'/download',
|
||||
Controller\Api\Stations\Podcasts\Episodes\Media\GetMediaAction::class
|
||||
)->setName('api:stations:podcast:episode:download');
|
||||
}
|
||||
);
|
||||
}
|
||||
)->add(Middleware\RequirePublishedPodcastEpisodeMiddleware::class);
|
||||
|
||||
// Private-only podcast pages
|
||||
$group->group(
|
||||
'/podcasts',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Api\Stations\PodcastsController::class . ':listAction')
|
||||
->setName('api:stations:podcasts');
|
||||
|
||||
$group->post('', Controller\Api\Stations\PodcastsController::class . ':createAction');
|
||||
|
||||
$group->post('/art', Controller\Api\Stations\Podcasts\Art\PostArtAction::class)
|
||||
->setName('api:stations:podcasts:new-art');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::STATION_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}',
|
||||
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(Acl::STATION_PODCASTS, true));
|
||||
|
||||
$station_api_endpoints = [
|
||||
['file', 'files', Controller\Api\Stations\FilesController::class, Acl::STATION_MEDIA],
|
||||
['mount', 'mounts', Controller\Api\Stations\MountsController::class, Acl::STATION_MOUNTS],
|
||||
[
|
||||
'playlist',
|
||||
'playlists',
|
||||
Controller\Api\Stations\PlaylistsController::class,
|
||||
Acl::STATION_MEDIA,
|
||||
],
|
||||
['remote', 'remotes', Controller\Api\Stations\RemotesController::class, Acl::STATION_REMOTES],
|
||||
[
|
||||
'sftp-user',
|
||||
'sftp-users',
|
||||
Controller\Api\Stations\SftpUsersController::class,
|
||||
Acl::STATION_MEDIA,
|
||||
],
|
||||
[
|
||||
'streamer',
|
||||
'streamers',
|
||||
Controller\Api\Stations\StreamersController::class,
|
||||
Acl::STATION_STREAMERS,
|
||||
],
|
||||
[
|
||||
'webhook',
|
||||
'webhooks',
|
||||
Controller\Api\Stations\WebhooksController::class,
|
||||
Acl::STATION_WEB_HOOKS,
|
||||
],
|
||||
];
|
||||
|
||||
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->map(
|
||||
['GET', 'POST'],
|
||||
'/upload',
|
||||
Controller\Api\Stations\Files\FlowUploadAction::class
|
||||
)->setName('api:stations:files:upload');
|
||||
}
|
||||
)
|
||||
->add(Middleware\Module\StationFiles::class)
|
||||
->add(new Middleware\Permissions(Acl::STATION_MEDIA, true));
|
||||
|
||||
$group->post(
|
||||
'/mounts/intro',
|
||||
Controller\Api\Stations\Mounts\Intro\PostIntroAction::class
|
||||
)->setName('api:stations:mounts:new-intro')
|
||||
->add(new Middleware\Permissions(Acl::STATION_MOUNTS, true));
|
||||
|
||||
$group->group(
|
||||
'/mount/{id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$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\Permissions(Acl::STATION_MOUNTS, true));
|
||||
|
||||
$group->get(
|
||||
'/playlists/schedule',
|
||||
Controller\Api\Stations\PlaylistsController::class . ':scheduleAction'
|
||||
)
|
||||
->setName('api:stations:playlists:schedule')
|
||||
->add(new Middleware\Permissions(Acl::STATION_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(Acl::STATION_MEDIA, true));
|
||||
|
||||
$group->group(
|
||||
'/reports',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->group(
|
||||
'/requests',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'',
|
||||
Controller\Api\Stations\Reports\RequestsController::class . ':listAction'
|
||||
)->setName('api:stations:reports:requests');
|
||||
|
||||
$group->post(
|
||||
'/clear',
|
||||
Controller\Api\Stations\Reports\RequestsController::class . ':clearAction'
|
||||
)->setName('api:stations:reports:requests:clear');
|
||||
|
||||
$group->delete(
|
||||
'/{request_id}',
|
||||
Controller\Api\Stations\Reports\RequestsController::class . ':deleteAction'
|
||||
)->setName('api:stations:reports:requests:delete');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::STATION_BROADCASTING, true));
|
||||
|
||||
$group->get(
|
||||
'/performance',
|
||||
Controller\Api\Stations\Reports\PerformanceAction::class
|
||||
)->setName('api:stations:reports:performance');
|
||||
|
||||
$group->get(
|
||||
'/overview/charts',
|
||||
Controller\Api\Stations\Reports\Overview\ChartsAction::class
|
||||
)->setName('api:stations:reports:overview-charts');
|
||||
|
||||
$group->get(
|
||||
'/overview/best-and-worst',
|
||||
Controller\Api\Stations\Reports\Overview\BestAndWorstAction::class
|
||||
)->setName('api:stations:reports:best-and-worst');
|
||||
|
||||
$group->get(
|
||||
'/overview/most-played',
|
||||
Controller\Api\Stations\Reports\Overview\MostPlayedAction::class
|
||||
)->setName('api:stations:reports:most-played');
|
||||
|
||||
$group->get(
|
||||
'/soundexchange',
|
||||
Controller\Api\Stations\Reports\SoundExchangeAction::class
|
||||
)->setName('api:stations:reports:soundexchange');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::STATION_REPORTS, true));
|
||||
|
||||
$group->get(
|
||||
'/streamers/schedule',
|
||||
Controller\Api\Stations\StreamersController::class . ':scheduleAction'
|
||||
)
|
||||
->setName('api:stations:streamers:schedule')
|
||||
->add(new Middleware\Permissions(Acl::STATION_STREAMERS, true));
|
||||
|
||||
$group->get(
|
||||
'/streamers/broadcasts',
|
||||
Controller\Api\Stations\Streamers\BroadcastsController::class . ':listAction'
|
||||
)
|
||||
->setName('api:stations:streamers:broadcasts')
|
||||
->add(new Middleware\Permissions(Acl::STATION_STREAMERS, true));
|
||||
|
||||
$group->group(
|
||||
'/streamer/{id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$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');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::STATION_STREAMERS, true));
|
||||
|
||||
$group->get('/status', Controller\Api\Stations\ServicesController::class . ':statusAction')
|
||||
->setName('api:stations:status')
|
||||
->add(new Middleware\Permissions(Acl::STATION_VIEW, true));
|
||||
|
||||
$group->post('/backend/{do}', Controller\Api\Stations\ServicesController::class . ':backendAction')
|
||||
->setName('api:stations:backend')
|
||||
->add(new Middleware\Permissions(Acl::STATION_BROADCASTING, true));
|
||||
|
||||
$group->post(
|
||||
'/frontend/{do}',
|
||||
Controller\Api\Stations\ServicesController::class . ':frontendAction'
|
||||
)
|
||||
->setName('api:stations:frontend')
|
||||
->add(new Middleware\Permissions(Acl::STATION_BROADCASTING, true));
|
||||
|
||||
$group->post('/restart', Controller\Api\Stations\ServicesController::class . ':restartAction')
|
||||
->setName('api:stations:restart')
|
||||
->add(new Middleware\Permissions(Acl::STATION_BROADCASTING, true));
|
||||
|
||||
$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(Acl::STATION_WEB_HOOKS, true));
|
||||
}
|
||||
)->add(Middleware\RequireStation::class)
|
||||
->add(Middleware\GetStation::class);
|
||||
call_user_func(include(__DIR__ . '/api_admin.php'), $group);
|
||||
call_user_func(include(__DIR__ . '/api_frontend.php'), $group);
|
||||
call_user_func(include(__DIR__ . '/api_station.php'), $group);
|
||||
}
|
||||
)->add(Middleware\Module\Api::class);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
<?php
|
||||
|
||||
use App\Acl;
|
||||
use App\Controller;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Middleware;
|
||||
use Slim\Routing\RouteCollectorProxy;
|
||||
|
||||
return static function (RouteCollectorProxy $group) {
|
||||
$group->group(
|
||||
'/admin',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->group(
|
||||
'',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'/api-keys',
|
||||
Controller\Api\Admin\ApiKeysController::class . ':listAction'
|
||||
)->setName('api:admin:api-keys');
|
||||
|
||||
$group->get(
|
||||
'/api-key/{id}',
|
||||
Controller\Api\Admin\ApiKeysController::class . ':getAction'
|
||||
)->setName('api:admin:api-key');
|
||||
|
||||
$group->delete(
|
||||
'/api-key/{id}',
|
||||
Controller\Api\Admin\ApiKeysController::class . ':deleteAction'
|
||||
);
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::GLOBAL_API_KEYS));
|
||||
|
||||
$group->get('/auditlog', Controller\Api\Admin\AuditLogAction::class)
|
||||
->setName('api:admin:auditlog')
|
||||
->add(new Middleware\Permissions(Acl::GLOBAL_LOGS));
|
||||
|
||||
$group->group(
|
||||
'/backups',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Api\Admin\Backups\GetAction::class)
|
||||
->setName('api:admin:backups');
|
||||
|
||||
$group->post('/run', Controller\Api\Admin\Backups\RunAction::class)
|
||||
->setName('api:admin:backups:run');
|
||||
|
||||
$group->get('/log/{path}', Controller\Api\Admin\Backups\GetLogAction::class)
|
||||
->setName('api:admin:backups:log');
|
||||
|
||||
$group->get('/download/{path}', Controller\Api\Admin\Backups\DownloadAction::class)
|
||||
->setName('api:admin:backups:download');
|
||||
|
||||
$group->delete('/delete/{path}', Controller\Api\Admin\Backups\DeleteAction::class)
|
||||
->setName('api:admin:backups:delete');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::GLOBAL_BACKUPS));
|
||||
|
||||
$group->get('/permissions', Controller\Api\Admin\PermissionsController::class)
|
||||
->add(new Middleware\Permissions(Acl::GLOBAL_ALL));
|
||||
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/relays',
|
||||
function (ServerRequest $request, Response $response) {
|
||||
return $response->withRedirect(
|
||||
(string)$request->getRouter()->fromHere('api:internal:relays')
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
$group->group(
|
||||
'',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'/settings[/{group}]',
|
||||
Controller\Api\Admin\SettingsController::class . ':listAction'
|
||||
)->setName('api:admin:settings');
|
||||
|
||||
$group->put(
|
||||
'/settings[/{group}]',
|
||||
Controller\Api\Admin\SettingsController::class . ':updateAction'
|
||||
);
|
||||
|
||||
$group->get(
|
||||
'/custom_assets/{type}',
|
||||
Controller\Api\Admin\CustomAssets\GetCustomAssetAction::class
|
||||
)->setName('api:admin:custom_assets');
|
||||
|
||||
$group->post(
|
||||
'/custom_assets/{type}',
|
||||
Controller\Api\Admin\CustomAssets\PostCustomAssetAction::class
|
||||
);
|
||||
$group->delete(
|
||||
'/custom_assets/{type}',
|
||||
Controller\Api\Admin\CustomAssets\DeleteCustomAssetAction::class
|
||||
);
|
||||
|
||||
$group->get(
|
||||
'/geolite',
|
||||
Controller\Api\Admin\GeoLite\GetAction::class
|
||||
)->setName('api:admin:geolite');
|
||||
|
||||
$group->post(
|
||||
'/geolite',
|
||||
Controller\Api\Admin\GeoLite\PostAction::class
|
||||
);
|
||||
|
||||
$group->get(
|
||||
'/shoutcast',
|
||||
Controller\Api\Admin\Shoutcast\GetAction::class
|
||||
)->setName('api:admin:shoutcast');
|
||||
|
||||
$group->post(
|
||||
'/shoutcast',
|
||||
Controller\Api\Admin\Shoutcast\PostAction::class
|
||||
);
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::GLOBAL_SETTINGS));
|
||||
|
||||
$admin_api_endpoints = [
|
||||
[
|
||||
'custom_field',
|
||||
'custom_fields',
|
||||
Controller\Api\Admin\CustomFieldsController::class,
|
||||
Acl::GLOBAL_CUSTOM_FIELDS,
|
||||
],
|
||||
['role', 'roles', Controller\Api\Admin\RolesController::class, Acl::GLOBAL_ALL],
|
||||
['station', 'stations', Controller\Api\Admin\StationsController::class, Acl::GLOBAL_STATIONS],
|
||||
['user', 'users', Controller\Api\Admin\UsersController::class, Acl::GLOBAL_ALL],
|
||||
[
|
||||
'storage_location',
|
||||
'storage_locations',
|
||||
Controller\Api\Admin\StorageLocationsController::class,
|
||||
Acl::GLOBAL_STORAGE_LOCATIONS,
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($admin_api_endpoints as [$singular, $plural, $class, $permission]) {
|
||||
$group->group(
|
||||
'',
|
||||
function (RouteCollectorProxy $group) use ($singular, $plural, $class) {
|
||||
$group->get('/' . $plural, $class . ':listAction')
|
||||
->setName('api:admin:' . $plural);
|
||||
$group->post('/' . $plural, $class . ':createAction');
|
||||
|
||||
$group->get('/' . $singular . '/{id}', $class . ':getAction')
|
||||
->setName('api:admin:' . $singular);
|
||||
$group->put('/' . $singular . '/{id}', $class . ':editAction');
|
||||
$group->delete('/' . $singular . '/{id}', $class . ':deleteAction');
|
||||
}
|
||||
)->add(new Middleware\Permissions($permission));
|
||||
}
|
||||
|
||||
$group->post('/station/{id}/clone', Controller\Api\Admin\Stations\CloneAction::class)
|
||||
->setName('api:admin:station:clone')
|
||||
->add(new Middleware\Permissions(Acl::GLOBAL_STATIONS));
|
||||
|
||||
$group->get(
|
||||
'/stations/storage-locations',
|
||||
Controller\Api\Admin\Stations\StorageLocationsAction::class
|
||||
)->setName('api:admin:stations:storage-locations')
|
||||
->add(new Middleware\Permissions(Acl::GLOBAL_STATIONS));
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
use App\Controller;
|
||||
use App\Middleware;
|
||||
use Slim\Routing\RouteCollectorProxy;
|
||||
|
||||
return static function (RouteCollectorProxy $group) {
|
||||
$group->group(
|
||||
'/frontend',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->group(
|
||||
'/account',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('/me', Controller\Api\Frontend\Account\GetMeAction::class)
|
||||
->setName('api:frontend:account:me');
|
||||
|
||||
$group->put('/me', Controller\Api\Frontend\Account\PutMeAction::class);
|
||||
|
||||
$group->put('/password', Controller\Api\Frontend\Account\PutPasswordAction::class)
|
||||
->setName('api:frontend:account:password');
|
||||
|
||||
$group->get('/two-factor', Controller\Api\Frontend\Account\GetTwoFactorAction::class)
|
||||
->setName('api:frontend:account:two-factor');
|
||||
|
||||
$group->put('/two-factor', Controller\Api\Frontend\Account\PutTwoFactorAction::class);
|
||||
|
||||
$group->delete('/two-factor', Controller\Api\Frontend\Account\DeleteTwoFactorAction::class);
|
||||
|
||||
$group->get(
|
||||
'/api-keys',
|
||||
Controller\Api\Frontend\Account\ApiKeysController::class . ':listAction'
|
||||
)->setName('api:frontend:api-keys');
|
||||
|
||||
$group->post(
|
||||
'/api-keys',
|
||||
Controller\Api\Frontend\Account\ApiKeysController::class . ':createAction'
|
||||
);
|
||||
|
||||
$group->get(
|
||||
'/api-key/{id}',
|
||||
Controller\Api\Frontend\Account\ApiKeysController::class . ':getAction'
|
||||
)->setName('api:frontend:api-key');
|
||||
|
||||
$group->delete(
|
||||
'/api-key/{id}',
|
||||
Controller\Api\Frontend\Account\ApiKeysController::class . ':deleteAction'
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
$group->group(
|
||||
'/dashboard',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('/charts', Controller\Api\Frontend\Dashboard\ChartsAction::class)
|
||||
->setName('api:frontend:dashboard:charts');
|
||||
|
||||
$group->get('/notifications', Controller\Api\Frontend\Dashboard\NotificationsAction::class)
|
||||
->setName('api:frontend:dashboard:notifications');
|
||||
|
||||
$group->get('/stations', Controller\Api\Frontend\Dashboard\StationsAction::class)
|
||||
->setName('api:frontend:dashboard:stations');
|
||||
}
|
||||
);
|
||||
}
|
||||
)->add(Middleware\RequireLogin::class);
|
||||
};
|
|
@ -0,0 +1,549 @@
|
|||
<?php
|
||||
|
||||
use App\Acl;
|
||||
use App\Controller;
|
||||
use App\Middleware;
|
||||
use Slim\Routing\RouteCollectorProxy;
|
||||
|
||||
return static function (RouteCollectorProxy $group) {
|
||||
$group->group(
|
||||
'/station/{station_id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Api\Stations\IndexController::class . ':indexAction')
|
||||
->setName('api:stations:index')
|
||||
->add(new Middleware\RateLimit('api', 5, 2));
|
||||
|
||||
$group->group(
|
||||
'/automation',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'/settings',
|
||||
Controller\Api\Stations\Automation\GetSettingsAction::class
|
||||
)->setName('api:stations:automation:settings');
|
||||
|
||||
$group->put(
|
||||
'/settings',
|
||||
Controller\Api\Stations\Automation\PutSettingsAction::class
|
||||
);
|
||||
|
||||
$group->put(
|
||||
'/run',
|
||||
Controller\Api\Stations\Automation\RunAction::class
|
||||
)->setName('api:stations:automation:run');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::STATION_AUTOMATION, true));
|
||||
|
||||
$group->get('/nowplaying', Controller\Api\NowPlayingAction::class . ':indexAction');
|
||||
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/nowplaying/update',
|
||||
Controller\Api\Stations\UpdateMetadataAction::class
|
||||
)
|
||||
->add(new Middleware\Permissions(Acl::STATION_BROADCASTING, true));
|
||||
|
||||
$group->get('/profile', Controller\Api\Stations\ProfileController::class)
|
||||
->setName('api:stations:profile')
|
||||
->add(new Middleware\Permissions(Acl::STATION_VIEW, true));
|
||||
|
||||
$group->get(
|
||||
'/profile/edit',
|
||||
Controller\Api\Stations\ProfileEditController::class . ':getProfileAction'
|
||||
)->setName('api:stations:profile:edit')
|
||||
->add(new Middleware\Permissions(Acl::STATION_PROFILE, true));
|
||||
|
||||
$group->put(
|
||||
'/profile/edit',
|
||||
Controller\Api\Stations\ProfileEditController::class . ':putProfileAction'
|
||||
)->add(new Middleware\Permissions(Acl::STATION_PROFILE, true));
|
||||
|
||||
$group->get('/schedule', Controller\Api\Stations\ScheduleAction::class)
|
||||
->setName('api:stations:schedule');
|
||||
|
||||
$group->get('/history', Controller\Api\Stations\HistoryController::class)
|
||||
->setName('api:stations:history')
|
||||
->add(new Middleware\Permissions(Acl::STATION_REPORTS, true));
|
||||
|
||||
$group->group(
|
||||
'/queue',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Api\Stations\QueueController::class . ':listAction')
|
||||
->setName('api:stations:queue');
|
||||
|
||||
$group->post('/clear', Controller\Api\Stations\QueueController::class . ':clearAction')
|
||||
->setName('api:stations:queue:clear');
|
||||
|
||||
$group->delete('/{id}', Controller\Api\Stations\QueueController::class . ':deleteAction')
|
||||
->setName('api:stations:queue:record');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::STATION_BROADCASTING, true));
|
||||
|
||||
$group->get('/requests', Controller\Api\Stations\RequestsController::class . ':listAction')
|
||||
->setName('api:requests:list');
|
||||
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/request/{media_id}',
|
||||
Controller\Api\Stations\RequestsController::class . ':submitAction'
|
||||
)
|
||||
->setName('api:requests:submit')
|
||||
->add(new Middleware\RateLimit('api', 5, 2));
|
||||
|
||||
$group->get('/ondemand', Controller\Api\Stations\OnDemand\ListAction::class)
|
||||
->setName('api:stations:ondemand:list');
|
||||
|
||||
$group->get('/ondemand/download/{media_id}', Controller\Api\Stations\OnDemand\DownloadAction::class)
|
||||
->setName('api:stations:ondemand:download')
|
||||
->add(new Middleware\RateLimit('ondemand', 1, 2));
|
||||
|
||||
$group->get('/listeners', Controller\Api\Stations\ListenersAction::class)
|
||||
->setName('api:listeners:index')
|
||||
->add(new Middleware\Permissions(Acl::STATION_REPORTS, true));
|
||||
|
||||
$group->get(
|
||||
'/waveform/{media_id:[a-zA-Z0-9\-]+}.json',
|
||||
Controller\Api\Stations\Waveform\GetWaveformAction::class
|
||||
)
|
||||
->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');
|
||||
|
||||
$group->get('/art/{media_id:[a-zA-Z0-9\-]+}', Controller\Api\Stations\Art\GetArtAction::class)
|
||||
->setName('api:stations:media:art-internal');
|
||||
|
||||
$group->post('/art/{media_id:[a-zA-Z0-9]+}', Controller\Api\Stations\Art\PostArtAction::class)
|
||||
->add(new Middleware\Permissions(Acl::STATION_MEDIA, true));
|
||||
|
||||
$group->delete('/art/{media_id:[a-zA-Z0-9]+}', Controller\Api\Stations\Art\DeleteArtAction::class)
|
||||
->add(new Middleware\Permissions(Acl::STATION_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(Acl::STATION_BROADCASTING, true));
|
||||
|
||||
// Public and private podcast pages
|
||||
$group->group(
|
||||
'/podcast/{podcast_id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Api\Stations\PodcastsController::class . ':getAction')
|
||||
->setName('api:stations:podcast');
|
||||
|
||||
$group->get(
|
||||
'/art',
|
||||
Controller\Api\Stations\Podcasts\Art\GetArtAction::class
|
||||
)->setName('api:stations:podcast:art');
|
||||
|
||||
$group->get(
|
||||
'/episodes',
|
||||
Controller\Api\Stations\PodcastEpisodesController::class . ':listAction'
|
||||
)->setName('api:stations:podcast:episodes');
|
||||
|
||||
$group->group(
|
||||
'/episode/{episode_id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'',
|
||||
Controller\Api\Stations\PodcastEpisodesController::class . ':getAction'
|
||||
)->setName('api:stations:podcast:episode');
|
||||
|
||||
$group->get(
|
||||
'/art',
|
||||
Controller\Api\Stations\Podcasts\Episodes\Art\GetArtAction::class
|
||||
)->setName('api:stations:podcast:episode:art');
|
||||
|
||||
$group->get(
|
||||
'/download',
|
||||
Controller\Api\Stations\Podcasts\Episodes\Media\GetMediaAction::class
|
||||
)->setName('api:stations:podcast:episode:download');
|
||||
}
|
||||
);
|
||||
}
|
||||
)->add(Middleware\RequirePublishedPodcastEpisodeMiddleware::class);
|
||||
|
||||
// Private-only podcast pages
|
||||
$group->group(
|
||||
'/podcasts',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Api\Stations\PodcastsController::class . ':listAction')
|
||||
->setName('api:stations:podcasts');
|
||||
|
||||
$group->post('', Controller\Api\Stations\PodcastsController::class . ':createAction');
|
||||
|
||||
$group->post('/art', Controller\Api\Stations\Podcasts\Art\PostArtAction::class)
|
||||
->setName('api:stations:podcasts:new-art');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::STATION_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}',
|
||||
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(Acl::STATION_PODCASTS, true));
|
||||
|
||||
$station_api_endpoints = [
|
||||
['file', 'files', Controller\Api\Stations\FilesController::class, Acl::STATION_MEDIA],
|
||||
['mount', 'mounts', Controller\Api\Stations\MountsController::class, Acl::STATION_MOUNTS],
|
||||
[
|
||||
'playlist',
|
||||
'playlists',
|
||||
Controller\Api\Stations\PlaylistsController::class,
|
||||
Acl::STATION_MEDIA,
|
||||
],
|
||||
['remote', 'remotes', Controller\Api\Stations\RemotesController::class, Acl::STATION_REMOTES],
|
||||
[
|
||||
'sftp-user',
|
||||
'sftp-users',
|
||||
Controller\Api\Stations\SftpUsersController::class,
|
||||
Acl::STATION_MEDIA,
|
||||
],
|
||||
[
|
||||
'streamer',
|
||||
'streamers',
|
||||
Controller\Api\Stations\StreamersController::class,
|
||||
Acl::STATION_STREAMERS,
|
||||
],
|
||||
[
|
||||
'webhook',
|
||||
'webhooks',
|
||||
Controller\Api\Stations\WebhooksController::class,
|
||||
Acl::STATION_WEB_HOOKS,
|
||||
],
|
||||
];
|
||||
|
||||
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->map(
|
||||
['GET', 'POST'],
|
||||
'/upload',
|
||||
Controller\Api\Stations\Files\FlowUploadAction::class
|
||||
)->setName('api:stations:files:upload');
|
||||
}
|
||||
)
|
||||
->add(Middleware\Module\StationFiles::class)
|
||||
->add(new Middleware\Permissions(Acl::STATION_MEDIA, true));
|
||||
|
||||
$group->post(
|
||||
'/mounts/intro',
|
||||
Controller\Api\Stations\Mounts\Intro\PostIntroAction::class
|
||||
)->setName('api:stations:mounts:new-intro')
|
||||
->add(new Middleware\Permissions(Acl::STATION_MOUNTS, true));
|
||||
|
||||
$group->group(
|
||||
'/mount/{id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$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\Permissions(Acl::STATION_MOUNTS, true));
|
||||
|
||||
$group->get(
|
||||
'/playlists/schedule',
|
||||
Controller\Api\Stations\PlaylistsController::class . ':scheduleAction'
|
||||
)
|
||||
->setName('api:stations:playlists:schedule')
|
||||
->add(new Middleware\Permissions(Acl::STATION_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(Acl::STATION_MEDIA, true));
|
||||
|
||||
$group->group(
|
||||
'/reports',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->group(
|
||||
'/requests',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'',
|
||||
Controller\Api\Stations\Reports\RequestsController::class . ':listAction'
|
||||
)->setName('api:stations:reports:requests');
|
||||
|
||||
$group->post(
|
||||
'/clear',
|
||||
Controller\Api\Stations\Reports\RequestsController::class . ':clearAction'
|
||||
)->setName('api:stations:reports:requests:clear');
|
||||
|
||||
$group->delete(
|
||||
'/{request_id}',
|
||||
Controller\Api\Stations\Reports\RequestsController::class . ':deleteAction'
|
||||
)->setName('api:stations:reports:requests:delete');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::STATION_BROADCASTING, true));
|
||||
|
||||
$group->get(
|
||||
'/performance',
|
||||
Controller\Api\Stations\Reports\PerformanceAction::class
|
||||
)->setName('api:stations:reports:performance');
|
||||
|
||||
$group->get(
|
||||
'/overview/charts',
|
||||
Controller\Api\Stations\Reports\Overview\ChartsAction::class
|
||||
)->setName('api:stations:reports:overview-charts');
|
||||
|
||||
$group->get(
|
||||
'/overview/best-and-worst',
|
||||
Controller\Api\Stations\Reports\Overview\BestAndWorstAction::class
|
||||
)->setName('api:stations:reports:best-and-worst');
|
||||
|
||||
$group->get(
|
||||
'/overview/most-played',
|
||||
Controller\Api\Stations\Reports\Overview\MostPlayedAction::class
|
||||
)->setName('api:stations:reports:most-played');
|
||||
|
||||
$group->get(
|
||||
'/soundexchange',
|
||||
Controller\Api\Stations\Reports\SoundExchangeAction::class
|
||||
)->setName('api:stations:reports:soundexchange');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::STATION_REPORTS, true));
|
||||
|
||||
$group->get(
|
||||
'/streamers/schedule',
|
||||
Controller\Api\Stations\StreamersController::class . ':scheduleAction'
|
||||
)
|
||||
->setName('api:stations:streamers:schedule')
|
||||
->add(new Middleware\Permissions(Acl::STATION_STREAMERS, true));
|
||||
|
||||
$group->get(
|
||||
'/streamers/broadcasts',
|
||||
Controller\Api\Stations\Streamers\BroadcastsController::class . ':listAction'
|
||||
)
|
||||
->setName('api:stations:streamers:broadcasts')
|
||||
->add(new Middleware\Permissions(Acl::STATION_STREAMERS, true));
|
||||
|
||||
$group->group(
|
||||
'/streamer/{id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$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');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::STATION_STREAMERS, true));
|
||||
|
||||
$group->get('/status', Controller\Api\Stations\ServicesController::class . ':statusAction')
|
||||
->setName('api:stations:status')
|
||||
->add(new Middleware\Permissions(Acl::STATION_VIEW, true));
|
||||
|
||||
$group->post('/backend/{do}', Controller\Api\Stations\ServicesController::class . ':backendAction')
|
||||
->setName('api:stations:backend')
|
||||
->add(new Middleware\Permissions(Acl::STATION_BROADCASTING, true));
|
||||
|
||||
$group->post(
|
||||
'/frontend/{do}',
|
||||
Controller\Api\Stations\ServicesController::class . ':frontendAction'
|
||||
)
|
||||
->setName('api:stations:frontend')
|
||||
->add(new Middleware\Permissions(Acl::STATION_BROADCASTING, true));
|
||||
|
||||
$group->post('/restart', Controller\Api\Stations\ServicesController::class . ':restartAction')
|
||||
->setName('api:stations:restart')
|
||||
->add(new Middleware\Permissions(Acl::STATION_BROADCASTING, true));
|
||||
|
||||
$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(Acl::STATION_WEB_HOOKS, true));
|
||||
}
|
||||
)->add(Middleware\RequireStation::class)
|
||||
->add(Middleware\GetStation::class);
|
||||
};
|
|
@ -30,7 +30,7 @@ return static function (RouteCollectorProxy $app) {
|
|||
->setName('stations:files:index')
|
||||
->add(new Middleware\Permissions(Acl::STATION_MEDIA, true));
|
||||
|
||||
$group->map(['GET', 'POST'], '/ls_config', Controller\Stations\EditLiquidsoapConfigAction::class)
|
||||
$group->get('/ls_config', Controller\Stations\EditLiquidsoapConfigAction::class)
|
||||
->setName('stations:util:ls_config')
|
||||
->add(new Middleware\Permissions(Acl::STATION_BROADCASTING, true));
|
||||
|
||||
|
|
|
@ -128,8 +128,6 @@ export default {
|
|||
this.axios.get(this.apiUrl).then((resp) => {
|
||||
this.populateForm(resp.data);
|
||||
this.loading = false;
|
||||
}).catch((error) => {
|
||||
this.close();
|
||||
});
|
||||
},
|
||||
populateForm(data) {
|
||||
|
@ -181,7 +179,6 @@ export default {
|
|||
this.$notifySuccess(this.$gettext('Changes saved.'));
|
||||
this.relist();
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
<template>
|
||||
<form class="form vue-form" @submit.prevent="submit">
|
||||
<section class="card" role="region">
|
||||
<div class="card-header bg-primary-dark">
|
||||
<h2 class="card-title">
|
||||
<translate key="lang_hdr">Edit Liquidsoap Configuration</translate>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<b-overlay variant="card" :show="loading">
|
||||
<div class="card-body">
|
||||
<b-form-fieldset v-for="(row, index) in config" :key="index" class="mb-0">
|
||||
<b-wrapped-form-group v-if="row.is_field" :field="$v.form[row.field_name]"
|
||||
:id="'form_edit_'+row.field_name" input-type="textarea"
|
||||
:input-attrs="{class: 'text-preformatted mb-3', spellcheck: 'false', style: 'height: 150px;'}">
|
||||
</b-wrapped-form-group>
|
||||
<b-form-markup v-else :id="'form_section_'+index">
|
||||
<pre class="typography-body-1">{{ row.markup }}</pre>
|
||||
</b-form-markup>
|
||||
</b-form-fieldset>
|
||||
|
||||
<b-button size="lg" type="submit" variant="primary" :disabled="$v.form.$invalid">
|
||||
<translate key="lang_btn_save_changes">Save Changes</translate>
|
||||
</b-button>
|
||||
</div>
|
||||
</b-overlay>
|
||||
</section>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BFormFieldset from "~/components/Form/BFormFieldset";
|
||||
import BWrappedFormGroup from "~/components/Form/BWrappedFormGroup";
|
||||
import BFormMarkup from "~/components/Form/BFormMarkup";
|
||||
import {validationMixin} from "vuelidate";
|
||||
import _ from "lodash";
|
||||
import mergeExisting from "~/functions/mergeExisting";
|
||||
|
||||
export default {
|
||||
name: 'StationsLiquidsoapConfig',
|
||||
components: {BFormFieldset, BWrappedFormGroup, BFormMarkup},
|
||||
props: {
|
||||
settingsUrl: String,
|
||||
config: Array,
|
||||
sections: Array,
|
||||
},
|
||||
mixins: [
|
||||
validationMixin
|
||||
],
|
||||
validations() {
|
||||
let validations = {form: {}};
|
||||
_.forEach(this.sections, (section) => {
|
||||
validations.form[section] = {};
|
||||
});
|
||||
return validations;
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
form: {},
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.relist();
|
||||
},
|
||||
methods: {
|
||||
resetForm() {
|
||||
let form = {};
|
||||
_.forEach(this.sections, (section) => {
|
||||
form[section] = null;
|
||||
});
|
||||
this.form = form;
|
||||
},
|
||||
relist() {
|
||||
this.resetForm();
|
||||
this.$v.form.$reset();
|
||||
|
||||
this.loading = true;
|
||||
this.axios.get(this.settingsUrl).then((resp) => {
|
||||
this.form = mergeExisting(this.form, resp.data);
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
submit() {
|
||||
this.$v.form.$touch();
|
||||
if (this.$v.form.$anyError) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.$wrapWithLoading(
|
||||
this.axios({
|
||||
method: 'PUT',
|
||||
url: this.settingsUrl,
|
||||
data: this.form
|
||||
})
|
||||
).then((resp) => {
|
||||
this.$notifySuccess();
|
||||
this.relist();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,7 @@
|
|||
import initBase from '~/base.js';
|
||||
|
||||
import '~/vendor/bootstrapVue.js';
|
||||
|
||||
import LiquidsoapConfig from '~/components/Stations/LiquidsoapConfig.vue';
|
||||
|
||||
export default initBase(LiquidsoapConfig);
|
|
@ -31,6 +31,7 @@ module.exports = {
|
|||
SetupSettings: '~/pages/Setup/Settings.js',
|
||||
SetupStation: '~/pages/Setup/Station.js',
|
||||
StationsAutomation: '~/pages/Stations/Automation.js',
|
||||
StationsLiquidsoapConfig: '~/pages/Stations/LiquidsoapConfig.js',
|
||||
StationsMedia: '~/pages/Stations/Media.js',
|
||||
StationsMounts: '~/pages/Stations/Mounts.js',
|
||||
StationsPlaylists: '~/pages/Stations/Playlists.js',
|
||||
|
|
|
@ -15,7 +15,7 @@ use Psr\Http\Message\ResponseInterface;
|
|||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
class NowplayingController implements EventSubscriberInterface
|
||||
class NowPlayingAction implements EventSubscriberInterface
|
||||
{
|
||||
public function __construct(
|
||||
protected EntityManagerInterface $em,
|
|
@ -9,7 +9,7 @@ use App\Http\Response;
|
|||
use App\Http\ServerRequest;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class OpenApiController
|
||||
class OpenApiAction
|
||||
{
|
||||
public function __invoke(
|
||||
ServerRequest $request,
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controller\Api\Stations\LiquidsoapConfig;
|
||||
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Radio\Backend\Liquidsoap\ConfigWriter;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class GetAction
|
||||
{
|
||||
public function __invoke(
|
||||
ServerRequest $request,
|
||||
Response $response
|
||||
): ResponseInterface {
|
||||
$backendConfig = $request->getStation()->getBackendConfig();
|
||||
|
||||
$return = [];
|
||||
foreach (ConfigWriter::getCustomConfigurationSections() as $field) {
|
||||
$return[$field] = $backendConfig[$field] ?? null;
|
||||
}
|
||||
|
||||
return $response->withJson($return);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controller\Api\Stations\LiquidsoapConfig;
|
||||
|
||||
use App\Doctrine\ReloadableEntityManagerInterface;
|
||||
use App\Entity;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Radio\Backend\Liquidsoap\ConfigWriter;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class PutAction
|
||||
{
|
||||
public function __invoke(
|
||||
ServerRequest $request,
|
||||
Response $response,
|
||||
ReloadableEntityManagerInterface $em
|
||||
): ResponseInterface {
|
||||
$body = (array)$request->getParsedBody();
|
||||
|
||||
$station = $em->refetch($request->getStation());
|
||||
|
||||
$backendConfig = $station->getBackendConfig();
|
||||
foreach (ConfigWriter::getCustomConfigurationSections() as $field) {
|
||||
if (isset($body[$field])) {
|
||||
$backendConfig->set($field, $body[$field]);
|
||||
}
|
||||
}
|
||||
|
||||
$station->setBackendConfig($backendConfig);
|
||||
|
||||
$em->persist($station);
|
||||
$em->flush();
|
||||
|
||||
return $response->withJson(Entity\Api\Status::updated());
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ use Psr\Http\Message\ResponseInterface;
|
|||
|
||||
use const ARRAY_FILTER_USE_KEY;
|
||||
|
||||
class UpdateMetadataController
|
||||
class UpdateMetadataAction
|
||||
{
|
||||
public function __invoke(ServerRequest $request, Response $response): ResponseInterface
|
||||
{
|
|
@ -5,13 +5,10 @@ declare(strict_types=1);
|
|||
namespace App\Controller\Stations;
|
||||
|
||||
use App\Entity\Repository\SettingsRepository;
|
||||
use App\Exception\AdvancedFeatureException;
|
||||
use App\Exception\StationUnsupportedException;
|
||||
use App\Form\Form;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Radio\Backend\Liquidsoap;
|
||||
use App\Session\Flash;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
|
@ -24,102 +21,50 @@ class EditLiquidsoapConfigAction
|
|||
SettingsRepository $settingsRepo
|
||||
): ResponseInterface {
|
||||
$station = $request->getStation();
|
||||
|
||||
$backend = $request->getStationBackend();
|
||||
|
||||
$settings = $settingsRepo->readSettings();
|
||||
if (!$settings->getEnableAdvancedFeatures()) {
|
||||
throw new AdvancedFeatureException();
|
||||
}
|
||||
|
||||
if (!($backend instanceof Liquidsoap)) {
|
||||
throw new StationUnsupportedException();
|
||||
}
|
||||
|
||||
$configSections = Liquidsoap\ConfigWriter::getCustomConfigurationSections();
|
||||
|
||||
$config = $backend->getEditableConfiguration($station);
|
||||
|
||||
$tokens = Liquidsoap\ConfigWriter::getDividerString();
|
||||
|
||||
$formConfig = [
|
||||
'method' => 'post',
|
||||
'enctype' => 'multipart/form-data',
|
||||
|
||||
'groups' => [
|
||||
'ls_config' => [
|
||||
'elements' => [],
|
||||
],
|
||||
|
||||
'submit_grp' => [
|
||||
'elements' => [
|
||||
'submit' => [
|
||||
'submit',
|
||||
[
|
||||
'type' => 'submit',
|
||||
'label' => __('Save Changes'),
|
||||
'class' => 'btn btn-lg btn-primary',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
$areas = [];
|
||||
|
||||
$tok = strtok($config, $tokens);
|
||||
$i = 0;
|
||||
|
||||
while ($tok !== false) {
|
||||
$tok = trim($tok);
|
||||
$i++;
|
||||
|
||||
if (in_array($tok, $configSections, true)) {
|
||||
$formConfig['groups']['ls_config']['elements'][$tok] = [
|
||||
'textarea',
|
||||
[
|
||||
'belongsTo' => 'backend_config',
|
||||
'class' => 'text-preformatted',
|
||||
'spellcheck' => 'false',
|
||||
],
|
||||
$areas[] = [
|
||||
'is_field' => true,
|
||||
'field_name' => $tok,
|
||||
];
|
||||
} else {
|
||||
$formConfig['groups']['ls_config']['elements']['config_section_' . $i] = [
|
||||
'markup',
|
||||
[
|
||||
'markup' => '<pre class="typography-body-1">' . $tok . '</pre>',
|
||||
],
|
||||
$areas[] = [
|
||||
'is_field' => false,
|
||||
'markup' => $tok,
|
||||
];
|
||||
}
|
||||
|
||||
$tok = strtok($tokens);
|
||||
}
|
||||
|
||||
$backendConfig = $station->getBackendConfig();
|
||||
$form = new Form($formConfig, ['backend_config' => $backendConfig->toArray()]);
|
||||
|
||||
if ($form->isValid($request)) {
|
||||
$data = $form->getValues();
|
||||
|
||||
foreach ($data['backend_config'] as $configKey => $configValue) {
|
||||
$backendConfig[$configKey] = $configValue;
|
||||
}
|
||||
|
||||
$station->setBackendConfig($backendConfig);
|
||||
|
||||
$em->persist($station);
|
||||
$em->flush();
|
||||
|
||||
$request->getFlash()->addMessage(__('Changes saved.'), Flash::SUCCESS);
|
||||
return $response->withRedirect($request->getUri()->getPath());
|
||||
}
|
||||
|
||||
return $request->getView()->renderToResponse(
|
||||
$response,
|
||||
'system/form_page',
|
||||
[
|
||||
'form' => $form,
|
||||
'render_mode' => 'edit',
|
||||
'title' => __('Edit Liquidsoap Configuration'),
|
||||
]
|
||||
$router = $request->getRouter();
|
||||
return $request->getView()->renderVuePage(
|
||||
response: $response,
|
||||
component: 'Vue_StationsLiquidsoapConfig',
|
||||
id: 'station-liquidsoap-config',
|
||||
title: __('Edit Liquidsoap Configuration'),
|
||||
props: [
|
||||
'settingsUrl' => (string)$router->fromHere('api:stations:liquidsoap-config'),
|
||||
'config' => $areas,
|
||||
'sections' => $configSections,
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue