More work on web installer

This commit is contained in:
Duncan Sommerville 2014-12-09 17:48:16 -05:00
parent 9fed113f74
commit f5b4928538
23 changed files with 728 additions and 186 deletions

View File

@ -34,7 +34,7 @@ class Config {
$CC_CONFIG['baseDir'] = $values['general']['base_dir']; $CC_CONFIG['baseDir'] = $values['general']['base_dir'];
$CC_CONFIG['baseUrl'] = $values['general']['base_url']; $CC_CONFIG['baseUrl'] = $values['general']['base_url'];
$CC_CONFIG['basePort'] = $values['general']['base_port']; $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']; $CC_CONFIG['cache_ahead_hours'] = $values['general']['cache_ahead_hours'];

View File

@ -20,19 +20,18 @@ $r = array_reduce($phpDependencies, "booleanReduce", true);
$result = $r && $database; $result = $r && $database;
?> ?>
<html style="background-color: #f5f5f5"> <html>
<head> <head>
<link rel="stylesheet" type="text/css" href="css/bootstrap-3.3.1.min.css"> <link rel="stylesheet" type="text/css" href="css/bootstrap-3.3.1.min.css">
<link rel="stylesheet" type="text/css" href="css/setup/config-check.css"> <link rel="stylesheet" type="text/css" href="css/setup/config-check.css">
</head> </head>
<body style="padding: 2em 0; min-width: 600px; width: 50%; text-align: center; margin: 3em auto; <body>
border: 1px solid lightgray; border-radius: 5em;">
<h2> <h2>
<img src="css/images/airtime_logo_jp.png" style="margin-bottom: .5em;" /><br/> <img class="logo" src="css/images/airtime_logo_jp.png" /><br/>
<strong>Configuration Checklist</strong> <strong>Configuration Checklist</strong>
</h2> </h2>
<table class="table" style="padding: 0; margin: 3em 0 0 0; font-weight: bold"> <table class="table">
<thead> <thead>
<tr> <tr>
<td class="component"> <td class="component">
@ -61,10 +60,10 @@ $result = $r && $database;
<td class="description"> <td class="description">
Zend MVC Framework Zend MVC Framework
</td> </td>
<td class="solution" <?php if ($zend) {echo 'style="background: #dff0d8 url(css/images/accept.png) no-repeat center"';?>> <td class="solution <?php if ($zend) {echo 'check';?>">
<?php <?php
} else { } else {
?>> ?>">
<b>Ubuntu</b>: try running <code>sudo apt-get install libzend-framework-php</code> <b>Ubuntu</b>: try running <code>sudo apt-get install libzend-framework-php</code>
<br/><b>Debian</b>: try running <code>sudo apt-get install zendframework</code> <br/><b>Debian</b>: try running <code>sudo apt-get install zendframework</code>
<?php <?php
@ -79,10 +78,10 @@ $result = $r && $database;
<td class="description"> <td class="description">
PDO and PostgreSQL libraries PDO and PostgreSQL libraries
</td> </td>
<td class="solution" <?php if ($postgres) {echo 'style="background: #dff0d8 url(css/images/accept.png) no-repeat center"';?>> <td class="solution <?php if ($postgres) {echo 'check';?>">
<?php <?php
} else { } else {
?>> ?>">
Try running <code>sudo apt-get install php5-pgsql</code> Try running <code>sudo apt-get install php5-pgsql</code>
<?php <?php
} }
@ -104,10 +103,10 @@ $result = $r && $database;
<td class="description"> <td class="description">
Database configuration for Airtime Database configuration for Airtime
</td> </td>
<td class="solution" <?php if ($database) {echo 'style="background: #dff0d8 url(css/images/accept.png) no-repeat center"';?>> <td class="solution <?php if ($database) {echo 'check';?>">
<?php <?php
} else { } else {
?>> ?>">
Make sure you aren't missing any of the Postgres dependencies in the table above. 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 If your dependencies check out, make sure your database configuration settings in
<code>airtime.conf</code> is correct and the Airtime database was installed correctly. <code>airtime.conf</code> is correct and the Airtime database was installed correctly.
@ -118,6 +117,7 @@ $result = $r && $database;
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div>
<?php <?php
if (!$result) { if (!$result) {
?> ?>
@ -135,8 +135,6 @@ $result = $r && $database;
<?php <?php
} }
?> ?>
</div>
<div class="footer"> <div class="footer">
<h3> <h3>
PHP Extension List PHP Extension List

View File

@ -6,12 +6,12 @@
<span id="helpBlock" class="help-block help-message"></span> <span id="helpBlock" class="help-block help-message"></span>
<div class="form-group"> <div class="form-group">
<label class="control-label" for="dbUser">Username</label> <label class="control-label" for="dbUser">Username</label>
<input required class="form-control" type="text" name="dbUser" id="dbUser" placeholder="Username"/> <input required class="form-control" type="text" name="dbUser" id="dbUser" placeholder="Username" value="airtime"/>
<span class="glyphicon glyphicon-remove form-control-feedback"></span> <span class="glyphicon glyphicon-remove form-control-feedback"></span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-label" for="dbPass">Password</label> <label class="control-label" for="dbPass">Password</label>
<input required class="form-control" type="password" name="dbPass" id="dbPass" placeholder="Password"/> <input required class="form-control" type="password" name="dbPass" id="dbPass" placeholder="Password" value="airtime"/>
<span class="glyphicon glyphicon-remove form-control-feedback"></span> <span class="glyphicon glyphicon-remove form-control-feedback"></span>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -26,25 +26,12 @@
<input class="form-control" type="hidden" name="dbErr" id="dbErr" aria-describedby="helpBlock"/> <input class="form-control" type="hidden" name="dbErr" id="dbErr" aria-describedby="helpBlock"/>
<div> <div>
<input type="submit" formtarget="dbSettingsForm" class="btn btn-primary btn-next" value="Next &#10097;"/> <input type="submit" formtarget="dbSettingsForm" class="btn btn-primary btn-next" value="Next &#10097;"/>
<input type="button" class="btn btn-primary btn-back btn-disabled" value="&#10096; Back"/>
<input type="button" class="btn btn-default btn-skip" value="Skip this step &#10097;"/> <input type="button" class="btn btn-default btn-skip" value="Skip this step &#10097;"/>
</div> </div>
</form> </form>
<script> <script>
$("#dbSettingsForm").submit(function(e) { $("#dbSettingsForm").submit(function(e) {
resetFeedback(); submitForm(e, "DatabaseSetup");
e.preventDefault();
var d = $('#dbSettingsForm').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=DatabaseSetup', d, cleanupProxy, "json");
});
}); });
</script> </script>

