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

Conflicts:
	install/airtime-install.php
This commit is contained in:
Paul Baranowski 2011-05-30 15:35:38 -04:00
commit d8f4c3e616
23 changed files with 473 additions and 234 deletions

View file

@ -16,6 +16,7 @@ Highlights:
- In the "Add Media" page, the "start upload" button vanished after upload. Now it remains there after upload so it is possible to upload again. - In the "Add Media" page, the "start upload" button vanished after upload. Now it remains there after upload so it is possible to upload again.
- When canceling a playing show, the currently playing audio file still showed as playing. This has been fixed. - When canceling a playing show, the currently playing audio file still showed as playing. This has been fixed.
- Audio files greater than 100MB were not being played. - Audio files greater than 100MB were not being played.
- Fixed uploading audio on Chrome 11 and higher
1.8.1 - May 2, 2011 1.8.1 - May 2, 2011

View file

@ -1,6 +1,6 @@
<?php <?php
define('AIRTIME_VERSION', '1.8.2'); define('AIRTIME_VERSION', '1.9.0-devel');
define('AIRTIME_COPYRIGHT_DATE', '2010-2011'); define('AIRTIME_COPYRIGHT_DATE', '2010-2011');
define('AIRTIME_REST_VERSION', '1.1'); define('AIRTIME_REST_VERSION', '1.1');

View file

@ -19,16 +19,16 @@ class ApiController extends Zend_Controller_Action
// action body // action body
} }
/** /**
* Returns Airtime version. i.e "1.7.0 alpha" * Returns Airtime version. i.e "1.7.0 alpha"
* *
* First checks to ensure the correct API key was * First checks to ensure the correct API key was
* supplied, then returns AIRTIME_VERSION as defined * supplied, then returns AIRTIME_VERSION as defined
* in application/conf.php * in application/conf.php
* *
* @return void * @return void
* *
*/ */
public function versionAction() public function versionAction()
{ {
global $CC_CONFIG; global $CC_CONFIG;
@ -40,20 +40,20 @@ class ApiController extends Zend_Controller_Action
$api_key = $this->_getParam('api_key'); $api_key = $this->_getParam('api_key');
if (!in_array($api_key, $CC_CONFIG["apiKey"])) if (!in_array($api_key, $CC_CONFIG["apiKey"]))
{ {
header('HTTP/1.0 401 Unauthorized'); header('HTTP/1.0 401 Unauthorized');
print 'You are not allowed to access this resource.'; print 'You are not allowed to access this resource.';
exit; exit;
} }
$jsonStr = json_encode(array("version"=>AIRTIME_VERSION)); $jsonStr = json_encode(array("version"=>AIRTIME_VERSION));
echo $jsonStr; echo $jsonStr;
} }
/** /**
* Allows remote client to download requested media file. * Allows remote client to download requested media file.
* *
* @return void * @return void
* The given value increased by the increment amount. * The given value increased by the increment amount.
*/ */
public function getMediaAction() public function getMediaAction()
{ {
global $CC_CONFIG; global $CC_CONFIG;
@ -67,9 +67,9 @@ class ApiController extends Zend_Controller_Action
if(!in_array($api_key, $CC_CONFIG["apiKey"])) if(!in_array($api_key, $CC_CONFIG["apiKey"]))
{ {
header('HTTP/1.0 401 Unauthorized'); header('HTTP/1.0 401 Unauthorized');
print 'You are not allowed to access this resource.'; print 'You are not allowed to access this resource.';
exit; exit;
} }
$filename = $this->_getParam("file"); $filename = $this->_getParam("file");
@ -80,39 +80,40 @@ class ApiController extends Zend_Controller_Action
$filepath = $media->getRealFilePath(); $filepath = $media->getRealFilePath();
if(!is_file($filepath)) if(!is_file($filepath))
{ {
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found"); header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
//print 'Resource in database, but not in storage. Sorry.'; //print 'Resource in database, but not in storage. Sorry.';
exit; exit;
} }
// !! binary mode !!
$fp = fopen($filepath, 'rb');
// possibly use fileinfo module here in the future. // possibly use fileinfo module here in the future.
// http://www.php.net/manual/en/book.fileinfo.php // http://www.php.net/manual/en/book.fileinfo.php
$ext = pathinfo($filename, PATHINFO_EXTENSION); $ext = pathinfo($filename, PATHINFO_EXTENSION);
if ($ext == "ogg") if ($ext == "ogg")
header("Content-Type: audio/ogg"); header("Content-Type: audio/ogg");
else if ($ext == "mp3") else if ($ext == "mp3")
header("Content-Type: audio/mpeg"); header("Content-Type: audio/mpeg");
if ($download){ if ($download){
header('Content-Disposition: attachment; filename="'.$media->getName().'"'); header('Content-Disposition: attachment; filename="'.$media->getName().'"');
} }
header("Content-Length: " . filesize($filepath)); header("Content-Length: " . filesize($filepath));
//flush the file contents 16 KBytes at a time. In the future we may // !! binary mode !!
//want to use the "X-Sendfile header" method instead. $fp = fopen($filepath, 'rb');
while (!feof($fp)) {
echo fread($fp, 64*1024); //We can have multiple levels of output buffering. Need to
ob_end_flush(); //keep looping until all have been disabled!!!
} //http://www.php.net/manual/en/function.ob-end-flush.php
while (@ob_end_flush());
fpassthru($fp);
fclose($fp); fclose($fp);
return; return;
} }
} }
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found"); header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
exit; exit;
} }
public function liveInfoAction() public function liveInfoAction()
@ -261,9 +262,9 @@ class ApiController extends Zend_Controller_Action
$api_key = $this->_getParam('api_key'); $api_key = $this->_getParam('api_key');
if (!in_array($api_key, $CC_CONFIG["apiKey"])) if (!in_array($api_key, $CC_CONFIG["apiKey"]))
{ {
header('HTTP/1.0 401 Unauthorized'); header('HTTP/1.0 401 Unauthorized');
print 'You are not allowed to access this resource.'; print 'You are not allowed to access this resource.';
exit; exit;
} }
$today_timestamp = date("Y-m-d H:i:s"); $today_timestamp = date("Y-m-d H:i:s");
@ -288,9 +289,9 @@ class ApiController extends Zend_Controller_Action
$api_key = $this->_getParam('api_key'); $api_key = $this->_getParam('api_key');
if (!in_array($api_key, $CC_CONFIG["apiKey"])) if (!in_array($api_key, $CC_CONFIG["apiKey"]))
{ {
header('HTTP/1.0 401 Unauthorized'); header('HTTP/1.0 401 Unauthorized');
print 'You are not allowed to access this resource.'; print 'You are not allowed to access this resource.';
exit; exit;
} }
$upload_dir = ini_get("upload_tmp_dir"); $upload_dir = ini_get("upload_tmp_dir");
@ -350,9 +351,9 @@ class ApiController extends Zend_Controller_Action
$api_key = $this->_getParam('api_key'); $api_key = $this->_getParam('api_key');
if (!in_array($api_key, $CC_CONFIG["apiKey"])) if (!in_array($api_key, $CC_CONFIG["apiKey"]))
{ {
header('HTTP/1.0 401 Unauthorized'); header('HTTP/1.0 401 Unauthorized');
print 'You are not allowed to access this resource.'; print 'You are not allowed to access this resource.';
exit; exit;
} }
$md = $this->_getParam('md'); $md = $this->_getParam('md');

