Merge branch 'master' of dev.sourcefabric.org:campcaster

Conflicts:
	application/models/Shows.php
This commit is contained in:
naomiaro 2011-03-22 12:16:42 -04:00
commit 8016737968
11 changed files with 650 additions and 310 deletions

View file

@ -20,6 +20,8 @@ require_once 'StoredFile.php';
require_once 'Schedule.php';
require_once 'Shows.php';
require_once 'Users.php';
require_once 'RabbitMq.php';
global $CC_CONFIG, $CC_DBC;
$dsn = $CC_CONFIG['dsn'];

View file

@ -1,6 +1,7 @@
<?php
define('AIRTIME_VERSION', '1.7.0 alpha');
define('AIRTIME_COPYRIGHT_DATE', '2010-2011');
define('AIRTIME_REST_VERSION', '1.1');
// These are the default values for the config.
global $CC_CONFIG;
@ -25,6 +26,12 @@ $CC_CONFIG = array(
// Name of the web server user
'webServerUser' => 'www-data',
'rabbitmq' => array("host" => "127.0.0.1",
"port" => "5672",
"user" => "guest",
"password" => "guest",
"vhost" => "/"),
// ***********************************************************************
// STOP CUSTOMIZING HERE
//
@ -58,26 +65,26 @@ $CC_CONFIG = array(
//'AdminsGr' => 'Admins',
// name of station preferences group
'StationPrefsGr'=> 'StationPrefs',
// 'StationPrefsGr'=> 'StationPrefs',
// name of 'all users' group
//'AllGr' => 'All',
/* ==================================== application-specific configuration */
'objtypes' => array(
'Storage' => array(/*'Folder',*/ 'File' /*, 'Replica'*/),
'File' => array(),
'audioclip' => array(),
'playlist' => array(),
),
'allowedActions'=> array(
'File' => array('editPrivs', 'write', 'read'),
'audioclip' => array('editPrivs', 'write', 'read'),
'playlist' => array('editPrivs', 'write', 'read'),
),
'allActions' => array(
'editPrivs', 'write', 'read', 'subjects'
),
// 'objtypes' => array(
// 'Storage' => array(/*'Folder',*/ 'File' /*, 'Replica'*/),
// 'File' => array(),
// 'audioclip' => array(),
// 'playlist' => array(),
// ),
// 'allowedActions'=> array(
// 'File' => array('editPrivs', 'write', 'read'),
// 'audioclip' => array('editPrivs', 'write', 'read'),
// 'playlist' => array('editPrivs', 'write', 'read'),
// ),
// 'allActions' => array(
// 'editPrivs', 'write', 'read', 'subjects'
// ),
/* =================================================== cron configuration */
'cronUserName' => 'www-data',
@ -85,7 +92,7 @@ $CC_CONFIG = array(
'lockfile' => dirname(__FILE__).'/stor/buffer/cron.lock',
'cronfile' => dirname(__FILE__).'/cron/croncall.php',
'paramdir' => dirname(__FILE__).'/cron/params',
'systemPrefId' => "0", // ID for system prefs in prefs table
// 'systemPrefId' => "0", // ID for system prefs in prefs table
);
// Add database table names
@ -97,10 +104,8 @@ $CC_CONFIG['permTable'] = $CC_CONFIG['tblNamePrefix'].'perms';
$CC_CONFIG['sessTable'] = $CC_CONFIG['tblNamePrefix'].'sess';
$CC_CONFIG['subjTable'] = $CC_CONFIG['tblNamePrefix'].'subjs';
$CC_CONFIG['smembTable'] = $CC_CONFIG['tblNamePrefix'].'smemb';
$CC_CONFIG['transTable'] = $CC_CONFIG['tblNamePrefix'].'trans';
$CC_CONFIG['prefTable'] = $CC_CONFIG['tblNamePrefix'].'pref';
$CC_CONFIG['scheduleTable'] = $CC_CONFIG['tblNamePrefix'].'schedule';
$CC_CONFIG['backupTable'] = $CC_CONFIG['tblNamePrefix'].'backup';
$CC_CONFIG['playListTimeView'] = $CC_CONFIG['tblNamePrefix'].'playlisttimes';
$CC_CONFIG['showSchedule'] = $CC_CONFIG['tblNamePrefix'].'show_schedule';
$CC_CONFIG['showDays'] = $CC_CONFIG['tblNamePrefix'].'show_days';
@ -109,16 +114,15 @@ $CC_CONFIG['showInstances'] = $CC_CONFIG['tblNamePrefix'].'show_instances';
$CC_CONFIG['playListSequence'] = $CC_CONFIG['playListTable'].'_id';
$CC_CONFIG['filesSequence'] = $CC_CONFIG['filesTable'].'_id';
$CC_CONFIG['transSequence'] = $CC_CONFIG['transTable'].'_id';
$CC_CONFIG['prefSequence'] = $CC_CONFIG['prefTable'].'_id';
$CC_CONFIG['permSequence'] = $CC_CONFIG['permTable'].'_id';
$CC_CONFIG['subjSequence'] = $CC_CONFIG['subjTable'].'_id';
$CC_CONFIG['smembSequence'] = $CC_CONFIG['smembTable'].'_id';
// System users/groups - they cannot be deleted
$CC_CONFIG['sysSubjs'] = array(
'root', /*$CC_CONFIG['AdminsGr'],*/ /*$CC_CONFIG['AllGr'],*/ $CC_CONFIG['StationPrefsGr']
);
//$CC_CONFIG['sysSubjs'] = array(
// 'root', /*$CC_CONFIG['AdminsGr'],*/ /*$CC_CONFIG['AllGr'],*/ $CC_CONFIG['StationPrefsGr']
//);
// Add libs to the PHP path
$old_include_path = get_include_path();

View file

@ -101,6 +101,19 @@ class ApiController extends Zend_Controller_Action
exit;
}
public function liveInfoAction(){
global $CC_CONFIG;
// disable the view and the layout
$this->view->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
$result = Schedule::GetPlayOrderRange(0, 1);
//echo json_encode($result);
header("Content-type: text/javascript");
echo $_GET['callback'].'('.json_encode($result).')';
}
public function scheduleAction()
{
global $CC_CONFIG;
@ -123,14 +136,10 @@ class ApiController extends Zend_Controller_Action
$to = $this->_getParam("to");
if (Schedule::ValidPypoTimeFormat($from) && Schedule::ValidPypoTimeFormat($to)) {
$result = Schedule::ExportRangeAsJson($from, $to);
$result['stream_metadata'] = array();
$result['stream_metadata']['format'] = Application_Model_Preference::GetStreamLabelFormat();
$result['stream_metadata']['station_name'] = Application_Model_Preference::GetStationName();
echo json_encode($result);
}
}
public function notifyMediaItemStartPlayAction()
{
global $CC_CONFIG;

View file

@ -111,6 +111,7 @@ class ScheduleController extends Zend_Controller_Action
if(isset($error))
$this->view->error = $error;
}
public function resizeShowAction()

View file

@ -4,41 +4,65 @@ class Application_Model_DateHelper
{
private $_timestamp;
function __construct() {
function __construct()
{
$this->_timestamp = date("U");
}
function getDate(){
/**
* Get time of object construction in the format
* YYYY-MM-DD HH:mm:ss
*/
function getDate()
{
return date("Y-m-d H:i:s", $this->_timestamp);
}
function getTime(){
/**
* Get time of object construction in the format
* HH:mm:ss
*/
function getTime()
{
return date("H:i:s", $this->_timestamp);
}
function setDate($dateString){
/**
* Set the internal timestamp of the object.
*/
function setDate($dateString)
{
$this->_timestamp = strtotime($dateString);
}
function getNowDayStartDiff(){
/**
*
* Enter description here ...
*/
function getNowDayStartDiff()
{
$dayStartTS = strtotime(date("Y-m-d", $this->_timestamp));
return $this->_timestamp - $dayStartTS;
}
function getNowDayEndDiff(){
function getNowDayEndDiff()
{
$dayEndTS = strtotime(date("Y-m-d", $this->_timestamp+(86400)));
return $dayEndTS - $this->_timestamp;
}
function getEpochTime(){
function getEpochTime()
{
return $this->_timestamp;
}
public static function TimeDiff($time1, $time2){
public static function TimeDiff($time1, $time2)
{
return strtotime($time2) - strtotime($time1);
}
public static function ConvertMSToHHMMSSmm($time){
public static function ConvertMSToHHMMSSmm($time)
{
$hours = floor($time / 3600000);
$time -= 3600000*$hours;

View file

@ -0,0 +1,33 @@
<?php
require_once 'php-amqplib/amqp.inc';
class RabbitMq
{
/**
* Push the current schedule to RabbitMQ, to be picked up by Pypo.
* Will push the schedule in the range from 24 hours ago to 24 hours
* in the future.
*/
public static function PushSchedule() {
// global $CC_CONFIG;
// $conn = new AMQPConnection($CC_CONFIG["rabbitmq"]["host"],
// $CC_CONFIG["rabbitmq"]["port"],
// $CC_CONFIG["rabbitmq"]["user"],
// $CC_CONFIG["rabbitmq"]["password"]);
// $channel = $conn->channel();
// $channel->access_request($CC_CONFIG["rabbitmq"]["vhost"], false, false, true, true);
//
// $EXCHANGE = 'airtime-schedule';
// $channel->exchange_declare($EXCHANGE, 'direct', false, false, false);
//
// $data = json_encode(Schedule::ExportRangeAsJson());
// $msg = new AMQPMessage($data, array('content_type' => 'text/plain'));
//
// $channel->basic_publish($msg, $EXCHANGE);
// $channel->close();
// $conn->close();
}
}

View file

@ -73,7 +73,6 @@ class ScheduleGroup {
//var_dump($sql);
return $result;
}
return $this->groupId;
}
elseif (!is_null($p_playlistId)){
@ -116,8 +115,9 @@ class ScheduleGroup {
$itemStartTime = $CC_DBC->getOne("SELECT TIMESTAMP '$itemStartTime' + INTERVAL '$trackLength'");
$id = $this->dateToId($itemStartTime);
}
return $this->groupId;
}
RabbitMq::PushSchedule();
return $this->groupId;
}
public function addFileAfter($show_instance, $p_groupId, $p_audioFileId) {
@ -154,7 +154,9 @@ class ScheduleGroup {
$sql = "DELETE FROM ".$CC_CONFIG["scheduleTable"]
." WHERE group_id = ".$this->groupId;
//echo $sql;
return $CC_DBC->query($sql);
$retVal = $CC_DBC->query($sql);
RabbitMq::PushSchedule();
return $retVal;
}
/**
@ -190,17 +192,14 @@ class ScheduleGroup {
return $CC_DBC->GetAll($sql);
}
public function reschedule($toDateTime) {
global $CC_CONFIG, $CC_DBC;
// $sql = "UPDATE ".$CC_CONFIG["scheduleTable"]. " SET id=, starts=,ends="
}
public function notifyGroupStartPlay() {
global $CC_CONFIG, $CC_DBC;
$sql = "UPDATE ".$CC_CONFIG['scheduleTable']
." SET schedule_group_played=TRUE"
." WHERE group_id=".$this->groupId;
return $CC_DBC->query($sql);
$retVal = $CC_DBC->query($sql);
RabbitMq::PushSchedule();
return $retVal;
}
public function notifyMediaItemStartPlay($p_fileId) {
@ -209,7 +208,9 @@ class ScheduleGroup {
." SET media_item_played=TRUE"
." WHERE group_id=".$this->groupId
." AND file_id=".pg_escape_string($p_fileId);
return $CC_DBC->query($sql);
$retVal = $CC_DBC->query($sql);
RabbitMq::PushSchedule();
return $retVal;
}
}
@ -293,7 +294,8 @@ class Schedule {
return $res;
}
public static function GetPercentScheduled($instance_id, $s_datetime, $e_datetime){
public static function GetPercentScheduled($instance_id, $s_datetime, $e_datetime)
{
$time = Schedule::GetTotalShowTime($instance_id);
$s_epoch = strtotime($s_datetime);
@ -355,7 +357,8 @@ class Schedule {
* @return array
* Returns empty array if nothing found
*/
public static function GetItems($p_fromDateTime, $p_toDateTime, $p_playlistsOnly = true) {
public static function GetItems($p_fromDateTime, $p_toDateTime, $p_playlistsOnly = true)
{
global $CC_CONFIG, $CC_DBC;
$rows = array();
if (!$p_playlistsOnly) {
@ -416,7 +419,8 @@ class Schedule {
* @param int $next
* @return date
*/
public static function GetPlayOrderRange($prev = 1, $next = 1) {
public static function GetPlayOrderRange($prev = 1, $next = 1)
{
if (!is_int($prev) || !is_int($next)){
//must enter integers to specify ranges
return array();
@ -428,9 +432,9 @@ class Schedule {
$timeNow = $date->getDate();
return array("env"=>APPLICATION_ENV,
"schedulerTime"=>gmdate("Y-m-d H:i:s"),
"previous"=>Schedule::Get_Scheduled_Item_Data($timeNow, -1, $prev, "24 hours"),
"current"=>Schedule::Get_Scheduled_Item_Data($timeNow, 0),
"next"=>Schedule::Get_Scheduled_Item_Data($timeNow, 1, $next, "48 hours"),
"previous"=>Schedule::GetScheduledItemData($timeNow, -1, $prev, "24 hours"),
"current"=>Schedule::GetScheduledItemData($timeNow, 0),
"next"=>Schedule::GetScheduledItemData($timeNow, 1, $next, "48 hours"),
"currentShow"=>Show_DAL::GetCurrentShow($timeNow),
"nextShow"=>Show_DAL::GetNextShow($timeNow),
"timezone"=> date("T"),
@ -460,7 +464,8 @@ class Schedule {
* want to search the database. For example "5 days", "18 hours", "60 minutes",
* "30 seconds" etc.
*/
public static function Get_Scheduled_Item_Data($timeStamp, $timePeriod=0, $count = 0, $interval="0 hours"){
public static function GetScheduledItemData($timeStamp, $timePeriod=0, $count = 0, $interval="0 hours")
{
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT DISTINCT pt.name, ft.track_title, ft.artist_name, ft.album_title, st.starts, st.ends, st.clip_length, st.media_item_played, st.group_id, show.name as show_name, st.instance_id"
@ -490,7 +495,8 @@ class Schedule {
return $rows;
}
public static function GetShowInstanceItems($instance_id){
public static function GetShowInstanceItems($instance_id)
{
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT DISTINCT pt.name, ft.track_title, ft.artist_name, ft.album_title, st.starts, st.ends, st.clip_length, st.media_item_played, st.group_id, show.name as show_name, st.instance_id"
@ -506,12 +512,15 @@ class Schedule {
return $rows;
}
public static function UpdateMediaPlayedStatus($id){
public static function UpdateMediaPlayedStatus($p_id)
{
global $CC_CONFIG, $CC_DBC;
$sql = "UPDATE ".$CC_CONFIG['scheduleTable']
." SET media_item_played=TRUE"
." WHERE id=$id";
return $CC_DBC->query($sql);
." WHERE id=$p_id";
$retVal = $CC_DBC->query($sql);
RabbitMq::PushSchedule();
return $retVal;
}
@ -522,7 +531,7 @@ class Schedule {
* @param string $p_time
* @return string
*/
private static function CcTimeToPypoTime($p_time)
private static function AirtimeTimeToPypoTime($p_time)
{
$p_time = substr($p_time, 0, 19);
$p_time = str_replace(" ", "-", $p_time);
@ -537,7 +546,7 @@ class Schedule {
* @param string $p_time
* @return string
*/
private static function PypoTimeToCcTime($p_time)
private static function PypoTimeToAirtimeTime($p_time)
{
$t = explode("-", $p_time);
return $t[0]."-".$t[1]."-".$t[2]." ".$t[3].":".$t[4].":00";
@ -617,17 +626,29 @@ class Schedule {
/**
* Export the schedule in json formatted for pypo (the liquidsoap scheduler)
*
* @param string $range
* In the format "YYYY-MM-DD HH:mm:ss"
* @param string $source
* In the format "YYYY-MM-DD HH:mm:ss"
* @param string $p_fromDateTime
* In the format "YYYY-MM-DD-HH-mm-SS"
* @param string $p_toDateTime
* In the format "YYYY-MM-DD-HH-mm-SS"
*/
public static function ExportRangeAsJson($p_fromDateTime, $p_toDateTime)
public static function ExportRangeAsJson($p_fromDateTime = null , $p_toDateTime = null)
{
global $CC_CONFIG, $CC_DBC;
$range_start = Schedule::PypoTimeToCcTime($p_fromDateTime);
$range_end = Schedule::PypoTimeToCcTime($p_toDateTime);
if (is_null($p_fromDateTime)) {
$t1 = new DateTime();
$t1->sub(new DateInterval("PT24H"));
$range_start = $t1->format("Y-m-d H:i:s");
} else {
$range_start = Schedule::PypoTimeToAirtimeTime($p_fromDateTime);
}
if (is_null($p_fromDateTime)) {
$t2 = new DateTime();
$t2->add(new DateInterval("PT24H"));
$range_end = $t2->format("Y-m-d H:i:s");
} else {
$range_end = Schedule::PypoTimeToAirtimeTime($p_toDateTime);
}
// Scheduler wants everything in a playlist
$data = Schedule::GetItems($range_start, $range_end, true);
@ -643,7 +664,7 @@ class Schedule {
$start = substr($start, 0, 19);
//Start time is the array key, needs to be in the format "YYYY-MM-DD-HH-mm-ss"
$pkey = Schedule::CcTimeToPypoTime($start);
$pkey = Schedule::AirtimeTimeToPypoTime($start);
$timestamp = strtotime($start);
$playlists[$pkey]['source'] = "PLAYLIST";
$playlists[$pkey]['x_ident'] = $dx["playlist_id"];
@ -655,8 +676,8 @@ class Schedule {
$playlists[$pkey]['show_name'] = $dx['show_name'];
$playlists[$pkey]['user_id'] = 0;
$playlists[$pkey]['id'] = $dx["playlist_id"];
$playlists[$pkey]['start'] = Schedule::CcTimeToPypoTime($dx["start"]);
$playlists[$pkey]['end'] = Schedule::CcTimeToPypoTime($dx["end"]);
$playlists[$pkey]['start'] = Schedule::AirtimeTimeToPypoTime($dx["start"]);
$playlists[$pkey]['end'] = Schedule::AirtimeTimeToPypoTime($dx["end"]);
}
}
@ -693,9 +714,12 @@ class Schedule {
$result = array();
$result['status'] = array('range' => array('start' => $range_start, 'end' => $range_end),
'version' => "1.1");
'version' => AIRTIME_REST_VERSION);
$result['playlists'] = $playlists;
$result['check'] = 1;
$result['stream_metadata'] = array();
$result['stream_metadata']['format'] = Application_Model_Preference::GetStreamLabelFormat();
$result['stream_metadata']['station_name'] = Application_Model_Preference::GetStationName();
return $result;
}
@ -716,6 +740,7 @@ class Schedule {
$scheduleGroup = new ScheduleGroup($item["group_id"]);
$scheduleGroup->remove();
}
RabbitMq::PushSchedule();
}
}

View file

@ -9,47 +9,57 @@ class Show {
$this->_showId = $showId;
}
public function getName() {
public function getName()
{
$show = CcShowQuery::create()->findPK($this->_showId);
return $show->getDbName();
}
public function setName($name) {
public function setName($name)
{
$show = CcShowQuery::create()->findPK($this->_showId);
$show->setDbName($name);
RabbitMq::PushSchedule();
}
public function getDescription() {
public function getDescription()
{
$show = CcShowQuery::create()->findPK($this->_showId);
return $show->getDbDescription();
}
public function setDescription($description) {
public function setDescription($description)
{
$show = CcShowQuery::create()->findPK($this->_showId);
$show->setDbDescription($description);
}
public function getColor() {
public function getColor()
{
$show = CcShowQuery::create()->findPK($this->_showId);
return $show->getDbColor();
}
public function setColor($color) {
public function setColor($color)
{
$show = CcShowQuery::create()->findPK($this->_showId);
$show->setDbColor($color);
}
public function getBackgroundColor() {
public function getBackgroundColor()
{
$show = CcShowQuery::create()->findPK($this->_showId);
return $show->getDbBackgroundColor();
}
public function setBackgroundColor($backgroundColor) {
public function setBackgroundColor($backgroundColor)
{
$show = CcShowQuery::create()->findPK($this->_showId);
$show->setDbBackgroundColor($backgroundColor);
}
public function cancelShow($day_timestamp) {
public function cancelShow($day_timestamp)
{
global $CC_DBC;
$timeinfo = explode(" ", $day_timestamp);
@ -62,11 +72,12 @@ class Show {
WHERE starts >= '{$day_timestamp}' AND show_id = {$this->_showId}";
$CC_DBC->query($sql);
RabbitMq::PushSchedule();
}
//end dates are non inclusive.
public static function addShow($data) {
public static function addShow($data)
{
$con = Propel::getConnection(CcShowPeer::DATABASE_NAME);
$sql = "SELECT time '{$data['add_show_start_time']}' + INTERVAL '{$data['add_show_duration']} hour' ";
@ -127,7 +138,6 @@ class Show {
//don't set day for monthly repeat type, it's invalid.
if($data['add_show_repeats'] && $data["add_show_repeat_type"] == 2) {
$showDay = new CcShowDays();
$showDay->setDbFirstShow($data['add_show_start_date']);
$showDay->setDbLastShow($endDate);
@ -137,12 +147,9 @@ class Show {
$showDay->setDbShowId($showId);
$showDay->setDbRecord($isRecorded);
$showDay->save();
}
else {
foreach ($data['add_show_day_check'] as $day) {
if($startDow !== $day){
if ($startDow > $day)
@ -159,7 +166,6 @@ class Show {
}
if(strtotime($start) < strtotime($endDate) || is_null($endDate)) {
$showDay = new CcShowDays();
$showDay->setDbFirstShow($start);
$showDay->setDbLastShow($endDate);
@ -180,7 +186,6 @@ class Show {
for($i=1; $i<=5; $i++) {
if($data['add_show_rebroadcast_date_'.$i]) {
$showRebroad = new CcShowRebroadcast();
$showRebroad->setDbDayOffset($data['add_show_rebroadcast_date_'.$i]);
$showRebroad->setDbStartTime($data['add_show_rebroadcast_time_'.$i]);
@ -194,7 +199,6 @@ class Show {
for($i=1; $i<=5; $i++) {
if($data['add_show_rebroadcast_absolute_date_'.$i]) {
$sql = "SELECT date '{$data['add_show_rebroadcast_absolute_date_'.$i]}' - date '{$data['add_show_start_date']}' ";
$r = $con->query($sql);
$offset_days = $r->fetchColumn(0);
@ -219,9 +223,11 @@ class Show {
}
Show::populateShowUntilLastGeneratedDate($showId);
RabbitMq::PushSchedule();
}
public static function getShows($start_timestamp, $end_timestamp, $excludeInstance=NULL, $onlyRecord=FALSE) {
public static function getShows($start_timestamp, $end_timestamp, $excludeInstance=NULL, $onlyRecord=FALSE)
{
global $CC_DBC;
$sql = "SELECT starts, ends, record, rebroadcast, instance_id, show_id, name, description,
@ -257,8 +263,8 @@ class Show {
return $CC_DBC->GetAll($sql);
}
private static function setNextPop($next_date, $show_id, $day) {
private static function setNextPop($next_date, $show_id, $day)
{
$nextInfo = explode(" ", $next_date);
$repeatInfo = CcShowDaysQuery::create()
@ -271,7 +277,8 @@ class Show {
}
//for a show with repeat_type == -1
private static function populateNonRepeatingShow($show_id, $first_show, $start_time, $duration, $day, $record, $end_timestamp) {
private static function populateNonRepeatingShow($show_id, $first_show, $start_time, $duration, $day, $record, $end_timestamp)
{
global $CC_DBC;
$next_date = $first_show." ".$start_time;
@ -315,6 +322,7 @@ class Show {
$newRebroadcastInstance->save();
}
}
RabbitMq::PushSchedule();
}
//for a show with repeat_type == 0,1,2
@ -373,6 +381,7 @@ class Show {
}
Show::setNextPop($next_date, $show_id, $day);
RabbitMq::PushSchedule();
}
private static function populateShow($repeat_type, $show_id, $next_pop_date,
@ -503,53 +512,65 @@ class ShowInstance {
$this->_instanceId = $instanceId;
}
public function getShowId() {
public function getShowId()
{
$showInstance = CcShowInstancesQuery::create()->findPK($this->_instanceId);
return $showInstance->getDbShowId();
}
public function getShowInstanceId() {
public function getShowInstanceId()
{
return $this->_instanceId;
}
public function isRebroadcast() {
public function isRebroadcast()
{
$showInstance = CcShowInstancesQuery::create()->findPK($this->_instanceId);
return $showInstance->getDbOriginalShow();
}
public function isRecorded() {
public function isRecorded()
{
$showInstance = CcShowInstancesQuery::create()->findPK($this->_instanceId);
return $showInstance->getDbRecord();
}
public function getName() {
public function getName()
{
$show = CcShowQuery::create()->findPK($this->getShowId());
return $show->getDbName();
}
public function getShowStart() {
public function getShowStart()
{
$showInstance = CcShowInstancesQuery::create()->findPK($this->_instanceId);
return $showInstance->getDbStarts();
}
public function getShowEnd() {
public function getShowEnd()
{
$showInstance = CcShowInstancesQuery::create()->findPK($this->_instanceId);
return $showInstance->getDbEnds();
}
public function setShowStart($start) {
public function setShowStart($start)
{
$showInstance = CcShowInstancesQuery::create()->findPK($this->_instanceId);
$showInstance->setDbStarts($start)
->save();
RabbitMq::PushSchedule();
}
public function setShowEnd($end) {
public function setShowEnd($end)
{
$showInstance = CcShowInstancesQuery::create()->findPK($this->_instanceId);
$showInstance->setDbEnds($end)
->save();
RabbitMq::PushSchedule();
}
public function moveScheduledShowContent($deltaDay, $deltaHours, $deltaMin) {
public function moveScheduledShowContent($deltaDay, $deltaHours, $deltaMin)
{
global $CC_DBC;
$sql = "UPDATE cc_schedule
@ -558,9 +579,11 @@ class ShowInstance {
WHERE instance_id = '{$this->_instanceId}'";
$CC_DBC->query($sql);
RabbitMq::PushSchedule();
}
public function moveShow($deltaDay, $deltaMin){
public function moveShow($deltaDay, $deltaMin)
{
global $CC_DBC;
$hours = $deltaMin/60;
@ -604,9 +627,11 @@ class ShowInstance {
$this->moveScheduledShowContent($deltaDay, $hours, $mins);
$this->setShowStart($new_starts);
$this->setShowEnd($new_ends);
RabbitMq::PushSchedule();
}
public function resizeShow($deltaDay, $deltaMin){
public function resizeShow($deltaDay, $deltaMin)
{
global $CC_DBC;
$hours = $deltaMin/60;
@ -641,14 +666,14 @@ class ShowInstance {
}
$this->setShowEnd($new_ends);
RabbitMq::PushSchedule();
}
private function getLastGroupId() {
private function getLastGroupId()
{
global $CC_DBC;
$sql = "SELECT group_id FROM cc_schedule WHERE instance_id = '{$this->_instanceId}' ORDER BY ends DESC LIMIT 1";
$res = $CC_DBC->GetOne($sql);
return $res;
}
@ -664,6 +689,7 @@ class ShowInstance {
else {
$groupId = $sched->addPlaylistAfter($this->_instanceId, $lastGroupId, $plId);
}
RabbitMq::PushSchedule();
}
public function addFileToShow($file_id)
@ -678,6 +704,7 @@ class ShowInstance {
else {
$groupId = $sched->addFileAfter($this->_instanceId, $lastGroupId, $file_id);
}
RabbitMq::PushSchedule();
}
public function scheduleShow($plIds) {
@ -687,7 +714,8 @@ class ShowInstance {
}
}
public function removeGroupFromShow($group_id){
public function removeGroupFromShow($group_id)
{
global $CC_DBC;
$sql = "SELECT MAX(ends) as end_timestamp, (MAX(ends) - MIN(starts)) as length
@ -705,24 +733,27 @@ class ShowInstance {
WHERE starts >= '{$groupBoundry["end_timestamp"]}' AND instance_id = {$this->_instanceId}";
$CC_DBC->query($sql);
RabbitMq::PushSchedule();
}
public function clearShow() {
public function clearShow()
{
CcScheduleQuery::create()
->filterByDbInstanceId($this->_instanceId)
->delete();
RabbitMq::PushSchedule();
}
public function deleteShow() {
public function deleteShow()
{
CcShowInstancesQuery::create()
->findPK($this->_instanceId)
->delete();
RabbitMq::PushSchedule();
}
public function setRecordedFile($file_id) {
public function setRecordedFile($file_id)
{
$showInstance = CcShowInstancesQuery::create()
->findPK($this->_instanceId);
$showInstance->setDbRecordedFile($file_id)
@ -736,38 +767,36 @@ class ShowInstance {
$rebroad = new ShowInstance($rebroadcast->getDbId());
$rebroad->addFileToShow($file_id);
RabbitMq::PushSchedule();
}
}
public function getTimeScheduled() {
public function getTimeScheduled()
{
$instance_id = $this->getShowInstanceId();
$time = Schedule::GetTotalShowTime($instance_id);
return $time;
}
public function getTimeUnScheduled() {
public function getTimeUnScheduled()
{
$start_timestamp = $this->getShowStart();
$end_timestamp = $this->getShowEnd();
$instance_id = $this->getShowInstanceId();
$time = Schedule::getTimeUnScheduledInRange($instance_id, $start_timestamp, $end_timestamp);
return $time;
}
public function getPercentScheduled() {
public function getPercentScheduled()
{
$start_timestamp = $this->getShowStart();
$end_timestamp = $this->getShowEnd();
$instance_id = $this->getShowInstanceId();
return Schedule::GetPercentScheduled($instance_id, $start_timestamp, $end_timestamp);
}
public function getShowLength() {
public function getShowLength()
{
global $CC_DBC;
$start_timestamp = $this->getShowStart();
@ -779,14 +808,14 @@ class ShowInstance {
return $length;
}
public function searchPlaylistsForShow($datatables){
public function searchPlaylistsForShow($datatables)
{
$time_remaining = $this->getTimeUnScheduled();
return StoredFile::searchPlaylistsForSchedule($time_remaining, $datatables);
}
public function getShowListContent() {
public function getShowListContent()
{
global $CC_DBC;
$sql = "SELECT *
@ -798,7 +827,8 @@ class ShowInstance {
return $CC_DBC->GetAll($sql);
}
public function getShowContent() {
public function getShowContent()
{
global $CC_DBC;
$res = $this->getShowListContent();
@ -841,7 +871,8 @@ class ShowInstance {
/* Show Data Access Layer */
class Show_DAL {
public static function GetCurrentShow($timeNow) {
public static function GetCurrentShow($timeNow)
{
global $CC_CONFIG, $CC_DBC;
$timestamp = explode(" ", $timeNow);
@ -858,7 +889,8 @@ class Show_DAL{
return $rows;
}
public static function GetNextShow($timeNow) {
public static function GetNextShow($timeNow)
{
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT *, si.starts as start_timestamp, si.ends as end_timestamp FROM "
@ -873,7 +905,8 @@ class Show_DAL{
return $rows;
}
public static function GetShowsInRange($timeNow, $start, $end){
public static function GetShowsInRange($timeNow, $start, $end)
{
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT"
." si.starts as show_starts,"

214
plugins/jquery.showinfo.js Normal file
View file

@ -0,0 +1,214 @@
(function($){
$.fn.airtimeShowSchedule = function(options) {
var defaults = {
updatePeriod: 5, //seconds
};
var options = $.extend(defaults, options);
return this.each(function() {
var obj = $(this);
obj.append("<h3>On air today</h3>");
obj.append(
"<table width='100%' border='0' cellspacing='0' cellpadding='0' class='widget widget no-playing-list small'>"+
"<tbody><tr>" +
"<td class='time'>13:15 - 13:30</td>" +
"<td><a href='#'>Program name</a> <a href='#' class='listen'>Listen</a></td>" +
"</tr>"+
"<tr>"+
"<td class='time'>13:15 - 13:30</td>"+
"<td><a href='#'>Lorem ipsum dolor</a></td>"+
"</tr>"+
"</tbody></table>");
});
};
})(jQuery);
(function($){
$.fn.airtimeLiveInfo = function(options) {
var defaults = {
updatePeriod: 5, //seconds
sourceDomain: "http://localhost/", //where to get show status from
audioStreamSource: "" //where to get audio stream from
};
var options = $.extend(defaults, options);
return this.each(function() {
var obj = $(this);
var sd;
getServerData();
function updateWidget(){
var currentShow = sd.getCurrentShowName();
var timeRemaining = sd.getCurrentShowTimeRemaining();
var timeElapsed = sd.getCurrentShowTimeElapsed();
var showStatus = sd.getCurrentShowStatus();
var nextShow = sd.getNextShowName();
var nextShowRange = sd.getNextShowRange();
obj.empty();
obj.append("<a id='listenWadrLive'><span>Listen WADR Live</span></a>");
obj.append("<h4>"+showStatus+" &gt;&gt;</h4>");
obj.append("<ul class='widget no-playing-bar'>" +
"<li class='current'>"+currentShow+ "<span id='time-elapsed' class='time-elapsed'>"+timeElapsed+"</span>" +
"<span id='time-remaining' class='time-remaining'>"+timeRemaining+"</span></li>" +
"<li class='next'>"+nextShow+"<span>"+nextShowRange+"</span></li>" +
"</ul>");
//refresh the UI
setTimeout(updateWidget, 1000);
}
function processData(data){
sd = new ScheduleData(data);
updateWidget();
}
function getServerData(){
$.ajax({ url: options.sourceDomain + "api/live-info/", dataType:"jsonp", success:function(data){
processData(data);
}, error:function(jqXHR, textStatus, errorThrown){}});
setTimeout(getServerData, defaults.updatePeriod*1000);
}
});
};
})(jQuery);
/* The rest of this file is the ScheduleData class */
function ScheduleData(data){
this.data = data;
this.estimatedSchedulePosixTime;
this.schedulePosixTime = this.convertDateToPosixTime(data.schedulerTime);
this.schedulePosixTime += parseInt(data.timezoneOffset)*1000;
var date = new Date();
this.localRemoteTimeOffset = date.getTime() - this.schedulePosixTime;
}
ScheduleData.prototype.secondsTimer = function(){
var date = new Date();
this.estimatedSchedulePosixTime = date.getTime() - this.localRemoteTimeOffset;
}
ScheduleData.prototype.getCurrentShowName = function() {
var currentShow = this.data.currentShow;
if (currentShow.length > 0){
return "Current: " + currentShow[0].name;
} else {
return "";
}
};
ScheduleData.prototype.getCurrentShowStatus = function() {
var currentShow = this.data.currentShow;
if (currentShow.length > 0){
return "On Air Now";
} else {
return "Offline";
}
};
ScheduleData.prototype.getNextShowName = function() {
var nextShow = this.data.nextShow;
if (nextShow.length > 0){
return "Next: " + nextShow[0].name;
} else {
return "";
}
};
ScheduleData.prototype.getNextShowRange = function() {
var nextShow = this.data.nextShow;
if (nextShow.length > 0){
return this.getTime(nextShow[0].start_timestamp) + " - " + this.getTime(nextShow[0].end_timestamp);
} else {
return "";
}
};
ScheduleData.prototype.getCurrentShowTimeElapsed = function() {
this.secondsTimer();
var currentShow = this.data.currentShow;
if (currentShow.length > 0){
var showStart = this.convertDateToPosixTime(currentShow[0].start_timestamp);
return this.convertToHHMMSS(this.estimatedSchedulePosixTime - showStart);
} else {
return "";
}
};
ScheduleData.prototype.getCurrentShowTimeRemaining = function() {
this.secondsTimer();
var currentShow = this.data.currentShow;
if (currentShow.length > 0){
var showEnd = this.convertDateToPosixTime(currentShow[0].end_timestamp);
return this.convertToHHMMSS(showEnd - this.estimatedSchedulePosixTime);
} else {
return "";
}
};
ScheduleData.prototype.getTime = function(timestamp) {
return timestamp.split(" ")[1];
};
/* Takes an input parameter of milliseconds and converts these into
* the format HH:MM:SS */
ScheduleData.prototype.convertToHHMMSS = function(timeInMS){
var time = parseInt(timeInMS);
var hours = parseInt(time / 3600000);
time -= 3600000*hours;
var minutes = parseInt(time / 60000);
time -= 60000*minutes;
var seconds = parseInt(time / 1000);
hours = hours.toString();
minutes = minutes.toString();
seconds = seconds.toString();
if (hours.length == 1)
hours = "0" + hours;
if (minutes.length == 1)
minutes = "0" + minutes;
if (seconds.length == 1)
seconds = "0" + seconds;
if (hours == "00")
return minutes + ":" + seconds;
else
return hours + ":" + minutes + ":" + seconds;
}
/* Takes in a string of format similar to 2011-02-07 02:59:57,
* and converts this to epoch/posix time. */
ScheduleData.prototype.convertDateToPosixTime = function(s){
var datetime = s.split(" ");
var date = datetime[0].split("-");
var time = datetime[1].split(":");
var year = date[0];
var month = date[1];
var day = date[2];
var hour = time[0];
var minute = time[1];
var sec = 0;
var msec = 0;
if (time[2].indexOf(".") != -1){
var temp = time[2].split(".");
sec = temp[0];
msec = temp[1];
} else
sec = time[2];
return Date.UTC(year, month, day, hour, minute, sec, msec);
}

View file

@ -1,9 +0,0 @@
import airtime_api_client
import obp_api_client
def create_api_client(config):
if config["api_client"] == "airtime":
return campcaster_api_client.AirtimeApiClient(config)
elif config["api_client"] == "obp":
return obp_api_client.ObpApiClient(config)

View file

@ -7,14 +7,13 @@ Python part of radio playout (pypo)
The main functions are "fetch" (./pypo_cli.py -f) and "push" (./pypo_cli.py -p)
"""
# python defaults (debian default)
import time
#import calendar
#import traceback
from optparse import *
import sys
import os
import signal
#import datetime
import logging
import logging.config
@ -32,7 +31,6 @@ from Queue import Queue
from pypopush import PypoPush
from pypofetch import PypoFetch
# additional modules (should be checked)
from configobj import ConfigObj
# custom imports
@ -54,7 +52,6 @@ parser.add_option("-v", "--compat", help="Check compatibility with server API ve
parser.add_option("-t", "--test", help="Do a test to make sure everything is working properly.", default=False, action="store_true", dest="test")
parser.add_option("-f", "--fetch-scheduler", help="Fetch the schedule from server. This is a polling process that runs forever.", default=False, action="store_true", dest="fetch_scheduler")
parser.add_option("-p", "--push-scheduler", help="Push the schedule to Liquidsoap. This is a polling process that runs forever.", default=False, action="store_true", dest="push_scheduler")
parser.add_option("-b", "--cleanup", help="Cleanup", default=False, action="store_true", dest="cleanup")
parser.add_option("-c", "--check", help="Check the cached schedule and exit", default=False, action="store_true", dest="check")
@ -118,15 +115,19 @@ class Global:
for media in playlist['medias']:
print media
def keyboardInterruptHandler(signum, frame):
print "\nKeyboard Interrupt\n"
sys.exit();
if __name__ == '__main__':
print '###########################################'
print '# *** pypo *** #'
print '# Liquidsoap + External Scheduler #'
print '# Playout System #'
print '# Liquidsoap Scheduled Playout System #'
print '###########################################'
signal.signal(signal.SIGINT, keyboardInterruptHandler)
# initialize
g = Global()
g.selfcheck()
@ -140,14 +141,17 @@ if __name__ == '__main__':
q = Queue()
pp = PypoPush(q)
pp.daemon = True
pp.start()
pf = PypoFetch(q)
pf.daemon = True
pf.start()
pp.join()
pf.join()
while True: time.sleep(3600)
#pp.join()
#pf.join()
"""
if options.check:
try: g.check_schedule()