View File

@ -0,0 +1,22 @@
<?php
?>
<form action="#" role="form" id="finishSettingsForm">
<h3 class="form-title">Media Settings</h3>
<span id="helpBlock" class="help-block help-message"></span>
<p>
Looks like you're almost done! Click "Done!" to bring up the Airtime configuration checklist; if
your configuration is all green, you're ready to get started with your personal Airtime station!
</p>
<div>
<input type="submit" formtarget="finishSettingsForm" class="btn btn-primary btn-next" value="Done!"/>
<input type="button" class="btn btn-primary btn-back" value="&#10096; Back"/>
</div>
</form>
<script>
$("#finishSettingsForm").submit(function(e) {
submitForm(e, "FinishSetup");
// window.location.replace("/?config");
});
</script>

View File

@ -0,0 +1,31 @@
<?php
?>
<form action="#" role="form" id="generalSettingsForm">
<h3 class="form-title">General Settings</h3>
<span id="helpBlock" class="help-block help-message"></span>
<div id="generalFormBody">
<div class="form-group">
<label class="control-label" for="generalHost">Webserver Host</label>
<input required class="form-control" type="text" name="generalHost" id="generalHost" placeholder="Host" value="localhost"/>
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
</div>
<div class="form-group">
<label class="control-label" for="generalPort">Webserver Port</label>
<input required class="form-control" type="text" name="generalPort" id="generalPort" placeholder="Port" value="80"/>
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
</div>
<input class="form-control" type="hidden" name="generalErr" id="generalErr" aria-describedby="helpBlock"/>
</div>
<div>
<input type="submit" formtarget="generalSettingsForm" class="btn btn-primary btn-next" value="Next &#10097;"/>
<input type="button" class="btn btn-primary btn-back" value="&#10096; Back"/>
<input type="button" class="btn btn-default btn-skip" value="Skip this step &#10097;"/>
</div>
</form>
<script>
$("#generalSettingsForm").submit(function(e) {
submitForm(e, "GeneralSetup");
});
</script>

View File

@ -0,0 +1,31 @@
<?php
?>
<form action="#" role="form" id="mediaSettingsForm">
<h3 class="form-title">Media Settings</h3>
<span id="helpBlock" class="help-block help-message"></span>
<p>
Here you can set the default media storage directory for Airtime. If left blank, we'll create a new
directory located at <code>/srv/airtime/stor/</code> for you.
</p>
<div class="form-group">
<label class="control-label" for="mediaFolder">Media folder</label>
<input class="form-control" type="text" name="mediaFolder" id="mediaFolder" placeholder="/path/to/my/airtime/music/directory/"/>
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
<span id="mediaHelpBlock" class="help-block">
Note that you need to enter the <strong>fully qualified</strong> path name!
</span>
</div>
<input class="form-control" type="hidden" name="mediaErr" id="mediaErr" aria-describedby="helpBlock"/>
<div>
<input type="submit" formtarget="mediaSettingsForm" class="btn btn-primary btn-next" value="Next &#10097;"/>
<input type="button" class="btn btn-primary btn-back" value="&#10096; Back"/>
<input type="button" class="btn btn-default btn-skip" value="Skip this step &#10097;"/>
</div>
</form>
<script>
$("#mediaSettingsForm").submit(function(e) {
submitForm(e, "MediaSetup");
});
</script>

View File

