From 17087fc035c74d2e65b4a1ac1d37d8588c192c2f Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Mon, 5 Nov 2012 18:08:47 -0500 Subject: [PATCH 01/37] Added better error message. not much else can be done --- utils/airtime-import/airtime-import.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/utils/airtime-import/airtime-import.py b/utils/airtime-import/airtime-import.py index c77a0f21e..221f644f9 100644 --- a/utils/airtime-import/airtime-import.py +++ b/utils/airtime-import/airtime-import.py @@ -168,6 +168,8 @@ def WatchAddAction(option, opt, value, parser): print "%s added to watched folder list successfully" % path else: print "Adding a watched folder failed: %s" % res['msg']['error'] + print "This error most likely caused by wrong permissions" + print "Try fixing this error by chmodding the parent directory(ies)" else: print "Given path is not a directory: %s" % path From 78f617cacb226da44840b54a674aed18b68f675a Mon Sep 17 00:00:00 2001 From: denise Date: Wed, 23 Jan 2013 17:33:34 -0500 Subject: [PATCH 02/37] CC-4873: Airtime takes 7 seconds to load 32K (very small) from db - put makeFullCalendarEvent inline with loop - removed unnecessary epoch time conversion --- airtime_mvc/application/models/Show.php | 56 ++++++++++++++++--------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/airtime_mvc/application/models/Show.php b/airtime_mvc/application/models/Show.php index 20e6e3e23..6c0e5a0c8 100644 --- a/airtime_mvc/application/models/Show.php +++ b/airtime_mvc/application/models/Show.php @@ -1750,12 +1750,13 @@ SQL; $interval = $p_start->diff($p_end); $days = $interval->format('%a'); $shows = Application_Model_Show::getShows($p_start, $p_end); - $nowEpoch = time(); $content_count = Application_Model_ShowInstance::getContentCount( $p_start, $p_end); $isFull = Application_Model_ShowInstance::getIsFull($p_start, $p_end); $timezone = date_default_timezone_get(); + $current_timezone = new DateTimeZone($timezone); $utc = new DateTimeZone("UTC"); + $now = new DateTime("now", $utc); foreach ($shows as $show) { $options = array(); @@ -1767,7 +1768,6 @@ SQL; if (isset($show["parent_starts"])) { $parentStartsDT = new DateTime($show["parent_starts"], $utc); - $parentStartsEpoch = intval($parentStartsDT->format("U")); } $startsDT = DateTime::createFromFormat("Y-m-d G:i:s", @@ -1775,35 +1775,53 @@ SQL; $endsDT = DateTime::createFromFormat("Y-m-d G:i:s", $show["ends"], $utc); - $startsEpochStr = $startsDT->format("U"); - $endsEpochStr = $endsDT->format("U"); - - $startsEpoch = intval($startsEpochStr); - $endsEpoch = intval($endsEpochStr); - - $startsDT->setTimezone(new DateTimeZone($timezone)); - $endsDT->setTimezone(new DateTimeZone($timezone)); - if( $p_editable ) { - if ($show["record"] && $nowEpoch > $startsEpoch) { + if ($show["record"] && $now > $startsDT) { $options["editable"] = false; } elseif ($show["rebroadcast"] && - $nowEpoch > $parentStartsEpoch) { + $now > $parentStartsDT) { $options["editable"] = false; - } elseif ($nowEpoch < $endsEpoch) { + } elseif ($now < $endsDT) { $options["editable"] = true; } } + $startsDT->setTimezone($current_timezone); + $endsDT->setTimezone($current_timezone); + $options["show_empty"] = (array_key_exists($show['instance_id'], $content_count)) ? 0 : 1; $options["show_partial_filled"] = !$isFull[$show['instance_id']]; - $events[] = &self::makeFullCalendarEvent($show, $options, - $startsDT, $endsDT, $startsEpochStr, $endsEpochStr); - } + $event = array(); + $event["id"] = intval($show["instance_id"]); + $event["title"] = $show["name"]; + $event["start"] = $startsDT->format("Y-m-d H:i:s"); + $event["end"] = $endsDT->format("Y-m-d H:i:s"); + $event["allDay"] = false; + $event["showId"] = intval($show["show_id"]); + $event["record"] = intval($show["record"]); + $event["rebroadcast"] = intval($show["rebroadcast"]); + $event["soundcloud_id"] = is_null($show["soundcloud_id"]) + ? -1 : $show["soundcloud_id"]; + + //event colouring + if ($show["color"] != "") { + $event["textColor"] = "#".$show["color"]; + } + + if ($show["background_color"] != "") { + $event["color"] = "#".$show["background_color"]; + } + + foreach ($options as $key => $value) { + $event[$key] = $value; + } + + $events[] = $event; + } return $events; } @@ -1820,7 +1838,7 @@ SQL; return $percent; } - private static function &makeFullCalendarEvent(&$show, $options=array(), $startDateTime, $endDateTime, $startsEpoch, $endsEpoch) +/* private static function &makeFullCalendarEvent(&$show, $options=array(), $startDateTime, $endDateTime, $startsEpoch, $endsEpoch) { $event = array(); @@ -1851,7 +1869,7 @@ SQL; } return $event; - } + }*/ /* Takes in a UTC DateTime object. * Converts this to local time, since cc_show days From 548b73db429109d8a25dfb49de274ecc0585d8a8 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Wed, 23 Jan 2013 18:31:45 -0500 Subject: [PATCH 03/37] CC-4873: Airtime takes 7 seconds to load 32K (very small) from db -remove an unnecessary roundtrip to server --- .../application/controllers/ScheduleController.php | 10 +++++++++- airtime_mvc/public/js/airtime/schedule/add-show.js | 4 ++-- airtime_mvc/public/js/airtime/schedule/schedule.js | 5 +++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/airtime_mvc/application/controllers/ScheduleController.php b/airtime_mvc/application/controllers/ScheduleController.php index 15dca0621..3348cbbe5 100644 --- a/airtime_mvc/application/controllers/ScheduleController.php +++ b/airtime_mvc/application/controllers/ScheduleController.php @@ -96,7 +96,15 @@ class ScheduleController extends Zend_Controller_Action $this->view->preloadShowForm = true; } - $this->view->headScript()->appendScript("var weekStart = ".Application_Model_Preference::GetWeekStartDay().";"); + $this->view->headScript()->appendScript( + "var calendarPref = {};\n". + "calendarPref.weekStart = ".Application_Model_Preference::GetWeekStartDay().";\n". + "calendarPref.timestamp = ".time().";\n". + "calendarPref.timezoneOffset = ".date("Z").";\n". + "calendarPref.timeScale = '".Application_Model_Preference::GetCalendarTimeScale()."';\n". + "calendarPref.timeInterval = ".Application_Model_Preference::GetCalendarTimeInterval().";\n". + "calendarPref.weekStartDay = ".Application_Model_Preference::GetWeekStartDay().";\n" + ); } public function eventFeedAction() diff --git a/airtime_mvc/public/js/airtime/schedule/add-show.js b/airtime_mvc/public/js/airtime/schedule/add-show.js index 2242f3c66..4f33ccdc7 100644 --- a/airtime_mvc/public/js/airtime/schedule/add-show.js +++ b/airtime_mvc/public/js/airtime/schedule/add-show.js @@ -37,7 +37,7 @@ function createDateInput(el, onSelect) { dayNamesMin: i18n_days_short, closeText: $.i18n._('Close'), //showButtonPanel: true, - firstDay: weekStart + firstDay: calendarPref.weekStart }); } @@ -324,7 +324,7 @@ function setAddShowEvents() { dayNamesMin: i18n_days_short, closeText: 'Close', showButtonPanel: true, - firstDay: weekStart + firstDay: calendarPref.weekStart }); form.find('input[name^="add_show_rebroadcast_time"]').timepicker({ amPmText: ['', ''], diff --git a/airtime_mvc/public/js/airtime/schedule/schedule.js b/airtime_mvc/public/js/airtime/schedule/schedule.js index 2de53cdb5..beb1381cd 100644 --- a/airtime_mvc/public/js/airtime/schedule/schedule.js +++ b/airtime_mvc/public/js/airtime/schedule/schedule.js @@ -328,8 +328,9 @@ function alertShowErrorAndReload(){ } $(document).ready(function() { - $.ajax({ url: baseUrl+"Api/calendar-init/format/json", dataType:"json", success:createFullCalendar - , error:function(jqXHR, textStatus, errorThrown){}}); + var data = {}; + data.calendarInit = calendarPref; + createFullCalendar(data); setInterval(checkCalendarSCUploadStatus, 5000); From 1e336fa2d708ee95603d14ab6418e4ebea4744c0 Mon Sep 17 00:00:00 2001 From: denise Date: Thu, 24 Jan 2013 12:00:31 -0500 Subject: [PATCH 04/37] CC-4875: use a reference when iterating over show events --- airtime_mvc/application/models/Show.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airtime_mvc/application/models/Show.php b/airtime_mvc/application/models/Show.php index 6c0e5a0c8..c30ba717e 100644 --- a/airtime_mvc/application/models/Show.php +++ b/airtime_mvc/application/models/Show.php @@ -1758,7 +1758,7 @@ SQL; $utc = new DateTimeZone("UTC"); $now = new DateTime("now", $utc); - foreach ($shows as $show) { + foreach ($shows as &$show) { $options = array(); //only bother calculating percent for week or day view. From 091f5ff49f680b58ba204b1e5ea1a50014ea6128 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Thu, 24 Jan 2013 12:13:55 -0500 Subject: [PATCH 05/37] CC-4873: Airtime takes 7 seconds to load 32K (very small) from db -we know what month will be the initial view for the user. -Provide this data ahead of time. --- .../controllers/ScheduleController.php | 19 +++++++++++- airtime_mvc/application/models/Show.php | 14 +++++++++ .../schedule/full-calendar-functions.js | 29 ++++++++++++------- 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/airtime_mvc/application/controllers/ScheduleController.php b/airtime_mvc/application/controllers/ScheduleController.php index 3348cbbe5..49f4ff723 100644 --- a/airtime_mvc/application/controllers/ScheduleController.php +++ b/airtime_mvc/application/controllers/ScheduleController.php @@ -96,6 +96,22 @@ class ScheduleController extends Zend_Controller_Action $this->view->preloadShowForm = true; } + $userInfo = Zend_Auth::getInstance()->getStorage()->read(); + $user = new Application_Model_User($userInfo->id); + if ($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) { + $editable = true; + } else { + $editable = false; + } + + $calendar_interval = Application_Model_Preference::GetCalendarTimeInterval(); + if ($calendar_interval == "agendaDay") { + } else if ($calendar_interval == "agendaWeek") { + } else if ($calendar_interval == "month") { + } + list($start, $end) = Application_Model_Show::getStartEndCurrentMonthView(); + $events = &Application_Model_Show::getFullCalendarEvents($start, $end, $editable); + $this->view->headScript()->appendScript( "var calendarPref = {};\n". "calendarPref.weekStart = ".Application_Model_Preference::GetWeekStartDay().";\n". @@ -103,7 +119,8 @@ class ScheduleController extends Zend_Controller_Action "calendarPref.timezoneOffset = ".date("Z").";\n". "calendarPref.timeScale = '".Application_Model_Preference::GetCalendarTimeScale()."';\n". "calendarPref.timeInterval = ".Application_Model_Preference::GetCalendarTimeInterval().";\n". - "calendarPref.weekStartDay = ".Application_Model_Preference::GetWeekStartDay().";\n" + "calendarPref.weekStartDay = ".Application_Model_Preference::GetWeekStartDay().";\n". + "var calendarEvents = ".json_encode($events).";" ); } diff --git a/airtime_mvc/application/models/Show.php b/airtime_mvc/application/models/Show.php index 6c0e5a0c8..7422cc1ae 100644 --- a/airtime_mvc/application/models/Show.php +++ b/airtime_mvc/application/models/Show.php @@ -2176,4 +2176,18 @@ SQL; } return $assocArray; } + + public static function getStartEndCurrentMonthView() { + $first_day_of_calendar_month_view = mktime(0, 0, 0, date("n"), 1); + $weekStart = Application_Model_Preference::GetWeekStartDay(); + while (date('w', $first_day_of_calendar_month_view) != $weekStart) { + $first_day_of_calendar_month_view -= 60*60*24; + } + $last_day_of_calendar_view = $first_day_of_calendar_month_view + 3600*24*41; + + $start = new DateTime("@".$first_day_of_calendar_month_view); + $end = new DateTime("@".$last_day_of_calendar_view); + + return array($start, $end); + } } diff --git a/airtime_mvc/public/js/airtime/schedule/full-calendar-functions.js b/airtime_mvc/public/js/airtime/schedule/full-calendar-functions.js index 08dd31116..51cc4106a 100644 --- a/airtime_mvc/public/js/airtime/schedule/full-calendar-functions.js +++ b/airtime_mvc/public/js/airtime/schedule/full-calendar-functions.js @@ -326,19 +326,26 @@ function eventResize( event, dayDelta, minuteDelta, revertFunc, jsEvent, ui, vie }); } +var initialLoad = true; function getFullCalendarEvents(start, end, callback) { - var url, start_date, end_date; - - start_date = makeTimeStamp(start); - end_date = makeTimeStamp(end); - - url = baseUrl+'Schedule/event-feed'; - - var d = new Date(); - $.post(url, {format: "json", start: start_date, end: end_date, cachep: d.getTime()}, function(json){ - callback(json.events); - }); + if (initialLoad) { + initialLoad = false; + callback(calendarEvents); + } else { + var url, start_date, end_date; + + start_date = makeTimeStamp(start); + end_date = makeTimeStamp(end); + url = baseUrl+'Schedule/event-feed'; + + var d = new Date(); + $.post(url, {format: "json", start: start_date, end: end_date, cachep: d.getTime()}, function(json){ + callback(json.events); + }); + } + //TODO: Look at the type of calendar view...we may be returning too much information + } function checkSCUploadStatus(){ From 2f3a30b580620c12a47bbcbc57adb541caf07352 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Thu, 24 Jan 2013 12:52:24 -0500 Subject: [PATCH 06/37] CC-4873: Airtime takes 7 seconds to load 32K (very small) from db -we know what month will be the initial view for the user. -Provide this data ahead of time via ajax request --- .../controllers/ScheduleController.php | 45 +++++++++---------- .../schedule/full-calendar-functions.js | 11 +++++ .../public/js/airtime/schedule/schedule.js | 4 -- 3 files changed, 32 insertions(+), 28 deletions(-) diff --git a/airtime_mvc/application/controllers/ScheduleController.php b/airtime_mvc/application/controllers/ScheduleController.php index 49f4ff723..cd48ccb13 100644 --- a/airtime_mvc/application/controllers/ScheduleController.php +++ b/airtime_mvc/application/controllers/ScheduleController.php @@ -9,6 +9,7 @@ class ScheduleController extends Zend_Controller_Action { $ajaxContext = $this->_helper->getHelper('AjaxContext'); $ajaxContext->addActionContext('event-feed', 'json') + ->addActionContext('event-feed-preload', 'json') ->addActionContext('make-context-menu', 'json') ->addActionContext('add-show-dialog', 'json') ->addActionContext('add-show', 'json') @@ -88,30 +89,13 @@ class ScheduleController extends Zend_Controller_Action $this->view->headLink()->appendStylesheet($baseUrl.'css/showbuilder.css?'.$CC_CONFIG['airtime_version']); //End Show builder JS/CSS requirements + Application_Model_Schedule::createNewFormSections($this->view); - $user = Application_Model_User::getCurrentUser(); - if ($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) { $this->view->preloadShowForm = true; } - $userInfo = Zend_Auth::getInstance()->getStorage()->read(); - $user = new Application_Model_User($userInfo->id); - if ($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) { - $editable = true; - } else { - $editable = false; - } - - $calendar_interval = Application_Model_Preference::GetCalendarTimeInterval(); - if ($calendar_interval == "agendaDay") { - } else if ($calendar_interval == "agendaWeek") { - } else if ($calendar_interval == "month") { - } - list($start, $end) = Application_Model_Show::getStartEndCurrentMonthView(); - $events = &Application_Model_Show::getFullCalendarEvents($start, $end, $editable); - $this->view->headScript()->appendScript( "var calendarPref = {};\n". "calendarPref.weekStart = ".Application_Model_Preference::GetWeekStartDay().";\n". @@ -120,7 +104,7 @@ class ScheduleController extends Zend_Controller_Action "calendarPref.timeScale = '".Application_Model_Preference::GetCalendarTimeScale()."';\n". "calendarPref.timeInterval = ".Application_Model_Preference::GetCalendarTimeInterval().";\n". "calendarPref.weekStartDay = ".Application_Model_Preference::GetWeekStartDay().";\n". - "var calendarEvents = ".json_encode($events).";" + "var calendarEvents = null;" ); } @@ -133,16 +117,29 @@ class ScheduleController extends Zend_Controller_Action $userInfo = Zend_Auth::getInstance()->getStorage()->read(); $user = new Application_Model_User($userInfo->id); - if ($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) { - $editable = true; - } else { - $editable = false; - } + $editable = $user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)); $events = &Application_Model_Show::getFullCalendarEvents($start, $end, $editable); $this->view->events = $events; } + public function eventFeedPreloadAction() + { + $userInfo = Zend_Auth::getInstance()->getStorage()->read(); + $user = new Application_Model_User($userInfo->id); + $editable = $user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)); + + $calendar_interval = Application_Model_Preference::GetCalendarTimeInterval(); + if ($calendar_interval == "agendaDay") { + } else if ($calendar_interval == "agendaWeek") { + } else if ($calendar_interval == "month") { + } + list($start, $end) = Application_Model_Show::getStartEndCurrentMonthView(); + $events = &Application_Model_Show::getFullCalendarEvents($start, $end, $editable); + + $this->view->events = $events; + } + public function getCurrentShowAction() { $currentShow = Application_Model_Show::getCurrentShow(); diff --git a/airtime_mvc/public/js/airtime/schedule/full-calendar-functions.js b/airtime_mvc/public/js/airtime/schedule/full-calendar-functions.js index 51cc4106a..2590bf29d 100644 --- a/airtime_mvc/public/js/airtime/schedule/full-calendar-functions.js +++ b/airtime_mvc/public/js/airtime/schedule/full-calendar-functions.js @@ -326,6 +326,17 @@ function eventResize( event, dayDelta, minuteDelta, revertFunc, jsEvent, ui, vie }); } +function preload () { + var url = baseUrl+'Schedule/event-feed-preload'; + var d = new Date(); + + $.post(url, {format: "json", cachep: d.getTime()}, function(json){ + calendarEvents = json.events; + createFullCalendar({calendarInit: calendarPref}); + }); +} +preload(); + var initialLoad = true; function getFullCalendarEvents(start, end, callback) { diff --git a/airtime_mvc/public/js/airtime/schedule/schedule.js b/airtime_mvc/public/js/airtime/schedule/schedule.js index beb1381cd..3c4f9fd3b 100644 --- a/airtime_mvc/public/js/airtime/schedule/schedule.js +++ b/airtime_mvc/public/js/airtime/schedule/schedule.js @@ -328,10 +328,6 @@ function alertShowErrorAndReload(){ } $(document).ready(function() { - var data = {}; - data.calendarInit = calendarPref; - createFullCalendar(data); - setInterval(checkCalendarSCUploadStatus, 5000); $.contextMenu({ From c3f2bf57dee93c2480b4c2f6a5aed72fff3fc463 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Thu, 24 Jan 2013 14:02:50 -0500 Subject: [PATCH 07/37] CC-4873: Airtime takes 7 seconds to load 32K (very small) from db -further optimization by looking at the preferred time scale --- .../controllers/ScheduleController.php | 11 +++++--- airtime_mvc/application/models/Show.php | 26 ++++++++++++++++++- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/airtime_mvc/application/controllers/ScheduleController.php b/airtime_mvc/application/controllers/ScheduleController.php index cd48ccb13..0b384911e 100644 --- a/airtime_mvc/application/controllers/ScheduleController.php +++ b/airtime_mvc/application/controllers/ScheduleController.php @@ -129,14 +129,19 @@ class ScheduleController extends Zend_Controller_Action $user = new Application_Model_User($userInfo->id); $editable = $user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)); - $calendar_interval = Application_Model_Preference::GetCalendarTimeInterval(); + $calendar_interval = Application_Model_Preference::GetCalendarTimeScale(); + Logging::info($calendar_interval); if ($calendar_interval == "agendaDay") { + list($start, $end) = Application_Model_Show::getStartEndCurrentDayView(); } else if ($calendar_interval == "agendaWeek") { + list($start, $end) = Application_Model_Show::getStartEndCurrentWeekView(); } else if ($calendar_interval == "month") { + list($start, $end) = Application_Model_Show::getStartEndCurrentMonthView(); + } else { + Logging::error("Invalid Calendar Interval '$calendar_interval'"); } - list($start, $end) = Application_Model_Show::getStartEndCurrentMonthView(); - $events = &Application_Model_Show::getFullCalendarEvents($start, $end, $editable); + $events = &Application_Model_Show::getFullCalendarEvents($start, $end, $editable); $this->view->events = $events; } diff --git a/airtime_mvc/application/models/Show.php b/airtime_mvc/application/models/Show.php index 2d66d5443..933c2c841 100644 --- a/airtime_mvc/application/models/Show.php +++ b/airtime_mvc/application/models/Show.php @@ -2183,11 +2183,35 @@ SQL; while (date('w', $first_day_of_calendar_month_view) != $weekStart) { $first_day_of_calendar_month_view -= 60*60*24; } - $last_day_of_calendar_view = $first_day_of_calendar_month_view + 3600*24*41; + $last_day_of_calendar_view = $first_day_of_calendar_month_view + 3600*24*42; $start = new DateTime("@".$first_day_of_calendar_month_view); $end = new DateTime("@".$last_day_of_calendar_view); return array($start, $end); } + + public static function getStartEndCurrentWeekView() { + $first_day_of_calendar_week_view = mktime(0, 0, 0, date("n"), date("j")); + $weekStart = Application_Model_Preference::GetWeekStartDay(); + while (date('w', $first_day_of_calendar_week_view) != $weekStart) { + $first_day_of_calendar_week_view -= 60*60*24; + } + $last_day_of_calendar_view = $first_day_of_calendar_week_view + 3600*24*7; + + $start = new DateTime("@".$first_day_of_calendar_week_view); + $end = new DateTime("@".$last_day_of_calendar_view); + + return array($start, $end); + } + + public static function getStartEndCurrentDayView() { + $today = mktime(0, 0, 0, date("n"), date("j")); + $tomorrow = $today + 3600*24; + + $start = new DateTime("@".$today); + $end = new DateTime("@".$tomorrow); + + return array($start, $end); + } } From 56c61d4ab70286b6d96068659973ce6168bfc9f1 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Thu, 24 Jan 2013 14:09:14 -0500 Subject: [PATCH 08/37] CC-4873: Airtime takes 7 seconds to load 32K (very small) from db -minor cleanup of function init --- .../public/js/airtime/schedule/full-calendar-functions.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/airtime_mvc/public/js/airtime/schedule/full-calendar-functions.js b/airtime_mvc/public/js/airtime/schedule/full-calendar-functions.js index 2590bf29d..810ce0d88 100644 --- a/airtime_mvc/public/js/airtime/schedule/full-calendar-functions.js +++ b/airtime_mvc/public/js/airtime/schedule/full-calendar-functions.js @@ -326,7 +326,7 @@ function eventResize( event, dayDelta, minuteDelta, revertFunc, jsEvent, ui, vie }); } -function preload () { +function preloadEventFeed () { var url = baseUrl+'Schedule/event-feed-preload'; var d = new Date(); @@ -335,7 +335,6 @@ function preload () { createFullCalendar({calendarInit: calendarPref}); }); } -preload(); var initialLoad = true; function getFullCalendarEvents(start, end, callback) { @@ -355,8 +354,6 @@ function getFullCalendarEvents(start, end, callback) { callback(json.events); }); } - //TODO: Look at the type of calendar view...we may be returning too much information - } function checkSCUploadStatus(){ @@ -559,6 +556,7 @@ function alertShowErrorAndReload(){ window.location.reload(); } +preloadEventFeed(); $(document).ready(function(){ setInterval( "checkSCUploadStatus()", 5000 ); setInterval( "getCurrentShow()", 5000 ); From 1873022a132fd66c8cee530ea3a17fb02f91dd6d Mon Sep 17 00:00:00 2001 From: denise Date: Fri, 25 Jan 2013 11:21:34 -0500 Subject: [PATCH 09/37] CC-4876: Default interface language setting does not appear to affect text or drop-down menu on login page? -fixed --- airtime_mvc/application/controllers/LocaleController.php | 6 +----- airtime_mvc/application/controllers/plugins/Acl_plugin.php | 2 +- airtime_mvc/public/js/airtime/login/login.js | 2 +- airtime_mvc/public/js/airtime/preferences/preferences.js | 1 + 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/airtime_mvc/application/controllers/LocaleController.php b/airtime_mvc/application/controllers/LocaleController.php index d689417be..efdecff80 100644 --- a/airtime_mvc/application/controllers/LocaleController.php +++ b/airtime_mvc/application/controllers/LocaleController.php @@ -4,10 +4,6 @@ class LocaleController extends Zend_Controller_Action { public function init() { - $ajaxContext = $this->_helper->getHelper("AjaxContext"); - $ajaxContext->addActionContext("general-translation-table", "json") - ->addActionContext("datatables-translation-table", "json") - ->initContext(); } public function datatablesTranslationTableAction() @@ -26,7 +22,7 @@ class LocaleController extends Zend_Controller_Action $locale.".txt") ); } - + public function generalTranslationTableAction() { $translations = array ( diff --git a/airtime_mvc/application/controllers/plugins/Acl_plugin.php b/airtime_mvc/application/controllers/plugins/Acl_plugin.php index 4cadba9db..44555e533 100644 --- a/airtime_mvc/application/controllers/plugins/Acl_plugin.php +++ b/airtime_mvc/application/controllers/plugins/Acl_plugin.php @@ -110,7 +110,7 @@ class Zend_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract { $controller = strtolower($request->getControllerName()); - if (in_array($controller, array("api", "auth"))) { + if (in_array($controller, array("api", "auth", "locale"))) { $this->setRoleName("G"); } elseif (!Zend_Auth::getInstance()->hasIdentity()) { diff --git a/airtime_mvc/public/js/airtime/login/login.js b/airtime_mvc/public/js/airtime/login/login.js index a37210b35..f21043c31 100644 --- a/airtime_mvc/public/js/airtime/login/login.js +++ b/airtime_mvc/public/js/airtime/login/login.js @@ -1,6 +1,6 @@ $(window).load(function(){ $("#username").focus(); - $("#locale").val($.cookie("airtime_locale")!== null?$.cookie("airtime_locale"):'en_CA'); + $("#locale").val($.cookie("airtime_locale")!== null?$.cookie("airtime_locale"):$.cookie("default_airtime_locale")); }); $(document).ready(function() { diff --git a/airtime_mvc/public/js/airtime/preferences/preferences.js b/airtime_mvc/public/js/airtime/preferences/preferences.js index 1d529617d..eec5e1c7e 100644 --- a/airtime_mvc/public/js/airtime/preferences/preferences.js +++ b/airtime_mvc/public/js/airtime/preferences/preferences.js @@ -111,6 +111,7 @@ $(document).ready(function() { $.post(url, {format: "json", data: data}, function(data){ var json = $.parseJSON(data); $('#content').empty().append(json.html); + $.cookie("default_airtime_locale", $('#locale').val(), {path: '/'}); setTimeout(removeSuccessMsg, 5000); showErrorSections(); }); From 7b3850fac6c6322b8b9b40efa63199ac76b6f257 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Fri, 25 Jan 2013 11:30:36 -0500 Subject: [PATCH 10/37] false not being returned on connection error --- python_apps/api_clients/api_client.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/python_apps/api_clients/api_client.py b/python_apps/api_clients/api_client.py index 048da729c..517870e45 100644 --- a/python_apps/api_clients/api_client.py +++ b/python_apps/api_clients/api_client.py @@ -168,9 +168,9 @@ class AirtimeApiClient(object): def get_schedule(self): # TODO : properly refactor this routine - # For now thre return type is a little fucked for compatibility reasons + # For now the return type is a little fucked for compatibility reasons try: return (True, self.services.export_url()) - except: (False, "") + except: return (False, None) def notify_liquidsoap_started(self): return self.services.notify_liquidsoap_started() @@ -356,7 +356,7 @@ class AirtimeApiClient(object): """ #http://localhost/api/get-files-without-replay-gain/dir_id/1 return self.services.get_files_without_replay_gain(dir_id=dir_id) - + def get_files_without_silan_value(self): """ Download a list of files that need to have their cue in/out value @@ -372,7 +372,7 @@ class AirtimeApiClient(object): """ self.logger.debug(self.services.update_replay_gain_value( _post_data={'data': json.dumps(pairs)})) - + def update_cue_values_by_silan(self, pairs): """ 'pairs' is a list of pairs in (x, y), where x is the file's database From 0cf8526f87df1d9b3d2dc0b98d559ae233cee1b9 Mon Sep 17 00:00:00 2001 From: denise Date: Fri, 25 Jan 2013 11:51:56 -0500 Subject: [PATCH 11/37] CC-4878"Send support feedback" button at initial login tries to load "http://showbuilder" and was missing the local host IP. -fixed --- airtime_mvc/application/forms/RegisterAirtime.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airtime_mvc/application/forms/RegisterAirtime.php b/airtime_mvc/application/forms/RegisterAirtime.php index d1557612a..2da7083c8 100644 --- a/airtime_mvc/application/forms/RegisterAirtime.php +++ b/airtime_mvc/application/forms/RegisterAirtime.php @@ -7,7 +7,7 @@ class Application_Form_RegisterAirtime extends Zend_Form public function init() { - $this->setAction(Application_Common_OsPath::getBaseDir().'/Showbuilder'); + $this->setAction(Application_Common_OsPath::getBaseDir().'Showbuilder'); $this->setMethod('post'); $country_list = Application_Model_Preference::GetCountryList(); From 21a04803e576fa5dc746dc635c239636a911aff5 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Fri, 25 Jan 2013 12:11:50 -0500 Subject: [PATCH 12/37] Fix Pypo giving up too early on attempting to receive schedule --- python_apps/pypo/pypofetch.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/python_apps/pypo/pypofetch.py b/python_apps/pypo/pypofetch.py index ec3ef11ce..b690ace04 100644 --- a/python_apps/pypo/pypofetch.py +++ b/python_apps/pypo/pypofetch.py @@ -217,7 +217,7 @@ class PypoFetch(Thread): self.set_bootstrap_variables() #get the most up to date schedule, which will #initiate the process #of making sure Liquidsoap is playing the schedule - self.manual_schedule_fetch() + self.persistent_manual_schedule_fetch(max_attempts=5) except Exception, e: self.logger.error(str(e)) @@ -488,10 +488,20 @@ class PypoFetch(Thread): self.process_schedule(self.schedule_data) return success + def persistent_manual_schedule_fetch(self, max_attempts=1): + success = False + num_attempts = 0 + while not success and num_attempts < max_attempts: + success = self.manual_schedule_fetch() + num_attempts += 1 + + return success + + def main(self): # Bootstrap: since we are just starting up, we need to grab the # most recent schedule. After that we can just wait for updates. - success = self.manual_schedule_fetch() + success = self.persistent_manual_schedule_fetch(max_attempts=5) if success: self.logger.info("Bootstrap schedule received: %s", self.schedule_data) self.set_bootstrap_variables() @@ -519,7 +529,7 @@ class PypoFetch(Thread): self.handle_message(message) except Empty, e: self.logger.info("Queue timeout. Fetching schedule manually") - self.manual_schedule_fetch() + self.persistent_manual_schedule_fetch(max_attempts=5) except Exception, e: import traceback top = traceback.format_exc() From a16e8d05aac5dc1d1b6890e0c74622d621f10692 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Fri, 25 Jan 2013 12:33:27 -0500 Subject: [PATCH 13/37] -don't push new schedule until end of request --- airtime_mvc/application/controllers/PreferenceController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airtime_mvc/application/controllers/PreferenceController.php b/airtime_mvc/application/controllers/PreferenceController.php index 269215783..00b0fa6ca 100644 --- a/airtime_mvc/application/controllers/PreferenceController.php +++ b/airtime_mvc/application/controllers/PreferenceController.php @@ -273,7 +273,7 @@ class PreferenceController extends Zend_Controller_Action Application_Model_Preference::SetEnableReplayGain($values["enableReplayGain"]); Application_Model_Preference::setReplayGainModifier($values["replayGainModifier"]); $md = array('schedule' => Application_Model_Schedule::getSchedule()); - Application_Model_RabbitMq::SendMessageToPypo("update_schedule", $md); + Application_Model_RabbitMq::PushSchedule(); } if (!Application_Model_Preference::GetMasterDjConnectionUrlOverride()) { From a6f4805e1a3f9378a780baac67b79a6cb1ae36a9 Mon Sep 17 00:00:00 2001 From: denise Date: Fri, 25 Jan 2013 12:44:20 -0500 Subject: [PATCH 14/37] CC-4879: Pop-up HTML Audio Player still seems to be changing spaces to %20 and so on... -fixed --- .../application/controllers/AudiopreviewController.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/airtime_mvc/application/controllers/AudiopreviewController.php b/airtime_mvc/application/controllers/AudiopreviewController.php index e094a7450..302e8c545 100644 --- a/airtime_mvc/application/controllers/AudiopreviewController.php +++ b/airtime_mvc/application/controllers/AudiopreviewController.php @@ -60,8 +60,10 @@ class AudiopreviewController extends Zend_Controller_Action $this->view->uri = $uri; $this->view->mime = $mime; $this->view->audioFileID = $audioFileID; - $this->view->audioFileArtist = $audioFileArtist; - $this->view->audioFileTitle = $audioFileTitle; + // We need to decode artist and title because it gets + // encoded twice in js + $this->view->audioFileArtist = urldecode($audioFileArtist); + $this->view->audioFileTitle = urldecode($audioFileTitle); $this->view->type = $type; $this->_helper->viewRenderer->setRender('audio-preview'); From 8dd7ffee8c93474b6fbd89b53e18d89fb99c4cb9 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Fri, 25 Jan 2013 14:16:53 -0500 Subject: [PATCH 15/37] locks should occur inside try/catch --- python_apps/pypo/pypofetch.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/python_apps/pypo/pypofetch.py b/python_apps/pypo/pypofetch.py index b690ace04..1448c65da 100644 --- a/python_apps/pypo/pypofetch.py +++ b/python_apps/pypo/pypofetch.py @@ -132,8 +132,8 @@ class PypoFetch(Thread): elif(sourcename == "live_dj"): command += "live_dj_harbor.kick\n" - lock.acquire() try: + lock.acquire() tn = telnetlib.Telnet(LS_HOST, LS_PORT) tn.write(command) tn.write('exit\n') @@ -159,8 +159,9 @@ class PypoFetch(Thread): else: command += "stop\n" - lock.acquire() try: + lock.acquire() + tn = telnetlib.Telnet(LS_HOST, LS_PORT) tn.write(command) tn.write('exit\n') @@ -179,7 +180,6 @@ class PypoFetch(Thread): info = self.api_client.get_bootstrap_info() if info is None: self.logger.error('Unable to get bootstrap info.. Exiting pypo...') - sys.exit(1) else: self.logger.debug('info:%s', info) for k, v in info['switch_status'].iteritems(): @@ -190,8 +190,8 @@ class PypoFetch(Thread): def restart_liquidsoap(self): - self.telnet_lock.acquire() try: + self.telnet_lock.acquire() self.logger.info("Restarting Liquidsoap") subprocess.call('/etc/init.d/airtime-liquidsoap restart', shell=True) @@ -322,8 +322,8 @@ class PypoFetch(Thread): This function updates the bootup time variable in Liquidsoap script """ - self.telnet_lock.acquire() try: + self.telnet_lock.acquire() tn = telnetlib.Telnet(LS_HOST, LS_PORT) # update the boot up time of Liquidsoap. Since Liquidsoap is not restarting, # we are manually adjusting the bootup time variable so the status msg will get @@ -395,8 +395,8 @@ class PypoFetch(Thread): self.logger.info(LS_HOST) self.logger.info(LS_PORT) - self.telnet_lock.acquire() try: + self.telnet_lock.acquire() tn = telnetlib.Telnet(LS_HOST, LS_PORT) command = ('vars.station_name %s\n' % station_name).encode('utf-8') self.logger.info(command) From 807aa6b4a683a2ba9c55a645d4460c1214e7aecc Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Fri, 25 Jan 2013 15:14:40 -0500 Subject: [PATCH 16/37] fix restart liquidsoap being sent as default no arguments for pypo-notify --- python_apps/pypo/pyponotify.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python_apps/pypo/pyponotify.py b/python_apps/pypo/pyponotify.py index 9c2f1688c..797d1ce9b 100644 --- a/python_apps/pypo/pyponotify.py +++ b/python_apps/pypo/pyponotify.py @@ -43,7 +43,7 @@ parser.add_option("-t", "--time", help="Liquidsoap boot up time", action="store" parser.add_option("-x", "--source-name", help="source connection name", metavar="source_name") parser.add_option("-y", "--source-status", help="source connection status", metavar="source_status") parser.add_option("-w", "--webstream", help="JSON metadata associated with webstream", metavar="json_data") -parser.add_option("-n", "--liquidsoap-started", help="notify liquidsoap started", metavar="json_data", action="store_true", default=True) +parser.add_option("-n", "--liquidsoap-started", help="notify liquidsoap started", metavar="json_data", action="store_true", default=False) # parse options From 2ef8604c31d149bc609e63b85d263ea0df6a09fe Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Fri, 25 Jan 2013 16:23:12 -0500 Subject: [PATCH 17/37] remove unnecessary code --- .../application/models/Systemstatus.php | 37 ++++++------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/airtime_mvc/application/models/Systemstatus.php b/airtime_mvc/application/models/Systemstatus.php index ef694ccf2..6f6a05fff 100644 --- a/airtime_mvc/application/models/Systemstatus.php +++ b/airtime_mvc/application/models/Systemstatus.php @@ -214,35 +214,22 @@ class Application_Model_Systemstatus { $partions = array(); - if (isset($_SERVER['AIRTIME_SRV'])) { - //connect to DB and find how much total space user has allocated. - $totalSpace = Application_Model_Preference::GetDiskQuota(); + /* First lets get all the watched directories. Then we can group them + * into the same partitions by comparing the partition sizes. */ + $musicDirs = Application_Model_MusicDir::getWatchedDirs(); + $musicDirs[] = Application_Model_MusicDir::getStorDir(); - $storPath = Application_Model_MusicDir::getStorDir()->getDirectory(); + foreach ($musicDirs as $md) { + $totalSpace = disk_total_space($md->getDirectory()); - list($usedSpace,) = preg_split("/[\s]+/", exec("du -bs $storPath")); + if (!isset($partitions[$totalSpace])) { + $partitions[$totalSpace] = new StdClass; + $partitions[$totalSpace]->totalSpace = $totalSpace; + $partitions[$totalSpace]->totalFreeSpace = disk_free_space($md->getDirectory()); - $partitions[$totalSpace]->totalSpace = $totalSpace; - $partitions[$totalSpace]->totalFreeSpace = $totalSpace - $usedSpace; - Logging::info($partitions[$totalSpace]->totalFreeSpace); - } else { - /* First lets get all the watched directories. Then we can group them - * into the same partitions by comparing the partition sizes. */ - $musicDirs = Application_Model_MusicDir::getWatchedDirs(); - $musicDirs[] = Application_Model_MusicDir::getStorDir(); - - foreach ($musicDirs as $md) { - $totalSpace = disk_total_space($md->getDirectory()); - - if (!isset($partitions[$totalSpace])) { - $partitions[$totalSpace] = new StdClass; - $partitions[$totalSpace]->totalSpace = $totalSpace; - $partitions[$totalSpace]->totalFreeSpace = disk_free_space($md->getDirectory()); - - } - - $partitions[$totalSpace]->dirs[] = $md->getDirectory(); } + + $partitions[$totalSpace]->dirs[] = $md->getDirectory(); } return array_values($partitions); From c93b90cc54cc44975ba04971c73fc7ec159d88b1 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Sat, 26 Jan 2013 20:05:31 -0500 Subject: [PATCH 18/37] prepare for improvements to way pypo communicates with LS --- python_apps/pypo/pypofetch.py | 47 ++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/python_apps/pypo/pypofetch.py b/python_apps/pypo/pypofetch.py index 1448c65da..03c79cfc6 100644 --- a/python_apps/pypo/pypofetch.py +++ b/python_apps/pypo/pypofetch.py @@ -143,6 +143,24 @@ class PypoFetch(Thread): finally: lock.release() + @staticmethod + def telnet_send(logger, lock, commands): + try: + lock.acquire() + + tn = telnetlib.Telnet(LS_HOST, LS_PORT) + for i in commands: + logger.info(i) + tn.write(i) + + tn.write('exit\n') + tn.read_all() + except Exception, e: + logger.error(str(e)) + finally: + lock.release() + + @staticmethod def switch_source(logger, lock, sourcename, status): logger.debug('Switching source: %s to "%s" status', sourcename, status) @@ -159,17 +177,7 @@ class PypoFetch(Thread): else: command += "stop\n" - try: - lock.acquire() - - tn = telnetlib.Telnet(LS_HOST, LS_PORT) - tn.write(command) - tn.write('exit\n') - tn.read_all() - except Exception, e: - logger.error(str(e)) - finally: - lock.release() + PypoFetch.telnet_send(logger, lock, [command]) """ grabs some information that are needed to be set on bootstrap time @@ -184,9 +192,19 @@ class PypoFetch(Thread): self.logger.debug('info:%s', info) for k, v in info['switch_status'].iteritems(): self.switch_source(self.logger, self.telnet_lock, k, v) - self.update_liquidsoap_stream_format(info['stream_label']) - self.update_liquidsoap_station_name(info['station_name']) - self.update_liquidsoap_transition_fade(info['transition_fade']) + #self.update_liquidsoap_stream_format(info['stream_label']) + #self.update_liquidsoap_station_name(info['station_name']) + #self.update_liquidsoap_transition_fade(info['transition_fade']) + + stream_format = info['stream_label'] + station_name = info['station_name'] + fade = info['transition_fade'] + + commands = [] + commands.append(('vars.stream_metadata_type %s\n' % stream_format).encode('utf-8')) + commands.append(('vars.station_name %s\n' % station_name).encode('utf-8')) + commands.append(('vars.default_dj_fade %s\n' % fade).encode('utf-8')) + PypoFetch.telnet_send(self.logger, self.telnet_lock, commands) def restart_liquidsoap(self): @@ -356,6 +374,7 @@ class PypoFetch(Thread): if(status == "true"): self.api_client.notify_liquidsoap_status("OK", stream_id, str(fake_time)) + def update_liquidsoap_stream_format(self, stream_format): # Push stream metadata to liquidsoap # TODO: THIS LIQUIDSOAP STUFF NEEDS TO BE MOVED TO PYPO-PUSH!!! From b389e440019426f5cce94910ca4e5cfb2f578442 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Sun, 27 Jan 2013 15:00:56 -0500 Subject: [PATCH 19/37] take liquidsoap by the horns if it misbehaves. --- python_apps/pypo/airtime-liquidsoap-init-d | 6 +++--- .../pypo/liquidsoap_scripts/liquidsoap_prepare_terminate.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/python_apps/pypo/airtime-liquidsoap-init-d b/python_apps/pypo/airtime-liquidsoap-init-d index 4180d5c67..7096bc59c 100755 --- a/python_apps/pypo/airtime-liquidsoap-init-d +++ b/python_apps/pypo/airtime-liquidsoap-init-d @@ -28,10 +28,10 @@ start () { stop () { monit unmonitor airtime-liquidsoap >/dev/null 2>&1 - /usr/lib/airtime/airtime_virtualenv/bin/python /usr/lib/airtime/pypo/bin/liquidsoap_scripts/liquidsoap_prepare_terminate.py - + #send term signal after 10 seconds + timeout 10 /usr/lib/airtime/airtime_virtualenv/bin/python /usr/lib/airtime/pypo/bin/liquidsoap_scripts/liquidsoap_prepare_terminate.py # Send TERM after 5 seconds, wait at most 30 seconds. - start-stop-daemon --stop --oknodo --retry 5 --quiet --pidfile $PIDFILE + start-stop-daemon --stop --oknodo --retry=TERM/10/KILL/5 --quiet --pidfile $PIDFILE rm -f $PIDFILE } diff --git a/python_apps/pypo/liquidsoap_scripts/liquidsoap_prepare_terminate.py b/python_apps/pypo/liquidsoap_scripts/liquidsoap_prepare_terminate.py index e1dac82b6..2f632d9c7 100644 --- a/python_apps/pypo/liquidsoap_scripts/liquidsoap_prepare_terminate.py +++ b/python_apps/pypo/liquidsoap_scripts/liquidsoap_prepare_terminate.py @@ -6,14 +6,14 @@ try: config = ConfigObj('/etc/airtime/pypo.cfg') LS_HOST = config['ls_host'] LS_PORT = config['ls_port'] - + tn = telnetlib.Telnet(LS_HOST, LS_PORT) tn.write("master_harbor.stop\n") tn.write("live_dj_harbor.stop\n") tn.write('exit\n') tn.read_all() - + except Exception, e: print('Error loading config file: %s', e) sys.exit() - \ No newline at end of file + From f1215c10fdd7fcbbb3534473caee67e0848589d3 Mon Sep 17 00:00:00 2001 From: denise Date: Mon, 28 Jan 2013 14:21:11 -0500 Subject: [PATCH 20/37] CC-4882: Scheduled item does not take into account cue_out - cue_in time -fixed --- airtime_mvc/application/models/Scheduler.php | 7 +++++-- airtime_mvc/application/models/StoredFile.php | 8 ++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/airtime_mvc/application/models/Scheduler.php b/airtime_mvc/application/models/Scheduler.php index 2530eb7bf..be9930402 100644 --- a/airtime_mvc/application/models/Scheduler.php +++ b/airtime_mvc/application/models/Scheduler.php @@ -136,13 +136,17 @@ class Application_Model_Scheduler if ($type === "audioclip") { $file = CcFilesQuery::create()->findPK($id, $this->con); + $storedFile = new Application_Model_StoredFile($file->getDbId()); if (is_null($file) || !$file->visible()) { throw new Exception(_("A selected File does not exist!")); } else { $data = $this->fileInfo; $data["id"] = $id; - $data["cliplength"] = $file->getDbLength(); + $data["cliplength"] = $storedFile->getRealClipLength( + $file->getDbCuein(), + $file->getDbCueout()); + $data["cuein"] = $file->getDbCuein(); $data["cueout"] = $file->getDbCueout(); @@ -438,7 +442,6 @@ class Application_Model_Scheduler } foreach ($schedFiles as $file) { - $endTimeDT = $this->findEndTime($nextStartDT, $file['cliplength']); //item existed previously and is being moved. diff --git a/airtime_mvc/application/models/StoredFile.php b/airtime_mvc/application/models/StoredFile.php index bd50f2826..9ca6ff32c 100644 --- a/airtime_mvc/application/models/StoredFile.php +++ b/airtime_mvc/application/models/StoredFile.php @@ -1285,6 +1285,14 @@ SQL; } } } + + 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 {} From 5f3f2cd97ccfb8da8d706dc66018ce2e5b63a35f Mon Sep 17 00:00:00 2001 From: denise Date: Mon, 28 Jan 2013 16:46:11 -0500 Subject: [PATCH 21/37] CC-4881: Cue in time can be greater than Cue out time in some situations -fixed --- airtime_mvc/application/models/Schedule.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/airtime_mvc/application/models/Schedule.php b/airtime_mvc/application/models/Schedule.php index 481f22b2d..81a3c55e7 100644 --- a/airtime_mvc/application/models/Schedule.php +++ b/airtime_mvc/application/models/Schedule.php @@ -696,6 +696,10 @@ SQL; 'replay_gain' => $replay_gain, 'independent_event' => $independent_event, ); + + if ($schedule_item['cue_in'] > $schedule_item['cue_out']) { + $schedule_item['cue_in'] = $schedule_item['cue_out']; + } self::appendScheduleItem($data, $start, $schedule_item); } @@ -906,7 +910,6 @@ SQL; self::createScheduledEvents($data, $range_start, $range_end); self::foldData($data["media"]); - return $data; } From d7358338f0355cda0ba44e8bbf5d2f5258865cd8 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Mon, 28 Jan 2013 17:00:16 -0500 Subject: [PATCH 22/37] improved logging in pypo fetch --- python_apps/pypo/pypofetch.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/python_apps/pypo/pypofetch.py b/python_apps/pypo/pypofetch.py index 1448c65da..9a94a4103 100644 --- a/python_apps/pypo/pypofetch.py +++ b/python_apps/pypo/pypofetch.py @@ -135,6 +135,7 @@ class PypoFetch(Thread): try: lock.acquire() tn = telnetlib.Telnet(LS_HOST, LS_PORT) + self.logger.info(command) tn.write(command) tn.write('exit\n') tn.read_all() @@ -330,8 +331,13 @@ class PypoFetch(Thread): # updated. current_time = time.time() boot_up_time_command = "vars.bootup_time " + str(current_time) + "\n" + self.logger.info(boot_up_time_command) tn.write(boot_up_time_command) - tn.write("streams.connection_status\n") + + connection_status = "streams.connection_status\n" + self.logger.info(connection_status) + tn.write(connection_status) + tn.write('exit\n') output = tn.read_all() From 9d8a9faca872b7697437da0811b7664694840c7e Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Mon, 28 Jan 2013 17:00:35 -0500 Subject: [PATCH 23/37] make code formatting easier on eyes --- .../pypo/liquidsoap_scripts/ls_script.liq | 79 ++++++++++++++++--- 1 file changed, 66 insertions(+), 13 deletions(-) diff --git a/python_apps/pypo/liquidsoap_scripts/ls_script.liq b/python_apps/pypo/liquidsoap_scripts/ls_script.liq index cd01ad453..489d494a3 100644 --- a/python_apps/pypo/liquidsoap_scripts/ls_script.liq +++ b/python_apps/pypo/liquidsoap_scripts/ls_script.liq @@ -195,28 +195,81 @@ def check_dj_client(user,password) = hd == "True" end -def append_dj_inputs(master_harbor_input_port, master_harbor_input_mount_point, dj_harbor_input_port, dj_harbor_input_mount_point, s) = - if master_harbor_input_port != 0 and master_harbor_input_mount_point != "" and dj_harbor_input_port != 0 and dj_harbor_input_mount_point != "" then - master_dj = mksafe(audio_to_stereo(input.harbor(id="master_harbor", master_harbor_input_mount_point, port=master_harbor_input_port, auth=check_master_dj_client, - max=40., on_connect=master_dj_connect, on_disconnect=master_dj_disconnect))) - dj_live = mksafe(audio_to_stereo(input.harbor(id="live_dj_harbor", dj_harbor_input_mount_point, port=dj_harbor_input_port, auth=check_dj_client, - max=40., on_connect=live_dj_connect, on_disconnect=live_dj_disconnect))) +def append_dj_inputs(master_harbor_input_port, + master_harbor_input_mount_point, + dj_harbor_input_port, + dj_harbor_input_mount_point, + s) = + if master_harbor_input_port != 0 + and master_harbor_input_mount_point != "" + and dj_harbor_input_port != 0 + and dj_harbor_input_mount_point != "" then + + master_dj = mksafe( + audio_to_stereo( + input.harbor(id="master_harbor", + master_harbor_input_mount_point, + port=master_harbor_input_port, + auth=check_master_dj_client, + max=40., + on_connect=master_dj_connect, + on_disconnect=master_dj_disconnect))) + + dj_live = mksafe( + audio_to_stereo( + input.harbor(id="live_dj_harbor", + dj_harbor_input_mount_point, + port=dj_harbor_input_port, + auth=check_dj_client, + max=40., + on_connect=live_dj_connect, + on_disconnect=live_dj_disconnect))) ignore(output.dummy(master_dj, fallible=true)) ignore(output.dummy(dj_live, fallible=true)) - switch(id="master_dj_switch", track_sensitive=false, transitions=[transition, transition, transition], [({!master_dj_enabled},master_dj), ({!live_dj_enabled},dj_live), ({true}, s)]) + + switch(id="master_dj_switch", + track_sensitive=false, + transitions=[transition, transition, transition], + [({!master_dj_enabled},master_dj), + ({!live_dj_enabled},dj_live), + ({true}, s)]) + elsif master_harbor_input_port != 0 and master_harbor_input_mount_point != "" then - master_dj = mksafe(audio_to_stereo(input.harbor(id="master_harbor", master_harbor_input_mount_point, port=master_harbor_input_port, auth=check_master_dj_client, - max=40., on_connect=master_dj_connect, on_disconnect=master_dj_disconnect))) + master_dj = mksafe( + audio_to_stereo( + input.harbor(id="master_harbor", + master_harbor_input_mount_point, + port=master_harbor_input_port, + auth=check_master_dj_client, + max=40., + on_connect=master_dj_connect, + on_disconnect=master_dj_disconnect))) + ignore(output.dummy(master_dj, fallible=true)) - switch(id="master_dj_switch", track_sensitive=false, transitions=[transition, transition], [({!master_dj_enabled},master_dj), ({true}, s)]) + switch(id="master_dj_switch", + track_sensitive=false, + transitions=[transition, transition], + [({!master_dj_enabled},master_dj), ({true}, s)]) + elsif dj_harbor_input_port != 0 and dj_harbor_input_mount_point != "" then - dj_live = mksafe(audio_to_stereo(input.harbor(id="live_dj_harbor", dj_harbor_input_mount_point, port=dj_harbor_input_port, auth=check_dj_client, - max=40., on_connect=live_dj_connect, on_disconnect=live_dj_disconnect))) + dj_live = mksafe( + audio_to_stereo( + input.harbor(id="live_dj_harbor", + dj_harbor_input_mount_point, + port=dj_harbor_input_port, + auth=check_dj_client, + max=40., + on_connect=live_dj_connect, + on_disconnect=live_dj_disconnect))) ignore(output.dummy(dj_live, fallible=true)) - switch(id="live_dj_switch", track_sensitive=false, transitions=[transition, transition], [({!live_dj_enabled},dj_live), ({true}, s)]) + + switch(id="live_dj_switch", + track_sensitive=false, + transitions=[transition, transition], + [({!live_dj_enabled},dj_live), ({true}, s)]) else s end From db4e6bb94afd6d362254ba570014f085c7ec3589 Mon Sep 17 00:00:00 2001 From: drigato Date: Tue, 29 Jan 2013 10:29:29 -0500 Subject: [PATCH 24/37] CC-4889: API client URL request is not wrapping in try/catch -fixed --- python_apps/api_clients/api_client.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/python_apps/api_clients/api_client.py b/python_apps/api_clients/api_client.py index 517870e45..b28a4ca5a 100644 --- a/python_apps/api_clients/api_client.py +++ b/python_apps/api_clients/api_client.py @@ -73,17 +73,26 @@ class ApcUrl(object): else: return self.base_url class ApiRequest(object): - def __init__(self, name, url): + def __init__(self, name, url, logger=None): self.name = name self.url = url self.__req = None + if logger is None: self.logger = logging + else: self.logger = logger def __call__(self,_post_data=None, **kwargs): # TODO : get rid of god damn urllib and replace everything with # grequests or requests at least final_url = self.url.params(**kwargs).url() if _post_data is not None: _post_data = urllib.urlencode(_post_data) - req = urllib2.Request(final_url, _post_data) - response = urllib2.urlopen(req).read() + try: + req = urllib2.Request(final_url, _post_data) + response = urllib2.urlopen(req).read() + except Exception, e: + self.logger.error('Exception: %s', e) + import traceback + top = traceback.format_exc() + self.logger.error("traceback: %s", top) + response = "" # Ghetto hack for now because we don't the content type we are getting # (Pointless to look at mime since it's not being set correctly always) try: return json.loads(response) From 28c01760dde01dabd84d079d6675fd46f3fd8dcf Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Tue, 29 Jan 2013 12:17:05 -0500 Subject: [PATCH 25/37] be more gentle to Liquidsoap when sending lots of commands --- python_apps/pypo/pypofetch.py | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/python_apps/pypo/pypofetch.py b/python_apps/pypo/pypofetch.py index 03c79cfc6..ea602581c 100644 --- a/python_apps/pypo/pypofetch.py +++ b/python_apps/pypo/pypofetch.py @@ -179,6 +179,25 @@ class PypoFetch(Thread): PypoFetch.telnet_send(logger, lock, [command]) + + #TODO: Merge this with switch_source + def switch_source_temp(self, sourcename, status): + self.logger.debug('Switching source: %s to "%s" status', sourcename, status) + command = "streams." + if sourcename == "master_dj": + command += "master_dj_" + elif sourcename == "live_dj": + command += "live_dj_" + elif sourcename == "scheduled_play": + command += "scheduled_play_" + + if status == "on": + command += "start\n" + else: + command += "stop\n" + + return command + """ grabs some information that are needed to be set on bootstrap time and configures them @@ -190,17 +209,14 @@ class PypoFetch(Thread): self.logger.error('Unable to get bootstrap info.. Exiting pypo...') else: self.logger.debug('info:%s', info) + commands = [] for k, v in info['switch_status'].iteritems(): - self.switch_source(self.logger, self.telnet_lock, k, v) - #self.update_liquidsoap_stream_format(info['stream_label']) - #self.update_liquidsoap_station_name(info['station_name']) - #self.update_liquidsoap_transition_fade(info['transition_fade']) + commands.append(self.switch_source_temp(k, v)) stream_format = info['stream_label'] station_name = info['station_name'] fade = info['transition_fade'] - commands = [] commands.append(('vars.stream_metadata_type %s\n' % stream_format).encode('utf-8')) commands.append(('vars.station_name %s\n' % station_name).encode('utf-8')) commands.append(('vars.default_dj_fade %s\n' % fade).encode('utf-8')) From b15c4569ebe90949fd55da5e1a7db5eea5ce1b41 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Tue, 29 Jan 2013 15:17:29 -0500 Subject: [PATCH 26/37] CC-4894: Need to filter output for potential XSS exploits -fixed few areas --- .../application/controllers/LibraryController.php | 9 +++++++++ airtime_mvc/application/controllers/UserController.php | 2 +- airtime_mvc/application/layouts/scripts/layout.phtml | 2 +- airtime_mvc/application/models/ShowBuilder.php | 2 +- airtime_mvc/application/models/User.php | 2 ++ .../application/views/scripts/form/edit-user.phtml | 4 ++-- .../views/scripts/form/preferences_watched_dirs.phtml | 4 ++-- .../application/views/scripts/playlist/playlist.phtml | 2 +- .../public/js/airtime/preferences/streamsetting.js | 2 +- 9 files changed, 20 insertions(+), 9 deletions(-) diff --git a/airtime_mvc/application/controllers/LibraryController.php b/airtime_mvc/application/controllers/LibraryController.php index 2b38349dd..1e3ac996a 100644 --- a/airtime_mvc/application/controllers/LibraryController.php +++ b/airtime_mvc/application/controllers/LibraryController.php @@ -385,6 +385,15 @@ class LibraryController extends Zend_Controller_Action //TODO move this to the datatables row callback. foreach ($r["aaData"] as &$data) { + foreach ($data as $k => &$v) { + if ($k != "image" && $k != "checkbox") { + $v = htmlspecialchars($v); + } + } + //TODO: Replace the above foreach loop with the line below when ticket + //CC-4896 is completed. + //$data = array_map('htmlspecialchars', $data); + if ($data['ftype'] == 'audioclip') { $file = Application_Model_StoredFile::Recall($data['id']); $scid = $file->getSoundCloudId(); diff --git a/airtime_mvc/application/controllers/UserController.php b/airtime_mvc/application/controllers/UserController.php index 395156f97..3faa1477f 100644 --- a/airtime_mvc/application/controllers/UserController.php +++ b/airtime_mvc/application/controllers/UserController.php @@ -115,7 +115,7 @@ class UserController extends Zend_Controller_Action $post = $this->getRequest()->getPost(); $users = Application_Model_User::getUsersDataTablesInfo($post); - die(json_encode($users)); + $this->_helper->json->sendJson($users); } public function getUserDataAction() diff --git a/airtime_mvc/application/layouts/scripts/layout.phtml b/airtime_mvc/application/layouts/scripts/layout.phtml index 29d04c0d6..dedda7c88 100644 --- a/airtime_mvc/application/layouts/scripts/layout.phtml +++ b/airtime_mvc/application/layouts/scripts/layout.phtml @@ -24,7 +24,7 @@ diff --git a/airtime_mvc/application/models/ShowBuilder.php b/airtime_mvc/application/models/ShowBuilder.php index a1ef7c588..72a5f6ab0 100644 --- a/airtime_mvc/application/models/ShowBuilder.php +++ b/airtime_mvc/application/models/ShowBuilder.php @@ -227,7 +227,7 @@ class Application_Model_ShowBuilder $row["endDate"] = $showEndDT->format("Y-m-d"); $row["endTime"] = $showEndDT->format("H:i"); $row["duration"] = floatval($showEndDT->format("U.u")) - floatval($showStartDT->format("U.u")); - $row["title"] = $p_item["show_name"]; + $row["title"] = htmlspecialchars($p_item["show_name"]); $row["instance"] = intval($p_item["si_id"]); $row["image"] = ''; diff --git a/airtime_mvc/application/models/User.php b/airtime_mvc/application/models/User.php index 63b82820a..97c9ca3ad 100644 --- a/airtime_mvc/application/models/User.php +++ b/airtime_mvc/application/models/User.php @@ -335,6 +335,8 @@ class Application_Model_User } else { $record['delete'] = ""; } + + $record = array_map('htmlspecialchars', $record); } return $res; diff --git a/airtime_mvc/application/views/scripts/form/edit-user.phtml b/airtime_mvc/application/views/scripts/form/edit-user.phtml index cd4b70bd9..79a0081fc 100644 --- a/airtime_mvc/application/views/scripts/form/edit-user.phtml +++ b/airtime_mvc/application/views/scripts/form/edit-user.phtml @@ -1,4 +1,4 @@ -

currentUser) ?>

+

escape($this->currentUser)) ?>