View file

@ -456,9 +456,13 @@ class ScheduleController extends Zend_Controller_Action
array_push($days, $showDay->getDbDay()); array_push($days, $showDay->getDbDay());
} }
$displayedEndDate = new DateTime($show->getRepeatingEndDate());
$displayedEndDate->sub(new DateInterval("P1D"));//end dates are stored non-inclusively.
$displayedEndDate = $displayedEndDate->format("Y-m-d");
$formRepeats->populate(array('add_show_repeat_type' => $show->getRepeatType(), $formRepeats->populate(array('add_show_repeat_type' => $show->getRepeatType(),
'add_show_day_check' => $days, 'add_show_day_check' => $days,
'add_show_end_date' => $show->getRepeatingEndDate(), 'add_show_end_date' => $displayedEndDate,
'add_show_no_end' => ($show->getRepeatingEndDate() == ''))); 'add_show_no_end' => ($show->getRepeatingEndDate() == '')));
$formRecord->populate(array('add_show_record' => $show->isRecorded(), $formRecord->populate(array('add_show_record' => $show->isRecorded(),

View file

@ -43,9 +43,7 @@ class Application_Form_EditAudioMD extends Zend_Form
'required' => true, 'required' => true,
'class' => 'input_text', 'class' => 'input_text',
'filters' => array('StringTrim'), 'filters' => array('StringTrim'),
'validators' => array( 'validators' => array('NotEmpty')
'NotEmpty',
)
)); ));
// Add album field // Add album field
@ -55,11 +53,12 @@ class Application_Form_EditAudioMD extends Zend_Form
'filters' => array('StringTrim') 'filters' => array('StringTrim')
)); ));
// Add mood field // Add track number field
$this->addElement('text', 'track_number', array( $this->addElement('text', 'track_number', array(
'label' => 'Track:', 'label' => 'Track:',
'class' => 'input_text', 'class' => 'input_text',
'filters' => array('StringTrim') 'filters' => array('StringTrim'),
'validators' => array('Int')
)); ));
// Add genre field // Add genre field

View file

