Merge branch '2.4.x' into 2.4.x-saas

Conflicts:
	python_apps/pypo/liquidsoap_scripts/ls_script.liq
	utils/phone_home_stat.php
This commit is contained in:
Naomi Aro 2013-06-26 01:25:26 -04:00
commit f2d5fa96da
114 changed files with 9850 additions and 9170 deletions

View file

@ -8,7 +8,7 @@ Common Non-linked Code
- Web site: https://github.com/torvalds/linux - Web site: https://github.com/torvalds/linux
- License: GPLv2 - License: GPLv2
* RabbitMQ (works with version 1.7.2 and above) * RabbitMQ
- What is it: Interprocess Message Passing with Queuing - What is it: Interprocess Message Passing with Queuing
- Web site: http://www.rabbitmq.com/ - Web site: http://www.rabbitmq.com/
- License: Mozilla Public License (http://www.rabbitmq.com/mpl.html) - License: Mozilla Public License (http://www.rabbitmq.com/mpl.html)
@ -63,11 +63,11 @@ Non-linked code:
- Web site: http://httpd.apache.org/ - Web site: http://httpd.apache.org/
- License: Apache 2.0. See http://httpd.apache.org/docs/2.2/license.html - License: Apache 2.0. See http://httpd.apache.org/docs/2.2/license.html
* PostgreSQL 8.4 * PostgreSQL 9.1
- Web site: http://www.postgresql.org/ - Web site: http://www.postgresql.org/
- License: The PostgreSQL License. See http://www.postgresql.org/about/licence - License: The PostgreSQL License. See http://www.postgresql.org/about/licence
* PHP 5.3 * PHP 5.3
- Web site: http://www.php.net/ - Web site: http://www.php.net/
- License: The PHP License. See http://www.php.net/license/3_01.txt - License: The PHP License. See http://www.php.net/license/3_01.txt
@ -137,7 +137,7 @@ Linked code:
- License: MIT - License: MIT
Non-linked code: Non-linked code:
* Python 2.6 * Python 2.7
- Web site: http://www.python.org/ - Web site: http://www.python.org/
- License: PSF License. See http://docs.python.org/license.html - License: PSF License. See http://docs.python.org/license.html
@ -158,11 +158,11 @@ Linked code:
- Compatible with GPLv3? Yes. - Compatible with GPLv3? Yes.
Non-linked code: Non-linked code:
* Python 2.6 * Python 2.7
- Web site: http://www.python.org/ - Web site: http://www.python.org/
- License: PSF License. See http://docs.python.org/license.html - License: PSF License. See http://docs.python.org/license.html
* ecasound 2.7.2 * ecasound 2.8.1
- What is it: Records audio from line-in - What is it: Records audio from line-in
- Web site: http://www.eca.cx/ecasound/ - Web site: http://www.eca.cx/ecasound/
- License: GPLv2 - License: GPLv2
@ -177,10 +177,10 @@ Linked code:
- Compatible with GPLv3? Yes. - Compatible with GPLv3? Yes.
Non-linked code: Non-linked code:
* Python 2.6 * Python 2.7
- Web site: http://www.python.org/ - Web site: http://www.python.org/
- License: PSF License. See http://docs.python.org/license.html - License: PSF License. See http://docs.python.org/license.html
* Liquidsoap 1.0.1 * Liquidsoap 1.1.1
- Web site: http://savonet.sourceforge.net/ - Web site: http://savonet.sourceforge.net/
- License: GPLv2 - License: GPLv2

View file

@ -523,6 +523,15 @@ class ApiController extends Zend_Controller_Action
} }
//Updating a metadata change. //Updating a metadata change.
else { else {
//CC-5207 - restart media-monitor causes it to reevaluate all
//files in watched directories, and reset their cue-in/cue-out
//values. Since media-monitor has nothing to do with cue points
//let's unset it here. Note that on mode == "create", we still
//want media-monitor sending info about cue_out which by default
//will be equal to length of track until silan can take over.
unset($md['MDATA_KEY_CUE_IN']);
unset($md['MDATA_KEY_CUE_OUT']);
$file->setMetadata($md); $file->setMetadata($md);
} }
} elseif ($mode == "moved") { } elseif ($mode == "moved") {

View file

@ -24,7 +24,7 @@ class ErrorController extends Zend_Controller_Action
} }
// Log exception, if logger available // Log exception, if logger available
if ($log = $this->getLog()) { if (($log = $this->getLog())) {
$log->crit($this->view->message, $errors->exception); $log->crit($this->view->message, $errors->exception);
} }

View file