@ -33,10 +33,12 @@
<div class="form-group"> <div class="form-group">
<label class="control-label" for="rmqHost">Host</label> <label class="control-label" for="rmqHost">Host</label>
<input required class="form-control" type="text" name="rmqHost" id="rmqHost" placeholder="Host" value="127.0.0.1"/> <input required class="form-control" type="text" name="rmqHost" id="rmqHost" placeholder="Host" value="127.0.0.1"/>
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-label" for="rmqPort">Port</label> <label class="control-label" for="rmqPort">Port</label>
<input required class="form-control" type="text" name="rmqPort" id="rmqPort" placeholder="Port" value="5672"/> <input required class="form-control" type="text" name="rmqPort" id="rmqPort" placeholder="Port" value="5672"/>
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-label" for="rmqVHost">Virtual Host</label> <label class="control-label" for="rmqVHost">Virtual Host</label>
@ -59,18 +61,6 @@
}); });
$("#rmqSettingsForm").submit(function(e) { $("#rmqSettingsForm").submit(function(e) {
resetFeedback(); submitForm(e, "RabbitMQSetup");
e.preventDefault();
var d = $('#rmqSettingsForm').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=RabbitMQSetup', d, cleanupProxy, "json");
});
}); });
</script> </script>

View File

@ -1,5 +1,8 @@
<?php <?php
define("RMQ_INI_SECTION", "rabbitmq");
require_once dirname(dirname( __DIR__)) . '/library/php-amqplib/amqp.inc';
/** /**
* Check to see if Airtime is properly configured. * Check to see if Airtime is properly configured.
* *
@ -8,7 +11,8 @@
*/ */
function checkConfiguration() { function checkConfiguration() {
return checkPhpDependencies() return checkPhpDependencies()
&& checkDatabaseConfiguration(); && checkDatabaseConfiguration()
&& checkRMQConnection();
} }
/** /**
@ -73,6 +77,23 @@ function configureDatabase() {
Propel::init(CONFIG_PATH . 'airtime-conf-production.php'); Propel::init(CONFIG_PATH . 'airtime-conf-production.php');
} }
function validateDatabaseSchema() { /**
* Check that we can connect to RabbitMQ
*/
function checkRMQConnection() {
// Check for airtime.conf in /etc/airtime/ first, then check in the build directory,
if (file_exists(AIRTIME_CONFIG_STOR . AIRTIME_CONFIG)) {
$ini = parse_ini_file(AIRTIME_CONFIG_STOR . AIRTIME_CONFIG, true);
} else if (file_exists(BUILD_PATH . AIRTIME_CONFIG)) {
$ini = parse_ini_file(BUILD_PATH . AIRTIME_CONFIG, true);
} else {
$ini = parse_ini_file(BUILD_PATH . "airtime.example.conf", true);
}
$conn = new AMQPConnection($ini[RMQ_INI_SECTION]["host"],
$ini[RMQ_INI_SECTION]["port"],
$ini[RMQ_INI_SECTION]["user"],
$ini[RMQ_INI_SECTION]["password"],
$ini[RMQ_INI_SECTION]["vhost"]);
return isset($conn);
} }

View File

@ -1,5 +1,4 @@
<?php <?php
?> ?>
<html> <html>
@ -17,7 +16,7 @@
<img src="css/images/airtime_logo_jp.png" id="airtimeLogo" /><br/> <img src="css/images/airtime_logo_jp.png" id="airtimeLogo" /><br/>
<strong>Setup</strong> <strong>Setup</strong>
</h3> </h3>
<strong>Step <span id="stepCount">1</span> of 4</strong> <strong>Step <span id="stepCount">1</span> of 5</strong>
</div> </div>
<div class="viewport"> <div class="viewport">
@ -32,6 +31,21 @@
require_once SETUP_PATH . "forms/rabbitmq-settings.php"; require_once SETUP_PATH . "forms/rabbitmq-settings.php";
?> ?>
</div> </div>
<div id="generalSettings" class="form-wrapper">
<?php
require_once SETUP_PATH . "forms/general-settings.php";
?>
</div>
<div id="mediaSettings" class="form-wrapper">
<?php
require_once SETUP_PATH . "forms/media-settings.php";
?>
</div>
<div id="finishSettings" class="form-wrapper">
<?php
require_once SETUP_PATH . "forms/finish-settings.php";
?>
</div>
</div> </div>
</div> </div>

View File