@ -87,8 +87,9 @@ class Application_Model_Dashboard
if (count($row) == 0){ if (count($row) == 0){
return null; return null;
} else { } else {
//should never reach here. Doesnt make sense to have return array("name"=>$row[0]["artist_name"]." - ".$row[0]["track_title"],
//a schedule item not within a show_instance. "starts"=>$row[0]["starts"],
"ends"=>$row[0]["ends"]);
} }
} else { } else {
if (count($row) == 0){ if (count($row) == 0){

View file

@ -320,7 +320,7 @@ class Show {
* @param string $p_date * @param string $p_date
* The date which to delete after * The date which to delete after
*/ */
public function removeAllInstancesAfterDate($p_date){ public function removeAllInstancesFromDate($p_date){
global $CC_DBC; global $CC_DBC;
$date = new DateHelper; $date = new DateHelper;
@ -328,7 +328,7 @@ class Show {
$showId = $this->getId(); $showId = $this->getId();
$sql = "DELETE FROM cc_show_instances " $sql = "DELETE FROM cc_show_instances "
." WHERE date(starts) > DATE '$p_date'" ." WHERE date(starts) >= DATE '$p_date'"
." AND starts > TIMESTAMP '$timestamp'" ." AND starts > TIMESTAMP '$timestamp'"
." AND show_id = $showId"; ." AND show_id = $showId";
@ -590,7 +590,7 @@ class Show {
//show "Never Ends" option was toggled. //show "Never Ends" option was toggled.
if ($p_data['add_show_no_end']){ if ($p_data['add_show_no_end']){
} else { } else {
$p_show->removeAllInstancesAfterDate($p_endDate); $p_show->removeAllInstancesFromDate($p_endDate);
} }
} }
if ($p_show->getRepeatingEndDate() != $p_data['add_show_end_date']){ if ($p_show->getRepeatingEndDate() != $p_data['add_show_end_date']){
@ -599,7 +599,7 @@ class Show {
$newDate = strtotime($p_data['add_show_end_date']); $newDate = strtotime($p_data['add_show_end_date']);
$oldDate = strtotime($p_show->getRepeatingEndDate()); $oldDate = strtotime($p_show->getRepeatingEndDate());
if ($newDate < $oldDate){ if ($newDate < $oldDate){
$p_show->removeAllInstancesAfterDate($p_endDate); $p_show->removeAllInstancesFromDate($p_endDate);
} }
} }
} }
@ -608,7 +608,7 @@ class Show {
/** /**
* Create a show. * Create a show.
* *
* Note: end dates are non inclusive. * Note: end dates are inclusive.
* *
* @param array $data * @param array $data
* @return int * @return int
@ -624,7 +624,6 @@ class Show {
if ($data['add_show_no_end']) { if ($data['add_show_no_end']) {
$endDate = NULL; $endDate = NULL;
//$data['add_show_repeats'] = 1;
} }
else if ($data['add_show_repeats']) { else if ($data['add_show_repeats']) {
$sql = "SELECT date '{$data['add_show_end_date']}' + INTERVAL '1 day' "; $sql = "SELECT date '{$data['add_show_end_date']}' + INTERVAL '1 day' ";
@ -703,7 +702,7 @@ class Show {
$start = $data['add_show_start_date']; $start = $data['add_show_start_date'];
} }
if (strtotime($start) < strtotime($endDate) || is_null($endDate)) { if (strtotime($start) <= strtotime($endDate) || is_null($endDate)) {
$showDay = new CcShowDays(); $showDay = new CcShowDays();
$showDay->setDbFirstShow($start); $showDay->setDbFirstShow($start);
$showDay->setDbLastShow($endDate); $showDay->setDbLastShow($endDate);
@ -921,7 +920,7 @@ class Show {
$rebroadcasts = $CC_DBC->GetAll($sql); $rebroadcasts = $CC_DBC->GetAll($sql);
$show = new Show($show_id); $show = new Show($show_id);
while(strtotime($next_date) < strtotime($end_timestamp) && (strtotime($last_show) > strtotime($next_date) || is_null($last_show))) { while(strtotime($next_date) <= strtotime($end_timestamp) && (strtotime($last_show) > strtotime($next_date) || is_null($last_show))) {
$start = $next_date; $start = $next_date;

View file

@ -546,10 +546,12 @@ class StoredFile {
$data = array(); $data = array();
foreach ($p_values as $category => $value) { foreach ($p_values as $category => $value) {
$escapedValue = pg_escape_string($value); if (isset($value) && ($value != '')) {
$columnName = $category; $escapedValue = pg_escape_string($value);
if (!is_null($columnName)) { $columnName = $category;
$data[] = "$columnName='$escapedValue'"; if (!is_null($columnName)) {
$data[] = "$columnName='$escapedValue'";
}
} }
} }
@ -734,7 +736,14 @@ class StoredFile {
$storedFile->mtime = $row['mtime']; $storedFile->mtime = $row['mtime'];
$storedFile->md5 = $row['md5']; $storedFile->md5 = $row['md5'];
$storedFile->filepath = $row['filepath']; $storedFile->filepath = $row['filepath'];
$storedFile->exists = TRUE;
if(file_exists($row['filepath'])) {
$storedFile->exists = true;
}
else {
$storedFile->exists = false;
}
$storedFile->setFormat($row['ftype']); $storedFile->setFormat($row['ftype']);
return $storedFile; return $storedFile;
} }
@ -867,7 +876,7 @@ class StoredFile {
* local path * local path
* @return TRUE|PEAR_Error * @return TRUE|PEAR_Error
*/ */
public function replaceFile($p_localFilePath) public function replaceFile($p_localFilePath, $p_copyMedia=TRUE)
{ {
// Dont do anything if the source and destination files are // Dont do anything if the source and destination files are
// the same. // the same.
@ -881,7 +890,7 @@ class StoredFile {
return $r; return $r;
} }
} }
return $this->addFile($p_localFilePath); return $this->addFile($p_localFilePath, $p_copyMedia);
} }
@ -1783,8 +1792,17 @@ class StoredFile {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' . $duplicate->getMessage() .'}}'); die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' . $duplicate->getMessage() .'}}');
} }
else { else {
$duplicateName = $duplicate->getMetadataValue(UI_MDATA_KEY_TITLE); if (file_exists($duplicate->getRealFilePath())) {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "An identical audioclip named ' . $duplicateName . ' already exists in the storage server."}}'); $duplicateName = $duplicate->getMetadataValue(UI_MDATA_KEY_TITLE);
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "An identical audioclip named ' . $duplicateName . ' already exists in the storage server."}}');
}
else {
$res = $duplicate->replaceFile($audio_file);
if (PEAR::isError($res)) {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' . $duplicate->getMessage() .'}}');
}
return $duplicate;
}
} }
} }

View file

