Merge pull request #816 from Robbt/add_show_analytics
Add show-based listener analytics
This commit is contained in:
commit
9ac28a1aa5
8 changed files with 369 additions and 5 deletions
|
@ -26,6 +26,7 @@ $ccAcl->add(new Zend_Acl_Resource('library'))
|
|||
->add(new Zend_Acl_Resource('playouthistory'))
|
||||
->add(new Zend_Acl_Resource('playouthistorytemplate'))
|
||||
->add(new Zend_Acl_Resource('listenerstat'))
|
||||
->add(new Zend_Acl_Resource('showlistenerstat'))
|
||||
->add(new Zend_Acl_Resource('usersettings'))
|
||||
->add(new Zend_Acl_Resource('audiopreview'))
|
||||
->add(new Zend_Acl_Resource('webstream'))
|
||||
|
@ -84,6 +85,7 @@ $ccAcl->allow('G', 'index')
|
|||
->allow('H', 'playlist')
|
||||
->allow('H', 'playouthistory')
|
||||
->allow('H', 'listenerstat')
|
||||
->allow('H', 'showlistenerstat')
|
||||
->allow('A', 'playouthistorytemplate')
|
||||
->allow('A', 'user')
|
||||
->allow('A', 'systemstatus')
|
||||
|
|
|
@ -138,6 +138,14 @@ $pages[] = array(
|
|||
'action' => 'index',
|
||||
'resource' => 'listenerstat'
|
||||
),
|
||||
array(
|
||||
'label' => _('Show Listener Stats'),
|
||||
'module' => 'default',
|
||||
'controller' => 'listenerstat',
|
||||
'action' => 'show',
|
||||
'resource' => 'showlistenerstat'
|
||||
),
|
||||
|
||||
)
|
||||
);
|
||||
if (LIBRETIME_ENABLE_BILLING === true) {
|
||||
|
@ -221,4 +229,4 @@ $container = new Zend_Navigation($pages);
|
|||
$container->id = "nav";
|
||||
|
||||
//store it in the registry:
|
||||
Zend_Registry::set('Zend_Navigation', $container);
|
||||
Zend_Registry::set('Zend_Navigation', $container);
|
||||
|
|
|
@ -26,7 +26,6 @@ class ListenerstatController extends Zend_Controller_Action
|
|||
$this->view->headScript()->appendFile($baseUrl.'js/timepicker/jquery.ui.timepicker.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/airtime/buttons/buttons.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/airtime/utilities/utilities.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/jquery.ui.timepicker.css?'.$CC_CONFIG['airtime_version']);
|
||||
|
||||
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($request);
|
||||
|
@ -56,12 +55,76 @@ class ListenerstatController extends Zend_Controller_Action
|
|||
$this->view->errorStatus = $out;
|
||||
$this->view->date_form = $form;
|
||||
}
|
||||
public function showAction() {
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
|
||||
$request = $this->getRequest();
|
||||
$baseUrl = Application_Common_OsPath::getBaseDir();
|
||||
$headScript = $this->view->headScript();
|
||||
AirtimeTableView::injectTableJavaScriptDependencies($headScript, $baseUrl, $CC_CONFIG['airtime_version']);
|
||||
Zend_Layout::getMvcInstance()->assign('parent_page', 'Analytics');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/timepicker/jquery.ui.timepicker.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/airtime/buttons/buttons.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/airtime/utilities/utilities.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/airtime/listenerstat/showlistenerstat.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
|
||||
|
||||
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/datatables/css/ColVis.css?'.$CC_CONFIG['airtime_version']);
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/datatables/css/dataTables.colReorder.min.css?'.$CC_CONFIG['airtime_version']);
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'js/datatables/plugin/TableTools-2.1.5/css/TableTools.css?'.$CC_CONFIG['airtime_version']);
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/jquery.ui.timepicker.css?'.$CC_CONFIG['airtime_version']);
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/show_analytics.css'.$CC_CONFIG['airtime_version']);
|
||||
|
||||
$user = Application_Model_User::getCurrentUser();
|
||||
if ($user->isUserType(array(UTYPE_SUPERADMIN, UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) {
|
||||
$this->view->showAllShows = true;
|
||||
}
|
||||
$data = [];
|
||||
$this->view->showData = $data;
|
||||
|
||||
$form = new Application_Form_ShowListenerStat();
|
||||
|
||||
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($request);
|
||||
$userTimezone = new DateTimeZone(Application_Model_Preference::GetUserTimezone());
|
||||
$startsDT->setTimezone($userTimezone);
|
||||
$endsDT->setTimezone($userTimezone);
|
||||
$form->populate(array(
|
||||
'his_date_start' => $startsDT->format("Y-m-d"),
|
||||
'his_time_start' => $startsDT->format("H:i"),
|
||||
'his_date_end' => $endsDT->format("Y-m-d"),
|
||||
'his_time_end' => $endsDT->format("H:i")
|
||||
));
|
||||
|
||||
$this->view->date_form = $form;
|
||||
}
|
||||
|
||||
public function getDataAction(){
|
||||
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($this->getRequest());
|
||||
|
||||
$data = Application_Model_ListenerStat::getDataPointsWithinRange($startsDT->format(DEFAULT_TIMESTAMP_FORMAT),
|
||||
$endsDT->format(DEFAULT_TIMESTAMP_FORMAT));
|
||||
$this->_helper->json->sendJson($data);
|
||||
}
|
||||
|
||||
public function getShowDataAction(){
|
||||
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($this->getRequest());
|
||||
$show_id = $this->getRequest()->getParam("show_id", null);
|
||||
$data = Application_Model_ListenerStat::getShowDataPointsWithinRange($startsDT->format(DEFAULT_TIMESTAMP_FORMAT),
|
||||
$endsDT->format(DEFAULT_TIMESTAMP_FORMAT),$show_id);
|
||||
$this->_helper->json->sendJson($data);
|
||||
}
|
||||
public function getAllShowData(){
|
||||
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($this->getRequest());
|
||||
$data = Application_Model_ListenerStat::getAllShowDataPointsWithinRange($startsDT->format(DEFAULT_TIMESTAMP_FORMAT),
|
||||
$endsDT->format(DEFAULT_TIMESTAMP_FORMAT));
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function getAllShowDataAction(){
|
||||
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($this->getRequest());
|
||||
$show_id = $this->getRequest()->getParam("show_id", null);
|
||||
$data = Application_Model_ListenerStat::getAllShowDataPointsWithinRange($startsDT->format(DEFAULT_TIMESTAMP_FORMAT),
|
||||
$endsDT->format(DEFAULT_TIMESTAMP_FORMAT));
|
||||
$this->_helper->json->sendJson($data);
|
||||
}
|
||||
}
|
||||
|
|
68
airtime_mvc/application/forms/ShowListenerStat.php
Normal file
68
airtime_mvc/application/forms/ShowListenerStat.php
Normal file
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
class Application_Form_ShowListenerStat extends Zend_Form_SubForm
|
||||
{
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->setDecorators(array(
|
||||
array('ViewScript', array('viewScript' => 'form/daterange.phtml'))
|
||||
));
|
||||
|
||||
// Add start date element
|
||||
$startDate = new Zend_Form_Element_Text('his_date_start');
|
||||
$startDate->class = 'input_text';
|
||||
$startDate->setRequired(true)
|
||||
->setLabel(_('Date Start:'))
|
||||
->setValue(date("Y-m-d"))
|
||||
->setFilters(array('StringTrim'))
|
||||
->setValidators(array(
|
||||
'NotEmpty',
|
||||
array('date', false, array('YYYY-MM-DD'))))
|
||||
->setDecorators(array('ViewHelper'));
|
||||
$startDate->setAttrib('alt', 'date');
|
||||
$this->addElement($startDate);
|
||||
|
||||
// Add start time element
|
||||
$startTime = new Zend_Form_Element_Text('his_time_start');
|
||||
$startTime->class = 'input_text';
|
||||
$startTime->setRequired(true)
|
||||
->setValue('00:00')
|
||||
->setFilters(array('StringTrim'))
|
||||
->setValidators(array(
|
||||
'NotEmpty',
|
||||
array('date', false, array('HH:mm')),
|
||||
array('regex', false, array('/^[0-2]?[0-9]:[0-5][0-9]$/', 'messages' => _('Invalid character entered')))))
|
||||
->setDecorators(array('ViewHelper'));
|
||||
$startTime->setAttrib('alt', 'time');
|
||||
$this->addElement($startTime);
|
||||
|
||||
// Add end date element
|
||||
$endDate = new Zend_Form_Element_Text('his_date_end');
|
||||
$endDate->class = 'input_text';
|
||||
$endDate->setRequired(true)
|
||||
->setLabel(_('Date End:'))
|
||||
->setValue(date("Y-m-d"))
|
||||
->setFilters(array('StringTrim'))
|
||||
->setValidators(array(
|
||||
'NotEmpty',
|
||||
array('date', false, array('YYYY-MM-DD'))))
|
||||
->setDecorators(array('ViewHelper'));
|
||||
$endDate->setAttrib('alt', 'date');
|
||||
$this->addElement($endDate);
|
||||
|
||||
// Add end time element
|
||||
$endTime = new Zend_Form_Element_Text('his_time_end');
|
||||
$endTime->class = 'input_text';
|
||||
$endTime->setRequired(true)
|
||||
->setValue('01:00')
|
||||
->setFilters(array('StringTrim'))
|
||||
->setValidators(array(
|
||||
'NotEmpty',
|
||||
array('date', false, array('HH:mm')),
|
||||
array('regex', false, array('/^[0-2]?[0-9]:[0-5][0-9]$/', 'messages' => _('Invalid character entered')))))
|
||||
->setDecorators(array('ViewHelper'));
|
||||
$endTime->setAttrib('alt', 'time');
|
||||
$this->addElement($endTime);
|
||||
}
|
||||
}
|
|
@ -16,8 +16,8 @@ group by mount_name
|
|||
SQL;
|
||||
$data = Application_Common_Database::prepareAndExecute($sql,
|
||||
array('p1'=>$p_start, 'p2'=>$p_end));
|
||||
|
||||
$out = array();
|
||||
|
||||
foreach ($data as $d) {
|
||||
$jump = intval($d['count']/1000);
|
||||
$jump = max(1, $jump);
|
||||
|
@ -36,7 +36,7 @@ WHERE (temp.rownum%:p4) = :p5;
|
|||
SQL;
|
||||
$result = Application_Common_Database::prepareAndExecute($sql,
|
||||
array('p1'=>$p_start, 'p2'=>$p_end, 'p3'=>$d['mount_name'], 'p4'=>$jump, 'p5'=>$remainder));
|
||||
|
||||
|
||||
$utcTimezone = new DateTimeZone("UTC");
|
||||
$displayTimezone = new DateTimeZone(Application_Model_Preference::GetUserTimezone());
|
||||
|
||||
|
@ -51,6 +51,7 @@ SQL;
|
|||
}
|
||||
}
|
||||
|
||||
return $out;
|
||||
$enabledStreamIds = Application_Model_StreamSetting::getEnabledStreamIds();
|
||||
$enabledOut = array();
|
||||
|
||||
|
@ -77,6 +78,68 @@ SQL;
|
|||
|
||||
return $enabledOut;
|
||||
}
|
||||
// this will currently log the average number of listeners to a specific show during a certain range
|
||||
public static function getShowDataPointsWithinRange($p_start, $p_end, $show_id) {
|
||||
$showData = [];
|
||||
$ccShow = CcShowQuery::create()->findPk($show_id);
|
||||
$showName = $ccShow->getDbName();
|
||||
|
||||
|
||||
// this query selects all show instances that aired in this date range that match the show_id
|
||||
$sql = <<<SQL
|
||||
SELECT id, starts, ends FROM cc_show_instances WHERE show_id =:p1
|
||||
AND starts >=:p2 AND ends <=:p3
|
||||
SQL;
|
||||
$data = Application_Common_Database::prepareAndExecute($sql,
|
||||
array('p1'=>$show_id,'p2'=>$p_start, 'p3'=>$p_end));
|
||||
foreach ($data as $d) {
|
||||
$sql = <<<SQL
|
||||
SELECT timestamp, SUM(listener_count) AS listeners
|
||||
FROM cc_listener_count AS lc
|
||||
INNER JOIN cc_timestamp AS ts ON (lc.timestamp_id = ts.ID)
|
||||
INNER JOIN cc_mount_name AS mn ON (lc.mount_name_id = mn.ID)
|
||||
WHERE (ts.timestamp >=:p1 AND ts.timestamp <=:p2)
|
||||
GROUP BY timestamp
|
||||
SQL;
|
||||
$data = Application_Common_Database::prepareAndExecute($sql,
|
||||
array('p1'=>$d['starts'], 'p2'=>$d['ends']));
|
||||
$utcTimezone = new DateTimeZone("UTC");
|
||||
$displayTimezone = new DateTimeZone(Application_Model_Preference::GetUserTimezone());
|
||||
if (sizeof($data) > 0) {
|
||||
$t = new DateTime($data[0]['timestamp'], $utcTimezone);
|
||||
$t->setTimezone($displayTimezone);
|
||||
// tricking javascript so it thinks the server timezone is in UTC
|
||||
$average_listeners = array_sum(array_column($data, 'listeners')) / sizeof($data);
|
||||
$max_num_listeners = max(array_column($data, 'listeners'));
|
||||
$entry = array("show" => $showName, "time" => $t->format( 'Y-m-d H:i:s')
|
||||
, "average_number_of_listeners" => $average_listeners,
|
||||
"maximum_number_of_listeners" => $max_num_listeners);
|
||||
array_push($showData, $entry);
|
||||
}
|
||||
}
|
||||
return($showData);
|
||||
}
|
||||
public static function getAllShowDataPointsWithinRange($p_start, $p_end) {
|
||||
// this query selects the id of all show instances that aired in this date range
|
||||
$all_show_data = [];
|
||||
$sql = <<<SQL
|
||||
SELECT show_id FROM cc_show_instances
|
||||
WHERE starts >=:p1 AND ends <=:p2
|
||||
GROUP BY show_id
|
||||
SQL;
|
||||
$data = Application_Common_Database::prepareAndExecute($sql,
|
||||
array('p1'=>$p_start, 'p2'=>$p_end));
|
||||
|
||||
foreach($data as $show_id) {
|
||||
$all_show_data = array_merge(self::getShowDataPointsWithinRange($p_start,$p_end,$show_id['show_id']), $all_show_data);
|
||||
}
|
||||
/* option to sort by number of listeners currently commented out
|
||||
usort($all_show_data, function($a, $b) {
|
||||
return $a['average_number_of_listeners'] - $b['average_number_of_listeners'];
|
||||
});
|
||||
*/
|
||||
return $all_show_data;
|
||||
}
|
||||
|
||||
public static function insertDataPoints($p_dataPoints) {
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<div id="showlistenerstat_content" class="alpha-block padded">
|
||||
<H2><?php echo _("Listeners")?></H2>
|
||||
<div class="error_window"></div>
|
||||
<div id="date_form" style="float:left; margin:0px 0px">
|
||||
<h3 style="padding-left: 0px">Date Range</h3>
|
||||
<?php echo $this->date_form; ?>
|
||||
</div>
|
||||
|
||||
<table id="show_builder_table" cellpadding="0" cellspacing="0" class="datatable"></table>
|
||||
<table cellspacing="0" cellpadding="0" style="" id="show_stats_datatable" class="datatable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php echo _("Show Name") ?></th>
|
||||
<th><?php echo _("Air Date") ?></th>
|
||||
<th><?php echo _("Average Listeners")?></th>
|
||||
<th><?php echo _("Maximum Number of Listeners")?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<div style="clear: both;"></div>
|
||||
</div>
|
Loading…
Add table
Add a link
Reference in a new issue