mirror of
https://github.com/AzuraCast/AzuraCast.git
synced 2024-06-14 13:16:37 +00:00
176 lines
5.0 KiB
PHP
176 lines
5.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Controller\Api;
|
|
|
|
use App\Entity;
|
|
use App\Http\Response;
|
|
use App\Http\RouterInterface;
|
|
use App\Http\ServerRequest;
|
|
use App\OpenApi;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Doctrine\ORM\NoResultException;
|
|
use OpenApi\Attributes as OA;
|
|
use Psr\Http\Message\ResponseInterface;
|
|
use Psr\SimpleCache\CacheInterface;
|
|
|
|
#[
|
|
OA\Get(
|
|
path: '/nowplaying',
|
|
description: "Returns a full summary of all stations' current state.",
|
|
tags: ['Now Playing'],
|
|
parameters: [],
|
|
responses: [
|
|
new OA\Response(
|
|
response: 200,
|
|
description: 'Success',
|
|
content: new OA\JsonContent(
|
|
type: 'array',
|
|
items: new OA\Items(ref: '#/components/schemas/Api_NowPlaying')
|
|
)
|
|
),
|
|
]
|
|
),
|
|
OA\Get(
|
|
path: '/nowplaying/{station_id}',
|
|
description: "Returns a full summary of the specified station's current state.",
|
|
tags: ['Now Playing'],
|
|
parameters: [
|
|
new OA\Parameter(ref: OpenApi::REF_STATION_ID_REQUIRED),
|
|
],
|
|
responses: [
|
|
new OA\Response(
|
|
response: 200,
|
|
description: 'Success',
|
|
content: new OA\JsonContent(ref: '#/components/schemas/Api_NowPlaying')
|
|
),
|
|
new OA\Response(ref: OpenApi::REF_RESPONSE_NOT_FOUND, response: 404),
|
|
]
|
|
)
|
|
]
|
|
final class NowPlayingController
|
|
{
|
|
public function __construct(
|
|
private readonly EntityManagerInterface $em,
|
|
private readonly CacheInterface $cache
|
|
) {
|
|
}
|
|
|
|
public function getAction(
|
|
ServerRequest $request,
|
|
Response $response,
|
|
?string $station_id = null
|
|
): ResponseInterface {
|
|
$router = $request->getRouter();
|
|
|
|
if (!empty($station_id)) {
|
|
$np = $this->getForStation($station_id, $router);
|
|
|
|
if (null !== $np) {
|
|
return $response->withJson($np);
|
|
}
|
|
|
|
return $response->withStatus(404)
|
|
->withJson(Entity\Api\Error::notFound());
|
|
}
|
|
|
|
return $response->withJson(
|
|
$this->getForAllStations(
|
|
$router,
|
|
$request->getAttribute('user') === null // If unauthenticated, hide non-public stations from full view.
|
|
)
|
|
);
|
|
}
|
|
|
|
public function getArtAction(
|
|
ServerRequest $request,
|
|
Response $response,
|
|
string $station_id,
|
|
?string $timestamp = null
|
|
): ResponseInterface {
|
|
$np = $this->getForStation($station_id, $request->getRouter());
|
|
|
|
$currentArt = $np?->now_playing?->song?->art;
|
|
if (null !== $currentArt) {
|
|
return $response->withRedirect((string)$currentArt, 302);
|
|
}
|
|
|
|
return $response->withStatus(404)
|
|
->withJson(Entity\Api\Error::notFound());
|
|
}
|
|
|
|
private function getForStation(
|
|
string $station,
|
|
RouterInterface $router
|
|
): ?Entity\Api\NowPlaying\NowPlaying {
|
|
// Check cache first.
|
|
$np = $this->cache->get('nowplaying.' . $station);
|
|
|
|
if (!($np instanceof Entity\Api\NowPlaying\NowPlaying)) {
|
|
// Pull from DB if possible.
|
|
if (is_numeric($station)) {
|
|
$dql = <<<'DQL'
|
|
SELECT s.nowplaying FROM App\Entity\Station s
|
|
WHERE s.id = :id
|
|
DQL;
|
|
} else {
|
|
$dql = <<<'DQL'
|
|
SELECT s.nowplaying FROM App\Entity\Station s
|
|
WHERE s.short_name = :id
|
|
DQL;
|
|
}
|
|
|
|
try {
|
|
$npResult = $this->em->createQuery($dql)
|
|
->setParameter('id', $station)
|
|
->setMaxResults(1)
|
|
->getSingleResult();
|
|
|
|
$np = $npResult['nowplaying'] ?? null;
|
|
} catch (NoResultException) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
if ($np instanceof Entity\Api\NowPlaying\NowPlaying) {
|
|
$np->resolveUrls($router->getBaseUrl());
|
|
$np->update();
|
|
return $np;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private function getForAllStations(
|
|
RouterInterface $router,
|
|
bool $publicOnly = false,
|
|
): array {
|
|
if ($publicOnly) {
|
|
$dql = <<<'DQL'
|
|
SELECT s.nowplaying FROM App\Entity\Station s
|
|
WHERE s.is_enabled = 1 AND s.enable_public_page = 1
|
|
DQL;
|
|
} else {
|
|
$dql = <<<'DQL'
|
|
SELECT s.nowplaying FROM App\Entity\Station s
|
|
WHERE s.is_enabled = 1
|
|
DQL;
|
|
}
|
|
|
|
$np = [];
|
|
$baseUrl = $router->getBaseUrl();
|
|
|
|
foreach ($this->em->createQuery($dql)->getArrayResult() as $row) {
|
|
$npRow = $row['nowplaying'];
|
|
if ($npRow instanceof Entity\Api\NowPlaying\NowPlaying) {
|
|
$npRow->resolveUrls($baseUrl);
|
|
$npRow->update();
|
|
$np[] = $npRow;
|
|
}
|
|
}
|
|
|
|
return $np;
|
|
}
|
|
}
|