Merge branch '2.5.x-installer' into saas-installer-albert
Conflicts: .gitignore airtime_mvc/application/Bootstrap.php airtime_mvc/application/configs/conf.php airtime_mvc/application/controllers/SystemstatusController.php airtime_mvc/application/controllers/UpgradeController.php airtime_mvc/application/upgrade/Upgrades.php airtime_mvc/application/views/scripts/systemstatus/index.phtml airtime_mvc/build/airtime.conf airtime_mvc/build/sql/defaultdata.sql airtime_mvc/public/index.php airtime_mvc/tests/application/helpers/AirtimeInstall.php install_minimal/airtime-install install_minimal/include/airtime-constants.php install_minimal/include/airtime-copy-files.sh install_minimal/include/airtime-db-install.php install_minimal/include/airtime-initialize.sh install_minimal/include/airtime-install.php install_minimal/include/airtime-installed-check.php install_minimal/include/airtime-remove-files.sh install_minimal/include/airtime-upgrade.php python_apps/media-monitor/install/media-monitor-copy-files.py python_apps/monit/monit-airtime-generic.cfg python_apps/pypo/airtime-playout python_apps/pypo/install/pypo-copy-files.py python_apps/pypo/liquidsoap/generate_liquidsoap_cfg.py python_apps/pypo/liquidsoap/ls_script.liq python_apps/pypo/pypo/__main__.py python_apps/pypo/pypo/media/update/replaygain.py python_apps/pypo/pypo/media/update/replaygainupdater.py python_apps/pypo/pypo/media/update/silananalyzer.py python_apps/python-virtualenv/airtime_virtual_env.pybundle python_apps/python-virtualenv/requirements utils/airtime-check-system.php
This commit is contained in:
commit
11c6818e61
|
@ -1,10 +1,11 @@
|
|||
.*
|
||||
*.*~
|
||||
*.pyc
|
||||
vendor/*
|
||||
composer.phar
|
||||
*~$
|
||||
*log.*
|
||||
**/airtime_analyzer.egg-info/*
|
||||
**/*.egg-info/*
|
||||
**/build/*
|
||||
**/dist/*
|
||||
*~
|
||||
|
|
59
README
59
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
|
||||
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
<?php
|
||||
require_once __DIR__."/configs/conf.php";
|
||||
require_once CONFIG_PATH . "conf.php";
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
|
||||
require_once __DIR__."/configs/ACL.php";
|
||||
if (!@include_once('propel/propel1/runtime/lib/Propel.php'))
|
||||
{
|
||||
die('Error: Propel not found. Did you install Airtime\'s third-party dependencies with composer? (Check the README.)');
|
||||
}
|
||||
require_once CONFIG_PATH . "ACL.php";
|
||||
|
||||
Propel::init(__DIR__."/configs/airtime-conf-production.php");
|
||||
// Since we initialize the database during the configuration check,
|
||||
// check the $configRun global to avoid reinitializing unnecessarily
|
||||
if (!isset($configRun) || !$configRun) {
|
||||
Propel::init(CONFIG_PATH . 'airtime-conf-production.php');
|
||||
}
|
||||
|
||||
//Composer's autoloader
|
||||
require_once 'autoload.php';
|
||||
|
||||
require_once __DIR__."/configs/constants.php";
|
||||
require_once CONFIG_PATH . "constants.php";
|
||||
require_once 'Preference.php';
|
||||
require_once 'Locale.php';
|
||||
require_once "DateHelper.php";
|
||||
|
@ -34,8 +34,9 @@ require_once __DIR__.'/controllers/plugins/Maintenance.php';
|
|||
require_once __DIR__.'/controllers/plugins/ConversionTracking.php';
|
||||
require_once __DIR__.'/modules/rest/controllers/ShowImageController.php';
|
||||
require_once __DIR__.'/modules/rest/controllers/MediaController.php';
|
||||
require_once __DIR__.'/upgrade/Upgrades.php';
|
||||
|
||||
require_once (APPLICATION_PATH."/logging/Logging.php");
|
||||
require_once (APPLICATION_PATH . "/logging/Logging.php");
|
||||
Logging::setLogPath('/var/log/airtime/zendphp.log');
|
||||
|
||||
// We need to manually route because we can't load Zend without the database being initialized first.
|
||||
|
@ -46,7 +47,7 @@ if (array_key_exists("REQUEST_URI", $_SERVER) && (stripos($_SERVER["REQUEST_URI"
|
|||
}
|
||||
|
||||
Config::setAirtimeVersion();
|
||||
require_once __DIR__."/configs/navigation.php";
|
||||
require_once (CONFIG_PATH . 'navigation.php');
|
||||
|
||||
Zend_Validate::setDefaultNamespaces("Zend");
|
||||
|
||||
|
@ -121,6 +122,14 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
|
|||
$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) {
|
||||
UpgradeManager::checkIfUpgradeIsNeeded(); //This will do the upgrade too if it's needed...
|
||||
}
|
||||
}
|
||||
|
||||
protected function _initHeadLink()
|
||||
{
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
|
@ -224,8 +233,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));
|
||||
}
|
||||
|
||||
|
@ -238,7 +246,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") {
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
|
||||
// Only enable cookie secure if we are supporting https.
|
||||
// Ideally, this would always be on and we would force https,
|
||||
// but the default installation configs are likely to be installed by
|
||||
// amature users on the setup that does not have https. Forcing
|
||||
// cookie_secure on non https would result in confusing login problems.
|
||||
if(!empty($_SERVER['HTTPS'])) {
|
||||
ini_set('session.cookie_secure', '1');
|
||||
}
|
||||
ini_set('session.cookie_httponly', '1');
|
||||
|
||||
error_reporting(E_ALL|E_STRICT);
|
||||
|
||||
function exception_error_handler($errno, $errstr, $errfile, $errline) {
|
||||
//Check if the statement that threw this error wanted its errors to be
|
||||
//suppressed. If so then return without with throwing exception.
|
||||
if (0 === error_reporting()) return;
|
||||
throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
|
||||
return false;
|
||||
}
|
||||
|
||||
set_error_handler("exception_error_handler");
|
||||
|
||||
// Define application environment
|
||||
defined('APPLICATION_ENV')
|
||||
|| define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));
|
||||
|
||||
defined('VERBOSE_STACK_TRACE')
|
||||
|| define('VERBOSE_STACK_TRACE', (getenv('VERBOSE_STACK_TRACE') ? getenv('VERBOSE_STACK_TRACE') : true));
|
||||
|
||||
// Ensure library/ is on include_path
|
||||
set_include_path(implode(PATH_SEPARATOR, array(
|
||||
get_include_path(),
|
||||
realpath(LIB_PATH)
|
||||
)));
|
||||
|
||||
set_include_path(APPLICATION_PATH . 'common' . PATH_SEPARATOR . get_include_path());
|
||||
|
||||
//Propel classes.
|
||||
set_include_path(APPLICATION_PATH . 'models' . PATH_SEPARATOR . get_include_path());
|
||||
|
||||
//Controller plugins.
|
||||
set_include_path(APPLICATION_PATH . 'controllers' . PATH_SEPARATOR . get_include_path());
|
||||
|
||||
//Controller plugins.
|
||||
set_include_path(APPLICATION_PATH . 'controllers/plugins' . PATH_SEPARATOR . get_include_path());
|
||||
|
||||
//Zend framework
|
||||
if (file_exists('/usr/share/php/libzend-framework-php')) {
|
||||
set_include_path('/usr/share/php/libzend-framework-php' . PATH_SEPARATOR . get_include_path());
|
||||
}
|
||||
|
||||
//Services.
|
||||
set_include_path(APPLICATION_PATH . '/services/' . PATH_SEPARATOR . get_include_path());
|
||||
|
||||
//cloud storage directory
|
||||
set_include_path(APPLICATION_PATH . '/cloud_storage' . PATH_SEPARATOR . get_include_path());
|
||||
|
||||
//Upgrade directory
|
||||
set_include_path(APPLICATION_PATH . '/upgrade/' . PATH_SEPARATOR . get_include_path());
|
||||
|
||||
//Common directory
|
||||
set_include_path(APPLICATION_PATH . '/common/' . PATH_SEPARATOR . get_include_path());
|
||||
|
||||
|
||||
|
||||
/** Zend_Application */
|
||||
require_once 'Zend/Application.php';
|
||||
$application = new Zend_Application(
|
||||
APPLICATION_ENV,
|
||||
CONFIG_PATH . 'application.ini'
|
||||
);
|
||||
|
||||
require_once(APPLICATION_PATH . "logging/Logging.php");
|
||||
Logging::setLogPath('/var/log/airtime/zendphp.log');
|
||||
Logging::setupParseErrorLogging();
|
||||
|
||||
// Create application, bootstrap, and run
|
||||
try {
|
||||
$sapi_type = php_sapi_name();
|
||||
if (substr($sapi_type, 0, 3) == 'cli') {
|
||||
set_include_path(APPLICATION_PATH . PATH_SEPARATOR . get_include_path());
|
||||
require_once("Bootstrap.php");
|
||||
} else {
|
||||
$application->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 "<pre>";
|
||||
echo $e->getTraceAsString();
|
||||
echo "</pre>";
|
||||
Logging::info($e->getMessage());
|
||||
Logging::info($e->getTraceAsString());
|
||||
} else {
|
||||
Logging::info($e->getTrace());
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
|
|
@ -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 {
|
||||
|
@ -37,7 +35,6 @@ 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'];
|
||||
if (isset($values['general']['dev_env'])) {
|
||||
$CC_CONFIG['dev_env'] = $values['general']['dev_env'];
|
||||
} else {
|
||||
|
@ -71,9 +68,6 @@ class Config {
|
|||
|
||||
$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'];
|
||||
|
|
|
@ -0,0 +1,265 @@
|
|||
<?php
|
||||
/*
|
||||
* We only get here after setup, or if there's an error in the configuration.
|
||||
*
|
||||
* Display a table to the user showing the necessary dependencies
|
||||
* (both PHP and binary) and the status of any application services,
|
||||
* along with steps to fix them if they're not found or misconfigured.
|
||||
*/
|
||||
|
||||
$phpDependencies = checkPhpDependencies();
|
||||
$externalServices = checkExternalServices();
|
||||
$zend = $phpDependencies["zend"];
|
||||
$postgres = $phpDependencies["postgres"];
|
||||
|
||||
$database = $externalServices["database"];
|
||||
$rabbitmq = $externalServices["rabbitmq"];
|
||||
|
||||
$pypo = $externalServices["pypo"];
|
||||
$liquidsoap = $externalServices["liquidsoap"];
|
||||
$mediamonitor = $externalServices["media-monitor"];
|
||||
|
||||
$r1 = array_reduce($phpDependencies, "booleanReduce", true);
|
||||
$r2 = array_reduce($externalServices, "booleanReduce", true);
|
||||
$result = $r1 && $r2;
|
||||
?>
|
||||
<html>
|
||||
<head>
|
||||
<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">
|
||||
</head>
|
||||
<style>
|
||||
/*
|
||||
This is here because we're using the config-check css for
|
||||
both this page and the system status page
|
||||
*/
|
||||
html {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
body {
|
||||
padding: 2em;
|
||||
min-width: 600px;
|
||||
text-align: center;
|
||||
margin: 3em ;
|
||||
border: 1px solid lightgray;
|
||||
border-radius: 5px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<h2>
|
||||
<img class="logo" src="css/images/airtime_logo_jp.png" /><br/>
|
||||
<strong>Configuration Checklist</strong>
|
||||
</h2>
|
||||
|
||||
<?php
|
||||
if (!$result) {
|
||||
?>
|
||||
<br/>
|
||||
<h3 class="error">Looks like something went wrong!</h3>
|
||||
<p>
|
||||
Take a look at the checklist below for possible solutions. If you're tried the suggestions and are
|
||||
still experiencing issues, come
|
||||
<a href="https://forum.sourcefabric.org/">visit our forums</a>
|
||||
or <a href="http://www.sourcefabric.org/en/airtime/manuals/">check out the manual</a>.
|
||||
</p>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<p>
|
||||
Your Airtime station is up and running! Get started by logging in with the default username and password: admin/admin
|
||||
</p>
|
||||
<button onclick="location = location.pathname;">Log in to Airtime!</button>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="component">
|
||||
Component
|
||||
</th>
|
||||
<th class="description">
|
||||
<strong>Description</strong>
|
||||
</th>
|
||||
<th class="solution">
|
||||
<strong>Status or Solution</strong>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
|
||||
<div class="checklist">
|
||||
<table class="table table-striped">
|
||||
<caption class="caption">
|
||||
PHP Dependencies
|
||||
</caption>
|
||||
<tbody>
|
||||
<tr class="<?=$zend ? 'success' : 'danger';?>">
|
||||
<td class="component">
|
||||
Zend
|
||||
</td>
|
||||
<td class="description">
|
||||
Zend MVC Framework
|
||||
</td>
|
||||
<td class="solution <?php if ($zend) {echo 'check';?>">
|
||||
<?php
|
||||
} else {
|
||||
?>">
|
||||
<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>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="<?=$postgres ? 'success' : 'danger';?>">
|
||||
<td class="component">
|
||||
Postgres
|
||||
</td>
|
||||
<td class="description">
|
||||
PDO and PostgreSQL libraries
|
||||
</td>
|
||||
<td class="solution <?php if ($postgres) {echo 'check';?>">
|
||||
<?php
|
||||
} else {
|
||||
?>">
|
||||
Try running <code>sudo apt-get install php5-pgsql</code>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table class="table table-striped">
|
||||
<caption class="caption">
|
||||
External Services
|
||||
</caption>
|
||||
<tbody>
|
||||
<tr class="<?=$database ? 'success' : 'danger';?>">
|
||||
<td class="component">
|
||||
Database
|
||||
</td>
|
||||
<td class="description">
|
||||
Database configuration for Airtime
|
||||
</td>
|
||||
<td class="solution <?php if ($database) {echo 'check';?>">
|
||||
<?php
|
||||
} else {
|
||||
?>">
|
||||
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
|
||||
<code>/etc/airtime.conf</code> are correct and the Airtime database was installed correctly.
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="<?=$rabbitmq ? 'success' : 'danger';?>">
|
||||
<td class="component">
|
||||
RabbitMQ
|
||||
</td>
|
||||
<td class="description">
|
||||
RabbitMQ configuration for Airtime
|
||||
</td>
|
||||
<td class="solution <?php if ($rabbitmq) {echo 'check';?>">
|
||||
<?php
|
||||
} else {
|
||||
?>">
|
||||
Make sure RabbitMQ is installed correctly, and that your settings in /etc/airtime/airtime.conf
|
||||
are correct. Try using <code>sudo rabbitmqctl list_users</code> and <code>sudo rabbitmqctl list_vhosts</code>
|
||||
to see if the airtime user (or your custom RabbitMQ user) exists, then checking that
|
||||
<code>sudo rabbitmqctl list_exchanges</code> contains entries for airtime-media-monitor, airtime-pypo,
|
||||
and airtime-uploads.
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="<?=$mediamonitor ? 'success' : 'danger';?>">
|
||||
<td class="component">
|
||||
Media Monitor
|
||||
</td>
|
||||
<td class="description">
|
||||
Airtime media-monitor service
|
||||
</td>
|
||||
<td class="solution <?php if ($mediamonitor) {echo 'check';?>">
|
||||
<?php
|
||||
} else {
|
||||
?>">
|
||||
Check that the airtime-media-monitor service is installed correctly in <code>/etc/init</code>,
|
||||
and ensure that it's running with
|
||||
<br/><code>initctl list | grep airtime-media-monitor</code><br/>
|
||||
If not, try running <code>sudo service airtime-media-monitor start</code>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="<?=$pypo ? 'success' : 'danger';?>">
|
||||
<td class="component">
|
||||
Pypo
|
||||
</td>
|
||||
<td class="description">
|
||||
Airtime playout service
|
||||
</td>
|
||||
<td class="solution <?php if ($pypo) {echo 'check';?>">
|
||||
<?php
|
||||
} else {
|
||||
?>">
|
||||
Check that the airtime-playout service is installed correctly in <code>/etc/init</code>,
|
||||
and ensure that it's running with
|
||||
<br/><code>initctl list | grep airtime-playout</code><br/>
|
||||
If not, try running <code>sudo service airtime-playout restart</code>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="<?=$liquidsoap ? 'success' : 'danger';?>">
|
||||
<td class="component">
|
||||
Liquidsoap
|
||||
</td>
|
||||
<td class="description">
|
||||
Airtime liquidsoap service
|
||||
</td>
|
||||
<td class="solution <?php if ($liquidsoap) {echo 'check';?>">
|
||||
<?php
|
||||
} else {
|
||||
?>">
|
||||
Check that the airtime-liquidsoap service is installed correctly in <code>/etc/init</code>,
|
||||
and ensure that it's running with
|
||||
<br/><code>initctl list | grep airtime-liquidsoap</code><br/>
|
||||
If not, try running <code>sudo service airtime-liquidsoap restart</code>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<h3>
|
||||
PHP Extension List
|
||||
</h3>
|
||||
<p>
|
||||
<?php
|
||||
global $extensions;
|
||||
$first = true;
|
||||
foreach ($extensions as $ext) {
|
||||
if (!$first) {
|
||||
echo " | ";
|
||||
} else {
|
||||
$first = false;
|
||||
}
|
||||
echo $ext;
|
||||
}
|
||||
?>
|
||||
</p>
|
||||
</div>
|
|
@ -19,6 +19,7 @@ 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.2');
|
||||
|
||||
// Metadata Keys for files
|
||||
define('MDATA_KEY_FILEPATH' , 'filepath');
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,38 +13,18 @@ class UpgradeController extends Zend_Controller_Action
|
|||
return;
|
||||
}
|
||||
|
||||
$upgraders = array();
|
||||
array_push($upgraders, new AirtimeUpgrader253());
|
||||
array_push($upgraders, new AirtimeUpgrader254());
|
||||
array_push($upgraders, new AirtimeUpgrader255());
|
||||
array_push($upgraders, new AirtimeUpgrader259());
|
||||
array_push($upgraders, new AirtimeUpgrader2510());
|
||||
array_push($upgraders, new AirtimeUpgrader2511());
|
||||
array_push($upgraders, new AirtimeUpgrader2512());
|
||||
try {
|
||||
$upgradeManager = new UpgradeManager();
|
||||
$didWePerformAnUpgrade = $upgradeManager->doUpgrade();
|
||||
|
||||
$didWePerformAnUpgrade = false;
|
||||
try
|
||||
{
|
||||
for ($i = 0; $i < count($upgraders); $i++)
|
||||
{
|
||||
$upgrader = $upgraders[$i];
|
||||
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;
|
||||
if (!$didWePerformAnUpgrade) {
|
||||
$this->getResponse()
|
||||
->setHttpResponseCode(200)
|
||||
->appendBody("Upgrade to Airtime " . $upgrader->getNewVersion() . " OK<br>");
|
||||
$i = 0; //Start over, in case the upgrade handlers are not in ascending order.
|
||||
}
|
||||
}
|
||||
|
||||
if (!$didWePerformAnUpgrade)
|
||||
{
|
||||
->appendBody("No upgrade was performed. The current schema version is " . Application_Model_Preference::GetSchemaVersion() . ".<br>");
|
||||
} else {
|
||||
$this->getResponse()
|
||||
->setHttpResponseCode(200)
|
||||
->appendBody("No upgrade was performed. The current Airtime version is " . AirtimeUpgrader::getCurrentVersion() . ".<br>");
|
||||
->appendBody("Upgrade to Airtime schema version " . Application_Model_Preference::GetSchemaVersion() . " OK<br>");
|
||||
}
|
||||
}
|
||||
catch (Exception $e)
|
||||
|
|
|
@ -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 '';
|
|
@ -875,9 +875,29 @@ 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()
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
@ -1024,14 +1024,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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,21 +1,75 @@
|
|||
<?php
|
||||
|
||||
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('2.5.12');
|
||||
}
|
||||
|
||||
public static function checkIfUpgradeIsNeeded()
|
||||
{
|
||||
$schemaVersion = Application_Model_Preference::GetSchemaVersion();
|
||||
$supportedSchemaVersions = self::getSupportedSchemaVersions();
|
||||
$upgradeNeeded = !in_array($schemaVersion, $supportedSchemaVersions);
|
||||
if ($upgradeNeeded) {
|
||||
self::doUpgrade();
|
||||
}
|
||||
}
|
||||
|
||||
public static function doUpgrade()
|
||||
{
|
||||
$upgradeManager = new UpgradeManager();
|
||||
$upgraders = array();
|
||||
array_push($upgraders, new AirtimeUpgrader253());
|
||||
array_push($upgraders, new AirtimeUpgrader254());
|
||||
array_push($upgraders, new AirtimeUpgrader255());
|
||||
array_push($upgraders, new AirtimeUpgrader259());
|
||||
array_push($upgraders, new AirtimeUpgrader2510());
|
||||
array_push($upgraders, new AirtimeUpgrader2511());
|
||||
array_push($upgraders, new AirtimeUpgrader2512());
|
||||
return $upgradeManager->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;
|
||||
|
||||
for($i = 0; $i < count($upgraders); $i++) {
|
||||
$upgrader = $upgraders[$i];
|
||||
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.
|
||||
$upgradePerformed = true;
|
||||
$i = 0; // Start over, in case the upgrade handlers are not in ascending order.
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,7 +78,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;
|
||||
|
@ -58,9 +112,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()
|
||||
{
|
||||
|
@ -109,8 +164,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::SetSchemaVersion($this->getNewVersion());
|
||||
|
||||
Application_Model_Preference::SetAirtimeVersion($this->getNewVersion());
|
||||
//clear out the cache
|
||||
Cache::clear();
|
||||
|
||||
|
@ -125,7 +180,7 @@ class AirtimeUpgrader253 extends AirtimeUpgrader
|
|||
|
||||
class AirtimeUpgrader254 extends AirtimeUpgrader
|
||||
{
|
||||
protected function getSupportedVersions()
|
||||
protected function getSupportedSchemaVersions()
|
||||
{
|
||||
return array('2.5.3');
|
||||
}
|
||||
|
@ -195,7 +250,7 @@ class AirtimeUpgrader254 extends AirtimeUpgrader
|
|||
}
|
||||
|
||||
//$con->commit();
|
||||
Application_Model_Preference::SetAirtimeVersion($newVersion);
|
||||
Application_Model_Preference::SetSchemaVersion($newVersion);
|
||||
Cache::clear();
|
||||
|
||||
$this->toggleMaintenanceScreen(false);
|
||||
|
@ -211,7 +266,7 @@ class AirtimeUpgrader254 extends AirtimeUpgrader
|
|||
}
|
||||
|
||||
class AirtimeUpgrader255 extends AirtimeUpgrader {
|
||||
protected function getSupportedVersions() {
|
||||
protected function getSupportedSchemaVersions() {
|
||||
return array (
|
||||
'2.5.4'
|
||||
);
|
||||
|
@ -243,7 +298,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);
|
||||
|
@ -257,7 +312,7 @@ class AirtimeUpgrader255 extends AirtimeUpgrader {
|
|||
}
|
||||
|
||||
class AirtimeUpgrader259 extends AirtimeUpgrader {
|
||||
protected function getSupportedVersions() {
|
||||
protected function getSupportedSchemaVersions() {
|
||||
return array (
|
||||
'2.5.5'
|
||||
);
|
||||
|
@ -289,7 +344,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);
|
||||
|
@ -302,7 +357,7 @@ class AirtimeUpgrader259 extends AirtimeUpgrader {
|
|||
|
||||
class AirtimeUpgrader2510 extends AirtimeUpgrader
|
||||
{
|
||||
protected function getSupportedVersions() {
|
||||
protected function getSupportedSchemaVersions() {
|
||||
return array (
|
||||
'2.5.9'
|
||||
);
|
||||
|
@ -334,7 +389,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);
|
||||
|
@ -347,7 +402,7 @@ class AirtimeUpgrader2510 extends AirtimeUpgrader
|
|||
|
||||
class AirtimeUpgrader2511 extends AirtimeUpgrader
|
||||
{
|
||||
protected function getSupportedVersions() {
|
||||
protected function getSupportedSchemaVersions() {
|
||||
return array (
|
||||
'2.5.10'
|
||||
);
|
||||
|
@ -375,7 +430,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);
|
||||
|
@ -391,7 +446,7 @@ class AirtimeUpgrader2511 extends AirtimeUpgrader
|
|||
|
||||
class AirtimeUpgrader2512 extends AirtimeUpgrader
|
||||
{
|
||||
protected function getSupportedVersions() {
|
||||
protected function getSupportedSchemaVersions() {
|
||||
return array (
|
||||
'2.5.10',
|
||||
'2.5.11'
|
||||
|
@ -424,7 +479,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);
|
||||
|
|
|
@ -11,7 +11,7 @@ echo sprintf(_('%1$s %2$s, the open radio software for scheduling and remote sta
|
|||
$this->airtime_version)
|
||||
?>
|
||||
<br />
|
||||
<br />© 2013
|
||||
<br />© <?php echo(gmdate('Y')); ?>
|
||||
<?php
|
||||
$companySiteAnchor = "<a href='" . COMPANY_SITE_URL . "' target='_blank'>"
|
||||
. COMPANY_NAME . " " . COMPANY_SUFFIX
|
||||
|
|
|
@ -1,8 +1,178 @@
|
|||
<table width="60%" cellpadding="0" cellspacing="0" border="0" class="statustable">
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="css/setup/config-check.css">
|
||||
</head>
|
||||
|
||||
<?php
|
||||
$phpDependencies = checkPhpDependencies();
|
||||
$externalServices = checkExternalServices();
|
||||
$zend = $phpDependencies["zend"];
|
||||
$postgres = $phpDependencies["postgres"];
|
||||
|
||||
$database = $externalServices["database"];
|
||||
$rabbitmq = $externalServices["rabbitmq"];
|
||||
|
||||
$pypo = $externalServices["pypo"];
|
||||
$liquidsoap = $externalServices["liquidsoap"];
|
||||
$mediamonitor = $externalServices["media-monitor"];
|
||||
|
||||
$r1 = array_reduce($phpDependencies, "booleanReduce", true);
|
||||
$r2 = array_reduce($externalServices, "booleanReduce", true);
|
||||
$result = $r1 && $r2;
|
||||
?>
|
||||
|
||||
<table width="60%" cellpadding="0" cellspacing="0" border="0" class="statustable">
|
||||
<thead>
|
||||
<tr class="ui-state-default strong">
|
||||
<td><?php echo _("Service") ?></td>
|
||||
<td><?php echo _("Description") ?></td>
|
||||
<td><?php echo _("Status") ?></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!--
|
||||
<tr class="odd">
|
||||
<td><?php echo sprintf(_("%s Version"), PRODUCT_NAME) ?></td>
|
||||
<td>1.9.3</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
-->
|
||||
<tr>
|
||||
<td class="component">
|
||||
Zend
|
||||
</td>
|
||||
<td class="description">
|
||||
Zend MVC Framework
|
||||
</td>
|
||||
<td class="solution <?php if ($zend) {echo 'check';?>">
|
||||
<?php
|
||||
} else {
|
||||
?>">
|
||||
<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>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="component">
|
||||
Postgres
|
||||
</td>
|
||||
<td class="description">
|
||||
PDO and PostgreSQL libraries
|
||||
</td>
|
||||
<td class="solution <?php if ($postgres) {echo 'check';?>">
|
||||
<?php
|
||||
} else {
|
||||
?>">
|
||||
Try running <code>sudo apt-get install php5-pgsql</code>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="component">
|
||||
Database
|
||||
</td>
|
||||
<td class="description">
|
||||
Database configuration for Airtime
|
||||
</td>
|
||||
<td class="solution <?php if ($database) {echo 'check';?>">
|
||||
<?php
|
||||
} else {
|
||||
?>">
|
||||
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
|
||||
<code>/etc/airtime.conf</code> are correct and the Airtime database was installed correctly.
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="component">
|
||||
RabbitMQ
|
||||
</td>
|
||||
<td class="description">
|
||||
RabbitMQ configuration for Airtime
|
||||
</td>
|
||||
<td class="solution <?php if ($rabbitmq) {echo 'check';?>">
|
||||
<?php
|
||||
} else {
|
||||
?>">
|
||||
Make sure RabbitMQ is installed correctly, and that your settings in /etc/airtime/airtime.conf
|
||||
are correct. Try using <code>sudo rabbitmqctl list_users</code> and <code>sudo rabbitmqctl list_vhosts</code>
|
||||
to see if the airtime user (or your custom RabbitMQ user) exists, then checking that
|
||||
<code>sudo rabbitmqctl list_exchanges</code> contains entries for airtime-media-monitor, airtime-pypo,
|
||||
and airtime-uploads.
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="component">
|
||||
Media Monitor
|
||||
</td>
|
||||
<td class="description">
|
||||
Airtime media-monitor service
|
||||
</td>
|
||||
<td class="solution <?php if ($mediamonitor) {echo 'check';?>">
|
||||
<?php
|
||||
} else {
|
||||
?>">
|
||||
Check that the airtime-media-monitor service is installed correctly in <code>/etc/init</code>,
|
||||
and ensure that it's running with
|
||||
<br/><code>initctl list | grep airtime-media-monitor</code><br/>
|
||||
If not, try <br/><code>sudo service airtime-media-monitor start</code>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="component">
|
||||
Pypo
|
||||
</td>
|
||||
<td class="description">
|
||||
Airtime playout service
|
||||
</td>
|
||||
<td class="solution <?php if ($pypo) {echo 'check';?>">
|
||||
<?php
|
||||
} else {
|
||||
?>">
|
||||
Check that the airtime-playout service is installed correctly in <code>/etc/init</code>,
|
||||
and ensure that it's running with
|
||||
<br/><code>initctl list | grep airtime-playout</code><br/>
|
||||
If not, try <br/><code>sudo service airtime-playout restart</code>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="component">
|
||||
Liquidsoap
|
||||
</td>
|
||||
<td class="description">
|
||||
Airtime liquidsoap service
|
||||
</td>
|
||||
<td class="solution <?php if ($liquidsoap) {echo 'check';?>">
|
||||
<?php
|
||||
} else {
|
||||
?>">
|
||||
Check that the airtime-liquidsoap service is installed correctly in <code>/etc/init</code>,
|
||||
and ensure that it's running with
|
||||
<br/><code>initctl list | grep airtime-liquidsoap</code><br/>
|
||||
If not, try <br/><code>sudo service airtime-liquidsoap restart</code>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="partitions" class="even">
|
||||
<th colspan="5"><?php echo _("Disk Space") ?></th>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</table>
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
$tempConfigPath = "/etc/airtime/airtime.conf.tmp";
|
||||
if (file_exists($tempConfigPath)) {
|
||||
$airtimeConfig = parse_ini_file($tempConfigPath, true);
|
||||
$db = $airtimeConfig["database"];
|
||||
}
|
||||
?>
|
||||
|
||||
<form action="#" role="form" id="dbSettingsForm">
|
||||
<h3 class="form-title">Database Settings</h3>
|
||||
<span id="helpBlock" class="help-block help-message"></span>
|
||||
<p>
|
||||
Enter your Airtime database settings here. Empty or non-existent databases will be created and populated
|
||||
if the given user has administrative permissions in postgres.
|
||||
</p>
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="dbUser">Username</label>
|
||||
<input required class="form-control" type="text" name="dbUser" id="dbUser" placeholder="Username"
|
||||
value="<?php echo (isset($db) ? $db["dbuser"] : "airtime"); ?>" />
|
||||
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="dbPass">Password</label>
|
||||
<input required class="form-control" type="password" name="dbPass" id="dbPass" placeholder="Password"
|
||||
value="<?php echo (isset($db) ? $db["dbpass"] : "airtime"); ?>" />
|
||||
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="dbName">Name</label>
|
||||
<input required class="form-control" type="text" name="dbName" id="dbName" placeholder="Name"
|
||||
value="<?php echo (isset($db) ? $db["dbname"] : "airtime"); ?>" />
|
||||
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="dbHost">Host</label>
|
||||
<input required class="form-control" type="text" name="dbHost" id="dbHost" placeholder="Host"
|
||||
value="<?php echo (isset($db) ? $db["host"] : "localhost"); ?>" />
|
||||
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
|
||||
</div>
|
||||
<input class="form-control" type="hidden" name="dbErr" id="dbErr" aria-describedby="helpBlock"/>
|
||||
<div>
|
||||
<p style="text-align:right">
|
||||
This may take up to 30 seconds to complete!
|
||||
</p>
|
||||
<input type="submit" formtarget="dbSettingsForm" class="btn btn-primary btn-next" value="Next ❱"/>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
$("#dbSettingsForm").submit(function(e) {
|
||||
submitForm(e, "DatabaseSetup");
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
?>
|
||||
|
||||
<form action="#" role="form" id="finishSettingsForm">
|
||||
<h3 class="form-title">Manual Step: Start Airtime Services</h3>
|
||||
<span id="helpBlock" class="help-block help-message"></span>
|
||||
<p>
|
||||
Looks like you're almost done! As a final step, please run the following commands from the terminal:
|
||||
</p>
|
||||
<pre style="text-align: left">sudo service airtime-playout start
|
||||
sudo service airtime-liquidsoap start
|
||||
sudo service airtime-media-monitor start</pre>
|
||||
<p>
|
||||
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>
|
||||
<p>
|
||||
If you need to re-run the web installer, just remove <code>/etc/airtime/airtime.conf</code>.
|
||||
</p>
|
||||
<div>
|
||||
<input type="submit" formtarget="finishSettingsForm" class="btn btn-primary btn-next" value="Done!"/>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
$("#finishSettingsForm").submit(function(e) {
|
||||
e.preventDefault();
|
||||
window.location.assign("/?config");
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
?>
|
||||
|
||||
<form action="#" role="form" id="generalSettingsForm">
|
||||
<h3 class="form-title">General Settings</h3>
|
||||
<p>
|
||||
These values are automatically pulled from your webserver settings, under most circumstances you will not need to change them.
|
||||
</p>
|
||||
<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="<?=$_SERVER["SERVER_NAME"]?>"/>
|
||||
<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="<?=$_SERVER["SERVER_PORT"]?>"/>
|
||||
<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 ❱"/>
|
||||
<input type="button" class="btn btn-primary btn-back" value="❰ Back"/>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
$("#generalSettingsForm").submit(function(e) {
|
||||
submitForm(e, "GeneralSetup");
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,30 @@
|
|||
<?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 ❱"/>
|
||||
<input type="button" class="btn btn-primary btn-back" value="❰ Back"/>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
$("#mediaSettingsForm").submit(function(e) {
|
||||
submitForm(e, "MediaSetup");
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
$tempConfigPath = "/etc/airtime/airtime.conf.tmp";
|
||||
if (file_exists($tempConfigPath)) {
|
||||
$airtimeConfig = parse_ini_file($tempConfigPath, true);
|
||||
$rmq = $airtimeConfig["rabbitmq"];
|
||||
}
|
||||
?>
|
||||
|
||||
<form action="#" role="form" id="rmqSettingsForm">
|
||||
<h3 class="form-title">RabbitMQ Settings</h3>
|
||||
<span id="helpBlock" class="help-block help-message"></span>
|
||||
<p>
|
||||
RabbitMQ is an AMQP-based messaging system used by Airtime. You should only edit these settings
|
||||
if you have changed the defaults since running the installer, or if you've opted to install RabbitMQ manually.
|
||||
</p>
|
||||
<p>
|
||||
In either case, we recommend that you change at least the default password provided -
|
||||
you can do this by running the following line from the command line:<br/>
|
||||
<code>sudo rabbitmqctl change_password <username> <newpassword></code>
|
||||
</p>
|
||||
<div id="rmqSlideToggle">
|
||||
<span><strong>Advanced </strong></span><span id="advCaret" class="caret"></span><hr/>
|
||||
</div>
|
||||
<div id="rmqFormBody">
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="rmqUser">Username</label>
|
||||
<input required class="form-control" type="text" name="rmqUser" id="rmqUser" placeholder="Username"
|
||||
value="<?php echo (isset($rmq) ? $rmq["user"] : "airtime"); ?>" />
|
||||
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="rmqPass">Password</label>
|
||||
<input class="form-control" type="password" name="rmqPass" id="rmqPass" placeholder="Password"
|
||||
value="<?php echo (isset($rmq) ? $rmq["password"] : "airtime"); ?>" />
|
||||
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
|
||||
<span id="rmqHelpBlock" class="help-block">
|
||||
You probably want to change this!
|
||||
</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="rmqHost">Host</label>
|
||||
<input required class="form-control" type="text" name="rmqHost" id="rmqHost" placeholder="Host"
|
||||
value="<?php echo (isset($rmq) ? $rmq["host"] : "127.0.0.1"); ?>" />
|
||||
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="rmqPort">Port</label>
|
||||
<input required class="form-control" type="text" name="rmqPort" id="rmqPort" placeholder="Port"
|
||||
value="<?php echo (isset($rmq) ? $rmq["port"] : "5672"); ?>" />
|
||||
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="rmqVHost">Virtual Host</label>
|
||||
<input required class="form-control" type="text" name="rmqVHost" id="rmqVHost" placeholder="VHost"
|
||||
value="<?php echo (isset($rmq) ? $rmq["vhost"] : "/airtime"); ?>" />
|
||||
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
|
||||
</div>
|
||||
<input class="form-control" type="hidden" name="rmqErr" id="rmqErr" aria-describedby="helpBlock"/>
|
||||
</div>
|
||||
<div>
|
||||
<input type="submit" formtarget="rmqSettingsForm" class="btn btn-primary btn-next" value="Next ❱"/>
|
||||
<input type="button" class="btn btn-primary btn-back" value="❰ Back"/>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
$("#rmqSlideToggle").click(function() {
|
||||
$("#rmqFormBody").slideToggle(500);
|
||||
$("#advCaret").toggleClass("caret-up");
|
||||
});
|
||||
|
||||
$("#rmqSettingsForm").submit(function(e) {
|
||||
submitForm(e, "RabbitMQSetup");
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,158 @@
|
|||
<?php
|
||||
|
||||
define("RMQ_INI_SECTION", "rabbitmq");
|
||||
require_once dirname(dirname( __DIR__)) . '/library/php-amqplib/amqp.inc';
|
||||
|
||||
function booleanReduce($a, $b) {
|
||||
return $a && $b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if Airtime is properly configured.
|
||||
*
|
||||
* @return boolean true if all Airtime dependencies and services are
|
||||
* properly configured and running
|
||||
*/
|
||||
function checkConfiguration() {
|
||||
$r1 = array_reduce(checkPhpDependencies(), "booleanReduce", true);
|
||||
$r2 = array_reduce(checkExternalServices(), "booleanReduce", true);
|
||||
return $r1 && $r2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for Airtime's PHP dependencies and return an associative
|
||||
* array with the results
|
||||
*
|
||||
* @return array associative array of dependency check results
|
||||
*/
|
||||
function checkPhpDependencies() {
|
||||
return array(
|
||||
"zend" => checkZendDependencies(),
|
||||
"postgres" => checkDatabaseDependencies()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the Zend framework libraries are installed
|
||||
*
|
||||
* @return boolean true if Zend exists in /usr/share/php
|
||||
*/
|
||||
function checkZendDependencies() {
|
||||
return file_exists('/usr/share/php/libzend-framework-php')
|
||||
|| file_exists('/usr/share/php/Zend'); // Debian version
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the PHP dependencies for the database exist
|
||||
*
|
||||
* @return boolean true if the database dependencies exist
|
||||
*/
|
||||
function checkDatabaseDependencies() {
|
||||
global $extensions;
|
||||
// Check the PHP extension list for the Postgres db extensions
|
||||
return (in_array('pdo_pgsql', $extensions)
|
||||
&& in_array('pgsql', $extensions));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that all external services are configured correctly and return an associative
|
||||
* array with the results
|
||||
*
|
||||
* @return array associative array of external service check results
|
||||
*/
|
||||
function checkExternalServices() {
|
||||
return array(
|
||||
"database" => checkDatabaseConfiguration(),
|
||||
"media-monitor" => checkMediaMonitorService(),
|
||||
"pypo" => checkPlayoutService(),
|
||||
"liquidsoap" => checkLiquidsoapService(),
|
||||
"rabbitmq" => checkRMQConnection()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the database configuration by fetching a connection from Propel
|
||||
*
|
||||
* @return boolean true if a connection is made to the database
|
||||
*/
|
||||
function checkDatabaseConfiguration() {
|
||||
configureDatabase();
|
||||
|
||||
try {
|
||||
// Try to establish a database connection. If something goes
|
||||
// wrong, the database is improperly configured
|
||||
Propel::getConnection();
|
||||
Propel::close();
|
||||
} catch (Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize Propel to configure the Airtime database
|
||||
*/
|
||||
function configureDatabase() {
|
||||
Propel::init(CONFIG_PATH . 'airtime-conf-production.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that we can connect to RabbitMQ
|
||||
*
|
||||
* @return true if the RabbitMQ connection can be established
|
||||
*/
|
||||
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 {
|
||||
$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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if airtime-media-monitor is currently running
|
||||
*
|
||||
* @return boolean true if airtime-media-monitor is running
|
||||
*/
|
||||
function checkMediaMonitorService() {
|
||||
exec("pgrep -f -u www-data airtime-media-monitor", $out, $status);
|
||||
if (array_key_exists(0, $out) && $status == 0) {
|
||||
return posix_kill(rtrim($out[0]), 0);
|
||||
}
|
||||
return $status == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if airtime-playout is currently running
|
||||
*
|
||||
* @return boolean true if airtime-playout is running
|
||||
*/
|
||||
function checkPlayoutService() {
|
||||
exec("pgrep -f -u www-data airtime-playout", $out, $status);
|
||||
if (array_key_exists(0, $out) && $status == 0) {
|
||||
return posix_kill(rtrim($out[0]), 0);
|
||||
}
|
||||
return $status == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if airtime-liquidsoap is currently running
|
||||
*
|
||||
* @return boolean true if airtime-liquidsoap is running
|
||||
*/
|
||||
function checkLiquidsoapService() {
|
||||
exec("pgrep -f -u www-data airtime-liquidsoap", $out, $status);
|
||||
if (array_key_exists(0, $out) && $status == 0) {
|
||||
return posix_kill(rtrim($out[0]), 0);
|
||||
}
|
||||
return $status == 0;
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
?>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="js/libs/jquery-1.8.3.min.js"></script>
|
||||
<script type="text/javascript" src="js/libs/jquery-ui-1.8.24.min.js"></script>
|
||||
<script type="text/javascript" src="js/setup/setup-config.js"></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="css/bootstrap-3.3.1.min.css" />
|
||||
<link rel="stylesheet" type="text/css" href="css/setup/setup-config.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h3 class="logo">
|
||||
<img src="css/images/airtime_logo_jp.png" id="airtimeLogo" /><br/>
|
||||
<strong>Setup</strong>
|
||||
</h3>
|
||||
<strong>Step <span id="stepCount">1</span> of 5</strong>
|
||||
</div>
|
||||
|
||||
<div class="viewport">
|
||||
<div class="form-slider">
|
||||
<div id="databaseSettings" class="form-wrapper">
|
||||
<?php
|
||||
require_once SETUP_PATH . "forms/database-settings.php";
|
||||
?>
|
||||
</div>
|
||||
<div id="rabbitmqSettings" class="form-wrapper">
|
||||
<?php
|
||||
require_once SETUP_PATH . "forms/rabbitmq-settings.php";
|
||||
?>
|
||||
</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>
|
||||
|
||||
<script>
|
||||
$(".btn-skip").click(nextSlide);
|
||||
$(".btn-back").click(prevSlide);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,32 +0,0 @@
|
|||
[database]
|
||||
host = localhost
|
||||
dbname = airtime
|
||||
dbuser = airtime
|
||||
dbpass = airtime
|
||||
|
||||
[rabbitmq]
|
||||
host = 127.0.0.1
|
||||
port = 5672
|
||||
user = guest
|
||||
password = guest
|
||||
vhost = /
|
||||
|
||||
[general]
|
||||
api_key = AAA
|
||||
web_server_user = www-data
|
||||
airtime_dir = x
|
||||
base_url = localhost
|
||||
base_port = 80
|
||||
base_dir = '/'
|
||||
|
||||
;How many hours ahead of time should Airtime playout engine (PYPO)
|
||||
;cache scheduled media files.
|
||||
cache_ahead_hours = 1
|
||||
|
||||
[monit]
|
||||
monit_user = guest
|
||||
monit_password = airtime
|
||||
|
||||
[soundcloud]
|
||||
connection_retries = 3
|
||||
time_between_retries = 60
|
|
@ -0,0 +1,274 @@
|
|||
# ----------------------------------------------------------------------
|
||||
# A I R T I M E C O N F I G U R A T I O N
|
||||
# ----------------------------------------------------------------------
|
||||
#
|
||||
# This is an example configuration for Airtime. If you just want to
|
||||
# get started with a basic Airtime setup, or don't know if you should
|
||||
# be reconfiguring any of the following values, just rename this file
|
||||
# to 'airtime.conf'.
|
||||
#
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# G E N E R A L S E T T I N G S
|
||||
# ----------------------------------------------------------------------
|
||||
#
|
||||
# These settings are used for Airtime's webserver configuration, and
|
||||
# for general-purpose properties.
|
||||
#
|
||||
# api_key: The API key for your Airtime installation.
|
||||
# The value is generated the first time you use Airtime.
|
||||
#
|
||||
# web_server_user: The default webserver user.
|
||||
# The default is www-data.
|
||||
#
|
||||
# base_url: The host name for your webserver.
|
||||
# The default is localhost.
|
||||
#
|
||||
# base_port: The port for your webserver.
|
||||
# The default is 80.
|
||||
#
|
||||
# base_dir: The root directory for your Airtime installation
|
||||
# on your webserver, relative to the base_url.
|
||||
# The default is /.
|
||||
#
|
||||
# cache_ahead_hours: How many hours ahead of time the Airtime playout
|
||||
# engine (pypo) should cache scheduled media files.
|
||||
# The default is 1.
|
||||
#
|
||||
[general]
|
||||
api_key =
|
||||
web_server_user = www-data
|
||||
base_url = localhost
|
||||
base_port = 80
|
||||
base_dir = /
|
||||
cache_ahead_hours = 1
|
||||
#
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# D A T A B A S E
|
||||
# ----------------------------------------------------------------------
|
||||
#
|
||||
# These settings are used to configure your database connection.
|
||||
#
|
||||
# host: The hostname of the database server.
|
||||
# On a default Airtime installation, set this to localhost.
|
||||
#
|
||||
# dbname: The name of the Airtime database.
|
||||
# The default is airtime.
|
||||
#
|
||||
# dbuser: The username for the Airtime database user.
|
||||
# The default is airtime.
|
||||
#
|
||||
# dbpass: The password for the Airtime database user.
|
||||
# The default is airtime.
|
||||
#
|
||||
[database]
|
||||
host = localhost
|
||||
dbname = airtime
|
||||
dbuser = airtime
|
||||
dbpass = airtime
|
||||
#
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# R A B B I T M Q
|
||||
# ----------------------------------------------------------------------
|
||||
#
|
||||
# These settings are used to configure the RabbitMQ messaging
|
||||
# configuration for your Airtime installation.
|
||||
#
|
||||
# host: The IP address for the RabbitMQ service.
|
||||
# The default is 127.0.0.1.
|
||||
#
|
||||
# port: The port for the RabbitMQ service.
|
||||
# The default is 5672.
|
||||
#
|
||||
# user: The username for the RabbitMQ user.
|
||||
# The default is airtime.
|
||||
#
|
||||
# password: The password for the RabbitMQ user.
|
||||
# The default is airtime.
|
||||
#
|
||||
# vhost: The virtual host for the RabbitMQ service database.
|
||||
# The default is /airtime.
|
||||
#
|
||||
[rabbitmq]
|
||||
host = 127.0.0.1
|
||||
port = 5672
|
||||
user = airtime
|
||||
password = airtime
|
||||
vhost = /airtime
|
||||
#
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# M E D I A M O N I T O R
|
||||
# ----------------------------------------------------------------------
|
||||
#
|
||||
# check_filesystem_events: How long to queue up events performed on the
|
||||
# files themselves, in seconds
|
||||
# The default is 5
|
||||
#
|
||||
# check_airtime_events: How long to queue metadata input from airtime,
|
||||
# in seconds
|
||||
# The default is 30
|
||||
#
|
||||
# touch_interval:
|
||||
# The default is 5
|
||||
#
|
||||
# chunking_number:
|
||||
# The default is 450
|
||||
#
|
||||
# request_max_wait: The maximum request wait time, in seconds
|
||||
# The default is 3.0
|
||||
#
|
||||
# rmq_event_wait: The RabbitMQ event wait time, in seconds
|
||||
# The default is 0.1
|
||||
#
|
||||
# logpath: The media monitor log file path
|
||||
# The default is '/var/log/airtime/media-monitor/media-monitor.log'
|
||||
#
|
||||
# index_path: The media monitor index path
|
||||
# The default is '/var/tmp/airtime/media-monitor/last_index'
|
||||
#
|
||||
[media-monitor]
|
||||
check_filesystem_events = 5
|
||||
check_airtime_events = 30
|
||||
touch_interval = 5
|
||||
chunking_number = 450
|
||||
request_max_wait = 3.0
|
||||
rmq_event_wait = 0.1
|
||||
logpath = '/var/log/airtime/media-monitor/media-monitor.log'
|
||||
index_path = '/var/tmp/airtime/media-monitor/last_index'
|
||||
#
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# P Y P O
|
||||
# ----------------------------------------------------------------------
|
||||
#
|
||||
# api_client: Set the type of client you are using.
|
||||
# Currently supported types:
|
||||
# 1) 'obp' = Open Broadcast Platform
|
||||
# 2) 'airtime'
|
||||
# The default is 'airtime'
|
||||
#
|
||||
# cache_dir: The directory for pypo cache files
|
||||
# The default is '/var/tmp/airtime/pypo/cache/'
|
||||
#
|
||||
# file_dir: The directory for pypo media files
|
||||
# The default is '/var/tmp/airtime/pypo/files/'
|
||||
#
|
||||
# tmp_dir: The directory for pypo temp files
|
||||
# The default is '/var/tmp/airtime/pypo/tmp/'
|
||||
#
|
||||
# cache_base_dir: The pypo base cache directory
|
||||
# The default is '/var/tmp/airtime/pypo/'
|
||||
#
|
||||
# log_base_dir: The base directory for Airtime log files
|
||||
# The default is '/var/log/airtime'
|
||||
#
|
||||
# pypo_log_dir: The directory for pypo log files
|
||||
# The default is '/var/log/airtime/pypo'
|
||||
#
|
||||
# liquidsoap_log_dir: The directory for liquidsoap log files
|
||||
# The default is '/var/log/airtime/pypo-liquidsoap'
|
||||
#
|
||||
# ls_host: Liquidsoap connection host
|
||||
# The default is '127.0.0.1'
|
||||
#
|
||||
# ls_port: Liquidsoap connection port
|
||||
# The default is '1234'
|
||||
#
|
||||
# poll_interval: Poll interval in seconds
|
||||
#
|
||||
# This will rarely need to be changed because any schedule
|
||||
# changes are automatically sent to pypo immediately
|
||||
# This is how often the poll script downloads new schedules
|
||||
# and files from the server in the event that no changes
|
||||
# are made to the schedule
|
||||
# The default is 3600
|
||||
#
|
||||
# push_interval: Push interval in seconds
|
||||
#
|
||||
# This is how often the push script checks whether it has
|
||||
# something new to push to liquidsoap
|
||||
# The default is 1
|
||||
#
|
||||
# cue_style: Can be set to 'pre' or 'otf'
|
||||
# 'pre' cues while playlist preparation
|
||||
# 'otf' (on the fly) cues while loading into ls
|
||||
# (needs the post_processor patch)
|
||||
# The default is 'pre'
|
||||
#
|
||||
# record_bitrate: The bitrate for recordings
|
||||
# The default is 256
|
||||
#
|
||||
# record_samplerate: The samplerate for recordings
|
||||
# The default is 44100
|
||||
#
|
||||
# record_channels: The number of channels for recordings
|
||||
# The default is 2
|
||||
#
|
||||
# record_sample_size: The sample size for recordings
|
||||
# The default is 16
|
||||
#
|
||||
# record_file_type: Can be either ogg|mp3, mp3 recording requires
|
||||
# installation of the package "lame"
|
||||
# The default is ogg
|
||||
#
|
||||
# base_recorded_files: Base path to store recordered shows at
|
||||
# The default is '/var/tmp/airtime/show-recorder/'
|
||||
#
|
||||
[pypo]
|
||||
api_client = 'airtime'
|
||||
# ---------- Cache directories - !! Include trailing slash !! ----------
|
||||
cache_dir = '/var/tmp/airtime/pypo/cache/'
|
||||
file_dir = '/var/tmp/airtime/pypo/files/'
|
||||
tmp_dir = '/var/tmp/airtime/pypo/tmp/'
|
||||
# ------- Setup directories - !! Don't include trailing slash !! -------
|
||||
cache_base_dir = '/var/tmp/airtime/pypo'
|
||||
log_base_dir = '/var/log/airtime'
|
||||
pypo_log_dir = '/var/log/airtime/pypo'
|
||||
liquidsoap_log_dir = '/var/log/airtime/pypo-liquidsoap'
|
||||
# ------------------------ Liquidsoap Settings -------------------------
|
||||
ls_host = '127.0.0.1'
|
||||
ls_port = '1234'
|
||||
# -------------------------- Pypo Preferences --------------------------
|
||||
poll_interval = 3600
|
||||
push_interval = 1
|
||||
cue_style = 'pre'
|
||||
# ---------------------- Recorded Audio Settings -----------------------
|
||||
record_bitrate = 256
|
||||
record_samplerate = 44100
|
||||
record_channels = 2
|
||||
record_sample_size = 16
|
||||
record_file_type = 'ogg'
|
||||
base_recorded_files = '/var/tmp/airtime/show-recorder/'
|
||||
#
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# S O U N D C L O U D
|
||||
# ----------------------------------------------------------------------
|
||||
#
|
||||
# connection_retries: The number of times to retry the connection to
|
||||
# Soundcloud.
|
||||
# The default is 3.
|
||||
#
|
||||
# time_between_retries: The time between connection retries, in seconds.
|
||||
# The default is 60.
|
||||
#
|
||||
[soundcloud]
|
||||
connection_retries = 3
|
||||
time_between_retries = 60
|
||||
#
|
||||
# ----------------------------------------------------------------------
|
|
@ -1,5 +1,5 @@
|
|||
-- Schema version
|
||||
INSERT INTO cc_pref("keystr", "valstr") VALUES('system_version', '2.5.9');
|
||||
INSERT INTO cc_pref("keystr", "valstr") VALUES('schema_version', '2.5.12');
|
||||
|
||||
INSERT INTO cc_subjs ("login", "type", "pass") VALUES ('admin', 'A', md5('admin'));
|
||||
-- added in 2.3
|
||||
|
|
|
@ -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);
|
||||
|
@ -601,12 +604,17 @@ class AMQPConnection extends AbstractChannel
|
|||
*/
|
||||
public function close($reply_code=0, $reply_text="", $method_sig=array(0, 0))
|
||||
{
|
||||
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
|
||||
));
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,39 @@
|
|||
.logo {
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
|
||||
.table {
|
||||
padding: 5px;
|
||||
margin: 1em 0 0 0;
|
||||
}
|
||||
|
||||
.checklist {
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.caption {
|
||||
padding-left: .5em;
|
||||
}
|
||||
|
||||
.component {
|
||||
font-weight: bold;
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.description {
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.check {
|
||||
background: #dff0d8 url("../images/accept.png") no-repeat center;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin: inherit;
|
||||
width: inherit;
|
||||
bottom: 0;
|
||||
}
|
|
@ -0,0 +1,252 @@
|
|||
html {
|
||||
background: -webkit-linear-gradient(#444, black); /* For Safari 5.1 to 6.0 */
|
||||
background: -o-linear-gradient(#444, black); /* For Opera 11.1 to 12.0 */
|
||||
background: -moz-linear-gradient(#444, black); /* For Firefox 3.6 to 15 */
|
||||
background: linear-gradient(#444, black); /* Standard syntax */
|
||||
}
|
||||
|
||||
body {
|
||||
background: rgba(0,0,0,0); /* Make the bg transparent */
|
||||
color: white;
|
||||
min-width: 400px;
|
||||
width: 30%;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
p, h1, h2, h3, h4, h5, h6 {
|
||||
text-shadow: 0px 1px 1px #000;
|
||||
}
|
||||
|
||||
code {
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.header {
|
||||
padding-top: 1em;
|
||||
height: 10%;
|
||||
min-height: 75px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.header strong {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.logo {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.logo strong {
|
||||
padding-left: .5em;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#airtimeLogo {
|
||||
float: left;
|
||||
padding-top: 0.6em;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
text-shadow: 0px 1px 1px #000000;
|
||||
background-color: #ff5d1a;
|
||||
border-color: #8d3715;
|
||||
}
|
||||
|
||||
.btn-primary:focus, .btn-primary:active, .form-control:focus
|
||||
{
|
||||
border-color: #ff5d1a;
|
||||
outline: 0;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(255, 93, 26, 0.6);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(255, 93, 26, 0.6);
|
||||
}
|
||||
|
||||
.btn-primary:hover, .btn-primary:focus, .btn-primary.focus, .btn-primary:active, .btn-primary.active, .open>.dropdown-toggle.btn-primary,
|
||||
.btn-primary.disabled, .btn-primary[disabled], fieldset[disabled] .btn-primary, .btn-primary.disabled:hover, .btn-primary[disabled]:hover,
|
||||
fieldset[disabled] .btn-primary:hover, .btn-primary.disabled:focus, .btn-primary[disabled]:focus, fieldset[disabled] .btn-primary:focus,
|
||||
.btn-primary.disabled.focus, .btn-primary[disabled].focus, fieldset[disabled] .btn-primary.focus, .btn-primary.disabled:active,
|
||||
.btn-primary[disabled]:active, fieldset[disabled] .btn-primary:active, .btn-primary.disabled.active, .btn-primary[disabled].active,
|
||||
fieldset[disabled] .btn-primary.active
|
||||
{
|
||||
background-color: #dc5118;
|
||||
border-color: #632910;
|
||||
}
|
||||
|
||||
/* ############################################################################
|
||||
*
|
||||
* Form Styles
|
||||
*
|
||||
* ############################################################################ */
|
||||
|
||||
form {
|
||||
margin: auto;
|
||||
top: 0;
|
||||
width: 99%;
|
||||
position: absolute;
|
||||
float: right;
|
||||
|
||||
}
|
||||
|
||||
form p {
|
||||
text-align: left;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
form .form-group {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.viewport {
|
||||
position: absolute;
|
||||
width: 30%;
|
||||
min-width: 400px;
|
||||
height: 89%; /* Keep 1% off of 100 to avoid overflow */
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.form-wrapper {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.form-title {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.form-slider {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.form-control-feedback {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ############################################################################
|
||||
*
|
||||
* Form Help Box Styles
|
||||
*
|
||||
* ############################################################################ */
|
||||
|
||||
.help-block.help-message {
|
||||
font-weight:bold;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.has-error, .has-error .control-label,
|
||||
.has-error .form-control-feedback,
|
||||
.has-error .form-control {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.has-success {
|
||||
color: lawngreen;
|
||||
}
|
||||
|
||||
/* ############################################################################
|
||||
*
|
||||
* Overlay Styles
|
||||
*
|
||||
* ############################################################################ */
|
||||
|
||||
#overlay {
|
||||
display: none;
|
||||
opacity: 0.6;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: #000;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 5000;
|
||||
}
|
||||
|
||||
#loadingImage {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 40%;
|
||||
left: 49%; /* Shave 1% to account for half image width */
|
||||
z-index: 5001;
|
||||
}
|
||||
|
||||
/* ############################################################################
|
||||
*
|
||||
* Button Styles
|
||||
*
|
||||
* ############################################################################ */
|
||||
|
||||
.btn-primary {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.btn-disabled {
|
||||
disabled: disabled;
|
||||
visibility: hidden;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.btn-next {
|
||||
float: right;
|
||||
width: 49%;
|
||||
}
|
||||
|
||||
.btn-skip {
|
||||
margin-top: .5em;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.btn-back {
|
||||
float: left;
|
||||
width: 49%;
|
||||
}
|
||||
|
||||
.caret.caret-up {
|
||||
border-top-width: 0;
|
||||
border-bottom: 4px solid #fff;
|
||||
}
|
||||
|
||||
/* ############################################################################
|
||||
*
|
||||
* RabbitMQ Settings Form Styles
|
||||
*
|
||||
* ############################################################################ */
|
||||
|
||||
#rmqSettingsForm {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
#rmqFormBody {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ############################################################################
|
||||
*
|
||||
* General Settings Form Styles
|
||||
*
|
||||
* ############################################################################ */
|
||||
|
||||
#generalSettingsForm {
|
||||
left: 200%;
|
||||
}
|
||||
|
||||
/* ############################################################################
|
||||
*
|
||||
* Media Settings Form Styles
|
||||
*
|
||||
* ############################################################################ */
|
||||
|
||||
#mediaSettingsForm {
|
||||
left: 300%;
|
||||
}
|
||||
|
||||
/* ############################################################################
|
||||
*
|
||||
* Finish Settings Form Styles
|
||||
*
|
||||
* ############################################################################ */
|
||||
|
||||
#finishSettingsForm {
|
||||
left: 400%;
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,229 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata></metadata>
|
||||
<defs>
|
||||
<font id="glyphicons_halflingsregular" horiz-adv-x="1200" >
|
||||
<font-face units-per-em="1200" ascent="960" descent="-240" />
|
||||
<missing-glyph horiz-adv-x="500" />
|
||||
<glyph />
|
||||
<glyph />
|
||||
<glyph unicode="
" />
|
||||
<glyph unicode=" " />
|
||||
<glyph unicode="*" d="M100 500v200h259l-183 183l141 141l183 -183v259h200v-259l183 183l141 -141l-183 -183h259v-200h-259l183 -183l-141 -141l-183 183v-259h-200v259l-183 -183l-141 141l183 183h-259z" />
|
||||
<glyph unicode="+" d="M0 400v300h400v400h300v-400h400v-300h-400v-400h-300v400h-400z" />
|
||||
<glyph unicode=" " />
|
||||
<glyph unicode=" " horiz-adv-x="652" />
|
||||
<glyph unicode=" " horiz-adv-x="1304" />
|
||||
<glyph unicode=" " horiz-adv-x="652" />
|
||||
<glyph unicode=" " horiz-adv-x="1304" />
|
||||
<glyph unicode=" " horiz-adv-x="434" />
|
||||
<glyph unicode=" " horiz-adv-x="326" />
|
||||
<glyph unicode=" " horiz-adv-x="217" />
|
||||
<glyph unicode=" " horiz-adv-x="217" />
|
||||
<glyph unicode=" " horiz-adv-x="163" />
|
||||
<glyph unicode=" " horiz-adv-x="260" />
|
||||
<glyph unicode=" " horiz-adv-x="72" />
|
||||
<glyph unicode=" " horiz-adv-x="260" />
|
||||
<glyph unicode=" " horiz-adv-x="326" />
|
||||
<glyph unicode="€" d="M100 500l100 100h113q0 47 5 100h-218l100 100h135q37 167 112 257q117 141 297 141q242 0 354 -189q60 -103 66 -209h-181q0 55 -25.5 99t-63.5 68t-75 36.5t-67 12.5q-24 0 -52.5 -10t-62.5 -32t-65.5 -67t-50.5 -107h379l-100 -100h-300q-6 -46 -6 -100h406l-100 -100 h-300q9 -74 33 -132t52.5 -91t62 -54.5t59 -29t46.5 -7.5q29 0 66 13t75 37t63.5 67.5t25.5 96.5h174q-31 -172 -128 -278q-107 -117 -274 -117q-205 0 -324 158q-36 46 -69 131.5t-45 205.5h-217z" />
|
||||
<glyph unicode="−" d="M200 400h900v300h-900v-300z" />
|
||||
<glyph unicode="◼" horiz-adv-x="500" d="M0 0z" />
|
||||
<glyph unicode="☁" d="M-14 494q0 -80 56.5 -137t135.5 -57h750q120 0 205 86.5t85 207.5t-85 207t-205 86q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5z" />
|
||||
<glyph unicode="✉" d="M0 100l400 400l200 -200l200 200l400 -400h-1200zM0 300v600l300 -300zM0 1100l600 -603l600 603h-1200zM900 600l300 300v-600z" />
|
||||
<glyph unicode="✏" d="M-13 -13l333 112l-223 223zM187 403l214 -214l614 614l-214 214zM887 1103l214 -214l99 92q13 13 13 32.5t-13 33.5l-153 153q-15 13 -33 13t-33 -13z" />
|
||||
<glyph unicode="" d="M0 1200h1200l-500 -550v-550h300v-100h-800v100h300v550z" />
|
||||
<glyph unicode="" d="M14 84q18 -55 86 -75.5t147 5.5q65 21 109 69t44 90v606l600 155v-521q-64 16 -138 -7q-79 -26 -122.5 -83t-25.5 -111q18 -55 86 -75.5t147 4.5q70 23 111.5 63.5t41.5 95.5v881q0 10 -7 15.5t-17 2.5l-752 -193q-10 -3 -17 -12.5t-7 -19.5v-689q-64 17 -138 -7 q-79 -25 -122.5 -82t-25.5 -112z" />
|
||||
<glyph unicode="" d="M23 693q0 200 142 342t342 142t342 -142t142 -342q0 -142 -78 -261l300 -300q7 -8 7 -18t-7 -18l-109 -109q-8 -7 -18 -7t-18 7l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 693q0 -136 97 -233t234 -97t233.5 96.5t96.5 233.5t-96.5 233.5t-233.5 96.5 t-234 -97t-97 -233z" />
|
||||
<glyph unicode="" d="M100 784q0 64 28 123t73 100.5t104.5 64t119 20.5t120 -38.5t104.5 -104.5q48 69 109.5 105t121.5 38t118.5 -20.5t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-149.5 152.5t-126.5 127.5 t-94 124.5t-33.5 117.5z" />
|
||||
<glyph unicode="" d="M-72 800h479l146 400h2l146 -400h472l-382 -278l145 -449l-384 275l-382 -275l146 447zM168 71l2 1z" />
|
||||
<glyph unicode="" d="M-72 800h479l146 400h2l146 -400h472l-382 -278l145 -449l-384 275l-382 -275l146 447zM168 71l2 1zM237 700l196 -142l-73 -226l192 140l195 -141l-74 229l193 140h-235l-77 211l-78 -211h-239z" />
|
||||
<glyph unicode="" d="M0 0v143l400 257v100q-37 0 -68.5 74.5t-31.5 125.5v200q0 124 88 212t212 88t212 -88t88 -212v-200q0 -51 -31.5 -125.5t-68.5 -74.5v-100l400 -257v-143h-1200z" />
|
||||
<glyph unicode="" d="M0 0v1100h1200v-1100h-1200zM100 100h100v100h-100v-100zM100 300h100v100h-100v-100zM100 500h100v100h-100v-100zM100 700h100v100h-100v-100zM100 900h100v100h-100v-100zM300 100h600v400h-600v-400zM300 600h600v400h-600v-400zM1000 100h100v100h-100v-100z M1000 300h100v100h-100v-100zM1000 500h100v100h-100v-100zM1000 700h100v100h-100v-100zM1000 900h100v100h-100v-100z" />
|
||||
<glyph unicode="" d="M0 50v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5zM0 650v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5zM600 50v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5zM600 650v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5z" />
|
||||
<glyph unicode="" d="M0 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM0 450v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5zM0 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5 t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 450v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5 v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 450v200q0 21 14.5 35.5t35.5 14.5h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5z" />
|
||||
<glyph unicode="" d="M0 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM0 450q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v200q0 21 -14.5 35.5t-35.5 14.5h-200q-21 0 -35.5 -14.5 t-14.5 -35.5v-200zM0 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 50v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5 t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5zM400 450v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5zM400 850v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5 v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5z" />
|
||||
<glyph unicode="" d="M29 454l419 -420l818 820l-212 212l-607 -607l-206 207z" />
|
||||
<glyph unicode="" d="M106 318l282 282l-282 282l212 212l282 -282l282 282l212 -212l-282 -282l282 -282l-212 -212l-282 282l-282 -282z" />
|
||||
<glyph unicode="" d="M23 693q0 200 142 342t342 142t342 -142t142 -342q0 -142 -78 -261l300 -300q7 -8 7 -18t-7 -18l-109 -109q-8 -7 -18 -7t-18 7l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 693q0 -136 97 -233t234 -97t233.5 96.5t96.5 233.5t-96.5 233.5t-233.5 96.5 t-234 -97t-97 -233zM300 600v200h100v100h200v-100h100v-200h-100v-100h-200v100h-100z" />
|
||||
<glyph unicode="" d="M23 694q0 200 142 342t342 142t342 -142t142 -342q0 -141 -78 -262l300 -299q7 -7 7 -18t-7 -18l-109 -109q-8 -8 -18 -8t-18 8l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 694q0 -136 97 -233t234 -97t233.5 97t96.5 233t-96.5 233t-233.5 97t-234 -97 t-97 -233zM300 601h400v200h-400v-200z" />
|
||||
<glyph unicode="" d="M23 600q0 183 105 331t272 210v-166q-103 -55 -165 -155t-62 -220q0 -177 125 -302t302 -125t302 125t125 302q0 120 -62 220t-165 155v166q167 -62 272 -210t105 -331q0 -118 -45.5 -224.5t-123 -184t-184 -123t-224.5 -45.5t-224.5 45.5t-184 123t-123 184t-45.5 224.5 zM500 750q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v400q0 21 -14.5 35.5t-35.5 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-400z" />
|
||||
<glyph unicode="" d="M100 1h200v300h-200v-300zM400 1v500h200v-500h-200zM700 1v800h200v-800h-200zM1000 1v1200h200v-1200h-200z" />
|
||||
<glyph unicode="" d="M26 601q0 -33 6 -74l151 -38l2 -6q14 -49 38 -93l3 -5l-80 -134q45 -59 105 -105l133 81l5 -3q45 -26 94 -39l5 -2l38 -151q40 -5 74 -5q27 0 74 5l38 151l6 2q46 13 93 39l5 3l134 -81q56 44 104 105l-80 134l3 5q24 44 39 93l1 6l152 38q5 40 5 74q0 28 -5 73l-152 38 l-1 6q-16 51 -39 93l-3 5l80 134q-44 58 -104 105l-134 -81l-5 3q-45 25 -93 39l-6 1l-38 152q-40 5 -74 5q-27 0 -74 -5l-38 -152l-5 -1q-50 -14 -94 -39l-5 -3l-133 81q-59 -47 -105 -105l80 -134l-3 -5q-25 -47 -38 -93l-2 -6l-151 -38q-6 -48 -6 -73zM385 601 q0 88 63 151t152 63t152 -63t63 -151q0 -89 -63 -152t-152 -63t-152 63t-63 152z" />
|
||||
<glyph unicode="" d="M100 1025v50q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-50q0 -11 -7 -18t-18 -7h-1050q-11 0 -18 7t-7 18zM200 100v800h900v-800q0 -41 -29.5 -71t-70.5 -30h-700q-41 0 -70.5 30 t-29.5 71zM300 100h100v700h-100v-700zM500 100h100v700h-100v-700zM500 1100h300v100h-300v-100zM700 100h100v700h-100v-700zM900 100h100v700h-100v-700z" />
|
||||
<glyph unicode="" d="M1 601l656 644l644 -644h-200v-600h-300v400h-300v-400h-300v600h-200z" />
|
||||
<glyph unicode="" d="M100 25v1150q0 11 7 18t18 7h475v-500h400v-675q0 -11 -7 -18t-18 -7h-850q-11 0 -18 7t-7 18zM700 800v300l300 -300h-300z" />
|
||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM500 500v400h100 v-300h200v-100h-300z" />
|
||||
<glyph unicode="" d="M-100 0l431 1200h209l-21 -300h162l-20 300h208l431 -1200h-538l-41 400h-242l-40 -400h-539zM488 500h224l-27 300h-170z" />
|
||||
<glyph unicode="" d="M0 0v400h490l-290 300h200v500h300v-500h200l-290 -300h490v-400h-1100zM813 200h175v100h-175v-100z" />
|
||||
<glyph unicode="" d="M1 600q0 122 47.5 233t127.5 191t191 127.5t233 47.5t233 -47.5t191 -127.5t127.5 -191t47.5 -233t-47.5 -233t-127.5 -191t-191 -127.5t-233 -47.5t-233 47.5t-191 127.5t-127.5 191t-47.5 233zM188 600q0 -170 121 -291t291 -121t291 121t121 291t-121 291t-291 121 t-291 -121t-121 -291zM350 600h150v300h200v-300h150l-250 -300z" />
|
||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM350 600l250 300 l250 -300h-150v-300h-200v300h-150z" />
|
||||
<glyph unicode="" d="M0 25v475l200 700h800l199 -700l1 -475q0 -11 -7 -18t-18 -7h-1150q-11 0 -18 7t-7 18zM200 500h200l50 -200h300l50 200h200l-97 500h-606z" />
|
||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -172 121.5 -293t292.5 -121t292.5 121t121.5 293q0 171 -121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM500 397v401 l297 -200z" />
|
||||
<glyph unicode="" d="M23 600q0 -118 45.5 -224.5t123 -184t184 -123t224.5 -45.5t224.5 45.5t184 123t123 184t45.5 224.5h-150q0 -177 -125 -302t-302 -125t-302 125t-125 302t125 302t302 125q136 0 246 -81l-146 -146h400v400l-145 -145q-157 122 -355 122q-118 0 -224.5 -45.5t-184 -123 t-123 -184t-45.5 -224.5z" />
|
||||
<glyph unicode="" d="M23 600q0 118 45.5 224.5t123 184t184 123t224.5 45.5q198 0 355 -122l145 145v-400h-400l147 147q-112 80 -247 80q-177 0 -302 -125t-125 -302h-150zM100 0v400h400l-147 -147q112 -80 247 -80q177 0 302 125t125 302h150q0 -118 -45.5 -224.5t-123 -184t-184 -123 t-224.5 -45.5q-198 0 -355 122z" />
|
||||
<glyph unicode="" d="M100 0h1100v1200h-1100v-1200zM200 100v900h900v-900h-900zM300 200v100h100v-100h-100zM300 400v100h100v-100h-100zM300 600v100h100v-100h-100zM300 800v100h100v-100h-100zM500 200h500v100h-500v-100zM500 400v100h500v-100h-500zM500 600v100h500v-100h-500z M500 800v100h500v-100h-500z" />
|
||||
<glyph unicode="" d="M0 100v600q0 41 29.5 70.5t70.5 29.5h100v200q0 82 59 141t141 59h300q82 0 141 -59t59 -141v-200h100q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-900q-41 0 -70.5 29.5t-29.5 70.5zM400 800h300v150q0 21 -14.5 35.5t-35.5 14.5h-200 q-21 0 -35.5 -14.5t-14.5 -35.5v-150z" />
|
||||
<glyph unicode="" d="M100 0v1100h100v-1100h-100zM300 400q60 60 127.5 84t127.5 17.5t122 -23t119 -30t110 -11t103 42t91 120.5v500q-40 -81 -101.5 -115.5t-127.5 -29.5t-138 25t-139.5 40t-125.5 25t-103 -29.5t-65 -115.5v-500z" />
|
||||
<glyph unicode="" d="M0 275q0 -11 7 -18t18 -7h50q11 0 18 7t7 18v300q0 127 70.5 231.5t184.5 161.5t245 57t245 -57t184.5 -161.5t70.5 -231.5v-300q0 -11 7 -18t18 -7h50q11 0 18 7t7 18v300q0 116 -49.5 227t-131 192.5t-192.5 131t-227 49.5t-227 -49.5t-192.5 -131t-131 -192.5 t-49.5 -227v-300zM200 20v460q0 8 6 14t14 6h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14zM800 20v460q0 8 6 14t14 6h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14z" />
|
||||
<glyph unicode="" d="M0 400h300l300 -200v800l-300 -200h-300v-400zM688 459l141 141l-141 141l71 71l141 -141l141 141l71 -71l-141 -141l141 -141l-71 -71l-141 141l-141 -141z" />
|
||||
<glyph unicode="" d="M0 400h300l300 -200v800l-300 -200h-300v-400zM700 857l69 53q111 -135 111 -310q0 -169 -106 -302l-67 54q86 110 86 248q0 146 -93 257z" />
|
||||
<glyph unicode="" d="M0 401v400h300l300 200v-800l-300 200h-300zM702 858l69 53q111 -135 111 -310q0 -170 -106 -303l-67 55q86 110 86 248q0 145 -93 257zM889 951l7 -8q123 -151 123 -344q0 -189 -119 -339l-7 -8l81 -66l6 8q142 178 142 405q0 230 -144 408l-6 8z" />
|
||||
<glyph unicode="" d="M0 0h500v500h-200v100h-100v-100h-200v-500zM0 600h100v100h400v100h100v100h-100v300h-500v-600zM100 100v300h300v-300h-300zM100 800v300h300v-300h-300zM200 200v100h100v-100h-100zM200 900h100v100h-100v-100zM500 500v100h300v-300h200v-100h-100v-100h-200v100 h-100v100h100v200h-200zM600 0v100h100v-100h-100zM600 1000h100v-300h200v-300h300v200h-200v100h200v500h-600v-200zM800 800v300h300v-300h-300zM900 0v100h300v-100h-300zM900 900v100h100v-100h-100zM1100 200v100h100v-100h-100z" />
|
||||
<glyph unicode="" d="M0 200h100v1000h-100v-1000zM100 0v100h300v-100h-300zM200 200v1000h100v-1000h-100zM500 0v91h100v-91h-100zM500 200v1000h200v-1000h-200zM700 0v91h100v-91h-100zM800 200v1000h100v-1000h-100zM900 0v91h200v-91h-200zM1000 200v1000h200v-1000h-200z" />
|
||||
<glyph unicode="" d="M0 700l1 475q0 10 7.5 17.5t17.5 7.5h474l700 -700l-500 -500zM148 953q0 -42 29 -71q30 -30 71.5 -30t71.5 30q29 29 29 71t-29 71q-30 30 -71.5 30t-71.5 -30q-29 -29 -29 -71z" />
|
||||
<glyph unicode="" d="M1 700l1 475q0 11 7 18t18 7h474l700 -700l-500 -500zM148 953q0 -42 30 -71q29 -30 71 -30t71 30q30 29 30 71t-30 71q-29 30 -71 30t-71 -30q-30 -29 -30 -71zM701 1200h100l700 -700l-500 -500l-50 50l450 450z" />
|
||||
<glyph unicode="" d="M100 0v1025l175 175h925v-1000l-100 -100v1000h-750l-100 -100h750v-1000h-900z" />
|
||||
<glyph unicode="" d="M200 0l450 444l450 -443v1150q0 20 -14.5 35t-35.5 15h-800q-21 0 -35.5 -15t-14.5 -35v-1151z" />
|
||||
<glyph unicode="" d="M0 100v700h200l100 -200h600l100 200h200v-700h-200v200h-800v-200h-200zM253 829l40 -124h592l62 124l-94 346q-2 11 -10 18t-18 7h-450q-10 0 -18 -7t-10 -18zM281 24l38 152q2 10 11.5 17t19.5 7h500q10 0 19.5 -7t11.5 -17l38 -152q2 -10 -3.5 -17t-15.5 -7h-600 q-10 0 -15.5 7t-3.5 17z" />
|
||||
<glyph unicode="" d="M0 200q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-150q-4 8 -11.5 21.5t-33 48t-53 61t-69 48t-83.5 21.5h-200q-41 0 -82 -20.5t-70 -50t-52 -59t-34 -50.5l-12 -20h-150q-41 0 -70.5 -29.5t-29.5 -70.5v-600z M356 500q0 100 72 172t172 72t172 -72t72 -172t-72 -172t-172 -72t-172 72t-72 172zM494 500q0 -44 31 -75t75 -31t75 31t31 75t-31 75t-75 31t-75 -31t-31 -75zM900 700v100h100v-100h-100z" />
|
||||
<glyph unicode="" d="M53 0h365v66q-41 0 -72 11t-49 38t1 71l92 234h391l82 -222q16 -45 -5.5 -88.5t-74.5 -43.5v-66h417v66q-34 1 -74 43q-18 19 -33 42t-21 37l-6 13l-385 998h-93l-399 -1006q-24 -48 -52 -75q-12 -12 -33 -25t-36 -20l-15 -7v-66zM416 521l178 457l46 -140l116 -317h-340 z" />
|
||||
<glyph unicode="" d="M100 0v89q41 7 70.5 32.5t29.5 65.5v827q0 28 -1 39.5t-5.5 26t-15.5 21t-29 14t-49 14.5v71l471 -1q120 0 213 -88t93 -228q0 -55 -11.5 -101.5t-28 -74t-33.5 -47.5t-28 -28l-12 -7q8 -3 21.5 -9t48 -31.5t60.5 -58t47.5 -91.5t21.5 -129q0 -84 -59 -156.5t-142 -111 t-162 -38.5h-500zM400 200h161q89 0 153 48.5t64 132.5q0 90 -62.5 154.5t-156.5 64.5h-159v-400zM400 700h139q76 0 130 61.5t54 138.5q0 82 -84 130.5t-239 48.5v-379z" />
|
||||
<glyph unicode="" d="M200 0v57q77 7 134.5 40.5t65.5 80.5l173 849q10 56 -10 74t-91 37q-6 1 -10.5 2.5t-9.5 2.5v57h425l2 -57q-33 -8 -62 -25.5t-46 -37t-29.5 -38t-17.5 -30.5l-5 -12l-128 -825q-10 -52 14 -82t95 -36v-57h-500z" />
|
||||
<glyph unicode="" d="M-75 200h75v800h-75l125 167l125 -167h-75v-800h75l-125 -167zM300 900v300h150h700h150v-300h-50q0 29 -8 48.5t-18.5 30t-33.5 15t-39.5 5.5t-50.5 1h-200v-850l100 -50v-100h-400v100l100 50v850h-200q-34 0 -50.5 -1t-40 -5.5t-33.5 -15t-18.5 -30t-8.5 -48.5h-49z " />
|
||||
<glyph unicode="" d="M33 51l167 125v-75h800v75l167 -125l-167 -125v75h-800v-75zM100 901v300h150h700h150v-300h-50q0 29 -8 48.5t-18 30t-33.5 15t-40 5.5t-50.5 1h-200v-650l100 -50v-100h-400v100l100 50v650h-200q-34 0 -50.5 -1t-39.5 -5.5t-33.5 -15t-18.5 -30t-8 -48.5h-50z" />
|
||||
<glyph unicode="" d="M0 50q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 350q0 -20 14.5 -35t35.5 -15h800q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-800q-21 0 -35.5 -14.5t-14.5 -35.5 v-100zM0 650q0 -20 14.5 -35t35.5 -15h1000q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1000q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 950q0 -20 14.5 -35t35.5 -15h600q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-600q-21 0 -35.5 -14.5 t-14.5 -35.5v-100z" />
|
||||
<glyph unicode="" d="M0 50q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 650q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5 v-100zM200 350q0 -20 14.5 -35t35.5 -15h700q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-700q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM200 950q0 -20 14.5 -35t35.5 -15h700q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-700q-21 0 -35.5 -14.5 t-14.5 -35.5v-100z" />
|
||||
<glyph unicode="" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1000q-21 0 -35.5 15 t-14.5 35zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-600 q-21 0 -35.5 15t-14.5 35z" />
|
||||
<glyph unicode="" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM0 350v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15 t-14.5 35zM0 650v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM0 950v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100 q-21 0 -35.5 15t-14.5 35z" />
|
||||
<glyph unicode="" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35zM0 350v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15 t-14.5 35zM0 650v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35zM0 950v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15 t-14.5 35zM300 50v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800 q-21 0 -35.5 15t-14.5 35zM300 650v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM300 950v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15 h-800q-21 0 -35.5 15t-14.5 35z" />
|
||||
<glyph unicode="" d="M-101 500v100h201v75l166 -125l-166 -125v75h-201zM300 0h100v1100h-100v-1100zM500 50q0 -20 14.5 -35t35.5 -15h600q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-600q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 350q0 -20 14.5 -35t35.5 -15h300q20 0 35 15t15 35 v100q0 21 -15 35.5t-35 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 650q0 -20 14.5 -35t35.5 -15h500q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 950q0 -20 14.5 -35t35.5 -15h100q20 0 35 15t15 35v100 q0 21 -15 35.5t-35 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-100z" />
|
||||
<glyph unicode="" d="M1 50q0 -20 14.5 -35t35.5 -15h600q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-600q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 350q0 -20 14.5 -35t35.5 -15h300q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 650 q0 -20 14.5 -35t35.5 -15h500q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 950q0 -20 14.5 -35t35.5 -15h100q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM801 0v1100h100v-1100 h-100zM934 550l167 -125v75h200v100h-200v75z" />
|
||||
<glyph unicode="" d="M0 275v650q0 31 22 53t53 22h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53zM900 600l300 300v-600z" />
|
||||
<glyph unicode="" d="M0 44v1012q0 18 13 31t31 13h1112q19 0 31.5 -13t12.5 -31v-1012q0 -18 -12.5 -31t-31.5 -13h-1112q-18 0 -31 13t-13 31zM100 263l247 182l298 -131l-74 156l293 318l236 -288v500h-1000v-737zM208 750q0 56 39 95t95 39t95 -39t39 -95t-39 -95t-95 -39t-95 39t-39 95z " />
|
||||
<glyph unicode="" d="M148 745q0 124 60.5 231.5t165 172t226.5 64.5q123 0 227 -63t164.5 -169.5t60.5 -229.5t-73 -272q-73 -114 -166.5 -237t-150.5 -189l-57 -66q-10 9 -27 26t-66.5 70.5t-96 109t-104 135.5t-100.5 155q-63 139 -63 262zM342 772q0 -107 75.5 -182.5t181.5 -75.5 q107 0 182.5 75.5t75.5 182.5t-75.5 182t-182.5 75t-182 -75.5t-75 -181.5z" />
|
||||
<glyph unicode="" d="M1 600q0 122 47.5 233t127.5 191t191 127.5t233 47.5t233 -47.5t191 -127.5t127.5 -191t47.5 -233t-47.5 -233t-127.5 -191t-191 -127.5t-233 -47.5t-233 47.5t-191 127.5t-127.5 191t-47.5 233zM173 600q0 -177 125.5 -302t301.5 -125v854q-176 0 -301.5 -125 t-125.5 -302z" />
|
||||
<glyph unicode="" d="M117 406q0 94 34 186t88.5 172.5t112 159t115 177t87.5 194.5q21 -71 57.5 -142.5t76 -130.5t83 -118.5t82 -117t70 -116t50 -125.5t18.5 -136q0 -89 -39 -165.5t-102 -126.5t-140 -79.5t-156 -33.5q-114 6 -211.5 53t-161.5 139t-64 210zM243 414q14 -82 59.5 -136 t136.5 -80l16 98q-7 6 -18 17t-34 48t-33 77q-15 73 -14 143.5t10 122.5l9 51q-92 -110 -119.5 -185t-12.5 -156z" />
|
||||
<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5q366 -6 397 -14l-186 -186h-311q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v125l200 200v-225q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5 t-117.5 282.5zM436 341l161 50l412 412l-114 113l-405 -405zM995 1015l113 -113l113 113l-21 85l-92 28z" />
|
||||
<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h261l2 -80q-133 -32 -218 -120h-145q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-53q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5 zM423 524q30 38 81.5 64t103 35.5t99 14t77.5 3.5l29 -1v-209l360 324l-359 318v-216q-7 0 -19 -1t-48 -8t-69.5 -18.5t-76.5 -37t-76.5 -59t-62 -88t-39.5 -121.5z" />
|
||||
<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q61 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-169q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5 t-117.5 282.5zM342 632l283 -284l567 567l-137 137l-430 -431l-146 147z" />
|
||||
<glyph unicode="" d="M0 603l300 296v-198h200v200h-200l300 300l295 -300h-195v-200h200v198l300 -296l-300 -300v198h-200v-200h195l-295 -300l-300 300h200v200h-200v-198z" />
|
||||
<glyph unicode="" d="M200 50v1000q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-437l500 487v-1100l-500 488v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5z" />
|
||||
<glyph unicode="" d="M0 50v1000q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-437l500 487v-487l500 487v-1100l-500 488v-488l-500 488v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5z" />
|
||||
<glyph unicode="" d="M136 550l564 550v-487l500 487v-1100l-500 488v-488z" />
|
||||
<glyph unicode="" d="M200 0l900 550l-900 550v-1100z" />
|
||||
<glyph unicode="" d="M200 150q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v800q0 21 -14.5 35.5t-35.5 14.5h-200q-21 0 -35.5 -14.5t-14.5 -35.5v-800zM600 150q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v800q0 21 -14.5 35.5t-35.5 14.5h-200 q-21 0 -35.5 -14.5t-14.5 -35.5v-800z" />
|
||||
<glyph unicode="" d="M200 150q0 -20 14.5 -35t35.5 -15h800q21 0 35.5 15t14.5 35v800q0 21 -14.5 35.5t-35.5 14.5h-800q-21 0 -35.5 -14.5t-14.5 -35.5v-800z" />
|
||||
<glyph unicode="" d="M0 0v1100l500 -487v487l564 -550l-564 -550v488z" />
|
||||
<glyph unicode="" d="M0 0v1100l500 -487v487l500 -487v437q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-500 -488v488z" />
|
||||
<glyph unicode="" d="M300 0v1100l500 -487v437q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438z" />
|
||||
<glyph unicode="" d="M100 250v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5zM100 500h1100l-550 564z" />
|
||||
<glyph unicode="" d="M185 599l592 -592l240 240l-353 353l353 353l-240 240z" />
|
||||
<glyph unicode="" d="M272 194l353 353l-353 353l241 240l572 -571l21 -22l-1 -1v-1l-592 -591z" />
|
||||
<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM300 500h200v-200h200v200h200v200h-200v200h-200v-200h-200v-200z" />
|
||||
<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM300 500h600v200h-600v-200z" />
|
||||
<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM246 459l213 -213l141 142l141 -142l213 213l-142 141l142 141l-213 212l-141 -141l-141 142l-212 -213l141 -141 z" />
|
||||
<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM270 551l276 -277l411 411l-175 174l-236 -236l-102 102z" />
|
||||
<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM364 700h143q4 0 11.5 -1t11 -1t6.5 3t3 9t1 11t3.5 8.5t3.5 6t5.5 4t6.5 2.5t9 1.5t9 0.5h11.5h12.5 q19 0 30 -10t11 -26q0 -22 -4 -28t-27 -22q-5 -1 -12.5 -3t-27 -13.5t-34 -27t-26.5 -46t-11 -68.5h200q5 3 14 8t31.5 25.5t39.5 45.5t31 69t14 94q0 51 -17.5 89t-42 58t-58.5 32t-58.5 15t-51.5 3q-50 0 -90.5 -12t-75 -38.5t-53.5 -74.5t-19 -114zM500 300h200v100h-200 v-100z" />
|
||||
<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM400 300h400v100h-100v300h-300v-100h100v-200h-100v-100zM500 800h200v100h-200v-100z" />
|
||||
<glyph unicode="" d="M0 500v200h195q31 125 98.5 199.5t206.5 100.5v200h200v-200q54 -20 113 -60t112.5 -105.5t71.5 -134.5h203v-200h-203q-25 -102 -116.5 -186t-180.5 -117v-197h-200v197q-140 27 -208 102.5t-98 200.5h-194zM290 500q24 -73 79.5 -127.5t130.5 -78.5v206h200v-206 q149 48 201 206h-201v200h200q-25 74 -75.5 127t-124.5 77v-204h-200v203q-75 -23 -130 -77t-79 -126h209v-200h-210z" />
|
||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM356 465l135 135 l-135 135l109 109l135 -135l135 135l109 -109l-135 -135l135 -135l-109 -109l-135 135l-135 -135z" />
|
||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM322 537l141 141 l87 -87l204 205l142 -142l-346 -345z" />
|
||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -115 62 -215l568 567q-100 62 -216 62q-171 0 -292.5 -121.5t-121.5 -292.5zM391 245q97 -59 209 -59q171 0 292.5 121.5t121.5 292.5 q0 112 -59 209z" />
|
||||
<glyph unicode="" d="M0 547l600 453v-300h600v-300h-600v-301z" />
|
||||
<glyph unicode="" d="M0 400v300h600v300l600 -453l-600 -448v301h-600z" />
|
||||
<glyph unicode="" d="M204 600l450 600l444 -600h-298v-600h-300v600h-296z" />
|
||||
<glyph unicode="" d="M104 600h296v600h300v-600h298l-449 -600z" />
|
||||
<glyph unicode="" d="M0 200q6 132 41 238.5t103.5 193t184 138t271.5 59.5v271l600 -453l-600 -448v301q-95 -2 -183 -20t-170 -52t-147 -92.5t-100 -135.5z" />
|
||||
<glyph unicode="" d="M0 0v400l129 -129l294 294l142 -142l-294 -294l129 -129h-400zM635 777l142 -142l294 294l129 -129v400h-400l129 -129z" />
|
||||
<glyph unicode="" d="M34 176l295 295l-129 129h400v-400l-129 130l-295 -295zM600 600v400l129 -129l295 295l142 -141l-295 -295l129 -130h-400z" />
|
||||
<glyph unicode="" d="M23 600q0 118 45.5 224.5t123 184t184 123t224.5 45.5t224.5 -45.5t184 -123t123 -184t45.5 -224.5t-45.5 -224.5t-123 -184t-184 -123t-224.5 -45.5t-224.5 45.5t-184 123t-123 184t-45.5 224.5zM456 851l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5 t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5h-207q-21 0 -33 -14.5t-8 -34.5zM500 300h200v100h-200v-100z" />
|
||||
<glyph unicode="" d="M0 800h100v-200h400v300h200v-300h400v200h100v100h-111q1 1 1 6.5t-1.5 15t-3.5 17.5l-34 172q-11 39 -41.5 63t-69.5 24q-32 0 -61 -17l-239 -144q-22 -13 -40 -35q-19 24 -40 36l-238 144q-33 18 -62 18q-39 0 -69.5 -23t-40.5 -61l-35 -177q-2 -8 -3 -18t-1 -15v-6 h-111v-100zM100 0h400v400h-400v-400zM200 900q-3 0 14 48t36 96l18 47l213 -191h-281zM700 0v400h400v-400h-400zM731 900l202 197q5 -12 12 -32.5t23 -64t25 -72t7 -28.5h-269z" />
|
||||
<glyph unicode="" d="M0 -22v143l216 193q-9 53 -13 83t-5.5 94t9 113t38.5 114t74 124q47 60 99.5 102.5t103 68t127.5 48t145.5 37.5t184.5 43.5t220 58.5q0 -189 -22 -343t-59 -258t-89 -181.5t-108.5 -120t-122 -68t-125.5 -30t-121.5 -1.5t-107.5 12.5t-87.5 17t-56.5 7.5l-99 -55z M238.5 300.5q19.5 -6.5 86.5 76.5q55 66 367 234q70 38 118.5 69.5t102 79t99 111.5t86.5 148q22 50 24 60t-6 19q-7 5 -17 5t-26.5 -14.5t-33.5 -39.5q-35 -51 -113.5 -108.5t-139.5 -89.5l-61 -32q-369 -197 -458 -401q-48 -111 -28.5 -117.5z" />
|
||||
<glyph unicode="" d="M111 408q0 -33 5 -63q9 -56 44 -119.5t105 -108.5q31 -21 64 -16t62 23.5t57 49.5t48 61.5t35 60.5q32 66 39 184.5t-13 157.5q79 -80 122 -164t26 -184q-5 -33 -20.5 -69.5t-37.5 -80.5q-10 -19 -14.5 -29t-12 -26t-9 -23.5t-3 -19t2.5 -15.5t11 -9.5t19.5 -5t30.5 2.5 t42 8q57 20 91 34t87.5 44.5t87 64t65.5 88.5t47 122q38 172 -44.5 341.5t-246.5 278.5q22 -44 43 -129q39 -159 -32 -154q-15 2 -33 9q-79 33 -120.5 100t-44 175.5t48.5 257.5q-13 -8 -34 -23.5t-72.5 -66.5t-88.5 -105.5t-60 -138t-8 -166.5q2 -12 8 -41.5t8 -43t6 -39.5 t3.5 -39.5t-1 -33.5t-6 -31.5t-13.5 -24t-21 -20.5t-31 -12q-38 -10 -67 13t-40.5 61.5t-15 81.5t10.5 75q-52 -46 -83.5 -101t-39 -107t-7.5 -85z" />
|
||||
<glyph unicode="" d="M-61 600l26 40q6 10 20 30t49 63.5t74.5 85.5t97 90t116.5 83.5t132.5 59t145.5 23.5t145.5 -23.5t132.5 -59t116.5 -83.5t97 -90t74.5 -85.5t49 -63.5t20 -30l26 -40l-26 -40q-6 -10 -20 -30t-49 -63.5t-74.5 -85.5t-97 -90t-116.5 -83.5t-132.5 -59t-145.5 -23.5 t-145.5 23.5t-132.5 59t-116.5 83.5t-97 90t-74.5 85.5t-49 63.5t-20 30zM120 600q7 -10 40.5 -58t56 -78.5t68 -77.5t87.5 -75t103 -49.5t125 -21.5t123.5 20t100.5 45.5t85.5 71.5t66.5 75.5t58 81.5t47 66q-1 1 -28.5 37.5t-42 55t-43.5 53t-57.5 63.5t-58.5 54 q49 -74 49 -163q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 85 46 158q-102 -87 -226 -258zM377 656q49 -124 154 -191l105 105q-37 24 -75 72t-57 84l-20 36z" />
|
||||
<glyph unicode="" d="M-61 600l26 40q6 10 20 30t49 63.5t74.5 85.5t97 90t116.5 83.5t132.5 59t145.5 23.5q61 0 121 -17l37 142h148l-314 -1200h-148l37 143q-82 21 -165 71.5t-140 102t-109.5 112t-72 88.5t-29.5 43zM120 600q210 -282 393 -336l37 141q-107 18 -178.5 101.5t-71.5 193.5 q0 85 46 158q-102 -87 -226 -258zM377 656q49 -124 154 -191l47 47l23 87q-30 28 -59 69t-44 68l-14 26zM780 161l38 145q22 15 44.5 34t46 44t40.5 44t41 50.5t33.5 43.5t33 44t24.5 34q-97 127 -140 175l39 146q67 -54 131.5 -125.5t87.5 -103.5t36 -52l26 -40l-26 -40 q-7 -12 -25.5 -38t-63.5 -79.5t-95.5 -102.5t-124 -100t-146.5 -79z" />
|
||||
<glyph unicode="" d="M-97.5 34q13.5 -34 50.5 -34h1294q37 0 50.5 35.5t-7.5 67.5l-642 1056q-20 34 -48 36.5t-48 -29.5l-642 -1066q-21 -32 -7.5 -66zM155 200l445 723l445 -723h-345v100h-200v-100h-345zM500 600l100 -300l100 300v100h-200v-100z" />
|
||||
<glyph unicode="" d="M100 262v41q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44t106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -91 100 -113v-64q0 -20 -13 -28.5t-32 0.5l-94 78h-222l-94 -78q-19 -9 -32 -0.5t-13 28.5 v64q0 22 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5z" />
|
||||
<glyph unicode="" d="M0 50q0 -20 14.5 -35t35.5 -15h1000q21 0 35.5 15t14.5 35v750h-1100v-750zM0 900h1100v150q0 21 -14.5 35.5t-35.5 14.5h-150v100h-100v-100h-500v100h-100v-100h-150q-21 0 -35.5 -14.5t-14.5 -35.5v-150zM100 100v100h100v-100h-100zM100 300v100h100v-100h-100z M100 500v100h100v-100h-100zM300 100v100h100v-100h-100zM300 300v100h100v-100h-100zM300 500v100h100v-100h-100zM500 100v100h100v-100h-100zM500 300v100h100v-100h-100zM500 500v100h100v-100h-100zM700 100v100h100v-100h-100zM700 300v100h100v-100h-100zM700 500 v100h100v-100h-100zM900 100v100h100v-100h-100zM900 300v100h100v-100h-100zM900 500v100h100v-100h-100z" />
|
||||
<glyph unicode="" d="M0 200v200h259l600 600h241v198l300 -295l-300 -300v197h-159l-600 -600h-341zM0 800h259l122 -122l141 142l-181 180h-341v-200zM678 381l141 142l122 -123h159v198l300 -295l-300 -300v197h-241z" />
|
||||
<glyph unicode="" d="M0 400v600q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5z" />
|
||||
<glyph unicode="" d="M100 600v200h300v-250q0 -113 6 -145q17 -92 102 -117q39 -11 92 -11q37 0 66.5 5.5t50 15.5t36 24t24 31.5t14 37.5t7 42t2.5 45t0 47v25v250h300v-200q0 -42 -3 -83t-15 -104t-31.5 -116t-58 -109.5t-89 -96.5t-129 -65.5t-174.5 -25.5t-174.5 25.5t-129 65.5t-89 96.5 t-58 109.5t-31.5 116t-15 104t-3 83zM100 900v300h300v-300h-300zM800 900v300h300v-300h-300z" />
|
||||
<glyph unicode="" d="M-30 411l227 -227l352 353l353 -353l226 227l-578 579z" />
|
||||
<glyph unicode="" d="M70 797l580 -579l578 579l-226 227l-353 -353l-352 353z" />
|
||||
<glyph unicode="" d="M-198 700l299 283l300 -283h-203v-400h385l215 -200h-800v600h-196zM402 1000l215 -200h381v-400h-198l299 -283l299 283h-200v600h-796z" />
|
||||
<glyph unicode="" d="M18 939q-5 24 10 42q14 19 39 19h896l38 162q5 17 18.5 27.5t30.5 10.5h94q20 0 35 -14.5t15 -35.5t-15 -35.5t-35 -14.5h-54l-201 -961q-2 -4 -6 -10.5t-19 -17.5t-33 -11h-31v-50q0 -20 -14.5 -35t-35.5 -15t-35.5 15t-14.5 35v50h-300v-50q0 -20 -14.5 -35t-35.5 -15 t-35.5 15t-14.5 35v50h-50q-21 0 -35.5 15t-14.5 35q0 21 14.5 35.5t35.5 14.5h535l48 200h-633q-32 0 -54.5 21t-27.5 43z" />
|
||||
<glyph unicode="" d="M0 0v800h1200v-800h-1200zM0 900v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500v-100h-1200z" />
|
||||
<glyph unicode="" d="M1 0l300 700h1200l-300 -700h-1200zM1 400v600h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500v-200h-1000z" />
|
||||
<glyph unicode="" d="M302 300h198v600h-198l298 300l298 -300h-198v-600h198l-298 -300z" />
|
||||
<glyph unicode="" d="M0 600l300 298v-198h600v198l300 -298l-300 -297v197h-600v-197z" />
|
||||
<glyph unicode="" d="M0 100v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM31 400l172 739q5 22 23 41.5t38 19.5h672q19 0 37.5 -22.5t23.5 -45.5l172 -732h-1138zM800 100h100v100h-100v-100z M1000 100h100v100h-100v-100z" />
|
||||
<glyph unicode="" d="M-101 600v50q0 24 25 49t50 38l25 13v-250l-11 5.5t-24 14t-30 21.5t-24 27.5t-11 31.5zM100 500v250v8v8v7t0.5 7t1.5 5.5t2 5t3 4t4.5 3.5t6 1.5t7.5 0.5h200l675 250v-850l-675 200h-38l47 -276q2 -12 -3 -17.5t-11 -6t-21 -0.5h-8h-83q-20 0 -34.5 14t-18.5 35 q-55 337 -55 351zM1100 200v850q0 21 14.5 35.5t35.5 14.5q20 0 35 -14.5t15 -35.5v-850q0 -20 -15 -35t-35 -15q-21 0 -35.5 15t-14.5 35z" />
|
||||
<glyph unicode="" d="M74 350q0 21 13.5 35.5t33.5 14.5h18l117 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3 32t29 13h94q20 0 29 -10.5t3 -29.5q-18 -36 -18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q20 0 33.5 -14.5t13.5 -35.5q0 -20 -13 -40t-31 -27q-8 -3 -23 -8.5 t-65 -20t-103 -25t-132.5 -19.5t-158.5 -9q-125 0 -245.5 20.5t-178.5 40.5l-58 20q-18 7 -31 27.5t-13 40.5zM497 110q12 -49 40 -79.5t63 -30.5t63 30.5t39 79.5q-48 -6 -102 -6t-103 6z" />
|
||||
<glyph unicode="" d="M21 445l233 -45l-78 -224l224 78l45 -233l155 179l155 -179l45 233l224 -78l-78 224l234 45l-180 155l180 156l-234 44l78 225l-224 -78l-45 233l-155 -180l-155 180l-45 -233l-224 78l78 -225l-233 -44l179 -156z" />
|
||||
<glyph unicode="" d="M0 200h200v600h-200v-600zM300 275q0 -75 100 -75h61q124 -100 139 -100h250q46 0 83 57l238 344q29 31 29 74v100q0 44 -30.5 84.5t-69.5 40.5h-328q28 118 28 125v150q0 44 -30.5 84.5t-69.5 40.5h-50q-27 0 -51 -20t-38 -48l-96 -198l-145 -196q-20 -26 -20 -63v-400z M400 300v375l150 213l100 212h50v-175l-50 -225h450v-125l-250 -375h-214l-136 100h-100z" />
|
||||
<glyph unicode="" d="M0 400v600h200v-600h-200zM300 525v400q0 75 100 75h61q124 100 139 100h250q46 0 83 -57l238 -344q29 -31 29 -74v-100q0 -44 -30.5 -84.5t-69.5 -40.5h-328q28 -118 28 -125v-150q0 -44 -30.5 -84.5t-69.5 -40.5h-50q-27 0 -51 20t-38 48l-96 198l-145 196 q-20 26 -20 63zM400 525l150 -212l100 -213h50v175l-50 225h450v125l-250 375h-214l-136 -100h-100v-375z" />
|
||||
<glyph unicode="" d="M8 200v600h200v-600h-200zM308 275v525q0 17 14 35.5t28 28.5l14 9l362 230q14 6 25 6q17 0 29 -12l109 -112q14 -14 14 -34q0 -18 -11 -32l-85 -121h302q85 0 138.5 -38t53.5 -110t-54.5 -111t-138.5 -39h-107l-130 -339q-7 -22 -20.5 -41.5t-28.5 -19.5h-341 q-7 0 -90 81t-83 94zM408 289l100 -89h293l131 339q6 21 19.5 41t28.5 20h203q16 0 25 15t9 36q0 20 -9 34.5t-25 14.5h-457h-6.5h-7.5t-6.5 0.5t-6 1t-5 1.5t-5.5 2.5t-4 4t-4 5.5q-5 12 -5 20q0 14 10 27l147 183l-86 83l-339 -236v-503z" />
|
||||
<glyph unicode="" d="M-101 651q0 72 54 110t139 38l302 -1l-85 121q-11 16 -11 32q0 21 14 34l109 113q13 12 29 12q11 0 25 -6l365 -230q7 -4 17 -10.5t26.5 -26t16.5 -36.5v-526q0 -13 -86 -93.5t-94 -80.5h-341q-16 0 -29.5 20t-19.5 41l-130 339h-107q-84 0 -139 39t-55 111zM-1 601h222 q15 0 28.5 -20.5t19.5 -40.5l131 -339h293l107 89v502l-343 237l-87 -83l145 -184q10 -11 10 -26q0 -11 -5 -20q-1 -3 -3.5 -5.5l-4 -4t-5 -2.5t-5.5 -1.5t-6.5 -1t-6.5 -0.5h-7.5h-6.5h-476v-100zM1000 201v600h200v-600h-200z" />
|
||||
<glyph unicode="" d="M97 719l230 -363q4 -6 10.5 -15.5t26 -25t36.5 -15.5h525q13 0 94 83t81 90v342q0 15 -20 28.5t-41 19.5l-339 131v106q0 84 -39 139t-111 55t-110 -53.5t-38 -138.5v-302l-121 84q-15 12 -33.5 11.5t-32.5 -13.5l-112 -110q-22 -22 -6 -53zM172 739l83 86l183 -146 q22 -18 47 -5q3 1 5.5 3.5l4 4t2.5 5t1.5 5.5t1 6.5t0.5 6.5v7.5v6.5v456q0 22 25 31t50 -0.5t25 -30.5v-202q0 -16 20 -29.5t41 -19.5l339 -130v-294l-89 -100h-503zM400 0v200h600v-200h-600z" />
|
||||
<glyph unicode="" d="M2 585q-16 -31 6 -53l112 -110q13 -13 32 -13.5t34 10.5l121 85q0 -51 -0.5 -153.5t-0.5 -148.5q0 -84 38.5 -138t110.5 -54t111 55t39 139v106l339 131q20 6 40.5 19.5t20.5 28.5v342q0 7 -81 90t-94 83h-525q-17 0 -35.5 -14t-28.5 -28l-10 -15zM77 565l236 339h503 l89 -100v-294l-340 -130q-20 -6 -40 -20t-20 -29v-202q0 -22 -25 -31t-50 0t-25 31v456v14.5t-1.5 11.5t-5 12t-9.5 7q-24 13 -46 -5l-184 -146zM305 1104v200h600v-200h-600z" />
|
||||
<glyph unicode="" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM298 701l2 -201h300l-2 -194l402 294l-402 298v-197h-300z" />
|
||||
<glyph unicode="" d="M0 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t231.5 47.5q122 0 232.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-218 -217.5t-300 -80t-299.5 80t-217.5 217.5t-80 299.5zM200 600l402 -294l-2 194h300l2 201h-300v197z" />
|
||||
<glyph unicode="" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 600h200v-300h200v300h200l-300 400z" />
|
||||
<glyph unicode="" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 600l300 -400l300 400h-200v300h-200v-300h-200z" />
|
||||
<glyph unicode="" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q121 0 231.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM254 780q-8 -33 5.5 -92.5t7.5 -87.5q0 -9 17 -44t16 -60 q12 0 23 -5.5t23 -15t20 -13.5q24 -12 108 -42q22 -8 53 -31.5t59.5 -38.5t57.5 -11q8 -18 -15 -55t-20 -57q42 -71 87 -80q0 -6 -3 -15.5t-3.5 -14.5t4.5 -17q104 -3 221 112q30 29 47 47t34.5 49t20.5 62q-14 9 -37 9.5t-36 7.5q-14 7 -49 15t-52 19q-9 0 -39.5 -0.5 t-46.5 -1.5t-39 -6.5t-39 -16.5q-50 -35 -66 -12q-4 2 -3.5 25.5t0.5 25.5q-6 13 -26.5 17t-24.5 7q2 22 -2 41t-16.5 28t-38.5 -20q-23 -25 -42 4q-19 28 -8 58q6 16 22 22q6 -1 26 -1.5t33.5 -4t19.5 -13.5q12 -19 32 -37.5t34 -27.5l14 -8q0 3 9.5 39.5t5.5 57.5 q-4 23 14.5 44.5t22.5 31.5q5 14 10 35t8.5 31t15.5 22.5t34 21.5q-6 18 10 37q8 0 23.5 -1.5t24.5 -1.5t20.5 4.5t20.5 15.5q-10 23 -30.5 42.5t-38 30t-49 26.5t-43.5 23q11 39 2 44q31 -13 58 -14.5t39 3.5l11 4q7 36 -16.5 53.5t-64.5 28.5t-56 23q-19 -3 -37 0 q-15 -12 -36.5 -21t-34.5 -12t-44 -8t-39 -6q-15 -3 -45.5 0.5t-45.5 -2.5q-21 -7 -52 -26.5t-34 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -90.5t-29.5 -79.5zM518 916q3 12 16 30t16 25q10 -10 18.5 -10t14 6t14.5 14.5t16 12.5q0 -24 17 -66.5t17 -43.5 q-9 2 -31 5t-36 5t-32 8t-30 14zM692 1003h1h-1z" />
|
||||
<glyph unicode="" d="M0 164.5q0 21.5 15 37.5l600 599q-33 101 6 201.5t135 154.5q164 92 306 -9l-259 -138l145 -232l251 126q13 -175 -151 -267q-123 -70 -253 -23l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1220" d="M0 196v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM0 596v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5zM0 996v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM600 596h500v100h-500v-100zM800 196h300v100h-300v-100zM900 996h200v100h-200v-100z" />
|
||||
<glyph unicode="" d="M100 1100v100h1000v-100h-1000zM150 1000h900l-350 -500v-300l-200 -200v500z" />
|
||||
<glyph unicode="" d="M0 200v200h1200v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM0 500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500z M500 1000h200v100h-200v-100z" />
|
||||
<glyph unicode="" d="M0 0v400l129 -129l200 200l142 -142l-200 -200l129 -129h-400zM0 800l129 129l200 -200l142 142l-200 200l129 129h-400v-400zM729 329l142 142l200 -200l129 129v-400h-400l129 129zM729 871l200 200l-129 129h400v-400l-129 129l-200 -200z" />
|
||||
<glyph unicode="" d="M0 596q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM182 596q0 -172 121.5 -293t292.5 -121t292.5 121t121.5 293q0 171 -121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM291 655 q0 23 15.5 38.5t38.5 15.5t39 -16t16 -38q0 -23 -16 -39t-39 -16q-22 0 -38 16t-16 39zM400 850q0 22 16 38.5t39 16.5q22 0 38 -16t16 -39t-16 -39t-38 -16q-23 0 -39 16.5t-16 38.5zM514 609q0 32 20.5 56.5t51.5 29.5l122 126l1 1q-9 14 -9 28q0 22 16 38.5t39 16.5 q22 0 38 -16t16 -39t-16 -39t-38 -16q-14 0 -29 10l-55 -145q17 -22 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5t-61.5 25.5t-25.5 61.5zM800 655q0 22 16 38t39 16t38.5 -15.5t15.5 -38.5t-16 -39t-38 -16q-23 0 -39 16t-16 39z" />
|
||||
<glyph unicode="" d="M-40 375q-13 -95 35 -173q35 -57 94 -89t129 -32q63 0 119 28q33 16 65 40.5t52.5 45.5t59.5 64q40 44 57 61l394 394q35 35 47 84t-3 96q-27 87 -117 104q-20 2 -29 2q-46 0 -78.5 -16.5t-67.5 -51.5l-389 -396l-7 -7l69 -67l377 373q20 22 39 38q23 23 50 23 q38 0 53 -36q16 -39 -20 -75l-547 -547q-52 -52 -125 -52q-55 0 -100 33t-54 96q-5 35 2.5 66t31.5 63t42 50t56 54q24 21 44 41l348 348q52 52 82.5 79.5t84 54t107.5 26.5q25 0 48 -4q95 -17 154 -94.5t51 -175.5q-7 -101 -98 -192l-252 -249l-253 -256l7 -7l69 -60 l517 511q67 67 95 157t11 183q-16 87 -67 154t-130 103q-69 33 -152 33q-107 0 -197 -55q-40 -24 -111 -95l-512 -512q-68 -68 -81 -163z" />
|
||||
<glyph unicode="" d="M80 784q0 131 98.5 229.5t230.5 98.5q143 0 241 -129q103 129 246 129q129 0 226 -98.5t97 -229.5q0 -46 -17.5 -91t-61 -99t-77 -89.5t-104.5 -105.5q-197 -191 -293 -322l-17 -23l-16 23q-43 58 -100 122.5t-92 99.5t-101 100q-71 70 -104.5 105.5t-77 89.5t-61 99 t-17.5 91zM250 784q0 -27 30.5 -70t61.5 -75.5t95 -94.5l22 -22q93 -90 190 -201q82 92 195 203l12 12q64 62 97.5 97t64.5 79t31 72q0 71 -48 119.5t-105 48.5q-74 0 -132 -83l-118 -171l-114 174q-51 80 -123 80q-60 0 -109.5 -49.5t-49.5 -118.5z" />
|
||||
<glyph unicode="" d="M57 353q0 -95 66 -159l141 -142q68 -66 159 -66q93 0 159 66l283 283q66 66 66 159t-66 159l-141 141q-8 9 -19 17l-105 -105l212 -212l-389 -389l-247 248l95 95l-18 18q-46 45 -75 101l-55 -55q-66 -66 -66 -159zM269 706q0 -93 66 -159l141 -141q7 -7 19 -17l105 105 l-212 212l389 389l247 -247l-95 -96l18 -17q47 -49 77 -100l29 29q35 35 62.5 88t27.5 96q0 93 -66 159l-141 141q-66 66 -159 66q-95 0 -159 -66l-283 -283q-66 -64 -66 -159z" />
|
||||
<glyph unicode="" d="M200 100v953q0 21 30 46t81 48t129 38t163 15t162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5zM300 300h600v700h-600v-700zM496 150q0 -43 30.5 -73.5t73.5 -30.5t73.5 30.5t30.5 73.5t-30.5 73.5t-73.5 30.5 t-73.5 -30.5t-30.5 -73.5z" />
|
||||
<glyph unicode="" d="M0 0l303 380l207 208l-210 212h300l267 279l-35 36q-15 14 -15 35t15 35q14 15 35 15t35 -15l283 -282q15 -15 15 -36t-15 -35q-14 -15 -35 -15t-35 15l-36 35l-279 -267v-300l-212 210l-208 -207z" />
|
||||
<glyph unicode="" d="M295 433h139q5 -77 48.5 -126.5t117.5 -64.5v335q-6 1 -15.5 4t-11.5 3q-46 14 -79 26.5t-72 36t-62.5 52t-40 72.5t-16.5 99q0 92 44 159.5t109 101t144 40.5v78h100v-79q38 -4 72.5 -13.5t75.5 -31.5t71 -53.5t51.5 -84t24.5 -118.5h-159q-8 72 -35 109.5t-101 50.5 v-307l64 -14q34 -7 64 -16.5t70 -31.5t67.5 -52t47.5 -80.5t20 -112.5q0 -139 -89 -224t-244 -96v-77h-100v78q-152 17 -237 104q-40 40 -52.5 93.5t-15.5 139.5zM466 889q0 -29 8 -51t16.5 -34t29.5 -22.5t31 -13.5t38 -10q7 -2 11 -3v274q-61 -8 -97.5 -37.5t-36.5 -102.5 zM700 237q170 18 170 151q0 64 -44 99.5t-126 60.5v-311z" />
|
||||
<glyph unicode="" d="M100 600v100h166q-24 49 -44 104q-10 26 -14.5 55.5t-3 72.5t25 90t68.5 87q97 88 263 88q129 0 230 -89t101 -208h-153q0 52 -34 89.5t-74 51.5t-76 14q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -28 16.5 -69.5t28 -62.5t41.5 -72h241v-100h-197q8 -50 -2.5 -115 t-31.5 -94q-41 -59 -99 -113q35 11 84 18t70 7q33 1 103 -16t103 -17q76 0 136 30l50 -147q-41 -25 -80.5 -36.5t-59 -13t-61.5 -1.5q-23 0 -128 33t-155 29q-39 -4 -82 -17t-66 -25l-24 -11l-55 145l16.5 11t15.5 10t13.5 9.5t14.5 12t14.5 14t17.5 18.5q48 55 54 126.5 t-30 142.5h-221z" />
|
||||
<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM602 900l298 300l298 -300h-198v-900h-200v900h-198z" />
|
||||
<glyph unicode="" d="M2 300h198v900h200v-900h198l-298 -300zM700 0v200h100v-100h200v-100h-300zM700 400v100h300v-200h-99v-100h-100v100h99v100h-200zM700 700v500h300v-500h-100v100h-100v-100h-100zM801 900h100v200h-100v-200z" />
|
||||
<glyph unicode="" d="M2 300h198v900h200v-900h198l-298 -300zM700 0v500h300v-500h-100v100h-100v-100h-100zM700 700v200h100v-100h200v-100h-300zM700 1100v100h300v-200h-99v-100h-100v100h99v100h-200zM801 200h100v200h-100v-200z" />
|
||||
<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM800 100v400h300v-500h-100v100h-200zM800 1100v100h200v-500h-100v400h-100zM901 200h100v200h-100v-200z" />
|
||||
<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM800 400v100h200v-500h-100v400h-100zM800 800v400h300v-500h-100v100h-200zM901 900h100v200h-100v-200z" />
|
||||
<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM700 100v200h500v-200h-500zM700 400v200h400v-200h-400zM700 700v200h300v-200h-300zM700 1000v200h200v-200h-200z" />
|
||||
<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM700 100v200h200v-200h-200zM700 400v200h300v-200h-300zM700 700v200h400v-200h-400zM700 1000v200h500v-200h-500z" />
|
||||
<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q162 0 281 -118.5t119 -281.5v-300q0 -165 -118.5 -282.5t-281.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500z" />
|
||||
<glyph unicode="" d="M0 400v300q0 163 119 281.5t281 118.5h300q165 0 282.5 -117.5t117.5 -282.5v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-163 0 -281.5 117.5t-118.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM400 300l333 250l-333 250v-500z" />
|
||||
<glyph unicode="" d="M0 400v300q0 163 117.5 281.5t282.5 118.5h300q163 0 281.5 -119t118.5 -281v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM300 700l250 -333l250 333h-500z" />
|
||||
<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q165 0 282.5 -117.5t117.5 -282.5v-300q0 -162 -118.5 -281t-281.5 -119h-300q-165 0 -282.5 118.5t-117.5 281.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM300 400h500l-250 333z" />
|
||||
<glyph unicode="" d="M0 400v300h300v200l400 -350l-400 -350v200h-300zM500 0v200h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-500v200h400q165 0 282.5 -117.5t117.5 -282.5v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-400z" />
|
||||
<glyph unicode="" d="M217 519q8 -19 31 -19h302q-155 -438 -160 -458q-5 -21 4 -32l9 -8h9q14 0 26 15q11 13 274.5 321.5t264.5 308.5q14 19 5 36q-8 17 -31 17l-301 -1q1 4 78 219.5t79 227.5q2 15 -5 27l-9 9h-9q-15 0 -25 -16q-4 -6 -98 -111.5t-228.5 -257t-209.5 -237.5q-16 -19 -6 -41 z" />
|
||||
<glyph unicode="" d="M0 400q0 -165 117.5 -282.5t282.5 -117.5h300q47 0 100 15v185h-500q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5h500v185q-14 4 -114 7.5t-193 5.5l-93 2q-165 0 -282.5 -117.5t-117.5 -282.5v-300zM600 400v300h300v200l400 -350l-400 -350v200h-300z " />
|
||||
<glyph unicode="" d="M0 400q0 -165 117.5 -282.5t282.5 -117.5h300q163 0 281.5 117.5t118.5 282.5v98l-78 73l-122 -123v-148q0 -41 -29.5 -70.5t-70.5 -29.5h-500q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5h156l118 122l-74 78h-100q-165 0 -282.5 -117.5t-117.5 -282.5 v-300zM496 709l353 342l-149 149h500v-500l-149 149l-342 -353z" />
|
||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM406 600 q0 80 57 137t137 57t137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137z" />
|
||||
<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 800l445 -500l450 500h-295v400h-300v-400h-300zM900 150h100v50h-100v-50z" />
|
||||
<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 700h300v-300h300v300h295l-445 500zM900 150h100v50h-100v-50z" />
|
||||
<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 705l305 -305l596 596l-154 155l-442 -442l-150 151zM900 150h100v50h-100v-50z" />
|
||||
<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 988l97 -98l212 213l-97 97zM200 400l697 1l3 699l-250 -239l-149 149l-212 -212l149 -149zM900 150h100v50h-100v-50z" />
|
||||
<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM200 612l212 -212l98 97l-213 212zM300 1200l239 -250l-149 -149l212 -212l149 148l249 -237l-1 697zM900 150h100v50h-100v-50z" />
|
||||
<glyph unicode="" d="M23 415l1177 784v-1079l-475 272l-310 -393v416h-392zM494 210l672 938l-672 -712v-226z" />
|
||||
<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-850q0 -21 -15 -35.5t-35 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 1000h100v200h-100v-200z" />
|
||||
<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-218l-276 -275l-120 120l-126 -127h-378v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM581 306l123 123l120 -120l353 352l123 -123l-475 -476zM600 1000h100v200h-100v-200z" />
|
||||
<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-269l-103 -103l-170 170l-298 -298h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 1000h100v200h-100v-200zM700 133l170 170l-170 170l127 127l170 -170l170 170l127 -128l-170 -169l170 -170 l-127 -127l-170 170l-170 -170z" />
|
||||
<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-300h-400v-200h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 300l300 -300l300 300h-200v300h-200v-300h-200zM600 1000v200h100v-200h-100z" />
|
||||
<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-402l-200 200l-298 -298h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 300h200v-300h200v300h200l-300 300zM600 1000v200h100v-200h-100z" />
|
||||
<glyph unicode="" d="M0 250q0 -21 14.5 -35.5t35.5 -14.5h1100q21 0 35.5 14.5t14.5 35.5v550h-1200v-550zM0 900h1200v150q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-150zM100 300v200h400v-200h-400z" />
|
||||
<glyph unicode="" d="M0 400l300 298v-198h400v-200h-400v-198zM100 800v200h100v-200h-100zM300 800v200h100v-200h-100zM500 800v200h400v198l300 -298l-300 -298v198h-400zM800 300v200h100v-200h-100zM1000 300h100v200h-100v-200z" />
|
||||
<glyph unicode="" d="M100 700v400l50 100l50 -100v-300h100v300l50 100l50 -100v-300h100v300l50 100l50 -100v-400l-100 -203v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447zM800 597q0 -29 10.5 -55.5t25 -43t29 -28.5t25.5 -18l10 -5v-397q0 -21 14.5 -35.5 t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v1106q0 31 -18 40.5t-44 -7.5l-276 -116q-25 -17 -43.5 -51.5t-18.5 -65.5v-359z" />
|
||||
<glyph unicode="" d="M100 0h400v56q-75 0 -87.5 6t-12.5 44v394h500v-394q0 -38 -12.5 -44t-87.5 -6v-56h400v56q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v888q0 22 25 34.5t50 13.5l25 2v56h-400v-56q75 0 87.5 -6t12.5 -44v-394h-500v394q0 38 12.5 44t87.5 6v56h-400v-56q4 0 11 -0.5 t24 -3t30 -7t24 -15t11 -24.5v-888q0 -22 -25 -34.5t-50 -13.5l-25 -2v-56z" />
|
||||
<glyph unicode="" d="M0 300q0 -41 29.5 -70.5t70.5 -29.5h300q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-300q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM100 100h400l200 200h105l295 98v-298h-425l-100 -100h-375zM100 300v200h300v-200h-300zM100 600v200h300v-200h-300z M100 1000h400l200 -200v-98l295 98h105v200h-425l-100 100h-375zM700 402v163l400 133v-163z" />
|
||||
<glyph unicode="" d="M16.5 974.5q0.5 -21.5 16 -90t46.5 -140t104 -177.5t175 -208q103 -103 207.5 -176t180 -103.5t137 -47t92.5 -16.5l31 1l163 162q17 18 13.5 41t-22.5 37l-192 136q-19 14 -45 12t-42 -19l-118 -118q-142 101 -268 227t-227 268l118 118q17 17 20 41.5t-11 44.5 l-139 194q-14 19 -36.5 22t-40.5 -14l-162 -162q-1 -11 -0.5 -32.5z" />
|
||||
<glyph unicode="" d="M0 50v212q0 20 10.5 45.5t24.5 39.5l365 303v50q0 4 1 10.5t12 22.5t30 28.5t60 23t97 10.5t97 -10t60 -23.5t30 -27.5t12 -24l1 -10v-50l365 -303q14 -14 24.5 -39.5t10.5 -45.5v-212q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-20 0 -35 14.5t-15 35.5zM0 712 q0 -21 14.5 -33.5t34.5 -8.5l202 33q20 4 34.5 21t14.5 38v146q141 24 300 24t300 -24v-146q0 -21 14.5 -38t34.5 -21l202 -33q20 -4 34.5 8.5t14.5 33.5v200q-6 8 -19 20.5t-63 45t-112 57t-171 45t-235 20.5q-92 0 -175 -10.5t-141.5 -27t-108.5 -36.5t-81.5 -40 t-53.5 -36.5t-31 -27.5l-9 -10v-200z" />
|
||||
<glyph unicode="" d="M100 0v100h1100v-100h-1100zM175 200h950l-125 150v250l100 100v400h-100v-200h-100v200h-200v-200h-100v200h-200v-200h-100v200h-100v-400l100 -100v-250z" />
|
||||
<glyph unicode="" d="M100 0h300v400q0 41 -29.5 70.5t-70.5 29.5h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-400zM500 0v1000q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-1000h-300zM900 0v700q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-700h-300z" />
|
||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v300h-200v100h200v100h-300v-300h200v-100h-200v-100zM600 300h200v100h100v300h-100v100h-200v-500 zM700 400v300h100v-300h-100z" />
|
||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h100v200h100v-200h100v500h-100v-200h-100v200h-100v-500zM600 300h200v100h100v300h-100v100h-200v-500 zM700 400v300h100v-300h-100z" />
|
||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v100h-200v300h200v100h-300v-500zM600 300h300v100h-200v300h200v100h-300v-500z" />
|
||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 550l300 -150v300zM600 400l300 150l-300 150v-300z" />
|
||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300v500h700v-500h-700zM300 400h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130v-300zM575 549 q0 -65 27 -107t68 -42h130v300h-130q-38 0 -66.5 -43t-28.5 -108z" />
|
||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v300h-200v100h200v100h-300v-300h200v-100h-200v-100zM601 300h100v100h-100v-100zM700 700h100 v-400h100v500h-200v-100z" />
|
||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v400h-200v100h-100v-500zM301 400v200h100v-200h-100zM601 300h100v100h-100v-100zM700 700h100 v-400h100v500h-200v-100z" />
|
||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 700v100h300v-300h-99v-100h-100v100h99v200h-200zM201 300v100h100v-100h-100zM601 300v100h100v-100h-100z M700 700v100h200v-500h-100v400h-100z" />
|
||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM400 500v200 l100 100h300v-100h-300v-200h300v-100h-300z" />
|
||||
<glyph unicode="" d="M0 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM182 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM400 400v400h300 l100 -100v-100h-100v100h-200v-100h200v-100h-200v-100h-100zM700 400v100h100v-100h-100z" />
|
||||
<glyph unicode="" d="M-14 494q0 -80 56.5 -137t135.5 -57h222v300h400v-300h128q120 0 205 86.5t85 207.5t-85 207t-205 86q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5zM300 200h200v300h200v-300h200 l-300 -300z" />
|
||||
<glyph unicode="" d="M-14 494q0 -80 56.5 -137t135.5 -57h8l414 414l403 -403q94 26 154.5 104.5t60.5 178.5q0 120 -85 206.5t-205 86.5q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5zM300 200l300 300 l300 -300h-200v-300h-200v300h-200z" />
|
||||
<glyph unicode="" d="M100 200h400v-155l-75 -45h350l-75 45v155h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170z" />
|
||||
<glyph unicode="" d="M121 700q0 -53 28.5 -97t75.5 -65q-4 -16 -4 -38q0 -74 52.5 -126.5t126.5 -52.5q56 0 100 30v-306l-75 -45h350l-75 45v306q46 -30 100 -30q74 0 126.5 52.5t52.5 126.5q0 24 -9 55q50 32 79.5 83t29.5 112q0 90 -61.5 155.5t-150.5 71.5q-26 89 -99.5 145.5 t-167.5 56.5q-116 0 -197.5 -81.5t-81.5 -197.5q0 -4 1 -11.5t1 -11.5q-14 2 -23 2q-74 0 -126.5 -52.5t-52.5 -126.5z" />
|
||||
</font>
|
||||
</defs></svg>
|
After Width: | Height: | Size: 62 KiB |
Binary file not shown.
Binary file not shown.
|
@ -1,117 +1,65 @@
|
|||
<?php
|
||||
|
||||
// Only enable cookie secure if we are supporting https.
|
||||
// Ideally, this would always be on and we would force https,
|
||||
// but the default installation configs are likely to be installed by
|
||||
// amature users on the setup that does not have https. Forcing
|
||||
// cookie_secure on non https would result in confusing login problems.
|
||||
if(!empty($_SERVER['HTTPS'])){
|
||||
ini_set('session.cookie_secure', '1');
|
||||
}
|
||||
ini_set('session.cookie_httponly', '1');
|
||||
$configRun = false;
|
||||
$extensions = get_loaded_extensions();
|
||||
$airtimeSetup = false;
|
||||
|
||||
error_reporting(E_ALL|E_STRICT);
|
||||
|
||||
function exception_error_handler($errno, $errstr, $errfile, $errline)
|
||||
{
|
||||
//Check if the statement that threw this error wanted its errors to be
|
||||
//suppressed. If so then return without with throwing exception.
|
||||
if (0 === error_reporting()) {
|
||||
return;
|
||||
function showConfigCheckPage() {
|
||||
global $configRun;
|
||||
if (!$configRun) {
|
||||
// This will run any necessary setup we need if
|
||||
// configuration hasn't been initialized
|
||||
checkConfiguration();
|
||||
}
|
||||
throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
|
||||
return false;
|
||||
|
||||
require_once(CONFIG_PATH . 'config-check.php');
|
||||
die();
|
||||
}
|
||||
|
||||
// Define path to application directory
|
||||
defined('APPLICATION_PATH')
|
||||
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
|
||||
function isApiCall() {
|
||||
$path = $_SERVER['PHP_SELF'];
|
||||
return strpos($path, "api") !== false;
|
||||
}
|
||||
|
||||
// Define application environment
|
||||
defined('APPLICATION_ENV')
|
||||
|| define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));
|
||||
// Define application path constants
|
||||
define('ROOT_PATH', dirname( __DIR__) . '/');
|
||||
define('LIB_PATH', ROOT_PATH . 'library/');
|
||||
define('BUILD_PATH', ROOT_PATH . 'build/');
|
||||
define('SETUP_PATH', BUILD_PATH . 'airtime-setup/');
|
||||
define('APPLICATION_PATH', ROOT_PATH . 'application/');
|
||||
define('CONFIG_PATH', APPLICATION_PATH . 'configs/');
|
||||
define('VENDOR_PATH', ROOT_PATH . '../vendor/');
|
||||
|
||||
defined('VERBOSE_STACK_TRACE')
|
||||
|| define('VERBOSE_STACK_TRACE', (getenv('VERBOSE_STACK_TRACE') ? getenv('VERBOSE_STACK_TRACE') : true));
|
||||
define("AIRTIME_CONFIG_STOR", "/etc/airtime/");
|
||||
|
||||
//Vendors
|
||||
set_include_path(realpath(dirname(__FILE__) . '/../../vendor'));
|
||||
define('AIRTIME_CONFIG', 'airtime.conf');
|
||||
|
||||
//Vendors (Composer)
|
||||
set_include_path(VENDOR_PATH . PATH_SEPARATOR . get_include_path());
|
||||
|
||||
// Ensure library/ is on include_path
|
||||
set_include_path(implode(PATH_SEPARATOR, array(
|
||||
get_include_path(),
|
||||
realpath(APPLICATION_PATH . '/../library')
|
||||
)));
|
||||
set_include_path(LIB_PATH . PATH_SEPARATOR . get_include_path());
|
||||
|
||||
set_include_path(APPLICATION_PATH . '/common' . PATH_SEPARATOR . get_include_path());
|
||||
|
||||
//Propel classes.
|
||||
set_include_path(APPLICATION_PATH . '/models' . PATH_SEPARATOR . get_include_path());
|
||||
|
||||
//Controllers
|
||||
set_include_path(APPLICATION_PATH . '/controllers' . PATH_SEPARATOR . get_include_path());
|
||||
|
||||
//Controller plugins.
|
||||
set_include_path(APPLICATION_PATH . '/controllers/plugins' . PATH_SEPARATOR . get_include_path());
|
||||
|
||||
//Services.
|
||||
set_include_path(APPLICATION_PATH . '/services/' . PATH_SEPARATOR . get_include_path());
|
||||
|
||||
//Zend framework
|
||||
if (file_exists('/usr/share/php/libzend-framework-php')) {
|
||||
set_include_path('/usr/share/php/libzend-framework-php' . PATH_SEPARATOR . get_include_path());
|
||||
if (!@include_once(VENDOR_PATH . 'propel/propel1/runtime/lib/Propel.php'))
|
||||
{
|
||||
die('Error: Propel not found. Did you install Airtime\'s third-party dependencies with composer? (Check the README.)');
|
||||
}
|
||||
|
||||
//cloud storage directory
|
||||
set_include_path(APPLICATION_PATH . '/cloud_storage' . PATH_SEPARATOR . get_include_path());
|
||||
require_once(CONFIG_PATH . 'conf.php');
|
||||
require_once(SETUP_PATH . 'load.php');
|
||||
|
||||
//Upgrade directory
|
||||
set_include_path(APPLICATION_PATH . '/upgrade/' . PATH_SEPARATOR . get_include_path());
|
||||
|
||||
//Common directory
|
||||
set_include_path(APPLICATION_PATH . '/common/' . PATH_SEPARATOR . get_include_path());
|
||||
|
||||
|
||||
/** Zend_Application */
|
||||
require_once 'Zend/Application.php';
|
||||
$application = new Zend_Application(
|
||||
APPLICATION_ENV,
|
||||
//$_SERVER["AIRTIME_APPINI"] // Old SaaS customization that's no longer needed -- Albert May 2, 2014
|
||||
APPLICATION_PATH . '/configs/application.ini'
|
||||
);
|
||||
|
||||
require_once (APPLICATION_PATH."/logging/Logging.php");
|
||||
Logging::setLogPath('/var/log/airtime/zendphp.log');
|
||||
Logging::setupParseErrorLogging();
|
||||
|
||||
// Create application, bootstrap, and run
|
||||
try {
|
||||
$sapi_type = php_sapi_name();
|
||||
if (substr($sapi_type, 0, 3) == 'cli') {
|
||||
set_include_path(APPLICATION_PATH . PATH_SEPARATOR . get_include_path());
|
||||
require_once("Bootstrap.php");
|
||||
} else {
|
||||
$application->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() . '<br>';
|
||||
echo "<pre>";
|
||||
echo $e->getTraceAsString();
|
||||
echo "</pre>";
|
||||
Logging::error($e->getTraceAsString());
|
||||
} else {
|
||||
Logging::error($e->getTrace());
|
||||
}
|
||||
throw $e;
|
||||
// This allows us to pass ?config as a parameter to any page
|
||||
// and get to the config checklist.
|
||||
if (array_key_exists('config', $_GET)) {
|
||||
showConfigCheckPage();
|
||||
}
|
||||
|
||||
// If a configuration file exists, forward to our boot script
|
||||
if (file_exists(AIRTIME_CONFIG_STOR . AIRTIME_CONFIG)) {
|
||||
require_once(APPLICATION_PATH . 'airtime-boot.php');
|
||||
}
|
||||
// Otherwise, we'll need to run our configuration setup
|
||||
else {
|
||||
$airtimeSetup = true;
|
||||
require_once(SETUP_PATH . 'setup-config.php');
|
||||
}
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
/**
|
||||
* 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);
|
||||
// If there are no errors, we can continue with
|
||||
// the installation process
|
||||
if (data.errors.length == 0) {
|
||||
// Call nextSlide from the submit button's context
|
||||
nextSlide.call($(e.target));
|
||||
}
|
||||
removeOverlay();
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the form feedback when we get POST results
|
||||
* @param data the POST request return data
|
||||
*/
|
||||
function showFeedback(data) {
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset form feedback when resubmitting
|
||||
*/
|
||||
function resetFeedback() {
|
||||
$(".form-control-feedback").hide();
|
||||
$(".has-success, .has-error, .has-feedback").removeClass("has-success has-error has-feedback");
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the return message from the POST request, then set a timeout to hide it again
|
||||
* @param msg the return message from the POST request
|
||||
*/
|
||||
function toggleMessage(msg) {
|
||||
/*
|
||||
* Since setting display:none; on this element causes odd behaviour
|
||||
* 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.
|
||||
*/
|
||||
var help = $(".help-message");
|
||||
help.html(msg).show();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the overlay and loading gif
|
||||
*/
|
||||
function addOverlay() {
|
||||
$("body").append("<div id='overlay'></div><img src='css/images/file_import_loader.gif' id='loadingImage'/>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the overlay and loading gif
|
||||
*/
|
||||
function removeOverlay() {
|
||||
var overlay = $("#overlay, #loadingImage");
|
||||
$("#loadingImage").fadeOut(250);
|
||||
$("#overlay").fadeOut(500, function() {
|
||||
overlay.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function formSlide(dir) {
|
||||
var delta = (dir == "next") ? "-=100%" : "+=100%",
|
||||
parent = $(this).parents("div.form-wrapper"),
|
||||
toForm = (dir == "next") ? parent.next() : parent.prev();
|
||||
|
||||
parent.find(".btn").attr("disabled", "disabled");
|
||||
toForm.find(".btn").removeAttr("disabled");
|
||||
toForm.find(":input :first").focus();
|
||||
|
||||
$(".form-slider").animate({left: delta}, 500);
|
||||
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() {
|
||||
formSlide.call($(this), "next");
|
||||
}
|
||||
|
||||
/**
|
||||
* Fade out the current setup step and fade in the previous one
|
||||
*/
|
||||
function prevSlide() {
|
||||
formSlide.call($(this), "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 call 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");
|
||||
});
|
||||
}
|
||||
|
||||
$(function() {
|
||||
// Stop the user from dragging the slider
|
||||
$(".form-slider").draggable('disable');
|
||||
$(".btn").attr("disabled", "disabled");
|
||||
$("form:first .btn").removeAttr("disabled");
|
||||
|
||||
window.onresize = function() {
|
||||
var headerHeight = $(".header").outerHeight(),
|
||||
viewport = $(".viewport"),
|
||||
viewportHeight = viewport.outerHeight();
|
||||
// If the viewport would go outside the page bounds,
|
||||
// shrink it to fit the window
|
||||
if (viewportHeight + headerHeight > window.innerHeight) {
|
||||
viewport.css("height", window.innerHeight - headerHeight);
|
||||
}
|
||||
// Otherwise, go back to what we have in the stylesheet
|
||||
else {
|
||||
viewport.css("height", "");
|
||||
}
|
||||
};
|
||||
});
|
|
@ -0,0 +1,196 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* User: sourcefabric
|
||||
* Date: 02/12/14
|
||||
* Class DatabaseSetup
|
||||
* Wrapper class for validating and installing the Airtime database during the installation process
|
||||
*/
|
||||
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",
|
||||
DB_PASS = "dbPass",
|
||||
DB_NAME = "dbName",
|
||||
DB_HOST = "dbHost";
|
||||
|
||||
// Form field values
|
||||
private $user, $pass, $name, $host;
|
||||
|
||||
// Array of key->value pairs for airtime.conf
|
||||
static $properties;
|
||||
|
||||
static $dbh = null;
|
||||
|
||||
public function __construct($settings) {
|
||||
$this->user = $settings[self::DB_USER];
|
||||
$this->pass = $settings[self::DB_PASS];
|
||||
$this->name = $settings[self::DB_NAME];
|
||||
$this->host = $settings[self::DB_HOST];
|
||||
|
||||
self::$properties = array(
|
||||
"host" => $this->host,
|
||||
"dbname" => $this->name,
|
||||
"dbuser" => $this->user,
|
||||
"dbpass" => $this->pass,
|
||||
);
|
||||
}
|
||||
|
||||
private function setNewDatabaseConnection($dbName) {
|
||||
self::$dbh = new PDO("pgsql:host=" . $this->host . ";dbname=" . $dbName . ";port=5432"
|
||||
. ";user=" . $this->user . ";password=" . $this->pass);
|
||||
$err = self::$dbh->errorInfo();
|
||||
if ($err[1] != null) {
|
||||
throw new PDOException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs various database checks against the given settings. If a database with the given name already exists,
|
||||
* we attempt to install the Airtime schema. If not, we first check if the user can create databases, then try
|
||||
* to create the database. If we encounter errors, the offending fields are returned in an array to the browser.
|
||||
* @return array associative array containing a display message and fields with errors
|
||||
* @throws AirtimeDatabaseException
|
||||
*/
|
||||
public function runSetup() {
|
||||
try {
|
||||
$this->setNewDatabaseConnection("postgres");
|
||||
if ($this->checkDatabaseExists()) {
|
||||
$this->installDatabaseTables();
|
||||
} else {
|
||||
$this->checkUserCanCreateDb();
|
||||
$this->createDatabase();
|
||||
$this->installDatabaseTables();
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
throw new AirtimeDatabaseException("Couldn't establish a connection to the database! "
|
||||
. "Please check your credentials and try again. "
|
||||
. "PDO Exception: " . $e->getMessage(),
|
||||
array(
|
||||
self::DB_NAME,
|
||||
self::DB_USER,
|
||||
self::DB_PASS,
|
||||
));
|
||||
}
|
||||
|
||||
$this->writeToTemp();
|
||||
|
||||
self::$dbh = null;
|
||||
return array(
|
||||
"message" => "Airtime database was created successfully!",
|
||||
"errors" => array(),
|
||||
);
|
||||
}
|
||||
|
||||
protected function writeToTemp() {
|
||||
parent::writeToTemp(self::SECTION, self::$properties);
|
||||
}
|
||||
|
||||
private function installDatabaseTables() {
|
||||
$this->checkDatabaseEncoding();
|
||||
$this->setNewDatabaseConnection($this->name);
|
||||
$this->checkSchemaExists();
|
||||
$this->createDatabaseTables();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
private function checkDatabaseExists() {
|
||||
$statement = self::$dbh->prepare("SELECT datname FROM pg_database WHERE datname = :dbname");
|
||||
$statement->execute(array(":dbname" => $this->name));
|
||||
$result = $statement->fetch();
|
||||
return isset($result[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the database schema has already been set up
|
||||
* @throws AirtimeDatabaseException
|
||||
*/
|
||||
private function checkSchemaExists() {
|
||||
$statement = self::$dbh->prepare("SELECT EXISTS (SELECT relname FROM pg_class WHERE relname='cc_files')");
|
||||
$statement->execute();
|
||||
$result = $statement->fetch();
|
||||
if (isset($result[0]) && $result[0] == "t") {
|
||||
throw new AirtimeDatabaseException("Airtime is already installed in this database!", array());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given user has access on the given host to create a new database
|
||||
* @throws AirtimeDatabaseException
|
||||
*/
|
||||
private function checkUserCanCreateDb() {
|
||||
$statement = self::$dbh->prepare("SELECT 1 FROM pg_roles WHERE rolname=:dbuser AND rolcreatedb='t'");
|
||||
$statement->execute(array(":dbuser" => $this->user));
|
||||
$result = $statement->fetch();
|
||||
if (!isset($result[0])) {
|
||||
throw new AirtimeDatabaseException("No database " . $this->name . " exists; user '" . $this->user
|
||||
. "' does not have permission to create databases on " . $this->host,
|
||||
array(
|
||||
self::DB_NAME,
|
||||
self::DB_USER,
|
||||
self::DB_PASS,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the Airtime database using the given credentials
|
||||
* @throws AirtimeDatabaseException
|
||||
*/
|
||||
private function createDatabase() {
|
||||
$statement = self::$dbh->prepare("CREATE DATABASE " . pg_escape_string($this->name)
|
||||
. " WITH ENCODING 'UTF8' TEMPLATE template0"
|
||||
. " OWNER " . pg_escape_string($this->user));
|
||||
if (!$statement->execute()) {
|
||||
throw new AirtimeDatabaseException("There was an error creating the database!",
|
||||
array(self::DB_NAME,));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the Airtime database schema using the given credentials
|
||||
* @throws AirtimeDatabaseException
|
||||
*/
|
||||
private function createDatabaseTables() {
|
||||
$sqlDir = dirname(dirname(__DIR__)) . "/build/sql/";
|
||||
$files = array("schema.sql", "sequences.sql", "views.sql", "triggers.sql", "defaultdata.sql");
|
||||
foreach ($files as $f) {
|
||||
try {
|
||||
/*
|
||||
* Unfortunately, we need to use exec here due to PDO's lack of support for importing
|
||||
* multi-line .sql files. PDO->exec() almost works, but any SQL errors stop the import,
|
||||
* so the necessary DROPs on non-existent tables make it unusable. Prepared statements
|
||||
* have multiple issues; they similarly die on any SQL errors, fail to read in multi-line
|
||||
* commands, and fail on any unescaped ? or $ characters.
|
||||
*/
|
||||
exec("export PGPASSWORD=" . $this->pass . " && psql -U " . $this->user . " --dbname "
|
||||
. $this->name . " -h " . $this->host . " -f $sqlDir$f 2>/dev/null", $out, $status);
|
||||
} catch (Exception $e) {
|
||||
throw new AirtimeDatabaseException("There was an error setting up the Airtime schema!",
|
||||
array(self::DB_NAME,));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the newly-created database's encoding was properly set to UTF8
|
||||
* @throws AirtimeDatabaseException
|
||||
*/
|
||||
private function checkDatabaseEncoding() {
|
||||
$statement = self::$dbh->prepare("SELECT pg_encoding_to_char(encoding) "
|
||||
. "FROM pg_database WHERE datname = :dbname");
|
||||
$statement->execute(array(":dbname" => $this->name));
|
||||
$encoding = $statement->fetch();
|
||||
if (!($encoding && $encoding[0] == "UTF8")) {
|
||||
throw new AirtimeDatabaseException("The database was installed with an incorrect encoding type!",
|
||||
array(self::DB_NAME,));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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() {
|
||||
// TODO Do we need to validate these settings?
|
||||
|
||||
if (count(self::$errors) <= 0) {
|
||||
$this->writeToTemp();
|
||||
}
|
||||
|
||||
return array(
|
||||
"message" => self::$message,
|
||||
"errors" => self::$errors
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
<?php
|
||||
|
||||
define("CONFIG_PATH", dirname(dirname( __DIR__)) . "/application/configs/");
|
||||
define("DEFAULT_STOR_DIR", "/srv/airtime/stor/");
|
||||
|
||||
require_once(dirname(dirname( __DIR__)) . "/../vendor/propel/propel1/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");
|
||||
|
||||
/**
|
||||
* Author: 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";
|
||||
const AIRTIME_CONF_PATH = "/etc/airtime/airtime.conf";
|
||||
|
||||
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 = DEFAULT_STOR_DIR;
|
||||
if (!file_exists(DEFAULT_STOR_DIR)) {
|
||||
mkdir(DEFAULT_STOR_DIR, 0755, true);
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Finalize and move airtime.conf.temp
|
||||
if (file_exists("/etc/airtime/")) {
|
||||
if (!$this->moveAirtimeConfig()) {
|
||||
$message = "Error moving airtime.conf or deleting /tmp/airtime.conf.temp!";
|
||||
$errors[] = "ERR";
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're upgrading from an old Airtime instance (pre-2.5.2) we rename their old
|
||||
* airtime.conf to airtime.conf.tmp during the setup process. Now that we're done,
|
||||
* we can rename it to airtime.conf.bak to avoid confusion.
|
||||
*/
|
||||
if (file_exists(self::AIRTIME_CONF_PATH . ".tmp")) {
|
||||
rename(self::AIRTIME_CONF_PATH . ".tmp", self::AIRTIME_CONF_PATH . ".bak");
|
||||
}
|
||||
} else {
|
||||
$message = "Failed to move airtime.conf; /etc/airtime doesn't exist!";
|
||||
$errors[] = "ERR";
|
||||
}
|
||||
|
||||
return array(
|
||||
"message" => self::$message,
|
||||
"errors" => self::$errors
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves /tmp/airtime.conf.temp to /etc/airtime.conf and then removes it to complete setup
|
||||
* @return boolean false if either of the copy or removal operations fail
|
||||
*/
|
||||
function moveAirtimeConfig() {
|
||||
return copy(AIRTIME_CONF_TEMP_PATH, self::AIRTIME_CONF_PATH)
|
||||
&& unlink(AIRTIME_CONF_TEMP_PATH);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
|
||||
require_once dirname(dirname( __DIR__)) . '/library/php-amqplib/amqp.inc';
|
||||
|
||||
/**
|
||||
* User: sourcefabric
|
||||
* Date: 02/12/14
|
||||
*
|
||||
* Class RabbitMQSetup
|
||||
*
|
||||
* Wrapper class for validating and setting up RabbitMQ during the installation process
|
||||
*/
|
||||
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",
|
||||
RMQ_PASS = "rmqPass",
|
||||
RMQ_PORT = "rmqPort",
|
||||
RMQ_HOST = "rmqHost",
|
||||
RMQ_VHOST = "rmqVHost";
|
||||
|
||||
// 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) {
|
||||
self::$user = $settings[self::RMQ_USER];
|
||||
self::$pass = $settings[self::RMQ_PASS];
|
||||
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() {
|
||||
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" => 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
<?php
|
||||
define("BUILD_PATH", dirname(dirname(__DIR__)) . "/build/");
|
||||
define("AIRTIME_CONF_TEMP_PATH", "/tmp/airtime.conf.temp");
|
||||
|
||||
/**
|
||||
* Class Setup
|
||||
*
|
||||
* @author sourcefabric
|
||||
*
|
||||
* Abstract superclass for the setup and installation process
|
||||
*/
|
||||
abstract class Setup {
|
||||
|
||||
abstract function __construct($settings);
|
||||
|
||||
abstract function runSetup();
|
||||
|
||||
/**
|
||||
* Write new property values to a given section in airtime.conf.temp
|
||||
*
|
||||
* @param string $section
|
||||
* the configuration section to write to
|
||||
* @param array $properties
|
||||
* the configuration properties and values to overwrite
|
||||
*/
|
||||
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 (substr(trim($line), 0, 1) == "#") {
|
||||
/* Workaround to strip comments from airtime.conf.
|
||||
* We need to do this because python's ConfigObj and PHP
|
||||
* have different (and equally strict) rules about comment
|
||||
* characters in configuration files.
|
||||
*/
|
||||
} else 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.
|
||||
*
|
||||
* @param integer $p_len
|
||||
* length of the output string
|
||||
* @param string $p_chars
|
||||
* characters to use in the output string
|
||||
* @return string the generated random string
|
||||
*/
|
||||
protected function generateRandomString($p_len = 20, $p_chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') {
|
||||
$string = '';
|
||||
for($i = 0; $i < $p_len; $i++) {
|
||||
$pos = mt_rand(0, strlen($p_chars) - 1);
|
||||
$string .= $p_chars{$pos};
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Class AirtimeDatabaseException
|
||||
*
|
||||
* @author sourcefabric
|
||||
*
|
||||
* Exception class for database setup errors
|
||||
*/
|
||||
class AirtimeDatabaseException extends Exception {
|
||||
|
||||
protected $message = "Unknown Airtime database exception";
|
||||
protected $errors = array();
|
||||
|
||||
public function __construct($message = null, $errors = array(), $code = 0, Exception $previous = null) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
$this->errors = $errors;
|
||||
}
|
||||
|
||||
public function getErrorFields() {
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Import Setup subclasses
|
||||
require_once ('database-setup.php');
|
||||
require_once ('rabbitmq-setup.php');
|
||||
require_once ('general-setup.php');
|
||||
require_once ('media-setup.php');
|
||||
|
||||
// If airtime.conf exists, we shouldn't be here
|
||||
if (!file_exists("/etc/airtime/airtime.conf")) {
|
||||
if (isset($_GET["obj"]) && $objType = $_GET["obj"]) {
|
||||
$obj = new $objType($_POST);
|
||||
if ($obj instanceof Setup) {
|
||||
try {
|
||||
$response = $obj->runSetup();
|
||||
} catch (AirtimeDatabaseException $e) {
|
||||
$response = array(
|
||||
"message" => $e->getMessage(),
|
||||
"errors" => $e->getErrorFields()
|
||||
);
|
||||
}
|
||||
|
||||
echo json_encode($response);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,10 @@ error_reporting(E_ALL | E_STRICT);
|
|||
|
||||
// Define path to application directory
|
||||
defined('APPLICATION_PATH')
|
||||
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../../application'));
|
||||
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../../application/'));
|
||||
|
||||
// Define path to configs directory
|
||||
define('CONFIG_PATH', APPLICATION_PATH . '/configs/');
|
||||
|
||||
// Define application environment
|
||||
defined('APPLICATION_ENV')
|
||||
|
|
|
@ -5,25 +5,20 @@ if (file_exists('/usr/share/php/libzend-framework-php')){
|
|||
set_include_path('/usr/share/php/libzend-framework-php' . PATH_SEPARATOR . get_include_path());
|
||||
}
|
||||
#require_once('Zend/Loader/Autoloader.php');
|
||||
|
||||
class AirtimeInstall
|
||||
{
|
||||
const CONF_DIR_BINARIES = "/usr/lib/airtime";
|
||||
const CONF_DIR_WWW = "/usr/share/airtime";
|
||||
const CONF_DIR_LOG = "/var/log/airtime";
|
||||
|
||||
public static $databaseTablesCreated = false;
|
||||
|
||||
public static function GetAirtimeSrcDir()
|
||||
{
|
||||
return __DIR__."/../../airtime_mvc";
|
||||
return __DIR__."/../../..";
|
||||
}
|
||||
|
||||
public static function GetUtilsSrcDir()
|
||||
{
|
||||
return __DIR__."/../../utils";
|
||||
return __DIR__."/../../../../utils";
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the user is running this PHP script with root
|
||||
* permissions. If not running with root permissions, causes the
|
||||
|
@ -37,7 +32,6 @@ class AirtimeInstall
|
|||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the version of Airtime currently installed.
|
||||
* If not installed, return null.
|
||||
|
@ -51,14 +45,12 @@ class AirtimeInstall
|
|||
} catch (PropelException $e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (file_exists('/etc/airtime/airtime.conf')) {
|
||||
$values = parse_ini_file('/etc/airtime/airtime.conf', true);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
|
||||
$sql = "SELECT valstr FROM cc_pref WHERE keystr = 'system_version' LIMIT 1";
|
||||
|
||||
try {
|
||||
|
@ -70,7 +62,6 @@ class AirtimeInstall
|
|||
//the database because it was busy, so it just removed the tables instead.
|
||||
return null;
|
||||
}
|
||||
|
||||
//if version is empty string, then version is older than version 1.8.0
|
||||
if ($version == '') {
|
||||
try {
|
||||
|
@ -82,10 +73,8 @@ class AirtimeInstall
|
|||
$version = null;
|
||||
}
|
||||
}
|
||||
|
||||
return $version;
|
||||
}
|
||||
|
||||
public static function DbTableExists($p_name)
|
||||
{
|
||||
$con = Propel::getConnection();
|
||||
|
@ -97,7 +86,6 @@ class AirtimeInstall
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function InstallQuery($sql, $verbose = true)
|
||||
{
|
||||
$con = Propel::getConnection();
|
||||
|
@ -112,7 +100,6 @@ class AirtimeInstall
|
|||
echo " ".$sql."\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
public static function DropSequence($p_sequenceName)
|
||||
{
|
||||
AirtimeInstall::InstallQuery("DROP SEQUENCE IF EXISTS $p_sequenceName", false);
|
||||
|
@ -142,20 +129,15 @@ class AirtimeInstall
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* TODO: This function should be moved to the media-monitor
|
||||
* install script. */
|
||||
public static function InstallStorageDirectory()
|
||||
{
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
echo "* Storage directory setup".PHP_EOL;
|
||||
|
||||
$ini = parse_ini_file(__DIR__."/airtime-install.ini");
|
||||
$stor_dir = $ini["storage_dir"];
|
||||
|
||||
$dirs = array($stor_dir, $stor_dir."/organize");
|
||||
|
||||
foreach ($dirs as $dir){
|
||||
if (!file_exists($dir)) {
|
||||
if (mkdir($dir, 02775, true)){
|
||||
|
@ -175,24 +157,19 @@ class AirtimeInstall
|
|||
echo "* Error: Directory already exists, but is not writable: $rp".PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
echo "* Giving Apache permission to access $rp".PHP_EOL;
|
||||
$success = chown($rp, $CC_CONFIG["webServerUser"]);
|
||||
$success = chgrp($rp, $CC_CONFIG["webServerUser"]);
|
||||
$success = chmod($rp, 0775);
|
||||
}
|
||||
}
|
||||
|
||||
public static function CreateDatabaseUser()
|
||||
{
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
|
||||
echo " * Creating Airtime database user".PHP_EOL;
|
||||
|
||||
$username = $CC_CONFIG['dsn']['username'];
|
||||
$password = $CC_CONFIG['dsn']['password'];
|
||||
$command = "echo \"CREATE USER $username ENCRYPTED PASSWORD '$password' LOGIN CREATEDB NOCREATEUSER;\" | su postgres -c psql 2>/dev/null";
|
||||
|
||||
@exec($command, $output, $results);
|
||||
if ($results == 0) {
|
||||
echo " * Database user '{$CC_CONFIG['dsn']['username']}' created.".PHP_EOL;
|
||||
|
@ -206,13 +183,9 @@ class AirtimeInstall
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function CreateDatabase()
|
||||
{
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
|
||||
|
||||
$database = $CC_CONFIG['dsn']['database'];
|
||||
$username = $CC_CONFIG['dsn']['username'];
|
||||
#$command = "echo \"CREATE DATABASE $database OWNER $username\" | su postgres -c psql 2>/dev/null";
|
||||
|
@ -222,37 +195,30 @@ class AirtimeInstall
|
|||
putenv("LC_ALL=en_CA.UTF-8"); //Squash warnings when running unit tests
|
||||
$command = "su postgres -c \"psql -l | cut -f2 -d' ' | grep -w '{$database}'\";";
|
||||
exec($command, $output, $rv);
|
||||
|
||||
if ($rv == 0) {
|
||||
//database already exists
|
||||
echo "Database already exists." . PHP_EOL;
|
||||
return true;
|
||||
}
|
||||
|
||||
$command = "sudo -i -u postgres psql postgres -c \"CREATE DATABASE ".$database." WITH ENCODING 'UTF8' TEMPLATE template0 OWNER ".$username."\"";
|
||||
|
||||
@exec($command, $output, $results);
|
||||
if ($results == 0) {
|
||||
echo " * Database '{$CC_CONFIG['dsn']['database']}' created.".PHP_EOL;
|
||||
echo " * Database $database created.".PHP_EOL;
|
||||
} else {
|
||||
if (count($output) > 0) {
|
||||
echo " * Could not create database '{$CC_CONFIG['dsn']['database']}': ".PHP_EOL;
|
||||
echo " * Could not create database $database: ".PHP_EOL;
|
||||
echo implode(PHP_EOL, $output);
|
||||
}
|
||||
else {
|
||||
echo " * Database '{$CC_CONFIG['dsn']['database']}' already exists.".PHP_EOL;
|
||||
echo " * Database $database already exists.".PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
$databaseExisted = ($results != 0);
|
||||
|
||||
return $databaseExisted;
|
||||
}
|
||||
|
||||
public static function InstallPostgresScriptingLanguage()
|
||||
{
|
||||
$con = Propel::getConnection();
|
||||
|
||||
// Install postgres scripting language
|
||||
$sql = 'SELECT COUNT(*) FROM pg_language WHERE lanname = \'plpgsql\'';
|
||||
$langIsInstalled = $con->query($sql)->fetchColumn(0);
|
||||
|
@ -264,25 +230,19 @@ class AirtimeInstall
|
|||
echo " * Postgres scripting language already installed".PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
public static function CreateDatabaseTables($p_dbuser, $p_dbpasswd, $p_dbname, $p_dbhost)
|
||||
{
|
||||
echo " * Creating database tables".PHP_EOL;
|
||||
|
||||
// Put Propel sql files in Database
|
||||
//$command = AirtimeInstall::CONF_DIR_WWW."/library/propel/generator/bin/propel-gen ".AirtimeInstall::CONF_DIR_WWW."/build/ insert-sql 2>/dev/null";
|
||||
|
||||
$dir = self::GetAirtimeSrcDir()."/build/sql/";
|
||||
$files = array("schema.sql", "sequences.sql", "views.sql", "triggers.sql", "defaultdata.sql");
|
||||
|
||||
foreach ($files as $f){
|
||||
$command = "export PGPASSWORD=$p_dbpasswd && psql --username $p_dbuser --dbname $p_dbname --host $p_dbhost --file $dir$f 2>/dev/null";
|
||||
$command = "export PGPASSWORD=$p_dbpasswd && psql --username $p_dbuser --dbname $p_dbname --host $p_dbhost --file $dir$f 2>&1";
|
||||
@exec($command, $output, $results);
|
||||
}
|
||||
|
||||
AirtimeInstall::$databaseTablesCreated = true;
|
||||
}
|
||||
|
||||
public static function BypassMigrations($dir, $version)
|
||||
{
|
||||
$appDir = AirtimeInstall::GetAirtimeSrcDir();
|
||||
|
@ -292,7 +252,6 @@ class AirtimeInstall
|
|||
"--no-interaction --add migrations:version $version";
|
||||
system($command);
|
||||
}
|
||||
|
||||
public static function MigrateTablesToVersion($dir, $version)
|
||||
{
|
||||
$appDir = AirtimeInstall::GetAirtimeSrcDir();
|
||||
|
@ -302,22 +261,18 @@ class AirtimeInstall
|
|||
"--no-interaction migrations:migrate $version";
|
||||
system($command);
|
||||
}
|
||||
|
||||
public static function SetAirtimeVersion($p_version)
|
||||
{
|
||||
$con = Propel::getConnection();
|
||||
$sql = "DELETE FROM cc_pref WHERE keystr = 'system_version'";
|
||||
$con->exec($sql);
|
||||
|
||||
Application_Model_Preference::SetAirtimeVersion($p_version);
|
||||
}
|
||||
|
||||
public static function SetUniqueId()
|
||||
{
|
||||
$uniqueId = md5(uniqid("", true));
|
||||
Application_Model_Preference::SetUniqueId($uniqueId);
|
||||
}
|
||||
|
||||
public static function GetAirtimeVersion()
|
||||
{
|
||||
$con = Propel::getConnection();
|
||||
|
@ -325,72 +280,23 @@ class AirtimeInstall
|
|||
$version = $con->query($sql)->fetchColumn(0);
|
||||
return $version;
|
||||
}
|
||||
|
||||
public static function DeleteFilesRecursive($p_path)
|
||||
{
|
||||
$command = "rm -rf \"$p_path\"";
|
||||
exec($command);
|
||||
}
|
||||
|
||||
public static function CreateSymlinksToUtils()
|
||||
{
|
||||
echo "* Creating /usr/bin symlinks".PHP_EOL;
|
||||
AirtimeInstall::RemoveSymlinks();
|
||||
|
||||
echo "* Installing airtime-import".PHP_EOL;
|
||||
$dir = AirtimeInstall::CONF_DIR_BINARIES."/utils/airtime-import/airtime-import";
|
||||
exec("ln -s $dir /usr/bin/airtime-import");
|
||||
|
||||
echo "* Installing airtime-check-system".PHP_EOL;
|
||||
$dir = AirtimeInstall::CONF_DIR_BINARIES."/utils/airtime-check-system";
|
||||
exec("ln -s $dir /usr/bin/airtime-check-system");
|
||||
|
||||
echo "* Installing airtime-user".PHP_EOL;
|
||||
$dir = AirtimeInstall::CONF_DIR_BINARIES."/utils/airtime-user";
|
||||
exec("ln -s $dir /usr/bin/airtime-user");
|
||||
|
||||
echo "* Installing airtime-log".PHP_EOL;
|
||||
$dir = AirtimeInstall::CONF_DIR_BINARIES."/utils/airtime-log";
|
||||
exec("ln -s $dir /usr/bin/airtime-log");
|
||||
}
|
||||
|
||||
public static function RemoveSymlinks()
|
||||
{
|
||||
exec("rm -f /usr/bin/airtime-import");
|
||||
exec("rm -f /usr/bin/airtime-check-system");
|
||||
exec("rm -f /usr/bin/airtime-user");
|
||||
exec("rm -f /usr/bin/airtime-log");
|
||||
exec("rm -f /usr/bin/airtime-clean-storage");
|
||||
}
|
||||
|
||||
public static function InstallPhpCode()
|
||||
{
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
echo "* Installing PHP code to ".AirtimeInstall::CONF_DIR_WWW.PHP_EOL;
|
||||
exec("mkdir -p ".AirtimeInstall::CONF_DIR_WWW);
|
||||
exec("cp -R ".AirtimeInstall::GetAirtimeSrcDir()."/* ".AirtimeInstall::CONF_DIR_WWW);
|
||||
|
||||
}
|
||||
|
||||
public static function UninstallPhpCode()
|
||||
{
|
||||
echo "* Removing PHP code from ".AirtimeInstall::CONF_DIR_WWW.PHP_EOL;
|
||||
exec('rm -rf "'.AirtimeInstall::CONF_DIR_WWW.'"');
|
||||
}
|
||||
|
||||
public static function InstallBinaries()
|
||||
{
|
||||
echo "* Installing binaries to ".AirtimeInstall::CONF_DIR_BINARIES.PHP_EOL;
|
||||
exec("mkdir -p ".AirtimeInstall::CONF_DIR_BINARIES);
|
||||
exec("cp -R ".AirtimeInstall::GetUtilsSrcDir()." ".AirtimeInstall::CONF_DIR_BINARIES);
|
||||
}
|
||||
|
||||
public static function UninstallBinaries()
|
||||
{
|
||||
echo "* Removing Airtime binaries from ".AirtimeInstall::CONF_DIR_BINARIES.PHP_EOL;
|
||||
exec('rm -rf "'.AirtimeInstall::CONF_DIR_BINARIES.'"');
|
||||
}
|
||||
|
||||
public static function DirCheck()
|
||||
{
|
||||
echo "Legend: \"+\" means the dir/file exists, \"-\" means that it does not.".PHP_EOL;
|
||||
|
@ -412,54 +318,44 @@ class AirtimeInstall
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function CreateZendPhpLogFile(){
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
|
||||
$path = AirtimeInstall::CONF_DIR_LOG;
|
||||
$file = $path.'/zendphp.log';
|
||||
if (!file_exists($path)){
|
||||
mkdir($path, 0755, true);
|
||||
}
|
||||
|
||||
touch($file);
|
||||
chmod($file, 0644);
|
||||
chown($file, $CC_CONFIG['webServerUser']);
|
||||
chgrp($file, $CC_CONFIG['webServerUser']);
|
||||
}
|
||||
|
||||
public static function RemoveLogDirectories(){
|
||||
$path = AirtimeInstall::CONF_DIR_LOG;
|
||||
echo "* Removing logs directory ".$path.PHP_EOL;
|
||||
|
||||
exec("rm -rf \"$path\"");
|
||||
}
|
||||
|
||||
public static function CreateCronFile(){
|
||||
echo "* Creating Cron File".PHP_EOL;
|
||||
// Create CRON task to run every day. Time of day is initialized to a random time.
|
||||
$hour = rand(0,23);
|
||||
$minute = rand(0,59);
|
||||
|
||||
$fp = fopen('/etc/cron.d/airtime-crons','w');
|
||||
fwrite($fp, "$minute $hour * * * root /usr/lib/airtime/utils/phone_home_stat\n");
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
public static function removeVirtualEnvDistributeFile(){
|
||||
echo "* Removing distribute-0.6.10.tar.gz".PHP_EOL;
|
||||
if(file_exists('/usr/share/python-virtualenv/distribute-0.6.10.tar.gz')){
|
||||
exec("rm -f /usr/share/python-virtualenv/distribute-0.6.10.tar.gz");
|
||||
}
|
||||
}
|
||||
|
||||
public static function printUsage($opts)
|
||||
{
|
||||
$msg = $opts->getUsageMessage();
|
||||
echo PHP_EOL."Usage: airtime-install [options]";
|
||||
echo substr($msg, strpos($msg, "\n")).PHP_EOL;
|
||||
}
|
||||
|
||||
public static function getOpts()
|
||||
{
|
||||
try {
|
||||
|
@ -482,7 +378,6 @@ class AirtimeInstall
|
|||
}
|
||||
return $opts;
|
||||
}
|
||||
|
||||
public static function checkPHPVersion()
|
||||
{
|
||||
if (PHP_VERSION_ID < 50300)
|
|
@ -62,7 +62,7 @@ class TestHelper
|
|||
// cc_subjs - Most of Airtime requires an admin account to work, which has id=1,
|
||||
// so don't clear it.
|
||||
// cc_music_dirs - Has foreign key constraints against cc_files, so we clear cc_files
|
||||
// first and ckear cc_music_dirs after
|
||||
// first and clear cc_music_dirs after
|
||||
$tablesToNotClear = array("cc_subjs", "cc_music_dirs");
|
||||
|
||||
$con->beginTransaction();
|
||||
|
@ -128,7 +128,7 @@ class TestHelper
|
|||
|
||||
public static function setupZendBootstrap()
|
||||
{
|
||||
$application = new Zend_Application(APPLICATION_ENV, APPLICATION_PATH .'/configs/application.ini');
|
||||
$application = new Zend_Application(APPLICATION_ENV, CONFIG_PATH . 'application.ini');
|
||||
$application->bootstrap();
|
||||
return $application;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ class PreferenceUnitTest extends PHPUnit_Framework_TestCase
|
|||
public function testSetHeadTitle()
|
||||
{
|
||||
$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);
|
||||
$this->assertEquals(Application_Model_Preference::GetHeadTitle(), $title);
|
||||
}
|
||||
|
|
|
@ -33,5 +33,5 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|||
cd $DIR
|
||||
|
||||
#Run the unit tests
|
||||
phpunit --log-junit test_results.xml
|
||||
phpunit --verbose --log-junit test_results.xml
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ class AirtimeMediaMonitorBootstrap():
|
|||
api_clients -- reference of api_clients to communicate with airtime-server
|
||||
"""
|
||||
def __init__(self):
|
||||
config = ConfigObj('/etc/airtime/media-monitor.cfg')
|
||||
config = ConfigObj('/etc/airtime/airtime.conf')
|
||||
self.api_client = apc.api_client_factory(config)
|
||||
|
||||
"""
|
||||
|
|
|
@ -18,7 +18,7 @@ if [ "$1" = "--enable" ]; then
|
|||
|
||||
echo "Changing ownership to user $1"
|
||||
chmod -R a+rw /var/log/airtime/pypo
|
||||
chmod a+r /etc/airtime/pypo.cfg
|
||||
chmod a+r /etc/airtime/airtime.conf
|
||||
chown -Rv $user:$user /var/tmp/airtime/pypo/
|
||||
chmod -v a+r /etc/airtime/api_client.cfg
|
||||
elif [ "$1" = "--disable" ]; then
|
||||
|
@ -26,7 +26,7 @@ elif [ "$1" = "--disable" ]; then
|
|||
user="pypo"
|
||||
|
||||
echo "Changing ownership to user $1"
|
||||
chmod 644 /etc/airtime/pypo.cfg
|
||||
chmod 644 /etc/airtime/airtime.conf
|
||||
chown -Rv $user:$user /var/tmp/airtime/pypo/
|
||||
chmod -v a+r /etc/airtime/api_client.cfg
|
||||
|
||||
|
|
|
@ -0,0 +1,625 @@
|
|||
#!/bin/bash -e
|
||||
#-e Causes bash script to exit if any of the installers
|
||||
#return with a non-zero return value.
|
||||
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "Please run as root user."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
|
||||
AIRTIMEROOT=${SCRIPT_DIR}
|
||||
|
||||
showhelp () {
|
||||
echo "Usage: sudo bash install [options]
|
||||
-h, --help, -?
|
||||
Display usage information
|
||||
-V, --version
|
||||
Display version information
|
||||
-v, --verbose
|
||||
More output
|
||||
-q, --quiet, --silent
|
||||
No output except errors
|
||||
-f, --force
|
||||
Turn off interactive prompts
|
||||
--distribution
|
||||
Linux distribution the installation is being run on
|
||||
--release
|
||||
Distribution release
|
||||
-d, --ignore-dependencies
|
||||
Don't install binary dependencies
|
||||
-w, --web-user=WEB_USER
|
||||
Set the apache web user. Defaults to www-data. Only change
|
||||
this setting if you've changed the default apache web user
|
||||
-r, --web-root=WEB_ROOT
|
||||
Set the web root for Airtime files
|
||||
This will copy the Airtime application files, but you will need
|
||||
to give your web user access to the given directory if it is
|
||||
not accessible
|
||||
-I, --in-place
|
||||
Set the current Airtime directory as the web root
|
||||
Note that you will need to give your web user permission to
|
||||
access this directory if it is not accessible
|
||||
-p, --postgres
|
||||
Create a default postgres user named 'airtime' with password
|
||||
'airtime'
|
||||
-a, --apache
|
||||
Install apache and deploy a basic configuration for Airtime
|
||||
-i, --icecast
|
||||
Install Icecast 2 and deploy a basic configuration for Airtime"
|
||||
exit 0
|
||||
}
|
||||
|
||||
showversion () {
|
||||
version=$(php -r 'require_once(__DIR__ . "/airtime_mvc/application/configs/constants.php"); echo AIRTIME_CODE_VERSION;')
|
||||
echo "Airtime Version ${version}"
|
||||
exit 0
|
||||
}
|
||||
|
||||
web_user="www-data"
|
||||
web_root=""
|
||||
in_place="f"
|
||||
postgres="f"
|
||||
apache="f"
|
||||
icecast="f"
|
||||
ignore_dependencies="f"
|
||||
# Interactive
|
||||
_i=1
|
||||
# Verbose
|
||||
_v=0
|
||||
# Quiet
|
||||
_q=0
|
||||
upgrade="f"
|
||||
dist=""
|
||||
code=""
|
||||
|
||||
function verbose() {
|
||||
if [[ ${_v} -eq 1 ]]; then
|
||||
echo -e "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
function loud() {
|
||||
if [[ ${_q} -eq 0 ]]; then
|
||||
echo -e "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
# Evaluate commands silently if quiet
|
||||
function loudCmd() {
|
||||
if [[ ${_q} -eq 0 ]]; then
|
||||
eval $@
|
||||
else
|
||||
eval $@ > /dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
function checkCommandExists() {
|
||||
set +e
|
||||
command=$@
|
||||
eval hash ${command} 2>/dev/null
|
||||
commandFound=$?
|
||||
if [[ ! ${commandFound} -eq 0 ]]; then
|
||||
echo -e "Error: ${command} not found. Please ensure you have the corresponding dependency installed."
|
||||
exit
|
||||
fi
|
||||
set -e
|
||||
}
|
||||
|
||||
while :; do
|
||||
case "$1" in
|
||||
--help)
|
||||
showhelp
|
||||
;;
|
||||
--version)
|
||||
showversion
|
||||
;;
|
||||
--verbose)
|
||||
_v=1
|
||||
;;
|
||||
--quiet|--silent)
|
||||
_q=1
|
||||
;;
|
||||
--force)
|
||||
_i=0
|
||||
;;
|
||||
--distribution)
|
||||
if [ "$2" ]; then
|
||||
dist=$2
|
||||
shift 2
|
||||
continue
|
||||
else
|
||||
echo 'ERROR: Must specify a non-empty "--distribution DISTRIBUTION" argument.' >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
--distribution=?*)
|
||||
dist=${1#*=} # Delete everything up to "=" and assign the remainder.
|
||||
;;
|
||||
--distribution=)
|
||||
echo 'ERROR: Must specify a non-empty "--distribution DISTRIBUTION" argument.' >&2
|
||||
exit 1
|
||||
;;
|
||||
--release)
|
||||
if [ "$2" ]; then
|
||||
code=$2
|
||||
shift 2
|
||||
continue
|
||||
else
|
||||
echo 'ERROR: Must specify a non-empty "--release RELEASE" argument.' >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
--release=?*)
|
||||
code=${1#*=} # Delete everything up to "=" and assign the remainder.
|
||||
;;
|
||||
--release=)
|
||||
echo 'ERROR: Must specify a non-empty "--release RELEASE" argument.' >&2
|
||||
exit 1
|
||||
;;
|
||||
--ignore-dependencies)
|
||||
ignore_dependencies="t"
|
||||
;;
|
||||
--apache)
|
||||
apache="t"
|
||||
;;
|
||||
--icecast)
|
||||
icecast="t"
|
||||
;;
|
||||
--postgres)
|
||||
postgres="t"
|
||||
;;
|
||||
--in-place)
|
||||
in_place="t"
|
||||
;;
|
||||
--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
|
||||
;;
|
||||
--web-root)
|
||||
if [ "$2" ]; then
|
||||
web_root=$(readlink -f $2)
|
||||
shift 2
|
||||
continue
|
||||
else
|
||||
echo 'ERROR: Must specify a non-empty "--web-root WEB_ROOT" argument.' >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
--web-root=?*)
|
||||
web_root=${1#*=} # Delete everything up to "=" and assign the remainder.
|
||||
;;
|
||||
--web-root=)
|
||||
echo 'ERROR: Must specify a non-empty "--web-root=WEB_ROOT" argument.' >&2
|
||||
exit 1
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
-?*)
|
||||
for ((i = 1; i < ${#1}; i++)); do
|
||||
case "${1:$i:1}" in
|
||||
h|\?)
|
||||
showhelp
|
||||
;;
|
||||
V)
|
||||
showversion
|
||||
;;
|
||||
v)
|
||||
_v=1
|
||||
;;
|
||||
q)
|
||||
_q=1
|
||||
;;
|
||||
f)
|
||||
_i=0
|
||||
;;
|
||||
d)
|
||||
ignore_dependencies="t"
|
||||
;;
|
||||
a)
|
||||
apache="t"
|
||||
;;
|
||||
i)
|
||||
icecast="t"
|
||||
;;
|
||||
p)
|
||||
postgres="t"
|
||||
;;
|
||||
I)
|
||||
in_place="t"
|
||||
;;
|
||||
w)
|
||||
if [ "$2" ]; then
|
||||
web_user=$2
|
||||
continue
|
||||
else
|
||||
echo 'ERROR: Must specify a non-empty "-w WEB_USER" argument.' >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
r)
|
||||
if [ "$2" ]; then
|
||||
web_root=$(readlink -f $2)
|
||||
continue
|
||||
else
|
||||
echo 'ERROR: Must specify a non-empty "-d WEB_ROOT" argument.' >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "$0: error - unrecognized option '${1:$i:1}'" >&2;
|
||||
echo "Try 'install --help' for more information."
|
||||
exit 1
|
||||
esac
|
||||
done
|
||||
;;
|
||||
*)
|
||||
break
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [ -z web_root -a ! -d web_root ]; then
|
||||
echo "$web_root doesn't exist!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "\n _____ .________________________.___ _____ ___________ "
|
||||
echo " / _ \ | \______ \__ ___/| | / \ \_ _____/ "
|
||||
echo " / /_\ \| || _/ | | | |/ \ / \ | __)_ "
|
||||
echo "/ | \ || | \ | | | / Y \| \ "
|
||||
echo "\____|__ /___||____|_ / |____| |___\____|__ /_______ / "
|
||||
echo -e " \/ \/ \/ \/ \n"
|
||||
|
||||
if [ "$ignore_dependencies" = "f" ]; then
|
||||
set +e
|
||||
if [ -z "${dist}" ]; then
|
||||
loudCmd "apt-get -y --force-yes install lsb-release"
|
||||
dist=`lsb_release -ds | awk '{print tolower($1);}'`
|
||||
code=`lsb_release -cs`
|
||||
fi
|
||||
|
||||
loud "\n-----------------------------------------------------"
|
||||
loud " * Installing External Dependencies * "
|
||||
loud "-----------------------------------------------------"
|
||||
|
||||
verbose "\n * Reading requirements-${dist,,}-${code,,}.apt..."
|
||||
loudCmd "apt-get update"
|
||||
if [ -f ${SCRIPT_DIR}/installer/lib/requirements-${dist,,}-${code,,}.apt ]; then
|
||||
loudCmd "DEBIAN_FRONTEND=noninteractive apt-get -y -m --force-yes install $(grep -vE '^\s*#' ${SCRIPT_DIR}/installer/lib/requirements-${dist,,}-${code,,}.apt | tr '\n' ' ')"
|
||||
else
|
||||
loudCmd "DEBIAN_FRONTEND=noninteractive apt-get -y -m --force-yes install $(grep -vE '^\s*#' ${SCRIPT_DIR}/installer/lib/requirements-ubuntu-trusty.apt | tr '\n' ' ')"
|
||||
fi
|
||||
set -e
|
||||
else
|
||||
checkCommandExists "apache2"
|
||||
checkCommandExists "rabbitmqctl"
|
||||
checkCommandExists "psql"
|
||||
fi
|
||||
|
||||
if [ -f /etc/airtime/airtime.conf ]; then
|
||||
OLD_CONF=$(grep "[media-monitor]" /etc/airtime/airtime.conf)
|
||||
|
||||
if [ -n "${OLD_CONF}" ]; then
|
||||
upgrade="t"
|
||||
|
||||
set +e
|
||||
verbose "Stopping airtime services..."
|
||||
loudCmd "service airtime-playout stop-with-monit"
|
||||
loudCmd "service airtime-media-monitor stop-with-monit"
|
||||
loudCmd "service airtime-liquidsoap stop-with-monit"
|
||||
verbose "...Done"
|
||||
|
||||
echo "Looks like you have an old version of Airtime. Your current /etc/airtime/airtime.conf \
|
||||
will be moved to /etc/airtime/airtime.conf.tmp"
|
||||
# If we don't remove the existing python files in /usr/lib and the
|
||||
# /etc/init.d startup scripts, services won't work properly
|
||||
if [ -d /usr/lib/airtime/ ]; then
|
||||
rm -rf /usr/lib/airtime/
|
||||
fi
|
||||
|
||||
rm /etc/init.d/airtime-*
|
||||
|
||||
if [ "$apache" = "t" ]; then
|
||||
# If the user selects an "in-place" install or passes in a web root,
|
||||
# we need to replace the old apache airtime.conf
|
||||
rm /etc/apache2/sites-available/airtime.conf
|
||||
fi
|
||||
|
||||
if [ -d /usr/share/airtime -a web_root = /usr/share/airtime ]; then
|
||||
rm -rf /usr/share/airtime
|
||||
fi
|
||||
|
||||
mv /etc/airtime/airtime.conf /etc/airtime/airtime.conf.tmp
|
||||
set -e
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$apache" = "f" -a ${_i} -eq 1 ]; then
|
||||
echo -e "Install default Airtime apache configuration? (Y/n): \c"
|
||||
read IN
|
||||
if [ "$IN" = "y" -o "$IN" = "Y" ]; then
|
||||
apache="t"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$in_place" = "t" ]; then
|
||||
verbose "\n * Setting current Airtime directory as web root..."
|
||||
web_root=${AIRTIMEROOT}/airtime_mvc/public
|
||||
elif [ -n "$web_root" ]; then
|
||||
verbose "\n * Creating Apache web root directory..."
|
||||
cp -R ${AIRTIMEROOT}/airtime_mvc/* ${web_root}
|
||||
web_root=${web_root}/public/
|
||||
else
|
||||
verbose "\n * Creating default Apache web root directory /usr/share/airtime/..."
|
||||
web_root="/usr/share/airtime"
|
||||
mkdir -p ${web_root}
|
||||
cp -R ${AIRTIMEROOT}/airtime_mvc/* ${web_root}
|
||||
web_root=${web_root}/public/
|
||||
fi
|
||||
verbose "...Done"
|
||||
|
||||
if [ "$apache" = "t" ]; then
|
||||
loud "\n-----------------------------------------------------"
|
||||
loud " * Configuring Apache * "
|
||||
loud "-----------------------------------------------------"
|
||||
|
||||
set +e
|
||||
apache2 -v | grep "2\.4" > /dev/null
|
||||
apacheversion=$?
|
||||
set -e
|
||||
|
||||
if [ "$apacheversion" != "1" ]; then
|
||||
airtimeconfigfile="airtime.conf"
|
||||
oldconfigfile="airtime-vhost.conf"
|
||||
else
|
||||
airtimeconfigfile="airtime"
|
||||
oldconfigfile="airtime-vhost"
|
||||
fi
|
||||
|
||||
# If we're upgrading (installing over an existing Airtime install) and we've been told to
|
||||
# install apache, we should overwrite any existing configuration. If we don't do this, doing
|
||||
# an in-place installation over an old Airtime install (which installs to /usr/share by default)
|
||||
# will fail
|
||||
if [ "$upgrade" = "t" -o ! -f /etc/apache2/sites-available/${airtimeconfigfile} ]; then
|
||||
verbose "\n * Creating Apache config for Airtime..."
|
||||
|
||||
if [ "$apacheversion" != "1" ]; then
|
||||
sed -e "s@WEB_ROOT@${web_root}@g" ${SCRIPT_DIR}/installer/apache/airtime-vhost-2.4 > /etc/apache2/sites-available/${airtimeconfigfile}
|
||||
else
|
||||
sed -e "s@WEB_ROOT@${web_root}@g" ${SCRIPT_DIR}/installer/apache/airtime-vhost > /etc/apache2/sites-available/${airtimeconfigfile}
|
||||
fi
|
||||
loudCmd "a2dissite 000-default"
|
||||
# If Airtime was previously installed with apt, the vhost file name is different,
|
||||
# so we need to specifically disable it.
|
||||
if [ -f "/etc/apache2/sites-available/${oldconfigfile}" ]; then
|
||||
loudCmd "a2dissite airtime-vhost"
|
||||
fi
|
||||
loudCmd "a2ensite airtime"
|
||||
else
|
||||
verbose "\nApache config for Airtime already exists, skipping"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$icecast" = "f" -a ${_i} -eq 1 ]; then
|
||||
echo -e "Install default Airtime Icecast configuration? (Y/n): \c"
|
||||
read IN
|
||||
if [ "$IN" = "y" -o "$IN" = "Y" ]; then
|
||||
icecast="t"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$icecast" = "t" ]; then
|
||||
loud "\n-----------------------------------------------------"
|
||||
loud " * Configuring Icecast * "
|
||||
loud "-----------------------------------------------------"
|
||||
|
||||
verbose "\n * Enabling Icecast 2..."
|
||||
sed -i 's/ENABLE=false/ENABLE=true/g' /etc/default/icecast2
|
||||
set +e
|
||||
loudCmd "service icecast2 start"
|
||||
set -e
|
||||
verbose "...Done"
|
||||
fi
|
||||
|
||||
loud "\n-----------------------------------------------------"
|
||||
loud " * Installing Airtime Services * "
|
||||
loud "-----------------------------------------------------"
|
||||
|
||||
verbose "\n * Installing necessary python services..."
|
||||
loudCmd "pip install setuptools"
|
||||
verbose "...Done"
|
||||
|
||||
verbose "\n * Creating /run/airtime..."
|
||||
mkdir -p /run/airtime
|
||||
chmod 755 /run/airtime
|
||||
chown -R ${web_user}:${web_user} /run/airtime
|
||||
verbose "...Done"
|
||||
|
||||
verbose "\n * Installing log writer..."
|
||||
loudCmd "python ${AIRTIMEROOT}/python_apps/std_err_override/setup.py install --install-scripts=/usr/bin"
|
||||
verbose "...Done"
|
||||
|
||||
verbose "\n * Installing API client..."
|
||||
loudCmd "python ${AIRTIMEROOT}/python_apps/api_clients/setup.py install --install-scripts=/usr/bin"
|
||||
verbose "...Done"
|
||||
|
||||
verbose "\n * Installing media-monitor..."
|
||||
loudCmd "python ${AIRTIMEROOT}/python_apps/media-monitor/setup.py install --install-scripts=/usr/bin"
|
||||
verbose "...Done"
|
||||
|
||||
verbose "\n * Installing pypo..."
|
||||
loudCmd "python ${AIRTIMEROOT}/python_apps/pypo/setup.py install --install-scripts=/usr/bin"
|
||||
verbose "...Done"
|
||||
|
||||
for i in /etc/init/airtime*.template; do
|
||||
chmod 644 $i
|
||||
sed -i "s/WEB_USER/${web_user}/g" $i
|
||||
mv $i ${i%.template}
|
||||
done
|
||||
|
||||
set +e
|
||||
loudCmd "initctl reload-configuration"
|
||||
loudCmd "systemctl daemon-reload" #systemd hipsters
|
||||
loudCmd "update-rc.d airtime-playout defaults" # Start at bootup, on Debian
|
||||
loudCmd "update-rc.d airtime-media-monitor defaults" # Start at bootup, on Debian
|
||||
loudCmd "update-rc.d airtime-liquidsoap defaults" # Start at bootup, on Debian
|
||||
set -e
|
||||
|
||||
if [ ! -d /var/log/airtime ]; then
|
||||
loud "\n-----------------------------------------------------"
|
||||
loud " * Installing Log Files * "
|
||||
loud "-----------------------------------------------------"
|
||||
|
||||
verbose "\n * Creating /var/tmp/airtime..."
|
||||
mkdir -p /var/tmp/airtime/show-recorder/
|
||||
|
||||
verbose "\n * Copying logrotate files..."
|
||||
cp ${AIRTIMEROOT}/airtime_mvc/build/airtime-php.logrotate /etc/logrotate.d/airtime-php
|
||||
cp ${AIRTIMEROOT}/python_apps/pypo/pypo/liquidsoap_scripts/airtime-liquidsoap.logrotate /etc/logrotate.d/airtime-liquidsoap
|
||||
fi
|
||||
|
||||
verbose "\n * Setting permissions on /var/log/airtime..."
|
||||
chmod -R a+x /var/log/airtime
|
||||
chown -R ${web_user}:${web_user} /var/log/airtime/
|
||||
|
||||
verbose "\n * Setting permissions on /var/tmp/airtime..."
|
||||
chmod -R a+x /var/tmp/airtime
|
||||
chown -R ${web_user}:${web_user} /var/tmp/airtime/
|
||||
|
||||
# PHP Config File for Apache
|
||||
if [ ! -f "/etc/php5/apache2/conf.d/airtime.ini" ]; then
|
||||
verbose "\n * Creating Airtime PHP config for Apache..."
|
||||
cp ${SCRIPT_DIR}/installer/php/airtime.ini /etc/php5/apache2/conf.d/airtime.ini
|
||||
else
|
||||
verbose "\nAirtime PHP config for Apache already exists, skipping"
|
||||
fi
|
||||
|
||||
# Enable Apache modules
|
||||
loudCmd "a2enmod rewrite php5"
|
||||
|
||||
loud "\n-----------------------------------------------------"
|
||||
loud " * Configuring PostgreSQL * "
|
||||
loud "-----------------------------------------------------"
|
||||
|
||||
# Ensure postgres is running - It isn't after you install the postgres package on Ubuntu 15.04
|
||||
loudCmd "service postgresql start"
|
||||
|
||||
setupAirtimePostgresUser() {
|
||||
# here-doc to execute this block as postgres user
|
||||
su postgres <<'EOF'
|
||||
set +e
|
||||
psql -d postgres -tAc "CREATE USER airtime WITH ENCRYPTED PASSWORD 'airtime'; ALTER USER airtime CREATEDB;"
|
||||
set -e
|
||||
# don't indent this!
|
||||
EOF
|
||||
}
|
||||
|
||||
if [ "$postgres" = "t" ]; then
|
||||
setupAirtimePostgresUser
|
||||
elif [ ${_i} -eq 1 ]; then
|
||||
echo -e "Create default airtime postgres user? (Y/n): \c"
|
||||
read IN
|
||||
if [ "$IN" = "y" -o "$IN" = "Y" ]; then
|
||||
setupAirtimePostgresUser
|
||||
fi
|
||||
fi
|
||||
|
||||
loud "\n-----------------------------------------------------"
|
||||
loud " * Configuring RabbitMQ * "
|
||||
loud "-----------------------------------------------------"
|
||||
|
||||
RABBITMQ_VHOST=/airtime
|
||||
RABBITMQ_USER=airtime
|
||||
RABBITMQ_PASSWORD=airtime
|
||||
EXCHANGES="airtime-pypo|pypo-fetch|airtime-media-monitor|media-monitor"
|
||||
|
||||
# Ignore errors in this check to avoid dying when vhost isn't found
|
||||
set +e
|
||||
rabbitmqctl list_vhosts | grep -w ${RABBITMQ_VHOST} > /dev/null
|
||||
RESULT="$?"
|
||||
set -e
|
||||
|
||||
# Only run these if the vhost doesn't exist
|
||||
if [ "$RESULT" != "0" ]; then
|
||||
verbose "\n * Creating RabbitMQ user ${RABBITMQ_USER}..."
|
||||
|
||||
rabbitmqctl add_vhost ${RABBITMQ_VHOST}
|
||||
rabbitmqctl add_user ${RABBITMQ_USER} ${RABBITMQ_PASSWORD}
|
||||
else
|
||||
verbose "\nRabbitMQ user already exists, skipping creation"
|
||||
fi
|
||||
|
||||
verbose "\n * Setting RabbitMQ user permissions..."
|
||||
loudCmd "rabbitmqctl set_permissions -p ${RABBITMQ_VHOST} ${RABBITMQ_USER} \"$EXCHANGES\" \"$EXCHANGES\" \"$EXCHANGES\""
|
||||
|
||||
if [ ! -d "/etc/airtime" ]; then
|
||||
loud "\n-----------------------------------------------------"
|
||||
loud " * Installing Airtime * "
|
||||
loud "-----------------------------------------------------"
|
||||
|
||||
verbose "\n * Creating /etc/airtime/ directory..."
|
||||
mkdir /etc/airtime
|
||||
fi
|
||||
chown -R ${web_user}:${web_user} /etc/airtime
|
||||
|
||||
if [ ! -d "/srv/airtime" ]; then
|
||||
mkdir -p /srv/airtime
|
||||
fi
|
||||
chown -R ${web_user}:${web_user} /srv/airtime
|
||||
|
||||
|
||||
# We only generate the locales for Airtime if you're allowing us
|
||||
# to install our dependencies, so that we won't automatically do this
|
||||
# when this install script runs from our DEB package.
|
||||
if [ "$ignore_dependencies" = "f" ]; then
|
||||
loud "\n-----------------------------------------------------"
|
||||
loud " * Installing Locales * "
|
||||
loud "-----------------------------------------------------"
|
||||
|
||||
set +e
|
||||
verbose "\n * Generating locales"
|
||||
for i in `ls ${web_root}/../locale | grep ".._.."`; do
|
||||
if [ "$dist" = "debian" ]; then
|
||||
grep -qi "^$i" /etc/locale.gen
|
||||
if [ $? -ne 0 ]; then
|
||||
verbose "$i.UTF-8 UTF-8" >> /etc/locale.gen
|
||||
fi
|
||||
else
|
||||
loudCmd "locale-gen \"$i.utf8\""
|
||||
fi
|
||||
done
|
||||
set -e
|
||||
|
||||
if [ "$dist" = "debian" ]; then
|
||||
loudCmd "/usr/sbin/locale-gen"
|
||||
fi
|
||||
fi
|
||||
|
||||
verbose "\n * Reloading apache..."
|
||||
loudCmd "service apache2 reload 2>/dev/null"
|
||||
|
||||
IP=$(ifconfig eth0 2>/dev/null|awk '/inet addr:/ {print $2}'|sed 's/addr://')
|
||||
|
||||
echo -e "\n-----------------------------------------------------"
|
||||
echo " * Basic Setup DONE! * "
|
||||
echo " "
|
||||
echo " To get started with Airtime, visit ${IP} "
|
||||
echo " or, if you've set up your own web configuration, "
|
||||
echo " the Airtime webroot on your webserver "
|
||||
echo "-----------------------------------------------------"
|
|
@ -1,14 +0,0 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Auto install script for airtime on Debian
|
||||
|
||||
|
||||
#Current dir
|
||||
# Absolute path to this script, e.g. /home/user/bin/foo.sh
|
||||
SCRIPT=`readlink -f $0`
|
||||
# Absolute path this script is in, thus /home/user/bin
|
||||
SCRIPTPATH=`dirname $SCRIPT`
|
||||
|
||||
cd $SCRIPTPATH/../ubuntu
|
||||
./airtime-full-install
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
# This file is contributed by Eugene MechanisM
|
||||
# Link to the post:
|
||||
# http://forum.sourcefabric.org/discussion/13563/first-step-to-run-airtime-via-nginx-based-on-airtime-2.0-beta-files
|
||||
|
||||
upstream php5-fpm {
|
||||
ip_hash;
|
||||
server unix:/var/run/airtime.php.sock;
|
||||
}
|
||||
server {
|
||||
listen 80;
|
||||
server_name airtime; #change to your host
|
||||
include mime.types;
|
||||
root /usr/share/airtime/public;
|
||||
access_log /var/log/airtime.access.log;
|
||||
error_log /var/log/airtime.error.log;
|
||||
index index.php;
|
||||
include fastcgi_params;
|
||||
client_max_body_size 1G;
|
||||
|
||||
location ~* ^.+\.(css|js|jpg|jpeg|gif|png|ico|gz|svg|svgz|ttf|otf|woff|eot|mp4|ogg|ogv|webm)$ {
|
||||
expires max;
|
||||
access_log off;
|
||||
add_header Pragma public;
|
||||
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
|
||||
}
|
||||
location / {
|
||||
if (-e $request_filename){
|
||||
set $rule_0 1;
|
||||
}
|
||||
if ($request_filename ~ "-l"){
|
||||
set $rule_0 1;
|
||||
}
|
||||
if (-d $request_filename){
|
||||
set $rule_0 1;
|
||||
}
|
||||
rewrite ^/.*$ /index.php last;
|
||||
try_files $uri $uri/ index.php;
|
||||
|
||||
}
|
||||
location ~ \.php$ {
|
||||
include fastcgi_params;
|
||||
fastcgi_pass php5-fpm;
|
||||
}
|
||||
location = /favicon.ico {
|
||||
log_not_found off;
|
||||
access_log off;
|
||||
}
|
||||
location = /robots.txt {
|
||||
allow all;
|
||||
log_not_found off;
|
||||
access_log off;
|
||||
}
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
}
|
|
@ -1,250 +0,0 @@
|
|||
# NGINX changes are contributed by Eugene MechanisM
|
||||
# Link to the post:
|
||||
# http://forum.sourcefabric.org/discussion/13563/first-step-to-run-airtime-via-nginx-based-on-airtime-2.0-beta-files
|
||||
|
||||
; Start a new pool named 'airtime'.
|
||||
; the variable $pool can we used in any directive and will be replaced by the
|
||||
; pool name ('airtime' here)
|
||||
[airtime]
|
||||
|
||||
; Per pool prefix
|
||||
; It only applies on the following directives:
|
||||
; - 'slowlog'
|
||||
; - 'listen' (unixsocket)
|
||||
; - 'chroot'
|
||||
; - 'chdir'
|
||||
; - 'php_values'
|
||||
; - 'php_admin_values'
|
||||
; When not set, the global prefix (or /usr) applies instead.
|
||||
; Note: This directive can also be relative to the global prefix.
|
||||
; Default Value: none
|
||||
;prefix = /path/to/pools/$pool
|
||||
|
||||
; The address on which to accept FastCGI requests.
|
||||
; Valid syntaxes are:
|
||||
; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific address on
|
||||
; a specific port;
|
||||
; 'port' - to listen on a TCP socket to all addresses on a
|
||||
; specific port;
|
||||
; '/path/to/unix/socket' - to listen on a unix socket.
|
||||
; Note: This value is mandatory.
|
||||
listen = '/var/run/airtime.php.sock'
|
||||
|
||||
; Set listen(2) backlog. A value of '-1' means unlimited.
|
||||
; Default Value: 128 (-1 on FreeBSD and OpenBSD)
|
||||
;listen.backlog = -1
|
||||
|
||||
; List of ipv4 addresses of FastCGI clients which are allowed to connect.
|
||||
; Equivalent to the FCGI_WEB_SERVER_ADDRS environment variable in the original
|
||||
; PHP FCGI (5.2.2+). Makes sense only with a tcp listening socket. Each address
|
||||
; must be separated by a comma. If this value is left blank, connections will be
|
||||
; accepted from any ip address.
|
||||
; Default Value: any
|
||||
;listen.allowed_clients = 127.0.0.1
|
||||
|
||||
; Set permissions for unix socket, if one is used. In Linux, read/write
|
||||
; permissions must be set in order to allow connections from a web server. Many
|
||||
; BSD-derived systems allow connections regardless of permissions.
|
||||
; Default Values: user and group are set as the running user
|
||||
; mode is set to 0666
|
||||
;listen.owner = www-data
|
||||
;listen.group = www-data
|
||||
;listen.mode = 0666
|
||||
|
||||
; Unix user/group of processes
|
||||
; Note: The user is mandatory. If the group is not set, the default user's group
|
||||
; will be used.
|
||||
user = www-data
|
||||
group = www-data
|
||||
|
||||
; Choose how the process manager will control the number of child processes.
|
||||
; Possible Values:
|
||||
; static - a fixed number (pm.max_children) of child processes;
|
||||
; dynamic - the number of child processes are set dynamically based on the
|
||||
; following directives:
|
||||
; pm.max_children - the maximum number of children that can
|
||||
; be alive at the same time.
|
||||
; pm.start_servers - the number of children created on startup.
|
||||
; pm.min_spare_servers - the minimum number of children in 'idle'
|
||||
; state (waiting to process). If the number
|
||||
; of 'idle' processes is less than this
|
||||
; number then some children will be created.
|
||||
; pm.max_spare_servers - the maximum number of children in 'idle'
|
||||
; state (waiting to process). If the number
|
||||
; of 'idle' processes is greater than this
|
||||
; number then some children will be killed.
|
||||
; Note: This value is mandatory.
|
||||
pm = dynamic
|
||||
|
||||
; The number of child processes to be created when pm is set to 'static' and the
|
||||
; maximum number of child processes to be created when pm is set to 'dynamic'.
|
||||
; This value sets the limit on the number of simultaneous requests that will be
|
||||
; served. Equivalent to the ApacheMaxClients directive with mpm_prefork.
|
||||
; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP
|
||||
; CGI.
|
||||
; Note: Used when pm is set to either 'static' or 'dynamic'
|
||||
; Note: This value is mandatory.
|
||||
pm.max_children = 10
|
||||
|
||||
; The number of child processes created on startup.
|
||||
; Note: Used only when pm is set to 'dynamic'
|
||||
; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2
|
||||
pm.start_servers = 4
|
||||
|
||||
; The desired minimum number of idle server processes.
|
||||
; Note: Used only when pm is set to 'dynamic'
|
||||
; Note: Mandatory when pm is set to 'dynamic'
|
||||
pm.min_spare_servers = 2
|
||||
|
||||
; The desired maximum number of idle server processes.
|
||||
; Note: Used only when pm is set to 'dynamic'
|
||||
; Note: Mandatory when pm is set to 'dynamic'
|
||||
pm.max_spare_servers = 6
|
||||
|
||||
; The number of requests each child process should execute before respawning.
|
||||
; This can be useful to work around memory leaks in 3rd party libraries. For
|
||||
; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS.
|
||||
; Default Value: 0
|
||||
;pm.max_requests = 500
|
||||
|
||||
; The URI to view the FPM status page. If this value is not set, no URI will be
|
||||
; recognized as a status page. By default, the status page shows the following
|
||||
; information:
|
||||
; accepted conn - the number of request accepted by the pool;
|
||||
; pool - the name of the pool;
|
||||
; process manager - static or dynamic;
|
||||
; idle processes - the number of idle processes;
|
||||
; active processes - the number of active processes;
|
||||
; total processes - the number of idle + active processes.
|
||||
; max children reached - number of times, the process limit has been reached,
|
||||
; when pm tries to start more children (works only for
|
||||
; pm 'dynamic')
|
||||
; The values of 'idle processes', 'active processes' and 'total processes' are
|
||||
; updated each second. The value of 'accepted conn' is updated in real time.
|
||||
; Example output:
|
||||
; accepted conn: 12073
|
||||
; pool: www
|
||||
; process manager: static
|
||||
; idle processes: 35
|
||||
; active processes: 65
|
||||
; total processes: 100
|
||||
; max children reached: 1
|
||||
; By default the status page output is formatted as text/plain. Passing either
|
||||
; 'html' or 'json' as a query string will return the corresponding output
|
||||
; syntax. Example:
|
||||
; http://www.foo.bar/status
|
||||
; http://www.foo.bar/status?json
|
||||
; http://www.foo.bar/status?html
|
||||
; Note: The value must start with a leading slash (/). The value can be
|
||||
; anything, but it may not be a good idea to use the .php extension or it
|
||||
; may conflict with a real PHP file.
|
||||
; Default Value: not set
|
||||
;pm.status_path = /status
|
||||
|
||||
; The ping URI to call the monitoring page of FPM. If this value is not set, no
|
||||
; URI will be recognized as a ping page. This could be used to test from outside
|
||||
; that FPM is alive and responding, or to
|
||||
; - create a graph of FPM availability (rrd or such);
|
||||
; - remove a server from a group if it is not responding (load balancing);
|
||||
; - trigger alerts for the operating team (24/7).
|
||||
; Note: The value must start with a leading slash (/). The value can be
|
||||
; anything, but it may not be a good idea to use the .php extension or it
|
||||
; may conflict with a real PHP file.
|
||||
; Default Value: not set
|
||||
;ping.path = /ping
|
||||
|
||||
; This directive may be used to customize the response of a ping request. The
|
||||
; response is formatted as text/plain with a 200 response code.
|
||||
; Default Value: pong
|
||||
;ping.response = pong
|
||||
|
||||
; The timeout for serving a single request after which the worker process will
|
||||
; be killed. This option should be used when the 'max_execution_time' ini option
|
||||
; does not stop script execution for some reason. A value of '0' means 'off'.
|
||||
; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)
|
||||
; Default Value: 0
|
||||
;request_terminate_timeout = 0
|
||||
|
||||
; The timeout for serving a single request after which a PHP backtrace will be
|
||||
; dumped to the 'slowlog' file. A value of '0s' means 'off'.
|
||||
; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)
|
||||
; Default Value: 0
|
||||
;request_slowlog_timeout = 0
|
||||
|
||||
; The log file for slow requests
|
||||
; Default Value: not set
|
||||
; Note: slowlog is mandatory if request_slowlog_timeout is set
|
||||
;slowlog = log/$pool.log.slow
|
||||
|
||||
; Set open file descriptor rlimit.
|
||||
; Default Value: system defined value
|
||||
;rlimit_files = 1024
|
||||
|
||||
; Set max core size rlimit.
|
||||
; Possible Values: 'unlimited' or an integer greater or equal to 0
|
||||
; Default Value: system defined value
|
||||
;rlimit_core = 0
|
||||
|
||||
; Chroot to this directory at the start. This value must be defined as an
|
||||
; absolute path. When this value is not set, chroot is not used.
|
||||
; Note: you can prefix with '$prefix' to chroot to the pool prefix or one
|
||||
; of its subdirectories. If the pool prefix is not set, the global prefix
|
||||
; will be used instead.
|
||||
; Note: chrooting is a great security feature and should be used whenever
|
||||
; possible. However, all PHP paths will be relative to the chroot
|
||||
; (error_log, sessions.save_path, ...).
|
||||
; Default Value: not set
|
||||
;chroot =
|
||||
|
||||
; Chdir to this directory at the start.
|
||||
; Note: relative path can be used.
|
||||
; Default Value: current directory or / when chroot
|
||||
chdir = /
|
||||
|
||||
; Redirect worker stdout and stderr into main error log. If not set, stdout and
|
||||
; stderr will be redirected to /dev/null according to FastCGI specs.
|
||||
; Note: on highloaded environement, this can cause some delay in the page
|
||||
; process time (several ms).
|
||||
; Default Value: no
|
||||
;catch_workers_output = yes
|
||||
|
||||
; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
|
||||
; the current environment.
|
||||
; Default Value: clean env
|
||||
;env[HOSTNAME] = $HOSTNAME
|
||||
;env[PATH] = /usr/local/bin:/usr/bin:/bin
|
||||
;env[TMP] = /tmp
|
||||
;env[TMPDIR] = /tmp
|
||||
;env[TEMP] = /tmp
|
||||
|
||||
; Additional php.ini defines, specific to this pool of workers. These settings
|
||||
; overwrite the values previously defined in the php.ini. The directives are the
|
||||
; same as the PHP SAPI:
|
||||
; php_value/php_flag - you can set classic ini defines which can
|
||||
; be overwritten from PHP call 'ini_set'.
|
||||
; php_admin_value/php_admin_flag - these directives won't be overwritten by
|
||||
; PHP call 'ini_set'
|
||||
; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no.
|
||||
|
||||
; Defining 'extension' will load the corresponding shared extension from
|
||||
; extension_dir. Defining 'disable_functions' or 'disable_classes' will not
|
||||
; overwrite previously defined php.ini values, but will append the new value
|
||||
; instead.
|
||||
|
||||
; Note: path INI options can be relative and will be expanded with the prefix
|
||||
; (pool, global or /usr)
|
||||
|
||||
; Default Value: nothing is defined by default except the values in php.ini and
|
||||
; specified at startup with the -d argument
|
||||
;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com
|
||||
;php_flag[display_errors] = off
|
||||
;php_admin_value[error_log] = /var/log/fpm-php.www.log
|
||||
;php_admin_flag[log_errors] = on
|
||||
;php_admin_value[memory_limit] = 32M
|
||||
|
||||
php_admin_value[error_log] = /var/log/airtime.php-fpm.error.log
|
||||
php_admin_value[post_max_size] = 500M
|
||||
php_admin_value[upload_max_filesize] = 500M
|
||||
php_admin_value[request_order] = GPC
|
||||
php_admin_value[session.gc_probability] = 0
|
||||
php_admin_value[upload_tmp_dir] = /tmp
|
|
@ -1,216 +0,0 @@
|
|||
#!/bin/bash -e
|
||||
#
|
||||
# Auto install script for airtime on Ubuntu
|
||||
#
|
||||
# NGINX changes are contributed by Eugene MechanisM
|
||||
# Link to the post:
|
||||
# http://forum.sourcefabric.org/discussion/13563/first-step-to-run-airtime-via-nginx-based-on-airtime-2.0-beta-files
|
||||
|
||||
exec > >(tee install_log.txt)
|
||||
exec 2>&1
|
||||
|
||||
if [ "$(id -u)" != "0" ]; then
|
||||
echo "Please run as root user."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
server="$1"
|
||||
|
||||
#Current dir
|
||||
# Absolute path to this script, e.g. /home/user/bin/foo.sh
|
||||
SCRIPT=`readlink -f $0`
|
||||
# Absolute path this script is in, thus /home/user/bin
|
||||
SCRIPTPATH=`dirname $SCRIPT`
|
||||
|
||||
#Prerequisite
|
||||
echo "----------------------------------------------------"
|
||||
echo " 1. Install Packages"
|
||||
echo "----------------------------------------------------"
|
||||
|
||||
dist=`lsb_release -is`
|
||||
code=`lsb_release -cs`
|
||||
|
||||
#enable squeeze backports to get lame packages
|
||||
if [ "$dist" = "Debian" -a "$code" = "squeeze" ]; then
|
||||
set +e
|
||||
grep -E "deb http://backports.debian.org/debian-backports squeeze-backports main" /etc/apt/sources.list
|
||||
returncode=$?
|
||||
set -e
|
||||
if [ "$returncode" -ne "0" ]; then
|
||||
echo "deb http://backports.debian.org/debian-backports squeeze-backports main" >> /etc/apt/sources.list
|
||||
fi
|
||||
fi
|
||||
|
||||
codename=`lsb_release -sc`
|
||||
set +e
|
||||
grep -E "deb +http://apt.sourcefabric.org/? +$codename +main" /etc/apt/sources.list
|
||||
returncode=$?
|
||||
set -e
|
||||
if [ "$returncode" != "0" ]; then
|
||||
echo "deb http://apt.sourcefabric.org/ $codename main" >> /etc/apt/sources.list
|
||||
fi
|
||||
|
||||
apt-get update
|
||||
|
||||
# Updated package list
|
||||
apt-get -y --force-yes install tar gzip curl php5-pgsql \
|
||||
php-pear php5-gd postgresql odbc-postgresql python libsoundtouch-ocaml \
|
||||
libtaglib-ocaml libao-ocaml libmad-ocaml ecasound \
|
||||
libesd0 libportaudio2 libsamplerate0 rabbitmq-server patch \
|
||||
php5-curl mpg123 monit python-virtualenv multitail libcamomile-ocaml-data \
|
||||
libpulse0 vorbis-tools lsb-release lsof sudo mp3gain vorbisgain flac vorbis-tools \
|
||||
pwgen libfaad2 php-apc
|
||||
|
||||
|
||||
#install packages with --force-yes option (this is useful in the case
|
||||
#of Debian, where these packages are unauthorized)
|
||||
apt-get -y --force-yes install libmp3lame-dev lame icecast2
|
||||
|
||||
#Debian Squeeze only has zendframework package. Newer versions of Ubuntu have zend-framework package.
|
||||
#Ubuntu Lucid has both zendframework and zend-framework. Difference appears to be that zendframework is for
|
||||
#1.10 and zend-framework is 1.11
|
||||
if [ "$dist" = "Debian" ]; then
|
||||
apt-get -y --force-yes install zendframework
|
||||
else
|
||||
apt-get -y --force-yes install libzend-framework-php
|
||||
fi
|
||||
|
||||
#get the "timeout" unix command
|
||||
if [ "$code" = "lucid" ]; then
|
||||
apt-get -y --force-yes install timeout
|
||||
else
|
||||
apt-get -y --force-yes install coreutils
|
||||
fi
|
||||
|
||||
#install aac package only available in new distributions: (Debian Wheezy, Ubuntu Precise or newer)
|
||||
if [ "$code" != "squeeze" -a "$code" != "lucid" ]; then
|
||||
apt-get -y --force-yes install libvo-aacenc0
|
||||
fi
|
||||
|
||||
#Install some plugin packages on Ubuntu Saucy.
|
||||
if [ "$dist" = "Ubuntu" -a "$code" = "saucy" ]; then
|
||||
apt-get -y --force-yes install php5-json
|
||||
apt-get -y --force-yes install liquidsoap-plugin-alsa liquidsoap-plugin-ao liquidsoap-plugin-faad liquidsoap-plugin-flac liquidsoap-plugin-icecast liquidsoap-plugin-lame liquidsoap-plugin-mad liquidsoap-plugin-ogg liquidsoap-plugin-opus liquidsoap-plugin-portaudio liquidsoap-plugin-pulseaudio liquidsoap-plugin-taglib liquidsoap-plugin-voaacenc liquidsoap-plugin-vorbis
|
||||
|
||||
fi
|
||||
|
||||
#Install packages back-ported by Sourcefabric
|
||||
apt-get -y --force-yes install sourcefabric-keyring
|
||||
apt-get -y --force-yes install liquidsoap
|
||||
apt-get -y --force-yes install silan
|
||||
apt-get -y --force-yes install libopus0
|
||||
|
||||
if [ "$server" = "nginx" ]; then
|
||||
apt-get -y --force-yes install nginx php5-fpm
|
||||
# NGINX Config File
|
||||
echo "----------------------------------------------------"
|
||||
echo "2.1 NGINX Config File"
|
||||
echo "----------------------------------------------------"
|
||||
if [ ! -f /etc/nginx/sites-available/airtime ]; then
|
||||
cp $SCRIPTPATH/../nginx/airtime-vhost /etc/nginx/sites-available/airtime
|
||||
ln -s /etc/nginx/sites-available/airtime /etc/nginx/sites-enabled/airtime
|
||||
service nginx reload
|
||||
else
|
||||
echo "NGINX config for Airtime already exists..."
|
||||
fi
|
||||
|
||||
# php-fpm Airtime pool file
|
||||
echo "----------------------------------------------------"
|
||||
echo "2.2 Airtime php pool file"
|
||||
echo "----------------------------------------------------"
|
||||
if [ ! -f /etc/php5/fpm/pool.d/airtime.conf ]; then
|
||||
cp $SCRIPTPATH/../php5-fpm/airtime.conf /etc/php5/fpm/pool.d/airtime.conf
|
||||
service php5-fpm reload
|
||||
else
|
||||
echo "Airtime php pool file already exists..."
|
||||
fi
|
||||
else
|
||||
apt-get -y --force-yes install apache2 libapache2-mod-php5
|
||||
set +e
|
||||
apache2 -v | grep "2\.4" > /dev/null
|
||||
apacheversion=$?
|
||||
set -e
|
||||
|
||||
|
||||
# Apache Config File
|
||||
echo "----------------------------------------------------"
|
||||
echo "2.1 Apache Config File"
|
||||
echo "----------------------------------------------------"
|
||||
|
||||
if [ "$apacheversion" != "1" ]; then
|
||||
airtimeconfigfile="airtime.conf"
|
||||
else
|
||||
airtimeconfigfile="airtime"
|
||||
fi
|
||||
|
||||
if [ ! -f /etc/apache2/sites-available/$airtimeconfigfile ]; then
|
||||
echo "Creating Apache config for Airtime..."
|
||||
|
||||
cp $SCRIPTPATH/../apache/airtime-vhost /etc/apache2/sites-available/$airtimeconfigfile
|
||||
a2dissite 000-default
|
||||
a2ensite airtime
|
||||
else
|
||||
echo "Apache config for Airtime already exists..."
|
||||
fi
|
||||
|
||||
if [ ! -d /usr/share/airtime/public ]; then
|
||||
echo "Creating Apache web root directory..."
|
||||
mkdir -p /usr/share/airtime/public/
|
||||
else
|
||||
echo "Airtime web root directory already exists..."
|
||||
fi
|
||||
|
||||
# PHP Config File for Apache
|
||||
echo "----------------------------------------------------"
|
||||
echo "2.2 PHP Config File for Apache"
|
||||
echo "----------------------------------------------------"
|
||||
if [ ! -f /etc/php5/apache2/airtime.ini ]; then
|
||||
echo "Creating Airtime PHP config for Apache..."
|
||||
cp $SCRIPTPATH/../php5/airtime.ini /etc/php5/apache2/conf.d/airtime.ini
|
||||
else
|
||||
echo "Airtime PHP config for Apache already exists..."
|
||||
fi
|
||||
|
||||
# Enable modules and restart Apache to enable any configuration changes
|
||||
echo "----------------------------------------------------"
|
||||
echo "2.3 Enable Apache Modules and Restart Apache"
|
||||
echo "----------------------------------------------------"
|
||||
a2enmod rewrite php5
|
||||
service apache2 restart
|
||||
fi
|
||||
|
||||
# Enable Icecast
|
||||
echo "----------------------------------------------------"
|
||||
echo "3. Enable Icecast"
|
||||
echo "----------------------------------------------------"
|
||||
cd /etc/default/
|
||||
sed -i 's/ENABLE=false/ENABLE=true/g' icecast2
|
||||
set +e
|
||||
service icecast2 start
|
||||
set -e
|
||||
echo ""
|
||||
|
||||
# Enable Monit
|
||||
echo "----------------------------------------------------"
|
||||
echo "4. Enable Monit"
|
||||
echo "----------------------------------------------------"
|
||||
cd /etc/default/
|
||||
sed -i 's/startup=0/startup=1/g' monit
|
||||
|
||||
set +e
|
||||
grep -q "include /etc/monit/conf.d" /etc/monit/monitrc
|
||||
RETVAL=$?
|
||||
set -e
|
||||
if [ $RETVAL -ne 0 ] ; then
|
||||
mkdir -p /etc/monit/conf.d
|
||||
echo "include /etc/monit/conf.d/*" >> /etc/monit/monitrc
|
||||
fi
|
||||
|
||||
# Run Airtime Install
|
||||
echo "----------------------------------------------------"
|
||||
echo "5. Run Airtime Install"
|
||||
echo "----------------------------------------------------"
|
||||
cd $SCRIPTPATH/../../install_minimal
|
||||
# Restart apache to clear php cache
|
||||
service apache2 restart
|
||||
./airtime-install
|
|
@ -1,10 +0,0 @@
|
|||
#!/bin/bash
|
||||
# Auto install script for airtime + nginx
|
||||
|
||||
# Absolute path to this script, e.g. /home/user/bin/foo.sh
|
||||
SCRIPT=`readlink -f $0`
|
||||
# Absolute path this script is in, thus /home/user/bin
|
||||
SCRIPTPATH=`dirname $SCRIPT`
|
||||
|
||||
$SCRIPTPATH/airtime-full-install nginx
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration,
|
||||
Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
class Version20110312121200 extends AbstractMigration
|
||||
{
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$schema->dropTable("cc_backup");
|
||||
$schema->dropTable("cc_trans");
|
||||
}
|
||||
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration,
|
||||
Doctrine\DBAL\Schema\Schema,
|
||||
Doctrine\DBAL\Schema\Table,
|
||||
Doctrine\DBAL\Schema\Column,
|
||||
Doctrine\DBAL\Types\Type;
|
||||
|
||||
class Version20110331111708 extends AbstractMigration
|
||||
{
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
//start cc_show_instances modifications
|
||||
$show_instances_table = $schema->getTable('cc_show_instances');
|
||||
|
||||
$show_instances_table->addColumn('record', 'smallint', array('notnull' => 0, 'default' => 0));
|
||||
$show_instances_table->addColumn('rebroadcast', 'smallint', array('notnull' => 0, 'default' => 0));
|
||||
$show_instances_table->addColumn('instance_id', 'integer', array('notnull' => 0));
|
||||
$show_instances_table->addColumn('file_id', 'integer', array('notnull' => 0));
|
||||
$show_instances_table->addColumn('soundcloud_id', 'integer', array('notnull' => 0));
|
||||
|
||||
$show_instances_table->addNamedForeignKeyConstraint('cc_original_show_instance_fkey', $show_instances_table, array('instance_id'), array('id'), array('onDelete' => 'CASCADE'));
|
||||
|
||||
$files_table = $schema->getTable('cc_files');
|
||||
$show_instances_table->addNamedForeignKeyConstraint('cc_recorded_file_fkey', $files_table, array('file_id'), array('id'), array('onDelete' => 'CASCADE'));
|
||||
//end cc_show_instances modifications
|
||||
|
||||
//start cc_show_days modifications
|
||||
$show_days_table = $schema->getTable('cc_show_days');
|
||||
|
||||
$show_days_table->addColumn('record', 'smallint', array( 'notnull' => 0, 'default' => 0));
|
||||
//end cc_show_days modifications
|
||||
|
||||
//start cc_show modifications
|
||||
$show_table = $schema->getTable('cc_show');
|
||||
|
||||
$show_table->addColumn('url', 'string', array('notnull' => 0, 'length' => 255));
|
||||
//end cc_show modifications
|
||||
|
||||
//start cc_schedule modifications
|
||||
$schedule_table = $schema->getTable('cc_schedule');
|
||||
|
||||
$playlist_id_col = $schedule_table->getColumn('playlist_id');
|
||||
$playlist_id_col->setNotnull(false);
|
||||
//end cc_schedule modifications
|
||||
|
||||
//create cc_show_rebroadcast table
|
||||
$cc_show_rebroadcast_table = $schema->createTable('cc_show_rebroadcast');
|
||||
|
||||
$cc_show_rebroadcast_table->addColumn('id', 'integer', array('unsigned' => true, 'autoincrement' => true));
|
||||
$cc_show_rebroadcast_table->addColumn('day_offset', 'string', array('length' => 255));
|
||||
$cc_show_rebroadcast_table->addColumn('start_time', 'datetime', array('notnull' => 1));
|
||||
$cc_show_rebroadcast_table->addColumn('show_id', 'integer', array('notnull' => 1));
|
||||
|
||||
$cc_show_rebroadcast_table->setPrimaryKey(array('id'));
|
||||
//end create cc_show_rebroadcast table
|
||||
}
|
||||
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
//start cc_show_instances modifications
|
||||
$show_instances_table = $schema->getTable('cc_show_instances');
|
||||
|
||||
$show_instances_table->dropColumn('record');
|
||||
$show_instances_table->dropColumn('rebroadcast');
|
||||
$show_instances_table->dropColumn('instance_id');
|
||||
$show_instances_table->dropColumn('file_id');
|
||||
$show_instances_table->dropColumn('soundcloud_id');
|
||||
//end cc_show_instances modifications
|
||||
|
||||
//start cc_show_days modifications
|
||||
$show_days_table = $schema->getTable('cc_show_days');
|
||||
|
||||
$show_days_table->dropColumn('record');
|
||||
//end cc_show_days modifications
|
||||
|
||||
//start cc_show modifications
|
||||
$show_table = $schema->getTable('cc_show');
|
||||
|
||||
$show_table->dropColumn('url');
|
||||
//end cc_show modifications
|
||||
|
||||
//start cc_schedule modifications
|
||||
$schedule_table = $schema->getTable('cc_schedule');
|
||||
|
||||
$playlist_id_col = $schedule_table->getColumn('playlist_id');
|
||||
$playlist_id_col->setNotnull(true);
|
||||
//end cc_schedule modifications
|
||||
|
||||
//drop cc_show_rebroadcast table
|
||||
$schema->dropTable('cc_show_rebroadcast');
|
||||
//end drop cc_show_rebroadcast table
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration,
|
||||
Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
class Version20110402164819 extends AbstractMigration
|
||||
{
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
//start cc_show modifications
|
||||
$show_table = $schema->getTable('cc_show');
|
||||
|
||||
$show_table->addColumn('genre', 'string', array('notnull' => 0, 'length' => 255, 'default' => ""));
|
||||
//end cc_show modifications
|
||||
|
||||
}
|
||||
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
//start cc_show modifications
|
||||
$show_table = $schema->getTable('cc_show');
|
||||
|
||||
$show_table->dropColumn('genre');
|
||||
//end cc_show modifications
|
||||
}
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration,
|
||||
Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
class Version20110406182005 extends AbstractMigration
|
||||
{
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
//start cc_show_instances modifications
|
||||
$cc_show_instances = $schema->getTable('cc_show_instances');
|
||||
|
||||
$cc_show_instances->addColumn('time_filled', 'time', array('notnull' => false));
|
||||
//end cc_show_instances modifications
|
||||
|
||||
//start cc_show_rebroadcast modifications
|
||||
$cc_show_rebroadcast = $schema->getTable('cc_show_rebroadcast');
|
||||
|
||||
$type = $cc_show_rebroadcast->getColumn('start_time')->getType()->getName();
|
||||
if($type == 'datetime') {
|
||||
$cc_show_rebroadcast->dropColumn('start_time');
|
||||
$cc_show_rebroadcast->addColumn('start_time', 'time', array('notnull' => true));
|
||||
}
|
||||
//end cc_show_rebroadcast modifications
|
||||
}
|
||||
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
//start cc_show_instances modifications
|
||||
$cc_show_instances = $schema->getTable('cc_show_instances');
|
||||
|
||||
$cc_show_instances->dropColumn('time_filled');
|
||||
//end cc_show_instances modifications
|
||||
|
||||
//start cc_show_rebroadcast modifications
|
||||
$cc_show_rebroadcast = $schema->getTable('cc_show_rebroadcast');
|
||||
|
||||
$type = $cc_show_rebroadcast->getColumn('start_time')->getType()->getName();
|
||||
if($type == 'datetime') {
|
||||
$cc_show_rebroadcast->dropColumn('start_time');
|
||||
$cc_show_rebroadcast->addColumn('start_time', 'datetime', array('notnull' => 1));
|
||||
}
|
||||
//end cc_show_rebroadcast modifications
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
<?php
|
||||
namespace DoctrineMigrations;
|
||||
//CC-2279 Upgrade script for creating the cc_music_dirs table.
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration,
|
||||
Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
class Version20110629143017 extends AbstractMigration
|
||||
{
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
//create cc_music_dirs table
|
||||
$cc_music_dirs = $schema->createTable('cc_music_dirs');
|
||||
|
||||
$cc_music_dirs->addColumn('id', 'integer', array('unsigned' => true, 'autoincrement' => true));
|
||||
$cc_music_dirs->addColumn('type', 'string', array('length' => 255));
|
||||
$cc_music_dirs->addColumn('directory', 'text', array('unique' => true));
|
||||
|
||||
$cc_music_dirs->setPrimaryKey(array('id'));
|
||||
|
||||
//end create cc_music_dirs table
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
$schema->dropTable('cc_music_dirs');
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
/*
|
||||
1) update cc_files table to include to "directory" column
|
||||
2) create a foreign key relationship from cc_files to cc_music_dirs
|
||||
3) create a foreign key relationship from cc_schedule to cc_files
|
||||
*/
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration,
|
||||
Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
class Version20110711161043 extends AbstractMigration
|
||||
{
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$ini = parse_ini_file(__DIR__."/../include/airtime-install.ini");
|
||||
$stor_dir = $ini["storage_dir"];
|
||||
|
||||
/* 1) update cc_files table to include to "directory" column */
|
||||
$this->_addSql("INSERT INTO cc_music_dirs (type, directory) VALUES ('stor', $stor_dir);");
|
||||
|
||||
$this->_addSql("INSERT INTO cc_music_dirs (type, directory) VALUES ('link', '');");
|
||||
|
||||
$cc_music_dirs = $schema->getTable('cc_music_dirs');
|
||||
|
||||
/* 2) create a foreign key relationship from cc_files to cc_music_dirs */
|
||||
$cc_files = $schema->getTable('cc_files');
|
||||
$cc_files->addColumn('directory', 'integer', array('notnull' => 0, 'default'=> NULL));
|
||||
|
||||
$cc_files->addNamedForeignKeyConstraint('cc_music_dirs_folder_fkey', $cc_music_dirs, array('directory'), array('id'), array('onDelete' => 'CASCADE'));
|
||||
|
||||
// before 3) we have to delete all entries in cc_schedule with file_id that are not in cc_file table
|
||||
$this->_addSql("DELETE FROM cc_schedule WHERE cc_schedule.id IN(
|
||||
SELECT cc_schedule.id
|
||||
FROM cc_schedule
|
||||
LEFT JOIN cc_files
|
||||
ON cc_schedule.file_id = cc_files.id
|
||||
WHERE cc_files.id IS NULL)");
|
||||
|
||||
/* 3) create a foreign key relationship from cc_schedule to cc_files */
|
||||
$cc_schedule = $schema->getTable('cc_schedule');
|
||||
$cc_schedule->addNamedForeignKeyConstraint('cc_files_folder_fkey', $cc_files, array('file_id'), array('id'), array('onDelete' => 'CASCADE'));
|
||||
}
|
||||
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration,
|
||||
Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
class Version20110713161043 extends AbstractMigration
|
||||
{
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
//create cc_country table
|
||||
$cc_country = $schema->createTable('cc_country');
|
||||
|
||||
$cc_country->addColumn('isocode', 'string', array('length' => 3));
|
||||
$cc_country->addColumn('name', 'string', array('length' => 255));
|
||||
|
||||
$cc_country->setPrimaryKey(array('isocode'));
|
||||
//end create cc_country table
|
||||
}
|
||||
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
$schema->dropTable('cc_country');
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration,
|
||||
Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
class Version20110829143306 extends AbstractMigration
|
||||
{
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
//create cc_stream_setting table
|
||||
$cc_stream_setting = $schema->createTable('cc_stream_setting');
|
||||
|
||||
$cc_stream_setting->addColumn('keyname', 'string', array('length' => 64));
|
||||
$cc_stream_setting->addColumn('value', 'string', array('length' => 255));
|
||||
$cc_stream_setting->addColumn('type', 'string', array('length' => 16));
|
||||
|
||||
$cc_stream_setting->setPrimaryKey(array('keyname'));
|
||||
//end create cc_stream_setting table
|
||||
}
|
||||
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
$schema->dropTable('cc_stream_setting');
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration,
|
||||
Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
class Version20110922153933 extends AbstractMigration
|
||||
{
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
// add soundcloud_id, soundcloud_error_code, soundcloud_error_msg columns to cc_files
|
||||
$cc_files = $schema->getTable('cc_files');
|
||||
$cc_files->addColumn('soundcloud_id', 'integer', array('notnull' => 0, 'default'=> NULL));
|
||||
$cc_files->addColumn('soundcloud_error_code', 'integer', array('notnull' => 0, 'default'=> NULL));
|
||||
$cc_files->addColumn('soundcloud_error_msg', 'string', array('length' => 255, 'notnull' => 0, 'default'=> NULL));
|
||||
}
|
||||
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration,
|
||||
Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
class Version20110925171051 extends AbstractMigration
|
||||
{
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
// move soundcloud_id from cc_show_instances to cc_files
|
||||
$this->_addSql("update cc_files as cf set soundcloud_id = csi.soundcloud_id
|
||||
from cc_show_instances as csi
|
||||
where csi.file_id = cf.id and file_id is not NULL");
|
||||
|
||||
// remove soundcloud_id from cc_show_instance table
|
||||
$cc_show_instances = $schema->getTable('cc_show_instances');
|
||||
$cc_show_instances->dropColumn('soundcloud_id');
|
||||
}
|
||||
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration,
|
||||
Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
class Version20110925171256 extends AbstractMigration
|
||||
{
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
// create cc_login_sttempts table
|
||||
$cc_login = $schema->createTable('cc_login_attempts');
|
||||
|
||||
$cc_login->addColumn('ip', 'string', array('length' => 32));
|
||||
$cc_login->addColumn('attempts', 'integer', array('notnull' => 0, 'default'=> 0));
|
||||
|
||||
$cc_login->setPrimaryKey(array('ip'));
|
||||
|
||||
// add login_attempts column to cc_subjs table
|
||||
$cc_subjs = $schema->getTable('cc_subjs');
|
||||
$cc_subjs->addColumn('login_attempts', 'integer', array('notnull' => 0, 'default'=> 0));
|
||||
}
|
||||
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration,
|
||||
Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
class Version20110929184401 extends AbstractMigration
|
||||
{
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$cc_component = $schema->createTable('cc_service_register');
|
||||
$cc_component->addColumn('name', 'string', array('length' => 32));
|
||||
$cc_component->addColumn('ip', 'string', array('length' => 18));
|
||||
|
||||
$cc_component->setPrimaryKey(array('name'));
|
||||
}
|
||||
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration,
|
||||
Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
class Version20111102142811 extends AbstractMigration
|
||||
{
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
// change 'soundcloud_upload' -> 'soundcloud_auto_upload_recorded_show' CC-2928
|
||||
$this->_addSql("UPDATE cc_pref SET keystr = 'soundcloud_auto_upload_recorded_show'
|
||||
WHERE keystr = 'soundcloud_upload'");
|
||||
|
||||
// add soundcloud_link_to_file
|
||||
$cc_files = $schema->getTable('cc_files');
|
||||
$cc_files->addColumn('soundcloud_link_to_file', 'string', array('length' => 4096, 'notnull' => 0, 'default'=> NULL));
|
||||
}
|
||||
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration,
|
||||
Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
class Version20111103141311 extends AbstractMigration
|
||||
{
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
// add timezone column to cc_show_days
|
||||
$cc_subjs = $schema->getTable('cc_show_days');
|
||||
$cc_subjs->addColumn('timezone', 'string', array('required' => true, 'default'=> ''));
|
||||
}
|
||||
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration,
|
||||
Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
class Version20111114222927 extends AbstractMigration
|
||||
{
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$cc_show_instances = $schema->getTable('cc_show_instances');
|
||||
$cc_show_instances->addColumn('modified_instance', 'boolean', array('notnull' => true, 'default'=> '0'));
|
||||
}
|
||||
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration,
|
||||
Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
class Version20120613123039 extends AbstractMigration
|
||||
{
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$table = $schema->getTable("cc_subjs");
|
||||
$table->addColumn("cell_phone", "string");
|
||||
}
|
||||
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<doctrine-migrations xmlns="http://doctrine-project.org/schemas/migrations/configuration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://doctrine-project.org/schemas/migrations/configuration
|
||||
http://doctrine-project.org/schemas/migrations/configuration.xsd">
|
||||
|
||||
<name>Airtime 2.0.0 Database Upgrade</name>
|
||||
|
||||
<migrations-namespace>DoctrineMigrations</migrations-namespace>
|
||||
|
||||
<table name="doctrine_migration_versions" />
|
||||
|
||||
<migrations-directory>./</migrations-directory>
|
||||
|
||||
</doctrine-migrations>
|
|
@ -1,5 +0,0 @@
|
|||
<?php
|
||||
require_once(dirname(__FILE__).'/include/AirtimeIni.php');
|
||||
require_once(dirname(__FILE__).'/include/AirtimeInstall.php');
|
||||
|
||||
AirtimeInstall::DirCheck();
|
|
@ -1,261 +0,0 @@
|
|||
#!/bin/bash -e
|
||||
#-e Causes bash script to exit if any of the installers
|
||||
#return with a non-zero return value.
|
||||
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "Please run as root user."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
showhelp () {
|
||||
echo "Usage: airtime-install [options]
|
||||
--help|-h Displays usage information.
|
||||
--overwrite|-o Overwrite any existing config files.
|
||||
--preserve|-p Keep any existing config files.
|
||||
--no-db|-n Turn off database install.
|
||||
--reinstall|-r Force a fresh install of this Airtime Version
|
||||
--media-monitor|-m Install only media-monitor
|
||||
--pypo|-p Install only pypo and liquidsoap
|
||||
--web|-w Install only files for web-server"
|
||||
exit 0
|
||||
}
|
||||
|
||||
rabbitmq_install () {
|
||||
RABBITMQ_VHOST="/airtime"
|
||||
RABBITMQ_USER="airtime"
|
||||
RABBITMQ_PASSWORD=$(awk -F ' = ' '{if (! ($0 ~ /^;/) && $0 ~ /^password/ ) print $2}' /etc/airtime/airtime.conf)
|
||||
EXCHANGES="airtime-pypo|pypo-fetch|airtime-media-monitor|media-monitor"
|
||||
|
||||
rabbitmqctl list_vhosts | grep $RABBITMQ_VHOST
|
||||
RESULT="$?"
|
||||
|
||||
if [ $RESULT = "0" ]; then
|
||||
rabbitmqctl delete_vhost $RABBITMQ_VHOST
|
||||
rabbitmqctl delete_user $RABBITMQ_USER
|
||||
fi
|
||||
|
||||
rabbitmqctl add_vhost $RABBITMQ_VHOST
|
||||
rabbitmqctl add_user $RABBITMQ_USER $RABBITMQ_PASSWORD
|
||||
rabbitmqctl set_permissions -p $RABBITMQ_VHOST $RABBITMQ_USER "$EXCHANGES" "$EXCHANGES" "$EXCHANGES"
|
||||
rabbitmqctl set_permissions -p $RABBITMQ_VHOST $RABBITMQ_USER .\* .\* .\*
|
||||
|
||||
export RABBITMQ_USER
|
||||
export RABBITMQ_PASSWORD
|
||||
export RABBITMQ_VHOST
|
||||
}
|
||||
|
||||
overwrite="f"
|
||||
preserve="f"
|
||||
nodb="f"
|
||||
reinstall="f"
|
||||
mediamonitor="f"
|
||||
airtime_analyzer="f"
|
||||
pypo="f"
|
||||
showrecorder="f"
|
||||
web="f"
|
||||
disable_deb_check="f"
|
||||
|
||||
set -- $(getopt -l help,overwrite,preserve,no-db,reinstall,media-monitor,pypo,web,liquidsoap-keep-alive,disable-deb-check "hopnrmywld" "$@")
|
||||
while [ $# -gt 0 ]
|
||||
do
|
||||
case "$1" in
|
||||
(-h|--help) showhelp; exit 0;;
|
||||
(-o|--overwrite) overwrite="t";;
|
||||
(-p|--preserve) preserve="t";;
|
||||
(-n|--no-db) nodb="t";;
|
||||
(-r|--reinstall) reinstall="t";;
|
||||
(-m|--media-monitor) mediamonitor="t";;
|
||||
(-a|--airtime-analyzer) airtime_analyzer="t";;
|
||||
(-y|--pypo) pypo="t";;
|
||||
(-w|--web) web="t";;
|
||||
(-d|--disable-deb-check) disable_deb_check="t";;
|
||||
|
||||
(--) shift; break;;
|
||||
(-*) echo "$0: error - unrecognized option $1" 1>&2; exit 1;;
|
||||
(*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [ "$mediamonitor" = "f" -a "$pypo" = "f" -a "$web" = "f" -a "$airtime_analyzer" = "f" ]; then
|
||||
#none of these install parameters were specified, so by default we install all of them
|
||||
mediamonitor="f" # FIXME: Remove media_monitor! -- Albert
|
||||
pypo="t"
|
||||
showrecorder="t"
|
||||
airtime_analyzer="t"
|
||||
web="t"
|
||||
fi
|
||||
|
||||
if [ "$disable_deb_check" == "f" ]; then
|
||||
set +e
|
||||
DEB=$(dpkg -s airtime 2> /dev/null | grep Status)
|
||||
set -e
|
||||
if [[ "$DEB" = "Status: install ok installed" ]]; then
|
||||
echo -e "\nDebian package of Airtime detected. Please use the debian package to upgrade.\n"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
#Update apt sources.list to point to the new deb-multimedia domain.
|
||||
sed -i s/www.debian-multimedia.org/www.deb-multimedia.org/g /etc/apt/sources.list
|
||||
|
||||
# Absolute path to this script, e.g. /home/user/bin/foo.sh
|
||||
SCRIPT=`readlink -f $0`
|
||||
# Absolute path this script is in, thus /home/user/bin
|
||||
SCRIPTPATH=`dirname $SCRIPT`
|
||||
AIRTIMEROOT=$SCRIPTPATH/../
|
||||
|
||||
echo "* Making sure /etc/default/locale is set properly"
|
||||
set +e
|
||||
update-locale
|
||||
cat /etc/default/locale | grep -i "LANG=.*UTF-\?8"
|
||||
if [ "$?" != "0" ]; then
|
||||
echo -e " * Fail\n"
|
||||
echo "A non UTF-8 default locale found in /etc/default/locale. Airtime requires
|
||||
a UTF-8 locale to run. To fix this please do the following:
|
||||
|
||||
Ubuntu:
|
||||
Put line 'en_US.UTF-8 UTF-8' (or similar) without quotes to '/var/lib/locales/supported.d/local',
|
||||
replacing any existing lines.
|
||||
A list of supported locales is available in '/usr/share/i18n/SUPPORTED'
|
||||
Then run 'sudo dpkg-reconfigure locales'
|
||||
|
||||
Debian:
|
||||
Run 'sudo dpkg-reconfigure locales' and use the interface to select 'en_US.UTF-8 UTF-8' (or similar).
|
||||
On the second page select this new locale as the default.
|
||||
|
||||
After these changes have been made simply run install again.
|
||||
|
||||
Now exiting install...
|
||||
"
|
||||
exit 1
|
||||
fi
|
||||
set -e
|
||||
|
||||
# Check if airtime exists already
|
||||
set +e
|
||||
php --php-ini ${SCRIPTPATH}/airtime-php.ini ${SCRIPTPATH}/include/airtime-installed-check.php
|
||||
result=$?
|
||||
set -e
|
||||
|
||||
DO_UPGRADE="0"
|
||||
if [ "$result" -eq "0" ]; then
|
||||
echo " * None found."
|
||||
|
||||
#Make sure any straggler config files are removed. Reason for this is that they may be from
|
||||
#an older version of Airtime, but since there no database installed, we have no idea how to
|
||||
#handle these (what version are they from?).
|
||||
rm -f "/etc/airtime/airtime.conf"
|
||||
rm -f "/etc/airtime/api_client.cfg"
|
||||
rm -f "/etc/airtime/liquidsoap.cfg"
|
||||
rm -f "/etc/airtime/media-monitor.cfg"
|
||||
rm -f "/etc/airtime/pypo.cfg"
|
||||
elif [ "$result" -eq "1" -a "$reinstall" = "f" ]; then
|
||||
echo " * Same version of Airtime already installed! Reusing database."
|
||||
nodb='t'
|
||||
overwrite='f'
|
||||
elif [ "$result" -eq "2" ]; then
|
||||
echo " * Previous version of Airtime already installed..will perform upgrade."
|
||||
DO_UPGRADE="1"
|
||||
elif [ "$result" -eq "3" ]; then
|
||||
echo " * You require at least Airtime 1.8.0 installed for upgrade."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#We don't want any of our python services running if we are doing an upgrade/reinstall.
|
||||
#They will be automatically restarted later on.
|
||||
echo "* Temporarily stopping any previous running services"
|
||||
set +e
|
||||
monit unmonitor airtime-media-monitor >/dev/null 2>&1
|
||||
monit unmonitor airtime-liquidsoap >/dev/null 2>&1
|
||||
monit unmonitor airtime-playout >/dev/null 2>&1
|
||||
set -e
|
||||
if [ -e /etc/init.d/airtime-media-monitor ]; then
|
||||
invoke-rc.d airtime-media-monitor stop > /dev/null 2>&1
|
||||
fi
|
||||
if [ -e /etc/init.d/airtime-playout ]; then
|
||||
invoke-rc.d airtime-playout stop > /dev/null 2>&1
|
||||
fi
|
||||
if [ -e /etc/init.d/airtime-liquidsoap ]; then
|
||||
invoke-rc.d airtime-liquidsoap stop > /dev/null 2>&1
|
||||
fi
|
||||
|
||||
#export these variables to make them available in sub bash scripts
|
||||
export DO_UPGRADE
|
||||
export mediamonitor
|
||||
export airtime_analyzer
|
||||
export pypo
|
||||
export showrecorder
|
||||
export web
|
||||
export reinstall
|
||||
export nodb
|
||||
export overwrite
|
||||
export preserve
|
||||
|
||||
set +e
|
||||
test "$mediamonitor" = "t" -o "$pypo" = "t"
|
||||
export python_service=$?
|
||||
set -e
|
||||
|
||||
echo -e "\n******************************** Install Begin *********************************"
|
||||
rm -rf "/usr/lib/airtime"
|
||||
mkdir -p /usr/lib/airtime
|
||||
|
||||
if [ "$python_service" -eq "0" ]; then
|
||||
$AIRTIMEROOT/python_apps/python-virtualenv/virtualenv-install.sh
|
||||
|
||||
virtualenv_bin="/usr/lib/airtime/airtime_virtualenv/bin/"
|
||||
. ${virtualenv_bin}activate
|
||||
python $AIRTIMEROOT/python_apps/create-pypo-user.py
|
||||
fi
|
||||
|
||||
if [ "$DO_UPGRADE" -eq "1" ]; then
|
||||
#do upgrade
|
||||
php --php-ini ${SCRIPTPATH}/airtime-php.ini ${SCRIPTPATH}/include/airtime-upgrade.php $@
|
||||
fi
|
||||
|
||||
set +e
|
||||
if [ "$DO_UPGRADE" -eq "0" ]; then
|
||||
php --php-ini ${SCRIPTPATH}/airtime-php.ini ${SCRIPTPATH}/include/airtime-install.php $@
|
||||
result=$?
|
||||
|
||||
if [ "$result" -ne "0" ]; then
|
||||
#There was an error, exit with error code.
|
||||
echo "There was an error during install. Exit code $result"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
rabbitmq_install
|
||||
set -e
|
||||
|
||||
|
||||
export airtime_service_start='t'
|
||||
$SCRIPTPATH/include/airtime-copy-files.sh
|
||||
$SCRIPTPATH/include/airtime-initialize.sh $@
|
||||
|
||||
if [ "$mediamonitor" = "t" -o "$pypo" = "t" ]; then
|
||||
#deactivate virtualenv
|
||||
deactivate
|
||||
fi
|
||||
|
||||
# Restart airtime_analyzer (or start it)
|
||||
service airtime_analyzer restart
|
||||
|
||||
|
||||
#An attempt to force apache to realize that files are updated on upgrade...
|
||||
touch /usr/share/airtime/public/index.php
|
||||
|
||||
if [ "$python_service" -eq "0" ]; then
|
||||
#only run airtime-check-system if all components were installed
|
||||
echo -e "\n*** Verifying your system environment, running airtime-check-system ***"
|
||||
sleep 10
|
||||
|
||||
set +e
|
||||
airtime-check-system --no-color
|
||||
set -e
|
||||
fi
|
||||
|
||||
echo -e "\n******************************* Install Complete *******************************"
|
File diff suppressed because it is too large
Load Diff
|
@ -1,66 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
#Check if root user
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "Please run as root user."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
options=$(getopt -o p -l purge -- "$@")
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "only -p or --purge parameter allowed"
|
||||
exit 1
|
||||
fi
|
||||
eval set -- "$options"
|
||||
|
||||
purge='f'
|
||||
|
||||
while true
|
||||
do
|
||||
case "$1" in
|
||||
-p|--purge) purge='t'; shift;;
|
||||
--) shift 1; break ;;
|
||||
*) break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
#Make 'purge' env variable available to sub bash script
|
||||
export purge
|
||||
|
||||
rabbitmq_uninstall () {
|
||||
RABBITMQ_VHOST="/airtime"
|
||||
RABBITMQ_USER="airtime"
|
||||
|
||||
rabbitmqctl delete_vhost $RABBITMQ_VHOST
|
||||
rabbitmqctl delete_user $RABBITMQ_USER
|
||||
}
|
||||
|
||||
echo -e "\n******************************* Uninstall Begin ********************************"
|
||||
|
||||
# Absolute path to this script, e.g. /home/user/bin/foo.sh
|
||||
SCRIPT=`readlink -f $0`
|
||||
# Absolute path this script is in, thus /home/user/bin
|
||||
SCRIPTPATH=`dirname $SCRIPT`
|
||||
|
||||
rabbitmq_uninstall
|
||||
|
||||
virtualenv_bin="/usr/lib/airtime/airtime_virtualenv/bin/"
|
||||
. ${virtualenv_bin}activate
|
||||
|
||||
#Uninitialize Airtime
|
||||
$SCRIPTPATH/include/airtime-uninitialize.sh
|
||||
|
||||
#Remove Airtime files
|
||||
$SCRIPTPATH/include/airtime-remove-files.sh
|
||||
|
||||
#Remove pypo user
|
||||
python $SCRIPTPATH/../python_apps/remove-pypo-user.py
|
||||
|
||||
#deactivate virtualenv
|
||||
deactivate
|
||||
|
||||
echo -e "\n****************************** Uninstall Complete *******************************\n"
|
||||
echo "NOTE: To fully remove all Airtime files, you will also have to manually delete"
|
||||
echo " the directories '/srv/airtime'(default storage location of media files)"
|
||||
echo -e " and '/etc/airtime'(where the config files are stored).\n"
|
|
@ -1,349 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @package Airtime
|
||||
* @copyright 2011 Sourcefabric o.p.s.
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.txt
|
||||
*/
|
||||
|
||||
// Do not allow remote execution
|
||||
$arr = array_diff_assoc($_SERVER, $_ENV);
|
||||
if (isset($arr["DOCUMENT_ROOT"]) && ($arr["DOCUMENT_ROOT"] != "") ) {
|
||||
header("HTTP/1.1 400");
|
||||
header("Content-type: text/plain; charset=UTF-8");
|
||||
echo "400 Not executable\r\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
//make sure user has Postgresql PHP extension installed.
|
||||
if (!function_exists('pg_connect')) {
|
||||
trigger_error("PostgreSQL PHP extension required and not found.", E_USER_ERROR);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
|
||||
/* This class deals with the config files stored in /etc/airtime */
|
||||
class AirtimeIni
|
||||
{
|
||||
const CONF_FILE_AIRTIME = "/etc/airtime/airtime.conf";
|
||||
const CONF_FILE_PYPO = "/etc/airtime/pypo.cfg";
|
||||
const CONF_FILE_RECORDER = "/etc/airtime/recorder.cfg";
|
||||
const CONF_FILE_API_CLIENT = "/etc/airtime/api_client.cfg";
|
||||
const CONF_FILE_LIQUIDSOAP = "/etc/airtime/liquidsoap.cfg";
|
||||
const CONF_FILE_MEDIAMONITOR = "/etc/airtime/media-monitor.cfg";
|
||||
const CONF_FILE_MONIT = "/etc/monit/conf.d/airtime-monit.cfg";
|
||||
|
||||
const CONF_PYPO_GRP = "pypo";
|
||||
const CONF_WWW_DATA_GRP = "www-data";
|
||||
|
||||
public static function IniFilesExist()
|
||||
{
|
||||
$configFiles = array(self::CONF_FILE_AIRTIME,
|
||||
self::CONF_FILE_PYPO,
|
||||
self::CONF_FILE_RECORDER,
|
||||
self::CONF_FILE_LIQUIDSOAP,
|
||||
self::CONF_FILE_MEDIAMONITOR);
|
||||
$exist = false;
|
||||
foreach ($configFiles as $conf) {
|
||||
if (file_exists($conf)) {
|
||||
echo "Existing config file detected at $conf".PHP_EOL;
|
||||
$exist = true;
|
||||
}
|
||||
}
|
||||
return $exist;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function creates the /etc/airtime configuration folder
|
||||
* and copies the default config files to it.
|
||||
*/
|
||||
public static function CreateIniFiles()
|
||||
{
|
||||
if (!file_exists("/etc/airtime/")){
|
||||
if (!mkdir("/etc/airtime/", 0755, true)){
|
||||
echo "Could not create /etc/airtime/ directory. Exiting.";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!copy(AirtimeInstall::GetAirtimeSrcDir()."/build/airtime.conf", self::CONF_FILE_AIRTIME)){
|
||||
echo "Could not copy airtime.conf to /etc/airtime/. Exiting.";
|
||||
exit(1);
|
||||
} else if (!self::ChangeFileOwnerGroupMod(self::CONF_FILE_AIRTIME, self::CONF_WWW_DATA_GRP)){
|
||||
echo "Could not set ownership of api_client.cfg to 'pypo'. Exiting.";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
if (getenv("python_service") == "0"){
|
||||
if (!copy(__DIR__."/../../python_apps/api_clients/api_client.cfg", self::CONF_FILE_API_CLIENT)){
|
||||
echo "Could not copy api_client.cfg to /etc/airtime/. Exiting.";
|
||||
exit(1);
|
||||
} else if (!self::ChangeFileOwnerGroupMod(self::CONF_FILE_API_CLIENT, self::CONF_PYPO_GRP)){
|
||||
echo "Could not set ownership of api_client.cfg to 'pypo'. Exiting.";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!copy(__DIR__."/../../python_apps/pypo/pypo.cfg", self::CONF_FILE_PYPO)){
|
||||
echo "Could not copy pypo.cfg to /etc/airtime/. Exiting.";
|
||||
exit(1);
|
||||
} else if (!self::ChangeFileOwnerGroupMod(self::CONF_FILE_PYPO, self::CONF_PYPO_GRP)){
|
||||
echo "Could not set ownership of pypo.cfg to 'pypo'. Exiting.";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
if (!copy(__DIR__."/../../python_apps/pypo/liquidsoap_scripts/liquidsoap.cfg", self::CONF_FILE_LIQUIDSOAP)){
|
||||
echo "Could not copy liquidsoap.cfg to /etc/airtime/. Exiting.";
|
||||
exit(1);
|
||||
} else if (!self::ChangeFileOwnerGroupMod(self::CONF_FILE_LIQUIDSOAP, self::CONF_PYPO_GRP)){
|
||||
echo "Could not set ownership of liquidsoap.cfg to 'pypo'. Exiting.";
|
||||
exit(1);
|
||||
}
|
||||
* */
|
||||
|
||||
if (!copy(__DIR__."/../../python_apps/media-monitor/media-monitor.cfg", self::CONF_FILE_MEDIAMONITOR)){
|
||||
echo "Could not copy media-monitor.cfg to /etc/airtime/. Exiting.";
|
||||
exit(1);
|
||||
} else if (!self::ChangeFileOwnerGroupMod(self::CONF_FILE_MEDIAMONITOR, self::CONF_PYPO_GRP)){
|
||||
echo "Could not set ownership of media-monitor.cfg to 'pypo'. Exiting.";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function ChangeFileOwnerGroupMod($filename, $user){
|
||||
return (chown($filename, $user) &&
|
||||
chgrp($filename, $user) &&
|
||||
chmod($filename, 0640));
|
||||
}
|
||||
|
||||
public static function RemoveMonitFile(){
|
||||
@unlink("/etc/monit/conf.d/airtime-monit.cfg");
|
||||
}
|
||||
|
||||
/**
|
||||
* This function removes /etc/airtime and the configuration
|
||||
* files present within it.
|
||||
*/
|
||||
public static function RemoveIniFiles()
|
||||
{
|
||||
if (file_exists(self::CONF_FILE_AIRTIME)){
|
||||
unlink(self::CONF_FILE_AIRTIME);
|
||||
}
|
||||
|
||||
if (file_exists(self::CONF_FILE_PYPO)){
|
||||
unlink(self::CONF_FILE_PYPO);
|
||||
}
|
||||
|
||||
if (file_exists(self::CONF_FILE_RECORDER)){
|
||||
unlink(self::CONF_FILE_RECORDER);
|
||||
}
|
||||
|
||||
if (file_exists(self::CONF_FILE_LIQUIDSOAP)){
|
||||
unlink(self::CONF_FILE_LIQUIDSOAP);
|
||||
}
|
||||
|
||||
//wait until Airtime 1.9.0
|
||||
if (file_exists(self::CONF_FILE_MEDIAMONITOR)){
|
||||
unlink(self::CONF_FILE_MEDIAMONITOR);
|
||||
}
|
||||
|
||||
if (file_exists("etc/airtime")){
|
||||
rmdir("/etc/airtime/");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function generates a random string.
|
||||
*
|
||||
* The random string uses two parameters: $p_len and $p_chars. These
|
||||
* parameters do not need to be provided, in which case defaults are
|
||||
* used.
|
||||
*
|
||||
* @param string $p_len
|
||||
* How long should the generated string be.
|
||||
* @param string $p_chars
|
||||
* String containing chars that should be used for generating.
|
||||
* @return string
|
||||
* The generated random string.
|
||||
*/
|
||||
public static function GenerateRandomString($p_len=20, $p_chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
|
||||
{
|
||||
$string = '';
|
||||
for ($i = 0; $i < $p_len; $i++)
|
||||
{
|
||||
$pos = mt_rand(0, strlen($p_chars)-1);
|
||||
$string .= $p_chars{$pos};
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function updates an INI style config file.
|
||||
*
|
||||
* A property and the value the property should be changed to are
|
||||
* supplied. If the property is not found, then no changes are made.
|
||||
*
|
||||
* @param string $p_filename
|
||||
* The path the to the file.
|
||||
* @param string $p_property
|
||||
* The property to look for in order to change its value.
|
||||
* @param string $p_value
|
||||
* The value the property should be changed to.
|
||||
*
|
||||
*/
|
||||
public static function UpdateIniValue($p_filename, $p_property, $p_value)
|
||||
{
|
||||
$lines = file($p_filename);
|
||||
$n=count($lines);
|
||||
foreach ($lines as &$line) {
|
||||
if ($line[0] != "#"){
|
||||
$key_value = explode("=", $line);
|
||||
$key = trim($key_value[0]);
|
||||
|
||||
if ($key == $p_property){
|
||||
$line = "$p_property = $p_value".PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$fp=fopen($p_filename, 'w');
|
||||
for($i=0; $i<$n; $i++){
|
||||
fwrite($fp, $lines[$i]);
|
||||
}
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
//stupid hack found on http://stackoverflow.com/a/1268642/276949
|
||||
//with some modifications: 1) Spaces are inserted in between sections and
|
||||
//2) values are not quoted.
|
||||
public static function write_ini_file($assoc_arr, $path, $has_sections = false) {
|
||||
$content = "";
|
||||
|
||||
if ($has_sections) {
|
||||
$first_line = true;
|
||||
foreach ($assoc_arr as $key=>$elem) {
|
||||
if ($first_line) {
|
||||
$content .= "[".$key."]\n";
|
||||
$first_line = false;
|
||||
} else {
|
||||
$content .= "\n[".$key."]\n";
|
||||
}
|
||||
foreach ($elem as $key2=>$elem2) {
|
||||
if(is_array($elem2))
|
||||
{
|
||||
for($i=0;$i<count($elem2);$i++)
|
||||
{
|
||||
$content .= $key2."[] = \"".$elem2[$i]."\"\n";
|
||||
}
|
||||
}
|
||||
else if($elem2=="") $content .= $key2." = \n";
|
||||
else $content .= $key2." = ".$elem2."\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach ($assoc_arr as $key=>$elem) {
|
||||
if(is_array($elem))
|
||||
{
|
||||
for($i=0;$i<count($elem);$i++)
|
||||
{
|
||||
$content .= $key."[] = \"".$elem[$i]."\"\n";
|
||||
}
|
||||
}
|
||||
else if($elem=="") $content .= $key." = \n";
|
||||
else $content .= $key." = ".$elem."\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (!$handle = fopen($path, 'w')) {
|
||||
return false;
|
||||
}
|
||||
if (!fwrite($handle, $content)) {
|
||||
return false;
|
||||
}
|
||||
fclose($handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* After the configuration files have been copied to /etc/airtime,
|
||||
* this function will update them to values unique to this
|
||||
* particular installation.
|
||||
*/
|
||||
public static function UpdateIniFiles()
|
||||
{
|
||||
$api_key = self::GenerateRandomString();
|
||||
if (getenv("web") == "t"){
|
||||
//self::UpdateIniValue(self::CONF_FILE_AIRTIME, 'api_key', $api_key);
|
||||
//self::UpdateIniValue(self::CONF_FILE_AIRTIME, 'airtime_dir', AirtimeInstall::CONF_DIR_WWW);
|
||||
//self::UpdateIniValue(self::CONF_FILE_AIRTIME, 'password', self::GenerateRandomString());
|
||||
$ini = parse_ini_file(self::CONF_FILE_AIRTIME, true);
|
||||
|
||||
$ini['general']['api_key'] = $api_key;
|
||||
$ini['general']['airtime_dir'] = AirtimeInstall::CONF_DIR_WWW;
|
||||
|
||||
|
||||
$ini['rabbitmq']['vhost'] = '/airtime';
|
||||
$ini['rabbitmq']['user'] = 'airtime';
|
||||
$ini['rabbitmq']['password'] = self::GenerateRandomString();
|
||||
|
||||
self::write_ini_file($ini, self::CONF_FILE_AIRTIME, true);
|
||||
}
|
||||
//self::UpdateIniValue(self::CONF_FILE_API_CLIENT, 'api_key', "'$api_key'");
|
||||
|
||||
$ini = parse_ini_file(self::CONF_FILE_API_CLIENT);
|
||||
$ini['api_key'] = "'$api_key'";
|
||||
self::write_ini_file($ini, self::CONF_FILE_API_CLIENT);
|
||||
}
|
||||
|
||||
public static function ReadPythonConfig($p_filename)
|
||||
{
|
||||
$values = array();
|
||||
|
||||
$lines = file($p_filename);
|
||||
$n=count($lines);
|
||||
for ($i=0; $i<$n; $i++) {
|
||||
if (strlen($lines[$i]) && !in_array(substr($lines[$i], 0, 1), array('#', PHP_EOL))){
|
||||
$info = explode("=", $lines[$i], 2);
|
||||
$values[trim($info[0])] = trim($info[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
public static function MergeConfigFiles($configFiles, $suffix) {
|
||||
foreach ($configFiles as $conf) {
|
||||
if (file_exists("$conf$suffix.bak")) {
|
||||
|
||||
if($conf === CONF_FILE_AIRTIME) {
|
||||
// Parse with sections
|
||||
$newSettings = parse_ini_file($conf, true);
|
||||
$oldSettings = parse_ini_file("$conf$suffix.bak", true);
|
||||
}
|
||||
else {
|
||||
$newSettings = self::ReadPythonConfig($conf);
|
||||
$oldSettings = self::ReadPythonConfig("$conf$suffix.bak");
|
||||
}
|
||||
|
||||
$settings = array_keys($newSettings);
|
||||
|
||||
foreach($settings as $section) {
|
||||
if(isset($oldSettings[$section])) {
|
||||
if(is_array($oldSettings[$section])) {
|
||||
$sectionKeys = array_keys($newSettings[$section]);
|
||||
foreach($sectionKeys as $sectionKey) {
|
||||
if(isset($oldSettings[$section][$sectionKey])) {
|
||||
self::UpdateIniValue($conf, $sectionKey, $oldSettings[$section][$sectionKey]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
self::UpdateIniValue($conf, $section, $oldSettings[$section]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
<?php
|
||||
|
||||
define('AIRTIME_VERSION', '2.5.3');
|
|
@ -1,112 +0,0 @@
|
|||
#!/bin/bash -e
|
||||
#-e Causes bash script to exit if any of the installers
|
||||
#return with a non-zero return value.
|
||||
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "Please run as root user."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#copy files to
|
||||
## /etc/airtime
|
||||
#+ /etc/apache2/sites-available/airtime
|
||||
#+ /etc/apache2/sites-enabled/airtime
|
||||
## /etc/cron.d/
|
||||
## /etc/init.d/
|
||||
## /etc/monit/conf.d/
|
||||
# /usr/lib/airtime/airtime_virtualenv
|
||||
## /usr/lib/airtime/api_clients
|
||||
## /usr/lib/airtime/media-monitor
|
||||
# /srv/airtime/stor
|
||||
## /usr/lib/airtime/pypo
|
||||
## /usr/lib/airtime/show-recorder
|
||||
## /usr/lib/airtime/utils
|
||||
## /usr/bin/airtime-*
|
||||
## /usr/share/airtime
|
||||
## /var/log/airtime
|
||||
## /var/tmp/airtime
|
||||
|
||||
# Absolute path to this script, e.g. /home/user/bin/foo.sh
|
||||
SCRIPT=`readlink -f $0`
|
||||
# Absolute path this script is in, thus /home/user/bin
|
||||
SCRIPTPATH=`dirname $SCRIPT`
|
||||
|
||||
AIRTIMEROOT=$SCRIPTPATH/../../
|
||||
|
||||
echo "* Creating /etc/airtime"
|
||||
mkdir -p /etc/airtime
|
||||
if [ ! -e /etc/airtime/airtime.conf ]; then
|
||||
#config file airtime.conf exists, but Airtime is not installed
|
||||
cp $AIRTIMEROOT/airtime_mvc/build/airtime.conf /etc/airtime
|
||||
fi
|
||||
|
||||
#if [ -e /etc/airtime/airtime.conf -a "$DO_UPGRADE" -eq "0" ]; then
|
||||
#config file airtime.conf exists, but Airtime is not installed
|
||||
# mv /etc/airtime/airtime.conf airtime.conf.bak
|
||||
# cp $AIRTIMEROOT/airtime_mvc/build/airtime.conf /etc/airtime
|
||||
#fi
|
||||
|
||||
|
||||
echo "* Creating /etc/monit/conf.d/monit-airtime-generic.cfg"
|
||||
mkdir -p /etc/monit/conf.d/
|
||||
if [ ! -e /etc/monit/conf.d/monit-airtime-generic.cfg ]; then
|
||||
rm -f /etc/monit/conf.d/*airtime*
|
||||
cp $AIRTIMEROOT/python_apps/monit/monit-airtime-generic.cfg /etc/monit/conf.d/
|
||||
fi
|
||||
|
||||
|
||||
echo "* Creating /etc/cron.d/airtime-crons"
|
||||
HOUR=$(($RANDOM%24))
|
||||
MIN=$(($RANDOM%60))
|
||||
echo "$MIN $HOUR * * * root /usr/lib/airtime/utils/phone_home_stat" > /etc/cron.d/airtime-crons
|
||||
|
||||
echo "* Creating /usr/lib/airtime"
|
||||
if [ "$python_service" -eq "0" ]; then
|
||||
python $AIRTIMEROOT/python_apps/api_clients/install/api_client_install.py
|
||||
|
||||
if [ "$airtime_analyzer" = "t" ]; then
|
||||
pushd $AIRTIMEROOT/python_apps/airtime_analyzer/
|
||||
python setup.py install
|
||||
popd
|
||||
fi
|
||||
if [ "$pypo" = "t" ]; then
|
||||
python $AIRTIMEROOT/python_apps/pypo/install/pypo-copy-files.py
|
||||
fi
|
||||
fi
|
||||
|
||||
cp -R $AIRTIMEROOT/utils /usr/lib/airtime
|
||||
cp -R $AIRTIMEROOT/python_apps/std_err_override /usr/lib/airtime
|
||||
|
||||
echo "* Creating symbolic links in /usr/bin"
|
||||
#create symbolic links
|
||||
ln -sf /usr/lib/airtime/utils/airtime-import/airtime-import /usr/bin/airtime-import
|
||||
ln -sf /usr/lib/airtime/utils/airtime-check-system /usr/bin/airtime-check-system
|
||||
ln -sf /usr/lib/airtime/utils/airtime-log /usr/bin/airtime-log
|
||||
ln -sf /usr/lib/airtime/utils/airtime-test-soundcard /usr/bin/airtime-test-soundcard
|
||||
ln -sf /usr/lib/airtime/utils/airtime-test-stream /usr/bin/airtime-test-stream
|
||||
ln -sf /usr/lib/airtime/utils/airtime-silan /usr/bin/airtime-silan
|
||||
|
||||
echo "* Creating /var/log/airtime"
|
||||
mkdir -p /var/log/airtime
|
||||
chmod a+x /var/log/airtime
|
||||
chown www-data:www-data /var/log/airtime/
|
||||
chown pypo:pypo /var/log/airtime/pypo
|
||||
chown pypo:pypo /var/log/airtime/pypo-liquidsoap
|
||||
|
||||
|
||||
if [ "$web" = "t" ]; then
|
||||
echo "* Creating /usr/share/airtime"
|
||||
rm -rf "/usr/share/airtime"
|
||||
mkdir -p /usr/share/airtime
|
||||
cp -R $AIRTIMEROOT/airtime_mvc/* /usr/share/airtime/
|
||||
rm -f /etc/logrotate.d/airtime-php
|
||||
cp $AIRTIMEROOT/airtime_mvc/build/airtime-php.logrotate /etc/logrotate.d/airtime-php
|
||||
fi
|
||||
|
||||
echo "* Creating /var/log/airtime"
|
||||
mkdir -p /var/log/airtime
|
||||
|
||||
echo "* Creating /var/tmp/airtime"
|
||||
mkdir -p /var/tmp/airtime
|
||||
|
||||
#Finished copying files
|
|
@ -1,84 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is separated out so that it can be run separately for DEB package installation.
|
||||
* When installing a DEB package, Postgresql may not be installed yet and thus the database
|
||||
* cannot be created. So this script is run after all DEB packages have been installed.
|
||||
*/
|
||||
|
||||
require_once(__DIR__.'/AirtimeIni.php');
|
||||
require_once(__DIR__.'/AirtimeInstall.php');
|
||||
require_once(__DIR__.'/airtime-constants.php');
|
||||
|
||||
require_once(AirtimeInstall::GetAirtimeSrcDir().'/application/configs/conf.php');
|
||||
|
||||
|
||||
//Propel classes.
|
||||
set_include_path(AirtimeInstall::GetAirtimeSrcDir().'/application/models' . PATH_SEPARATOR . get_include_path());
|
||||
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
require_once 'vendor/propel/propel1/runtime/lib/Propel.php';
|
||||
Propel::init(AirtimeInstall::GetAirtimeSrcDir()."/application/configs/airtime-conf-production.php");
|
||||
|
||||
//use this class to set new values in the cache as well.
|
||||
require_once(AirtimeInstall::GetAirtimeSrcDir().'/application/common/Database.php');
|
||||
require_once(AirtimeInstall::GetAirtimeSrcDir().'/application/models/Preference.php');
|
||||
|
||||
echo PHP_EOL."* Database Installation".PHP_EOL;
|
||||
|
||||
AirtimeInstall::CreateDatabaseUser();
|
||||
|
||||
$databaseExisted = AirtimeInstall::CreateDatabase();
|
||||
|
||||
AirtimeInstall::DbConnect(true);
|
||||
|
||||
AirtimeInstall::InstallPostgresScriptingLanguage();
|
||||
|
||||
//Load Database parameters
|
||||
$dbuser = $CC_CONFIG['dsn']['username'];
|
||||
$dbpasswd = $CC_CONFIG['dsn']['password'];
|
||||
$dbname = $CC_CONFIG['dsn']['database'];
|
||||
$dbhost = $CC_CONFIG['dsn']['hostspec'];
|
||||
|
||||
if (isset($argv[1]) && $argv[1] == 'y') {
|
||||
AirtimeInstall::CreateDatabaseTables($dbuser, $dbpasswd, $dbname, $dbhost);
|
||||
} else if ($databaseExisted) {
|
||||
//Database already exists. Ask the user how they want to
|
||||
//proceed. Warn them that creating the database tables again
|
||||
//will cause them to lose their old ones.
|
||||
|
||||
$userAnswer = "x";
|
||||
while (!in_array($userAnswer, array("y", "Y", "n", "N", ""))) {
|
||||
echo PHP_EOL."Database already exists. Do you want to delete all tables and recreate? (y/N)";
|
||||
$userAnswer = trim(fgets(STDIN));
|
||||
}
|
||||
if (in_array($userAnswer, array("y", "Y"))) {
|
||||
AirtimeInstall::CreateDatabaseTables($dbuser, $dbpasswd, $dbname, $dbhost);
|
||||
}
|
||||
} else {
|
||||
//Database was just created, meaning the tables do not
|
||||
//exist. Let's create them.
|
||||
AirtimeInstall::CreateDatabaseTables($dbuser, $dbpasswd, $dbname, $dbhost);
|
||||
}
|
||||
|
||||
echo " * Setting Airtime version".PHP_EOL;
|
||||
AirtimeInstall::SetAirtimeVersion(AIRTIME_VERSION);
|
||||
|
||||
|
||||
if (AirtimeInstall::$databaseTablesCreated) {
|
||||
// set up some keys in DB
|
||||
AirtimeInstall::SetUniqueId();
|
||||
|
||||
$ini = parse_ini_file(__DIR__."/airtime-install.ini");
|
||||
|
||||
$stor_dir = realpath($ini["storage_dir"])."/";
|
||||
echo " * Inserting stor directory location $stor_dir into music_dirs table".PHP_EOL;
|
||||
$con = Propel::getConnection();
|
||||
$sql = "INSERT INTO cc_music_dirs (directory, type) VALUES ('$stor_dir', 'stor')";
|
||||
try {
|
||||
$con->exec($sql);
|
||||
} catch (Exception $e) {
|
||||
echo " * Failed inserting {$stor_dir} in cc_music_dirs".PHP_EOL;
|
||||
echo " * Message {$e->getMessage()}".PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
#!/bin/bash -e
|
||||
#-e Causes bash script to exit if any of the installers
|
||||
#return with a non-zero return value.
|
||||
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "Please run as root user."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set +e
|
||||
dist=`lsb_release -is`
|
||||
echo "Generating locales"
|
||||
for i in `ls /usr/share/airtime/locale | grep ".._.."`; do
|
||||
if [ "$dist" = "Debian" ]; then
|
||||
grep -qi "^$i" /etc/locale.gen
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "$i.UTF-8 UTF-8" >> /etc/locale.gen
|
||||
fi
|
||||
else
|
||||
locale-gen "$i.utf8"
|
||||
fi
|
||||
done
|
||||
set -e
|
||||
|
||||
if [ "$dist" = "Debian" ]; then
|
||||
/usr/sbin/locale-gen
|
||||
fi
|
||||
|
||||
# Absolute path to this script, e.g. /home/user/bin/foo.sh
|
||||
SCRIPT=`readlink -f $0`
|
||||
# Absolute path this script is in, thus /home/user/bin
|
||||
SCRIPTPATH=`dirname $SCRIPT`
|
||||
|
||||
AIRTIMEROOT=$SCRIPTPATH/../../
|
||||
|
||||
if [ "$mediamonitor" = "t" ]; then
|
||||
python $AIRTIMEROOT/python_apps/media-monitor/install/media-monitor-initialize.py
|
||||
fi
|
||||
if [ "$pypo" = "t" ]; then
|
||||
python $AIRTIMEROOT/python_apps/pypo/install/pypo-initialize.py
|
||||
fi
|
||||
|
||||
chmod 600 /etc/monit/conf.d/monit-airtime-generic.cfg
|
||||
chmod 600 /etc/monit/conf.d/monit-airtime-liquidsoap.cfg
|
||||
if [ "$mediamonitor" = "t" ]; then
|
||||
chmod 600 /etc/monit/conf.d/monit-airtime-media-monitor.cfg
|
||||
fi
|
||||
chmod 600 /etc/monit/conf.d/monit-airtime-playout.cfg
|
||||
chmod 600 /etc/monit/conf.d/monit-airtime-liquidsoap.cfg
|
||||
|
||||
# Start monit if it is not running, or restart if it is.
|
||||
# Need to ensure monit is running before Airtime daemons are run. This is
|
||||
# so we can ensure they can register with monit to monitor them when they start.
|
||||
# If monit is already running, this step is still useful as we need monit to
|
||||
# reload its config files.
|
||||
invoke-rc.d monit restart
|
||||
|
||||
#give monit some time to boot-up before issuing commands
|
||||
sleep 1
|
||||
|
||||
set +e
|
||||
if [ "$mediamonitor" = "t" ]; then
|
||||
monit monitor airtime-media-monitor
|
||||
fi
|
||||
if [ "$pypo" = "t" ]; then
|
||||
monit monitor airtime-playout
|
||||
monit monitor airtime-liquidsoap
|
||||
fi
|
||||
set -e
|
|
@ -1 +0,0 @@
|
|||
storage_dir = /srv/airtime/stor/
|
|
@ -1,88 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @package Airtime
|
||||
* @copyright 2011 Sourcefabric O.P.S.
|
||||
* @license http://www.gnu.org/licenses/gpl.txt
|
||||
*/
|
||||
require_once(__DIR__.'/AirtimeIni.php');
|
||||
require_once(__DIR__.'/AirtimeInstall.php');
|
||||
require_once(__DIR__.'/airtime-constants.php');
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// The only way we get here is if we are doing a new install or a reinstall.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
if (PHP_VERSION_ID < 50300) //PHP 5.3
|
||||
{
|
||||
echo("ERROR: Your PHP version is too old!\nAirtime requires PHP 5.3 or greater.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$iniExists = file_exists("/etc/airtime/airtime.conf");
|
||||
if ($iniExists) {
|
||||
//reinstall, Will ask if we should rewrite config files.
|
||||
require_once(AirtimeInstall::GetAirtimeSrcDir().'/application/configs/conf.php');
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
require_once 'vendor/propel/propel1/runtime/lib/Propel.php';
|
||||
Propel::init(AirtimeInstall::GetAirtimeSrcDir()."/application/configs/airtime-conf-production.php");
|
||||
$version = AirtimeInstall::GetVersionInstalled();
|
||||
$newInstall = is_null($version);
|
||||
} else {
|
||||
//create config files without asking
|
||||
$newInstall = true;
|
||||
}
|
||||
|
||||
$overwrite = false;
|
||||
if (getenv("overwrite") == "t" || $newInstall == true) {
|
||||
$overwrite = true;
|
||||
} else if (getenv("preserve") == "f" && getenv("overwrite") == "f" && getenv("reinstall") == "t") {
|
||||
if (AirtimeIni::IniFilesExist()) {
|
||||
$userAnswer = "x";
|
||||
while (!in_array($userAnswer, array("o", "O", "p", "P", ""))) {
|
||||
echo PHP_EOL."You have existing config files. Do you want to (O)verwrite them, or (P)reserve them? (o/P) ";
|
||||
$userAnswer = trim(fgets(STDIN));
|
||||
}
|
||||
if (in_array($userAnswer, array("o", "O"))) {
|
||||
$overwrite = true;
|
||||
}
|
||||
} else {
|
||||
$overwrite = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($overwrite) {
|
||||
echo "* Creating INI files".PHP_EOL;
|
||||
AirtimeIni::CreateIniFiles();
|
||||
echo "* Initializing INI files".PHP_EOL;
|
||||
AirtimeIni::UpdateIniFiles();
|
||||
}
|
||||
if (!$iniExists){
|
||||
require_once(AirtimeInstall::GetAirtimeSrcDir().'/application/configs/conf.php');
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
require_once 'vendor/propel/propel1/runtime/lib/Propel.php';
|
||||
Propel::init(AirtimeInstall::GetAirtimeSrcDir()."/application/configs/airtime-conf-production.php");
|
||||
}
|
||||
|
||||
echo "* Airtime Version: ".AIRTIME_VERSION.PHP_EOL;
|
||||
|
||||
AirtimeInstall::InstallStorageDirectory();
|
||||
|
||||
$db_install = getenv("nodb")!="t";
|
||||
if ($db_install) {
|
||||
|
||||
echo "* Checking database for correct encoding".PHP_EOL;
|
||||
exec('su -c \'psql -t -c "SHOW SERVER_ENCODING"\' postgres | grep -i "UTF.*8"', $out, $return_code);
|
||||
if ($return_code != 0){
|
||||
echo " * Unfortunately your postgresql database has not been created using a UTF-8 encoding.".PHP_EOL;
|
||||
echo " * As of Airtime 2.1, installs will fail unless the encoding has been set to UTF-8. Please verify this is the case".PHP_EOL;
|
||||
echo " * and try the install again".PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if($newInstall) {
|
||||
//call external script. "y" argument means force creation of database tables.
|
||||
passthru('php '.__DIR__.'/airtime-db-install.php y');
|
||||
} else {
|
||||
require_once('airtime-db-install.php');
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Checks if a current version of Airtime is installed.
|
||||
* If so, the user is presented with the help menu and can
|
||||
* choose -r to reinstall.
|
||||
*
|
||||
* Returns 0 if Airtime is not installed
|
||||
* Returns 1 if the same version of Airtime already installed
|
||||
* Returns 2 if a previous version of Airtime is installed we can upgrade from
|
||||
* Returns 3 if a version of Airtime is installed that we can't upgrade from.
|
||||
*/
|
||||
require_once(__DIR__.'/AirtimeInstall.php');
|
||||
require_once(__DIR__.'/airtime-constants.php');
|
||||
|
||||
AirtimeInstall::ExitIfNotRoot();
|
||||
|
||||
if (!file_exists('/etc/airtime/airtime.conf')) {
|
||||
#airtime.conf doesn't exist, and we need it to connect to database
|
||||
#Assume Airtime is not installed.
|
||||
exit(0);
|
||||
}
|
||||
|
||||
require_once(AirtimeInstall::GetAirtimeSrcDir()."/application/configs/db-conf.php");
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
require_once('vendor/propel/propel1/runtime/lib/Propel.php');
|
||||
Propel::init(AirtimeInstall::GetAirtimeSrcDir()."/application/configs/airtime-conf-production.php");
|
||||
|
||||
$version = AirtimeInstall::GetVersionInstalled();
|
||||
|
||||
// The current version is already installed.
|
||||
echo "* Checking for existing Airtime installation...".PHP_EOL;
|
||||
if (isset($version)){
|
||||
if (is_null($version)){
|
||||
//version of Airtime older than 1.7.0 detected
|
||||
exit(3);
|
||||
} else {
|
||||
if (($version == AIRTIME_VERSION)) {
|
||||
//same version of Airtime is already installed
|
||||
exit(1);
|
||||
} else if (strcmp($version, AIRTIME_VERSION) < 0){
|
||||
//previous version of Airtime is installed.
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//no previous version of Airtime found
|
||||
exit(0);
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "Please run as root user."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
########################################################################
|
||||
# Complete list of files that we need to remove is available in
|
||||
# airtime-copy-files.sh
|
||||
#######################################################################
|
||||
|
||||
|
||||
# Absolute path to this script, e.g. /home/user/bin/foo.sh
|
||||
SCRIPT=`readlink -f $0`
|
||||
# Absolute path this script is in, thus /home/user/bin
|
||||
SCRIPTPATH=`dirname $SCRIPT`
|
||||
|
||||
AIRTIMEROOT=$SCRIPTPATH/../../
|
||||
|
||||
rm -f /etc/cron.d/airtime-crons
|
||||
rm -f /etc/monit/conf.d/monit-airtime*
|
||||
rm -f /etc/logrotate.d/airtime-php
|
||||
|
||||
echo "* API Client"
|
||||
python $AIRTIMEROOT/python_apps/api_clients/install/api_client_uninstall.py
|
||||
echo "* Pypo"
|
||||
python $AIRTIMEROOT/python_apps/pypo/install/pypo-remove-files.py
|
||||
echo "* Media-Monitor"
|
||||
python $AIRTIMEROOT/python_apps/media-monitor/install/media-monitor-remove-files.py
|
||||
|
||||
#remove symlinks
|
||||
rm -f /usr/bin/airtime-import
|
||||
rm -f /usr/bin/airtime-check-system
|
||||
rm -f /usr/bin/airtime-log
|
||||
rm -f /usr/bin/airtime-test-soundcard
|
||||
rm -f /usr/bin/airtime-test-stream
|
||||
rm -f /usr/bin/airtime-silan
|
||||
|
||||
rm -rf /usr/lib/airtime
|
||||
rm -rf /usr/share/airtime
|
||||
|
||||
rm -rf /var/log/airtime
|
||||
rm -rf /var/tmp/airtime
|
|
@ -1,31 +0,0 @@
|
|||
#!/bin/bash
|
||||
#-e Causes bash script to exit if any of the installers
|
||||
#return with a non-zero return value.
|
||||
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "Please run as root user."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Absolute path to this script, e.g. /home/user/bin/foo.sh
|
||||
SCRIPT=`readlink -f $0`
|
||||
# Absolute path this script is in, thus /home/user/bin
|
||||
SCRIPTPATH=`dirname $SCRIPT`
|
||||
AIRTIMEROOT=$SCRIPTPATH/../../
|
||||
|
||||
#unmonitor services
|
||||
echo "Unmonitoring Airtime Services"
|
||||
set +e
|
||||
monit unmonitor airtime-media-monitor >/dev/null 2>&1
|
||||
monit unmonitor airtime-liquidsoap >/dev/null 2>&1
|
||||
monit unmonitor airtime-playout >/dev/null 2>&1
|
||||
set -e
|
||||
|
||||
#uninitialize Airtime services
|
||||
python $AIRTIMEROOT/python_apps/pypo/install/pypo-uninitialize.py
|
||||
python $AIRTIMEROOT/python_apps/media-monitor/install/media-monitor-uninitialize.py
|
||||
|
||||
if [ "$purge" = "t" ]; then
|
||||
#call Airtime uninstall script
|
||||
php --php-ini ${SCRIPTPATH}/../airtime-php.ini ${SCRIPTPATH}/airtime-uninstall.php
|
||||
fi
|
|
@ -1,107 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @package Airtime
|
||||
* @copyright 2010 Sourcefabric O.P.S.
|
||||
* @license http://www.gnu.org/licenses/gpl.txt
|
||||
*/
|
||||
|
||||
require_once(dirname(__FILE__).'/AirtimeIni.php');
|
||||
require_once(dirname(__FILE__).'/AirtimeInstall.php');
|
||||
// Need to check that we are superuser before running this.
|
||||
AirtimeInstall::ExitIfNotRoot();
|
||||
|
||||
if (!file_exists(AirtimeIni::CONF_FILE_AIRTIME)) {
|
||||
echo PHP_EOL."Airtime config file '".AirtimeIni::CONF_FILE_AIRTIME."' does not exist.".PHP_EOL;
|
||||
echo "Most likely this means that Airtime is not installed, so there is nothing to do.".PHP_EOL.PHP_EOL;
|
||||
exit();
|
||||
}
|
||||
require_once(__DIR__.'/airtime-constants.php');
|
||||
require_once(AirtimeInstall::GetAirtimeSrcDir().'/application/configs/conf.php');
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
|
||||
|
||||
require_once 'propel/runtime/lib/Propel.php';
|
||||
Propel::init(AirtimeInstall::GetAirtimeSrcDir()."/application/configs/airtime-conf-production.php");
|
||||
|
||||
echo PHP_EOL;
|
||||
echo "* Uninstalling Airtime ".AIRTIME_VERSION.PHP_EOL;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Delete the database
|
||||
// Note: Do not put a call to AirtimeInstall::DbConnect()
|
||||
// before this function, it will create a connection to the database
|
||||
// and you wont be able to delete it.
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//close connection for any process id using airtime database since we are about to drop the database.
|
||||
$sql = "SELECT pg_cancel_backend(procpid) FROM pg_stat_activity WHERE datname = 'airtime';";
|
||||
$command = "echo \"$sql\" | su postgres -c psql";
|
||||
@exec($command, $output);
|
||||
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
echo " * Dropping the database '".$CC_CONFIG["dsn"]["database"]."'...".PHP_EOL;
|
||||
|
||||
//dropdb returns 1 if other sessions are using the database, otherwise returns 0
|
||||
$command = "su postgres -c \"dropdb ".$CC_CONFIG["dsn"]["database"]."\"";
|
||||
|
||||
@exec($command, $output, $dbDeleteFailed);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Delete DB tables
|
||||
// We do this if dropping the database fails above.
|
||||
//------------------------------------------------------------------------
|
||||
if ($dbDeleteFailed) {
|
||||
$connected = AirtimeInstall::DbConnect(false);
|
||||
|
||||
if ($connected) {
|
||||
echo " * Couldn't delete the database, so deleting all the DB tables...".PHP_EOL;
|
||||
$con = Propel::getConnection();
|
||||
$sql = "select * from pg_tables where tableowner = 'airtime'";
|
||||
try {
|
||||
$rows = $con->query($sql)->fetchAll();
|
||||
} catch (Exception $e) {
|
||||
$rows = array();
|
||||
}
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$tablename = $row["tablename"];
|
||||
echo " * Removing database table $tablename...";
|
||||
|
||||
$sql = "DROP TABLE $tablename CASCADE";
|
||||
AirtimeInstall::InstallQuery($sql, false);
|
||||
AirtimeInstall::DropSequence($tablename."_id");
|
||||
echo "done.".PHP_EOL;
|
||||
}
|
||||
|
||||
|
||||
echo " * Deleting database sequences...".PHP_EOL;
|
||||
$sql = "SELECT c.relname FROM pg_class c WHERE c.relkind = 'S';";
|
||||
try {
|
||||
$rows = $con->query($sql)->fetchAll();
|
||||
} catch (Exception $e) {
|
||||
$rows = array();
|
||||
}
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$sequence = $row["relname"];
|
||||
echo " * Removing database sequence $sequence...";
|
||||
|
||||
$sql = "DROP SEQUENCE $sequence CASCADE";
|
||||
AirtimeInstall::InstallQuery($sql, false);
|
||||
echo "done.".PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Delete the user
|
||||
//------------------------------------------------------------------------
|
||||
echo " * Deleting database user '{$CC_CONFIG['dsn']['username']}'...".PHP_EOL;
|
||||
$command = "echo \"DROP USER IF EXISTS {$CC_CONFIG['dsn']['username']}\" | su postgres -c psql >/dev/null 2>&1";
|
||||
@exec($command, $output, $results);
|
||||
if ($results == 0) {
|
||||
echo " * User '{$CC_CONFIG['dsn']['username']}' deleted.".PHP_EOL;
|
||||
} else {
|
||||
echo " * Nothing to delete.".PHP_EOL;
|
||||
}
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @package Airtime
|
||||
* @subpackage StorageServer
|
||||
* @copyright 2010 Sourcefabric O.P.S.
|
||||
* @license http://www.gnu.org/licenses/gpl.txt
|
||||
*/
|
||||
if (posix_geteuid() != 0) {
|
||||
echo "Must be root user.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once(__DIR__.'/airtime-constants.php');
|
||||
require_once(__DIR__.'/AirtimeIni.php');
|
||||
require_once(__DIR__.'/AirtimeInstall.php');
|
||||
require_once 'vendor/propel/propel1/runtime/lib/Propel.php';
|
||||
Propel::init(AirtimeInstall::GetAirtimeSrcDir()."/application/configs/db-conf.php");
|
||||
Propel::init(AirtimeInstall::GetAirtimeSrcDir()."/application/configs/airtime-conf-production.php");
|
||||
|
||||
|
||||
function pause()
|
||||
{
|
||||
/* Type "sudo -s" to change to root user then type "export AIRTIME_INSTALL_DEBUG=1" and then
|
||||
* start airtime-install to enable this feature. Is used to pause between upgrade scripts
|
||||
* to examine the state of the system and see if everything is as expected. */
|
||||
if (getenv("AIRTIME_INSTALL_DEBUG") === "1") {
|
||||
echo "Press Enter to Continue".PHP_EOL;
|
||||
fgets(STDIN);
|
||||
}
|
||||
}
|
||||
|
||||
AirtimeInstall::DbConnect(true);
|
||||
$con = Propel::getConnection();
|
||||
|
||||
$version = AirtimeInstall::GetVersionInstalled();
|
||||
|
||||
//Enforce a minimum PHP version
|
||||
if (!AirtimeInstall::checkPHPVersion())
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
|
||||
echo "******************************** Upgrade Begin *********************************".PHP_EOL;
|
||||
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
$user = $CC_CONFIG['dsn']['username'];
|
||||
$password = $CC_CONFIG['dsn']['password'];
|
||||
$host = $CC_CONFIG['dsn']['hostspec'];
|
||||
$database = $CC_CONFIG['dsn']['database'];
|
||||
$airtime_version = AIRTIME_VERSION;
|
||||
|
||||
$target_dir = trim(getenv("HOME"));
|
||||
if (strlen($target_dir) == 0) {
|
||||
$target_dir = "/tmp";
|
||||
}
|
||||
|
||||
$target_file = "/airtime_$airtime_version.sql";
|
||||
$target_path = $target_dir.$target_file;
|
||||
echo "* Backing up current database to $target_path".PHP_EOL;
|
||||
exec("export PGPASSWORD=$password && pg_dump -h $host -U $user -f $target_path $database", $arr, $return_code);
|
||||
if ($return_code == 0) {
|
||||
echo " * Success".PHP_EOL;
|
||||
} else {
|
||||
echo " * Failed".PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Stop media-monitor and disable it -- Airtime 2.5.3+
|
||||
@exec("service media-monitor stop-with-monit");
|
||||
@exec("rm /etc/init.d/airtime-media-monitor");
|
||||
|
||||
|
||||
//convert strings like 1.9.0-devel to 1.9.0
|
||||
$version = substr($version, 0, 5);
|
||||
|
||||
$SCRIPTPATH = __DIR__;
|
||||
|
||||
if (strcmp($version, "2.2.0") < 0) {
|
||||
echo "Unsupported Airtime version. You must upgrade from at least Airtime 2.2.0.".PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
if (strcmp($version, "2.2.1") < 0) {
|
||||
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini $SCRIPTPATH/../upgrades/airtime-2.2.1/airtime-upgrade.php");
|
||||
pause();
|
||||
}
|
||||
if (strcmp($version, "2.3.0") < 0) {
|
||||
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini $SCRIPTPATH/../upgrades/airtime-2.3.0/airtime-upgrade.php");
|
||||
pause();
|
||||
}
|
||||
if (strcmp($version, "2.3.1") < 0) {
|
||||
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini $SCRIPTPATH/../upgrades/airtime-2.3.1/airtime-upgrade.php");
|
||||
pause();
|
||||
}
|
||||
if (strcmp($version, "2.4.0") < 0) {
|
||||
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini $SCRIPTPATH/../upgrades/airtime-2.4.0/airtime-upgrade.php");
|
||||
pause();
|
||||
}
|
||||
if (strcmp($version, "2.4.1") < 0) {
|
||||
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini $SCRIPTPATH/../upgrades/airtime-2.4.1/airtime-upgrade.php");
|
||||
pause();
|
||||
}
|
||||
if (strcmp($version, "2.5.0") < 0) {
|
||||
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini $SCRIPTPATH/../upgrades/airtime-2.5.0/airtime-upgrade.php");
|
||||
pause();
|
||||
}
|
||||
if (strcmp($version, "2.5.1") < 0) {
|
||||
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini $SCRIPTPATH/../upgrades/airtime-2.5.1/airtime-upgrade.php");
|
||||
pause();
|
||||
}
|
||||
if (strcmp($version, "2.5.3") < 0) {
|
||||
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini $SCRIPTPATH/../upgrades/airtime-2.5.3/airtime-upgrade.php");
|
||||
pause();
|
||||
}
|
||||
echo "******************************* Upgrade Complete *******************************".PHP_EOL;
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
/* This class deals with any modifications to config files in /etc/airtime
|
||||
* as well as backups. All functions other than start() should be marked
|
||||
* as private. */
|
||||
class AirtimeConfigFileUpgrade{
|
||||
|
||||
public static function start(){
|
||||
echo "* Updating configFiles".PHP_EOL;
|
||||
self::task0();
|
||||
}
|
||||
|
||||
private static function task0(){
|
||||
UpgradeCommon::upgradeConfigFiles();
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
<?php
|
||||
|
||||
/* All functions other than start() should be marked as
|
||||
* private.
|
||||
*/
|
||||
class AirtimeDatabaseUpgrade{
|
||||
|
||||
public static function start($p_dbValues){
|
||||
echo "* Updating Database".PHP_EOL;
|
||||
self::task0($p_dbValues);
|
||||
echo " * Complete".PHP_EOL;
|
||||
}
|
||||
|
||||
private static function task0($p_dbValues){
|
||||
|
||||
$username = $p_dbValues['database']['dbuser'];
|
||||
$password = $p_dbValues['database']['dbpass'];
|
||||
$host = $p_dbValues['database']['host'];
|
||||
$database = $p_dbValues['database']['dbname'];
|
||||
$dir = __DIR__;
|
||||
|
||||
passthru("export PGPASSWORD=$password && psql -h $host -U $username -q -f $dir/data/upgrade.sql $database 2>&1 | grep -v \"will create implicit index\"");
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
need to install the following packages:
|
||||
|
||||
mp3gain
|
||||
vorbisgain
|
||||
flac
|
||||
vorbis-tools
|
||||
|
||||
|
||||
calculate Replay Gain dB on upgrade: the default value should be NULL.
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
|
||||
require_once 'DbUpgrade.php';
|
||||
require_once 'ConfFileUpgrade.php';
|
||||
require_once 'common/UpgradeCommon.php';
|
||||
|
||||
$filename = "/etc/airtime/airtime.conf";
|
||||
$values = parse_ini_file($filename, true);
|
||||
|
||||
AirtimeConfigFileUpgrade::start();
|
||||
AirtimeDatabaseUpgrade::start($values);
|
|
@ -1,322 +0,0 @@
|
|||
<?php
|
||||
/* These are helper functions that are common to each upgrade such as
|
||||
* creating connections to a database, backing up config files etc.
|
||||
*/
|
||||
class UpgradeCommon{
|
||||
const CONF_FILE_AIRTIME = "/etc/airtime/airtime.conf";
|
||||
const CONF_FILE_PYPO = "/etc/airtime/pypo.cfg";
|
||||
const CONF_FILE_LIQUIDSOAP = "/etc/airtime/liquidsoap.cfg";
|
||||
const CONF_FILE_MEDIAMONITOR = "/etc/airtime/media-monitor.cfg";
|
||||
const CONF_FILE_API_CLIENT = "/etc/airtime/api_client.cfg";
|
||||
|
||||
const CONF_PYPO_GRP = "pypo";
|
||||
const CONF_WWW_DATA_GRP = "www-data";
|
||||
const CONF_BACKUP_SUFFIX = "220";
|
||||
const VERSION_NUMBER = "2.2.0";
|
||||
|
||||
public static function SetDefaultTimezone()
|
||||
{
|
||||
$sql = "SELECT valstr from cc_pref WHERE keystr = 'timezone'";
|
||||
|
||||
$result = self::queryDb($sql);
|
||||
$timezone = $result->fetchColumn();
|
||||
|
||||
date_default_timezone_set($timezone);
|
||||
}
|
||||
|
||||
public static function connectToDatabase($p_exitOnError = true)
|
||||
{
|
||||
try {
|
||||
$con = Propel::getConnection();
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage().PHP_EOL;
|
||||
echo "Database connection problem.".PHP_EOL;
|
||||
echo "Check if database exists with corresponding permissions.".PHP_EOL;
|
||||
if ($p_exitOnError) {
|
||||
exit(1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static function DbTableExists($p_name)
|
||||
{
|
||||
$con = Propel::getConnection();
|
||||
try {
|
||||
$sql = "SELECT * FROM ".$p_name." LIMIT 1";
|
||||
$con->query($sql);
|
||||
} catch (PDOException $e){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static function GetAirtimeSrcDir()
|
||||
{
|
||||
return __DIR__."/../../../../airtime_mvc";
|
||||
}
|
||||
|
||||
public static function MigrateTablesToVersion($dir, $version)
|
||||
{
|
||||
echo "Upgrading database, may take several minutes, please wait".PHP_EOL;
|
||||
|
||||
$appDir = self::GetAirtimeSrcDir();
|
||||
$command = "php --php-ini $dir/../../airtime-php.ini ".
|
||||
"$appDir/library/doctrine/migrations/doctrine-migrations.phar ".
|
||||
"--configuration=$dir/common/migrations.xml ".
|
||||
"--db-configuration=$appDir/library/doctrine/migrations/migrations-db.php ".
|
||||
"--no-interaction migrations:migrate $version";
|
||||
system($command);
|
||||
}
|
||||
|
||||
public static function BypassMigrations($dir, $version)
|
||||
{
|
||||
$appDir = self::GetAirtimeSrcDir();
|
||||
$command = "php --php-ini $dir/../../airtime-php.ini ".
|
||||
"$appDir/library/doctrine/migrations/doctrine-migrations.phar ".
|
||||
"--configuration=$dir/common/migrations.xml ".
|
||||
"--db-configuration=$appDir/library/doctrine/migrations/migrations-db.php ".
|
||||
"--no-interaction --add migrations:version $version";
|
||||
system($command);
|
||||
}
|
||||
|
||||
public static function upgradeConfigFiles(){
|
||||
|
||||
$configFiles = array(UpgradeCommon::CONF_FILE_AIRTIME,
|
||||
UpgradeCommon::CONF_FILE_PYPO,
|
||||
//this is not necessary because liquidsoap configs
|
||||
//are automatically generated
|
||||
//UpgradeCommon::CONF_FILE_LIQUIDSOAP,
|
||||
UpgradeCommon::CONF_FILE_MEDIAMONITOR,
|
||||
UpgradeCommon::CONF_FILE_API_CLIENT);
|
||||
|
||||
// Backup the config files
|
||||
$suffix = date("Ymdhis")."-".UpgradeCommon::VERSION_NUMBER;
|
||||
foreach ($configFiles as $conf) {
|
||||
// do not back up monit cfg -- ok?? not being done anyway
|
||||
if (file_exists($conf)) {
|
||||
echo "Backing up $conf to $conf$suffix.bak".PHP_EOL;
|
||||
//copy($conf, $conf.$suffix.".bak");
|
||||
exec("cp -p $conf $conf$suffix.bak"); //use cli version to preserve file attributes
|
||||
}
|
||||
}
|
||||
|
||||
self::CreateIniFiles(UpgradeCommon::CONF_BACKUP_SUFFIX);
|
||||
self::MergeConfigFiles($configFiles, $suffix);
|
||||
|
||||
//HACK: This will fix a last minute bug we discovered with our upgrade scripts.
|
||||
//Will be fixed properly in 2.3.0
|
||||
$old = "list_all_db_files = 'list-all-files/format/json/api_key/%%api_key%%/dir_id/%%dir_id%%'";
|
||||
$new = "list_all_db_files = 'list-all-files/format/json/api_key/%%api_key%%/dir_id/%%dir_id%%/all/%%all%%'";
|
||||
exec("sed -i \"s#$old#$new#g\" /etc/airtime/api_client.cfg");
|
||||
|
||||
$old = "update_start_playing_url = 'notify-media-item-start-play/api_key/%%api_key%%/media_id/%%media_id%%/schedule_id/%%schedule_id%%'";
|
||||
$new = "update_start_playing_url = 'notify-media-item-start-play/api_key/%%api_key%%/media_id/%%media_id%%/'";
|
||||
exec("sed -i \"s#$old#$new#g\" /etc/airtime/api_client.cfg");
|
||||
}
|
||||
|
||||
/**
|
||||
* This function creates the /etc/airtime configuration folder
|
||||
* and copies the default config files to it.
|
||||
*/
|
||||
public static function CreateIniFiles($suffix)
|
||||
{
|
||||
if (!file_exists("/etc/airtime/")){
|
||||
if (!mkdir("/etc/airtime/", 0755, true)){
|
||||
echo "Could not create /etc/airtime/ directory. Exiting.";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
$config_copy = array(
|
||||
"../etc/airtime.conf" => self::CONF_FILE_AIRTIME,
|
||||
"../etc/pypo.cfg" => self::CONF_FILE_PYPO,
|
||||
"../etc/media-monitor.cfg" => self::CONF_FILE_MEDIAMONITOR,
|
||||
"../etc/api_client.cfg" => self::CONF_FILE_API_CLIENT
|
||||
);
|
||||
|
||||
echo "Copying configs:\n";
|
||||
foreach ($config_copy as $path_part => $destination) {
|
||||
$full_path = OsPath::normpath(OsPath::join(__DIR__,
|
||||
"$path_part.$suffix"));
|
||||
echo "'$full_path' --> '$destination'\n";
|
||||
if(!copy($full_path, $destination)) {
|
||||
echo "Failed on the copying operation above\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function MergeConfigFiles(array $configFiles, $suffix) {
|
||||
foreach ($configFiles as $conf) {
|
||||
if (file_exists("$conf$suffix.bak")) {
|
||||
|
||||
if($conf === self::CONF_FILE_AIRTIME) {
|
||||
// Parse with sections
|
||||
$newSettings = parse_ini_file($conf, true);
|
||||
$oldSettings = parse_ini_file("$conf$suffix.bak", true);
|
||||
}
|
||||
else {
|
||||
$newSettings = self::ReadPythonConfig($conf);
|
||||
$oldSettings = self::ReadPythonConfig("$conf$suffix.bak");
|
||||
}
|
||||
|
||||
$settings = array_keys($newSettings);
|
||||
|
||||
foreach($settings as $section) {
|
||||
if(isset($oldSettings[$section])) {
|
||||
if(is_array($oldSettings[$section])) {
|
||||
$sectionKeys = array_keys($newSettings[$section]);
|
||||
foreach($sectionKeys as $sectionKey) {
|
||||
|
||||
if(isset($oldSettings[$section][$sectionKey])) {
|
||||
self::UpdateIniValue($conf, $sectionKey,
|
||||
$oldSettings[$section][$sectionKey]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self::UpdateIniValue($conf, $section,
|
||||
$oldSettings[$section]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function ReadPythonConfig($p_filename)
|
||||
{
|
||||
$values = array();
|
||||
|
||||
$fh = fopen($p_filename, 'r');
|
||||
|
||||
while(!feof($fh)){
|
||||
$line = fgets($fh);
|
||||
if(substr(trim($line), 0, 1) == '#' || trim($line) == ""){
|
||||
continue;
|
||||
}else{
|
||||
$info = explode('=', $line, 2);
|
||||
$values[trim($info[0])] = trim($info[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function updates an INI style config file.
|
||||
*
|
||||
* A property and the value the property should be changed to are
|
||||
* supplied. If the property is not found, then no changes are made.
|
||||
*
|
||||
* @param string $p_filename
|
||||
* The path the to the file.
|
||||
* @param string $p_property
|
||||
* The property to look for in order to change its value.
|
||||
* @param string $p_value
|
||||
* The value the property should be changed to.
|
||||
*
|
||||
*/
|
||||
private static function UpdateIniValue($p_filename, $p_property, $p_value)
|
||||
{
|
||||
$lines = file($p_filename);
|
||||
$n = count($lines);
|
||||
foreach ($lines as &$line) {
|
||||
if ($line[0] != "#"){
|
||||
$key_value = explode("=", $line);
|
||||
$key = trim($key_value[0]);
|
||||
|
||||
if ($key == $p_property){
|
||||
$line = "$p_property = $p_value".PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$fp=fopen($p_filename, 'w');
|
||||
for($i=0; $i<$n; $i++){
|
||||
fwrite($fp, $lines[$i]);
|
||||
}
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
public static function queryDb($p_sql){
|
||||
$con = Propel::getConnection();
|
||||
|
||||
try {
|
||||
$result = $con->query($p_sql);
|
||||
} catch (Exception $e) {
|
||||
echo "Error executing $p_sql. Exiting.";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
class OsPath {
|
||||
// this function is from http://stackoverflow.com/questions/2670299/is-there-a-php-equivalent-function-to-the-python-os-path-normpath
|
||||
public static function normpath($path)
|
||||
{
|
||||
if (empty($path))
|
||||
return '.';
|
||||
|
||||
if (strpos($path, '/') === 0)
|
||||
$initial_slashes = true;
|
||||
else
|
||||
$initial_slashes = false;
|
||||
if (
|
||||
($initial_slashes) &&
|
||||
(strpos($path, '//') === 0) &&
|
||||
(strpos($path, '///') === false)
|
||||
)
|
||||
$initial_slashes = 2;
|
||||
$initial_slashes = (int) $initial_slashes;
|
||||
|
||||
$comps = explode('/', $path);
|
||||
$new_comps = array();
|
||||
foreach ($comps as $comp)
|
||||
{
|
||||
if (in_array($comp, array('', '.')))
|
||||
continue;
|
||||
if (
|
||||
($comp != '..') ||
|
||||
(!$initial_slashes && !$new_comps) ||
|
||||
($new_comps && (end($new_comps) == '..'))
|
||||
)
|
||||
array_push($new_comps, $comp);
|
||||
elseif ($new_comps)
|
||||
array_pop($new_comps);
|
||||
}
|
||||
$comps = $new_comps;
|
||||
$path = implode('/', $comps);
|
||||
if ($initial_slashes)
|
||||
$path = str_repeat('/', $initial_slashes) . $path;
|
||||
if ($path)
|
||||
return $path;
|
||||
else
|
||||
return '.';
|
||||
}
|
||||
|
||||
/* Similar to the os.path.join python method
|
||||
* http://stackoverflow.com/a/1782990/276949 */
|
||||
public static function join() {
|
||||
$args = func_get_args();
|
||||
$paths = array();
|
||||
|
||||
foreach($args as $arg) {
|
||||
$paths = array_merge($paths, (array)$arg);
|
||||
}
|
||||
|
||||
foreach($paths as &$path) {
|
||||
$path = trim($path, DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
if (substr($args[0], 0, 1) == DIRECTORY_SEPARATOR) {
|
||||
$paths[0] = DIRECTORY_SEPARATOR . $paths[0];
|
||||
}
|
||||
|
||||
return join(DIRECTORY_SEPARATOR, $paths);
|
||||
}
|
||||
}
|
|
@ -1,227 +0,0 @@
|
|||
DELETE FROM cc_pref WHERE keystr = 'system_version';
|
||||
INSERT INTO cc_pref (keystr, valstr) VALUES ('system_version', '2.2.0');
|
||||
|
||||
--DELETE user column order prefs, since the number of columns has increased in 2.2
|
||||
DELETE FROM cc_pref where keystr = 'library_datatable';
|
||||
DELETE FROM cc_pref where keystr = 'timeline_datatable';
|
||||
|
||||
INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s1_name', 'Airtime!', 'string');
|
||||
INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s2_name', '', 'string');
|
||||
INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s3_name', '', 'string');
|
||||
|
||||
INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s1_channels', 'stereo', 'string');
|
||||
INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s2_channels', 'stereo', 'string');
|
||||
INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s3_channels', 'stereo', 'string');
|
||||
|
||||
|
||||
CREATE FUNCTION airtime_to_int(chartoconvert character varying) RETURNS integer
|
||||
AS
|
||||
'SELECT CASE WHEN trim($1) SIMILAR TO ''[0-9]+'' THEN CAST(trim($1) AS integer) ELSE NULL END;'
|
||||
LANGUAGE SQL
|
||||
IMMUTABLE
|
||||
RETURNS NULL ON NULL INPUT;
|
||||
|
||||
--clean up database of scheduled items that weren't properly deleted in 2.1.x
|
||||
--due to a bug
|
||||
DELETE
|
||||
FROM cc_schedule
|
||||
WHERE id IN
|
||||
(SELECT s.id
|
||||
FROM cc_schedule s
|
||||
LEFT JOIN cc_show_instances si ON s.instance_id = si.id
|
||||
WHERE si.modified_instance = 't');
|
||||
|
||||
ALTER TABLE cc_files
|
||||
DROP CONSTRAINT cc_files_gunid_idx;
|
||||
|
||||
DROP INDEX cc_files_file_exists_idx;
|
||||
|
||||
DROP TABLE cc_access;
|
||||
|
||||
CREATE SEQUENCE cc_block_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MAXVALUE
|
||||
NO MINVALUE
|
||||
CACHE 1;
|
||||
|
||||
CREATE SEQUENCE cc_blockcontents_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MAXVALUE
|
||||
NO MINVALUE
|
||||
CACHE 1;
|
||||
|
||||
CREATE SEQUENCE cc_blockcriteria_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MAXVALUE
|
||||
NO MINVALUE
|
||||
CACHE 1;
|
||||
|
||||
CREATE SEQUENCE cc_webstream_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MAXVALUE
|
||||
NO MINVALUE
|
||||
CACHE 1;
|
||||
|
||||
CREATE SEQUENCE cc_webstream_metadata_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MAXVALUE
|
||||
NO MINVALUE
|
||||
CACHE 1;
|
||||
|
||||
CREATE TABLE cc_block (
|
||||
id integer DEFAULT nextval('cc_block_id_seq'::regclass) NOT NULL,
|
||||
name character varying(255) DEFAULT ''::character varying NOT NULL,
|
||||
mtime timestamp(6) without time zone,
|
||||
utime timestamp(6) without time zone,
|
||||
creator_id integer,
|
||||
description character varying(512),
|
||||
length interval DEFAULT '00:00:00'::interval,
|
||||
type character varying(7) DEFAULT 'static'::character varying
|
||||
);
|
||||
|
||||
CREATE TABLE cc_blockcontents (
|
||||
id integer DEFAULT nextval('cc_blockcontents_id_seq'::regclass) NOT NULL,
|
||||
block_id integer,
|
||||
file_id integer,
|
||||
"position" integer,
|
||||
cliplength interval DEFAULT '00:00:00'::interval,
|
||||
cuein interval DEFAULT '00:00:00'::interval,
|
||||
cueout interval DEFAULT '00:00:00'::interval,
|
||||
fadein time without time zone DEFAULT '00:00:00'::time without time zone,
|
||||
fadeout time without time zone DEFAULT '00:00:00'::time without time zone
|
||||
);
|
||||
|
||||
CREATE TABLE cc_blockcriteria (
|
||||
id integer DEFAULT nextval('cc_blockcriteria_id_seq'::regclass) NOT NULL,
|
||||
criteria character varying(32) NOT NULL,
|
||||
modifier character varying(16) NOT NULL,
|
||||
"value" character varying(512) NOT NULL,
|
||||
extra character varying(512),
|
||||
block_id integer NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE cc_webstream (
|
||||
id integer DEFAULT nextval('cc_webstream_id_seq'::regclass) NOT NULL,
|
||||
name character varying(255) NOT NULL,
|
||||
description character varying(255) NOT NULL,
|
||||
url character varying(512) NOT NULL,
|
||||
length interval DEFAULT '00:00:00'::interval NOT NULL,
|
||||
creator_id integer NOT NULL,
|
||||
mtime timestamp(6) without time zone NOT NULL,
|
||||
utime timestamp(6) without time zone NOT NULL,
|
||||
lptime timestamp(6) without time zone,
|
||||
mime character varying(255)
|
||||
);
|
||||
|
||||
CREATE TABLE cc_webstream_metadata (
|
||||
id integer DEFAULT nextval('cc_webstream_metadata_id_seq'::regclass) NOT NULL,
|
||||
instance_id integer NOT NULL,
|
||||
start_time timestamp without time zone NOT NULL,
|
||||
liquidsoap_data character varying(1024) NOT NULL
|
||||
);
|
||||
|
||||
ALTER TABLE cc_files
|
||||
DROP COLUMN gunid,
|
||||
ADD COLUMN replay_gain numeric,
|
||||
ADD COLUMN owner_id integer,
|
||||
ALTER COLUMN bpm TYPE integer using airtime_to_int(bpm) /* TYPE change - table: cc_files original: character varying(8) new: integer */;
|
||||
|
||||
ALTER TABLE cc_files
|
||||
ADD CONSTRAINT cc_files_owner_fkey FOREIGN KEY (owner_id) REFERENCES cc_subjs(id);
|
||||
|
||||
ALTER TABLE cc_playlistcontents
|
||||
ADD COLUMN block_id integer,
|
||||
ADD COLUMN stream_id integer,
|
||||
ADD COLUMN type smallint DEFAULT 0 NOT NULL;
|
||||
|
||||
ALTER TABLE cc_schedule
|
||||
ADD COLUMN stream_id integer;
|
||||
|
||||
CREATE INDEX cc_schedule_instance_id_idx
|
||||
ON cc_schedule
|
||||
USING btree
|
||||
(instance_id);
|
||||
|
||||
|
||||
ALTER TABLE cc_subjs
|
||||
ADD COLUMN cell_phone character varying(255);
|
||||
|
||||
ALTER TABLE cc_block
|
||||
ADD CONSTRAINT cc_block_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE cc_blockcontents
|
||||
ADD CONSTRAINT cc_blockcontents_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE cc_blockcriteria
|
||||
ADD CONSTRAINT cc_blockcriteria_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE cc_webstream
|
||||
ADD CONSTRAINT cc_webstream_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE cc_webstream_metadata
|
||||
ADD CONSTRAINT cc_webstream_metadata_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE cc_block
|
||||
ADD CONSTRAINT cc_block_createdby_fkey FOREIGN KEY (creator_id) REFERENCES cc_subjs(id);
|
||||
|
||||
ALTER TABLE cc_blockcontents
|
||||
ADD CONSTRAINT cc_blockcontents_block_id_fkey FOREIGN KEY (block_id) REFERENCES cc_block(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE cc_blockcontents
|
||||
ADD CONSTRAINT cc_blockcontents_file_id_fkey FOREIGN KEY (file_id) REFERENCES cc_files(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE cc_blockcriteria
|
||||
ADD CONSTRAINT cc_blockcontents_block_id_fkey FOREIGN KEY (block_id) REFERENCES cc_block(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE cc_playlistcontents
|
||||
ADD CONSTRAINT cc_playlistcontents_block_id_fkey FOREIGN KEY (block_id) REFERENCES cc_block(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE cc_schedule
|
||||
ADD CONSTRAINT cc_show_stream_fkey FOREIGN KEY (stream_id) REFERENCES cc_webstream(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE cc_webstream_metadata
|
||||
ADD CONSTRAINT cc_schedule_inst_fkey FOREIGN KEY (instance_id) REFERENCES cc_schedule(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
|
||||
|
||||
ALTER TABLE cc_playlist
|
||||
DROP CONSTRAINT cc_playlist_createdby_fkey;
|
||||
|
||||
ALTER SEQUENCE cc_block_id_seq
|
||||
OWNED BY cc_block.id;
|
||||
|
||||
ALTER SEQUENCE cc_blockcontents_id_seq
|
||||
OWNED BY cc_blockcontents.id;
|
||||
|
||||
ALTER SEQUENCE cc_blockcriteria_id_seq
|
||||
OWNED BY cc_blockcriteria.id;
|
||||
|
||||
ALTER SEQUENCE cc_webstream_id_seq
|
||||
OWNED BY cc_webstream.id;
|
||||
|
||||
ALTER SEQUENCE cc_webstream_metadata_id_seq
|
||||
OWNED BY cc_webstream_metadata.id;
|
||||
|
||||
ALTER TABLE cc_playlist
|
||||
ADD CONSTRAINT cc_playlist_createdby_fkey FOREIGN KEY (creator_id) REFERENCES cc_subjs(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
|
||||
|
||||
DROP FUNCTION airtime_to_int(chartoconvert character varying);
|
||||
|
||||
UPDATE cc_files
|
||||
SET owner_id=(SELECT id FROM cc_subjs WHERE type='A' LIMIT 1)
|
||||
WHERE owner_id is NULL;
|
||||
|
||||
UPDATE cc_files
|
||||
SET mime='audio/ogg'
|
||||
WHERE mime='audio/vorbis';
|
||||
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
[database]
|
||||
host = localhost
|
||||
dbname = airtime
|
||||
dbuser = airtime
|
||||
dbpass = airtime
|
||||
|
||||
[rabbitmq]
|
||||
host = 127.0.0.1
|
||||
port = 5672
|
||||
user = guest
|
||||
password = guest
|
||||
vhost = /
|
||||
|
||||
[general]
|
||||
api_key = AAA
|
||||
web_server_user = www-data
|
||||
airtime_dir = x
|
||||
base_url = localhost
|
||||
base_port = 80
|
||||
|
||||
;How many hours ahead of time should Airtime playout engine (PYPO)
|
||||
;cache scheduled media files.
|
||||
cache_ahead_hours = 1
|
||||
|
||||
[monit]
|
||||
monit_user = guest
|
||||
monit_password = airtime
|
||||
|
||||
[soundcloud]
|
||||
connection_retries = 3
|
||||
time_between_retries = 60
|
|
@ -1,121 +0,0 @@
|
|||
bin_dir = "/usr/lib/airtime/api_clients"
|
||||
|
||||
#############################
|
||||
## Common
|
||||
#############################
|
||||
|
||||
# Value needed to access the API
|
||||
api_key = 'AAA'
|
||||
|
||||
# Path to the base of the API
|
||||
api_base = 'api'
|
||||
|
||||
# URL to get the version number of the server API
|
||||
version_url = 'version/api_key/%%api_key%%'
|
||||
|
||||
#URL to register a components IP Address with the central web server
|
||||
register_component = 'register-component/format/json/api_key/%%api_key%%/component/%%component%%'
|
||||
|
||||
# Hostname
|
||||
base_url = 'localhost'
|
||||
base_port = 80
|
||||
|
||||
#############################
|
||||
## Config for Media Monitor
|
||||
#############################
|
||||
|
||||
# URL to setup the media monitor
|
||||
media_setup_url = 'media-monitor-setup/format/json/api_key/%%api_key%%'
|
||||
|
||||
# Tell Airtime the file id associated with a show instance.
|
||||
upload_recorded = 'upload-recorded/format/json/api_key/%%api_key%%/fileid/%%fileid%%/showinstanceid/%%showinstanceid%%'
|
||||
|
||||
# URL to tell Airtime to update file's meta data
|
||||
update_media_url = 'reload-metadata/format/json/api_key/%%api_key%%/mode/%%mode%%'
|
||||
|
||||
# URL to tell Airtime we want a listing of all files it knows about
|
||||
list_all_db_files = 'list-all-files/format/json/api_key/%%api_key%%/dir_id/%%dir_id%%'
|
||||
|
||||
# URL to tell Airtime we want a listing of all dirs its watching (including the stor dir)
|
||||
list_all_watched_dirs = 'list-all-watched-dirs/format/json/api_key/%%api_key%%'
|
||||
|
||||
# URL to tell Airtime we want to add watched directory
|
||||
add_watched_dir = 'add-watched-dir/format/json/api_key/%%api_key%%/path/%%path%%'
|
||||
|
||||
# URL to tell Airtime we want to add watched directory
|
||||
remove_watched_dir = 'remove-watched-dir/format/json/api_key/%%api_key%%/path/%%path%%'
|
||||
|
||||
# URL to tell Airtime we want to add watched directory
|
||||
set_storage_dir = 'set-storage-dir/format/json/api_key/%%api_key%%/path/%%path%%'
|
||||
|
||||
# URL to tell Airtime about file system mount change
|
||||
update_fs_mount = 'update-file-system-mount/format/json/api_key/%%api_key%%'
|
||||
|
||||
# URL to commit multiple updates from media monitor at the same time
|
||||
|
||||
reload_metadata_group = 'reload-metadata-group/format/json/api_key/%%api_key%%'
|
||||
|
||||
# URL to tell Airtime about file system mount change
|
||||
handle_watched_dir_missing = 'handle-watched-dir-missing/format/json/api_key/%%api_key%%/dir/%%dir%%'
|
||||
|
||||
#############################
|
||||
## Config for Recorder
|
||||
#############################
|
||||
|
||||
# URL to get the schedule of shows set to record
|
||||
show_schedule_url = 'recorded-shows/format/json/api_key/%%api_key%%'
|
||||
|
||||
# URL to upload the recorded show's file to Airtime
|
||||
upload_file_url = 'upload-file/format/json/api_key/%%api_key%%'
|
||||
|
||||
# URL to commit multiple updates from media monitor at the same time
|
||||
|
||||
#number of retries to upload file if connection problem
|
||||
upload_retries = 3
|
||||
|
||||
#time to wait between attempts to upload file if connection problem (in seconds)
|
||||
upload_wait = 60
|
||||
|
||||
################################################################################
|
||||
# Uncomment *one of the sets* of values from the API clients below, and comment
|
||||
# out all the others.
|
||||
################################################################################
|
||||
|
||||
#############################
|
||||
## Config for Pypo
|
||||
#############################
|
||||
|
||||
# Schedule export path.
|
||||
# %%from%% - starting date/time in the form YYYY-MM-DD-hh-mm
|
||||
# %%to%% - starting date/time in the form YYYY-MM-DD-hh-mm
|
||||
export_url = 'schedule/api_key/%%api_key%%'
|
||||
|
||||
get_media_url = 'get-media/file/%%file%%/api_key/%%api_key%%'
|
||||
|
||||
# Update whether a schedule group has begun playing.
|
||||
update_item_url = 'notify-schedule-group-play/api_key/%%api_key%%/schedule_id/%%schedule_id%%'
|
||||
|
||||
# Update whether an audio clip is currently playing.
|
||||
update_start_playing_url = 'notify-media-item-start-play/api_key/%%api_key%%/media_id/%%media_id%%/schedule_id/%%schedule_id%%'
|
||||
|
||||
# URL to tell Airtime we want to get stream setting
|
||||
get_stream_setting = 'get-stream-setting/format/json/api_key/%%api_key%%/'
|
||||
|
||||
#URL to update liquidsoap status
|
||||
update_liquidsoap_status = 'update-liquidsoap-status/format/json/api_key/%%api_key%%/msg/%%msg%%/stream_id/%%stream_id%%/boot_time/%%boot_time%%'
|
||||
|
||||
#URL to check live stream auth
|
||||
check_live_stream_auth = 'check-live-stream-auth/format/json/api_key/%%api_key%%/username/%%username%%/password/%%password%%/djtype/%%djtype%%'
|
||||
|
||||
#URL to update source status
|
||||
update_source_status = 'update-source-status/format/json/api_key/%%api_key%%/sourcename/%%sourcename%%/status/%%status%%'
|
||||
|
||||
get_bootstrap_info = 'get-bootstrap-info/format/json/api_key/%%api_key%%'
|
||||
|
||||
get_files_without_replay_gain = 'get-files-without-replay-gain/api_key/%%api_key%%/dir_id/%%dir_id%%'
|
||||
|
||||
update_replay_gain_value = 'update-replay-gain-value/api_key/%%api_key%%'
|
||||
|
||||
notify_webstream_data = 'notify-webstream-data/api_key/%%api_key%%/media_id/%%media_id%%/format/json'
|
||||
|
||||
notify_liquidsoap_started = 'rabbitmq-do-push/api_key/%%api_key%%/format/json'
|
|
@ -1,31 +0,0 @@
|
|||
api_client = "airtime"
|
||||
|
||||
# where the binary files live
|
||||
bin_dir = '/usr/lib/airtime/media-monitor'
|
||||
|
||||
# where the logging files live
|
||||
log_dir = '/var/log/airtime/media-monitor'
|
||||
|
||||
|
||||
############################################
|
||||
# RabbitMQ settings #
|
||||
############################################
|
||||
rabbitmq_host = 'localhost'
|
||||
rabbitmq_user = 'guest'
|
||||
rabbitmq_password = 'guest'
|
||||
rabbitmq_vhost = '/'
|
||||
|
||||
############################################
|
||||
# Media-Monitor preferences #
|
||||
############################################
|
||||
check_filesystem_events = 5 #how long to queue up events performed on the files themselves.
|
||||
check_airtime_events = 30 #how long to queue metadata input from airtime.
|
||||
|
||||
# MM2 only:
|
||||
touch_interval = 5
|
||||
chunking_number = 450
|
||||
request_max_wait = 3.0
|
||||
rmq_event_wait = 0.1
|
||||
logpath = '/var/log/airtime/media-monitor/media-monitor.log'
|
||||
index_path = '/var/tmp/airtime/media-monitor/last_index'
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
############################################
|
||||
# pypo - configuration #
|
||||
############################################
|
||||
|
||||
# Set the type of client you are using.
|
||||
# Currently supported types:
|
||||
# 1) "obp" = Open Broadcast Platform
|
||||
# 2) "airtime"
|
||||
#
|
||||
api_client = "airtime"
|
||||
|
||||
############################################
|
||||
# Cache Directories #
|
||||
# *include* trailing slash !! #
|
||||
############################################
|
||||
cache_dir = '/var/tmp/airtime/pypo/cache/'
|
||||
file_dir = '/var/tmp/airtime/pypo/files/'
|
||||
tmp_dir = '/var/tmp/airtime/pypo/tmp/'
|
||||
|
||||
############################################
|
||||
# Setup Directories #
|
||||
# Do *not* include trailing slash !! #
|
||||
############################################
|
||||
cache_base_dir = '/var/tmp/airtime/pypo'
|
||||
bin_dir = '/usr/lib/airtime/pypo'
|
||||
log_base_dir = '/var/log/airtime'
|
||||
pypo_log_dir = '/var/log/airtime/pypo'
|
||||
liquidsoap_log_dir = '/var/log/airtime/pypo-liquidsoap'
|
||||
|
||||
############################################
|
||||
# Liquidsoap settings #
|
||||
############################################
|
||||
ls_host = '127.0.0.1'
|
||||
ls_port = '1234'
|
||||
|
||||
############################################
|
||||
# RabbitMQ settings #
|
||||
############################################
|
||||
rabbitmq_host = 'localhost'
|
||||
rabbitmq_user = 'guest'
|
||||
rabbitmq_password = 'guest'
|
||||
rabbitmq_vhost = '/'
|
||||
|
||||
############################################
|
||||
# pypo preferences #
|
||||
############################################
|
||||
|
||||
# Poll interval in seconds.
|
||||
#
|
||||
# This will rarely need to be changed because any schedule changes are
|
||||
# automatically sent to pypo immediately.
|
||||
#
|
||||
# This is how often the poll script downloads new schedules and files from the
|
||||
# server in the event that no changes are made to the schedule.
|
||||
#
|
||||
poll_interval = 3600 # in seconds.
|
||||
|
||||
|
||||
# Push interval in seconds.
|
||||
#
|
||||
# This is how often the push script checks whether it has something new to
|
||||
# push to liquidsoap.
|
||||
#
|
||||
# It's hard to imagine a situation where this should be more than 1 second.
|
||||
#
|
||||
push_interval = 1 # in seconds
|
||||
|
||||
# 'pre' or 'otf'. 'pre' cues while playlist preparation
|
||||
# while 'otf' (on the fly) cues while loading into ls
|
||||
# (needs the post_processor patch)
|
||||
cue_style = 'pre'
|
||||
|
||||
############################################
|
||||
# Recorded Audio settings #
|
||||
############################################
|
||||
record_bitrate = 256
|
||||
record_samplerate = 44100
|
||||
record_channels = 2
|
||||
record_sample_size = 16
|
||||
|
||||
#can be either ogg|mp3, mp3 recording requires installation of the package "lame"
|
||||
record_file_type = 'ogg'
|
||||
|
||||
# base path to store recordered shows at
|
||||
base_recorded_files = '/var/tmp/airtime/show-recorder/'
|
|
@ -1,24 +0,0 @@
|
|||
<?php
|
||||
|
||||
/* All functions other than start() should be marked as
|
||||
* private.
|
||||
*/
|
||||
class AirtimeDatabaseUpgrade{
|
||||
|
||||
public static function start($p_dbValues){
|
||||
echo "* Updating Database".PHP_EOL;
|
||||
self::task0($p_dbValues);
|
||||
echo " * Complete".PHP_EOL;
|
||||
}
|
||||
|
||||
private static function task0($p_dbValues){
|
||||
|
||||
$username = $p_dbValues['database']['dbuser'];
|
||||
$password = $p_dbValues['database']['dbpass'];
|
||||
$host = $p_dbValues['database']['host'];
|
||||
$database = $p_dbValues['database']['dbname'];
|
||||
$dir = __DIR__;
|
||||
|
||||
passthru("export PGPASSWORD=$password && psql -h $host -U $username -q -f $dir/data/upgrade.sql $database 2>&1 | grep -v \"will create implicit index\"");
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue