Make unprocessable media downloadable and show processing errors.
This commit is contained in:
parent
c93d888459
commit
bdc6dcc22d
|
@ -7,194 +7,230 @@ use Slim\App;
|
|||
use Slim\Routing\RouteCollectorProxy;
|
||||
|
||||
return function (App $app) {
|
||||
$app->group('/admin', function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Admin\IndexController::class)
|
||||
->setName('admin:index:index');
|
||||
|
||||
$group->group('/debug', function (RouteCollectorProxy $group) {
|
||||
|
||||
$group->get('', Controller\Admin\DebugController::class)
|
||||
->setName('admin:debug:index');
|
||||
|
||||
$group->get('/clear-cache', Controller\Admin\DebugController::class . ':clearCacheAction')
|
||||
->setName('admin:debug:clear-cache');
|
||||
|
||||
$group->get('/clear-queue[/{queue}]',
|
||||
Controller\Admin\DebugController::class . ':clearQueueAction')
|
||||
->setName('admin:debug:clear-queue');
|
||||
|
||||
$group->get('/sync/{type}', Controller\Admin\DebugController::class . ':syncAction')
|
||||
->setName('admin:debug:sync');
|
||||
|
||||
$group->get('/log/{path}', Controller\Admin\DebugController::class . ':logAction')
|
||||
->setName('admin:debug:log');
|
||||
|
||||
$group->group('/station/{station_id}', function (RouteCollectorProxy $group) {
|
||||
|
||||
$group->map(['GET', 'POST'], '/nextsong', Controller\Admin\DebugController::class . ':nextsongAction')
|
||||
->setName('admin:debug:nextsong');
|
||||
|
||||
$group->post('/telnet', Controller\Admin\DebugController::class . ':telnetAction')
|
||||
->setName('admin:debug:telnet');
|
||||
|
||||
})->add(Middleware\GetStation::class);
|
||||
|
||||
})->add(new Middleware\Permissions(Acl::GLOBAL_ALL));
|
||||
|
||||
$group->group('/install', function (RouteCollectorProxy $group) {
|
||||
|
||||
$group->map(['GET', 'POST'], '/shoutcast', Controller\Admin\InstallShoutcastController::class)
|
||||
->setName('admin:install_shoutcast:index');
|
||||
|
||||
$group->map(['GET', 'POST'], '/geolite', Controller\Admin\InstallGeoLiteController::class)
|
||||
->setName('admin:install_geolite:index');
|
||||
|
||||
$group->get(
|
||||
'/geolite/uninstall/{csrf}',
|
||||
Controller\Admin\InstallGeoLiteController::class . ':uninstallAction'
|
||||
)->setName('admin:install_geolite:uninstall');
|
||||
|
||||
})->add(new Middleware\Permissions(Acl::GLOBAL_ALL));
|
||||
|
||||
$group->get('/auditlog', Controller\Admin\AuditLogController::class)
|
||||
->setName('admin:auditlog:index')
|
||||
->add(new Middleware\Permissions(Acl::GLOBAL_LOGS));
|
||||
|
||||
$group->group('/api', function (RouteCollectorProxy $group) {
|
||||
|
||||
$group->get('', Controller\Admin\ApiController::class . ':indexAction')
|
||||
->setName('admin:api:index');
|
||||
|
||||
$group->map(['GET', 'POST'], '/edit/{id}', Controller\Admin\ApiController::class . ':editAction')
|
||||
->setName('admin:api:edit');
|
||||
|
||||
$group->get('/delete/{id}/{csrf}', Controller\Admin\ApiController::class . ':deleteAction')
|
||||
->setName('admin:api:delete');
|
||||
|
||||
})->add(new Middleware\Permissions(Acl::GLOBAL_API_KEYS));
|
||||
|
||||
$group->group('/backups', function (RouteCollectorProxy $group) {
|
||||
|
||||
$group->get('', Controller\Admin\BackupsController::class)
|
||||
->setName('admin:backups:index');
|
||||
|
||||
$group->map(['GET', 'POST'], '/configure', Controller\Admin\BackupsController::class . ':configureAction')
|
||||
->setName('admin:backups:configure');
|
||||
|
||||
$group->map(['GET', 'POST'], '/run', Controller\Admin\BackupsController::class . ':runAction')
|
||||
->setName('admin:backups:run');
|
||||
|
||||
$group->get('/log/{path}', Controller\Admin\BackupsController::class . ':logAction')
|
||||
->setName('admin:backups:log');
|
||||
|
||||
$group->get('/download/{path}', Controller\Admin\BackupsController::class . ':downloadAction')
|
||||
->setName('admin:backups:download');
|
||||
|
||||
$group->get('/delete/{path}/{csrf}', Controller\Admin\BackupsController::class . ':deleteAction')
|
||||
->setName('admin:backups:delete');
|
||||
|
||||
})->add(new Middleware\Permissions(Acl::GLOBAL_BACKUPS));
|
||||
|
||||
$group->map(['GET', 'POST'], '/branding', Controller\Admin\BrandingController::class)
|
||||
->setName('admin:branding:index')
|
||||
->add(new Middleware\Permissions(Acl::GLOBAL_SETTINGS));
|
||||
|
||||
$group->group('/custom_fields', function (RouteCollectorProxy $group) {
|
||||
|
||||
$group->get('', Controller\Admin\CustomFieldsController::class . ':indexAction')
|
||||
->setName('admin:custom_fields:index');
|
||||
|
||||
$group->map(['GET', 'POST'], '/edit/{id}', Controller\Admin\CustomFieldsController::class . ':editAction')
|
||||
->setName('admin:custom_fields:edit');
|
||||
|
||||
$group->map(['GET', 'POST'], '/add', Controller\Admin\CustomFieldsController::class . ':editAction')
|
||||
->setName('admin:custom_fields:add');
|
||||
|
||||
$group->get('/delete/{id}/{csrf}', Controller\Admin\CustomFieldsController::class . ':deleteAction')
|
||||
->setName('admin:custom_fields:delete');
|
||||
|
||||
})->add(new Middleware\Permissions(Acl::GLOBAL_CUSTOM_FIELDS));
|
||||
|
||||
$group->group('/logs', function (RouteCollectorProxy $group) {
|
||||
|
||||
$group->get('', Controller\Admin\LogsController::class)
|
||||
->setName('admin:logs:index');
|
||||
|
||||
$group->get('/view/{station_id}/{log}', Controller\Admin\LogsController::class . ':viewAction')
|
||||
->setName('admin:logs:view')
|
||||
->add(Middleware\GetStation::class);
|
||||
|
||||
})->add(new Middleware\Permissions(Acl::GLOBAL_LOGS));
|
||||
|
||||
$group->group('/permissions', function (RouteCollectorProxy $group) {
|
||||
|
||||
$group->get('', Controller\Admin\PermissionsController::class . ':indexAction')
|
||||
->setName('admin:permissions:index');
|
||||
|
||||
$group->map(['GET', 'POST'], '/edit/{id}', Controller\Admin\PermissionsController::class . ':editAction')
|
||||
->setName('admin:permissions:edit');
|
||||
|
||||
$group->map(['GET', 'POST'], '/add', Controller\Admin\PermissionsController::class . ':editAction')
|
||||
->setName('admin:permissions:add');
|
||||
|
||||
$group->get('/delete/{id}/{csrf}', Controller\Admin\PermissionsController::class . ':deleteAction')
|
||||
->setName('admin:permissions:delete');
|
||||
|
||||
})->add(new Middleware\Permissions(Acl::GLOBAL_ALL));
|
||||
|
||||
$group->get('/relays', Controller\Admin\RelaysController::class)
|
||||
->setName('admin:relays:index')
|
||||
->add(new Middleware\Permissions(Acl::GLOBAL_STATIONS));
|
||||
|
||||
$group->map(['GET', 'POST'], '/settings', Controller\Admin\SettingsController::class)
|
||||
->setName('admin:settings:index')
|
||||
->add(new Middleware\Permissions(Acl::GLOBAL_SETTINGS));
|
||||
|
||||
$group->group('/stations', function (RouteCollectorProxy $group) {
|
||||
|
||||
$group->get('', Controller\Admin\StationsController::class)
|
||||
->setName('admin:stations:index');
|
||||
|
||||
$group->map(['GET', 'POST'], '/edit/{id}', Controller\Admin\StationsController::class . ':editAction')
|
||||
->setName('admin:stations:edit');
|
||||
|
||||
$group->map(['GET', 'POST'], '/add', Controller\Admin\StationsController::class . ':editAction')
|
||||
->setName('admin:stations:add');
|
||||
|
||||
$group->map(['GET', 'POST'], '/clone/{id}', Controller\Admin\StationsController::class . ':cloneAction')
|
||||
->setName('admin:stations:clone');
|
||||
|
||||
$group->get('/delete/{id}/{csrf}', Controller\Admin\StationsController::class . ':deleteAction')
|
||||
->setName('admin:stations:delete');
|
||||
|
||||
})->add(new Middleware\Permissions(Acl::GLOBAL_STATIONS));
|
||||
|
||||
$group->get('/storage_locations', Controller\Admin\StorageLocationsController::class)
|
||||
->setName('admin:storage_locations:index')
|
||||
->add(new Middleware\Permissions(Acl::GLOBAL_STORAGE_LOCATIONS));
|
||||
|
||||
$group->group('/users', function (RouteCollectorProxy $group) {
|
||||
|
||||
$group->get('', Controller\Admin\UsersController::class . ':indexAction')
|
||||
->setName('admin:users:index');
|
||||
|
||||
$group->map(['GET', 'POST'], '/edit/{id}', Controller\Admin\UsersController::class . ':editAction')
|
||||
->setName('admin:users:edit');
|
||||
|
||||
$group->map(['GET', 'POST'], '/add', Controller\Admin\UsersController::class . ':editAction')
|
||||
->setName('admin:users:add');
|
||||
|
||||
$group->get('/delete/{id}/{csrf}', Controller\Admin\UsersController::class . ':deleteAction')
|
||||
->setName('admin:users:delete');
|
||||
|
||||
$group->get('/login-as/{id}/{csrf}', Controller\Admin\UsersController::class . ':impersonateAction')
|
||||
->setName('admin:users:impersonate');
|
||||
|
||||
})->add(new Middleware\Permissions(Acl::GLOBAL_ALL));
|
||||
|
||||
// END /admin GROUP
|
||||
|
||||
})
|
||||
$app->group(
|
||||
'/admin',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Admin\IndexController::class)
|
||||
->setName('admin:index:index');
|
||||
|
||||
$group->group(
|
||||
'/debug',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Admin\DebugController::class)
|
||||
->setName('admin:debug:index');
|
||||
|
||||
$group->get('/clear-cache', Controller\Admin\DebugController::class . ':clearCacheAction')
|
||||
->setName('admin:debug:clear-cache');
|
||||
|
||||
$group->get(
|
||||
'/clear-queue[/{queue}]',
|
||||
Controller\Admin\DebugController::class . ':clearQueueAction'
|
||||
)
|
||||
->setName('admin:debug:clear-queue');
|
||||
|
||||
$group->get('/sync/{type}', Controller\Admin\DebugController::class . ':syncAction')
|
||||
->setName('admin:debug:sync');
|
||||
|
||||
$group->get('/log/{path}', Controller\Admin\DebugController::class . ':logAction')
|
||||
->setName('admin:debug:log');
|
||||
|
||||
$group->group(
|
||||
'/station/{station_id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/nextsong',
|
||||
Controller\Admin\DebugController::class . ':nextsongAction'
|
||||
)
|
||||
->setName('admin:debug:nextsong');
|
||||
|
||||
$group->post('/telnet', Controller\Admin\DebugController::class . ':telnetAction')
|
||||
->setName('admin:debug:telnet');
|
||||
}
|
||||
)->add(Middleware\GetStation::class);
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::GLOBAL_ALL));
|
||||
|
||||
$group->group(
|
||||
'/install',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->map(['GET', 'POST'], '/shoutcast', Controller\Admin\InstallShoutcastController::class)
|
||||
->setName('admin:install_shoutcast:index');
|
||||
|
||||
$group->map(['GET', 'POST'], '/geolite', Controller\Admin\InstallGeoLiteController::class)
|
||||
->setName('admin:install_geolite:index');
|
||||
|
||||
$group->get(
|
||||
'/geolite/uninstall/{csrf}',
|
||||
Controller\Admin\InstallGeoLiteController::class . ':uninstallAction'
|
||||
)->setName('admin:install_geolite:uninstall');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::GLOBAL_ALL));
|
||||
|
||||
$group->get('/auditlog', Controller\Admin\AuditLogController::class)
|
||||
->setName('admin:auditlog:index')
|
||||
->add(new Middleware\Permissions(Acl::GLOBAL_LOGS));
|
||||
|
||||
$group->group(
|
||||
'/api',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Admin\ApiController::class . ':indexAction')
|
||||
->setName('admin:api:index');
|
||||
|
||||
$group->map(['GET', 'POST'], '/edit/{id}', Controller\Admin\ApiController::class . ':editAction')
|
||||
->setName('admin:api:edit');
|
||||
|
||||
$group->get('/delete/{id}/{csrf}', Controller\Admin\ApiController::class . ':deleteAction')
|
||||
->setName('admin:api:delete');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::GLOBAL_API_KEYS));
|
||||
|
||||
$group->group(
|
||||
'/backups',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Admin\BackupsController::class)
|
||||
->setName('admin:backups:index');
|
||||
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/configure',
|
||||
Controller\Admin\BackupsController::class . ':configureAction'
|
||||
)
|
||||
->setName('admin:backups:configure');
|
||||
|
||||
$group->map(['GET', 'POST'], '/run', Controller\Admin\BackupsController::class . ':runAction')
|
||||
->setName('admin:backups:run');
|
||||
|
||||
$group->get('/log/{path}', Controller\Admin\BackupsController::class . ':logAction')
|
||||
->setName('admin:backups:log');
|
||||
|
||||
$group->get('/download/{path}', Controller\Admin\BackupsController::class . ':downloadAction')
|
||||
->setName('admin:backups:download');
|
||||
|
||||
$group->get('/delete/{path}/{csrf}', Controller\Admin\BackupsController::class . ':deleteAction')
|
||||
->setName('admin:backups:delete');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::GLOBAL_BACKUPS));
|
||||
|
||||
$group->map(['GET', 'POST'], '/branding', Controller\Admin\BrandingController::class)
|
||||
->setName('admin:branding:index')
|
||||
->add(new Middleware\Permissions(Acl::GLOBAL_SETTINGS));
|
||||
|
||||
$group->group(
|
||||
'/custom_fields',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Admin\CustomFieldsController::class . ':indexAction')
|
||||
->setName('admin:custom_fields:index');
|
||||
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/edit/{id}',
|
||||
Controller\Admin\CustomFieldsController::class . ':editAction'
|
||||
)
|
||||
->setName('admin:custom_fields:edit');
|
||||
|
||||
$group->map(['GET', 'POST'], '/add', Controller\Admin\CustomFieldsController::class . ':editAction')
|
||||
->setName('admin:custom_fields:add');
|
||||
|
||||
$group->get('/delete/{id}/{csrf}', Controller\Admin\CustomFieldsController::class . ':deleteAction')
|
||||
->setName('admin:custom_fields:delete');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::GLOBAL_CUSTOM_FIELDS));
|
||||
|
||||
$group->group(
|
||||
'/logs',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Admin\LogsController::class)
|
||||
->setName('admin:logs:index');
|
||||
|
||||
$group->get('/view/{station_id}/{log}', Controller\Admin\LogsController::class . ':viewAction')
|
||||
->setName('admin:logs:view')
|
||||
->add(Middleware\GetStation::class);
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::GLOBAL_LOGS));
|
||||
|
||||
$group->group(
|
||||
'/permissions',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Admin\PermissionsController::class . ':indexAction')
|
||||
->setName('admin:permissions:index');
|
||||
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/edit/{id}',
|
||||
Controller\Admin\PermissionsController::class . ':editAction'
|
||||
)
|
||||
->setName('admin:permissions:edit');
|
||||
|
||||
$group->map(['GET', 'POST'], '/add', Controller\Admin\PermissionsController::class . ':editAction')
|
||||
->setName('admin:permissions:add');
|
||||
|
||||
$group->get('/delete/{id}/{csrf}', Controller\Admin\PermissionsController::class . ':deleteAction')
|
||||
->setName('admin:permissions:delete');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::GLOBAL_ALL));
|
||||
|
||||
$group->get('/relays', Controller\Admin\RelaysController::class)
|
||||
->setName('admin:relays:index')
|
||||
->add(new Middleware\Permissions(Acl::GLOBAL_STATIONS));
|
||||
|
||||
$group->map(['GET', 'POST'], '/settings', Controller\Admin\SettingsController::class)
|
||||
->setName('admin:settings:index')
|
||||
->add(new Middleware\Permissions(Acl::GLOBAL_SETTINGS));
|
||||
|
||||
$group->group(
|
||||
'/stations',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Admin\StationsController::class)
|
||||
->setName('admin:stations:index');
|
||||
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/edit/{id}',
|
||||
Controller\Admin\StationsController::class . ':editAction'
|
||||
)
|
||||
->setName('admin:stations:edit');
|
||||
|
||||
$group->map(['GET', 'POST'], '/add', Controller\Admin\StationsController::class . ':editAction')
|
||||
->setName('admin:stations:add');
|
||||
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/clone/{id}',
|
||||
Controller\Admin\StationsController::class . ':cloneAction'
|
||||
)
|
||||
->setName('admin:stations:clone');
|
||||
|
||||
$group->get('/delete/{id}/{csrf}', Controller\Admin\StationsController::class . ':deleteAction')
|
||||
->setName('admin:stations:delete');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::GLOBAL_STATIONS));
|
||||
|
||||
$group->get('/storage_locations', Controller\Admin\StorageLocationsController::class)
|
||||
->setName('admin:storage_locations:index')
|
||||
->add(new Middleware\Permissions(Acl::GLOBAL_STORAGE_LOCATIONS));
|
||||
|
||||
$group->group(
|
||||
'/users',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Admin\UsersController::class . ':indexAction')
|
||||
->setName('admin:users:index');
|
||||
|
||||
$group->map(['GET', 'POST'], '/edit/{id}', Controller\Admin\UsersController::class . ':editAction')
|
||||
->setName('admin:users:edit');
|
||||
|
||||
$group->map(['GET', 'POST'], '/add', Controller\Admin\UsersController::class . ':editAction')
|
||||
->setName('admin:users:add');
|
||||
|
||||
$group->get('/delete/{id}/{csrf}', Controller\Admin\UsersController::class . ':deleteAction')
|
||||
->setName('admin:users:delete');
|
||||
|
||||
$group->get('/login-as/{id}/{csrf}', Controller\Admin\UsersController::class . ':impersonateAction')
|
||||
->setName('admin:users:impersonate');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::GLOBAL_ALL));
|
||||
}
|
||||
)
|
||||
->add(Middleware\Module\Admin::class)
|
||||
->add(Middleware\EnableView::class)
|
||||
->add(new Middleware\Permissions(Acl::GLOBAL_VIEW))
|
||||
|
|
|
@ -9,302 +9,404 @@ use Slim\App;
|
|||
use Slim\Routing\RouteCollectorProxy;
|
||||
|
||||
return function (App $app) {
|
||||
|
||||
$app->group('/api', function (RouteCollectorProxy $group) {
|
||||
|
||||
$group->options('/{routes:.+}', function (ServerRequest $request, Response $response) {
|
||||
return $response
|
||||
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
|
||||
->withHeader('Access-Control-Allow-Headers',
|
||||
'x-requested-with, Content-Type, Accept, Origin, Authorization')
|
||||
->withHeader('Access-Control-Allow-Origin', '*');
|
||||
});
|
||||
|
||||
$group->get('', Controller\Api\IndexController::class . ':indexAction')
|
||||
->setName('api:index:index');
|
||||
|
||||
$group->get('/openapi.yml', Controller\Api\OpenApiController::class)
|
||||
->setName('api:openapi');
|
||||
|
||||
$group->get('/status', Controller\Api\IndexController::class . ':statusAction')
|
||||
->setName('api:index:status');
|
||||
|
||||
$group->get('/time', Controller\Api\IndexController::class . ':timeAction')
|
||||
->setName('api:index:time');
|
||||
|
||||
$group->group('/internal', function (RouteCollectorProxy $group) {
|
||||
|
||||
$group->group('/{station_id}', function (RouteCollectorProxy $group) {
|
||||
|
||||
// Liquidsoap internal authentication functions
|
||||
$group->map(['GET', 'POST'], '/auth', Controller\Api\InternalController::class . ':authAction')
|
||||
->setName('api:internal:auth');
|
||||
|
||||
$group->map(['GET', 'POST'], '/nextsong', Controller\Api\InternalController::class . ':nextsongAction')
|
||||
->setName('api:internal:nextsong');
|
||||
|
||||
$group->map(['GET', 'POST'], '/djon', Controller\Api\InternalController::class . ':djonAction')
|
||||
->setName('api:internal:djon');
|
||||
|
||||
$group->map(['GET', 'POST'], '/djoff', Controller\Api\InternalController::class . ':djoffAction')
|
||||
->setName('api:internal:djoff');
|
||||
|
||||
$group->map(['GET', 'POST'], '/feedback', Controller\Api\InternalController::class . ':feedbackAction')
|
||||
->setName('api:internal:feedback');
|
||||
|
||||
})->add(Middleware\GetStation::class);
|
||||
|
||||
$group->get('/relays', Controller\Api\Admin\RelaysController::class)
|
||||
->setName('api:internal:relays')
|
||||
->add(Middleware\RequireLogin::class);
|
||||
|
||||
$group->post('/relays', Controller\Api\Admin\RelaysController::class . ':updateAction')
|
||||
->add(Middleware\RequireLogin::class);
|
||||
|
||||
});
|
||||
|
||||
$group->get('/nowplaying[/{station_id}]', Controller\Api\NowplayingController::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->get('/auditlog', Controller\Api\Admin\AuditLogController::class)
|
||||
->setName('api:admin:auditlog')
|
||||
->add(new Middleware\Permissions(Acl::GLOBAL_LOGS));
|
||||
|
||||
$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', Controller\Api\Admin\SettingsController::class . ':listAction')
|
||||
->setName('api:admin:settings');
|
||||
|
||||
$group->put('/settings', Controller\Api\Admin\SettingsController::class . ':updateAction');
|
||||
})->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->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->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('/schedule', Controller\Api\Stations\ScheduleController::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->get('/{id}', Controller\Api\Stations\QueueController::class . ':getAction')
|
||||
->setName('api:stations:queue:record');
|
||||
|
||||
$group->delete('/{id}', Controller\Api\Stations\QueueController::class . ':deleteAction');
|
||||
})->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\ListenersController::class . ':indexAction')
|
||||
->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));
|
||||
|
||||
$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],
|
||||
['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->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->get('/download/{id}', Controller\Api\Stations\Files\DownloadAction::class)
|
||||
->setName('api:stations:file:download')
|
||||
->add(new Middleware\Permissions(Acl::STATION_MEDIA, 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\PlaylistsController::class . ':toggleAction')
|
||||
->setName('api:stations:playlist:toggle');
|
||||
|
||||
$group->put('/reshuffle', Controller\Api\Stations\PlaylistsController::class . ':reshuffleAction')
|
||||
->setName('api:stations:playlist:reshuffle');
|
||||
|
||||
$group->get('/order', Controller\Api\Stations\PlaylistsController::class . ':getOrderAction')
|
||||
->setName('api:stations:playlist:order');
|
||||
|
||||
$group->put('/order', Controller\Api\Stations\PlaylistsController::class . ':putOrderAction');
|
||||
|
||||
$group->post('/import', Controller\Api\Stations\PlaylistsController::class . ':importAction')
|
||||
->setName('api:stations:playlist:import');
|
||||
|
||||
$group->get('/export[/{format}]',
|
||||
Controller\Api\Stations\PlaylistsController::class . ':exportAction')
|
||||
->setName('api:stations:playlist:export');
|
||||
|
||||
})->add(new Middleware\Permissions(Acl::STATION_MEDIA, 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->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));
|
||||
|
||||
})->add(Middleware\RequireStation::class)
|
||||
->add(Middleware\GetStation::class);
|
||||
|
||||
// END /api GROUP
|
||||
|
||||
})->add(Middleware\Module\Api::class);
|
||||
|
||||
$app->group(
|
||||
'/api',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->options(
|
||||
'/{routes:.+}',
|
||||
function (ServerRequest $request, Response $response) {
|
||||
return $response
|
||||
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
|
||||
->withHeader(
|
||||
'Access-Control-Allow-Headers',
|
||||
'x-requested-with, Content-Type, Accept, Origin, Authorization'
|
||||
)
|
||||
->withHeader('Access-Control-Allow-Origin', '*');
|
||||
}
|
||||
);
|
||||
|
||||
$group->get('', Controller\Api\IndexController::class . ':indexAction')
|
||||
->setName('api:index:index');
|
||||
|
||||
$group->get('/openapi.yml', Controller\Api\OpenApiController::class)
|
||||
->setName('api:openapi');
|
||||
|
||||
$group->get('/status', Controller\Api\IndexController::class . ':statusAction')
|
||||
->setName('api:index:status');
|
||||
|
||||
$group->get('/time', Controller\Api\IndexController::class . ':timeAction')
|
||||
->setName('api:index:time');
|
||||
|
||||
$group->group(
|
||||
'/internal',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->group(
|
||||
'/{station_id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
// Liquidsoap internal authentication functions
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/auth',
|
||||
Controller\Api\InternalController::class . ':authAction'
|
||||
)->setName('api:internal:auth');
|
||||
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/nextsong',
|
||||
Controller\Api\InternalController::class . ':nextsongAction'
|
||||
)->setName('api:internal:nextsong');
|
||||
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/djon',
|
||||
Controller\Api\InternalController::class . ':djonAction'
|
||||
)->setName('api:internal:djon');
|
||||
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/djoff',
|
||||
Controller\Api\InternalController::class . ':djoffAction'
|
||||
)->setName('api:internal:djoff');
|
||||
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/feedback',
|
||||
Controller\Api\InternalController::class . ':feedbackAction'
|
||||
)->setName('api:internal:feedback');
|
||||
}
|
||||
)->add(Middleware\GetStation::class);
|
||||
|
||||
$group->get('/relays', Controller\Api\Admin\RelaysController::class)
|
||||
->setName('api:internal:relays')
|
||||
->add(Middleware\RequireLogin::class);
|
||||
|
||||
$group->post('/relays', Controller\Api\Admin\RelaysController::class . ':updateAction')
|
||||
->add(Middleware\RequireLogin::class);
|
||||
}
|
||||
);
|
||||
|
||||
$group->get('/nowplaying[/{station_id}]', Controller\Api\NowplayingController::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->get('/auditlog', Controller\Api\Admin\AuditLogController::class)
|
||||
->setName('api:admin:auditlog')
|
||||
->add(new Middleware\Permissions(Acl::GLOBAL_LOGS));
|
||||
|
||||
$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', Controller\Api\Admin\SettingsController::class . ':listAction')
|
||||
->setName('api:admin:settings');
|
||||
|
||||
$group->put('/settings', Controller\Api\Admin\SettingsController::class . ':updateAction');
|
||||
}
|
||||
)->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->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->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('/schedule', Controller\Api\Stations\ScheduleController::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->get('/{id}', Controller\Api\Stations\QueueController::class . ':getAction')
|
||||
->setName('api:stations:queue:record');
|
||||
|
||||
$group->delete('/{id}', Controller\Api\Stations\QueueController::class . ':deleteAction');
|
||||
}
|
||||
)->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\ListenersController::class . ':indexAction')
|
||||
->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));
|
||||
|
||||
$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],
|
||||
[
|
||||
'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->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\PlaylistsController::class . ':toggleAction')
|
||||
->setName('api:stations:playlist:toggle');
|
||||
|
||||
$group->put(
|
||||
'/reshuffle',
|
||||
Controller\Api\Stations\PlaylistsController::class . ':reshuffleAction'
|
||||
)
|
||||
->setName('api:stations:playlist:reshuffle');
|
||||
|
||||
$group->get(
|
||||
'/order',
|
||||
Controller\Api\Stations\PlaylistsController::class . ':getOrderAction'
|
||||
)
|
||||
->setName('api:stations:playlist:order');
|
||||
|
||||
$group->put(
|
||||
'/order',
|
||||
Controller\Api\Stations\PlaylistsController::class . ':putOrderAction'
|
||||
);
|
||||
|
||||
$group->post(
|
||||
'/import',
|
||||
Controller\Api\Stations\PlaylistsController::class . ':importAction'
|
||||
)
|
||||
->setName('api:stations:playlist:import');
|
||||
|
||||
$group->get(
|
||||
'/export[/{format}]',
|
||||
Controller\Api\Stations\PlaylistsController::class . ':exportAction'
|
||||
)
|
||||
->setName('api:stations:playlist:export');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::STATION_MEDIA, 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->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));
|
||||
}
|
||||
)->add(Middleware\RequireStation::class)
|
||||
->add(Middleware\GetStation::class);
|
||||
}
|
||||
)->add(Middleware\Module\Api::class);
|
||||
};
|
||||
|
|
|
@ -6,52 +6,61 @@ use Slim\App;
|
|||
use Slim\Routing\RouteCollectorProxy;
|
||||
|
||||
return function (App $app) {
|
||||
|
||||
$app->get('/', Controller\Frontend\IndexController::class . ':indexAction')
|
||||
->setName('home');
|
||||
|
||||
$app->group('', function (RouteCollectorProxy $group) {
|
||||
$app->group(
|
||||
'',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('/dashboard', Controller\Frontend\DashboardController::class . ':indexAction')
|
||||
->setName('dashboard');
|
||||
|
||||
$group->get('/dashboard', Controller\Frontend\DashboardController::class . ':indexAction')
|
||||
->setName('dashboard');
|
||||
$group->get('/logout', Controller\Frontend\Account\LogoutAction::class)
|
||||
->setName('account:logout');
|
||||
|
||||
$group->get('/logout', Controller\Frontend\Account\LogoutAction::class)
|
||||
->setName('account:logout');
|
||||
$group->get('/endsession', Controller\Frontend\Account\EndMasqueradeAction::class)
|
||||
->setName('account:endmasquerade');
|
||||
|
||||
$group->get('/endsession', Controller\Frontend\Account\EndMasqueradeAction::class)
|
||||
->setName('account:endmasquerade');
|
||||
$group->get('/profile', Controller\Frontend\Profile\IndexAction::class)
|
||||
->setName('profile:index');
|
||||
|
||||
$group->get('/profile', Controller\Frontend\Profile\IndexAction::class)
|
||||
->setName('profile:index');
|
||||
$group->map(['GET', 'POST'], '/profile/edit', Controller\Frontend\Profile\EditAction::class)
|
||||
->setName('profile:edit');
|
||||
|
||||
$group->map(['GET', 'POST'], '/profile/edit', Controller\Frontend\Profile\EditAction::class)
|
||||
->setName('profile:edit');
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/profile/2fa/enable',
|
||||
Controller\Frontend\Profile\EnableTwoFactorAction::class
|
||||
)
|
||||
->setName('profile:2fa:enable');
|
||||
|
||||
$group->map(['GET', 'POST'], '/profile/2fa/enable',
|
||||
Controller\Frontend\Profile\EnableTwoFactorAction::class)
|
||||
->setName('profile:2fa:enable');
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/profile/2fa/disable',
|
||||
Controller\Frontend\Profile\DisableTwoFactorAction::class
|
||||
)
|
||||
->setName('profile:2fa:disable');
|
||||
|
||||
$group->map(['GET', 'POST'], '/profile/2fa/disable',
|
||||
Controller\Frontend\Profile\DisableTwoFactorAction::class)
|
||||
->setName('profile:2fa:disable');
|
||||
$group->get('/profile/theme', Controller\Frontend\Profile\ThemeAction::class)
|
||||
->setName('profile:theme');
|
||||
|
||||
$group->get('/profile/theme', Controller\Frontend\Profile\ThemeAction::class)
|
||||
->setName('profile:theme');
|
||||
$group->get('/api_keys', Controller\Frontend\ApiKeysController::class . ':indexAction')
|
||||
->setName('api_keys:index');
|
||||
|
||||
$group->get('/api_keys', Controller\Frontend\ApiKeysController::class . ':indexAction')
|
||||
->setName('api_keys:index');
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/api_keys/edit/{id}',
|
||||
Controller\Frontend\ApiKeysController::class . ':editAction'
|
||||
)
|
||||
->setName('api_keys:edit');
|
||||
|
||||
$group->map(['GET', 'POST'], '/api_keys/edit/{id}',
|
||||
Controller\Frontend\ApiKeysController::class . ':editAction')
|
||||
->setName('api_keys:edit');
|
||||
$group->map(['GET', 'POST'], '/api_keys/add', Controller\Frontend\ApiKeysController::class . ':editAction')
|
||||
->setName('api_keys:add');
|
||||
|
||||
$group->map(['GET', 'POST'], '/api_keys/add', Controller\Frontend\ApiKeysController::class . ':editAction')
|
||||
->setName('api_keys:add');
|
||||
|
||||
$group->get('/api_keys/delete/{id}/{csrf}', Controller\Frontend\ApiKeysController::class . ':deleteAction')
|
||||
->setName('api_keys:delete');
|
||||
|
||||
})->add(Middleware\EnableView::class)
|
||||
$group->get('/api_keys/delete/{id}/{csrf}', Controller\Frontend\ApiKeysController::class . ':deleteAction')
|
||||
->setName('api_keys:delete');
|
||||
}
|
||||
)->add(Middleware\EnableView::class)
|
||||
->add(Middleware\RequireLogin::class);
|
||||
|
||||
$app->map(['GET', 'POST'], '/login', Controller\Frontend\Account\LoginAction::class)
|
||||
|
@ -62,23 +71,23 @@ return function (App $app) {
|
|||
->setName('account:login:2fa')
|
||||
->add(Middleware\EnableView::class);
|
||||
|
||||
$app->group('/setup', function (RouteCollectorProxy $group) {
|
||||
$app->group(
|
||||
'/setup',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->map(['GET', 'POST'], '', Controller\Frontend\SetupController::class . ':indexAction')
|
||||
->setName('setup:index');
|
||||
|
||||
$group->map(['GET', 'POST'], '', Controller\Frontend\SetupController::class . ':indexAction')
|
||||
->setName('setup:index');
|
||||
$group->map(['GET', 'POST'], '/complete', Controller\Frontend\SetupController::class . ':completeAction')
|
||||
->setName('setup:complete');
|
||||
|
||||
$group->map(['GET', 'POST'], '/complete', Controller\Frontend\SetupController::class . ':completeAction')
|
||||
->setName('setup:complete');
|
||||
$group->map(['GET', 'POST'], '/register', Controller\Frontend\SetupController::class . ':registerAction')
|
||||
->setName('setup:register');
|
||||
|
||||
$group->map(['GET', 'POST'], '/register', Controller\Frontend\SetupController::class . ':registerAction')
|
||||
->setName('setup:register');
|
||||
$group->map(['GET', 'POST'], '/station', Controller\Frontend\SetupController::class . ':stationAction')
|
||||
->setName('setup:station');
|
||||
|
||||
$group->map(['GET', 'POST'], '/station', Controller\Frontend\SetupController::class . ':stationAction')
|
||||
->setName('setup:station');
|
||||
|
||||
$group->map(['GET', 'POST'], '/settings', Controller\Frontend\SetupController::class . ':settingsAction')
|
||||
->setName('setup:settings');
|
||||
|
||||
})->add(Middleware\EnableView::class);
|
||||
|
||||
};
|
||||
$group->map(['GET', 'POST'], '/settings', Controller\Frontend\SetupController::class . ':settingsAction')
|
||||
->setName('setup:settings');
|
||||
}
|
||||
)->add(Middleware\EnableView::class);
|
||||
};
|
||||
|
|
|
@ -6,25 +6,25 @@ use Slim\App;
|
|||
use Slim\Routing\RouteCollectorProxy;
|
||||
|
||||
return function (App $app) {
|
||||
$app->group(
|
||||
'/public/{station_id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('[/{embed:embed}]', Controller\Frontend\PublicPages\PlayerAction::class)
|
||||
->setName('public:index');
|
||||
|
||||
$app->group('/public/{station_id}', function (RouteCollectorProxy $group) {
|
||||
$group->get('/embed-requests', Controller\Frontend\PublicPages\RequestsAction::class)
|
||||
->setName('public:embedrequests');
|
||||
|
||||
$group->get('[/{embed:embed}]', Controller\Frontend\PublicPages\PlayerAction::class)
|
||||
->setName('public:index');
|
||||
$group->get('/playlist[.{format}]', Controller\Frontend\PublicPages\PlaylistAction::class)
|
||||
->setName('public:playlist');
|
||||
|
||||
$group->get('/embed-requests', Controller\Frontend\PublicPages\RequestsAction::class)
|
||||
->setName('public:embedrequests');
|
||||
$group->get('/dj', Controller\Frontend\PublicPages\WebDjAction::class)
|
||||
->setName('public:dj');
|
||||
|
||||
$group->get('/playlist[.{format}]', Controller\Frontend\PublicPages\PlaylistAction::class)
|
||||
->setName('public:playlist');
|
||||
|
||||
$group->get('/dj', Controller\Frontend\PublicPages\WebDjAction::class)
|
||||
->setName('public:dj');
|
||||
|
||||
$group->get('/ondemand[/{embed:embed}]', Controller\Frontend\PublicPages\OnDemandAction::class)
|
||||
->setName('public:ondemand');
|
||||
|
||||
})
|
||||
$group->get('/ondemand[/{embed:embed}]', Controller\Frontend\PublicPages\OnDemandAction::class)
|
||||
->setName('public:ondemand');
|
||||
}
|
||||
)
|
||||
->add(Middleware\GetStation::class)
|
||||
->add(Middleware\EnableView::class);
|
||||
};
|
||||
|
|
|
@ -9,179 +9,224 @@ use Slim\App;
|
|||
use Slim\Routing\RouteCollectorProxy;
|
||||
|
||||
return function (App $app) {
|
||||
$app->group(
|
||||
'/station/{station_id}',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'',
|
||||
function (ServerRequest $request, Response $response) {
|
||||
return $response->withRedirect(
|
||||
(string)$request->getRouter()->fromHere('stations:profile:index')
|
||||
);
|
||||
}
|
||||
)->setName('stations:index:index');
|
||||
|
||||
$app->group('/station/{station_id}', function (RouteCollectorProxy $group) {
|
||||
$group->group(
|
||||
'/automation',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->map(['GET', 'POST'], '', Controller\Stations\AutomationController::class . ':indexAction')
|
||||
->setName('stations:automation:index');
|
||||
|
||||
$group->get('', function (ServerRequest $request, Response $response) {
|
||||
return $response->withRedirect((string)$request->getRouter()->fromHere('stations:profile:index'));
|
||||
})->setName('stations:index:index');
|
||||
$group->get('/run', Controller\Stations\AutomationController::class . ':runAction')
|
||||
->setName('stations:automation:run');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::STATION_AUTOMATION, true));
|
||||
|
||||
$group->group('/automation', function (RouteCollectorProxy $group) {
|
||||
$group->get('/files', Controller\Stations\FilesController::class)
|
||||
->setName('stations:files:index')
|
||||
->add(new Middleware\Permissions(Acl::STATION_MEDIA, true));
|
||||
|
||||
$group->map(['GET', 'POST'], '', Controller\Stations\AutomationController::class . ':indexAction')
|
||||
->setName('stations:automation:index');
|
||||
$group->map(['GET', 'POST'], '/ls_config', Controller\Stations\EditLiquidsoapConfigController::class)
|
||||
->setName('stations:util:ls_config')
|
||||
->add(new Middleware\Permissions(Acl::STATION_BROADCASTING, true));
|
||||
|
||||
$group->get('/run', Controller\Stations\AutomationController::class . ':runAction')
|
||||
->setName('stations:automation:run');
|
||||
$group->group(
|
||||
'/logs',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Stations\LogsController::class)
|
||||
->setName('stations:logs:index');
|
||||
|
||||
})->add(new Middleware\Permissions(Acl::STATION_AUTOMATION, true));
|
||||
$group->get('/view/{log}', Controller\Stations\LogsController::class . ':viewAction')
|
||||
->setName('stations:logs:view');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::STATION_LOGS, true));
|
||||
|
||||
$group->get('/files', Controller\Stations\FilesController::class)
|
||||
->setName('stations:files:index')
|
||||
->add(new Middleware\Permissions(Acl::STATION_MEDIA, true));
|
||||
$group->get('/playlists', Controller\Stations\PlaylistsController::class)
|
||||
->setName('stations:playlists:index')
|
||||
->add(new Middleware\Permissions(Acl::STATION_MEDIA, true));
|
||||
|
||||
$group->map(['GET', 'POST'], '/ls_config', Controller\Stations\EditLiquidsoapConfigController::class)
|
||||
->setName('stations:util:ls_config')
|
||||
->add(new Middleware\Permissions(Acl::STATION_BROADCASTING, true));
|
||||
$group->group(
|
||||
'/mounts',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Stations\MountsController::class . ':indexAction')
|
||||
->setName('stations:mounts:index');
|
||||
|
||||
$group->group('/logs', function (RouteCollectorProxy $group) {
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/edit/{id}',
|
||||
Controller\Stations\MountsController::class . ':editAction'
|
||||
)
|
||||
->setName('stations:mounts:edit');
|
||||
|
||||
$group->get('', Controller\Stations\LogsController::class)
|
||||
->setName('stations:logs:index');
|
||||
$group->map(['GET', 'POST'], '/add', Controller\Stations\MountsController::class . ':editAction')
|
||||
->setName('stations:mounts:add');
|
||||
|
||||
$group->get('/view/{log}', Controller\Stations\LogsController::class . ':viewAction')
|
||||
->setName('stations:logs:view');
|
||||
$group->get('/delete/{id}/{csrf}', Controller\Stations\MountsController::class . ':deleteAction')
|
||||
->setName('stations:mounts:delete');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::STATION_MOUNTS, true));
|
||||
|
||||
})->add(new Middleware\Permissions(Acl::STATION_LOGS, true));
|
||||
$group->get('/profile', Controller\Stations\ProfileController::class)
|
||||
->setName('stations:profile:index');
|
||||
|
||||
$group->get('/playlists', Controller\Stations\PlaylistsController::class)
|
||||
->setName('stations:playlists:index')
|
||||
->add(new Middleware\Permissions(Acl::STATION_MEDIA, true));
|
||||
$group->get(
|
||||
'/profile/toggle/{feature}/{csrf}',
|
||||
Controller\Stations\ProfileController::class . ':toggleAction'
|
||||
)
|
||||
->setName('stations:profile:toggle')
|
||||
->add(new Middleware\Permissions(Acl::STATION_PROFILE, true));
|
||||
|
||||
$group->group('/mounts', function (RouteCollectorProxy $group) {
|
||||
$group->map(['GET', 'POST'], '/profile/edit', Controller\Stations\ProfileController::class . ':editAction')
|
||||
->setName('stations:profile:edit')
|
||||
->add(new Middleware\Permissions(Acl::STATION_PROFILE, true));
|
||||
|
||||
$group->get('', Controller\Stations\MountsController::class . ':indexAction')
|
||||
->setName('stations:mounts:index');
|
||||
$group->get('/queue', Controller\Stations\QueueController::class)
|
||||
->setName('stations:queue:index')
|
||||
->add(new Middleware\Permissions(Acl::STATION_BROADCASTING, true));
|
||||
|
||||
$group->map(['GET', 'POST'], '/edit/{id}', Controller\Stations\MountsController::class . ':editAction')
|
||||
->setName('stations:mounts:edit');
|
||||
$group->group(
|
||||
'/remotes',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Stations\RemotesController::class . ':indexAction')
|
||||
->setName('stations:remotes:index');
|
||||
|
||||
$group->map(['GET', 'POST'], '/add', Controller\Stations\MountsController::class . ':editAction')
|
||||
->setName('stations:mounts:add');
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/edit/{id}',
|
||||
Controller\Stations\RemotesController::class . ':editAction'
|
||||
)
|
||||
->setName('stations:remotes:edit');
|
||||
|
||||
$group->get('/delete/{id}/{csrf}', Controller\Stations\MountsController::class . ':deleteAction')
|
||||
->setName('stations:mounts:delete');
|
||||
$group->map(['GET', 'POST'], '/add', Controller\Stations\RemotesController::class . ':editAction')
|
||||
->setName('stations:remotes:add');
|
||||
|
||||
})->add(new Middleware\Permissions(Acl::STATION_MOUNTS, true));
|
||||
$group->get('/delete/{id}/{csrf}', Controller\Stations\RemotesController::class . ':deleteAction')
|
||||
->setName('stations:remotes:delete');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::STATION_REMOTES, true));
|
||||
|
||||
$group->get('/profile', Controller\Stations\ProfileController::class)
|
||||
->setName('stations:profile:index');
|
||||
$group->group(
|
||||
'/reports',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('/overview', Controller\Stations\Reports\OverviewController::class)
|
||||
->setName('stations:reports:overview');
|
||||
|
||||
$group->get('/profile/toggle/{feature}/{csrf}', Controller\Stations\ProfileController::class . ':toggleAction')
|
||||
->setName('stations:profile:toggle')
|
||||
->add(new Middleware\Permissions(Acl::STATION_PROFILE, true));
|
||||
$group->get('/timeline[/format/{format}]', Controller\Stations\Reports\TimelineController::class)
|
||||
->setName('stations:reports:timeline');
|
||||
|
||||
$group->map(['GET', 'POST'], '/profile/edit', Controller\Stations\ProfileController::class . ':editAction')
|
||||
->setName('stations:profile:edit')
|
||||
->add(new Middleware\Permissions(Acl::STATION_PROFILE, true));
|
||||
$group->get(
|
||||
'/performance[/format/{format}]',
|
||||
Controller\Stations\Reports\PerformanceController::class
|
||||
)
|
||||
->setName('stations:reports:performance');
|
||||
|
||||
$group->get('/queue', Controller\Stations\QueueController::class)
|
||||
->setName('stations:queue:index')
|
||||
->add(new Middleware\Permissions(Acl::STATION_BROADCASTING, true));
|
||||
$group->get('/duplicates', Controller\Stations\Reports\DuplicatesController::class)
|
||||
->setName('stations:reports:duplicates');
|
||||
|
||||
$group->group('/remotes', function (RouteCollectorProxy $group) {
|
||||
$group->get(
|
||||
'/duplicates/delete/{media_id}',
|
||||
Controller\Stations\Reports\DuplicatesController::class . ':deleteAction'
|
||||
)
|
||||
->setName('stations:reports:duplicates:delete');
|
||||
|
||||
$group->get('', Controller\Stations\RemotesController::class . ':indexAction')
|
||||
->setName('stations:remotes:index');
|
||||
$group->map(['GET', 'POST'], '/listeners', Controller\Stations\Reports\ListenersController::class)
|
||||
->setName('stations:reports:listeners');
|
||||
|
||||
$group->map(['GET', 'POST'], '/edit/{id}', Controller\Stations\RemotesController::class . ':editAction')
|
||||
->setName('stations:remotes:edit');
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/soundexchange',
|
||||
Controller\Stations\Reports\SoundExchangeController::class
|
||||
)
|
||||
->setName('stations:reports:soundexchange');
|
||||
|
||||
$group->map(['GET', 'POST'], '/add', Controller\Stations\RemotesController::class . ':editAction')
|
||||
->setName('stations:remotes:add');
|
||||
$group->get('/requests', Controller\Stations\Reports\RequestsController::class)
|
||||
->setName('stations:reports:requests');
|
||||
|
||||
$group->get('/delete/{id}/{csrf}', Controller\Stations\RemotesController::class . ':deleteAction')
|
||||
->setName('stations:remotes:delete');
|
||||
$group->get(
|
||||
'/requests/delete/{request_id}/{csrf}',
|
||||
Controller\Stations\Reports\RequestsController::class . ':deleteAction'
|
||||
)
|
||||
->setName('stations:reports:requests:delete');
|
||||
|
||||
})->add(new Middleware\Permissions(Acl::STATION_REMOTES, true));
|
||||
$group->get(
|
||||
'/requests/clear/{csrf}',
|
||||
Controller\Stations\Reports\RequestsController::class . ':clearAction'
|
||||
)
|
||||
->setName('stations:reports:requests:clear');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::STATION_REPORTS, true));
|
||||
|
||||
$group->group('/reports', function (RouteCollectorProxy $group) {
|
||||
$group->group(
|
||||
'/sftp_users',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Stations\SftpUsersController::class . ':indexAction')
|
||||
->setName('stations:sftp_users:index');
|
||||
|
||||
$group->get('/overview', Controller\Stations\Reports\OverviewController::class)
|
||||
->setName('stations:reports:overview');
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/edit/{id}',
|
||||
Controller\Stations\SftpUsersController::class . ':editAction'
|
||||
)
|
||||
->setName('stations:sftp_users:edit');
|
||||
|
||||
$group->get('/timeline[/format/{format}]', Controller\Stations\Reports\TimelineController::class)
|
||||
->setName('stations:reports:timeline');
|
||||
$group->map(['GET', 'POST'], '/add', Controller\Stations\SftpUsersController::class . ':editAction')
|
||||
->setName('stations:sftp_users:add');
|
||||
|
||||
$group->get('/performance[/format/{format}]', Controller\Stations\Reports\PerformanceController::class)
|
||||
->setName('stations:reports:performance');
|
||||
$group->get('/delete/{id}/{csrf}', Controller\Stations\SftpUsersController::class . ':deleteAction')
|
||||
->setName('stations:sftp_users:delete');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::STATION_MEDIA, true));
|
||||
|
||||
$group->get('/duplicates', Controller\Stations\Reports\DuplicatesController::class)
|
||||
->setName('stations:reports:duplicates');
|
||||
$group->get('/streamers', Controller\Stations\StreamersController::class)
|
||||
->setName('stations:streamers:index')
|
||||
->add(new Middleware\Permissions(Acl::STATION_STREAMERS, true));
|
||||
|
||||
$group->get('/duplicates/delete/{media_id}',
|
||||
Controller\Stations\Reports\DuplicatesController::class . ':deleteAction')
|
||||
->setName('stations:reports:duplicates:delete');
|
||||
$group->group(
|
||||
'/webhooks',
|
||||
function (RouteCollectorProxy $group) {
|
||||
$group->get('', Controller\Stations\WebhooksController::class . ':indexAction')
|
||||
->setName('stations:webhooks:index');
|
||||
|
||||
$group->map(['GET', 'POST'], '/listeners', Controller\Stations\Reports\ListenersController::class)
|
||||
->setName('stations:reports:listeners');
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/edit/{id}',
|
||||
Controller\Stations\WebhooksController::class . ':editAction'
|
||||
)
|
||||
->setName('stations:webhooks:edit');
|
||||
|
||||
$group->map(['GET', 'POST'], '/soundexchange', Controller\Stations\Reports\SoundExchangeController::class)
|
||||
->setName('stations:reports:soundexchange');
|
||||
$group->map(
|
||||
['GET', 'POST'],
|
||||
'/add[/{type}]',
|
||||
Controller\Stations\WebhooksController::class . ':addAction'
|
||||
)
|
||||
->setName('stations:webhooks:add');
|
||||
|
||||
$group->get('/requests', Controller\Stations\Reports\RequestsController::class)
|
||||
->setName('stations:reports:requests');
|
||||
$group->get('/toggle/{id}/{csrf}', Controller\Stations\WebhooksController::class . ':toggleAction')
|
||||
->setName('stations:webhooks:toggle');
|
||||
|
||||
$group->get('/requests/delete/{request_id}/{csrf}',
|
||||
Controller\Stations\Reports\RequestsController::class . ':deleteAction')
|
||||
->setName('stations:reports:requests:delete');
|
||||
$group->get('/test/{id}/{csrf}', Controller\Stations\WebhooksController::class . ':testAction')
|
||||
->setName('stations:webhooks:test');
|
||||
|
||||
$group->get('/requests/clear/{csrf}',
|
||||
Controller\Stations\Reports\RequestsController::class . ':clearAction')
|
||||
->setName('stations:reports:requests:clear');
|
||||
|
||||
})->add(new Middleware\Permissions(Acl::STATION_REPORTS, true));
|
||||
|
||||
$group->group('/sftp_users', function (RouteCollectorProxy $group) {
|
||||
|
||||
$group->get('', Controller\Stations\SftpUsersController::class . ':indexAction')
|
||||
->setName('stations:sftp_users:index');
|
||||
|
||||
$group->map(['GET', 'POST'], '/edit/{id}', Controller\Stations\SftpUsersController::class . ':editAction')
|
||||
->setName('stations:sftp_users:edit');
|
||||
|
||||
$group->map(['GET', 'POST'], '/add', Controller\Stations\SftpUsersController::class . ':editAction')
|
||||
->setName('stations:sftp_users:add');
|
||||
|
||||
$group->get('/delete/{id}/{csrf}', Controller\Stations\SftpUsersController::class . ':deleteAction')
|
||||
->setName('stations:sftp_users:delete');
|
||||
|
||||
})->add(new Middleware\Permissions(Acl::STATION_MEDIA, true));
|
||||
|
||||
$group->get('/streamers', Controller\Stations\StreamersController::class)
|
||||
->setName('stations:streamers:index')
|
||||
->add(new Middleware\Permissions(Acl::STATION_STREAMERS, true));
|
||||
|
||||
$group->group('/webhooks', function (RouteCollectorProxy $group) {
|
||||
|
||||
$group->get('', Controller\Stations\WebhooksController::class . ':indexAction')
|
||||
->setName('stations:webhooks:index');
|
||||
|
||||
$group->map(['GET', 'POST'], '/edit/{id}', Controller\Stations\WebhooksController::class . ':editAction')
|
||||
->setName('stations:webhooks:edit');
|
||||
|
||||
$group->map(['GET', 'POST'], '/add[/{type}]', Controller\Stations\WebhooksController::class . ':addAction')
|
||||
->setName('stations:webhooks:add');
|
||||
|
||||
$group->get('/toggle/{id}/{csrf}', Controller\Stations\WebhooksController::class . ':toggleAction')
|
||||
->setName('stations:webhooks:toggle');
|
||||
|
||||
$group->get('/test/{id}/{csrf}', Controller\Stations\WebhooksController::class . ':testAction')
|
||||
->setName('stations:webhooks:test');
|
||||
|
||||
$group->get('/delete/{id}/{csrf}', Controller\Stations\WebhooksController::class . ':deleteAction')
|
||||
->setName('stations:webhooks:delete');
|
||||
|
||||
})->add(new Middleware\Permissions(Acl::STATION_WEB_HOOKS, true));
|
||||
|
||||
// END /stations GROUP
|
||||
|
||||
})
|
||||
$group->get('/delete/{id}/{csrf}', Controller\Stations\WebhooksController::class . ':deleteAction')
|
||||
->setName('stations:webhooks:delete');
|
||||
}
|
||||
)->add(new Middleware\Permissions(Acl::STATION_WEB_HOOKS, true));
|
||||
}
|
||||
)
|
||||
->add(Middleware\Module\Stations::class)
|
||||
->add(new Middleware\Permissions(Acl::STATION_VIEW, true))
|
||||
->add(Middleware\RequireStation::class)
|
||||
->add(Middleware\GetStation::class)
|
||||
->add(Middleware\EnableView::class)
|
||||
->add(Middleware\RequireLogin::class);
|
||||
|
||||
};
|
||||
};
|
||||
|
|
|
@ -38,14 +38,19 @@
|
|||
{{ row.item.text }}
|
||||
</a>
|
||||
</template>
|
||||
<template v-else>
|
||||
<template v-else-if="row.item.media_play_url">
|
||||
<a class="name" :href="row.item.media_play_url" target="_blank" :title="row.item.name">
|
||||
{{ row.item.media_name }}
|
||||
</a>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a class="name" :href="row.item.download_url" target="_blank" :title="row.item.text">
|
||||
{{ row.item.text }}
|
||||
</a>
|
||||
</template>
|
||||
<br>
|
||||
<small v-if="row.item.is_dir" key="lang_dir" v-translate>Directory</small>
|
||||
<small v-else>{{ row.item.text }}</small>
|
||||
<small v-if="row.item.media_play_url">{{ row.item.text }}</small>
|
||||
<small v-else>{{ row.item.media_name }}</small>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:cell(media_genre)="row">
|
||||
|
@ -68,18 +73,17 @@
|
|||
</template>
|
||||
</template>
|
||||
<template v-slot:cell(commands)="row">
|
||||
<template v-if="row.item.media_can_edit">
|
||||
<template v-if="row.item.media_edit_url">
|
||||
<b-button size="sm" variant="primary"
|
||||
@click.prevent="edit(row.item.media_edit_url, row.item.media_art_url, row.item.media_play_url, row.item.media_waveform_url)">
|
||||
{{ langEditButton }}
|
||||
</b-button>
|
||||
</template>
|
||||
<template v-else-if="row.item.can_rename">
|
||||
<template v-else>
|
||||
<b-button size="sm" variant="primary" @click.prevent="rename(row.item.path)">
|
||||
{{ langRenameButton }}
|
||||
</b-button>
|
||||
</template>
|
||||
<template v-else> </template>
|
||||
</template>
|
||||
</data-table>
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace App\Controller\Api\Stations\Files;
|
||||
|
||||
use App\Entity;
|
||||
use App\Entity\Api\Error;
|
||||
use App\Flysystem\FilesystemManager;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
|
@ -13,23 +13,21 @@ class DownloadAction
|
|||
public function __invoke(
|
||||
ServerRequest $request,
|
||||
Response $response,
|
||||
int $id,
|
||||
FilesystemManager $filesystem,
|
||||
Entity\Repository\StationMediaRepository $mediaRepo
|
||||
FilesystemManager $filesystem
|
||||
): ResponseInterface {
|
||||
set_time_limit(600);
|
||||
|
||||
$station = $request->getStation();
|
||||
$storageLocation = $station->getMediaStorageLocation();
|
||||
$fs = $storageLocation->getFilesystem();
|
||||
|
||||
$media = $mediaRepo->find($id, $station);
|
||||
$path = $request->getParam('file');
|
||||
|
||||
if (!$media instanceof Entity\StationMedia) {
|
||||
if (!$fs->has($path)) {
|
||||
return $response->withStatus(404)
|
||||
->withJson(new Entity\Api\Error(404, 'Not Found'));
|
||||
->withJson(new Error(404, 'File not found.'));
|
||||
}
|
||||
|
||||
$fs = $filesystem->getForStation($station, false);
|
||||
|
||||
return $fs->streamToResponse($response, $media->getPathUri());
|
||||
return $fs->streamToResponse($response, $path);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,9 +47,12 @@ class FlowUploadAction
|
|||
try {
|
||||
$stationMedia = $mediaRepo->getOrCreate($station, $destPath, $flowResponse['path']);
|
||||
} catch (CannotProcessMediaException $e) {
|
||||
$logger->error($e->getMessage(), [
|
||||
'exception' => $e,
|
||||
]);
|
||||
$logger->error(
|
||||
$e->getMessageWithPath(),
|
||||
[
|
||||
'exception' => $e,
|
||||
]
|
||||
);
|
||||
|
||||
return $response->withJson(Entity\Api\Error::fromException($e));
|
||||
}
|
||||
|
@ -61,10 +64,12 @@ class FlowUploadAction
|
|||
if (0 === strpos($search_phrase, 'playlist:')) {
|
||||
$playlist_name = substr($search_phrase, 9);
|
||||
|
||||
$playlist = $em->getRepository(Entity\StationPlaylist::class)->findOneBy([
|
||||
'station_id' => $station->getId(),
|
||||
'name' => $playlist_name,
|
||||
]);
|
||||
$playlist = $em->getRepository(Entity\StationPlaylist::class)->findOneBy(
|
||||
[
|
||||
'station_id' => $station->getId(),
|
||||
'name' => $playlist_name,
|
||||
]
|
||||
);
|
||||
|
||||
if ($playlist instanceof Entity\StationPlaylist) {
|
||||
$spmRepo->addMediaToPlaylist($stationMedia, $playlist);
|
||||
|
|
|
@ -83,6 +83,8 @@ class ListAction
|
|||
}
|
||||
|
||||
$folders_in_dir_raw = [];
|
||||
|
||||
$unprocessableMediaRaw = [];
|
||||
} else {
|
||||
// Avoid loading subfolder media.
|
||||
$media_query->andWhere('sm.path NOT LIKE :pathWithSubfolders')
|
||||
|
@ -99,6 +101,17 @@ class ListAction
|
|||
)->setParameter('station', $station)
|
||||
->setParameter('path', $currentDir . '%')
|
||||
->getArrayResult();
|
||||
|
||||
$unprocessableMediaRaw = $em->createQuery(
|
||||
<<<'DQL'
|
||||
SELECT upm
|
||||
FROM App\Entity\UnprocessableMedia upm
|
||||
WHERE upm.storage_location = :storageLocation
|
||||
AND upm.path LIKE :path
|
||||
DQL
|
||||
)->setParameter('storageLocation', $storageLocation)
|
||||
->setParameter('path', $currentDir . '%')
|
||||
->getArrayResult();
|
||||
}
|
||||
|
||||
$media_in_dir_raw = $media_query->getQuery()
|
||||
|
@ -152,13 +165,12 @@ class ListAction
|
|||
'media_id' => $media_row['unique_id'] . '-' . $media_row['art_updated_at'],
|
||||
]
|
||||
),
|
||||
'can_edit' => true,
|
||||
'edit_url' => (string)$router->named(
|
||||
'api:stations:file',
|
||||
['station_id' => $station->getId(), 'id' => $media_row['id']]
|
||||
),
|
||||
'play_url' => (string)$router->named(
|
||||
'api:stations:file:download',
|
||||
'api:stations:files:play',
|
||||
['station_id' => $station->getId(), 'id' => $media_row['id']],
|
||||
[],
|
||||
true
|
||||
|
@ -181,6 +193,11 @@ class ListAction
|
|||
];
|
||||
}
|
||||
|
||||
$unprocessableMedia = [];
|
||||
foreach ($unprocessableMediaRaw as $unprocessableRow) {
|
||||
$unprocessableMedia[$unprocessableRow['path']] = $unprocessableRow['error'];
|
||||
}
|
||||
|
||||
$files = [];
|
||||
if (!empty($searchPhrase)) {
|
||||
foreach ($media_in_dir as $short_path => $media_row) {
|
||||
|
@ -216,10 +233,22 @@ class ListAction
|
|||
}
|
||||
} elseif (isset($media_in_dir[$short])) {
|
||||
$media = $media_in_dir[$short];
|
||||
} elseif (isset($unprocessableMedia[$short])) {
|
||||
$media = [
|
||||
'name' => __(
|
||||
'File Not Processed: %s',
|
||||
Utilities\Strings::truncateText($unprocessableMedia[$short])
|
||||
),
|
||||
];
|
||||
} else {
|
||||
$media = ['name' => __('File Not Processed'), 'playlists' => [], 'is_playable' => false];
|
||||
$media = [
|
||||
'name' => __('File Processing'),
|
||||
];
|
||||
}
|
||||
|
||||
$media['playlists'] ??= [];
|
||||
$media['is_playable'] ??= false;
|
||||
|
||||
$max_length = 60;
|
||||
$shortname = $meta['basename'];
|
||||
if (mb_strlen($shortname) > $max_length) {
|
||||
|
@ -233,7 +262,11 @@ class ListAction
|
|||
'path' => $short,
|
||||
'text' => $shortname,
|
||||
'is_dir' => ('dir' === $meta['type']),
|
||||
'can_rename' => true,
|
||||
'download_url' => (string)$router->named(
|
||||
'api:stations:files:download',
|
||||
['station_id' => $station->getId()],
|
||||
['file' => $short]
|
||||
),
|
||||
'rename_url' => (string)$router->named(
|
||||
'api:stations:files:rename',
|
||||
['station_id' => $station->getId()],
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace App\Controller\Api\Stations\Files;
|
||||
|
||||
use App\Entity;
|
||||
use App\Flysystem\FilesystemManager;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class PlayAction
|
||||
{
|
||||
public function __invoke(
|
||||
ServerRequest $request,
|
||||
Response $response,
|
||||
int $id,
|
||||
FilesystemManager $filesystem,
|
||||
Entity\Repository\StationMediaRepository $mediaRepo
|
||||
): ResponseInterface {
|
||||
set_time_limit(600);
|
||||
|
||||
$station = $request->getStation();
|
||||
|
||||
$media = $mediaRepo->find($id, $station);
|
||||
|
||||
if (!$media instanceof Entity\StationMedia) {
|
||||
return $response->withStatus(404)
|
||||
->withJson(new Entity\Api\Error(404, 'Not Found'));
|
||||
}
|
||||
|
||||
$fs = $filesystem->getForStation($station, false);
|
||||
|
||||
return $fs->streamToResponse($response, $media->getPathUri());
|
||||
}
|
||||
}
|
|
@ -8,6 +8,8 @@ use Throwable;
|
|||
|
||||
class CannotProcessMediaException extends Exception
|
||||
{
|
||||
protected ?string $path = null;
|
||||
|
||||
public function __construct(
|
||||
string $message = 'Cannot process media file.',
|
||||
int $code = 0,
|
||||
|
@ -17,12 +19,29 @@ class CannotProcessMediaException extends Exception
|
|||
parent::__construct($message, $code, $previous, $loggerLevel);
|
||||
}
|
||||
|
||||
public function setPath(?string $path): void
|
||||
{
|
||||
$this->path = $path;
|
||||
}
|
||||
|
||||
public function getPath(): ?string
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
public function getMessageWithPath(): string
|
||||
{
|
||||
return sprintf(
|
||||
'Cannot process media file at path "%s": %s',
|
||||
$this->path,
|
||||
$this->message
|
||||
);
|
||||
}
|
||||
|
||||
public static function forPath(string $path, string $error = 'General Error'): self
|
||||
{
|
||||
return new self(sprintf(
|
||||
'Cannot process media file at path "%s": %s',
|
||||
basename($path),
|
||||
$error
|
||||
));
|
||||
$exception = new self($error);
|
||||
$exception->setPath(basename($path));
|
||||
return $exception;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue