From f5b492853888706de84e749de24cce19f175f6ed Mon Sep 17 00:00:00 2001 From: Duncan Sommerville Date: Tue, 9 Dec 2014 17:48:16 -0500 Subject: [PATCH] More work on web installer --- airtime_mvc/application/configs/conf.php | 2 +- .../application/configs/config-check.php | 24 ++-- .../airtime-setup/forms/database-settings.php | 19 +--- .../airtime-setup/forms/finish-settings.php | 22 ++++ .../airtime-setup/forms/general-settings.php | 31 +++++ .../airtime-setup/forms/media-settings.php | 31 +++++ .../airtime-setup/forms/rabbitmq-settings.php | 16 +-- airtime_mvc/build/airtime-setup/load.php | 25 +++- .../build/airtime-setup/setup-config.php | 18 ++- airtime_mvc/library/php-amqplib/amqp.inc | 22 ++-- airtime_mvc/public/css/setup/config-check.css | 27 +++++ airtime_mvc/public/css/setup/setup-config.css | 65 ++++++----- airtime_mvc/public/index.php | 4 +- airtime_mvc/public/js/setup/setup-config.js | 83 ++++++++------ airtime_mvc/public/setup/database-setup.php | 98 +++++++++++++--- airtime_mvc/public/setup/finish-setup.php | 31 +++++ airtime_mvc/public/setup/general-setup.php | 61 ++++++++++ airtime_mvc/public/setup/media-setup.php | 107 ++++++++++++++++++ airtime_mvc/public/setup/rabbitmq-setup.php | 69 ++++++++++- airtime_mvc/public/setup/setup-functions.php | 41 ++++++- .../models/unit/PreferenceUnitTest.php | 2 +- installer/install | 64 +++++++++-- utils/soundcloud-uploader.php | 52 +++------ 23 files changed, 728 insertions(+), 186 deletions(-) create mode 100644 airtime_mvc/build/airtime-setup/forms/finish-settings.php create mode 100644 airtime_mvc/build/airtime-setup/forms/general-settings.php create mode 100644 airtime_mvc/build/airtime-setup/forms/media-settings.php create mode 100644 airtime_mvc/public/setup/finish-setup.php create mode 100644 airtime_mvc/public/setup/general-setup.php create mode 100644 airtime_mvc/public/setup/media-setup.php diff --git a/airtime_mvc/application/configs/conf.php b/airtime_mvc/application/configs/conf.php index 903b845c2..132605179 100644 --- a/airtime_mvc/application/configs/conf.php +++ b/airtime_mvc/application/configs/conf.php @@ -34,7 +34,7 @@ class Config { $CC_CONFIG['baseDir'] = $values['general']['base_dir']; $CC_CONFIG['baseUrl'] = $values['general']['base_url']; $CC_CONFIG['basePort'] = $values['general']['base_port']; - $CC_CONFIG['phpDir'] = $values['general']['airtime_dir']; +// $CC_CONFIG['phpDir'] = $values['general']['airtime_dir']; $CC_CONFIG['cache_ahead_hours'] = $values['general']['cache_ahead_hours']; diff --git a/airtime_mvc/application/configs/config-check.php b/airtime_mvc/application/configs/config-check.php index 11291d446..384856dbd 100644 --- a/airtime_mvc/application/configs/config-check.php +++ b/airtime_mvc/application/configs/config-check.php @@ -20,19 +20,18 @@ $r = array_reduce($phpDependencies, "booleanReduce", true); $result = $r && $database; ?> - + - +

-
+
Configuration Checklist

- +
- - -
@@ -61,10 +60,10 @@ $result = $r && $database; Zend MVC Framework > + > + ?>"> Ubuntu: try running sudo apt-get install libzend-framework-php
Debian: try running sudo apt-get install zendframework PDO and PostgreSQL libraries
> + > + ?>"> Try running sudo apt-get install php5-pgsql Database configuration for Airtime > + > + ?>"> 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 airtime.conf is correct and the Airtime database was installed correctly. @@ -118,6 +117,7 @@ $result = $r && $database;
+ @@ -135,8 +135,6 @@ $result = $r && $database; - -
@@ -32,6 +31,21 @@ require_once SETUP_PATH . "forms/rabbitmq-settings.php"; ?>
+
+ +
+
+ +
+
+ +
diff --git a/airtime_mvc/library/php-amqplib/amqp.inc b/airtime_mvc/library/php-amqplib/amqp.inc index 1bf03b3c4..eca4de6fe 100644 --- a/airtime_mvc/library/php-amqplib/amqp.inc +++ b/airtime_mvc/library/php-amqplib/amqp.inc @@ -436,10 +436,13 @@ class AMQPConnection extends AbstractChannel $len = strlen($data); while(true) { - if(false === ($written = fwrite($this->sock, $data))) + $written = fwrite($this->sock, $data); + + if($written == false || $written <= 0) { throw new Exception ("Error sending data"); } + $len = $len - $written; if($len>0) $data=substr($data,0-$len); @@ -599,12 +602,17 @@ class AMQPConnection extends AbstractChannel */ public function close($reply_code=0, $reply_text="", $method_sig=array(0, 0)) { - $args = new AMQPWriter(); - $args->write_short($reply_code); - $args->write_shortstr($reply_text); - $args->write_short($method_sig[0]); // class_id - $args->write_short($method_sig[1]); // method_id - $this->send_method_frame(array(10, 60), $args); + try { + $args = new AMQPWriter(); + $args->write_short($reply_code); + $args->write_shortstr($reply_text); + $args->write_short($method_sig[0]); // class_id + $args->write_short($method_sig[1]); // method_id + $this->send_method_frame(array(10, 60), $args); + } catch(Exception $e) { + return; + } + return $this->wait(array( "10,61", // Connection.close_ok )); diff --git a/airtime_mvc/public/css/setup/config-check.css b/airtime_mvc/public/css/setup/config-check.css index d535a5dd3..6967f1165 100644 --- a/airtime_mvc/public/css/setup/config-check.css +++ b/airtime_mvc/public/css/setup/config-check.css @@ -1,3 +1,26 @@ +html { + background-color: #f5f5f5; +} + +body { + padding: 2em 0; + min-width: 600px; + width: 50%; + text-align: center; + margin: 3em auto; + border: 1px solid lightgray; + border-radius: 5em; +} + +.logo { + margin-bottom: .5em; +} + +.table { + padding: 0; + margin: 3em 0 0 0; +} + .checklist { overflow: auto; height: 50%; @@ -16,6 +39,10 @@ width: 40%; } +.check { + background: #dff0d8 url("css/images/accept.png") no-repeat center; +} + .footer { margin: inherit; width: inherit; diff --git a/airtime_mvc/public/css/setup/setup-config.css b/airtime_mvc/public/css/setup/setup-config.css index 9c5356791..b2dd4844f 100644 --- a/airtime_mvc/public/css/setup/setup-config.css +++ b/airtime_mvc/public/css/setup/setup-config.css @@ -47,8 +47,12 @@ body { * ############################################################################ */ form { - width: 80%; margin: auto; + top: 0; + width: 99%; + position: absolute; + float: right; + } form p { @@ -69,6 +73,10 @@ form .form-group { overflow-y: auto; } +.form-wrapper { + overflow: auto; +} + .form-title { margin: 1em 0; } @@ -166,23 +174,6 @@ form .form-group { border-bottom: 4px solid #fff; } -/* ############################################################################ - * - * Database Settings Form Styles - * - * ############################################################################ */ - -#dbSettingsForm { - top: 0; - width: 99%; - position: absolute; - float: right; -} - -#dbSettings { - overflow: auto; -} - /* ############################################################################ * * RabbitMQ Settings Form Styles @@ -190,17 +181,39 @@ form .form-group { * ############################################################################ */ #rmqSettingsForm { - top: 0; left: 100%; - width: 99%; - position: absolute; - float: right; -} - -#rmqSettings { - overflow: auto; } #rmqFormBody { display: none; +} + +/* ############################################################################ + * + * General Settings Form Styles + * + * ############################################################################ */ + +#generalSettingsForm { + left: 200%; +} + +/* ############################################################################ + * + * Media Settings Form Styles + * + * ############################################################################ */ + +#mediaSettingsForm { + left: 300%; +} + +/* ############################################################################ + * + * Finish Settings Form Styles + * + * ############################################################################ */ + +#finishSettingsForm { + left: 400%; } \ No newline at end of file diff --git a/airtime_mvc/public/index.php b/airtime_mvc/public/index.php index 41c2b7966..45e519111 100644 --- a/airtime_mvc/public/index.php +++ b/airtime_mvc/public/index.php @@ -24,6 +24,8 @@ define('SETUP_PATH', BUILD_PATH . 'airtime-setup/'); define('APPLICATION_PATH', ROOT_PATH . 'application/'); define('CONFIG_PATH', APPLICATION_PATH . 'configs/'); +define("AIRTIME_CONFIG_STOR", "/etc/airtime/"); + define('AIRTIME_CONFIG', 'airtime.conf'); require_once(LIB_PATH . "propel/runtime/lib/Propel.php"); @@ -37,7 +39,7 @@ if (array_key_exists('config', $_GET)) { } // If a configuration file exists, forward to our boot script -if (file_exists(BUILD_PATH . AIRTIME_CONFIG)) { +if (file_exists(AIRTIME_CONFIG_STOR . AIRTIME_CONFIG)) { /* * Even if the user has been through the setup process and * created an airtime.conf file (or they may have simply diff --git a/airtime_mvc/public/js/setup/setup-config.js b/airtime_mvc/public/js/setup/setup-config.js index 113710e8f..9441ed44d 100644 --- a/airtime_mvc/public/js/setup/setup-config.js +++ b/airtime_mvc/public/js/setup/setup-config.js @@ -2,6 +2,7 @@ * Do some cleanup when we get a success response from a POST request * during setup * @param data the POST request return data + * @param e the jquery event */ function cleanupStep(data, e) { showFeedback(data); @@ -19,16 +20,16 @@ function cleanupStep(data, e) { * @param data the POST request return data */ function showFeedback(data) { - if (data.errors.length > 0) { - $(".help-message").addClass("has-error"); - $(".form-control-feedback").show(); - } else { - $(".help-message").addClass("has-success"); - } toggleMessage(data.message); for (var i = 0; i < data.errors.length; i++) { $("#" + data.errors[i]).parent().addClass("has-error has-feedback"); } + if (data.errors.length > 0) { + $(".help-message").addClass("has-error"); + $(".has-error .form-control-feedback").show(); + } else { + $(".help-message").addClass("has-success"); + } } /** @@ -36,8 +37,7 @@ function showFeedback(data) { */ function resetFeedback() { $(".form-control-feedback").hide(); - $("#helpBlock").html(""); - $(".has-error, .has-feedback").removeClass("has-error has-feedback"); + $(".has-success, .has-error, .has-feedback").removeClass("has-success has-error has-feedback"); } /** @@ -47,16 +47,12 @@ function resetFeedback() { function toggleMessage(msg) { /* * Since setting display:none; on this element causes odd behaviour - * with bootstrap, hide() the element so we can slide it in. + * with bootstrap, hide() the element so we can formSlide it in. * This is only really only necessary the first time this * function is called after page load. */ - $(".help-message").hide(); - $(".help-message").html(msg); - $(".help-message").slideDown(200); - window.setTimeout(function() { - $(".help-message").slideUp(200); - }, 3000); + var help = $(".help-message"); + help.html(msg).show(); } /** @@ -77,37 +73,60 @@ function removeOverlay() { }); } +function formSlide(dir) { + var delta = (dir == "next") ? "-=100%" : "+=100%"; + $(".btn").attr("disabled", "disabled"); + $(".form-slider").animate({left: delta}, 500, function() { + $(".btn").removeAttr("disabled"); + }); + var stepCount = $("#stepCount"), + steps = parseInt(stepCount.html()); + stepCount.html((dir == "next") ? (steps + 1) : (steps - 1)); + hideRMQForm(); +} + /** * Fade out the previous setup step and fade in the next one */ function nextSlide() { - $(".btn").attr("disabled", "disabled"); - $(".form-slider").animate({left: "-=100%"}, 500, function() { - $(".btn").removeAttr("disabled"); - }); - var stepCount = parseInt($("#stepCount").html()); - $("#stepCount").html(stepCount + 1); + formSlide("next"); } /** * Fade out the current setup step and fade in the previous one */ function prevSlide() { - $(".btn").attr("disabled", "disabled"); - $(".form-slider").animate({left: "+=100%"}, 500, function() { - $(".btn").removeAttr("disabled"); + formSlide("prev"); +} + +/** + * Hide the RMQ form when the slider is called to avoid showing + * scrollbars on slider panels that fit vertically + */ +function hideRMQForm() { + $("#rmqFormBody").slideUp(500); + $("#advCaret").removeClass("caret-up"); +} + +function submitForm(e, obj) { + resetFeedback(); + e.preventDefault(); + var d = $(e.target).serializeArray(); + addOverlay(); + // Append .promise().done() rather than using a + // callback to avoid weird alert duplication + $("#overlay, #loadingImage").fadeIn(500).promise().done(function() { + // Proxy function for passing the event to the cleanup function + var cleanupProxy = function(data) { + cleanupStep.call(this, data, e); + }; + $.post('setup/setup-functions.php?obj=' + obj, d, cleanupProxy, "json"); }); - var stepCount = parseInt($("#stepCount").html()); - $("#stepCount").html(stepCount - 1); } $(function() { - $(".form-slider").draggable({ - revert: true, - axis: 'x', - snap: ".viewport", - snapMode: "both", - }); + // Stop the user from dragging the slider + $(".form-slider").draggable('disable'); window.onresize = function() { var headerHeight = $(".header").outerHeight(), diff --git a/airtime_mvc/public/setup/database-setup.php b/airtime_mvc/public/setup/database-setup.php index f29355d83..115cf840c 100644 --- a/airtime_mvc/public/setup/database-setup.php +++ b/airtime_mvc/public/setup/database-setup.php @@ -1,20 +1,29 @@ value pairs for airtime.conf + static $properties; + + // Message and error fields to return to the front-end static $message = null; static $errors = array(); @@ -23,6 +32,13 @@ class DatabaseSetup extends Setup { self::$pass = $settings[self::DB_PASS]; self::$name = $settings[self::DB_NAME]; self::$host = $settings[self::DB_HOST]; + + self::$properties = array( + "host" => self::$host, + "dbname" => self::$name, + "dbuser" => self::$user, + "dbpass" => self::$pass, + ); } /** @@ -33,47 +49,70 @@ class DatabaseSetup extends Setup { */ function runSetup() { // Check the connection and user credentials - if ($this->validateDatabaseConnection()) { + if ($this->checkDatabaseConnection()) { // We know that the user credentials check out, so check if the database exists - if ($this->validateDatabaseSettings()) { - // The database already exists, so we can just set up the schema - if ($this->createDatabaseTables()) { - self::$message = "Successfully installed Airtime database to '" . self::$name . "'"; + if ($this->checkDatabaseExists()) { + // The database already exists, check if the schema exists as well + if ($this->checkSchemaExists()) { + self::$message = "Airtime is already installed in this database!"; } else { - self::$message = "Something went wrong setting up the Airtime schema!"; + if ($this->createDatabaseTables()) { + self::$message = "Successfully installed Airtime database to '" . self::$name . "'"; + } else { + self::$message = "Something went wrong setting up the Airtime schema!"; + self::$errors[] = self::DB_NAME; + } } } else { // The database doesn't exist, so check if the user can create databases if ($this->checkUserCanCreateDb()) { // The user can create a database, do it if ($this->createDatabase()) { - if ($this->createDatabaseTables()) { - self::$message = "Successfully installed Airtime database to '" . self::$name . "'"; + // Ensure that the database was installed in UTF8 (we only care about the Airtime database) + if ($this->checkDatabaseSchema()) { + if ($this->createDatabaseTables()) { + self::$message = "Successfully installed Airtime database to '" . self::$name . "'"; + } else { + self::$message = "Something went wrong setting up the Airtime schema!"; + self::$errors[] = self::DB_NAME; + } } else { - self::$message = "Something went wrong setting up the Airtime schema!"; + self::$message = "The database was installed with an incorrect encoding type!"; + self::$errors[] = self::DB_NAME; } } else { self::$message = "There was an error installing the database!"; + self::$errors[] = self::DB_NAME; } } // The user can't create databases, so we're done else { self::$message = "No database " . self::$name . " exists; user " . self::$user . " does not have permission to create databases on " . self::$host; + self::$errors[] = self::DB_NAME; } } } + if (count(self::$errors) <= 0) { + $this->writeToTemp(); + } + return array( "message" => self::$message, "errors" => self::$errors, ); } + function writeToTemp() { + parent::writeToTemp(self::SECTION, self::$properties); + } + + /** * Check if the user's database connection is valid * @return boolean true if the connection are valid */ - function validateDatabaseConnection() { + function checkDatabaseConnection() { // This is pretty redundant, but we need to test both // the existence and the validity of the given credentials exec("export PGPASSWORD=" . self::$pass . " && psql -h " @@ -97,12 +136,23 @@ class DatabaseSetup extends Setup { * Check if the database settings and credentials given are valid * @return boolean true if the database given exists and the user is valid and can access it */ - function validateDatabaseSettings() { + function checkDatabaseExists() { exec("export PGPASSWORD=" . self::$pass . " && psql -lqt -h " . self::$host . " -U " . self::$user . "| cut -d \\| -f 1 | grep -w " . self::$name, $out, $status); return $status == 0; } + /** + * Check if the database schema has already been set up + * @return boolean true if the database schema exists + */ + function checkSchemaExists() { + // Check for cc_pref to see if the schema is already installed in this database + exec("export PGPASSWORD=" . self::$pass . " && psql -U " . self::$user . " -h " + . self::$host . " -d " . self::$name . " -tAc \"SELECT * FROM cc_pref\"", $out, $status); + return $status == 0; + } + /** * Check if the given user has access on the given host to create a new database * @return boolean true if the given user has permission to create a database on the given host @@ -132,15 +182,33 @@ class DatabaseSetup extends Setup { $sqlDir = dirname(dirname(__DIR__)) . "/build/sql/"; $files = array("schema.sql", "sequences.sql", "views.sql", "triggers.sql", "defaultdata.sql"); - foreach($files as $f) { + foreach ($files as $f) { try { exec("export PGPASSWORD=" . self::$pass . " && psql -U " . self::$user . " --dbname " . self::$name . " -h " . self::$host . " -f $sqlDir$f 2>/dev/null", $out, $status); - } catch(Exception $e) { + } catch (Exception $e) { return false; } } return true; } + /** + * Checks whether the newly-created database's encoding was properly set to UTF8 + * @return boolean true if the database encoding is UTF8 + */ + function checkDatabaseEncoding() { + exec("export PGPASSWORD=" . self::$pass . " && psql -U " . self::$user . " -h " + . self::$host . " -d " . self::$name . " -tAc \"SHOW SERVER_ENCODING\"", $out, $status); + return $out && $out[0] == "UTF8"; + } + + // TODO Since we already check the encoding, is there a purpose to verifying the schema? + function checkDatabaseSchema() { + $outFile = "/tmp/tempSchema.xml"; + exec("export PGPASSWORD=" . self::$pass . " && psql -U " . self::$user . " -h " + . self::$host . " -o ${outFile} -tAc \"SELECT database_to_xml(FALSE, FALSE, '" + . self::$name . "')\"", $out, $status); + } + } diff --git a/airtime_mvc/public/setup/finish-setup.php b/airtime_mvc/public/setup/finish-setup.php new file mode 100644 index 000000000..704164c14 --- /dev/null +++ b/airtime_mvc/public/setup/finish-setup.php @@ -0,0 +1,31 @@ +createAirtimeConfigDirectory()) { + $this->moveAirtimeConfig(); + } + } + + function createAirtimeConfigDirectory() { + return file_exists("/etc/airtime/") ? true + : mkdir("/etc/airtime/", 0755, true); + } + + function moveAirtimeConfig() { + return copy(AIRTIME_CONF_TEMP_PATH, "/etc/airtime/airtime.conf"); + } + +} \ No newline at end of file diff --git a/airtime_mvc/public/setup/general-setup.php b/airtime_mvc/public/setup/general-setup.php new file mode 100644 index 000000000..cf5516820 --- /dev/null +++ b/airtime_mvc/public/setup/general-setup.php @@ -0,0 +1,61 @@ +value pairs for airtime.conf + static $properties; + + // Message and error fields to return to the front-end + static $message = null; + static $errors = array(); + + function __construct($settings) { + self::$host = $settings[self::GENERAL_HOST]; + self::$port = $settings[self::GENERAL_PORT]; + + self::$properties = array( + "api_key" => $this->generateRandomString(), + "base_url" => self::$host, + "base_port" => self::$port, + ); + } + + function writeToTemp() { + parent::writeToTemp(self::SECTION, self::$properties); + } + + /** + * @return array associative array containing a display message and fields with errors + */ + function runSetup() { + + + if (count(self::$errors) <= 0) { + $this->writeToTemp(); + } + + return array( + "message" => self::$message, + "errors" => self::$errors + ); + } + +} \ No newline at end of file diff --git a/airtime_mvc/public/setup/media-setup.php b/airtime_mvc/public/setup/media-setup.php new file mode 100644 index 000000000..a5525b0df --- /dev/null +++ b/airtime_mvc/public/setup/media-setup.php @@ -0,0 +1,107 @@ +setupMusicDirectory(); + } else { + self::$message = "Invalid path!"; + self::$errors[] = self::MEDIA_FOLDER; + } + + return array( + "message" => self::$message, + "errors" => self::$errors + ); + } + + /** + * Add the given directory to cc_music_dirs + * TODO Should we check for an existing entry in cc_music_dirs? + */ + function setupMusicDirectory() { + try { + $_SERVER['AIRTIME_CONF'] = AIRTIME_CONF_TEMP_PATH; + Propel::init(CONFIG_PATH . "airtime-conf-production.php"); + $con = Propel::getConnection(); + } catch(Exception $e) { + self::$message = "Failed to insert media folder; database isn't configured properly!"; + self::$errors[] = self::MEDIA_FOLDER; + return; + } + + $this->runMusicDirsQuery($con); + } + + function runMusicDirsQuery($con) { + try { + if ($this->checkMusicDirectoryExists($con)) { + $dir = CcMusicDirsQuery::create()->findPk(1, $con); + } else { + $dir = new CcMusicDirs(); + } + + $dir->setDirectory(self::$path) + ->setType("stor") + ->save(); + self::$message = "Successfully set up media folder!"; + Propel::close(); + unset($_SERVER['AIRTIME_CONF']); + } catch (Exception $e) { + self::$message = "Failed to insert " . self::$path . " into cc_music_dirs"; + self::$errors[] = self::MEDIA_FOLDER; + } + + } + + function checkMusicDirectoryExists($con) { + $entry = CcMusicDirsQuery::create()->findPk(1, $con); + return isset($entry) && $entry; + } + +} \ No newline at end of file diff --git a/airtime_mvc/public/setup/rabbitmq-setup.php b/airtime_mvc/public/setup/rabbitmq-setup.php index 0dc2334c2..817b51742 100644 --- a/airtime_mvc/public/setup/rabbitmq-setup.php +++ b/airtime_mvc/public/setup/rabbitmq-setup.php @@ -1,4 +1,7 @@ value pairs for airtime.conf + static $properties; + + // Message and error fields to return to the front-end + static $message = null; + static $errors = array(); function __construct($settings) { self::$user = $settings[self::RMQ_USER]; @@ -23,19 +38,63 @@ class RabbitMQSetup extends Setup { self::$port = $settings[self::RMQ_PORT]; self::$host = $settings[self::RMQ_HOST]; self::$vhost = $settings[self::RMQ_VHOST]; + + self::$properties = array( + "host" => self::$host, + "port" => self::$port, + "user" => self::$user, + "password" => self::$pass, + "vhost" => self::$vhost, + ); } /** * @return array associative array containing a display message and fields with errors */ function runSetup() { - $message = ""; - $errors = array(); + try { + if ($this->checkRMQConnection()) { + self::$message = "Connection successful!"; + } else { + $this->identifyRMQConnectionError(); + } + } catch(Exception $e) { + $this->identifyRMQConnectionError(); + } + + if (count(self::$errors) <= 0) { + $this->writeToTemp(); + } return array( - "message" => $message, - "errors" => $errors + "message" => self::$message, + "errors" => self::$errors ); } + function writeToTemp() { + parent::writeToTemp(self::SECTION, self::$properties); + } + + function checkRMQConnection() { + $conn = new AMQPConnection(self::$host, + self::$port, + self::$user, + self::$pass, + self::$vhost); + return isset($conn); + } + + function identifyRMQConnectionError() { + // It's impossible to identify errors coming out of amqp.inc without a major + // rewrite, so for now just tell the user ALL THE THINGS went wrong + self::$message = "Couldn't connect to RabbitMQ server! Please check if the server " + . "is running and your credentials are correct."; + self::$errors[] = self::RMQ_USER; + self::$errors[] = self::RMQ_PASS; + self::$errors[] = self::RMQ_HOST; + self::$errors[] = self::RMQ_PORT; + self::$errors[] = self::RMQ_VHOST; + } + } \ No newline at end of file diff --git a/airtime_mvc/public/setup/setup-functions.php b/airtime_mvc/public/setup/setup-functions.php index 7273527ad..d7c61c050 100644 --- a/airtime_mvc/public/setup/setup-functions.php +++ b/airtime_mvc/public/setup/setup-functions.php @@ -1,5 +1,8 @@ assertEquals(Application_Model_Preference::GetHeadTitle(), $title); } diff --git a/installer/install b/installer/install index bcfa5eb8d..79fdc7413 100644 --- a/installer/install +++ b/installer/install @@ -9,22 +9,50 @@ fi showhelp () { echo "Usage: airtime-install [options] ---help|-h Displays usage information. ---apache|-a Installs apache and deploys a basic configuration for Airtime." +-h, --help Displays usage information. +-w, --web-user=WEB_USER Set the default apache web user. +-a, --apache Installs apache and deploys a basic configuration for Airtime." exit 0 } +web_user="www-data" apache="f" -while [ $# -gt 0 ] -do +while :; do case "$1" in - (-h|--help) showhelp; exit 0;; - (-a|--apache) apache="t";; - - (--) shift; break;; - (-*) echo "$0: error - unrecognized option $1" 1>&2; exit 1;; - (*) break;; + -h|-\?|--help) + showhelp + exit + ;; + -a|--apache) + apache="t" + ;; + -w|--web-user) + if [ "$2" ]; then + web_user=$2 + shift 2 + continue + else + echo 'ERROR: Must specify a non-empty "--web-user WEB_USER" argument.' >&2 + exit 1 + fi + ;; + --web-user=?*) + web_user=${1#*=} # Delete everything up to "=" and assign the remainder. + ;; + --web-user=) + echo 'ERROR: Must specify a non-empty "--web-user WEB_USER" argument.' >&2 + exit 1 + ;; + --) + shift + break + ;; + -?*) + echo "$0: error - unrecognized option $1" 1>&2; + ;; + *) + break esac shift done @@ -136,14 +164,26 @@ EXCHANGES="airtime-pypo|pypo-fetch|airtime-media-monitor|media-monitor" rabbitmqctl list_vhosts | grep -w ${RABBITMQ_VHOST} RESULT="$?" +# Only run these if the user doesn't exist if [ ${RESULT} != "0" ]; then - echo " ## Creating RabbitMQ user $RABBITMQ_USER" + echo " ## Creating RabbitMQ user ${RABBITMQ_USER}..." rabbitmqctl add_vhost ${RABBITMQ_VHOST} rabbitmqctl add_user ${RABBITMQ_USER} ${RABBITMQ_PASSWORD} - rabbitmqctl set_permissions -p ${RABBITMQ_VHOST} ${RABBITMQ_USER} "$EXCHANGES" "$EXCHANGES" "$EXCHANGES" +else + echo "RabbitMQ user already exists, skipping creation" fi +echo " ## Setting RabbitMQ user permissions..." +rabbitmqctl set_permissions -p ${RABBITMQ_VHOST} ${RABBITMQ_USER} "$EXCHANGES" "$EXCHANGES" "$EXCHANGES" + +echo -e "\n-----------------------------------------------------" +echo " * Installing Airtime * " +echo "-----------------------------------------------------" + +mkdir /etc/airtime +chown -R ${web_user}:${web_user} /etc/airtime + echo -e "\n-----------------------------------------------------" echo " * Basic Setup DONE! * " echo " " diff --git a/utils/soundcloud-uploader.php b/utils/soundcloud-uploader.php index 0e1245945..646c1695d 100644 --- a/utils/soundcloud-uploader.php +++ b/utils/soundcloud-uploader.php @@ -1,52 +1,31 @@ setSoundCloudFileId(SOUNDCLOUD_PROGRESS); $file->uploadToSoundCloud(); -