@ -74,7 +74,8 @@ function addLibraryItemEvents() {
$('#library_display tr[id ^= "au"]') $('#library_display tr[id ^= "au"]')
.draggable({ .draggable({
helper: 'clone' helper: 'clone',
cursor: 'pointer'
}); });
$('#library_display tbody tr') $('#library_display tbody tr')

View file

@ -171,11 +171,17 @@ function createDataGrid(){
var gapTime = oSettings.aoData[ oSettings.aiDisplay[iDisplayIndex]]._aData[4]; var gapTime = oSettings.aoData[ oSettings.aiDisplay[iDisplayIndex]]._aData[4];
var hours = parseInt( gapTime / 3600 ) % 24;
var minutes = parseInt( gapTime / 60 ) % 60;
var seconds = gapTime % 60;
var gapTimeFormat = (hours < 10 ? "0" + hours : hours) + ":" + (minutes < 10 ? "0" + minutes : minutes) + ":" + (seconds < 10 ? "0" + seconds : seconds);
var nGroup = document.createElement('tr'); var nGroup = document.createElement('tr');
var nCell = document.createElement('td'); var nCell = document.createElement('td');
nCell.colSpan = iColspan; nCell.colSpan = iColspan;
nCell.className = "gap"; nCell.className = "gap";
nCell.innerHTML = "Gap until show end: " + gapTime + " seconds"; nCell.innerHTML = "Gap until show end: " + gapTimeFormat + " seconds";
nGroup.appendChild(nCell); nGroup.appendChild(nCell);
nTrs[i].parentNode.replaceChild(nGroup, nTrs[i]); nTrs[i].parentNode.replaceChild(nGroup, nTrs[i]);
} else if ( sType.indexOf("r") != -1 ){ } else if ( sType.indexOf("r") != -1 ){

View file

@ -55,6 +55,16 @@ function findHosts(request, callback) {
} }
function beginEditShow(data){
$("#add-show-form")
.empty()
.append(data.newForm);
removeAddShowButton();
setAddShowEvents();
openAddShowForm();
}
function setAddShowEvents() { function setAddShowEvents() {
var form = $("#add-show-form"); var form = $("#add-show-form");

View file

@ -46,16 +46,6 @@ function removeAddShowButton(){
span.remove(); span.remove();
} }
function beginEditShow(data){
$("#add-show-form")
.empty()
.append(data.newForm);
removeAddShowButton();
setAddShowEvents();
openAddShowForm();
}
function makeTimeStamp(date){ function makeTimeStamp(date){
var sy, sm, sd, h, m, s, timestamp; var sy, sm, sd, h, m, s, timestamp;
sy = date.getFullYear(); sy = date.getFullYear();

File diff suppressed because one or more lines are too long

View file

@ -3,6 +3,10 @@
* @package Airtime * @package Airtime
* @copyright 2011 Sourcefabric O.P.S. * @copyright 2011 Sourcefabric O.P.S.
* @license http://www.gnu.org/licenses/gpl.txt * @license http://www.gnu.org/licenses/gpl.txt
*
* Checks if a previous version of Airtime is currently installed, upgrades Airtime if so.
* Performs a new install (new configs, database install) if a version of Airtime is not found
* If the current version is found to be installed the User is presented with the help menu and can choose -r to reinstall.
*/ */
set_include_path(__DIR__.'/../airtime_mvc/library' . PATH_SEPARATOR . get_include_path()); set_include_path(__DIR__.'/../airtime_mvc/library' . PATH_SEPARATOR . get_include_path());
@ -16,7 +20,7 @@ require_once(AirtimeInstall::GetAirtimeSrcDir().'/application/configs/constants.
AirtimeInstall::ExitIfNotRoot(); AirtimeInstall::ExitIfNotRoot();
$newInstall = false; $newInstall = false;
$version = AirtimeInstall::CheckForVersionBeforeInstall(); $version = AirtimeInstall::GetVersionInstalled();
require_once('Zend/Loader/Autoloader.php'); require_once('Zend/Loader/Autoloader.php');
$autoloader = Zend_Loader_Autoloader::getInstance(); $autoloader = Zend_Loader_Autoloader::getInstance();
@ -42,27 +46,29 @@ if (isset($opts->h)) {
exit; exit;
} }
//the current version exists. // The current version is already installed.
if(isset($version) && $version != false && $version == AIRTIME_VERSION && !isset($opts->r)) { if(isset($version) && ($version != false) && ($version == AIRTIME_VERSION) && !isset($opts->r)) {
echo "Airtime $version is already installed.".PHP_EOL;
echo "Airtime $version is already installed.\n".PHP_EOL;
echo $opts->getUsageMessage(); echo $opts->getUsageMessage();
exit(); exit();
} }
//a previous version exists. // A previous version exists - if so, upgrade.
if(isset($version) && $version != false && $version < AIRTIME_VERSION) { if(isset($version) && ($version != false) && ($version < AIRTIME_VERSION)) {
echo "Airtime version $version found.".PHP_EOL; echo "Airtime version $version found.".PHP_EOL;
$command = "php airtime-upgrade.php"; require_once("airtime-upgrade.php");
system($command);
exit(); exit();
} }
// -------------------------------------------------------------------------
// The only way we get here is if we are doing a new install or a reinstall.
// -------------------------------------------------------------------------
if(is_null($version)) { if(is_null($version)) {
$newInstall = true; $newInstall = true;
} }
$db_install = true; $db_install = true;
if (is_null($opts->r) && isset($opts->n) && !$newInstall){ if (is_null($opts->r) && isset($opts->n)){
$db_install = false; $db_install = false;
} }
@ -130,5 +136,9 @@ system("python ".__DIR__."/../python_apps/show-recorder/install/recorder-install
//echo PHP_EOL."*** Media Monitor Installation ***".PHP_EOL; //echo PHP_EOL."*** Media Monitor Installation ***".PHP_EOL;
//system("python ".__DIR__."/../python_apps/pytag-fs/install/media-monitor-install.py"); //system("python ".__DIR__."/../python_apps/pytag-fs/install/media-monitor-install.py");
echo PHP_EOL."*** Verifying Correct System Environment ***".PHP_EOL;
$command = "airtime-check-system";
system($command);
echo "******************************* Install Complete *******************************".PHP_EOL; echo "******************************* Install Complete *******************************".PHP_EOL;

View file

@ -34,7 +34,7 @@ class AirtimeInstall
} }
} }
public static function CheckForVersionBeforeInstall() public static function GetVersionInstalled()
{ {
global $CC_DBC, $CC_CONFIG; global $CC_DBC, $CC_CONFIG;
@ -300,6 +300,10 @@ class AirtimeInstall
echo "* Installing airtime-update-db-settings".PHP_EOL; echo "* Installing airtime-update-db-settings".PHP_EOL;
$dir = AirtimeInstall::CONF_DIR_BINARIES."/utils/airtime-update-db-settings"; $dir = AirtimeInstall::CONF_DIR_BINARIES."/utils/airtime-update-db-settings";
exec("ln -s $dir /usr/bin/airtime-update-db-settings"); exec("ln -s $dir /usr/bin/airtime-update-db-settings");
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");
} }
public static function RemoveSymlinks() public static function RemoveSymlinks()
@ -307,6 +311,7 @@ class AirtimeInstall
exec("rm -f /usr/bin/airtime-import"); exec("rm -f /usr/bin/airtime-import");
exec("rm -f /usr/bin/airtime-clean-storage"); exec("rm -f /usr/bin/airtime-clean-storage");
exec("rm -f /usr/bin/airtime-update-db-settings"); exec("rm -f /usr/bin/airtime-update-db-settings");
exec("rm -f /usr/bin/airtime-check-system");
} }
public static function InstallPhpCode() public static function InstallPhpCode()