@@ -160,4 +160,4 @@
-
\ No newline at end of file + diff --git a/airtime_mvc/application/views/scripts/form/preferences_watched_dirs.phtml b/airtime_mvc/application/views/scripts/form/preferences_watched_dirs.phtml index 4889892dd..ad8e77797 100644 --- a/airtime_mvc/application/views/scripts/form/preferences_watched_dirs.phtml +++ b/airtime_mvc/application/views/scripts/form/preferences_watched_dirs.phtml @@ -11,7 +11,7 @@ element->getElement('storageFolder')->hasErrors()) : ?>
    element->getElement('storageFolder')->getMessages() as $error): ?> -
  • +
  • escape($error); ?>
@@ -29,7 +29,7 @@ element->getElement('watchedFolder')->hasErrors()) : ?>
    element->getElement('watchedFolder')->getMessages() as $error): ?> -
  • +
  • escape($error); ?>
diff --git a/airtime_mvc/application/views/scripts/playlist/playlist.phtml b/airtime_mvc/application/views/scripts/playlist/playlist.phtml index f8496d926..a516f2746 100644 --- a/airtime_mvc/application/views/scripts/playlist/playlist.phtml +++ b/airtime_mvc/application/views/scripts/playlist/playlist.phtml @@ -39,7 +39,7 @@ if (isset($this->obj)) { diff --git a/airtime_mvc/public/js/airtime/preferences/streamsetting.js b/airtime_mvc/public/js/airtime/preferences/streamsetting.js index 54bb986ca..6e76b693c 100644 --- a/airtime_mvc/public/js/airtime/preferences/streamsetting.js +++ b/airtime_mvc/public/js/airtime/preferences/streamsetting.js @@ -28,7 +28,7 @@ function rebuildStreamURL(ele){ }else{ streamurl = "http://"+host+":"+port+"/" } - div.find("#stream_url").html(streamurl) + div.find("#stream_url").text(streamurl) } function restrictOggBitrate(ele, on){ var div = ele.closest("div") From 2a0cc9e45fafc44f28319f222873b546497a2942 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Wed, 30 Jan 2013 11:23:20 -0500 Subject: [PATCH 27/37] fix indentation --- python_apps/pypo/pypofetch.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/python_apps/pypo/pypofetch.py b/python_apps/pypo/pypofetch.py index 0d9884881..b026f3a22 100644 --- a/python_apps/pypo/pypofetch.py +++ b/python_apps/pypo/pypofetch.py @@ -146,20 +146,20 @@ class PypoFetch(Thread): @staticmethod def telnet_send(logger, lock, commands): - try: - lock.acquire() + try: + lock.acquire() - tn = telnetlib.Telnet(LS_HOST, LS_PORT) - for i in commands: - logger.info(i) - tn.write(i) + tn = telnetlib.Telnet(LS_HOST, LS_PORT) + for i in commands: + logger.info(i) + tn.write(i) - tn.write('exit\n') - tn.read_all() - except Exception, e: - logger.error(str(e)) - finally: - lock.release() + tn.write('exit\n') + tn.read_all() + except Exception, e: + logger.error(str(e)) + finally: + lock.release() @staticmethod From e459f739f2b189d8c08a2b6a9dc7faf3b8fb21db Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Wed, 30 Jan 2013 11:29:28 -0500 Subject: [PATCH 28/37] indentation error fix --- python_apps/pypo/pypofetch.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/python_apps/pypo/pypofetch.py b/python_apps/pypo/pypofetch.py index b026f3a22..b0cbdc69a 100644 --- a/python_apps/pypo/pypofetch.py +++ b/python_apps/pypo/pypofetch.py @@ -147,19 +147,19 @@ class PypoFetch(Thread): @staticmethod def telnet_send(logger, lock, commands): try: - lock.acquire() + lock.acquire() - tn = telnetlib.Telnet(LS_HOST, LS_PORT) - for i in commands: - logger.info(i) - tn.write(i) + tn = telnetlib.Telnet(LS_HOST, LS_PORT) + for i in commands: + logger.info(i) + tn.write(i) - tn.write('exit\n') - tn.read_all() - except Exception, e: - logger.error(str(e)) - finally: - lock.release() + tn.write('exit\n') + tn.read_all() + except Exception, e: + logger.error(str(e)) + finally: + lock.release() @staticmethod From 595429e6e514aab20ac75a714cf2891bd3c1264c Mon Sep 17 00:00:00 2001 From: denise Date: Wed, 30 Jan 2013 11:51:27 -0500 Subject: [PATCH 29/37] CC-4897: XSS exploit on library page -fixed --- airtime_mvc/application/controllers/LibraryController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airtime_mvc/application/controllers/LibraryController.php b/airtime_mvc/application/controllers/LibraryController.php index 1e3ac996a..15ae12944 100644 --- a/airtime_mvc/application/controllers/LibraryController.php +++ b/airtime_mvc/application/controllers/LibraryController.php @@ -438,7 +438,7 @@ class LibraryController extends Zend_Controller_Action $formValues = $this->_getParam('data', null); $formdata = array(); foreach ($formValues as $val) { - $formdata[$val["name"]] = $val["value"]; + $formdata[$val["name"]] = htmlspecialchars($val["value"]); } $file->setDbColMetadata($formdata); From cc5acf3c9e7786fc8fab1197c180942440d62124 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Wed, 30 Jan 2013 14:34:06 -0500 Subject: [PATCH 30/37] improved logging for boolean vars --- airtime_mvc/application/logging/Logging.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/airtime_mvc/application/logging/Logging.php b/airtime_mvc/application/logging/Logging.php index dfe7e1fbe..65a8f6dc2 100644 --- a/airtime_mvc/application/logging/Logging.php +++ b/airtime_mvc/application/logging/Logging.php @@ -32,6 +32,8 @@ class Logging { { if (is_array($p_msg) || is_object($p_msg)) { return print_r($p_msg, true); + } else if (is_bool($p_msg)) { + return $p_msg ? "true" : "false"; } else { return $p_msg; } From 52d96241daedaa98e2833686cae9f6b01046811f Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Wed, 30 Jan 2013 14:40:29 -0500 Subject: [PATCH 31/37] CC-4754: Replay gain modifier -fix regression --- airtime_mvc/application/controllers/PreferenceController.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/airtime_mvc/application/controllers/PreferenceController.php b/airtime_mvc/application/controllers/PreferenceController.php index 00b0fa6ca..e68e6c603 100644 --- a/airtime_mvc/application/controllers/PreferenceController.php +++ b/airtime_mvc/application/controllers/PreferenceController.php @@ -273,7 +273,8 @@ class PreferenceController extends Zend_Controller_Action Application_Model_Preference::SetEnableReplayGain($values["enableReplayGain"]); Application_Model_Preference::setReplayGainModifier($values["replayGainModifier"]); $md = array('schedule' => Application_Model_Schedule::getSchedule()); - Application_Model_RabbitMq::PushSchedule(); + Application_Model_RabbitMq::SendMessageToPypo("update_schedule", $md); + //Application_Model_RabbitMq::PushSchedule(); } if (!Application_Model_Preference::GetMasterDjConnectionUrlOverride()) { From 3553ebc2ee3bde9cd7c8352f322b7848d31e65c0 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Wed, 30 Jan 2013 18:21:46 -0500 Subject: [PATCH 32/37] fix upgrade script so that cue out of files is not 00:00:00 by default --- install_minimal/upgrades/airtime-2.3.0/data/upgrade.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install_minimal/upgrades/airtime-2.3.0/data/upgrade.sql b/install_minimal/upgrades/airtime-2.3.0/data/upgrade.sql index c2d176b23..cd34a28bb 100644 --- a/install_minimal/upgrades/airtime-2.3.0/data/upgrade.sql +++ b/install_minimal/upgrades/airtime-2.3.0/data/upgrade.sql @@ -15,6 +15,8 @@ INSERT INTO cc_stream_setting ("keyname", "value", "type") VALUES ('s3_admin_pas UPDATE cc_music_dirs SET directory = directory || '/' where id in (select id from cc_music_dirs where substr(directory, length(directory)) != '/'); UPDATE cc_files SET filepath = substring(filepath from 2) where id in (select id from cc_files where substring(filepath from 1 for 1) = '/'); +UPDATE cc_files SET cueout = length where cueout = '00:00:00'; + INSERT INTO cc_pref("keystr", "valstr") VALUES('locale', 'en_CA'); INSERT INTO cc_pref("subjid", "keystr", "valstr") VALUES(1, 'user_locale', 'en_CA'); From 617e1049aab8a763fbbfda4355bc05353015f164 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Wed, 30 Jan 2013 23:31:24 -0500 Subject: [PATCH 33/37] fix changelog mistakes --- changelog | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/changelog b/changelog index 9aa22c634..aff42ec52 100644 --- a/changelog +++ b/changelog @@ -1,6 +1,7 @@ 2.3.0 - Jan 21st, 2013 * New features - * Localization (Brazilian, Chinese, Czech, English, French, German, Italian, Korean, Portugese, Russian, Spanish) + * Localization (Chinese, Czech, English, French, German, Italian, Korean, + Portuguese, Russian, Spanish) * User management page for non-admin users * Listener statistics (Icecast/Shoutcast) * Airtime no longer requires Apache document root From 8adb4b259c031ff7107a8b30ec20e8dec185fe2c Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Thu, 31 Jan 2013 12:33:14 -0500 Subject: [PATCH 34/37] CC-4905: Unit tests for Pypo --- python_apps/pypo/pypocli.py | 2 +- python_apps/pypo/pypofetch.py | 3 +- python_apps/pypo/pypopush.py | 20 ++++++++++++-- python_apps/pypo/tests/run_tests.sh | 18 ++++++++++++ python_apps/pypo/tests/test_modify_cue_in.py | 29 ++++++++++++++++++++ 5 files changed, 67 insertions(+), 5 deletions(-) create mode 100755 python_apps/pypo/tests/run_tests.sh create mode 100644 python_apps/pypo/tests/test_modify_cue_in.py diff --git a/python_apps/pypo/pypocli.py b/python_apps/pypo/pypocli.py index ea8950d41..93a1718aa 100644 --- a/python_apps/pypo/pypocli.py +++ b/python_apps/pypo/pypocli.py @@ -176,7 +176,7 @@ if __name__ == '__main__': sys.exit() api_client = api_client.AirtimeApiClient() - + ReplayGainUpdater.start_reply_gain(api_client) api_client.register_component("pypo") diff --git a/python_apps/pypo/pypofetch.py b/python_apps/pypo/pypofetch.py index b0cbdc69a..e073efda9 100644 --- a/python_apps/pypo/pypofetch.py +++ b/python_apps/pypo/pypofetch.py @@ -18,7 +18,8 @@ from std_err_override import LogWriter from configobj import ConfigObj # configure logging -logging.config.fileConfig("logging.cfg") +logging_cfg = os.path.join(os.path.dirname(__file__), "logging.cfg") +logging.config.fileConfig(logging_cfg) logger = logging.getLogger() LogWriter.override_std_err(logger) diff --git a/python_apps/pypo/pypopush.py b/python_apps/pypo/pypopush.py index 6fedfab1b..f438b3bb1 100644 --- a/python_apps/pypo/pypopush.py +++ b/python_apps/pypo/pypopush.py @@ -9,6 +9,7 @@ import logging.config import telnetlib import calendar import math +import os from pypofetch import PypoFetch from Queue import Empty @@ -21,7 +22,8 @@ from configobj import ConfigObj # configure logging -logging.config.fileConfig("logging.cfg") +logging_cfg = os.path.join(os.path.dirname(__file__), "logging.cfg") +logging.config.fileConfig(logging_cfg) logger = logging.getLogger() LogWriter.override_std_err(logger) @@ -249,7 +251,7 @@ class PypoPush(Thread): self.start_web_stream_buffer(current_item) self.start_web_stream(current_item) if is_file(current_item): - self.modify_cue_point(file_chain[0]) + file_chain = self.modify_first_link_cue_point(file_chain) self.push_to_liquidsoap(file_chain) #we've changed the queue, so let's refetch it liquidsoap_queue_approx = self.get_queue_items_from_liquidsoap() @@ -279,7 +281,7 @@ class PypoPush(Thread): chain_to_push = file_chain[problem_at_iteration:] if len(chain_to_push) > 0: - self.modify_cue_point(chain_to_push[0]) + chain_to_push = self.modify_first_link_cue_point(chain_to_push) self.push_to_liquidsoap(chain_to_push) @@ -363,6 +365,18 @@ class PypoPush(Thread): original_cue_in_td = timedelta(seconds=float(link['cue_in'])) link['cue_in'] = self.date_interval_to_seconds(original_cue_in_td) + diff_sec + def modify_first_link_cue_point(self, chain): + if not len(chain): + return [] + + first_link = chain[0] + + self.modify_cue_point(first_link) + if float(first_link['cue_in']) >= float(first_link['cue_out']): + chain = chain [1:] + + return chain + """ Returns two chains, original chain and current_chain. current_chain is a subset of original_chain but can also be equal to original chain. diff --git a/python_apps/pypo/tests/run_tests.sh b/python_apps/pypo/tests/run_tests.sh new file mode 100755 index 000000000..830a9bb85 --- /dev/null +++ b/python_apps/pypo/tests/run_tests.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +which py.test +pytest_exist=$? + +if [ "$pytest_exist" != "0" ]; then + echo "Need to have py.test installed. Exiting..." + exit 1 +fi + +SCRIPT=`readlink -f $0` +# Absolute directory this script is in +SCRIPTPATH=`dirname $SCRIPT` + +export PYTHONPATH=$PYTHONPATH:$SCRIPTPATH/..:$SCRIPTPATH/../.. + +py.test + diff --git a/python_apps/pypo/tests/test_modify_cue_in.py b/python_apps/pypo/tests/test_modify_cue_in.py new file mode 100644 index 000000000..d5049bde5 --- /dev/null +++ b/python_apps/pypo/tests/test_modify_cue_in.py @@ -0,0 +1,29 @@ +from pypopush import PypoPush +from threading import Lock +from Queue import Queue + +import datetime + +pypoPush_q = Queue() +telnet_lock = Lock() + +pp = PypoPush(pypoPush_q, telnet_lock) + +def test_modify_cue_in(): + + link = pp.modify_first_link_cue_point([]) + assert len(link) == 0 + + min_ago = datetime.datetime.utcnow() - datetime.timedelta(minutes = 1) + link = [{"start":min_ago.strftime("%Y-%m-%d-%H-%M-%S"), + "cue_in":"0", "cue_out":"30"}] + link = pp.modify_first_link_cue_point(link) + assert len(link) == 0 + + link = [{"start":min_ago.strftime("%Y-%m-%d-%H-%M-%S"), + "cue_in":"0", "cue_out":"70"}] + link = pp.modify_first_link_cue_point(link) + assert len(link) == 1 + + + From f145ede01b99823a96554cad3b5e58bd186315c5 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Thu, 31 Jan 2013 17:45:57 -0500 Subject: [PATCH 35/37] CC-4905: Unit tests for Pypo -whitespace removal --- python_apps/pypo/tests/test_modify_cue_in.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/python_apps/pypo/tests/test_modify_cue_in.py b/python_apps/pypo/tests/test_modify_cue_in.py index d5049bde5..da17fd53f 100644 --- a/python_apps/pypo/tests/test_modify_cue_in.py +++ b/python_apps/pypo/tests/test_modify_cue_in.py @@ -10,7 +10,6 @@ telnet_lock = Lock() pp = PypoPush(pypoPush_q, telnet_lock) def test_modify_cue_in(): - link = pp.modify_first_link_cue_point([]) assert len(link) == 0 @@ -25,5 +24,3 @@ def test_modify_cue_in(): link = pp.modify_first_link_cue_point(link) assert len(link) == 1 - - From 149b744ba7d775b447f0d4bbf6bea84d422792cc Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Fri, 1 Feb 2013 01:40:48 -0500 Subject: [PATCH 36/37] remove using self in a static method --- python_apps/pypo/pypofetch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python_apps/pypo/pypofetch.py b/python_apps/pypo/pypofetch.py index e073efda9..2d6ad0fb5 100644 --- a/python_apps/pypo/pypofetch.py +++ b/python_apps/pypo/pypofetch.py @@ -136,7 +136,7 @@ class PypoFetch(Thread): try: lock.acquire() tn = telnetlib.Telnet(LS_HOST, LS_PORT) - self.logger.info(command) + logger.info(command) tn.write(command) tn.write('exit\n') tn.read_all() From 1f4cfa8f65c2a0651a555eae31028d80bc8da162 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Sat, 2 Feb 2013 08:50:44 -0500 Subject: [PATCH 37/37] fix pypo not auto restarting --- python_apps/pypo/monit-airtime-playout.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python_apps/pypo/monit-airtime-playout.cfg b/python_apps/pypo/monit-airtime-playout.cfg index 5b096c72a..453f4efec 100644 --- a/python_apps/pypo/monit-airtime-playout.cfg +++ b/python_apps/pypo/monit-airtime-playout.cfg @@ -5,5 +5,5 @@ check process airtime-playout with pidfile "/var/run/airtime-playout.pid" - start program = "/etc/init.d/airtime-playout monit-restart" with timeout 5 seconds + start program = "/etc/init.d/airtime-playout start" with timeout 5 seconds stop program = "/etc/init.d/airtime-playout stop"