@ -436,10 +436,13 @@ class AMQPConnection extends AbstractChannel
$len = strlen($data); $len = strlen($data);
while(true) 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"); throw new Exception ("Error sending data");
} }
$len = $len - $written; $len = $len - $written;
if($len>0) if($len>0)
$data=substr($data,0-$len); $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)) public function close($reply_code=0, $reply_text="", $method_sig=array(0, 0))
{ {
$args = new AMQPWriter(); try {
$args->write_short($reply_code); $args = new AMQPWriter();
$args->write_shortstr($reply_text); $args->write_short($reply_code);
$args->write_short($method_sig[0]); // class_id $args->write_shortstr($reply_text);
$args->write_short($method_sig[1]); // method_id $args->write_short($method_sig[0]); // class_id
$this->send_method_frame(array(10, 60), $args); $args->write_short($method_sig[1]); // method_id
$this->send_method_frame(array(10, 60), $args);
} catch(Exception $e) {
return;
}
return $this->wait(array( return $this->wait(array(
"10,61", // Connection.close_ok "10,61", // Connection.close_ok
)); ));

View File

@ -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 { .checklist {
overflow: auto; overflow: auto;
height: 50%; height: 50%;
@ -16,6 +39,10 @@
width: 40%; width: 40%;
} }
.check {
background: #dff0d8 url("css/images/accept.png") no-repeat center;
}
.footer { .footer {
margin: inherit; margin: inherit;
width: inherit; width: inherit;

View File

@ -47,8 +47,12 @@ body {
* ############################################################################ */ * ############################################################################ */
form { form {
width: 80%;
margin: auto; margin: auto;
top: 0;
width: 99%;
position: absolute;
float: right;
} }
form p { form p {
@ -69,6 +73,10 @@ form .form-group {
overflow-y: auto; overflow-y: auto;
} }
.form-wrapper {
overflow: auto;
}
.form-title { .form-title {
margin: 1em 0; margin: 1em 0;
} }
@ -166,23 +174,6 @@ form .form-group {
border-bottom: 4px solid #fff; 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 * RabbitMQ Settings Form Styles
@ -190,17 +181,39 @@ form .form-group {
* ############################################################################ */ * ############################################################################ */
#rmqSettingsForm { #rmqSettingsForm {
top: 0;
left: 100%; left: 100%;
width: 99%;
position: absolute;
float: right;
}
#rmqSettings {
overflow: auto;
} }
#rmqFormBody { #rmqFormBody {
display: none; display: none;
}
/* ############################################################################
*
* General Settings Form Styles
*
* ############################################################################ */
#generalSettingsForm {
left: 200%;
}
/* ############################################################################
*
* Media Settings Form Styles
*
* ############################################################################ */
#mediaSettingsForm {
left: 300%;
}
/* ############################################################################
*
* Finish Settings Form Styles
*
* ############################################################################ */
#finishSettingsForm {
left: 400%;
} }

View File

