Merge branch 'master' of dev.sourcefabric.org:airtime into 1.8.1

Conflicts:
	VERSION
	airtime_mvc/application/configs/conf.php
This commit is contained in:
martin 2011-04-26 15:34:53 -04:00
commit 9236f4941d
26 changed files with 494 additions and 275 deletions

57
CREDITS
View File

@ -19,51 +19,24 @@ Daniel James
Paul Baranowski (paul.baranowski@sourcefabric.org)
Role: Project Manager
Version 1.8.0
-------------
-The calendar is now faster by 5-8X. For example, if the "month" calendar view had shows scheduled for every hour of every day, it used to take 16 seconds to load. Now it takes 2 seconds.
-Users can now edit shows. Now it is possible to change a show after it is created - you can change the simple stuff, like "Name", "Description", and "URL", but also change the complex stuff like repeat days and rebroadcast days.
-It is possible to have up to ten rebroadcast shows now, previously it was only up to five. Rebroadcast shows are hidden
-New improved look & feel of the calendar (thanks to the "FullCalendar" jQuery project).
-Installation now puts files in standard locations in the Linux file hierarchy, which prepares the project to be accepted into Ubuntu and Debian. Also because of our wish to be part of those projects, the default output stream type is now OGG instead of MP3 -- due to MP3 licensing issues. This configuration can be changed in "/etc/airtime/liquidsoap.conf".
-You now have the ability to start and stop pypo and the show recorder from the command line with the commands "airtime-pypo-start", "airtime-pypo-stop", "airtime-show-recorder-start", and "airtime-show-recorder-stop".
-The installation script now has two options: --perserve to keep your existing config files, or --overwrite to replace your existing config files with new ones.
-Uninstall will no longer remove your Airtime config files or remove your music storage directory.
-Bug fixes:
-CC-2192 Schedule sent to pypo is not sorted by start time.
-CC-2175 Overbooking: Cut off shows when they are done
-CC-2174 Need formatting and a warning icon for the message for overbooking a show
-CC-2039 Upload file: file name cropped
-CC-2177 Schedule editing does not work under Firefox 4
Version 1.7.0
-------------
-Recording and automatic scheduling/broadcasting of live shows
-Recording/rebroadcast status of a show is shown in "Now Playing" and "Calendar"
-Can rebroadcast a show at multiple times and dates
-Automatic upload of recorded shows to Soundcloud
-Frontend JQuery widgets for public-facing websites to show your visitors what's playing and the upcoming schedule
-Ability to over-book a show and automatically cut and fade out song if it goes beyond the show time
-Ability to delete audio files
-Ability to cancel the currently playing show
-Any changes to the schedule are immediately seen by the playout engine
-In version 1.6, you had to make sure that your show was ready to go 30 seconds before it started.
-Upgrade support (should be able to upgrade from any version, unlike 1.6.1 which required an uninstall of 1.6.0 first)
-"Now Playing" list view:
-audio items are now grouped by show.
-If a show is not fully scheduled, the user is notified how many seconds of silence are at the end of the show in this View.
-Audio items that play past the show's end time have a visual notification that they will be cut off
-Ability to change metadata tag display format for web streams
-Config files moved to /etc/airtime. This means all config files are in one convenient location and separated from the code, so you can -upgrade your code independently of your config files.
-Redesign of Preferences screen
-Bug fixes:
-CC-2082 OGG stream dies after every song when using MPlayer
-CC-1894 Warn users about time zone differences or clock drift problems on the server
-CC-2058 Utilities are not in the system $PATH
-CC-2051 Unable to change user password
-CC-2030 Icon needed for Cue In/Out
-CC-1955 Special character support in the library search
Naomi Aro (naomi.aro@sourcefabric.org)
Role: Software Developer
Martin Konecny (martin.konecny@sourcefabric.org)
Role: Software Developer
Ofir Gal (ofir.gal@sourcefabric.org)
Role: QA
Daniel James
Role: Documentor & QA
Paul Baranowski (paul.baranowski@sourcefabric.org)
Role: Project Manager
Version 1.6.1
-------------

View File

