Merge branch 'devel' of dev.sourcefabric.org:airtime into devel

This commit is contained in:
Paul Baranowski 2012-05-30 13:59:34 -04:00
commit 4fec2d3982
81 changed files with 676 additions and 292 deletions

30
CREDITS
View File

@ -1,3 +1,33 @@
=======
CREDITS
=======
Version 2.1.0
-------------
Martin Konecny (martin.konecny@sourcefabric.org)
Role: Developer Team Lead
Naomi Aro (naomi.aro@sourcefabric.org)
Role: Software Developer
James Moon (james.moon@sourcefabric.org)
Role: Software Developer
Denise Rigato (denise.rigato@sourcefabric.org)
Role: Software Developer
Cliff Wang (cliff.wang@sourcefabric.org)
Role: QA
Mikayel Karapetian (michael.karapetian@sourcefabric.org)
Role: QA
Daniel James (daniel.james@sourcefabric.org)
Role: Documentor & QA
Paul Baranowski (paul.baranowski@sourcefabric.org)
Role: Project Manager
=======
CREDITS
=======

View File

@ -89,9 +89,8 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
$userType = "";
}
$view->headScript()->appendScript("var userType = '$userType';");
if (Application_Model_Preference::GetPlanLevel() != "disabled"
&& ($_SERVER['REQUEST_URI'] != '/Dashboard/stream-player' || $_SERVER['REQUEST_URI'] != '/audiopreview/audio-preview-player')) {
&& !($_SERVER['REQUEST_URI'] == '/Dashboard/stream-player' || $_SERVER['REQUEST_URI'] == '/audiopreview/audio-preview-player')) {
$client_id = Application_Model_Preference::GetClientId();
$view->headScript()->appendScript("var livechat_client_id = '$client_id';");
$view->headScript()->appendFile($baseUrl . '/js/airtime/common/livechat.js?'.$CC_CONFIG['airtime_version'], 'text/javascript');

View File

@ -34,11 +34,11 @@ $ccAcl->allow('G', 'index')
->allow('G', 'api')
->allow('G', 'schedule')
->allow('G', 'dashboard')
->allow('G', 'audiopreview')
->allow('H', 'usersettings')
->allow('H', 'plupload')
->allow('H', 'library')
->allow('H', 'playlist')
->allow('H', 'audiopreview')
->allow('A', 'playouthistory')
->allow('A', 'user')
->allow('A', 'systemstatus')

View File

@ -6,7 +6,7 @@ class PreferenceController extends Zend_Controller_Action
public function init()
{
/* Initialize action controller here */
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('server-browse', 'json')
->addActionContext('change-stor-directory', 'json')
->addActionContext('reload-watch-directory', 'json')
@ -143,6 +143,8 @@ class PreferenceController extends Zend_Controller_Action
$baseUrl = $request->getBaseUrl();
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/preferences/streamsetting.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
$isSaas = Application_Model_Preference::GetPlanLevel() == 'disabled'?false:true;
// get current settings
$temp = Application_Model_StreamSetting::getStreamSetting();
@ -197,13 +199,12 @@ class PreferenceController extends Zend_Controller_Action
$values = $post_data;
if($form->isValid($post_data)){
if(Application_Model_Preference::GetPlanLevel() == 'disabled'){
if (!$isSaas) {
$values['output_sound_device'] = $form->getValue('output_sound_device');
$values['output_sound_device_type'] = $form->getValue('output_sound_device_type');
}
$values['icecast_vorbis_metadata'] = $form->getValue('icecast_vorbis_metadata');
$values['output_sound_device_type'] = $form->getValue('output_sound_device_type');
$values['streamFormat'] = $form->getValue('streamFormat');
Application_Model_StreamSetting::setStreamSetting($values);
@ -214,17 +215,19 @@ class PreferenceController extends Zend_Controller_Action
Application_Model_Preference::SetLiveSteamMasterPassword($values["master_password"]);
Application_Model_Preference::SetDefaultTransitionFade($values["transition_fade"]);
$master_connection_url = "http://".$_SERVER['SERVER_NAME'].":".$values["master_harbor_input_port"]."/".$values["master_harbor_input_mount_point"];
$live_connection_url = "http://".$_SERVER['SERVER_NAME'].":".$values["dj_harbor_input_port"]."/".$values["dj_harbor_input_mount_point"];
if (!$isSaas) {
$master_connection_url = "http://".$_SERVER['SERVER_NAME'].":".$values["master_harbor_input_port"]."/".$values["master_harbor_input_mount_point"];
$live_connection_url = "http://".$_SERVER['SERVER_NAME'].":".$values["dj_harbor_input_port"]."/".$values["dj_harbor_input_mount_point"];
Application_Model_Preference::SetMasterDJSourceConnectionURL($master_connection_url);
Application_Model_Preference::SetLiveDJSourceConnectionURL($live_connection_url);
Application_Model_Preference::SetMasterDJSourceConnectionURL($master_connection_url);
Application_Model_Preference::SetLiveDJSourceConnectionURL($live_connection_url);
// extra info that goes into cc_stream_setting
Application_Model_StreamSetting::SetMasterLiveSteamPort($values["master_harbor_input_port"]);
Application_Model_StreamSetting::SetMasterLiveSteamMountPoint($values["master_harbor_input_mount_point"]);
Application_Model_StreamSetting::SetDJLiveSteamPort($values["dj_harbor_input_port"]);
Application_Model_StreamSetting::SetDJLiveSteamMountPoint($values["dj_harbor_input_mount_point"]);
// extra info that goes into cc_stream_setting
Application_Model_StreamSetting::SetMasterLiveSteamPort($values["master_harbor_input_port"]);
Application_Model_StreamSetting::SetMasterLiveSteamMountPoint($values["master_harbor_input_mount_point"]);
Application_Model_StreamSetting::SetDJLiveSteamPort($values["dj_harbor_input_port"]);
Application_Model_StreamSetting::SetDJLiveSteamMountPoint($values["dj_harbor_input_mount_point"]);
}
// store stream update timestamp
Application_Model_Preference::SetStreamUpdateTimestamp();

View File

@ -272,47 +272,25 @@ class ScheduleController extends Zend_Controller_Action
}
if ($showStartLocalDT->getTimestamp() <= $epochNow &&
$epochNow < $showEndLocalDT->getTimestamp() &&
($isAdminOrPM || $isDJ)) {
$epochNow < $showEndLocalDT->getTimestamp() && $isAdminOrPM) {
if ($instance->isRecorded()) {
if($isAdminOrPM){
$menu["cancel_recorded"] = array("name"=> "Cancel Current Show", "icon" => "delete");
}
} else {
if($instance->isRepeating()){
/*$menu["edit"] = array("name"=> "Edit", "icon" => "edit", "items" => array());
$menu["edit"]["items"]["instance"] = array("name"=> "Edit Show Instance", "icon" => "edit", "url" => "/Schedule/populate-show-instance-form");
$menu["edit"]["items"]["all"] = array("name"=> "Edit Show", "icon" => "edit", "url" => "/Schedule/populate-show-form");*/
$menu["cancel_recorded"] = array("name"=> "Cancel Current Show", "icon" => "delete");
}
else {
if (!$instance->isRebroadcast()) {
$menu["edit"] = array("name"=> "Edit Show", "icon" => "edit", "_type"=>"all", "url" => "/Schedule/populate-show-form");
}else{
if($instance->isRebroadcast()){
$menu["edit"] = array("name"=> "Edit Show", "icon" => "edit", "_type"=>"rebroadcast", "url" => "/Schedule/populate-show-form");
}else{
$menu["edit"] = array("name"=> "Edit Show", "icon" => "edit", "_type"=>"all", "url" => "/Schedule/populate-show-form");
}
}
if($isAdminOrPM){
$menu["cancel"] = array("name"=> "Cancel Current Show", "icon" => "delete");
}
$menu["cancel"] = array("name"=> "Cancel Current Show", "icon" => "delete");
}
}
if ($epochNow < $showStartLocalDT->getTimestamp()) {
if ($isAdminOrPM || $isDJ) {
if($instance->isRepeating()){
/*$menu["edit"] = array("name"=> "Edit", "icon" => "edit", "items" => array());
$menu["edit"]["items"]["instance"] = array("name"=> "Edit Show Instance", "icon" => "edit", "url" => "/Schedule/populate-show-instance-form");
$menu["edit"]["items"]["all"] = array("name"=> "Edit Show", "icon" => "edit", "url" => "/Schedule/populate-show-form");*/
if (!$instance->isRebroadcast() && $isAdminOrPM) {
$menu["edit"] = array("name"=> "Edit Show", "icon" => "edit", "_type"=>"all", "url" => "/Schedule/populate-show-form");
}else{
if($instance->isRebroadcast()){
$menu["edit"] = array("name"=> "Edit Show", "icon" => "edit", "_type"=>"rebroadcast", "url" => "/Schedule/populate-show-form");
}else{
$menu["edit"] = array("name"=> "Edit Show", "icon" => "edit", "_type"=>"all", "url" => "/Schedule/populate-show-form");
}
}
if ($instance->getShow()->isRepeating() && $isAdminOrPM) {
@ -324,11 +302,10 @@ class ScheduleController extends Zend_Controller_Action
$menu["del"]["items"]["following"] = array("name"=> "Delete This Instance and All Following", "icon" => "delete", "url" => "/schedule/cancel-show");
}
else if($isAdminOrPM){
//window["scheduleRefetchEvents"]'
$menu["del"] = array("name"=> "Delete", "icon" => "delete", "url" => "/schedule/delete-show");
else if ($isAdminOrPM){
$menu["del"] = array("name"=> "Delete", "icon" => "delete", "url" => "/schedule/delete-show");
}
}
}
$this->view->items = $menu;

View File

@ -22,6 +22,10 @@ class ShowbuilderController extends Zend_Controller_Action
$request = $this->getRequest();
$baseUrl = $request->getBaseUrl();
$user = Application_Model_User::GetCurrentUser();
$userType = $user->getType();
$this->view->headScript()->appendScript("localStorage.setItem( 'user-type', '$userType' );");
$data = Application_Model_Preference::GetValue("library_datatable", true);
if ($data != "") {
@ -60,8 +64,7 @@ class ShowbuilderController extends Zend_Controller_Action
$this->view->headLink()->appendStylesheet($baseUrl.'/css/datatables/css/ColReorder.css?'.$CC_CONFIG['airtime_version']);
$this->view->headScript()->appendFile($this->view->baseUrl('/js/airtime/library/events/library_showbuilder.js?'.$CC_CONFIG['airtime_version']),'text/javascript');
$user = Application_Model_User::GetCurrentUser();
$refer_sses = new Zend_Session_Namespace('referrer');
if ($request->isPost()) {

View File

@ -14,7 +14,7 @@ class Application_Form_AddShowLiveStream extends Zend_Form_SubForm
->setDecorators(array('ViewHelper'));
$this->addElement($cb_airtime_auth);
$description2 = "Specify custom authentication which will work for only for this show.";
$description2 = "Specify custom authentication which will work only for this show.";
$cb_custom_auth = new Zend_Form_Element_Checkbox("cb_custom_auth");
$cb_custom_auth ->setLabel("Use Custom Authentication:")
->setDescription($description2)

View File

@ -2,9 +2,10 @@
class Application_Form_LiveStreamingPreferences extends Zend_Form_SubForm
{
public function init()
{
$isSaas = Application_Model_Preference::GetPlanLevel() == 'disabled'?false:true;
$defaultFade = Application_Model_Preference::GetDefaultTransitionFade();
if($defaultFade == ""){
$defaultFade = '00.000000';
@ -42,42 +43,44 @@ class Application_Form_LiveStreamingPreferences extends Zend_Form_SubForm
$this->addElement($master_password);
//liquidsoap harbor.input port
$m_port = Application_Model_StreamSetting::GetMasterLiveSteamPort();
$master_dj_port = new Zend_Form_Element_Text('master_harbor_input_port');
$master_dj_port->setLabel("Master Source Port")
->setValue($m_port)
->setValidators(array(new Zend_Validate_Between(array('min'=>1024, 'max'=>49151))))
->addValidator('regex', false, array('pattern'=>'/^[0-9]+$/', 'messages'=>array('regexNotMatch'=>'Only numbers are allowed.')))
->setDecorators(array('ViewHelper'));
$this->addElement($master_dj_port);
$m_mount = Application_Model_StreamSetting::GetMasterLiveSteamMountPoint();
$master_dj_mount = new Zend_Form_Element_Text('master_harbor_input_mount_point');
$master_dj_mount->setLabel("Master Source Mount Point")
->setValue($m_mount)
->setValidators(array(
array('regex', false, array('/^[^ &<>]+$/', 'messages' => 'Invalid character entered'))))
->setDecorators(array('ViewHelper'));
$this->addElement($master_dj_mount);
//liquidsoap harbor.input port
$l_port = Application_Model_StreamSetting::GetDJLiveSteamPort();
$live_dj_port = new Zend_Form_Element_Text('dj_harbor_input_port');
$live_dj_port->setLabel("Show Source Port")
->setValue($l_port)
->setValidators(array(new Zend_Validate_Between(array('min'=>1024, 'max'=>49151))))
->addValidator('regex', false, array('pattern'=>'/^[0-9]+$/', 'messages'=>array('regexNotMatch'=>'Only numbers are allowed.')))
->setDecorators(array('ViewHelper'));
$this->addElement($live_dj_port);
$l_mount = Application_Model_StreamSetting::GetDJLiveSteamMountPoint();
$live_dj_mount = new Zend_Form_Element_Text('dj_harbor_input_mount_point');
$live_dj_mount->setLabel("Show Source Mount Point")
->setValue($l_mount)
->setValidators(array(
array('regex', false, array('/^[^ &<>]+$/', 'messages' => 'Invalid character entered'))))
->setDecorators(array('ViewHelper'));
$this->addElement($live_dj_mount);
if (!$isSaas) {
$m_port = Application_Model_StreamSetting::GetMasterLiveSteamPort();
$master_dj_port = new Zend_Form_Element_Text('master_harbor_input_port');
$master_dj_port->setLabel("Master Source Port")
->setValue($m_port)
->setValidators(array(new Zend_Validate_Between(array('min'=>1024, 'max'=>49151))))
->addValidator('regex', false, array('pattern'=>'/^[0-9]+$/', 'messages'=>array('regexNotMatch'=>'Only numbers are allowed.')))
->setDecorators(array('ViewHelper'));
$this->addElement($master_dj_port);
$m_mount = Application_Model_StreamSetting::GetMasterLiveSteamMountPoint();
$master_dj_mount = new Zend_Form_Element_Text('master_harbor_input_mount_point');
$master_dj_mount->setLabel("Master Source Mount Point")
->setValue($m_mount)
->setValidators(array(
array('regex', false, array('/^[^ &<>]+$/', 'messages' => 'Invalid character entered'))))
->setDecorators(array('ViewHelper'));
$this->addElement($master_dj_mount);
//liquidsoap harbor.input port
$l_port = Application_Model_StreamSetting::GetDJLiveSteamPort();
$live_dj_port = new Zend_Form_Element_Text('dj_harbor_input_port');
$live_dj_port->setLabel("Show Source Port")
->setValue($l_port)
->setValidators(array(new Zend_Validate_Between(array('min'=>1024, 'max'=>49151))))
->addValidator('regex', false, array('pattern'=>'/^[0-9]+$/', 'messages'=>array('regexNotMatch'=>'Only numbers are allowed.')))
->setDecorators(array('ViewHelper'));
$this->addElement($live_dj_port);
$l_mount = Application_Model_StreamSetting::GetDJLiveSteamMountPoint();
$live_dj_mount = new Zend_Form_Element_Text('dj_harbor_input_mount_point');
$live_dj_mount->setLabel("Show Source Mount Point")
->setValue($l_mount)
->setValidators(array(
array('regex', false, array('/^[^ &<>]+$/', 'messages' => 'Invalid character entered'))))
->setDecorators(array('ViewHelper'));
$this->addElement($live_dj_mount);
}
}
public function updateVariables(){
@ -106,45 +109,47 @@ class Application_Form_LiveStreamingPreferences extends Zend_Form_SubForm
}
public function isValid($data){
$isSaas = Application_Model_Preference::GetPlanLevel() == 'disabled'?false:true;
$isValid = parent::isValid($data);
$master_harbor_input_port = $data['master_harbor_input_port'];
$dj_harbor_input_port = $data['dj_harbor_input_port'];
if($master_harbor_input_port == $dj_harbor_input_port && $master_harbor_input_port != ""){
$element = $this->getElement("dj_harbor_input_port");
$element->addError("You cannot use same port as Master DJ port.");
}
if($master_harbor_input_port != ""){
if(is_numeric($master_harbor_input_port)){
if($master_harbor_input_port != Application_Model_StreamSetting::GetMasterLiveSteamPort()){
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$res = socket_bind($sock, 0, $master_harbor_input_port);
if(!$res){
$element = $this->getElement("master_harbor_input_port");
$element->addError("Port '$master_harbor_input_port' is not available.");
$isValid = false;
}
socket_close($sock);
}
}else{
$isValid = false;
if (!$isSaas) {
$master_harbor_input_port = $data['master_harbor_input_port'];
$dj_harbor_input_port = $data['dj_harbor_input_port'];
if($master_harbor_input_port == $dj_harbor_input_port && $master_harbor_input_port != ""){
$element = $this->getElement("dj_harbor_input_port");
$element->addError("You cannot use same port as Master DJ port.");
}
}
if($dj_harbor_input_port != ""){
if(is_numeric($dj_harbor_input_port)){
if($dj_harbor_input_port != Application_Model_StreamSetting::GetDJLiveSteamPort()){
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$res = socket_bind($sock, 0, $dj_harbor_input_port);
if(!$res){
$element = $this->getElement("dj_harbor_input_port");
$element->addError("Port '$dj_harbor_input_port' is not available.");
$isValid = false;
if($master_harbor_input_port != ""){
if(is_numeric($master_harbor_input_port)){
if($master_harbor_input_port != Application_Model_StreamSetting::GetMasterLiveSteamPort()){
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$res = socket_bind($sock, 0, $master_harbor_input_port);
if(!$res){
$element = $this->getElement("master_harbor_input_port");
$element->addError("Port '$master_harbor_input_port' is not available.");
$isValid = false;
}
socket_close($sock);
}
socket_close($sock);
}else{
$isValid = false;
}
}
if($dj_harbor_input_port != ""){
if(is_numeric($dj_harbor_input_port)){
if($dj_harbor_input_port != Application_Model_StreamSetting::GetDJLiveSteamPort()){
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$res = socket_bind($sock, 0, $dj_harbor_input_port);
if(!$res){
$element = $this->getElement("dj_harbor_input_port");
$element->addError("Port '$dj_harbor_input_port' is not available.");
$isValid = false;
}
socket_close($sock);
}
}else{
$isValid = false;
}
}else{
$isValid = false;
}
}
return $isValid;

View File

@ -237,8 +237,9 @@ class Application_Model_LiveLog
public static function SetNewLogTime($state, $dateTime){
try {
$con = Propel::getConnection();
if ($state == 'L') {
$scheduled = Application_Model_Preference::GetSourceSwitchStatus('scheduled_play');
if ($state == 'L' && $scheduled == 'on') {
self::SetEndTime('S', $dateTime);
}
@ -253,6 +254,10 @@ class Application_Model_LiveLog
$sql_insert = "INSERT INTO CC_LIVE_LOG (state, start_time)"
." VALUES ('$state', '{$dateTime->format("Y-m-d H:i:s")}')";
$con->exec($sql_insert);
if($state == "S"){
// if scheduled play source is getting broadcasted
Application_Model_Schedule::UpdateBrodcastedStatus($dateTime, 1);
}
}
} catch (Exception $e) {
@ -298,4 +303,4 @@ class Application_Model_LiveLog
}
}
}
}

View File

@ -66,7 +66,7 @@ class Application_Model_PlayoutHistory {
select count(schedule.file_id) as played, schedule.file_id as file_id
from cc_schedule as schedule
where schedule.starts >= '{$start}' and schedule.starts < '{$end}'
and schedule.playout_status > 0 and schedule.media_item_played != FALSE
and schedule.playout_status > 0 and schedule.media_item_played != FALSE and schedule.broadcasted = 1
group by schedule.file_id
)
AS playout left join cc_files as file on (file.id = playout.file_id)";

View File

@ -412,7 +412,13 @@ class Application_Model_Preference
$key == 'FREE_RAM' || $key == 'AIRTIME_VERSION' || $key == 'KERNAL_VERSION' ||
$key == 'MACHINE_ARCHITECTURE' || $key == 'TOTAL_MEMORY_MBYTES' || $key == 'TOTAL_SWAP_MBYTES' ||
$key == 'PLAYOUT_ENGINE_CPU_PERC' ) {
$systemInfoArray[$key] = $info[1];
if($key == 'AIRTIME_VERSION'){
// remove hash tag on the version string
$version = explode('+', $info[1]);
$systemInfoArray[$key] = $version[0];
}else{
$systemInfoArray[$key] = $info[1];
}
}
}
}
@ -481,6 +487,10 @@ class Application_Model_Preference
} else if (!$out) {
$outputString .= $key." : FALSE\n";
}
}else if ($key == "SAAS") {
if (strcmp($out, 'disabled')!=0) {
$outputString .= $key.' : '.$out."\n";
}
}else{
$outputString .= $key.' : '.$out."\n";
}

View File

@ -48,7 +48,8 @@ class Application_Model_Schedule {
$range = array("env"=>APPLICATION_ENV,
"schedulerTime"=>$timeNow,
"previous"=>$results['previous'] !=null?$results['previous']:(count($shows['previousShow'])>0?$shows['previousShow'][0]:null),
"current"=>$results['current'] !=null?$results['current']:(count($shows['currentShow'])>0?$shows['currentShow'][0]:null),
"current"=>$results['current'] !=null?$results['current']:((count($shows['currentShow'])>0 && $shows['currentShow'][0]['record'] == 1)?$shows['currentShow'][0]:null),
//"current"=>$results['current'] !=null?$results['current']:(count($shows['currentShow'])>0?$shows['currentShow'][0]:null),
"next"=> $results['next'] !=null?$results['next']:(count($shows['nextShow'])>0?$shows['nextShow'][0]:null),
"currentShow"=>$shows['currentShow'],
"nextShow"=>$shows['nextShow'],
@ -290,8 +291,30 @@ class Application_Model_Schedule {
global $CC_CONFIG;
$con = Propel::getConnection();
$sql = "UPDATE ".$CC_CONFIG['scheduleTable']
." SET media_item_played=TRUE"
." WHERE id=$p_id";
." SET media_item_played=TRUE";
// we need to update 'broadcasted' column as well
// check the current switch status
$live_dj = Application_Model_Preference::GetSourceSwitchStatus('live_dj') == 'on'?true:false;
$master_dj = Application_Model_Preference::GetSourceSwitchStatus('master_dj') == 'on'?true:false;
$scheduled_play = Application_Model_Preference::GetSourceSwitchStatus('scheduled_play') == 'on'?true:false;
if(!$live_dj && !$master_dj && $scheduled_play){
$sql .= ", broadcasted=1";
}
$sql .= " WHERE id=$p_id";
$retVal = $con->exec($sql);
return $retVal;
}
public static function UpdateBrodcastedStatus($dateTime, $value){
global $CC_CONFIG;
$con = Propel::getConnection();
$now = $dateTime->format("Y-m-d H:i:s");
$sql = "UPDATE ".$CC_CONFIG['scheduleTable']
." SET broadcasted=$value"
." WHERE starts <= '$now' AND ends >= '$now'";
$retVal = $con->exec($sql);
return $retVal;
}

View File

@ -848,7 +848,7 @@ class Application_Model_Show {
$showId = $this->getId();
$sql = "SELECT id FROM cc_show_instances"
." WHERE date(starts) = date(TIMESTAMP '$timestamp') "
." AND show_id = $showId";
." AND show_id = $showId AND rebroadcast = 0";
$query = $con->query($sql);
$row = ($query !== false) ? $query->fetchColumn(0) : null;
@ -1484,32 +1484,34 @@ class Application_Model_Show {
Application_Model_Preference::SetShowsPopulatedUntil($end_timestamp);
}
$sql = "SELECT starts, ends, record, rebroadcast, instance_id, show_id, name,
color, background_color, file_id, cc_show_instances.id AS instance_id,
created, last_scheduled, time_filled
FROM cc_show_instances
LEFT JOIN cc_show ON cc_show.id = cc_show_instances.show_id
WHERE cc_show_instances.modified_instance = FALSE";
$sql = "SELECT si1.starts AS starts, si1.ends AS ends, si1.record AS record, si1.rebroadcast AS rebroadcast, si2.starts AS parent_starts,
si1.instance_id AS record_id, si1.show_id AS show_id, show.name AS name,
show.color AS color, show.background_color AS background_color, si1.file_id AS file_id, si1.id AS instance_id,
si1.created AS created, si1.last_scheduled AS last_scheduled, si1.time_filled AS time_filled
FROM cc_show_instances AS si1
LEFT JOIN cc_show_instances AS si2 ON si1.instance_id = si2.id
LEFT JOIN cc_show AS show ON show.id = si1.show_id
WHERE si1.modified_instance = FALSE";
//only want shows that are starting at the time or later.
$start_string = $start_timestamp->format("Y-m-d H:i:s");
$end_string = $end_timestamp->format("Y-m-d H:i:s");
if ($onlyRecord) {
$sql = $sql." AND (starts >= '{$start_string}' AND starts < timestamp '{$end_string}')";
$sql = $sql." AND (record = 1)";
$sql = $sql." AND (si1.starts >= '{$start_string}' AND si1.starts < timestamp '{$end_string}')";
$sql = $sql." AND (si1.record = 1)";
}
else {
$sql = $sql." AND ((starts >= '{$start_string}' AND starts < '{$end_string}')
OR (ends > '{$start_string}' AND ends <= '{$end_string}')
OR (starts <= '{$start_string}' AND ends >= '{$end_string}'))";
$sql = $sql." AND ((si1.starts >= '{$start_string}' AND si1.starts < '{$end_string}')
OR (si1.ends > '{$start_string}' AND si1.ends <= '{$end_string}')
OR (si1.starts <= '{$start_string}' AND si1.ends >= '{$end_string}'))";
}
if (isset($excludeInstance)) {
foreach($excludeInstance as $instance) {
$sql_exclude[] = "cc_show_instances.id != {$instance}";
$sql_exclude[] = "si1.id != {$instance}";
}
$exclude = join(" OR ", $sql_exclude);
@ -1517,8 +1519,6 @@ class Application_Model_Show {
$sql = $sql." AND ({$exclude})";
}
//Logging::log("getShows");
//Logging::log($sql);
$result = $con->query($sql)->fetchAll();
return $result;
}
@ -1594,15 +1594,22 @@ class Application_Model_Show {
$options["percent"] = Application_Model_Show::getPercentScheduled($show["starts"], $show["ends"], $show["time_filled"]);
}
if (isset($show["parent_starts"])) {
$parentStartsDT = new DateTime($show["parent_starts"], new DateTimeZone("UTC"));
$parentStartsEpoch = intval($parentStartsDT->format("U"));
}
$startsDT = new DateTime($show["starts"], new DateTimeZone("UTC"));
$endsDT = new DateTime($show["ends"], new DateTimeZone("UTC"));
$startsEpoch = intval($startsDT->format("U"));
$endsEpoch = intval($endsDT->format("U"));
if ($p_editable && $show["record"] && $nowEpoch < $endsEpoch) {
if ($p_editable && $show["record"] && $nowEpoch > $startsEpoch) {
$options["editable"] = false;
}
else if ($p_editable && $show["rebroadcast"] && $nowEpoch > $parentStartsEpoch) {
$options["editable"] = false;
}
else if ($p_editable && $nowEpoch < $endsEpoch) {
$options["editable"] = true;
}
@ -1764,7 +1771,7 @@ class Application_Model_Show {
for( $i = 0; $i < $numberOfRows; ++$i ){
//Find the show that is within the current time.
if ((strtotime($rows[$i]['starts']) <= $timeNowAsMillis) && (strtotime($rows[$i]['ends']) >= $timeNowAsMillis)){
if ((strtotime($rows[$i]['starts']) <= $timeNowAsMillis) && (strtotime($rows[$i]['ends']) > $timeNowAsMillis)){
if ( $i - 1 >= 0){
$results['previousShow'][0] = array(
"id"=>$rows[$i-1]['id'],

View File

@ -59,6 +59,22 @@ class Application_Model_ShowBuilder {
$this->epoch_now = floatval(microtime(true));
$this->currentShow = false;
}
private function getUsersShows() {
$shows = array();
$host_shows = CcShowHostsQuery::create()
->setFormatter(ModelCriteria::FORMAT_ON_DEMAND)
->filterByDbHost($this->user->getId())
->find();
foreach ($host_shows as $host_show) {
$shows[] = $host_show->getDbShow();
}
return $shows;
}
//check to see if this row should be editable by the user.
private function isAllowed($p_item, &$row) {
@ -333,27 +349,43 @@ class Application_Model_ShowBuilder {
public function hasBeenUpdatedSince($timestamp, $instances) {
$outdated = false;
$shows = Application_Model_Show::getShows($this->startDT, $this->endDT);
if ($this->opts["showFilter"] !== 0) {
$include[] = $this->opts["showFilter"];
}
else if ($this->opts["myShows"] === 1) {
$include = $this->getUsersShows();
}
$currentInstances = array();
foreach ($shows as $show) {
$currentInstances[] = $show["instance_id"];
if (isset($show["last_scheduled"])) {
$dt = new DateTime($show["last_scheduled"], new DateTimeZone("UTC"));
}
else {
$dt = new DateTime($show["created"], new DateTimeZone("UTC"));
}
//check if any of the shows have a more recent timestamp.
if ($timestamp < intval($dt->format("U"))) {
$outdated = true;
break;
if (empty($include) || in_array($show["show_id"], $include)) {
$currentInstances[] = $show["instance_id"];
if (isset($show["last_scheduled"])) {
$dt = new DateTime($show["last_scheduled"], new DateTimeZone("UTC"));
}
else {
$dt = new DateTime($show["created"], new DateTimeZone("UTC"));
}
//check if any of the shows have a more recent timestamp.
$showTimeStamp = intval($dt->format("U"));
if ($timestamp < $showTimeStamp) {
Logging::debug("timestamp is {$timestamp} show timestamp is {$showTimeStamp}");
$outdated = true;
break;
}
}
}
//see if the displayed show instances have changed. (deleted, empty schedule etc)
if ($outdated === false && count($instances) !== count($currentInstances)) {
Logging::debug("show instances have changed.");
$outdated = true;
}
@ -368,14 +400,7 @@ class Application_Model_ShowBuilder {
$shows = array();
if ($this->opts["myShows"] === 1) {
$host_shows = CcShowHostsQuery::create()
->setFormatter(ModelCriteria::FORMAT_ON_DEMAND)
->filterByDbHost($this->user->getId())
->find();
foreach ($host_shows as $host_show) {
$shows[] = $host_show->getDbShow();
}
$shows = $this->getUsersShows();
}
else if ($this->opts["showFilter"] !== 0) {
$shows[] = $this->opts["showFilter"];

View File

@ -50,6 +50,7 @@ class CcScheduleTableMap extends TableMap {
$this->addColumn('MEDIA_ITEM_PLAYED', 'DbMediaItemPlayed', 'BOOLEAN', false, null, false);
$this->addForeignKey('INSTANCE_ID', 'DbInstanceId', 'INTEGER', 'cc_show_instances', 'ID', true, null, null);
$this->addColumn('PLAYOUT_STATUS', 'DbPlayoutStatus', 'SMALLINT', true, null, 1);
$this->addColumn('BROADCASTED', 'DbBroadcasted', 'SMALLINT', true, null, 0);
// validators
} // initialize()

View File

@ -103,6 +103,13 @@ abstract class BaseCcSchedule extends BaseObject implements Persistent
*/
protected $playout_status;
/**
* The value for the broadcasted field.
* Note: this column has a database default value of: 0
* @var int
*/
protected $broadcasted;
/**
* @var CcShowInstances
*/
@ -142,6 +149,7 @@ abstract class BaseCcSchedule extends BaseObject implements Persistent
$this->cue_out = '00:00:00';
$this->media_item_played = false;
$this->playout_status = 1;
$this->broadcasted = 0;
}
/**
@ -366,6 +374,16 @@ abstract class BaseCcSchedule extends BaseObject implements Persistent
return $this->playout_status;
}
/**
* Get the [broadcasted] column value.
*
* @return int
*/
public function getDbBroadcasted()
{
return $this->broadcasted;
}
/**
* Set the value of [id] column.
*
@ -732,6 +750,26 @@ abstract class BaseCcSchedule extends BaseObject implements Persistent
return $this;
} // setDbPlayoutStatus()
/**
* Set the value of [broadcasted] column.
*
* @param int $v new value
* @return CcSchedule The current object (for fluent API support)
*/
public function setDbBroadcasted($v)
{
if ($v !== null) {
$v = (int) $v;
}
if ($this->broadcasted !== $v || $this->isNew()) {
$this->broadcasted = $v;
$this->modifiedColumns[] = CcSchedulePeer::BROADCASTED;
}
return $this;
} // setDbBroadcasted()
/**
* Indicates whether the columns in this object are only set to default values.
*
@ -770,6 +808,10 @@ abstract class BaseCcSchedule extends BaseObject implements Persistent
return false;
}
if ($this->broadcasted !== 0) {
return false;
}
// otherwise, everything was equal, so return TRUE
return true;
} // hasOnlyDefaultValues()
@ -804,6 +846,7 @@ abstract class BaseCcSchedule extends BaseObject implements Persistent
$this->media_item_played = ($row[$startcol + 9] !== null) ? (boolean) $row[$startcol + 9] : null;
$this->instance_id = ($row[$startcol + 10] !== null) ? (int) $row[$startcol + 10] : null;
$this->playout_status = ($row[$startcol + 11] !== null) ? (int) $row[$startcol + 11] : null;
$this->broadcasted = ($row[$startcol + 12] !== null) ? (int) $row[$startcol + 12] : null;
$this->resetModified();
$this->setNew(false);
@ -812,7 +855,7 @@ abstract class BaseCcSchedule extends BaseObject implements Persistent
$this->ensureConsistency();
}
return $startcol + 12; // 12 = CcSchedulePeer::NUM_COLUMNS - CcSchedulePeer::NUM_LAZY_LOAD_COLUMNS).
return $startcol + 13; // 13 = CcSchedulePeer::NUM_COLUMNS - CcSchedulePeer::NUM_LAZY_LOAD_COLUMNS).
} catch (Exception $e) {
throw new PropelException("Error populating CcSchedule object", $e);
@ -1192,6 +1235,9 @@ abstract class BaseCcSchedule extends BaseObject implements Persistent
case 11:
return $this->getDbPlayoutStatus();
break;
case 12:
return $this->getDbBroadcasted();
break;
default:
return null;
break;
@ -1228,6 +1274,7 @@ abstract class BaseCcSchedule extends BaseObject implements Persistent
$keys[9] => $this->getDbMediaItemPlayed(),
$keys[10] => $this->getDbInstanceId(),
$keys[11] => $this->getDbPlayoutStatus(),
$keys[12] => $this->getDbBroadcasted(),
);
if ($includeForeignObjects) {
if (null !== $this->aCcShowInstances) {
@ -1303,6 +1350,9 @@ abstract class BaseCcSchedule extends BaseObject implements Persistent
case 11:
$this->setDbPlayoutStatus($value);
break;
case 12:
$this->setDbBroadcasted($value);
break;
} // switch()
}
@ -1339,6 +1389,7 @@ abstract class BaseCcSchedule extends BaseObject implements Persistent
if (array_key_exists($keys[9], $arr)) $this->setDbMediaItemPlayed($arr[$keys[9]]);
if (array_key_exists($keys[10], $arr)) $this->setDbInstanceId($arr[$keys[10]]);
if (array_key_exists($keys[11], $arr)) $this->setDbPlayoutStatus($arr[$keys[11]]);
if (array_key_exists($keys[12], $arr)) $this->setDbBroadcasted($arr[$keys[12]]);
}
/**
@ -1362,6 +1413,7 @@ abstract class BaseCcSchedule extends BaseObject implements Persistent
if ($this->isColumnModified(CcSchedulePeer::MEDIA_ITEM_PLAYED)) $criteria->add(CcSchedulePeer::MEDIA_ITEM_PLAYED, $this->media_item_played);
if ($this->isColumnModified(CcSchedulePeer::INSTANCE_ID)) $criteria->add(CcSchedulePeer::INSTANCE_ID, $this->instance_id);
if ($this->isColumnModified(CcSchedulePeer::PLAYOUT_STATUS)) $criteria->add(CcSchedulePeer::PLAYOUT_STATUS, $this->playout_status);
if ($this->isColumnModified(CcSchedulePeer::BROADCASTED)) $criteria->add(CcSchedulePeer::BROADCASTED, $this->broadcasted);
return $criteria;
}
@ -1434,6 +1486,7 @@ abstract class BaseCcSchedule extends BaseObject implements Persistent
$copyObj->setDbMediaItemPlayed($this->media_item_played);
$copyObj->setDbInstanceId($this->instance_id);
$copyObj->setDbPlayoutStatus($this->playout_status);
$copyObj->setDbBroadcasted($this->broadcasted);
$copyObj->setNew(true);
$copyObj->setDbId(NULL); // this is a auto-increment column, so set to default value
@ -1592,6 +1645,7 @@ abstract class BaseCcSchedule extends BaseObject implements Persistent
$this->media_item_played = null;
$this->instance_id = null;
$this->playout_status = null;
$this->broadcasted = null;
$this->alreadyInSave = false;
$this->alreadyInValidation = false;
$this->clearAllReferences();

View File

@ -26,7 +26,7 @@ abstract class BaseCcSchedulePeer {
const TM_CLASS = 'CcScheduleTableMap';
/** The total number of columns. */
const NUM_COLUMNS = 12;
const NUM_COLUMNS = 13;
/** The number of lazy-loaded columns. */
const NUM_LAZY_LOAD_COLUMNS = 0;
@ -67,6 +67,9 @@ abstract class BaseCcSchedulePeer {
/** the column name for the PLAYOUT_STATUS field */
const PLAYOUT_STATUS = 'cc_schedule.PLAYOUT_STATUS';
/** the column name for the BROADCASTED field */
const BROADCASTED = 'cc_schedule.BROADCASTED';
/**
* An identiy map to hold any loaded instances of CcSchedule objects.
* This must be public so that other peer classes can access this when hydrating from JOIN
@ -83,12 +86,12 @@ abstract class BaseCcSchedulePeer {
* e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id'
*/
private static $fieldNames = array (
BasePeer::TYPE_PHPNAME => array ('DbId', 'DbStarts', 'DbEnds', 'DbFileId', 'DbClipLength', 'DbFadeIn', 'DbFadeOut', 'DbCueIn', 'DbCueOut', 'DbMediaItemPlayed', 'DbInstanceId', 'DbPlayoutStatus', ),
BasePeer::TYPE_STUDLYPHPNAME => array ('dbId', 'dbStarts', 'dbEnds', 'dbFileId', 'dbClipLength', 'dbFadeIn', 'dbFadeOut', 'dbCueIn', 'dbCueOut', 'dbMediaItemPlayed', 'dbInstanceId', 'dbPlayoutStatus', ),
BasePeer::TYPE_COLNAME => array (self::ID, self::STARTS, self::ENDS, self::FILE_ID, self::CLIP_LENGTH, self::FADE_IN, self::FADE_OUT, self::CUE_IN, self::CUE_OUT, self::MEDIA_ITEM_PLAYED, self::INSTANCE_ID, self::PLAYOUT_STATUS, ),
BasePeer::TYPE_RAW_COLNAME => array ('ID', 'STARTS', 'ENDS', 'FILE_ID', 'CLIP_LENGTH', 'FADE_IN', 'FADE_OUT', 'CUE_IN', 'CUE_OUT', 'MEDIA_ITEM_PLAYED', 'INSTANCE_ID', 'PLAYOUT_STATUS', ),
BasePeer::TYPE_FIELDNAME => array ('id', 'starts', 'ends', 'file_id', 'clip_length', 'fade_in', 'fade_out', 'cue_in', 'cue_out', 'media_item_played', 'instance_id', 'playout_status', ),
BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, )
BasePeer::TYPE_PHPNAME => array ('DbId', 'DbStarts', 'DbEnds', 'DbFileId', 'DbClipLength', 'DbFadeIn', 'DbFadeOut', 'DbCueIn', 'DbCueOut', 'DbMediaItemPlayed', 'DbInstanceId', 'DbPlayoutStatus', 'DbBroadcasted', ),
BasePeer::TYPE_STUDLYPHPNAME => array ('dbId', 'dbStarts', 'dbEnds', 'dbFileId', 'dbClipLength', 'dbFadeIn', 'dbFadeOut', 'dbCueIn', 'dbCueOut', 'dbMediaItemPlayed', 'dbInstanceId', 'dbPlayoutStatus', 'dbBroadcasted', ),
BasePeer::TYPE_COLNAME => array (self::ID, self::STARTS, self::ENDS, self::FILE_ID, self::CLIP_LENGTH, self::FADE_IN, self::FADE_OUT, self::CUE_IN, self::CUE_OUT, self::MEDIA_ITEM_PLAYED, self::INSTANCE_ID, self::PLAYOUT_STATUS, self::BROADCASTED, ),
BasePeer::TYPE_RAW_COLNAME => array ('ID', 'STARTS', 'ENDS', 'FILE_ID', 'CLIP_LENGTH', 'FADE_IN', 'FADE_OUT', 'CUE_IN', 'CUE_OUT', 'MEDIA_ITEM_PLAYED', 'INSTANCE_ID', 'PLAYOUT_STATUS', 'BROADCASTED', ),
BasePeer::TYPE_FIELDNAME => array ('id', 'starts', 'ends', 'file_id', 'clip_length', 'fade_in', 'fade_out', 'cue_in', 'cue_out', 'media_item_played', 'instance_id', 'playout_status', 'broadcasted', ),
BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, )
);
/**
@ -98,12 +101,12 @@ abstract class BaseCcSchedulePeer {
* e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0
*/
private static $fieldKeys = array (
BasePeer::TYPE_PHPNAME => array ('DbId' => 0, 'DbStarts' => 1, 'DbEnds' => 2, 'DbFileId' => 3, 'DbClipLength' => 4, 'DbFadeIn' => 5, 'DbFadeOut' => 6, 'DbCueIn' => 7, 'DbCueOut' => 8, 'DbMediaItemPlayed' => 9, 'DbInstanceId' => 10, 'DbPlayoutStatus' => 11, ),
BasePeer::TYPE_STUDLYPHPNAME => array ('dbId' => 0, 'dbStarts' => 1, 'dbEnds' => 2, 'dbFileId' => 3, 'dbClipLength' => 4, 'dbFadeIn' => 5, 'dbFadeOut' => 6, 'dbCueIn' => 7, 'dbCueOut' => 8, 'dbMediaItemPlayed' => 9, 'dbInstanceId' => 10, 'dbPlayoutStatus' => 11, ),
BasePeer::TYPE_COLNAME => array (self::ID => 0, self::STARTS => 1, self::ENDS => 2, self::FILE_ID => 3, self::CLIP_LENGTH => 4, self::FADE_IN => 5, self::FADE_OUT => 6, self::CUE_IN => 7, self::CUE_OUT => 8, self::MEDIA_ITEM_PLAYED => 9, self::INSTANCE_ID => 10, self::PLAYOUT_STATUS => 11, ),
BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'STARTS' => 1, 'ENDS' => 2, 'FILE_ID' => 3, 'CLIP_LENGTH' => 4, 'FADE_IN' => 5, 'FADE_OUT' => 6, 'CUE_IN' => 7, 'CUE_OUT' => 8, 'MEDIA_ITEM_PLAYED' => 9, 'INSTANCE_ID' => 10, 'PLAYOUT_STATUS' => 11, ),
BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'starts' => 1, 'ends' => 2, 'file_id' => 3, 'clip_length' => 4, 'fade_in' => 5, 'fade_out' => 6, 'cue_in' => 7, 'cue_out' => 8, 'media_item_played' => 9, 'instance_id' => 10, 'playout_status' => 11, ),
BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, )
BasePeer::TYPE_PHPNAME => array ('DbId' => 0, 'DbStarts' => 1, 'DbEnds' => 2, 'DbFileId' => 3, 'DbClipLength' => 4, 'DbFadeIn' => 5, 'DbFadeOut' => 6, 'DbCueIn' => 7, 'DbCueOut' => 8, 'DbMediaItemPlayed' => 9, 'DbInstanceId' => 10, 'DbPlayoutStatus' => 11, 'DbBroadcasted' => 12, ),
BasePeer::TYPE_STUDLYPHPNAME => array ('dbId' => 0, 'dbStarts' => 1, 'dbEnds' => 2, 'dbFileId' => 3, 'dbClipLength' => 4, 'dbFadeIn' => 5, 'dbFadeOut' => 6, 'dbCueIn' => 7, 'dbCueOut' => 8, 'dbMediaItemPlayed' => 9, 'dbInstanceId' => 10, 'dbPlayoutStatus' => 11, 'dbBroadcasted' => 12, ),
BasePeer::TYPE_COLNAME => array (self::ID => 0, self::STARTS => 1, self::ENDS => 2, self::FILE_ID => 3, self::CLIP_LENGTH => 4, self::FADE_IN => 5, self::FADE_OUT => 6, self::CUE_IN => 7, self::CUE_OUT => 8, self::MEDIA_ITEM_PLAYED => 9, self::INSTANCE_ID => 10, self::PLAYOUT_STATUS => 11, self::BROADCASTED => 12, ),
BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'STARTS' => 1, 'ENDS' => 2, 'FILE_ID' => 3, 'CLIP_LENGTH' => 4, 'FADE_IN' => 5, 'FADE_OUT' => 6, 'CUE_IN' => 7, 'CUE_OUT' => 8, 'MEDIA_ITEM_PLAYED' => 9, 'INSTANCE_ID' => 10, 'PLAYOUT_STATUS' => 11, 'BROADCASTED' => 12, ),
BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'starts' => 1, 'ends' => 2, 'file_id' => 3, 'clip_length' => 4, 'fade_in' => 5, 'fade_out' => 6, 'cue_in' => 7, 'cue_out' => 8, 'media_item_played' => 9, 'instance_id' => 10, 'playout_status' => 11, 'broadcasted' => 12, ),
BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, )
);
/**
@ -187,6 +190,7 @@ abstract class BaseCcSchedulePeer {
$criteria->addSelectColumn(CcSchedulePeer::MEDIA_ITEM_PLAYED);
$criteria->addSelectColumn(CcSchedulePeer::INSTANCE_ID);
$criteria->addSelectColumn(CcSchedulePeer::PLAYOUT_STATUS);
$criteria->addSelectColumn(CcSchedulePeer::BROADCASTED);
} else {
$criteria->addSelectColumn($alias . '.ID');
$criteria->addSelectColumn($alias . '.STARTS');
@ -200,6 +204,7 @@ abstract class BaseCcSchedulePeer {
$criteria->addSelectColumn($alias . '.MEDIA_ITEM_PLAYED');
$criteria->addSelectColumn($alias . '.INSTANCE_ID');
$criteria->addSelectColumn($alias . '.PLAYOUT_STATUS');
$criteria->addSelectColumn($alias . '.BROADCASTED');
}
}

View File

@ -18,6 +18,7 @@
* @method CcScheduleQuery orderByDbMediaItemPlayed($order = Criteria::ASC) Order by the media_item_played column
* @method CcScheduleQuery orderByDbInstanceId($order = Criteria::ASC) Order by the instance_id column
* @method CcScheduleQuery orderByDbPlayoutStatus($order = Criteria::ASC) Order by the playout_status column
* @method CcScheduleQuery orderByDbBroadcasted($order = Criteria::ASC) Order by the broadcasted column
*
* @method CcScheduleQuery groupByDbId() Group by the id column
* @method CcScheduleQuery groupByDbStarts() Group by the starts column
@ -31,6 +32,7 @@
* @method CcScheduleQuery groupByDbMediaItemPlayed() Group by the media_item_played column
* @method CcScheduleQuery groupByDbInstanceId() Group by the instance_id column
* @method CcScheduleQuery groupByDbPlayoutStatus() Group by the playout_status column
* @method CcScheduleQuery groupByDbBroadcasted() Group by the broadcasted column
*
* @method CcScheduleQuery leftJoin($relation) Adds a LEFT JOIN clause to the query
* @method CcScheduleQuery rightJoin($relation) Adds a RIGHT JOIN clause to the query
@ -59,6 +61,7 @@
* @method CcSchedule findOneByDbMediaItemPlayed(boolean $media_item_played) Return the first CcSchedule filtered by the media_item_played column
* @method CcSchedule findOneByDbInstanceId(int $instance_id) Return the first CcSchedule filtered by the instance_id column
* @method CcSchedule findOneByDbPlayoutStatus(int $playout_status) Return the first CcSchedule filtered by the playout_status column
* @method CcSchedule findOneByDbBroadcasted(int $broadcasted) Return the first CcSchedule filtered by the broadcasted column
*
* @method array findByDbId(int $id) Return CcSchedule objects filtered by the id column
* @method array findByDbStarts(string $starts) Return CcSchedule objects filtered by the starts column
@ -72,6 +75,7 @@
* @method array findByDbMediaItemPlayed(boolean $media_item_played) Return CcSchedule objects filtered by the media_item_played column
* @method array findByDbInstanceId(int $instance_id) Return CcSchedule objects filtered by the instance_id column
* @method array findByDbPlayoutStatus(int $playout_status) Return CcSchedule objects filtered by the playout_status column
* @method array findByDbBroadcasted(int $broadcasted) Return CcSchedule objects filtered by the broadcasted column
*
* @package propel.generator.airtime.om
*/
@ -498,6 +502,37 @@ abstract class BaseCcScheduleQuery extends ModelCriteria
return $this->addUsingAlias(CcSchedulePeer::PLAYOUT_STATUS, $dbPlayoutStatus, $comparison);
}
/**
* Filter the query on the broadcasted column
*
* @param int|array $dbBroadcasted The value to use as filter.
* Accepts an associative array('min' => $minValue, 'max' => $maxValue)
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return CcScheduleQuery The current query, for fluid interface
*/
public function filterByDbBroadcasted($dbBroadcasted = null, $comparison = null)
{
if (is_array($dbBroadcasted)) {
$useMinMax = false;
if (isset($dbBroadcasted['min'])) {
$this->addUsingAlias(CcSchedulePeer::BROADCASTED, $dbBroadcasted['min'], Criteria::GREATER_EQUAL);
$useMinMax = true;
}
if (isset($dbBroadcasted['max'])) {
$this->addUsingAlias(CcSchedulePeer::BROADCASTED, $dbBroadcasted['max'], Criteria::LESS_EQUAL);
$useMinMax = true;
}
if ($useMinMax) {
return $this;
}
if (null === $comparison) {
$comparison = Criteria::IN;
}
}
return $this->addUsingAlias(CcSchedulePeer::BROADCASTED, $dbBroadcasted, $comparison);
}
/**
* Filter the query by a related CcShowInstances object
*

View File

@ -25,7 +25,7 @@
<a href="<?php echo $this->baseUrl('login/password-restore'); ?>" class="link reset">Reset password</a>
</dd>
<?php endif; ?>
<?php echo $this->element->getElement('captcha') ?>
<dt id="submit-label">&nbsp;</dt>
<dd id="submit-element">
<?php echo $this->element->getElement('submit') ?>

View File

@ -1,14 +1,9 @@
<div class="sb-timerange">
<div id="sb_edit" class="ui-button ui-state-default" title="open the library to schedule files.">
<span class="ui-icon ui-icon-arrowthick-1-nw"></span>
</div>
<?php echo $this->element->getElement('sb_date_start') ?>
<?php echo $this->element->getElement('sb_time_start') ?>
<?php echo $this->element->getElement('sb_date_end') ?>
<?php echo $this->element->getElement('sb_time_end') ?>
<div id="sb_submit" class="ui-button ui-state-default" title="Find Shows">
<span class="ui-icon ui-icon-search"></span>
</div>
<?php echo $this->element->getElement('sb_date_start'); ?>
<?php echo $this->element->getElement('sb_time_start'); ?>
<?php echo $this->element->getElement('sb_date_end'); ?>
<?php echo $this->element->getElement('sb_time_end'); ?>
<div id="sb_submit" class="ui-button ui-state-default" title="Find Shows">
<span class="ui-icon ui-icon-search"></span>
</div>
<div class="sb-advanced-options">
<fieldset class="padded display_field push-down-8 closed">

View File

@ -9,7 +9,14 @@
<?php endif; ?>
<div id="show_builder" class="sb-content ui-widget ui-widget-content block-shadow omega-block padded">
<div class="sb-timerange">
<?php if(!$this->disableLib && !$this->showLib):?>
<div id="sb_edit" class="ui-button ui-state-default" title="open the library to schedule files.">
<span class="ui-icon ui-icon-arrowthick-1-nw"></span>
</div>
<?php endif; ?>
<?php echo $this->sb_form; ?>
</div>
<table id="show_builder_table" cellpadding="0" cellspacing="0" class="datatable"></table>
</div>

View File

@ -281,6 +281,7 @@
<column name="media_item_played" phpName="DbMediaItemPlayed" type="BOOLEAN" required="false" defaultValue="0"/>
<column name="instance_id" phpName="DbInstanceId" type="INTEGER" required="true"/>
<column name="playout_status" phpName="DbPlayoutStatus" type="SMALLINT" required="true" defaultValue="1"/>
<column name="broadcasted" phpName="DbBroadcasted" type="SMALLINT" required="true" defaultValue="0"/>
<!-- This foreign key is still useful even though it may seem we don't ever delete cc_show_instances anymore.
We will do delete them in some cases (when editing a show and changing the repeating days of the week
for example. \

View File

@ -377,6 +377,7 @@ CREATE TABLE "cc_schedule"
"media_item_played" BOOLEAN default 'f',
"instance_id" INTEGER NOT NULL,
"playout_status" INT2 default 1 NOT NULL,
"broadcasted" INT2 default 0 NOT NULL,
PRIMARY KEY ("id")
);

0
airtime_mvc/public/css/TableTools.css Executable file → Normal file
View File

0
airtime_mvc/public/css/TableTools_JUI.css Executable file → Normal file
View File

0
airtime_mvc/public/css/datatables/css/TableTools.css Executable file → Normal file
View File

0
airtime_mvc/public/css/images/icon_copy.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 309 B

After

Width:  |  Height:  |  Size: 309 B

0
airtime_mvc/public/css/images/icon_cut.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 648 B

After

Width:  |  Height:  |  Size: 648 B

0
airtime_mvc/public/css/images/icon_delete.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 536 B

After

Width:  |  Height:  |  Size: 536 B

0
airtime_mvc/public/css/images/icon_door.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 412 B

After

Width:  |  Height:  |  Size: 412 B

0
airtime_mvc/public/css/images/icon_edit.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 618 B

After

Width:  |  Height:  |  Size: 618 B

0
airtime_mvc/public/css/images/icon_paste.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 620 B

After

Width:  |  Height:  |  Size: 620 B

0
airtime_mvc/public/css/jquery.contextMenu.css Executable file → Normal file
View File

View File

@ -96,12 +96,14 @@ div.sb-timerange div#sb_edit {
}
div.sb-timerange div#sb_submit {
position: absolute;
bottom: 0px;
padding: 3px;
margin-left: 5px;
}
div.sb-timerange input {
vertical-align: top;
}
div.sb-timerange input#sb_date_start {
margin-left: 30px;
}

View File

@ -108,11 +108,10 @@ select {
.info-tooltip {
cursor: help;
position: relative;
display:inline-block; zoom:1; display:inline;
display:inline-block; zoom:1;
width:14px; height:14px;
background:url(/css/images/icon_info.png) 0 0 no-repeat;
float:right; position:relative; top:4px; right:7px; left: 3px;
top:2px; right:7px; left: 3px;
line-height:16px !important;
}
.info-tooltip span {
@ -2420,7 +2419,7 @@ tfoot tr th {
height:38px;
display:block;
position:absolute;
right:20px;
left:20px;
bottom:10px;
background-color:#222;
background-color:rgba(0, 0, 0, 0.7);

View File

@ -76,7 +76,7 @@ function updateProgressBarValue(){
var scheduled_play_line_to_switch = scheduled_play_div.parent().find(".line-to-switch");
if (currentSong !== null){
var songElpasedTime = 0;
var songElapsedTime = 0;
songPercentDone = (estimatedSchedulePosixTime - currentSong.songStartPosixTime)/currentSong.songLengthMs*100;
songElapsedTime = estimatedSchedulePosixTime - currentSong.songStartPosixTime;
if (songPercentDone < 0 || songPercentDone > 100){
@ -239,11 +239,11 @@ function parseItems(obj){
if (nextSong !== null)
calcAdditionalData(nextSong);
currentShow = obj.currentShow;
nextShow = obj.nextShow;
calcAdditionalShowData(obj.currentShow);
calcAdditionalShowData(obj.nextShow);
currentShow = obj.currentShow;
nextShow = obj.nextShow;
var schedulePosixTime = convertDateToPosixTime(obj.schedulerTime);
//timezoneOffset = parseInt(obj.timezoneOffset)*1000;
@ -276,7 +276,7 @@ function parseSourceStatus(obj){
function parseSwitchStatus(obj){
if(obj.live_dj_source == "on" && obj.master_dj_source == "off"){
if(obj.live_dj_source == "on"){
live_dj_on_air = true;
}else{
live_dj_on_air = false;
@ -398,7 +398,6 @@ function setSwitchListener(ele){
var sourcename = $(ele).attr('id');
var status_span = $(ele).find("span");
var status = status_span.html();
$.get("/Dashboard/switch-source/format/json/sourcename/"+sourcename+"/status/"+status, function(data){
if(data.error){
alert(data.error);

View File

@ -48,14 +48,20 @@ var AIRTIME = (function(AIRTIME){
$('#library_display tr.lib-audio').draggable({
helper: function(){
var selected = mod.getChosenAudioFilesLength(),
var $el = $(this),
selected = mod.getChosenAudioFilesLength(),
container,
message,
li = $("#side_playlist ul li:first"),
width = li.width(),
height = li.height();
//dragging an element that has an unselected checkbox.
if (mod.isChosenItem($el) === false) {
selected++;
}
if (selected === 0 || selected === 1) {
if (selected === 1) {
message = "Adding 1 Item.";
}
else {

View File

@ -48,14 +48,20 @@ var AIRTIME = (function(AIRTIME){
$('#library_display tr.lib-audio, tr.lib-pl').draggable({
helper: function(){
var selected = mod.getChosenItemsLength(),
var $el = $(this),
selected = mod.getChosenItemsLength(),
container,
thead = $("#show_builder_table thead"),
colspan = thead.find("th").length,
width = thead.find("tr:first").width(),
message;
if (selected === 0 || selected === 1) {
//dragging an element that has an unselected checkbox.
if (mod.isChosenItem($el) === false) {
selected++;
}
if (selected === 1) {
message = "Adding 1 Item.";
}
else {

View File

@ -98,6 +98,13 @@ var AIRTIME = (function(AIRTIME) {
}
};
mod.isChosenItem = function($el) {
var id = $el.attr("id"),
item = chosenItems[id];
return item !== undefined ? true : false;
};
mod.addToChosen = function($el) {
var id = $el.attr("id");

View File

@ -1,6 +1,3 @@
$(window).load(function(){
$("#username").focus()
var captcha = $("#captcha-label").next()
captcha.css("padding-left", (((captcha.parents('div:eq(0)').width()-captcha.width())/2+"px")));
$("#username").focus();
})

View File

@ -2,6 +2,8 @@ var AIRTIME = (function(AIRTIME){
var mod,
oSchedTable,
SB_SELECTED_CLASS = "sb-selected",
CURSOR_SELECTED_CLASS = "cursor-selected-row",
NOW_PLAYING_CLASS = "sb-now-playing",
$sbContent,
$sbTable,
$toolbar,
@ -56,8 +58,19 @@ var AIRTIME = (function(AIRTIME){
oSchedTable.fnDraw();
};
mod.checkSelectButton = function() {
var $selectable = $sbTable.find("tbody").find("input:checkbox");
if ($selectable.length !== 0) {
AIRTIME.button.enableButton("sb-button-select");
}
else {
AIRTIME.button.disableButton("sb-button-select");
}
};
mod.checkTrimButton = function() {
var $over = $sbTable.find(".sb-over");
var $over = $sbTable.find(".sb-over.sb-allowed");
if ($over.length !== 0) {
AIRTIME.button.enableButton("sb-button-trim");
@ -79,7 +92,7 @@ var AIRTIME = (function(AIRTIME){
};
mod.checkJumpToCurrentButton = function() {
var $current = $sbTable.find(".sb-now-playing");
var $current = $sbTable.find("."+NOW_PLAYING_CLASS);
if ($current.length !== 0) {
AIRTIME.button.enableButton("sb-button-current");
@ -90,9 +103,12 @@ var AIRTIME = (function(AIRTIME){
};
mod.checkCancelButton = function() {
var $current = $sbTable.find(".sb-current-show");
var $current = $sbTable.find(".sb-current-show.sb-allowed"),
//this user type should be refactored into a separate users module later
//when there's more time and more JS will need to know user data.
userType = localStorage.getItem('user-type');
if ($current.length !== 0) {
if ($current.length !== 0 && (userType === 'A' || userType === 'P')) {
AIRTIME.button.enableButton("sb-button-cancel");
}
else {
@ -103,18 +119,38 @@ var AIRTIME = (function(AIRTIME){
mod.checkToolBarIcons = function() {
AIRTIME.library.checkAddButton();
mod.checkSelectButton();
mod.checkTrimButton();
mod.checkDeleteButton();
mod.checkJumpToCurrentButton();
mod.checkCancelButton();
};
mod.selectCursor = function($el) {
$el.addClass(CURSOR_SELECTED_CLASS);
mod.checkToolBarIcons();
};
mod.removeCursor = function($el) {
$el.removeClass(CURSOR_SELECTED_CLASS);
mod.checkToolBarIcons();
};
mod.getSelectedData = function() {
/*
* sNot is an optional string to filter selected elements by. (ex removing the currently playing item)
*/
mod.getSelectedData = function(sNot) {
var $selected = $sbTable.find("tbody").find("input:checkbox").filter(":checked").parents("tr"),
aData = [],
i, length,
$item;
if (sNot !== undefined) {
$selected = $selected.not("."+sNot);
}
for (i = 0, length = $selected.length; i < length; i++) {
$item = $($selected.get(i));
aData.push($item.data('aData'));
@ -513,7 +549,7 @@ var AIRTIME = (function(AIRTIME){
$nRow.data({"aData": aData});
if (aData.scheduled === 1) {
$nRow.addClass("sb-now-playing");
$nRow.addClass(NOW_PLAYING_CLASS);
}
else if (aData.scheduled === 0) {
$nRow.addClass("sb-past");
@ -618,7 +654,7 @@ var AIRTIME = (function(AIRTIME){
//order of importance of elements for setting the next timeout.
elements = [
$sbTable.find("tr.sb-now-playing"),
$sbTable.find("tr."+NOW_PLAYING_CLASS),
$sbTable.find("tbody").find("tr.sb-future.sb-footer, tr.sb-future.sb-header").filter(":first")
];
@ -776,7 +812,7 @@ var AIRTIME = (function(AIRTIME){
forcePlaceholderSize: true,
distance: 10,
helper: function(event, item) {
var selected = mod.getSelectedData(),
var selected = mod.getSelectedData(NOW_PLAYING_CLASS),
thead = $("#show_builder_table thead"),
colspan = thead.find("th").length,
trfirst = thead.find("tr:first"),
@ -816,7 +852,17 @@ var AIRTIME = (function(AIRTIME){
receive: fnReceive,
update: fnUpdate,
start: function(event, ui) {
var elements = $sbTable.find('tr:not(:first) input:checked').parents('tr');
/*
var elements = $sbTable.find('tr input:checked').parents('tr')
.not(ui.item)
.not("."+NOW_PLAYING_CLASS);
//remove all other items from the screen,
//don't remove ui.item or else we can not get position information when the user drops later.
elements.remove();
*/
var elements = $sbTable.find('tr input:checked').parents('tr').not("."+NOW_PLAYING_CLASS);
elements.hide();
}
@ -895,7 +941,7 @@ var AIRTIME = (function(AIRTIME){
var $scroll = $sbContent.find(".dataTables_scrolling"),
scrolled = $scroll.scrollTop(),
scrollingTop = $scroll.offset().top,
current = $sbTable.find(".sb-now-playing"),
current = $sbTable.find("."+NOW_PLAYING_CLASS),
currentTop = current.offset().top;
$scroll.scrollTop(currentTop - scrollingTop + scrolled);
@ -911,7 +957,7 @@ var AIRTIME = (function(AIRTIME){
var temp,
aItems = [],
trs = $sbTable.find(".sb-over.sb-future");
trs = $sbTable.find(".sb-over.sb-future.sb-allowed");
trs.each(function(){
temp = $(this).data("aData");
@ -935,22 +981,20 @@ var AIRTIME = (function(AIRTIME){
//add events to cursors.
$sbTable.find("tbody").on("click", "div.marker", function(event) {
var $tr = $(this).parents("tr"),
cursorSelClass = "cursor-selected-row";
$trs;
if ($tr.hasClass(cursorSelClass)) {
$tr.removeClass(cursorSelClass);
if ($tr.hasClass(CURSOR_SELECTED_CLASS)) {
mod.removeCursor($tr);
}
else {
$tr.addClass(cursorSelClass);
mod.selectCursor($tr);
}
if (event.ctrlKey === false) {
$sbTable.find('.'+cursorSelClass).not($tr)
.removeClass(cursorSelClass);
$trs = $sbTable.find('.'+CURSOR_SELECTED_CLASS).not($tr);
mod.removeCursor($trs);
}
mod.checkToolBarIcons();
return false;
});
@ -983,7 +1027,9 @@ var AIRTIME = (function(AIRTIME){
if (oItems.selCurs !== undefined) {
callback = function() {
$(this).parents('tr').next().addClass(cursorClass);
var $tr = $(this).parents('tr').next();
mod.selectCursor($tr);
};
oItems.selCurs.callback = callback;
@ -993,7 +1039,9 @@ var AIRTIME = (function(AIRTIME){
if (oItems.delCurs !== undefined) {
callback = function() {
$(this).parents('tr').next().removeClass(cursorClass);
var $tr = $(this).parents('tr').next();
mod.removeCursor($tr);
};
oItems.delCurs.callback = callback;

View File

View File

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

View File

View File

View File

View File

View File

View File

@ -1,3 +1,43 @@
2.1.0 - June 5th, 2012
* The cool stuff:
* Real-time show editing in the Now Playing and Calendar screens
* Add/Remove/Rearrange tracks within a show, even if it currently playing
* Color-coded which tracks are inside the show, which are on the show boundary, and which are outside the show boundary
* Ability to cut all tracks that are outside the show boundary
* Edit the length of a show that is currently playing
* Live Stream Rebroadcasting
* Two live streams can be connected to Airtime: DJ stream and Master stream. The DJ stream can connect to Airtime and override the scheduled playout. The Master stream can connect to Airtime and override the DJ stream and the scheduled playout. Live Streams are activated in the interface and the interface displays which stream is being output.
* Library usability improvements
* Bulk actions added: "Add to Playlist", "Add to Show", and "Delete File"
* Ability to choose which columns to display and the order of the columns, sort by multiple columns
* Any metadata can be shown in the list
* Added a "Date Uploaded" column
* Preview tracks
* Ability to seek to a specific part of a track
* Ability to listen to all tracks in a playlist or show back-to-back.
* Media Monitor - added support for network and USB drives.
* Removing a watched directory and adding it again preserves playlists & shows with those files.
* An icon in the playlist shows whether a file is missing on disk, warning the user that the playlist will not go according to plan.
* Media monitor detects add and removal of watched temporary local storage (USB disks for example) and network drives.
* Broadcast Log - export play count of tracks within a given time range.&nbsp; Useful for royalty reporting purposes.
* Minor Improvements:
* Ability to turn off the broadcast.
* Editing metadata in the library will update the metadata on disk.
* Password reset - user can request a password reset if they forgot it.
* Overbooked shows now fade out properly
* Playlists & Shows can now be infinite length. Previously they were limited to 24 hours long.
* Default fade time set to 0.5 of a second
* Repeating shows default to "No End"
* Ability to "View on Soundcloud" for recorded shows in the calendar
* "Listen" preview player no longer falls behind the broadcast (you can only mute the stream now, not stop it)
* Tracks that cannot be played will be rejected on upload and put in to the directory "/srv/airtime/store/problem_files" (but currently it will not tell you that it rejected them - sorry\!)
* Library is automatically refreshed when media import is finished
* Show "Disk Full" message when trying to upload a file that wont fit on the disk
* Reduced CPU utilization for OGG streams
* New command line utilities:
* airtime-test-soundcard - verify that the soundcard is working
* airtime-test-icecast - verify that you can connect to an Icecast server
2.0.3 - April 3rd, 2012
* Bug Fixes:
* monit user should have read-only permissions by default

View File

@ -87,8 +87,10 @@ echo "----------------------------------------------------"
cd /etc/default/
sed -i 's/startup=0/startup=1/g' monit
set +e
grep -q "include /etc/monit/conf.d" /etc/monit/monitrc
RETVAL=$?
set -e
if [ $RETVAL -ne 0 ] ; then
mkdir -p /etc/monit/conf.d
echo "include /etc/monit/conf.d/*" >> /etc/monit/monitrc

View File

@ -98,8 +98,10 @@ echo "----------------------------------------------------"
cd /etc/default/
sed -i 's/startup=0/startup=1/g' monit
set +e
grep -q "include /etc/monit/conf.d" /etc/monit/monitrc
RETVAL=$?
set -e
if [ $RETVAL -ne 0 ] ; then
mkdir -p /etc/monit/conf.d
echo "include /etc/monit/conf.d/*" >> /etc/monit/monitrc

View File

@ -203,6 +203,7 @@ if [ "$DO_UPGRADE" -eq "0" ]; then
fi
set -e
export airtime_service_start='t'
$SCRIPTPATH/include/airtime-copy-files.sh
$SCRIPTPATH/include/airtime-initialize.sh $@

View File

@ -91,6 +91,7 @@ class AirtimeIni
exit(1);
}
/*
if (!copy(__DIR__."/../../python_apps/pypo/liquidsoap_scripts/liquidsoap.cfg", AirtimeIni::CONF_FILE_LIQUIDSOAP)){
echo "Could not copy liquidsoap.cfg to /etc/airtime/. Exiting.";
exit(1);
@ -98,6 +99,7 @@ class AirtimeIni
echo "Could not set ownership of liquidsoap.cfg to 'pypo'. Exiting.";
exit(1);
}
* */
if (!copy(__DIR__."/../../python_apps/media-monitor/media-monitor.cfg", AirtimeIni::CONF_FILE_MEDIAMONITOR)){
echo "Could not copy media-monitor.cfg to /etc/airtime/. Exiting.";

View File

@ -54,7 +54,7 @@ ALTER TABLE cc_files
ALTER COLUMN length TYPE interval /* TYPE change - table: cc_files original: time without time zone new: interval */,
ALTER COLUMN length SET DEFAULT '00:00:00'::interval;
UPDATE cc_files SET utime = now();
UPDATE cc_files SET utime = now()::timestamp(0);
ALTER TABLE cc_music_dirs
ADD COLUMN "exists" boolean DEFAULT true,
@ -86,6 +86,7 @@ ALTER TABLE cc_schedule
DROP COLUMN group_id,
DROP COLUMN schedule_group_played,
ADD COLUMN playout_status smallint DEFAULT 1 NOT NULL,
ADD COLUMN broadcasted smallint DEFAULT 0 NOT NULL,
ALTER COLUMN clip_length TYPE interval /* TYPE change - table: cc_schedule original: time without time zone new: interval */,
ALTER COLUMN clip_length SET DEFAULT '00:00:00'::interval,
ALTER COLUMN cue_in TYPE interval /* TYPE change - table: cc_schedule original: time without time zone new: interval */,
@ -105,6 +106,7 @@ ALTER TABLE cc_show_instances
ALTER COLUMN time_filled TYPE interval /* TYPE change - table: cc_show_instances original: time without time zone new: interval */,
ALTER COLUMN time_filled SET DEFAULT '00:00:00'::interval;
UPDATE cc_show_instances SET time_filled = '00:00:00' WHERE time_filled is NULL;
UPDATE cc_show_instances SET created = now();
UPDATE cc_show_instances SET last_scheduled = now();

0
python_apps/api_clients/api_client.py Executable file → Normal file
View File

View File

@ -77,6 +77,10 @@ class AirtimeMediaMonitorBootstrap():
dir -- pathname of the directory
"""
def sync_database_to_filesystem(self, dir_id, dir):
dir = os.path.normpath(dir)+"/"
"""
set to hold new and/or modified files. We use a set to make it ok if files are added
twice. This is because some of the tests for new files return result sets that are not

View File

@ -14,8 +14,8 @@ try:
subprocess.call("update-rc.d airtime-media-monitor defaults >/dev/null 2>&1", shell=True)
#Start media-monitor daemon
print "* Waiting for media-monitor processes to start..."
subprocess.call("invoke-rc.d airtime-media-monitor start-no-monit", shell=True)
if "airtime_service_start" in os.environ and os.environ["airtime_service_start"] == "t":
print "* Waiting for media-monitor processes to start..."
subprocess.call("invoke-rc.d airtime-media-monitor start-no-monit", shell=True)
except Exception, e:
print e

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/bin/bash -e
virtualenv_bin="/usr/lib/airtime/airtime_virtualenv/bin/"
. ${virtualenv_bin}activate
@ -10,10 +10,13 @@ ls_path="/usr/bin/airtime-liquidsoap --verbose"
ls_param="/usr/lib/airtime/pypo/bin/liquidsoap_scripts/ls_script.liq"
exec 2>&1
export PYTHONPATH=${api_client_path}
rm -f /etc/airtime/liquidsoap.cfg
cd /usr/lib/airtime/pypo/bin/liquidsoap_scripts
python generate_liquidsoap_cfg.py
export PYTHONPATH=${api_client_path}
exec ${ls_path} ${ls_param}
# EOF

View File

@ -44,6 +44,9 @@ stop_pypo () {
}
start () {
chown pypo:pypo /etc/airtime
chown pypo:pypo /etc/airtime/liquidsoap.cfg
start-stop-daemon --start --background --quiet --chuid $USERID:$GROUPID --make-pidfile --pidfile $PIDFILE0 --startas $DAEMON0
monit monitor airtime-playout >/dev/null 2>&1

View File

@ -1,4 +1,6 @@
import os
import grp
import stat
import shutil
import sys
import subprocess
@ -42,7 +44,15 @@ try:
if not os.path.exists(PATH_INI_FILE):
shutil.copy('%s/../pypo.cfg'%current_script_dir, PATH_INI_FILE)
try:
os.remove("/etc/airtime/liquidsoap.cfg")
except Exception, e:
pass
gid = grp.getgrnam("pypo").gr_gid
os.chown("/etc/airtime", -1, gid)
os.chmod("/etc/airtime", stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
# load config file
try:
config = ConfigObj(PATH_INI_FILE)

View File

@ -48,9 +48,7 @@ def generate_liquidsoap_config(ss):
buffer = d[u'keyname'] + " = "
if(d[u'type'] == 'string'):
temp = d[u'value']
if(temp == ""):
temp = ""
buffer += "\"" + temp + "\""
buffer += '"%s"' % temp
else:
temp = d[u'value']
if(temp == ""):
@ -58,7 +56,7 @@ def generate_liquidsoap_config(ss):
buffer += temp
buffer += "\n"
fh.write(api_client.encode_to(buffer))
fh.write("log_file = \"/var/log/airtime/pypo-liquidsoap/<script>.log\"\n");
fh.write('log_file = "/var/log/airtime/pypo-liquidsoap/<script>.log"\n')
fh.close()
PATH_INI_FILE = '/etc/airtime/pypo.cfg'
@ -111,17 +109,19 @@ try:
print e
sys.exit(1)
"""
logging.basicConfig(format='%(message)s')
#generate liquidsoap config file
#access the DB and generate liquidsoap.cfg under /etc/airtime/
ac = api_client.api_client_factory(config, logging.getLogger())
ss = ac.get_stream_setting()
if ss is not None:
generate_liquidsoap_config(ss)
else:
print "Unable to connect to the Airtime server."
"""
#initialize init.d scripts
subprocess.call("update-rc.d airtime-playout defaults >/dev/null 2>&1", shell=True)
@ -130,8 +130,9 @@ try:
print "* Clearing previous pypo cache"
subprocess.call("rm -rf '/var/tmp/airtime/pypo/cache/scheduler/*' >/dev/null 2>&1", shell=True)
print "* Waiting for pypo processes to start..."
subprocess.call("invoke-rc.d airtime-playout start-no-monit > /dev/null 2>&1", shell=True)
if "airtime_service_start" in os.environ and os.environ["airtime_service_start"] == "t":
print "* Waiting for pypo processes to start..."
subprocess.call("invoke-rc.d airtime-playout start-no-monit > /dev/null 2>&1", shell=True)
except Exception, e:
print e

View File

@ -9,6 +9,10 @@ if os.geteuid() != 0:
try:
#stop pypo and liquidsoap processes
print "Waiting for pypo processes to stop...",
try:
os.remove("/usr/bin/airtime-liquidsoap")
except Exception, e:
pass
if (os.path.exists('/etc/init.d/airtime-playout')):
subprocess.call("invoke-rc.d airtime-playout stop", shell=True)
print "OK"

View File

@ -0,0 +1,46 @@
import logging
import sys
from api_clients import api_client
from configobj import ConfigObj
def generate_liquidsoap_config(ss):
data = ss['msg']
fh = open('/etc/airtime/liquidsoap.cfg', 'w')
fh.write("################################################\n")
fh.write("# THIS FILE IS AUTO GENERATED. DO NOT CHANGE!! #\n")
fh.write("################################################\n")
for d in data:
buffer = d[u'keyname'] + " = "
if(d[u'type'] == 'string'):
temp = d[u'value']
buffer += '"%s"' % temp
else:
temp = d[u'value']
if(temp == ""):
temp = "0"
buffer += temp
buffer += "\n"
fh.write(api_client.encode_to(buffer))
fh.write('log_file = "/var/log/airtime/pypo-liquidsoap/<script>.log"\n')
fh.close()
PATH_INI_FILE = '/etc/airtime/pypo.cfg'
try:
config = ConfigObj(PATH_INI_FILE)
except Exception, e:
print 'Error loading config file: ', e
sys.exit(1)
logging.basicConfig(format='%(message)s')
ac = api_client.api_client_factory(config, logging.getLogger())
ss = ac.get_stream_setting()
if ss is not None:
try:
generate_liquidsoap_config(ss)
except Exception, e:
logging.error(e)
else:
print "Unable to connect to the Airtime server."
sys.exit(1)

View File

@ -170,42 +170,78 @@ class PypoFetch(Thread):
self.update_liquidsoap_station_name(info['station_name'])
self.update_liquidsoap_transition_fade(info['transition_fade'])
def regenerateLiquidsoapConf(self, setting_p):
def write_liquidsoap_config(self, setting):
fh = open('/etc/airtime/liquidsoap.cfg', 'w')
self.logger.info("Rewriting liquidsoap.cfg...")
fh.write("################################################\n")
fh.write("# THIS FILE IS AUTO GENERATED. DO NOT CHANGE!! #\n")
fh.write("################################################\n")
for k, d in setting:
buffer_str = d[u'keyname'] + " = "
if d[u'type'] == 'string':
temp = d[u'value']
buffer_str += '"%s"' % temp
else:
temp = d[u'value']
if temp == "":
temp = "0"
buffer_str += temp
buffer_str += "\n"
fh.write(api_client.encode_to(buffer_str))
fh.write("log_file = \"/var/log/airtime/pypo-liquidsoap/<script>.log\"\n");
fh.close()
# restarting pypo.
# we could just restart liquidsoap but it take more time somehow.
self.logger.info("Restarting pypo...")
sys.exit(0)
def regenerateLiquidsoapConf(self, setting):
existing = {}
# create a temp file
fh = open('/etc/airtime/liquidsoap.cfg', 'r')
setting = sorted(setting.items())
try:
fh = open('/etc/airtime/liquidsoap.cfg', 'r')
except IOError, e:
#file does not exist
self.write_liquidsoap_config(setting)
self.logger.info("Reading existing config...")
# read existing conf file and build dict
while 1:
while True:
line = fh.readline()
# empty line means EOF
if not line:
break
line = line.strip()
if line.find('#') == 0:
if line[0] == "#":
continue
# if empty line
if not line:
try:
key, value = line.split('=', 1)
except ValueError:
continue
key, value = line.split(' = ')
key = key.strip()
value = value.strip()
value = value.replace('"', '')
if value == "" or value == "0":
if value == '' or value == "0":
value = ''
existing[key] = value
existing[key] = value
fh.close()
# dict flag for any change in cofig
change = {}
# this flag is to detect diable -> disable change
# this flag is to detect disable -> disable change
# in that case, we don't want to restart even if there are chnges.
state_change_restart = {}
#restart flag
restart = False
self.logger.info("Looking for changes...")
setting = sorted(setting_p.items())
# look for changes
for k, s in setting:
if "output_sound_device" in s[u'keyname'] or "icecast_vorbis_metadata" in s[u'keyname']:
@ -249,31 +285,7 @@ class PypoFetch(Thread):
restart = True
# rewrite
if restart:
fh = open('/etc/airtime/liquidsoap.cfg', 'w')
self.logger.info("Rewriting liquidsoap.cfg...")
fh.write("################################################\n")
fh.write("# THIS FILE IS AUTO GENERATED. DO NOT CHANGE!! #\n")
fh.write("################################################\n")
for k, d in setting:
buffer_str = d[u'keyname'] + " = "
if(d[u'type'] == 'string'):
temp = d[u'value']
if(temp == ""):
temp = ""
buffer_str += "\"" + temp + "\""
else:
temp = d[u'value']
if(temp == ""):
temp = "0"
buffer_str += temp
buffer_str += "\n"
fh.write(api_client.encode_to(buffer_str))
fh.write("log_file = \"/var/log/airtime/pypo-liquidsoap/<script>.log\"\n");
fh.close()
# restarting pypo.
# we could just restart liquidsoap but it take more time somehow.
self.logger.info("Restarting pypo...")
sys.exit(0)
self.write_liquidsoap_config(setting)
else:
self.logger.info("No change detected in setting...")
self.update_liquidsoap_connection_status()

View File

@ -82,6 +82,9 @@ class PypoPush(Thread):
self.modify_cue_point(current_event_chain[0])
next_media_item_chain = current_event_chain
time_until_next_play = 0
#sleep for 0.2 seconds to give pypo-file time to copy. This is a quick
#fix that will be improved in 2.1.1
time.sleep(0.2)
else:
media_chain = filter(lambda item: (item["type"] == "file"), current_event_chain)
self.handle_new_media_schedule(media_schedule, liquidsoap_queue_approx, media_chain)

View File

@ -69,10 +69,9 @@ catch (Zend_Console_Getopt_Exception $e) {
exit(1);
}
$infoArray = Application_Model_Preference::GetSystemInfo(true, isset($opts->t));
if(Application_Model_Preference::GetSupportFeedback() == '1'){
$infoArray = Application_Model_Preference::GetSystemInfo(true, isset($opts->t));
$url = 'http://stat.sourcefabric.org/index.php?p=airtime';
//$url = 'http://localhost:9999/index.php?p=airtime';