Merge branch 'devel' of dev.sourcefabric.org:airtime into devel

This commit is contained in:
James 2011-09-22 11:48:07 -04:00
commit b3654c62bc
22 changed files with 524 additions and 152 deletions

View File

@ -14,6 +14,10 @@
-Fixed issue where upgrading from any previous Airtime would set "Toronto/America" as the default timezone
-Fixed playout engine (Pypo) using a large amount of CPU when there was a long history of played shows
-Fixed playout engine (Pypo) using 100% CPU when it could not connect to RabbitMQ
-Fixed issue where incorrect Start Date and Time entered for a new show was not handled gracefully
-Fixed issue where using Cyrillic characters in a show name would sometimes cause it to not play
-Fixed pypo hanging if web server is unavailable
-Fixed items that were being dragged and dropped in the Playlist Builder being obscured by other UI elements.
1.9.3 - August 26th, 2011
*Improvements

View File

@ -656,12 +656,15 @@ class ApiController extends Zend_Controller_Action
$status = array(
"platform"=>Application_Model_Systemstatus::GetPlatformInfo(),
"airtime_version"=>Application_Model_Systemstatus::GetAirtimeVersion(),
"icecast2"=>Application_Model_Systemstatus::GetIcecastStatus(),
"rabbitmq"=>Application_Model_Systemstatus::GetRabbitMqStatus(),
"pypo"=>Application_Model_Systemstatus::GetPypoStatus(),
"liquidsoap"=>Application_Model_Systemstatus::GetLiquidsoapStatus(),
"show_recorder"=>Application_Model_Systemstatus::GetShowRecorderStatus(),
"media_monitor"=>Application_Model_Systemstatus::GetMediaMonitorStatus()
"services"=>array(
"icecast2"=>Application_Model_Systemstatus::GetIcecastStatus(),
"rabbitmq"=>Application_Model_Systemstatus::GetRabbitMqStatus(),
"pypo"=>Application_Model_Systemstatus::GetPypoStatus(),
"liquidsoap"=>Application_Model_Systemstatus::GetLiquidsoapStatus(),
"show_recorder"=>Application_Model_Systemstatus::GetShowRecorderStatus(),
"media_monitor"=>Application_Model_Systemstatus::GetMediaMonitorStatus()
),
"partitions"=>Application_Model_Systemstatus::GetDiskInfo()
);
$this->view->status = $status;

View File

