diff --git a/airtime_mvc/application/controllers/ScheduleController.php b/airtime_mvc/application/controllers/ScheduleController.php index 953cfee52..970c9fc1d 100644 --- a/airtime_mvc/application/controllers/ScheduleController.php +++ b/airtime_mvc/application/controllers/ScheduleController.php @@ -176,15 +176,18 @@ class ScheduleController extends Zend_Controller_Action public function makeContextMenuAction() { $id = $this->_getParam('id'); - $today_timestamp = date("Y-m-d H:i:s"); + $epochNow = time(); $userInfo = Zend_Auth::getInstance()->getStorage()->read(); $user = new User($userInfo->id); $show = new ShowInstance($id); $params = '/format/json/id/#id#'; - - if (strtotime($today_timestamp) < strtotime($show->getShowStart())) { + + $showStartDateHelper = DateHelper::ConvertToLocalDateTime($show->getShowStart()); + $showEndDateHelper = DateHelper::ConvertToLocalDateTime($show->getShowEnd()); + + if ($epochNow < $showStartDateHelper->getTimestamp()) { if ($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER, UTYPE_HOST),$show->getShowId()) && !$show->isRecorded() && !$show->isRebroadcast()) { @@ -202,7 +205,7 @@ class ScheduleController extends Zend_Controller_Action 'callback' => 'window["buildContentDialog"]'), 'title' => 'Show Content'); } - if (strtotime($show->getShowEnd()) <= strtotime($today_timestamp) + if ($showEndDateHelper->getTimestamp() <= $epochNow && is_null($show->getSoundCloudFileId()) && $show->isRecorded() && Application_Model_Preference::GetDoSoundCloudUpload()) { @@ -212,15 +215,15 @@ class ScheduleController extends Zend_Controller_Action } - if (strtotime($show->getShowStart()) <= strtotime($today_timestamp) && - strtotime($today_timestamp) < strtotime($show->getShowEnd()) && + if ($showStartDateHelper->getTimestamp() <= $epochNow && + $epochNow < $showEndDateHelper->getTimestamp() && $user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) { $menu[] = array('action' => array('type' => 'fn', 'callback' => "window['confirmCancelShow']($id)"), 'title' => 'Cancel Current Show'); } - if (strtotime($today_timestamp) < strtotime($show->getShowStart())) { + if ($epochNow < $showStartDateHelper->getTimestamp()) { if ($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) { @@ -425,11 +428,17 @@ class ScheduleController extends Zend_Controller_Action 'add_show_url' => $show->getUrl(), 'add_show_genre' => $show->getGenre(), 'add_show_description' => $show->getDescription())); + + $startsDateTime = new DateTime($showInstance->getShowStart(), new DateTimeZone("UTC")); + $endsDateTime = new DateTime($showInstance->getShowEnd(), new DateTimeZone("UTC")); + + $startsDateTime->setTimezone(new DateTimeZone(date_default_timezone_get())); + $endsDateTime->setTimezone(new DateTimeZone(date_default_timezone_get())); - $formWhen->populate(array('add_show_start_date' => $show->getStartDate(), - 'add_show_start_time' => DateHelper::removeSecondsFromTime($show->getStartTime()), - 'add_show_end_date_no_repeat' => $show->getEndDate(), - 'add_show_end_time' => DateHelper::removeSecondsFromTime($show->getEndTime()), + $formWhen->populate(array('add_show_start_date' => $startsDateTime->format("Y-m-d"), + 'add_show_start_time' => $startsDateTime->format("H:i"), + 'add_show_end_date_no_repeat' => $endsDateTime->format("Y-m-d"), + 'add_show_end_time' => $endsDateTime->format("H:i"), 'add_show_duration' => $show->getDuration(true), 'add_show_repeats' => $show->isRepeating() ? 1 : 0)); @@ -443,13 +452,13 @@ class ScheduleController extends Zend_Controller_Action array_push($days, $showDay->getDbDay()); } - $displayedEndDate = new DateTime($show->getRepeatingEndDate()); + $displayedEndDate = new DateTime($show->getRepeatingEndDate(), new DateTimeZone("UTC")); $displayedEndDate->sub(new DateInterval("P1D"));//end dates are stored non-inclusively. - $displayedEndDate = $displayedEndDate->format("Y-m-d"); + $displayedEndDate->setTimezone(new DateTimeZone(date_default_timezone_get())); $formRepeats->populate(array('add_show_repeat_type' => $show->getRepeatType(), 'add_show_day_check' => $days, - 'add_show_end_date' => $displayedEndDate, + 'add_show_end_date' => $displayedEndDate->format("Y-m-d"), 'add_show_no_end' => ($show->getRepeatingEndDate() == ''))); $formRecord->populate(array('add_show_record' => $show->isRecorded(), diff --git a/airtime_mvc/application/forms/AddShowWhen.php b/airtime_mvc/application/forms/AddShowWhen.php index e843727a3..3ed5d35b0 100644 --- a/airtime_mvc/application/forms/AddShowWhen.php +++ b/airtime_mvc/application/forms/AddShowWhen.php @@ -88,18 +88,16 @@ class Application_Form_AddShowWhen extends Zend_Form_SubForm } public function checkReliantFields($formData, $startDateModified) { - $valid = true; - $now_timestamp = date("Y-m-d H:i:s"); - $start_timestamp = $formData['add_show_start_date']." ".$formData['add_show_start_time']; - - $now_epoch = strtotime($now_timestamp); - $start_epoch = strtotime($start_timestamp); - + $start_time = $formData['add_show_start_date']." ".$formData['add_show_start_time']; + + //DateTime stores $start_time in the current timezone + $nowDateTime = new DateTime(); + $showStartDateTime = new DateTime($start_time); if ((($formData['add_show_id'] != -1) && $startDateModified) || ($formData['add_show_id'] == -1)){ - if($start_epoch < $now_epoch) { + if($showStartDateTime->getTimestamp() < $nowDateTime->getTimestamp()) { $this->getElement('add_show_start_time')->setErrors(array('Cannot create show in the past')); $valid = false; } @@ -118,6 +116,5 @@ class Application_Form_AddShowWhen extends Zend_Form_SubForm return $valid; } - } diff --git a/airtime_mvc/application/forms/GeneralPreferences.php b/airtime_mvc/application/forms/GeneralPreferences.php index a2807c716..0190f63a1 100644 --- a/airtime_mvc/application/forms/GeneralPreferences.php +++ b/airtime_mvc/application/forms/GeneralPreferences.php @@ -13,9 +13,7 @@ class Application_Form_GeneralPreferences extends Zend_Form_SubForm $this->addElement('text', 'stationName', array( 'class' => 'input_text', 'label' => 'Station Name', - 'required' => true, 'filters' => array('StringTrim'), - 'validators' => array('NotEmpty'), 'value' => Application_Model_Preference::GetValue("station_name"), 'decorators' => array( 'ViewHelper' diff --git a/airtime_mvc/application/logging/Logging.php b/airtime_mvc/application/logging/Logging.php index 096dbd717..01ec88240 100644 --- a/airtime_mvc/application/logging/Logging.php +++ b/airtime_mvc/application/logging/Logging.php @@ -16,4 +16,9 @@ class Logging { public static function setLogPath($path){ self::$_path = $path; } + + public static function log($p_msg){ + $logger = self::getLogger(); + $logger->info($p_msg); + } } diff --git a/airtime_mvc/application/models/DateHelper.php b/airtime_mvc/application/models/DateHelper.php index bc7b21a86..41068f319 100644 --- a/airtime_mvc/application/models/DateHelper.php +++ b/airtime_mvc/application/models/DateHelper.php @@ -2,11 +2,11 @@ class DateHelper { - private $_timestamp; + private $_dateTime; function __construct() { - $this->_timestamp = date("U"); + $this->_dateTime = date("U"); } /** @@ -15,7 +15,19 @@ class DateHelper */ function getTimestamp() { - return date("Y-m-d H:i:s", $this->_timestamp); + return date("Y-m-d H:i:s", $this->_dateTime); + } + + /** + * Get time of object construction in the format + * YYYY-MM-DD HH:mm:ss + */ + function getUtcTimestamp() + { + $dateTime = new DateTime("@".$this->_dateTime); + $dateTime->setTimezone(new DateTimeZone("UTC")); + + return $dateTime->format("Y-m-d H:i:s"); } /** @@ -24,7 +36,7 @@ class DateHelper */ function getDate() { - return date("Y-m-d", $this->_timestamp); + return date("Y-m-d", $this->_dateTime); } /** @@ -33,7 +45,7 @@ class DateHelper */ function getTime() { - return date("H:i:s", $this->_timestamp); + return date("H:i:s", $this->_dateTime); } /** @@ -41,28 +53,30 @@ class DateHelper */ function setDate($dateString) { - $this->_timestamp = strtotime($dateString); + $this->_dateTime = strtotime($dateString); } /** - * - * Enter description here ... + * Find the epoch timestamp difference from "now" to the beginning of today. */ function getNowDayStartDiff() { - $dayStartTS = strtotime(date("Y-m-d", $this->_timestamp)); - return $this->_timestamp - $dayStartTS; + $dayStartTs = ((int)($this->_dateTime/86400))*86400; + return $this->_dateTime - $dayStartTs; } + /** + * Find the epoch timestamp difference from "now" to the end of today. + */ function getNowDayEndDiff() { - $dayEndTS = strtotime(date("Y-m-d", $this->_timestamp+(86400))); - return $dayEndTS - $this->_timestamp; + $dayEndTs = ((int)(($this->_dateTime+86400)/86400))*86400; + return $dayEndTs - $this->_dateTime; } function getEpochTime() { - return $this->_timestamp; + return $this->_dateTime; } public static function TimeDiff($time1, $time2) @@ -100,31 +114,31 @@ class DateHelper * format "hh:mm:ss". But when dealing with show times, we * do not care about the seconds. * - * @param int $p_timestamp + * @param int $p_dateTime * The value which to format. * @return int * The timestamp with the new format "hh:mm", or * the original input parameter, if it does not have * the correct format. */ - public static function removeSecondsFromTime($p_timestamp) + public static function removeSecondsFromTime($p_dateTime) { //Format is in hh:mm:ss. We want hh:mm - $timeExplode = explode(":", $p_timestamp); + $timeExplode = explode(":", $p_dateTime); if (count($timeExplode) == 3) return $timeExplode[0].":".$timeExplode[1]; else - return $p_timestamp; + return $p_dateTime; } - public static function getDateFromTimestamp($p_timestamp){ - $explode = explode(" ", $p_timestamp); + public static function getDateFromTimestamp($p_dateTime){ + $explode = explode(" ", $p_dateTime); return $explode[0]; } - public static function getTimeFromTimestamp($p_timestamp){ - $explode = explode(" ", $p_timestamp); + public static function getTimeFromTimestamp($p_dateTime){ + $explode = explode(" ", $p_dateTime); return $explode[1]; } @@ -157,5 +171,19 @@ class DateHelper return $totalSeconds; } + + public static function ConvertToLocalDateTime($p_dateString){ + $dateTime = new DateTime($p_dateString, new DateTimeZone("UTC")); + $dateTime->setTimezone(new DateTimeZone(date_default_timezone_get())); + + return $dateTime; + } + + public static function ConvertToLocalDateTimeString($p_dateString, $format="Y-m-d H:i:s"){ + $dateTime = new DateTime($p_dateString, new DateTimeZone("UTC")); + $dateTime->setTimezone(new DateTimeZone(date_default_timezone_get())); + + return $dateTime->format($format); + } } diff --git a/airtime_mvc/application/models/Nowplaying.php b/airtime_mvc/application/models/Nowplaying.php index eea8bbbb9..61fd9554c 100644 --- a/airtime_mvc/application/models/Nowplaying.php +++ b/airtime_mvc/application/models/Nowplaying.php @@ -3,21 +3,31 @@ class Application_Model_Nowplaying { - public static function CreateHeaderRow($p_showName, $p_showStart, $p_showEnd){ + private static function CreateHeaderRow($p_showName, $p_showStart, $p_showEnd){ return array("h", "", $p_showStart, $p_showEnd, $p_showName, "", "", "", "", "", ""); } - public static function CreateDatatableRows($p_dbRows){ + private static function CreateDatatableRows($p_dbRows){ $dataTablesRows = array(); - $date = new DateHelper; - $timeNow = $date->getTimestamp(); + $epochNow = time(); foreach ($p_dbRows as $dbRow){ + + $showStartDateTime = DateHelper::ConvertToLocalDateTime($dbRow['show_starts']); + $showEndDateTime = DateHelper::ConvertToLocalDateTime($dbRow['show_ends']); + $itemStartDateTime = DateHelper::ConvertToLocalDateTime($dbRow['item_starts']); + $itemEndDateTime = DateHelper::ConvertToLocalDateTime($dbRow['item_ends']); + + $showStarts = $showStartDateTime->format("Y-m-d H:i:s"); + $showEnds = $showEndDateTime->format("Y-m-d H:i:s"); + $itemStarts = $itemStartDateTime->format("Y-m-d H:i:s"); + $itemEnds = $itemEndDateTime->format("Y-m-d H:i:s"); + $status = ($dbRow['show_ends'] < $dbRow['item_ends']) ? "x" : ""; $type = "a"; - $type .= ($dbRow['item_ends'] > $timeNow && $dbRow['item_starts'] <= $timeNow) ? "c" : ""; + $type .= ($itemEndDateTime->getTimestamp() > $epochNow && $itemStartDateTime->getTimestamp() <= $epochNow) ? "c" : ""; // remove millisecond from the time format $itemStart = explode('.', $dbRow['item_starts']); @@ -25,36 +35,36 @@ class Application_Model_Nowplaying //format duration $duration = explode('.', $dbRow['clip_length']); - $formated = Application_Model_Nowplaying::FormatDuration($duration[0]); - $dataTablesRows[] = array($type, $dbRow['show_starts'], $itemStart[0], $itemEnd[0], - $formated, $dbRow['track_title'], $dbRow['artist_name'], $dbRow['album_title'], + $formatted = self::FormatDuration($duration[0]); + $dataTablesRows[] = array($type, $showStarts, $itemStarts, $itemEnds, + $formatted, $dbRow['track_title'], $dbRow['artist_name'], $dbRow['album_title'], $dbRow['playlist_name'], $dbRow['show_name'], $status); } return $dataTablesRows; } - public static function CreateGapRow($p_gapTime){ + private static function CreateGapRow($p_gapTime){ return array("g", "", "", "", $p_gapTime, "", "", "", "", "", ""); } - public static function CreateRecordingRow($p_showInstance){ + private static function CreateRecordingRow($p_showInstance){ return array("r", "", "", "", $p_showInstance->getName(), "", "", "", "", "", ""); } public static function GetDataGridData($viewType, $dateString){ if ($viewType == "now"){ - $date = new DateHelper; - $timeNow = $date->getTimestamp(); - + $dateTime = new DateTime("now", new DateTimeZone("UTC")); + $timeNow = $dateTime->format("Y-m-d H:i:s"); + $startCutoff = 60; $endCutoff = 86400; //60*60*24 - seconds in a day } else { $date = new DateHelper; $time = $date->getTime(); $date->setDate($dateString." ".$time); - $timeNow = $date->getTimestamp(); + $timeNow = $date->getUtcTimestamp(); $startCutoff = $date->getNowDayStartDiff(); $endCutoff = $date->getNowDayEndDiff(); @@ -71,21 +81,24 @@ class Application_Model_Nowplaying $showId = $si->getShowId(); $show = new Show($showId); + $showStartDateTime = DateHelper::ConvertToLocalDateTime($si->getShowStart()); + $showEndDateTime = DateHelper::ConvertToLocalDateTime($si->getShowEnd()); + //append show header row - $data[] = Application_Model_Nowplaying::CreateHeaderRow($show->getName(), $si->getShowStart(), $si->getShowEnd()); + $data[] = self::CreateHeaderRow($show->getName(), $showStartDateTime->format("Y-m-d H:i:s"), $showEndDateTime->format("Y-m-d H:i:s")); $scheduledItems = $si->getScheduleItemsInRange($timeNow, $startCutoff, $endCutoff); - $dataTablesRows = Application_Model_Nowplaying::CreateDatatableRows($scheduledItems); + $dataTablesRows = self::CreateDatatableRows($scheduledItems); //append show audio item rows $data = array_merge($data, $dataTablesRows); //append show gap time row - $gapTime = Application_Model_Nowplaying::FormatDuration($si->getShowEndGapTime(), true); + $gapTime = self::FormatDuration($si->getShowEndGapTime(), true); if ($si->isRecorded()) - $data[] = Application_Model_Nowplaying::CreateRecordingRow($si); + $data[] = self::CreateRecordingRow($si); else if ($gapTime > 0) - $data[] = Application_Model_Nowplaying::CreateGapRow($gapTime); + $data[] = self::CreateGapRow($gapTime); } return array("currentShow"=>Show_DAL::GetCurrentShow($timeNow), "rows"=>$data); @@ -102,7 +115,7 @@ class Application_Model_Nowplaying * default $time format should be in format of 00:00:00 * if $inSecond = true, then $time should be in seconds */ - public static function FormatDuration($time, $inSecond=false){ + private static function FormatDuration($time, $inSecond=false){ if($inSecond == false){ $duration = explode(':', $time); }else{ diff --git a/airtime_mvc/application/models/Preference.php b/airtime_mvc/application/models/Preference.php index 8cf1be22f..4be4882f5 100644 --- a/airtime_mvc/application/models/Preference.php +++ b/airtime_mvc/application/models/Preference.php @@ -264,7 +264,6 @@ class Application_Model_Preference Application_Model_Preference::SetValue("timezone", $timezone); date_default_timezone_set($timezone); $md = array("timezone" => $timezone); - RabbitMq::SendMessageToPypo("update_timezone", $md); } public static function GetTimezone(){ diff --git a/airtime_mvc/application/models/RabbitMq.php b/airtime_mvc/application/models/RabbitMq.php index 2e7167f32..9cb3cb166 100644 --- a/airtime_mvc/application/models/RabbitMq.php +++ b/airtime_mvc/application/models/RabbitMq.php @@ -108,13 +108,12 @@ class RabbitMq $EXCHANGE = 'airtime-show-recorder'; $channel->exchange_declare($EXCHANGE, 'direct', false, true); - $today_timestamp = date("Y-m-d H:i:s"); - $now = new DateTime($today_timestamp); - $end_timestamp = $now->add(new DateInterval("PT2H")); - $end_timestamp = $end_timestamp->format("Y-m-d H:i:s"); + $now = new DateTime("@".time()); + $end_timestamp = new DateTime("@".time() + 3600*2); + $temp['event_type'] = $event_type; if($event_type = "update_schedule"){ - $temp['shows'] = Show::getShows($today_timestamp, $end_timestamp, $excludeInstance=NULL, $onlyRecord=TRUE); + $temp['shows'] = Show::getShows($now->format("Y-m-d H:i:s"), $end_timestamp->format("Y-m-d H:i:s"), $excludeInstance=NULL, $onlyRecord=TRUE); } $data = json_encode($temp); $msg = new AMQPMessage($data, array('content_type' => 'text/plain')); diff --git a/airtime_mvc/application/models/Schedule.php b/airtime_mvc/application/models/Schedule.php index 33abd6d93..46bcdc7ec 100644 --- a/airtime_mvc/application/models/Schedule.php +++ b/airtime_mvc/application/models/Schedule.php @@ -364,12 +364,9 @@ class Schedule { global $CC_CONFIG; $date = new DateHelper; - $timeNow = $date->getTimestamp(); + $timeNow = $date->getUtcTimestamp(); return array("env"=>APPLICATION_ENV, - "schedulerTime"=>gmdate("Y-m-d H:i:s"), - //"previous"=>Schedule::GetScheduledItemData($timeNow, -1, $prev, "24 hours"), - //"current"=>Schedule::GetScheduledItemData($timeNow, 0), - //"next"=>Schedule::GetScheduledItemData($timeNow, 1, $next, "48 hours"), + "schedulerTime"=>$timeNow, "previous"=>Application_Model_Dashboard::GetPreviousItem($timeNow), "current"=>Application_Model_Dashboard::GetCurrentItem($timeNow), "next"=>Application_Model_Dashboard::GetNextItem($timeNow), @@ -660,13 +657,13 @@ class Schedule { global $CC_CONFIG, $CC_DBC; if (is_null($p_fromDateTime)) { - $t1 = new DateTime(); + $t1 = new DateTime("now", new DateTimeZone("UTC")); $range_start = $t1->format("Y-m-d H:i:s"); } else { $range_start = Schedule::PypoTimeToAirtimeTime($p_fromDateTime); } if (is_null($p_fromDateTime)) { - $t2 = new DateTime(); + $t2 = new DateTime("now", new DateTimeZone("UTC")); $t2->add(new DateInterval("PT24H")); $range_end = $t2->format("Y-m-d H:i:s"); } else { @@ -740,7 +737,6 @@ class Schedule { $result['stream_metadata'] = array(); $result['stream_metadata']['format'] = Application_Model_Preference::GetStreamLabelFormat(); $result['stream_metadata']['station_name'] = Application_Model_Preference::GetStationName(); - $result['server_timezone'] = date('O'); return $result; } diff --git a/airtime_mvc/application/models/Shows.php b/airtime_mvc/application/models/Shows.php index 1311b837a..b5895d111 100644 --- a/airtime_mvc/application/models/Shows.php +++ b/airtime_mvc/application/models/Shows.php @@ -724,27 +724,26 @@ class Show { */ public static function create($data) { - $con = Propel::getConnection(CcShowPeer::DATABASE_NAME); - - $sql = "SELECT EXTRACT(DOW FROM TIMESTAMP '{$data['add_show_start_date']} {$data['add_show_start_time']}')"; - $r = $con->query($sql); - $startDow = $r->fetchColumn(0); - + + $utcStartDateTime = new DateTime($data['add_show_start_date']." ".$data['add_show_start_time']); + $utcStartDateTime->setTimezone(new DateTimeZone('UTC')); + if ($data['add_show_no_end']) { - $endDate = NULL; + $endDateTime = NULL; } else if ($data['add_show_repeats']) { - $sql = "SELECT date '{$data['add_show_end_date']}' + INTERVAL '1 day' "; - $r = $con->query($sql); - $endDate = $r->fetchColumn(0); + $endDateTime = new DateTime($data['add_show_end_date']); + $endDateTime->setTimezone(new DateTimeZone('UTC')); + $endDateTime->add(new DateInterval("P1D")); } else { - $sql = "SELECT date '{$data['add_show_start_date']}' + INTERVAL '1 day' "; - $r = $con->query($sql); - $endDate = $r->fetchColumn(0); + $endDateTime = new DateTime($data['add_show_start_date']); + $endDateTime->setTimezone(new DateTimeZone('UTC')); + $endDateTime->add(new DateInterval("P1D")); } //only want the day of the week from the start date. + $startDow = date("w", $utcStartDateTime->getTimestamp()); if (!$data['add_show_repeats']) { $data['add_show_day_check'] = array($startDow); } else if ($data['add_show_repeats'] && $data['add_show_day_check'] == "") { @@ -768,12 +767,12 @@ class Show { $ccShow->save(); $showId = $ccShow->getDbId(); - $show = new Show($showId); $isRecorded = ($data['add_show_record']) ? 1 : 0; if ($data['add_show_id'] != -1){ - $show->deletePossiblyInvalidInstances($data, $endDate, $isRecorded, $repeatType); + $show = new Show($showId); + $show->deletePossiblyInvalidInstances($data, $endDateTime->format("Y-m-d"), $isRecorded, $repeatType); } //check if we are adding or updating a show, and if updating @@ -785,37 +784,30 @@ class Show { //don't set day for monthly repeat type, it's invalid. if ($data['add_show_repeats'] && $data['add_show_repeat_type'] == 2){ $showDay = new CcShowDays(); - $showDay->setDbFirstShow($data['add_show_start_date']); - $showDay->setDbLastShow($endDate); - $showDay->setDbStartTime($data['add_show_start_time']); + $showDay->setDbFirstShow($utcStartDateTime->format("Y-m-d")); + $showDay->setDbLastShow($endDateTime->format("Y-m-d")); + $showDay->setDbStartTime($utcStartDateTime->format("H:i:s")); $showDay->setDbDuration($data['add_show_duration']); $showDay->setDbRepeatType($repeatType); $showDay->setDbShowId($showId); $showDay->setDbRecord($isRecorded); $showDay->save(); - } - else { + } else { foreach ($data['add_show_day_check'] as $day) { if ($startDow !== $day){ - if ($startDow > $day) $daysAdd = 6 - $startDow + 1 + $day; else $daysAdd = $day - $startDow; - - $sql = "SELECT date '{$data['add_show_start_date']}' + INTERVAL '{$daysAdd} day' "; - $r = $con->query($sql); - $start = $r->fetchColumn(0); - } - else { - $start = $data['add_show_start_date']; + + $utcStartDateTime->add("P".$daysAdd."d"); } - if (strtotime($start) <= strtotime($endDate) || is_null($endDate)) { + if (is_null($endDateTime) || strtotime($utcStartDateTime->format("Y-m-d")) <= $endDateTime->getTimestamp()) { $showDay = new CcShowDays(); - $showDay->setDbFirstShow($start); - $showDay->setDbLastShow($endDate); - $showDay->setDbStartTime($data['add_show_start_time']); + $showDay->setDbFirstShow($utcStartDateTime->format("Y-m-d")); + $showDay->setDbLastShow($endDateTime->format("Y-m-d")); + $showDay->setDbStartTime($utcStartDateTime->format("H:i:s")); $showDay->setDbDuration($data['add_show_duration']); $showDay->setDbDay($day); $showDay->setDbRepeatType($repeatType); @@ -826,15 +818,11 @@ class Show { } } - $date = new DateHelper(); - $currentTimestamp = $date->getTimestamp(); - //check if we are adding or updating a show, and if updating //erase all the show's future show_rebroadcast information first. if (($data['add_show_id'] != -1) && $data['add_show_rebroadcast']){ CcShowRebroadcastQuery::create() ->filterByDbShowId($data['add_show_id']) - //->filterByDbStartTime($currentTimestamp, Criteria::GREATER_EQUAL) ->delete(); } //adding rows to cc_show_rebroadcast @@ -852,6 +840,7 @@ class Show { else if ($isRecorded && $data['add_show_rebroadcast'] && ($repeatType == -1)){ for ($i=1; $i<=10; $i++) { if ($data['add_show_rebroadcast_date_absolute_'.$i]) { + $con = Propel::getConnection(CcShowPeer::DATABASE_NAME); $sql = "SELECT date '{$data['add_show_rebroadcast_date_absolute_'.$i]}' - date '{$data['add_show_start_date']}' "; $r = $con->query($sql); $offset_days = $r->fetchColumn(0); @@ -1236,11 +1225,17 @@ class Show { if($show["rebroadcast"]) { $event["disableResizing"] = true; } + + $startDateTime = new DateTime($show["starts"], new DateTimeZone("UTC")); + $startDateTime->setTimezone(new DateTimeZone(date_default_timezone_get())); + + $endDateTime = new DateTime($show["ends"], new DateTimeZone("UTC")); + $endDateTime->setTimezone(new DateTimeZone(date_default_timezone_get())); $event["id"] = $show["instance_id"]; $event["title"] = $show["name"]; - $event["start"] = $show["starts"]; - $event["end"] = $show["ends"]; + $event["start"] = $startDateTime->format("Y-m-d H:i:s"); + $event["end"] = $endDateTime->format("Y-m-d H:i:s"); $event["allDay"] = false; $event["description"] = $show["description"]; $event["showId"] = $show["show_id"]; diff --git a/airtime_mvc/application/views/scripts/schedule/show-content-dialog.phtml b/airtime_mvc/application/views/scripts/schedule/show-content-dialog.phtml index c830dd3da..e1562983b 100644 --- a/airtime_mvc/application/views/scripts/schedule/show-content-dialog.phtml +++ b/airtime_mvc/application/views/scripts/schedule/show-content-dialog.phtml @@ -12,7 +12,9 @@ showContent as $row): ?> " class=""> - + setTimezone(new DateTimeZone(date_default_timezone_get())); + echo $dt->format("Y-m-d H:i:s") ?> diff --git a/airtime_mvc/public/js/airtime/dashboard/playlist.js b/airtime_mvc/public/js/airtime/dashboard/playlist.js index 8b85621a7..9b469d47e 100644 --- a/airtime_mvc/public/js/airtime/dashboard/playlist.js +++ b/airtime_mvc/public/js/airtime/dashboard/playlist.js @@ -13,6 +13,8 @@ var currentElem; var serverUpdateInterval = 5000; var uiUpdateInterval = 200; +var timezoneOffset = 0; + //set to "development" if we are developing :). Useful to disable alerts //when entering production mode. var APPLICATION_ENV = ""; @@ -169,7 +171,7 @@ function updatePlaybar(){ } /* Column 2 update */ - $('#time').text(convertDateToHHMMSS(estimatedSchedulePosixTime)); + $('#time').text(convertDateToHHMMSS(estimatedSchedulePosixTime + timezoneOffset)); } function calcAdditionalData(currentItem){ @@ -209,7 +211,7 @@ function parseItems(obj){ calcAdditionalShowData(obj.nextShow); var schedulePosixTime = convertDateToPosixTime(obj.schedulerTime); - schedulePosixTime += parseInt(obj.timezoneOffset)*1000; + timezoneOffset = parseInt(obj.timezoneOffset)*1000; var date = new Date(); localRemoteTimeOffset = date.getTime() - schedulePosixTime; } diff --git a/install_full/ubuntu/airtime-full-install b/install_full/ubuntu/airtime-full-install index 9c6800ac1..ce959286d 100755 --- a/install_full/ubuntu/airtime-full-install +++ b/install_full/ubuntu/airtime-full-install @@ -26,9 +26,9 @@ echo "----------------------------------------------------" # Updated package list sudo apt-get -y install tar gzip curl apache2 php5-pgsql libapache2-mod-php5 \ php-pear php5-gd postgresql odbc-postgresql python2.6 lame libsoundtouch-ocaml \ -libvorbis-ocaml-dev libmp3lame-dev libtaglib-ocaml libao-ocaml libmad-ocaml \ -libesd0 icecast2 sudo libportaudio2 libsamplerate0 libcamomile-ocaml-dev \ -ecasound php5-curl mpg123 rabbitmq-server monit python-virtualenv +libmp3lame-dev libtaglib-ocaml libao-ocaml libmad-ocaml ecasound \ +libesd0 icecast2 sudo libportaudio2 libsamplerate0 rabbitmq-server \ +php5-curl mpg123 monit python-virtualenv if [ "$?" -ne "0" ]; then echo "" diff --git a/install_minimal/include/airtime-db-install.php b/install_minimal/include/airtime-db-install.php index 87f07161d..0e0f7baa4 100644 --- a/install_minimal/include/airtime-db-install.php +++ b/install_minimal/include/airtime-db-install.php @@ -50,20 +50,20 @@ AirtimeInstall::SetAirtimeVersion(AIRTIME_VERSION); // set up some keys in DB AirtimeInstall::SetUniqueId(); AirtimeInstall::SetImportTimestamp(); -AirtimeInstall::SetDefaultTimezone(); if (AirtimeInstall::$databaseTablesCreated) { + AirtimeInstall::SetDefaultTimezone(); - $ini = parse_ini_file(__DIR__."/airtime-install.ini"); - - $stor_dir = realpath($ini["storage_dir"])."/"; - echo "* Inserting stor directory location $stor_dir into music_dirs table".PHP_EOL; + $ini = parse_ini_file(__DIR__."/airtime-install.ini"); - $sql = "INSERT INTO cc_music_dirs (directory, type) VALUES ('$stor_dir', 'stor')"; - $result = $CC_DBC->query($sql); - if (PEAR::isError($result)) { - echo "* Failed inserting {$stor_dir} in cc_music_dirs".PHP_EOL; - echo "* Message {$result->getMessage()}".PHP_EOL; - exit(1); - } + $stor_dir = realpath($ini["storage_dir"])."/"; + echo "* Inserting stor directory location $stor_dir into music_dirs table".PHP_EOL; + + $sql = "INSERT INTO cc_music_dirs (directory, type) VALUES ('$stor_dir', 'stor')"; + $result = $CC_DBC->query($sql); + if (PEAR::isError($result)) { + echo "* Failed inserting {$stor_dir} in cc_music_dirs".PHP_EOL; + echo "* Message {$result->getMessage()}".PHP_EOL; + exit(1); + } } \ No newline at end of file diff --git a/python_apps/api_clients/api_client.py b/python_apps/api_clients/api_client.py index 7252b16a0..35c7c92ee 100644 --- a/python_apps/api_clients/api_client.py +++ b/python_apps/api_clients/api_client.py @@ -622,7 +622,9 @@ class ObpApiClient(): return obp_version - + """ + NOTE: The server currently ignores start and end parameters we send to it. + """ def get_schedule(self, start=None, end=None): logger = logging.getLogger() @@ -630,13 +632,12 @@ class ObpApiClient(): calculate start/end time range (format: YYYY-DD-MM-hh-mm-ss,YYYY-DD-MM-hh-mm-ss) (seconds are ignored, just here for consistency) """ - tnow = time.localtime(time.time()) if (not start): - tstart = time.localtime(time.time() - 3600 * int(self.config["cache_for"])) + tstart = time.gmtime(time.time() - 3600 * int(self.config["cache_for"])) start = "%04d-%02d-%02d-%02d-%02d" % (tstart[0], tstart[1], tstart[2], tstart[3], tstart[4]) if (not end): - tend = time.localtime(time.time() + 3600 * int(self.config["prepare_ahead"])) + tend = time.gmtime(time.time() + 3600 * int(self.config["prepare_ahead"])) end = "%04d-%02d-%02d-%02d-%02d" % (tend[0], tend[1], tend[2], tend[3], tend[4]) range = {} diff --git a/python_apps/pypo/liquidsoap_bin/liquidsoap-amd64 b/python_apps/pypo/liquidsoap_bin/liquidsoap-amd64 index 1043e873e..ad554e0f1 100755 Binary files a/python_apps/pypo/liquidsoap_bin/liquidsoap-amd64 and b/python_apps/pypo/liquidsoap_bin/liquidsoap-amd64 differ diff --git a/python_apps/pypo/liquidsoap_bin/liquidsoap-i386 b/python_apps/pypo/liquidsoap_bin/liquidsoap-i386 index cba2e3bce..639af043a 100755 Binary files a/python_apps/pypo/liquidsoap_bin/liquidsoap-i386 and b/python_apps/pypo/liquidsoap_bin/liquidsoap-i386 differ diff --git a/python_apps/pypo/liquidsoap_bin/liquidsoap-natty-amd64 b/python_apps/pypo/liquidsoap_bin/liquidsoap-natty-amd64 index cce067613..4e1067210 100755 Binary files a/python_apps/pypo/liquidsoap_bin/liquidsoap-natty-amd64 and b/python_apps/pypo/liquidsoap_bin/liquidsoap-natty-amd64 differ diff --git a/python_apps/pypo/liquidsoap_bin/liquidsoap-natty-i386 b/python_apps/pypo/liquidsoap_bin/liquidsoap-natty-i386 index 217b1ef5a..8ace8750f 100755 Binary files a/python_apps/pypo/liquidsoap_bin/liquidsoap-natty-i386 and b/python_apps/pypo/liquidsoap_bin/liquidsoap-natty-i386 differ diff --git a/python_apps/pypo/pypofetch.py b/python_apps/pypo/pypofetch.py index db8b57616..bc644b2dc 100755 --- a/python_apps/pypo/pypofetch.py +++ b/python_apps/pypo/pypofetch.py @@ -1,6 +1,7 @@ import os import sys import time +import calendar import logging import logging.config import shutil @@ -53,12 +54,9 @@ Hopefully there is a better way to do this. if(command == 'update_schedule'): SCHEDULE_PUSH_MSG = m['schedule'] - elif (command == 'update_timezone'): - logger.info("Setting timezone to %s", m['timezone']) - os.environ['TZ'] = m['timezone'] - time.tzset() elif (command == 'update_stream_setting'): logger.info("Updating stream setting: %s", m['setting']) + # ACK the message to take it off the queue message.ack()""" @@ -104,10 +102,6 @@ class PypoFetch(Thread): if(command == 'update_schedule'): self.schedule_data = m['schedule'] self.process_schedule(self.schedule_data, "scheduler", False) - elif (command == 'update_timezone'): - logger.info("Setting timezone to %s", m['timezone']) - os.environ['TZ'] = m['timezone'] - time.tzset() elif (command == 'update_stream_setting'): logger.info("Updating stream setting...") self.regenerateLiquidsoapConf(m['setting']) @@ -212,20 +206,6 @@ class PypoFetch(Thread): self.cache_dir = config["cache_dir"] + self.export_source + '/' logger.info("Creating cache directory at %s", self.cache_dir) - def check_matching_timezones(self, server_timezone): - logger = logging.getLogger('fetch') - - process = Popen(["date", "+%z"], stdout=PIPE) - pypo_timezone = (process.communicate()[0]).strip(' \r\n\t') - - if server_timezone != pypo_timezone: - logger.error("ERROR: Airtime server and pypo timezone offsets do not match. Audio playback will not start when expected!!!") - logger.error(" * Server timezone offset: %s", server_timezone) - logger.error(" * Pypo timezone offset: %s", pypo_timezone) - logger.error(" * To fix this, you need to set the 'date.timezone' value in your php.ini file and restart apache.") - logger.error(" * See this page for more info (v1.7): http://wiki.sourcefabric.org/x/BQBF") - logger.error(" * and also the 'FAQ and Support' page underneath it.") - """ def get_currently_scheduled(self, playlistsOrMedias, str_tnow_s): for key in playlistsOrMedias: @@ -274,12 +254,6 @@ class PypoFetch(Thread): logger = logging.getLogger('fetch') playlists = schedule_data["playlists"] - #if bootstrapping: - #TODO: possible allow prepare_playlists to handle this. - #self.handle_shows_currently_scheduled(playlists) - - self.check_matching_timezones(schedule_data["server_timezone"]) - # Push stream metadata to liquidsoap # TODO: THIS LIQUIDSOAP STUFF NEEDS TO BE MOVED TO PYPO-PUSH!!! stream_metadata = schedule_data['stream_metadata'] @@ -465,7 +439,7 @@ class PypoFetch(Thread): for r, d, f in os.walk(self.cache_dir): for dir in d: try: - timestamp = time.mktime(time.strptime(dir, "%Y-%m-%d-%H-%M-%S")) + timestamp = calendar.timegm(time.strptime(dir, "%Y-%m-%d-%H-%M-%S")) if (now - timestamp) > offset: try: logger.debug('trying to remove %s - timestamp: %s', os.path.join(r, dir), timestamp) diff --git a/python_apps/pypo/pypopush.py b/python_apps/pypo/pypopush.py index cacf84b42..a9dc79a14 100755 --- a/python_apps/pypo/pypopush.py +++ b/python_apps/pypo/pypopush.py @@ -85,23 +85,19 @@ class PypoPush(Thread): playedItems = self.load_schedule_tracker() timenow = time.time() - tcoming = time.localtime(timenow + self.push_ahead) + tcoming = time.gmtime(timenow + self.push_ahead) str_tcoming_s = "%04d-%02d-%02d-%02d-%02d-%02d" % (tcoming[0], tcoming[1], tcoming[2], tcoming[3], tcoming[4], tcoming[5]) - tcoming2 = time.localtime(timenow + self.push_ahead2) + tcoming2 = time.gmtime(timenow + self.push_ahead2) str_tcoming2_s = "%04d-%02d-%02d-%02d-%02d-%02d" % (tcoming2[0], tcoming2[1], tcoming2[2], tcoming2[3], tcoming2[4], tcoming2[5]) - tnow = time.localtime(timenow) + tnow = time.gmtime(timenow) str_tnow_s = "%04d-%02d-%02d-%02d-%02d-%02d" % (tnow[0], tnow[1], tnow[2], tnow[3], tnow[4], tnow[5]) for pkey in schedule: plstart = schedule[pkey]['start'][0:19] - #plstart = pkey[0:19] - #playedFlag = (pkey in playedItems) and playedItems[pkey].get("played", 0) - playedFlag = False - - if plstart == str_tcoming_s or (plstart < str_tcoming_s and plstart > str_tcoming2_s and not playedFlag): + if plstart == str_tcoming_s or (plstart < str_tcoming_s and plstart > str_tcoming2_s): logger.debug('Preparing to push playlist scheduled at: %s', pkey) playlist = schedule[pkey] @@ -156,7 +152,7 @@ class PypoPush(Thread): #mktime takes a time_struct and returns a floating point #gmtime Convert a time expressed in seconds since the epoch to a struct_time in UTC #mktime: expresses the time in local time, not UTC. It returns a floating point number, for compatibility with time(). - epoch_start = calendar.timegm(time.gmtime(time.mktime(time.strptime(pkey, '%Y-%m-%d-%H-%M-%S')))) + epoch_start = calendar.timegm(time.strptime(pkey, '%Y-%m-%d-%H-%M-%S')) #Return the time as a floating point number expressed in seconds since the epoch, in UTC. epoch_now = time.time() diff --git a/python_apps/show-recorder/recorder.py b/python_apps/show-recorder/recorder.py index bb05d02ba..fe0638e90 100644 --- a/python_apps/show-recorder/recorder.py +++ b/python_apps/show-recorder/recorder.py @@ -42,12 +42,14 @@ except Exception, e: sys.exit() def getDateTimeObj(time): - timeinfo = time.split(" ") date = timeinfo[0].split("-") time = timeinfo[1].split(":") + + date = map(int, date) + time = map(int, time) - return datetime.datetime(int(date[0]), int(date[1]), int(date[2]), int(time[0]), int(time[1]), int(time[2])) + return datetime.datetime(date[0], date[1], date[2], time[0], time[1], time[2], 0, None) class ShowRecorder(Thread): @@ -168,7 +170,7 @@ class CommandListener(Thread): self.logger = logging.getLogger('root') self.sr = None self.current_schedule = {} - self.shows_to_record = [] + self.shows_to_record = {} self.time_till_next_show = 3600 self.logger.info("RecorderFetch: init complete") @@ -211,9 +213,8 @@ class CommandListener(Thread): show_starts = getDateTimeObj(show[u'starts']) show_end = getDateTimeObj(show[u'ends']) time_delta = show_end - show_starts - + self.shows_to_record[show[u'starts']] = [time_delta, show[u'instance_id'], show[u'name']] - delta = self.get_time_till_next_show() # awake at least 5 seconds prior to the show start self.time_till_next_show = delta - 5 @@ -222,7 +223,7 @@ class CommandListener(Thread): def get_time_till_next_show(self): if len(self.shows_to_record) != 0: - tnow = datetime.datetime.now() + tnow = datetime.datetime.utcnow() sorted_show_keys = sorted(self.shows_to_record.keys()) start_time = sorted_show_keys[0]