diff --git a/application/Bootstrap.php b/application/Bootstrap.php index d9ffceae0..bf9591e56 100644 --- a/application/Bootstrap.php +++ b/application/Bootstrap.php @@ -20,8 +20,10 @@ 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; + +global $CC_CONFIG, $CC_DBC; $dsn = $CC_CONFIG['dsn']; $CC_DBC = DB::connect($dsn, FALSE); @@ -65,14 +67,14 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap $this->view->headScript()->appendFile('/js/playlist/helperfunctions.js','text/javascript'); $this->view->headScript()->appendFile('/js/playlist/playlist.js','text/javascript'); - $view->headScript()->appendFile('/js/airtime/common/common.js','text/javascript'); + $view->headScript()->appendFile('/js/airtime/common/common.js','text/javascript'); } - + protected function _initViewHelpers(){ $view = $this->getResource('view'); $view->addHelperPath('../application/views/helpers', 'Airtime_View_Helper'); } - + protected function _initTitle(){ $view = $this->getResource('view'); $view->headTitle(Application_Model_Preference::GetHeadTitle()); diff --git a/application/configs/conf.php b/application/configs/conf.php index c1e98d0bb..da0c5e9b3 100644 --- a/application/configs/conf.php +++ b/application/configs/conf.php @@ -1,14 +1,15 @@ 'www-data', -// *********************************************************************** + 'rabbitmq' => array("host" => "127.0.0.1", + "port" => "5672", + "user" => "guest", + "password" => "guest", + "vhost" => "/"), + + // *********************************************************************** // STOP CUSTOMIZING HERE // - // You don't need to touch anything below this point. + // You don't need to touch anything below this point. // *********************************************************************** 'baseFilesDir' => $baseFilesDir, @@ -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(); @@ -128,9 +132,9 @@ set_include_path('.'.PATH_SEPARATOR.$CC_CONFIG['pearPath'] function load_airtime_config(){ $ini_array = parse_ini_file(dirname(__FILE__).'/../../build/airtime.conf', true); - + return array( - 'database' => array( + 'database' => array( 'username' => $ini_array['database']['dbuser'], 'password' => $ini_array['database']['dbpass'], 'hostspec' => $ini_array['database']['host'], diff --git a/application/controllers/ApiController.php b/application/controllers/ApiController.php index 1ef0d1155..b4dd0d3a2 100644 --- a/application/controllers/ApiController.php +++ b/application/controllers/ApiController.php @@ -24,7 +24,7 @@ class ApiController extends Zend_Controller_Action * in application/conf.php * * @return void - * + * */ public function versionAction() { @@ -136,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; diff --git a/application/controllers/ScheduleController.php b/application/controllers/ScheduleController.php index db0ec0526..daf774517 100644 --- a/application/controllers/ScheduleController.php +++ b/application/controllers/ScheduleController.php @@ -19,9 +19,9 @@ class ScheduleController extends Zend_Controller_Action ->addActionContext('schedule-show-dialog', 'json') ->addActionContext('show-content-dialog', 'json') ->addActionContext('clear-show', 'json') - ->addActionContext('get-current-playlist', 'json') + ->addActionContext('get-current-playlist', 'json') ->addActionContext('find-playlists', 'json') - ->addActionContext('remove-group', 'json') + ->addActionContext('remove-group', 'json') ->addActionContext('edit-show', 'json') ->addActionContext('add-show', 'json') ->addActionContext('cancel-show', 'json') @@ -64,7 +64,7 @@ class ScheduleController extends Zend_Controller_Action $formRepeats->removeDecorator('DtDdWrapper'); $formStyle->removeDecorator('DtDdWrapper'); $formRecord->removeDecorator('DtDdWrapper'); - + $this->view->what = $formWhat; $this->view->when = $formWhen; @@ -84,7 +84,7 @@ class ScheduleController extends Zend_Controller_Action { $start = $this->_getParam('start', null); $end = $this->_getParam('end', null); - + $userInfo = Zend_Auth::getInstance()->getStorage()->read(); $user = new User($userInfo->id); if($user->isAdmin()) @@ -111,6 +111,7 @@ class ScheduleController extends Zend_Controller_Action if(isset($error)) $this->view->error = $error; + } public function resizeShowAction() @@ -134,7 +135,7 @@ class ScheduleController extends Zend_Controller_Action public function deleteShowAction() { $showInstanceId = $this->_getParam('id'); - + $userInfo = Zend_Auth::getInstance()->getStorage()->read(); $user = new User($userInfo->id); @@ -158,41 +159,41 @@ class ScheduleController extends Zend_Controller_Action if (strtotime($today_timestamp) < strtotime($show->getShowStart())) { if (($user->isHost($show->getShowId()) || $user->isAdmin()) && !$show->isRecorded() && !$show->isRebroadcast()) { - - $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/schedule-show-dialog'.$params, + + $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/schedule-show-dialog'.$params, 'callback' => 'window["buildScheduleDialog"]'), 'title' => 'Add Content'); - $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/clear-show'.$params, + $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/clear-show'.$params, 'callback' => 'window["scheduleRefetchEvents"]'), 'title' => 'Remove All Content'); } } if(!$show->isRecorded()) { - $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/show-content-dialog'.$params, + $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/show-content-dialog'.$params, 'callback' => 'window["buildContentDialog"]'), 'title' => 'Show Content'); } - + if (strtotime($show->getShowStart()) <= strtotime($today_timestamp) && strtotime($today_timestamp) < strtotime($show->getShowEnd())) { $menu[] = array('action' => array('type' => 'fn', //'url' => '/Schedule/cancel-current-show'.$params, - 'callback' => "window['confirmCancelShow']($id)"), - 'title' => 'Cancel Current Show'); + 'callback' => "window['confirmCancelShow']($id)"), + 'title' => 'Cancel Current Show'); } - + if (strtotime($today_timestamp) < strtotime($show->getShowStart())) { if ($user->isAdmin()) { - $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/delete-show'.$params, + $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/delete-show'.$params, 'callback' => 'window["scheduleRefetchEvents"]'), 'title' => 'Delete This Instance'); - $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/cancel-show'.$params, + $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/cancel-show'.$params, 'callback' => 'window["scheduleRefetchEvents"]'), 'title' => 'Delete This Instance and All Following'); } } - + //returns format jjmenu is looking for. die(json_encode($menu)); } @@ -219,7 +220,7 @@ class ScheduleController extends Zend_Controller_Action $this->view->timeFilled = $show->getTimeScheduled(); $this->view->percentFilled = $show->getPercentScheduled(); - $this->view->chosen = $this->view->render('schedule/scheduled-content.phtml'); + $this->view->chosen = $this->view->render('schedule/scheduled-content.phtml'); unset($this->view->showContent); } @@ -242,7 +243,7 @@ class ScheduleController extends Zend_Controller_Action public function findPlaylistsAction() { $post = $this->getRequest()->getPost(); - + $show = new ShowInstance($this->sched_sess->showInstanceId); $playlists = $show->searchPlaylistsForShow($post); @@ -267,7 +268,7 @@ class ScheduleController extends Zend_Controller_Action $this->view->showContent = $show->getShowContent(); $this->view->timeFilled = $show->getTimeScheduled(); $this->view->percentFilled = $show->getPercentScheduled(); - $this->view->chosen = $this->view->render('schedule/scheduled-content.phtml'); + $this->view->chosen = $this->view->render('schedule/scheduled-content.phtml'); unset($this->view->showContent); } @@ -275,7 +276,7 @@ class ScheduleController extends Zend_Controller_Action { $showInstanceId = $this->_getParam('id'); $this->sched_sess->showInstanceId = $showInstanceId; - + $show = new ShowInstance($showInstanceId); $start_timestamp = $show->getShowStart(); $end_timestamp = $show->getShowEnd(); @@ -285,14 +286,14 @@ class ScheduleController extends Zend_Controller_Action $this->view->error = "cannot schedule an overlapping show."; return; } - + $start = explode(" ", $start_timestamp); $end = explode(" ", $end_timestamp); $startTime = explode(":", $start[1]); $endTime = explode(":", $end[1]); $dateInfo_s = getDate(strtotime($start_timestamp)); $dateInfo_e = getDate(strtotime($end_timestamp)); - + $this->view->showContent = $show->getShowContent(); $this->view->timeFilled = $show->getTimeScheduled(); $this->view->showName = $show->getName(); @@ -308,7 +309,7 @@ class ScheduleController extends Zend_Controller_Action $this->view->startTime = sprintf("%d:%02d", $startTime[0], $startTime[1]); $this->view->endTime = sprintf("%d:%02d", $endTime[0], $endTime[1]); - $this->view->chosen = $this->view->render('schedule/scheduled-content.phtml'); + $this->view->chosen = $this->view->render('schedule/scheduled-content.phtml'); $this->view->dialog = $this->view->render('schedule/schedule-show-dialog.phtml'); unset($this->view->showContent); } @@ -335,7 +336,7 @@ class ScheduleController extends Zend_Controller_Action { $js = $this->_getParam('data'); $data = array(); - + //need to convert from serialized jQuery array. foreach($js as $j){ $data[$j["name"]] = $j["value"]; @@ -392,8 +393,8 @@ class ScheduleController extends Zend_Controller_Action $rebroadAb = $formAbsoluteRebroadcast->isValid($data); $rebroad = $formRebroadcast->isValid($data); - if ($what && $when && $repeats && $who && $style && $record && $rebroadAb && $rebroad) { - + if ($what && $when && $repeats && $who && $style && $record && $rebroadAb && $rebroad) { + $userInfo = Zend_Auth::getInstance()->getStorage()->read(); $user = new User($userInfo->id); if($user->isAdmin()) { @@ -413,7 +414,7 @@ class ScheduleController extends Zend_Controller_Action $formRecord->reset(); $formAbsoluteRebroadcast->reset(); $formRebroadcast->reset(); - + $this->view->newForm = $this->view->render('schedule/add-show-form.phtml'); } else { @@ -426,7 +427,7 @@ class ScheduleController extends Zend_Controller_Action { $userInfo = Zend_Auth::getInstance()->getStorage()->read(); $user = new User($userInfo->id); - + if($user->isAdmin()) { $showInstanceId = $this->_getParam('id'); @@ -434,14 +435,14 @@ class ScheduleController extends Zend_Controller_Action $show = new Show($showInstance->getShowId()); $show->cancelShow($showInstance->getShowStart()); - } + } } public function cancelCurrentShowAction() { $userInfo = Zend_Auth::getInstance()->getStorage()->read(); $user = new User($userInfo->id); - + if($user->isAdmin()) { $showInstanceId = $this->_getParam('id'); $show = new ShowInstance($showInstanceId); diff --git a/application/models/DateHelper.php b/application/models/DateHelper.php index 640e5cd6a..d0f56f647 100644 --- a/application/models/DateHelper.php +++ b/application/models/DateHelper.php @@ -2,61 +2,85 @@ class Application_Model_DateHelper { - private $_timestamp; - - function __construct() { + private $_timestamp; + + function __construct() + { $this->_timestamp = date("U"); - } - - function getDate(){ - return date("Y-m-d H:i:s", $this->_timestamp); - } - - function getTime(){ - return date("H:i:s", $this->_timestamp); - } - - function setDate($dateString){ + } + + /** + * 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); + } + + /** + * Get time of object construction in the format + * HH:mm:ss + */ + function getTime() + { + return date("H:i:s", $this->_timestamp); + } + + /** + * Set the internal timestamp of the object. + */ + function setDate($dateString) + { $this->_timestamp = strtotime($dateString); - } - - function getNowDayStartDiff(){ - $dayStartTS = strtotime(date("Y-m-d", $this->_timestamp)); - return $this->_timestamp - $dayStartTS; - } + } - function getNowDayEndDiff(){ - $dayEndTS = strtotime(date("Y-m-d", $this->_timestamp+(86400))); - return $dayEndTS - $this->_timestamp; - } + /** + * + * Enter description here ... + */ + function getNowDayStartDiff() + { + $dayStartTS = strtotime(date("Y-m-d", $this->_timestamp)); + return $this->_timestamp - $dayStartTS; + } - function getEpochTime(){ + function getNowDayEndDiff() + { + $dayEndTS = strtotime(date("Y-m-d", $this->_timestamp+(86400))); + return $dayEndTS - $this->_timestamp; + } + + 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; - + $minutes = floor($time / 60000); $time -= 60000*$minutes; - + $seconds = floor($time / 1000); $time -= 1000*$seconds; - + $ms = $time; - + if (strlen($hours) == 1) - $hours = "0".$hours; + $hours = "0".$hours; if (strlen($minutes) == 1) - $minutes = "0".$minutes; + $minutes = "0".$minutes; if (strlen($seconds) == 1) - $seconds = "0".$seconds; - + $seconds = "0".$seconds; + return $hours.":".$minutes.":".$seconds.".".$ms; } } diff --git a/application/models/RabbitMq.php b/application/models/RabbitMq.php new file mode 100644 index 000000000..d251116bf --- /dev/null +++ b/application/models/RabbitMq.php @@ -0,0 +1,33 @@ +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(); + } + +} + diff --git a/application/models/Schedule.php b/application/models/Schedule.php index 5fe66f2ca..6113eae2e 100644 --- a/application/models/Schedule.php +++ b/application/models/Schedule.php @@ -24,41 +24,6 @@ class ScheduleGroup { return $result != "0"; } - /** - * Convert a date to an ID by stripping out all characters - * and padding with zeros. - * - * @param string $p_dateStr - */ - public static function dateToId($p_dateStr) { - $p_dateStr = str_replace(":", "", $p_dateStr); - $p_dateStr = str_replace(" ", "", $p_dateStr); - $p_dateStr = str_replace(".", "", $p_dateStr); - $p_dateStr = str_replace("-", "", $p_dateStr); - $p_dateStr = substr($p_dateStr, 0, 17); - $p_dateStr = str_pad($p_dateStr, 17, "0"); - return $p_dateStr; - } - - /** - * Add the two times together, return the result. - * - * @param string $p_baseTime - * Specified as YYYY-MM-DD HH:MM:SS - * - * @param string $p_addTime - * Specified as HH:MM:SS.nnnnnn - * - * @return string - * The end time, to the nearest second. - */ - // protected function calculateEndTime($p_startTime, $p_trackTime) { - // $p_trackTime = substr($p_startTime, 0, ); - // $start = new DateTime(); - // $interval = new DateInterval() - // - // } - /** * Add a music clip or playlist to the schedule. * @@ -77,6 +42,7 @@ class ScheduleGroup { */ public function add($show_instance, $p_datetime, $p_audioFileId = null, $p_playlistId = null, $p_options = null) { global $CC_CONFIG, $CC_DBC; + if (!is_null($p_audioFileId)) { // Schedule a single audio track @@ -92,27 +58,24 @@ class ScheduleGroup { if (empty($length)) { return new PEAR_Error("Length is empty."); } - if (!Schedule::isScheduleEmptyInRange($p_datetime, $length)) { - return new PEAR_Error("Schedule conflict.", 555); - } - + // Insert into the table $this->groupId = $CC_DBC->GetOne("SELECT nextval('schedule_group_id_seq')"); - $id = $this->dateToId($p_datetime); + $sql = "INSERT INTO ".$CC_CONFIG["scheduleTable"] - ." (playlist_id, starts, ends, clip_length, group_id, file_id)" - ." VALUES (0, TIMESTAMP '$p_datetime', " + ." (instance_id, starts, ends, clip_length, group_id, file_id, cue_out)" + ." VALUES ($show_instance, TIMESTAMP '$p_datetime', " ." (TIMESTAMP '$p_datetime' + INTERVAL '$length')," ." '$length'," - ." {$this->groupId}, $p_audioFileId)"; + ." {$this->groupId}, $p_audioFileId, '$length')"; $result = $CC_DBC->query($sql); if (PEAR::isError($result)) { //var_dump($sql); return $result; } - return $this->groupId; - } elseif (!is_null($p_playlistId)){ + } + elseif (!is_null($p_playlistId)){ // Schedule a whole playlist // Load existing playlist @@ -130,7 +93,6 @@ class ScheduleGroup { // Insert all items into the schedule $this->groupId = $CC_DBC->GetOne("SELECT nextval('schedule_group_id_seq')"); - $id = $this->dateToId($p_datetime); $itemStartTime = $p_datetime; $plItems = $playlist->getContents(); @@ -153,11 +115,12 @@ 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 addAfter($show_instance, $p_groupId, $p_audioFileId) { + public function addFileAfter($show_instance, $p_groupId, $p_audioFileId) { global $CC_CONFIG, $CC_DBC; // Get the end time for the given entry $sql = "SELECT MAX(ends) FROM ".$CC_CONFIG["scheduleTable"] @@ -176,10 +139,6 @@ class ScheduleGroup { return $this->add($show_instance, $startTime, null, $p_playlistId); } - public function update() { - - } - /** * Remove the group from the schedule. * Note: does not check if it is in the past, you can remove anything. @@ -195,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; } /** @@ -231,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) { @@ -250,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; } } @@ -334,9 +294,10 @@ 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); $e_epoch = strtotime($e_datetime); @@ -396,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) { @@ -433,7 +395,7 @@ class Schedule { ." AND (st.ends <= TIMESTAMP '$p_toDateTime')" //next line makes sure that we aren't returning items that //are past the show's scheduled timeslot. - ." AND (st.starts < si.ends)" + ." AND (st.starts < si.ends)" ." GROUP BY st.group_id" ." ORDER BY starts"; @@ -457,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(); @@ -469,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"), @@ -501,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" @@ -531,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" @@ -547,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; } @@ -563,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); @@ -578,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"; @@ -658,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); @@ -684,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"]; @@ -696,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"]); } } @@ -734,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; } @@ -757,6 +740,7 @@ class Schedule { $scheduleGroup = new ScheduleGroup($item["group_id"]); $scheduleGroup->remove(); } + RabbitMq::PushSchedule(); } } diff --git a/application/models/Shows.php b/application/models/Shows.php index 57ba0fb45..ea2cf5401 100644 --- a/application/models/Shows.php +++ b/application/models/Shows.php @@ -6,50 +6,60 @@ class Show { public function __construct($showId=NULL) { - $this->_showId = $showId; + $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,20 +72,21 @@ 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' "; $r = $con->query($sql); - $endTime = $r->fetchColumn(0); + $endTime = $r->fetchColumn(0); $sql = "SELECT EXTRACT(DOW FROM TIMESTAMP '{$data['add_show_start_date']} {$data['add_show_start_time']}')"; $r = $con->query($sql); - $startDow = $r->fetchColumn(0); + $startDow = $r->fetchColumn(0); if($data['add_show_no_end']) { $endDate = NULL; @@ -84,13 +95,13 @@ class Show { else if($data['add_show_repeats']) { $sql = "SELECT date '{$data['add_show_end_date']}' + INTERVAL '1 day' "; $r = $con->query($sql); - $endDate = $r->fetchColumn(0); + $endDate = $r->fetchColumn(0); } else { $sql = "SELECT date '{$data['add_show_start_date']}' + INTERVAL '1 day' "; $r = $con->query($sql); $endDate = $r->fetchColumn(0); - } + } //only want the day of the week from the start date. if(!$data['add_show_repeats']) { @@ -98,7 +109,7 @@ class Show { } else if($data['add_show_repeats'] && $data['add_show_day_check'] == "") { $data['add_show_day_check'] = array($startDow); - } + } //find repeat type or set to a non repeating show. if($data['add_show_repeats']) { @@ -114,7 +125,7 @@ class Show { $show->setDbUrl($data['add_show_url']); $show->setDbColor($data['add_show_color']); $show->setDbBackgroundColor($data['add_show_background_color']); - $show->save(); + $show->save(); $showId = $show->getDbId(); @@ -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,29 +147,25 @@ 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) + + if ($startDow > $day) $daysAdd = 6 - $startDow + 1 + $day; else - $daysAdd = $day - $startDow; + $daysAdd = $day - $startDow; $sql = "SELECT date '{$data['add_show_start_date']}' + INTERVAL '{$daysAdd} day' "; $r = $con->query($sql); - $start = $r->fetchColumn(0); + $start = $r->fetchColumn(0); } else { $start = $data['add_show_start_date']; } 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]); @@ -190,14 +195,13 @@ class Show { } } else if($data['add_show_record'] && $data['add_show_rebroadcast'] && $repeat_type == -1){ - + 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); + $offset_days = $r->fetchColumn(0); $showRebroad = new CcShowRebroadcast(); $showRebroad->setDbDayOffset($offset_days." days"); @@ -207,7 +211,7 @@ class Show { } } } - + if(is_array($data['add_show_hosts'])) { //add selected hosts to cc_show_hosts table. foreach ($data['add_show_hosts'] as $host) { @@ -219,18 +223,20 @@ 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, - color, background_color, cc_show_instances.id AS instance_id - FROM cc_show_instances + $sql = "SELECT starts, ends, record, rebroadcast, instance_id, show_id, name, description, + color, background_color, cc_show_instances.id AS instance_id + FROM cc_show_instances LEFT JOIN cc_show ON cc_show.id = cc_show_instances.show_id"; //only want shows that are starting at the time or later. - if($onlyRecord) { + if ($onlyRecord) { $sql = $sql." WHERE (starts >= '{$start_timestamp}' AND starts < timestamp '{$start_timestamp}' + interval '2 hours')"; $sql = $sql." AND (record = 1)"; @@ -240,10 +246,10 @@ class Show { $sql = $sql." WHERE ((starts >= '{$start_timestamp}' AND starts < '{$end_timestamp}') OR (ends > '{$start_timestamp}' AND ends <= '{$end_timestamp}') OR (starts <= '{$start_timestamp}' AND ends >= '{$end_timestamp}'))"; - } - + } - if(isset($excludeInstance)) { + + if (isset($excludeInstance)) { foreach($excludeInstance as $instance) { $sql_exclude[] = "cc_show_instances.id != {$instance}"; } @@ -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,15 +277,16 @@ 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; - + if(strtotime($next_date) < strtotime($end_timestamp)) { - + $start = $next_date; - + $sql = "SELECT timestamp '{$start}' + interval '{$duration}'"; $end = $CC_DBC->GetOne($sql); @@ -298,10 +305,10 @@ class Show { foreach($rebroadcasts as $rebroadcast) { $timeinfo = explode(" ", $start); - + $sql = "SELECT timestamp '{$timeinfo[0]}' + interval '{$rebroadcast["day_offset"]}' + interval '{$rebroadcast["start_time"]}'"; $rebroadcast_start_time = $CC_DBC->GetOne($sql); - + $sql = "SELECT timestamp '{$rebroadcast_start_time}' + interval '{$duration}'"; $rebroadcast_end_time = $CC_DBC->GetOne($sql); @@ -315,12 +322,13 @@ class Show { $newRebroadcastInstance->save(); } } + RabbitMq::PushSchedule(); } //for a show with repeat_type == 0,1,2 - private static function populateRepeatingShow($show_id, $next_pop_date, $first_show, $last_show, + private static function populateRepeatingShow($show_id, $next_pop_date, $first_show, $last_show, $start_time, $duration, $day, $record, $end_timestamp, $interval) { - global $CC_DBC; + global $CC_DBC; if(isset($next_pop_date)) { $next_date = $next_pop_date." ".$start_time; @@ -333,9 +341,9 @@ class Show { $rebroadcasts = $CC_DBC->GetAll($sql); while(strtotime($next_date) < strtotime($end_timestamp) && (strtotime($last_show) > strtotime($next_date) || is_null($last_show))) { - + $start = $next_date; - + $sql = "SELECT timestamp '{$start}' + interval '{$duration}'"; $end = $CC_DBC->GetOne($sql); @@ -351,10 +359,10 @@ class Show { foreach($rebroadcasts as $rebroadcast) { $timeinfo = explode(" ", $next_date); - + $sql = "SELECT timestamp '{$timeinfo[0]}' + interval '{$rebroadcast["day_offset"]}' + interval '{$rebroadcast["start_time"]}'"; $rebroadcast_start_time = $CC_DBC->GetOne($sql); - + $sql = "SELECT timestamp '{$rebroadcast_start_time}' + interval '{$duration}'"; $rebroadcast_end_time = $CC_DBC->GetOne($sql); @@ -373,64 +381,65 @@ class Show { } Show::setNextPop($next_date, $show_id, $day); + RabbitMq::PushSchedule(); } - private static function populateShow($repeat_type, $show_id, $next_pop_date, + private static function populateShow($repeat_type, $show_id, $next_pop_date, $first_show, $last_show, $start_time, $duration, $day, $record, $end_timestamp) { if($repeat_type == -1) { Show::populateNonRepeatingShow($show_id, $first_show, $start_time, $duration, $day, $record, $end_timestamp); } else if($repeat_type == 0) { - Show::populateRepeatingShow($show_id, $next_pop_date, $first_show, $last_show, + Show::populateRepeatingShow($show_id, $next_pop_date, $first_show, $last_show, $start_time, $duration, $day, $record, $end_timestamp, '7 days'); } else if($repeat_type == 1) { - Show::populateRepeatingShow($show_id, $next_pop_date, $first_show, $last_show, + Show::populateRepeatingShow($show_id, $next_pop_date, $first_show, $last_show, $start_time, $duration, $day, $record, $end_timestamp, '14 days'); } else if($repeat_type == 2) { - Show::populateRepeatingShow($show_id, $next_pop_date, $first_show, $last_show, + Show::populateRepeatingShow($show_id, $next_pop_date, $first_show, $last_show, $start_time, $duration, $day, $record, $end_timestamp, '1 month'); } - } + } //used to catch up a newly added show private static function populateShowUntilLastGeneratedDate($show_id) { global $CC_DBC; $showsPopUntil = Application_Model_Preference::GetShowsPopulatedUntil(); - + $sql = "SELECT * FROM cc_show_days WHERE show_id = {$show_id}"; - $res = $CC_DBC->GetAll($sql); + $res = $CC_DBC->GetAll($sql); foreach($res as $row) { - Show::populateShow($row["repeat_type"], $row["show_id"], $row["next_pop_date"], $row["first_show"], - $row["last_show"], $row["start_time"], $row["duration"], $row["day"], $row["record"], $showsPopUntil); - } + Show::populateShow($row["repeat_type"], $row["show_id"], $row["next_pop_date"], $row["first_show"], + $row["last_show"], $row["start_time"], $row["duration"], $row["day"], $row["record"], $showsPopUntil); + } } public static function populateShowsUntil($pop_timestamp, $end_timestamp) { global $CC_DBC; if($pop_timestamp != "") { - $sql = "SELECT * FROM cc_show_days - WHERE last_show IS NULL + $sql = "SELECT * FROM cc_show_days + WHERE last_show IS NULL OR first_show < '{$end_timestamp}' AND last_show > '{$pop_timestamp}'"; } else { $today_timestamp = date("Y-m-d"); - $sql = "SELECT * FROM cc_show_days - WHERE last_show IS NULL + $sql = "SELECT * FROM cc_show_days + WHERE last_show IS NULL OR first_show < '{$end_timestamp}' AND last_show > '{$today_timestamp}'"; } - $res = $CC_DBC->GetAll($sql); + $res = $CC_DBC->GetAll($sql); foreach($res as $row) { - Show::populateShow($row["repeat_type"], $row["show_id"], $row["next_pop_date"], $row["first_show"], - $row["last_show"], $row["start_time"], $row["duration"], $row["day"], $row["record"], $end_timestamp); - } + Show::populateShow($row["repeat_type"], $row["show_id"], $row["next_pop_date"], $row["first_show"], + $row["last_show"], $row["start_time"], $row["duration"], $row["day"], $row["record"], $end_timestamp); + } } public static function getFullCalendarEvents($start, $end, $editable=false) { @@ -460,7 +469,7 @@ class Show { private static function makeFullCalendarEvent($show, $options=array()) { global $CC_DBC; - + $event = array(); if($show["rebroadcast"]) { @@ -500,56 +509,68 @@ class ShowInstance { public function __construct($instanceId) { - $this->_instanceId = $instanceId; + $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(); + ->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; @@ -572,7 +595,7 @@ class ShowInstance { $mins = abs($deltaMin%60); $starts = $this->getShowStart(); - $ends = $this->getShowEnd(); + $ends = $this->getShowEnd(); $sql = "SELECT timestamp '{$starts}' + interval '{$deltaDay} days' + interval '{$hours}:{$mins}'"; $new_starts = $CC_DBC->GetOne($sql); @@ -595,18 +618,20 @@ class ShowInstance { if($rebroadcast) { $sql = "SELECT timestamp '{$new_starts}' < (SELECT starts FROM cc_show_instances WHERE id = {$rebroadcast})"; $isBeforeRecordedOriginal = $CC_DBC->GetOne($sql); - + if($isBeforeRecordedOriginal === 't'){ return "Cannot move a rebroadcast show before its original"; } } - + $this->moveScheduledShowContent($deltaDay, $hours, $mins); $this->setShowStart($new_starts); - $this->setShowEnd($new_ends); + $this->setShowEnd($new_ends); + RabbitMq::PushSchedule(); } - public function resizeShow($deltaDay, $deltaMin){ + public function resizeShow($deltaDay, $deltaMin) + { global $CC_DBC; $hours = $deltaMin/60; @@ -618,7 +643,7 @@ class ShowInstance { $mins = abs($deltaMin%60); $starts = $this->getShowStart(); - $ends = $this->getShowEnd(); + $ends = $this->getShowEnd(); $sql = "SELECT timestamp '{$ends}' + interval '{$deltaDay} days' + interval '{$hours}:{$mins}'"; $new_ends = $CC_DBC->GetOne($sql); @@ -639,114 +664,142 @@ class ShowInstance { WHERE rebroadcast = 1 AND instance_id = {$this->_instanceId}"; $CC_DBC->query($sql); } - + $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); - + $res = $CC_DBC->GetOne($sql); return $res; } - public function addPlaylistToShow($plId) { - + public function addPlaylistToShow($plId) + { $sched = new ScheduleGroup(); $lastGroupId = $this->getLastGroupId(); - + if(is_null($lastGroupId)) { - $groupId = $sched->add($this->_instanceId, $this->getShowStart(), null, $plId); + $groupId = $sched->add($this->_instanceId, $this->getShowStart(), null, $plId); } else { $groupId = $sched->addPlaylistAfter($this->_instanceId, $lastGroupId, $plId); } + RabbitMq::PushSchedule(); } + public function addFileToShow($file_id) + { + $sched = new ScheduleGroup(); + $lastGroupId = $this->getLastGroupId(); + + if(is_null($lastGroupId)) { + + $groupId = $sched->add($this->_instanceId, $this->getShowStart(), $file_id); + } + else { + $groupId = $sched->addFileAfter($this->_instanceId, $lastGroupId, $file_id); + } + RabbitMq::PushSchedule(); + } + public function scheduleShow($plIds) { - + foreach($plIds as $plId) { $this->addPlaylistToShow($plId); } } - 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 - FROM cc_schedule + FROM cc_schedule WHERE group_id = '{$group_id}'"; - + $groupBoundry = $CC_DBC->GetRow($sql); $group = CcScheduleQuery::create() ->filterByDbGroupId($group_id) ->delete(); - $sql = "UPDATE cc_schedule - SET starts = (starts - INTERVAL '{$groupBoundry["length"]}'), ends = (ends - INTERVAL '{$groupBoundry["length"]}') + $sql = "UPDATE cc_schedule + SET starts = (starts - INTERVAL '{$groupBoundry["length"]}'), ends = (ends - INTERVAL '{$groupBoundry["length"]}') 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) - ->save(); + ->save(); + + $rebroadcasts = CcShowInstancesQuery::create() + ->filterByDbOriginalShow($this->_instanceId) + ->find(); + + foreach ($rebroadcasts as $rebroadcast) { + + $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() { - - $start_timestamp = $this->getShowStart(); + 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() { - - $start_timestamp = $this->getShowStart(); + 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(); + $start_timestamp = $this->getShowStart(); $end_timestamp = $this->getShowEnd(); $sql = "SELECT TIMESTAMP '{$end_timestamp}' - TIMESTAMP '{$start_timestamp}' "; @@ -755,26 +808,27 @@ 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 * + $sql = "SELECT * FROM (cc_schedule AS s LEFT JOIN cc_files AS f ON f.id = s.file_id LEFT JOIN cc_playlist AS p ON p.id = s.playlist_id ) WHERE s.instance_id = '{$this->_instanceId}' ORDER BY starts"; - return $CC_DBC->GetAll($sql); + return $CC_DBC->GetAll($sql); } - public function getShowContent() { + public function getShowContent() + { global $CC_DBC; $res = $this->getShowListContent(); @@ -796,7 +850,7 @@ class ShowInstance { $items[$pl_counter]["pl_name"] = $row["name"]; $items[$pl_counter]["pl_creator"] = $row["creator"]; $items[$pl_counter]["pl_description"] = $row["description"]; - $items[$pl_counter]["pl_group"] = $row["group_id"]; + $items[$pl_counter]["pl_group"] = $row["group_id"]; $sql = "SELECT SUM(clip_length) FROM cc_schedule WHERE group_id = '{$currGroupId}'"; $length = $CC_DBC->GetOne($sql); @@ -810,33 +864,35 @@ class ShowInstance { $items[$pl_counter]["pl_content"][$f_counter]["f_length"] = $row["length"]; } - return $items; + return $items; } } /* Show Data Access Layer */ -class Show_DAL{ - - public static function GetCurrentShow($timeNow) { +class Show_DAL { + + public static function GetCurrentShow($timeNow) + { global $CC_CONFIG, $CC_DBC; - + $timestamp = explode(" ", $timeNow); $date = $timestamp[0]; $time = $timestamp[1]; - + $sql = "SELECT si.starts as start_timestamp, si.ends as end_timestamp, s.name, s.id, si.id as instance_id, si.record" ." FROM $CC_CONFIG[showInstances] si, $CC_CONFIG[showTable] s" ." WHERE si.show_id = s.id" ." AND si.starts <= TIMESTAMP '$timeNow'" ." AND si.ends > TIMESTAMP '$timeNow'"; - + $rows = $CC_DBC->GetAll($sql); 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 " ." $CC_CONFIG[showInstances] si, $CC_CONFIG[showTable] s" ." WHERE si.show_id = s.id" @@ -844,12 +900,13 @@ class Show_DAL{ ." AND si.starts < TIMESTAMP '$timeNow' + INTERVAL '48 hours'" ." ORDER BY si.starts" ." LIMIT 1"; - + $rows = $CC_DBC->GetAll($sql); 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," @@ -881,5 +938,5 @@ class Show_DAL{ return $CC_DBC->GetAll($sql); } - + } diff --git a/application/models/airtime/map/CcScheduleTableMap.php b/application/models/airtime/map/CcScheduleTableMap.php index 3f2502f1c..92afaab0c 100644 --- a/application/models/airtime/map/CcScheduleTableMap.php +++ b/application/models/airtime/map/CcScheduleTableMap.php @@ -39,7 +39,7 @@ class CcScheduleTableMap extends TableMap { $this->setPrimaryKeyMethodInfo('cc_schedule_id_seq'); // columns $this->addPrimaryKey('ID', 'DbId', 'INTEGER', true, null, null); - $this->addColumn('PLAYLIST_ID', 'DbPlaylistId', 'INTEGER', true, null, null); + $this->addColumn('PLAYLIST_ID', 'DbPlaylistId', 'INTEGER', false, null, null); $this->addColumn('STARTS', 'DbStarts', 'TIMESTAMP', true, null, null); $this->addColumn('ENDS', 'DbEnds', 'TIMESTAMP', true, null, null); $this->addColumn('GROUP_ID', 'DbGroupId', 'INTEGER', false, null, null); diff --git a/build/schema.xml b/build/schema.xml index 36941da37..f00ad14fb 100644 --- a/build/schema.xml +++ b/build/schema.xml @@ -234,7 +234,7 @@ - + diff --git a/build/sql/schema.sql b/build/sql/schema.sql index ee2f9b109..71ff970ef 100644 --- a/build/sql/schema.sql +++ b/build/sql/schema.sql @@ -345,7 +345,7 @@ DROP TABLE "cc_schedule" CASCADE; CREATE TABLE "cc_schedule" ( "id" serial NOT NULL, - "playlist_id" INTEGER NOT NULL, + "playlist_id" INTEGER, "starts" TIMESTAMP NOT NULL, "ends" TIMESTAMP NOT NULL, "group_id" INTEGER, diff --git a/pypo/api_clients/api_client_factory.py b/pypo/api_clients/api_client_factory.py deleted file mode 100644 index 4762b0fc7..000000000 --- a/pypo/api_clients/api_client_factory.py +++ /dev/null @@ -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) - diff --git a/pypo/pypo-cli.py b/pypo/pypo-cli.py index ca630f618..208049d7b 100755 --- a/pypo/pypo-cli.py +++ b/pypo/pypo-cli.py @@ -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()