4
0
mirror of https://github.com/AzuraCast/AzuraCast.git synced 2024-06-14 13:16:37 +00:00

Vote API endpoint work.

This commit is contained in:
Buster Neece 2014-05-27 06:25:48 -05:00
parent bf7a33a815
commit d8cad3ee84
6 changed files with 144 additions and 6 deletions

View File

@ -90,4 +90,58 @@ class Utilities
return false;
}
/**
* Array Sorting
*/
public static function orderBy(&$ary, $clause, $ascending = true)
{
$clause = str_ireplace('order by', '', $clause);
$clause = preg_replace('/\s+/', ' ', $clause);
$keys = explode(',', $clause);
$dirMap = array('desc' => 1, 'asc' => -1);
$def = $ascending ? -1 : 1;
$keyAry = array();
$dirAry = array();
foreach($keys as $key) {
$key = explode(' ', trim($key));
$keyAry[] = trim($key[0]);
if(isset($key[1])) {
$dir = strtolower(trim($key[1]));
$dirAry[] = $dirMap[$dir] ? $dirMap[$dir] : $def;
} else {
$dirAry[] = $def;
}
}
$fnBody = '';
for($i = count($keyAry) - 1; $i >= 0; $i--) {
$k = $keyAry[$i];
$t = $dirAry[$i];
$f = -1 * $t;
$aStr = '$a[\''.$k.'\']';
$bStr = '$b[\''.$k.'\']';
if(strpos($k, '(') !== false) {
$aStr = '$a->'.$k;
$bStr = '$b->'.$k;
}
if($fnBody == '') {
$fnBody .= "if({$aStr} == {$bStr}) { return 0; }\n";
$fnBody .= "return ({$aStr} < {$bStr}) ? {$t} : {$f};\n";
} else {
$fnBody = "if({$aStr} == {$bStr}) {\n" . $fnBody;
$fnBody .= "}\n";
$fnBody .= "return ({$aStr} < {$bStr}) ? {$t} : {$f};\n";
}
}
if($fnBody) {
$sortFn = create_function('$a,$b', $fnBody);
usort($ary, $sortFn);
}
}
}

View File

@ -37,6 +37,9 @@ class Api_SongController extends \PVL\Controller\Action\Api
protected function _vote($value)
{
if (!$this->_request->isPost())
return $this->returnError('Votes must be submitted via HTTP POST.');
$sh_id = (int)$this->_getParam('sh_id');
$sh = SongHistory::find($sh_id);

View File

@ -2,6 +2,10 @@
use \Entity\Station;
use \Entity\StationManager;
use \Entity\Song;
use \Entity\SongHistory;
use \Entity\SongVote;
class Stations_IndexController extends \PVL\Controller\Action\Station
{
public function selectAction()
@ -199,7 +203,7 @@ class Stations_IndexController extends \PVL\Controller\Action\Station
$this->doNotRender();
$export_all = array();
$export_all[] = array('Date', 'Time', 'Listeners', 'Likes', 'Dislikes', 'Delta', 'Track', 'Artist', 'Event');
$export_all[] = array('Date', 'Time', 'Listeners', 'Delta', 'Likes', 'Dislikes', 'Track', 'Artist', 'Event');
foreach($songs as $song_row)
{
@ -230,6 +234,27 @@ class Stations_IndexController extends \PVL\Controller\Action\Station
}
}
public function votesAction()
{
$threshold = strtotime('-2 weeks');
$votes_raw = $this->em->createQuery('SELECT sv.song_id, SUM(sv.vote) AS vote_total FROM Entity\SongVote sv WHERE sv.station_id = :station_id AND sv.timestamp >= :threshold GROUP BY sv.song_id')
->setParameter('station_id', $this->station->id)
->setParameter('threshold', $threshold)
->getArrayResult();
\PVL\Utilities::orderBy($votes_raw, 'vote_total DESC');
$votes = array();
foreach($votes_raw as $row)
{
$row['song'] = Song::find($row['song_id']);
$votes[] = $row;
}
$this->view->votes = $votes;
}
public function addadminAction()
{
$this->doNotRender();

View File

@ -43,6 +43,9 @@ Highcharts.setOptions({
<dt><a href="<?=$this->routeFromHere(array('action' => 'timeline')) ?>">Song Playback Timeline</a></dt>
<dd>View the entire playback history of your station over the last 48 hours, along with the rise and fall of listener counts and special events.</dd>
<dt><a href="<?=$this->routeFromHere(array('action' => 'votes')) ?>">Song Vote Totals</a></dt>
<dd>View most/least popular songs on the station over the last two weeks.</dd>
<dt><a href="<?=$this->routeFromHere(array('controller' => 'urls', 'action' => 'index')) ?>">PVL Short URLs</a></dt>
<dd>Manage the "pvlive.me" URL shortener links for your station.</dd>

View File

@ -0,0 +1,51 @@
<?
$this->headTitle('Station Center');
$this->layout()->manual = true;
?>
<?=$this->renderHere('header') ?>
<?=$this->renderHere('homelink', true) ?>
<div class="row-fluid">
<div class="span12">
<h2>Song Vote Totals on Station</h2>
<table class="datatable table-striped table-condensed table-nopadding">
<colgroup>
<col width="10%">
<col width="90%">
</colgroup>
<thead>
<tr>
<th>Score</th>
<th>Song Title</th>
</tr>
</thead>
<tbody>
<? foreach($this->votes as $song_row): ?>
<tr class="input">
<td class="center">
<big>
<? if ($song_row['vote_total'] > 0): ?>
<span class="text-success"><i class="icon-thumbs-up"></i> <?=$song_row['vote_total'] ?></span>
<? elseif ($song_row['vote_total'] < 0): ?>
<span class="text-error"><i class="icon-thumbs-down"></i> <?=abs($song_row['vote_total']) ?></span>
<? else: ?>
0
<? endif; ?>
</big>
</td>
<td>
<? if ($song_row['song']['title']): ?>
<b><?=$song_row['song']['title'] ?></b><br>
<?=$song_row['song']['artist'] ?>
<? else: ?>
<?=$song_row['song']['text'] ?>
<? endif; ?>
</td>
</tr>
<? endforeach; ?>
</tbody>
</table>
</div>
</div>

View File

@ -56,9 +56,6 @@ $(function() {
return false;
vote_ratelimit = true;
setTimeout(function() {
vote_ratelimit = false;
}, 500);
// Action to call remotely.
if ($(this).hasClass('btn-active'))
@ -74,12 +71,17 @@ $(function() {
if (songhist_id == 0)
return false;
var remote_url = $(this).attr('href')+'/'+vote_function+'/sh_id/'+songhist_id;
var remote_url = '/api/song/'+vote_function;
jQuery.ajax({
'type': 'POST',
'url': remote_url,
'dataType': 'json'
'dataType': 'json',
'data': {
'sh_id': songhist_id,
}
}).done(function(return_data) {
vote_ratelimit = false;
console.log(return_data);
});