@ -24,6 +24,8 @@ define('SETUP_PATH', BUILD_PATH . 'airtime-setup/');
define('APPLICATION_PATH', ROOT_PATH . 'application/'); define('APPLICATION_PATH', ROOT_PATH . 'application/');
define('CONFIG_PATH', APPLICATION_PATH . 'configs/'); define('CONFIG_PATH', APPLICATION_PATH . 'configs/');
define("AIRTIME_CONFIG_STOR", "/etc/airtime/");
define('AIRTIME_CONFIG', 'airtime.conf'); define('AIRTIME_CONFIG', 'airtime.conf');
require_once(LIB_PATH . "propel/runtime/lib/Propel.php"); 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 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 * Even if the user has been through the setup process and
* created an airtime.conf file (or they may have simply * created an airtime.conf file (or they may have simply

View File

@ -2,6 +2,7 @@
* Do some cleanup when we get a success response from a POST request * Do some cleanup when we get a success response from a POST request
* during setup * during setup
* @param data the POST request return data * @param data the POST request return data
* @param e the jquery event
*/ */
function cleanupStep(data, e) { function cleanupStep(data, e) {
showFeedback(data); showFeedback(data);
@ -19,16 +20,16 @@ function cleanupStep(data, e) {
* @param data the POST request return data * @param data the POST request return data
*/ */
function showFeedback(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); toggleMessage(data.message);
for (var i = 0; i < data.errors.length; i++) { for (var i = 0; i < data.errors.length; i++) {
$("#" + data.errors[i]).parent().addClass("has-error has-feedback"); $("#" + 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() { function resetFeedback() {
$(".form-control-feedback").hide(); $(".form-control-feedback").hide();
$("#helpBlock").html(""); $(".has-success, .has-error, .has-feedback").removeClass("has-success has-error has-feedback");
$(".has-error, .has-feedback").removeClass("has-error has-feedback");
} }
/** /**
@ -47,16 +47,12 @@ function resetFeedback() {
function toggleMessage(msg) { function toggleMessage(msg) {
/* /*
* Since setting display:none; on this element causes odd behaviour * 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 * This is only really only necessary the first time this
* function is called after page load. * function is called after page load.
*/ */
$(".help-message").hide(); var help = $(".help-message");
$(".help-message").html(msg); help.html(msg).show();
$(".help-message").slideDown(200);
window.setTimeout(function() {
$(".help-message").slideUp(200);
}, 3000);
} }
/** /**
@ -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 * Fade out the previous setup step and fade in the next one
*/ */
function nextSlide() { function nextSlide() {
$(".btn").attr("disabled", "disabled"); formSlide("next");
$(".form-slider").animate({left: "-=100%"}, 500, function() {
$(".btn").removeAttr("disabled");
});
var stepCount = parseInt($("#stepCount").html());
$("#stepCount").html(stepCount + 1);
} }
/** /**
* Fade out the current setup step and fade in the previous one * Fade out the current setup step and fade in the previous one
*/ */
function prevSlide() { function prevSlide() {
$(".btn").attr("disabled", "disabled"); formSlide("prev");
$(".form-slider").animate({left: "+=100%"}, 500, function() { }
$(".btn").removeAttr("disabled");
/**
* 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() { $(function() {
$(".form-slider").draggable({ // Stop the user from dragging the slider
revert: true, $(".form-slider").draggable('disable');
axis: 'x',
snap: ".viewport",
snapMode: "both",
});
window.onresize = function() { window.onresize = function() {
var headerHeight = $(".header").outerHeight(), var headerHeight = $(".header").outerHeight(),

View File

@ -1,20 +1,29 @@
<?php <?php
/** /**
* User: sourcefabric * User: sourcefabric
* Date: 02/12/14 * Date: 02/12/14
*
* Class DatabaseSetup * Class DatabaseSetup
*
* Wrapper class for validating and installing the Airtime database during the installation process * Wrapper class for validating and installing the Airtime database during the installation process
*/ */
class DatabaseSetup extends Setup { class DatabaseSetup extends Setup {
// airtime.conf section header
const SECTION = "[database]";
// Constant form field names for passing errors back to the front-end
const DB_USER = "dbUser", const DB_USER = "dbUser",
DB_PASS = "dbPass", DB_PASS = "dbPass",
DB_NAME = "dbName", DB_NAME = "dbName",
DB_HOST = "dbHost"; DB_HOST = "dbHost";
// Form field values
static $user, $pass, $name, $host; static $user, $pass, $name, $host;
// Array of key->value pairs for airtime.conf
static $properties;
// Message and error fields to return to the front-end
static $message = null; static $message = null;
static $errors = array(); static $errors = array();
@ -23,6 +32,13 @@ class DatabaseSetup extends Setup {
self::$pass = $settings[self::DB_PASS]; self::$pass = $settings[self::DB_PASS];
self::$name = $settings[self::DB_NAME]; self::$name = $settings[self::DB_NAME];
self::$host = $settings[self::DB_HOST]; 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() { function runSetup() {
// Check the connection and user credentials // 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 // We know that the user credentials check out, so check if the database exists
if ($this->validateDatabaseSettings()) { if ($this->checkDatabaseExists()) {
// The database already exists, so we can just set up the schema // The database already exists, check if the schema exists as well
if ($this->createDatabaseTables()) { if ($this->checkSchemaExists()) {
self::$message = "Successfully installed Airtime database to '" . self::$name . "'"; self::$message = "Airtime is already installed in this database!";
} else { } 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 { } else {
// The database doesn't exist, so check if the user can create databases // The database doesn't exist, so check if the user can create databases
if ($this->checkUserCanCreateDb()) { if ($this->checkUserCanCreateDb()) {
// The user can create a database, do it // The user can create a database, do it
if ($this->createDatabase()) { if ($this->createDatabase()) {
if ($this->createDatabaseTables()) { // Ensure that the database was installed in UTF8 (we only care about the Airtime database)
self::$message = "Successfully installed Airtime database to '" . self::$name . "'"; 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 { } 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 { } else {
self::$message = "There was an error installing the database!"; self::$message = "There was an error installing the database!";
self::$errors[] = self::DB_NAME;
} }
} // The user can't create databases, so we're done } // The user can't create databases, so we're done
else { else {
self::$message = "No database " . self::$name . " exists; user " . self::$user self::$message = "No database " . self::$name . " exists; user " . self::$user
. " does not have permission to create databases on " . self::$host; . " does not have permission to create databases on " . self::$host;
self::$errors[] = self::DB_NAME;
} }
} }
} }
if (count(self::$errors) <= 0) {
$this->writeToTemp();
}
return array( return array(
"message" => self::$message, "message" => self::$message,
"errors" => self::$errors, "errors" => self::$errors,
); );
} }
function writeToTemp() {
parent::writeToTemp(self::SECTION, self::$properties);
}
/** /**
* Check if the user's database connection is valid * Check if the user's database connection is valid
* @return boolean true if the connection are valid * @return boolean true if the connection are valid
*/ */
function validateDatabaseConnection() { function checkDatabaseConnection() {
// This is pretty redundant, but we need to test both // This is pretty redundant, but we need to test both
// the existence and the validity of the given credentials // the existence and the validity of the given credentials
exec("export PGPASSWORD=" . self::$pass . " && psql -h " 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 * 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 * @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 exec("export PGPASSWORD=" . self::$pass . " && psql -lqt -h " . self::$host . " -U " . self::$user
. "| cut -d \\| -f 1 | grep -w " . self::$name, $out, $status); . "| cut -d \\| -f 1 | grep -w " . self::$name, $out, $status);
return $status == 0; 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 * 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 * @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/"; $sqlDir = dirname(dirname(__DIR__)) . "/build/sql/";
$files = array("schema.sql", "sequences.sql", "views.sql", "triggers.sql", "defaultdata.sql"); $files = array("schema.sql", "sequences.sql", "views.sql", "triggers.sql", "defaultdata.sql");
foreach($files as $f) { foreach ($files as $f) {
try { try {
exec("export PGPASSWORD=" . self::$pass . " && psql -U " . self::$user . " --dbname " exec("export PGPASSWORD=" . self::$pass . " && psql -U " . self::$user . " --dbname "
. self::$name . " -h " . self::$host . " -f $sqlDir$f 2>/dev/null", $out, $status); . self::$name . " -h " . self::$host . " -f $sqlDir$f 2>/dev/null", $out, $status);
} catch(Exception $e) { } catch (Exception $e) {
return false; return false;
} }
} }
return true; 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);
}
} }

View File

@ -0,0 +1,31 @@
<?php
/**
* User: sourcefabric
* Date: 09/12/14
*
* Class FinishSetup
*
* Wrapper class for finalizing and moving airtime.conf
*/
class FinishSetup extends Setup {
function __construct($settings) {
}
function runSetup() {
if ($this->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");
}
}

View File

@ -0,0 +1,61 @@
<?php
/**
* User: sourcefabric
* Date: 08/12/14
*
* Class GeneralSetup
*
* Wrapper class for validating and setting up general settings during the installation process
*/
class GeneralSetup extends Setup {
// airtime.conf section header
const SECTION = "[general]";
// Constant form field names for passing errors back to the front-end
const GENERAL_PORT = "generalPort",
GENERAL_HOST = "generalHost";
// Form field values
static $user, $host, $port, $root;
// Array of key->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
);
}
}

View File

@ -0,0 +1,107 @@
<?php
define("CONFIG_PATH", dirname(dirname( __DIR__)) . "/application/configs/");
require_once(dirname(dirname( __DIR__)) . "/library/propel/runtime/lib/Propel.php");
require_once(CONFIG_PATH . 'conf.php');
require_once(dirname(dirname( __DIR__)) . "/application/models/airtime/map/CcMusicDirsTableMap.php");
require_once(dirname(dirname( __DIR__)) . "/application/models/airtime/om/BaseCcMusicDirsQuery.php");
require_once(dirname(dirname( __DIR__)) . "/application/models/airtime/CcMusicDirsQuery.php");
require_once(dirname(dirname( __DIR__)) . "/application/models/airtime/om/BaseCcMusicDirs.php");
require_once(dirname(dirname( __DIR__)) . "/application/models/airtime/CcMusicDirs.php");
require_once(dirname(dirname( __DIR__)) . "/application/models/airtime/om/BaseCcMusicDirsPeer.php");
require_once(dirname(dirname( __DIR__)) . "/application/models/airtime/CcMusicDirsPeer.php");
/**
* User: sourcefabric
* Date: 08/12/14
*
* Class MediaSetup
*
* Wrapper class for validating and setting up media folder during the installation process
*/
class MediaSetup extends Setup {
const MEDIA_FOLDER = "mediaFolder";
static $path;
static $message = null;
static $errors = array();
function __construct($settings) {
self::$path = $settings[self::MEDIA_FOLDER];
}
/**
* @return array associative array containing a display message and fields with errors
*/
function runSetup() {
// If the path passed in is empty, set it to the default
if (strlen(self::$path) == 0) {
self::$path = "/srv/airtime/stor/";
}
// Append a trailing / if they didn't
if (!(substr(self::$path, -1) == "/")) {
self::$path .= "/";
}
if (file_exists(self::$path)) {
$this->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;
}
}

View File

@ -1,4 +1,7 @@
<?php <?php
require_once dirname(dirname( __DIR__)) . '/library/php-amqplib/amqp.inc';
/** /**
* User: sourcefabric * User: sourcefabric
* Date: 02/12/14 * Date: 02/12/14
@ -9,13 +12,25 @@
*/ */
class RabbitMQSetup extends Setup { class RabbitMQSetup extends Setup {
// airtime.conf section header
const SECTION = "[rabbitmq]";
// Constant form field names for passing errors back to the front-end
const RMQ_USER = "rmqUser", const RMQ_USER = "rmqUser",
RMQ_PASS = "rmqPass", RMQ_PASS = "rmqPass",
RMQ_PORT = "rmqPort", RMQ_PORT = "rmqPort",
RMQ_HOST = "rmqHost", RMQ_HOST = "rmqHost",
RMQ_VHOST = "rmqVHost"; RMQ_VHOST = "rmqVHost";
static $user, $pass, $name, $host, $port, $vhost; // Form field values
static $user, $pass, $host, $port, $vhost;
// Array of key->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) { function __construct($settings) {
self::$user = $settings[self::RMQ_USER]; self::$user = $settings[self::RMQ_USER];
@ -23,19 +38,63 @@ class RabbitMQSetup extends Setup {
self::$port = $settings[self::RMQ_PORT]; self::$port = $settings[self::RMQ_PORT];
self::$host = $settings[self::RMQ_HOST]; self::$host = $settings[self::RMQ_HOST];
self::$vhost = $settings[self::RMQ_VHOST]; 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 * @return array associative array containing a display message and fields with errors
*/ */
function runSetup() { function runSetup() {
$message = ""; try {
$errors = array(); if ($this->checkRMQConnection()) {
self::$message = "Connection successful!";
} else {
$this->identifyRMQConnectionError();
}
} catch(Exception $e) {
$this->identifyRMQConnectionError();
}
if (count(self::$errors) <= 0) {
$this->writeToTemp();
}
return array( return array(
"message" => $message, "message" => self::$message,
"errors" => $errors "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;
}
} }

View File

@ -1,5 +1,8 @@
<?php <?php
define("BUILD_PATH", dirname(dirname( __DIR__)) . "/build/");
define("AIRTIME_CONF_TEMP_PATH", "/tmp/airtime.conf.temp");
/** /**
* Class Setup * Class Setup
* *
@ -11,6 +14,34 @@ abstract class Setup {
abstract function runSetup(); abstract function runSetup();
protected function writeToTemp($section, $properties) {
if (!file_exists(AIRTIME_CONF_TEMP_PATH)) {
copy(BUILD_PATH . "airtime.example.conf", AIRTIME_CONF_TEMP_PATH);
}
$file = file(AIRTIME_CONF_TEMP_PATH);
$fileOutput = "";
$inSection = false;
foreach($file as $line) {
if(strpos($line, $section) !== false) {
$inSection = true;
} else if (strpos($line, "[") !== false) {
$inSection = false;
}
if ($inSection) {
$key = trim(@substr($line, 0, strpos($line, "=")));
$fileOutput .= $key && isset($properties[$key]) ? $key . " = " . $properties[$key] . "\n" : $line;
} else {
$fileOutput .= $line;
}
}
file_put_contents(AIRTIME_CONF_TEMP_PATH, $fileOutput);
}
/** /**
* Generates a random string. * Generates a random string.
* *
@ -18,8 +49,7 @@ abstract class Setup {
* @param string $p_chars characters to use in the output string * @param string $p_chars characters to use in the output string
* @return string the generated random string * @return string the generated random string
*/ */
protected function generateRandomString($p_len=20, $p_chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') protected function generateRandomString($p_len=20, $p_chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') {
{
$string = ''; $string = '';
for ($i = 0; $i < $p_len; $i++) for ($i = 0; $i < $p_len; $i++)
{ {
@ -31,11 +61,16 @@ abstract class Setup {
} }
// Import Setup subclasses
require_once('database-setup.php'); require_once('database-setup.php');
require_once('rabbitmq-setup.php'); require_once('rabbitmq-setup.php');
require_once('general-setup.php');
require_once('media-setup.php');
require_once('finish-setup.php');
// If airtime.conf exists, we shouldn't be here // If airtime.conf exists, we shouldn't be here
if (!file_exists(dirname(dirname(__DIR__)) . '/build/airtime.conf')) { if (!file_exists("/etc/airtime/airtime.conf")) {
if (isset($_GET["obj"]) && $objType = $_GET["obj"]) { if (isset($_GET["obj"]) && $objType = $_GET["obj"]) {
$obj = new $objType($_POST); $obj = new $objType($_POST);
if ($obj instanceof Setup) { if ($obj instanceof Setup) {

View File

@ -17,7 +17,7 @@ class PreferenceUnitTest extends PHPUnit_Framework_TestCase
public function testSetHeadTitle() public function testSetHeadTitle()
{ {
$title = "unit test"; $title = "unit test";
//This function is confusing and doesn't really work so we're just gonna let it slide... //This function is confusing and doesn't really work so we're just gonna let it formSlide...
Application_Model_Preference::SetHeadTitle($title); Application_Model_Preference::SetHeadTitle($title);
$this->assertEquals(Application_Model_Preference::GetHeadTitle(), $title); $this->assertEquals(Application_Model_Preference::GetHeadTitle(), $title);
} }

View File

@ -9,22 +9,50 @@ fi
showhelp () { showhelp () {
echo "Usage: airtime-install [options] echo "Usage: airtime-install [options]
--help|-h Displays usage information. -h, --help Displays usage information.
--apache|-a Installs apache and deploys a basic configuration for Airtime." -w, --web-user=WEB_USER Set the default apache web user.
-a, --apache Installs apache and deploys a basic configuration for Airtime."
exit 0 exit 0
} }
web_user="www-data"
apache="f" apache="f"
while [ $# -gt 0 ] while :; do
do
case "$1" in case "$1" in
(-h|--help) showhelp; exit 0;; -h|-\?|--help)
(-a|--apache) apache="t";; showhelp
exit
(--) shift; break;; ;;
(-*) echo "$0: error - unrecognized option $1" 1>&2; exit 1;; -a|--apache)
(*) break;; 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 esac
shift shift
done done
@ -136,14 +164,26 @@ EXCHANGES="airtime-pypo|pypo-fetch|airtime-media-monitor|media-monitor"
rabbitmqctl list_vhosts | grep -w ${RABBITMQ_VHOST} rabbitmqctl list_vhosts | grep -w ${RABBITMQ_VHOST}
RESULT="$?" RESULT="$?"
# Only run these if the user doesn't exist
if [ ${RESULT} != "0" ]; then if [ ${RESULT} != "0" ]; then
echo " ## Creating RabbitMQ user $RABBITMQ_USER" echo " ## Creating RabbitMQ user ${RABBITMQ_USER}..."
rabbitmqctl add_vhost ${RABBITMQ_VHOST} rabbitmqctl add_vhost ${RABBITMQ_VHOST}
rabbitmqctl add_user ${RABBITMQ_USER} ${RABBITMQ_PASSWORD} 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 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 -e "\n-----------------------------------------------------"
echo " * Basic Setup DONE! * " echo " * Basic Setup DONE! * "
echo " " echo " "

View File

@ -1,52 +1,31 @@
<?php <?php
date_default_timezone_set("UTC"); date_default_timezone_set("UTC");
$values = parse_ini_file('/etc/airtime/airtime.conf', true); $webRoot = apache_getenv("DOCUMENT_ROOT");
//require_once $webRoot . "/../application/configs/conf.php";
//$CC_CONFIG = Config::getConfig();
// Name of the web server user require_once($webRoot.'/application/configs/constants.php');
$CC_CONFIG['webServerUser'] = $values['general']['web_server_user']; require_once($webRoot.'/application/configs/conf.php');
$CC_CONFIG['phpDir'] = $values['general']['airtime_dir'];
$CC_CONFIG['rabbitmq'] = $values['rabbitmq'];
$CC_CONFIG['baseUrl'] = $values['general']['base_url'];
$CC_CONFIG['basePort'] = $values['general']['base_port'];
// Database config
$CC_CONFIG['dsn']['username'] = $values['database']['dbuser'];
$CC_CONFIG['dsn']['password'] = $values['database']['dbpass'];
$CC_CONFIG['dsn']['hostspec'] = $values['database']['host'];
$CC_CONFIG['dsn']['phptype'] = 'pgsql';
$CC_CONFIG['dsn']['database'] = $values['database']['dbname'];
$CC_CONFIG['soundcloud-connection-retries'] = $values['soundcloud']['connection_retries'];
$CC_CONFIG['soundcloud-connection-wait'] = $values['soundcloud']['time_between_retries'];
require_once($CC_CONFIG['phpDir'].'/application/configs/constants.php');
require_once($CC_CONFIG['phpDir'].'/application/configs/conf.php');
$CC_CONFIG['phpDir'] = $values['general']['airtime_dir'];
// Ensure library/ is on include_path // Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array( set_include_path(implode(PATH_SEPARATOR, array(
get_include_path(), get_include_path(),
realpath($CC_CONFIG['phpDir'] . '/library') realpath($webRoot . '/library')
))); )));
require_once($CC_CONFIG['phpDir'].'/application/common/Database.php'); require_once($webRoot.'/application/common/Database.php');
require_once($CC_CONFIG['phpDir'].'/application/models/StoredFile.php'); require_once($webRoot.'/application/models/StoredFile.php');
require_once($CC_CONFIG['phpDir'].'/application/models/Preference.php'); require_once($webRoot.'/application/models/Preference.php');
require_once($CC_CONFIG['phpDir'].'/application/models/MusicDir.php'); require_once($webRoot.'/application/models/MusicDir.php');
require_once($CC_CONFIG['phpDir'].'/application/common/OsPath.php'); require_once($webRoot.'/application/common/OsPath.php');
set_include_path($CC_CONFIG['phpDir'].'/library' . PATH_SEPARATOR . get_include_path()); set_include_path($webRoot.'/library' . PATH_SEPARATOR . get_include_path());
require_once($CC_CONFIG['phpDir'].'/application/models/Soundcloud.php'); require_once($webRoot.'/application/models/Soundcloud.php');
set_include_path($CC_CONFIG['phpDir']."/application/models" . PATH_SEPARATOR . get_include_path());
require_once($CC_CONFIG['phpDir']."/library/propel/runtime/lib/Propel.php");
Propel::init($CC_CONFIG['phpDir']."/application/configs/airtime-conf.php");
set_include_path($webRoot."/application/models" . PATH_SEPARATOR . get_include_path());
require_once 'propel/runtime/lib/Propel.php'; require_once 'propel/runtime/lib/Propel.php';
Propel::init($CC_CONFIG['phpDir']."/application/configs/airtime-conf-production.php"); Propel::init($webRoot."/application/configs/airtime-conf-production.php");
if(count($argv) != 2){ if(count($argv) != 2){
exit; exit;
@ -58,4 +37,3 @@ $file = Application_Model_StoredFile::RecallById($id);
// set id with -2 which is indicator for processing // set id with -2 which is indicator for processing
$file->setSoundCloudFileId(SOUNDCLOUD_PROGRESS); $file->setSoundCloudFileId(SOUNDCLOUD_PROGRESS);
$file->uploadToSoundCloud(); $file->uploadToSoundCloud();