View file

@ -164,10 +164,14 @@ function UpdateIniValue($p_filename, $p_property, $p_value)
{ {
$lines = file($p_filename); $lines = file($p_filename);
$n=count($lines); $n=count($lines);
for ($i=0; $i<$n; $i++) { foreach ($lines as &$line) {
if (strlen($lines[$i]) > strlen($p_property)) if ($line[0] != "#"){
if ($p_property == substr($lines[$i], 0, strlen($p_property))){ $key_value = split("=", $line);
$lines[$i] = "$p_property = $p_value\n"; $key = trim($key_value[0]);
if ($key == $p_property){
$line = "$p_property = $p_value".PHP_EOL;
}
} }
} }
@ -232,7 +236,8 @@ function InstallBinaries()
exec("cp -R ".$AIRTIME_UTILS." ".CONF_DIR_BINARIES); exec("cp -R ".$AIRTIME_UTILS." ".CONF_DIR_BINARIES);
} }
$suffix = date("Ymdhis"); // Backup the config files
$suffix = date("Ymdhis")."-1.8.1";
foreach ($configFiles as $conf) { foreach ($configFiles as $conf) {
if (file_exists($conf)) { if (file_exists($conf)) {
echo "Backing up $conf to $conf$suffix.bak".PHP_EOL; echo "Backing up $conf to $conf$suffix.bak".PHP_EOL;

View file

@ -164,10 +164,14 @@ function UpdateIniValue($p_filename, $p_property, $p_value)
{ {
$lines = file($p_filename); $lines = file($p_filename);
$n=count($lines); $n=count($lines);
for ($i=0; $i<$n; $i++) { foreach ($lines as &$line) {
if (strlen($lines[$i]) > strlen($p_property)) if ($line[0] != "#"){
if ($p_property == substr($lines[$i], 0, strlen($p_property))){ $key_value = split("=", $line);
$lines[$i] = "$p_property = $p_value\n"; $key = trim($key_value[0]);
if ($key == $p_property){
$line = "$p_property = $p_value".PHP_EOL;
}
} }
} }
@ -232,7 +236,7 @@ function InstallBinaries()
exec("cp -R ".$AIRTIME_UTILS." ".CONF_DIR_BINARIES); exec("cp -R ".$AIRTIME_UTILS." ".CONF_DIR_BINARIES);
} }
$suffix = date("Ymdhis"); $suffix = date("Ymdhis")."-1.8.2";
foreach ($configFiles as $conf) { foreach ($configFiles as $conf) {
if (file_exists($conf)) { if (file_exists($conf)) {
echo "Backing up $conf to $conf$suffix.bak".PHP_EOL; echo "Backing up $conf to $conf$suffix.bak".PHP_EOL;

View file

@ -19,7 +19,7 @@ import json
import os import os
from urlparse import urlparse from urlparse import urlparse
AIRTIME_VERSION = "1.8.2" AIRTIME_VERSION = "1.9.0-devel"
def api_client_factory(config): def api_client_factory(config):
if config["api_client"] == "airtime": if config["api_client"] == "airtime":

View file

@ -113,7 +113,10 @@ if __name__ == '__main__':
# initialize # initialize
g = Global() g = Global()
while not g.selfcheck(): time.sleep(5000) #NOTE: MUST EXIT HERE!! while not g.selfcheck(): time.sleep()
#Causes pypo to hang on system boot!!!
if not g.selfcheck():
sys.exit()
logger = logging.getLogger() logger = logging.getLogger()

View file

@ -70,20 +70,32 @@ end
if output_icecast_vorbis then if output_icecast_vorbis then
#remove metadata from ogg source and merge tracks to fix bug
#with vlc and mplayer disconnecting at the end of every track
if output_icecast_vorbis_metadata then if output_icecast_vorbis_metadata then
out_vorbis = output.icecast(%vorbis,
host = icecast_host, port = icecast_port,
password = icecast_pass, mount = mount_point_vorbis,
fallible = true,
restart = true,
restart_delay = 5,
url = icecast_url,
description = icecast_description,
genre = icecast_genre,
s)
else
#remove metadata from ogg source and merge tracks to fix bug
#with vlc and mplayer disconnecting at the end of every track
s = add(normalize=false, [amplify(0.00001, noise()),s]) s = add(normalize=false, [amplify(0.00001, noise()),s])
out_vorbis = output.icecast(%vorbis,
host = icecast_host, port = icecast_port,
password = icecast_pass, mount = mount_point_vorbis,
fallible = true,
restart = true,
restart_delay = 5,
url = icecast_url,
description = icecast_description,
genre = icecast_genre,
s)
end end
out_vorbis = output.icecast(%vorbis,
host = icecast_host, port = icecast_port,
password = icecast_pass, mount = mount_point_vorbis,
fallible = true,
restart = true,
restart_delay = 5,
url = icecast_url,
description = icecast_description,
genre = icecast_genre,
s)
end end

34
utils/airtime-check-system Executable file
View file

@ -0,0 +1,34 @@
#!/bin/bash
#-------------------------------------------------------------------------------
# Copyright (c) 2010 Sourcefabric O.P.S.
#
# This file is part of the Airtime project.
# http://airtime.sourcefabric.org/
#
# Airtime is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Airtime is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Airtime; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# This script cleans audio files in Airtime.
#
# Absolute path to this script
SCRIPT=`readlink -f $0`
# Absolute path this script is in
SCRIPTPATH=`dirname $SCRIPT`
invokePwd=$PWD
cd $SCRIPTPATH
php -q airtime-check-system.php "$@" || exit 1

View file

@ -1,5 +1,11 @@
<?php <?php
require_once '../airtime_mvc/library/php-amqplib/amqp.inc';
AirtimeCheck::ExitIfNotRoot();
$airtimeIni = AirtimeCheck::GetAirtimeConf();
$airtime_base_dir = $airtimeIni['general']['airtime_dir'];
require_once "$airtime_base_dir/library/php-amqplib/amqp.inc";
set_error_handler("myErrorHandler"); set_error_handler("myErrorHandler");
@ -7,7 +13,7 @@ AirtimeCheck::CheckOsTypeVersion();
AirtimeCheck::CheckConfigFilesExist(); AirtimeCheck::CheckConfigFilesExist();
$airtimeIni = AirtimeCheck::GetAirtimeConf();
$pypoCfg = AirtimeCheck::GetPypoCfg(); $pypoCfg = AirtimeCheck::GetPypoCfg();
AirtimeCheck::GetDbConnection($airtimeIni); AirtimeCheck::GetDbConnection($airtimeIni);
@ -20,15 +26,53 @@ AirtimeCheck::CheckApacheVHostFiles();
AirtimeCheck::GetAirtimeServerVersion($pypoCfg); AirtimeCheck::GetAirtimeServerVersion($pypoCfg);
AirtimeCheck::CheckPypoRunning(); AirtimeCheck::CheckPypoRunning();
AirtimeCheck::CheckLiquidsoapRunning(); AirtimeCheck::CheckLiquidsoapRunning();
AirtimeCheck::CheckIcecastRunning();
echo PHP_EOL;
if (AirtimeCheck::$check_system_ok){
output_msg("System setup looks OK!");
} else {
output_msg("There appears to be problems with your setup. Please visit");
output_msg("http://wiki.sourcefabric.org/x/HABQ for troubleshooting info.");
}
echo PHP_EOL;
class AirtimeCheck{ function output_status($key, $value)
{
echo sprintf("%-31s= %s", $key, $value).PHP_EOL;
}
function output_msg($msg)
{
//echo " -- ".PHP_EOL;
echo " -- $msg".PHP_EOL;
//echo " -- ".PHP_EOL;
}
class AirtimeCheck {
const CHECK_OK = "OK"; const CHECK_OK = "OK";
const CHECK_FAILED = "FAILED"; const CHECK_FAILED = "FAILED";
public static function CheckPypoRunning(){ public static $check_system_ok = true;
/**
* Ensures that the user is running this PHP script with root
* permissions. If not running with root permissions, causes the
* script to exit.
*/
public static function ExitIfNotRoot()
{
// Need to check that we are superuser before running this.
if(exec("whoami") != "root"){
echo "Must be root user.\n";
exit(1);
}
}
public static function CheckPypoRunning()
{
$command = "sudo svstat /etc/service/pypo"; $command = "sudo svstat /etc/service/pypo";
exec($command, $output, $result); exec($command, $output, $result);
@ -42,9 +86,11 @@ class AirtimeCheck{
$start = $pos + 4; $start = $pos + 4;
$end = strpos($value, ")", $start); $end = strpos($value, ")", $start);
$status = substr($value, $start, $end-$start); $status = substr($value, $start, $end-$start);
} else {
self::$check_system_ok = false;
} }
echo "PYPO_PID=".$status.PHP_EOL; output_status("PLAYOUT_ENGINE_PROCESS_ID", $status);
$status = AirtimeCheck::CHECK_FAILED; $status = AirtimeCheck::CHECK_FAILED;
$pos = strpos($value, ")"); $pos = strpos($value, ")");
@ -52,12 +98,23 @@ class AirtimeCheck{
$start = $pos + 2; $start = $pos + 2;
$end = strpos($value, " ", $start); $end = strpos($value, " ", $start);
$status = substr($value, $start, $end-$start); $status = substr($value, $start, $end-$start);
} else {
self::$check_system_ok = false;
}
output_status("PLAYOUT_ENGINE_RUNNING_SECONDS", $status);
if (is_numeric($status) && (int)$status < 3) {
self::$check_system_ok = false;
output_msg("WARNING! It looks like the playout engine is continually restarting.");
$command = "tail -10 /var/log/airtime/pypo/main/current";
exec($command, $output, $result);
foreach ($output as $line) {
output_msg($line);
}
} }
echo "PYPO_RUNNING_SECONDS=".$status.PHP_EOL;
} }
public static function CheckLiquidsoapRunning(){ public static function CheckLiquidsoapRunning()
{
$command = "sudo svstat /etc/service/pypo-liquidsoap"; $command = "sudo svstat /etc/service/pypo-liquidsoap";
exec($command, $output, $result); exec($command, $output, $result);
@ -70,9 +127,11 @@ class AirtimeCheck{
$start = $pos + 4; $start = $pos + 4;
$end = strpos($value, ")", $start); $end = strpos($value, ")", $start);
$status = substr($value, $start, $end-$start); $status = substr($value, $start, $end-$start);
} else {
self::$check_system_ok = false;
} }
echo "LIQUIDSOAP_PID=".$status.PHP_EOL; output_status("LIQUIDSOAP_PROCESS_ID", $status);
$status = AirtimeCheck::CHECK_FAILED; $status = AirtimeCheck::CHECK_FAILED;
$pos = strpos($value, ")"); $pos = strpos($value, ")");
@ -80,13 +139,39 @@ class AirtimeCheck{
$start = $pos + 2; $start = $pos + 2;
$end = strpos($value, " ", $start); $end = strpos($value, " ", $start);
$status = substr($value, $start, $end-$start); $status = substr($value, $start, $end-$start);
} else {
self::$check_system_ok = false;
} }
echo "LIQUIDSOAP_RUNNING_SECONDS=".$status.PHP_EOL; output_status("LIQUIDSOAP_RUNNING_SECONDS", $status);
if (is_numeric($status) && (int)$status < 3) {
self::$check_system_ok = false;
output_msg("WARNING! It looks like liquidsoap is continually restarting.");
$command = "tail -10 /var/log/airtime/pypo-liquidsoap/main/current";
exec($command, $output, $result);
foreach ($output as $line) {
output_msg($line);
}
}
} }
public static function CheckConfigFilesExist(){ public static function CheckIcecastRunning()
{
$command = "ps aux | grep \"^icecast2\"";
exec($command, $output, $result);
$status = AirtimeCheck::CHECK_FAILED;
if (count($output) > 0){
$delimited = split("[ ]+", $output[0]);
$status = $delimited[1];
} else {
self::$check_system_ok = false;
}
output_status("ICECAST_PROCESS_ID", $status);
}
public static function CheckConfigFilesExist()
{
//echo PHP_EOL."Verifying Config Files in /etc/airtime".PHP_EOL; //echo PHP_EOL."Verifying Config Files in /etc/airtime".PHP_EOL;
$confFiles = array("airtime.conf", $confFiles = array("airtime.conf",
"liquidsoap.cfg", "liquidsoap.cfg",
@ -99,14 +184,16 @@ class AirtimeCheck{
$fullPath = "/etc/airtime/$cf"; $fullPath = "/etc/airtime/$cf";
if (!file_exists($fullPath)){ if (!file_exists($fullPath)){
$allFound = AirtimeCheck::CHECK_FAILED; $allFound = AirtimeCheck::CHECK_FAILED;
self::$check_system_ok = false;
} }
} }
echo "AIRTIME_CONFIG_FILES=$allFound".PHP_EOL; output_status("AIRTIME_CONFIG_FILES", $allFound);
} }
public static function GetAirtimeConf(){ public static function GetAirtimeConf()
{
$ini = parse_ini_file("/etc/airtime/airtime.conf", true); $ini = parse_ini_file("/etc/airtime/airtime.conf", true);
if ($ini === false){ if ($ini === false){
@ -117,7 +204,8 @@ class AirtimeCheck{
return $ini; return $ini;
} }
public static function GetPypoCfg(){ public static function GetPypoCfg()
{
$ini = parse_ini_file("/etc/airtime/pypo.cfg", false); $ini = parse_ini_file("/etc/airtime/pypo.cfg", false);
if ($ini === false){ if ($ini === false){
@ -128,7 +216,8 @@ class AirtimeCheck{
return $ini; return $ini;
} }
public static function GetDbConnection($airtimeIni){ public static function GetDbConnection($airtimeIni)
{
$host = $airtimeIni["database"]["host"]; $host = $airtimeIni["database"]["host"];
$dbname = $airtimeIni["database"]["dbname"]; $dbname = $airtimeIni["database"]["dbname"];
$dbuser = $airtimeIni["database"]["dbuser"]; $dbuser = $airtimeIni["database"]["dbuser"];
@ -138,14 +227,16 @@ class AirtimeCheck{
if ($dbconn === false){ if ($dbconn === false){
$status = AirtimeCheck::CHECK_FAILED; $status = AirtimeCheck::CHECK_FAILED;
self::$check_system_ok = false;
} else { } else {
$status = AirtimeCheck::CHECK_OK; $status = AirtimeCheck::CHECK_OK;
} }
echo "TEST_PGSQL_DATABASE=$status".PHP_EOL; output_status("POSTGRESQL_DATABASE", $status);
} }
public static function PythonLibrariesInstalled(){ public static function PythonLibrariesInstalled()
{
$command = "pip freeze | grep kombu"; $command = "pip freeze | grep kombu";
exec($command, $output, $result); exec($command, $output, $result);
@ -153,9 +244,11 @@ class AirtimeCheck{
if (count($output[0]) > 0){ if (count($output[0]) > 0){
$key_value = split("==", $output[0]); $key_value = split("==", $output[0]);
$status = trim($key_value[1]); $status = trim($key_value[1]);
} else {
self::$check_system_ok = false;
} }
echo "PYTHON_KOMBU_VERSION=$status".PHP_EOL; output_status("PYTHON_KOMBU_VERSION", $status);
unset($output); unset($output);
$command = "pip freeze | grep poster"; $command = "pip freeze | grep poster";
@ -165,12 +258,15 @@ class AirtimeCheck{
if (count($output[0]) > 0){ if (count($output[0]) > 0){
$key_value = split("==", $output[0]); $key_value = split("==", $output[0]);
$status = trim($key_value[1]); $status = trim($key_value[1]);
} else {
self::$check_system_ok = false;
} }
echo "PYTHON_POSTER_VERSION=$status".PHP_EOL; output_status("PYTHON_POSTER_VERSION", $status);
} }
public static function CheckDbTables(){ public static function CheckDbTables()
{
} }
@ -201,7 +297,8 @@ class AirtimeCheck{
} }
* */ * */
public static function CheckRabbitMqConnection($airtimeIni){ public static function CheckRabbitMqConnection($airtimeIni)
{
try { try {
$status = AirtimeCheck::CHECK_OK; $status = AirtimeCheck::CHECK_OK;
$conn = new AMQPConnection($airtimeIni["rabbitmq"]["host"], $conn = new AMQPConnection($airtimeIni["rabbitmq"]["host"],
@ -210,34 +307,40 @@ class AirtimeCheck{
$airtimeIni["rabbitmq"]["password"]); $airtimeIni["rabbitmq"]["password"]);
} catch (Exception $e){ } catch (Exception $e){
$status = AirtimeCheck::CHECK_FAILED; $status = AirtimeCheck::CHECK_FAILED;
self::$check_system_ok = false;
} }
echo "TEST_RABBITMQ_SERVER=$status".PHP_EOL; output_status("RABBITMQ_SERVER", $status);
} }
public static function GetAirtimeServerVersion($pypoCfg){ public static function GetAirtimeServerVersion($pypoCfg)
{
$baseUrl = $pypoCfg["base_url"]; $baseUrl = $pypoCfg["base_url"];
$basePort = $pypoCfg["base_port"]; $basePort = $pypoCfg["base_port"];
$apiKey = "%%api_key%%"; $apiKey = "%%api_key%%";
$url = "http://$baseUrl:$basePort/api/version/api_key/$apiKey"; $url = "http://$baseUrl:$basePort/api/version/api_key/$apiKey";
echo "AIRTIME_VERSION_URL=$url".PHP_EOL; output_status("AIRTIME_VERSION_URL", $url);
$apiKey = $pypoCfg["api_key"]; $apiKey = $pypoCfg["api_key"];
$url = "http://$baseUrl:$basePort/api/version/api_key/$apiKey"; $url = "http://$baseUrl:$basePort/api/version/api_key/$apiKey";
$rh = fopen($url, "r"); $rh = fopen($url, "r");
if ($rh !== false){ $version = "Could not contact server";
if ($rh !== false) {
output_status("APACHE_CONFIGURED", "YES");
while (($buffer = fgets($rh)) !== false) { while (($buffer = fgets($rh)) !== false) {
$json = json_decode(trim($buffer), true); $json = json_decode(trim($buffer), true);
if (!is_null($json)){ if (!is_null($json)){
$version = $json["version"]; $version = $json["version"];
echo "AIRTIME_VERSION_STRING=$version".PHP_EOL;
} }
} }
} else {
output_status("APACHE_CONFIGURED", "NO");
} }
output_status("AIRTIME_VERSION", $version);
} }
public static function CheckApacheVHostFiles(){ public static function CheckApacheVHostFiles(){
@ -249,6 +352,7 @@ class AirtimeCheck{
foreach ($fileNames as $fn){ foreach ($fileNames as $fn){
if (!file_exists($fn)){ if (!file_exists($fn)){
$status = AirtimeCheck::CHECK_FAILED; $status = AirtimeCheck::CHECK_FAILED;
self::$check_system_ok = false;
} }
} }
@ -290,7 +394,7 @@ class AirtimeCheck{
$os_string = "Unknown"; $os_string = "Unknown";
} }
echo "OS_TYPE=$os_string".PHP_EOL; output_status("OS", $os_string);
} }
} }
@ -298,6 +402,9 @@ class AirtimeCheck{
// error handler function // error handler function
function myErrorHandler($errno, $errstr, $errfile, $errline) function myErrorHandler($errno, $errstr, $errfile, $errline)
{ {
return true;
/*
if ($errno == E_WARNING){ if ($errno == E_WARNING){
if (strpos($errstr, "401") !== false){ if (strpos($errstr, "401") !== false){
echo "\t\tServer is running but could not find Airtime".PHP_EOL; echo "\t\tServer is running but could not find Airtime".PHP_EOL;
@ -308,6 +415,7 @@ function myErrorHandler($errno, $errstr, $errfile, $errline)
} }
} }
/* Don't execute PHP internal error handler */ //Don't execute PHP internal error handler
return true; return true;
*/
} }

View file

@ -112,6 +112,7 @@ function import_audio_file($p_filepath, $p_importMode = null, $p_testOnly = fals
global $STORAGE_SERVER_PATH; global $STORAGE_SERVER_PATH;
global $g_fileCount; global $g_fileCount;
global $g_duplicates; global $g_duplicates;
global $g_replaced;
// Check parameters // Check parameters
$p_importMode = strtolower($p_importMode); $p_importMode = strtolower($p_importMode);
@ -204,9 +205,32 @@ function import_audio_file($p_filepath, $p_importMode = null, $p_testOnly = fals
// Look up md5sum in database // Look up md5sum in database
$duplicate = StoredFile::RecallByMd5($md5sum); $duplicate = StoredFile::RecallByMd5($md5sum);
if ($duplicate) { if (PEAR::isError($duplicate)) {
echo "DUPLICATE: $p_filepath\n"; echo $duplicate->getMessage();
$g_duplicates++; echo "\n";
}
//row exists in database
if (isset($duplicate)) {
if (file_exists($duplicate->getRealFilePath())) {
echo "DUPLICATE: $p_filepath\n";
$g_duplicates++;
}
else{
if ($p_importMode == "copy") {
$doCopyFiles = true;
}
else if ($p_importMode == "link") {
$doCopyFiles = false;
}
$res = $duplicate->replaceFile($p_filepath, $doCopyFiles);
if (PEAR::isError($res)) {
echo $res->getMessage();
echo "\n";
return;
}
$g_replaced++;
}
return; return;
} }
@ -323,7 +347,10 @@ if ( ($importMode == "copy") && !is_writable($CC_CONFIG["storageDir"])) {
global $g_fileCount; global $g_fileCount;
global $g_duplicates; global $g_duplicates;
global $g_replaced;
$g_fileCount = 0; $g_fileCount = 0;
$g_duplicates = 0;
$g_replaced = 0;
if (is_array($files)) { if (is_array($files)) {
foreach ($files as $filepath) { foreach ($files as $filepath) {
// absolute path // absolute path
@ -356,6 +383,7 @@ if ($importMode == "copy") {
echo " *** Destination folder: ".$CC_CONFIG['storageDir']."\n"; echo " *** Destination folder: ".$CC_CONFIG['storageDir']."\n";
} }
echo " *** Files imported: $g_fileCount\n"; echo " *** Files imported: $g_fileCount\n";
echo " *** Files restored: $g_replaced\n";
echo " *** Duplicate files (not imported): $g_duplicates\n"; echo " *** Duplicate files (not imported): $g_duplicates\n";
if ($g_errors > 0) { if ($g_errors > 0) {
echo " *** Errors: $g_errors\n"; echo " *** Errors: $g_errors\n";