Merge branch 'devel' of dev.sourcefabric.org:airtime into devel
This commit is contained in:
commit
41e7150462
|
@ -12,21 +12,26 @@ require_once "DateHelper.php";
|
|||
require_once "OsPath.php";
|
||||
require_once __DIR__.'/controllers/plugins/RabbitMqPlugin.php';
|
||||
|
||||
|
||||
//DateTime in PHP 5.3.0+ need a default timezone set. Set to UTC initially
|
||||
//in case Application_Model_Preference::GetTimezone fails and creates needs to create
|
||||
//a log entry. This log entry requires a call to date(), which then complains that
|
||||
//timezone isn't set. Setting a default timezone allows us to create a a graceful log
|
||||
//that getting the real timezone failed, without PHP complaining that it cannot log because
|
||||
//there is no timezone :|.
|
||||
date_default_timezone_set('UTC');
|
||||
date_default_timezone_set(Application_Model_Preference::GetTimezone());
|
||||
|
||||
global $CC_CONFIG;
|
||||
$CC_CONFIG['airtime_version'] = Application_Model_Preference::GetAirtimeVersion();
|
||||
|
||||
require_once __DIR__."/configs/navigation.php";
|
||||
|
||||
//DateTime in PHP 5.3.0+ need a default timezone set.
|
||||
date_default_timezone_set(Application_Model_Preference::GetTimezone());
|
||||
|
||||
Zend_Validate::setDefaultNamespaces("Zend");
|
||||
|
||||
$front = Zend_Controller_Front::getInstance();
|
||||
$front->registerPlugin(new RabbitMqPlugin());
|
||||
|
||||
//Logging::debug($_SERVER['REQUEST_URI']);
|
||||
|
||||
/* The bootstrap class should only be used to initialize actions that return a view.
|
||||
Actions that return JSON will not use the bootstrap class! */
|
||||
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
|
||||
|
|
|
@ -45,7 +45,7 @@ class Application_Common_OsPath{
|
|||
|
||||
/* Similar to the os.path.join python method
|
||||
* http://stackoverflow.com/a/1782990/276949 */
|
||||
function join() {
|
||||
public static function join() {
|
||||
$args = func_get_args();
|
||||
$paths = array();
|
||||
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
<?php
|
||||
|
||||
class Airtime_Zend_Log extends Zend_Log
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $_registeredErrorHandler = false;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array|boolean
|
||||
*/
|
||||
protected $_errorHandlerMap = false;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var callback
|
||||
*/
|
||||
protected $_origErrorHandler = null;
|
||||
|
||||
|
||||
public function __construct(Zend_Log_Writer_Abstract $writer = null)
|
||||
{
|
||||
parent::__construct($writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Error Handler will convert error into log message, and then call the original error handler
|
||||
*
|
||||
* @link http://www.php.net/manual/en/function.set-error-handler.php Custom error handler
|
||||
* @param int $errno
|
||||
* @param string $errstr
|
||||
* @param string $errfile
|
||||
* @param int $errline
|
||||
* @param array $errcontext
|
||||
* @return boolean
|
||||
*/
|
||||
public function errorHandler($errno, $errstr, $errfile, $errline, $errcontext)
|
||||
{
|
||||
$errorLevel = error_reporting();
|
||||
|
||||
if ($errorLevel && $errno) {
|
||||
if (isset($this->_errorHandlerMap[$errno])) {
|
||||
$priority = $this->_errorHandlerMap[$errno];
|
||||
} else {
|
||||
$priority = Zend_Log::INFO;
|
||||
}
|
||||
$this->log($errstr, $priority, array('errno'=>$errno, 'file'=>$errfile, 'line'=>$errline, 'context'=>$errcontext));
|
||||
}
|
||||
|
||||
if ($this->_origErrorHandler !== null) {
|
||||
return call_user_func($this->_origErrorHandler, $errno, $errstr, $errfile, $errline, $errcontext);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register Logging system as an error handler to log php errors
|
||||
* Note: it still calls the original error handler if set_error_handler is able to return it.
|
||||
*
|
||||
* Errors will be mapped as:
|
||||
* E_NOTICE, E_USER_NOTICE => NOTICE
|
||||
* E_WARNING, E_CORE_WARNING, E_USER_WARNING => WARN
|
||||
* E_ERROR, E_USER_ERROR, E_CORE_ERROR, E_RECOVERABLE_ERROR => ERR
|
||||
* E_DEPRECATED, E_STRICT, E_USER_DEPRECATED => DEBUG
|
||||
* (unknown/other) => INFO
|
||||
*
|
||||
* @link http://www.php.net/manual/en/function.set-error-handler.php Custom error handler
|
||||
*
|
||||
* @return Zend_Log
|
||||
*/
|
||||
public function registerErrorHandler()
|
||||
{
|
||||
// Only register once. Avoids loop issues if it gets registered twice.
|
||||
if ($this->_registeredErrorHandler) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->_origErrorHandler = set_error_handler(array($this, 'errorHandler'));
|
||||
|
||||
// Contruct a default map of phpErrors to Zend_Log priorities.
|
||||
// Some of the errors are uncatchable, but are included for completeness
|
||||
$this->_errorHandlerMap = array(
|
||||
E_NOTICE => Zend_Log::NOTICE,
|
||||
E_USER_NOTICE => Zend_Log::NOTICE,
|
||||
E_WARNING => Zend_Log::WARN,
|
||||
E_CORE_WARNING => Zend_Log::WARN,
|
||||
E_USER_WARNING => Zend_Log::WARN,
|
||||
E_ERROR => Zend_Log::ERR,
|
||||
E_USER_ERROR => Zend_Log::ERR,
|
||||
E_CORE_ERROR => Zend_Log::ERR,
|
||||
E_RECOVERABLE_ERROR => Zend_Log::ERR,
|
||||
E_STRICT => Zend_Log::DEBUG,
|
||||
);
|
||||
// PHP 5.3.0+
|
||||
if (defined('E_DEPRECATED')) {
|
||||
$this->_errorHandlerMap['E_DEPRECATED'] = Zend_Log::DEBUG;
|
||||
}
|
||||
if (defined('E_USER_DEPRECATED')) {
|
||||
$this->_errorHandlerMap['E_USER_DEPRECATED'] = Zend_Log::DEBUG;
|
||||
}
|
||||
|
||||
$this->_registeredErrorHandler = true;
|
||||
return $this;
|
||||
}
|
||||
}
|
|
@ -6,9 +6,18 @@ class Logging {
|
|||
private static $_path;
|
||||
|
||||
public static function getLogger(){
|
||||
if (!isset(self::$logger)) {
|
||||
if (!isset(self::$_logger)) {
|
||||
$writer = new Zend_Log_Writer_Stream(self::$_path);
|
||||
self::$_logger = new Zend_Log($writer);
|
||||
|
||||
if (Zend_Version::compareVersion("1.11") > 0){
|
||||
//Running Zend version 1.10 or lower. Need to instantiate our
|
||||
//own Zend Log class with backported code from 1.11.
|
||||
require_once __DIR__."/AirtimeLog.php";
|
||||
self::$_logger = new Airtime_Zend_Log($writer);
|
||||
} else {
|
||||
self::$_logger = new Zend_Log($writer);
|
||||
}
|
||||
self::$_logger->registerErrorHandler();
|
||||
}
|
||||
return self::$_logger;
|
||||
}
|
||||
|
|
|
@ -3,96 +3,109 @@
|
|||
class Application_Model_Preference
|
||||
{
|
||||
|
||||
public static function SetValue($key, $value, $isUserValue = false){
|
||||
global $CC_CONFIG;
|
||||
$con = Propel::getConnection();
|
||||
public static function SetValue($key, $value, $isUserValue = false){
|
||||
try {
|
||||
$con = Propel::getConnection();
|
||||
|
||||
//called from a daemon process
|
||||
if(!class_exists("Zend_Auth", false) || !Zend_Auth::getInstance()->hasIdentity()) {
|
||||
$id = NULL;
|
||||
}
|
||||
else {
|
||||
$auth = Zend_Auth::getInstance();
|
||||
$id = $auth->getIdentity()->id;
|
||||
}
|
||||
//called from a daemon process
|
||||
if(!class_exists("Zend_Auth", false) || !Zend_Auth::getInstance()->hasIdentity()) {
|
||||
$id = NULL;
|
||||
}
|
||||
else {
|
||||
$auth = Zend_Auth::getInstance();
|
||||
$id = $auth->getIdentity()->id;
|
||||
}
|
||||
|
||||
$key = pg_escape_string($key);
|
||||
$value = pg_escape_string($value);
|
||||
$key = pg_escape_string($key);
|
||||
$value = pg_escape_string($value);
|
||||
|
||||
//Check if key already exists
|
||||
$sql = "SELECT COUNT(*) FROM cc_pref"
|
||||
." WHERE keystr = '$key'";
|
||||
|
||||
//For user specific preference, check if id matches as well
|
||||
if($isUserValue) {
|
||||
$sql .= " AND subjid = '$id'";
|
||||
}
|
||||
|
||||
$result = $con->query($sql)->fetchColumn(0);
|
||||
|
||||
if($value == "") {
|
||||
$value = "NULL";
|
||||
}else {
|
||||
$value = "'$value'";
|
||||
}
|
||||
|
||||
if($result == 1) {
|
||||
// result found
|
||||
if(is_null($id) || !$isUserValue) {
|
||||
// system pref
|
||||
$sql = "UPDATE cc_pref"
|
||||
." SET subjid = NULL, valstr = $value"
|
||||
." WHERE keystr = '$key'";
|
||||
} else {
|
||||
// user pref
|
||||
$sql = "UPDATE cc_pref"
|
||||
. " SET valstr = $value"
|
||||
. " WHERE keystr = '$key' AND subjid = $id";
|
||||
}
|
||||
} else {
|
||||
// result not found
|
||||
if(is_null($id) || !$isUserValue) {
|
||||
// system pref
|
||||
$sql = "INSERT INTO cc_pref (keystr, valstr)"
|
||||
." VALUES ('$key', $value)";
|
||||
} else {
|
||||
// user pref
|
||||
$sql = "INSERT INTO cc_pref (subjid, keystr, valstr)"
|
||||
." VALUES ($id, '$key', $value)";
|
||||
}
|
||||
}
|
||||
return $con->exec($sql);
|
||||
}
|
||||
|
||||
public static function GetValue($key, $isUserValue = false){
|
||||
global $CC_CONFIG;
|
||||
$con = Propel::getConnection();
|
||||
|
||||
//Check if key already exists
|
||||
$sql = "SELECT COUNT(*) FROM cc_pref"
|
||||
." WHERE keystr = '$key'";
|
||||
//For user specific preference, check if id matches as well
|
||||
if ($isUserValue) {
|
||||
$auth = Zend_Auth::getInstance();
|
||||
if($auth->hasIdentity()) {
|
||||
$id = $auth->getIdentity()->id;
|
||||
$sql .= " AND subjid = '$id'";
|
||||
}
|
||||
}
|
||||
$result = $con->query($sql)->fetchColumn(0);
|
||||
if ($result == 0)
|
||||
return "";
|
||||
else {
|
||||
$sql = "SELECT valstr FROM cc_pref"
|
||||
//Check if key already exists
|
||||
$sql = "SELECT COUNT(*) FROM cc_pref"
|
||||
." WHERE keystr = '$key'";
|
||||
|
||||
//For user specific preference, check if id matches as well
|
||||
if($isUserValue && $auth->hasIdentity()) {
|
||||
$sql .= " AND subjid = '$id'";
|
||||
}
|
||||
|
||||
//For user specific preference, check if id matches as well
|
||||
if($isUserValue) {
|
||||
$sql .= " AND subjid = '$id'";
|
||||
}
|
||||
|
||||
$result = $con->query($sql)->fetchColumn(0);
|
||||
return ($result !== false) ? $result : "";
|
||||
|
||||
if($value == "") {
|
||||
$value = "NULL";
|
||||
}else {
|
||||
$value = "'$value'";
|
||||
}
|
||||
|
||||
if($result == 1) {
|
||||
// result found
|
||||
if(is_null($id) || !$isUserValue) {
|
||||
// system pref
|
||||
$sql = "UPDATE cc_pref"
|
||||
." SET subjid = NULL, valstr = $value"
|
||||
." WHERE keystr = '$key'";
|
||||
} else {
|
||||
// user pref
|
||||
$sql = "UPDATE cc_pref"
|
||||
. " SET valstr = $value"
|
||||
. " WHERE keystr = '$key' AND subjid = $id";
|
||||
}
|
||||
} else {
|
||||
// result not found
|
||||
if(is_null($id) || !$isUserValue) {
|
||||
// system pref
|
||||
$sql = "INSERT INTO cc_pref (keystr, valstr)"
|
||||
." VALUES ('$key', $value)";
|
||||
} else {
|
||||
// user pref
|
||||
$sql = "INSERT INTO cc_pref (subjid, keystr, valstr)"
|
||||
." VALUES ($id, '$key', $value)";
|
||||
}
|
||||
}
|
||||
|
||||
$con->exec($sql);
|
||||
|
||||
} catch (Exception $e){
|
||||
header('HTTP/1.0 503 Service Unavailable');
|
||||
Logging::log("Could not connect to database.");
|
||||
exit;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static function GetValue($key, $isUserValue = false){
|
||||
try {
|
||||
$con = Propel::getConnection();
|
||||
|
||||
//Check if key already exists
|
||||
$sql = "SELECT COUNT(*) FROM cc_pref"
|
||||
." WHERE keystr = '$key'";
|
||||
//For user specific preference, check if id matches as well
|
||||
if ($isUserValue) {
|
||||
$auth = Zend_Auth::getInstance();
|
||||
if($auth->hasIdentity()) {
|
||||
$id = $auth->getIdentity()->id;
|
||||
$sql .= " AND subjid = '$id'";
|
||||
}
|
||||
}
|
||||
$result = $con->query($sql)->fetchColumn(0);
|
||||
if ($result == 0)
|
||||
return "";
|
||||
else {
|
||||
$sql = "SELECT valstr FROM cc_pref"
|
||||
." WHERE keystr = '$key'";
|
||||
|
||||
//For user specific preference, check if id matches as well
|
||||
if($isUserValue && $auth->hasIdentity()) {
|
||||
$sql .= " AND subjid = '$id'";
|
||||
}
|
||||
|
||||
$result = $con->query($sql)->fetchColumn(0);
|
||||
return ($result !== false) ? $result : "";
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
header('HTTP/1.0 503 Service Unavailable');
|
||||
Logging::log("Could not connect to database.");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -561,10 +574,12 @@ class Application_Model_Preference
|
|||
|
||||
public static function GetAirtimeVersion(){
|
||||
if (defined('APPLICATION_ENV') && APPLICATION_ENV == "development" && function_exists('exec')){
|
||||
return self::GetValue("system_version")."+".exec("git rev-parse --short HEAD");
|
||||
} else {
|
||||
return self::GetValue("system_version");
|
||||
$version = exec("git rev-parse --short HEAD 2>/dev/null", $out, $return_code);
|
||||
if ($return_code == 0){
|
||||
return self::GetValue("system_version")."+".$version;
|
||||
}
|
||||
}
|
||||
return self::GetValue("system_version");
|
||||
}
|
||||
|
||||
public static function GetLatestVersion(){
|
||||
|
|
|
@ -25,6 +25,12 @@ class Application_Model_Scheduler {
|
|||
|
||||
$this->epochNow = microtime(true);
|
||||
$this->nowDT = DateTime::createFromFormat("U.u", $this->epochNow, new DateTimeZone("UTC"));
|
||||
|
||||
if ($this->nowDT === false){
|
||||
// DateTime::createFromFormat does not support millisecond string formatting in PHP 5.3.2 (Ubuntu 10.04).
|
||||
// In PHP 5.3.3 (Ubuntu 10.10), this has been fixed.
|
||||
$this->nowDT = DateTime::createFromFormat("U", time(), new DateTimeZone("UTC"));
|
||||
}
|
||||
|
||||
$this->user = Application_Model_User::GetCurrentUser();
|
||||
}
|
||||
|
@ -190,6 +196,12 @@ class Application_Model_Scheduler {
|
|||
$endEpoch = bcadd($startEpoch , (string) $durationSeconds, 6);
|
||||
|
||||
$dt = DateTime::createFromFormat("U.u", $endEpoch, new DateTimeZone("UTC"));
|
||||
|
||||
if ($dt === false) {
|
||||
//PHP 5.3.2 problem
|
||||
$dt = DateTime::createFromFormat("U", intval($endEpoch), new DateTimeZone("UTC"));
|
||||
}
|
||||
|
||||
return $dt;
|
||||
}
|
||||
|
||||
|
|
|
@ -91,6 +91,27 @@ class Application_Model_StoredFile {
|
|||
}
|
||||
else {
|
||||
$dbMd = array();
|
||||
|
||||
if (isset($p_md["MDATA_KEY_YEAR"])){
|
||||
// We need to make sure to clean this value before inserting into database.
|
||||
// If value is outside of range [-2^31, 2^31-1] then postgresl will throw error
|
||||
// when trying to retrieve this value. We could make sure number is within these bounds,
|
||||
// but simplest is to do substring to 4 digits (both values are garbage, but at least our
|
||||
// new garbage value won't cause errors). If the value is 2012-01-01, then substring to
|
||||
// 4 digits is an OK result.
|
||||
// CC-3771
|
||||
|
||||
$year = $p_md["MDATA_KEY_YEAR"];
|
||||
|
||||
if (strlen($year) > 4){
|
||||
$year = substr($year, 0, 4);
|
||||
}
|
||||
if (!is_numeric($year)){
|
||||
$year = 0;
|
||||
}
|
||||
$p_md["MDATA_KEY_YEAR"] = $year;
|
||||
}
|
||||
|
||||
foreach ($p_md as $mdConst => $mdValue) {
|
||||
$dbMd[constant($mdConst)] = $mdValue;
|
||||
}
|
||||
|
@ -235,7 +256,9 @@ class Application_Model_StoredFile {
|
|||
foreach ($c['user'] as $constant => $value) {
|
||||
if (preg_match('/^MDATA_KEY/', $constant)) {
|
||||
if (isset($dbmd_copy[$value])) {
|
||||
$md[$constant] = $this->getDbColMetadataValue($value);
|
||||
$propelColumn = $dbmd_copy[$value];
|
||||
$method = "get$propelColumn";
|
||||
$md[$constant] = $this->_file->$method();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
//error_reporting(E_ALL|E_STRICT);
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 'on');
|
||||
//error_reporting(E_ALL);
|
||||
//ini_set('display_errors', 'on');
|
||||
|
||||
// Define path to application directory
|
||||
defined('APPLICATION_PATH')
|
||||
|
|
|
@ -160,6 +160,19 @@ if [ "$DO_UPGRADE" -eq "1" ]; then
|
|||
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
|
||||
set -e
|
||||
|
||||
$SCRIPTPATH/include/airtime-copy-files.sh
|
||||
$SCRIPTPATH/include/airtime-initialize.sh $@
|
||||
|
||||
|
|
|
@ -261,7 +261,7 @@ class AirtimeInstall
|
|||
// 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 = AirtimeInstall::CONF_DIR_WWW."/build/sql/";
|
||||
$dir = self::GetAirtimeSrcDir()."/build/sql/";
|
||||
$files = array("schema.sql", "sequences.sql", "views.sql", "triggers.sql", "defaultdata.sql");
|
||||
|
||||
foreach ($files as $f){
|
||||
|
@ -453,7 +453,7 @@ class AirtimeInstall
|
|||
}
|
||||
|
||||
touch($file);
|
||||
chmod($file, 0755);
|
||||
chmod($file, 0644);
|
||||
chown($file, $CC_CONFIG['webServerUser']);
|
||||
chgrp($file, $CC_CONFIG['webServerUser']);
|
||||
}
|
||||
|
|
|
@ -35,11 +35,18 @@ AIRTIMEROOT=$SCRIPTPATH/../../
|
|||
|
||||
echo "* Creating /etc/airtime"
|
||||
mkdir -p /etc/airtime
|
||||
#if [ "$DO_UPGRADE" -eq "0" ]; then
|
||||
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
|
||||
|
@ -78,6 +85,13 @@ 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
|
||||
|
||||
echo "* Creating /var/log/airtime"
|
||||
mkdir -p /var/log/airtime
|
||||
chmod a+x /var/log/airtime
|
||||
touch /var/log/airtime/zendphp.log
|
||||
chown www-data:www-data /var/log/airtime/zendphp.log
|
||||
chmod 644 /var/log/airtime/zendphp.log
|
||||
|
||||
if [ "$web" = "t" ]; then
|
||||
echo "* Creating /usr/share/airtime"
|
||||
rm -rf "/usr/share/airtime"
|
||||
|
|
|
@ -14,22 +14,6 @@ SCRIPTPATH=`dirname $SCRIPT`
|
|||
|
||||
AIRTIMEROOT=$SCRIPTPATH/../../
|
||||
|
||||
#virtualenv_bin="/usr/lib/airtime/airtime_virtualenv/bin/"
|
||||
#. ${virtualenv_bin}activate
|
||||
|
||||
set +e
|
||||
if [ "$DO_UPGRADE" -eq "0" ]; then
|
||||
php --php-ini ${SCRIPTPATH}/../airtime-php.ini ${SCRIPTPATH}/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
|
||||
set -e
|
||||
|
||||
if [ "$mediamonitor" = "t" ]; then
|
||||
python $AIRTIMEROOT/python_apps/media-monitor/install/media-monitor-initialize.py
|
||||
fi
|
||||
|
|
|
@ -3,9 +3,6 @@
|
|||
* @package Airtime
|
||||
* @copyright 2011 Sourcefabric O.P.S.
|
||||
* @license http://www.gnu.org/licenses/gpl.txt
|
||||
*
|
||||
* Checks if a previous version of Airtime is currently installed and upgrades Airtime if so.
|
||||
* Performs a new install (new configs, database install) otherwise.
|
||||
*/
|
||||
require_once(__DIR__.'/AirtimeIni.php');
|
||||
require_once(__DIR__.'/AirtimeInstall.php');
|
||||
|
@ -56,7 +53,7 @@ if ($overwrite) {
|
|||
}
|
||||
|
||||
// Update the build.properties file to point to the correct directory.
|
||||
AirtimeIni::UpdateIniValue(AirtimeInstall::CONF_DIR_WWW.'/build/build.properties', 'project.home', AirtimeInstall::CONF_DIR_WWW);
|
||||
//AirtimeIni::UpdateIniValue(AirtimeInstall::CONF_DIR_WWW.'/build/build.properties', 'project.home', AirtimeInstall::CONF_DIR_WWW);
|
||||
|
||||
require_once(AirtimeInstall::GetAirtimeSrcDir().'/application/configs/conf.php');
|
||||
|
||||
|
@ -74,6 +71,4 @@ if ($db_install) {
|
|||
}
|
||||
}
|
||||
|
||||
AirtimeInstall::CreateZendPhpLogFile();
|
||||
|
||||
/* FINISHED AIRTIME PHP INSTALLER */
|
||||
|
|
|
@ -5,14 +5,23 @@
|
|||
*/
|
||||
class AirtimeDatabaseUpgrade{
|
||||
|
||||
public static function start(){
|
||||
public static function start($p_dbValues){
|
||||
echo "* Updating Database".PHP_EOL;
|
||||
self::task0();
|
||||
self::task0($p_dbValues);
|
||||
self::task1();
|
||||
echo " * Complete".PHP_EOL;
|
||||
}
|
||||
|
||||
private static function task0(){
|
||||
UpgradeCommon::MigrateTablesToVersion(__DIR__, '20120411174904');
|
||||
private static function task0($p_dbValues){
|
||||
//UpgradeCommon::MigrateTablesToVersion(__DIR__, '20120411174904');
|
||||
|
||||
$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\"");
|
||||
|
||||
$sql = "INSERT INTO cc_pref(\"keystr\", \"valstr\") VALUES('scheduled_play_switch', 'on')";
|
||||
UpgradeCommon::queryDb($sql);
|
||||
|
|
|
@ -49,9 +49,13 @@ require_once 'ConfFileUpgrade.php';
|
|||
require_once 'DbUpgrade.php';
|
||||
require_once 'MiscUpgrade.php';
|
||||
|
||||
|
||||
$filename = "/etc/airtime/airtime.conf";
|
||||
$values = parse_ini_file($filename, true);
|
||||
|
||||
UpgradeCommon::connectToDatabase();
|
||||
UpgradeCommon::SetDefaultTimezone();
|
||||
|
||||
AirtimeConfigFileUpgrade::start();
|
||||
AirtimeDatabaseUpgrade::start();
|
||||
AirtimeDatabaseUpgrade::start($values);
|
||||
AirtimeMiscUpgrade::start();
|
||||
|
|
|
@ -13,18 +13,18 @@ class Version20120411174904 extends AbstractMigration
|
|||
public function up(Schema $schema)
|
||||
{
|
||||
$this->_addSql("ALTER TABLE cc_show_instances ADD created timestamp");
|
||||
$this->_addSql("ALTER TABLE cc_show_instances ALTER COLUMN created SET NOT NULL");
|
||||
|
||||
$this->_addSql("ALTER TABLE cc_show_instances ADD last_scheduled timestamp");
|
||||
|
||||
//setting these to a default now for timeline refresh purposes.
|
||||
$now = gmdate("Y-m-d H:i:s");
|
||||
$this->_addSql("UPDATE cc_show_instances SET created = '$now'");
|
||||
$this->_addSql("UPDATE cc_show_instances SET last_scheduled = '$now'");
|
||||
|
||||
$this->_addSql("ALTER TABLE cc_show_instances ALTER COLUMN created SET NOT NULL");
|
||||
}
|
||||
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
DROP TRIGGER calculate_position ON cc_playlistcontents;
|
||||
|
||||
DROP FUNCTION calculate_position();
|
||||
|
||||
DROP VIEW cc_playlisttimes;
|
||||
|
||||
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;
|
||||
|
||||
ALTER TABLE cc_files
|
||||
DROP CONSTRAINT cc_music_dirs_folder_fkey;
|
||||
|
||||
ALTER TABLE cc_playlist
|
||||
DROP CONSTRAINT cc_playlist_editedby_fkey;
|
||||
|
||||
CREATE SEQUENCE cc_subjs_token_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MAXVALUE
|
||||
NO MINVALUE
|
||||
CACHE 1;
|
||||
|
||||
CREATE TABLE cc_subjs_token (
|
||||
id integer DEFAULT nextval('cc_subjs_token_id_seq'::regclass) NOT NULL,
|
||||
user_id integer NOT NULL,
|
||||
"action" character varying(255) NOT NULL,
|
||||
token character varying(40) NOT NULL,
|
||||
created timestamp without time zone NOT NULL
|
||||
);
|
||||
|
||||
ALTER TABLE cc_files
|
||||
ADD COLUMN utime timestamp(6) without time zone,
|
||||
ADD COLUMN lptime timestamp(6) without time zone,
|
||||
ADD COLUMN file_exists boolean DEFAULT true,
|
||||
ALTER COLUMN bit_rate TYPE integer USING airtime_to_int(bit_rate) /* TYPE change - table: cc_files original: character varying(32) new: integer */,
|
||||
ALTER COLUMN sample_rate TYPE integer USING airtime_to_int(bit_rate) /* TYPE change - table: cc_files original: character varying(32) new: integer */,
|
||||
ALTER COLUMN length TYPE interval /* TYPE change - table: cc_files original: time without time zone new: interval */,
|
||||
ALTER COLUMN length SET DEFAULT '00:00:00'::interval;
|
||||
|
||||
ALTER TABLE cc_music_dirs
|
||||
ADD COLUMN "exists" boolean DEFAULT true,
|
||||
ADD COLUMN watched boolean DEFAULT true;
|
||||
|
||||
ALTER TABLE cc_playlist
|
||||
DROP COLUMN "state",
|
||||
DROP COLUMN currentlyaccessing,
|
||||
DROP COLUMN editedby,
|
||||
DROP COLUMN creator,
|
||||
ADD COLUMN utime timestamp(6) without time zone,
|
||||
ADD COLUMN creator_id integer,
|
||||
ADD COLUMN length interval DEFAULT '00:00:00'::interval;
|
||||
|
||||
ALTER TABLE cc_playlistcontents
|
||||
ALTER COLUMN cliplength TYPE interval /* TYPE change - table: cc_playlistcontents original: time without time zone new: interval */,
|
||||
ALTER COLUMN cliplength SET DEFAULT '00:00:00'::interval,
|
||||
ALTER COLUMN cuein TYPE interval /* TYPE change - table: cc_playlistcontents original: time without time zone new: interval */,
|
||||
ALTER COLUMN cuein SET DEFAULT '00:00:00'::interval,
|
||||
ALTER COLUMN cueout TYPE interval /* TYPE change - table: cc_playlistcontents original: time without time zone new: interval */,
|
||||
ALTER COLUMN cueout SET DEFAULT '00:00:00'::interval;
|
||||
|
||||
ALTER TABLE cc_schedule
|
||||
DROP COLUMN playlist_id,
|
||||
DROP COLUMN group_id,
|
||||
DROP COLUMN schedule_group_played,
|
||||
ADD COLUMN playout_status smallint DEFAULT 1 NOT NULL,
|
||||
ALTER COLUMN clip_length TYPE interval /* TYPE change - table: cc_schedule original: time without time zone new: interval */,
|
||||
ALTER COLUMN clip_length SET DEFAULT '00:00:00'::interval,
|
||||
ALTER COLUMN cue_in TYPE interval /* TYPE change - table: cc_schedule original: time without time zone new: interval */,
|
||||
ALTER COLUMN cue_in SET DEFAULT '00:00:00'::interval,
|
||||
ALTER COLUMN cue_out TYPE interval /* TYPE change - table: cc_schedule original: time without time zone new: interval */,
|
||||
ALTER COLUMN cue_out SET DEFAULT '00:00:00'::interval;
|
||||
|
||||
ALTER TABLE cc_show
|
||||
ADD COLUMN live_stream_using_airtime_auth boolean DEFAULT false,
|
||||
ADD COLUMN live_stream_using_custom_auth boolean DEFAULT false,
|
||||
ADD COLUMN live_stream_user character varying(255),
|
||||
ADD COLUMN live_stream_pass character varying(255);
|
||||
|
||||
ALTER TABLE cc_show_instances
|
||||
ADD COLUMN created timestamp without time zone,
|
||||
ADD COLUMN last_scheduled timestamp without time zone,
|
||||
ALTER COLUMN time_filled TYPE interval /* TYPE change - table: cc_show_instances original: time without time zone new: interval */,
|
||||
ALTER COLUMN time_filled SET DEFAULT '00:00:00'::interval;
|
||||
|
||||
UPDATE cc_show_instances SET created = now();
|
||||
|
||||
ALTER TABLE cc_show_instances
|
||||
ALTER COLUMN created SET NOT NULL;
|
||||
|
||||
ALTER TABLE cc_subjs_token
|
||||
ADD CONSTRAINT cc_subjs_token_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE cc_files
|
||||
ADD CONSTRAINT cc_music_dirs_folder_fkey FOREIGN KEY (directory) REFERENCES cc_music_dirs(id);
|
||||
|
||||
ALTER TABLE cc_playlist
|
||||
ADD CONSTRAINT cc_playlist_createdby_fkey FOREIGN KEY (creator_id) REFERENCES cc_subjs(id);
|
||||
|
||||
ALTER TABLE cc_subjs_token
|
||||
ADD CONSTRAINT cc_subjs_token_idx UNIQUE (token);
|
||||
|
||||
ALTER TABLE cc_subjs_token
|
||||
ADD CONSTRAINT cc_subjs_token_userid_fkey FOREIGN KEY (user_id) REFERENCES cc_subjs(id) ON DELETE CASCADE;
|
||||
|
||||
CREATE INDEX cc_files_file_exists_idx ON cc_files USING btree (file_exists);
|
||||
|
||||
DROP FUNCTION airtime_to_int(chartoconvert character varying);
|
|
@ -88,17 +88,16 @@ class AirtimeMetadata:
|
|||
try:
|
||||
airtime_file = mutagen.File(m['MDATA_KEY_FILEPATH'], easy=True)
|
||||
|
||||
for key in m.keys() :
|
||||
for key in m:
|
||||
if key in self.airtime2mutagen:
|
||||
value = m[key]
|
||||
if (value is not None):
|
||||
self.logger.debug("Saving %s to file", key)
|
||||
self.logger.debug(value)
|
||||
if isinstance(value, basestring) and (len(value) > 0):
|
||||
airtime_file[self.airtime2mutagen[key]] = api_client.encode_to(value, 'utf-8')
|
||||
elif isinstance(value, int):
|
||||
airtime_file[self.airtime2mutagen[key]] = str(value)
|
||||
|
||||
|
||||
if value is not None:
|
||||
value = unicode(value)
|
||||
|
||||
if len(value) > 0:
|
||||
self.logger.debug("Saving key '%s' with value '%s' to file", key, value)
|
||||
airtime_file[self.airtime2mutagen[key]] = value
|
||||
|
||||
airtime_file.save()
|
||||
except Exception, e:
|
||||
|
|
|
@ -62,7 +62,7 @@ class AirtimeNotifier(Notifier):
|
|||
message.ack()
|
||||
|
||||
self.logger.info("Received md from RabbitMQ: " + body)
|
||||
m = json.loads(message.body)
|
||||
m = json.loads(message.body)
|
||||
|
||||
if m['event_type'] == "md_update":
|
||||
self.logger.info("AIRTIME NOTIFIER md update event")
|
||||
|
@ -103,9 +103,9 @@ class AirtimeNotifier(Notifier):
|
|||
self.mmc.ensure_is_dir(self.config.imported_directory)
|
||||
self.mmc.ensure_is_dir(self.config.organize_directory)
|
||||
|
||||
self.mmc.set_needed_file_permissions(self.config.storage_directory, True)
|
||||
self.mmc.set_needed_file_permissions(self.config.imported_directory, True)
|
||||
self.mmc.set_needed_file_permissions(self.config.organize_directory, True)
|
||||
self.mmc.is_readable(self.config.storage_directory, True)
|
||||
self.mmc.is_readable(self.config.imported_directory, True)
|
||||
self.mmc.is_readable(self.config.organize_directory, True)
|
||||
|
||||
self.watch_directory(new_storage_directory)
|
||||
elif m['event_type'] == "file_delete":
|
||||
|
@ -150,7 +150,6 @@ class AirtimeNotifier(Notifier):
|
|||
file_md = None
|
||||
data = None
|
||||
|
||||
|
||||
if (os.path.exists(filepath) and (mode == self.config.MODE_CREATE)):
|
||||
if file_md is None:
|
||||
mutagen = self.md_manager.get_md_from_file(filepath)
|
||||
|
@ -192,17 +191,13 @@ class AirtimeNotifier(Notifier):
|
|||
|
||||
mm = self.proc_fun()
|
||||
|
||||
self.mmc.set_needed_file_permissions(directory, True)
|
||||
self.mmc.is_readable(directory, True)
|
||||
for (path, dirs, files) in os.walk(directory):
|
||||
|
||||
for d in dirs:
|
||||
self.mmc.set_needed_file_permissions(os.path.join(path, d), True)
|
||||
|
||||
for filename in files:
|
||||
full_filepath = os.path.join(path, filename)
|
||||
|
||||
if self.mmc.is_audio_file(full_filepath):
|
||||
if self.mmc.set_needed_file_permissions(full_filepath, False):
|
||||
if self.mmc.is_readable(full_filepath, False):
|
||||
self.logger.info("importing %s", full_filepath)
|
||||
event = {'filepath': full_filepath, 'mode': self.config.MODE_CREATE, 'is_recorded_show': False}
|
||||
mm.multi_queue.put(event)
|
||||
|
|
|
@ -134,7 +134,7 @@ class AirtimeProcessEvent(ProcessEvent):
|
|||
#file is being overwritten/replaced in GUI.
|
||||
elif "goutputstream" in pathname:
|
||||
self.temp_files[pathname] = None
|
||||
elif self.mmc.is_audio_file(pathname):
|
||||
elif self.mmc.is_audio_file(pathname) and self.mmc.is_readable(pathname, False):
|
||||
if self.mmc.is_parent_directory(pathname, self.config.organize_directory):
|
||||
#file was created in /srv/airtime/stor/organize. Need to process and move
|
||||
#to /srv/airtime/stor/imported
|
||||
|
@ -151,14 +151,14 @@ class AirtimeProcessEvent(ProcessEvent):
|
|||
self.logger.error('Exception: %s', e)
|
||||
self.logger.error("traceback: %s", traceback.format_exc())
|
||||
|
||||
self.mmc.set_needed_file_permissions(pathname, dir)
|
||||
self.mmc.is_readable(pathname, dir)
|
||||
is_recorded = self.mmc.is_parent_directory(pathname, self.config.recorded_directory)
|
||||
self.file_events.append({'mode': self.config.MODE_CREATE, 'filepath': pathname, 'is_recorded_show': is_recorded})
|
||||
|
||||
else:
|
||||
#event is because of a created directory
|
||||
if self.mmc.is_parent_directory(pathname, self.config.storage_directory):
|
||||
self.mmc.set_needed_file_permissions(pathname, dir)
|
||||
self.mmc.is_readable(pathname, dir)
|
||||
|
||||
def process_IN_MODIFY(self, event):
|
||||
# if IN_MODIFY is followed by IN_CREATE, it's not true modify event
|
||||
|
@ -236,10 +236,9 @@ class AirtimeProcessEvent(ProcessEvent):
|
|||
filename = self.mount_file_dir +"/mtab"
|
||||
if event.pathname in filename:
|
||||
self.handle_mount_change()
|
||||
#if stuff dropped in stor via a UI move must change file permissions.
|
||||
self.mmc.set_needed_file_permissions(event.pathname, event.dir)
|
||||
|
||||
if not event.dir:
|
||||
if self.mmc.is_audio_file(event.name):
|
||||
if self.mmc.is_audio_file(event.name) and self.mmc.is_readable(event.pathname, False):
|
||||
if event.cookie in self.temp_files:
|
||||
self.file_events.append({'filepath': event.pathname, 'mode': self.config.MODE_MODIFY})
|
||||
del self.temp_files[event.cookie]
|
||||
|
|
|
@ -49,7 +49,7 @@ class MediaMonitorCommon:
|
|||
return False
|
||||
|
||||
#check if file is readable by "nobody"
|
||||
def has_correct_permissions(self, filepath, euid='nobody', egid='nogroup'):
|
||||
def is_user_readable(self, filepath, euid='nobody', egid='nogroup'):
|
||||
|
||||
try:
|
||||
uid = pwd.getpwnam(euid)[2]
|
||||
|
@ -76,35 +76,13 @@ class MediaMonitorCommon:
|
|||
return readable
|
||||
|
||||
# the function only changes the permission if its not readable by www-data
|
||||
def set_needed_file_permissions(self, item, is_dir):
|
||||
def is_readable(self, item, is_dir):
|
||||
try:
|
||||
omask = os.umask(0)
|
||||
if not self.has_correct_permissions(item, 'www-data', 'www-data') or not self.has_correct_permissions(item, 'pypo', 'pypo'):
|
||||
# stats.st_mode is the original permission
|
||||
# stat.S_IROTH - readable by all permission
|
||||
# stat.S_IXOTH - excutable by all permission
|
||||
# try to set permission
|
||||
if self.is_parent_directory(item, self.config.storage_directory) or self.is_parent_directory(item, self.config.imported_directory) or self.is_parent_directory(item, self.config.organize_directory):
|
||||
if is_dir is True:
|
||||
os.chmod(item, 02777)
|
||||
else:
|
||||
os.chmod(item, 0666)
|
||||
else :
|
||||
# add world readable permission
|
||||
stats = os.stat(item)
|
||||
if is_dir is True:
|
||||
bitor = stats.st_mode | stat.S_IROTH | stat.S_IXOTH
|
||||
else:
|
||||
bitor = stats.st_mode | stat.S_IROTH
|
||||
os.chmod(item, bitor)
|
||||
return self.is_user_readable(item, 'www-data', 'www-data') \
|
||||
and self.is_user_readable(item, 'pypo', 'pypo')
|
||||
except Exception, e:
|
||||
self.logger.error("Failed to change file's owner/group/permissions. %s", e)
|
||||
self.logger.error("traceback: %s", traceback.format_exc())
|
||||
self.logger.warn("Failed to check owner/group/permissions for %s", item)
|
||||
return False
|
||||
finally:
|
||||
os.umask(omask)
|
||||
return True
|
||||
|
||||
|
||||
#checks if path is a directory, and if it doesnt exist, then creates it.
|
||||
#Otherwise prints error to log file.
|
||||
|
|
|
@ -51,6 +51,7 @@ def configure_locale():
|
|||
|
||||
if current_locale_encoding not in ['utf-8', 'utf8']:
|
||||
logger.error("Need a UTF-8 locale. Currently '%s'. Exiting..." % current_locale_encoding)
|
||||
sys.exit(1)
|
||||
|
||||
# configure logging
|
||||
try:
|
||||
|
|
|
@ -129,7 +129,8 @@ class PypoPush(Thread):
|
|||
tn.write('exit\n')
|
||||
tn.read_all()
|
||||
except Exception, e:
|
||||
self.logger.error(str(e))
|
||||
self.logger.error("Error connecting to Liquidsoap: %s", e)
|
||||
response = []
|
||||
finally:
|
||||
self.telnet_lock.release()
|
||||
|
||||
|
|
Loading…
Reference in New Issue