@ -4,20 +4,30 @@ class SystemstatusController extends Zend_Controller_Action
{
public function init()
{
$request = $this->getRequest();
$baseUrl = $request->getBaseUrl();
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/status/status.js','text/javascript');
$this->view->headScript()->appendFile($baseUrl.'/js/sprintf/sprintf-0.7-beta1.js','text/javascript');
}
public function indexAction()
{
$status = array(
"icecast2"=>Application_Model_Systemstatus::GetIcecastStatus(),
$services = array(
"pypo"=>Application_Model_Systemstatus::GetPypoStatus(),
"liquidsoap"=>Application_Model_Systemstatus::GetLiquidsoapStatus(),
"show-recorder"=>Application_Model_Systemstatus::GetShowRecorderStatus(),
"media-monitor"=>Application_Model_Systemstatus::GetMediaMonitorStatus()
"media-monitor"=>Application_Model_Systemstatus::GetMediaMonitorStatus(),
"rabbitmq-server"=>Application_Model_Systemstatus::GetRabbitMqStatus(),
"icecast2"=>Application_Model_Systemstatus::GetIcecastStatus()
);
$partitions = Application_Model_Systemstatus::GetDiskInfo();
$this->view->status = $status;
$this->view->status = new StdClass;
$this->view->status->services = $services;
$this->view->status->partitions = $partitions;
}
public function getLogFileAction()

View File

@ -19,7 +19,8 @@
</div>
<div class="wrapper">
<div id="library_content" class="tabs ui-widget ui-widget-content block-shadow alpha-block padded"><?php echo $this->layout()->library ?></div>
<!--Set to z-index 254 to make it lower than the top-panel and the ZFDebug info bar, but higher than the side-playlist-->
<div id="library_content" class="tabs ui-widget ui-widget-content block-shadow omega-block padded" style="z-index:254"><?php echo $this->layout()->library ?></div>
<div id="side_playlist" class="ui-widget ui-widget-content block-shadow omega-block"><?php echo $this->layout()->spl ?></div>
</div>
</body>

View File

@ -222,8 +222,7 @@ class MusicDir {
->find();
foreach($dirs as $dir) {
$tmp = new MusicDir($dir);
$result[] = $tmp;
$result[] = new MusicDir($dir);
}
return $result;

View File

@ -14,85 +14,102 @@ class Application_Model_Systemstatus
$result = curl_exec($ch);
curl_close($ch);
$xmlDoc = new DOMDocument();
$xmlDoc->loadXML($result);
$docRoot = null;
if ($result != ""){
$xmlDoc = new DOMDocument();
$xmlDoc->loadXML($result);
$docRoot = $xmlDoc->documentElement;
}
return $xmlDoc->documentElement;
return $docRoot;
}
public static function ExtractServiceInformation($p_docRoot, $p_serviceName){
$data = array();
$starting = array("process_id"=>"STARTING...",
"uptime_seconds"=>"STARTING...",
"memory_perc"=>"UNKNOWN",
"memory_kb"=>"UNKNOWN",
"cpu_perc"=>"UNKNOWN");
$starting = array(
"name"=>"",
"process_id"=>"STARTING...",
"uptime_seconds"=>"-1",
"status"=>true,
"memory_perc"=>"0%",
"memory_kb"=>"0",
"cpu_perc"=>"0%");
$notRunning = array("process_id"=>"FAILED",
"uptime_seconds"=>"FAILED",
"memory_perc"=>"UNKNOWN",
"memory_kb"=>"UNKNOWN",
"cpu_perc"=>"UNKNOWN"
$notRunning = array(
"name"=>$p_serviceName,
"process_id"=>"FAILED",
"uptime_seconds"=>"-1",
"status"=>false,
"memory_perc"=>"0%",
"memory_kb"=>"0",
"cpu_perc"=>"0%"
);
$data = $notRunning;
if (!is_null($p_docRoot)){
foreach ($p_docRoot->getElementsByTagName("service") AS $item)
{
if ($item->getElementsByTagName("name")->item(0)->nodeValue == $p_serviceName){
foreach ($p_docRoot->getElementsByTagName("service") AS $item)
{
if ($item->getElementsByTagName("name")->item(0)->nodeValue == $p_serviceName){
$monitor = $item->getElementsByTagName("monitor");
if ($monitor->length > 0){
$status = $monitor->item(0)->nodeValue;
if ($status == "2"){
$data = $starting;
} else if ($status == 0){
$data = $notRunning;
$monitor = $item->getElementsByTagName("monitor");
if ($monitor->length > 0){
$status = $monitor->item(0)->nodeValue;
if ($status == "2"){
$data = $starting;
} else if ($status == 0){
$data = $notRunning;
}
}
}
$process_id = $item->getElementsByTagName("pid");
if ($process_id->length > 0){
$data["process_id"] = $process_id->item(0)->nodeValue;
}
$uptime = $item->getElementsByTagName("uptime");
if ($uptime->length > 0){
$data["uptime_seconds"] = $uptime->item(0)->nodeValue;
$process_id = $item->getElementsByTagName("name");
if ($process_id->length > 0){
$data["name"] = $process_id->item(0)->nodeValue;
}
$process_id = $item->getElementsByTagName("pid");
if ($process_id->length > 0){
$data["process_id"] = $process_id->item(0)->nodeValue;
$data["status"] = true;
}
$uptime = $item->getElementsByTagName("uptime");
if ($uptime->length > 0){
$data["uptime_seconds"] = $uptime->item(0)->nodeValue;
}
$memory = $item->getElementsByTagName("memory");
if ($memory->length > 0){
$data["memory_perc"] = $memory->item(0)->getElementsByTagName("percenttotal")->item(0)->nodeValue."%";
$data["memory_kb"] = $memory->item(0)->getElementsByTagName("kilobytetotal")->item(0)->nodeValue;
}
$cpu = $item->getElementsByTagName("cpu");
if ($cpu->length > 0){
$data["cpu_perc"] = $cpu->item(0)->getElementsByTagName("percent")->item(0)->nodeValue."%";
}
break;
}
$memory = $item->getElementsByTagName("memory");
if ($memory->length > 0){
$data["memory_perc"] = $memory->item(0)->getElementsByTagName("percenttotal")->item(0)->nodeValue."%";
$data["memory_kb"] = $memory->item(0)->getElementsByTagName("kilobytetotal")->item(0)->nodeValue;
}
$cpu = $item->getElementsByTagName("cpu");
if ($cpu->length > 0){
$data["cpu_perc"] = $cpu->item(0)->getElementsByTagName("percent")->item(0)->nodeValue."%";
}
break;
}
}
return $data;
}
public static function GetPlatformInfo(){
$docRoot = self::GetMonitStatus("localhost");
$data = array("release"=>"UNKNOWN",
"machine"=>"UNKNOWN",
"memory"=>"UNKNOWN",
"swap"=>"UNKNOWN");
foreach ($docRoot->getElementsByTagName("platform") AS $item)
{
$data["release"] = $item->getElementsByTagName("release")->item(0)->nodeValue;
$data["machine"] = $item->getElementsByTagName("machine")->item(0)->nodeValue;
$data["memory"] = $item->getElementsByTagName("memory")->item(0)->nodeValue;
$data["swap"] = $item->getElementsByTagName("swap")->item(0)->nodeValue;
$docRoot = self::GetMonitStatus("localhost");
if (!is_null($docRoot)){
foreach ($docRoot->getElementsByTagName("platform") AS $item)
{
$data["release"] = $item->getElementsByTagName("release")->item(0)->nodeValue;
$data["machine"] = $item->getElementsByTagName("machine")->item(0)->nodeValue;
$data["memory"] = $item->getElementsByTagName("memory")->item(0)->nodeValue;
$data["swap"] = $item->getElementsByTagName("swap")->item(0)->nodeValue;
}
}
return $data;
@ -161,6 +178,32 @@ class Application_Model_Systemstatus
public static function GetAirtimeVersion(){
return AIRTIME_VERSION;
}
public static function GetDiskInfo(){
/* First lets get all the watched directories. Then we can group them
* into the same paritions by comparing the partition sizes. */
$musicDirs = MusicDir::getWatchedDirs();
$musicDirs[] = MusicDir::getStorDir();
$partions = array();
foreach($musicDirs as $md){
$totalSpace = disk_total_space($md->getDirectory());
if (!isset($partitions[$totalSpace])){
$partitions[$totalSpace] = new StdClass;
$partitions[$totalSpace]->totalSpace = $totalSpace;
$partitions[$totalSpace]->totalFreeSpace = disk_free_space($md->getDirectory());
}
$partitions[$totalSpace]->dirs[] = $md->getDirectory();
}
return array_values($partitions);
}
/*

View File

@ -1,11 +1,33 @@
<?php foreach($this->status as $key=>$value): ?>
<div>
<?php echo $key; ?>
<?php echo "PID: ".$value["process_id"]; ?>
<?php echo "UPTIME: ".$value["uptime_seconds"]; ?>
<?php if (true): ?>
<a href="systemstatus/get-log-file/id/<?php echo $key ?>">Log file</a>
<?php endif; ?>
</div>
<?php endforeach; ?>
<table width="60%" cellpadding="0" cellspacing="0" border="0" class="statustable">
<thead>
<tr class="ui-state-default strong">
<td>Service</td>
<td>Status</td>
<td>Uptime</td>
<td>CPU</td>
<td>Memory</td>
</tr>
</thead>
<tbody>
<!--
<tr class="odd">
<td>Airtime Version</td>
<td>1.9.3</td>
<td>&nbsp;</td>
</tr>
-->
<?php $i=0; ?>
<?php foreach($this->status->services as $key=>$value): ?>
<tr class="<?php echo ($i&1) == 0 ? "even":"odd"; $i++; ?>" id="<?php echo $value["name"]; ?>">
<td><?php echo $value["name"]; ?></td>
<td><span></span></td>
<td></td>
<td></td>
<td></td>
</tr>
<?php endforeach; ?>
<tr id="partitions" class="even">
<th colspan="5">Disk Space</th>
</tr>
</tbody>
</table>

Binary file not shown.

After

Width:  |  Height:  |  Size: 693 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 957 B

View File

@ -11,6 +11,23 @@ function popup(mylink){
return false;
}
function convertSecondsToDaysHoursMinutesSeconds(seconds){
if (seconds < 0)
seconds = 0;
seconds = parseInt(seconds, 10);
var days = parseInt(seconds / 86400);
seconds -= days*86400;
var hours = parseInt(seconds / 3600);
seconds -= hours*3600;
var minutes = parseInt(seconds / 60);
seconds -= minutes*60;
return {days:days, hours:hours, minutes:minutes, seconds:seconds};
}
/* Takes an input parameter of milliseconds and converts these into
* the format HH:MM:SS */

View File

@ -381,6 +381,9 @@ function setAddShowEvents() {
}else{
duration = '0m';
}
if(isNaN(duration)){
duration = '1h';
}
$('#add_show_duration').val(duration);
}

View File

@ -0,0 +1,66 @@
function generatePartitions(partitions){
var rowTemplate =
'<tr class="partition-info">'+
'<td><span class="strong">Disk #%s</span>'+
'<ul id="watched-dir-list-%s">'+
'</ul>'+
'</td>'+
'<td>%sGB of %sGB</td>'+
'<td colspan="3">'+
'<div class="big">'+
'<div class="diskspace" style="width:%s%%;">'+
'</div>'+
'</div>'+
'<div>%s%% in use</div>'+
'</td>'+
'</tr>';
$(".partition-info").remove();
var lastElement = $('#partitions');
for (var i=0; i<partitions.length; i++){
var spaceUsed = partitions[i].totalSpace-partitions[i].totalFreeSpace;
var totalSpace = partitions[i].totalSpace;
var percUsed = sprintf("%01.1f", spaceUsed/totalSpace*100);
var spaceUsedGb = sprintf("%01.1f", spaceUsed/Math.pow(10, 9));
var totalSpaceGb = sprintf("%01.1f", totalSpace/Math.pow(10, 9));
var row = sprintf(rowTemplate, i, i, spaceUsedGb, totalSpaceGb, percUsed, percUsed);
var tr = $(row);
lastElement.after(tr);
var watched_dirs_ul = $('#watched-dir-list-'+i);
for (var j=0; j<partitions[i].dirs.length; j++){
watched_dirs_ul.append('<li>'+partitions[i].dirs[j]+'</li>');
}
lastElement = tr;
}
}
function success(data, textStatus, jqXHR){
var services = data.status.services;
for (var key in services){
var s = services[key];
var children = $("#"+s.name).children();
$(children[0]).text(s.name);
$($(children[1]).children()[0]).attr("class", s.status ? "checked-icon": "not-available-icon");
$(children[2]).text(sprintf('%(days)sd %(hours)sh %(minutes)sm %(seconds)ss', convertSecondsToDaysHoursMinutesSeconds(s.uptime_seconds)));
$(children[3]).text(s.cpu_perc);
$(children[4]).text(sprintf('%01.1fMB (%s)', parseInt(s.memory_kb)/1000, s.memory_perc));
}
generatePartitions(data.status.partitions);
}
function updateStatus(){
$.getJSON( "api/status/format/json", null, success);
}
$(document).ready(function() {
updateStatus();
setInterval(updateStatus, 5000);
});

View File

@ -0,0 +1,183 @@
/**
sprintf() for JavaScript 0.7-beta1
http://www.diveintojavascript.com/projects/javascript-sprintf
Copyright (c) Alexandru Marasteanu <alexaholic [at) gmail (dot] com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of sprintf() for JavaScript nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL Alexandru Marasteanu BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Changelog:
2010.09.06 - 0.7-beta1
- features: vsprintf, support for named placeholders
- enhancements: format cache, reduced global namespace pollution
2010.05.22 - 0.6:
- reverted to 0.4 and fixed the bug regarding the sign of the number 0
Note:
Thanks to Raphael Pigulla <raph (at] n3rd [dot) org> (http://www.n3rd.org/)
who warned me about a bug in 0.5, I discovered that the last update was
a regress. I appologize for that.
2010.05.09 - 0.5:
- bug fix: 0 is now preceeded with a + sign
- bug fix: the sign was not at the right position on padded results (Kamal Abdali)
- switched from GPL to BSD license
2007.10.21 - 0.4:
- unit test and patch (David Baird)
2007.09.17 - 0.3:
- bug fix: no longer throws exception on empty paramenters (Hans Pufal)
2007.09.11 - 0.2:
- feature: added argument swapping
2007.04.03 - 0.1:
- initial release
**/
var sprintf = (function() {
function get_type(variable) {
return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
}
function str_repeat(input, multiplier) {
for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */}
return output.join('');
}
var str_format = function() {
if (!str_format.cache.hasOwnProperty(arguments[0])) {
str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
}
return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
};
str_format.format = function(parse_tree, argv) {
var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
for (i = 0; i < tree_length; i++) {
node_type = get_type(parse_tree[i]);
if (node_type === 'string') {
output.push(parse_tree[i]);
}
else if (node_type === 'array') {
match = parse_tree[i]; // convenience purposes only
if (match[2]) { // keyword argument
arg = argv[cursor];
for (k = 0; k < match[2].length; k++) {
if (!arg.hasOwnProperty(match[2][k])) {
throw(sprintf('[sprintf] property "%s" does not exist', match[2][k]));
}
arg = arg[match[2][k]];
}
}
else if (match[1]) { // positional argument (explicit)
arg = argv[match[1]];
}
else { // positional argument (implicit)
arg = argv[cursor++];
}
if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
throw(sprintf('[sprintf] expecting number but found %s', get_type(arg)));
}
switch (match[8]) {
case 'b': arg = arg.toString(2); break;
case 'c': arg = String.fromCharCode(arg); break;
case 'd': arg = parseInt(arg, 10); break;
case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
case 'o': arg = arg.toString(8); break;
case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
case 'u': arg = Math.abs(arg); break;
case 'x': arg = arg.toString(16); break;
case 'X': arg = arg.toString(16).toUpperCase(); break;
}
arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
pad_length = match[6] - String(arg).length;
pad = match[6] ? str_repeat(pad_character, pad_length) : '';
output.push(match[5] ? arg + pad : pad + arg);
}
}
return output.join('');
};
str_format.cache = {};
str_format.parse = function(fmt) {
var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
while (_fmt) {
if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
parse_tree.push(match[0]);
}
else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
parse_tree.push('%');
}
else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
if (match[2]) {
arg_names |= 1;
var field_list = [], replacement_field = match[2], field_match = [];
if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
field_list.push(field_match[1]);
while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
field_list.push(field_match[1]);
}
else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
field_list.push(field_match[1]);
}
else {
throw('[sprintf] huh?');
}
}
}
else {
throw('[sprintf] huh?');
}
match[2] = field_list;
}
else {
arg_names |= 2;
}
if (arg_names === 3) {
throw('[sprintf] mixing positional and named placeholders is not (yet) supported');
}
parse_tree.push(match);
}
else {
throw('[sprintf] huh?');
}
_fmt = _fmt.substring(match[0].length);
}
return parse_tree;
};
return str_format;
})();
var vsprintf = function(fmt, argv) {
argv.unshift(fmt);
return sprintf.apply(null, argv);
};

