119 lines
3.6 KiB
PHP
119 lines
3.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Radio\Backend\Liquidsoap\Command;
|
|
|
|
use App\Entity;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Exception;
|
|
use Monolog\Logger;
|
|
use RuntimeException;
|
|
|
|
final class FeedbackCommand extends AbstractCommand
|
|
{
|
|
public function __construct(
|
|
Logger $logger,
|
|
private readonly EntityManagerInterface $em,
|
|
private readonly Entity\Repository\StationQueueRepository $queueRepo,
|
|
private readonly Entity\Repository\SongHistoryRepository $historyRepo
|
|
) {
|
|
parent::__construct($logger);
|
|
}
|
|
|
|
protected function doRun(
|
|
Entity\Station $station,
|
|
bool $asAutoDj = false,
|
|
array $payload = []
|
|
): bool {
|
|
// Process extra metadata sent by Liquidsoap (if it exists).
|
|
try {
|
|
$historyRow = $this->getSongHistory($station, $payload);
|
|
$this->em->persist($historyRow);
|
|
|
|
$this->historyRepo->changeCurrentSong($station, $historyRow);
|
|
|
|
$this->em->flush();
|
|
return true;
|
|
} catch (Exception $e) {
|
|
$this->logger->error(
|
|
sprintf('Liquidsoap feedback error: %s', $e->getMessage()),
|
|
[
|
|
'exception' => $e,
|
|
]
|
|
);
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private function getSongHistory(
|
|
Entity\Station $station,
|
|
array $payload
|
|
): Entity\SongHistory {
|
|
if (isset($payload['artist'])) {
|
|
$newSong = Entity\Song::createFromArray([
|
|
'artist' => $payload['artist'],
|
|
'title' => $payload['title'] ?? '',
|
|
]);
|
|
|
|
if (!$this->historyRepo->isDifferentFromCurrentSong($station, $newSong)) {
|
|
throw new RuntimeException('Song is not different from current song.');
|
|
}
|
|
|
|
return new Entity\SongHistory(
|
|
$station,
|
|
$newSong
|
|
);
|
|
}
|
|
|
|
if (empty($payload['media_id'])) {
|
|
throw new RuntimeException('No payload provided.');
|
|
}
|
|
|
|
$media = $this->em->find(Entity\StationMedia::class, $payload['media_id']);
|
|
if (!$media instanceof Entity\StationMedia) {
|
|
throw new RuntimeException('Media ID does not exist for station.');
|
|
}
|
|
|
|
if (!$this->historyRepo->isDifferentFromCurrentSong($station, $media)) {
|
|
throw new RuntimeException('Song is not different from current song.');
|
|
}
|
|
|
|
$sq = $this->queueRepo->findRecentlyCuedSong($station, $media);
|
|
|
|
if (null !== $sq) {
|
|
// If there's an existing record, ensure it has all the proper metadata.
|
|
if (null === $sq->getMedia()) {
|
|
$sq->setMedia($media);
|
|
}
|
|
|
|
if (!empty($payload['playlist_id']) && null === $sq->getPlaylist()) {
|
|
$playlist = $this->em->find(Entity\StationPlaylist::class, $payload['playlist_id']);
|
|
if ($playlist instanceof Entity\StationPlaylist) {
|
|
$sq->setPlaylist($playlist);
|
|
}
|
|
}
|
|
|
|
$this->em->persist($sq);
|
|
$this->em->flush();
|
|
|
|
$this->queueRepo->trackPlayed($station, $sq);
|
|
|
|
return Entity\SongHistory::fromQueue($sq);
|
|
}
|
|
|
|
$history = new Entity\SongHistory($station, $media);
|
|
$history->setMedia($media);
|
|
|
|
if (!empty($payload['playlist_id'])) {
|
|
$playlist = $this->em->find(Entity\StationPlaylist::class, $payload['playlist_id']);
|
|
if ($playlist instanceof Entity\StationPlaylist) {
|
|
$history->setPlaylist($playlist);
|
|
}
|
|
}
|
|
|
|
return $history;
|
|
}
|
|
}
|