@ -1,10 +1,36 @@
1.8.0 - April 19, 2011
* Ability to edit a show
* Speedup of calendar (approx to 5-8x faster now)
* Install process now put files in the right place for linux systems
* Improvements to upgrade framework
* The biggest feature of this release is the ability to edit shows. You can
change everything from Name, Description, and URL, to repeat and
rebroadcast days. Show instances will be dynamically created or removed as
needed. Radio stations will be pleased to know they can now have up to
ten rebroadcast shows too.
* Airtimes calendar now looks, feels and performs better than ever. Loading
a station schedule is now five to eight times faster. In our tests of 1.7,
if the month calendar had shows scheduled for every hour of every day, it
used to take 16 seconds to load. Now in 1.8 it takes two seconds.
* It is possible to have up to ten rebroadcast shows now, in 1.7 it was only
up to five.
* Airtimes new installation script has two options for increased install
flexibility: --preserve to keep your existing config files, or --overwrite
to replace your existing config files with new ones. Uninstall no longer
removes Airtime config files or the music storage directory.
* New improved look & feel of the calendar (thanks to the "FullCalendar"
jQuery project).
* Installation now puts files in standard locations in the Linux file
hierarchy, which prepares the project to be accepted into Ubuntu and Debian.
Also because of our wish to be part of those projects, the default output
stream type is now OGG instead of MP3 -- due to MP3 licensing issues.
This configuration can be changed in "/etc/airtime/liquidsoap.conf".
* You now have the ability to start and stop pypo and the show recorder from
the command line with the commands "airtime-pypo-start",
"airtime-pypo-stop", "airtime-show-recorder-start", and
"airtime-show-recorder-stop".
* Bug fixes:
o CC-2192 Schedule sent to pypo is not sorted by start time.
* CC-2192 Schedule sent to pypo is not sorted by start time.
* CC-2175 Overbooking: Cut off shows when they are done
* CC-2174 Need formatting and a warning icon for the message for overbooking a show
* CC-2039 Upload file: file name cropped
* CC-2177 Schedule editing does not work under Firefox 4
1.7.0 - April 4, 2011
* Recording and automatic scheduling/broadcasting of live shows

View File

@ -10,6 +10,7 @@ Propel::init(__DIR__."/configs/airtime-conf.php");
$tz = ini_get('date.timezone') ? ini_get('date.timezone') : 'UTC';
date_default_timezone_set($tz);
require_once __DIR__."/logging/Logging.php";
require_once __DIR__."/configs/constants.php";
require_once __DIR__."/configs/conf.php";
require_once 'DB.php';
@ -33,8 +34,8 @@ if (PEAR::isError($CC_DBC)) {
exit(1);
}
$CC_DBC->setFetchMode(DB_FETCHMODE_ASSOC);
Logging::setLogPath('/var/log/airtime/zendphp.log');
//Zend_Session::start();
Zend_Validate::setDefaultNamespaces("Zend");
$front = Zend_Controller_Front::getInstance();

View File

@ -0,0 +1,19 @@
<?php
class Logging {
private static $_logger;
private static $_path;
public static function getLogger(){
if (!isset(self::$logger)) {
$writer = new Zend_Log_Writer_Stream(self::$_path);
self::$_logger = new Zend_Log($writer);
}
return self::$_logger;
}
public static function setLogPath($path){
self::$_path = $path;
}
}

View File