@ -393,7 +393,8 @@ class LibraryController extends Zend_Controller_Action
} }
$c[0] = $c['item_id']; $c[0] = $c['item_id'];
} }
$newPl->addAudioClips($contents, null, 'begining');
$newPl->addAudioClips($contents, null, 'before');
$newPl->setCreator(Application_Model_User::getCurrentUser()->getId()); $newPl->setCreator(Application_Model_User::getCurrentUser()->getId());
$newPl->setDescription($originalPl->getDescription()); $newPl->setDescription($originalPl->getDescription());
@ -425,6 +426,9 @@ class LibraryController extends Zend_Controller_Action
$request = $this->getRequest(); $request = $this->getRequest();
$file_id = $this->_getParam('id', null); $file_id = $this->_getParam('id', null);
$file = Application_Model_StoredFile::RecallById($file_id); $file = Application_Model_StoredFile::RecallById($file_id);
@ -437,7 +441,15 @@ class LibraryController extends Zend_Controller_Action
$form->populate($file->getDbColMetadata()); $form->populate($file->getDbColMetadata());
if ($request->isPost()) { if ($request->isPost()) {
if ($form->isValid($request->getPost())) {
$js = $this->_getParam('data');
$serialized = array();
//need to convert from serialized jQuery array.
foreach ($js as $j) {
$serialized[$j["name"]] = $j["value"];
}
if ($form->isValid($serialized)) {
$formValues = $this->_getParam('data', null); $formValues = $this->_getParam('data', null);
$formdata = array(); $formdata = array();

View file

@ -9,36 +9,36 @@ class ListenerstatController extends Zend_Controller_Action
->addActionContext('get-data', 'json') ->addActionContext('get-data', 'json')
->initContext(); ->initContext();
} }
public function indexAction() public function indexAction()
{ {
$CC_CONFIG = Config::getConfig(); $CC_CONFIG = Config::getConfig();
$request = $this->getRequest(); $request = $this->getRequest();
$baseUrl = Application_Common_OsPath::getBaseDir(); $baseUrl = Application_Common_OsPath::getBaseDir();
$this->view->headScript()->appendFile($baseUrl.'js/flot/jquery.flot.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/flot/jquery.flot.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
$this->view->headScript()->appendFile($baseUrl.'js/flot/jquery.flot.crosshair.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/flot/jquery.flot.crosshair.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
$this->view->headScript()->appendFile($baseUrl.'js/airtime/listenerstat/listenerstat.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/airtime/listenerstat/listenerstat.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
$offset = date("Z") * -1; $offset = date("Z") * -1;
$this->view->headScript()->appendScript("var serverTimezoneOffset = {$offset}; //in seconds"); $this->view->headScript()->appendScript("var serverTimezoneOffset = {$offset}; //in seconds");
$this->view->headScript()->appendFile($baseUrl.'js/timepicker/jquery.ui.timepicker.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/timepicker/jquery.ui.timepicker.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
$this->view->headScript()->appendFile($baseUrl.'js/airtime/buttons/buttons.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/airtime/buttons/buttons.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
$this->view->headScript()->appendFile($baseUrl.'js/airtime/utilities/utilities.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/airtime/utilities/utilities.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
$this->view->headLink()->appendStylesheet($baseUrl.'css/jquery.ui.timepicker.css?'.$CC_CONFIG['airtime_version']); $this->view->headLink()->appendStylesheet($baseUrl.'css/jquery.ui.timepicker.css?'.$CC_CONFIG['airtime_version']);
//default time is the last 24 hours. //default time is the last 24 hours.
$now = time(); $now = time();
$from = $request->getParam("from", $now - (24*60*60)); $from = $request->getParam("from", $now - (24*60*60));
$to = $request->getParam("to", $now); $to = $request->getParam("to", $now);
$start = DateTime::createFromFormat("U", $from, new DateTimeZone("UTC")); $start = DateTime::createFromFormat("U", $from, new DateTimeZone("UTC"));
$start->setTimezone(new DateTimeZone(date_default_timezone_get())); $start->setTimezone(new DateTimeZone(date_default_timezone_get()));
$end = DateTime::createFromFormat("U", $to, new DateTimeZone("UTC")); $end = DateTime::createFromFormat("U", $to, new DateTimeZone("UTC"));
$end->setTimezone(new DateTimeZone(date_default_timezone_get())); $end->setTimezone(new DateTimeZone(date_default_timezone_get()));
$form = new Application_Form_DateRange(); $form = new Application_Form_DateRange();
$form->populate(array( $form->populate(array(
'his_date_start' => $start->format("Y-m-d"), 'his_date_start' => $start->format("Y-m-d"),
@ -46,7 +46,7 @@ class ListenerstatController extends Zend_Controller_Action
'his_date_end' => $end->format("Y-m-d"), 'his_date_end' => $end->format("Y-m-d"),
'his_time_end' => $end->format("H:i") 'his_time_end' => $end->format("H:i")
)); ));
$errorStatus = Application_Model_StreamSetting::GetAllListenerStatErrors(); $errorStatus = Application_Model_StreamSetting::GetAllListenerStatErrors();
Logging::info($errorStatus); Logging::info($errorStatus);
$out = array(); $out = array();
@ -57,25 +57,24 @@ class ListenerstatController extends Zend_Controller_Action
} }
$out[$key[0]] = $v['value']; $out[$key[0]] = $v['value'];
} }
$this->view->errorStatus = $out; $this->view->errorStatus = $out;
$this->view->date_form = $form; $this->view->date_form = $form;
} }
public function getDataAction(){ public function getDataAction(){
$request = $this->getRequest(); $request = $this->getRequest();
$current_time = time(); $current_time = time();
$params = $request->getParams(); $params = $request->getParams();
$starts_epoch = $request->getParam("startTimestamp", $current_time - (60*60*24)); $starts_epoch = $request->getParam("startTimestamp", $current_time - (60*60*24));
$ends_epoch = $request->getParam("endTimestamp", $current_time); $ends_epoch = $request->getParam("endTimestamp", $current_time);
$mountName = $request->getParam("mountName", null);
$startsDT = DateTime::createFromFormat("U", $starts_epoch, new DateTimeZone("UTC")); $startsDT = DateTime::createFromFormat("U", $starts_epoch, new DateTimeZone("UTC"));
$endsDT = DateTime::createFromFormat("U", $ends_epoch, new DateTimeZone("UTC")); $endsDT = DateTime::createFromFormat("U", $ends_epoch, new DateTimeZone("UTC"));
$data = Application_Model_ListenerStat::getDataPointsWithinRange($startsDT->format("Y-m-d H:i:s"), $endsDT->format("Y-m-d H:i:s"), $mountName); $data = Application_Model_ListenerStat::getDataPointsWithinRange($startsDT->format("Y-m-d H:i:s"), $endsDT->format("Y-m-d H:i:s"));
$this->_helper->json->sendJson($data); $this->_helper->json->sendJson($data);
} }
} }

View file

@ -167,7 +167,7 @@ class LocaleController extends Zend_Controller_Action
"Are you sure you want to remove the watched folder?" => _("Are you sure you want to remove the watched folder?"), "Are you sure you want to remove the watched folder?" => _("Are you sure you want to remove the watched folder?"),
"This path is currently not accessible." => _("This path is currently not accessible."), "This path is currently not accessible." => _("This path is currently not accessible."),
//preferences/streamsetting.js //preferences/streamsetting.js
"Some steam types require extra configuration. Details about enabling %sAAC+ Support%s or %sOpus Support%s are provided." => _("Some steam types require extra configuration. Details about enabling %sAAC+ Support%s or %sOpus Support%s are provided."), "Some stream types require extra configuration. Details about enabling %sAAC+ Support%s or %sOpus Support%s are provided." => _("Some stream types require extra configuration. Details about enabling %sAAC+ Support%s or %sOpus Support%s are provided."),
"Connected to the streaming server" => _("Connected to the streaming server"), "Connected to the streaming server" => _("Connected to the streaming server"),
"The stream is disabled" => _("The stream is disabled"), "The stream is disabled" => _("The stream is disabled"),
"Getting information from the server..." => _("Getting information from the server..."), "Getting information from the server..." => _("Getting information from the server..."),
@ -193,6 +193,7 @@ class LocaleController extends Zend_Controller_Action
"If your live streaming client does not ask for a username, this field should be 'source'." => _("If your live streaming client does not ask for a username, this field should be 'source'."), "If your live streaming client does not ask for a username, this field should be 'source'." => _("If your live streaming client does not ask for a username, this field should be 'source'."),
"The show instance doesn't exist anymore!" => _("The show instance doesn't exist anymore!"), "The show instance doesn't exist anymore!" => _("The show instance doesn't exist anymore!"),
"Warning: Shows cannot be re-linked" => _("Warning: Shows cannot be re-linked"), "Warning: Shows cannot be re-linked" => _("Warning: Shows cannot be re-linked"),
"By linking your repeating shows any media items scheduled in any repeat show will also get scheduled in the other repeat shows" => _("By linking your repeating shows any media items scheduled in any repeat show will also get scheduled in the other repeat shows"),
//schedule/full-calendar-functions //schedule/full-calendar-functions
//already in schedule/add-show.js //already in schedule/add-show.js
//"The show instance doesn't exist anymore!" => _("The show instance doesn't exist anymore!"), //"The show instance doesn't exist anymore!" => _("The show instance doesn't exist anymore!"),

View file

@ -30,6 +30,7 @@ class PreferenceController extends Zend_Controller_Action
$this->view->statusMsg = ""; $this->view->statusMsg = "";
$form = new Application_Form_Preferences(); $form = new Application_Form_Preferences();
$values = array();
if ($request->isPost()) { if ($request->isPost()) {
$params = $request->getPost(); $params = $request->getPost();
@ -137,11 +138,12 @@ class PreferenceController extends Zend_Controller_Action
$setting[$t['keyname']] = $t['value']; $setting[$t['keyname']] = $t['value'];
} }
$name_map = array('ogg' => 'Ogg Vorbis', $name_map = array(
'aacplus' => 'AAC+', 'ogg' => 'Ogg Vorbis',
'fdkaac' => 'AAC+',
'aac' => 'AAC', 'aac' => 'AAC',
'opus' => 'Opus', 'opus' => 'Opus',
'mp3' => 'MP3' 'mp3' => 'MP3',
); );
// get predefined type and bitrate from pref table // get predefined type and bitrate from pref table
@ -162,7 +164,7 @@ class PreferenceController extends Zend_Controller_Action
$stream_bitrates = array(); $stream_bitrates = array();
foreach ($temp_bitrate as $type) { foreach ($temp_bitrate as $type) {
if (intval($type) <= $max_bitrate) { if (intval($type) <= $max_bitrate) {
$stream_bitrates[trim($type)] = strtoupper(trim($type))." Kbit/s"; $stream_bitrates[trim($type)] = strtoupper(trim($type))." kbit/s";
} }
} }
@ -193,6 +195,7 @@ class PreferenceController extends Zend_Controller_Action
$s1_data = array(); $s1_data = array();
$s2_data = array(); $s2_data = array();
$s3_data = array(); $s3_data = array();
$values = array();
foreach($postData as $k=>$v) { foreach($postData as $k=>$v) {
$v = explode('=', urldecode($v)); $v = explode('=', urldecode($v));
if (strpos($v[0], "s1_data") !== false) { if (strpos($v[0], "s1_data") !== false) {

View file

@ -600,6 +600,7 @@ class ScheduleController extends Zend_Controller_Action
$baseUrl = $this->getRequest()->getBaseUrl(); $baseUrl = $this->getRequest()->getBaseUrl();
$url = $file->getRelativeFileUrl($baseUrl).'download/true'; $url = $file->getRelativeFileUrl($baseUrl).'download/true';
$menu = array();
$menu[] = array('action' => array('type' => 'gourl', 'url' => $url), $menu[] = array('action' => array('type' => 'gourl', 'url' => $url),
'title' => _('Download')); 'title' => _('Download'));

View file

@ -41,6 +41,7 @@ class UserController extends Zend_Controller_Action
if ($request->isPost()) { if ($request->isPost()) {
$params = $request->getPost(); $params = $request->getPost();
$postData = explode('&', $params['data']); $postData = explode('&', $params['data']);
$formData = array();
foreach($postData as $k=>$v) { foreach($postData as $k=>$v) {
$v = explode('=', $v); $v = explode('=', $v);
$formData[$v[0]] = urldecode($v[1]); $formData[$v[0]] = urldecode($v[1]);

View file

@ -39,7 +39,7 @@ class Application_Form_EditAudioMD extends Zend_Form
$this->addElement('text', 'track_number', array( $this->addElement('text', 'track_number', array(
'label' => _('Track:'), 'label' => _('Track:'),
'class' => 'input_text', 'class' => 'input_text',
'filters' => array('StringTrim') 'filters' => array('StringTrim'),
)); ));
// Add genre field // Add genre field
@ -50,16 +50,17 @@ class Application_Form_EditAudioMD extends Zend_Form
)); ));
// Add year field // Add year field
$this->addElement('text', 'year', array( $year = new Zend_Form_Element_Text('year');
'label' => _('Year:'), $year->class = 'input_text';
'class' => 'input_text', $year->setLabel(_('Year:'))
'filters' => array('StringTrim'), ->setFilters(array('StringTrim'))
'validators' => array( ->setValidators(array(
new Zend_Validate_StringLength(array('max' => 10)),
Application_Form_Helper_ValidationTypes::overrrideDateValidator("YYYY-MM-DD"), Application_Form_Helper_ValidationTypes::overrrideDateValidator("YYYY-MM-DD"),
Application_Form_Helper_ValidationTypes::overrrideDateValidator("YYYY-MM"), Application_Form_Helper_ValidationTypes::overrrideDateValidator("YYYY-MM"),
Application_Form_Helper_ValidationTypes::overrrideDateValidator("YYYY") Application_Form_Helper_ValidationTypes::overrrideDateValidator("YYYY")
) ));
)); $this->addElement($year);
// Add label field // Add label field
$this->addElement('text', 'label', array( $this->addElement('text', 'label', array(

View file

@ -5,7 +5,7 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
private $stringCriteriaOptions; private $stringCriteriaOptions;
private $numericCriteriaOptions; private $numericCriteriaOptions;
private $limitOptions; private $limitOptions;
/* We need to know if the criteria value will be a string /* We need to know if the criteria value will be a string
* or numeric value in order to populate the modifier * or numeric value in order to populate the modifier
* select list * select list
@ -40,7 +40,7 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
"info_url" => "s", "info_url" => "s",
"year" => "n" "year" => "n"
); );
private function getCriteriaOptions($option = null) private function getCriteriaOptions($option = null)
{ {
if (!isset($this->criteriaOptions)) { if (!isset($this->criteriaOptions)) {
@ -75,7 +75,7 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
"year" => _("Year") "year" => _("Year")
); );
} }
if (is_null($option)) return $this->criteriaOptions; if (is_null($option)) return $this->criteriaOptions;
else return $this->criteriaOptions[$option]; else return $this->criteriaOptions[$option];
} }
@ -122,7 +122,7 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
} }
return $this->limitOptions; return $this->limitOptions;
} }
public function init() public function init()
{ {
@ -259,7 +259,7 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
$repeatTracks->setChecked($storedCrit["repeat_tracks"]["value"] == 1?true:false); $repeatTracks->setChecked($storedCrit["repeat_tracks"]["value"] == 1?true:false);
} }
$this->addElement($repeatTracks); $this->addElement($repeatTracks);
$limit = new Zend_Form_Element_Select('sp_limit_options'); $limit = new Zend_Form_Element_Select('sp_limit_options');
$limit->setAttrib('class', 'sp_input_select') $limit->setAttrib('class', 'sp_input_select')
->setDecorators(array('viewHelper')) ->setDecorators(array('viewHelper'))
@ -268,7 +268,7 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
$limit->setValue($storedCrit["limit"]["modifier"]); $limit->setValue($storedCrit["limit"]["modifier"]);
} }
$this->addElement($limit); $this->addElement($limit);
$limitValue = new Zend_Form_Element_Text('sp_limit_value'); $limitValue = new Zend_Form_Element_Text('sp_limit_value');
$limitValue->setAttrib('class', 'sp_input_text_limit') $limitValue->setAttrib('class', 'sp_input_text_limit')
->setLabel(_('Limit to')) ->setLabel(_('Limit to'))
@ -541,7 +541,7 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
$isValid = false; $isValid = false;
} }
// length check // length check
if (intval($d['sp_criteria_value']) >= pow(2,31)) { if ($d['sp_criteria_value'] >= pow(2,31)) {
$element->addError(_("The value should be less then 2147483648")); $element->addError(_("The value should be less then 2147483648"));
$isValid = false; $isValid = false;
} }

View file

@ -36,6 +36,7 @@
<script id="tmpl-pl-cues" type="text/template"> <script id="tmpl-pl-cues" type="text/template">
<div class="waveform-cues"> <div class="waveform-cues">
<div class="playlist-time-scale"></div>
<div class="playlist-tracks"></div> <div class="playlist-tracks"></div>
<div class="playlist-controls"> <div class="playlist-controls">
<a class="btn btn-small btn_play"><i class="icon-play icon-white"></i><?php echo _("Play"); ?></a> <a class="btn btn-small btn_play"><i class="icon-play icon-white"></i><?php echo _("Play"); ?></a>
@ -61,10 +62,12 @@
<script id="tmpl-pl-fades" type="text/template"> <script id="tmpl-pl-fades" type="text/template">
<div class="waveform-fades"> <div class="waveform-fades">
<div class="playlist-time-scale"></div>
<div class="playlist-tracks"></div> <div class="playlist-tracks"></div>
<div class="playlist-controls left-floated"> <div class="playlist-controls left-floated">
<a class="btn btn-small btn_play"><i class="icon-play icon-white"></i><?php echo _("Play"); ?></a> <a class="btn btn-small btn_play"><i class="icon-play icon-white"></i><?php echo _("Play"); ?></a>
<a class="btn btn-small btn_stop"><i class="icon-stop icon-white"></i><?php echo _("Stop"); ?></a> <a class="btn btn-small btn_stop"><i class="icon-stop icon-white"></i><?php echo _("Stop"); ?></a>
<label class="audio audio_pos">00:00:00.0</label>
</div> </div>
<div class="set-fade left-floated"> <div class="set-fade left-floated">
<a type="button" class="btn btn-small btn_cursor" data-state="cursor"><?php echo _("Cursor"); ?></a> <a type="button" class="btn btn-small btn_cursor" data-state="cursor"><?php echo _("Cursor"); ?></a>

View file

@ -330,7 +330,7 @@ SQL;
{ {
list($value, $modifier) = $this->getLimitValueAndModifier(); list($value, $modifier) = $this->getLimitValueAndModifier();
if ($modifier == "items") { if ($modifier == "items") {
$length = $value." ".$modifier; $length = $value." "._("items");
} else { } else {
$hour = "00"; $hour = "00";
$mins = "00"; $mins = "00";
@ -686,6 +686,10 @@ SQL;
public function createCrossfade($id1, $fadeOut, $id2, $fadeIn, $offset) public function createCrossfade($id1, $fadeOut, $id2, $fadeIn, $offset)
{ {
$this->con->beginTransaction(); $this->con->beginTransaction();
if (!isset($offset)) {
$offset = Application_Model_Preference::GetDefaultCrossfadeDuration();
}
try { try {
if (isset($id1)) { if (isset($id1)) {
@ -1350,6 +1354,21 @@ SQL;
"year" => _("Year") "year" => _("Year")
); );
$modifierOptions = array(
"0" => _("Select modifier"),
"contains" => _("contains"),
"does not contain" => _("does not contain"),
"is" => _("is"),
"is not" => _("is not"),
"starts with" => _("starts with"),
"ends with" => _("ends with"),
"is" => _("is"),
"is not" => _("is not"),
"is greater than" => _("is greater than"),
"is less than" => _("is less than"),
"is in the range" => _("is in the range")
);
// Load criteria from db // Load criteria from db
$out = CcBlockcriteriaQuery::create()->orderByDbCriteria()->findByDbBlockId($this->id); $out = CcBlockcriteriaQuery::create()->orderByDbCriteria()->findByDbBlockId($this->id);
$storedCrit = array(); $storedCrit = array();
@ -1361,11 +1380,20 @@ SQL;
$extra = $crit->getDbExtra(); $extra = $crit->getDbExtra();
if ($criteria == "limit") { if ($criteria == "limit") {
$storedCrit["limit"] = array("value"=>$value, "modifier"=>$modifier); $storedCrit["limit"] = array(
"value"=>$value,
"modifier"=>$modifier,
"display_modifier"=>_($modifier));
} else if($criteria == "repeat_tracks") { } else if($criteria == "repeat_tracks") {
$storedCrit["repeat_tracks"] = array("value"=>$value); $storedCrit["repeat_tracks"] = array("value"=>$value);
} else { } else {
$storedCrit["crit"][$criteria][] = array("criteria"=>$criteria, "value"=>$value, "modifier"=>$modifier, "extra"=>$extra, "display_name"=>$criteriaOptions[$criteria]); $storedCrit["crit"][$criteria][] = array(
"criteria"=>$criteria,
"value"=>$value,
"modifier"=>$modifier,
"extra"=>$extra,
"display_name"=>$criteriaOptions[$criteria],
"display_modifier"=>$modifierOptions[$modifier]);
} }
} }

View file

@ -4,6 +4,7 @@ class Application_Model_Datatables
{ {
private static function buildWhereClauseForAdvancedSearch($dbname2searchTerm) private static function buildWhereClauseForAdvancedSearch($dbname2searchTerm)
{ {
$where = array();
$where['clause'] = array(); $where['clause'] = array();
$where['params'] = array(); $where['params'] = array();
foreach ($dbname2searchTerm as $dbname=>$term) { foreach ($dbname2searchTerm as $dbname=>$term) {

View file

@ -4,7 +4,7 @@ class Application_Model_ListenerStat
public function __construct() public function __construct()
{ {
} }
public static function getDataPointsWithinRange($p_start, $p_end) { public static function getDataPointsWithinRange($p_start, $p_end) {
$sql = <<<SQL $sql = <<<SQL
SELECT mount_name, count(*) SELECT mount_name, count(*)
@ -16,13 +16,13 @@ group by mount_name
SQL; SQL;
$data = Application_Common_Database::prepareAndExecute($sql, $data = Application_Common_Database::prepareAndExecute($sql,
array('p1'=>$p_start, 'p2'=>$p_end)); array('p1'=>$p_start, 'p2'=>$p_end));
$out = array(); $out = array();
foreach ($data as $d) { foreach ($data as $d) {
$jump = intval($d['count']/1000); $jump = intval($d['count']/1000);
$jump = max(1, $jump); $jump = max(1, $jump);
$remainder = $jump == 1?0:1; $remainder = $jump == 1?0:1;
$sql = <<<SQL $sql = <<<SQL
SELECT * SELECT *
FROM FROM
@ -41,29 +41,36 @@ SQL;
$t->setTimezone(new DateTimeZone(date_default_timezone_get())); $t->setTimezone(new DateTimeZone(date_default_timezone_get()));
// tricking javascript so it thinks the server timezone is in UTC // tricking javascript so it thinks the server timezone is in UTC
$dt = new DateTime($t->format("Y-m-d H:i:s"), new DateTimeZone("UTC")); $dt = new DateTime($t->format("Y-m-d H:i:s"), new DateTimeZone("UTC"));
$r['timestamp'] = $dt->format("U"); $r['timestamp'] = $dt->format("U");
$out[$r['mount_name']][] = $r; $out[$r['mount_name']][] = $r;
} }
} }
$enabledStreamIds = Application_Model_StreamSetting::getEnabledStreamIds(); $enabledStreamIds = Application_Model_StreamSetting::getEnabledStreamIds();
$enabledOut = array(); $enabledOut = array();
foreach ($enabledStreamIds as $sId) { foreach ($enabledStreamIds as $sId) {
$sql = "SELECT value FROM cc_stream_setting" $sql = "SELECT value FROM cc_stream_setting"
." WHERE keyname = :key"; ." WHERE keyname = :key";
$result = Application_Common_Database::prepareAndExecute($sql, array('key' => $sId."_mount"), "single"); $result = Application_Common_Database::prepareAndExecute($sql, array('key' => $sId."_mount"), "single");
$enabledMountPoint = $result["value"]; $enabledMountPoint = $result["value"];
if (isset($out[$enabledMountPoint])) { if (isset($out[$enabledMountPoint])) {
$enabledOut[$enabledMountPoint] = $out[$enabledMountPoint]; $enabledOut[$enabledMountPoint] = $out[$enabledMountPoint];
} }
else {
//TODO fix this hack (here for CC-5254)
//all shoutcast streams are automatically put under "shoutcast" mount point.
if (isset($out["shoutcast"])) {
$enabledOut["shoutcast"] = $out["shoutcast"];
}
}
} }
return $enabledOut; return $enabledOut;
} }

View file

@ -154,8 +154,6 @@ class Application_Model_Playlist implements Application_Model_LibraryEditable
*/ */
public function getContents($filterFiles=false) public function getContents($filterFiles=false)
{ {
Logging::info("Getting contents for playlist {$this->id}");
$sql = <<<SQL $sql = <<<SQL
SELECT * SELECT *
FROM ( FROM (
@ -411,26 +409,44 @@ SQL;
|| $obj instanceof CcWebstream || || $obj instanceof CcWebstream ||
$obj instanceof CcBlock) { $obj instanceof CcBlock) {
$entry = $this->plItem; $entry = $this->plItem;
$entry["id"] = $obj->getDbId(); $entry["id"] = $obj->getDbId();
$entry["pos"] = $pos; $entry["pos"] = $pos;
$entry["cliplength"] = $obj->getDbLength(); $entry["cliplength"] = $obj->getDbLength();
if ($obj instanceof CcFiles && $obj) { if ($obj instanceof CcFiles && $obj) {
$entry["cuein"] = $obj->getDbCuein();
$entry["cueout"] = $obj->getDbCueout(); $entry["cuein"] = isset($p_item['cuein']) ?
$p_item['cuein'] : $obj->getDbCuein();
$entry["cueout"] = isset($p_item['cueout']) ?
$p_item['cueout'] : $obj->getDbCueout();
$cue_out = Application_Common_DateHelper::calculateLengthInSeconds($entry['cueout']); $cue_in = isset($p_item['cueInSec']) ?
$cue_in = Application_Common_DateHelper::calculateLengthInSeconds($entry['cuein']); $p_item['cueInSec'] : Application_Common_DateHelper::calculateLengthInSeconds($entry['cuein']);
$entry["cliplength"] = Application_Common_DateHelper::secondsToPlaylistTime($cue_out-$cue_in);
} elseif ($obj instanceof CcWebstream && $obj) { $cue_out = isset($p_item['cueOutSec']) ?
$p_item['cueOutSec'] : Application_Common_DateHelper::calculateLengthInSeconds($entry['cueout']);
$entry["cliplength"] = isset($p_item['length']) ?
$p_item['length'] : Application_Common_DateHelper::secondsToPlaylistTime($cue_out-$cue_in);
}
elseif ($obj instanceof CcWebstream && $obj) {
$entry["cuein"] = "00:00:00"; $entry["cuein"] = "00:00:00";
$entry["cueout"] = $entry["cliplength"]; $entry["cueout"] = $entry["cliplength"];
} }
$entry["ftype"] = $objType; $entry["ftype"] = $objType;
$entry["fadein"] = isset($p_item['fadein']) ?
$p_item['fadein'] : $entry["fadein"];
$entry["fadeout"] = isset($p_item['fadeout']) ?
$p_item['fadeout'] : $entry["fadeout"];
} }
return $entry; return $entry;
} else { }
else {
throw new Exception("trying to add a object that does not exist."); throw new Exception("trying to add a object that does not exist.");
} }
} }
@ -451,11 +467,10 @@ SQL;
try { try {
if (is_numeric($p_afterItem)) { if (is_numeric($p_afterItem)) {
Logging::info("Finding playlist content item {$p_afterItem}");
$afterItem = CcPlaylistcontentsQuery::create()->findPK($p_afterItem); $afterItem = CcPlaylistcontentsQuery::create()->findPK($p_afterItem);
$index = $afterItem->getDbPosition(); $index = $afterItem->getDbPosition();
Logging::info("index is {$index}");
$pos = ($addType == 'after') ? $index + 1 : $index; $pos = ($addType == 'after') ? $index + 1 : $index;
$contentsToUpdate = CcPlaylistcontentsQuery::create() $contentsToUpdate = CcPlaylistcontentsQuery::create()
@ -488,9 +503,6 @@ SQL;
} }
Logging::info("Adding to playlist");
Logging::info("at position {$pos}");
foreach ($p_items as $ac) { foreach ($p_items as $ac) {
$res = $this->insertPlaylistElement($this->buildEntry($ac, $pos)); $res = $this->insertPlaylistElement($this->buildEntry($ac, $pos));
@ -500,8 +512,6 @@ SQL;
$db_file->setDbIsPlaylist(true)->save($this->con); $db_file->setDbIsPlaylist(true)->save($this->con);
$pos = $pos + 1; $pos = $pos + 1;
Logging::info("Adding $ac[1] $ac[0]");
} }
//reset the positions of the remaining items. //reset the positions of the remaining items.
@ -673,6 +683,10 @@ SQL;
{ {
$this->con->beginTransaction(); $this->con->beginTransaction();
if (!isset($offset)) {
$offset = Application_Model_Preference::GetDefaultCrossfadeDuration();
}
try { try {
if (isset($id1)) { if (isset($id1)) {
$this->changeFadeInfo($id1, null, $fadeOut); $this->changeFadeInfo($id1, null, $fadeOut);
@ -729,7 +743,6 @@ SQL;
if (!is_null($offset)) { if (!is_null($offset)) {
$row->setDbTrackOffset($offset); $row->setDbTrackOffset($offset);
Logging::info("Setting offset {$offset} on item {$id}");
$row->save($this->con); $row->save($this->con);
} }
} }
@ -1071,8 +1084,7 @@ SQL;
$sql .= "END WHERE position IN ($currentPos) and playlist_id=:p1"; $sql .= "END WHERE position IN ($currentPos) and playlist_id=:p1";
Application_Common_Database::prepareAndExecute($sql, array("p1"=>$this->id)); Application_Common_Database::prepareAndExecute($sql, array("p1"=>$this->id));
$result['result'] = 0; return array('result' => 0);
return $result;
} }
public static function getAllPlaylistFiles() public static function getAllPlaylistFiles()

View file

@ -38,9 +38,11 @@ class Application_Model_Preference
$paramMap[':id'] = $userId; $paramMap[':id'] = $userId;
} }
Application_Common_Database::prepareAndExecute("LOCK TABLE cc_pref");
$result = Application_Common_Database::prepareAndExecute($sql, $result = Application_Common_Database::prepareAndExecute($sql,
$paramMap, $paramMap,
'column', Application_Common_Database::COLUMN,
PDO::FETCH_ASSOC, PDO::FETCH_ASSOC,
$con); $con);

View file

@ -30,7 +30,7 @@ AND file_id is not null
SQL; SQL;
$files = Application_Common_Database::prepareAndExecute( $sql, array()); $files = Application_Common_Database::prepareAndExecute( $sql, array());
$real_files = array(); $real_files = array();
foreach ($files as $f) { foreach ($files as $f) {
$real_files[] = $f['file_id']; $real_files[] = $f['file_id'];
@ -48,7 +48,7 @@ WHERE ends > now() AT TIME ZONE 'UTC'
AND stream_id is not null AND stream_id is not null
SQL; SQL;
$streams = Application_Common_Database::prepareAndExecute( $sql, array()); $streams = Application_Common_Database::prepareAndExecute( $sql, array());
$real_streams = array(); $real_streams = array();
foreach ($streams as $s) { foreach ($streams as $s) {
$real_streams[] = $s['stream_id']; $real_streams[] = $s['stream_id'];
@ -322,7 +322,8 @@ SQL;
ft.album_title AS file_album_title, ft.album_title AS file_album_title,
ft.length AS file_length, ft.length AS file_length,
ft.file_exists AS file_exists, ft.file_exists AS file_exists,
ft.mime AS file_mime ft.mime AS file_mime,
ft.soundcloud_id AS soundcloud_id
SQL; SQL;
$filesJoin = <<<SQL $filesJoin = <<<SQL
cc_schedule AS sched cc_schedule AS sched
@ -357,7 +358,8 @@ SQL;
ws.description AS file_album_title, ws.description AS file_album_title,
ws.length AS file_length, ws.length AS file_length,
't'::BOOL AS file_exists, 't'::BOOL AS file_exists,
ws.mime as file_mime ws.mime AS file_mime,
(SELECT NULL::integer AS soundcloud_id)
SQL; SQL;
$streamJoin = <<<SQL $streamJoin = <<<SQL
cc_schedule AS sched cc_schedule AS sched
@ -391,17 +393,17 @@ SQL;
$showPredicate = ""; $showPredicate = "";
if (count($p_shows) > 0) { if (count($p_shows) > 0) {
$params = array(); $params = array();
$map = array(); $map = array();
for ($i = 0, $len = count($p_shows); $i < $len; $i++) { for ($i = 0, $len = count($p_shows); $i < $len; $i++) {
$holder = "show_".$i; $holder = ":show_".$i;
$params[] = $holder; $params[] = $holder;
$map[$holder] = $p_shows[$i]; $map[$holder] = $p_shows[$i];
} }
$showPredicate = " AND show_id IN (".implode(",", $params).")"; $showPredicate = " AND show_id IN (".implode(",", $params).")";
$paramMap = $paramMap + $map; $paramMap = $paramMap + $map;
} else if (count($p_show_instances) > 0) { } else if (count($p_show_instances) > 0) {
@ -448,13 +450,13 @@ SQL;
":ts_6" => $p_end_str, ":ts_6" => $p_end_str,
); );
$paramMap = $paramMap + $map; $paramMap = $paramMap + $map;
$rows = Application_Common_Database::prepareAndExecute( $rows = Application_Common_Database::prepareAndExecute(
$sql, $sql,
$paramMap, $paramMap,
Application_Common_Database::ALL Application_Common_Database::ALL
); );
return $rows; return $rows;
} }
@ -475,7 +477,7 @@ SQL;
$sql .= " WHERE id=:pid"; $sql .= " WHERE id=:pid";
$map = array(":pid" => $p_id); $map = array(":pid" => $p_id);
Application_Common_Database::prepareAndExecute($sql, $map, Application_Common_Database::prepareAndExecute($sql, $map,
Application_Common_Database::EXECUTE); Application_Common_Database::EXECUTE);
} }
@ -501,9 +503,9 @@ SQL;
{ {
$sql = "SELECT count(*) as cnt FROM cc_schedule"; $sql = "SELECT count(*) as cnt FROM cc_schedule";
$res = Application_Common_Database::prepareAndExecute($sql, array(), $res = Application_Common_Database::prepareAndExecute($sql, array(),
Application_Common_Database::COLUMN); Application_Common_Database::COLUMN);
return $res; return $res;
} }
@ -706,7 +708,7 @@ SQL;
$key = "{$time}_{$i}"; $key = "{$time}_{$i}";
$i++; $i++;
} }
$data["media"][$key] = $item; $data["media"][$key] = $item;
} }
@ -755,7 +757,7 @@ SQL;
$replay_gain = is_null($item["replay_gain"]) ? "0": $item["replay_gain"]; $replay_gain = is_null($item["replay_gain"]) ? "0": $item["replay_gain"];
$replay_gain += Application_Model_Preference::getReplayGainModifier(); $replay_gain += Application_Model_Preference::getReplayGainModifier();
if ( !Application_Model_Preference::GetEnableReplayGain() ) { if ( !Application_Model_Preference::GetEnableReplayGain() ) {
$replay_gain = 0; $replay_gain = 0;
} }
@ -775,7 +777,7 @@ SQL;
'replay_gain' => $replay_gain, 'replay_gain' => $replay_gain,
'independent_event' => $independent_event, 'independent_event' => $independent_event,
); );
if ($schedule_item['cue_in'] > $schedule_item['cue_out']) { if ($schedule_item['cue_in'] > $schedule_item['cue_out']) {
$schedule_item['cue_in'] = $schedule_item['cue_out']; $schedule_item['cue_in'] = $schedule_item['cue_out'];
} }
@ -915,10 +917,10 @@ SQL;
} else { } else {
throw new Exception("Unknown schedule type: ".print_r($item, true)); throw new Exception("Unknown schedule type: ".print_r($item, true));
} }
} }
} }
/* Check if two events are less than or equal to 1 second apart /* Check if two events are less than or equal to 1 second apart
*/ */
public static function areEventsLinked($event1, $event2) { public static function areEventsLinked($event1, $event2) {
@ -996,7 +998,7 @@ SQL;
public static function deleteAll() public static function deleteAll()
{ {
$sql = "TRUNCATE TABLE cc_schedule"; $sql = "TRUNCATE TABLE cc_schedule";
Application_Common_Database::prepareAndExecute($sql, array(), Application_Common_Database::prepareAndExecute($sql, array(),
Application_Common_Database::EXECUTE); Application_Common_Database::EXECUTE);
} }
@ -1199,14 +1201,14 @@ SQL;
$update=false, $instanceId=null, $showId=null) $update=false, $instanceId=null, $showId=null)
{ {
$overlapping = false; $overlapping = false;
$params = array( $params = array(
':show_end1' => $show_end->format('Y-m-d H:i:s'), ':show_end1' => $show_end->format('Y-m-d H:i:s'),
':show_end2' => $show_end->format('Y-m-d H:i:s'), ':show_end2' => $show_end->format('Y-m-d H:i:s'),
':show_end3' => $show_end->format('Y-m-d H:i:s') ':show_end3' => $show_end->format('Y-m-d H:i:s')
); );
/* If a show is being edited, exclude it from the query /* If a show is being edited, exclude it from the query
* In both cases (new and edit) we only grab shows that * In both cases (new and edit) we only grab shows that
* are scheduled 2 days prior * are scheduled 2 days prior
@ -1277,18 +1279,18 @@ SQL;
return 'file'; return 'file';
} }
} }
public static function GetFileId($p_scheduleId) public static function GetFileId($p_scheduleId)
{ {
$scheduledItem = CcScheduleQuery::create()->findPK($p_scheduleId); $scheduledItem = CcScheduleQuery::create()->findPK($p_scheduleId);
return $scheduledItem->getDbFileId(); return $scheduledItem->getDbFileId();
} }
public static function GetStreamId($p_scheduleId) public static function GetStreamId($p_scheduleId)
{ {
$scheduledItem = CcScheduleQuery::create()->findPK($p_scheduleId); $scheduledItem = CcScheduleQuery::create()->findPK($p_scheduleId);
return $scheduledItem->getDbStreamId(); return $scheduledItem->getDbStreamId();
} }
} }

View file

@ -17,7 +17,7 @@ class Application_Model_Scheduler
private $epochNow; private $epochNow;
private $nowDT; private $nowDT;
private $user; private $user;
private $crossfadeDuration; private $crossfadeDuration;
private $checkUserPermissions = true; private $checkUserPermissions = true;
@ -40,7 +40,7 @@ class Application_Model_Scheduler
} }
$this->user = Application_Model_User::getCurrentUser(); $this->user = Application_Model_User::getCurrentUser();
$this->crossfadeDuration = Application_Model_Preference::GetDefaultCrossfadeDuration(); $this->crossfadeDuration = Application_Model_Preference::GetDefaultCrossfadeDuration();
} }
@ -85,6 +85,9 @@ class Application_Model_Scheduler
$nowEpoch = floatval($this->nowDT->format("U.u")); $nowEpoch = floatval($this->nowDT->format("U.u"));
$schedInfo = array();
$instanceInfo = array();
for ($i = 0; $i < count($items); $i++) { for ($i = 0; $i < count($items); $i++) {
$id = $items[$i]["id"]; $id = $items[$i]["id"];
@ -103,7 +106,7 @@ class Application_Model_Scheduler
} }
$schedIds = array(); $schedIds = array();
if (isset($schedInfo)) { if (count($schedInfo) > 0) {
$schedIds = array_keys($schedInfo); $schedIds = array_keys($schedInfo);
} }
$schedItems = CcScheduleQuery::create()->findPKs($schedIds, $this->con); $schedItems = CcScheduleQuery::create()->findPKs($schedIds, $this->con);
@ -191,16 +194,18 @@ class Application_Model_Scheduler
if ($type === "audioclip") { if ($type === "audioclip") {
$file = CcFilesQuery::create()->findPK($id, $this->con); $file = CcFilesQuery::create()->findPK($id, $this->con);
$storedFile = new Application_Model_StoredFile($file, $this->con);
if (is_null($file) || !$file->visible()) { if (is_null($file) || !$file->visible()) {
throw new Exception(_("A selected File does not exist!")); throw new Exception(_("A selected File does not exist!"));
} else { } else {
$data = $this->fileInfo; $data = $this->fileInfo;
$data["id"] = $id; $data["id"] = $id;
$data["cliplength"] = $storedFile->getRealClipLength(
$file->getDbCuein(), $cuein = Application_Common_DateHelper::playlistTimeToSeconds($file->getDbCuein());
$file->getDbCueout()); $cueout = Application_Common_DateHelper::playlistTimeToSeconds($file->getDbCueout());
$row_length = Application_Common_DateHelper::secondsToPlaylistTime($cueout - $cuein);
$data["cliplength"] = $row_length;
$data["cuein"] = $file->getDbCuein(); $data["cuein"] = $file->getDbCuein();
$data["cueout"] = $file->getDbCueout(); $data["cueout"] = $file->getDbCueout();
@ -263,11 +268,11 @@ class Application_Model_Scheduler
$cuein = Application_Common_DateHelper::calculateLengthInSeconds($data["cuein"]); $cuein = Application_Common_DateHelper::calculateLengthInSeconds($data["cuein"]);
$cueout = Application_Common_DateHelper::calculateLengthInSeconds($data["cueout"]); $cueout = Application_Common_DateHelper::calculateLengthInSeconds($data["cueout"]);
$data["cliplength"] = Application_Common_DateHelper::secondsToPlaylistTime($cueout - $cuein); $data["cliplength"] = Application_Common_DateHelper::secondsToPlaylistTime($cueout - $cuein);
//fade is in format SS.uuuuuu //fade is in format SS.uuuuuu
$data["fadein"] = $defaultFadeIn; $data["fadein"] = $defaultFadeIn;
$data["fadeout"] = $defaultFadeOut; $data["fadeout"] = $defaultFadeOut;
$data["type"] = 0; $data["type"] = 0;
$files[] = $data; $files[] = $data;
} }
@ -322,11 +327,11 @@ class Application_Model_Scheduler
$cuein = Application_Common_DateHelper::calculateLengthInSeconds($data["cuein"]); $cuein = Application_Common_DateHelper::calculateLengthInSeconds($data["cuein"]);
$cueout = Application_Common_DateHelper::calculateLengthInSeconds($data["cueout"]); $cueout = Application_Common_DateHelper::calculateLengthInSeconds($data["cueout"]);
$data["cliplength"] = Application_Common_DateHelper::secondsToPlaylistTime($cueout - $cuein); $data["cliplength"] = Application_Common_DateHelper::secondsToPlaylistTime($cueout - $cuein);
//fade is in format SS.uuuuuu //fade is in format SS.uuuuuu
$data["fadein"] = $defaultFadeIn; $data["fadein"] = $defaultFadeIn;
$data["fadeout"] = $defaultFadeOut; $data["fadeout"] = $defaultFadeOut;
$data["type"] = 0; $data["type"] = 0;
$files[] = $data; $files[] = $data;
} }
@ -336,7 +341,7 @@ class Application_Model_Scheduler
return $files; return $files;
} }
/* /*
* @param DateTime startDT in UTC * @param DateTime startDT in UTC
* @param string duration * @param string duration
@ -347,18 +352,18 @@ class Application_Model_Scheduler
private function findTimeDifference($p_startDT, $p_seconds) private function findTimeDifference($p_startDT, $p_seconds)
{ {
$startEpoch = $p_startDT->format("U.u"); $startEpoch = $p_startDT->format("U.u");
//add two float numbers to 6 subsecond precision //add two float numbers to 6 subsecond precision
//DateTime::createFromFormat("U.u") will have a problem if there is no decimal in the resulting number. //DateTime::createFromFormat("U.u") will have a problem if there is no decimal in the resulting number.
$newEpoch = bcsub($startEpoch , (string) $p_seconds, 6); $newEpoch = bcsub($startEpoch , (string) $p_seconds, 6);
$dt = DateTime::createFromFormat("U.u", $newEpoch, new DateTimeZone("UTC")); $dt = DateTime::createFromFormat("U.u", $newEpoch, new DateTimeZone("UTC"));
if ($dt === false) { if ($dt === false) {
//PHP 5.3.2 problem //PHP 5.3.2 problem
$dt = DateTime::createFromFormat("U", intval($newEpoch), new DateTimeZone("UTC")); $dt = DateTime::createFromFormat("U", intval($newEpoch), new DateTimeZone("UTC"));
} }
return $dt; return $dt;
} }
@ -388,7 +393,7 @@ class Application_Model_Scheduler
return $dt; return $dt;
} }
private function findNextStartTime($DT, $instance) private function findNextStartTime($DT, $instanceId)
{ {
$sEpoch = $DT->format("U.u"); $sEpoch = $DT->format("U.u");
$nEpoch = $this->epochNow; $nEpoch = $this->epochNow;
@ -410,7 +415,7 @@ class Application_Model_Scheduler
->setDbCueIn('00:00:00') ->setDbCueIn('00:00:00')
->setDbCueOut('00:00:00') ->setDbCueOut('00:00:00')
->setDbPlayoutStatus(-1) ->setDbPlayoutStatus(-1)
->setDbInstanceId($instance->getDbId()) ->setDbInstanceId($instanceId)
->save($this->con); ->save($this->con);
} else { } else {
$nextDT = $DT; $nextDT = $DT;
@ -418,39 +423,45 @@ class Application_Model_Scheduler
return $nextDT; return $nextDT;
} }
/* /*
* @param int $showInstance * @param int $showInstance
* This function recalculates the start/end times of items in a gapless show to * This function recalculates the start/end times of items in a gapless show to
* account for crossfade durations. * account for crossfade durations.
*/ */
private function calculateCrossfades($showInstance) private function calculateCrossfades($instanceId)
{ {
Logging::info("adjusting start, end times of scheduled items to account for crossfades show instance #".$showInstance); Logging::info("adjusting start, end times of scheduled items to account for crossfades show instance #".$instanceId);
$instance = CcShowInstancesQuery::create()->findPK($showInstance, $this->con);
if (is_null($instance)) {
throw new OutDatedScheduleException(_("The schedule you're viewing is out of date!"));
}
$itemStartDT = $instance->getDbStarts(null);
$itemEndDT = null;
$schedule = CcScheduleQuery::create()
->filterByDbInstanceId($showInstance)
->orderByDbStarts()
->find($this->con);
foreach ($schedule as $item) {
$itemEndDT = $this->findEndTime($itemStartDT, $item->getDbClipLength());
$item->setDbStarts($itemStartDT) $sql = "SELECT * FROM cc_show_instances ".
->setDbEnds($itemEndDT); "WHERE id = {$instanceId}";
$instance = Application_Common_Database::prepareAndExecute(
$sql, array(), Application_Common_Database::SINGLE);
$itemStartDT = $this->findTimeDifference($itemEndDT, $this->crossfadeDuration); if (is_null($instance)) {
} throw new OutDatedScheduleException(_("The schedule you're viewing is out of date!"));
}
$schedule->save($this->con);
$itemStartDT = new DateTime($instance["starts"], new DateTimeZone("UTC"));
$itemEndDT = null;
$schedule_sql = "SELECT * FROM cc_schedule ".
"WHERE instance_id = {$instanceId} ".
"ORDER BY starts";
$schedule = Application_Common_Database::prepareAndExecute($schedule_sql);
foreach ($schedule as $item) {
$itemEndDT = $this->findEndTime($itemStartDT, $item["clip_length"]);
$update_sql = "UPDATE cc_schedule SET ".
"starts = '{$itemStartDT->format("Y-m-d H:i:s")}', ".
"ends = '{$itemEndDT->format("Y-m-d H:i:s")}' ".
"WHERE id = {$item["id"]}";
Application_Common_Database::prepareAndExecute(
$update_sql, array(), Application_Common_Database::EXECUTE);
$itemStartDT = $this->findTimeDifference($itemEndDT, $this->crossfadeDuration);
}
} }
/* /*
@ -491,7 +502,7 @@ class Application_Model_Scheduler
} }
/** /**
* *
* Enter description here ... * Enter description here ...
* @param $scheduleItems * @param $scheduleItems
* cc_schedule items, where the items get inserted after * cc_schedule items, where the items get inserted after
@ -531,12 +542,18 @@ class Application_Model_Scheduler
* of inserted items * of inserted items
*/ */
if ($id != 0) { if ($id != 0) {
$ccSchedule = CcScheduleQuery::create()->findPk($id); $schedule_sql = "SELECT * FROM cc_schedule WHERE id = ".$id;
$ccShowInstance = CcShowInstancesQuery::create()->findPk($ccSchedule->getDbInstanceId()); $ccSchedule = Application_Common_Database::prepareAndExecute(
$ccShow = $ccShowInstance->getCcShow(); $schedule_sql, array(), Application_Common_Database::SINGLE);
$linked = $ccShow->isLinked();
$show_sql = "SELECT * FROM cc_show WHERE id IN (".
"SELECT show_id FROM cc_show_instances WHERE id = ".$ccSchedule["instance_id"].")";
$ccShow = Application_Common_Database::prepareAndExecute(
$show_sql, array(), Application_Common_Database::SINGLE);
$linked = $ccShow["linked"];
if ($linked) { if ($linked) {
$unique = $ccShow->getDbId() . $ccSchedule->getDbPosition(); $unique = $ccShow["id"] . $ccSchedule["position"];
if (!in_array($unique, $temp)) { if (!in_array($unique, $temp)) {
$temp[] = $unique; $temp[] = $unique;
} else { } else {
@ -544,11 +561,14 @@ class Application_Model_Scheduler
} }
} }
} else { } else {
$ccShowInstance = CcShowInstancesQuery::create()->findPk($schedule["instance"]); $show_sql = "SELECT * FROM cc_show WHERE id IN (".
$ccShow = $ccShowInstance->getccShow(); "SELECT show_id FROM cc_show_instances WHERE id = ".$schedule["instance"].")";
$linked = $ccShow->isLinked(); $ccShow = Application_Common_Database::prepareAndExecute(
$show_sql, array(), Application_Common_Database::SINGLE);
$linked = $ccShow["linked"];
if ($linked) { if ($linked) {
$unique = $ccShow->getDbId() . "a"; $unique = $ccShow["id"] . "a";
if (!in_array($unique, $temp)) { if (!in_array($unique, $temp)) {
$temp[] = $unique; $temp[] = $unique;
} else { } else {
@ -562,38 +582,59 @@ class Application_Model_Scheduler
* to that show * to that show
*/ */
if ($linked) { if ($linked) {
$instances = $ccShow->getCcShowInstancess(); $instance_sql = "SELECT * FROM cc_show_instances ".
"WHERE show_id = ".$ccShow["id"];
$instances = Application_Common_Database::prepareAndExecute(
$instance_sql);
} else { } else {
$instances = array($ccShowInstance); $instance_sql = "SELECT * FROM cc_show_instances ".
"WHERE id = ".$schedule["instance"];
$instances = Application_Common_Database::prepareAndExecute(
$instance_sql);
} }
$excludePositions = array();
foreach($instances as &$instance) { foreach($instances as &$instance) {
$instanceId = $instance->getDbId(); $instanceId = $instance["id"];
if ($id !== 0) { if ($id !== 0) {
/* We use the selected cursor's position to find the same /* We use the selected cursor's position to find the same
* positions in every other linked instance * positions in every other linked instance
*/ */
$pos = $ccSchedule->getDbPosition(); $pos = $ccSchedule["position"];
$linkCcSchedule = CcScheduleQuery::create() $linkedItem_sql = "SELECT ends FROM cc_schedule ".
->filterByDbInstanceId($instanceId) "WHERE instance_id = {$instanceId} ".
->filterByDbPosition($pos) "AND position = {$pos} ".
->findOne(); "AND playout_status != -1";
$linkedItemEnds = Application_Common_Database::prepareAndExecute(
$linkedItem_sql, array(), Application_Common_Database::COLUMN);
$schedItemEndDT = $linkCcSchedule->getDbEnds(null); $nextStartDT = $this->findNextStartTime(
$nextStartDT = $this->findNextStartTime($schedItemEndDT, $instance); new DateTime($linkedItemEnds, new DateTimeZone("UTC")),
$instanceId);
$pos++; $pos++;
/* Show is not empty so we need to apply crossfades
* for the first inserted item
*/
$applyCrossfades = true;
} }
//selected empty row to add after //selected empty row to add after
else { else {
$showStartDT = $instance->getDbStarts(null); $showStartDT = new DateTime($instance["starts"], new DateTimeZone("UTC"));
$nextStartDT = $this->findNextStartTime($showStartDT, $instance); $nextStartDT = $this->findNextStartTime($showStartDT, $instanceId);
//show is empty so start position counter at 0 //first item in show so start position counter at 0
$pos = 0; $pos = 0;
/* Show is empty so we don't need to calculate crossfades
* for the first inserted item
*/
$applyCrossfades = false;
} }
if (!in_array($instance->getDbId(), $affectedShowInstances)) { if (!in_array($instanceId, $affectedShowInstances)) {
$affectedShowInstances[] = $instanceId; $affectedShowInstances[] = $instanceId;
} }
@ -605,7 +646,12 @@ class Application_Model_Scheduler
$pstart = microtime(true); $pstart = microtime(true);
$initalStartDT = clone $nextStartDT; if ($applyCrossfades) {
$initalStartDT = clone $this->findTimeDifference(
$nextStartDT, $this->crossfadeDuration);
} else {
$initalStartDT = clone $nextStartDT;
}
$pend = microtime(true); $pend = microtime(true);
Logging::debug("finding all following items."); Logging::debug("finding all following items.");
@ -620,83 +666,129 @@ class Application_Model_Scheduler
} }
} }
$doInsert = false;
$doUpdate = false;
$values = array();
foreach ($filesToInsert as &$file) { foreach ($filesToInsert as &$file) {
//item existed previously and is being moved. //item existed previously and is being moved.
//need to keep same id for resources if we want REST. //need to keep same id for resources if we want REST.
if (isset($file['sched_id'])) { if (isset($file['sched_id'])) {
$sched = CcScheduleQuery::create()->findPk($file["sched_id"]); $adjustFromDT = clone $nextStartDT;
$doUpdate = true;
$movedItem_sql = "SELECT * FROM cc_schedule ".
"WHERE id = ".$file["sched_id"];
$sched = Application_Common_Database::prepareAndExecute(
$movedItem_sql, array(), Application_Common_Database::SINGLE);
/* We need to keep a record of the original positon a track /* We need to keep a record of the original positon a track
* is being moved from so we can use it to retrieve the correct * is being moved from so we can use it to retrieve the correct
* items in linked instances * items in linked instances
*/ */
if (!isset($originalPosition)) { if (!isset($originalPosition)) {
$originalPosition = $sched->getDbPosition(); $originalPosition = $sched["position"];
} }
/* If we are moving an item in a linked show we need to get /* If we are moving an item in a linked show we need to get
* the relative item to move in each instance. We know what the * the relative item to move in each instance. We know what the
* relative item is by its position * relative item is by its position
*/ */
if ($linked && $moveAction) { if ($linked) {
$sched = CcScheduleQuery::create() $movedItem_sql = "SELECT * FROM cc_schedule ".
->filterByDbInstanceId($instanceId) "WHERE position = {$originalPosition} ".
->filterByDbPosition($originalPosition) "AND instance_id = {$instanceId}";
->findOne();
}
$excludeIds[] = intval($sched->getDbId());
$file["cliplength"] = $sched->getDbClipLength(); $sched = Application_Common_Database::prepareAndExecute(
$file["cuein"] = $sched->getDbCueIn(); $movedItem_sql, array(), Application_Common_Database::SINGLE);
$file["cueout"] = $sched->getDbCueOut(); }
$file["fadein"] = $sched->getDbFadeIn(); $excludeIds[] = intval($sched["id"]);
$file["fadeout"] = $sched->getDbFadeOut();
$file["cliplength"] = $sched["clip_length"];
$file["cuein"] = $sched["cue_in"];
$file["cueout"] = $sched["cue_out"];
$file["fadein"] = $sched["fade_in"];
$file["fadeout"] = $sched["fade_out"];
} else { } else {
$sched = new CcSchedule(); $doInsert = true;
} }
$endTimeDT = $this->findEndTime($nextStartDT, $file['cliplength']);
// default fades are in seconds // default fades are in seconds
// we need to convert to '00:00:00' format // we need to convert to '00:00:00' format
$file['fadein'] = Application_Common_DateHelper::secondsToPlaylistTime($file['fadein']); $file['fadein'] = Application_Common_DateHelper::secondsToPlaylistTime($file['fadein']);
$file['fadeout'] = Application_Common_DateHelper::secondsToPlaylistTime($file['fadeout']); $file['fadeout'] = Application_Common_DateHelper::secondsToPlaylistTime($file['fadeout']);
$sched->setDbStarts($nextStartDT)
->setDbEnds($endTimeDT)
->setDbCueIn($file['cuein'])
->setDbCueOut($file['cueout'])
->setDbFadeIn($file['fadein'])
->setDbFadeOut($file['fadeout'])
->setDbClipLength($file['cliplength'])
->setDbPosition($pos);
if (!$moveAction) {
$sched->setDbInstanceId($instanceId);
}
switch ($file["type"]) { switch ($file["type"]) {
case 0: case 0:
$sched->setDbFileId($file['id']); $fileId = $file["id"];
$streamId = "null";
break; break;
case 1: case 1:
$sched->setDbStreamId($file['id']); $streamId = $file["id"];
$fileId = "null";
break; break;
default: break; default: break;
} }
$sched->save($this->con); if ($applyCrossfades) {
$nextStartDT = $this->findTimeDifference($nextStartDT,
$this->crossfadeDuration);
$endTimeDT = $this->findEndTime($nextStartDT, $file['cliplength']);
$endTimeDT = $this->findTimeDifference($endTimeDT, $this->crossfadeDuration);
/* Set it to false because the rest of the crossfades
* will be applied after we insert each item
*/
$applyCrossfades = false;
}
$nextStartDT = $endTimeDT; $endTimeDT = $this->findEndTime($nextStartDT, $file['cliplength']);
if ($doInsert) {
$values[] = "(".
"'{$nextStartDT->format("Y-m-d H:i:s")}', ".
"'{$endTimeDT->format("Y-m-d H:i:s")}', ".
"'{$file["cuein"]}', ".
"'{$file["cueout"]}', ".
"'{$file["fadein"]}', ".
"'{$file["fadeout"]}', ".
"'{$file["cliplength"]}', ".
"{$pos}, ".
"{$instanceId}, ".
"{$fileId}, ".
"{$streamId})";
} elseif ($doUpdate) {
$update_sql = "UPDATE cc_schedule SET ".
"starts = '{$nextStartDT->format("Y-m-d H:i:s")}', ".
"ends = '{$endTimeDT->format("Y-m-d H:i:s")}', ".
"cue_in = '{$file["cuein"]}', ".
"cue_out = '{$file["cueout"]}', ".
"fade_in = '{$file["fadein"]}', ".
"fade_out = '{$file["fadeout"]}', ".
"clip_length = '{$file["cliplength"]}', ".
"position = {$pos} ".
"WHERE id = {$sched["id"]}";
Application_Common_Database::prepareAndExecute(
$update_sql, array(), Application_Common_Database::EXECUTE);
}
$nextStartDT = $this->findTimeDifference($endTimeDT, $this->crossfadeDuration);
$pos++; $pos++;
/* If we are adjusting start and end times for items
* after the insert location, we need to exclude the
* schedule item we just inserted because it has correct
* start and end times*/
$excludeIds[] = $sched->getDbId();
}//all files have been inserted/moved }//all files have been inserted/moved
if ($doInsert) {
$insert_sql = "INSERT INTO cc_schedule ".
"(starts, ends, cue_in, cue_out, fade_in, fade_out, ".
"clip_length, position, instance_id, file_id, stream_id) VALUES ".
implode($values, ",")." RETURNING id";
$stmt = $this->con->prepare($insert_sql);
if ($stmt->execute()) {
foreach ($stmt->fetchAll() as $row) {
$excludeIds[] = $row["id"];
}
};
}
// update is_scheduled flag for each cc_file // update is_scheduled flag for each cc_file
$fileIds = array(); $fileIds = array();
foreach ($filesToInsert as &$file) { foreach ($filesToInsert as &$file) {
@ -717,34 +809,43 @@ class Application_Model_Scheduler
} }
if ($adjustSched === true) { if ($adjustSched === true) {
$followingSchedItems = CcScheduleQuery::create()
->filterByDBStarts($initalStartDT->format("Y-m-d H:i:s.u"), Criteria::GREATER_EQUAL) $followingItems_sql = "SELECT * FROM cc_schedule ".
->filterByDbInstanceId($instance->getDbId()) "WHERE starts >= '{$initalStartDT->format("Y-m-d H:i:s.u")}' ".
->filterByDbId($excludeIds, Criteria::NOT_IN) "AND instance_id = {$instanceId} ";
->orderByDbStarts() if (count($excludeIds) > 0) {
->find($this->con); $followingItems_sql .= "AND id NOT IN (". implode($excludeIds, ",").") ";
}
$followingItems_sql .= "ORDER BY starts";
$followingSchedItems = Application_Common_Database::prepareAndExecute(
$followingItems_sql);
$pstart = microtime(true); $pstart = microtime(true);
//recalculate the start/end times after the inserted items. //recalculate the start/end times after the inserted items.
foreach ($followingSchedItems as $item) { foreach ($followingSchedItems as $item) {
$endTimeDT = $this->findEndTime($nextStartDT, $item->getDbClipLength()); $endTimeDT = $this->findEndTime($nextStartDT, $item["clip_length"]);
$item->setDbStarts($nextStartDT); $endTimeDT = $this->findTimeDifference($endTimeDT, $this->crossfadeDuration);
$item->setDbEnds($endTimeDT); $update_sql = "UPDATE cc_schedule SET ".
$item->setDbPosition($pos); "starts = '{$nextStartDT->format("Y-m-d H:i:s")}', ".
$item->save($this->con); "ends = '{$endTimeDT->format("Y-m-d H:i:s")}', ".
$nextStartDT = $endTimeDT; "position = {$pos} ".
"WHERE id = {$item["id"]}";
Application_Common_Database::prepareAndExecute(
$update_sql, array(), Application_Common_Database::EXECUTE);
$nextStartDT = $this->findTimeDifference($endTimeDT, $this->crossfadeDuration);
$pos++; $pos++;
} }
$pend = microtime(true); $pend = microtime(true);
Logging::debug("adjusting all following items."); Logging::debug("adjusting all following items.");
Logging::debug(floatval($pend) - floatval($pstart)); Logging::debug(floatval($pend) - floatval($pstart));
}
$this->calculateCrossfades($instance->getDbId()); if ($moveAction) {
$this->calculateCrossfades($instanceId);
} }
}//for each instance }//for each instance
}//for each schedule location }//for each schedule location
$endProfile = microtime(true); $endProfile = microtime(true);
@ -782,6 +883,11 @@ class Application_Model_Scheduler
} }
} }
private function updateMovedItem()
{
}
private function getInstances($instanceId) private function getInstances($instanceId)
{ {
$ccShowInstance = CcShowInstancesQuery::create()->findPk($instanceId); $ccShowInstance = CcShowInstancesQuery::create()->findPk($instanceId);
@ -999,7 +1105,7 @@ class Application_Model_Scheduler
} else { } else {
$removedItem->delete($this->con); $removedItem->delete($this->con);
} }
// update is_scheduled in cc_files but only if // update is_scheduled in cc_files but only if
// the file is not scheduled somewhere else // the file is not scheduled somewhere else
$fileId = $removedItem->getDbFileId(); $fileId = $removedItem->getDbFileId();

View file

@ -388,6 +388,7 @@ class Application_Model_ShowBuilder
$outdated = false; $outdated = false;
$shows = Application_Model_Show::getShows($this->startDT, $this->endDT); $shows = Application_Model_Show::getShows($this->startDT, $this->endDT);
$include = array();
if ($this->opts["showFilter"] !== 0) { if ($this->opts["showFilter"] !== 0) {
$include[] = $this->opts["showFilter"]; $include[] = $this->opts["showFilter"];
} elseif ($this->opts["myShows"] === 1) { } elseif ($this->opts["myShows"] === 1) {

View file

@ -352,10 +352,10 @@ SQL;
); );
//only need to check overlap if show increased in size. //only need to check overlap if show increased in size.
if (strtotime($new_ends) > strtotime($ends)) { if (strtotime($now_ends) > strtotime($ends)) {
$utcStartDateTime = new DateTime($ends, new DateTimeZone("UTC")); $utcStartDateTime = new DateTime($ends, new DateTimeZone("UTC"));
$utcEndDateTime = new DateTime($new_ends, new DateTimeZone("UTC")); $utcEndDateTime = new DateTime($now_ends, new DateTimeZone("UTC"));
$overlap = Application_Model_Show::getShows($utcStartDateTime, $utcEndDateTime); $overlap = Application_Model_Show::getShows($utcStartDateTime, $utcEndDateTime);
@ -381,7 +381,7 @@ SQL;
} }
$this->setShowEnd($new_ends); $this->setShowEnd($now_ends);
Application_Model_RabbitMq::PushSchedule(); Application_Model_RabbitMq::PushSchedule();
} }

