mirror of
https://github.com/AzuraCast/AzuraCast.git
synced 2024-06-26 10:57:06 +00:00
Add ability to view requests, delete un-queued ones, and force queue in LS to not overload.
This commit is contained in:
parent
47de040244
commit
c97662787b
|
@ -35,7 +35,7 @@ class StationRequestRepository extends \App\Doctrine\Repository
|
|||
}
|
||||
|
||||
// Check if the song is already enqueued as a request.
|
||||
$pending_request_threshold = time() - (60 * 30);
|
||||
$pending_request_threshold = time() - (60 * 10);
|
||||
|
||||
try {
|
||||
$pending_request = $this->_em->createQuery('SELECT sr.timestamp
|
||||
|
|
43
app/modules/stations/controllers/RequestsController.php
Normal file
43
app/modules/stations/controllers/RequestsController.php
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
namespace Controller\Stations;
|
||||
|
||||
use Entity;
|
||||
|
||||
class RequestsController extends BaseController
|
||||
{
|
||||
protected function permissions()
|
||||
{
|
||||
return $this->acl->isAllowed('view station reports', $this->station->id);
|
||||
}
|
||||
|
||||
public function indexAction()
|
||||
{
|
||||
$this->view->requests = $this->em->createQuery('SELECT sr, sm, s FROM Entity\StationRequest sr
|
||||
JOIN sr.track sm
|
||||
JOIN sm.song s
|
||||
WHERE sr.station_id = :station_id
|
||||
ORDER BY sr.timestamp DESC')
|
||||
->setParameter('station_id', $this->station->id)
|
||||
->getArrayResult();
|
||||
}
|
||||
|
||||
public function deleteAction()
|
||||
{
|
||||
$id = (int)$this->getParam('request_id');
|
||||
|
||||
$media = $this->em->getRepository(Entity\StationRequest::class)->findOneBy([
|
||||
'id' => $id,
|
||||
'station_id' => $this->station->id,
|
||||
'played_at' => 0
|
||||
]);
|
||||
|
||||
if ($media instanceof Entity\StationRequest) {
|
||||
$this->em->remove($media);
|
||||
$this->em->flush();
|
||||
|
||||
$this->alert('<b>Request deleted!</b>', 'green');
|
||||
}
|
||||
|
||||
return $this->redirectFromHere(['action' => 'index', 'media_id' => null]);
|
||||
}
|
||||
}
|
|
@ -55,6 +55,13 @@ return function(\Slim\App $app) {
|
|||
|
||||
});
|
||||
|
||||
$this->group('/requests', function () {
|
||||
|
||||
$this->get('', 'stations:requests:index')->setName('stations:requests:index');
|
||||
$this->get('/delete/{request_id}', 'stations:requests:delete')->setName('stations:requests:delete');
|
||||
|
||||
});
|
||||
|
||||
$this->group('/reports', function () {
|
||||
|
||||
$this->get('/timeline[/format/{format}]', 'stations:index:timeline')->setName('stations:index:timeline');
|
||||
|
|
77
app/modules/stations/views/requests/index.phtml
Normal file
77
app/modules/stations/views/requests/index.phtml
Normal file
|
@ -0,0 +1,77 @@
|
|||
<?php $this->layout('main', ['title' => _('Song Requests'), 'manual' => true]) ?>
|
||||
|
||||
<div class="block-header">
|
||||
<h2><?=$this->e($station->name) ?></h2>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header ch-alt">
|
||||
<h2><?=_('Song Requests') ?></h2>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="data-table table table-striped">
|
||||
<colgroup>
|
||||
<col width="20%">
|
||||
<col width="20%">
|
||||
<col width="30%">
|
||||
<col width="15%">
|
||||
<col width="15%">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-column-id="timestamp"><?=_('Date Requested') ?></th>
|
||||
<th data-column-id="played_at"><?=_('Date Played') ?></th>
|
||||
<th data-column-id="song"><?=_('Song Title') ?></th>
|
||||
<th data-column-id="ip"><?=_('Requester IP') ?></th>
|
||||
<th data-column-id="actions"><?=_('Actions') ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($requests as $request_row): ?>
|
||||
<tr class="input" id="request_<?=$request_row['id'] ?>">
|
||||
<td class="text-center"><?=date('F j, Y g:ia', $request_row['timestamp']) ?></td>
|
||||
<td class="text-center">
|
||||
<?php if ($request_row['played_at'] > 0): ?>
|
||||
<?=date('F j, Y g:ia', $request_row['played_at']) ?>
|
||||
<?php else: ?>
|
||||
<?=_('Not Played') ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($request_row['track']['song']['title']): ?>
|
||||
<b><?=$request_row['track']['song']['title'] ?></b><br>
|
||||
<?=$request_row['track']['song']['artist'] ?>
|
||||
<?php else: ?>
|
||||
<?=$request_row['track']['song']['text'] ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?=$request_row['ip'] ?></td>
|
||||
<td>
|
||||
<?php if ($request_row['played_at'] == 0): ?>
|
||||
<a class="btn btn-sm btn-danger" href="<?=$url->routeFromHere(['action' => 'delete', 'request_id' => $request_row['id']]) ?>"><?=_('Delete') ?></a>
|
||||
<?php else: ?>
|
||||
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
$(".data-table").bootgrid({
|
||||
caseSensitive: false,
|
||||
sorting: false,
|
||||
css: {
|
||||
icon: 'zmdi icon',
|
||||
iconColumns: 'zmdi-view-module',
|
||||
iconDown: 'zmdi-sort-amount-desc',
|
||||
iconRefresh: 'zmdi-refresh',
|
||||
iconUp: 'zmdi-sort-amount-asc'
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
|
@ -44,6 +44,9 @@
|
|||
<a href="" data-ma-action="submenu-toggle"><i class="zmdi zmdi-assignment"></i> <?=_('Reports') ?></a>
|
||||
|
||||
<ul>
|
||||
<?php if ($station->enable_requests): ?>
|
||||
<li><a href="<?=$url->named('stations:requests:index', ['station' => $station->id]) ?>"><?=_('Song Requests') ?></a></li>
|
||||
<?php endif; ?>
|
||||
<li><a href="<?=$url->named('stations:index:timeline', ['station' => $station->id]) ?>"><?=_('Song Playback Timeline') ?></a></li>
|
||||
<?php if ($backend->supportsMedia()): ?>
|
||||
<li><a href="<?=$url->named('stations:reports:performance', ['station' => $station->id]) ?>"><?=_('Song Listener Impact') ?></a></li>
|
||||
|
|
|
@ -325,6 +325,12 @@ class LiquidSoap extends BackendAbstract
|
|||
|
||||
public function request($music_file)
|
||||
{
|
||||
$queue = $this->command('requests.queue');
|
||||
|
||||
if (!empty($queue[0])) {
|
||||
throw new \Exception('Song(s) still pending in request queue.');
|
||||
}
|
||||
|
||||
return $this->command('requests.push ' . $music_file);
|
||||
}
|
||||
|
||||
|
@ -343,14 +349,14 @@ class LiquidSoap extends BackendAbstract
|
|||
|
||||
fwrite($fp, str_replace(["\\'", '&'], ["'", '&'], urldecode($command_str)) . "\nquit\n");
|
||||
|
||||
$eat = '';
|
||||
$response = [];
|
||||
while (!feof($fp)) {
|
||||
$eat .= fgets($fp, 1024);
|
||||
$response[] = trim(fgets($fp, 1024));
|
||||
}
|
||||
|
||||
fclose($fp);
|
||||
|
||||
return true;
|
||||
return $response;
|
||||
}
|
||||
|
||||
protected function _getTelnetPort()
|
||||
|
|
|
@ -3,19 +3,21 @@ namespace AzuraCast\Sync;
|
|||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Entity\Station;
|
||||
use Entity\StationRequest;
|
||||
|
||||
class RadioRequests extends SyncAbstract
|
||||
{
|
||||
/** @var EntityManager $em */
|
||||
protected $em;
|
||||
|
||||
public function run()
|
||||
{
|
||||
/** @var EntityManager $em */
|
||||
$em = $this->di['em'];
|
||||
$this->em = $this->di['em'];
|
||||
|
||||
$stations = $em->getRepository(Station::class)->findAll();
|
||||
$stations = $this->em->getRepository(Station::class)->findAll();
|
||||
|
||||
foreach ($stations as $station) {
|
||||
/** @var $station Station */
|
||||
|
||||
if (!$station->enable_requests) {
|
||||
continue;
|
||||
}
|
||||
|
@ -28,29 +30,44 @@ class RadioRequests extends SyncAbstract
|
|||
$threshold = time() - ($threshold_minutes * 60);
|
||||
|
||||
// Look up all requests that have at least waited as long as the threshold.
|
||||
$requests = $em->createQuery('SELECT sr, sm FROM \Entity\StationRequest sr JOIN sr.track sm
|
||||
$request = $this->em->createQuery('SELECT sr, sm FROM \Entity\StationRequest sr JOIN sr.track sm
|
||||
WHERE sr.played_at = 0 AND sr.station_id = :station_id AND sr.timestamp <= :threshold
|
||||
ORDER BY sr.id ASC')
|
||||
->setParameter('station_id', $station->id)
|
||||
->setParameter('threshold', $threshold)
|
||||
->execute();
|
||||
->setMaxResults(1)
|
||||
->getOneOrNullResult();
|
||||
|
||||
foreach ($requests as $request) {
|
||||
\App\Debug::log($station->name . ': Request to play ' . $request->track->artist . ' - ' . $request->track->title);
|
||||
|
||||
// Log the request as played.
|
||||
$request->played_at = time();
|
||||
|
||||
$em->persist($request);
|
||||
$em->flush();
|
||||
|
||||
// Send request to the station to play the request.
|
||||
$backend = $station->getBackendAdapter($this->di);
|
||||
|
||||
if (method_exists($backend, 'request')) {
|
||||
$backend->request($request->track->getFullPath());
|
||||
}
|
||||
if ($request instanceof StationRequest) {
|
||||
$this->_submitRequest($station, $request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function _submitRequest(Station $station, StationRequest $request)
|
||||
{
|
||||
\App\Debug::log($station->name . ': Request to play ' . $request->track->artist . ' - ' . $request->track->title);
|
||||
|
||||
// Send request to the station to play the request.
|
||||
$backend = $station->getBackendAdapter($this->di);
|
||||
|
||||
if (!method_exists($backend, 'request')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$backend->request($request->track->getFullPath());
|
||||
} catch(\Exception $e) {
|
||||
\App\Debug::log('Request error: '.$e->getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Log the request as played.
|
||||
$request->played_at = time();
|
||||
|
||||
$this->em->persist($request);
|
||||
$this->em->flush();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user