@ -113,6 +113,12 @@ class Playlist {
return TRUE;
}
public static function deleteAll()
{
global $CC_CONFIG, $CC_DBC;
$sql = 'DELETE FROM '.$CC_CONFIG["playListTable"];
$CC_DBC->query($sql);
}
/**
* Delete the file from all playlists.

View File

@ -60,7 +60,6 @@ class ScheduleGroup {
if (empty($length)) {
return new PEAR_Error("Length is empty.");
}
// Insert into the table
$this->groupId = $CC_DBC->GetOne("SELECT nextval('schedule_group_id_seq')");
@ -681,5 +680,11 @@ class Schedule {
return $result;
}
public static function deleteAll()
{
global $CC_CONFIG, $CC_DBC;
$CC_DBC->query("TRUNCATE TABLE ".$CC_CONFIG["scheduleTable"]);
}
}

View File

@ -1,6 +1,6 @@
<?php
require_once("Playlist.php");
require_once(dirname(__FILE__)."/../../library/getid3/var/getid3.php");
require_once("getid3/var/getid3.php");
require_once("Schedule.php");
class Metadata {
@ -730,7 +730,6 @@ class StoredFile {
return $storedFile;
}
/**
* Create instance of StoreFile object and recall existing file
* by gunid.
@ -757,6 +756,14 @@ class StoredFile {
}
public static function GetAll()
{
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT * FROM ".$CC_CONFIG["filesTable"];
$rows = $CC_DBC->GetAll($sql);
return $rows;
}
/**
* Generate the location to store the file.
* It creates the subdirectory if needed.
@ -1163,10 +1170,7 @@ class StoredFile {
return TRUE;
}
else {
return PEAR::raiseError(
"StoredFile::deleteFile: unlink failed ({$this->filepath})",
GBERR_FILEIO
);
return PEAR::raiseError("StoredFile::deleteFile: unlink failed ({$this->filepath})");
}
}
else {
@ -1205,6 +1209,34 @@ class StoredFile {
}
public static function deleteById($p_id)
{
global $CC_CONFIG, $CC_DBC;
if (!is_numeric($p_id)) {
return FALSE;
}
$sql = "DELETE FROM ".$CC_CONFIG["filesTable"]." WHERE id=$p_id";
$res = $CC_DBC->query($sql);
if (PEAR::isError($res)) {
return $res;
}
return TRUE;
}
public static function deleteAll()
{
global $CC_CONFIG, $CC_DBC;
$files = StoredFile::getAll();
foreach ($files as $file) {
$media = StoredFile::Recall($file["id"]);
$result = $media->delete();
if (PEAR::isError($result)) {
return $result;
}
}
}
/**
* Returns an array of playlist objects that this file is a part of.
* @return array

View File

@ -36,7 +36,7 @@
?>
<?php foreach ($this->element->getElement('streamFormat')->getMultiOptions() as $radio) : ?>
<label for="streamFormat-<?php echo $i ?>">
<input type="radio" value="<?php echo $i ?>" id="streamFormat-<?php echo $i ?>" name="streamFormat" <?php if($i == $value){echo 'checked="checked"';}?>/>
<input type="radio" value="<?php echo $i ?>" id="streamFormat-<?php echo $i ?>" name="streamFormat" <?php if($i == $value){echo 'checked="checked"';}?> >
<?php echo $radio ?>
</input>
</label>
@ -59,7 +59,7 @@
?>
<?php foreach ($this->element->getElement('thirdPartyApi')->getMultiOptions() as $radio) : ?>
<label for="thirdPartyApi-<?php echo $i ?>">
<input type="radio" value="<?php echo $i ?>" id="thirdPartyApi-<?php echo $i ?>" name="thirdPartyApi" <?php if($i == $value){echo 'checked="checked"';}?> />
<input type="radio" value="<?php echo $i ?>" id="thirdPartyApi-<?php echo $i ?>" name="thirdPartyApi" <?php if($i == $value){echo 'checked="checked"';}?>>
<?php echo $radio ?>
</input>
</label>

View File

@ -1,3 +1,3 @@
<?php
echo this->entries;
echo $this->entries;
?>

View File

@ -104,6 +104,7 @@ function setAddShowEvents() {
form.find("#add_show_rebroadcast").click(function(){
$(this).blur();
if(form.find("#add_show_record").attr('checked')){
if($(this).attr('checked') && !form.find("#add_show_repeats").attr('checked')) {
form.find("#add_show_rebroadcast_absolute").show();
}
@ -113,6 +114,7 @@ function setAddShowEvents() {
else {
form.find("#schedule-record-rebroadcast > fieldset:not(:first-child)").hide();
}
}
});
form.find("#add_show_repeat_type").change(function(){

View File

@ -228,7 +228,7 @@ function buildScheduleDialog(json){
dialog.dialog({
autoOpen: false,
title: 'Schedule Playlist',
title: 'Schedule Media',
width: 1100,
height: 550,
modal: true,

View File

@ -51,10 +51,10 @@ else if (!isset($opts->p) && !isset($opts->o)) {
}
}
else {
echo "* Creating INI files".PHP_EOL;
AirtimeIni::CreateIniFiles();
$overwrite = true;
}
}
if ($overwrite) {
echo "* Creating INI files".PHP_EOL;
AirtimeIni::CreateIniFiles();
@ -90,6 +90,8 @@ AirtimeInstall::ChangeDirOwnerToWebserver($CC_CONFIG["storageDir"]);
AirtimeInstall::CreateSymlinksToUtils();
AirtimeInstall::CreateZendPhpLogFile();
echo PHP_EOL."*** Pypo Installation ***".PHP_EOL;
system("python ".__DIR__."/../python_apps/pypo/install/pypo-install.py");

View File

@ -90,6 +90,7 @@ system($command);
AirtimeInstall::RemoveSymlinks();
AirtimeInstall::UninstallBinaries();
AirtimeInstall::RemoveLogDirectories();
echo PHP_EOL;
echo "****************************** Uninstall Complete ******************************".PHP_EOL;

View File

@ -14,13 +14,16 @@ require_once(dirname(__FILE__).'/include/AirtimeInstall.php');
AirtimeInstall::ExitIfNotRoot();
AirtimeInstall::DbConnect(true);
if(AirtimeInstall::DbTableExists('cc_show_rebroadcast') === true) {
$version = AirtimeInstall::GetAirtimeVersion();
if (!$version){
if(AirtimeInstall::DbTableExists('cc_show_rebroadcast') === true) {
$version = "1.7.0";
echo "Airtime Version: ".$version." ".PHP_EOL;
}
else {
}
else {
$version = "1.6";
echo "Airtime Version: ".$version." ".PHP_EOL;
}
}
echo "******************************** Update Begin *********************************".PHP_EOL;
@ -31,6 +34,9 @@ if(strcmp($version, "1.7.0") < 0) {
if(strcmp($version, "1.8.0") < 0) {
system("php ".__DIR__."/upgrades/airtime-1.8/airtime-upgrade.php");
}
if (strcmp($version, "1.9.0") < 0){
system("php ".__DIR__."/upgrades/airtime-1.9/airtime-upgrade.php");
}
AirtimeInstall::SetAirtimeVersion(AIRTIME_VERSION);

View File

@ -8,6 +8,7 @@ class AirtimeInstall
const CONF_DIR_BINARIES = "/usr/lib/airtime";
const CONF_DIR_STORAGE = "/srv/airtime";
const CONF_DIR_WWW = "/var/www/airtime";
const CONF_DIR_LOG = "/var/log/airtime";
public static function GetAirtimeSrcDir()
{
@ -321,4 +322,28 @@ class AirtimeInstall
}
}
}
public static function CreateZendPhpLogFile(){
global $CC_CONFIG;
echo "* Creating logs directory ".AirtimeInstall::CONF_DIR_LOG.PHP_EOL;
$path = AirtimeInstall::CONF_DIR_LOG;
$file = $path.'/zendphp.log';
if (!file_exists($path)){
mkdir($path, 0755, true);
}
touch($file);
chmod($file, 0755);
chown($file, $CC_CONFIG['webServerUser']);
chgrp($file, $CC_CONFIG['webServerUser']);
}
public static function RemoveLogDirectories(){
$path = AirtimeInstall::CONF_DIR_LOG;
echo "* Removing logs directory ".$path.PHP_EOL;
exec("rm -rf $path");
}
}

View File

@ -0,0 +1,14 @@
<?php
/**
* @package Airtime
* @subpackage StorageServer
* @copyright 2010 Sourcefabric O.P.S.
* @license http://www.gnu.org/licenses/gpl.txt
*/
set_include_path(__DIR__.'/../../../airtime_mvc/library' . PATH_SEPARATOR . get_include_path());
require_once __DIR__.'/../../../airtime_mvc/application/configs/conf.php';
require_once(dirname(__FILE__).'/../../include/AirtimeInstall.php');
require_once(dirname(__FILE__).'/../../include/AirtimeIni.php');
AirtimeInstall::CreateZendPhpLogFile();