View File

@ -7,7 +7,7 @@ exec > >(tee install_log.txt)
exec 2>&1
if [ "$(id -u)" != "0" ]; then
echo "You need root privileges to run this script"
echo "Please run as root user."
exit 1
fi

View File

@ -2,6 +2,11 @@
#-e Causes bash script to exit if any of the installers
#return with a non-zero return value.
if [ `whoami` != 'root' ]; then
echo "Please run as root user."
exit 1
fi
set +e
DEB=$(dpkg -s airtime 2> /dev/null | grep Status)
set -e
@ -26,7 +31,7 @@ echo -e "\n*** Creating Pypo User ***"
python ${SCRIPTPATH}/../python_apps/create-pypo-user.py
set +e
php --php-ini ${SCRIPTPATH}/airtime-php.ini --file ${SCRIPTPATH}/include/airtime-install.php $@
php --php-ini ${SCRIPTPATH}/airtime-php.ini ${SCRIPTPATH}/include/airtime-install.php $@
result=$?
if [ "$result" -eq "2" ]; then
#We've just finished an upgrade, so let's exit
@ -37,6 +42,15 @@ elif [ "$result" -ne "0" ]; then
fi
set -e
# 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.
/etc/init.d/monit start
# We may have updated the monit config files, and monit was already running.
# In this case the previous "start" command didn't do anything, and we need
# to reload the config files instead.
/etc/init.d/monit force-reload
echo -e "\n*** API Client Installation ***"
python ${SCRIPTPATH}/../python_apps/api_clients/install/api_client_install.py
@ -49,11 +63,11 @@ python ${SCRIPTPATH}/../python_apps/show-recorder/install/recorder-install.py
echo -e "\n*** Media Monitor Installation ***"
python ${SCRIPTPATH}/../python_apps/media-monitor/install/media-monitor-install.py
monit monitor icecast2 >/dev/null 2>&1
monit monitor rabbitmq-server >/dev/null 2>&1
monit monitor icecast2
monit monitor rabbitmq-server
echo -e "\n*** Verifying your system environment ***"
sleep 5
sleep 10
airtime-check-system
echo -e "\n******************************* Install Complete *******************************"

