diff --git a/airtime_mvc/application/common/Database.php b/airtime_mvc/application/common/Database.php index 2c61bc589..bb9557474 100644 --- a/airtime_mvc/application/common/Database.php +++ b/airtime_mvc/application/common/Database.php @@ -2,9 +2,11 @@ class Application_Common_Database { public static function prepareAndExecute($sql, array $paramValueMap, - $type='all', $fetchType=PDO::FETCH_ASSOC) + $type='all', $fetchType=PDO::FETCH_ASSOC, $con=null) { - $con = Propel::getConnection(); + if (is_null($con)) { + $con = Propel::getConnection(); + } $stmt = $con->prepare($sql); foreach ($paramValueMap as $param => $v) { $stmt->bindValue($param, $v); diff --git a/airtime_mvc/application/controllers/ScheduleController.php b/airtime_mvc/application/controllers/ScheduleController.php index 36b6bbe66..93750dccd 100644 --- a/airtime_mvc/application/controllers/ScheduleController.php +++ b/airtime_mvc/application/controllers/ScheduleController.php @@ -367,13 +367,6 @@ class ScheduleController extends Zend_Controller_Action $service_showForm = new Application_Service_ShowFormService($showId, $instanceId); $isAdminOrPM = $currentUser->isAdminOrPM(); - /*$isHostOfShow = $currentUser->isHostOfShow($showId); - // in case a user was once a dj and had been assigned to a show - // but was then changed to an admin user we need to allow - // the user to edit the show as an admin (CC-4925) - if ($isHostOfShow && !$isAdminOrPM) { - $this->view->action = "dj-edit-show"; - }*/ $forms = $this->createShowFormAction(); @@ -397,30 +390,11 @@ class ScheduleController extends Zend_Controller_Action if ($currentUser->isAdminOrPM()) { $this->createShowFormAction(true); + $this->view->addNewShow = true; $this->view->form = $this->view->render('schedule/add-show-form.phtml'); } } - /*public function djEditShowAction() - { - $js = $this->_getParam('data'); - $data = array(); - - //need to convert from serialized jQuery array. - foreach ($js as $j) { - $data[$j["name"]] = $j["value"]; - } - - //update cc_show - $show = new Application_Model_Show($data["add_show_id"]); - $show->setAirtimeAuthFlag($data["cb_airtime_auth"]); - $show->setCustomAuthFlag($data["cb_custom_auth"]); - $show->setCustomUsername($data["custom_username"]); - $show->setCustomPassword($data["custom_password"]); - - $this->view->edit = true; - }*/ - public function editRepeatingShowInstanceAction(){ $js = $this->_getParam('data'); $data = array(); diff --git a/airtime_mvc/application/models/Block.php b/airtime_mvc/application/models/Block.php index 931445d2d..6098f2b85 100644 --- a/airtime_mvc/application/models/Block.php +++ b/airtime_mvc/application/models/Block.php @@ -33,6 +33,7 @@ class Application_Model_Block implements Application_Model_LibraryEditable "cueout" => "00:00:00", "fadein" => "0.0", "fadeout" => "0.0", + "crossfadeDuration" => 0 ); //using propel's phpNames. @@ -101,6 +102,7 @@ class Application_Model_Block implements Application_Model_LibraryEditable $this->blockItem["fadein"] = Application_Model_Preference::GetDefaultFadeIn(); $this->blockItem["fadeout"] = Application_Model_Preference::GetDefaultFadeOut(); + $this->blockItem["crossfadeDuration"] = Application_Model_Preference::GetDefaultCrossfadeDuration(); $this->con = isset($con) ? $con : Propel::getConnection(CcBlockPeer::DATABASE_NAME); $this->id = $this->block->getDbId(); @@ -390,6 +392,7 @@ SQL; $row->setDbCueout($info["cueout"]); $row->setDbFadein(Application_Common_DateHelper::secondsToPlaylistTime($info["fadein"])); $row->setDbFadeout(Application_Common_DateHelper::secondsToPlaylistTime($info["fadeout"])); + $row->setDbTrackOffset($info["crossfadeDuration"]); $row->save($this->con); // above save result update on cc_block table on length column. // but $this->block doesn't get updated automatically @@ -485,7 +488,7 @@ SQL; } foreach ($p_items as $ac) { - Logging::info("Adding audio file {$ac[0]}"); + //Logging::info("Adding audio file {$ac[0]}"); try { if (is_array($ac) && $ac[1] == 'audioclip') { $res = $this->insertBlockElement($this->buildEntry($ac[0], $pos)); @@ -655,7 +658,7 @@ SQL; public function getFadeInfo($pos) { - Logging::info("Getting fade info for pos {$pos}"); + //Logging::info("Getting fade info for pos {$pos}"); $row = CcBlockcontentsQuery::create() ->joinWith(CcFilesPeer::OM_CLASS) @@ -1272,8 +1275,10 @@ SQL; $isBlockFull = false; while ($iterator->valid()) { + $id = $iterator->current()->getDbId(); - $length = Application_Common_DateHelper::calculateLengthInSeconds($iterator->current()->getDbLength()); + $fileLength = $iterator->current()->getCueLength(); + $length = Application_Common_DateHelper::calculateLengthInSeconds($fileLength); $insertList[] = array('id'=>$id, 'length'=>$length); $totalTime += $length; $totalItems++; @@ -1288,8 +1293,11 @@ SQL; $sizeOfInsert = count($insertList); - // if block is not full and reapeat_track is check, fill up more + // if block is not full and repeat_track is check, fill up more while (!$isBlockFull && $repeat == 1 && $sizeOfInsert > 0) { + Logging::debug("adding repeated tracks."); + Logging::debug("total time = " . $totalTime); + $randomEleKey = array_rand(array_slice($insertList, 0, $sizeOfInsert)); $insertList[] = $insertList[$randomEleKey]; $totalTime += $insertList[$randomEleKey]['length']; diff --git a/airtime_mvc/application/models/Preference.php b/airtime_mvc/application/models/Preference.php index f2eeee8a4..6cba9814c 100644 --- a/airtime_mvc/application/models/Preference.php +++ b/airtime_mvc/application/models/Preference.php @@ -11,6 +11,9 @@ class Application_Model_Preference private static function setValue($key, $value, $isUserValue = false, $userId = null) { try { + $con = Propel::getConnection(CcPrefPeer::DATABASE_NAME); + $con->beginTransaction(); + //called from a daemon process if (!class_exists("Zend_Auth", false) || !Zend_Auth::getInstance()->hasIdentity()) { $id = NULL; @@ -35,10 +38,18 @@ class Application_Model_Preference $paramMap[':id'] = $userId; } - $result = Application_Common_Database::prepareAndExecute($sql, $paramMap, 'column'); + $result = Application_Common_Database::prepareAndExecute($sql, + $paramMap, + 'column', + PDO::FETCH_ASSOC, + $con); $paramMap = array(); - if ($result == 1) { + if ($result > 1) { + //this case should not happen. + throw new Exception("Invalid number of results returned. Should be ". + "0 or 1, but is '$result' instead"); + } elseif ($result == 1) { // result found if (is_null($id) || !$isUserValue) { // system pref @@ -76,11 +87,17 @@ class Application_Model_Preference $paramMap[':key'] = $key; $paramMap[':value'] = $value; - Application_Common_Database::prepareAndExecute($sql, $paramMap, 'execute'); + Application_Common_Database::prepareAndExecute($sql, + $paramMap, + 'execute', + PDO::FETCH_ASSOC, + $con); + $con->commit(); } catch (Exception $e) { + $con->rollback(); header('HTTP/1.0 503 Service Unavailable'); - Logging::info("Could not connect to database: ".$e->getMessage()); + Logging::info("Database error: ".$e->getMessage()); exit; } diff --git a/airtime_mvc/application/models/Scheduler.php b/airtime_mvc/application/models/Scheduler.php index 7f6272cee..e3f263360 100644 --- a/airtime_mvc/application/models/Scheduler.php +++ b/airtime_mvc/application/models/Scheduler.php @@ -557,6 +557,7 @@ class Application_Model_Scheduler */ $instances = $this->getInstances($schedule["instance"]); foreach($instances as $instance) { + $linked = $instance->getCcShow()->isLinked(); if ($id !== 0) { $schedItem = CcScheduleQuery::create()->findPK($id, $this->con); /* We use the selected cursor's position to find the same @@ -609,12 +610,31 @@ class Application_Model_Scheduler $filesToInsert = array_merge($filesToInsert, $this->retrieveMediaFiles($media["id"], $media["type"])); } } + foreach ($filesToInsert as $file) { //item existed previously and is being moved. //need to keep same id for resources if we want REST. if (isset($file['sched_id'])) { $sched = CcScheduleQuery::create()->findPk($file["sched_id"]); + /* 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 + * items in linked instances + */ + if (!isset($originalPosition)) { + $originalPosition = $sched->getDbPosition(); + } + + /* 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 + * relative item is by its position + */ + if ($linked && $moveAction) { + $sched = CcScheduleQuery::create() + ->filterByDbInstanceId($instance->getDbId()) + ->filterByDbPosition($originalPosition) + ->findOne(); + } $excludeIds[] = intval($sched->getDbId()); $file["cliplength"] = $sched->getDbClipLength(); @@ -694,7 +714,6 @@ class Application_Model_Scheduler //recalculate the start/end times after the inserted items. foreach ($followingSchedItems as $item) { $endTimeDT = $this->findEndTime($nextStartDT, $item->getDbClipLength()); - $item->setDbStarts($nextStartDT); $item->setDbEnds($endTimeDT); $item->setDbPosition($pos); diff --git a/airtime_mvc/application/models/airtime/CcFiles.php b/airtime_mvc/application/models/airtime/CcFiles.php index 001c2c7a1..7ceb5e5e8 100644 --- a/airtime_mvc/application/models/airtime/CcFiles.php +++ b/airtime_mvc/application/models/airtime/CcFiles.php @@ -12,6 +12,20 @@ * @package propel.generator.campcaster */ class CcFiles extends BaseCcFiles { + + public function getCueLength() + { + $cuein = $this->getDbCuein(); + $cueout = $this->getDbCueout(); + + $cueinSec = Application_Common_DateHelper::calculateLengthInSeconds($cuein); + $cueoutSec = Application_Common_DateHelper::calculateLengthInSeconds($cueout); + $lengthSec = bcsub($cueoutSec, $cueinSec, 6); + + $length = Application_Common_DateHelper::secondsToPlaylistTime($lengthSec); + + return $length; + } public function getDbLength($format = "H:i:s.u") { diff --git a/airtime_mvc/application/services/CalendarService.php b/airtime_mvc/application/services/CalendarService.php index 1c963fc45..0db7d4e2d 100644 --- a/airtime_mvc/application/services/CalendarService.php +++ b/airtime_mvc/application/services/CalendarService.php @@ -67,6 +67,11 @@ class Application_Service_CalendarService "name"=> $text, "icon" => "soundcloud"); } + } else { + $menu["content"] = array( + "name"=> _("Show Content"), + "icon" => "overview", + "url" => $baseUrl."schedule/show-content-dialog"); } } else { //Show content can be modified from the calendar if: diff --git a/airtime_mvc/application/services/SchedulerService.php b/airtime_mvc/application/services/SchedulerService.php index 2cf5711fc..7fe3ca6f8 100644 --- a/airtime_mvc/application/services/SchedulerService.php +++ b/airtime_mvc/application/services/SchedulerService.php @@ -68,8 +68,12 @@ class Application_Service_SchedulerService $ccSchedules = CcScheduleQuery::create() ->filterByDbInstanceId($instanceIds, Criteria::IN) ->find(); + + $interval = new DateInterval("PT".abs($diff)."S"); + if ($diff < 0) { + $interval->invert = 1; + } foreach ($ccSchedules as $ccSchedule) { - $interval = new DateInterval("PT".$diff."S"); $start = new DateTime($ccSchedule->getDbStarts()); $newStart = $start->add($interval); $end = new DateTime($ccSchedule->getDbEnds()); diff --git a/airtime_mvc/application/services/ShowFormService.php b/airtime_mvc/application/services/ShowFormService.php index e9cb8c5ea..a82279a56 100644 --- a/airtime_mvc/application/services/ShowFormService.php +++ b/airtime_mvc/application/services/ShowFormService.php @@ -216,7 +216,7 @@ class Application_Service_ShowFormService 'add_show_no_end' => (!$service_show->getRepeatingEndDate()), 'add_show_monthly_repeat_type' => $monthlyRepeatType)); - if (!$this->ccShow->isLinkable()) { + if (!$this->ccShow->isLinkable() || $this->ccShow->isRecorded()) { $form->getElement('add_show_linked')->setOptions(array('disabled' => true)); } } diff --git a/airtime_mvc/application/services/ShowService.php b/airtime_mvc/application/services/ShowService.php index 32aeb5da9..dab59e4d9 100644 --- a/airtime_mvc/application/services/ShowService.php +++ b/airtime_mvc/application/services/ShowService.php @@ -976,7 +976,7 @@ SQL; $this->createRebroadcastInstances($showDay, $date, $ccShowInstance->getDbId()); } } - $start = $this->getNextMonthlyMonthlyRepeatDate($start, $timezone); + $start = $this->getNextMonthlyMonthlyRepeatDate($start, $timezone, $showDay->getDbStartTime()); } $this->setNextRepeatingShowDate($start->format("Y-m-d"), $day, $show_id); } @@ -1034,7 +1034,7 @@ SQL; * Enter description here ... * @param $start */ - private function getNextMonthlyMonthlyRepeatDate($start, $timezone) + private function getNextMonthlyMonthlyRepeatDate($start, $timezone, $startTime) { $dt = new DateTime($start->format("Y-m"), new DateTimeZone($timezone)); do { @@ -1042,6 +1042,12 @@ SQL; } while (!checkdate($dt->format("m"), $start->format("d"), $dt->format("Y"))); $dt->setDate($dt->format("Y"), $dt->format("m"), $start->format("d")); + + $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; } diff --git a/airtime_mvc/public/js/airtime/schedule/add-show.js b/airtime_mvc/public/js/airtime/schedule/add-show.js index 7f0d0e29f..2e8fd7454 100644 --- a/airtime_mvc/public/js/airtime/schedule/add-show.js +++ b/airtime_mvc/public/js/airtime/schedule/add-show.js @@ -191,6 +191,12 @@ function setAddShowEvents() { $(this).blur(); form.find("#add_show_rebroadcast").toggle(); + if (form.find("#add_show_record").attr("checked")) { + form.find("#add_show_linked").attr("checked", false).attr("disabled", true); + } else { + form.find("#add_show_linked").attr("disabled", false); + } + //uncheck rebroadcast checkbox form.find("#add_show_rebroadcast").attr('checked', false); diff --git a/airtime_mvc/public/js/waveformplaylist/playout.js b/airtime_mvc/public/js/waveformplaylist/playout.js index 8a30098b2..a2a156b37 100644 --- a/airtime_mvc/public/js/waveformplaylist/playout.js +++ b/airtime_mvc/public/js/waveformplaylist/playout.js @@ -82,7 +82,9 @@ AudioPlayout.prototype.loadData = function (audioData, cb) { that.buffer = buffer; cb(buffer); }, - Error + function(err) { + console.log("err(decodeAudioData): "+err); + } ); }; diff --git a/install_minimal/airtime-install b/install_minimal/airtime-install index 88054685f..c646d2e83 100755 --- a/install_minimal/airtime-install +++ b/install_minimal/airtime-install @@ -21,6 +21,24 @@ showhelp () { exit 0 } +rabbitmq_install () { + RABBITMQ_VHOST="/airtime" + RABBITMQ_USER="airtime" + RABBITMQ_PASSWORD=$(awk -F ' = ' '{if (! ($0 ~ /^;/) && $0 ~ /^password/ ) print $2}' /etc/airtime/airtime.conf) + EXCHANGES="airtime-pypo|pypo-fetch|airtime-media-monitor|media-monitor" + + rabbitmqctl delete_vhost $RABBITMQ_VHOST + rabbitmqctl delete_user $RABBITMQ_USER + + rabbitmqctl add_vhost $RABBITMQ_VHOST + rabbitmqctl add_user $RABBITMQ_USER $RABBITMQ_PASSWORD + rabbitmqctl set_permissions -p $RABBITMQ_VHOST $RABBITMQ_USER "$EXCHANGES" "$EXCHANGES" "$EXCHANGES" + + export RABBITMQ_USER + export RABBITMQ_PASSWORD + export RABBITMQ_VHOST +} + overwrite="f" preserve="f" nodb="f" @@ -198,6 +216,8 @@ if [ "$DO_UPGRADE" -eq "0" ]; then echo "There was an error during install. Exit code $result" exit 1 fi + + rabbitmq_install fi set -e diff --git a/install_minimal/airtime-uninstall b/install_minimal/airtime-uninstall index 78e9b03e4..bc12a4403 100755 --- a/install_minimal/airtime-uninstall +++ b/install_minimal/airtime-uninstall @@ -28,6 +28,14 @@ done #Make 'purge' env variable available to sub bash script export purge +rabbitmq_uninstall () { + RABBITMQ_VHOST="/airtime" + RABBITMQ_USER="airtime" + + rabbitmqctl delete_vhost $RABBITMQ_VHOST + rabbitmqctl delete_user $RABBITMQ_USER +} + echo -e "\n******************************* Uninstall Begin ********************************" # Absolute path to this script, e.g. /home/user/bin/foo.sh @@ -35,6 +43,8 @@ SCRIPT=`readlink -f $0` # Absolute path this script is in, thus /home/user/bin SCRIPTPATH=`dirname $SCRIPT` +rabbitmq_uninstall + virtualenv_bin="/usr/lib/airtime/airtime_virtualenv/bin/" . ${virtualenv_bin}activate diff --git a/install_minimal/include/AirtimeIni.php b/install_minimal/include/AirtimeIni.php index 8d631f8e4..fc82ea8cb 100644 --- a/install_minimal/include/AirtimeIni.php +++ b/install_minimal/include/AirtimeIni.php @@ -37,11 +37,11 @@ class AirtimeIni public static function IniFilesExist() { - $configFiles = array(AirtimeIni::CONF_FILE_AIRTIME, - AirtimeIni::CONF_FILE_PYPO, - AirtimeIni::CONF_FILE_RECORDER, - AirtimeIni::CONF_FILE_LIQUIDSOAP, - AirtimeIni::CONF_FILE_MEDIAMONITOR); + $configFiles = array(self::CONF_FILE_AIRTIME, + self::CONF_FILE_PYPO, + self::CONF_FILE_RECORDER, + self::CONF_FILE_LIQUIDSOAP, + self::CONF_FILE_MEDIAMONITOR); $exist = false; foreach ($configFiles as $conf) { if (file_exists($conf)) { @@ -65,46 +65,46 @@ class AirtimeIni } } - if (!copy(AirtimeInstall::GetAirtimeSrcDir()."/build/airtime.conf", AirtimeIni::CONF_FILE_AIRTIME)){ + if (!copy(AirtimeInstall::GetAirtimeSrcDir()."/build/airtime.conf", self::CONF_FILE_AIRTIME)){ echo "Could not copy airtime.conf to /etc/airtime/. Exiting."; exit(1); - } else if (!self::ChangeFileOwnerGroupMod(AirtimeIni::CONF_FILE_AIRTIME, self::CONF_WWW_DATA_GRP)){ + } else if (!self::ChangeFileOwnerGroupMod(self::CONF_FILE_AIRTIME, self::CONF_WWW_DATA_GRP)){ echo "Could not set ownership of api_client.cfg to 'pypo'. Exiting."; exit(1); } if (getenv("python_service") == "0"){ - if (!copy(__DIR__."/../../python_apps/api_clients/api_client.cfg", AirtimeIni::CONF_FILE_API_CLIENT)){ + if (!copy(__DIR__."/../../python_apps/api_clients/api_client.cfg", self::CONF_FILE_API_CLIENT)){ echo "Could not copy api_client.cfg to /etc/airtime/. Exiting."; exit(1); - } else if (!self::ChangeFileOwnerGroupMod(AirtimeIni::CONF_FILE_API_CLIENT, self::CONF_PYPO_GRP)){ + } else if (!self::ChangeFileOwnerGroupMod(self::CONF_FILE_API_CLIENT, self::CONF_PYPO_GRP)){ echo "Could not set ownership of api_client.cfg to 'pypo'. Exiting."; exit(1); } - if (!copy(__DIR__."/../../python_apps/pypo/pypo.cfg", AirtimeIni::CONF_FILE_PYPO)){ + if (!copy(__DIR__."/../../python_apps/pypo/pypo.cfg", self::CONF_FILE_PYPO)){ echo "Could not copy pypo.cfg to /etc/airtime/. Exiting."; exit(1); - } else if (!self::ChangeFileOwnerGroupMod(AirtimeIni::CONF_FILE_PYPO, self::CONF_PYPO_GRP)){ + } else if (!self::ChangeFileOwnerGroupMod(self::CONF_FILE_PYPO, self::CONF_PYPO_GRP)){ echo "Could not set ownership of pypo.cfg to 'pypo'. Exiting."; exit(1); } /* - if (!copy(__DIR__."/../../python_apps/pypo/liquidsoap_scripts/liquidsoap.cfg", AirtimeIni::CONF_FILE_LIQUIDSOAP)){ + if (!copy(__DIR__."/../../python_apps/pypo/liquidsoap_scripts/liquidsoap.cfg", self::CONF_FILE_LIQUIDSOAP)){ echo "Could not copy liquidsoap.cfg to /etc/airtime/. Exiting."; exit(1); - } else if (!self::ChangeFileOwnerGroupMod(AirtimeIni::CONF_FILE_LIQUIDSOAP, self::CONF_PYPO_GRP)){ + } else if (!self::ChangeFileOwnerGroupMod(self::CONF_FILE_LIQUIDSOAP, self::CONF_PYPO_GRP)){ echo "Could not set ownership of liquidsoap.cfg to 'pypo'. Exiting."; exit(1); } * */ - if (!copy(__DIR__."/../../python_apps/media-monitor/media-monitor.cfg", AirtimeIni::CONF_FILE_MEDIAMONITOR)){ + if (!copy(__DIR__."/../../python_apps/media-monitor/media-monitor.cfg", self::CONF_FILE_MEDIAMONITOR)){ echo "Could not copy media-monitor.cfg to /etc/airtime/. Exiting."; exit(1); - } else if (!self::ChangeFileOwnerGroupMod(AirtimeIni::CONF_FILE_MEDIAMONITOR, self::CONF_PYPO_GRP)){ + } else if (!self::ChangeFileOwnerGroupMod(self::CONF_FILE_MEDIAMONITOR, self::CONF_PYPO_GRP)){ echo "Could not set ownership of media-monitor.cfg to 'pypo'. Exiting."; exit(1); } @@ -127,25 +127,25 @@ class AirtimeIni */ public static function RemoveIniFiles() { - if (file_exists(AirtimeIni::CONF_FILE_AIRTIME)){ - unlink(AirtimeIni::CONF_FILE_AIRTIME); + if (file_exists(self::CONF_FILE_AIRTIME)){ + unlink(self::CONF_FILE_AIRTIME); } - if (file_exists(AirtimeIni::CONF_FILE_PYPO)){ - unlink(AirtimeIni::CONF_FILE_PYPO); + if (file_exists(self::CONF_FILE_PYPO)){ + unlink(self::CONF_FILE_PYPO); } - if (file_exists(AirtimeIni::CONF_FILE_RECORDER)){ - unlink(AirtimeIni::CONF_FILE_RECORDER); + if (file_exists(self::CONF_FILE_RECORDER)){ + unlink(self::CONF_FILE_RECORDER); } - if (file_exists(AirtimeIni::CONF_FILE_LIQUIDSOAP)){ - unlink(AirtimeIni::CONF_FILE_LIQUIDSOAP); + if (file_exists(self::CONF_FILE_LIQUIDSOAP)){ + unlink(self::CONF_FILE_LIQUIDSOAP); } //wait until Airtime 1.9.0 - if (file_exists(AirtimeIni::CONF_FILE_MEDIAMONITOR)){ - unlink(AirtimeIni::CONF_FILE_MEDIAMONITOR); + if (file_exists(self::CONF_FILE_MEDIAMONITOR)){ + unlink(self::CONF_FILE_MEDIAMONITOR); } if (file_exists("etc/airtime")){ @@ -214,6 +214,57 @@ class AirtimeIni fclose($fp); } + //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$elem) { + if(is_array($elem)) + { + for($i=0;$i&1 diff --git a/python_apps/pypo/install/pypo-copy-files.py b/python_apps/pypo/install/pypo-copy-files.py index e88b46a64..f3e1a428d 100644 --- a/python_apps/pypo/install/pypo-copy-files.py +++ b/python_apps/pypo/install/pypo-copy-files.py @@ -81,6 +81,10 @@ try: # load config file try: config = ConfigObj(PATH_INI_FILE) + config['rabbitmq_user'] = os.environ['RABBITMQ_USER'] + config['rabbitmq_password'] = os.environ['RABBITMQ_PASSWORD'] + config['rabbitmq_vhost'] = os.environ['RABBITMQ_VHOST'] + config.write() except Exception, e: print 'Error loading config file: ', e sys.exit(1) diff --git a/python_apps/pypo/liquidsoap_scripts/generate_liquidsoap_cfg.py b/python_apps/pypo/liquidsoap_scripts/generate_liquidsoap_cfg.py index b123763e2..6144058e0 100644 --- a/python_apps/pypo/liquidsoap_scripts/generate_liquidsoap_cfg.py +++ b/python_apps/pypo/liquidsoap_scripts/generate_liquidsoap_cfg.py @@ -1,5 +1,6 @@ import logging import sys +import time from api_clients.api_client import AirtimeApiClient def generate_liquidsoap_config(ss): @@ -26,10 +27,19 @@ def generate_liquidsoap_config(ss): logging.basicConfig(format='%(message)s') ac = AirtimeApiClient(logging.getLogger()) -try: - ss = ac.get_stream_setting() - generate_liquidsoap_config(ss) -except Exception, e: - logging.error(str(e)) - print "Unable to connect to the Airtime server." - sys.exit(1) +attempts = 0 +max_attempts = 5 + +while True: + try: + ss = ac.get_stream_setting() + generate_liquidsoap_config(ss) + break + except Exception, e: + if attempts == max_attempts: + print "Unable to connect to the Airtime server." + logging.error(str(e)) + sys.exit(1) + else: + time.sleep(3) + attempts += 1 diff --git a/python_apps/pypo/pypofetch.py b/python_apps/pypo/pypofetch.py index 20212be51..38a72f363 100644 --- a/python_apps/pypo/pypofetch.py +++ b/python_apps/pypo/pypofetch.py @@ -432,6 +432,7 @@ class PypoFetch(Thread): for key in media: media_item = media[key] if (media_item['type'] == 'file'): + self.sanity_check_media_item(media_item) fileExt = os.path.splitext(media_item['uri'])[1] dst = os.path.join(download_dir, unicode(media_item['id']) + fileExt) media_item['dst'] = dst @@ -455,6 +456,20 @@ class PypoFetch(Thread): try: self.cache_cleanup(media) except Exception, e: self.logger.error("%s", e) + #do basic validation of file parameters. Useful for debugging + #purposes + def sanity_check_media_item(self, media_item): + start = datetime.strptime(media_item['start'], "%Y-%m-%d-%H-%M-%S") + end = datetime.strptime(media_item['end'], "%Y-%m-%d-%H-%M-%S") + + length1 = (end - start).total_seconds() + length2 = media_item['cue_out'] - media_item['cue_in'] + + if abs(length2 - length1) > 1: + self.logger.error("end - start length: %s", length1) + self.logger.error("cue_out - cue_in length: %s", length2) + self.logger.error("Two lengths are not equal!!!") + def is_file_opened(self, path): #Capture stderr to avoid polluting py-interpreter.log proc = Popen(["lsof", path], stdout=PIPE, stderr=PIPE)