View file

@ -150,7 +150,7 @@ class Application_Model_StoredFile
} }
} }
$dbMd[constant($mdConst)] = $mdValue; $dbMd[constant($mdConst)] = $mdValue;
} }
} }
$this->setDbColMetadata($dbMd); $this->setDbColMetadata($dbMd);
@ -214,7 +214,7 @@ class Application_Model_StoredFile
if (isset($this->_dbMD[$dbColumn])) { if (isset($this->_dbMD[$dbColumn])) {
$propelColumn = $this->_dbMD[$dbColumn]; $propelColumn = $this->_dbMD[$dbColumn];
$method = "set$propelColumn"; $method = "set$propelColumn";
/* We need to set track_number to null if it is an empty string /* We need to set track_number to null if it is an empty string
* because propel defaults empty strings to zeros */ * because propel defaults empty strings to zeros */
if ($dbColumn == "track_number" && empty($mdValue)) $mdValue = null; if ($dbColumn == "track_number" && empty($mdValue)) $mdValue = null;
@ -330,7 +330,7 @@ SQL;
$stmt = $con->prepare($sql); $stmt = $con->prepare($sql);
$stmt->bindParam(':file_id', $this->id, PDO::PARAM_INT); $stmt->bindParam(':file_id', $this->id, PDO::PARAM_INT);
if ($stmt->execute()) { if ($stmt->execute()) {
$ids = $stmt->fetchAll(); $ids = $stmt->fetchAll();
} else { } else {
@ -386,7 +386,7 @@ SQL;
// set hidden flag to true // set hidden flag to true
$this->_file->setDbHidden(true); $this->_file->setDbHidden(true);
$this->_file->save(); $this->_file->save();
// need to explicitly update any playlist's and block's length // need to explicitly update any playlist's and block's length
// that contains the file getting deleted // that contains the file getting deleted
$fileId = $this->_file->getDbId(); $fileId = $this->_file->getDbId();
@ -396,7 +396,7 @@ SQL;
$pl->setDbLength($pl->computeDbLength(Propel::getConnection(CcPlaylistPeer::DATABASE_NAME))); $pl->setDbLength($pl->computeDbLength(Propel::getConnection(CcPlaylistPeer::DATABASE_NAME)));
$pl->save(); $pl->save();
} }
$blRows = CcBlockcontentsQuery::create()->filterByDbFileId($fileId)->find(); $blRows = CcBlockcontentsQuery::create()->filterByDbFileId($fileId)->find();
foreach ($blRows as $row) { foreach ($blRows as $row) {
$bl = CcBlockQuery::create()->filterByDbId($row->getDbBlockId())->findOne(); $bl = CcBlockQuery::create()->filterByDbId($row->getDbBlockId())->findOne();
@ -506,19 +506,19 @@ SQL;
public function getFileUrl() public function getFileUrl()
{ {
$CC_CONFIG = Config::getConfig(); $CC_CONFIG = Config::getConfig();
$protocol = empty($_SERVER['HTTPS']) ? "http" : "https"; $protocol = empty($_SERVER['HTTPS']) ? "http" : "https";
$serverName = $_SERVER['SERVER_NAME']; $serverName = $_SERVER['SERVER_NAME'];
$serverPort = $_SERVER['SERVER_PORT']; $serverPort = $_SERVER['SERVER_PORT'];
$subDir = $CC_CONFIG['baseDir']; $subDir = $CC_CONFIG['baseDir'];
if ($subDir[0] === "/") { if ($subDir[0] === "/") {
$subDir = substr($subDir, 1, strlen($subDir) - 1); $subDir = substr($subDir, 1, strlen($subDir) - 1);
} }
$baseUrl = "{$protocol}://{$serverName}:{$serverPort}/{$subDir}"; $baseUrl = "{$protocol}://{$serverName}:{$serverPort}/{$subDir}";
return $this->getRelativeFileUrl($baseUrl); return $this->getRelativeFileUrl($baseUrl);
} }
@ -528,8 +528,6 @@ SQL;
*/ */
public function getRelativeFileUrl($baseUrl) public function getRelativeFileUrl($baseUrl)
{ {
Logging::debug("Zend base url: $baseUrl");
return $baseUrl."api/get-media/file/".$this->getId().".".$this->getFileExtension(); return $baseUrl."api/get-media/file/".$this->getId().".".$this->getFileExtension();
} }
@ -643,7 +641,7 @@ SQL;
public static function searchLibraryFiles($datatables) public static function searchLibraryFiles($datatables)
{ {
$baseUrl = Application_Common_OsPath::getBaseDir(); $baseUrl = Application_Common_OsPath::getBaseDir();
$con = Propel::getConnection(CcFilesPeer::DATABASE_NAME); $con = Propel::getConnection(CcFilesPeer::DATABASE_NAME);
$displayColumns = self::getLibraryColumns(); $displayColumns = self::getLibraryColumns();
@ -780,16 +778,18 @@ SQL;
foreach ($results['aaData'] as &$row) { foreach ($results['aaData'] as &$row) {
$row['id'] = intval($row['id']); $row['id'] = intval($row['id']);
$len_formatter = new LengthFormatter($row['length']);
$row['length'] = $len_formatter->format();
$cuein_formatter = new LengthFormatter($row["cuein"]);
$row["cuein"] = $cuein_formatter->format();
$cueout_formatter = new LengthFormatter($row["cueout"]);
$row["cueout"] = $cueout_formatter->format();
if ($row['ftype'] === "audioclip") { if ($row['ftype'] === "audioclip") {
$cuein_formatter = new LengthFormatter($row["cuein"]);
$row["cuein"] = $cuein_formatter->format();
$cueout_formatter = new LengthFormatter($row["cueout"]);
$row["cueout"] = $cueout_formatter->format();
$cuein = Application_Common_DateHelper::playlistTimeToSeconds($row["cuein"]);
$cueout = Application_Common_DateHelper::playlistTimeToSeconds($row["cueout"]);
$row_length = Application_Common_DateHelper::secondsToPlaylistTime($cueout - $cuein);
$formatter = new SamplerateFormatter($row['sample_rate']); $formatter = new SamplerateFormatter($row['sample_rate']);
$row['sample_rate'] = $formatter->format(); $row['sample_rate'] = $formatter->format();
@ -798,13 +798,20 @@ SQL;
//soundcloud status //soundcloud status
$file = Application_Model_StoredFile::RecallById($row['id']); $file = Application_Model_StoredFile::RecallById($row['id']);
$row['soundcloud_status'] = $file->getSoundCloudId(); $row['soundcloud_id'] = $file->getSoundCloudId();
// for audio preview // for audio preview
$row['audioFile'] = $row['id'].".".pathinfo($row['filepath'], PATHINFO_EXTENSION); $row['audioFile'] = $row['id'].".".pathinfo($row['filepath'], PATHINFO_EXTENSION);
} else {
$row['audioFile'] = $row['id'];
} }
else {
$row['audioFile'] = $row['id'];
$row_length = $row['length'];
}
$len_formatter = new LengthFormatter($row_length);
$row['length'] = $len_formatter->format();
//convert mtime and utime to localtime //convert mtime and utime to localtime
$row['mtime'] = new DateTime($row['mtime'], new DateTimeZone('UTC')); $row['mtime'] = new DateTime($row['mtime'], new DateTimeZone('UTC'));
@ -895,7 +902,7 @@ SQL;
$in = fopen($_FILES['file']['tmp_name'], "rb"); $in = fopen($_FILES['file']['tmp_name'], "rb");
if ($in) { if ($in) {
while ($buff = fread($in, 4096)) while (($buff = fread($in, 4096)))
fwrite($out, $buff); fwrite($out, $buff);
} else } else
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": _("Failed to open input stream.")}, "id" : "id"}'); die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": _("Failed to open input stream.")}, "id" : "id"}');
@ -914,7 +921,7 @@ SQL;
$in = fopen("php://input", "rb"); $in = fopen("php://input", "rb");
if ($in) { if ($in) {
while ($buff = fread($in, 4096)) while (($buff = fread($in, 4096)))
fwrite($out, $buff); fwrite($out, $buff);
} else } else
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": _("Failed to open input stream.")}, "id" : "id"}'); die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": _("Failed to open input stream.")}, "id" : "id"}');
@ -963,6 +970,7 @@ SQL;
// Check if we have enough space before copying // Check if we have enough space before copying
if (!self::isEnoughDiskSpaceToCopy($stor, $audio_file)) { if (!self::isEnoughDiskSpaceToCopy($stor, $audio_file)) {
$freeSpace = disk_free_space($stor); $freeSpace = disk_free_space($stor);
$fileSize = filesize($audio_file);
return array("code" => 107, return array("code" => 107,
"message" => sprintf(_("The file was not uploaded, there is " "message" => sprintf(_("The file was not uploaded, there is "
@ -1030,7 +1038,7 @@ SQL;
$LIQUIDSOAP_ERRORS = array('TagLib: MPEG::Properties::read() -- Could not find a valid last MPEG frame in the stream.'); $LIQUIDSOAP_ERRORS = array('TagLib: MPEG::Properties::read() -- Could not find a valid last MPEG frame in the stream.');
// Ask Liquidsoap if file is playable // Ask Liquidsoap if file is playable
$ls_command = sprintf('/usr/bin/airtime-liquidsoap -v -c "output.dummy(audio_to_stereo(single(%s)))" 2>&1', $ls_command = sprintf('/usr/bin/airtime-liquidsoap -v -c "output.dummy(audio_to_stereo(single(%s)))" 2>&1',
escapeshellarg($audio_file)); escapeshellarg($audio_file));
$command = "export PATH=/usr/local/bin:/usr/bin:/bin/usr/bin/ && $ls_command"; $command = "export PATH=/usr/local/bin:/usr/bin:/bin/usr/bin/ && $ls_command";
@ -1070,14 +1078,14 @@ SQL;
$stmt = $con->prepare($sql); $stmt = $con->prepare($sql);
$stmt->bindParam(':dir_id', $dir_id); $stmt->bindParam(':dir_id', $dir_id);
if ($stmt->execute()) { if ($stmt->execute()) {
$rows = $stmt->fetchAll(); $rows = $stmt->fetchAll();
} else { } else {
$msg = implode(',', $stmt->errorInfo()); $msg = implode(',', $stmt->errorInfo());
throw new Exception("Error: $msg"); throw new Exception("Error: $msg");
} }
$results = array(); $results = array();
foreach ($rows as $row) { foreach ($rows as $row) {
$results[] = $row["fp"]; $results[] = $row["fp"];
@ -1113,10 +1121,10 @@ SQL;
return $rows; return $rows;
} }
public static function getAllFilesWithoutSilan() { public static function getAllFilesWithoutSilan() {
$con = Propel::getConnection(); $con = Propel::getConnection();
$sql = <<<SQL $sql = <<<SQL
SELECT f.id, SELECT f.id,
m.directory || f.filepath AS fp m.directory || f.filepath AS fp
@ -1126,14 +1134,14 @@ WHERE file_exists = 'TRUE'
AND silan_check IS FALSE Limit 100 AND silan_check IS FALSE Limit 100
SQL; SQL;
$stmt = $con->prepare($sql); $stmt = $con->prepare($sql);
if ($stmt->execute()) { if ($stmt->execute()) {
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
} else { } else {
$msg = implode(',', $stmt->errorInfo()); $msg = implode(',', $stmt->errorInfo());
throw new Exception("Error: $msg"); throw new Exception("Error: $msg");
} }
return $rows; return $rows;
} }
@ -1229,7 +1237,7 @@ SQL;
->save(); ->save();
} }
// This method seems to be unsued everywhere so I've commented it out // This method seems to be unsued everywhere so I've commented it out
// If it's absence does not have any effect then it will be completely // If it's absence does not have any effect then it will be completely
// removed soon // removed soon
@ -1257,7 +1265,7 @@ SQL;
$description = $file->getDbTrackTitle(); $description = $file->getDbTrackTitle();
$tag = array(); $tag = array();
$genre = $file->getDbGenre(); $genre = $file->getDbGenre();
$release = $file->getDbYear(); $release = $file->getDbUtime();
try { try {
$soundcloud = new Application_Model_Soundcloud(); $soundcloud = new Application_Model_Soundcloud();
$soundcloud_res = $soundcloud->uploadTrack( $soundcloud_res = $soundcloud->uploadTrack(
@ -1286,7 +1294,7 @@ SQL;
} }
} }
} }
public static function setIsPlaylist($p_playlistItems, $p_type, $p_status) { public static function setIsPlaylist($p_playlistItems, $p_type, $p_status) {
foreach ($p_playlistItems as $item) { foreach ($p_playlistItems as $item) {
$file = self::RecallById($item->getDbFileId()); $file = self::RecallById($item->getDbFileId());
@ -1304,7 +1312,7 @@ SQL;
} }
} }
} }
public static function setIsScheduled($p_scheduleItem, $p_status, public static function setIsScheduled($p_scheduleItem, $p_status,
$p_fileId=null) { $p_fileId=null) {
@ -1347,14 +1355,6 @@ SQL;
Application_Common_Database::prepareAndExecute($sql, array(), Application_Common_Database::prepareAndExecute($sql, array(),
Application_Common_Database::EXECUTE); Application_Common_Database::EXECUTE);
} }
public function getRealClipLength($p_cuein, $p_cueout) {
$sql = "SELECT :cueout::INTERVAL - :cuein::INTERVAL";
return Application_Common_Database::prepareAndExecute($sql, array(
':cueout' => $p_cueout,
':cuein' => $p_cuein), 'column');
}
} }
class DeleteScheduledFileException extends Exception {} class DeleteScheduledFileException extends Exception {}

View file

@ -125,6 +125,7 @@ class Application_Model_Systemstatus
public static function GetPlatformInfo() public static function GetPlatformInfo()
{ {
$keys = array("release", "machine", "memory", "swap"); $keys = array("release", "machine", "memory", "swap");
$data = array();
foreach ($keys as $key) { foreach ($keys as $key) {
$data[$key] = "UNKNOWN"; $data[$key] = "UNKNOWN";
} }
@ -212,7 +213,7 @@ class Application_Model_Systemstatus
public static function GetDiskInfo() public static function GetDiskInfo()
{ {
$partions = array(); $partitions = array();
//connect to DB and find how much total space user has allocated. //connect to DB and find how much total space user has allocated.
$totalSpace = Application_Model_Preference::GetDiskQuota(); $totalSpace = Application_Model_Preference::GetDiskQuota();

View file

@ -226,7 +226,7 @@ class Application_Model_User
public function deleteAllFiles() public function deleteAllFiles()
{ {
$my_files = $this->getOwnedFiles(); $my_files = $this->getOwnedFiles();
foreach ($files as $file) { foreach ($my_files as $file) {
$file->delete(); $file->delete();
} }
} }

View file

@ -57,6 +57,14 @@ class CcFiles extends BaseCcFiles {
return $this; return $this;
} }
public function setDbTrackNumber($v)
{
$max = pow(2, 31)-1;
$v = ($v > $max) ? $max : $v;
return parent::setDbTrackNumber($v);
}
// returns true if the file exists and is not hidden // returns true if the file exists and is not hidden
public function visible() { public function visible() {
return $this->getDbFileExists() && !$this->getDbHidden(); return $this->getDbFileExists() && !$this->getDbHidden();

View file

@ -77,9 +77,9 @@ class Application_Service_CalendarService
//Show content can be modified from the calendar if: //Show content can be modified from the calendar if:
// the show has not started, // the show has not started,
// the user is admin or hosting the show, // the user is admin or hosting the show,
// the show is not recorded or rebroadcasted // the show is not recorded
if ($now < $start && ($isAdminOrPM || $isHostOfShow) && if ($now < $start && ($isAdminOrPM || $isHostOfShow) &&
!$this->ccShowInstance->isRecorded() && !$this->ccShowInstance->isRebroadcast()) { !$this->ccShowInstance->isRecorded() ) {
$menu["schedule"] = array( $menu["schedule"] = array(
"name"=> _("Add / Remove Content"), "name"=> _("Add / Remove Content"),
@ -117,7 +117,7 @@ class Application_Service_CalendarService
} }
$isRepeating = $this->ccShow->getFirstCcShowDay()->isRepeating(); $isRepeating = $this->ccShow->getFirstCcShowDay()->isRepeating();
if (!$this->ccShowInstance->isRebroadcast()) { if (!$this->ccShowInstance->isRebroadcast() && $isAdminOrPM) {
if ($isRepeating) { if ($isRepeating) {
$menu["edit"] = array( $menu["edit"] = array(
"name" => _("Edit"), "name" => _("Edit"),
@ -328,4 +328,4 @@ class Application_Service_CalendarService
} }
} }
} }

View file

@ -148,6 +148,24 @@ class Application_Service_SchedulerService
return $dt; return $dt;
} }
private static function findTimeDifference($p_startDT, $p_seconds)
{
$startEpoch = $p_startDT->format("U.u");
//add two float numbers to 6 subsecond precision
//DateTime::createFromFormat("U.u") will have a problem if there is no decimal in the resulting number.
$newEpoch = bcsub($startEpoch , (string) $p_seconds, 6);
$dt = DateTime::createFromFormat("U.u", $newEpoch, new DateTimeZone("UTC"));
if ($dt === false) {
//PHP 5.3.2 problem
$dt = DateTime::createFromFormat("U", intval($newEpoch), new DateTimeZone("UTC"));
}
return $dt;
}
public static function fillNewLinkedInstances($ccShow) public static function fillNewLinkedInstances($ccShow)
{ {
/* First check if any linked instances have content /* First check if any linked instances have content
@ -155,64 +173,98 @@ class Application_Service_SchedulerService
* any other instances with content * any other instances with content
*/ */
$instanceIds = $ccShow->getInstanceIds(); $instanceIds = $ccShow->getInstanceIds();
$ccSchedules = CcScheduleQuery::create() $schedule_sql = "SELECT * FROM cc_schedule ".
->filterByDbInstanceId($instanceIds, Criteria::IN) "WHERE instance_id IN (".implode($instanceIds, ",").")";
->find(); $ccSchedules = Application_Common_Database::prepareAndExecute(
if (!$ccSchedules->isEmpty()) { $schedule_sql);
if (count($ccSchedules) > 0) {
/* Find the show contents of just one of the instances. It doesn't /* Find the show contents of just one of the instances. It doesn't
* matter which instance we use since all the content is the same * matter which instance we use since all the content is the same
*/ */
$ccSchedule = $ccSchedules->getFirst(); $ccSchedule = $ccSchedules[0];
$showStamp = CcScheduleQuery::create() $showStamp_sql = "SELECT * FROM cc_schedule ".
->filterByDbInstanceId($ccSchedule->getDbInstanceId()) "WHERE instance_id = {$ccSchedule["instance_id"]} ".
->orderByDbStarts() "ORDER BY starts";
->find(); $showStamp = Application_Common_Database::prepareAndExecute(
$showStamp_sql);
//get time_filled so we can update cc_show_instances //get time_filled so we can update cc_show_instances
$timeFilled = $ccSchedule->getCcShowInstances()->getDbTimeFilled(); $timeFilled_sql = "SELECT time_filled FROM cc_show_instances ".
"WHERE id = {$ccSchedule["instance_id"]}";
$timeFilled = Application_Common_Database::prepareAndExecute(
$timeFilled_sql, array(), Application_Common_Database::COLUMN);
//need to find out which linked instances are empty //need to find out which linked instances are empty
foreach ($ccShow->getCcShowInstancess() as $ccShowInstance) { $values = array();
$ccSchedules = CcScheduleQuery::create() foreach ($instanceIds as $id) {
->filterByDbInstanceId($ccShowInstance->getDbId()) $instanceSched_sql = "SELECT * FROM cc_schedule ".
->find(); "WHERE instance_id = {$id} ".
"ORDER by starts";
$ccSchedules = Application_Common_Database::prepareAndExecute(
$instanceSched_sql);
/* If the show instance is empty OR it has different content than /* If the show instance is empty OR it has different content than
* the first instance, we cant to fill/replace with the show stamp * the first instance, we need to fill/replace with the show stamp
* (The show stamp is taken from the first show instance's content) * (The show stamp is taken from the first show instance's content)
*/ */
if ($ccSchedules->isEmpty() || if (count($ccSchedules) < 1 ||
self::replaceInstanceContentCheck($ccShowInstance, $showStamp)) { self::replaceInstanceContentCheck($ccSchedules, $showStamp)) {
$nextStartDT = $ccShowInstance->getDbStarts(null); $instanceStart_sql = "SELECT starts FROM cc_show_instances ".
"WHERE id = {$id} ".
"ORDER BY starts";
$nextStartDT = new DateTime(
Application_Common_Database::prepareAndExecute(
$instanceStart_sql, array(), Application_Common_Database::COLUMN),
new DateTimeZone("UTC"));
foreach ($showStamp as $item) { foreach ($showStamp as $item) {
$endTimeDT = self::findEndTime($nextStartDT, $item->getDbClipLength()); $endTimeDT = self::findEndTime($nextStartDT, $item["clip_length"]);
$ccSchedule = new CcSchedule(); if (is_null($item["file_id"])) {
$ccSchedule $item["file_id"] = "null";
->setDbStarts($nextStartDT) }
->setDbEnds($endTimeDT) if (is_null($item["stream_id"])) {
->setDbFileId($item->getDbFileId()) $item["stream_id"] = "null";
->setDbStreamId($item->getDbStreamId()) }
->setDbClipLength($item->getDbClipLength())
->setDbFadeIn($item->getDbFadeIn())
->setDbFadeOut($item->getDbFadeOut())
->setDbCuein($item->getDbCueIn())
->setDbCueOut($item->getDbCueOut())
->setDbInstanceId($ccShowInstance->getDbId())
->setDbPosition($item->getDbPosition())
->save();
$nextStartDT = $endTimeDT; $values[] = "(".
"'{$nextStartDT->format("Y-m-d H:i:s")}', ".
"'{$endTimeDT->format("Y-m-d H:i:s")}', ".
"'{$item["clip_length"]}', ".
"'{$item["fade_in"]}', ".
"'{$item["fade_out"]}', ".
"'{$item["cue_in"]}', ".
"'{$item["cue_out"]}', ".
"{$item["file_id"]}, ".
"{$item["stream_id"]}, ".
"{$id}, ".
"{$item["position"]})";
$nextStartDT = self::findTimeDifference($endTimeDT,
Application_Model_Preference::GetDefaultCrossfadeDuration());
} //foreach show item } //foreach show item
//update time_filled in cc_show_instances
$ccShowInstance
->setDbTimeFilled($timeFilled)
->setDbLastScheduled(gmdate("Y-m-d H:i:s"))
->save();
} }
} //foreach linked instance } //foreach linked instance
$insert_sql = "INSERT INTO cc_schedule (starts, ends, ".
"clip_length, fade_in, fade_out, cue_in, cue_out, ".
"file_id, stream_id, instance_id, position) VALUES ".
implode($values, ",");
Application_Common_Database::prepareAndExecute(
$insert_sql, array(), Application_Common_Database::EXECUTE);
//update time_filled in cc_show_instances
$now = gmdate("Y-m-d H:i:s");
$update_sql = "UPDATE cc_show_instances SET ".
"time_filled = '{$timeFilled}', ".
"last_scheduled = '{$now}' ".
"WHERE show_id = {$ccShow->getDbId()}";
Application_Common_Database::prepareAndExecute(
$update_sql, array(), Application_Common_Database::EXECUTE);
} //if at least one linked instance has content } //if at least one linked instance has content
} }
@ -248,7 +300,8 @@ class Application_Service_SchedulerService
->setDbPosition($item->getDbPosition()) ->setDbPosition($item->getDbPosition())
->save(); ->save();
$nextStartDT = $endTimeDT; $nextStartDT = self::findTimeDifference($endTimeDT,
Application_Model_Preference::GetDefaultCrossfadeDuration());
} //foreach show item } //foreach show item
$ccShowInstance $ccShowInstance
@ -259,20 +312,24 @@ class Application_Service_SchedulerService
} }
} }
private static function replaceInstanceContentCheck($ccShowInstance, $showStamp) private static function replaceInstanceContentCheck($currentShowStamp, $showStamp)
{ {
$currentShowStamp = CcScheduleQuery::create() /*$currentShowStamp = CcScheduleQuery::create()
->filterByDbInstanceId($ccShowInstance->getDbId()) ->filterByDbInstanceId($ccShowInstance->getDbId())
->orderByDbStarts() ->orderByDbStarts()
->find(); ->find();*/
$counter = 0; $counter = 0;
foreach ($showStamp as $item) { foreach ($showStamp as $item) {
if ($item->getDbFileId() != $currentShowStamp[$counter]->getDbFileId() || if ($item["file_id"] != $currentShowStamp[$counter]["file_id"] ||
$item->getDbStreamId() != $currentShowStamp[$counter]->getDbStreamId()) { $item["stream_id"] != $currentShowStamp[$counter]["stream_id"]) {
CcScheduleQuery::create() /*CcScheduleQuery::create()
->filterByDbInstanceId($ccShowInstance->getDbId()) ->filterByDbInstanceId($ccShowInstance->getDbId())
->delete(); ->delete();*/
$delete_sql = "DELETE FROM cc_schedule ".
"WHERE instance_id = {$currentShowStamp[$counter]["instance_id"]}";
Application_Common_Database::prepareAndExecute(
$delete_sql, array(), Application_Common_Database::EXECUTE);
return true; return true;
} }
} }

View file

@ -99,8 +99,9 @@ class Application_Service_ShowFormService
public function delegateShowFormPopulation($forms) public function delegateShowFormPopulation($forms)
{ {
$this->populateFormWhat($forms["what"]); $this->populateFormWhat($forms["what"]);
$this->populateFormWhen($forms["when"]); //local show start DT
$this->populateFormRepeats($forms["repeats"]); $showStart = $this->populateFormWhen($forms["when"]);
$this->populateFormRepeats($forms["repeats"], $showStart);
$this->populateFormWho($forms["who"]); $this->populateFormWho($forms["who"]);
$this->populateFormStyle($forms["style"]); $this->populateFormStyle($forms["style"]);
$this->populateFormLive($forms["live"]); $this->populateFormLive($forms["live"]);
@ -136,6 +137,9 @@ class Application_Service_ShowFormService
$form->disableStartDateAndTime(); $form->disableStartDateAndTime();
} else { } else {
list($showStart, $showEnd) = $this->getNextFutureRepeatShowTime(); list($showStart, $showEnd) = $this->getNextFutureRepeatShowTime();
if ($this->hasShowStarted($showStart)) {
$form->disableStartDateAndTime();
}
} }
} }
@ -147,6 +151,8 @@ class Application_Service_ShowFormService
'add_show_end_time' => $showEnd->format("H:i"), 'add_show_end_time' => $showEnd->format("H:i"),
'add_show_duration' => $ccShowDay->formatDuration(true), 'add_show_duration' => $ccShowDay->formatDuration(true),
'add_show_repeats' => $ccShowDay->isRepeating() ? 1 : 0)); 'add_show_repeats' => $ccShowDay->isRepeating() ? 1 : 0));
return $showStart;
} }
private function populateInstanceFormWhen($form) private function populateInstanceFormWhen($form)
@ -179,7 +185,13 @@ class Application_Service_ShowFormService
$form->getElement('add_show_repeats')->setOptions(array("disabled" => true)); $form->getElement('add_show_repeats')->setOptions(array("disabled" => true));
} }
private function populateFormRepeats($form) /**
*
* Enter description here ...
* @param $form
* @param DateTime $nextFutureShowStart user's local timezone
*/
private function populateFormRepeats($form, $nextFutureShowStart)
{ {
$ccShowDays = $this->ccShow->getCcShowDays(); $ccShowDays = $this->ccShow->getCcShowDays();
@ -219,6 +231,14 @@ class Application_Service_ShowFormService
if (!$this->ccShow->isLinkable() || $this->ccShow->isRecorded()) { if (!$this->ccShow->isLinkable() || $this->ccShow->isRecorded()) {
$form->getElement('add_show_linked')->setOptions(array('disabled' => true)); $form->getElement('add_show_linked')->setOptions(array('disabled' => true));
} }
/* Because live editing of a linked show is disabled, we will disable
* the linking option if the current show is being edited. We don't
* want the user to suddenly not be able to edit the current show
*/
if ($this->hasShowStarted($nextFutureShowStart)) {
$form->getElement('add_show_linked')->setOptions(array('disabled' => true));
}
} }
private function populateFormWho($form) private function populateFormWho($form)
@ -295,6 +315,22 @@ class Application_Service_ShowFormService
$form->populate($formValues); $form->populate($formValues);
} }
/**
*
* Enter description here ...
* @param DateTime $showStart user's local time
*/
private function hasShowStarted($p_showStart) {
$showStart = clone $p_showStart;
$showStart->setTimeZone(new DateTimeZone("UTC"));
if ($showStart->format("Y-m-d H:i:s") < gmdate("Y-m-d H:i:s")) {
return true;
} else {
return false;
}
}
/** /**
* *
* Before we send the form data in for validation, there * Before we send the form data in for validation, there

View file

@ -179,9 +179,6 @@ class Application_Service_ShowService
if (is_null($this->ccShow)) { if (is_null($this->ccShow)) {
$ccShowDays = $this->getShowDaysInRange($populateUntil, $end); $ccShowDays = $this->getShowDaysInRange($populateUntil, $end);
if (count($ccShowDays) > 0) {
$this->ccShow = $ccShowDays[0]->getCcShow();
}
} else { } else {
$ccShowDays = $this->ccShow->getCcShowDays(); $ccShowDays = $this->ccShow->getCcShowDays();
} }
@ -190,32 +187,43 @@ class Application_Service_ShowService
$populateUntil = $end; $populateUntil = $end;
} }
/* In case the user is moving forward in the calendar and there are
* linked shows in the schedule we need to keep track of each cc_show
* so we know which shows need to be filled with content
*/
$ccShows = array();
foreach ($ccShowDays as $day) { foreach ($ccShowDays as $day) {
$this->ccShow = $day->getCcShow();
if (!isset($ccShows[$day->getDbShowId()])) {
$ccShows[$day->getDbShowId()] = $day->getccShow();
}
switch ($day->getDbRepeatType()) { switch ($day->getDbRepeatType()) {
case NO_REPEAT: case NO_REPEAT:
$this->createNonRepeatingInstance($day, $populateUntil); $this->createNonRepeatingInstance($day, $populateUntil);
break; break;
case REPEAT_WEEKLY: case REPEAT_WEEKLY:
$this->createRepeatingInstances($day, $populateUntil, REPEAT_WEEKLY, $this->createWeeklyRepeatInstances($day, $populateUntil, REPEAT_WEEKLY,
new DateInterval("P7D"), $daysAdded); new DateInterval("P7D"), $daysAdded);
break; break;
case REPEAT_BI_WEEKLY: case REPEAT_BI_WEEKLY:
$this->createRepeatingInstances($day, $populateUntil, REPEAT_BI_WEEKLY, $this->createWeeklyRepeatInstances($day, $populateUntil, REPEAT_BI_WEEKLY,
new DateInterval("P14D"), $daysAdded); new DateInterval("P14D"), $daysAdded);
break; break;
case REPEAT_MONTHLY_MONTHLY: case REPEAT_MONTHLY_MONTHLY:
$this->createMonthlyMonthlyRepeatInstances($day, $populateUntil); $this->createMonthlyRepeatInstances($day, $populateUntil);
break; break;
case REPEAT_MONTHLY_WEEKLY: case REPEAT_MONTHLY_WEEKLY:
$this->createRepeatingInstances($day, $populateUntil, REPEAT_MONTHLY_WEEKLY, $this->createMonthlyRepeatInstances($day, $populateUntil);
null, $daysAdded);
break; break;
} }
} }
if (isset($this->ccShow) && ($this->isUpdate || $fillInstances) && foreach ($ccShows as $ccShow) {
$this->ccShow->isLinked()) { if (($this->isUpdate || $fillInstances) && $ccShow->isLinked()) {
Application_Service_SchedulerService::fillNewLinkedInstances($this->ccShow); Application_Service_SchedulerService::fillNewLinkedInstances($ccShow);
}
} }
if (isset($this->linkedShowContent)) { if (isset($this->linkedShowContent)) {
@ -322,7 +330,7 @@ SQL;
$this->deleteAllRepeatInstances($currentShowDay, $showId); $this->deleteAllRepeatInstances($currentShowDay, $showId);
//if repeat option was checked we need to treat the current show day //if repeat option was checked we need to treat the current show day
//as a new show day so the repeat instances get created properly //as a new show day so the repeat instances get created properly
//in createRepeatingInstances() //in createWeeklyRepeatInstances()
if ($showData['add_show_repeats']) { if ($showData['add_show_repeats']) {
array_push($daysAdded, $currentShowDay->getDbDay()); array_push($daysAdded, $currentShowDay->getDbDay());
} }
@ -619,29 +627,44 @@ SQL;
->filterByDbShowId($showId) ->filterByDbShowId($showId)
->filterByDbModifiedInstance(false) ->filterByDbModifiedInstance(false)
->filterByDbRebroadcast(0) ->filterByDbRebroadcast(0)
->orderByDbStarts()
->find(); ->find();
if ($ccShowInstances->isEmpty()) { if ($ccShowInstances->isEmpty()) {
return true; return true;
} }
//only 1 show instance left of the show, make it non repeating. /* We need to update the last_show in cc_show_days so the instances
else if (count($ccShowInstances) === 1) { * don't get recreated as the user moves forward in the calendar
$ccShowInstance = $ccShowInstances[0]; */
else if (count($ccShowInstances) >= 1) {
$lastShowDays = array();
/* Creates an array where the key is the day of the week (monday,
* tuesday, etc.) and the value is the last show date for each
* day of the week. We will use this array to update the last_show
* for each cc_show_days entry of a cc_show
*/
foreach ($ccShowInstances as $instance) {
$instanceStartDT = new DateTime($instance->getDbStarts(),
new DateTimeZone("UTC"));
$lastShowDays[$instanceStartDT->format("w")] = $instanceStartDT;
}
$ccShowDay = CcShowDaysQuery::create() foreach ($lastShowDays as $dayOfWeek => $lastShowStartDT) {
->filterByDbShowId($showId) $ccShowDay = CcShowDaysQuery::create()
->findOne(); ->filterByDbShowId($showId)
$tz = $ccShowDay->getDbTimezone(); ->filterByDbDay($dayOfWeek)
->findOne();
$startDate = new DateTime($ccShowInstance->getDbStarts(), new DateTimeZone("UTC")); $lastShowStartDT->setTimeZone(new DateTimeZone(
$startDate->setTimeZone(new DateTimeZone($tz)); $ccShowDay->getDbTimezone()));
$endDate = Application_Service_CalendarService::addDeltas($startDate, 1, 0); $lastShowEndDT = Application_Service_CalendarService::addDeltas(
$lastShowStartDT, 1, 0);
$ccShowDay->setDbFirstShow($startDate->format("Y-m-d")); $ccShowDay
$ccShowDay->setDbLastShow($endDate->format("Y-m-d")); ->setDbLastShow($lastShowEndDT->format("Y-m-d"))
$ccShowDay->setDbStartTime($startDate->format("H:i:s")); ->save();
$ccShowDay->setDbRepeatType(-1);
$ccShowDay->save(); }
//remove the old repeating deleted instances. //remove the old repeating deleted instances.
CcShowInstancesQuery::create() CcShowInstancesQuery::create()
@ -846,7 +869,7 @@ SQL;
* @param unknown_type $repeatInterval * @param unknown_type $repeatInterval
* @param unknown_type $isRebroadcast * @param unknown_type $isRebroadcast
*/ */
private function createRepeatingInstances($showDay, $populateUntil, private function createWeeklyRepeatInstances($showDay, $populateUntil,
$repeatType, $repeatInterval, $daysAdded=null) $repeatType, $repeatInterval, $daysAdded=null)
{ {
$show_id = $showDay->getDbShowId(); $show_id = $showDay->getDbShowId();
@ -872,7 +895,9 @@ SQL;
Application_Common_DateHelper::ConvertToUtcDateTime($last_show, $timezone) : null; Application_Common_DateHelper::ConvertToUtcDateTime($last_show, $timezone) : null;
$utcStartDateTime = new DateTime("now"); $utcStartDateTime = new DateTime("now");
$previousDate = clone $start;
foreach ($datePeriod as $date) { foreach ($datePeriod as $date) {
list($utcStartDateTime, $utcEndDateTime) = $this->createUTCStartEndDateTime( list($utcStartDateTime, $utcEndDateTime) = $this->createUTCStartEndDateTime(
$date, $duration); $date, $duration);
/* /*
@ -926,6 +951,7 @@ SQL;
$this->createRebroadcastInstances($showDay, $date, $ccShowInstance->getDbId()); $this->createRebroadcastInstances($showDay, $date, $ccShowInstance->getDbId());
} }
} }
$previousDate = clone $date;
} }
/* Set UTC to local time before setting the next repeat date. If we don't /* Set UTC to local time before setting the next repeat date. If we don't
@ -936,7 +962,7 @@ SQL;
$this->setNextRepeatingShowDate($nextDate->format("Y-m-d"), $day, $show_id); $this->setNextRepeatingShowDate($nextDate->format("Y-m-d"), $day, $show_id);
} }
private function createMonthlyMonthlyRepeatInstances($showDay, $populateUntil) private function createMonthlyRepeatInstances($showDay, $populateUntil)
{ {
$show_id = $showDay->getDbShowId(); $show_id = $showDay->getDbShowId();
$first_show = $showDay->getDbFirstShow(); //non-UTC $first_show = $showDay->getDbFirstShow(); //non-UTC
@ -954,6 +980,13 @@ SQL;
$end = $populateUntil; $end = $populateUntil;
} }
// We will only need this if the repeat type is MONTHLY_WEEKLY
list($weekNumberOfMonth, $dayOfWeek) =
$this->getMonthlyWeeklyRepeatInterval(
new DateTime($first_show, new DateTimeZone($timezone)));
$this->repeatType = $showDay->getDbRepeatType();
$utcLastShowDateTime = $last_show ? $utcLastShowDateTime = $last_show ?
Application_Common_DateHelper::ConvertToUtcDateTime($last_show, $timezone) : null; Application_Common_DateHelper::ConvertToUtcDateTime($last_show, $timezone) : null;
@ -999,10 +1032,23 @@ SQL;
} }
if ($this->isRebroadcast) { if ($this->isRebroadcast) {
$this->createRebroadcastInstances($showDay, $date, $ccShowInstance->getDbId()); $this->createRebroadcastInstances($showDay, $start, $ccShowInstance->getDbId());
} }
} }
$start = $this->getNextMonthlyMonthlyRepeatDate($start, $timezone, $showDay->getDbStartTime()); if ($this->repeatType == REPEAT_MONTHLY_WEEKLY) {
$monthlyWeeklyStart = new DateTime($utcStartDateTime->format("Y-m"),
new DateTimeZone("UTC"));
$monthlyWeeklyStart->add(new DateInterval("P1M"));
$start = $this->getNextMonthlyWeeklyRepeatDate(
$monthlyWeeklyStart,
$timezone,
$showDay->getDbStartTime(),
$weekNumberOfMonth,
$dayOfWeek);
} else {
$start = $this->getNextMonthlyMonthlyRepeatDate(
$start, $timezone, $showDay->getDbStartTime());
}
} }
$this->setNextRepeatingShowDate($start->format("Y-m-d"), $day, $show_id); $this->setNextRepeatingShowDate($start->format("Y-m-d"), $day, $show_id);
} }
@ -1018,7 +1064,6 @@ SQL;
private function getMonthlyWeeklyRepeatInterval($showStart) private function getMonthlyWeeklyRepeatInterval($showStart)
{ {
$start = clone $showStart; $start = clone $showStart;
$dayOfMonth = $start->format("j"); $dayOfMonth = $start->format("j");
$dayOfWeek = $start->format("l"); $dayOfWeek = $start->format("l");
$yearAndMonth = $start->format("Y-m"); $yearAndMonth = $start->format("Y-m");
@ -1047,22 +1092,24 @@ SQL;
$weekNumberOfMonth = "fourth"; $weekNumberOfMonth = "fourth";
break; break;
case 5: case 5:
$weekNumberOfMonth = "last"; $weekNumberOfMonth = "fifth";
break; break;
} }
return DateInterval::createFromDateString( /* return DateInterval::createFromDateString(
$weekNumberOfMonth." ".$dayOfWeek." of next month"); $weekNumberOfMonth." ".$dayOfWeek." of next month"); */
return array($weekNumberOfMonth, $dayOfWeek);
} }
/** /**
* *
* Enter description here ... * Enter description here ...
* @param $start * @param $start user's local time
*/ */
private function getNextMonthlyMonthlyRepeatDate($start, $timezone, $startTime) private function getNextMonthlyMonthlyRepeatDate($start, $timezone, $startTime)
{ {
$dt = new DateTime($start->format("Y-m"), new DateTimeZone($timezone)); $dt = new DateTime($start->format("Y-m"), new DateTimeZone($timezone));
do { do {
$dt->add(new DateInterval("P1M")); $dt->add(new DateInterval("P1M"));
} while (!checkdate($dt->format("m"), $start->format("d"), $dt->format("Y"))); } while (!checkdate($dt->format("m"), $start->format("d"), $dt->format("Y")));
@ -1077,6 +1124,41 @@ SQL;
return $dt; return $dt;
} }
private function getNextMonthlyWeeklyRepeatDate(
$start,
$timezone,
$startTime,
$weekNumberOfMonth,
$dayOfWeek)
{
$dt = new DateTime($start->format("Y-m"), new DateTimeZone($timezone));
$tempDT = clone $dt;
$fifthWeekExists = false;
do {
$nextDT = date_create($weekNumberOfMonth." ".$dayOfWeek.
" of ".$tempDT->format("F")." ".$tempDT->format("Y"));
/* We have to check if the next date is in the same month in case
* the repeat day is in the fifth week of the month.
* If it's not in the same month we know that a fifth week of
* the next month does not exist. So let's skip it.
*/
if ($tempDT->format("F") == $nextDT->format("F")) {
$fifthWeekExists = true;
}
$tempDT->add(new DateInterval("P1M"));
} while (!$fifthWeekExists);
$dt = $nextDT;
$startTime = explode(":", $startTime);
$hours = isset($startTime[0]) ? $startTime[0] : "00";
$minutes = isset($startTime[1]) ? $startTime[1] : "00";
$seconds = isset($startTime[2]) ? $startTime[2] : "00";
$dt->setTime($hours, $minutes, $seconds);
return $dt;
}
private function getNextRepeatingPopulateStartDateTime($showDay) private function getNextRepeatingPopulateStartDateTime($showDay)
{ {
$nextPopDate = $showDay->getDbNextPopDate(); $nextPopDate = $showDay->getDbNextPopDate();
@ -1426,4 +1508,4 @@ SQL;
$repeatInfo->setDbNextPopDate($nextInfo[0]) $repeatInfo->setDbNextPopDate($nextInfo[0])
->save(); ->save();
} }
} }

View file

@ -18,18 +18,26 @@
<div class="jp-type-playlist"> <div class="jp-type-playlist">
<div class="jp-gui jp-interface"> <div class="jp-gui jp-interface">
<ul class="jp-controls"> <ul class="jp-controls">
<?php if ($this->type != "audioclip"): ?>
<li class="ui-state-default ui-corner-all jp-previous"> <li class="ui-state-default ui-corner-all jp-previous">
<span class="ui-icon ui-icon-seek-prev" tabindex="1"><? echo _("previous") ?></span> <span class="ui-icon ui-icon-seek-prev" tabindex="1"><? echo _("previous") ?></span>
</li> </li>
<?php endif;?>
<li class="ui-state-default ui-corner-all jp-play"> <li class="ui-state-default ui-corner-all jp-play">
<span class="ui-icon ui-icon-play" tabindex="1"><? echo _("play") ?></span> <span class="ui-icon ui-icon-play" tabindex="1"><? echo _("play") ?></span>
</li> </li>
<li class="ui-state-default ui-corner-all jp-pause"> <li class="ui-state-default ui-corner-all jp-pause">
<span class="ui-icon ui-icon-pause" tabindex="1"><? echo _("pause") ?></span> <span class="ui-icon ui-icon-pause" tabindex="1"><? echo _("pause") ?></span>
</li> </li>
<?php if ($this->type != "audioclip"): ?>
<li class="ui-state-default ui-corner-all jp-next"> <li class="ui-state-default ui-corner-all jp-next">
<span class="ui-icon ui-icon-seek-next" tabindex="1"><? echo _("next") ?></span> <span class="ui-icon ui-icon-seek-next" tabindex="1"><? echo _("next") ?></span>
</li> </li>
<?php endif;?>
<li class="ui-state-default ui-corner-all jp-stop"> <li class="ui-state-default ui-corner-all jp-stop">
<span class="ui-icon ui-icon-stop" tabindex="1"><? echo _("stop") ?></span> <span class="ui-icon ui-icon-stop" tabindex="1"><? echo _("stop") ?></span>
</li> </li>
@ -42,7 +50,9 @@
</div> </div>
<div class="jp-time-holder"> <div class="jp-time-holder">
<div class="jp-current-time"></div> <div class="jp-current-time"></div>
<?php if ($this->type == "audioclip"): ?><div class="jp-duration"></div><?php endif;?> <?php if ($this->type == "audioclip"): ?>
<div class="jp-duration"></div>
<?php endif;?>
</div> </div>
</div> </div>
<div class="jp-volume-block"> <div class="jp-volume-block">

View file

@ -74,7 +74,7 @@ $(document).ready(function(){
if ($type == "ogg") if ($type == "ogg")
$type = "oga"; $type = "oga";
$label = "(".$streamData["${id}_host"].") ".$streamData["${id}_description"]." - ".$streamData["${id}_bitrate"]." Kbit/s"; $label = "(".$streamData["${id}_host"].") ".$streamData["${id}_description"]." - ".$streamData["${id}_bitrate"]." kbit/s";
echo sprintf("<option class='stream' value='%s' data-url='%s' data-type='%s' server-type='%s'>%s</option>", $id, $url, $type, $serverType, $label); echo sprintf("<option class='stream' value='%s' data-url='%s' data-type='%s' server-type='%s'>%s</option>", $id, $url, $type, $serverType, $label);
} }
?> ?>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 801 B

After

Width:  |  Height:  |  Size: 481 B

Before After
Before After

View file

@ -105,6 +105,10 @@ div.sb-timerange input#sb_date_start {
margin-left: 30px; margin-left: 30px;
} }
div.sb-timerange input.error {
background-color: rgba(255,0,0,0.2);
}
.sb-starts, .sb-starts,
.sb-ends { .sb-ends {
text-align: center; text-align: center;

View file

@ -125,7 +125,7 @@ select {
.airtime_auth_help_icon, .custom_auth_help_icon, .stream_username_help_icon, .airtime_auth_help_icon, .custom_auth_help_icon, .stream_username_help_icon,
.playlist_type_help_icon, .master_username_help_icon, .repeat_tracks_help_icon, .playlist_type_help_icon, .master_username_help_icon, .repeat_tracks_help_icon,
.admin_username_help_icon, .stream_type_help_icon { .admin_username_help_icon, .stream_type_help_icon, .show_linking_help_icon {
cursor: help; cursor: help;
position: relative; position: relative;
display:inline-block; zoom:1; display:inline-block; zoom:1;

View file

@ -14,11 +14,36 @@
.btn-small { .btn-small {
/*line-height: 20px;*/ /*line-height: 20px;*/
} }
.playlist-time-scale {
position: absolute;
top: 5px;
left: 0;
right: 0;
height: 30px;
overflow: hidden;
}
.playlist-time-scale canvas {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
height: 30px;
}
.playlist-time-scale div {
position: absolute;
}
.playlist-tracks { .playlist-tracks {
margin: 8px 0; position: relative;
top: 35px;
margin: 2px 0;
} }
.playlist-controls { .playlist-controls {
margin: 0 0 16px 0; margin: 40px 0 16px 0;
} }
.channel-wrapper { .channel-wrapper {
@ -30,6 +55,8 @@
margin: 0; margin: 0;
padding: 0; padding: 0;
background: #6e6e6e; background: #6e6e6e;
/*border-top: 1px solid #6e6e6e;*/
/*border-bottom: 1px solid #6e6e6e;*/
} }
.state-select { .state-select {
@ -41,6 +68,12 @@
overflow-y: hidden; overflow-y: hidden;
} }
.playlist-tracks > .error {
height: 80px;
width: 300px;
background-color: rgba(255,0,0,0.5);
}
.playlist-fade { .playlist-fade {
position: absolute; position: absolute;
background-color: rgba(0,0,0,0.1); background-color: rgba(0,0,0,0.1);
@ -50,7 +83,7 @@
margin: 12px 0 16px 0; margin: 12px 0 16px 0;
} }
.set-fade { .set-fade {
margin: 0 0 0 30px; margin: 40px 0 0 30px;
} }
.set-cue input[type="text"] { .set-cue input[type="text"] {
vertical-align: middle; vertical-align: middle;

View file

@ -260,16 +260,19 @@ function parseItems(obj){
calculateTimeToNextSong(); calculateTimeToNextSong();
} }
currentShow = new Array();
if (obj.currentShow.length > 0) { if (obj.currentShow.length > 0) {
calcAdditionalShowData(obj.currentShow); calcAdditionalShowData(obj.currentShow);
currentShow = obj.currentShow;
} }
nextShow = new Array();
if (obj.nextShow.length > 0) { if (obj.nextShow.length > 0) {
calcAdditionalShowData(obj.nextShow); calcAdditionalShowData(obj.nextShow);
nextShow = obj.nextShow;
calculateTimeToNextShow(); calculateTimeToNextShow();
} }
currentShow = obj.currentShow;
nextShow = obj.nextShow;
var schedulePosixTime = convertDateToPosixTime(obj.schedulerTime); var schedulePosixTime = convertDateToPosixTime(obj.schedulerTime);
var date = new Date(); var date = new Date();

View file

@ -391,7 +391,9 @@ var AIRTIME = (function(AIRTIME) {
$libTable = $libContent.find("table"); $libTable = $libContent.find("table");
var tableHeight = $libContent.height() - 130; function getTableHeight() {
return $libContent.height() - 175;
}
function setColumnFilter(oTable){ function setColumnFilter(oTable){
// TODO : remove this dirty hack once js is refactored // TODO : remove this dirty hack once js is refactored
@ -454,6 +456,13 @@ var AIRTIME = (function(AIRTIME) {
} else { } else {
$el.hide(); $el.hide();
} }
//resize to prevent double scroll bars.
var $fs = $el.parents("fieldset"),
tableHeight = getTableHeight(),
searchHeight = $fs.height();
$libContent.find(".dataTables_scrolling").css("max-height", tableHeight - searchHeight);
} }
oTable = $libTable.dataTable( { oTable = $libTable.dataTable( {
@ -593,12 +602,12 @@ var AIRTIME = (function(AIRTIME) {
"fnRowCallback": AIRTIME.library.fnRowCallback, "fnRowCallback": AIRTIME.library.fnRowCallback,
"fnCreatedRow": function( nRow, aData, iDataIndex ) { "fnCreatedRow": function( nRow, aData, iDataIndex ) {
//add soundcloud icon //add soundcloud icon
if (aData.soundcloud_status !== undefined) { if (aData.soundcloud_id !== undefined) {
if (aData.soundcloud_status === "-2") { if (aData.soundcloud_id === "-2") {
$(nRow).find("td.library_title").append('<span class="small-icon progress"/>'); $(nRow).find("td.library_title").append('<span class="small-icon progress"/>');
} else if (aData.soundcloud_status === "-3") { } else if (aData.soundcloud_id === "-3") {
$(nRow).find("td.library_title").append('<span class="small-icon sc-error"/>'); $(nRow).find("td.library_title").append('<span class="small-icon sc-error"/>');
} else if (aData.soundcloud_status !== null) { } else if (aData.soundcloud_id !== null) {
$(nRow).find("td.library_title").append('<span class="small-icon soundcloud"/>'); $(nRow).find("td.library_title").append('<span class="small-icon soundcloud"/>');
} }
} }
@ -784,10 +793,14 @@ var AIRTIME = (function(AIRTIME) {
$libContent.on("click", "legend", function(){ $libContent.on("click", "legend", function(){
$simpleSearch = $libContent.find("#library_display_filter label"); $simpleSearch = $libContent.find("#library_display_filter label");
var $fs = $(this).parents("fieldset"); var $fs = $(this).parents("fieldset"),
searchHeight,
tableHeight = getTableHeight(),
height;
if ($fs.hasClass("closed")) { if ($fs.hasClass("closed")) {
$fs.removeClass("closed"); $fs.removeClass("closed");
searchHeight = $fs.height();
//keep value of simple search for when user switches back to it //keep value of simple search for when user switches back to it
simpleSearchText = $simpleSearch.find('input').val(); simpleSearchText = $simpleSearch.find('input').val();
@ -796,6 +809,10 @@ var AIRTIME = (function(AIRTIME) {
$(".dataTables_filter input").val("").keyup(); $(".dataTables_filter input").val("").keyup();
$simpleSearch.addClass("sp-invisible"); $simpleSearch.addClass("sp-invisible");
//resize the library table to avoid a double scroll bar. CC-4504
height = tableHeight - searchHeight;
$libContent.find(".dataTables_scrolling").css("max-height", height);
} }
else { else {
// clear the advanced search fields // clear the advanced search fields
@ -817,9 +834,13 @@ var AIRTIME = (function(AIRTIME) {
$simpleSearch.removeClass("sp-invisible"); $simpleSearch.removeClass("sp-invisible");
$fs.addClass("closed"); $fs.addClass("closed");
//resize the library table to avoid a double scroll bar. CC-4504
$libContent.find(".dataTables_scrolling").css("max-height", tableHeight);
} }
}); });
var tableHeight = getTableHeight();
$libContent.find(".dataTables_scrolling").css("max-height", tableHeight); $libContent.find(".dataTables_scrolling").css("max-height", tableHeight);
AIRTIME.library.setupLibraryToolbar(oTable); AIRTIME.library.setupLibraryToolbar(oTable);
@ -1069,13 +1090,13 @@ function buildEditMetadataDialog (json){
width: 460, width: 460,
height: 660, height: 660,
modal: true, modal: true,
close: closeDialog close: closeDialogLibrary
}); });
dialog.dialog('open'); dialog.dialog('open');
} }
function closeDialog(event, ui) { function closeDialogLibrary(event, ui) {
$(this).remove(); $(this).remove();
} }
@ -1126,7 +1147,6 @@ function checkLibrarySCUploadStatus(){
else if (json.sc_id == "-3") { else if (json.sc_id == "-3") {
span.removeClass("progress").addClass("sc-error"); span.removeClass("progress").addClass("sc-error");
} }
setTimeout(checkLibrarySCUploadStatus, 5000);
} }
function checkSCUploadStatusRequest() { function checkSCUploadStatusRequest() {
@ -1138,12 +1158,16 @@ function checkLibrarySCUploadStatus(){
} }
$("#library_display span.progress").each(checkSCUploadStatusRequest); $("#library_display span.progress").each(checkSCUploadStatusRequest);
setTimeout(checkLibrarySCUploadStatus, 5000);
} }
function addQtipToSCIcons(){ function addQtipToSCIcons() {
$(".progress, .soundcloud, .sc-error").live('mouseover', function(){ $("#content")
.on('mouseover', ".progress, .soundcloud, .sc-error", function() {
var id = $(this).parent().parent().data("aData").id; var aData = $(this).parents("tr").data("aData"),
id = aData.id,
sc_id = aData.soundcloud_id;
if ($(this).hasClass("progress")){ if ($(this).hasClass("progress")){
$(this).qtip({ $(this).qtip({
@ -1163,24 +1187,15 @@ function addQtipToSCIcons(){
classes: "ui-tooltip-dark file-md-long" classes: "ui-tooltip-dark file-md-long"
}, },
show: { show: {
ready: true // Needed to make it show on first mouseover ready: true // Needed to make it show on first mouseover event
// event
} }
}); });
} }
else if($(this).hasClass("soundcloud")){ else if ($(this).hasClass("soundcloud")){
var sc_id = $(this).parent().parent().data("aData").soundcloud_id;
$(this).qtip({ $(this).qtip({
content: { content: {
text: $.i18n._("Retrieving data from the server..."), text: $.i18n._("The soundcloud id for this file is: ") + sc_id
ajax: {
url: baseUrl+"Library/get-upload-to-soundcloud-status",
type: "post",
data: ({format: "json", id : id, type: "file"}),
success: function(json, status){
this.set('content.text', $.i18n._("The soundcloud id for this file is: ")+json.sc_id);
}
}
}, },
position:{ position:{
adjust: { adjust: {
@ -1195,11 +1210,11 @@ function addQtipToSCIcons(){
classes: "ui-tooltip-dark file-md-long" classes: "ui-tooltip-dark file-md-long"
}, },
show: { show: {
ready: true // Needed to make it show on first mouseover ready: true // Needed to make it show on first mouseover event
// event
} }
}); });
}else if($(this).hasClass("sc-error")){ }
else if ($(this).hasClass("sc-error")) {
$(this).qtip({ $(this).qtip({
content: { content: {
text: $.i18n._("Retreiving data from the server..."), text: $.i18n._("Retreiving data from the server..."),
@ -1227,8 +1242,7 @@ function addQtipToSCIcons(){
classes: "ui-tooltip-dark file-md-long" classes: "ui-tooltip-dark file-md-long"
}, },
show: { show: {
ready: true // Needed to make it show on first mouseover ready: true // Needed to make it show on first mouseover event
// event
} }
}); });
} }

View file

@ -209,12 +209,11 @@ var AIRTIME = (function(AIRTIME){
} }
/* used from waveform pop-up */ /* used from waveform pop-up */
function changeCrossfade($el, id1, id2, fadeIn, fadeOut, offset) { function changeCrossfade($el, id1, id2, fadeIn, fadeOut, offset, id) {
var url = baseUrl+"Playlist/set-crossfade", var url = baseUrl+"Playlist/set-crossfade",
lastMod = getModified(), lastMod = getModified(),
type = $('#obj_type').val(), type = $('#obj_type').val();
li, id;
$.post(url, $.post(url,
{format: "json", fadeIn: fadeIn, fadeOut: fadeOut, id1: id1, id2: id2, offset: offset, modified: lastMod, type: type}, {format: "json", fadeIn: fadeIn, fadeOut: fadeOut, id1: id1, id2: id2, offset: offset, modified: lastMod, type: type},
@ -230,10 +229,9 @@ var AIRTIME = (function(AIRTIME){
setPlaylistContent(json); setPlaylistContent(json);
id = id1 === undefined ? id2 : id1; $li = $('#side_playlist li[unqid='+id+']');
li = $('#side_playlist li[unqid='+id+']'); $li.find('.crossfade').toggle();
li.find('.crossfade').toggle(); highlightActive($li.find('.spl_fade_control'));
highlightActive(li.find('.spl_fade_control'));
}); });
} }
@ -589,13 +587,13 @@ var AIRTIME = (function(AIRTIME){
var extra = (ele['extra']==null)?"":"- "+ele['extra']; var extra = (ele['extra']==null)?"":"- "+ele['extra'];
$html += "<li>" + $html += "<li>" +
"<span class='block-item-title'>"+ele['display_name']+"</span>" + "<span class='block-item-title'>"+ele['display_name']+"</span>" +
"<span class='block-item-criteria'>"+ele['modifier']+"</span>" + "<span class='block-item-criteria'>"+ele['display_modifier']+"</span>" +
"<span class='block-item-criteria'>"+ele['value']+"</span>" + "<span class='block-item-criteria'>"+ele['value']+"</span>" +
"<span class='block-item-criteria'>"+extra+"</span>" + "<span class='block-item-criteria'>"+extra+"</span>" +
"</li>"; "</li>";
}); });
} }
$html += "<li><br /><span class='block-item-title'>"+$.i18n._("Limit to: ")+data.limit.value+" "+data.limit.modifier+"</span></li>"; $html += "<li><br /><span class='block-item-title'>"+$.i18n._("Limit to: ")+data.limit.value+" "+data.limit.display_modifier+"</span></li>";
} }
$pl.find("#block_"+id+"_info").html($html).show(); $pl.find("#block_"+id+"_info").html($html).show();
mod.enableUI(); mod.enableUI();
@ -1179,13 +1177,16 @@ var AIRTIME = (function(AIRTIME){
mod.showFadesWaveform = function(e) { mod.showFadesWaveform = function(e) {
var $el = $(e.target), var $el = $(e.target),
$parent = $el.parents("dl"), $parent = $el.parents("dl"),
$li = $el.parents("li"),
$fadeOut = $parent.find(".spl_fade_out"), $fadeOut = $parent.find(".spl_fade_out"),
$fadeIn = $parent.find(".spl_fade_in"), $fadeIn = $parent.find(".spl_fade_in"),
$html = $($("#tmpl-pl-fades").html()), $html = $($("#tmpl-pl-fades").html()),
tracks = [], tracks = [],
dim = AIRTIME.utilities.findViewportDimensions(), dim = AIRTIME.utilities.findViewportDimensions(),
playlistEditor, playlistEditor,
id1, id2; id1, id2,
id = $li.attr("unqid");
function removeDialog() { function removeDialog() {
playlistEditor.stop(); playlistEditor.stop();
@ -1246,7 +1247,7 @@ var AIRTIME = (function(AIRTIME){
show: 'clip', show: 'clip',
hide: 'clip', hide: 'clip',
width: dim.width - 100, width: dim.width - 100,
height: dim.height - 100, height: 350,
buttons: [ buttons: [
{text: $.i18n._("Cancel"), class: "btn btn-small", click: removeDialog}, {text: $.i18n._("Cancel"), class: "btn btn-small", click: removeDialog},
{text: $.i18n._("Save"), class: "btn btn-small btn-inverse", click: function() { {text: $.i18n._("Save"), class: "btn btn-small btn-inverse", click: function() {
@ -1257,15 +1258,22 @@ var AIRTIME = (function(AIRTIME){
playlistEditor.stop(); playlistEditor.stop();
if (json.length === 1) { if (json.length === 0)
{
id1 = undefined;
id2 = undefined;
}
else if (json.length === 1) {
fade = json[0]["fades"][0]; fade = json[0]["fades"][0];
if (fade["type"] === "FadeOut") { if (fade["type"] === "FadeOut") {
fadeOut = fade["end"] - fade["start"]; fadeOut = fade["end"] - fade["start"];
id2 = undefined; //incase of track decode error.
} }
else { else {
fadeIn = fade["end"] - fade["start"]; fadeIn = fade["end"] - fade["start"];
id1 = undefined; //incase of track decode error.
} }
} }
else { else {
@ -1282,7 +1290,7 @@ var AIRTIME = (function(AIRTIME){
fadeIn = (fadeIn === undefined) ? undefined : fadeIn.toFixed(1); fadeIn = (fadeIn === undefined) ? undefined : fadeIn.toFixed(1);
fadeOut = (fadeOut === undefined) ? undefined : fadeOut.toFixed(1); fadeOut = (fadeOut === undefined) ? undefined : fadeOut.toFixed(1);
changeCrossfade($html, id1, id2, fadeIn, fadeOut, offset); changeCrossfade($html, id1, id2, fadeIn, fadeOut, offset, id);
}} }}
], ],
open: function (event, ui) { open: function (event, ui) {
@ -1291,6 +1299,7 @@ var AIRTIME = (function(AIRTIME){
resolution: 15000, resolution: 15000,
state: "cursor", state: "cursor",
mono: true, mono: true,
timescale: true,
waveHeight: 80, waveHeight: 80,
container: $html[0], container: $html[0],
UITheme: "jQueryUI", UITheme: "jQueryUI",
@ -1301,7 +1310,10 @@ var AIRTIME = (function(AIRTIME){
playlistEditor.setConfig(config); playlistEditor.setConfig(config);
playlistEditor.init(tracks); playlistEditor.init(tracks);
}, },
close: removeDialog close: removeDialog,
resizeStop: function(event, ui) {
playlistEditor.resize();
}
}); });
}; };
@ -1354,7 +1366,7 @@ var AIRTIME = (function(AIRTIME){
show: 'clip', show: 'clip',
hide: 'clip', hide: 'clip',
width: dim.width - 100, width: dim.width - 100,
height: dim.height - 100, height: 325,
buttons: [ buttons: [
{text: $.i18n._("Cancel"), class: "btn btn-small", click: removeDialog}, {text: $.i18n._("Cancel"), class: "btn btn-small", click: removeDialog},
{text: $.i18n._("Save"), class: "btn btn-small btn-inverse", click: function() { {text: $.i18n._("Save"), class: "btn btn-small btn-inverse", click: function() {
@ -1371,6 +1383,7 @@ var AIRTIME = (function(AIRTIME){
var config = new Config({ var config = new Config({
resolution: 15000, resolution: 15000,
mono: true, mono: true,
timescale: true,
waveHeight: 80, waveHeight: 80,
container: $html[0], container: $html[0],
UITheme: "jQueryUI", UITheme: "jQueryUI",
@ -1381,7 +1394,10 @@ var AIRTIME = (function(AIRTIME){
playlistEditor.setConfig(config); playlistEditor.setConfig(config);
playlistEditor.init(tracks); playlistEditor.init(tracks);
}, },
close: removeDialog close: removeDialog,
resizeStop: function(event, ui) {
playlistEditor.resize();
}
}); });
}; };
@ -1435,13 +1451,13 @@ var AIRTIME = (function(AIRTIME){
widgetHeight = viewport.height - 185; widgetHeight = viewport.height - 185;
width = Math.floor(viewport.width - 80); width = Math.floor(viewport.width - 80);
var libTableHeight = widgetHeight - 130; var libTableHeight = widgetHeight - 175;
if (!$pl.is(':hidden')) { if (!$pl.is(':hidden')) {
$lib.height(widgetHeight) $lib.height(widgetHeight)
.find(".dataTables_scrolling") .find(".dataTables_scrolling")
.css("max-height", libTableHeight) .css("max-height", libTableHeight)
.end() .end()
.width(Math.floor(width * 0.55)); .width(Math.floor(width * 0.55));
$pl.height(widgetHeight) $pl.height(widgetHeight)
@ -1449,8 +1465,8 @@ var AIRTIME = (function(AIRTIME){
} else { } else {
$lib.height(widgetHeight) $lib.height(widgetHeight)
.find(".dataTables_scrolling") .find(".dataTables_scrolling")
.css("max-height", libTableHeight) .css("max-height", libTableHeight)
.end() .end()
.width(width + 40); .width(width + 40);
} }
} }
@ -1459,8 +1475,6 @@ var AIRTIME = (function(AIRTIME){
$lib = $("#library_content"); $lib = $("#library_content");
$pl = $("#side_playlist"); $pl = $("#side_playlist");
setWidgetSize(); setWidgetSize();
AIRTIME.library.libraryInit(); AIRTIME.library.libraryInit();

View file

@ -192,7 +192,8 @@ function setAddShowEvents() {
$(this).parent().after("<ul id='show-link-warning' class='errors'><li>"+$.i18n._("Warning: Shows cannot be re-linked")+"</li></ul>"); $(this).parent().after("<ul id='show-link-warning' class='errors'><li>"+$.i18n._("Warning: Shows cannot be re-linked")+"</li></ul>");
} }
}); });
form.find("#add_show_linked-label").before("<span class='show_linking_help_icon'></span>");
form.find("#add_show_record").click(function(){ form.find("#add_show_record").click(function(){
$(this).blur(); $(this).blur();
@ -315,7 +316,26 @@ function setAddShowEvents() {
at: "right center" at: "right center"
} }
}); });
form.find(".show_linking_help_icon").qtip({
content: {
text: $.i18n._("By linking your repeating shows any media items scheduled in any repeat show will also get scheduled in the other repeat shows")
},
hide: {
delay: 500,
fixed: true
},
style: {
border: {
width: 0,
radius: 4
},
classes: "ui-tooltip-dark ui-tooltip-rounded"
},
position: {
my: "left bottom",
at: "right center"
}
});
function endDateVisibility(){ function endDateVisibility(){
if(form.find("#add_show_no_end").is(':checked')){ if(form.find("#add_show_no_end").is(':checked')){
form.find("#add_show_end_date").hide(); form.find("#add_show_end_date").hide();

View file

@ -116,12 +116,19 @@ function dayClick(date, allDay, jsEvent, view){
// duration in milisec // duration in milisec
var duration = (duration_h * 60 * 60 * 1000) + (duration_m * 60 * 1000); var duration = (duration_h * 60 * 60 * 1000) + (duration_m * 60 * 1000);
var startTime_string, startTime var startTime_string;
var startTime = 0;
// get start time value on the form // get start time value on the form
if(view.name === "month") { if(view.name === "month") {
startTime_string = $("#add_show_start_time").val(); startTime_string = $("#add_show_start_time").val();
var startTime_info = startTime_string.split(':'); var startTime_info = startTime_string.split(':');
startTime = (parseInt(startTime_info[0],10) * 60 * 60 * 1000) + (parseInt(startTime_info[1], 10) * 60 * 1000); if (startTime_info.length == 2) {
var start_time_temp = (parseInt(startTime_info[0],10) * 60 * 60 * 1000)
+ (parseInt(startTime_info[1], 10) * 60 * 1000);
if (!isNaN(start_time_temp)) {
startTime = start_time_temp;
}
}
}else{ }else{
// if in day or week view, selected has all the time info as well // if in day or week view, selected has all the time info as well
// so we don't ahve to calculate it explicitly // so we don't ahve to calculate it explicitly
@ -210,7 +217,9 @@ function viewDisplay( view ) {
} }
function eventRender(event, element, view) { function eventRender(event, element, view) {
$(element).attr("id", "fc-show-instance-"+event.id);
$(element).attr("data-show-id", event.showId);
$(element).attr("data-show-linked", event.linked);
$(element).data("event", event); $(element).data("event", event);
//only put progress bar on shows that aren't being recorded. //only put progress bar on shows that aren't being recorded.
@ -228,35 +237,28 @@ function eventRender(event, element, view) {
$(element).find(".fc-event-content").append(div); $(element).find(".fc-event-content").append(div);
} }
//need to add id for every event to find the current show
if (view.name === 'agendaDay' || view.name === 'agendaWeek') {
$(element).find(".fc-event-time").attr("id", event.id);
} else if (view.name === 'month') {
$(element).find(".fc-event-title").attr("id", event.id);
}
//add the record/rebroadcast/soundcloud icons if needed //add the record/rebroadcast/soundcloud icons if needed
if (event.record === 1) { if (event.record === 1) {
if (view.name === 'agendaDay' || view.name === 'agendaWeek') { if (view.name === 'agendaDay' || view.name === 'agendaWeek') {
if (event.soundcloud_id === -1) { if (event.soundcloud_id === -1) {
$(element).find(".fc-event-time").before('<span id="'+event.id+'" class="small-icon recording"></span>'); $(element).find(".fc-event-time").before('<span class="small-icon recording"></span>');
} else if ( event.soundcloud_id > 0) { } else if ( event.soundcloud_id > 0) {
$(element).find(".fc-event-time").before('<span id="'+event.id+'" class="small-icon recording"></span><span id="'+event.id+'" class="small-icon soundcloud"></span>'); $(element).find(".fc-event-time").before('<span class="small-icon recording"></span><span class="small-icon soundcloud"></span>');
} else if (event.soundcloud_id === -2) { } else if (event.soundcloud_id === -2) {
$(element).find(".fc-event-time").before('<span id="'+event.id+'" class="small-icon recording"></span><span id="'+event.id+'" class="small-icon progress"></span>'); $(element).find(".fc-event-time").before('<span class="small-icon recording"></span><span class="small-icon progress"></span>');
} else if (event.soundcloud_id === -3) { } else if (event.soundcloud_id === -3) {
$(element).find(".fc-event-time").before('<span id="'+event.id+'" class="small-icon recording"></span><span id="'+event.id+'" class="small-icon sc-error"></span>'); $(element).find(".fc-event-time").before('<span class="small-icon recording"></span><span class="small-icon sc-error"></span>');
} }
} else if (view.name === 'month') { } else if (view.name === 'month') {
if(event.soundcloud_id === -1) { if(event.soundcloud_id === -1) {
$(element).find(".fc-event-title").after('<span id="'+event.id+'" class="small-icon recording"></span>'); $(element).find(".fc-event-title").after('<span class="small-icon recording"></span>');
} else if (event.soundcloud_id > 0) { } else if (event.soundcloud_id > 0) {
$(element).find(".fc-event-title").after('<span id="'+event.id+'" class="small-icon recording"></span><span id="'+event.id+'" class="small-icon soundcloud"></span>'); $(element).find(".fc-event-title").after('<span class="small-icon recording"></span><span class="small-icon soundcloud"></span>');
} else if (event.soundcloud_id === -2) { } else if (event.soundcloud_id === -2) {
$(element).find(".fc-event-title").after('<span id="'+event.id+'" class="small-icon recording"></span><span id="'+event.id+'" class="small-icon progress"></span>'); $(element).find(".fc-event-title").after('<span class="small-icon recording"></span><span class="small-icon progress"></span>');
} else if (event.soundcloud_id === -3) { } else if (event.soundcloud_id === -3) {
$(element).find(".fc-event-title").after('<span id="'+event.id+'" class="small-icon recording"></span><span id="'+event.id+'" class="small-icon sc-error"></span>'); $(element).find(".fc-event-title").after('<span class="small-icon recording"></span><span class="small-icon sc-error"></span>');
} }
} }
} }
@ -267,27 +269,27 @@ function eventRender(event, element, view) {
if (event.linked) { if (event.linked) {
$(element) $(element)
.find(".fc-event-time") .find(".fc-event-time")
.before('<span id="'+event.id+'" class="small-icon linked"></span><span id="'+event.id+'" class="small-icon show-empty"></span>'); .before('<span class="small-icon linked"></span><span class="small-icon show-empty"></span>');
} else { } else {
$(element) $(element)
.find(".fc-event-time") .find(".fc-event-time")
.before('<span id="'+event.id+'" class="small-icon show-empty"></span>'); .before('<span class="small-icon show-empty"></span>');
} }
} else if (event.show_partial_filled === true) { } else if (event.show_partial_filled === true) {
if (event.linked) { if (event.linked) {
$(element) $(element)
.find(".fc-event-time") .find(".fc-event-time")
.before('<span id="'+event.id+'" class="small-icon linked"></span><span id="'+event.id+'" class="small-icon show-partial-filled"></span>'); .before('<span class="small-icon linked"></span><span class="small-icon show-partial-filled"></span>');
} else { } else {
$(element) $(element)
.find(".fc-event-time") .find(".fc-event-time")
.before('<span id="'+event.id+'" class="small-icon show-partial-filled"></span>'); .before('<span class="small-icon show-partial-filled"></span>');
} }
} else { } else {
if (event.linked) { if (event.linked) {
$(element) $(element)
.find(".fc-event-time") .find(".fc-event-time")
.before('<span id="'+event.id+'" class="small-icon linked"></span>'); .before('<span class="small-icon linked"></span>');
} }
} }
} else if (view.name === 'month') { } else if (view.name === 'month') {
@ -295,27 +297,27 @@ function eventRender(event, element, view) {
if (event.linked) { if (event.linked) {
$(element) $(element)
.find(".fc-event-title") .find(".fc-event-title")
.after('<span id="'+event.id+'" class="small-icon linked"></span><span id="'+event.id+'" title="'+$.i18n._("Show is empty")+'" class="small-icon show-empty"></span>'); .after('<span class="small-icon linked"></span><span title="'+$.i18n._("Show is empty")+'" class="small-icon show-empty"></span>');
} else { } else {
$(element) $(element)
.find(".fc-event-title") .find(".fc-event-title")
.after('<span id="'+event.id+'" title="'+$.i18n._("Show is empty")+'" class="small-icon show-empty"></span>'); .after('<span title="'+$.i18n._("Show is empty")+'" class="small-icon show-empty"></span>');
} }
} else if (event.show_partial_filled === true) { } else if (event.show_partial_filled === true) {
if (event.linked) { if (event.linked) {
$(element) $(element)
.find(".fc-event-title") .find(".fc-event-title")
.after('<span id="'+event.id+'" class="small-icon linked"></span><span id="'+event.id+'" title="'+$.i18n._("Show is partially filled")+'" class="small-icon show-partial-filled"></span>'); .after('<span class="small-icon linked"></span><span title="'+$.i18n._("Show is partially filled")+'" class="small-icon show-partial-filled"></span>');
} else { } else {
$(element) $(element)
.find(".fc-event-title") .find(".fc-event-title")
.after('<span id="'+event.id+'" title="'+$.i18n._("Show is partially filled")+'" class="small-icon show-partial-filled"></span>'); .after('<span title="'+$.i18n._("Show is partially filled")+'" class="small-icon show-partial-filled"></span>');
} }
} else { } else {
if (event.linked) { if (event.linked) {
$(element) $(element)
.find(".fc-event-title") .find(".fc-event-title")
.after('<span id="'+event.id+'" class="small-icon linked"></span>'); .after('<span class="small-icon linked"></span>');
} }
} }
} }
@ -324,9 +326,9 @@ function eventRender(event, element, view) {
//rebroadcast icon //rebroadcast icon
if (event.rebroadcast === 1) { if (event.rebroadcast === 1) {
if (view.name === 'agendaDay' || view.name === 'agendaWeek') { if (view.name === 'agendaDay' || view.name === 'agendaWeek') {
$(element).find(".fc-event-time").before('<span id="'+event.id+'" class="small-icon rebroadcast"></span>'); $(element).find(".fc-event-time").before('<span class="small-icon rebroadcast"></span>');
} else if (view.name === 'month') { } else if (view.name === 'month') {
$(element).find(".fc-event-title").after('<span id="'+event.id+'" class="small-icon rebroadcast"></span>'); $(element).find(".fc-event-title").after('<span class="small-icon rebroadcast"></span>');
} }
} }
} }
@ -334,7 +336,7 @@ function eventRender(event, element, view) {
function eventAfterRender( event, element, view ) { function eventAfterRender( event, element, view ) {
$(element).find(".small-icon").live('mouseover',function(){ $(element).find(".small-icon").live('mouseover',function(){
addQtipsToIcons($(this)); addQtipsToIcons($(this), event.id);
}); });
} }
@ -403,15 +405,25 @@ function getFullCalendarEvents(start, end, callback) {
} }
function checkSCUploadStatus(){ function checkSCUploadStatus(){
var url = baseUrl+'Library/get-upload-to-soundcloud-status/format/json'; var url = baseUrl+'Library/get-upload-to-soundcloud-status/format/json',
id;
$("span[class*=progress]").each(function(){ $("span[class*=progress]").each(function(){
var id = $(this).attr("id"); id = $(this).parents("div.fc-event").data("event").id;
$.post(url, {format: "json", id: id, type:"show"}, function(json){ $.post(url, {format: "json", id: id, type:"show"}, function(json){
if(json.sc_id > 0){ if (json.sc_id > 0){
$("span[id="+id+"]:not(.recording)").removeClass("progress").addClass("soundcloud"); $("#fc-show-instance-"+id)
}else if(json.sc_id == "-3"){ .find(".progress")
$("span[id="+id+"]:not(.recording)").removeClass("progress").addClass("sc-error"); .removeClass("progress")
.addClass("soundcloud");
} }
else if (json.sc_id == "-3"){
$("#fc-show-instance-"+id)
.find(".progress")
.removeClass("progress")
.addClass("sc-error");
}
setTimeout(checkSCUploadStatus, 5000); setTimeout(checkSCUploadStatus, 5000);
}); });
}); });
@ -425,7 +437,7 @@ function getCurrentShow(){
$el; $el;
$.post(url, {format: "json"}, function(json) { $.post(url, {format: "json"}, function(json) {
if (json.current_show === true) { if (json.current_show === true) {
$el = $("div[class*=fc-event-time][id="+json.si_id+"]"); $el = $("div[class*=fc-event-time]");
if (view_name === 'agendaDay' || view_name === 'agendaWeek') { if (view_name === 'agendaDay' || view_name === 'agendaWeek') {
/* Need to remove now-playing class because if user /* Need to remove now-playing class because if user
@ -440,40 +452,40 @@ function getCurrentShow(){
* icon will overwrite it. * icon will overwrite it.
*/ */
$el.siblings().remove("span[class=small-icon recording]"); $el.siblings().remove("span[class=small-icon recording]");
$el.before('<span id="'+json.si_id+'" class="small-icon now-playing"></span><span id="'+json.si_id+'" class="small-icon recording"></span>'); $el.before('<span class="small-icon now-playing"></span><span class="small-icon recording"></span>');
} else if ($el.siblings().hasClass("small-icon rebroadcast")) { } else if ($el.siblings().hasClass("small-icon rebroadcast")) {
/* Without removing rebroadcast icon, the now playing /* Without removing rebroadcast icon, the now playing
* icon will overwrite it. * icon will overwrite it.
*/ */
$el.siblings().remove("span[class=small-icon rebroadcast]"); $el.siblings().remove("span[class=small-icon rebroadcast]");
$el.before('<span id="'+json.si_id+'" class="small-icon now-playing"></span><span id="'+json.si_id+'" class="small-icon rebroadcast"></span>'); $el.before('<span class="small-icon now-playing"></span><span class="small-icon rebroadcast"></span>');
} else { } else {
$el.before('<span id="'+json.si_id+'" class="small-icon now-playing"></span>'); $el.before('<span class="small-icon now-playing"></span>');
} }
} }
} else if (view_name === 'month') { } else if (view_name === 'month') {
if (!$("span[class*=fc-event-title][id="+json.si_id+"]").siblings().hasClass("small-icon now-playing")) { if (!$("span[class*=fc-event-title]").siblings().hasClass("small-icon now-playing")) {
$("span[class*=fc-event-title][id="+json.si_id+"]").after('<span id="'+json.si_id+'" class="small-icon now-playing"></span>'); $("span[class*=fc-event-title]").after('<span class="small-icon now-playing"></span>');
} }
} }
} }
//remove icon from shows that have ended //remove icon from shows that have ended
$(".now-playing").each(function(){ $(".now-playing").each(function(){
id = $(this).attr("id"); id = $(this).parents("div.fc-event").data("event").id;
if (id != json.si_id) {
$(this).remove("span[small-icon now-playing]"); if (id != json.si_id) {
} $(this).remove("span[small-icon now-playing]");
}); }
});
setTimeout(getCurrentShow, 5000); setTimeout(getCurrentShow, 5000);
}); });
} }
function addQtipsToIcons(ele, id){
function addQtipsToIcons(ele){
var id = $(ele).attr("id"); if ($(ele).hasClass("progress")){
if($(ele).hasClass("progress")){
$(ele).qtip({ $(ele).qtip({
content: { content: {
text: $.i18n._("Uploading in progress...") text: $.i18n._("Uploading in progress...")

View file

@ -12,8 +12,8 @@ var AIRTIME = (function(AIRTIME){
var serverTimezoneOffset = 0; var serverTimezoneOffset = 0;
function closeDialog(event, ui) { function closeDialogCalendar(event, ui) {
$("#schedule_calendar").fullCalendar( 'refetchEvents' ); //$("#schedule_calendar").fullCalendar( 'refetchEvents' );
$(this).remove(); $(this).remove();
} }
@ -58,24 +58,22 @@ function confirmCancelRecordedShow(show_instance_id){
} }
} }
function uploadToSoundCloud(show_instance_id){ function uploadToSoundCloud(show_instance_id, el){
var url = baseUrl+"Schedule/upload-to-sound-cloud"; var url = baseUrl+"Schedule/upload-to-sound-cloud",
var span = $(window.triggerElement).find(".recording"); $el = $(el),
$span = $el.find(".soundcloud");
$.post(url, $.post(url, {id: show_instance_id, format: "json"});
{id: show_instance_id, format: "json"},
function(json){
scheduleRefetchEvents(json);
});
if(span.length == 0){ //first upload to soundcloud.
span = $(window.triggerElement).find(".soundcloud"); if ($span.length === 0){
span.removeClass("soundcloud") $span = $("<span/>", {"class": "progress"});
.addClass("progress");
}else{ $el.find(".fc-event-title").after($span);
span.removeClass("recording") }
.addClass("progress"); else {
$span.removeClass("soundcloud").addClass("progress");
} }
} }
@ -93,8 +91,6 @@ function checkCalendarSCUploadStatus(){
else if (json.sc_id == "-3") { else if (json.sc_id == "-3") {
span.removeClass("progress").addClass("sc-error"); span.removeClass("progress").addClass("sc-error");
} }
setTimeout(checkCalendarSCUploadStatus, 5000);
} }
function checkSCUploadStatusRequest() { function checkSCUploadStatusRequest() {
@ -106,6 +102,7 @@ function checkCalendarSCUploadStatus(){
} }
$("#schedule_calendar span.progress").each(checkSCUploadStatusRequest); $("#schedule_calendar span.progress").each(checkSCUploadStatusRequest);
setTimeout(checkCalendarSCUploadStatus, 5000);
} }
function findViewportDimensions() { function findViewportDimensions() {
@ -164,7 +161,7 @@ function buildScheduleDialog (json, instance_id) {
resizable: false, resizable: false,
draggable: true, draggable: true,
modal: true, modal: true,
close: closeDialog, close: closeDialogCalendar,
buttons: [ buttons: [
{ {
text: $.i18n._("Ok"), text: $.i18n._("Ok"),
@ -189,10 +186,10 @@ function buildScheduleDialog (json, instance_id) {
//set max heights of datatables. //set max heights of datatables.
dialog.find(".lib-content .dataTables_scrolling") dialog.find(".lib-content .dataTables_scrolling")
.css("max-height", height - 90 - 155); .css("max-height", height - 90 - 200);
dialog.find(".sb-content .dataTables_scrolling") dialog.find(".sb-content .dataTables_scrolling")
.css("max-height", height - 90 - 60); .css("max-height", height - 90 - 65);
dialog.dialog('open'); dialog.dialog('open');
} }
@ -217,7 +214,7 @@ function buildContentDialog (json){
width: width, width: width,
height: height, height: height,
modal: true, modal: true,
close: closeDialog, close: closeDialogCalendar,
buttons: [ buttons: [
{ {
text: $.i18n._("Ok"), text: $.i18n._("Ok"),
@ -421,7 +418,7 @@ $(document).ready(function() {
if (oItems.soundcloud_upload !== undefined) { if (oItems.soundcloud_upload !== undefined) {
callback = function() { callback = function() {
uploadToSoundCloud(data.id); uploadToSoundCloud(data.id, this.context);
}; };
oItems.soundcloud_upload.callback = callback; oItems.soundcloud_upload.callback = callback;
} }

View file

@ -40,8 +40,6 @@ var AIRTIME = (function(AIRTIME){
}; };
mod.updateCalendarStatusIcon = function(json) { mod.updateCalendarStatusIcon = function(json) {
//make sure we are only executing this code on the calendar view, not //make sure we are only executing this code on the calendar view, not
//the Now Playing view. //the Now Playing view.
if (window.location.pathname.toLowerCase().indexOf("schedule") < 0) { if (window.location.pathname.toLowerCase().indexOf("schedule") < 0) {
@ -52,16 +50,24 @@ var AIRTIME = (function(AIRTIME){
var instance_id = json.schedule[0].instance; var instance_id = json.schedule[0].instance;
var lastElem = json.schedule[json.schedule.length-1]; var lastElem = json.schedule[json.schedule.length-1];
var $elem = $($(".fc-event-inner.fc-event-skin .fc-event-title#"+instance_id).parent()); var $elem = $("#fc-show-instance-"+instance_id);
$elem.find(".small-icon").remove();
//if the show is linked, then replace $elem to reference all linked
//instances
if ($elem.data("show-linked") == "1") {
var show_id = $elem.data("show-id");
$elem = $('*[data-show-id="'+show_id+'"]');
}
$elem.find(".show-empty, .show-partial-filled").remove();
if (json.schedule[1].empty) { if (json.schedule[1].empty) {
$elem $elem
.find(".fc-event-title") .find(".fc-event-inner")
.after('<span id="'+instance_id+'" title="'+$.i18n._("Show is empty")+'" class="small-icon show-empty"></span>'); .append('<span id="'+instance_id+'" title="'+$.i18n._("Show is empty")+'" class="small-icon show-empty"></span>');
} else if (lastElem["fRuntime"][0] == "-") { } else if (lastElem["fRuntime"][0] == "-") {
$elem $elem
.find(".fc-event-title") .find(".fc-event-inner")
.after('<span id="'+instance_id+'" title="'+$.i18n._("Show is partially filled")+'" class="small-icon show-partial-filled"></span>'); .append('<span id="'+instance_id+'" title="'+$.i18n._("Show is partially filled")+'" class="small-icon show-partial-filled"></span>');
} }
} }
@ -479,7 +485,7 @@ var AIRTIME = (function(AIRTIME){
$image, $image,
$div, $div,
headerIcon; headerIcon;
fnPrepareSeparatorRow = function fnPrepareSeparatorRow(sRowContent, sClass, iNodeIndex) { fnPrepareSeparatorRow = function fnPrepareSeparatorRow(sRowContent, sClass, iNodeIndex) {
$node = $(nRow.children[iNodeIndex]); $node = $(nRow.children[iNodeIndex]);
$node.html(sRowContent); $node.html(sRowContent);
@ -546,7 +552,7 @@ var AIRTIME = (function(AIRTIME){
cl = 'sb-footer'; cl = 'sb-footer';
//check the show's content status. //check the show's content status.
if (aData.runtime > 0) { if (aData.runtime >= 0) {
$node.html('<span class="ui-icon ui-icon-check"></span>'); $node.html('<span class="ui-icon ui-icon-check"></span>');
cl = cl + ' ui-state-highlight'; cl = cl + ' ui-state-highlight';
} }
@ -614,7 +620,7 @@ var AIRTIME = (function(AIRTIME){
} }
$node = $(nRow.children[0]); $node = $(nRow.children[0]);
if (aData.allowed === true && aData.scheduled >= 1) { if (aData.allowed === true && aData.scheduled >= 1 && aData.linked_allowed) {
$node.html('<input type="checkbox" name="'+aData.id+'"></input>'); $node.html('<input type="checkbox" name="'+aData.id+'"></input>');
} }
else { else {
@ -835,7 +841,7 @@ var AIRTIME = (function(AIRTIME){
}); });
$sbTable.find("tbody").on("click", "input:checkbox", function(ev) { $sbTable.find("tbody").on("click", "input:checkbox", function(ev) {
var $cb = $(this), var $cb = $(this),
$tr = $cb.parents("tr"), $tr = $cb.parents("tr"),
$prev; $prev;

View file

@ -35,7 +35,8 @@ AIRTIME = (function(AIRTIME) {
dayNamesMin: i18n_days_short, dayNamesMin: i18n_days_short,
onClick: function(sDate, oDatePicker) { onClick: function(sDate, oDatePicker) {
$(this).datepicker( "setDate", sDate ); $(this).datepicker( "setDate", sDate );
} },
onClose: validateTimeRange
}; };
oBaseTimePickerSettings = { oBaseTimePickerSettings = {
@ -53,7 +54,7 @@ AIRTIME = (function(AIRTIME) {
widgetHeight = viewport.height - 180; widgetHeight = viewport.height - 180;
screenWidth = Math.floor(viewport.width - 40); screenWidth = Math.floor(viewport.width - 40);
var libTableHeight = widgetHeight - 130, var libTableHeight = widgetHeight - 175,
builderTableHeight = widgetHeight - 95, builderTableHeight = widgetHeight - 95,
oTable; oTable;
@ -90,32 +91,61 @@ AIRTIME = (function(AIRTIME) {
} }
} }
function validateTimeRange() {
var oRange,
inputs = $('.sb-timerange > input'),
start, end;
oRange = AIRTIME.utilities.fnGetScheduleRange(dateStartId, timeStartId, dateEndId, timeEndId);
start = oRange.start;
end = oRange.end;
if (end >= start) {
inputs.removeClass('error');
}
else {
if (!inputs.hasClass('error')) {
inputs.addClass('error');
}
}
return {
start: start,
end: end,
isValid: end >= start
};
}
function showSearchSubmit() { function showSearchSubmit() {
var fn, var fn,
oRange,
op, op,
oTable = $('#show_builder_table').dataTable(); oTable = $('#show_builder_table').dataTable(),
check;
//reset timestamp value since input values could have changed.
AIRTIME.showbuilder.resetTimestamp(); check = validateTimeRange();
oRange = AIRTIME.utilities.fnGetScheduleRange(dateStartId, timeStartId, dateEndId, timeEndId); if (check.isValid) {
fn = oTable.fnSettings().fnServerData; //reset timestamp value since input values could have changed.
fn.start = oRange.start; AIRTIME.showbuilder.resetTimestamp();
fn.end = oRange.end;
fn = oTable.fnSettings().fnServerData;
op = $("div.sb-advanced-options"); fn.start = check.start;
if (op.is(":visible")) { fn.end = check.end;
if (fn.ops === undefined) { op = $("div.sb-advanced-options");
fn.ops = {}; if (op.is(":visible")) {
}
fn.ops.showFilter = op.find("#sb_show_filter").val(); if (fn.ops === undefined) {
fn.ops.myShows = op.find("#sb_my_shows").is(":checked") ? 1 : 0; fn.ops = {};
}
fn.ops.showFilter = op.find("#sb_show_filter").val();
fn.ops.myShows = op.find("#sb_my_shows").is(":checked") ? 1 : 0;
}
oTable.fnDraw();
} }
oTable.fnDraw();
} }
mod.onReady = function() { mod.onReady = function() {
@ -134,10 +164,22 @@ AIRTIME = (function(AIRTIME) {
$(this).removeClass("ui-state-hover"); $(this).removeClass("ui-state-hover");
}); });
$builder.find(dateStartId).datepicker(oBaseDatePickerSettings); $builder.find(dateStartId)
$builder.find(timeStartId).timepicker(oBaseTimePickerSettings); .datepicker(oBaseDatePickerSettings)
$builder.find(dateEndId).datepicker(oBaseDatePickerSettings); .blur(validateTimeRange);
$builder.find(timeEndId).timepicker(oBaseTimePickerSettings);
$builder.find(timeStartId)
.timepicker(oBaseTimePickerSettings)
.blur(validateTimeRange);
$builder.find(dateEndId)
.datepicker(oBaseDatePickerSettings)
.blur(validateTimeRange);
$builder.find(timeEndId)
.timepicker(oBaseTimePickerSettings)
.blur(validateTimeRange);
oRange = AIRTIME.utilities.fnGetScheduleRange(dateStartId, timeStartId, oRange = AIRTIME.utilities.fnGetScheduleRange(dateStartId, timeStartId,
dateEndId, timeEndId); dateEndId, timeEndId);

View file

@ -88,19 +88,13 @@ var AIRTIME = (function(AIRTIME){
mod.fnGetScheduleRange = function(dateStart, timeStart, dateEnd, timeEnd) { mod.fnGetScheduleRange = function(dateStart, timeStart, dateEnd, timeEnd) {
var iStart, var iStart,
iEnd, iEnd,
iRange, iRange;
DEFAULT_RANGE = 60*60*24;
iStart = AIRTIME.utilities.fnGetTimestamp(dateStart, timeStart); iStart = AIRTIME.utilities.fnGetTimestamp(dateStart, timeStart);
iEnd = AIRTIME.utilities.fnGetTimestamp(dateEnd, timeEnd); iEnd = AIRTIME.utilities.fnGetTimestamp(dateEnd, timeEnd);
iRange = iEnd - iStart; iRange = iEnd - iStart;
if (iEnd < iStart) {
iEnd = iStart + DEFAULT_RANGE;
iRange = DEFAULT_RANGE;
}
return { return {
start: iStart, start: iStart,
end: iEnd, end: iEnd,

View file

@ -1,17 +1,23 @@
{ {
"sProcessing": "Bitte warten...", "sEmptyTable": "Tabelle enthält keine Daten",
"sLengthMenu": "_MENU_ Einträge anzeigen",
"sZeroRecords": "Keine Einträge vorhanden.",
"sInfo": "_START_ bis _END_ von _TOTAL_ Einträgen", "sInfo": "_START_ bis _END_ von _TOTAL_ Einträgen",
"sInfoEmpty": "0 bis 0 von 0 Einträgen", "sInfoEmpty": "0 bis 0 von 0 Einträgen",
"sInfoFiltered": "(gefiltert von _MAX_ Einträgen)", "sInfoFiltered": "(gefiltert von _MAX_ Einträgen)",
"sInfoPostFix": "", "sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "_MENU_ Einträge anzeigen",
"sLoadingRecords": "Lade...",
"sProcessing": "Bitte warten...",
"sSearch": "", "sSearch": "",
"sUrl": "", "sZeroRecords": "Keine Einträge vorhanden.",
"oAria": {
"sSortAscending": ": Spalte aufsteigend Sortieren",
"sSortDescending": ": Spalte absteigend Sortieren"
},
"oPaginate": { "oPaginate": {
"sFirst": "Erster", "sFirst": "Erste",
"sPrevious": "Zurück", "sPrevious": "Zurück",
"sNext": "Nächster", "sNext": "Nächste",
"sLast": "Letzter" "sLast": "Letzte"
} }
} }

View file

@ -1,25 +1,27 @@
// German // German
plupload.addI18n({ plupload.addI18n({
'Select files' : 'Dateien hochladen', '%d files queued': '%d Dateien in der Warteschlange',
'Add files to the upload queue and click the start button.' : 'Dateien hinzuf&uuml;gen und auf \'Hochladen\' klicken.', 'Add files to the upload queue and click the start button.' : '\'Dateien\' hinzuf&uuml;gen und auf \'Hochladen\' klicken.',
'Filename' : 'Dateiname',
'Status' : 'Status',
'Size' : 'Gr&ouml;&szlig;e',
'Add files' : 'Dateien', // hinzuf&uuml;gen', 'Add files' : 'Dateien', // hinzuf&uuml;gen',
'Stop current upload' : 'Aktuelles Hochladen stoppen', 'Add Files': 'Dateien', // hinzuf&uuml;gen',
'Start uploading queue' : 'Hochladen starten', 'Drag files here.' : 'Ziehe Dateien hier hin. (Drag &amp; Drop)',
'Uploaded %d/%d files': '%d/%d Dateien sind hochgeladen',
'N/A' : 'Nicht verf&uuml;gbar',
'Drag files here.' : 'Ziehen Sie die Dateien hier hin',
'File extension error.': 'Fehler bei Dateiendung', 'File extension error.': 'Fehler bei Dateiendung',
'File size error.': 'Fehler bei Dateigr&ouml;ße', 'File size error.': 'Fehler bei Dateigr&ouml;ße',
'Init error.': 'Initialisierungsfehler', 'Filename' : 'Dateiname',
'HTTP Error.': 'HTTP-Fehler',
'Security error.': 'Sicherheitsfehler',
'Generic error.': 'Typischer Fehler', 'Generic error.': 'Typischer Fehler',
'HTTP Error.': 'HTTP-Fehler',
'Init error.': 'Initialisierungsfehler',
'IO error.': 'Ein/Ausgabe-Fehler', 'IO error.': 'Ein/Ausgabe-Fehler',
'Stop Upload': 'Hochladen stoppen', 'N/A' : 'Nicht verf&uuml;gbar',
'Security error.': 'Sicherheitsfehler',
'Select files' : 'Dateien hochladen',
'Size' : 'Gr&ouml;&szlig;e',
'Start upload': 'Hochladen', 'Start upload': 'Hochladen',
'%d files queued': '%d Dateien in der Warteschlange', 'Start Upload': 'Hochladen',
'Start uploading queue' : 'Hochladen starten',
'Status' : 'Status',
'Stop current upload' : 'Aktuelles Hochladen stoppen',
'Stop Upload': 'Hochladen stoppen',
'Uploaded %d/%d files': '%d/%d Dateien sind hochgeladen',
"Error: Invalid file extension: " : $.i18n._("Error: Invalid file extension: ") "Error: Invalid file extension: " : $.i18n._("Error: Invalid file extension: ")
}); });

View file

@ -56,6 +56,16 @@ PlaylistEditor.prototype.init = function(tracks) {
trackEditor.on("deactivateSelection", "onAudioDeselection", audioControls); trackEditor.on("deactivateSelection", "onAudioDeselection", audioControls);
trackEditor.on("changecursor", "onCursorSelection", audioControls); trackEditor.on("changecursor", "onCursorSelection", audioControls);
trackEditor.on("changecursor", "onSelectUpdate", this); trackEditor.on("changecursor", "onSelectUpdate", this);
trackEditor.on("unregister", (function() {
var editor = this;
audioControls.remove("trackedit", "onTrackEdit", editor);
audioControls.remove("changeresolution", "onResolutionChange", editor);
that.removeTrack(editor);
}).bind(trackEditor));
} }
div.innerHTML = ''; div.innerHTML = '';
@ -79,7 +89,27 @@ PlaylistEditor.prototype.init = function(tracks) {
audioControls.on("trimaudio", "onTrimAudio", this); audioControls.on("trimaudio", "onTrimAudio", this);
audioControls.on("removeaudio", "onRemoveAudio", this); audioControls.on("removeaudio", "onRemoveAudio", this);
audioControls.on("changestate", "onStateChange", this); audioControls.on("changestate", "onStateChange", this);
audioControls.on("changeselection", "onSelectionChange", this); audioControls.on("changeselection", "onSelectionChange", this);
};
PlaylistEditor.prototype.removeTrack = function(trackEditor) {
var i,
len,
editor,
editors = this.trackEditors;
for (i = 0, len = editors.length; i < len; i++) {
editor = editors[i];
if (editor === trackEditor) {
editors.splice(i, 1);
return;
}
}
};
PlaylistEditor.prototype.resize = function() {
this.timeScale.onResize();
}; };
PlaylistEditor.prototype.onTrimAudio = function() { PlaylistEditor.prototype.onTrimAudio = function() {

View file

@ -16,8 +16,6 @@ AudioPlayout.prototype.init = function(config) {
this.gainNode = undefined; this.gainNode = undefined;
this.destination = this.ac.destination; this.destination = this.ac.destination;
this.analyser = this.ac.createAnalyser();
this.analyser.connect(this.destination);
}; };
AudioPlayout.prototype.getBuffer = function() { AudioPlayout.prototype.getBuffer = function() {
@ -41,7 +39,7 @@ AudioPlayout.prototype.applyFades = function(fades, relPos, now, delay) {
duration; duration;
this.gainNode && this.gainNode.disconnect(); this.gainNode && this.gainNode.disconnect();
this.gainNode = this.ac.createGainNode(); this.gainNode = this.ac.createGain();
for (id in fades) { for (id in fades) {
@ -83,7 +81,8 @@ AudioPlayout.prototype.loadData = function (audioData, cb) {
cb(buffer); cb(buffer);
}, },
function(err) { function(err) {
console.log("err(decodeAudioData): "+err); console.log("err(decodeAudioData): "+err);
cb(null, err);
} }
); );
}; };
@ -136,7 +135,7 @@ AudioPlayout.prototype.setSource = function(source) {
this.source.buffer = this.buffer; this.source.buffer = this.buffer;
this.source.connect(this.gainNode); this.source.connect(this.gainNode);
this.gainNode.connect(this.analyser); this.gainNode.connect(this.destination);
}; };
/* /*

View file

@ -8,7 +8,8 @@ TimeScale.prototype.init = function(config) {
var that = this, var that = this,
canv, canv,
div; div,
resizeTimer;
makePublisher(this); makePublisher(this);
@ -36,6 +37,24 @@ TimeScale.prototype.init = function(config) {
this.prevScrollPos = 0; //checking the horizontal scroll (must update timeline above in case of change) this.prevScrollPos = 0; //checking the horizontal scroll (must update timeline above in case of change)
//TODO check scroll adjust.
function doneResizing() {
that.width = that.container.clientWidth;
that.height = that.container.clientHeight;
canv.setAttribute('width', that.width);
canv.setAttribute('height', that.height);
that.drawScale();
};
function onResize() {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(doneResizing, 100);
};
TimeScale.prototype.onResize = onResize;
this.drawScale(); this.drawScale();
}; };

View file

@ -176,6 +176,7 @@ TrackEditor.prototype.loadBuffer = function(src) {
var that = this, var that = this,
xhr = new XMLHttpRequest(); xhr = new XMLHttpRequest();
xhr.open('GET', src, true);
xhr.responseType = 'arraybuffer'; xhr.responseType = 'arraybuffer';
xhr.addEventListener('progress', function(e) { xhr.addEventListener('progress', function(e) {
@ -198,7 +199,6 @@ TrackEditor.prototype.loadBuffer = function(src) {
); );
}, false); }, false);
xhr.open('GET', src, true);
xhr.send(); xhr.send();
}; };
@ -208,11 +208,20 @@ TrackEditor.prototype.drawTrack = function(buffer) {
this.drawer.drawFades(this.fades); this.drawer.drawFades(this.fades);
}; };
TrackEditor.prototype.onTrackLoad = function(buffer) { TrackEditor.prototype.onTrackLoad = function(buffer, err) {
var res, var res,
startTime, startTime,
endTime; endTime;
if (err !== undefined) {
this.container.innerHTML = "";
this.container.classList.add("error");
this.fire('unregister');
return;
}
if (this.cues === undefined) { if (this.cues === undefined) {
this.setCuePoints(0, buffer.length - 1); this.setCuePoints(0, buffer.length - 1);
} }
@ -282,6 +291,8 @@ TrackEditor.prototype.deactivate = function() {
/* start of state methods */ /* start of state methods */
TrackEditor.prototype.timeShift = function(e) { TrackEditor.prototype.timeShift = function(e) {
e.preventDefault();
var el = e.currentTarget, //want the events placed on the channel wrapper. var el = e.currentTarget, //want the events placed on the channel wrapper.
startX = e.pageX, startX = e.pageX,
diffX = 0, diffX = 0,
@ -296,6 +307,8 @@ TrackEditor.prototype.timeShift = function(e) {
//dynamically put an event on the element. //dynamically put an event on the element.
el.onmousemove = function(e) { el.onmousemove = function(e) {
e.preventDefault();
var endX = e.pageX; var endX = e.pageX;
diffX = endX - startX; diffX = endX - startX;
@ -303,7 +316,9 @@ TrackEditor.prototype.timeShift = function(e) {
editor.drawer.setTimeShift(updatedX); editor.drawer.setTimeShift(updatedX);
editor.leftOffset = editor.pixelsToSamples(updatedX); editor.leftOffset = editor.pixelsToSamples(updatedX);
}; };
el.onmouseup = function() { el.onmouseup = function(e) {
e.preventDefault();
var delta; var delta;
el.onmousemove = el.onmouseup = null; el.onmousemove = el.onmouseup = null;
@ -453,6 +468,8 @@ TrackEditor.prototype.findLayerOffset = function(e) {
}; };
TrackEditor.prototype.selectStart = function(e) { TrackEditor.prototype.selectStart = function(e) {
e.preventDefault();
var el = e.currentTarget, //want the events placed on the channel wrapper. var el = e.currentTarget, //want the events placed on the channel wrapper.
editor = this, editor = this,
startX = e.layerX || e.offsetX, //relative to e.target (want the canvas). startX = e.layerX || e.offsetX, //relative to e.target (want the canvas).
@ -475,6 +492,8 @@ TrackEditor.prototype.selectStart = function(e) {
//dynamically put an event on the element. //dynamically put an event on the element.
el.onmousemove = function(e) { el.onmousemove = function(e) {
e.preventDefault();
var currentX = layerOffset + (e.layerX || e.offsetX), var currentX = layerOffset + (e.layerX || e.offsetX),
delta = currentX - prevX, delta = currentX - prevX,
minX = Math.min(prevX, currentX, startX), minX = Math.min(prevX, currentX, startX),
@ -500,6 +519,8 @@ TrackEditor.prototype.selectStart = function(e) {
prevX = currentX; prevX = currentX;
}; };
el.onmouseup = function(e) { el.onmouseup = function(e) {
e.preventDefault();
var endX = layerOffset + (e.layerX || e.offsetX), var endX = layerOffset + (e.layerX || e.offsetX),
minX, maxX, minX, maxX,
startTime, endTime; startTime, endTime;
@ -555,6 +576,8 @@ TrackEditor.prototype.selectCursorPos = function(e) {
}; };
TrackEditor.prototype.selectFadeIn = function(e) { TrackEditor.prototype.selectFadeIn = function(e) {
e.preventDefault();
var startX = e.layerX || e.offsetX, //relative to e.target (want the canvas). var startX = e.layerX || e.offsetX, //relative to e.target (want the canvas).
layerOffset, layerOffset,
FADETYPE = "FadeIn", FADETYPE = "FadeIn",
@ -572,6 +595,8 @@ TrackEditor.prototype.selectFadeIn = function(e) {
}; };
TrackEditor.prototype.selectFadeOut = function(e) { TrackEditor.prototype.selectFadeOut = function(e) {
e.preventDefault();
var startX = e.layerX || e.offsetX, //relative to e.target (want the canvas). var startX = e.layerX || e.offsetX, //relative to e.target (want the canvas).
layerOffset, layerOffset,
FADETYPE = "FadeOut", FADETYPE = "FadeOut",

View file

@ -365,6 +365,16 @@ def airtime_221_tar():
do_run('tar xfz airtime-2.2.1.tar.gz') do_run('tar xfz airtime-2.2.1.tar.gz')
do_sudo('cd /home/martin/airtime-2.2.1/install_full/ubuntu && ./airtime-full-install') do_sudo('cd /home/martin/airtime-2.2.1/install_full/ubuntu && ./airtime-full-install')
def airtime_230_tar():
do_run('wget http://downloads.sourceforge.net/project/airtime/2.3.0/airtime-2.3.0.tar.gz')
do_run('tar xfz airtime-2.3.0.tar.gz')
do_sudo('cd /home/martin/airtime-2.3.0/install_full/ubuntu && ./airtime-full-install')
def airtime_231_tar():
do_run('wget http://downloads.sourceforge.net/project/airtime/2.3.1/airtime-2.3.1-ga.tar.gz')
do_run('tar xfz airtime-2.3.1-ga.tar.gz')
do_sudo('cd /home/martin/airtime-2.3.1/install_full/ubuntu && ./airtime-full-install')
def airtime_latest_deb(): def airtime_latest_deb():
append('/etc/apt/sources.list', "deb http://apt.sourcefabric.org/ lucid main", use_sudo=True) append('/etc/apt/sources.list', "deb http://apt.sourcefabric.org/ lucid main", use_sudo=True)

View file

@ -2,11 +2,11 @@
exec 2>&1 exec 2>&1
target="airtime_git_branch:devel" target="airtime_git_branch:2.4.x"
#target="airtime_git_branch:airtime-2.0.0-RC1" #target="airtime_git_branch:airtime-2.0.0-RC1"
airtime_versions=("") airtime_versions=("airtime_231_tar")
#airtime_versions=("airtime_191_tar" "airtime_192_tar" "airtime_192_tar" "airtime_194_tar" "airtime_195_tar") #airtime_versions=("airtime_191_tar" "airtime_192_tar" "airtime_192_tar" "airtime_194_tar" "airtime_195_tar")
ubuntu_versions=("ubuntu_lucid_32" "ubuntu_lucid_64" "ubuntu_natty_32" "ubuntu_natty_64" "ubuntu_oneiric_32" "ubuntu_oneiric_64" "ubuntu_precise_32" "ubuntu_precise_64" "ubuntu_quantal_32" "ubuntu_quantal_64" "debian_squeeze_32" "debian_squeeze_64" "debian_wheezy_32" "debian_wheezy_64") ubuntu_versions=("ubuntu_lucid_32" "ubuntu_lucid_64" "ubuntu_precise_32" "ubuntu_precise_64" "ubuntu_quantal_32" "ubuntu_quantal_64" "ubuntu_raring_32" "ubuntu_raring_64" "debian_squeeze_32" "debian_squeeze_64" "debian_wheezy_32" "debian_wheezy_64")
#ubuntu_versions=("debian_wheezy_32" "debian_wheezy_64") #ubuntu_versions=("debian_wheezy_32" "debian_wheezy_64")
num1=${#ubuntu_versions[@]} num1=${#ubuntu_versions[@]}

View file

@ -6,7 +6,7 @@ VERSION=2.4.0~$(date "+%Y%m%d")
BUILDDEST=/tmp/airtime-${VERSION}/ BUILDDEST=/tmp/airtime-${VERSION}/
DEBDIR=`pwd`/debian DEBDIR=`pwd`/debian
git checkout master git checkout $(git branch | grep "^*" | cut -d' ' -f 2)
git pull git pull
echo "cleaning up previous build..." echo "cleaning up previous build..."

View file

@ -0,0 +1,5 @@
[PHP]
memory_limit = 512M
magic_quotes_gpc = Off
file_uploads = On
upload_tmp_dir = /tmp

View file

@ -121,21 +121,43 @@ else
apt-get -y --force-yes install apache2 libapache2-mod-php5 apt-get -y --force-yes install apache2 libapache2-mod-php5
# Apache Config File # Apache Config File
echo "----------------------------------------------------" echo "----------------------------------------------------"
echo "2. Apache Config File" echo "2.1 Apache Config File"
echo "----------------------------------------------------" echo "----------------------------------------------------"
if [ ! -f /etc/apache2/sites-available/airtime ]; then if [ ! -f /etc/apache2/sites-available/airtime ]; then
echo "Creating Apache config for Airtime..."
cp $SCRIPTPATH/../apache/airtime-vhost /etc/apache2/sites-available/airtime cp $SCRIPTPATH/../apache/airtime-vhost /etc/apache2/sites-available/airtime
a2dissite default a2dissite default
a2ensite airtime a2ensite airtime
a2enmod rewrite php5
service apache2 restart
else else
echo "Apache config for Airtime already exists..." echo "Apache config for Airtime already exists..."
fi fi
if [ ! -d /usr/share/airtime/public ]; then
echo "Creating Apache web root directory..."
mkdir -p /usr/share/airtime/public/
else
echo "Airtime web root directory already exists..."
fi
# PHP Config File for Apache
echo "----------------------------------------------------"
echo "2.2 PHP Config File for Apache"
echo "----------------------------------------------------"
if [ ! -f /etc/php5/apache2/airtime.ini ]; then
echo "Creating Airtime PHP config for Apache..."
cp $SCRIPTPATH/../php5/airtime.ini /etc/php5/apache2/conf.d/airtime.ini
else
echo "Airtime PHP config for Apache already exists..."
fi
# Enable modules and restart Apache to enable any configuration changes
echo "----------------------------------------------------"
echo "2.3 Enable Apache Modules and Restart Apache"
echo "----------------------------------------------------"
a2enmod rewrite php5
service apache2 restart
fi fi
# Enable Icecast # Enable Icecast
echo "----------------------------------------------------" echo "----------------------------------------------------"
echo "3. Enable Icecast" echo "3. Enable Icecast"

View file

@ -0,0 +1,28 @@
<?php
/* This class deals with any modifications to config files in /etc/airtime
* as well as backups. All functions other than start() should be marked
* as private. */
class AirtimeConfigFileUpgrade{
public static function start(){
echo "* Updating configFiles".PHP_EOL;
self::UpdateIniFiles();
}
/**
* After the configuration files have been copied to /etc/airtime,
* this function will update them to values unique to this
* particular installation.
*/
private static function UpdateIniFiles()
{
$ini = parse_ini_file(UpgradeCommon::CONF_FILE_AIRTIME, true);
$ini['rabbitmq']['vhost'] = '/airtime';
$ini['rabbitmq']['user'] = 'airtime';
$ini['rabbitmq']['password'] = UpgradeCommon::GenerateRandomString();
UpgradeCommon::write_ini_file($ini, UpgradeCommon::CONF_FILE_AIRTIME, true);
}
}

View file

@ -1,8 +1,11 @@
<?php <?php
require_once 'DbUpgrade.php'; require_once 'DbUpgrade.php';
require_once 'ConfFileUpgrade.php';
require_once 'common/UpgradeCommon.php';
$filename = "/etc/airtime/airtime.conf"; $filename = "/etc/airtime/airtime.conf";
$values = parse_ini_file($filename, true); $values = parse_ini_file($filename, true);
AirtimeConfigFileUpgrade::start();
AirtimeDatabaseUpgrade::start($values); AirtimeDatabaseUpgrade::start($values);

View file

@ -0,0 +1,98 @@
<?php
/* These are helper functions that are common to each upgrade such as
* creating connections to a database, backing up config files etc.
*/
class UpgradeCommon{
const CONF_FILE_AIRTIME = "/etc/airtime/airtime.conf";
const CONF_FILE_PYPO = "/etc/airtime/pypo.cfg";
const CONF_FILE_LIQUIDSOAP = "/etc/airtime/liquidsoap.cfg";
const CONF_FILE_MEDIAMONITOR = "/etc/airtime/media-monitor.cfg";
const CONF_FILE_API_CLIENT = "/etc/airtime/api_client.cfg";
const CONF_PYPO_GRP = "pypo";
const CONF_WWW_DATA_GRP = "www-data";
const CONF_BACKUP_SUFFIX = "240";
const VERSION_NUMBER = "2.4.0";
private static function GetAirtimeSrcDir()
{
return __DIR__."/../../../../airtime_mvc";
}
/**
* This function generates a random string.
*
* The random string uses two parameters: $p_len and $p_chars. These
* parameters do not need to be provided, in which case defaults are
* used.
*
* @param string $p_len
* How long should the generated string be.
* @param string $p_chars
* String containing chars that should be used for generating.
* @return string
* The generated random string.
*/
public static function GenerateRandomString($p_len=20, $p_chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
{
$string = '';
for ($i = 0; $i < $p_len; $i++)
{
$pos = mt_rand(0, strlen($p_chars)-1);
$string .= $p_chars{$pos};
}
return $string;
}
//stupid hack found on http://stackoverflow.com/a/1268642/276949
//with some modifications: 1) Spaces are inserted in between sections and
//2) values are not quoted.
public static function write_ini_file($assoc_arr, $path, $has_sections = false)
{
$content = "";
if ($has_sections) {
$first_line = true;
foreach ($assoc_arr as $key=>$elem) {
if ($first_line) {
$content .= "[".$key."]\n";
$first_line = false;
} else {
$content .= "\n[".$key."]\n";
}
foreach ($elem as $key2=>$elem2) {
if(is_array($elem2))
{
for($i=0;$i<count($elem2);$i++)
{
$content .= $key2."[] = \"".$elem2[$i]."\"\n";
}
}
else if($elem2=="") $content .= $key2." = \n";
else $content .= $key2." = ".$elem2."\n";
}
}
} else {
foreach ($assoc_arr as $key=>$elem) {
if(is_array($elem))
{
for($i=0;$i<count($elem);$i++)
{
$content .= $key."[] = \"".$elem[$i]."\"\n";
}
}
else if($elem=="") $content .= $key." = \n";
else $content .= $key." = ".$elem."\n";
}
}
if (!$handle = fopen($path, 'w')) {
return false;
}
if (!fwrite($handle, $content)) {
return false;
}
fclose($handle);
return true;
}
}

View file

@ -1,3 +1,16 @@
DELETE FROM cc_pref WHERE id IN (
SELECT cc_pref.id
FROM cc_pref
LEFT OUTER JOIN (
SELECT MAX(id) as id, keystr, subjid
FROM cc_pref
GROUP BY keystr, subjid
) as KeepRows ON
cc_pref.id = KeepRows.id
WHERE
KeepRows.id IS NULL
);
DELETE FROM cc_pref WHERE keystr = 'system_version'; DELETE FROM cc_pref WHERE keystr = 'system_version';
INSERT INTO cc_pref (keystr, valstr) VALUES ('system_version', '2.4.0'); INSERT INTO cc_pref (keystr, valstr) VALUES ('system_version', '2.4.0');
@ -16,4 +29,4 @@ UPDATE cc_files
SET is_playlist = true SET is_playlist = true
WHERE id IN (SELECT DISTINCT(file_id) FROM cc_blockcontents); WHERE id IN (SELECT DISTINCT(file_id) FROM cc_blockcontents);
INSERT INTO cc_locale (locale_code, locale_lang) VALUES ('hu_HU', 'Magyar'); INSERT INTO cc_locale (locale_code, locale_lang) VALUES ('hu_HU', 'Magyar');

View file

@ -138,8 +138,8 @@ class ApiRequest(object):
content_type = f.info().getheader('Content-Type') content_type = f.info().getheader('Content-Type')
response = f.read() response = f.read()
except Exception, e: except Exception, e:
self.logger.error('Exception: %s', e) #self.logger.error('Exception: %s', e)
self.logger.error("traceback: %s", traceback.format_exc()) #self.logger.error("traceback: %s", traceback.format_exc())
raise raise
try: try:
@ -149,8 +149,8 @@ class ApiRequest(object):
else: else:
raise InvalidContentType() raise InvalidContentType()
except Exception: except Exception:
self.logger.error(response) #self.logger.error(response)
self.logger.error("traceback: %s", traceback.format_exc()) #self.logger.error("traceback: %s", traceback.format_exc())
raise raise
def req(self, *args, **kwargs): def req(self, *args, **kwargs):

View file

@ -2,7 +2,7 @@
### BEGIN INIT INFO ### BEGIN INIT INFO
# Provides: airtime-media-monitor # Provides: airtime-media-monitor
# Required-Start: $local_fs $remote_fs $network $syslog # Required-Start: $local_fs $remote_fs $network $syslog $all
# Required-Stop: $local_fs $remote_fs $network $syslog # Required-Stop: $local_fs $remote_fs $network $syslog
# Default-Start: 2 3 4 5 # Default-Start: 2 3 4 5
# Default-Stop: 0 1 6 # Default-Stop: 0 1 6

View file

@ -1,5 +1,6 @@
import pyinotify import pyinotify
import time import time
import os
from pydispatch import dispatcher from pydispatch import dispatcher
from os.path import normpath from os.path import normpath
@ -186,13 +187,12 @@ class Manager(Loggable):
try: mmp.create_dir(path) try: mmp.create_dir(path)
except mmp.FailedToCreateDir as e: self.unexpected_exception(e) except mmp.FailedToCreateDir as e: self.unexpected_exception(e)
os.chmod(store_paths['organize'], 0775)
self.set_problem_files_path(store_paths['problem_files']) self.set_problem_files_path(store_paths['problem_files'])
self.set_imported_path(store_paths['imported']) self.set_imported_path(store_paths['imported'])
self.set_recorded_path(store_paths['recorded']) self.set_recorded_path(store_paths['recorded'])
self.set_organize_path(store_paths['organize']) self.set_organize_path(store_paths['organize'])
mmp.create_dir(store)
for p in store_paths.values():
mmp.create_dir(p)
def has_watch(self, path): def has_watch(self, path):
""" returns true if the path is being watched or not. Any kind """ returns true if the path is being watched or not. Any kind

View file

@ -2,7 +2,7 @@
### BEGIN INIT INFO ### BEGIN INIT INFO
# Provides: airtime-liquidsoap # Provides: airtime-liquidsoap
# Required-Start: $local_fs $remote_fs $network $syslog # Required-Start: $local_fs $remote_fs $network $syslog $all
# Required-Stop: $local_fs $remote_fs $network $syslog # Required-Stop: $local_fs $remote_fs $network $syslog
# Default-Start: 2 3 4 5 # Default-Start: 2 3 4 5
# Default-Stop: 0 1 6 # Default-Stop: 0 1 6
@ -18,7 +18,6 @@ PIDFILE=/var/run/airtime-liquidsoap.pid
EXEC='/usr/bin/airtime-liquidsoap' EXEC='/usr/bin/airtime-liquidsoap'
start () { start () {
mkdir -p /var/log/airtime/pypo-liquidsoap mkdir -p /var/log/airtime/pypo-liquidsoap
chown $USERID:$GROUPID /var/log/airtime/pypo-liquidsoap chown $USERID:$GROUPID /var/log/airtime/pypo-liquidsoap
@ -36,9 +35,19 @@ start () {
} }
stop () { stop () {
timeout --version >/dev/null 2>&1
RESULT="$?"
#send term signal after 10 seconds #send term signal after 10 seconds
timeout -s9 10s /usr/lib/airtime/airtime_virtualenv/bin/python \ if [ "$RESULT" = "0" ]; then
/usr/lib/airtime/pypo/bin/liquidsoap_scripts/liquidsoap_prepare_terminate.py timeout -s9 10s /usr/lib/airtime/airtime_virtualenv/bin/python \
/usr/lib/airtime/pypo/bin/liquidsoap_scripts/liquidsoap_prepare_terminate.py
else
#some earlier versions of Ubuntu (Lucid) had a different timeout
#command that takes different input parameters.
timeout 10 /usr/lib/airtime/airtime_virtualenv/bin/python \
/usr/lib/airtime/pypo/bin/liquidsoap_scripts/liquidsoap_prepare_terminate.py
fi
# Send TERM after 5 seconds, wait at most 30 seconds. # Send TERM after 5 seconds, wait at most 30 seconds.
#start-stop-daemon --stop --oknodo --retry=TERM/10/KILL/5 --quiet --pidfile $PIDFILE #start-stop-daemon --stop --oknodo --retry=TERM/10/KILL/5 --quiet --pidfile $PIDFILE
start-stop-daemon --stop --oknodo --retry=TERM/10/KILL/5 --quiet --exec $EXEC start-stop-daemon --stop --oknodo --retry=TERM/10/KILL/5 --quiet --exec $EXEC

View file

@ -2,7 +2,7 @@
### BEGIN INIT INFO ### BEGIN INIT INFO
# Provides: airtime-playout # Provides: airtime-playout
# Required-Start: $local_fs $remote_fs $network $syslog # Required-Start: $local_fs $remote_fs $network $syslog $all
# Required-Stop: $local_fs $remote_fs $network $syslog # Required-Stop: $local_fs $remote_fs $network $syslog
# Default-Start: 2 3 4 5 # Default-Start: 2 3 4 5
# Default-Stop: 0 1 6 # Default-Stop: 0 1 6

View file

@ -88,8 +88,8 @@ try:
if "airtime_service_start" in os.environ and os.environ["airtime_service_start"] == "t": if "airtime_service_start" in os.environ and os.environ["airtime_service_start"] == "t":
print "* Waiting for pypo processes to start..." print "* Waiting for pypo processes to start..."
subprocess.call("invoke-rc.d airtime-playout start > /dev/null 2>&1", shell=True)
subprocess.call("invoke-rc.d airtime-liquidsoap start > /dev/null 2>&1", shell=True) subprocess.call("invoke-rc.d airtime-liquidsoap start > /dev/null 2>&1", shell=True)
subprocess.call("invoke-rc.d airtime-playout start > /dev/null 2>&1", shell=True)
except Exception, e: except Exception, e:
print e print e

View file

@ -0,0 +1,24 @@
if bitrate == 24 then
ignore(output_stereo(%fdkaac(bitrate = 24, aot="mpeg4_he_aac_v2"), !source))
elsif bitrate == 32 then
ignore(output_stereo(%fdkaac(bitrate = 32, aot="mpeg4_he_aac_v2"), !source))
elsif bitrate == 48 then
ignore(output_stereo(%fdkaac(bitrate = 48, aot="mpeg4_he_aac_v2"), !source))
elsif bitrate == 64 then
ignore(output_stereo(%fdkaac(bitrate = 64, aot="mpeg4_he_aac_v2"), !source))
elsif bitrate == 96 then
ignore(output_stereo(%fdkaac(bitrate = 96, aot="mpeg4_he_aac_v2"), !source))
elsif bitrate == 128 then
ignore(output_stereo(%fdkaac(bitrate = 128, aot="mpeg4_he_aac_v2"), !source))
elsif bitrate == 160 then
ignore(output_stereo(%fdkaac(bitrate = 160, aot="mpeg4_he_aac_v2"), !source))
elsif bitrate == 192 then
ignore(output_stereo(%fdkaac(bitrate = 192, aot="mpeg4_he_aac_v2"), !source))
elsif bitrate == 224 then
ignore(output_stereo(%fdkaac(bitrate = 224, aot="mpeg4_he_aac_v2"), !source))
elsif bitrate == 256 then
ignore(output_stereo(%fdkaac(bitrate = 256, aot="mpeg4_he_aac_v2"), !source))
elsif bitrate == 320 then
ignore(output_stereo(%fdkaac(bitrate = 320, aot="mpeg4_he_aac_v2"), !source))
end

View file

@ -1,6 +1,7 @@
import logging import logging
import sys import sys
import time import time
import traceback
from api_clients.api_client import AirtimeApiClient from api_clients.api_client import AirtimeApiClient
def generate_liquidsoap_config(ss): def generate_liquidsoap_config(ss):
@ -26,19 +27,21 @@ def generate_liquidsoap_config(ss):
fh.close() fh.close()
logging.basicConfig(format='%(message)s') logging.basicConfig(format='%(message)s')
ac = AirtimeApiClient(logging.getLogger())
attempts = 0 attempts = 0
max_attempts = 5 max_attempts = 10
successful = False
while True: while not successful:
try: try:
ac = AirtimeApiClient(logging.getLogger())
ss = ac.get_stream_setting() ss = ac.get_stream_setting()
generate_liquidsoap_config(ss) generate_liquidsoap_config(ss)
break successful = True
except Exception, e: except Exception, e:
if attempts == max_attempts: if attempts == max_attempts:
print "Unable to connect to the Airtime server." print "Unable to connect to the Airtime server."
logging.error(str(e)) logging.error(str(e))
logging.error("traceback: %s", traceback.format_exc())
sys.exit(1) sys.exit(1)
else: else:
time.sleep(3) time.sleep(3)

Some files were not shown because too many files have changed in this diff Show more