Merge branch 'saas-dev' into saas
This commit is contained in:
commit
c35a8cc952
29 changed files with 569 additions and 497 deletions
|
@ -130,9 +130,11 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
|
||||||
protected function _initTasks() {
|
protected function _initTasks() {
|
||||||
/* We need to wrap this here so that we aren't checking when we're running the unit test suite
|
/* We need to wrap this here so that we aren't checking when we're running the unit test suite
|
||||||
*/
|
*/
|
||||||
|
$taskManager = TaskManager::getInstance();
|
||||||
|
$taskManager->runTask(AirtimeTask::UPGRADE); // Run the upgrade on each request (if it needs to be run)
|
||||||
if (getenv("AIRTIME_UNIT_TEST") != 1) {
|
if (getenv("AIRTIME_UNIT_TEST") != 1) {
|
||||||
//This will do the upgrade too if it's needed...
|
//This will do the upgrade too if it's needed...
|
||||||
TaskManager::getInstance()->runTasks();
|
$taskManager->runTasks();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,27 @@
|
||||||
|
|
||||||
class FileDataHelper {
|
class FileDataHelper {
|
||||||
|
|
||||||
|
public static function getAudioMimeTypeArray() {
|
||||||
|
return array(
|
||||||
|
"audio/ogg" => "ogg",
|
||||||
|
"application/ogg" => "ogg",
|
||||||
|
"audio/vorbis" => "ogg",
|
||||||
|
"audio/mp3" => "mp3",
|
||||||
|
"audio/mpeg" => "mp3",
|
||||||
|
"audio/mpeg3" => "mp3",
|
||||||
|
"audio/aac" => "aac",
|
||||||
|
"audio/aacp" => "aac",
|
||||||
|
"audio/mp4" => "mp4",
|
||||||
|
"audio/x-flac" => "flac",
|
||||||
|
"audio/wav" => "wav",
|
||||||
|
"audio/x-wav" => "wav",
|
||||||
|
"audio/mp2" => "mp2",
|
||||||
|
"audio/mp1" => "mp1",
|
||||||
|
"audio/x-ms-wma" => "wma",
|
||||||
|
"audio/basic" => "au",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We want to throw out invalid data and process the upload successfully
|
* We want to throw out invalid data and process the upload successfully
|
||||||
* at all costs, so check the data and sanitize it if necessary
|
* at all costs, so check the data and sanitize it if necessary
|
||||||
|
@ -24,4 +45,24 @@ class FileDataHelper {
|
||||||
$data["bpm"] = intval($data["bpm"]);
|
$data["bpm"] = intval($data["bpm"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a suitable extension for the given file
|
||||||
|
*
|
||||||
|
* @param string $mime
|
||||||
|
*
|
||||||
|
* @return string file extension with(!) a dot (for convenience)
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static function getFileExtensionFromMime($mime)
|
||||||
|
{
|
||||||
|
$mime = trim(strtolower($mime));
|
||||||
|
try {
|
||||||
|
return ('.' . static::getAudioMimeTypeArray()[$mime]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
throw new Exception("Unknown file type: $mime");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -45,8 +45,6 @@ class Application_Common_HTTPHelper
|
||||||
|
|
||||||
class ZendActionHttpException extends Exception {
|
class ZendActionHttpException extends Exception {
|
||||||
|
|
||||||
private $_action;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Zend_Controller_Action $action
|
* @param Zend_Controller_Action $action
|
||||||
* @param int $statusCode
|
* @param int $statusCode
|
||||||
|
@ -58,8 +56,7 @@ class ZendActionHttpException extends Exception {
|
||||||
*/
|
*/
|
||||||
public function __construct(Zend_Controller_Action $action, $statusCode, $message,
|
public function __construct(Zend_Controller_Action $action, $statusCode, $message,
|
||||||
$code = 0, Exception $previous = null) {
|
$code = 0, Exception $previous = null) {
|
||||||
$this->_action = $action;
|
Logging::error("Error in action " . $action->getRequest()->getActionName()
|
||||||
Logging::info("Error in action " . $action->getRequest()->getActionName()
|
|
||||||
. " with status code $statusCode: $message");
|
. " with status code $statusCode: $message");
|
||||||
$action->getResponse()
|
$action->getResponse()
|
||||||
->setHttpResponseCode($statusCode)
|
->setHttpResponseCode($statusCode)
|
||||||
|
@ -67,8 +64,4 @@ class ZendActionHttpException extends Exception {
|
||||||
parent::__construct($message, $code, $previous);
|
parent::__construct($message, $code, $previous);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAction() {
|
|
||||||
return $this->_action;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -2,15 +2,19 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class TaskManager
|
* Class TaskManager
|
||||||
|
*
|
||||||
|
* When adding a new task, the new AirtimeTask class will need to be added to the internal task list,
|
||||||
|
* as an ENUM value to the AirtimeTask interface, and as a case in the TaskFactory.
|
||||||
*/
|
*/
|
||||||
final class TaskManager {
|
final class TaskManager {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array tasks to be run
|
* @var array tasks to be run. Maps task names to a boolean value denoting
|
||||||
|
* whether the task has been checked/run
|
||||||
*/
|
*/
|
||||||
protected $_taskList = [
|
protected $_taskList = [
|
||||||
AirtimeTask::UPGRADE, // Always run the upgrade first
|
AirtimeTask::UPGRADE => false,
|
||||||
AirtimeTask::CELERY
|
AirtimeTask::CELERY => false,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,8 +23,7 @@ final class TaskManager {
|
||||||
protected static $_instance;
|
protected static $_instance;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int TASK_INTERVAL_SECONDS how often, in seconds, to run the TaskManager tasks,
|
* @var int TASK_INTERVAL_SECONDS how often, in seconds, to run the TaskManager tasks
|
||||||
* if they need to be run
|
|
||||||
*/
|
*/
|
||||||
const TASK_INTERVAL_SECONDS = 30;
|
const TASK_INTERVAL_SECONDS = 30;
|
||||||
|
|
||||||
|
@ -47,6 +50,22 @@ final class TaskManager {
|
||||||
return self::$_instance;
|
return self::$_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run a single task.
|
||||||
|
*
|
||||||
|
* @param string $taskName the ENUM name of the task to be run
|
||||||
|
*/
|
||||||
|
public function runTask($taskName) {
|
||||||
|
$task = TaskFactory::getTask($taskName);
|
||||||
|
if ($task && $task->shouldBeRun()) {
|
||||||
|
$task->run();
|
||||||
|
}
|
||||||
|
$this->_taskList[$taskName] = true; // Mark that the task has been checked/run.
|
||||||
|
// This is important for prioritized tasks that
|
||||||
|
// we need to run on every request (such as the
|
||||||
|
// schema check/upgrade)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run all tasks that need to be run.
|
* Run all tasks that need to be run.
|
||||||
*
|
*
|
||||||
|
@ -81,10 +100,9 @@ final class TaskManager {
|
||||||
// better to be silent here to avoid log bloat
|
// better to be silent here to avoid log bloat
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
foreach ($this->_taskList as $task) {
|
foreach ($this->_taskList as $task => $hasTaskRun) {
|
||||||
$task = TaskFactory::getTask($task);
|
if (!$hasTaskRun) {
|
||||||
if ($task && $task->shouldBeRun()) {
|
$this->runTask($task);
|
||||||
$task->run();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,83 +57,93 @@ class WidgetHelper
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second version of this function.
|
/**
|
||||||
// Removing "next" days and creating two weekly arrays
|
* Returns a weeks worth of shows in UTC, and an info array of the current week's days.
|
||||||
public static function getWeekInfoV2($timezone)
|
* Returns an array of two arrays:
|
||||||
|
*
|
||||||
|
* The first array is 7 consecutive week days, starting with the current day.
|
||||||
|
*
|
||||||
|
* The second array contains shows scheduled during the 7 week days in the first array.
|
||||||
|
* The shows returned in this array are not in any order and are in UTC.
|
||||||
|
*
|
||||||
|
* We don't do any timezone conversion in this function on purpose. All timezone conversion
|
||||||
|
* and show time ordering should be done on the frontend.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getWeekInfoV2()
|
||||||
{
|
{
|
||||||
//weekStart is in station time.
|
|
||||||
//$weekStartDateTime = Application_Common_DateHelper::getWeekStartDateTime();
|
|
||||||
$weekStartDateTime = new DateTime("now", new DateTimeZone(Application_Model_Preference::GetTimezone()));
|
$weekStartDateTime = new DateTime("now", new DateTimeZone(Application_Model_Preference::GetTimezone()));
|
||||||
|
|
||||||
$maxNumOFWeeks = 2;
|
|
||||||
|
|
||||||
$result = array();
|
$result = array();
|
||||||
|
|
||||||
// default to the station timezone
|
|
||||||
$timezone = Application_Model_Preference::GetDefaultTimezone();
|
|
||||||
$userDefinedTimezone = strtolower($timezone);
|
|
||||||
// if the timezone defined by the user exists, use that
|
|
||||||
if (array_key_exists($userDefinedTimezone, timezone_abbreviations_list())) {
|
|
||||||
$timezone = $userDefinedTimezone;
|
|
||||||
}
|
|
||||||
$utcTimezone = new DateTimeZone("UTC");
|
$utcTimezone = new DateTimeZone("UTC");
|
||||||
|
|
||||||
$weekStartDateTime->setTimezone($utcTimezone);
|
$weekStartDateTime->setTimezone($utcTimezone);
|
||||||
|
|
||||||
// When querying for shows we need the start and end date range to have
|
// Use this variable as the start date/time range when querying
|
||||||
// a time of "00:00". $utcDayStart is used below when querying for shows.
|
// for shows. We set it to 1 day prior to the beginning of the
|
||||||
$utcDayStartDT = clone $weekStartDateTime;
|
// schedule widget data to account for show date changes when
|
||||||
$utcDayStartDT->setTime(0, 0, 0);
|
// converting their start day/time to the client's local timezone.
|
||||||
$utcDayStart = $utcDayStartDT->format(DEFAULT_TIMESTAMP_FORMAT);
|
$showQueryDateRangeStart = clone $weekStartDateTime;
|
||||||
$weekCounter = 0;
|
$showQueryDateRangeStart->sub(new DateInterval("P1D"));
|
||||||
while ($weekCounter < $maxNumOFWeeks) {
|
$showQueryDateRangeStart->setTime(0, 0, 0);
|
||||||
for ($dayOfWeekCounter = 0; $dayOfWeekCounter < DAYS_PER_WEEK; $dayOfWeekCounter++) {
|
|
||||||
$dateParse = date_parse($weekStartDateTime->format(DEFAULT_TIMESTAMP_FORMAT));
|
|
||||||
|
|
||||||
$result[$weekCounter][$dayOfWeekCounter]["dayOfMonth"] = $dateParse["day"];
|
for ($dayOfWeekCounter = 0; $dayOfWeekCounter < DAYS_PER_WEEK; $dayOfWeekCounter++) {
|
||||||
$result[$weekCounter][$dayOfWeekCounter]["dayOfWeek"] = strtoupper(date("D", $weekStartDateTime->getTimestamp()));
|
$dateParse = date_parse($weekStartDateTime->format("Y-m-d H:i:s"));
|
||||||
|
|
||||||
//have to be in station timezone when adding 1 day for daylight savings.
|
// Associate data to its date so that when we convert this array
|
||||||
$weekStartDateTime->setTimezone(new DateTimeZone($timezone));
|
// to json the order remains the same - in chronological order.
|
||||||
$weekStartDateTime->add(new DateInterval('P1D'));
|
// We also format the key to be for example: "2015-6-1" to match
|
||||||
|
// javascript date formats so it's easier to sort the shows by day.
|
||||||
|
$result["weekDays"][$weekStartDateTime->format("Y-n-j")] = array();
|
||||||
|
$result["weekDays"][$weekStartDateTime->format("Y-n-j")]["dayOfMonth"] = $dateParse["day"];
|
||||||
|
$result["weekDays"][$weekStartDateTime->format("Y-n-j")]["dayOfWeek"] = strtoupper(_(date("D", $weekStartDateTime->getTimestamp())));
|
||||||
|
|
||||||
//convert back to UTC to get the actual timestamp used for search.
|
// Shows scheduled for this day will get added to this array when
|
||||||
$weekStartDateTime->setTimezone($utcTimezone);
|
// we convert the show times to the client's local timezone in weekly-program.phtml
|
||||||
|
$result["weekDays"][$weekStartDateTime->format("Y-n-j")]["shows"] = array();
|
||||||
|
|
||||||
// When querying for shows we need the start and end date range to have
|
// $weekStartDateTime has to be in station timezone when adding 1 day for daylight savings.
|
||||||
// a time of "00:00".
|
// TODO: is this necessary since we set the time to "00:00" ?
|
||||||
$utcDayEndDT = clone $weekStartDateTime;
|
$stationTimezone = Application_Model_Preference::GetDefaultTimezone();
|
||||||
$utcDayEndDT->setTime(0, 0, 0);
|
$weekStartDateTime->setTimezone(new DateTimeZone($stationTimezone));
|
||||||
$utcDayEnd = $utcDayEndDT->format(DEFAULT_TIMESTAMP_FORMAT);
|
|
||||||
$shows = Application_Model_Show::getNextShows($utcDayStart, "ALL", $utcDayEnd);
|
|
||||||
$utcDayStart = $utcDayEnd;
|
|
||||||
|
|
||||||
// convert to user-defined timezone, or default to station
|
$weekStartDateTime->add(new DateInterval('P1D'));
|
||||||
Application_Common_DateHelper::convertTimestampsToTimezone(
|
|
||||||
$shows,
|
|
||||||
array("starts", "ends", "start_timestamp", "end_timestamp"),
|
|
||||||
$timezone
|
|
||||||
);
|
|
||||||
|
|
||||||
|
//convert back to UTC to get the actual timestamp used for search.
|
||||||
foreach($shows as &$show) {
|
$weekStartDateTime->setTimezone($utcTimezone);
|
||||||
$startParseDate = date_parse($show['starts']);
|
|
||||||
$show["show_start_hour"] = str_pad($startParseDate["hour"], 2, "0", STR_PAD_LEFT).":".str_pad($startParseDate["minute"], 2, 0, STR_PAD_LEFT);
|
|
||||||
|
|
||||||
$endParseDate = date_parse($show['ends']);
|
|
||||||
$show["show_end_hour"] = str_pad($endParseDate["hour"], 2, 0, STR_PAD_LEFT).":".str_pad($endParseDate["minute"],2, 0, STR_PAD_LEFT);
|
|
||||||
}
|
|
||||||
$result[$weekCounter][$dayOfWeekCounter]["shows"] = $shows;
|
|
||||||
|
|
||||||
}
|
|
||||||
$weekCounter += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use this variable as the end date/time range when querying
|
||||||
|
// for shows. We set it to 1 day after the end of the schedule
|
||||||
|
// widget data to account for show date changes when converting
|
||||||
|
// their start day/time to the client's local timezone.
|
||||||
|
$showQueryDateRangeEnd = clone $weekStartDateTime;
|
||||||
|
$showQueryDateRangeEnd->setTime(23, 59, 0);
|
||||||
|
|
||||||
|
$shows = Application_Model_Show::getNextShows(
|
||||||
|
$showQueryDateRangeStart->format("Y-m-d H:i:s"),
|
||||||
|
"ALL",
|
||||||
|
$showQueryDateRangeEnd->format("Y-m-d H:i:s"));
|
||||||
|
|
||||||
|
// Convert each start and end time string to DateTime objects
|
||||||
|
// so we can get a real timestamp. The timestamps will be used
|
||||||
|
// to convert into javascript Date objects.
|
||||||
|
foreach($shows as &$show) {
|
||||||
|
$dtStarts = new DateTime($show["starts"], new DateTimeZone("UTC"));
|
||||||
|
$show["starts_timestamp"] = $dtStarts->getTimestamp();
|
||||||
|
|
||||||
|
$dtEnds = new DateTime($show["ends"], new DateTimeZone("UTC"));
|
||||||
|
$show["ends_timestamp"] = $dtEnds->getTimestamp();
|
||||||
|
}
|
||||||
|
$result["shows"] = $shows;
|
||||||
|
|
||||||
// XSS exploit prevention
|
// XSS exploit prevention
|
||||||
SecurityHelper::htmlescape_recursive($result);
|
SecurityHelper::htmlescape_recursive($result);
|
||||||
|
|
||||||
// convert image paths to point to api endpoints
|
// convert image paths to point to api endpoints
|
||||||
|
//TODO: do we need this here?
|
||||||
self::findAndConvertPaths($result);
|
self::findAndConvertPaths($result);
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
|
|
|
@ -24,7 +24,8 @@ define('LICENSE_URL' , 'http://www.gnu.org/licenses/agpl-3.0-standalone.h
|
||||||
define('AIRTIME_COPYRIGHT_DATE' , '2010-2015');
|
define('AIRTIME_COPYRIGHT_DATE' , '2010-2015');
|
||||||
define('AIRTIME_REST_VERSION' , '1.1');
|
define('AIRTIME_REST_VERSION' , '1.1');
|
||||||
define('AIRTIME_API_VERSION' , '1.1');
|
define('AIRTIME_API_VERSION' , '1.1');
|
||||||
define('AIRTIME_CODE_VERSION' , '2.5.13');
|
// XXX: it's important that we upgrade this every time we add an upgrade!
|
||||||
|
define('AIRTIME_CODE_VERSION' , '2.5.14');
|
||||||
|
|
||||||
// Defaults
|
// Defaults
|
||||||
define('DEFAULT_LOGO_PLACEHOLDER', 1);
|
define('DEFAULT_LOGO_PLACEHOLDER', 1);
|
||||||
|
|
|
@ -198,23 +198,10 @@ class AudiopreviewController extends Zend_Controller_Action
|
||||||
$elementMap['type'] = $track['type'];
|
$elementMap['type'] = $track['type'];
|
||||||
|
|
||||||
if ($track['type'] == 0) {
|
if ($track['type'] == 0) {
|
||||||
$mime = $track['mime'];
|
$mime = trim(strtolower($track['mime']));
|
||||||
//type is file
|
try {
|
||||||
if (strtolower($mime) === 'audio/mp3') {
|
$elementMap['element_' . FileDataHelper::getAudioMimeTypeArray()[$mime]] = $track['item_id'];
|
||||||
$elementMap['element_mp3'] = $track['item_id'];
|
} catch (Exception $e) {
|
||||||
} elseif (strtolower($mime) === 'audio/ogg') {
|
|
||||||
$elementMap['element_oga'] = $track['item_id'];
|
|
||||||
} elseif (strtolower($mime) === 'audio/vorbis') {
|
|
||||||
$elementMap['element_oga'] = $track['item_id'];
|
|
||||||
} elseif (strtolower($mime) === 'audio/mp4') {
|
|
||||||
$elementMap['element_m4a'] = $track['item_id'];
|
|
||||||
} elseif (strtolower($mime) === 'audio/wav') {
|
|
||||||
$elementMap['element_wav'] = $track['item_id'];
|
|
||||||
} elseif (strtolower($mime) === 'audio/x-wav') {
|
|
||||||
$elementMap['element_wav'] = $track['item_id'];
|
|
||||||
} elseif (strtolower($mime) === 'audio/x-flac') {
|
|
||||||
$elementMap['element_flac'] = $track['item_id'];
|
|
||||||
} else {
|
|
||||||
throw new Exception("Unknown file type: $mime");
|
throw new Exception("Unknown file type: $mime");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,22 +275,10 @@ class AudiopreviewController extends Zend_Controller_Action
|
||||||
|
|
||||||
$elementMap['type'] = $track['type'];
|
$elementMap['type'] = $track['type'];
|
||||||
if ($track['type'] == 0) {
|
if ($track['type'] == 0) {
|
||||||
$mime = $track['mime'];
|
$mime = trim(strtolower($track['mime']));
|
||||||
if (strtolower($mime) === 'audio/mp3') {
|
try {
|
||||||
$elementMap['element_mp3'] = $track['item_id'];
|
$elementMap['element_' . FileDataHelper::getAudioMimeTypeArray()[$mime]] = $track['item_id'];
|
||||||
} elseif (strtolower($mime) === 'audio/ogg') {
|
} catch (Exception $e) {
|
||||||
$elementMap['element_oga'] = $track['item_id'];
|
|
||||||
} elseif (strtolower($mime) === 'audio/vorbis') {
|
|
||||||
$elementMap['element_oga'] = $track['item_id'];
|
|
||||||
} elseif (strtolower($mime) === 'audio/mp4') {
|
|
||||||
$elementMap['element_m4a'] = $track['item_id'];
|
|
||||||
} elseif (strtolower($mime) === 'audio/wav') {
|
|
||||||
$elementMap['element_wav'] = $track['item_id'];
|
|
||||||
} elseif (strtolower($mime) === 'audio/x-wav') {
|
|
||||||
$elementMap['element_wav'] = $track['item_id'];
|
|
||||||
} elseif (strtolower($mime) === 'audio/x-flac') {
|
|
||||||
$elementMap['element_flac'] = $track['item_id'];
|
|
||||||
} else {
|
|
||||||
throw new Exception("Unknown file type: $mime");
|
throw new Exception("Unknown file type: $mime");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,6 @@ class EmbedController extends Zend_Controller_Action
|
||||||
|
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
|
|
||||||
|
|
||||||
$widgetStyle = $request->getParam('style');
|
$widgetStyle = $request->getParam('style');
|
||||||
if ($widgetStyle == "premium") {
|
if ($widgetStyle == "premium") {
|
||||||
$this->view->widgetStyle = "premium";
|
$this->view->widgetStyle = "premium";
|
||||||
|
@ -95,10 +94,9 @@ class EmbedController extends Zend_Controller_Action
|
||||||
}
|
}
|
||||||
$this->view->jquery = Application_Common_HTTPHelper::getStationUrl() . "widgets/js/jquery-1.6.1.min.js?".$CC_CONFIG['airtime_version'];
|
$this->view->jquery = Application_Common_HTTPHelper::getStationUrl() . "widgets/js/jquery-1.6.1.min.js?".$CC_CONFIG['airtime_version'];
|
||||||
|
|
||||||
$weeklyScheduleData = WidgetHelper::getWeekInfoV2($this->getRequest()->getParam("timezone"));
|
$weeklyScheduleData = WidgetHelper::getWeekInfoV2();
|
||||||
|
|
||||||
// Return only the current week's schedule data. In the future we may use the next week's data.
|
$this->view->schedule_data = json_encode($weeklyScheduleData);
|
||||||
$this->view->weeklyScheduleData = ($weeklyScheduleData[0]);
|
|
||||||
|
|
||||||
$currentDay = new DateTime("now", new DateTimeZone(Application_Model_Preference::GetTimezone()));
|
$currentDay = new DateTime("now", new DateTimeZone(Application_Model_Preference::GetTimezone()));
|
||||||
//day of the month without leading zeros (1 to 31)
|
//day of the month without leading zeros (1 to 31)
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
ALTER TABLE cc_pref ALTER COLUMN subjid SET NULL;
|
||||||
|
ALTER TABLE cc_pref ALTER COLUMN subjid SET DEFAULT NULL;
|
||||||
|
CREATE UNIQUE INDEX cc_pref_key_idx ON cc_pref (keystr) WHERE subjid IS NULL;
|
||||||
|
ANALYZE cc_pref;
|
|
@ -8,14 +8,13 @@ class Application_Form_AddShowLiveStream extends Zend_Form_SubForm
|
||||||
{
|
{
|
||||||
$cb_airtime_auth = new Zend_Form_Element_Checkbox("cb_airtime_auth");
|
$cb_airtime_auth = new Zend_Form_Element_Checkbox("cb_airtime_auth");
|
||||||
$cb_airtime_auth->setLabel(sprintf(_("Use %s Authentication:"), PRODUCT_NAME))
|
$cb_airtime_auth->setLabel(sprintf(_("Use %s Authentication:"), PRODUCT_NAME))
|
||||||
->setRequired(false)
|
->setChecked(true)
|
||||||
->setDecorators(array('ViewHelper'));
|
->setRequired(false);
|
||||||
$this->addElement($cb_airtime_auth);
|
$this->addElement($cb_airtime_auth);
|
||||||
|
|
||||||
$cb_custom_auth = new Zend_Form_Element_Checkbox("cb_custom_auth");
|
$cb_custom_auth = new Zend_Form_Element_Checkbox("cb_custom_auth");
|
||||||
$cb_custom_auth ->setLabel(_("Use Custom Authentication:"))
|
$cb_custom_auth ->setLabel(_("Use Custom Authentication:"))
|
||||||
->setRequired(false)
|
->setRequired(false);
|
||||||
->setDecorators(array('ViewHelper'));
|
|
||||||
$this->addElement($cb_custom_auth);
|
$this->addElement($cb_custom_auth);
|
||||||
|
|
||||||
//custom username
|
//custom username
|
||||||
|
@ -26,8 +25,7 @@ class Application_Form_AddShowLiveStream extends Zend_Form_SubForm
|
||||||
->setLabel(_('Custom Username'))
|
->setLabel(_('Custom Username'))
|
||||||
->setFilters(array('StringTrim'))
|
->setFilters(array('StringTrim'))
|
||||||
->setValidators(array(
|
->setValidators(array(
|
||||||
new ConditionalNotEmpty(array("cb_custom_auth"=>"1"))))
|
new ConditionalNotEmpty(array("cb_custom_auth"=>"1"))));
|
||||||
->setDecorators(array('ViewHelper'));
|
|
||||||
$this->addElement($custom_username);
|
$this->addElement($custom_username);
|
||||||
|
|
||||||
//custom password
|
//custom password
|
||||||
|
@ -39,18 +37,34 @@ class Application_Form_AddShowLiveStream extends Zend_Form_SubForm
|
||||||
->setLabel(_('Custom Password'))
|
->setLabel(_('Custom Password'))
|
||||||
->setFilters(array('StringTrim'))
|
->setFilters(array('StringTrim'))
|
||||||
->setValidators(array(
|
->setValidators(array(
|
||||||
new ConditionalNotEmpty(array("cb_custom_auth"=>"1"))))
|
new ConditionalNotEmpty(array("cb_custom_auth"=>"1"))));
|
||||||
->setDecorators(array('ViewHelper'));
|
|
||||||
$this->addElement($custom_password);
|
$this->addElement($custom_password);
|
||||||
|
|
||||||
$connection_url = Application_Model_Preference::GetLiveDJSourceConnectionURL();
|
$showSourceParams = parse_url(Application_Model_Preference::GetLiveDJSourceConnectionURL());
|
||||||
if (trim($connection_url) == "") {
|
|
||||||
$connection_url = "N/A";
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->setDecorators(array(
|
// Show source connection url parameters
|
||||||
array('ViewScript', array('viewScript' => 'form/add-show-live-stream.phtml', "connection_url"=>$connection_url))
|
$showSourceHost = new Zend_Form_Element_Text('show_source_host');
|
||||||
));
|
$showSourceHost->setAttrib('readonly', true)
|
||||||
|
->setLabel(_('Host:'))
|
||||||
|
->setValue(isset($showSourceParams["host"])?$showSourceParams["host"]:"");
|
||||||
|
$this->addElement($showSourceHost);
|
||||||
|
|
||||||
|
$showSourcePort = new Zend_Form_Element_Text('show_source_port');
|
||||||
|
$showSourcePort->setAttrib('readonly', true)
|
||||||
|
->setLabel(_('Port:'))
|
||||||
|
->setValue(isset($showSourceParams["port"])?$showSourceParams["port"]:"");
|
||||||
|
$this->addElement($showSourcePort);
|
||||||
|
|
||||||
|
$showSourceMount = new Zend_Form_Element_Text('show_source_mount');
|
||||||
|
$showSourceMount->setAttrib('readonly', true)
|
||||||
|
->setLabel(_('Mount:'))
|
||||||
|
->setValue(isset($showSourceParams["path"])?$showSourceParams["path"]:"");
|
||||||
|
$this->addElement($showSourceMount);
|
||||||
|
|
||||||
|
$this->setDecorators(
|
||||||
|
array(
|
||||||
|
array('ViewScript', array('viewScript' => 'form/add-show-live-stream.phtml'))
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isValid($data)
|
public function isValid($data)
|
||||||
|
|
|
@ -11,38 +11,38 @@ class Application_Form_LiveStreamingPreferences extends Zend_Form_SubForm
|
||||||
|
|
||||||
$defaultFade = Application_Model_Preference::GetDefaultTransitionFade();
|
$defaultFade = Application_Model_Preference::GetDefaultTransitionFade();
|
||||||
|
|
||||||
|
$this->setDecorators(array(
|
||||||
|
array('ViewScript', array('viewScript' => 'form/preferences_livestream.phtml')),
|
||||||
|
));
|
||||||
|
|
||||||
// automatic trasition on source disconnection
|
// automatic trasition on source disconnection
|
||||||
$auto_transition = new Zend_Form_Element_Checkbox("auto_transition");
|
$auto_transition = new Zend_Form_Element_Checkbox("auto_transition");
|
||||||
$auto_transition->setLabel(_("Auto Switch Off"))
|
$auto_transition->setLabel(_("Auto Switch Off:"))
|
||||||
->setValue(Application_Model_Preference::GetAutoTransition())
|
->setValue(Application_Model_Preference::GetAutoTransition());
|
||||||
->setDecorators(array('ViewHelper'));
|
|
||||||
$this->addElement($auto_transition);
|
$this->addElement($auto_transition);
|
||||||
|
|
||||||
// automatic switch on upon source connection
|
// automatic switch on upon source connection
|
||||||
$auto_switch = new Zend_Form_Element_Checkbox("auto_switch");
|
$auto_switch = new Zend_Form_Element_Checkbox("auto_switch");
|
||||||
$auto_switch->setLabel(_("Auto Switch On"))
|
$auto_switch->setLabel(_("Auto Switch On:"))
|
||||||
->setValue(Application_Model_Preference::GetAutoSwitch())
|
->setValue(Application_Model_Preference::GetAutoSwitch());
|
||||||
->setDecorators(array('ViewHelper'));
|
|
||||||
$this->addElement($auto_switch);
|
$this->addElement($auto_switch);
|
||||||
|
|
||||||
// Default transition fade
|
// Default transition fade
|
||||||
$transition_fade = new Zend_Form_Element_Text("transition_fade");
|
$transition_fade = new Zend_Form_Element_Text("transition_fade");
|
||||||
$transition_fade->setLabel(_("Switch Transition Fade (s)"))
|
$transition_fade->setLabel(_("Switch Transition Fade (s):"))
|
||||||
->setFilters(array('StringTrim'))
|
->setFilters(array('StringTrim'))
|
||||||
->addValidator('regex', false, array('/^\d*(\.\d+)?$/',
|
->addValidator('regex', false, array('/^\d*(\.\d+)?$/',
|
||||||
'messages' => _('Please enter a time in seconds (eg. 0.5)')))
|
'messages' => _('Please enter a time in seconds (eg. 0.5)')))
|
||||||
->setValue($defaultFade)
|
->setValue($defaultFade);
|
||||||
->setDecorators(array('ViewHelper'));
|
|
||||||
$this->addElement($transition_fade);
|
$this->addElement($transition_fade);
|
||||||
|
|
||||||
//Master username
|
//Master username
|
||||||
$master_username = new Zend_Form_Element_Text('master_username');
|
$master_username = new Zend_Form_Element_Text('master_username');
|
||||||
$master_username->setAttrib('autocomplete', 'off')
|
$master_username->setAttrib('autocomplete', 'off')
|
||||||
->setAllowEmpty(true)
|
->setAllowEmpty(true)
|
||||||
->setLabel(_('Master Username'))
|
->setLabel(_('Username:'))
|
||||||
->setFilters(array('StringTrim'))
|
->setFilters(array('StringTrim'))
|
||||||
->setValue(Application_Model_Preference::GetLiveStreamMasterUsername())
|
->setValue(Application_Model_Preference::GetLiveStreamMasterUsername());
|
||||||
->setDecorators(array('ViewHelper'));
|
|
||||||
$this->addElement($master_username);
|
$this->addElement($master_username);
|
||||||
|
|
||||||
//Master password
|
//Master password
|
||||||
|
@ -56,26 +56,51 @@ class Application_Form_LiveStreamingPreferences extends Zend_Form_SubForm
|
||||||
->setAttrib('renderPassword','true')
|
->setAttrib('renderPassword','true')
|
||||||
->setAllowEmpty(true)
|
->setAllowEmpty(true)
|
||||||
->setValue(Application_Model_Preference::GetLiveStreamMasterPassword())
|
->setValue(Application_Model_Preference::GetLiveStreamMasterPassword())
|
||||||
->setLabel(_('Master Password'))
|
->setLabel(_('Password:'))
|
||||||
->setFilters(array('StringTrim'))
|
->setFilters(array('StringTrim'));
|
||||||
->setDecorators(array('ViewHelper'));
|
|
||||||
$this->addElement($master_password);
|
$this->addElement($master_password);
|
||||||
|
|
||||||
//Master source connection url
|
$masterSourceParams = parse_url(Application_Model_Preference::GetMasterDJSourceConnectionURL());
|
||||||
$master_dj_connection_url = new Zend_Form_Element_Text('master_dj_connection_url');
|
|
||||||
$master_dj_connection_url->setAttrib('readonly', true)
|
|
||||||
->setLabel(_('Master Source Connection URL'))
|
|
||||||
->setValue(Application_Model_Preference::GetMasterDJSourceConnectionURL())
|
|
||||||
->setDecorators(array('ViewHelper'));
|
|
||||||
$this->addElement($master_dj_connection_url);
|
|
||||||
|
|
||||||
//Show source connection url
|
// Master source connection url parameters
|
||||||
$live_dj_connection_url = new Zend_Form_Element_Text('live_dj_connection_url');
|
$masterSourceHost = new Zend_Form_Element_Text('master_source_host');
|
||||||
$live_dj_connection_url->setAttrib('readonly', true)
|
$masterSourceHost->setAttrib('readonly', true)
|
||||||
->setLabel(_('Show Source Connection URL'))
|
->setLabel(_('Host:'))
|
||||||
->setValue(Application_Model_Preference::GetLiveDJSourceConnectionURL())
|
->setValue(isset($masterSourceParams["host"])?$masterSourceParams["host"]:"");
|
||||||
->setDecorators(array('ViewHelper'));
|
$this->addElement($masterSourceHost);
|
||||||
$this->addElement($live_dj_connection_url);
|
|
||||||
|
$masterSourcePort = new Zend_Form_Element_Text('master_source_port');
|
||||||
|
$masterSourcePort->setAttrib('readonly', true)
|
||||||
|
->setLabel(_('Port:'))
|
||||||
|
->setValue(isset($masterSourceParams["port"])?$masterSourceParams["port"]:"");
|
||||||
|
$this->addElement($masterSourcePort);
|
||||||
|
|
||||||
|
$masterSourceMount = new Zend_Form_Element_Text('master_source_mount');
|
||||||
|
$masterSourceMount->setAttrib('readonly', true)
|
||||||
|
->setLabel(_('Mount:'))
|
||||||
|
->setValue(isset($masterSourceParams["path"])?$masterSourceParams["path"]:"");
|
||||||
|
$this->addElement($masterSourceMount);
|
||||||
|
|
||||||
|
$showSourceParams = parse_url(Application_Model_Preference::GetLiveDJSourceConnectionURL());
|
||||||
|
|
||||||
|
// Show source connection url parameters
|
||||||
|
$showSourceHost = new Zend_Form_Element_Text('show_source_host');
|
||||||
|
$showSourceHost->setAttrib('readonly', true)
|
||||||
|
->setLabel(_('Host:'))
|
||||||
|
->setValue(isset($showSourceParams["host"])?$showSourceParams["host"]:"");
|
||||||
|
$this->addElement($showSourceHost);
|
||||||
|
|
||||||
|
$showSourcePort = new Zend_Form_Element_Text('show_source_port');
|
||||||
|
$showSourcePort->setAttrib('readonly', true)
|
||||||
|
->setLabel(_('Port:'))
|
||||||
|
->setValue(isset($showSourceParams["port"])?$showSourceParams["port"]:"");
|
||||||
|
$this->addElement($showSourcePort);
|
||||||
|
|
||||||
|
$showSourceMount = new Zend_Form_Element_Text('show_source_mount');
|
||||||
|
$showSourceMount->setAttrib('readonly', true)
|
||||||
|
->setLabel(_('Mount:'))
|
||||||
|
->setValue(isset($showSourceParams["path"])?$showSourceParams["path"]:"");
|
||||||
|
$this->addElement($showSourceMount);
|
||||||
|
|
||||||
// demo only code
|
// demo only code
|
||||||
if (!$isStreamConfigable) {
|
if (!$isStreamConfigable) {
|
||||||
|
@ -93,19 +118,30 @@ class Application_Form_LiveStreamingPreferences extends Zend_Form_SubForm
|
||||||
$CC_CONFIG = Config::getConfig();
|
$CC_CONFIG = Config::getConfig();
|
||||||
|
|
||||||
$isDemo = isset($CC_CONFIG['demo']) && $CC_CONFIG['demo'] == 1;
|
$isDemo = isset($CC_CONFIG['demo']) && $CC_CONFIG['demo'] == 1;
|
||||||
$master_dj_connection_url = Application_Model_Preference::GetMasterDJSourceConnectionURL();
|
$masterSourceParams = parse_url(Application_Model_Preference::GetMasterDJSourceConnectionURL());
|
||||||
$live_dj_connection_url = Application_Model_Preference::GetLiveDJSourceConnectionURL();
|
$showSourceParams = parse_url(Application_Model_Preference::GetLiveDJSourceConnectionURL());
|
||||||
|
|
||||||
$this->setDecorators(array(
|
$this->setDecorators(
|
||||||
array('ViewScript', array('viewScript' => 'form/preferences_livestream.phtml', 'master_dj_connection_url'=>$master_dj_connection_url, 'live_dj_connection_url'=>$live_dj_connection_url, 'isDemo' => $isDemo))
|
array (
|
||||||
));
|
array ('ViewScript',
|
||||||
|
array (
|
||||||
|
'viewScript' => 'form/preferences_livestream.phtml',
|
||||||
|
'master_source_host' => isset($masterSourceParams["host"])?$masterSourceParams["host"]:"",
|
||||||
|
'master_source_port' => isset($masterSourceParams["port"])?$masterSourceParams["port"]:"",
|
||||||
|
'master_source_mount' => isset($masterSourceParams["path"])?$masterSourceParams["path"]:"",
|
||||||
|
'show_source_host' => isset($showSourceParams["host"])?$showSourceParams["host"]:"",
|
||||||
|
'show_source_port' => isset($showSourceParams["port"])?$showSourceParams["port"]:"",
|
||||||
|
'show_source_mount' => isset($showSourceParams["path"])?$showSourceParams["path"]:"",
|
||||||
|
'isDemo' => $isDemo,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isValid($data)
|
public function isValid($data)
|
||||||
{
|
{
|
||||||
$isValid = parent::isValid($data);
|
return parent::isValid($data);
|
||||||
|
|
||||||
return $isValid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,9 +163,9 @@ class Application_Model_Preference
|
||||||
$sql .= " AND subjid = :id";
|
$sql .= " AND subjid = :id";
|
||||||
$paramMap[':id'] = $userId;
|
$paramMap[':id'] = $userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = Application_Common_Database::prepareAndExecute($sql, $paramMap, Application_Common_Database::COLUMN);
|
$result = Application_Common_Database::prepareAndExecute($sql, $paramMap, Application_Common_Database::COLUMN);
|
||||||
|
|
||||||
//return an empty string if the result doesn't exist.
|
//return an empty string if the result doesn't exist.
|
||||||
if ($result == 0) {
|
if ($result == 0) {
|
||||||
$res = "";
|
$res = "";
|
||||||
|
|
|
@ -17,6 +17,7 @@ class Application_Model_StoredFile
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @holds propel database object
|
* @holds propel database object
|
||||||
|
* @var CcFiles
|
||||||
*/
|
*/
|
||||||
private $_file;
|
private $_file;
|
||||||
|
|
||||||
|
@ -467,48 +468,6 @@ SQL;
|
||||||
$this->_file->save();
|
$this->_file->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getRealFileExtension() {
|
|
||||||
$path = $this->_file->getDbFilepath();
|
|
||||||
$path_elements = explode('.', $path);
|
|
||||||
if (count($path_elements) < 2) {
|
|
||||||
return "";
|
|
||||||
} else {
|
|
||||||
return $path_elements[count($path_elements) - 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return suitable extension.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
* file extension without a dot
|
|
||||||
*/
|
|
||||||
public function getFileExtension()
|
|
||||||
{
|
|
||||||
$possible_ext = $this->getRealFileExtension();
|
|
||||||
if ($possible_ext !== "") {
|
|
||||||
return $possible_ext;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We fallback to guessing the extension from the mimetype if we
|
|
||||||
// cannot extract it from the file name
|
|
||||||
|
|
||||||
$mime = $this->_file->getDbMime();
|
|
||||||
|
|
||||||
if ($mime == "audio/ogg" || $mime == "application/ogg" || $mime == "audio/vorbis") {
|
|
||||||
return "ogg";
|
|
||||||
} elseif ($mime == "audio/mp3" || $mime == "audio/mpeg") {
|
|
||||||
return "mp3";
|
|
||||||
} elseif ($mime == "audio/x-flac") {
|
|
||||||
return "flac";
|
|
||||||
} elseif ($mime == "audio/mp4") {
|
|
||||||
return "mp4";
|
|
||||||
} else {
|
|
||||||
throw new Exception("Unknown $mime");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the absolute filepath
|
* Get the absolute filepath
|
||||||
*
|
*
|
||||||
|
@ -568,7 +527,7 @@ SQL;
|
||||||
*/
|
*/
|
||||||
public function getRelativeFileUrl($baseUrl)
|
public function getRelativeFileUrl($baseUrl)
|
||||||
{
|
{
|
||||||
return $baseUrl."api/get-media/file/".$this->getId().".".$this->getFileExtension();
|
return $baseUrl."api/get-media/file/".$this->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getResourceId()
|
public function getResourceId()
|
||||||
|
|
|
@ -205,11 +205,6 @@ class CcFiles extends BaseCcFiles {
|
||||||
$cloudFile->save();
|
$cloudFile->save();
|
||||||
|
|
||||||
Application_Model_Preference::updateDiskUsage($fileSizeBytes);
|
Application_Model_Preference::updateDiskUsage($fileSizeBytes);
|
||||||
|
|
||||||
$now = new DateTime("now", new DateTimeZone("UTC"));
|
|
||||||
$file->setDbMtime($now);
|
|
||||||
$file->save();
|
|
||||||
|
|
||||||
} else if ($file) {
|
} else if ($file) {
|
||||||
|
|
||||||
// Since we check for this value when deleting files, set it first
|
// Since we check for this value when deleting files, set it first
|
||||||
|
@ -238,14 +233,13 @@ class CcFiles extends BaseCcFiles {
|
||||||
$file->setDbFilepath($filePathRelativeToStor);
|
$file->setDbFilepath($filePathRelativeToStor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$now = new DateTime("now", new DateTimeZone("UTC"));
|
|
||||||
$file->setDbMtime($now);
|
|
||||||
$file->save();
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new FileNotFoundException();
|
throw new FileNotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$now = new DateTime("now", new DateTimeZone("UTC"));
|
||||||
|
$file->setDbMtime($now);
|
||||||
|
$file->save();
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException $e)
|
catch (FileNotFoundException $e)
|
||||||
{
|
{
|
||||||
|
@ -356,17 +350,27 @@ class CcFiles extends BaseCcFiles {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Strips out the private fields we do not want to send back in API responses
|
* Strips out the private fields we do not want to send back in API responses
|
||||||
* @param $file string a CcFiles object
|
*
|
||||||
|
* @param CcFiles $file a CcFiles object
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
*/
|
*/
|
||||||
//TODO: rename this function?
|
//TODO: rename this function?
|
||||||
public static function sanitizeResponse($file)
|
public static function sanitizeResponse($file) {
|
||||||
{
|
|
||||||
$response = $file->toArray(BasePeer::TYPE_FIELDNAME);
|
$response = $file->toArray(BasePeer::TYPE_FIELDNAME);
|
||||||
|
|
||||||
foreach (self::$privateFields as $key) {
|
foreach (self::$privateFields as $key) {
|
||||||
unset($response[$key]);
|
unset($response[$key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$mime = $file->getDbMime();
|
||||||
|
if (!empty($mime)) {
|
||||||
|
// Get an extension based on the file's mime type and change the path to use this extension
|
||||||
|
$path = pathinfo($file->getDbFilepath());
|
||||||
|
$ext = FileDataHelper::getFileExtensionFromMime($mime);
|
||||||
|
$response["filepath"] = ($path["dirname"] . '/' . $path["filename"] . $ext);
|
||||||
|
}
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -455,3 +455,21 @@ class AirtimeUpgrader2513 extends AirtimeUpgrader
|
||||||
return '2.5.13';
|
return '2.5.13';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class AirtimeUpgrader2514
|
||||||
|
*
|
||||||
|
* SAAS-923 - Add a partial constraint to cc_pref so that keystrings must be unique
|
||||||
|
*/
|
||||||
|
class AirtimeUpgrader2514 extends AirtimeUpgrader
|
||||||
|
{
|
||||||
|
protected function getSupportedSchemaVersions() {
|
||||||
|
return array (
|
||||||
|
'2.5.13'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getNewVersion() {
|
||||||
|
return '2.5.14';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,13 +2,20 @@
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular.js" type="text/javascript"></script>
|
||||||
<link rel="stylesheet" href="<?php echo $this->css?>" type="text/css">
|
<link rel="stylesheet" href="<?php echo $this->css?>" type="text/css">
|
||||||
<script src="<?php echo $this->jquery ?>" type="text/javascript"></script>
|
<script src="<?php echo $this->jquery ?>" type="text/javascript"></script>
|
||||||
<link href='https://fonts.googleapis.com/css?family=Roboto:400,100,300,700' rel='stylesheet' type='text/css'>
|
<link href='https://fonts.googleapis.com/css?family=Roboto:400,100,300,700' rel='stylesheet' type='text/css'>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
|
||||||
|
//initialize first day to active
|
||||||
|
$('.tabs').find("li").first().addClass("active");
|
||||||
|
$('.schedule_content').find('.schedule_item').first().addClass("active");
|
||||||
|
|
||||||
$('.tabs li').click(function(){
|
$('.tabs li').click(function(){
|
||||||
var tab_id = $(this).attr('data-tab');
|
//var tab_id = $(this).attr('data-tab');
|
||||||
|
var tab_id = "day-"+$(this).find('span').text();
|
||||||
|
|
||||||
$('.tabs li').removeClass('active');
|
$('.tabs li').removeClass('active');
|
||||||
$('.schedule_item').removeClass('active');
|
$('.schedule_item').removeClass('active');
|
||||||
|
@ -18,38 +25,71 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
String.prototype.paddingLeft = function(paddingValue) {
|
||||||
|
return String(paddingValue + this).slice(-paddingValue.length);
|
||||||
|
};
|
||||||
|
|
||||||
|
var schedule_data = <?php echo $this->schedule_data; ?>;
|
||||||
|
|
||||||
|
var app = angular.module('scheduleWidget', []);
|
||||||
|
app.controller('scheduleController', ['$scope', '$window', function($scope, $window) {
|
||||||
|
|
||||||
|
// Loop through every show and assign it to the corresponding day of the week's
|
||||||
|
// show array.
|
||||||
|
angular.forEach($window.schedule_data["shows"], function(value, key) {
|
||||||
|
|
||||||
|
// First we have to create a Date object out of the show time in UTC.
|
||||||
|
// Then we can format the string in the client's local timezone.
|
||||||
|
// NOTE: we have to multiply the timestamp by 1000 because in PHP
|
||||||
|
// the timestamps are in seconds and are in milliseconds in javascript.
|
||||||
|
var start_date = new Date(value.starts_timestamp*1000);
|
||||||
|
var end_date = new Date(value.ends_timestamp*1000);
|
||||||
|
|
||||||
|
// This variable is used to identify which schedule_data object (which day of the week)
|
||||||
|
// we should assign the show to.
|
||||||
|
// NOTE: we have to add 1 to the month because javascript's Date.getMonth()
|
||||||
|
// function returns the month number starting with an index of 0. In PHP,
|
||||||
|
// the months are indexed starting at 1.
|
||||||
|
var format_start_date = start_date.getFullYear() + "-" + (start_date.getMonth()+1) + "-" + start_date.getDate();
|
||||||
|
|
||||||
|
if ($window.schedule_data["weekDays"][format_start_date] !== undefined) {
|
||||||
|
$window.schedule_data["weekDays"][format_start_date]["shows"].push(
|
||||||
|
{
|
||||||
|
"show_start_hour": start_date.toLocaleTimeString([], { hour: 'numeric', minute : 'numeric' }),
|
||||||
|
"show_end_hour": end_date.toLocaleTimeString([], { hour: 'numeric', minute : 'numeric' }),
|
||||||
|
"name": value.name
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Convert the object into an array to maintain the same order when we
|
||||||
|
// iterate over each weekday
|
||||||
|
$scope.weekDays = $.map($window.schedule_data["weekDays"], function(value, index) {
|
||||||
|
return [value];
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.isEmpty = function(obj) {
|
||||||
|
return obj.length == 0;
|
||||||
|
};
|
||||||
|
}]);
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body ng-app="scheduleWidget" ng-controller="scheduleController">
|
||||||
|
|
||||||
<div class="schedule tab_content current">
|
<div class="schedule tab_content current">
|
||||||
<ul class="tabs">
|
<ul class="tabs">
|
||||||
<?php
|
<li ng-repeat="x in weekDays track by $index">
|
||||||
foreach($this->weeklyScheduleData as $day => $data) {
|
{{x.dayOfWeek}}<span>{{x.dayOfMonth}}</span>
|
||||||
$activeClass = $this->currentDayOfMonth == $data["dayOfMonth"] ? "active" : "";
|
</li>
|
||||||
echo "<li class='".$activeClass."' data-tab='day-".$data["dayOfMonth"]."'>" . $data["dayOfWeek"] . "<span>" . $data["dayOfMonth"] . "</span></li>";
|
|
||||||
}?>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="schedule_content">
|
<div class="schedule_content">
|
||||||
<?php
|
<div ng-repeat="x in weekDays track by $index" ng-attr-id="{{'day-' + x.dayOfMonth}}" class="schedule_item">
|
||||||
foreach($this->weeklyScheduleData as $day => $data) {
|
<div ng-if="isEmpty(x.shows)" class="row empty-schedule">Looks like there are no shows scheduled on this day.</div>
|
||||||
$activeClass = $this->currentDayOfMonth == $data["dayOfMonth"] ? "active" : "";
|
<div ng-repeat="show in x.shows" class="row">
|
||||||
|
<div class="time_grid">{{show.show_start_hour}} - {{show.show_end_hour}}</div>
|
||||||
echo "<div id='day-".$data["dayOfMonth"]."' class='schedule_item ".$activeClass."'>";
|
<div class="name_grid">{{show.name}}</div>
|
||||||
if (count($data["shows"]) == 0) {
|
</div>
|
||||||
echo "<div class='row empty-schedule'>Looks like there are no shows scheduled on this day.</div>";
|
</div>
|
||||||
} else {
|
|
||||||
foreach ($data["shows"] as $show => $showData) {
|
|
||||||
echo "<div class='row'>";
|
|
||||||
echo "<div class='time_grid'>" . $showData["show_start_hour"] . ' - ' . $showData["show_end_hour"] . "</div>";
|
|
||||||
echo "<div class='name_grid'>" . $showData["name"] . "</div>";
|
|
||||||
echo "</div>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
echo "</div>";
|
|
||||||
}?>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="weekly-schedule-widget-footer" <?php if ($this->widgetStyle == "premium") echo "style='display:none'"; ?>>
|
<div class="weekly-schedule-widget-footer" <?php if ($this->widgetStyle == "premium") echo "style='display:none'"; ?>>
|
||||||
|
|
|
@ -1,60 +1,20 @@
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<dl>
|
<dl>
|
||||||
<dt id="cb_airtime_auth_override-label">
|
<?php echo $this->element->getElement('cb_airtime_auth')->render(); ?>
|
||||||
<label class="optional" for="cb_airtime_auth">
|
<?php echo $this->element->getElement('cb_custom_auth')->render(); ?>
|
||||||
<?php echo $this->element->getElement('cb_airtime_auth')->getLabel() ?>
|
|
||||||
<span class='airtime_auth_help_icon'></span>
|
|
||||||
</label>
|
|
||||||
</dt>
|
|
||||||
<dd id="cb_airtime_auth_override-element">
|
|
||||||
<?php echo $this->element->getElement('cb_airtime_auth') ?>
|
|
||||||
</dd>
|
|
||||||
<dt id="cb_custom_auth_override-label">
|
|
||||||
<label class="optional" for="cb_custom_auth">
|
|
||||||
<?php echo $this->element->getElement('cb_custom_auth')->getLabel() ?>
|
|
||||||
<span class='custom_auth_help_icon'></span>
|
|
||||||
</label>
|
|
||||||
</dt>
|
|
||||||
<dd id="cb_custom_auth_override-element">
|
|
||||||
<?php echo $this->element->getElement('cb_custom_auth') ?>
|
|
||||||
</dd>
|
|
||||||
<div id="custom_auth_div">
|
<div id="custom_auth_div">
|
||||||
<dt id="custom_username-label" class="block-display">
|
<?php echo $this->element->getElement('custom_username')->render(); ?>
|
||||||
<label class="optional" for="custom_username"><?php echo $this->element->getElement('custom_username')->getLabel() ?> :
|
<?php echo $this->element->getElement('custom_password')->render(); ?>
|
||||||
<span class='stream_username_help_icon'></span>
|
|
||||||
</label>
|
|
||||||
</dt>
|
|
||||||
<dd id="custom_username-element" class="block-display">
|
|
||||||
<?php echo $this->element->getElement('custom_username') ?>
|
|
||||||
<?php if($this->element->getElement('custom_username')->hasErrors()) : ?>
|
|
||||||
<ul class='errors'>
|
|
||||||
<?php foreach($this->element->getElement('custom_username')->getMessages() as $error): ?>
|
|
||||||
<li><?php echo $error; ?></li>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</ul>
|
|
||||||
<?php endif; ?>
|
|
||||||
</dd>
|
|
||||||
<dt id="custom_password-label" class="block-display">
|
|
||||||
<label class="optional" for="custom_password"><?php echo $this->element->getElement('custom_password')->getLabel() ?> :
|
|
||||||
</label>
|
|
||||||
</dt>
|
|
||||||
<dd id="custom_password-element" class="block-display">
|
|
||||||
<?php echo $this->element->getElement('custom_password') ?>
|
|
||||||
<?php if($this->element->getElement('custom_password')->hasErrors()) : ?>
|
|
||||||
<ul class='errors'>
|
|
||||||
<?php foreach($this->element->getElement('custom_password')->getMessages() as $error): ?>
|
|
||||||
<li><?php echo $error; ?></li>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</ul>
|
|
||||||
<?php endif; ?>
|
|
||||||
</dd>
|
|
||||||
</div>
|
</div>
|
||||||
<dt id="Connection_URL-label">
|
<fieldset>
|
||||||
<label for="outputStreamURL"><?php echo _("Connection URL: "); ?></label>
|
<legend><?php echo _("Show Source") ?></legend>
|
||||||
</dt>
|
<p class="input-settings-inline-p">
|
||||||
<dd id="Connection_URL-element">
|
<?php echo _("DJs can use these settings to connect with compatible software and broadcast live during this show. Assign a DJ below.") ?>
|
||||||
<span id="stream_url" class="static_text"><?php echo $this->connection_url; ?></span>
|
</p>
|
||||||
</dd>
|
<?php echo $this->element->getElement("show_source_host")->render() ?>
|
||||||
|
<?php echo $this->element->getElement("show_source_port")->render() ?>
|
||||||
|
<?php echo $this->element->getElement("show_source_mount")->render() ?>
|
||||||
|
</fieldset>
|
||||||
</dl>
|
</dl>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
|
|
|
@ -1,102 +1,34 @@
|
||||||
<fieldset class="padded stream-setting-global" style="margin-top: 15px">
|
<fieldset class="padded stream-setting-global" style="margin-top: 15px">
|
||||||
<legend><?php echo _("Input Stream Settings") ?></legend>
|
<legend><?php echo _("Input Stream Settings") ?></legend>
|
||||||
<dl class="zend_form">
|
<dl class="zend_form">
|
||||||
<dt id="auto_transition-label">
|
<?php echo $this->element->getElement('auto_transition')->render() ?>
|
||||||
<label class="optional" for="auto_transition"><?php echo $this->element->getElement('auto_transition')->getLabel() ?> :
|
<span class="icecast_metadata_help_icon" id="auto_transition_help"></span>
|
||||||
<span class="icecast_metadata_help_icon" id="auto_transition_help">
|
<?php echo $this->element->getElement('auto_switch')->render() ?>
|
||||||
</span>
|
<span class="icecast_metadata_help_icon" id="auto_switch_help"></span>
|
||||||
</label>
|
<?php echo $this->element->getElement('transition_fade')->render() ?>
|
||||||
</dt>
|
|
||||||
<dd id="auto_transition-element">
|
<fieldset class="padded stream-setting-global" style="margin-top: 15px">
|
||||||
<?php echo $this->element->getElement('auto_transition') ?>
|
<legend><?php echo _("Master Source") ?></legend>
|
||||||
<?php if($this->element->getElement('auto_transition')->hasErrors()) : ?>
|
<p class="input-settings-inline-p">
|
||||||
<ul class='errors'>
|
<?php echo _("Use these settings in your broadcasting software to stream live at any time.") ?>
|
||||||
<?php foreach($this->element->getElement('auto_transition')->getMessages() as $error): ?>
|
</p>
|
||||||
<li><?php echo $error; ?></li>
|
<?php echo $this->element->getElement('master_username')->render() ?>
|
||||||
<?php endforeach; ?>
|
<span class="master_username_help_icon"></span>
|
||||||
</ul>
|
<?php echo $this->element->getElement('master_password')->render() ?>
|
||||||
<?php endif; ?>
|
|
||||||
</dd>
|
<?php echo $this->element->getElement("master_source_host")->render() ?>
|
||||||
<dt id="auto_switch-label">
|
<?php echo $this->element->getElement("master_source_port")->render() ?>
|
||||||
<label class="optional" for="auto_transition"><?php echo $this->element->getElement('auto_switch')->getLabel() ?> :
|
<?php echo $this->element->getElement("master_source_mount")->render() ?>
|
||||||
<span class="icecast_metadata_help_icon" id="auto_switch_help">
|
</fieldset>
|
||||||
</span>
|
|
||||||
</label>
|
<fieldset class="padded stream-setting-global" style="margin-top: 15px">
|
||||||
</dt>
|
<legend><?php echo _("Show Source") ?></legend>
|
||||||
<dd id="auto_switch-element">
|
<p class="input-settings-inline-p">
|
||||||
<?php echo $this->element->getElement('auto_switch') ?>
|
<?php echo _("DJs can use these settings in their broadcasting software to broadcast live only during shows assigned to them.") ?>
|
||||||
<?php if($this->element->getElement('auto_switch')->hasErrors()) : ?>
|
</p>
|
||||||
<ul class='errors'>
|
<?php echo $this->element->getElement("show_source_host")->render() ?>
|
||||||
<?php foreach($this->element->getElement('auto_switch')->getMessages() as $error): ?>
|
<?php echo $this->element->getElement("show_source_port")->render() ?>
|
||||||
<li><?php echo $error; ?></li>
|
<?php echo $this->element->getElement("show_source_mount")->render() ?>
|
||||||
<?php endforeach; ?>
|
</fieldset>
|
||||||
</ul>
|
|
||||||
<?php endif; ?>
|
|
||||||
</dd>
|
|
||||||
<dt id="transition_fade-label">
|
|
||||||
<label class="optional" for="transition_fade"><?php echo $this->element->getElement('transition_fade')->getLabel() ?> :
|
|
||||||
</label>
|
|
||||||
</dt>
|
|
||||||
<dd id="transition_fade-element">
|
|
||||||
<?php echo $this->element->getElement('transition_fade') ?>
|
|
||||||
<?php if($this->element->getElement('transition_fade')->hasErrors()) : ?>
|
|
||||||
<ul class='errors'>
|
|
||||||
<?php foreach($this->element->getElement('transition_fade')->getMessages() as $error): ?>
|
|
||||||
<li><?php echo $error; ?></li>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</ul>
|
|
||||||
<?php endif; ?>
|
|
||||||
</dd>
|
|
||||||
<dt id="master_username-label">
|
|
||||||
<label class="optional" for="master_username"><?php echo $this->element->getElement('master_username')->getLabel() ?> :
|
|
||||||
<span class='master_username_help_icon'></span>
|
|
||||||
</label>
|
|
||||||
</dt>
|
|
||||||
<dd id="master_username-element">
|
|
||||||
<?php echo $this->element->getElement('master_username') ?>
|
|
||||||
<?php if($this->element->getElement('master_username')->hasErrors()) : ?>
|
|
||||||
<ul class='errors'>
|
|
||||||
<?php foreach($this->element->getElement('master_username')->getMessages() as $error): ?>
|
|
||||||
<li><?php echo $error; ?></li>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</ul>
|
|
||||||
<?php endif; ?>
|
|
||||||
</dd>
|
|
||||||
<dt id="master_password-label">
|
|
||||||
<label class="optional" for="master_password"><?php echo $this->element->getElement('master_password')->getLabel() ?> :
|
|
||||||
</label>
|
|
||||||
</dt>
|
|
||||||
<dd id="master_password-element">
|
|
||||||
<?php echo $this->element->getElement('master_password') ?>
|
|
||||||
<?php if($this->element->getElement('master_password')->hasErrors()) : ?>
|
|
||||||
<ul class='errors'>
|
|
||||||
<?php foreach($this->element->getElement('master_password')->getMessages() as $error): ?>
|
|
||||||
<li><?php echo $error; ?></li>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</ul>
|
|
||||||
<?php endif; ?>
|
|
||||||
</dd>
|
|
||||||
<dt id="master_dj_connection_url-label">
|
|
||||||
<label class="optional" for="master_dj_connection_url" style="white-space: nowrap">
|
|
||||||
<?php echo _("Master Source Connection URL:")?>
|
|
||||||
</label>
|
|
||||||
</dt>
|
|
||||||
<dd id="master_dj_connection_url-element">
|
|
||||||
<span id="stream_url"><?php echo $this->element->getElement('master_dj_connection_url')->setValue($this->master_dj_connection_url) ?></span>
|
|
||||||
<div id="master_dj_connection_url_actions" style="display:none">
|
|
||||||
<a href=# id="ok" style="font-size: 12px;"><?php echo _("OK") ?></a> <a href=# id="reset" style="font-size: 12px;"><?php echo _("RESET"); ?></a>
|
|
||||||
</div>
|
|
||||||
</dd>
|
|
||||||
<dt id="live_dj_connection_url-label">
|
|
||||||
<label class="optional" for="live_dj_connection_url" style="white-space: nowrap">
|
|
||||||
<?php echo _("Show Source Connection URL:")?>
|
|
||||||
</label>
|
|
||||||
</dt>
|
|
||||||
<dd id="live_dj_connection_url-element">
|
|
||||||
<span id="stream_url"><?php echo $this->element->getElement('live_dj_connection_url')->setValue($this->live_dj_connection_url) ?></span>
|
|
||||||
<div id="live_dj_connection_url_actions" style="display:none">
|
|
||||||
<a href=# id="ok" style="font-size: 12px;"><?php echo _("OK") ?></a> <a href=# id="reset" style="font-size: 12px;"><?php echo _("RESET"); ?></a>
|
|
||||||
</div>
|
|
||||||
</dd>
|
|
||||||
</dl>
|
</dl>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
|
@ -376,3 +376,11 @@ INSERT INTO cc_stream_setting ("keyname", "value", "type") VALUES ('s4_descripti
|
||||||
INSERT INTO cc_stream_setting ("keyname", "value", "type") VALUES ('s4_genre', '', 'string');
|
INSERT INTO cc_stream_setting ("keyname", "value", "type") VALUES ('s4_genre', '', 'string');
|
||||||
INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s4_channels', 'stereo', 'string');
|
INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s4_channels', 'stereo', 'string');
|
||||||
|
|
||||||
|
-- added in 2.5.14 - this can't be set up in Propel's XML schema, so we need to do it here -- Duncan
|
||||||
|
|
||||||
|
ALTER TABLE cc_pref ALTER COLUMN subjid SET NULL;
|
||||||
|
ALTER TABLE cc_pref ALTER COLUMN subjid SET DEFAULT NULL;
|
||||||
|
CREATE UNIQUE INDEX cc_pref_key_idx ON cc_pref (keystr) WHERE subjid IS NULL;
|
||||||
|
ANALYZE cc_pref; -- this validates the new partial index
|
||||||
|
|
||||||
|
--end added in 2.5.14
|
||||||
|
|
|
@ -123,7 +123,7 @@ background: rgba(53, 53, 53, 1.0);
|
||||||
|
|
||||||
.schedule_item div.time_grid {
|
.schedule_item div.time_grid {
|
||||||
/*padding-right: 10px;*/
|
/*padding-right: 10px;*/
|
||||||
width: 20%;
|
width: 30%;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
color: #AAAAAA;
|
color: #AAAAAA;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -133,7 +133,7 @@ background: rgba(53, 53, 53, 1.0);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
width: 77%;
|
width: 67%;
|
||||||
display:inline-block;
|
display:inline-block;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
@ -182,11 +182,11 @@ background: rgba(53, 53, 53, 1.0);
|
||||||
|
|
||||||
@media (max-width: 630px) {
|
@media (max-width: 630px) {
|
||||||
.schedule_item div.time_grid {
|
.schedule_item div.time_grid {
|
||||||
width: 25%;
|
width: 37%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.schedule_item div.name_grid {
|
.schedule_item div.name_grid {
|
||||||
width: 72%;
|
width: 58%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,31 +197,31 @@ background: rgba(53, 53, 53, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
.schedule_item div.time_grid {
|
.schedule_item div.time_grid {
|
||||||
width: 30%;
|
width: 35%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.schedule_item div.name_grid {
|
.schedule_item div.name_grid {
|
||||||
width: 67%;
|
width: 60%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 500px) {
|
@media (max-width: 500px) {
|
||||||
.schedule_item div.time_grid {
|
.schedule_item div.time_grid {
|
||||||
width: 35%;
|
width: 40%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.schedule_item div.name_grid {
|
.schedule_item div.name_grid {
|
||||||
width: 62%;
|
width: 55%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 400px) {
|
@media (max-width: 400px) {
|
||||||
.schedule_item div.time_grid {
|
.schedule_item div.time_grid {
|
||||||
width: 40%;
|
width: 90%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.schedule_item div.name_grid {
|
.schedule_item div.name_grid {
|
||||||
width: 50%;
|
width: 90%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,7 @@ body {
|
||||||
|
|
||||||
.schedule_item div.time_grid {
|
.schedule_item div.time_grid {
|
||||||
/*padding-right: 10px;*/
|
/*padding-right: 10px;*/
|
||||||
width: 20%;
|
width: 30%;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
color: #AAAAAA;
|
color: #AAAAAA;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -107,7 +107,7 @@ body {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
width: 77%;
|
width: 67%;
|
||||||
display:inline-block;
|
display:inline-block;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
@ -132,11 +132,11 @@ body {
|
||||||
|
|
||||||
@media (max-width: 630px) {
|
@media (max-width: 630px) {
|
||||||
.schedule_item div.time_grid {
|
.schedule_item div.time_grid {
|
||||||
width: 25%;
|
width: 37%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.schedule_item div.name_grid {
|
.schedule_item div.name_grid {
|
||||||
width: 72%;
|
width: 58%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,31 +147,31 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.schedule_item div.time_grid {
|
.schedule_item div.time_grid {
|
||||||
width: 30%;
|
width: 35%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.schedule_item div.name_grid {
|
.schedule_item div.name_grid {
|
||||||
width: 67%;
|
width: 60%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 500px) {
|
@media (max-width: 500px) {
|
||||||
.schedule_item div.time_grid {
|
.schedule_item div.time_grid {
|
||||||
width: 35%;
|
width: 40%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.schedule_item div.name_grid {
|
.schedule_item div.name_grid {
|
||||||
width: 62%;
|
width: 55%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 400px) {
|
@media (max-width: 400px) {
|
||||||
.schedule_item div.time_grid {
|
.schedule_item div.time_grid {
|
||||||
width: 40%;
|
width: 90%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.schedule_item div.name_grid {
|
.schedule_item div.name_grid {
|
||||||
width: 50%;
|
width: 90%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,11 @@ select {
|
||||||
border:1px solid #9d9d9d;
|
border:1px solid #9d9d9d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fix for Firefox */
|
||||||
|
fieldset {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
background: transparent url(images/airtime_logo.png) no-repeat 0 0;
|
background: transparent url(images/airtime_logo.png) no-repeat 0 0;
|
||||||
height: 35px;
|
height: 35px;
|
||||||
|
@ -111,19 +116,38 @@ select {
|
||||||
margin-left: 7px !important;
|
margin-left: 7px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.override_help_icon, .icecast_metadata_help_icon {
|
.override_help_icon, .icecast_metadata_help_icon, .master_username_help_icon {
|
||||||
cursor: help;
|
cursor: help;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
display:inline-block; zoom:1; display:inline;
|
display: inline-block;
|
||||||
width:14px; height:14px;
|
zoom:1;
|
||||||
background:url(images/icon_info.png) 0 0 no-repeat;
|
width:14px; height:14px;
|
||||||
float:right; position:relative; top:2px; right:7px;
|
background:url(images/icon_info.png) 0 0 no-repeat;
|
||||||
line-height:16px !important;
|
float:right;
|
||||||
|
top:2px;
|
||||||
|
right:7px;
|
||||||
|
line-height:16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#auto_switch_help, #auto_transition_help {
|
||||||
|
right: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.master_username_help_icon {
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-settings-inline-p {
|
||||||
|
color: #4F4F4F;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 140%;
|
||||||
|
margin-top: 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.airtime_auth_help_icon, .custom_auth_help_icon, .stream_username_help_icon,
|
.airtime_auth_help_icon, .custom_auth_help_icon, .stream_username_help_icon,
|
||||||
.playlist_type_help_icon, .master_username_help_icon, .repeat_tracks_help_icon,
|
.playlist_type_help_icon, .repeat_tracks_help_icon,
|
||||||
.admin_username_help_icon, .stream_type_help_icon, .show_linking_help_icon,
|
.admin_username_help_icon, .stream_type_help_icon, .show_linking_help_icon,
|
||||||
.show_timezone_help_icon{
|
.show_timezone_help_icon{
|
||||||
cursor: help;
|
cursor: help;
|
||||||
|
@ -1510,7 +1534,7 @@ h2#scheduled_playlist_name span {
|
||||||
border-color:#343434;
|
border-color:#343434;
|
||||||
border-width: 1px 0 0 1px;
|
border-width: 1px 0 0 1px;
|
||||||
}
|
}
|
||||||
/*---//////////////////// Advenced Search ////////////////////---*/
|
/*---//////////////////// Advanced Search ////////////////////---*/
|
||||||
|
|
||||||
.search_control {
|
.search_control {
|
||||||
padding:8px;
|
padding:8px;
|
||||||
|
|
|
@ -63,6 +63,12 @@ if (file_exists($filename)) {
|
||||||
}
|
}
|
||||||
// Otherwise, we'll need to run our configuration setup
|
// Otherwise, we'll need to run our configuration setup
|
||||||
else {
|
else {
|
||||||
|
// Sometimes we can get into a weird NFS state where a station's airtime.conf has
|
||||||
|
// been neg-cached - redirect to a 404 instead until the NFS cache is updated
|
||||||
|
if (strpos($_SERVER['SERVER_NAME'], "airtime.pro") !== false) {
|
||||||
|
header($_SERVER['SERVER_PROTOCOL'] . ' 404 Page Not Found', true, 404);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
$airtimeSetup = true;
|
$airtimeSetup = true;
|
||||||
require_once(SETUP_PATH . 'setup-config.php');
|
require_once(SETUP_PATH . 'setup-config.php');
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
var _playlist_jplayer;
|
var _playlist_jplayer;
|
||||||
var _idToPostionLookUp;
|
var _idToPostionLookUp;
|
||||||
|
var URL_BAR_HEIGHT = 32;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*When the page loads the ready function will get all the data it can from the hidden span elements
|
*When the page loads the ready function will get all the data it can from the hidden span elements
|
||||||
*and call one of three functions depending on weather the window was open to play an audio file,
|
*and call one of three functions depending on weather the window was open to play an audio file,
|
||||||
*or a playlist or a show.
|
*or a playlist or a show.
|
||||||
*/
|
*/
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
|
|
||||||
$.jPlayer.timeFormat.showHour = true;
|
$.jPlayer.timeFormat.showHour = true;
|
||||||
|
|
||||||
var audioUri = $('.audioUri').text();
|
var audioUri = $('.audioUri').text();
|
||||||
|
@ -57,7 +58,7 @@ $(document).ready(function(){
|
||||||
$("#jp_container_1").on("mouseenter", "ul.jp-controls li", function(ev) {
|
$("#jp_container_1").on("mouseenter", "ul.jp-controls li", function(ev) {
|
||||||
$(this).addClass("ui-state-hover");
|
$(this).addClass("ui-state-hover");
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#jp_container_1").on("mouseleave", "ul.jp-controls li", function(ev) {
|
$("#jp_container_1").on("mouseleave", "ul.jp-controls li", function(ev) {
|
||||||
$(this).removeClass("ui-state-hover");
|
$(this).removeClass("ui-state-hover");
|
||||||
});
|
});
|
||||||
|
@ -65,14 +66,14 @@ $(document).ready(function(){
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets up the jPlayerPlaylist to play.
|
* Sets up the jPlayerPlaylist to play.
|
||||||
* - Get the playlist info based on the playlistID give.
|
* - Get the playlist info based on the playlistID give.
|
||||||
* - Update the playlistIndex to the position in the pllist to start playing.
|
* - Update the playlistIndex to the position in the pllist to start playing.
|
||||||
* - Select the element played from and start playing. If playlist is null then start at index 0.
|
* - Select the element played from and start playing. If playlist is null then start at index 0.
|
||||||
**/
|
**/
|
||||||
function playAllPlaylist(p_playlistID, p_playlistIndex) {
|
function playAllPlaylist(p_playlistID, p_playlistIndex) {
|
||||||
var viewsPlaylistID = $('.playlistID').text();
|
var viewsPlaylistID = $('.playlistID').text();
|
||||||
|
|
||||||
if ( _idToPostionLookUp !== undefined && viewsPlaylistID == p_playlistID ) {
|
if ( _idToPostionLookUp !== undefined && viewsPlaylistID == p_playlistID ) {
|
||||||
play(p_playlistIndex);
|
play(p_playlistIndex);
|
||||||
}else {
|
}else {
|
||||||
|
@ -83,7 +84,7 @@ function playAllPlaylist(p_playlistID, p_playlistIndex) {
|
||||||
function playBlock(p_blockId, p_blockIndex)
|
function playBlock(p_blockId, p_blockIndex)
|
||||||
{
|
{
|
||||||
var viewsBlockId = $('.blockId').text();
|
var viewsBlockId = $('.blockId').text();
|
||||||
|
|
||||||
if ( _idToPostionLookUp !== undefined && viewsBlockId == p_blockId ) {
|
if ( _idToPostionLookUp !== undefined && viewsBlockId == p_blockId ) {
|
||||||
play(p_blockIndex);
|
play(p_blockIndex);
|
||||||
} else {
|
} else {
|
||||||
|
@ -92,15 +93,15 @@ function playBlock(p_blockId, p_blockIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets up the show to play.
|
* Sets up the show to play.
|
||||||
* checks with the show id given to the show id on the page/view
|
* checks with the show id given to the show id on the page/view
|
||||||
* if the show id and the page or views show id are the same it means the user clicked another
|
* if the show id and the page or views show id are the same it means the user clicked another
|
||||||
* file in the same show, so don't refresh the show content tust play the track from the preloaded show.
|
* file in the same show, so don't refresh the show content tust play the track from the preloaded show.
|
||||||
* if the the ids are different they we'll need to get the show's context so create the uri
|
* if the the ids are different they we'll need to get the show's context so create the uri
|
||||||
* and call the controller.
|
* and call the controller.
|
||||||
**/
|
**/
|
||||||
function playAllShow(p_showID, p_index) {
|
function playAllShow(p_showID, p_index) {
|
||||||
|
|
||||||
var viewsShowID = $('.showID').text();
|
var viewsShowID = $('.showID').text();
|
||||||
if ( _idToPostionLookUp !== undefined && viewsShowID == p_showID ) {
|
if ( _idToPostionLookUp !== undefined && viewsShowID == p_showID ) {
|
||||||
play(p_index);
|
play(p_index);
|
||||||
|
@ -110,12 +111,12 @@ function playAllShow(p_showID, p_index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function will call the AudiopreviewController to get the contents of
|
* This function will call the AudiopreviewController to get the contents of
|
||||||
* either a show or playlist Looping throught the returned contents and
|
* either a show or playlist Looping throught the returned contents and
|
||||||
* creating media for each track.
|
* creating media for each track.
|
||||||
*
|
*
|
||||||
* Then trigger the jplayer to play the list.
|
* Then trigger the jplayer to play the list.
|
||||||
*/
|
*/
|
||||||
function buildplaylist(p_url, p_playIndex) {
|
function buildplaylist(p_url, p_playIndex) {
|
||||||
_idToPostionLookUp = Array();
|
_idToPostionLookUp = Array();
|
||||||
$.getJSON(p_url, function(data){ // get the JSON array produced by my PHP
|
$.getJSON(p_url, function(data){ // get the JSON array produced by my PHP
|
||||||
|
@ -126,7 +127,7 @@ function buildplaylist(p_url, p_playIndex) {
|
||||||
var skipped = 0;
|
var skipped = 0;
|
||||||
|
|
||||||
for(index in data) {
|
for(index in data) {
|
||||||
if (data[index]['type'] == 0) {
|
if (data[index]['type'] == 0) {
|
||||||
if (data[index]['element_mp3'] != undefined){
|
if (data[index]['element_mp3'] != undefined){
|
||||||
media = {title: data[index]['element_title'],
|
media = {title: data[index]['element_title'],
|
||||||
artist: data[index]['element_artist'],
|
artist: data[index]['element_artist'],
|
||||||
|
@ -152,7 +153,7 @@ function buildplaylist(p_url, p_playIndex) {
|
||||||
console.log("continue");
|
console.log("continue");
|
||||||
skipped++;
|
skipped++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if (data[index]['type'] == 1) {
|
} else if (data[index]['type'] == 1) {
|
||||||
var mime = data[index]['mime'];
|
var mime = data[index]['mime'];
|
||||||
if (mime.search(/mp3/i) > 0 || mime.search(/mpeg/i) > 0) {
|
if (mime.search(/mp3/i) > 0 || mime.search(/mpeg/i) > 0) {
|
||||||
|
@ -163,12 +164,12 @@ function buildplaylist(p_url, p_playIndex) {
|
||||||
key = "m4a";
|
key = "m4a";
|
||||||
} else if (mime.search(/wav/i) > 0) {
|
} else if (mime.search(/wav/i) > 0) {
|
||||||
key = "wav";
|
key = "wav";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key) {
|
if (key) {
|
||||||
media = {title: data[index]['element_title'],
|
media = {title: data[index]['element_title'],
|
||||||
artist: data[index]['element_artist']
|
artist: data[index]['element_artist']
|
||||||
};
|
};
|
||||||
media[key] = data[index]['uri']
|
media[key] = data[index]['uri']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,26 +187,19 @@ function buildplaylist(p_url, p_playIndex) {
|
||||||
_playlist_jplayer.setPlaylist(myPlaylist);
|
_playlist_jplayer.setPlaylist(myPlaylist);
|
||||||
_playlist_jplayer.option("autoPlay", true);
|
_playlist_jplayer.option("autoPlay", true);
|
||||||
play(p_playIndex);
|
play(p_playIndex);
|
||||||
|
|
||||||
var height = Math.min(143 + (26 * total), 400);
|
window.scrollbars = false;
|
||||||
var width = 505;
|
|
||||||
|
var container = $("#jp_container_1");
|
||||||
if (height === 400) {
|
// Add 2px to account for borders
|
||||||
window.scrollbars = true;
|
window.resizeTo(container.width() + 2, container.height() + URL_BAR_HEIGHT + 2);
|
||||||
}
|
|
||||||
else {
|
|
||||||
//there's no scrollbars so we don't need the window to be as wide.
|
|
||||||
width = 490;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.resizeTo(width, height);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*Function simply plays the given index, for playlists index can be different so need to look up the
|
*Function simply plays the given index, for playlists index can be different so need to look up the
|
||||||
*right index.
|
*right index.
|
||||||
*/
|
*/
|
||||||
function play(p_playlistIndex){
|
function play(p_playlistIndex){
|
||||||
playlistIndex = _idToPostionLookUp[p_playlistIndex];
|
playlistIndex = _idToPostionLookUp[p_playlistIndex];
|
||||||
if(playlistIndex == undefined){
|
if(playlistIndex == undefined){
|
||||||
|
@ -216,13 +210,13 @@ function play(p_playlistIndex){
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Playing one audio track occurs from the library. This function will create the media, setup
|
* Playing one audio track occurs from the library. This function will create the media, setup
|
||||||
* jplayer and play the track.
|
* jplayer and play the track.
|
||||||
*/
|
*/
|
||||||
function playOne(uri, mime) {
|
function playOne(uri, mime) {
|
||||||
var playlist = new Array();
|
var playlist = new Array();
|
||||||
|
|
||||||
var media = null;
|
var media = null;
|
||||||
var key = null;
|
var key = null;
|
||||||
if (mime.search(/mp3/i) > 0 || mime.search(/mpeg/i) > 0) {
|
if (mime.search(/mp3/i) > 0 || mime.search(/mpeg/i) > 0) {
|
||||||
key = "mp3";
|
key = "mp3";
|
||||||
|
@ -232,12 +226,12 @@ function playOne(uri, mime) {
|
||||||
key = "m4a";
|
key = "m4a";
|
||||||
} else if (mime.search(/wav/i) > 0) {
|
} else if (mime.search(/wav/i) > 0) {
|
||||||
key = "wav";
|
key = "wav";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key) {
|
if (key) {
|
||||||
media = {title: $('.audioFileTitle').text() != 'null' ?$('.audioFileTitle').text():"",
|
media = {title: $('.audioFileTitle').text() != 'null' ?$('.audioFileTitle').text():"",
|
||||||
artist: $('.audioFileArtist').text() != 'null' ?$('.audioFileArtist').text():""
|
artist: $('.audioFileArtist').text() != 'null' ?$('.audioFileArtist').text():""
|
||||||
};
|
};
|
||||||
media[key] = uri;
|
media[key] = uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,4 +241,8 @@ function playOne(uri, mime) {
|
||||||
_playlist_jplayer.setPlaylist(playlist);
|
_playlist_jplayer.setPlaylist(playlist);
|
||||||
_playlist_jplayer.play(0);
|
_playlist_jplayer.play(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var container = $("#jp_container_1");
|
||||||
|
// Add 2px to account for borders
|
||||||
|
window.resizeTo(container.width() + 2, container.height() + URL_BAR_HEIGHT + 2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
var previewWidth = 482,
|
||||||
|
previewHeight = 110;
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
|
||||||
/* Removed as this is now (hopefully) unnecessary */
|
/* Removed as this is now (hopefully) unnecessary */
|
||||||
|
@ -95,7 +98,7 @@ function open_audio_preview(type, id) {
|
||||||
// The reason that we need to encode artist and title string is that
|
// The reason that we need to encode artist and title string is that
|
||||||
// sometime they contain '/' or '\' and apache reject %2f or %5f
|
// sometime they contain '/' or '\' and apache reject %2f or %5f
|
||||||
// so the work around is to encode it twice.
|
// so the work around is to encode it twice.
|
||||||
openPreviewWindow(baseUrl+'audiopreview/audio-preview/audioFileID/'+id+'/type/'+type);
|
openPreviewWindow(baseUrl+'audiopreview/audio-preview/audioFileID/'+id+'/type/'+type, previewWidth, previewHeight);
|
||||||
_preview_window.focus();
|
_preview_window.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +116,7 @@ function open_playlist_preview(p_playlistID, p_playlistIndex) {
|
||||||
if (_preview_window != null && !_preview_window.closed)
|
if (_preview_window != null && !_preview_window.closed)
|
||||||
_preview_window.playAllPlaylist(p_playlistID, p_playlistIndex);
|
_preview_window.playAllPlaylist(p_playlistID, p_playlistIndex);
|
||||||
else
|
else
|
||||||
openPreviewWindow(baseUrl+'audiopreview/playlist-preview/playlistIndex/'+p_playlistIndex+'/playlistID/'+p_playlistID);
|
openPreviewWindow(baseUrl+'audiopreview/playlist-preview/playlistIndex/'+p_playlistIndex+'/playlistID/'+p_playlistID, previewWidth, previewHeight);
|
||||||
_preview_window.focus();
|
_preview_window.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +127,7 @@ function open_block_preview(p_blockId, p_blockIndex) {
|
||||||
if (_preview_window != null && !_preview_window.closed)
|
if (_preview_window != null && !_preview_window.closed)
|
||||||
_preview_window.playBlock(p_blockId, p_blockIndex);
|
_preview_window.playBlock(p_blockId, p_blockIndex);
|
||||||
else
|
else
|
||||||
openPreviewWindow(baseUrl+'audiopreview/block-preview/blockIndex/'+p_blockIndex+'/blockId/'+p_blockId);
|
openPreviewWindow(baseUrl+'audiopreview/block-preview/blockIndex/'+p_blockIndex+'/blockId/'+p_blockId, previewWidth, previewHeight);
|
||||||
_preview_window.focus();
|
_preview_window.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,13 +141,14 @@ function open_show_preview(p_showID, p_showIndex) {
|
||||||
if (_preview_window != null && !_preview_window.closed)
|
if (_preview_window != null && !_preview_window.closed)
|
||||||
_preview_window.playAllShow(p_showID, p_showIndex);
|
_preview_window.playAllShow(p_showID, p_showIndex);
|
||||||
else
|
else
|
||||||
openPreviewWindow(baseUrl+'audiopreview/show-preview/showID/'+p_showID+'/showIndex/'+p_showIndex);
|
openPreviewWindow(baseUrl+'audiopreview/show-preview/showID/'+p_showID+'/showIndex/'+p_showIndex, previewWidth, previewHeight);
|
||||||
_preview_window.focus();
|
_preview_window.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
function openPreviewWindow(url) {
|
function openPreviewWindow(url, w, h) {
|
||||||
|
var dim = (w && h) ? 'width=' + w + ',height=' + h + ',' : '';
|
||||||
// Hardcoding this here is kinda gross, but the alternatives aren't much better...
|
// Hardcoding this here is kinda gross, but the alternatives aren't much better...
|
||||||
_preview_window = window.open(url, $.i18n._('Audio Player'), 'width=482,height=110,scrollbars=yes');
|
_preview_window = window.open(url, $.i18n._('Audio Player'), dim + 'scrollbars=yes');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -786,6 +786,11 @@ function setAddShowEvents(form) {
|
||||||
scheduleRefetchEvents(json);
|
scheduleRefetchEvents(json);
|
||||||
$addShowForm.hide();
|
$addShowForm.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* CC-6062: Resize the window to avoid stretching the last column */
|
||||||
|
windowResize();
|
||||||
|
makeAddShowButton();
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
37
install
37
install
|
@ -312,6 +312,17 @@ else
|
||||||
checkCommandExists "psql"
|
checkCommandExists "psql"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Check if composer exists and install if it doesn't
|
||||||
|
eval hash "composer" 2>/dev/null
|
||||||
|
commandFound=$?
|
||||||
|
if [[ ! ${commandFound} -eq 0 ]]; then
|
||||||
|
curl -sS https://getcomposer.org/installer | php
|
||||||
|
mv composer.phar /usr/local/bin/composer
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run composer (install PHP dependencies) and create a VERSION file
|
||||||
|
loudCmd "./build.sh"
|
||||||
|
|
||||||
if [ -f /etc/airtime/airtime.conf ]; then
|
if [ -f /etc/airtime/airtime.conf ]; then
|
||||||
OLD_CONF=$(grep "[media-monitor]" /etc/airtime/airtime.conf)
|
OLD_CONF=$(grep "[media-monitor]" /etc/airtime/airtime.conf)
|
||||||
|
|
||||||
|
@ -472,19 +483,27 @@ verbose "\n * Installing airtime_analyzer..."
|
||||||
loudCmd "python ${AIRTIMEROOT}/python_apps/airtime_analyzer/setup.py install --install-scripts=/usr/bin"
|
loudCmd "python ${AIRTIMEROOT}/python_apps/airtime_analyzer/setup.py install --install-scripts=/usr/bin"
|
||||||
verbose "...Done"
|
verbose "...Done"
|
||||||
|
|
||||||
#for i in /etc/init/airtime*.template; do
|
for i in /etc/init/airtime*.template; do
|
||||||
# chmod 644 $i
|
chmod 644 $i
|
||||||
# sed -i "s/WEB_USER/${web_user}/g" $i
|
sed -i "s/WEB_USER/${web_user}/g" $i
|
||||||
# mv $i ${i%.template}
|
mv $i ${i%.template}
|
||||||
#done
|
done
|
||||||
|
|
||||||
set +e
|
set +e
|
||||||
loudCmd "initctl reload-configuration"
|
loudCmd "initctl reload-configuration"
|
||||||
loudCmd "systemctl daemon-reload" #systemd hipsters
|
|
||||||
loudCmd "update-rc.d airtime-playout defaults" # Start at bootup, on Debian
|
# airtime-celery only has an init.d startup script
|
||||||
loudCmd "update-rc.d airtime-celery defaults" # Start at bootup, on Debian
|
loudCmd "update-rc.d airtime-celery defaults" # Start at bootup, on Debian
|
||||||
loudCmd "update-rc.d airtime-liquidsoap defaults" # Start at bootup, on Debian
|
|
||||||
loudCmd "update-rc.d airtime_analyzer defaults" # Start at bootup, on Debian
|
# On Ubuntu, we already have the upstart configs, so this is redundant
|
||||||
|
# and causes multiple processes to spawn on startup
|
||||||
|
if [ "$dist" != "ubuntu" ]; then
|
||||||
|
loudCmd "systemctl daemon-reload" #systemd hipsters
|
||||||
|
|
||||||
|
loudCmd "update-rc.d airtime-playout defaults" # Start at bootup, on Debian
|
||||||
|
loudCmd "update-rc.d airtime-liquidsoap defaults" # Start at bootup, on Debian
|
||||||
|
loudCmd "update-rc.d airtime_analyzer defaults" # Start at bootup, on Debian
|
||||||
|
fi
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
if [ ! -d /var/log/airtime ]; then
|
if [ ! -d /var/log/airtime ]; then
|
||||||
|
|
|
@ -9,7 +9,10 @@ import pickle
|
||||||
import threading
|
import threading
|
||||||
from urlparse import urlparse
|
from urlparse import urlparse
|
||||||
|
|
||||||
requests.packages.urllib3.disable_warnings()
|
# Disable urllib3 warnings because these can cause a rare deadlock due to Python 2's crappy internal non-reentrant locking
|
||||||
|
# around POSIX stuff. See SAAS-714. The hasattr() is for compatibility with older versions of requests.
|
||||||
|
if hasattr(requests, 'packages'):
|
||||||
|
requests.packages.urllib3.disable_warnings()
|
||||||
|
|
||||||
class PicklableHttpRequest:
|
class PicklableHttpRequest:
|
||||||
def __init__(self, method, url, data, api_key):
|
def __init__(self, method, url, data, api_key):
|
||||||
|
|
|
@ -22,7 +22,7 @@ else:
|
||||||
mm2_files.append(os.path.join(root, filename))
|
mm2_files.append(os.path.join(root, filename))
|
||||||
|
|
||||||
data_files = [
|
data_files = [
|
||||||
# ('/etc/init', ['install/upstart/airtime-media-monitor.conf.template']),
|
('/etc/init', ['install/upstart/airtime-media-monitor.conf.template']),
|
||||||
('/etc/init.d', ['install/sysvinit/airtime-media-monitor']),
|
('/etc/init.d', ['install/sysvinit/airtime-media-monitor']),
|
||||||
('/etc/airtime', ['install/media_monitor_logging.cfg']),
|
('/etc/airtime', ['install/media_monitor_logging.cfg']),
|
||||||
('/var/log/airtime/media-monitor', []),
|
('/var/log/airtime/media-monitor', []),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue