AzuraCast/src/Controller/Api/Stations/Reports/Overview/ByStream.php

100 lines
3.4 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Controller\Api\Stations\Reports\Overview;
use App\Entity;
use App\Entity\Repository\SettingsRepository;
use App\Http\Response;
use App\Http\ServerRequest;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Http\Message\ResponseInterface;
final class ByStream extends AbstractReportAction
{
public function __construct(
SettingsRepository $settingsRepo,
EntityManagerInterface $em,
private readonly Entity\Repository\StationMountRepository $mountRepo,
private readonly Entity\Repository\StationRemoteRepository $remoteRepo
) {
parent::__construct($settingsRepo, $em);
}
public function __invoke(
ServerRequest $request,
Response $response,
string $station_id
): ResponseInterface {
// Get current analytics level.
if (!$this->isAnalyticsEnabled()) {
return $response->withStatus(400)
->withJson(new Entity\Api\Status(false, 'Reporting is restricted due to system analytics level.'));
}
$station = $request->getStation();
$stationTz = $station->getTimezoneObject();
$dateRange = $this->getDateRange($request, $stationTz);
$statsRaw = $this->em->getConnection()->fetchAllAssociative(
<<<'SQL'
SELECT l.stream_id,
COUNT(l.listener_hash) AS listeners,
SUM(l.connected_seconds) AS connected_seconds
FROM (
SELECT IF (
mount_id IS NOT NULL,
CONCAT('local_', mount_id),
CONCAT('remote_', remote_id)
) AS stream_id,
SUM(timestamp_end - timestamp_start) AS connected_seconds,
listener_hash
FROM listener
WHERE station_id = :station_id
AND timestamp_end >= :start
AND timestamp_start <= :end
GROUP BY listener_hash
) AS l
GROUP BY l.stream_id
SQL,
[
'station_id' => $station->getIdRequired(),
'start' => $dateRange->getStartTimestamp(),
'end' => $dateRange->getEndTimestamp(),
]
);
$streamLookup = [];
foreach ($this->mountRepo->getDisplayNames($station) as $id => $displayName) {
$streamLookup['local_' . $id] = $displayName;
}
foreach ($this->remoteRepo->getDisplayNames($station) as $id => $displayName) {
$streamLookup['remote_' . $id] = $displayName;
}
$listenersByStream = [];
$connectedTimeByStream = [];
$stats = [];
foreach ($statsRaw as $row) {
if (!isset($streamLookup[$row['stream_id']])) {
continue;
}
$row['stream'] = $streamLookup[$row['stream_id']];
$stats[] = $row;
$listenersByStream[$row['stream']] = $row['listeners'];
$connectedTimeByStream[$row['stream']] = $row['connected_seconds'];
}
return $response->withJson([
'all' => $stats,
'top_listeners' => $this->buildChart($listenersByStream, __('Listeners')),
'top_connected_time' => $this->buildChart($connectedTimeByStream, __('Connected Seconds')),
]);
}
}