2019-07-10 17:45:54 +00:00
|
|
|
<?php
|
2020-10-14 22:19:31 +00:00
|
|
|
|
2021-07-19 05:53:45 +00:00
|
|
|
declare(strict_types=1);
|
|
|
|
|
2019-07-10 17:45:54 +00:00
|
|
|
namespace App\Controller\Api\Admin;
|
|
|
|
|
|
|
|
use App\Acl;
|
|
|
|
use App\Entity;
|
2019-08-09 15:00:21 +00:00
|
|
|
use App\Http\Response;
|
|
|
|
use App\Http\ServerRequest;
|
2019-07-10 17:45:54 +00:00
|
|
|
use App\Radio\Adapters;
|
2020-06-26 20:22:53 +00:00
|
|
|
use Doctrine\ORM\EntityManagerInterface;
|
2019-07-10 17:45:54 +00:00
|
|
|
use OpenApi\Annotations as OA;
|
|
|
|
use Psr\Http\Message\ResponseInterface;
|
|
|
|
|
|
|
|
class RelaysController
|
|
|
|
{
|
2019-07-15 04:47:39 +00:00
|
|
|
public function __construct(
|
2021-04-23 05:24:12 +00:00
|
|
|
protected EntityManagerInterface $em,
|
|
|
|
protected Adapters $adapters
|
2019-07-15 04:47:39 +00:00
|
|
|
) {
|
2019-07-10 17:45:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-08-07 04:33:55 +00:00
|
|
|
* @OA\Get(path="/internal/relays",
|
2019-07-10 17:45:54 +00:00
|
|
|
* tags={"Administration: Relays"},
|
|
|
|
* description="Returns all necessary information to relay all 'relayable' stations.",
|
|
|
|
* parameters={},
|
|
|
|
* @OA\Response(
|
|
|
|
* response=200,
|
|
|
|
* description="Success",
|
|
|
|
* @OA\JsonContent(type="array", @OA\Items(ref="#/components/schemas/Api_Admin_Relay"))
|
|
|
|
* )
|
|
|
|
* )
|
|
|
|
*
|
2019-08-09 15:00:21 +00:00
|
|
|
* @param ServerRequest $request
|
|
|
|
* @param Response $response
|
2019-07-10 17:45:54 +00:00
|
|
|
*/
|
2019-08-09 15:00:21 +00:00
|
|
|
public function __invoke(ServerRequest $request, Response $response): ResponseInterface
|
2019-07-10 17:45:54 +00:00
|
|
|
{
|
2019-07-15 23:47:05 +00:00
|
|
|
$stations = $this->getManageableStations($request);
|
2019-07-10 17:45:54 +00:00
|
|
|
|
2019-08-09 15:00:21 +00:00
|
|
|
$router = $request->getRouter();
|
2019-07-10 17:45:54 +00:00
|
|
|
|
|
|
|
$return = [];
|
2019-09-04 18:00:51 +00:00
|
|
|
foreach ($stations as $station) {
|
2019-07-10 17:45:54 +00:00
|
|
|
$fa = $this->adapters->getFrontendAdapter($station);
|
|
|
|
|
2020-10-14 22:19:31 +00:00
|
|
|
$row = new Entity\Api\Admin\Relay();
|
2021-07-19 05:53:45 +00:00
|
|
|
$row->id = $station->getIdRequired();
|
2019-07-10 17:45:54 +00:00
|
|
|
$row->name = $station->getName();
|
|
|
|
$row->shortcode = $station->getShortName();
|
|
|
|
$row->description = $station->getDescription();
|
|
|
|
$row->url = $station->getUrl();
|
|
|
|
$row->genre = $station->getGenre();
|
|
|
|
|
|
|
|
$row->type = $station->getFrontendType();
|
|
|
|
|
2020-05-02 07:58:59 +00:00
|
|
|
$frontend_config = $station->getFrontendConfig();
|
|
|
|
$row->port = $frontend_config->getPort();
|
|
|
|
$row->relay_pw = $frontend_config->getRelayPassword();
|
|
|
|
$row->admin_pw = $frontend_config->getAdminPassword();
|
2019-07-10 17:45:54 +00:00
|
|
|
|
|
|
|
$mounts = [];
|
|
|
|
if ($station->getMounts()->count() > 0) {
|
|
|
|
foreach ($station->getMounts() as $mount) {
|
|
|
|
/** @var Entity\StationMount $mount */
|
|
|
|
$mounts[] = $mount->api($fa);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$row->mounts = $mounts;
|
2019-07-25 17:58:50 +00:00
|
|
|
$row->resolveUrls($router->getBaseUrl());
|
2019-07-10 17:45:54 +00:00
|
|
|
|
|
|
|
$return[] = $row;
|
|
|
|
}
|
|
|
|
|
2019-08-09 15:00:21 +00:00
|
|
|
return $response->withJson($return);
|
2019-07-10 17:45:54 +00:00
|
|
|
}
|
2019-07-15 04:47:39 +00:00
|
|
|
|
2019-09-04 18:00:51 +00:00
|
|
|
/**
|
|
|
|
* @param ServerRequest $request
|
2019-09-20 16:44:38 +00:00
|
|
|
*
|
2019-09-04 18:00:51 +00:00
|
|
|
* @return Entity\Station[]
|
|
|
|
*/
|
|
|
|
protected function getManageableStations(ServerRequest $request): array
|
|
|
|
{
|
2020-12-02 00:36:09 +00:00
|
|
|
$all_stations = $this->em->createQuery(
|
|
|
|
<<<'DQL'
|
|
|
|
SELECT s, sm
|
|
|
|
FROM App\Entity\Station s
|
|
|
|
JOIN s.mounts sm
|
|
|
|
WHERE s.is_enabled = 1
|
|
|
|
AND s.frontend_type != :remote_frontend
|
|
|
|
DQL
|
|
|
|
)->setParameter('remote_frontend', Adapters::FRONTEND_REMOTE)
|
2019-09-04 18:00:51 +00:00
|
|
|
->execute();
|
|
|
|
|
|
|
|
$acl = $request->getAcl();
|
|
|
|
|
2021-01-11 11:08:06 +00:00
|
|
|
return array_filter(
|
|
|
|
$all_stations,
|
2021-04-23 22:12:47 +00:00
|
|
|
static function (Entity\Station $station) use ($acl) {
|
2021-01-11 11:08:06 +00:00
|
|
|
return $acl->isAllowed(Acl::STATION_BROADCASTING, $station->getId());
|
|
|
|
}
|
|
|
|
);
|
2019-09-04 18:00:51 +00:00
|
|
|
}
|
|
|
|
|
2019-08-09 15:00:21 +00:00
|
|
|
public function updateAction(ServerRequest $request, Response $response): ResponseInterface
|
2019-07-15 04:47:39 +00:00
|
|
|
{
|
2019-07-15 23:47:05 +00:00
|
|
|
$relay_repo = $this->em->getRepository(Entity\Relay::class);
|
|
|
|
|
2021-07-19 05:53:45 +00:00
|
|
|
$body = (array)$request->getParsedBody();
|
2019-07-15 23:47:05 +00:00
|
|
|
|
|
|
|
if (!empty($body['base_url'])) {
|
|
|
|
$base_url = $body['base_url'];
|
|
|
|
} else {
|
2021-06-10 03:22:13 +00:00
|
|
|
/** @noinspection HttpUrlsUsage */
|
2021-07-19 05:53:45 +00:00
|
|
|
$base_url = 'http://' . $request->getIp();
|
2019-07-15 23:47:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
$relay = $relay_repo->findOneBy(['base_url' => $base_url]);
|
|
|
|
if (!$relay instanceof Entity\Relay) {
|
|
|
|
$relay = new Entity\Relay($base_url);
|
|
|
|
}
|
|
|
|
|
|
|
|
$relay->setName($body['name'] ?? 'Relay');
|
|
|
|
$relay->setIsVisibleOnPublicPages($body['is_visible_on_public_pages'] ?? true);
|
|
|
|
$relay->setNowplaying((array)$body['nowplaying']);
|
2019-08-12 05:03:00 +00:00
|
|
|
$relay->setUpdatedAt(time());
|
2019-07-15 23:47:05 +00:00
|
|
|
|
|
|
|
$this->em->persist($relay);
|
|
|
|
|
|
|
|
// List existing remotes to avoid duplication.
|
|
|
|
$existing_remotes = [];
|
|
|
|
|
2019-09-04 18:00:51 +00:00
|
|
|
foreach ($relay->getRemotes() as $remote) {
|
2019-07-15 23:47:05 +00:00
|
|
|
/** @var Entity\StationRemote $remote */
|
|
|
|
$existing_remotes[$remote->getStation()->getId()][$remote->getMount()] = $remote;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Iterate through all remotes that *should* exist.
|
2021-06-08 06:40:49 +00:00
|
|
|
foreach ($this->getManageableStations($request) as $station) {
|
2019-07-15 23:47:05 +00:00
|
|
|
$station_id = $station->getId();
|
|
|
|
|
2019-09-04 18:00:51 +00:00
|
|
|
foreach ($station->getMounts() as $mount) {
|
2019-07-15 23:47:05 +00:00
|
|
|
/** @var Entity\StationMount $mount */
|
|
|
|
$mount_path = $mount->getName();
|
|
|
|
|
|
|
|
if (isset($existing_remotes[$station_id][$mount_path])) {
|
|
|
|
/** @var Entity\StationRemote $remote */
|
|
|
|
$remote = $existing_remotes[$station_id][$mount_path];
|
2019-07-15 04:47:39 +00:00
|
|
|
|
2019-07-15 23:47:05 +00:00
|
|
|
unset($existing_remotes[$station_id][$mount_path]);
|
|
|
|
} else {
|
|
|
|
$remote = new Entity\StationRemote($station);
|
|
|
|
}
|
|
|
|
|
2019-07-16 01:35:13 +00:00
|
|
|
$remote->setRelay($relay);
|
2019-07-15 23:47:05 +00:00
|
|
|
$remote->setType(Adapters::REMOTE_AZURARELAY);
|
2019-09-04 18:00:51 +00:00
|
|
|
$remote->setDisplayName($mount->getDisplayName() . ' (' . $relay->getName() . ')');
|
2019-07-15 23:47:05 +00:00
|
|
|
$remote->setIsVisibleOnPublicPages($relay->isIsVisibleOnPublicPages());
|
2019-08-10 17:38:08 +00:00
|
|
|
$remote->setAutodjBitrate($mount->getAutodjBitrate());
|
|
|
|
$remote->setAutodjFormat($mount->getAutodjFormat());
|
2019-07-15 23:47:05 +00:00
|
|
|
$remote->setUrl($relay->getBaseUrl());
|
|
|
|
$remote->setMount($mount->getName());
|
|
|
|
|
|
|
|
$this->em->persist($remote);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove all remotes that weren't processed earlier.
|
2019-09-04 18:00:51 +00:00
|
|
|
foreach ($existing_remotes as $existing_remote_station) {
|
|
|
|
foreach ($existing_remote_station as $existing_remote) {
|
2019-07-15 23:47:05 +00:00
|
|
|
$this->em->remove($existing_remote);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->em->flush();
|
|
|
|
|
2020-10-14 22:19:31 +00:00
|
|
|
return $response->withJson(new Entity\Api\Status());
|
2019-07-15 23:47:05 +00:00
|
|
|
}
|
2019-07-10 17:45:54 +00:00
|
|
|
}
|