View File

@ -180,7 +180,7 @@ class AirTimeApiClient(ApiClientInterface):
print 'Unable to get Airtime version number.'
print
return False
elif (version[0:4] != "1.8."):
elif (version[0:4] != "1.9."):
if (verbose):
print 'Airtime version: ' + str(version)
print 'pypo not compatible with this version of Airtime.'

View File

@ -39,9 +39,6 @@ try:
os.system("python /usr/bin/airtime-pypo-stop")
print "Removing log directories"
remove_path(config["log_base_dir"])
print "Removing cache directories"
remove_path(config["cache_base_dir"])

View File

@ -0,0 +1,29 @@
api_client = "airtime"
# Hostname
base_url = 'localhost'
base_port = 80
# where the binary files live
bin_dir = '/usr/lib/airtime/media-monitor'
# base path to store recordered shows at
base_recorded_files = '/var/tmp/airtime/show-recorder/'
# where the logging files live
log_dir = '/var/log/airtime/show-recorder'
# Value needed to access the API
api_key = 'AAA'
# Path to the base of the API
api_base = 'api'
# URL to get the version number of the server API
version_url = 'version/api_key/%%api_key%%'
# URL to get the schedule of shows set to record
show_schedule_url = 'recorded-shows/format/json/api_key/%%api_key%%'
# URL to upload the recorded show's file to Airtime
upload_file_url = 'upload-recorded/format/json/api_key/%%api_key%%'

