diff --git a/.gitignore b/.gitignore
index cd3cdf4f3..fa7c75e95 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,10 +1,11 @@
.*
+*.*~
*.pyc
vendor/*
composer.phar
*~$
*log.*
-**/airtime_analyzer.egg-info/*
+**/*.egg-info/*
**/build/*
**/dist/*
*~
diff --git a/README b/README
index d83dbde3b..38e5b0f86 100644
--- a/README
+++ b/README
@@ -3,7 +3,7 @@
=========================================================================
Airtime is an open source application that provides remote and
-collaborative automation of a broadcast station.
+collaborative automation of a broadcast radio station.
Home page: http://www.sourcefabric.org/en/airtime/
@@ -18,28 +18,62 @@ Major features:
* Solid playout. Airtime uses the open source Liquidsoap streaming language
for reliable and precise playback to multiple outputs.
* Open, extensible architecture. Stations are free to extend and alter
- all parts of the program code, under the GNU GPLv3 license.
+ all parts of the program code, under the GNU AGPLv3 license.
INSTALLATION
------------
-Please see this chapter to begin a typical installation:
-http://sourcefabric.booktype.pro/airtime-25-for-broadcasters/preparing-the-server/
+Basic installation has two steps:
-If you are a developer, please see this page:
-http://wiki.sourcefabric.org/display/CC/Airtime+Dev+Site
+1) Run the install script, located in the Airtime root directory.
-For installation direct from a git checkout on Ubuntu 12.04 LTS, run:
+For an interactive installation, run:
- cd install_full/ubuntu
- sudo ./airtime-full-install
+ sudo ./install
-For installation from git on Debian wheezy, run:
+If you're using a terminal that is not running Bash, you'll need to run
- cd install_full/debian
- sudo ./airtime-full-install
+ sudo /bin/bash ./install
+instead. You may need to install Bash first.
+
+The installer will then prompt you about how you want to set up your Airtime
+installation.
+
+For a non-interactive full installation (do this if you're installing Airtime from
+scratch and don't have any of your own configuration set up), run
+
+ sudo ./install -fiap
+
+What this means:
+
+ -f - force; non-interactive (no prompts)
+ -i - install the default Icecast 2 setup for Airtime
+ -a - install the default apache setup for Airtime
+ -p - create a default Airtime postgres user
+
+This will install all components necessary for Airtime, and set up
+/usr/share/airtime as your web root (where apache looks for your Airtime files)
+
+There are several options for installation - to see them all, run
+
+ sudo ./install --help
+
+2) Once you've run the installer, open a web browser to http://localhost to run
+the interactive setup. (If you have a custom apache configuration, navigate to
+your Airtime web host instead.)
+
+If you just want to run Airtime with default settings, you won't need to change
+anything, but if you have any custom configuration settings you'll be able to
+specify them.
+
+Once you finish the setup process, you'll be presented with a configuration
+checklist so you can ensure that your Airtime installation is working
+correctly. If anything was mis-configured, the checklist will provide some .
+helpful tips to resolve the issue.
+
+If your checklist is all green, you're ready to get started with Airtime!
Quick links to our resources
----------------------------
@@ -48,4 +82,3 @@ Forums and mailing lists: http://forum.sourcefabric.org
Bug tracker: http://dev.sourcefabric.org
Source code: http://github.com/sourcefabric/Airtime
IRC chat: #airtime on Freenode
-
diff --git a/airtime_mvc/application/Bootstrap.php b/airtime_mvc/application/Bootstrap.php
index 7580eef69..6f71ff8a9 100644
--- a/airtime_mvc/application/Bootstrap.php
+++ b/airtime_mvc/application/Bootstrap.php
@@ -1,19 +1,19 @@
headScript()->appendScript("var USER_MANUAL_URL = '" . USER_MANUAL_URL . "';");
$view->headScript()->appendScript("var COMPANY_NAME = '" . COMPANY_NAME . "';");
}
+
+ protected function _initUpgrade() {
+ /* We need to wrap this here so that we aren't checking when we're running the unit test suite
+ */
+ if (getenv("AIRTIME_UNIT_TEST") != 1) {
+ //This will do the upgrade too if it's needed...
+ if (UpgradeManager::checkIfUpgradeIsNeeded()) {
+ $upgradeManager = new UpgradeManager();
+ $upgradeManager->doUpgrade();
+ }
+ }
+ }
protected function _initHeadLink()
{
@@ -196,12 +209,12 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
}
$view->headScript()->appendScript("var userType = '$userType';");
-
if (array_key_exists('REQUEST_URI', $_SERVER)) { //Doesn't exist for unit tests
if (strpos($_SERVER['REQUEST_URI'], $baseUrl . 'Dashboard/stream-player') === false
&& strpos($_SERVER['REQUEST_URI'], $baseUrl . 'audiopreview/audio-preview') === false
&& strpos($_SERVER['REQUEST_URI'], $baseUrl . 'audiopreview/playlist-preview') === false
&& strpos($_SERVER['REQUEST_URI'], $baseUrl . 'audiopreview/block-preview') === false
+ && $_SERVER['REQUEST_URI'] != "/"
) {
$plan_level = strval(Application_Model_Preference::GetPlanLevel());
// Since the Hobbyist plan doesn't come with Live Chat support, don't enable it
@@ -225,8 +238,7 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
protected function _initViewHelpers()
{
$view = $this->getResource('view');
- $view->addHelperPath('../application/views/helpers', 'Airtime_View_Helper');
-
+ $view->addHelperPath(APPLICATION_PATH . 'views/helpers', 'Airtime_View_Helper');
$view->assign('suspended', (Application_Model_Preference::getProvisioningStatus() == PROVISIONING_STATUS_SUSPENDED));
}
@@ -239,7 +251,7 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
protected function _initZFDebug()
{
- Zend_Controller_Front::getInstance()->throwExceptions(true);
+ Zend_Controller_Front::getInstance()->throwExceptions(false);
/*
if (APPLICATION_ENV == "development") {
diff --git a/airtime_mvc/application/airtime-boot.php b/airtime_mvc/application/airtime-boot.php
new file mode 100644
index 000000000..0fb1212dd
--- /dev/null
+++ b/airtime_mvc/application/airtime-boot.php
@@ -0,0 +1,110 @@
+bootstrap()->run();
+ }
+} catch (Exception $e) {
+ if ($e->getCode() == 401)
+ {
+ header($_SERVER['SERVER_PROTOCOL'] . ' 401 Unauthorized', true, 401);
+ return;
+ }
+
+ header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
+ Logging::error($e->getMessage());
+
+ if (VERBOSE_STACK_TRACE) {
+ echo $e->getMessage();
+ echo "
";
+ echo $e->getTraceAsString();
+ echo "
";
+ Logging::info($e->getMessage());
+ Logging::info($e->getTraceAsString());
+ } else {
+ Logging::info($e->getTrace());
+ }
+ throw $e;
+}
+
diff --git a/airtime_mvc/application/common/WidgetHelper.php b/airtime_mvc/application/common/WidgetHelper.php
new file mode 100644
index 000000000..d49be8648
--- /dev/null
+++ b/airtime_mvc/application/common/WidgetHelper.php
@@ -0,0 +1,173 @@
+setTimezone($utcTimezone);
+ $utcDayStart = $weekStartDateTime->format("Y-m-d H:i:s");
+ for ($i = 0; $i < 14; $i++) {
+ //have to be in station timezone when adding 1 day for daylight savings.
+ $weekStartDateTime->setTimezone(new DateTimeZone($timezone));
+ $weekStartDateTime->add(new DateInterval('P1D'));
+
+ //convert back to UTC to get the actual timestamp used for search.
+ $weekStartDateTime->setTimezone($utcTimezone);
+
+ $utcDayEnd = $weekStartDateTime->format("Y-m-d H:i:s");
+ $shows = Application_Model_Show::getNextShows($utcDayStart, "ALL", $utcDayEnd);
+ $utcDayStart = $utcDayEnd;
+
+ // convert to user-defined timezone, or default to station
+ Application_Common_DateHelper::convertTimestampsToTimezone(
+ $shows,
+ array("starts", "ends", "start_timestamp","end_timestamp"),
+ $timezone
+ );
+
+ $result[$dow[$i]] = $shows;
+
+ // XSS exploit prevention
+ self::convertSpecialChars($result, array("name", "url"));
+ // convert image paths to point to api endpoints
+ self::findAndConvertPaths($result);
+ }
+
+ return $result;
+ }
+
+ // Second version of this function.
+ // Removing "next" days and creating two weekly arrays
+ public static function getWeekInfoV2($timezone)
+ {
+ //weekStart is in station time.
+ //$weekStartDateTime = Application_Common_DateHelper::getWeekStartDateTime();
+ $weekStartDateTime = new DateTime("now", new DateTimeZone(Application_Model_Preference::GetTimezone()));
+
+ $maxNumOFWeeks = 2;
+
+ $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");
+
+ $weekStartDateTime->setTimezone($utcTimezone);
+ $utcDayStart = $weekStartDateTime->format("Y-m-d H:i:s");
+ $weekCounter = 0;
+ while ($weekCounter < $maxNumOFWeeks) {
+ for ($dayOfWeekCounter = 0; $dayOfWeekCounter < DAYS_PER_WEEK; $dayOfWeekCounter++) {
+ $dateParse = date_parse($weekStartDateTime->format("Y-m-d H:i:s"));
+
+ $result[$weekCounter][$dayOfWeekCounter]["dayOfMonth"] = $dateParse["day"];
+ $result[$weekCounter][$dayOfWeekCounter]["dayOfWeek"] = strtoupper(date("D", $weekStartDateTime->getTimestamp()));
+
+ //have to be in station timezone when adding 1 day for daylight savings.
+ $weekStartDateTime->setTimezone(new DateTimeZone($timezone));
+ $weekStartDateTime->add(new DateInterval('P1D'));
+
+ //convert back to UTC to get the actual timestamp used for search.
+ $weekStartDateTime->setTimezone($utcTimezone);
+
+ $utcDayEnd = $weekStartDateTime->format("Y-m-d H:i:s");
+ $shows = Application_Model_Show::getNextShows($utcDayStart, "ALL", $utcDayEnd);
+ $utcDayStart = $utcDayEnd;
+
+ // convert to user-defined timezone, or default to station
+ Application_Common_DateHelper::convertTimestampsToTimezone(
+ $shows,
+ array("starts", "ends", "start_timestamp", "end_timestamp"),
+ $timezone
+ );
+
+
+ foreach($shows as &$show) {
+ $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;
+
+ // XSS exploit prevention
+ self::convertSpecialChars($result, array("name", "url"));
+ // convert image paths to point to api endpoints
+ self::findAndConvertPaths($result);
+
+ }
+ $weekCounter += 1;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Go through a given array and sanitize any potentially exploitable fields
+ * by passing them through htmlspecialchars
+ *
+ * @param unknown $arr the array to sanitize
+ * @param unknown $keys indexes of values to be sanitized
+ */
+ public static function convertSpecialChars(&$arr, $keys)
+ {
+ foreach ($arr as &$a) {
+ if (is_array($a)) {
+ foreach ($keys as &$key) {
+ if (array_key_exists($key, $a)) {
+ $a[$key] = htmlspecialchars($a[$key]);
+ }
+ }
+ self::convertSpecialChars($a, $keys);
+ }
+ }
+ }
+
+ /**
+ * Recursively find image_path keys in the various $result subarrays,
+ * and convert them to point to the show-logo endpoint
+ *
+ * @param unknown $arr the array to search
+ */
+ public static function findAndConvertPaths(&$arr)
+ {
+ $CC_CONFIG = Config::getConfig();
+ $baseDir = Application_Common_OsPath::formatDirectoryWithDirectorySeparators($CC_CONFIG['baseDir']);
+
+ foreach ($arr as &$a) {
+ if (is_array($a)) {
+ if (array_key_exists("image_path", $a)) {
+ $a["image_path"] = $a["image_path"] && $a["image_path"] !== '' ?
+ "http://".$_SERVER['HTTP_HOST'].$baseDir."api/show-logo?id=".$a["id"] : '';
+ } else {
+ self::findAndConvertPaths($a);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/airtime_mvc/application/configs/ACL.php b/airtime_mvc/application/configs/ACL.php
index cde876b35..585227215 100644
--- a/airtime_mvc/application/configs/ACL.php
+++ b/airtime_mvc/application/configs/ACL.php
@@ -39,7 +39,8 @@ $ccAcl->add(new Zend_Acl_Resource('library'))
->add(new Zend_Acl_Resource('thank-you'))
->add(new Zend_Acl_Resource('provisioning'))
->add(new Zend_Acl_Resource('player'))
- ->add(new Zend_Acl_Resource('soundcloud'));
+ ->add(new Zend_Acl_Resource('soundcloud'))
+ ->add(new Zend_Acl_Resource('embeddablewidgets'));
/** Creating permissions */
$ccAcl->allow('G', 'index')
@@ -74,6 +75,7 @@ $ccAcl->allow('G', 'index')
->allow('A', 'preference')
->allow('A', 'player')
->allow('A', 'soundcloud')
+ ->allow('A', 'embeddablewidgets')
->allow('S', 'thank-you')
->allow('S', 'billing');
diff --git a/airtime_mvc/application/configs/conf.php b/airtime_mvc/application/configs/conf.php
index 80199b38c..00af3e337 100644
--- a/airtime_mvc/application/configs/conf.php
+++ b/airtime_mvc/application/configs/conf.php
@@ -2,8 +2,6 @@
/* THIS FILE IS NOT MEANT FOR CUSTOMIZING.
* PLEASE EDIT THE FOLLOWING TO CHANGE YOUR CONFIG:
* /etc/airtime/airtime.conf
- * /etc/airtime/pypo.cfg
- * /etc/airtime/recorder.cfg
*/
class Config {
@@ -69,12 +67,9 @@ class Config {
// Tells us where file uploads will be uploaded to.
// It will either be set to a cloud storage backend or local file storage.
$CC_CONFIG["current_backend"] = $cloudStorageValues["current_backend"]["storage_backend"];
-
+
$CC_CONFIG['cache_ahead_hours'] = $values['general']['cache_ahead_hours'];
- $CC_CONFIG['monit_user'] = $values['monit']['monit_user'];
- $CC_CONFIG['monit_password'] = $values['monit']['monit_password'];
-
// Database config
$CC_CONFIG['dsn']['username'] = $values['database']['dbuser'];
$CC_CONFIG['dsn']['password'] = $values['database']['dbpass'];
diff --git a/airtime_mvc/application/configs/config-check.php b/airtime_mvc/application/configs/config-check.php
new file mode 100644
index 000000000..9cfb9927b
--- /dev/null
+++ b/airtime_mvc/application/configs/config-check.php
@@ -0,0 +1,265 @@
+
+
+
+
+
+
+
+
+
+
+
+ Configuration Checklist
+
+
+
+
+
Looks like something went wrong!
+
+ Take a look at the checklist below for possible solutions. If you're tried the suggestions and are
+ still experiencing issues, come
+ visit our forums
+ or check out the manual.
+
+
+
+ Your Airtime station is up and running! Get started by logging in with the default username and password: admin/admin
+
+ ">
+ Make sure you aren't missing any of the Postgres dependencies in the table above.
+ If your dependencies check out, make sure your database configuration settings in
+ /etc/airtime.conf are correct and the Airtime database was installed correctly.
+
+
+
+
+
+ RabbitMQ
+
+
+ RabbitMQ configuration for Airtime
+
+
+ ">
+ Make sure RabbitMQ is installed correctly, and that your settings in /etc/airtime/airtime.conf
+ are correct. Try using sudo rabbitmqctl list_users and sudo rabbitmqctl list_vhosts
+ to see if the airtime user (or your custom RabbitMQ user) exists, then checking that
+ sudo rabbitmqctl list_exchanges contains entries for airtime-media-monitor, airtime-pypo,
+ and airtime-uploads.
+
+
+
+
+
+ Media Monitor
+
+
+ Airtime media-monitor service
+
+
+ ">
+ Check that the airtime-media-monitor service is installed correctly in /etc/init,
+ and ensure that it's running with
+ initctl list | grep airtime-media-monitor
+ If not, try running sudo service airtime-media-monitor start
+
+
+
+
+
+ Pypo
+
+
+ Airtime playout service
+
+
+ ">
+ Check that the airtime-playout service is installed correctly in /etc/init,
+ and ensure that it's running with
+ initctl list | grep airtime-playout
+ If not, try running sudo service airtime-playout restart
+
+
+
+
+
+ Liquidsoap
+
+
+ Airtime liquidsoap service
+
+
+ ">
+ Check that the airtime-liquidsoap service is installed correctly in /etc/init,
+ and ensure that it's running with
+ initctl list | grep airtime-liquidsoap
+ If not, try running sudo service airtime-liquidsoap restart
+
+
+
+
+
+
+
diff --git a/airtime_mvc/application/configs/constants.php b/airtime_mvc/application/configs/constants.php
index bb5184895..4409be287 100644
--- a/airtime_mvc/application/configs/constants.php
+++ b/airtime_mvc/application/configs/constants.php
@@ -3,6 +3,8 @@
define('PRODUCT_NAME' , 'Airtime');
define('PRODUCT_SITE_URL' , 'http://airtime.sourcefabric.org');
+define('SAAS_PRODUCT_BRANDING_NAME', 'Airtime Pro');
+
define('COMPANY_NAME' , 'Sourcefabric');
define('COMPANY_SUFFIX' , 'z.รบ.');
define('COMPANY_SITE' , 'Sourcefabric.org');
@@ -19,6 +21,10 @@ define('LICENSE_URL' , 'http://www.gnu.org/licenses/agpl-3.0-standalone.h
define('AIRTIME_COPYRIGHT_DATE' , '2010-2012');
define('AIRTIME_REST_VERSION' , '1.1');
define('AIRTIME_API_VERSION' , '1.1');
+define('AIRTIME_CODE_VERSION' , '2.5.13');
+
+define('DEFAULT_LOGO_PLACEHOLDER', 1);
+define('DEFAULT_LOGO_FILE', 'airtime_logo.png');
// Metadata Keys for files
define('MDATA_KEY_FILEPATH' , 'filepath');
diff --git a/airtime_mvc/application/configs/navigation.php b/airtime_mvc/application/configs/navigation.php
index 47b32b714..4a26366bf 100644
--- a/airtime_mvc/application/configs/navigation.php
+++ b/airtime_mvc/application/configs/navigation.php
@@ -66,12 +66,6 @@ $pages = array(
'controller' => 'Preference',
'action' => 'stream-setting'
),
- array(
- 'label' => _('Support Feedback'),
- 'module' => 'default',
- 'controller' => 'Preference',
- 'action' => 'support-setting'
- ),
array(
'label' => _('Status'),
'module' => 'default',
@@ -87,10 +81,10 @@ $pages = array(
'resource' => 'listenerstat'
),
array(
- 'label' => _('Player'),
+ 'label' => _('Widgets'),
'module' => 'default',
- 'controller' => 'player',
- 'action' => 'customize'
+ 'controller' => 'embeddablewidgets',
+ 'action' => 'index'
)
)
),
diff --git a/airtime_mvc/application/controllers/ApiController.php b/airtime_mvc/application/controllers/ApiController.php
index 440ec2d3a..347ce1782 100644
--- a/airtime_mvc/application/controllers/ApiController.php
+++ b/airtime_mvc/application/controllers/ApiController.php
@@ -1,4 +1,5 @@
convertSpecialChars($result, array("name", "url"));
+ WidgetHelper::convertSpecialChars($result, array("name", "url"));
// apply user-defined timezone, or default to station
Application_Common_DateHelper::convertTimestampsToTimezone(
$result['currentShow'],
@@ -218,7 +219,7 @@ class ApiController extends Zend_Controller_Action
$result["timezone"] = $upcase ? strtoupper($timezone) : $timezone;
$result["timezoneOffset"] = Application_Common_DateHelper::getTimezoneOffset($timezone);
// convert image paths to point to api endpoints
- $this->findAndConvertPaths($result);
+ WidgetHelper::findAndConvertPaths($result);
// used by caller to determine if the airtime they are running or widgets in use is out of date.
$result['AIRTIME_API_VERSION'] = AIRTIME_API_VERSION;
@@ -288,11 +289,11 @@ class ApiController extends Zend_Controller_Action
$result = Application_Model_Schedule::GetPlayOrderRange($utcTimeEnd, $showsToRetrieve);
// XSS exploit prevention
- $this->convertSpecialChars($result, array("name", "url"));
+ WidgetHelper::convertSpecialChars($result, array("name", "url"));
// apply user-defined timezone, or default to station
$this->applyLiveTimezoneAdjustments($result, $timezone, $upcase);
// convert image paths to point to api endpoints
- $this->findAndConvertPaths($result);
+ WidgetHelper::findAndConvertPaths($result);
// used by caller to determine if the airtime they are running or widgets in use is out of date.
$result["station"]["AIRTIME_API_VERSION"] = AIRTIME_API_VERSION;
@@ -343,7 +344,7 @@ class ApiController extends Zend_Controller_Action
* variables in the result to reflect the given timezone.
*
* @param object $result reference to the object to send back to the user
- * @param string $timezone the user's timezone parameter value
+ * @param string $timezone the user's timezone parameter value
* @param boolean $upcase whether the timezone output should be upcased
*/
private function applyLiveTimezoneAdjustments(&$result, $timezone, $upcase)
@@ -366,55 +367,11 @@ class ApiController extends Zend_Controller_Action
$this->view->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
- //weekStart is in station time.
- $weekStartDateTime = Application_Common_DateHelper::getWeekStartDateTime();
-
- $dow = array("monday", "tuesday", "wednesday", "thursday", "friday",
- "saturday", "sunday", "nextmonday", "nexttuesday", "nextwednesday",
- "nextthursday", "nextfriday", "nextsaturday", "nextsunday");
+ $result = WidgetHelper::getWeekInfo($this->getRequest()->getParam("timezone"));
- $result = array();
-
- // default to the station timezone
- $timezone = Application_Model_Preference::GetDefaultTimezone();
- $userDefinedTimezone = strtolower($this->getRequest()->getParam("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");
-
- $weekStartDateTime->setTimezone($utcTimezone);
- $utcDayStart = $weekStartDateTime->format("Y-m-d H:i:s");
- for ($i = 0; $i < 14; $i++) {
- //have to be in station timezone when adding 1 day for daylight savings.
- $weekStartDateTime->setTimezone(new DateTimeZone($timezone));
- $weekStartDateTime->add(new DateInterval('P1D'));
-
- //convert back to UTC to get the actual timestamp used for search.
- $weekStartDateTime->setTimezone($utcTimezone);
-
- $utcDayEnd = $weekStartDateTime->format("Y-m-d H:i:s");
- $shows = Application_Model_Show::getNextShows($utcDayStart, "ALL", $utcDayEnd);
- $utcDayStart = $utcDayEnd;
-
- // convert to user-defined timezone, or default to station
- Application_Common_DateHelper::convertTimestampsToTimezone(
- $shows,
- array("starts", "ends", "start_timestamp","end_timestamp"),
- $timezone
- );
-
- $result[$dow[$i]] = $shows;
- }
-
- // XSS exploit prevention
- $this->convertSpecialChars($result, array("name", "url"));
- // convert image paths to point to api endpoints
- $this->findAndConvertPaths($result);
-
//used by caller to determine if the airtime they are running or widgets in use is out of date.
$result['AIRTIME_API_VERSION'] = AIRTIME_API_VERSION;
+
header("Content-type: text/javascript");
if (version_compare(phpversion(), '5.4.0', '<')) {
@@ -431,50 +388,6 @@ class ApiController extends Zend_Controller_Action
}
}
- /**
- * Go through a given array and sanitize any potentially exploitable fields
- * by passing them through htmlspecialchars
- *
- * @param array $arr the array to sanitize
- * @param array $keys indexes of values to be sanitized
- */
- private function convertSpecialChars(&$arr, $keys)
- {
- foreach ($arr as &$a) {
- if (is_array($a)) {
- foreach ($keys as &$key) {
- if (array_key_exists($key, $a)) {
- $a[$key] = htmlspecialchars($a[$key]);
- }
- }
- $this->convertSpecialChars($a, $keys);
- }
- }
- }
-
- /**
- * Recursively find image_path keys in the various $result subarrays,
- * and convert them to point to the show-logo endpoint
- *
- * @param array $arr the array to search
- */
- private function findAndConvertPaths(&$arr)
- {
- $CC_CONFIG = Config::getConfig();
- $baseDir = Application_Common_OsPath::formatDirectoryWithDirectorySeparators($CC_CONFIG['baseDir']);
-
- foreach ($arr as &$a) {
- if (is_array($a)) {
- if (array_key_exists("image_path", $a)) {
- $a["image_path"] = $a["image_path"] && $a["image_path"] !== '' ?
- "http://".$_SERVER['HTTP_HOST'].$baseDir."api/show-logo?id=".$a["id"] : '';
- } else {
- $this->findAndConvertPaths($a);
- }
- }
- }
- }
-
/**
* API endpoint to display the show logo
*/
diff --git a/airtime_mvc/application/controllers/EmbedController.php b/airtime_mvc/application/controllers/EmbedController.php
index 3212c8e5d..c160ad9e2 100644
--- a/airtime_mvc/application/controllers/EmbedController.php
+++ b/airtime_mvc/application/controllers/EmbedController.php
@@ -1,4 +1,5 @@
getRequest();
- $this->view->css = Application_Common_HTTPHelper::getStationUrl() . "css/player.css?".$CC_CONFIG['airtime_version'];
$this->view->mrp_js = Application_Common_HTTPHelper::getStationUrl() . "js/airtime/player/mrp.js?".$CC_CONFIG['airtime_version'];
$this->view->jquery = Application_Common_HTTPHelper::getStationUrl() . "js/libs/jquery-1.10.2.js";
$this->view->muses_swf = Application_Common_HTTPHelper::getStationUrl() . "js/airtime/player/muses.swf";
$this->view->metadata_api_url = Application_Common_HTTPHelper::getStationUrl() . "api/live-info";
$this->view->player_title = json_encode($request->getParam('title'));
+ $styleParam = $request->getParam('style');
+ $player_style = isset($styleParam) ? $styleParam : "basic";
+ if ($player_style == "premium") {
+ $this->view->css = Application_Common_HTTPHelper::getStationUrl() . "css/radio-page/premium_player.css?".$CC_CONFIG['airtime_version'];
+ } else {
+ $this->view->css = Application_Common_HTTPHelper::getStationUrl() . "css/player.css?".$CC_CONFIG['airtime_version'];
+ }
+ $this->view->player_style = $player_style;
+
$stream = $request->getParam('stream');
$streamData = Application_Model_StreamSetting::getEnabledStreamData();
$availableMobileStreams = array();
@@ -54,4 +63,44 @@ class EmbedController extends Zend_Controller_Action
$this->view->availableMobileStreams = json_encode($availableMobileStreams);
$this->view->availableDesktopStreams = json_encode($availableDesktopStreams);
}
+
+ public function currentDayProgramAction()
+ {
+ $this->view->layout()->disableLayout();
+
+ $CC_CONFIG = Config::getConfig();
+
+ $this->view->css = Application_Common_HTTPHelper::getStationUrl() . "widgets/css/airtime-widgets.css?".$CC_CONFIG['airtime_version'];
+ $this->view->jquery = Application_Common_HTTPHelper::getStationUrl() . "widgets/js/jquery-1.6.1.min.js?".$CC_CONFIG['airtime_version'];
+ $this->view->jquery_custom = Application_Common_HTTPHelper::getStationUrl() . "widgets/js/jquery-ui-1.8.10.custom.min.js?".$CC_CONFIG['airtime_version'];
+ $this->view->widget_js = Application_Common_HTTPHelper::getStationUrl() . "widgets/js/jquery.showinfo.js?".$CC_CONFIG['airtime_version'];
+ }
+
+ public function weeklyProgramAction()
+ {
+ $this->view->layout()->disableLayout();
+
+ $CC_CONFIG = Config::getConfig();
+
+ $request = $this->getRequest();
+
+ $widgetStyle = $request->getParam('style');
+ if ($widgetStyle == "premium") {
+ $this->view->widgetStyle = "premium";
+ $this->view->css = Application_Common_HTTPHelper::getStationUrl() . "/css/embed/weekly-schedule-widget.css?" . $CC_CONFIG['airtime_version'];
+ } else {
+ $this->view->widgetStyle = "basic";
+ $this->view->css = Application_Common_HTTPHelper::getStationUrl() . "/css/embed/weekly-schedule-widget-basic.css?" . $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"));
+
+ // Return only the current week's schedule data. In the future we may use the next week's data.
+ $this->view->weeklyScheduleData = $weeklyScheduleData[0];
+
+ $currentDay = new DateTime("now", new DateTimeZone(Application_Model_Preference::GetTimezone()));
+ //day of the month without leading zeros (1 to 31)
+ $this->view->currentDayOfMonth = $currentDay->format("j");
+ }
}
diff --git a/airtime_mvc/application/controllers/PlayerController.php b/airtime_mvc/application/controllers/EmbeddablewidgetsController.php
similarity index 63%
rename from airtime_mvc/application/controllers/PlayerController.php
rename to airtime_mvc/application/controllers/EmbeddablewidgetsController.php
index bb3fbc2d3..3d3285d0a 100644
--- a/airtime_mvc/application/controllers/PlayerController.php
+++ b/airtime_mvc/application/controllers/EmbeddablewidgetsController.php
@@ -1,13 +1,14 @@
getElement('player_stream_url')->getAttrib('numberOfEnabledStreams');
if ($numEnabledStreams > 0 && $apiEnabled) {
- $this->view->form = $form;
+ $this->view->player_form = $form;
} else {
- $this->view->errorMsg = "To configure and use the embeddable player you must:
+ $this->view->player_error_msg = _("To configure and use the embeddable player you must:
1. Enable at least one MP3, AAC, or OGG stream under System -> Streams
- 2. Enable the Public Airtime API under System -> Preferences";
+ 2. Enable the Public Airtime API under System -> Preferences");
}
+ if (!$apiEnabled) {
+ $this->view->weekly_schedule_error_msg = _("To use the embeddable weekly schedule you must:
+ 1. Enable the Public Airtime API under System -> Preferences");
+ }
}
}
+
diff --git a/airtime_mvc/application/controllers/ErrorController.php b/airtime_mvc/application/controllers/ErrorController.php
index 315da3ac9..0c149749d 100644
--- a/airtime_mvc/application/controllers/ErrorController.php
+++ b/airtime_mvc/application/controllers/ErrorController.php
@@ -38,9 +38,12 @@ class ErrorController extends Zend_Controller_Action {
}
// Log exception, if logger available
+ /* No idea why this doesn't work or why it was implemented like this. Disabling it -- Albert
if (($log = $this->getLog())) {
$log->crit($this->view->message, $errors->exception);
- }
+ }*/
+ //Logging that actually works: -- Albert
+ Logging::error($this->view->message . ": " . $errors->exception);
// conditionally display exceptions
if ($this->getInvokeArg('displayExceptions') == true) {
diff --git a/airtime_mvc/application/controllers/IndexController.php b/airtime_mvc/application/controllers/IndexController.php
index 58f484c7e..d97264799 100644
--- a/airtime_mvc/application/controllers/IndexController.php
+++ b/airtime_mvc/application/controllers/IndexController.php
@@ -10,7 +10,24 @@ class IndexController extends Zend_Controller_Action
public function indexAction()
{
- $this->_redirect('Showbuilder');
+ $CC_CONFIG = Config::getConfig();
+ $baseUrl = Application_Common_OsPath::getBaseDir();
+ $this->view->headLink()->setStylesheet($baseUrl.'css/radio-page/radio-page.css?'.$CC_CONFIG['airtime_version']);
+ $this->view->headLink()->appendStylesheet($baseUrl.'css/embed/weekly-schedule-widget.css?'.$CC_CONFIG['airtime_version']);
+
+ $this->_helper->layout->setLayout('radio-page');
+
+ $this->view->stationLogo = Application_Model_Preference::GetStationLogo();
+
+ $stationName = Application_Model_Preference::GetStationName();
+ $this->view->stationName = $stationName;
+
+ $stationDescription = Application_Model_Preference::GetStationDescription();
+ $this->view->stationDescription = $stationDescription;
+
+ $this->view->stationUrl = Application_Common_HTTPHelper::getStationUrl();
+
+ $this->view->baseUrl = Application_Common_OsPath::getBaseDir();
}
public function mainAction()
diff --git a/airtime_mvc/application/controllers/SystemstatusController.php b/airtime_mvc/application/controllers/SystemstatusController.php
index 543fbef70..6098f71b7 100644
--- a/airtime_mvc/application/controllers/SystemstatusController.php
+++ b/airtime_mvc/application/controllers/SystemstatusController.php
@@ -13,18 +13,9 @@ class SystemstatusController extends Zend_Controller_Action
public function indexAction()
{
- /*
- $services = array(
- "pypo"=>Application_Model_Systemstatus::GetPypoStatus(),
- "liquidsoap"=>Application_Model_Systemstatus::GetLiquidsoapStatus(),
- //"media-monitor"=>Application_Model_Systemstatus::GetMediaMonitorStatus(),
- );
- */
-
$partitions = Application_Model_Systemstatus::GetDiskInfo();
$this->view->status = new StdClass;
- //$this->view->status->services = $services;
$this->view->status->partitions = $partitions;
}
}
diff --git a/airtime_mvc/application/controllers/UpgradeController.php b/airtime_mvc/application/controllers/UpgradeController.php
index 4c04da699..7c26eed3d 100644
--- a/airtime_mvc/application/controllers/UpgradeController.php
+++ b/airtime_mvc/application/controllers/UpgradeController.php
@@ -13,40 +13,25 @@ class UpgradeController extends Zend_Controller_Action
return;
}
- // Get all upgrades dynamically (in declaration order!) so we don't have to add them explicitly each time
- // TODO: explicitly sort classnames by ascending version suffix for safety
- $upgraders = getUpgrades();
+ try {
+ $upgradeManager = new UpgradeManager();
+ $didWePerformAnUpgrade = $upgradeManager->doUpgrade();
- $didWePerformAnUpgrade = false;
- try
- {
- foreach ($upgraders as $upgrader)
- {
- /** @var $upgrader AirtimeUpgrader */
- $upgrader = new $upgrader();
- if ($upgrader->checkIfUpgradeSupported())
- {
- // pass __DIR__ to the upgrades, since __DIR__ returns parent dir of file, not executor
- $upgrader->upgrade(__DIR__); //This will throw an exception if the upgrade fails.
- $didWePerformAnUpgrade = true;
- $this->getResponse()
- ->setHttpResponseCode(200)
- ->appendBody("Upgrade to Airtime " . $upgrader->getNewVersion() . " OK ");
- }
- }
-
- if (!$didWePerformAnUpgrade)
- {
+ if (!$didWePerformAnUpgrade) {
$this->getResponse()
- ->setHttpResponseCode(200)
- ->appendBody("No upgrade was performed. The current Airtime version is " . AirtimeUpgrader::getCurrentVersion() . ". ");
+ ->setHttpResponseCode(200)
+ ->appendBody("No upgrade was performed. The current schema version is " . Application_Model_Preference::GetSchemaVersion() . ". ");
+ } else {
+ $this->getResponse()
+ ->setHttpResponseCode(200)
+ ->appendBody("Upgrade to Airtime schema version " . Application_Model_Preference::GetSchemaVersion() . " OK ");
}
}
catch (Exception $e)
{
$this->getResponse()
- ->setHttpResponseCode(400)
- ->appendBody($e->getMessage());
+ ->setHttpResponseCode(400)
+ ->appendBody($e->getMessage());
}
}
}
diff --git a/airtime_mvc/application/controllers/UserController.php b/airtime_mvc/application/controllers/UserController.php
index 1a6356dab..4c85dc8b0 100644
--- a/airtime_mvc/application/controllers/UserController.php
+++ b/airtime_mvc/application/controllers/UserController.php
@@ -102,7 +102,6 @@ class UserController extends Zend_Controller_Action
public function getHostsAction()
{
$search = $this->_getParam('term');
- $res = Application_Model_User::getHosts($search);
$this->view->hosts = Application_Model_User::getHosts($search);
}
diff --git a/airtime_mvc/application/controllers/plugins/Acl_plugin.php b/airtime_mvc/application/controllers/plugins/Acl_plugin.php
index 9eef38fdb..3249bd4a2 100644
--- a/airtime_mvc/application/controllers/plugins/Acl_plugin.php
+++ b/airtime_mvc/application/controllers/plugins/Acl_plugin.php
@@ -139,12 +139,15 @@ class Zend_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract
}
else //Non-REST, regular Airtime web app requests
{
- //Redirect you to the login screen since you have no session.
- if ($controller !== 'login') {
+ // Redirect user to the landing page if they are trying to
+ // access a resource that requires a valid session.
+ // Skip the redirection if they are already on the landing page
+ // or the login page.
+ if ($controller !== 'index' && $controller !== 'login') {
if ($request->isXmlHttpRequest()) {
- $url = 'http://'.$request->getHttpHost().'/login';
+ $url = 'http://'.$request->getHttpHost().'/';
$json = Zend_Json::encode(array('auth' => false, 'url' => $url));
// Prepare response
@@ -157,7 +160,7 @@ class Zend_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract
Zend_Controller_Action_HelperBroker::getStaticHelper('redirector')->redirectAndExit();
} else {
$r = Zend_Controller_Action_HelperBroker::getStaticHelper('redirector');
- $r->gotoSimpleAndExit('index', 'login', $request->getModuleName());
+ $r->gotoSimpleAndExit('index', 'index', $request->getModuleName());
}
}
}
diff --git a/airtime_mvc/application/controllers/upgrade_sql/airtime_2.5.2/upgrade.sql b/airtime_mvc/application/controllers/upgrade_sql/airtime_2.5.2/upgrade.sql
new file mode 100644
index 000000000..2f805382d
--- /dev/null
+++ b/airtime_mvc/application/controllers/upgrade_sql/airtime_2.5.2/upgrade.sql
@@ -0,0 +1,6 @@
+-- Replacing system_version with schema_version
+DELETE FROM cc_pref WHERE keystr = 'system_version';
+INSERT INTO cc_pref (keystr, valstr) VALUES ('schema_version', '2.5.2');
+
+ALTER TABLE cc_show ADD COLUMN image_path varchar(255) DEFAULT '';
+ALTER TABLE cc_show_instances ADD COLUMN description varchar(255) DEFAULT '';
diff --git a/airtime_mvc/application/layouts/scripts/radio-page.phtml b/airtime_mvc/application/layouts/scripts/radio-page.phtml
new file mode 100644
index 000000000..0a863471f
--- /dev/null
+++ b/airtime_mvc/application/layouts/scripts/radio-page.phtml
@@ -0,0 +1,17 @@
+doctype() ?>
+
+
+
+
+
+
+ headTitle() ?>
+ headLink() ?>
+ headScript() ?>
+
+
+
+ layout()->content ?>
+
+
+
diff --git a/airtime_mvc/application/models/Preference.php b/airtime_mvc/application/models/Preference.php
index 7fa917ba8..0578c46de 100644
--- a/airtime_mvc/application/models/Preference.php
+++ b/airtime_mvc/application/models/Preference.php
@@ -427,7 +427,12 @@ class Application_Model_Preference
public static function GetStationDescription()
{
- return self::getValue("description");
+ $description = self::getValue("description");
+ if (!empty($description)) {
+ return $description;
+ } else {
+ return sprintf(_("Powered by %s"), SAAS_PRODUCT_BRANDING_NAME);
+ }
}
// Sets station default timezone (from preferences)
@@ -531,7 +536,14 @@ class Application_Model_Preference
public static function GetStationLogo()
{
- return self::getValue("logoImage");
+ $logoImage = self::getValue("logoImage");
+ if (!empty($logoImage)) {
+ return $logoImage;
+ } else {
+ // We return the Airtime logo if no logo is set in the database.
+ // airtime_logo.png is stored under the public directory
+ return DEFAULT_LOGO_PLACEHOLDER;
+ }
}
public static function SetUniqueId($id)
@@ -791,10 +803,30 @@ class Application_Model_Preference
return self::getValue("enable_stream_conf");
}
-
- public static function SetAirtimeVersion($version)
+
+ public static function GetSchemaVersion()
{
- self::setValue("system_version", $version);
+ CcPrefPeer::clearInstancePool(); //Ensure we don't get a cached Propel object (cached DB results)
+ //because we're updating this version number within this HTTP request as well.
+
+ //New versions use schema_version
+ $pref = CcPrefQuery::create()
+ ->filterByKeystr('schema_version')
+ ->findOne();
+
+ if (empty($pref)) {
+ //Pre-2.5.2 releases all used this ambiguous "system_version" key to represent both the code and schema versions...
+ $pref = CcPrefQuery::create()
+ ->filterByKeystr('system_version')
+ ->findOne();
+ }
+ $schemaVersion = $pref->getValStr();
+ return $schemaVersion;
+ }
+
+ public static function SetSchemaVersion($version)
+ {
+ self::setValue("schema_version", $version);
}
public static function GetAirtimeVersion()
diff --git a/airtime_mvc/application/models/Schedule.php b/airtime_mvc/application/models/Schedule.php
index 75123e5d3..56b25e207 100644
--- a/airtime_mvc/application/models/Schedule.php
+++ b/airtime_mvc/application/models/Schedule.php
@@ -268,6 +268,7 @@ SQL;
$nextMedia = CcScheduleQuery::create()
->filterByDbStarts($currentMedia["starts"], Criteria::GREATER_THAN)
->filterByDbId($currentMedia["id"], Criteria::NOT_EQUAL)
+ ->filterByDbPlayoutStatus(0, Criteria::GREATER_THAN)
->orderByDbStarts(Criteria::ASC)
->findOne();
if (isset($nextMedia)) {
diff --git a/airtime_mvc/application/models/Show.php b/airtime_mvc/application/models/Show.php
index e5eca649f..fd41ab904 100644
--- a/airtime_mvc/application/models/Show.php
+++ b/airtime_mvc/application/models/Show.php
@@ -1287,7 +1287,7 @@ SQL;
"starts" => $rows[$i-1]['starts'],
"ends" => $rows[$i-1]['ends'],
"record" => $rows[$i-1]['record'],
- "image_path" => $rows[$i-1]['image_path'],
+ "image_path" => $rows[$i-1]['image_path'],
"type" => "show");
}
@@ -1345,7 +1345,6 @@ SQL;
"starts" => $rows[$previousShowIndex]['starts'],
"ends" => $rows[$previousShowIndex]['ends'],
"record" => $rows[$previousShowIndex]['record'],
- "image_path" => $rows[$previousShowIndex]['image_path'],
"type" => "show");
}
diff --git a/airtime_mvc/application/models/StoredFile.php b/airtime_mvc/application/models/StoredFile.php
index 8c5eb809f..ac639b9bb 100644
--- a/airtime_mvc/application/models/StoredFile.php
+++ b/airtime_mvc/application/models/StoredFile.php
@@ -1027,14 +1027,16 @@ SQL;
$LIQUIDSOAP_ERRORS = array('TagLib: MPEG::Properties::read() -- Could not find a valid last MPEG frame in the stream.');
// Ask Liquidsoap if file is playable
- $ls_command = sprintf('/usr/bin/airtime-liquidsoap -v -c "output.dummy(audio_to_stereo(single(%s)))" 2>&1',
+ /* CC-5990/5991 - Changed to point directly to liquidsoap, removed PATH export */
+ $command = sprintf('liquidsoap -v -c "output.dummy(audio_to_stereo(single(%s)))" 2>&1',
escapeshellarg($audio_file));
- $command = "export PATH=/usr/local/bin:/usr/bin:/bin/usr/bin/ && $ls_command";
exec($command, $output, $rv);
$isError = count($output) > 0 && in_array($output[0], $LIQUIDSOAP_ERRORS);
+ Logging::info("Is error?! : " . $isError);
+ Logging::info("ls playability response: " . $rv);
return ($rv == 0 && !$isError);
}
diff --git a/airtime_mvc/application/models/StreamSetting.php b/airtime_mvc/application/models/StreamSetting.php
index 688ddc397..391ae7dbb 100644
--- a/airtime_mvc/application/models/StreamSetting.php
+++ b/airtime_mvc/application/models/StreamSetting.php
@@ -75,8 +75,13 @@ class Application_Model_StreamSetting
$host = $streamData[$prefix."host"];
$port = $streamData[$prefix."port"];
$mount = $streamData[$prefix."mount"];
+ if ($streamData[$prefix."output"] == "shoutcast") {
+ $url = "http://$host:$port/";
+ } else { //Icecast
+ $url = "http://$host:$port/$mount";
+ }
$streams[$id] = Array(
- "url" => "http://$host:$port/$mount",
+ "url" => $url,
"codec" => $streamData[$prefix."type"],
"bitrate" => $streamData[$prefix."bitrate"],
"mobile" => $streamData[$prefix."mobile"]
diff --git a/airtime_mvc/application/models/Systemstatus.php b/airtime_mvc/application/models/Systemstatus.php
index 1b07099c9..b97ea491e 100644
--- a/airtime_mvc/application/models/Systemstatus.php
+++ b/airtime_mvc/application/models/Systemstatus.php
@@ -6,15 +6,15 @@ class Application_Model_Systemstatus
public static function GetMonitStatus($p_ip)
{
$CC_CONFIG = Config::getConfig();
- $monit_user = $CC_CONFIG['monit_user'];
- $monit_password = $CC_CONFIG['monit_password'];
+// $monit_user = $CC_CONFIG['monit_user'];
+// $monit_password = $CC_CONFIG['monit_password'];
$url = "http://$p_ip:2812/_status?format=xml";
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_USERPWD, "$monit_user:$monit_password");
+// curl_setopt($ch, CURLOPT_USERPWD, "$monit_user:$monit_password");
//wait a max of 3 seconds before aborting connection attempt
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
$result = curl_exec($ch);
diff --git a/airtime_mvc/application/models/User.php b/airtime_mvc/application/models/User.php
index ac428fefc..76e563155 100644
--- a/airtime_mvc/application/models/User.php
+++ b/airtime_mvc/application/models/User.php
@@ -282,7 +282,6 @@ class Application_Model_User
$con = Propel::getConnection();
$sql_gen = "SELECT login AS value, login AS label, id as index FROM cc_subjs ";
- $sql = $sql_gen;
$types = array();
$params = array();
@@ -296,13 +295,8 @@ class Application_Model_User
$sql = $sql_gen ." WHERE (". $sql_type.") ";
- if (!is_null($search)) {
- //need to use addslashes for 'LIKE' values
- $search = addslashes($search);
- $like = "login ILIKE '%{$search}%'";
-
- $sql = $sql . " AND ".$like;
- }
+ $sql .= " AND login ILIKE :search";
+ $params[":search"] = "%$search%";
$sql = $sql ." ORDER BY login";
diff --git a/airtime_mvc/application/upgrade/Upgrades.php b/airtime_mvc/application/upgrade/Upgrades.php
index adb54002c..774b9cff8 100644
--- a/airtime_mvc/application/upgrade/Upgrades.php
+++ b/airtime_mvc/application/upgrade/Upgrades.php
@@ -20,22 +20,73 @@ function getUpgrades() {
return array_filter(get_declared_classes(), "isUpgrade");
}
+class UpgradeManager
+{
+ /** Used to determine if the database schema needs an upgrade in order for this version of the Airtime codebase to work correctly.
+ * @return array A list of schema versions that this version of the codebase supports.
+ */
+ public static function getSupportedSchemaVersions()
+ {
+ //What versions of the schema does the code support today:
+ return array(AIRTIME_CODE_VERSION);
+ }
+
+ public static function checkIfUpgradeIsNeeded()
+ {
+ $schemaVersion = Application_Model_Preference::GetSchemaVersion();
+ $supportedSchemaVersions = self::getSupportedSchemaVersions();
+ $upgradeNeeded = !in_array($schemaVersion, $supportedSchemaVersions);
+ // We shouldn't run the upgrade as a side-effect of this function!
+ /*
+ if ($upgradeNeeded) {
+ self::doUpgrade();
+ }
+ */
+ }
+
+ public function doUpgrade()
+ {
+ $didWePerformAnUpgrade = false;
+ // Get all upgrades dynamically (in declaration order!) so we don't have to add them explicitly each time
+ // TODO: explicitly sort classnames by ascending version suffix for safety
+ $upgraders = getUpgrades();
+ return $this->runUpgrades($upgraders, (dirname(__DIR__) . "/controllers"));
+ }
+
+ /**
+ * Run a given set of upgrades
+ *
+ * @param array $upgraders the upgrades to perform
+ * @param string $dir the directory containing the upgrade sql
+ * @return boolean whether or not an upgrade was performed
+ */
+ public function runUpgrades($upgraders, $dir) {
+ $upgradePerformed = false;
+ foreach ($upgraders as $upgrader) {
+ /** @var $upgrader AirtimeUpgrader */
+ $upgrader = new $upgrader();
+ if ($upgrader->checkIfUpgradeSupported())
+ {
+ // pass the given directory to the upgrades, since __DIR__ returns parent dir of file, not executor
+ $upgrader->upgrade($dir); //This will throw an exception if the upgrade fails.
+ $didWePerformAnUpgrade = true;
+ }
+ }
+ return $upgradePerformed;
+ }
+
+}
+
abstract class AirtimeUpgrader
{
- /** Versions that this upgrader class can upgrade from (an array of version strings). */
- abstract protected function getSupportedVersions();
- /** The version that this upgrader class will upgrade to. (returns a version string) */
+ /** Schema versions that this upgrader class can upgrade from (an array of version strings). */
+ abstract protected function getSupportedSchemaVersions();
+ /** The schema version that this upgrader class will upgrade to. (returns a version string) */
abstract public function getNewVersion();
- public static function getCurrentVersion()
+ public static function getCurrentSchemaVersion()
{
- CcPrefPeer::clearInstancePool(); //Ensure we don't get a cached Propel object (cached DB results)
- //because we're updating this version number within this HTTP request as well.
- $pref = CcPrefQuery::create()
- ->filterByKeystr('system_version')
- ->findOne();
- $airtime_version = $pref->getValStr();
- return $airtime_version;
+ return Application_Model_Preference::GetSchemaVersion();
}
/**
@@ -44,7 +95,7 @@ abstract class AirtimeUpgrader
*/
public function checkIfUpgradeSupported()
{
- if (!in_array(AirtimeUpgrader::getCurrentVersion(), $this->getSupportedVersions())) {
+ if (!in_array(AirtimeUpgrader::getCurrentSchemaVersion(), $this->getSupportedSchemaVersions())) {
return false;
}
return true;
@@ -78,9 +129,10 @@ abstract class AirtimeUpgrader
class AirtimeUpgrader253 extends AirtimeUpgrader
{
- protected function getSupportedVersions()
+ protected function getSupportedSchemaVersions()
{
return array('2.5.1', '2.5.2');
+
}
public function getNewVersion()
{
@@ -129,8 +181,8 @@ class AirtimeUpgrader253 extends AirtimeUpgrader
$database = $values['database']['dbname'];
passthru("export PGPASSWORD=$password && psql -h $host -U $username -q -f $dir/upgrade_sql/airtime_".$this->getNewVersion()."/upgrade.sql $database 2>&1 | grep -v -E \"will create implicit sequence|will create implicit index\"");
-
- Application_Model_Preference::SetAirtimeVersion($this->getNewVersion());
+ Application_Model_Preference::SetSchemaVersion($this->getNewVersion());
+
//clear out the cache
Cache::clear();
@@ -145,7 +197,7 @@ class AirtimeUpgrader253 extends AirtimeUpgrader
class AirtimeUpgrader254 extends AirtimeUpgrader
{
- protected function getSupportedVersions()
+ protected function getSupportedSchemaVersions()
{
return array('2.5.3');
}
@@ -215,7 +267,7 @@ class AirtimeUpgrader254 extends AirtimeUpgrader
}
//$con->commit();
- Application_Model_Preference::SetAirtimeVersion($newVersion);
+ Application_Model_Preference::SetSchemaVersion($newVersion);
Cache::clear();
$this->toggleMaintenanceScreen(false);
@@ -231,7 +283,7 @@ class AirtimeUpgrader254 extends AirtimeUpgrader
}
class AirtimeUpgrader255 extends AirtimeUpgrader {
- protected function getSupportedVersions() {
+ protected function getSupportedSchemaVersions() {
return array (
'2.5.4'
);
@@ -263,7 +315,7 @@ class AirtimeUpgrader255 extends AirtimeUpgrader {
passthru("export PGPASSWORD=$password && psql -h $host -U $username -q -f $dir/upgrade_sql/airtime_"
.$this->getNewVersion()."/upgrade.sql $database 2>&1 | grep -v -E \"will create implicit sequence|will create implicit index\"");
- Application_Model_Preference::SetAirtimeVersion($newVersion);
+ Application_Model_Preference::SetSchemaVersion($newVersion);
Cache::clear();
$this->toggleMaintenanceScreen(false);
@@ -277,7 +329,7 @@ class AirtimeUpgrader255 extends AirtimeUpgrader {
}
class AirtimeUpgrader259 extends AirtimeUpgrader {
- protected function getSupportedVersions() {
+ protected function getSupportedSchemaVersions() {
return array (
'2.5.5'
);
@@ -309,7 +361,7 @@ class AirtimeUpgrader259 extends AirtimeUpgrader {
passthru("export PGPASSWORD=$password && psql -h $host -U $username -q -f $dir/upgrade_sql/airtime_"
.$this->getNewVersion()."/upgrade.sql $database 2>&1 | grep -v -E \"will create implicit sequence|will create implicit index\"");
- Application_Model_Preference::SetAirtimeVersion($newVersion);
+ Application_Model_Preference::SetSchemaVersion($newVersion);
Cache::clear();
$this->toggleMaintenanceScreen(false);
@@ -322,7 +374,7 @@ class AirtimeUpgrader259 extends AirtimeUpgrader {
class AirtimeUpgrader2510 extends AirtimeUpgrader
{
- protected function getSupportedVersions() {
+ protected function getSupportedSchemaVersions() {
return array (
'2.5.9'
);
@@ -354,7 +406,7 @@ class AirtimeUpgrader2510 extends AirtimeUpgrader
passthru("export PGPASSWORD=$password && psql -h $host -U $username -q -f $dir/upgrade_sql/airtime_"
.$this->getNewVersion()."/upgrade.sql $database 2>&1 | grep -v -E \"will create implicit sequence|will create implicit index\"");
- Application_Model_Preference::SetAirtimeVersion($newVersion);
+ Application_Model_Preference::SetSchemaVersion($newVersion);
Cache::clear();
$this->toggleMaintenanceScreen(false);
@@ -367,7 +419,7 @@ class AirtimeUpgrader2510 extends AirtimeUpgrader
class AirtimeUpgrader2511 extends AirtimeUpgrader
{
- protected function getSupportedVersions() {
+ protected function getSupportedSchemaVersions() {
return array (
'2.5.10'
);
@@ -395,7 +447,7 @@ class AirtimeUpgrader2511 extends AirtimeUpgrader
$disk_usage = $queryResult[0];
Application_Model_Preference::setDiskUsage($disk_usage);
- Application_Model_Preference::SetAirtimeVersion($newVersion);
+ Application_Model_Preference::SetSchemaVersion($newVersion);
Cache::clear();
$this->toggleMaintenanceScreen(false);
@@ -411,7 +463,7 @@ class AirtimeUpgrader2511 extends AirtimeUpgrader
class AirtimeUpgrader2512 extends AirtimeUpgrader
{
- protected function getSupportedVersions() {
+ protected function getSupportedSchemaVersions() {
return array (
'2.5.10',
'2.5.11'
@@ -444,7 +496,7 @@ class AirtimeUpgrader2512 extends AirtimeUpgrader
passthru("export PGPASSWORD=$password && psql -h $host -U $username -q -f $dir/upgrade_sql/airtime_"
.$this->getNewVersion()."/upgrade.sql $database 2>&1 | grep -v -E \"will create implicit sequence|will create implicit index\"");
- Application_Model_Preference::SetAirtimeVersion($newVersion);
+ Application_Model_Preference::SetSchemaVersion($newVersion);
Cache::clear();
$this->toggleMaintenanceScreen(false);
diff --git a/airtime_mvc/application/views/scripts/dashboard/about.phtml b/airtime_mvc/application/views/scripts/dashboard/about.phtml
index 98e93e724..05880b422 100644
--- a/airtime_mvc/application/views/scripts/dashboard/about.phtml
+++ b/airtime_mvc/application/views/scripts/dashboard/about.phtml
@@ -11,7 +11,7 @@ echo sprintf(_('%1$s %2$s, the open radio software for scheduling and remote sta
$this->airtime_version)
?>
- ยฉ 2013
+ ยฉ
"
. COMPANY_NAME . " " . COMPANY_SUFFIX
diff --git a/airtime_mvc/application/views/scripts/embed/current-day-program.phtml b/airtime_mvc/application/views/scripts/embed/current-day-program.phtml
new file mode 100644
index 000000000..a4dbd3872
--- /dev/null
+++ b/airtime_mvc/application/views/scripts/embed/current-day-program.phtml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/airtime_mvc/application/views/scripts/embed/player.phtml b/airtime_mvc/application/views/scripts/embed/player.phtml
index 6c3b1d06b..80bc71fde 100644
--- a/airtime_mvc/application/views/scripts/embed/player.phtml
+++ b/airtime_mvc/application/views/scripts/embed/player.phtml
@@ -237,6 +237,18 @@
document.getElementById("stop_button").classList.toggle("hide_button");
}
+ $(document).ready(function() {
+ $(".play").click(function () {
+ if ($(this).hasClass("pause")) {
+ musesPlayer.stop();
+ } else {
+ musesPlayer.play();
+ }
+
+ $(this).toggleClass("pause");
+ });
+ });
+
// variables for updating the player's metadata
var time_to_next_track_starts = 0;
var metadataTimer = null;
@@ -252,11 +264,11 @@
success: function(data) {
if (data.current === null) {
- if (data.currentShow != null && data.currentShow.length != 0) {
- // Master/show source have no current track but they do have a current show.
- $("p.now_playing").html(data.currentShow[0].name);
+ if (data.currentShow != null && data.currentShow.length > 0) {
+ //Master/show source have no current track but they do have a current show.
+ $("p.now_playing").html("On Air:" + "" + data.currentShow[0].name + "");
} else {
- $("p.now_playing").html("Offline");
+ $("p.now_playing").html("Off Air" + "Offline");
}
time_to_next_track_starts = 20000;
} else {
@@ -294,6 +306,7 @@
metadataTimer = setTimeout(attachStreamMetadataToPlayer, time_to_next_track_starts+3000);
}
+