From 92f6ec029fef3c4b78aca2585c06c8da65804e3e Mon Sep 17 00:00:00 2001 From: denise Date: Tue, 7 May 2013 14:49:24 -0400 Subject: [PATCH 01/16] CC-5079: Timeline -> Moving items in linked shows doesn't work --- airtime_mvc/application/models/Scheduler.php | 21 +++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) 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); From 3ae3c7e802cec08ae3a204a85775e063a9971647 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Tue, 7 May 2013 15:05:14 -0400 Subject: [PATCH 02/16] sanity check to warn if cue_out - cue_in != end - start --- python_apps/pypo/pypofetch.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) 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) From ad82b4ff98b096f8a66e3f4f91d1a628dd3ebb65 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Tue, 7 May 2013 15:36:21 -0400 Subject: [PATCH 03/16] throw exception if we get unexpected numbers of results in cc_pref --- airtime_mvc/application/models/Preference.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/airtime_mvc/application/models/Preference.php b/airtime_mvc/application/models/Preference.php index f2eeee8a4..e96d4e888 100644 --- a/airtime_mvc/application/models/Preference.php +++ b/airtime_mvc/application/models/Preference.php @@ -38,7 +38,11 @@ class Application_Model_Preference $result = Application_Common_Database::prepareAndExecute($sql, $paramMap, 'column'); $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 @@ -80,7 +84,7 @@ class Application_Model_Preference } catch (Exception $e) { header('HTTP/1.0 503 Service Unavailable'); - Logging::info("Could not connect to database: ".$e->getMessage()); + Logging::info("Database error: ".$e->getMessage()); exit; } From 22b74126f936624ad2170693034ca4c415bf9e63 Mon Sep 17 00:00:00 2001 From: denise Date: Tue, 7 May 2013 16:16:32 -0400 Subject: [PATCH 04/16] CC-5087: Repeating show -> Same day by Month: Time slot of repeating instances aren't correct --- airtime_mvc/application/services/ShowService.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) 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; } From 9f6a1033ea54ea03faf90b930fa07107f6ef7a89 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Tue, 7 May 2013 16:21:34 -0400 Subject: [PATCH 05/16] CC-5109: Fix race-condition when updating cc_pref table --- airtime_mvc/application/common/Database.php | 6 ++++-- airtime_mvc/application/models/Preference.php | 17 +++++++++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) 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/models/Preference.php b/airtime_mvc/application/models/Preference.php index e96d4e888..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,7 +38,11 @@ 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) { @@ -80,9 +87,15 @@ 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("Database error: ".$e->getMessage()); exit; From 84a05d83f79ce7898d5a9c8762c2d46c20a0e4d1 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Tue, 7 May 2013 17:17:48 -0400 Subject: [PATCH 06/16] CC-5071: Better RabbitMQ passwords new improved airtime ini file updater. Way less hacky --- install_minimal/include/AirtimeIni.php | 64 ++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/install_minimal/include/AirtimeIni.php b/install_minimal/include/AirtimeIni.php index 8d631f8e4..c774c20a2 100644 --- a/install_minimal/include/AirtimeIni.php +++ b/install_minimal/include/AirtimeIni.php @@ -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) numeric 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 Date: Wed, 8 May 2013 11:43:53 -0400 Subject: [PATCH 07/16] CC-2301 : adding in crossfade durations to smart blocks. --- airtime_mvc/application/models/Block.php | 3 +++ airtime_mvc/public/js/waveformplaylist/playout.js | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/airtime_mvc/application/models/Block.php b/airtime_mvc/application/models/Block.php index 931445d2d..1a068fd08 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 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); + } ); }; From d8ba15fac4dd72abb8d266f54032c2807359bec5 Mon Sep 17 00:00:00 2001 From: denise Date: Wed, 8 May 2013 12:05:45 -0400 Subject: [PATCH 08/16] CC-5091: Linked Show: Cannot change the start time ahead --- airtime_mvc/application/services/SchedulerService.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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()); From fae0b2f873511d755e3492f350121953aa9df02e Mon Sep 17 00:00:00 2001 From: denise Date: Wed, 8 May 2013 13:11:30 -0400 Subject: [PATCH 09/16] CC-5111: Please make upgrade detect the tracks already scheduled and added in playlist --- install_minimal/upgrades/airtime-2.4.0/data/upgrade.sql | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/install_minimal/upgrades/airtime-2.4.0/data/upgrade.sql b/install_minimal/upgrades/airtime-2.4.0/data/upgrade.sql index 4b091c618..9474f5d37 100644 --- a/install_minimal/upgrades/airtime-2.4.0/data/upgrade.sql +++ b/install_minimal/upgrades/airtime-2.4.0/data/upgrade.sql @@ -3,3 +3,11 @@ INSERT INTO cc_pref (keystr, valstr) VALUES ('system_version', '2.4.0'); DELETE FROM cc_pref WHERE keystr = 'stream_type'; INSERT INTO cc_pref (keystr, valstr) VALUES ('stream_type', 'ogg, mp3, opus, aac'); + +UPDATE cc_files +SET is_scheduled = true +WHERE id IN (SELECT DISTINCT(file_id) FROM cc_schedule WHERE playout_status != -1); + +UPDATE cc_files +SET is_playlist = true +WHERE id IN (SELECT DISTINCT(file_id) FROM cc_playlistcontents); From 9dbec4636ac070d50416043bde12a85a4b8f7c40 Mon Sep 17 00:00:00 2001 From: denise Date: Wed, 8 May 2013 13:43:27 -0400 Subject: [PATCH 10/16] CC-5106: Calendar: Context menu "Show contents" is missing for past shows --- airtime_mvc/application/services/CalendarService.php | 5 +++++ 1 file changed, 5 insertions(+) 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: From f0e846db75fef4fe84beb8511a30635ff5522455 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Wed, 8 May 2013 13:47:24 -0400 Subject: [PATCH 11/16] CC-5049: Error messages on Liquidsoap start up/shut down after Airtime install fixed --- python_apps/pypo/airtime-liquidsoap | 6 ++++- .../generate_liquidsoap_cfg.py | 24 +++++++++++++------ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/python_apps/pypo/airtime-liquidsoap b/python_apps/pypo/airtime-liquidsoap index 259ff4646..0812bd47d 100755 --- a/python_apps/pypo/airtime-liquidsoap +++ b/python_apps/pypo/airtime-liquidsoap @@ -10,7 +10,11 @@ ls_param="/usr/lib/airtime/pypo/bin/liquidsoap_scripts/ls_script.liq" export PYTHONPATH=${api_client_path} -cd /usr/lib/airtime/pypo/bin/liquidsoap_scripts +SCRIPT=`readlink -f $0` +# Absolute directory this script is in +SCRIPTPATH=`dirname $SCRIPT` + +cd $SCRIPTPATH/liquidsoap_scripts python generate_liquidsoap_cfg.py exec ${ls_path} ${ls_param} 2>&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 From a18fc87d9751906ce245c7e58a6f028684c8a204 Mon Sep 17 00:00:00 2001 From: Naomi Date: Wed, 8 May 2013 14:19:22 -0400 Subject: [PATCH 12/16] CC-5065 : Playlist length is not built on actual cue in/out value --- airtime_mvc/application/models/Block.php | 13 +++++++++---- airtime_mvc/application/models/airtime/CcFiles.php | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/airtime_mvc/application/models/Block.php b/airtime_mvc/application/models/Block.php index 1a068fd08..6098f2b85 100644 --- a/airtime_mvc/application/models/Block.php +++ b/airtime_mvc/application/models/Block.php @@ -488,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)); @@ -658,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) @@ -1275,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++; @@ -1291,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/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") { From fe88e6249af8d2cacb0fbf3fdbb11cf9cba26b22 Mon Sep 17 00:00:00 2001 From: denise Date: Wed, 8 May 2013 15:08:56 -0400 Subject: [PATCH 13/16] CC-5093: Please disable link option for recording show --- airtime_mvc/application/services/ShowFormService.php | 2 +- airtime_mvc/public/js/airtime/schedule/add-show.js | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) 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/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); From 56b9d0580f92d2ca5ee967bbab5d97f0a1b052f5 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Wed, 8 May 2013 15:25:30 -0400 Subject: [PATCH 14/16] CC-5071: Better RabbitMQ passwords -fixed --- install_minimal/airtime-install | 22 +++++ install_minimal/include/AirtimeIni.php | 81 ++++++++++--------- .../install/media-monitor-copy-files.py | 4 + python_apps/pypo/install/pypo-copy-files.py | 4 + 4 files changed, 75 insertions(+), 36 deletions(-) diff --git a/install_minimal/airtime-install b/install_minimal/airtime-install index 88054685f..50cfab243 100755 --- a/install_minimal/airtime-install +++ b/install_minimal/airtime-install @@ -21,6 +21,26 @@ showhelp () { exit 0 } +rabbitmq_install () { + echo "RABBIT!!!" + 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 +218,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/include/AirtimeIni.php b/install_minimal/include/AirtimeIni.php index c774c20a2..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")){ @@ -216,7 +216,7 @@ class AirtimeIni //stupid hack found on http://stackoverflow.com/a/1268642/276949 //with some modifications: 1) Spaces are inserted in between sections and - //2) numeric values are not quoted. + //2) values are not quoted. public static function write_ini_file($assoc_arr, $path, $has_sections = false) { $content = ""; @@ -272,19 +272,28 @@ class AirtimeIni */ public static function UpdateIniFiles() { - $api_key = AirtimeIni::GenerateRandomString(); + $api_key = self::GenerateRandomString(); if (getenv("web") == "t"){ - $ini = parse_ini_file(AirtimeIni::CONF_FILE_AIRTIME, true); + //self::UpdateIniValue(self::CONF_FILE_AIRTIME, 'api_key', $api_key); + //self::UpdateIniValue(self::CONF_FILE_AIRTIME, 'airtime_dir', AirtimeInstall::CONF_DIR_WWW); + //self::UpdateIniValue(self::CONF_FILE_AIRTIME, 'password', self::GenerateRandomString()); + $ini = parse_ini_file(self::CONF_FILE_AIRTIME, true); $ini['general']['api_key'] = $api_key; $ini['general']['airtime_dir'] = AirtimeInstall::CONF_DIR_WWW; - AirtimeIni::write_ini_file($ini, AirtimeIni::CONF_FILE_AIRTIME, true); - } - $ini = parse_ini_file(AirtimeIni::CONF_FILE_API_CLIENT); + $ini['rabbitmq']['vhost'] = 'airtime'; + $ini['rabbitmq']['user'] = 'airtime'; + $ini['rabbitmq']['password'] = self::GenerateRandomString(); + + self::write_ini_file($ini, self::CONF_FILE_AIRTIME, true); + } + //self::UpdateIniValue(self::CONF_FILE_API_CLIENT, 'api_key', "'$api_key'"); + + $ini = parse_ini_file(self::CONF_FILE_API_CLIENT); $ini['api_key'] = "'$api_key'"; - AirtimeIni::write_ini_file($ini, AirtimeIni::CONF_FILE_API_CLIENT, false); + self::write_ini_file($ini, self::CONF_FILE_API_CLIENT); } public static function ReadPythonConfig($p_filename) @@ -313,8 +322,8 @@ class AirtimeIni $oldSettings = parse_ini_file("$conf$suffix.bak", true); } else { - $newSettings = AirtimeIni::ReadPythonConfig($conf); - $oldSettings = AirtimeIni::ReadPythonConfig("$conf$suffix.bak"); + $newSettings = self::ReadPythonConfig($conf); + $oldSettings = self::ReadPythonConfig("$conf$suffix.bak"); } $settings = array_keys($newSettings); @@ -325,12 +334,12 @@ class AirtimeIni $sectionKeys = array_keys($newSettings[$section]); foreach($sectionKeys as $sectionKey) { if(isset($oldSettings[$section][$sectionKey])) { - AirtimeIni::UpdateIniValue($conf, $sectionKey, $oldSettings[$section][$sectionKey]); + self::UpdateIniValue($conf, $sectionKey, $oldSettings[$section][$sectionKey]); } } } else { - AirtimeIni::UpdateIniValue($conf, $section, $oldSettings[$section]); + self::UpdateIniValue($conf, $section, $oldSettings[$section]); } } } diff --git a/python_apps/media-monitor/install/media-monitor-copy-files.py b/python_apps/media-monitor/install/media-monitor-copy-files.py index 5f3b5d0f0..073f09dad 100644 --- a/python_apps/media-monitor/install/media-monitor-copy-files.py +++ b/python_apps/media-monitor/install/media-monitor-copy-files.py @@ -44,6 +44,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/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) From f5b1daf2e071fbf467c26187bfbf5cf1fd01e99a Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Wed, 8 May 2013 15:53:53 -0400 Subject: [PATCH 15/16] CC-5071: Better RabbitMQ passwords -remove rabbitmq vhost on uninstall --- install_minimal/airtime-install | 2 -- install_minimal/airtime-uninstall | 10 ++++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/install_minimal/airtime-install b/install_minimal/airtime-install index 50cfab243..c646d2e83 100755 --- a/install_minimal/airtime-install +++ b/install_minimal/airtime-install @@ -22,7 +22,6 @@ showhelp () { } rabbitmq_install () { - echo "RABBIT!!!" RABBITMQ_VHOST="/airtime" RABBITMQ_USER="airtime" RABBITMQ_PASSWORD=$(awk -F ' = ' '{if (! ($0 ~ /^;/) && $0 ~ /^password/ ) print $2}' /etc/airtime/airtime.conf) @@ -38,7 +37,6 @@ rabbitmq_install () { export RABBITMQ_USER export RABBITMQ_PASSWORD export RABBITMQ_VHOST - } overwrite="f" 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 From 2e69b35d7576b340a2076be327e80b0c54a77d2d Mon Sep 17 00:00:00 2001 From: denise Date: Wed, 8 May 2013 16:28:45 -0400 Subject: [PATCH 16/16] CC-5086: Calendar: Update show pops up instead of Add show after clicking a cell --- .../controllers/ScheduleController.php | 28 +------------------ 1 file changed, 1 insertion(+), 27 deletions(-) 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();