View File

@ -0,0 +1,52 @@
import os
import pyinotify
from pyinotify import WatchManager, Notifier, ThreadedNotifier, EventsCodes, ProcessEvent
# configure logging
try:
logging.config.fileConfig("logging.cfg")
except Exception, e:
print 'Error configuring logging: ', e
sys.exit()
# loading config file
try:
config = ConfigObj('/etc/airtime/recorder.cfg')
except Exception, e:
print 'Error loading config file: ', e
sys.exit()
# watched events
mask = pyinotify.ALL_EVENTS
wm = WatchManager()
wdd = wm.add_watch('/srv/airtime/stor', mask, rec=True)
class PTmp(ProcessEvent):
def process_IN_CREATE(self, event):
if event.dir :
global wm
wdd = wm.add_watch(event.pathname, mask, rec=True)
#print wdd.keys()
print "%s: %s" % (event.maskname, os.path.join(event.path, event.name))
def process_IN_MODIFY(self, event):
if not event.dir :
print event.path
print "%s: %s" % (event.maskname, os.path.join(event.path, event.name))
def process_default(self, event):
print "%s: %s" % (event.maskname, os.path.join(event.path, event.name))
if __name__ == '__main__':
try:
notifier = Notifier(wm, PTmp(), read_freq=2, timeout=1)
notifier.coalesce_events()
notifier.loop()
except KeyboardInterrupt:
notifier.stop()

View File

@ -0,0 +1,22 @@
[loggers]
keys=root
[handlers]
keys=consoleHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=DEBUG
handlers=consoleHandler
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)
[formatter_simpleFormatter]
format=%(asctime)s %(levelname)s - [%(filename)s : %(funcName)s() : line %(lineno)d] - %(message)s
datefmt=

View File

@ -21,6 +21,14 @@
#
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# This script cleans audio files in the Airtime storageServer.
# 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-clean-storage.php "$@" || exit 1

View File