View File

@ -1,5 +1,10 @@
#!/bin/bash
if [ `whoami` != 'root' ]; then
echo "Please run as root user."
exit 1
fi
VIRTUAL_ENV_DIR="/usr/lib/airtime/airtime_virtualenv"
if [ ! -d "$VIRTUAL_ENV_DIR" ]; then
echo -e "\nAirtime is not installed, cannot uninstall.\n"

View File

@ -54,28 +54,28 @@ $version = substr($version, 0, 5);
$SCRIPTPATH = __DIR__;
if (strcmp($version, "1.7.0") < 0){
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini --file $SCRIPTPATH/../upgrades/airtime-1.7.0/airtime-upgrade.php");
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini $SCRIPTPATH/../upgrades/airtime-1.7.0/airtime-upgrade.php");
}
if (strcmp($version, "1.8.0") < 0){
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini --file $SCRIPTPATH/../upgrades/airtime-1.8.0/airtime-upgrade.php");
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini $SCRIPTPATH/../upgrades/airtime-1.8.0/airtime-upgrade.php");
}
if (strcmp($version, "1.8.1") < 0){
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini --file $SCRIPTPATH/../upgrades/airtime-1.8.1/airtime-upgrade.php");
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini $SCRIPTPATH/../upgrades/airtime-1.8.1/airtime-upgrade.php");
}
if (strcmp($version, "1.8.2") < 0){
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini --file $SCRIPTPATH/../upgrades/airtime-1.8.2/airtime-upgrade.php");
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini $SCRIPTPATH/../upgrades/airtime-1.8.2/airtime-upgrade.php");
}
if (strcmp($version, "1.9.0") < 0){
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini --file $SCRIPTPATH/../upgrades/airtime-1.9.0/airtime-upgrade.php");
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini $SCRIPTPATH/../upgrades/airtime-1.9.0/airtime-upgrade.php");
}
if (strcmp($version, "1.9.2") < 0){
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini --file $SCRIPTPATH/../upgrades/airtime-1.9.2/airtime-upgrade.php");
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini $SCRIPTPATH/../upgrades/airtime-1.9.2/airtime-upgrade.php");
}
if (strcmp($version, "1.9.3") < 0){
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini --file $SCRIPTPATH/../upgrades/airtime-1.9.3/airtime-upgrade.php");
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini $SCRIPTPATH/../upgrades/airtime-1.9.3/airtime-upgrade.php");
}
if (strcmp($version, "1.9.4") < 0){
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini --file $SCRIPTPATH/../upgrades/airtime-1.9.4/airtime-upgrade.php");
passthru("php --php-ini $SCRIPTPATH/../airtime-php.ini $SCRIPTPATH/../upgrades/airtime-1.9.4/airtime-upgrade.php");
}
if (strcmp($version, "2.0.0") < 0){
system("php ".__DIR__."/../upgrades/airtime-2.0.0/airtime-upgrade.php");

View File

@ -159,6 +159,26 @@ class AirTimeApiClient(ApiClientInterface):
logger = logging.getLogger()
logger.error('Error loading config file: %s', e)
sys.exit(1)
def get_response_from_server(self, url):
logger = logging.getLogger()
successful_response = False
while not successful_response:
try:
response = urllib.urlopen(url)
data = response.read()
successful_response = True
except IOError, e:
logger.error('Error Authenticating with remote server: %s', e)
except Exception, e:
logger.error('Couldn\'t connect to remote server. Is it running?')
logger.error("%s" % e)
if not successful_response:
time.sleep(5)
return data
def __get_airtime_version(self, verbose = True):
logger = logging.getLogger()
@ -169,30 +189,13 @@ class AirTimeApiClient(ApiClientInterface):
version = -1
response = None
try:
response = urllib.urlopen(url)
data = response.read()
data = self.get_response_from_server(url)
logger.debug("Data: %s", data)
response_json = json.loads(data)
version = response_json['version']
logger.debug("Airtime Version %s detected", version)
except IOError, e:
logger.error("Unable to detect Airtime Version - %s, Response: %s", e, data)
if e[1] == 401:
if (verbose):
logger.info('#####################################')
logger.info('# YOUR API KEY SEEMS TO BE INVALID:')
logger.info('# ' + self.config["api_key"])
logger.info('#####################################')
if e[1] == 404:
if (verbose):
logger.info('#####################################')
logger.info('# Unable to contact the Airtime-API')
logger.info('# ' + url)
logger.info('#####################################')
return -1
except Exception, e:
logger.error("Unable to detect Airtime Version - %s, Response: %s", e, data)
logger.error("Unable to detect Airtime Version - %s", e)
return -1
return version
@ -244,7 +247,7 @@ class AirTimeApiClient(ApiClientInterface):
response = ""
status = 0
try:
response_json = urllib.urlopen(export_url).read()
response_json = self.get_response_from_server(export_url)
response = json.loads(response_json)
status = response['check']
except Exception, e:
@ -334,9 +337,10 @@ class AirTimeApiClient(ApiClientInterface):
url = "http://%s:%s/%s/%s" % (self.config["base_url"], str(self.config["base_port"]), self.config["api_base"], self.config["show_schedule_url"])
logger.debug(url)
url = url.replace("%%api_key%%", self.config["api_key"])
response = self.get_response_from_server(url)
response = urllib.urlopen(url)
response = json.loads(response.read())
response = json.loads(response)
logger.info("shows %s", response)
except Exception, e:
@ -388,14 +392,9 @@ class AirTimeApiClient(ApiClientInterface):
url = "http://%s:%s/%s/%s" % (self.config["base_url"], str(self.config["base_port"]), self.config["api_base"], self.config["media_setup_url"])
url = url.replace("%%api_key%%", self.config["api_key"])
response = urllib.urlopen(url)
response = json.loads(response.read())
response = self.get_response_from_server(url)
response = json.loads(response)
logger.info("Connected to Airtime Server. Json Media Storage Dir: %s", response)
except IOError:
#this should be a common exception when media-monitor daemon
#has started before apache on bootup and apache isn't accepting
#connections yet.
response = None
except Exception, e:
response = None
logger.error("Exception: %s", e)

View File

@ -1,4 +1,4 @@
set daemon 10 # Poll at 10 second intervals
set daemon 10 # Poll at 5 second intervals
#set logfile syslog facility log_daemon
set logfile /var/log/monit.log

View File

@ -437,10 +437,6 @@ class PypoFetch(Thread):
def main(self):
logger = logging.getLogger('fetch')
while not self.init_rabbit_mq():
logger.error("Error connecting to RabbitMQ Server. Trying again in few seconds")
time.sleep(5)
try: os.mkdir(self.cache_dir)
except Exception, e: pass
@ -452,6 +448,11 @@ class PypoFetch(Thread):
self.process_schedule(self.schedule_data, "scheduler", True)
logger.info("Bootstrap complete: got initial copy of the schedule")
while not self.init_rabbit_mq():
logger.error("Error connecting to RabbitMQ Server. Trying again in few seconds")
time.sleep(5)
loops = 1
while True:
logger.info("Loop #%s", loops)

View File

@ -101,13 +101,15 @@ class PypoPush(Thread):
try:
playlist = playlists[pkey]
plstart = schedule[pkey]['start'][0:19]
#strptime returns struct_time in local time
#mktime takes a time_struct and returns a floating point
#gmtime Convert a time expressed in seconds since the epoch to a struct_time in UTC
#mktime: expresses the time in local time, not UTC. It returns a floating point number, for compatibility with time().
epoch_start = calendar.timegm(time.strptime(pkey, '%Y-%m-%d-%H-%M-%S'))
epoch_start = calendar.timegm(time.strptime(plstart, '%Y-%m-%d-%H-%M-%S'))
#Return the time as a floating point number expressed in seconds since the epoch, in UTC.
epoch_now = time.time()

View File

@ -69,30 +69,30 @@ class AirtimeCheck {
self::output_status("TOTAL_MEMORY_MBYTES", $p_status->platform->memory);
self::output_status("TOTAL_SWAP_MBYTES", $p_status->platform->swap);
self::output_status("AIRTIME_VERSION", $p_status->airtime_version);
self::output_status("PLAYOUT_ENGINE_PROCESS_ID", $p_status->pypo->process_id);
self::output_status("PLAYOUT_ENGINE_RUNNING_SECONDS", $p_status->pypo->uptime_seconds);
self::output_status("PLAYOUT_ENGINE_MEM_PERC", $p_status->pypo->memory_perc);
self::output_status("PLAYOUT_ENGINE_CPU_PERC", $p_status->pypo->cpu_perc);
self::output_status("LIQUIDSOAP_PROCESS_ID", $p_status->liquidsoap->process_id);
self::output_status("LIQUIDSOAP_RUNNING_SECONDS", $p_status->liquidsoap->uptime_seconds);
self::output_status("LIQUIDSOAP_MEM_PERC", $p_status->liquidsoap->memory_perc);
self::output_status("LIQUIDSOAP_CPU_PERC", $p_status->liquidsoap->cpu_perc);
self::output_status("MEDIA_MONITOR_PROCESS_ID", $p_status->media_monitor->process_id);
self::output_status("MEDIA_MONITOR_RUNNING_SECONDS", $p_status->media_monitor->uptime_seconds);
self::output_status("MEDIA_MONITOR_MEM_PERC", $p_status->media_monitor->memory_perc);
self::output_status("MEDIA_MONITOR_CPU_PERC", $p_status->media_monitor->cpu_perc);
self::output_status("SHOW_RECORDER_PROCESS_ID", $p_status->show_recorder->process_id);
self::output_status("SHOW_RECORDER_RUNNING_SECONDS", $p_status->show_recorder->uptime_seconds);
self::output_status("SHOW_RECORDER_MEM_PERC", $p_status->show_recorder->memory_perc);
self::output_status("SHOW_RECORDER_CPU_PERC", $p_status->show_recorder->cpu_perc);
self::output_status("ICECAST_PROCESS_ID", $p_status->icecast2->process_id);
self::output_status("ICECAST_RUNNING_SECONDS", $p_status->icecast2->uptime_seconds);
self::output_status("ICECAST_MEM_PERC", $p_status->icecast2->memory_perc);
self::output_status("ICECAST_CPU_PERC", $p_status->icecast2->cpu_perc);
self::output_status("RABBITMQ_PROCESS_ID", $p_status->rabbitmq->process_id);
self::output_status("RABBITMQ_RUNNING_SECONDS", $p_status->rabbitmq->uptime_seconds);
self::output_status("RABBITMQ_MEM_PERC", $p_status->rabbitmq->memory_perc);
self::output_status("RABBITMQ_CPU_PERC", $p_status->rabbitmq->cpu_perc);
self::output_status("PLAYOUT_ENGINE_PROCESS_ID", $p_status->services->pypo->process_id);
self::output_status("PLAYOUT_ENGINE_RUNNING_SECONDS", $p_status->services->pypo->uptime_seconds);
self::output_status("PLAYOUT_ENGINE_MEM_PERC", $p_status->services->pypo->memory_perc);
self::output_status("PLAYOUT_ENGINE_CPU_PERC", $p_status->services->pypo->cpu_perc);
self::output_status("LIQUIDSOAP_PROCESS_ID", $p_status->services->liquidsoap->process_id);
self::output_status("LIQUIDSOAP_RUNNING_SECONDS", $p_status->services->liquidsoap->uptime_seconds);
self::output_status("LIQUIDSOAP_MEM_PERC", $p_status->services->liquidsoap->memory_perc);
self::output_status("LIQUIDSOAP_CPU_PERC", $p_status->services->liquidsoap->cpu_perc);
self::output_status("MEDIA_MONITOR_PROCESS_ID", $p_status->services->media_monitor->process_id);
self::output_status("MEDIA_MONITOR_RUNNING_SECONDS", $p_status->services->media_monitor->uptime_seconds);
self::output_status("MEDIA_MONITOR_MEM_PERC", $p_status->services->media_monitor->memory_perc);
self::output_status("MEDIA_MONITOR_CPU_PERC", $p_status->services->media_monitor->cpu_perc);
self::output_status("SHOW_RECORDER_PROCESS_ID", $p_status->services->show_recorder->process_id);
self::output_status("SHOW_RECORDER_RUNNING_SECONDS", $p_status->services->show_recorder->uptime_seconds);
self::output_status("SHOW_RECORDER_MEM_PERC", $p_status->services->show_recorder->memory_perc);
self::output_status("SHOW_RECORDER_CPU_PERC", $p_status->services->show_recorder->cpu_perc);
self::output_status("ICECAST_PROCESS_ID", $p_status->services->icecast2->process_id);
self::output_status("ICECAST_RUNNING_SECONDS", $p_status->services->icecast2->uptime_seconds);
self::output_status("ICECAST_MEM_PERC", $p_status->services->icecast2->memory_perc);
self::output_status("ICECAST_CPU_PERC", $p_status->services->icecast2->cpu_perc);
self::output_status("RABBITMQ_PROCESS_ID", $p_status->services->rabbitmq->process_id);
self::output_status("RABBITMQ_RUNNING_SECONDS", $p_status->services->rabbitmq->uptime_seconds);
self::output_status("RABBITMQ_MEM_PERC", $p_status->services->rabbitmq->memory_perc);
self::output_status("RABBITMQ_CPU_PERC", $p_status->services->rabbitmq->cpu_perc);
}