@ -9,117 +9,111 @@ if (isset($arr["DOCUMENT_ROOT"]) && ($arr["DOCUMENT_ROOT"] != "") ) {
exit(1);
}
set_include_path('/var/www/airtime/library' . PATH_SEPARATOR . get_include_path());
set_include_path('/var/www/airtime/application/models' . PATH_SEPARATOR . get_include_path());
require_once('/var/www/airtime/application/configs/conf.php');
//require_once('/var/www/airtime/install/installInit.php');
require_once('/var/www/airtime/application/models/StoredFile.php');
require_once('DB.php');
require_once 'propel/runtime/lib/Propel.php';
Propel::init('/var/www/airtime/application/configs/airtime-conf.php');
function printUsage() {
global $CC_CONFIG;
echo "Usage:\n";
echo " ./airtime-clean-storage [OPTION] \n";
echo "\n";
echo "Options:\n";
echo " -c, --clean Removes all broken links from the storage server\n";
echo " and empties all missing file information from the database.\n";
echo "\n";
echo " -e, --empty Removes all files from the storage server \n";
echo " and empties all relevant information from the database.\n\n";
echo "Storage server: ". realpath($CC_CONFIG["storageDir"]) ."\n\n\n";
/**
*
* Look through all the files in the database and remove the rows
* that have no associated file.
*
* @return int
* The total number of files that were missing.
*/
function airtime_clean_files() {
$count = 0;
$files = StoredFile::GetAll();
foreach ($files as $file) {
if (($file["ftype"] == "audioclip") && !@file_exists($file["filepath"])) {
echo " * Removing metadata for id ".$file["id"].":".PHP_EOL;
echo " * File path: ".$file["filepath"].PHP_EOL;
echo " * Track title: ".$file["track_title"].PHP_EOL;
echo " * Artist: ".$file["artist_name"].PHP_EOL;
echo " * Album: ".$file["album_title"].PHP_EOL;
StoredFile::deleteById($file["id"]);
$count++;
}
}
return $count;
}
function airtime_clean_files($p_path) {
if (!empty($p_path) && (strlen($p_path) > 4)) {
list($dirList,$fileList) = File_Find::maptree($p_path);
function airtime_empty_db($db)
{
global $CC_CONFIG, $CC_DBC;
$array_mus;
foreach ($fileList as $filepath) {
// NOTE: order matter here.
echo " * Clearing schedule table...".PHP_EOL;
Schedule::deleteAll();
if (@substr($filepath, strlen($filepath) - 3) != "xml") {
$array_mus[] = $filepath;
}
}
// Ugly hack
echo " * Resetting show instance times to zero...".PHP_EOL;
$sql = "UPDATE cc_show_instances SET time_filled='00:00:00'";
$CC_DBC->query($sql);
foreach ($array_mus as $audio_file) {
echo " * Clearing playlist table...".PHP_EOL;
Playlist::deleteAll();
if (@is_link($audio_file) && !@stat($audio_file)) {
//filesystem clean up.
@unlink($audio_file);
echo "unlinked $audio_file\n";
@unlink($audio_file . ".xml");
echo "unlinked " . $audio_file . ".xml\n";
@rmdir(@dirname($audio_file));
echo "removed dir " . @dirname($audio_file) . "\n";
//database clean up.
$stored_audio_file = StoredFile::RecallByGunid(@basename($audio_file));
$stored_audio_file->delete();
}
}
}
}
function airtime_remove_files($p_path) {
if (!empty($p_path) && (strlen($p_path) > 4)) {
list($dirList,$fileList) = File_Find::maptree($p_path);
foreach ($fileList as $filepath) {
echo " * Removing $filepath\n";
@unlink($filepath);
echo "done.\n";
}
foreach ($dirList as $dirpath) {
echo " * Removing $dirpath\n";
@rmdir($dirpath);
echo "done.\n";
}
}
}
function airtime_empty_db($db) {
global $CC_CONFIG;
if (!PEAR::isError($db)) {
if (AirtimeInstall::DbTableExists($CC_CONFIG['filesTable'])) {
echo " * Deleting from database table ".$CC_CONFIG['filesTable']."\n";
$sql = "DELETE FROM ".$CC_CONFIG['filesTable'];
AirtimeInstall::InstallQuery($sql, false);
}
else {
echo " * Skipping: database table ".$CC_CONFIG['filesTable']."\n";
}
echo " * Clearing files table...".PHP_EOL;
$result = StoredFile::deleteAll();
if (PEAR::isError($result)) {
echo $result->getMessage().PHP_EOL;
}
}
global $CC_CONFIG;
$CC_DBC = DB::connect($CC_CONFIG['dsn'], TRUE);
$CC_DBC->setFetchMode(DB_FETCHMODE_ASSOC);
require_once('Zend/Loader/Autoloader.php');
$autoloader = Zend_Loader_Autoloader::getInstance();
if ($argc != 2){
printUsage();
try {
$opts = new Zend_Console_Getopt(
array(
'help|h' => 'Displays usage information.',
'clean|c' => 'Removes all audio file metadata from the database that does not have a matching file in the filesystem.',
'empty|e' => 'Removes all files and playlists from Airtime.'
)
);
$opts->parse();
} catch (Zend_Console_Getopt_Exception $e) {
exit($e->getMessage() .PHP_EOL. $e->getUsageMessage());
}
if (isset($opts->h)) {
echo PHP_EOL;
echo $opts->getUsageMessage();
echo "Storage directory: ". realpath($CC_CONFIG["storageDir"]).PHP_EOL.PHP_EOL;
exit;
}
// Need to check that we are superuser before running this.
if (exec("whoami") != "root") {
echo PHP_EOL."You must be root to use this script.".PHP_EOL.PHP_EOL;
exit(1);
}
switch($argv[1]){
$CC_DBC = DB::connect($CC_CONFIG['dsn'], TRUE);
$CC_DBC->setFetchMode(DB_FETCHMODE_ASSOC);
case '-e':
case '--empty':
if (isset($opts->e)) {
echo PHP_EOL;
airtime_empty_db($CC_DBC);
airtime_remove_files($CC_CONFIG['storageDir']);
break;
case '-c':
case '--clean':
airtime_clean_files($CC_CONFIG['storageDir']);
break;
default:
printUsage();
echo "Done.".PHP_EOL.PHP_EOL;
} elseif (isset($opts->c)) {
$count = airtime_clean_files($CC_CONFIG['storageDir']);
if ($count == 0) {
echo PHP_EOL."All file metadata in the database is linked to a real file. Nothing to be done.".PHP_EOL.PHP_EOL;
} else {
echo PHP_EOL."Total rows removed: $count".PHP_EOL;
}
} else {
echo PHP_EOL;
echo $opts->getUsageMessage();
echo "Storage directory: ". realpath($CC_CONFIG["storageDir"]).PHP_EOL.PHP_EOL;
}

View File

@ -21,7 +21,7 @@
#
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# This script imports audio files to the Airtime storageServer.
# This script imports audio files into Airtime.
#
# To get usage help, try the -h option
#-------------------------------------------------------------------------------

View File

@ -10,14 +10,16 @@
ini_set('memory_limit', '128M');
set_time_limit(0);
error_reporting(E_ALL);
set_error_handler("camp_import_error_handler", E_ALL & !E_NOTICE);
set_error_handler("import_error_handler", E_ALL & !E_NOTICE);
set_include_path('/var/www/airtime/library' . PATH_SEPARATOR . get_include_path());
require_once("/var/www/airtime/application/configs/conf.php");
require_once("/var/www/airtime/application/models/StoredFile.php");
require_once('DB.php');
require_once('Console/Getopt.php');
function camp_import_error_handler()
function import_error_handler()
{
echo var_dump(debug_backtrace());
exit();
@ -92,7 +94,7 @@ function import_err($p_pearErrorObj, $txt='')
*
* @return int
*/
function camp_import_audio_file($p_filepath, $p_importMode = null, $p_testOnly = false)
function import_audio_file($p_filepath, $p_importMode = null, $p_testOnly = false)
{
global $STORAGE_SERVER_PATH;
global $g_fileCount;
@ -126,7 +128,7 @@ function camp_import_audio_file($p_filepath, $p_importMode = null, $p_testOnly =
while (false !== ($file = readdir($d))) {
if ($file != "." && $file != "..") {
$path = "$p_filepath/$file";
camp_import_audio_file($path, $p_importMode, $p_testOnly);
import_audio_file($path, $p_importMode, $p_testOnly);
}
}
closedir($d);
@ -241,7 +243,7 @@ if ($DEBUG_IMPORT) {
$dsn = $CC_CONFIG['dsn'];
}
//PEAR::setErrorHandling(PEAR_ERROR_RETURN);
PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, "camp_import_error_handler");
PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, "import_error_handler");
$CC_DBC = DB::connect($dsn, TRUE);
if (PEAR::isError($CC_DBC)) {
echo "ERROR: ".$CC_DBC->getMessage()." ".$CC_DBC->getUserInfo()."\n";
@ -301,13 +303,14 @@ if (is_null($importMode)) {
global $CC_CONFIG;
if (!is_writable($CC_CONFIG["storageDir"])) {
if ( ($importMode == "copy") && !is_writable($CC_CONFIG["storageDir"])) {
echo "ERROR: You do not have write permissions to the directory you are trying to import to:\n " . $CC_CONFIG["storageDir"] . "\n\n";
exit;
}
global $g_fileCount;
global $g_duplicates;
$g_fileCount = 0;
if (is_array($files)) {
foreach ($files as $filepath) {
// absolute path
@ -323,7 +326,7 @@ if (is_array($files)) {
echo "ERROR: I cant find the given file: $filepath\n\n";
exit;
}
camp_import_audio_file($fullPath, $importMode, $testonly);
import_audio_file($fullPath, $importMode, $testonly);
}
}
$end = intval(date('U'));
@ -336,7 +339,9 @@ if ($time > 0) {
echo "==========================================================================\n";
echo " *** Import mode: $importMode\n";
echo " *** Destination folder: ".$CC_CONFIG['storageDir']."\n";
if ($importMode == "copy") {
echo " *** Destination folder: ".$CC_CONFIG['storageDir']."\n";
}
echo " *** Files imported: $g_fileCount\n";
echo " *** Duplicate files (not imported): $g_duplicates\n";
if ($g_errors > 0) {