Renaming top-level livesupport directory (/trunk/livesupport) to campcaster (trunk/campcaster).

This commit is contained in:
paul 2006-10-19 14:55:07 +00:00
parent 5dba86951e
commit fe31d2dfab
1923 changed files with 416891 additions and 0 deletions

View file

@ -0,0 +1,12 @@
DirectoryIndex index.php
Options +FollowSymLinks -Indexes
<IfModule mod_mime.c>
<IfModule mod_php4.c>
AddType application/x-httpd-php .php
php_flag magic_quotes_gpc On
php_flag register_globals Off
</IfModule>
</IfModule>

View file

@ -0,0 +1,94 @@
#!/bin/sh
#-------------------------------------------------------------------------------
# Copyright (c) 2004 Media Development Loan Fund
#
# This file is part of the Campcaster project.
# http://campcaster.campware.org/
# To report bugs, send an e-mail to bugs@campware.org
#
# Campcaster 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.
#
# Campcaster 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 Campcaster; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
# Author : $Author$
# Version : $Revision$
# Location : $URL$
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# Run this to set up the build system: configure, makefiles, etc.
# (based on the version in enlightenment's cvs)
#-------------------------------------------------------------------------------
package="StorageServer"
# assume we're in $basedir/bin
reldir=`dirname $0`/..
basedir=`cd $reldir; pwd;`
test -z "$basedir" && basedir=.
bindir=$basedir/bin
etcdir=$basedir/etc
tmpdir=$basedir/tmp
cd "$tmpdir"
DIE=0
(autoheader --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have autoconf installed to compile $package."
echo "Download the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
DIE=1
}
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have autoconf installed to compile $package."
echo "Download the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
DIE=1
}
if test "$DIE" -eq 1; then
exit 1
fi
if test -z "$*"; then
echo "I am going to run ./configure with no arguments - if you wish "
echo "to pass any to it, please specify them on the $0 command line."
fi
echo "Generating configuration files for $package, please wait...."
configure_ac=${etcdir}/configure.ac
configure=${tmpdir}/configure
aclocal_m4=${tmpdir}/aclocal.m4
# copy over configure.ac and acinlclude.m4 from etc to tmp,
# as aclocal >= 1.8 is sooo unbelivably stupid that it will simply try to
# look for configure.ac in the current directory, and include acinclude.m4
# in aclocal.m4 it without a directory path in front
#ACLOCAL_FLAGS="-I ${tmpdir} --acdir=${tmpdir} --output=${aclocal_m4}"
#echo " aclocal $ACLOCAL_FLAGS"
#cp -f ${configure_ac} ${tmpdir}
#cp -f ${etcdir}/acinclude.m4 ${tmpdir}
#aclocal $ACLOCAL_FLAGS
#echo " autoheader ${configure_ac}"
#autoheader ${configure_ac}
echo " autoconf -I ${tmpdir} -o ${configure} ${configure_ac}"
autoconf -I ${tmpdir} -o ${configure} ${configure_ac}

View file

@ -0,0 +1,18 @@
#!/bin/bash
# param $1: workdir what we would like to tar
# param $2: output file: the .tar file
# param $3: statusfile
echo "==>"
date +\ %Y%m%d\ %H:%M:%S
echo "backup.sh: create tarball $1 to $2"
echo "backup.sh: status: #$3#"
echo "<=="
echo -n "working" > $3;
touch $2 || { echo -n "fault|error with .tar file" > $3; exit 1; }
#sleep 120
cd $1
tar cf $2 * || { echo -n "fault|error in tar procedure" > $3; exit 1; }
chmod 666 $2
echo -n "success" > $3

View file

@ -0,0 +1,216 @@
#!/bin/sh
#-------------------------------------------------------------------------------
# Copyright (c) 2004 Media Development Loan Fund
#
# This file is part of the Campcaster project.
# http://campcaster.campware.org/
# To report bugs, send an e-mail to bugs@campware.org
#
# Campcaster 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.
#
# Campcaster 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 Campcaster; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
# Author : $Author$
# Version : $Revision$
# Location : $URL$
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# This script reates the database used by Campcaster
#
# Invoke as:
# ./bin/createDatabase.sh
#
# To get usage help, try the -h option
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# Determine directories, files
#-------------------------------------------------------------------------------
reldir=`dirname $0`/..
basedir=`cd $reldir; pwd;`
bindir=$basedir/bin
etcdir=$basedir/etc
docdir=$basedir/doc
tmpdir=$basedir/tmp
usrdir=$basedir/usr
#-------------------------------------------------------------------------------
# Print the usage information for this script.
#-------------------------------------------------------------------------------
printUsage()
{
echo "Campcaster scheduler database creation script.";
echo "parameters";
echo "";
echo " -D, --database The name of the Campcaster database.";
echo " [default: Campcaster]";
echo " -s, --dbserver The name of the database server host.";
echo " [default: localhost]";
echo " -u, --dbuser The name of the database user to access the"
echo " database. [default: campcaster]";
echo " -w, --dbpassword The database user password.";
echo " [default: campcaster]";
echo " -h, --help Print this message and exit.";
echo "";
}
#-------------------------------------------------------------------------------
# Process command line parameters
#-------------------------------------------------------------------------------
CMD=${0##*/}
opts=$(getopt -o D:hs:u:w: -l database:,dbserver:,dbuser:,dbpassword:,help, -n $CMD -- "$@") || exit 1
eval set -- "$opts"
while true; do
case "$1" in
-D|--database)
database=$2;
shift; shift;;
-h|--help)
printUsage;
exit 0;;
-s|--dbserver)
dbserver=$2;
shift; shift;;
-u|--dbuser)
dbuser=$2;
shift; shift;;
-w|--dbpassword)
dbpassword=$2;
shift; shift;;
--)
shift;
break;;
*)
echo "Unrecognized option $1.";
printUsage;
exit 1;
esac
done
if [ "x$dbserver" == "x" ]; then
dbserver=localhost;
fi
if [ "x$database" == "x" ]; then
database=Campcaster;
fi
if [ "x$dbuser" == "x" ]; then
dbuser=campcaster;
fi
if [ "x$dbpassword" == "x" ]; then
dbpassword=campcaster;
fi
echo "Creating database for Campcaster scheduler.";
echo "";
echo "Using the following parameters:";
echo "";
echo " database server: $dbserver";
echo " database: $database";
echo " database user: $dbuser";
echo " database user password: $dbpassword";
echo ""
#-------------------------------------------------------------------------------
# The details of installation
#-------------------------------------------------------------------------------
ls_dbserver=$dbserver
ls_dbuser=$dbuser
ls_dbpassword=$dbpassword
ls_database=$database
postgres_user=postgres
#-------------------------------------------------------------------------------
# Function to check for the existence of an executable on the PATH
#
# @param $1 the name of the exectuable
# @return 0 if the executable exists on the PATH, non-0 otherwise
#-------------------------------------------------------------------------------
check_exe() {
if [ -x "`which $1 2> /dev/null`" ]; then
echo "Executable $1 found...";
return 0;
else
echo "Executable $1 not found...";
return 1;
fi
}
#-------------------------------------------------------------------------------
# Check to see if this script is being run as root
#-------------------------------------------------------------------------------
if [ `whoami` != "root" ]; then
echo "Please run this script as root.";
exit ;
fi
#-------------------------------------------------------------------------------
# Check for required tools
#-------------------------------------------------------------------------------
echo "Checking for required tools..."
check_exe "su" || exit 1;
check_exe "psql" || exit 1;
#-------------------------------------------------------------------------------
# Create the necessary database user and database itself
#-------------------------------------------------------------------------------
echo "Creating database and database user...";
# FIXME: the below might not work for remote databases
if [ "x$ls_dbserver" == "xlocalhost" ]; then
su - $postgres_user -c "echo \"CREATE USER $ls_dbuser \
ENCRYPTED PASSWORD '$ls_dbpassword' \
CREATEDB NOCREATEUSER;\" \
| psql template1" \
|| echo "Couldn't create database user $ls_dbuser.";
su - $postgres_user -c "echo \"CREATE DATABASE \\\"$ls_database\\\" \
OWNER $ls_dbuser ENCODING 'utf-8';\" \
| psql template1" \
|| echo "Couldn't create database $ls_database.";
else
echo "Unable to automatically create database user and table for";
echo "remote database $ls_dbserver.";
echo "Make sure to create database user $ls_dbuser with password";
echo "$ls_dbpassword on database server at $ls_dbserver.";
echo "Also create a database called $ld_database, owned by this user.";
echo "";
echo "The easiest way to achieve this is by issuing the following SQL";
echo "commands to PostgreSQL:";
echo "CREATE USER $ls_dbuser";
echo " ENCRYPTED PASSWORD '$ls_dbpassword'";
echo " CREATEDB NOCREATEUSER;";
echo "CREATE DATABASE \"$ls_database\"";
echo " OWNER $ls_dbuser ENCODING 'utf-8';";
fi
# TODO: check for the success of these operations somehow
#-------------------------------------------------------------------------------
# Say goodbye
#-------------------------------------------------------------------------------
echo "Done."

View file

@ -0,0 +1,44 @@
#!/bin/bash
#-------------------------------------------------------------------------------
# Copyright (c) 2004 Media Development Loan Fund
#
# This file is part of the Campcaster project.
# http://campcaster.campware.org/
# To report bugs, send an e-mail to bugs@campware.org
#
# Campcaster 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.
#
# Campcaster 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 Campcaster; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
# Author : $Author$
# Version : $Revision$
# Location : $URL$
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# This script grabs string at suplied URL
#-------------------------------------------------------------------------------
URL=$1
RES=`curl -sf ${URL}` || \
{
ERN=$?;
if [ $ERN -eq 22 ] ; then
echo "ERROR: curl: 22 - wrong URL ($URL)";
else
echo "ERROR: $ERN - unknown";
fi;
exit $ERN;
}
echo $RES

View file

@ -0,0 +1,118 @@
#!/bin/bash
#-------------------------------------------------------------------------------
# Copyright (c) 2004 Media Development Loan Fund
#
# This file is part of the Campcaster project.
# http://campcaster.campware.org/
# To report bugs, send an e-mail to bugs@campware.org
#
# Campcaster 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.
#
# Campcaster 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 Campcaster; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
# Author : $Author: tomash $
# Version : $Revision: 1847 $
# Location : $URL: svn+ssh://tomash@code.campware.org/home/svn/repo/livesupport/trunk/livesupport/src/modules/storageAdmin/bin/backup.sh $
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# Playlist-to-file renderer caller. DUMMY VERSION.
#
# To get usage help, try the -h option
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# Determine directories, files
#-------------------------------------------------------------------------------
reldir=`dirname $0`/..
#-------------------------------------------------------------------------------
# Print the usage information for this script.
#-------------------------------------------------------------------------------
printUsage()
{
echo "Playlist-to-file renderer caller. DUMMY VERSION.";
echo "parameters:";
echo "";
echo " -p, --playlist URL of SMIL playlist to be rendered.";
echo " -s, --statusfile Status file name.";
echo " -o, --output File name where the output will be written.";
echo " -h, --help Print this message and exit.";
echo "";
}
#-------------------------------------------------------------------------------
# Process command line parameters
#-------------------------------------------------------------------------------
CMD=${0##*/}
opts=$(getopt -o hp:s:o: -l help,playlist:,statusfile:,output: -n $CMD -- "$@") || exit 1
eval set -- "$opts"
while true; do
case "$1" in
-h|--help)
printUsage;
exit 0;;
-p|--playlist)
playlist=$2
shift; shift;;
-s|--statusfile)
statusfile=$2
shift; shift;;
-o|--output)
output=$2
shift; shift;;
--)
shift;
break;;
*)
echo "Unrecognized option $1.";
printUsage;
exit 1;
esac
done
if [ "x$playlist" == "x" ]; then
echo "Error in playlist parameter";
printUsage;
exit 1;
fi
if [ "x$statusfile" == "x" ]; then
echo "Error in statusfile parameter";
printUsage;
exit 1;
fi
if [ "x$output" == "x" ]; then
echo "Error in output parameter";
printUsage;
exit 1;
fi
#-------------------------------------------------------------------------------
# Do it
#-------------------------------------------------------------------------------
echo "renderer.sh: rendering $playlist to $output"
echo "working" > $statusfile;
touch $output || { echo "fail" > $statusfile; exit 1; }
#sleep 4
#sleep 2
echo -e "$playlist\n$output" >> $output || { echo "fail" > $statusfile; exit 1; }
echo "success" > $statusfile
#-------------------------------------------------------------------------------
# Say goodbye
#-------------------------------------------------------------------------------
echo "done"
exit 0

View file

@ -0,0 +1,45 @@
#!/bin/bash
#-------------------------------------------------------------------------------
# Copyright (c) 2004 Media Development Loan Fund
#
# This file is part of the Campcaster project.
# http://campcaster.campware.org/
# To report bugs, send an e-mail to bugs@campware.org
#
# Campcaster 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.
#
# Campcaster 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 Campcaster; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
# Author : $Author$
# Version : $Revision$
# Location : $URL$
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# This script call locstor.resetStorage XMLRPC method
#-------------------------------------------------------------------------------
reldir=`dirname $0`/..
WWW_ROOT=`cd $reldir/var/install; php -q getWwwRoot.php` || exit $?
echo "# storageServer root URL: $WWW_ROOT"
#$reldir/var/xmlrpc/xr_cli_test.py -s $WWW_ROOT/xmlrpc/xrLocStor.php \
# resetStorage || exit $?
cd $reldir/var/xmlrpc
php -q xr_cli_test.php -s $WWW_ROOT/xmlrpc/xrLocStor.php \
resetStorage 1 1 || exit $?
echo "# resetStorage: OK"
exit 0

View file

@ -0,0 +1,41 @@
#!/usr/bin/php
<?php
/**
* Do database restore in background. - command line php application
*
* required command line parameters:
* @param 1. backup file
* @param 2. status file
* @param 3. token
* @param 4. sessid
*
*/
require_once dirname(__FILE__).'/../var/conf.php';
require_once dirname(__FILE__).'/../var/GreenBox.php';
require_once dirname(__FILE__).'/../var/Restore.php';
include_once 'DB.php';
PEAR::setErrorHandling(PEAR_ERROR_RETURN);
$dbc = DB::connect($config['dsn'], TRUE);
if (DB::isError($dbc)) {
die($dbc->getMessage());
}
$dbc->setFetchMode(DB_FETCHMODE_ASSOC);
$gb =& new GreenBox($dbc, $config);
$rs = new Restore($gb);
if ($rs->loglevel=='debug') {
$rs->addLogItem('argv:'.print_r($argv,true));
}
# sleep(2);
$backupfile = $argv[1];
$token = $argv[3];
$sessid = $argv[4];
$rs->startRestore($backupfile,$token,$sessid);
?>

View file

@ -0,0 +1,36 @@
#!/bin/bash
#-------------------------------------------------------------------------------
# Copyright (c) 2004 Media Development Loan Fund
#
# This file is part of the Campcaster project.
# http://campcaster.campware.org/
# To report bugs, send an e-mail to bugs@campware.org
#
# Campcaster 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.
#
# Campcaster 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 Campcaster; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
# Author : $Author$
# Version : $Revision$
# Location : $URL$
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
#
#-------------------------------------------------------------------------------
reldir=`dirname $0`/..
cd $reldir/var/tests
php -q $1 || exit $?
exit 0

View file

@ -0,0 +1,78 @@
#!/bin/bash
#-------------------------------------------------------------------------------
# Copyright (c) 2004 Media Development Loan Fund
#
# This file is part of the Campcaster project.
# http://campcaster.campware.org/
# To report bugs, send an e-mail to bugs@campware.org
#
# Campcaster 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.
#
# Campcaster 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 Campcaster; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
# Author : $Author$
# Version : $Revision$
# Location : $URL$
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# This script does httpd writeable directories setup
#-------------------------------------------------------------------------------
WWW_ROOT=`cd var/install; php -q getWwwRoot.php` || exit $?
echo "#StorageServer step 1:"
echo "# root URL: $WWW_ROOT"
PHP_PWD=`bin/getUrl.sh $WWW_ROOT/install/getPwd.php` || \
{
errno=$?
if [ $errno -eq 22 ]
then
echo "root URL is not accessible - configure HTTP entry point, please"
fi
exit $errno
}
echo "# webspace mapping test:"
echo "# mod_php : $PHP_PWD"
INSTALL_DIR="$PWD/var/install"
echo "# install : $INSTALL_DIR"
if [ $PHP_PWD == $INSTALL_DIR ]; then
echo "# mapping OK"
else
echo "# WARNING: probably problem in webspace mapping !!!"
fi
HTTP_GROUP=`bin/getUrl.sh $WWW_ROOT/install/getGname.php` || \
{
ERN=$?;
echo $HTTP_GROUP;
echo " -> Probably wrong setting in var/conf.php: URL configuration";
exit $ERN;
}
echo "# group running http daemon: $HTTP_GROUP"
for i in $*
do
echo "mkdir $i"
mkdir -p $i || exit $?
chown :$HTTP_GROUP $i || \
{
ERN=$?;
echo " -> You should have permissions to set group owner to group $HTTP_GROUP";
exit $ERN;
}
chmod g+sw $i || exit $?
done
echo "# Directories setup finished OK"
exit 0

View file

@ -0,0 +1,35 @@
#!/bin/bash
#-------------------------------------------------------------------------------
# Copyright (c) 2004 Media Development Loan Fund
#
# This file is part of the Campcaster project.
# http://campcaster.campware.org/
# To report bugs, send an e-mail to bugs@campware.org
#
# Campcaster 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.
#
# Campcaster 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 Campcaster; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
# Author : $Author$
# Version : $Revision$
# Location : $URL$
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# XMLRPC test client call
#-------------------------------------------------------------------------------
reldir=`dirname $0`/..
cd $reldir/var/xmlrpc
php -q ./xr_cli_test.php $*

View file

@ -0,0 +1,52 @@
#!/bin/sh
#-------------------------------------------------------------------------------
# Copyright (c) 2004 Media Development Loan Fund
#
# This file is part of the Campcaster project.
# http://campcaster.campware.org/
# To report bugs, send an e-mail to bugs@campware.org
#
# Campcaster 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.
#
# Campcaster 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 Campcaster; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
# Author : $Author$
# Version : $Revision$
# Location : $URL$
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# Run this script to configure the environment.
#
# This script in effect calls the real automake / autoconf configure script
#-------------------------------------------------------------------------------
# assume we're in $basedir
reldir=`dirname $0`
basedir=`cd $reldir; pwd;`
test -z "$basedir" && basedir=.
bindir=$basedir/bin
tmpdir=$basedir/tmp
autogen=$bindir/autogen.sh
configure=$tmpdir/configure
if [ ! -x $configure ]; then
(cd $basedir && $autogen $*)
fi
(cd $tmpdir && $configure $*)

View file

@ -0,0 +1,37 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<title>storageServer documentation</title>
<meta content="$Author$" name="author">
</head>
<body>
<h1>Preface</h1>
This document is part of the
<a href="http://campcaster.campware.org/">Campcaster</a>
project, Copyright © 2004 <a href="http://www.mdlf.org/">Media
Development Loan Fund</a>, under the GNU <a
href="http://www.gnu.org/licenses/gpl.html">GPL</a>.<br>
<ul>
<li>Author: $Author$</li>
<li>Version: $Revision: 1.2 $</li>
<li>Location: $URL$</li>
</ul>
<h1>Scope</h1>
This document collects storageServer documentation, both
generated and handwritten.<br>
<h1>Introduction</h1>
The links below provide useful documentation for the storageServer
developer or user.<br>
<h1>Static documentation.</h1>
<ul>
<!-- <li> <a href=".html"></a></li>-->
</ul>
<h1>Generated documentation</h1>
<ul>
<li><a href="doxygen/html/index.html">documentation generated from the source
code</a></li>
</ul>
<br>
</body>
</html>

View file

@ -0,0 +1,266 @@
#-------------------------------------------------------------------------------
# StorageServer - file storage component
# Copyright (c) 2004 Media Development Loan Fund
#
# This file is part of the Campcaster project.
#
# Campcaster 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.
#
# Campcaster 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 Campcaster; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
# Author : $Author$
# Version : $Revision$
# Location : $URL$
#
# @configure_input@
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# General command definitions
#-------------------------------------------------------------------------------
MKDIR = mkdir -p
RM = rm -f
RMDIR = rm -rf
DOXYGEN = doxygen
CP = cp -r
SED = sed
ECHO = echo
CAT = cat
PHP = php
#-------------------------------------------------------------------------------
# Misc
#-------------------------------------------------------------------------------
MODULE_NAME = storageServer
TAR_C = tar -cj --exclude .svn --exclude '*~' -C ${BASE_DIR} -f
DIST_EXT = .tgz
DATE = `date +%y%m%d`
#-------------------------------------------------------------------------------
# Basic directory and file definitions
#-------------------------------------------------------------------------------
#BASE_DIR = @builddir@
BASE_DIR = .
BIN_DIR = ${BASE_DIR}/bin
DOC_DIR = ${BASE_DIR}/doc
DOXYGEN_DIR = ${DOC_DIR}/doxygen
ETC_DIR = ${BASE_DIR}/etc
INCLUDE_DIR = ${BASE_DIR}/include
LIB_DIR = ${BASE_DIR}/lib
SRC_DIR = ${BASE_DIR}/src
TMP_DIR = ${BASE_DIR}/tmp
VAR_DIR = ${BASE_DIR}/var
prefix = @prefix@
USR_DIR = ${prefix}
USR_INCLUDE_DIR = ${USR_DIR}/include
USR_LIB_DIR = ${USR_DIR}/lib
USR_VAR_DIR = ${USR_DIR}/var
DOXYGEN_CONFIG = ${ETC_DIR}/doxygen.config
PHP_DIR = ${VAR_DIR}
INSTALL_DIR = ${PHP_DIR}/install
STOR_DIR = ${PHP_DIR}/stor
ACCESS_DIR = ${PHP_DIR}/access
TRANS_DIR = ${PHP_DIR}/trans
BUFF_DIR = ${STOR_DIR}/buffer
TEST_RUNNER = ${PHP_DIR}/xmlrpc/testRunner.sh
PEAR_TOOL_DIR = ${BASE_DIR}/../../tools/pear
PEAR_INSTALLER = ${PEAR_TOOL_DIR}/bin/install.sh
DEST_DIR = ${USR_VAR_DIR}/Campcaster/storageServer/var
HOSTNAME = @HOSTNAME@
APACHE_GROUP = @APACHE_GROUP@
WWW_PORT = @WWW_PORT@
DB_SERVER = @DB_SERVER@
DATABASE = @DATABASE@
DB_USER = @DB_USER@
DB_PASSWORD = @DB_PASSWORD@
SCHEDULER_PORT = @SCHEDULER_PORT@
WWW_DOCROOT = @WWW_DOCROOT@
PHP_URL_PREFIX=campcaster
SCHEDULER_URL_PREFIX =
SCHEDULER_XML_RPC_PREFIX = RC2
USR_LIB_DIR_S=$(shell ${ECHO} ${USR_LIB_DIR} | ${SED} -e "s/\//\\\\\\\\\//g")
PHP_URL_PREFIX_S=$(shell ${ECHO} ${PHP_URL_PREFIX} | ${SED} -e "s/\//\\\\\\\\\//g")
REPLACE_SED_STRING="s/ls_lib_dir/${USR_LIB_DIR_S}/; \
s/ls_dbuser/${DB_USER}/; \
s/ls_dbpassword/${DB_PASSWORD}/; \
s/ls_dbserver/${DB_SERVER}/; \
s/ls_database/${DATABASE}/; \
s/ls_apache_group/${APACHE_GROUP}/; \
s/ls_storageUrlPath/\/${PHP_URL_PREFIX_S}\/storageServer\/var/; \
s/ls_php_host/${HOSTNAME}/; \
s/ls_php_port/${WWW_PORT}/; \
s/ls_archiveUrlPath/\/${PHP_URL_PREFIX_S}\/archiveServer\/var/; \
s/ls_scheduler_urlPrefix/${SCHEDULER_URL_PREFIX}/; \
s/ls_scheduler_xmlRpcPrefix/${SCHEDULER_XML_RPC_PREFIX}/; \
s/ls_scheduler_host/${HOSTNAME}/; \
s/ls_scheduler_port/${SCHEDULER_PORT}/;"
#-------------------------------------------------------------------------------
# Configuration parameters
#-------------------------------------------------------------------------------
#CPPFLAGS = @CPPFLAGS@
#CXXFLAGS = @CXXFLAGS@ @DEFS@ -I${USR_INCLUDE_DIR} -I${INCLUDE_DIR} -I${TMP_DIR}\
# -pedantic -Wall
#LDFLAGS = @LDFLAGS@ -L${USR_LIB_DIR} -L${LIB_DIR}
#-------------------------------------------------------------------------------
# Dependencies
#-------------------------------------------------------------------------------
#HELLO_LIB_OBJS = ${TMP_DIR}/Hello.o
#TEST_RUNNER_OBJS = ${TMP_DIR}/HelloTest.o ${TMP_DIR}/TestRunner.o
#-------------------------------------------------------------------------------
# Targets
#-------------------------------------------------------------------------------
.PHONY: all dir_setup doc clean docclean depclean distclean dist install
.PHONY: db_init db_clean testonly transtest storage reset pear_setup_devel
.PHONY: copy_files create_database init_database
all:
doc:
${DOXYGEN} ${DOXYGEN_CONFIG}
clean: db_clean
${RMDIR} ${STOR_DIR}
${RMDIR} ${ACCESS_DIR}
${RMDIR} ${TRANS_DIR}
docclean:
${RMDIR} ${DOXYGEN_DIR}/html
depclean: clean
dist:
${TAR_C} ${MODULE_NAME}${DATE}${DIST_EXT} *
distclean: clean docclean
testonly: ${TEST_RUNNER}
${TEST_RUNNER}
check: all testonly
install: copy_files create_database init_database
copy_files:
${MKDIR} ${DEST_DIR}
${MKDIR} ${DEST_DIR}/access
${MKDIR} ${DEST_DIR}/cron
${MKDIR} ${DEST_DIR}/install
${MKDIR} ${DEST_DIR}/stor
${MKDIR} ${DEST_DIR}/stor/buffer
${MKDIR} ${DEST_DIR}/trans
${MKDIR} ${DEST_DIR}/xmlrpc
${CP} ${VAR_DIR}/*.{php,xml} ${DEST_DIR}
${CP} ${VAR_DIR}/cron/*.php ${DEST_DIR}/cron
${CP} ${VAR_DIR}/install/*.php \
${DEST_DIR}/install
${CP} ${VAR_DIR}/xmlrpc/*.php \
${DEST_DIR}/xmlrpc
${CAT} ${VAR_DIR}/conf.php.template | ${SED} -e ${REPLACE_SED_STRING} \
> ${DEST_DIR}/conf.php
chgrp ${APACHE_GROUP} ${DEST_DIR}/access
chgrp ${APACHE_GROUP} ${DEST_DIR}/stor
chgrp ${APACHE_GROUP} ${DEST_DIR}/stor/buffer
chgrp ${APACHE_GROUP} ${DEST_DIR}/trans
chmod g+sw ${DEST_DIR}/access
chmod g+sw ${DEST_DIR}/stor
chmod g+sw ${DEST_DIR}/stor/buffer
chmod g+sw ${DEST_DIR}/trans
${RM} ${WWW_DOCROOT}/campcaster
ln -sf ${USR_VAR_DIR}/Campcaster ${WWW_DOCROOT}/campcaster
create_database:
ifeq (@CREATE_LS_DATABASE@,yes)
${BIN_DIR}/createDatabase.sh --database=${DATABASE} \
--dbserver=${DB_SERVER} \
--dbuser=${DB_USER} \
--dbpassword=${DB_PASSWORD}
endif
init_database:
ifeq (@INIT_LS_DATABASE@,yes)
-cd ${DEST_DIR}/install && ${PHP} -q install.php
endif
recheck: clean check
#-------------------------------------------------------------------------------
# Specific targets
#-------------------------------------------------------------------------------
storage: pear_setup_devel dir_setup db_init
storagecheck: storage testonly
pear_setup_devel: pear_install
pear_install:
${PEAR_INSTALLER} -d ${USR_DIR}
dir_setup: ${DOXYGEN_DIR}
bin/setupDirs.sh ${STOR_DIR} ${ACCESS_DIR} ${TRANS_DIR} ${BUFF_DIR}
db_init:
-cd var/install && php -q install.php
db_clean:
-cd var/install && php -q uninstall.php
reset:
./bin/resetStorage.sh
archive:
$(MAKE) -C ../archiveServer all
archiveclean:
$(MAKE) -C ../archiveServer clean
transtest:
./var/tests/transTest.sh
# cd var/tests; php -q transTest.php
${TMP_DIR}:
${MKDIR} ${TMP_DIR}
${DOXYGEN_DIR}:
${MKDIR} ${DOXYGEN_DIR}
${TEST_RUNNER}:
#-------------------------------------------------------------------------------
# Pattern rules
#-------------------------------------------------------------------------------
#${TMP_DIR}/%.o : ${SRC_DIR}/%.cxx
# ${CXX} ${CPPFLAGS} ${CXXFLAGS} -c -o $@ $<

View file

@ -0,0 +1,211 @@
dnl-----------------------------------------------------------------------------
dnl Copyright (c) 2004 Media Development Loan Fund
dnl
dnl This file is part of the Campcaster project.
dnl http://campcaster.campware.org/
dnl To report bugs, send an e-mail to bugs@campware.org
dnl
dnl Campcaster is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
dnl the Free Software Foundation; either version 2 of the License, or
dnl (at your option) any later version.
dnl
dnl Campcaster is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
dnl GNU General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with Campcaster; if not, write to the Free Software
dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
dnl
dnl
dnl Author : $Author$
dnl Version : $Revision$
dnl Location : $URL$
dnl-----------------------------------------------------------------------------
dnl-----------------------------------------------------------------------------
dnl NOTE: Run all configure related scripts from the tmp directory of the
dnl project.
dnl This is due to the fact that configure spreads a lot of trash around,
dnl like atom4te cache directories, config.* files, etc. into the directory
dnl it is being run from. We clearly don't want these in our base directory.
dnl-----------------------------------------------------------------------------
AC_INIT(StorageServer, 1.0, bugs@campware.org)
AC_PREREQ(2.59)
AC_COPYRIGHT([Copyright (c) 2004 Media Development Loan Fund under the GNU GPL])
AC_REVISION($Revision$)
AC_CONFIG_SRCDIR(../var/BasicStor.php)
dnl-----------------------------------------------------------------------------
dnl specify wether the Campcaster database and user should be created
dnl-----------------------------------------------------------------------------
AC_SUBST(CREATE_LS_DATABASE)
AC_ARG_WITH([create-database],
AC_HELP_STRING([--with-create-database],
[specify wether the Campcaster database and database user
should be created (no)]),
[CREATE_LS_DATABASE=${withval}],
[CREATE_LS_DATABASE=no])
AC_MSG_RESULT([creating Campcaster database: ${CREATE_LS_DATABASE}])
dnl-----------------------------------------------------------------------------
dnl specify wether the Campcaster database tables should be initialized
dnl-----------------------------------------------------------------------------
AC_SUBST(INIT_LS_DATABASE)
AC_ARG_WITH([init-database],
AC_HELP_STRING([--with-init-database],
[specify wether the Campcaster database tables should be
initialized (no)]),
[INIT_LS_DATABASE=${withval}],
[INIT_LS_DATABASE=no])
AC_MSG_RESULT([initializing Campcaster database: ${INIT_LS_DATABASE}])
dnl-----------------------------------------------------------------------------
dnl specify the FQDN
dnl-----------------------------------------------------------------------------
AC_SUBST(HOSTNAME)
AC_ARG_WITH([hostname],
AC_HELP_STRING([--with-hostname],
[use the specified hostname (guess)]),
[HOSTNAME=${withval}], [HOSTNAME=`hostname -f`])
AC_MSG_RESULT([using hostname: ${HOSTNAME}])
dnl-----------------------------------------------------------------------------
dnl specify group in which apache is running
dnl-----------------------------------------------------------------------------
AC_SUBST(APACHE_GROUP)
AC_ARG_WITH([apache-group],
AC_HELP_STRING([--with-apache-group],
[use apache running in the specified group (apache)]),
[APACHE_GROUP=${withval}], [APACHE_GROUP=apache])
AC_MSG_RESULT([using apache group: ${APACHE_GROUP}])
dnl-----------------------------------------------------------------------------
dnl specify the web server port
dnl-----------------------------------------------------------------------------
AC_SUBST(WWW_PORT)
AC_ARG_WITH([www-port],
AC_HELP_STRING([--with-www-port],
[use the specified www port (80)]),
[WWW_PORT=${withval}], [WWW_PORT=80])
AC_MSG_RESULT([using www port: ${WWW_PORT}])
dnl-----------------------------------------------------------------------------
dnl specify the scheduler server port
dnl-----------------------------------------------------------------------------
AC_SUBST(SCHEDULER_PORT)
AC_ARG_WITH([scheduler-port],
AC_HELP_STRING([--with-scheduler-port],
[use the specified scheduler port (3344)]),
[SCHEDULER_PORT=${withval}], [SCHEDULER_PORT=3344])
AC_MSG_RESULT([using scheduler port: ${SCHEDULER_PORT}])
dnl-----------------------------------------------------------------------------
dnl specify the database server name
dnl-----------------------------------------------------------------------------
AC_SUBST(DB_SERVER)
AC_ARG_WITH([database-server],
AC_HELP_STRING([--with-database-server],
[use the specified database server (localhost)]),
[DB_SERVER=${withval}], [DB_SERVER=localhost])
AC_MSG_RESULT([using database server: ${DB_SERVER}])
dnl-----------------------------------------------------------------------------
dnl get the name of the Campcaster database
dnl-----------------------------------------------------------------------------
AC_SUBST(DATABASE)
AC_ARG_WITH([database],
AC_HELP_STRING([--with-database],
[the name of the postgresql database to use (Campcaster)]),
[DATABASE=${withval}], [DATABASE=Campcaster])
AC_MSG_RESULT([using database: ${DATABASE}])
dnl-----------------------------------------------------------------------------
dnl specify the database server user
dnl-----------------------------------------------------------------------------
AC_SUBST(DB_USER)
AC_ARG_WITH([database-user],
AC_HELP_STRING([--with-database-user],
[use the specified database server user (campcaster)]),
[DB_USER=${withval}], [DB_USER=campcaster])
AC_MSG_RESULT([using database server user: ${DB_USER}])
dnl-----------------------------------------------------------------------------
dnl specify the database server user password
dnl-----------------------------------------------------------------------------
AC_SUBST(DB_PASSWORD)
AC_ARG_WITH([database-password],
AC_HELP_STRING([--with-database-password],
[use the specified database server user password (campcaster)]),
[DB_PASSWORD=${withval}], [DB_PASSWORD=campcaster])
AC_MSG_RESULT([using database server user password: ${DB_PASSWORD}])
dnl-----------------------------------------------------------------------------
dnl specify web document root
dnl-----------------------------------------------------------------------------
AC_SUBST(WWW_DOCROOT)
AC_ARG_WITH([www-docroot],
AC_HELP_STRING([--with-www-docroot],
[deploy Campcaster under the specified docroot (/var/www)]),
[WWW_DOCROOT=${withval}], [WWW_DOCROOT=/var/www])
AC_MSG_RESULT([using www document root: ${WWW_DOCROOT}])
dnl display status info on what libraries will get compiled
AC_MSG_NOTICE(
[using the following configuration settings:
hostname: ${HOSTNAME}
www port: ${WWW_PORT}
scheduler port: ${SCHEDULER_PORT}
database server: ${DB_SERVER}
database name: ${DATABASE}
database user: ${DB_USER}
database user password: ${DB_PASSWORD}
creating Campcaster database: ${CREATE_LS_DATABASE}
initialize Campcaster database: ${INIT_LS_DATABASE}
www document root: ${WWW_DOCROOT}
])
AC_CONFIG_FILES(../Makefile:../etc/Makefile.in)
AC_OUTPUT()

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1 @@
keep me

View file

@ -0,0 +1,12 @@
DirectoryIndex index.php
Options +FollowSymLinks -Indexes
<IfModule mod_mime.c>
<IfModule mod_php4.c>
AddType application/x-httpd-php .php
php_flag magic_quotes_gpc On
php_flag register_globals Off
</IfModule>
</IfModule>

View file

@ -0,0 +1,183 @@
<?
/**
* AccessRecur class
*
* Handles recursive accessPlaylist/releasePlaylist.
* Should be 'required_once' from LocStor.php only.
*
* @author $Author$
* @version $Revision$
* @package Campcaster
* @subpackage StorageServer
*/
class AccessRecur {
function AccessRecur(&$ls, $sessid)
{
$this->ls =& $ls;
$this->dbc =& $ls->dbc;
$this->sessid = $sessid;
}
function accessPlaylist(&$ls, $sessid, $plid, $parent='0')
{
$ppa =& new AccessRecur($ls, $sessid);
$r = $ls->accessPlaylist($sessid, $plid, FALSE, $parent);
if (PEAR::isError($r)) {
return $r;
}
$plRes = $r;
$r = StoredFile::recallByGunid($ppa->ls, $plid);
if (PEAR::isError($r)) {
return $r;
}
$ac = $r;
$r = $ac->md->genPhpArray();
if (PEAR::isError($r)) {
return $r;
}
$pla = $r;
$r = $ppa->processPlaylist($pla, $plRes['token']);
if (PEAR::isError($r)) {
return $r;
}
$plRes['content'] = $r;
return $plRes;
}
function releasePlaylist(&$ls, $sessid, $token)
{
$ppa =& new AccessRecur($ls, $sessid);
$r = $ppa->dbc->getAll("
SELECT to_hex(token)as token2, to_hex(gunid)as gunid
FROM {$ppa->ls->accessTable}
WHERE parent=x'{$token}'::bigint
");
if ($ppa->dbc->isError($r)) {
return $r;
}
$arr = $r;
foreach ($arr as $i => $item) {
extract($item); // token2, gunid
$r = $ppa->ls->_getType($gunid);
if ($ppa->dbc->isError($r)) {
return $r;
}
$ftype = $r;
# echo "$ftype/$token2\n";
switch (strtolower($ftype)) {
case"audioclip":
$r = $ppa->ls->releaseRawAudioData($ppa->sessid, $token2);
if ($ppa->dbc->isError($r)) {
return $r;
}
# var_dump($r);
break;
case"playlist":
$r = $ppa->releasePlaylist($ppa->ls, $ppa->sessid, $token2);
if ($ppa->dbc->isError($r)) {
return $r;
}
# var_dump($r);
break;
default:
}
}
$r = $ppa->ls->releasePlaylist($ppa->sessid, $token, FALSE);
if ($ppa->dbc->isError($r)) {
return $r;
}
return $r;
}
function processPlaylist($pla, $parent)
{
$res = array();
foreach ($pla['children'] as $ple) {
switch ($ple['elementname']) {
case"playlistElement":
$r = $this->processPlEl($ple, $parent);
if (PEAR::isError($r)) {
return $r;
}
// $res = array_merge($res, $r);
$res[] = $r;
break;
default:
}
}
return $res;
}
function processAc($gunid, $parent)
{
$r = $this->ls->accessRawAudioData($this->sessid, $gunid, $parent);
if (PEAR::isError($r)) {
return $r;
}
return $r;
}
function processPlEl($ple, $parent='0')
{
foreach ($ple['children'] as $ac) {
switch ($ac['elementname']) {
case"audioClip":
$r = $this->processAc($ac['attrs']['id'], $parent);
if (PEAR::isError($r)) {
return $r;
}
return $r;
break;
case"playlist":
// if(empty($ac['children'])){
$r = $this->accessPlaylist($this->ls, $this->sessid,
$ac['attrs']['id'], $parent);
if (PEAR::isError($r)) {
if ($r->getCode() != GBERR_NOTF) {
return $r;
} else {
$r = $this->processPlaylist($ac, $parent);
if (PEAR::isError($r)) {
return $r;
}
$r = array(
'content' => $r,
'url' => NULL,
'token' => NULL,
'chsum' => NULL,
'size' => NULL,
'warning' => 'inline playlist?',
);
}
}
return $r;
/*
}else{
$r = $this->processPlaylist($ac, $parent);
if(PEAR::isError($r)) return $r;
$res = array(
'content' => $r,
'url' => NULL,
'token' => NULL,
'chsum' => NULL,
'size' => NULL,
'warning' => 'inline playlist',
);
return $res;
}
*/
break;
default:
}
}
return array();
}
} // class AccessRecur
?>

View file

@ -0,0 +1,464 @@
<?php
define('BACKUP_EXT', 'tar');
define('ACCESS_TYPE', 'backup');
/**
* @author $Author: $
* @version $Revision: $
* @package Campcaster
* @subpackage StorageServer
*/
class Backup
{
/**
* string - name of logfile
*/
var $logFile;
/**
* string - session id
*/
var $sessid;
/**
* struct - see search criteria
*/
var $criteria;
/**
* string - token
*/
var $token;
/**
* string - name of statusfile
*/
var $statusFile;
/**
* array - affected gunids
*/
var $ids;
/**
* array - array of affected filenames
*/
var $filenames = array();
/**
* string - base tmp name
*/
var $tmpName;
/**
* stirng - name of temporary tarball file
*/
var $tmpFile;
/**
* string - name of temporary directory
*/
var $tmpDir;
/**
* string - name of temporary playlist directory
*/
var $tmpDirPlaylist;
/**
* string - name of temporary audioclip directory
*/
var $tmpDirClip;
/**
* string - name of temporary metafile directory
*/
var $tmpDirMeta;
/**
* string - loglevel
*/
var $loglevel = 'warn'; # 'debug';
/**
* greenbox object reference
*/
var $gb;
/**
* Constructor
*
* @param gb: greenbox object reference
*/
function Backup (&$gb)
{
$this->gb =& $gb;
$this->token = null;
$this->logFile = $this->gb->bufferDir.'/'.ACCESS_TYPE.'.log';
$this->addLogItem("-I- ".date("Ymd-H:i:s")." construct\n");
}
/**
* Open a backup
* Create a backup file (tarball)
*
* @param sessid : string - session id
* @param criteria : struct - see search criteria
* @return hasharray with field:
* token string: backup token
*/
function openBackup($sessid,$criteria='')
{
if ($this->loglevel=='debug') {
$this->addLogItem("-I- ".date("Ymd-H:i:s")." openBackup - sessid:$sessid\n");
}
$this->sessid = $sessid;
$this->criteria = $criteria;
# get ids (and real filenames) which files match with criteria
$srch = $r = $this->gb->localSearch($this->criteria,$this->sessid);
if (PEAR::isError($r)) {
return $r;
}
$this->setIDs($srch);
#echo '<XMP>this->ids:'; print_r($this->ids); echo '</XMP>';
# get real filenames
if (is_array($this->ids)) {
$this->setFilenames();
#echo '<XMP>this->filenames:'; print_r($this->filenames); echo '</XMP>';
$this->setEnviroment(true);
# write a status file
file_put_contents($this->statusFile, 'working');
# save the metafile to tmpdir
$hostname = trim(`hostname`);
$ctime = time();
$ctime_f = date("Ymd-H:i:s");
file_put_contents("{$this->tmpDirMeta}/storage.xml",
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n".
"<storage\n".
" type=\"".ACCESS_TYPE."\"\n".
" version=\"1.0\"\n".
" ctime=\"$ctime\"\n".
" hostname=\"$hostname\"\n".
"/><!-- $ctime_f -->\n"
);
# copy all file to tmpdir
$this->copyAllFiles();
# do everything
$this->doIt();
return array('token'=>$this->token);
} else {
return false;
}
}
/**
* Check the status of backup.
*
* @param unknown $token
* @return array
* status : string - susccess | working | fault
* faultString: string - description of fault
* token : stirng - backup token
* url : string - access url
* tmpfile : string - access filename
*/
function checkBackup($token)
{
if ($this->loglevel=='debug') {
$this->addLogItem("-I- ".date("Ymd-H:i:s")." checkBackup - token:$token\n");
}
$this->token = $token;
$this->setEnviroment();
$status = file_get_contents($this->statusFile);
if (strpos($status,'fault')!==false) {
list($status,$faultString) = explode('|',$status);
}
switch ($status) {
case 'success':
$r['url'] = $this->gb->getUrlPart()."access/$token.".BACKUP_EXT;
$r['tmpfile'] = $this->gb->accessDir."/$token.".BACKUP_EXT;
case 'working':
case 'fault':
$r['status'] = $status;
$r['faultString'] = $faultString;
$r['token'] = $token;
break;
}
return $r;
}
/**
* Close a backup
*
* @param unknown $token
* @return boolean
*/
function closeBackup($token)
{
if ($this->loglevel=='debug') {
$this->addLogItem("-I- ".date("Ymd-H:i:s")." closeBackup - token:$token\n");
}
# post procedures
$this->token = $token;
$this->setEnviroment();
$this->gb->bsRelease($token,ACCESS_TYPE);
Backup::rRmDir($this->tmpDir);
unlink($this->statusFile);
unlink($this->tmpFile);
if (is_file($this->tmpName)) {
unlink($this->tmpName);
}
return !is_file($this->tmpFile);
}
/**
* list of unclosed backups
*
* @param string $stat (optional)
* if this parameter is not set, then return with all unclosed backups
* @return array of hasharray with field:
* status : string - susccess | working | fault
* token : stirng - backup token
* url : string - access url
*/
function listBackups($stat='')
{
if ($this->loglevel=='debug') {
$this->addLogItem("-I- ".date("Ymd-H:i:s")." listBackups - stat:$stat\n");
}
# open temporary dir
$tokens = $this->gb->getTokensByType(ACCESS_TYPE);
# echo '<XMP>tokens:'; print_r($tokens); echo '</XMP>';
foreach ($tokens as $token) {
$st = $this->checkBackup($token);
if ($stat=='' || $st['status']==$stat) {
$r[] = $st;
}
}
return $r;
}
/**
* Aet the ids from searchResult
*
* @param array $searchResult : array of gunids
*/
function setIDs($searchResult)
{
if ($this->loglevel=='debug') {
$this->addLogItem("-I- ".date("Ymd-H:i:s")." setIDs\n");
}
if (is_array($searchResult['results'])) {
$this->ids = $searchResult['results'];
} else {
$this->addLogItem("-E- ".date("Ymd-H:i:s")." setIDs - the parameter is not array!\n");
return PEAR::raiseError('The IDs variable isn\'t array.');
}
}
/**
* Set the filenames from ids.
*
*/
function setFilenames()
{
if ($this->loglevel=='debug') {
$this->addLogItem("-I- ".date("Ymd-H:i:s")." setFilenames\n");
}
if (is_array($this->ids)) {
foreach ($this->ids as $i=>$item) {
$gunid = $item['gunid'];
# get a stored file object of this gunid
$sf = $r = StoredFile::recallByGunid($this->gb, $gunid);
if (PEAR::isError($r)) {
return $r;
}
$lid = $this->gb->_idFromGunid($gunid);
if (($res = $this->gb->_authorize('read', $lid, $this->sessid)) !== TRUE) {
$this->addLogItem("-E- ".date("Ymd-H:i:s")." setFilenames - authorize gunid:$gunid\n");
return PEAR::raiseError('Backup::setFilenames : Authorize ... error.');
}
# if the file is a playlist then it have only meta file
if (strtolower($sf->md->format)!='playlist') {
$this->filenames[] = array(
'filename' => $sf->_getRealRADFname(), # get real filename of raw media data
'format' => $sf->md->format
);
}
$this->filenames[] = array(
'filename' => $sf->_getRealMDFname(), # get real filename of metadata file
'format' => $sf->md->format
);
if ($this->loglevel=='debug') {
$this->addLogItem("-I- ".date("Ymd-H:i:s")." setFilenames - add file: {$sf->md->format}|".$sf->_getRealMDFname()."\n");
}
}
return $this->filenames;
} else {
$this->addLogItem("-E- ".date("Ymd-H:i:s")." setFilenames - The IDs variable isn't array.\n");
return PEAR::raiseError('Backup::setFilenames : The IDs variable isn\'t array.');
}
}
/**
* Create the tarball - call the shell script
*
*/
function doIt()
{
if ($this->loglevel=='debug') {
$this->addLogItem("-I- ".date("Ymd-H:i:s")." doIt\n");
}
$command = dirname(__FILE__).'/../bin/backup.sh'.
" {$this->tmpDir}".
" {$this->tmpFile}".
" {$this->statusFile}".
" >> {$this->logFile} &";
$res = system("$command");
sleep(2);
if ($this->loglevel=='debug') {
$this->addLogItem("-I- ".date("Ymd-H:i:s")." doIt - command:$command\n");
}
}
/**
* Copy the real files into the tmp dirs to tar they.
*
*/
function copyAllFiles()
{
if ($this->loglevel=='debug') {
$this->addLogItem("-I- ".date("Ymd-H:i:s")." copyAllFiles\n");
}
//echo '<XMP>this->filenames:'; print_r($this->filenames); echo '</XMP>';
if (is_array($this->filenames)) {
foreach ($this->filenames as $v) {
# get the filename from full path
$fn = substr($v['filename'],strrpos($v['filename'],'/'));
switch (strtolower($v['format'])) {
case 'playlist':
# if playlist then copy to the playlist dir
copy($v['filename'],$this->tmpDirPlaylist.$fn);
break;
case 'audioclip':
# if audioclip then copy to the audioclip dir
copy($v['filename'],$this->tmpDirClip.$fn);
break;
}
}
}
}
/**
* Figure out the enviroment to the backup
*
*/
function setEnviroment($createDir=false)
{
if ($this->loglevel=='debug') {
$this->addLogItem("-I- ".date("Ymd-H:i:s")." setEnviroment - createDirs:$createDir\n");
}
# create a temporary directories
if (is_null($this->token) && $createDir) {
$this->tmpName = tempnam($this->gb->bufferDir, ACCESS_TYPE.'_');
$this->tmpFile = $this->tmpName.'.'.BACKUP_EXT;
$this->tmpDir = $this->tmpName.'.dir';
$this->tmpDirPlaylist = $this->tmpDir. '/playlist';
$this->tmpDirClip = $this->tmpDir. '/audioClip';
$this->tmpDirMeta = $this->tmpDir. '/meta-inf';
touch($this->tmpFile);
mkdir($this->tmpDir);
mkdir($this->tmpDirPlaylist);
mkdir($this->tmpDirClip);
mkdir($this->tmpDirMeta);
$this->genToken();
} else {
$symlink = $this->gb->accessDir.'/'.$this->token.'.'.BACKUP_EXT;
if (is_link($symlink) && is_file(readlink($symlink))) {
$this->tmpName = str_replace('.tar','',readlink($symlink));
$this->tmpFile = $this->tmpName.'.'.BACKUP_EXT;
$this->tmpDir = $this->tmpName.'.dir';
$this->tmpDirPlaylist = $this->tmpDir. '/playlist';
$this->tmpDirClip = $this->tmpDir. '/audioClip';
$this->tmpDirMeta = $this->tmpDir. '/meta-inf';
} else {
$this->addLogItem("-E- ".date("Ymd-H:i:s")." setEnviroment - Corrupt symbolic link.\n");
return false;
}
}
$this->statusFile = $this->gb->accessDir.'/'.$this->token.'.'.BACKUP_EXT.'.status';
if ($this->loglevel=='debug') {
$this->addLogItem("this->tmpName: $this->tmpName\n");
$this->addLogItem("this->tmpFile: $this->tmpFile\n");
$this->addLogItem("this->tmpDir: $this->tmpDir\n");
$this->addLogItem("this->tmpDirPlaylist: $this->tmpDirPlaylist\n");
$this->addLogItem("this->tmpDirClip: $this->tmpDirClip\n");
$this->addLogItem("this->tmpDirMeta: $this->tmpDirMeta\n");
$this->addLogItem("this->token: $this->token\n");
$this->addLogItem("this->statusFile: $this->statusFile\n");
}
}
/**
* Generate a new token.
* @return void
*/
function genToken()
{
$acc = $this->gb->bsAccess($this->tmpFile, BACKUP_EXT, null, ACCESS_TYPE);
if ($this->gb->dbc->isError($acc)) {
return $acc;
}
$this->token = $acc['token'];
}
/**
* Add a line to the logfile.
*
* @param string $item - the new row of log file
*/
function addLogItem($item)
{
$f = fopen ($this->logFile,'a');
fwrite($f,$item);
fclose($f);
//echo file_get_contents($this->logFile)."<BR><BR>\n\n";
}
/**
* Delete a directory recursive
*
* @param string $dirname - path of dir.
*/
function rRmDir($dirname)
{
if (is_dir($dirname)) {
$dir_handle = opendir($dirname);
}
while ($file = readdir($dir_handle)) {
if ( ($file != ".") && ($file != "..") ) {
if (!is_dir($dirname."/".$file)) {
unlink ($dirname."/".$file);
} else {
Backup::rRmDir($dirname."/".$file);
}
}
}
closedir($dir_handle);
rmdir($dirname);
return true;
}
} // classs Backup
?>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,419 @@
<?php
define('USE_INTERSECT', TRUE);
require_once "XML/Util.php";
/**
* DataEngine class
*
* Format of search criteria: hash, with following structure:<br>
* <ul>
* <li>filetype - string, type of searched files,
* meaningful values: 'audioclip', 'webstream', 'playlist', 'all'</li>
* <li>operator - string, type of conditions join
* (any condition matches / all conditions match),
* meaningful values: 'and', 'or', ''
* (may be empty or ommited only with less then 2 items in
* &quot;conditions&quot; field)
* </li>
* <li>orderby : string - metadata category for sorting (optional)</li>
* <li>desc : boolean - flag for descending order (optional)</li>
* <li>conditions - array of hashes with structure:
* <ul>
* <li>cat - string, metadata category name</li>
* <li>op - string, operator - meaningful values:
* 'full', 'partial', 'prefix', '=', '&lt;',
* '&lt;=', '&gt;', '&gt;='</li>
* <li>val - string, search value</li>
* </ul>
* </li>
* </ul>
* <p>
* Format of search/browse results: hash, with following structure:<br>
* <ul>
* <li>results : array of gunids have found</li>
* <li>cnt : integer - number of matching items</li>
* </ul>
*
* @Author $Author$
* @version $Revision$
* @package Campcaster
* @subpackage StorageServer
* @see MetaData
* @see StoredFile
*/
class DataEngine{
/**
* Constructor
*
* @param gb reference to BasicStor object
* @return this
*/
function DataEngine(&$gb)
{
$this->gb =& $gb;
$this->dbc =& $gb->dbc;
$this->mdataTable = $gb->mdataTable;
$this->filesTable = $gb->filesTable;
$this->filetypes = array(
'all'=>NULL,
'audioclip'=>'audioclip',
'webstream'=>'webstream',
'playlist'=>'playlist',
);
}
/**
* Method returning array with where-parts of sql queries
*
* @param conditions array - see conditions field in search criteria format
* definition in DataEngine class documentation
* @return array of strings - where-parts of SQL qyeries
*/
function _makeWhereArr($conditions)
{
$ops = array('full'=>"='%s'", 'partial'=>"like '%%%s%%'",
'prefix'=>"like '%s%%'", '<'=>"< '%s'", '='=>"= '%s'",
'>'=>"> '%s'", '<='=>"<= '%s'", '>='=>">= '%s'"
);
$whereArr = array();
if(is_array($conditions)){
foreach($conditions as $cond){
$catQn = $cond['cat'];
$op = strtolower($cond['op']);
$value = strtolower($cond['val']);
$splittedQn = XML_Util::splitQualifiedName($catQn);
$catNs = $splittedQn['namespace'];
$cat = $splittedQn['localPart'];
$opVal = sprintf($ops[$op], pg_escape_string($value));
// retype for timestamp value
if($cat == 'mtime'){
switch($op){
case'partial': case'prefix': break;
default:
$retype = "::timestamp with time zone";
$opVal = "$retype $opVal$retype";
}
}
// escape % for sprintf in whereArr construction:
$cat = str_replace("%", "%%", $cat);
$opVal = str_replace("%", "%%", $opVal);
$sqlCond =
" %s.predicate = '{$cat}' AND".
" %s.objns='_L' AND %s.predxml='T'".
" AND lower(%s.object) {$opVal}\n";
if(!is_null($catNs)){
$catNs = str_replace("%", "%%", $catNs);
$sqlCond = " %s.predns = '{$catNs}' AND $sqlCond";
}
$whereArr[] = $sqlCond;
}
}
return $whereArr;
}
/**
* Method returning SQL query for search/browse with AND operator
* (without using INTERSECT command)
*
* @param fldsPart string - fields part of sql query
* @param whereArr array - array of where-parts
* @param fileCond string - condition for files table
* @param browse boolean - true if browse vals required instead of gunids
* @param brFldNs string - namespace prefix of category for browse
* @param brFld string - category for browse
* @return query string
*/
function _makeAndSqlWoIntersect($fldsPart, $whereArr, $fileCond, $browse,
$brFldNs=NULL, $brFld=NULL)
{
$innerBlocks = array();
foreach($whereArr as $i=>$v){
$whereArr[$i] = sprintf($v, "md$i", "md$i", "md$i", "md$i", "md$i");
$lastTbl = ($i==0 ? "f" : "md".($i-1));
$innerBlocks[] =
"INNER JOIN {$this->mdataTable} md$i ON md$i.gunid = $lastTbl.gunid\n";
}
// query construcion:
$sql = "SELECT $fldsPart\nFROM {$this->filesTable} f\n".join("", $innerBlocks);
if($browse){
$sql .= "INNER JOIN {$this->mdataTable} br".
"\n ON br.gunid = f.gunid AND br.objns='_L'".
" AND br.predicate='{$brFld}' AND br.predxml='T'";
if(!is_null($brFldNs)) $sql .= " AND br.predns='{$brFldNs}'";
$sql .= "\n";
}
if(!is_null($fileCond)) $whereArr[] = " $fileCond";
if(count($whereArr)>0) $sql .= "WHERE\n".join(" AND\n", $whereArr);
if($browse) $sql .= "\nORDER BY br.object";
return $sql;
}
/**
* Method returning SQL query for search/browse with AND operator
* (using INTERSECT command)
*
* @param fldsPart string - fields part of sql query
* @param whereArr array - array of where-parts
* @param fileCond string - condition for files table
* @param browse boolean - true if browse vals required instead of gunids
* @param brFldNs string - namespace prefix of category for browse
* @param brFld string - category for browse
* @return query string
*/
function _makeAndSql($fldsPart, $whereArr, $fileCond, $browse,
$brFldNs=NULL, $brFld=NULL)
{
if(!USE_INTERSECT) return $this->_makeAndSqlWoIntersect(
$fldsPart, $whereArr, $fileCond, $browse, $brFldNs, $brFld);
$isectBlocks = array();
foreach($whereArr as $i=>$v){
$whereArr[$i] = sprintf($v, "md$i", "md$i", "md$i", "md$i", "md$i");
$isectBlocks[] =
" SELECT gunid FROM {$this->mdataTable} md$i\n".
" WHERE\n {$whereArr[$i]}";
}
// query construcion:
if(count($isectBlocks)>0){
$isectBlock =
"FROM\n(\n".join("INTERSECT\n", $isectBlocks).") sq\n".
"INNER JOIN {$this->filesTable} f ON f.gunid = sq.gunid";
}else{
$isectBlock = "FROM {$this->filesTable} f";
}
$sql =
"SELECT $fldsPart\n".$isectBlock;
if($browse){
$sql .= "\nINNER JOIN {$this->mdataTable} br ON br.gunid = f.gunid\n".
"WHERE br.objns='_L' AND br.predxml='T' AND br.predicate='{$brFld}'";
if(!is_null($brFldNs)) $sql .= " AND br.predns='{$brFldNs}'";
$glue = " AND";
}else{ $glue = "WHERE";}
if(!is_null($fileCond)) $sql .= "\n$glue $fileCond";
if($browse) $sql .= "\nORDER BY br.object";
return $sql;
}
/**
* Method returning SQL query for search/browse with OR operator
*
* @param fldsPart string - fields part of sql query
* @param whereArr array - array of where-parts
* @param fileCond string - condition for files table
* @param browse boolean - true if browse vals required instead of gunids
* @param brFldNs string - namespace prefix of category for browse
* @param brFld string - category for browse
* @return query string
*/
function _makeOrSql($fldsPart, $whereArr, $fileCond, $browse,
$brFldNs=NULL, $brFld=NULL)
{
//$whereArr[] = " FALSE\n";
foreach($whereArr as $i=>$v){
$whereArr[$i] = sprintf($v, "md", "md", "md", "md", "md");
}
// query construcion:
$sql = "SELECT $fldsPart\nFROM {$this->filesTable} f\n";
if($browse){
$sql .= "INNER JOIN {$this->mdataTable} br".
"\n ON br.gunid = f.gunid AND br.objns='_L'".
" AND br.predxml='T' AND br.predicate='{$brFld}'";
if(!is_null($brFldNs)) $sql .= " AND br.predns='{$brFldNs}'";
$sql .= "\n";
}
if(count($whereArr)>0){
$sql .= "INNER JOIN {$this->mdataTable} md ON md.gunid=f.gunid\n";
$sql .= "WHERE\n(\n".join(" OR\n", $whereArr).")";
$glue = " AND";
}else{ $glue = "WHERE"; }
if(!is_null($fileCond)) $sql .= "$glue $fileCond";
if($browse) $sql .= "\nORDER BY br.object";
return $sql;
}
/**
* Search in local metadata database.
*
* @param cri hash, search criteria see DataEngine class documentation
* @param limit int, limit for result arrays (0 means unlimited)
* @param offset int, starting point (0 means without offset)
* @return hash, fields:
* results : array with gunid strings
* cnt : integer - number of matching gunids
* of files have been found
*/
function localSearch($cri, $limit=0, $offset=0)
{
$res = $this->_localGenSearch($cri, $limit, $offset);
// if(PEAR::isError($res)) return $res;
return $res;
}
/**
* Search in local metadata database, more general version.
*
* @param criteria hash, search criteria see DataEngine class documentation
* @param limit int, limit for result arrays (0 means unlimited)
* @param offset int, starting point (0 means without offset)
* @param brFldNs string - namespace prefix of category for browse
* @param brFld string, metadata category identifier for browse
* @return arrays of hashes, fields:
* cnt : integer - number of matching gunids
* of files have been found
* results : array of hashes:
* gunid: string
* type: string - audioclip | playlist | webstream
* title: string - dc:title from metadata
* creator: string - dc:creator from metadata
* length: string - dcterms:extent in extent format
* OR (in browse mode)
* results: array of strings - browsed values
*/
function _localGenSearch($criteria, $limit=0, $offset=0,
$brFldNs=NULL, $brFld=NULL)
{
$filetype = (isset($criteria['filetype']) ? $criteria['filetype'] : 'all');
$filetype = strtolower($filetype);
if(!array_key_exists($filetype, $this->filetypes)){
return PEAR::raiseError(
'DataEngine::_localGenSearch: unknown filetype in search criteria'
);
}
$filetype = $this->filetypes[$filetype];
$operator = (isset($criteria['operator']) ? $criteria['operator'] : 'and');
$operator = strtolower($operator);
$desc = (isset($criteria['desc']) ? $criteria['desc'] : NULL);
$conditions = (isset($criteria['conditions']) ? $criteria['conditions'] : array());
$whereArr = $this->_makeWhereArr($conditions);
$orderbyQn = // default is dc:title
(isset($criteria['orderby']) ? $criteria['orderby'] : 'dc:title' /*NULL*/);
$obSplitQn = XML_Util::splitQualifiedName($orderbyQn);
$obNs = $obSplitQn['namespace'];
$orderby = $obSplitQn['localPart'];
$browse = !is_null($brFld);
if(!$browse){
if(!$orderby){
$fldsPart = "DISTINCT to_hex(f.gunid)as gunid, f.ftype, f.id";
}else{
$fldsPart = "DISTINCT f.gunid, f.ftype, f.id";
}
}else{
$fldsPart = "DISTINCT br.object as txt";
}
$limitPart = ($limit != 0 ? " LIMIT $limit" : '' ).
($offset != 0 ? " OFFSET $offset" : '' );
$fileCond = "f.state='ready'";
if(!is_null($filetype)) $fileCond .= " AND f.ftype='$filetype'";
if($operator == 'and'){ // operator: and
$sql = $this->_makeAndSql(
$fldsPart, $whereArr, $fileCond, $browse, $brFldNs, $brFld);
}else{ // operator: or
$sql = $this->_makeOrSql(
$fldsPart, $whereArr, $fileCond, $browse, $brFldNs, $brFld);
}
if(!$browse && $orderby){
$retype = ($orderby == 'mtime' ? '::timestamp with time zone' : '' );
$sql =
"SELECT to_hex(sq2.gunid)as gunid, m.object, sq2.ftype, sq2.id\n".
"FROM (\n$sql\n)sq2\n".
"LEFT JOIN {$this->mdataTable} m\n".
" ON m.gunid = sq2.gunid AND m.predicate='$orderby'".
" AND m.objns='_L' AND m.predxml='T'".
(!is_null($obNs)? " AND m.predns='$obNs'":'')."\n".
"ORDER BY sq2.ftype, m.object".$retype.($desc? ' DESC':'')."\n";
}
// echo "\n---\n$sql\n---\n";
$cnt = $this->_getNumRows($sql);
if(PEAR::isError($cnt)) return $cnt;
$res = $this->dbc->getAll($sql.$limitPart);
if(PEAR::isError($res)) return $res;
if(!is_array($res)) $res = array();
# if(!$browse){
# $res = array_map(array("StoredFile", "_normalizeGunid"), $res);
# }
$eres = array();
foreach($res as $it){
if(!$browse){
$gunid = StoredFile::_normalizeGunid($it['gunid']);
$titleA = $r = $this->gb->bsGetMetadataValue($it['id'], 'dc:title');
if(PEAR::isError($r)) return $r;
$title = (isset($titleA[0]['value']) ? $titleA[0]['value'] : '');
$creatorA = $r = $this->gb->bsGetMetadataValue($it['id'], 'dc:creator');
if(PEAR::isError($r)) return $r;
$creator = (isset($creatorA[0]['value']) ? $creatorA[0]['value'] : '');
$lengthA = $r = $this->gb->bsGetMetadataValue($it['id'], 'dcterms:extent');
if(PEAR::isError($r)) return $r;
$length = (isset($lengthA[0]['value']) ? $lengthA[0]['value'] : '');
$eres[] = array(
'gunid' => $gunid,
'type' => $it['ftype'],
'title' => $title,
'creator' => $creator,
'length' => $length,
);
}else{
$eres[] = $it['txt'];
}
}
return array('results'=>$eres, 'cnt'=>$cnt);
}
/**
* Return values of specified metadata category
*
* @param category string, metadata category name
* with or without namespace prefix (dc:title, author)
* @param limit int, limit for result arrays (0 means unlimited)
* @param offset int, starting point (0 means without offset)
* @param criteria hash
* @return hash, fields:
* results : array with found values
* cnt : integer - number of matching values
*/
function browseCategory($category, $limit=0, $offset=0, $criteria=NULL)
{
//$category = strtolower($category);
$r = XML_Util::splitQualifiedName($category);
$catNs = $r['namespace'];
$cat = $r['localPart'];
if(is_array($criteria) && count($criteria)>0){
return $this->_localGenSearch($criteria, $limit, $offset, $catNs, $cat);
}
$sqlCond = "m.predicate='$cat' AND m.objns='_L' AND m.predxml='T'";
if(!is_null($catNs)){
$sqlCond = "m.predns = '{$catNs}' AND $sqlCond";
}
$limitPart = ($limit != 0 ? " LIMIT $limit" : '' ).
($offset != 0 ? " OFFSET $offset" : '' );
$sql =
"SELECT DISTINCT m.object FROM {$this->mdataTable} m\n".
"WHERE $sqlCond";
// echo "\n---\n$sql\n---\n";
$cnt = $this->_getNumRows($sql);
if(PEAR::isError($cnt)) return $cnt;
$res = $this->dbc->getCol($sql.$limitPart);
if(PEAR::isError($res)) return $res;
if(!is_array($res)) $res = array();
return array('results'=>$res, 'cnt'=>$cnt);
}
/**
* Get number of rows in query result
*
* @param query string, sql query
* @return int, number of rows in query result
*/
function _getNumRows($query)
{
$rh = $this->dbc->query($query);
if(PEAR::isError($rh)) return $rh;
$cnt = $rh->numRows();
if(PEAR::isError($cnt)) return $cnt;
$rh->free();
return $cnt;
}
}
?>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,576 @@
<?
require_once "Playlist.php";
define('INDCH', ' ');
define('AC_URL_RELPATH', '../audioClip/');
define('PL_URL_RELPATH', '../playlist/');
/**
* LsPlaylist class
*
* Internal playlist format helper.
*
* @author $Author: tomash $
* @version $Revision: 1848 $
* @package Campcaster
* @subpackage StorageServer
* @todo Rename this class
*/
class LsPlaylist extends Playlist
{
/**
* Create instance of LsPlaylist object and recall existing file
* by gunid.<br/>
*
* @param Greenbox $gb, reference to GreenBox object
* @param string $gunid, global unique id
* @param string $className, optional classname to recall
* @return instance of LsPlaylist object
*/
function &recallByGunid(&$gb, $gunid, $className='LsPlaylist')
{
return parent::recallByGunid($gb, $gunid, $className);
}
/**
* Create instance of LsPlaylist object and recall existing file
* by access token.<br/>
*
* @param GreenBox $gb, reference to GreenBox object
* @param string $token, access token
* @param string $className, optional classname to recall
* @return instance of LsPlaylist object
*/
function &recallByToken(&$gb, $token, $className='LsPlaylist')
{
return parent::recallByToken($gb, $token, $className);
}
/**
* Export playlist as simplified SMIL XML file
*
* @param boolean $toString
* if false don't real export,
* return misc info about playlist only
* @return string
* XML string or hasharray with misc info
*/
function output2Smil($toString=TRUE)
{
$plGunid = $this->gunid;
$arr = $r = $this->md->genPhpArray();
if (PEAR::isError($r)) {
return $r;
}
if ($toString) {
$r = LsPlaylistTag::output2Smil($this, $arr);
if (PEAR::isError($r)) {
return $r;
}
return $r;
} else {
return array(
'type' => 'playlist',
'gunid' => $plGunid,
'src' => PL_URL_RELPATH."$plGunid.smil",
'playlength' => $arr['attrs']['playlength'],
);
}
}
/**
* Export playlist as M3U file
*
* @param toString boolean, if false don't real export,
* return misc info about playlist only
* @return M3U string or hasharray with misc info
*/
function output2m3u($toString=TRUE)
{
$plGunid = $this->gunid;
$arr = $r = $this->md->genPhpArray();
if (PEAR::isError($r)) {
return $r;
}
if ($toString) {
$r = LsPlaylistTag::output2m3u($this, $arr);
if (PEAR::isError($r)) {
return $r;
}
return $r;
} else {
return array(
'type' => 'playlist',
'gunid' => $plGunid,
'uri' => PL_URL_RELPATH."$plGunid.m3u",
'playlength' => $arr['attrs']['playlength'],
'title' => $arr['attrs']['title'],
);
}
}
/**
* Export playlist as RSS XML file
*
* @param boolean $toString
* if false don't really export,
* return misc info about playlist only
* @return mixed
* XML string or hasharray with misc info
*/
function output2RSS($toString=TRUE)
{
$plGunid = $this->gunid;
$arr = $r = $this->md->genPhpArray();
if (PEAR::isError($r)) {
return $r;
}
if ($toString) {
$r = LsPlaylistTag::output2RSS($this, $arr);
if (PEAR::isError($r)) {
return $r;
}
return $r;
} else {
return array(
'type' => 'playlist',
'gunid' => $plGunid,
'src' => PL_URL_RELPATH."$plGunid.smil",
'playlength' => $arr['attrs']['playlength'],
);
}
}
} // class LsPlaylist
/**
* Several auxiliary classes follows
* @package Campcaster
* @subpackage StorageServer
* @todo Rename this class PlaylistTag
*/
class LsPlaylistTag
{
function output2Smil(&$pl, $plt, $ind='')
{
$ind2 = $ind.INDCH;
$ind3 = $ind2.INDCH;
$ind4 = $ind3.INDCH;
$res = "";
foreach ($plt['children'] as $ple) {
switch ($ple['elementname']) {
case"playlistElement":
$r = LsPlaylistElement::output2Smil($pl, $ple, $ind4);
if (PEAR::isError($r)) {
return $r;
}
if (!is_null($r)) {
$res .= $r;
}
break;
case"metadata":
$r = LsPlaylistMetadata::output2Smil($pl, $ple, $ind4);
if (PEAR::isError($r)) {
return $r;
}
if (!is_null($r)) {
$res .= $r;
}
break;
default:
}
}
$res = "$ind<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n".
"$ind<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n".
"$ind2<body>\n".
"$ind3<par>\n".
"$res".
"$ind3</par>\n".
"$ind2</body>\n".
"$ind</smil>\n";
return $res;
}
function output2m3u(&$pl, $plt, $ind='')
{
$res = "";
foreach ($plt['children'] as $ple) {
switch ($ple['elementname']) {
case"playlistElement":
$r = LsPlaylistElement::output2m3u($pl, $ple);
if (PEAR::isError($r)) {
return $r;
}
if (!is_null($r)) {
$res .= $r;
}
break;
}
}
$res = "#EXTM3U\n$res";
return $res;
}
function output2RSS(&$pl, $plt, $ind='')
{
$ind2 = $ind.INDCH;
$ind3 = $ind2.INDCH;
$res = "";
foreach ($plt['children'] as $ple) {
switch ($ple['elementname']) {
case"playlistElement":
$r = LsPlaylistElement::output2RSS($pl, $ple, $ind3);
if (PEAR::isError($r)) {
return $r;
}
if (!is_null($r)) {
$res .= $r;
}
break;
case"metadata":
$r = LsPlaylistMetadata::output2RSS($pl, $ple, $ind3);
if (PEAR::isError($r)) {
return $r;
}
if (!is_null($r)) {
$res .= $r;
}
break;
default:
}
}
$res = "$ind<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n".
"$ind<rss version=\"2.0\">\n".
"$ind2<channel>\n".
"$res".
"$ind2</channel>\n".
"$ind</rss>\n";
return $res;
}
} // class LsPlaylistTag
/**
* @package Campcaster
* @subpackage StorageServer
* @todo Rename this class "PlaylistElement"
*/
class LsPlaylistElement {
function output2Smil(&$pl, $ple, $ind='')
{
$acOrPl = NULL;
$finfo = array('fi'=>0, 'fo'=>0);
$ind2 = $ind.INDCH;
$ind3 = $ind2.INDCH;
$anim = '';
foreach ($ple['children'] as $ac) {
switch ($ac['elementname']) {
case "audioClip":
$r = LsPlaylistAudioClip::output2Smil($pl, $ac, $ind2);
if (PEAR::isError($r)) {
return $r;
}
if (!is_null($r)) {
$acOrPl = $r;
}
break;
case "playlist":
$gunid = $ac['attrs']['id'];
$pl2 = $r = LsPlaylist::recallByGunid($pl->gb, $gunid);
if (PEAR::isError($r)) {
return $r;
}
$r = $pl2->output2Smil(FALSE);
if (PEAR::isError($r)) {
return $r;
}
if (!is_null($r)) {
$acOrPl = $r;
}
break;
case"fadeInfo":
$r = LsPlaylistFadeInfo::output2Smil($pl, $ac, $ind2);
if (PEAR::isError($r)) {
return $r;
}
if (!is_null($r)) {
$finfo = $r;
}
break;
default:
return PEAR::raiseError(
"LsPlaylistElement::output2Smil:".
" unknown tag {$ac['elementname']}"
);
}
}
$beginS = $pl->_plTimeToSecs($ple['attrs']['relativeOffset']);
$playlengthS = $pl->_plTimeToSecs($acOrPl['playlength']);
$fadeOutS = $pl->_plTimeToSecs($finfo['fo']);
$fiBeginS = 0;
$fiEndS = $pl->_plTimeToSecs($finfo['fi']);
$foBeginS = ($playlengthS - $fadeOutS);
$foEndS = $pl->_plTimeToSecs($acOrPl['playlength']);
foreach (array('fi','fo') as $ff) {
if (${$ff."EndS"} - ${$ff."BeginS"} > 0) {
$anim .= "{$ind2}<animate attributeName = \"soundLevel\"\n".
"{$ind3}from = \"".($ff == 'fi' ? 0 : 100)."%\"\n".
"{$ind3}to = \"".($ff == 'fi' ? 100 : 0)."%\"\n".
"{$ind3}calcMode = \"linear\"\n".
"{$ind3}begin = \"{${$ff."BeginS"}}s\"\n".
"{$ind3}end = \"{${$ff."EndS"}}s\"\n".
"{$ind3}fill = \"freeze\"\n".
"{$ind2}/>\n"
;
}
}
$src = $acOrPl['src'];
$str = "$ind<audio src=\"$src\" begin=\"{$beginS}s\"".
($anim ? ">\n$anim$ind</audio>" : " />").
" <!-- {$acOrPl['type']}, {$acOrPl['gunid']}, {$acOrPl['playlength']} -->".
"\n";
return $str;
}
function output2m3u(&$pl, $ple, $ind='')
{
$acOrPl = NULL;
foreach ($ple['children'] as $ac) {
switch ($ac['elementname']) {
case "audioClip":
$r = LsPlaylistAudioClip::output2m3u($pl, $ac);
if (PEAR::isError($r)) {
return $r;
}
if (!is_null($r)) {
$acOrPl = $r;
}
break;
case "playlist":
$gunid = $ac['attrs']['id'];
$pl2 = $r = LsPlaylist::recallByGunid($pl->gb, $gunid);
if (PEAR::isError($r)) {
return $r;
}
$r = $pl2->output2m3u(FALSE);
if (PEAR::isError($r)) {
return $r;
}
if (!is_null($r)) {
$acOrPl = $r;
}
break;
}
}
if (is_null($acOrPl)) {
return '';
}
$playlength = ceil($pl->_plTimeToSecs($acOrPl['playlength']));
$title = $acOrPl['title'];
$uri = (isset($acOrPl['uri']) ? $acOrPl['uri'] : '???' );
$res = "#EXTINF: $playlength, $title\n";
$res .= "$uri\n";
return $res;
}
function output2RSS(&$pl, $ple, $ind='')
{
$acOrPl = NULL;
$ind2 = $ind.INDCH;
$anim = '';
foreach ($ple['children'] as $ac) {
switch ($ac['elementname']) {
case "audioClip":
$r = LsPlaylistAudioClip::output2RSS($pl, $ac, $ind2);
if (PEAR::isError($r)) {
return $r;
}
if (!is_null($r)) {
$acOrPl = $r;
}
break;
case"playlist":
$gunid = $ac['attrs']['id'];
$pl2 = $r = LsPlaylist::recallByGunid($pl->gb, $gunid);
if (PEAR::isError($r)) {
return $r;
}
$r = $pl2->output2RSS(FALSE);
if (PEAR::isError($r)) {
return $r;
}
if (!is_null($r)) {
$acOrPl = $r;
}
break;
case"fadeInfo":
break;
default:
return PEAR::raiseError(
"LsPlaylistElement::output2RSS:".
" unknown tag {$ac['elementname']}"
);
}
}
$title = (isset($acOrPl['title']) ? htmlspecialchars($acOrPl['title']) : '' );
$desc = (isset($acOrPl['desc']) ? htmlspecialchars($acOrPl['desc']) : '' );
$link = htmlspecialchars($acOrPl['src']);
$desc = '';
$str = "$ind<item>\n".
"$ind2<title>$title</title>\n".
"$ind2<description>$desc</description>\n".
"$ind2<link>$link</link>\n".
"$ind</item>\n";
return $str;
}
}
/**
* @package Campcaster
* @subpackage StorageServer
* @todo Rename this class to PlaylistAudioClip (notice the caps)
*/
class LsPLaylistAudioClip
{
function output2Smil(&$pl, $plac, $ind='')
{
$gunid = $plac['attrs']['id'];
$ac = $r = StoredFile::recallByGunid($pl->gb, $gunid);
if (PEAR::isError($r)) {
return $r;
}
$RADext = $r =$ac->_getExt();
if (PEAR::isError($r)) {
return $r;
}
return array(
'type' => 'audioclip',
'gunid' => $gunid,
'src' => AC_URL_RELPATH."$gunid.$RADext",
'playlength' => $plac['attrs']['playlength'],
);
}
function output2m3u(&$pl, $plac, $ind='')
{
$gunid = $plac['attrs']['id'];
$ac = $r = StoredFile::recallByGunid($pl->gb, $gunid);
if (PEAR::isError($r)) {
return $r;
}
$RADext = $r =$ac->_getExt();
if (PEAR::isError($r)) {
return $r;
}
return array(
'playlength' => $plac['attrs']['playlength'],
'title' => $plac['attrs']['title'],
'uri' => AC_URL_RELPATH."$gunid.$RADext",
);
}
function output2RSS(&$pl, $plac, $ind='')
{
$gunid = $plac['attrs']['id'];
$ac = $r = StoredFile::recallByGunid($pl->gb, $gunid);
if (PEAR::isError($r)) {
return $r;
}
$RADext = $r =$ac->_getExt();
if (PEAR::isError($r)) {
return $r;
}
$r = $pl->gb->bsGetMetadataValue($ac->getId(), 'dc:title');
if (PEAR::isError($r)) {
return $r;
}
$title = ( isset($r[0]) ? $r[0]['value'] : '' );
$r = $pl->gb->bsGetMetadataValue($ac->getId(), 'dc:description');
if (PEAR::isError($r)) {
return $r;
}
$desc = ( isset($r[0]) ? $r[0]['value'] : '' );
return array(
'type' => 'audioclip',
'gunid' => $gunid,
'src' => "http://XXX/YY/$gunid.$RADext",
'playlength' => $plac['attrs']['playlength'],
'title' => $title,
'desc' => $desc,
);
}
} // class LsPlaylistAudioClip
/**
* @package Campcaster
* @subpackage StorageServer
* @todo Rename this class "PlaylistFadeInfo" (notive the caps)
*/
class LsPLaylistFadeInfo
{
function output2Smil(&$pl, $plfi, $ind='')
{
$r = array(
'fi'=>$plfi['attrs']['fadeIn'],
'fo'=>$plfi['attrs']['fadeOut'],
);
return $r;
}
function output2m3u(&$pl, $plfa, $ind='')
{
return '';
}
function output2RSS(&$pl, $plfa, $ind='')
{
return '';
}
} // class LsPlaylistFadeInfo
/**
* @package Campcaster
* @subpackage StorageServer
* @todo Rename this class to PlaylistMetadata (notive the caps)
*/
class LsPLaylistMetadata
{
function output2Smil(&$pl, $md, $ind='')
{
return NULL;
}
function output2m3u(&$pl, $md, $ind='')
{
return NULL;
}
function output2RSS(&$pl, $md, $ind='')
{
return NULL;
}
} // class PlaylistMetadata
?>

View file

@ -0,0 +1,352 @@
<?
define('INDCH', ' ');
/**
* M3uPlaylist class
*
* @author $Author: tomash $
* @version : $Revision: 1848 $
* @package Campcaster
* @subpackage StorageServer
*/
class M3uPlaylist {
/**
* Parse M3U file or string
*
* @param string $data
* local path to M3U file or M3U string
* @param string $loc
* location: 'file'|'string'
* @return array
* reference, parse result tree (or PEAR::error)
*/
function &parse($data='', $loc='file')
{
switch ($loc) {
case "file":
if (!is_file($data)) {
return PEAR::raiseError(
"M3uPlaylist::parse: file not found ($data)"
);
}
if (!is_readable($data)) {
return PEAR::raiseError(
"M3uPlaylist::parse: can't read file ($data)"
);
}
$data = file_get_contents($data);
case "string":
$arr = preg_split("|\n#EXTINF: |", $data);
if ($arr[0] != '#EXTM3U') {
return PEAR::raiseError(
"M3uPlaylist::parse: invalid M3U header"
);
}
array_shift($arr);
break;
default:
return PEAR::raiseError(
"M3uPlaylist::parse: unsupported data location ($loc)"
);
}
return $arr;
}
/**
* Import M3U file to storage
*
* @param GreenBox $gb
* @param string $aPath
* absolute path part of imported file (e.g. /home/user/campcaster)
* @param string $rPath
* relative path/filename part of imported file
* (e.g. playlists/playlist_1.smil)
* @param array $gunids
* hash relation from filenames to gunids
* @param string $plid
* playlist gunid
* @param int $parid
* destination folder local id
* @param int $subjid
* local subject (user) id (id of user doing the import)
* @return Playlist
*/
function import(&$gb, $aPath, $rPath, &$gunids, $plid, $parid, $subjid=NULL)
{
$path = realpath("$aPath/$rPath");
if (FALSE === $path) {
return PEAR::raiseError(
"M3uPlaylist::import: file doesn't exist ($aPath/$rPath)"
);
}
$arr = $r = M3uPlaylist::parse($path);
if (PEAR::isError($r)) {
return $r;
}
require_once("Playlist.php");
$pl = $r =& Playlist::create($gb, $plid, "imported_M3U", $parid);
if (PEAR::isError($r)) {
return $r;
}
$r = $pl->lock($gb, $subjid);
if (PEAR::isError($r)) {
return $r;
}
foreach ($arr as $i => $it) {
list($md, $uri) = preg_split("|\n|", $it);
list($length, $title) = preg_split("|, *|", $md);
// $gunid = StoredFile::_createGunid();
$gunid = ( isset($gunids[basename($uri)]) ? $gunids[basename($uri)] : NULL);
$acId = $r = $gb->_idFromGunid($gunid);
if (PEAR::isError($r)) {
return $r;
}
$length = Playlist::_secsToPlTime($length);
$offset = '???';
if (preg_match("|\.([a-zA-Z0-9]+)$|", $uri, $va)) {
switch (strtolower($ext = $va[1])) {
case "lspl":
case "xml":
case "smil":
case "m3u":
$acId = $r = $gb->bsImportPlaylistRaw($parid, $gunid,
$aPath, $uri, $ext, $gunids, $subjid);
if (PEAR::isError($r)) {
break;
}
//no break!
default:
if (is_null($gunid)) {
return PEAR::raiseError(
"M3uPlaylist::import: no gunid");
}
$r = $pl->addAudioClip($acId);
if (PEAR::isError($r)) {
return $r;
}
}
}
}
$r = $pl->unLock($gb);
if (PEAR::isError($r)) {
return $r;
}
return $pl;
}
/**
* Import M3U file to storage
*
* @param GreenBox $gb
* @param string $data
* local path to M3U file
* @return string
* XML playlist in Campcaster playlist format
*/
function convert2lspl(&$gb, $data)
{
$arr = $r = M3uPlaylist::parse($data);
if (PEAR::isError($r)) {
return $r;
}
$ind = '';
$ind2 = $ind.INDCH;
$ind3 = $ind2.INDCH;
$res = '';
foreach ($arr as $i => $it) {
list($md, $uri) = preg_split("|\n|", $it);
list($length, $title) = preg_split("|, *|", $md);
$gunid = StoredFile::_createGunid();
$gunid2 = StoredFile::_createGunid();
$length = Playlist::_secsToPlTime($length);
$offset = '???';
$uri_h = preg_replace("|--|", "&#2d;&#2d;", htmlspecialchars("$uri"));
if (preg_match("|\.([a-zA-Z0-9]+)$|", $uri, $va)) {
switch (strtolower($ext = $va[1])) {
case "lspl":
case "xml":
case "smil":
case "m3u":
$acOrPl = "$ind3<playlist id=\"$gunid2\" ".
"playlength=\"$length\" title=\"$title\"/> ".
"<!-- $uri_h -->\n";
break;
default:
$acOrPl = "$ind3<audioClip id=\"$gunid2\" ".
"playlength=\"$length\" title=\"$title\"/> ".
"<!-- $uri_h -->\n";
break;
}
}
$res .= "$ind2<playlistElement id=\"$gunid\" relativeOffset=\"$offset\">\n".
$acOrPl.
"$ind2</playlistElement>\n";
}
$res = "$ind<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n".
"$ind<playlist id=\"$gunid\" playlength=\"$playlength\" title=\"\">\n".
"$ind2<metadata/>\n".
"$res".
"$ind</playlist>\n";
return $res;
}
} // class M3uPlaylist
/**
* @author $Author$
* @version $Revision$
* @package Campcaster
* @subpackage StorageServer
*/
class M3uPlaylistBodyElement {
function convert2lspl(&$tree, $ind='')
{
$ind2 = $ind.INDCH;
if ($tree->name != 'body') {
return PEAR::raiseError("M3uPlaylist::parse: body tag expected");
}
if (isset($tree->children[1])) {
return PEAR::raiseError(sprintf(
"M3uPlaylist::parse: unexpected tag %s in tag body",
$tree->children[1]->name
));
}
$res = $r =
M3uPlaylistParElement::convert2lspl($tree->children[0], $ind2);
if (PEAR::isError($r)) {
return $r;
}
$gunid = StoredFile::_createGunid();
$playlength = '???'; // ***
$res = "$ind<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n".
"$ind<playlist id=\"$gunid\" playlength=\"$playlength\" title=\"\">\n".
"$ind2<metadata/>\n".
"$res".
"$ind</playlist>\n";
return $res;
}
}
/**
* @author $Author$
* @version $Revision$
* @package Campcaster
* @subpackage StorageServer
*/
class M3uPlaylistParElement {
function convert2lspl(&$tree, $ind='')
{
if ($tree->name != 'par') {
return PEAR::raiseError("M3uPlaylist::parse: par tag expected");
}
$res = '';
foreach ($tree->children as $i => $ch) {
$ch =& $tree->children[$i];
$r = M3uPlaylistAudioElement::convert2lspl($ch, $ind.INDCH);
if (PEAR::isError($r)) {
return $r;
}
$res .= $r;
}
return $res;
}
}
/**
* @author $Author$
* @version $Revision$
* @package Campcaster
* @subpackage StorageServer
*/
class M3uPlaylistAudioElement {
function convert2lspl(&$tree, $ind='')
{
$ind2 = $ind.INDCH;
if ($tree->name != 'audio') {
return PEAR::raiseError("M3uPlaylist::parse: audio tag expected");
}
if (isset($tree->children[2])) {
return PEAR::raiseError(sprintf(
"M3uPlaylist::parse: unexpected tag %s in tag audio",
$tree->children[2]->name
));
}
$res = ''; $fadeIn = 0; $fadeOut = 0;
foreach ($tree->children as $i => $ch) {
$ch =& $tree->children[$i];
$r = M3uPlaylistAnimateElement::convert2lspl($ch, $ind2);
if (PEAR::isError($r)) {
return $r;
}
switch ($r['type']) {
case "fadeIn":
$fadeIn = $r['val'];
break;
case "fadeOut":
$fadeOut = $r['val'];
break;
}
}
if ($fadeIn > 0 || $fadeOut > 0) {
$fadeIn = Playlist::_secsToPlTime($fadeIn);
$fadeOut = Playlist::_secsToPlTime($fadeOut);
$fInfo = "$ind2<fadeInfo fadeIn=\"$fadeIn\" fadeOut=\"$fadeOut\"/>\n";
} else {
$fInfo = '';
}
$plElGunid = StoredFile::_createGunid();
$aGunid = StoredFile::_createGunid();
$title = basename($tree->attrs['src']->val);
$offset = Playlist::_secsToPlTime($tree->attrs['begin']->val);
$playlength = '???'; # ***
$res = "$ind<playlistElement id=\"$plElGunid\" relativeOffset=\"$offset\">\n".
"$ind2<audioClip id=\"$aGunid\" playlength=\"$playlength\" title=\"$title\"/>\n".
$fInfo.
"$ind</playlistElement>\n";
return $res;
}
} // class M3uPlaylistAudioElement
/**
* @author $Author$
* @version $Revision$
* @package Campcaster
* @subpackage StorageServer
*/
class M3uPlaylistAnimateElement {
function convert2lspl(&$tree, $ind='') {
if ($tree->name != 'animate') {
return PEAR::raiseError("M3uPlaylist::parse: animate tag expected");
}
if ($tree->attrs['attributeName']->val == 'soundLevel' &&
$tree->attrs['from']->val == '0%' &&
$tree->attrs['to']->val == '100%' &&
$tree->attrs['calcMode']->val == 'linear' &&
$tree->attrs['fill']->val == 'freeze' &&
$tree->attrs['begin']->val == '0s' &&
preg_match("|^([0-9.]+)s$|", $tree->attrs['end']->val, $va)
) {
return array('type'=>'fadeIn', 'val'=>$va[1]);
}
if ($tree->attrs['attributeName']->val == 'soundLevel' &&
$tree->attrs['from']->val == '100%' &&
$tree->attrs['to']->val == '0%' &&
$tree->attrs['calcMode']->val == 'linear' &&
$tree->attrs['fill']->val == 'freeze' &&
preg_match("|^([0-9.]+)s$|", $tree->attrs['begin']->val, $vaBegin) &&
preg_match("|^([0-9.]+)s$|", $tree->attrs['end']->val, $vaEnd)
) {
return array('type'=>'fadeOut', 'val'=>($vaEnd[1] - $vaBegin[1]));
}
return PEAR::raiseError(
"M3uPlaylistAnimateElement::convert2lspl: animate parameters too general"
);
}
}
?>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,485 @@
<?php
/**
* Preference storage class.
*
* @author $Author$
* @version $Revision$
* @package Campcaster
* @subpackage StorageServer
* @see StoredFile
*/
/* ================== Prefs ================== */
class Prefs {
/**
* Constructor
*
* @param GreenBox $gb
* GreenBox object reference
*/
function Prefs(&$gb)
{
$this->gb =& $gb;
$this->dbc =& $gb->dbc;
$this->prefTable = $gb->config['tblNamePrefix'].'pref';
}
/* ======================================================= public methods */
/* ----------------------------------------------------- user preferences */
/**
* Read preference record by session id
*
* @param string $sessid
* session id
* @param string $key
* preference key
* @return string
* preference value
*/
function loadPref($sessid, $key)
{
$subjid = $this->gb->getSessUserId($sessid);
if (PEAR::isError($subjid)) {
return $subjid;
}
if (is_null($subjid)) {
return PEAR::raiseError("Prefs::loadPref: invalid session id",
GBERR_SESS);
}
$val = $this->readVal($subjid, $key);
if (PEAR::isError($val)) {
return $val;
}
if ($val === FALSE) {
return PEAR::raiseError("Prefs::loadPref: invalid preference key",
GBERR_PREF);
}
return $val;
}
/**
* Save preference record by session id
*
* @param string $sessid
* session id
* @param string $key
* preference key
* @param string $value
* preference value
* @return boolean
*/
function savePref($sessid, $key, $value)
{
$subjid = $this->gb->getSessUserId($sessid);
if (PEAR::isError($subjid)) {
return $subjid;
}
if (is_null($subjid)) {
return PEAR::raiseError("Prefs::savePref: invalid session id",
GBERR_SESS);
}
$r = $this->update($subjid, $key, $value);
if (PEAR::isError($r)) {
return $r;
}
if ($r === FALSE) {
$r = $this->insert($subjid, $key, $value);
if (PEAR::isError($r)) {
return $r;
}
}
return TRUE;
}
/**
* Delete preference record by session id
*
* @param string $sessid
* session id
* @param string $key
* preference key
* @return boolean
*/
function delPref($sessid, $key)
{
$subjid = $this->gb->getSessUserId($sessid);
if (PEAR::isError($subjid)) {
return $subjid;
}
if (is_null($subjid)) {
return PEAR::raiseError("Prefs::delPref: invalid session id",
GBERR_SESS);
}
$r = $this->delete($subjid, $key);
if (PEAR::isError($r)) {
return $r;
}
if ($r === FALSE) {
return PEAR::raiseError("Prefs::delPref: invalid preference key",
GBERR_PREF);
}
return TRUE;
}
/* ---------------------------------------------------- group preferences */
/**
* Read group preference record
*
* @param string $sessid
* session id
* @param string $group
* group name
* @param string $key
* preference key
* @return string
* preference value
*/
function loadGroupPref($sessid, $group, $key)
{
// if sessid is would be used here fix Transport::cronCallMethod !
$subjid = $this->gb->getSubjId($group);
if (PEAR::isError($subjid)) {
return $subjid;
}
if (is_null($subjid)) {
return PEAR::raiseError(
"Prefs::loadGroupPref: invalid group name", ALIBERR_NOTGR);
}
$val = $this->readVal($subjid, $key);
if (PEAR::isError($val)) {
return $val;
}
if ($val === FALSE) {
return PEAR::raiseError(
"Prefs::loadGroupPref: invalid preference key", GBERR_PREF);
}
return $val;
}
/**
* Save group preference record
*
* @param string $sessid
* session id
* @param string $group
* group name
* @param string $key
* preference key
* @param string $value
* preference value
* @return boolean
*/
function saveGroupPref($sessid, $group, $key, $value)
{
$uid = $this->gb->getSessUserId($sessid);
if (PEAR::isError($uid)) {
return $uid;
}
if (is_null($uid)) {
return PEAR::raiseError(
"Prefs::saveGroupPref: invalid session id", GBERR_SESS);
}
$gid = $this->gb->getSubjId($group);
if (PEAR::isError($gid)) {
return $gid;
}
if (is_null($gid)) {
return PEAR::raiseError(
"Prefs::saveGroupPref: invalid group name", GBERR_SESS);
}
$memb = $this->gb->isMemberOf($uid, $gid);
if (PEAR::isError($memb)) {
return $memb;
}
if (!$memb) {
return PEAR::raiseError(
"Prefs::saveGroupPref: access denied", GBERR_DENY);
}
$r = $this->update($gid, $key, $value);
if (PEAR::isError($r)) {
return $r;
}
if ($r === FALSE) {
$r = $this->insert($gid, $key, $value);
if (PEAR::isError($r)) {
return $r;
}
}
return TRUE;
}
/**
* Delete group preference record
*
* @param string $sessid
* session id
* @param string $group
* group name
* @param string $key
* preference key
* @return boolean
*/
function delGroupPref($sessid, $group, $key)
{
$uid = $this->gb->getSessUserId($sessid);
if (PEAR::isError($uid)) {
return $uid;
}
if (is_null($uid)) {
return PEAR::raiseError(
"Prefs::delGroupPref: invalid session id", GBERR_SESS);
}
$gid = $this->gb->getSubjId($group);
if (PEAR::isError($gid)) {
return $gid;
}
if (is_null($gid)) {
return PEAR::raiseError(
"Prefs::delGroupPref: invalid group name", GBERR_SESS);
}
$memb = $this->gb->isMemberOf($uid, $gid);
if (PEAR::isError($memb)) {
return $memb;
}
if (!$memb) {
return PEAR::raiseError(
"Prefs::delGroupPref: access denied", GBERR_DENY);
}
$r = $this->delete($gid, $key);
if (PEAR::isError($r)) {
return $r;
}
if ($r === FALSE) {
return PEAR::raiseError(
"Prefs::delGroupPref: invalid preference key", GBERR_PREF);
}
return TRUE;
}
/* ==================================================== low level methods */
/**
* Insert of new preference record
*
* @param int $subjid
* local user/group id
* @param string $keystr
* preference key
* @param string $valstr
* preference value
* @return int
* local user id
*/
function insert($subjid, $keystr, $valstr='')
{
$id = $this->dbc->nextId("{$this->prefTable}_id_seq");
if (PEAR::isError($id)) {
return $id;
}
$r = $this->dbc->query("
INSERT INTO {$this->prefTable}
(id, subjid, keystr, valstr)
VALUES
($id, $subjid, '$keystr', '$valstr')
");
if (PEAR::isError($r)) {
return $r;
}
return $id;
}
/**
* Read value of preference record
*
* @param int $subjid
* local user/group id
* @param string $keystr
* preference key
* @return string
* preference value
*/
function readVal($subjid, $keystr)
{
$val = $this->dbc->getOne("
SELECT valstr FROM {$this->prefTable}
WHERE subjid=$subjid AND keystr='$keystr'
");
if (PEAR::isError($val)) {
return $val;
}
if (is_null($val)) {
return FALSE;
}
return $val;
}
/**
* Read all keys of subject's preferences
*
* @param int $subjid
* local user/group id
* @return array
* preference keys
*/
function readKeys($subjid)
{
$res = $this->dbc->getAll("
SELECT keystr FROM {$this->prefTable}
WHERE subjid=$subjid
");
if (PEAR::isError($res)) {
return $res;
}
if (is_null($res)) {
return FALSE;
}
return $res;
}
/**
* Update value of preference record
*
* @param int $subjid
* local user/group id
* @param string $keystr
* preference key
* @param string $newvalstr
* new preference value
* @return boolean
*/
function update($subjid, $keystr, $newvalstr='')
{
$r = $this->dbc->query("
UPDATE {$this->prefTable} SET
valstr='$newvalstr'
WHERE subjid=$subjid AND keystr='$keystr'
");
if (PEAR::isError($r)) {
return $r;
}
if ($this->dbc->affectedRows() < 1) {
return FALSE;
}
return TRUE;
}
/**
* Delete preference record
*
* @param int $subjid
* local user/group id
* @param string $keystr
* preference key
* @return boolean
*/
function delete($subjid, $keystr)
{
$r = $this->dbc->query("
DELETE FROM {$this->prefTable}
WHERE subjid=$subjid AND keystr='$keystr'
");
if (PEAR::isError($r)) {
return $r;
}
if ($this->dbc->affectedRows() < 1) {
return FALSE;
}
return TRUE;
}
/* ==================================================== auxiliary methods */
/**
* Test method
*
*/
function test()
{
$sessid = $this->gb->login('root', $this->gb->config['tmpRootPass']);
$testkey = 'testKey';
$testVal = 'abcDef 0123 ěščřžýáíé ĚŠČŘŽÝÁÍÉ';
$r = savePref($sessid, $testKey, $testVal);
if (PEAR::isError($r)) {
return $r;
}
$val = loadPref($sessid, $testKey);
if ($val != $testVal) {
echo "ERROR: preference storage test failed.\n ($testVal / $val)\n";
return FALSE;
}
$r = savePref($sessid, $testKey, '');
if (PEAR::isError($r)) {
return $r;
}
$val = loadPref($sessid, $testKey);
if ($val != $testVal) {
echo "ERROR: preference storage test failed.\n ('' / '$val')\n";
return FALSE;
}
return TRUE;
}
/**
* Install database table for preference storage
*
* @return boolean
*/
function install()
{
$this->dbc->createSequence("{$this->prefTable}_id_seq");
$r = $this->dbc->query("CREATE TABLE {$this->prefTable} (
id int not null,
subjid int REFERENCES {$this->gb->subjTable} ON DELETE CASCADE,
keystr varchar(255),
valstr text
)");
if (PEAR::isError($r)) {
return $r;
}
$this->dbc->query("CREATE UNIQUE INDEX {$this->prefTable}_id_idx
ON {$this->prefTable} (id)");
$this->dbc->query("CREATE UNIQUE INDEX {$this->prefTable}_subj_key_idx
ON {$this->prefTable} (subjid, keystr)");
$this->dbc->query("CREATE INDEX {$this->prefTable}_subjid_idx
ON {$this->prefTable} (subjid)");
$stPrefGr = $this->gb->getSubjId($this->gb->config['StationPrefsGr']);
if (PEAR::isError($stPrefGr)) {
echo $stPrefGr->getMessage()."\n";
}
$r = $this->insert($stPrefGr, 'stationName', "Radio Station 1");
if (PEAR::isError($r)) {
echo $r->getMessage()."\n";
}
$genres = file_get_contents( dirname(__FILE__).'/genres.xml');
$r = $this->insert($stPrefGr, 'genres', $genres);
if (PEAR::isError($r)) {
echo $r->getMessage()."\n";
}
return TRUE;
}
/**
* Uninstall database table for preference storage
*
* @return boolean
*/
function uninstall()
{
$this->dbc->query("DROP TABLE {$this->prefTable}");
$this->dbc->dropSequence("{$this->prefTable}_id_seq");
}
} // class Prefs
?>

View file

@ -0,0 +1,240 @@
<?php
/**
* RawMediaData class
*
* File storage support class
* Store media files in real filesystem and handle access to them.<br>
*
* @author $Author$
* @version $Revision$
* @package Campcaster
* @subpackage StorageServer
* @see StoredFile
*/
class RawMediaData{
/**
* Constructor
*
* @param string $gunid
* global unique id
* @param string $resDir
* resource directory
*/
function RawMediaData($gunid, $resDir)
{
$this->gunid = $gunid;
$this->resDir = $resDir;
$this->fname = $this->makeFname();
$this->exists =
is_file($this->fname) &&
is_readable($this->fname)
;
}
/**
* Insert media file to filesystem
*
* @param string $mediaFileLP
* local path
* @return mixed
* true or PEAR::error
*/
function insert($mediaFileLP)
{
if ($this->exists) {
return FALSE;
}
// for files downloaded from archive:
if ($mediaFileLP == $this->fname) {
$this->exists = TRUE;
return TRUE;
}
umask(0002);
if (@copy($mediaFileLP, $this->fname)) {
$this->exists = TRUE;
return TRUE;
} else {
//@unlink($this->fname); // maybe useless
$this->exists = FALSE;
return PEAR::raiseError(
"RawMediaData::insert: file save failed".
" ($mediaFileLP, {$this->fname})",GBERR_FILEIO
);
}
}
/**
* Delete and insert media file
*
* @param string $mediaFileLP, local path
* @return mixed
* true or PEAR::error
*/
function replace($mediaFileLP)
{
if ($this->exists) {
$r = $this->delete();
} else {
$r = NULL;
}
if (PEAR::isError($r)) {
return $r;
}
return $this->insert($mediaFileLP);
}
/**
* Return true if file corresponding to the object exists
*
* @return boolean
*/
function exists()
{
return $this->exists;
}
/**
* Return filename
*
* @return string
*/
function getFname()
{
return $this->fname;
}
/**
* Delete media file from filesystem
*
* @return mixed
* boolean or PEAR::error
*/
function delete()
{
if (!$this->exists) {
return FALSE;
}
if (@unlink($this->fname)) {
$this->exists = FALSE;
return TRUE;
} else {
return PEAR::raiseError(
"RawMediaData::delete: unlink failed ({$this->fname})",
GBERR_FILEIO
);
}
return $this->exists;
}
/**
* Analyze media file with getid3 module
*
* @return array
* hierarchical hasharray with information about media file
*/
function analyze()
{
if (!$this->exists) {
return FALSE;
}
//$ia = @GetAllFileinfo($this->fname, 'mp3');
//prepared for getid3 upgrade:
$getID3 = new getID3;
$ia = $getID3->analyze($this->fname);
return $ia;
}
/**
* Get mime-type returned by getid3 module
*
* @return string
*/
function getMime()
{
$a = $this->analyze();
if ($a === FALSE) {
return $a;
}
if (isset($a['mime_type'])) {
return $a['mime_type'];
}
return '';
}
/**
* Contruct filepath of media file
*
* @return string
*/
function makeFname()
{
return "{$this->resDir}/{$this->gunid}";
}
/**
* Test method
*
* @param string $testFname1
* @param string $testFname2
* @param string $accLinkFname
* @return string
*/
function test($testFname1, $testFname2, $accLinkFname)
{
$log = '';
if ($this->exists()) {
$log .= "---: exists: YES\n";
} else {
$log .= "---: exists: NO\n";
}
if (!($r = $this->delete())) {
$log .= "---: delete: nothing to delete\n";
}
if (PEAR::isError($r)) {
$log .= "ERR: ".$r->getMessage()."\n";
}
if ($r = $this->insert($testFname1)) {
$log .= "---: insert: already exists\n";
}
if (PEAR::isError($r)) {
$log .= "ERR: ".$r->getMessage()."\n";
}
if ($r = $this->replace($testFname2)) {
$log .= "---: replace: already exists\n";
}
if (PEAR::isError($r)) {
$log .= "ERR: ".$r->getMessage()."\n";
}
if ($this->exists()) {
$log .= "---: exists: YES\n";
} else {
$log .= "---: exists: NO\n";
}
if (!$this->access($accLinkFname)) {
$log .= "---: access: not exists\n";
}
if (($ft = filetype($accLinkFname)) == 'link') {
if (($rl = readlink($accLinkFname)) != $this->fname) {
$log .= "ERR: wrong target ($rl)\n";
}
} else {
$log .= "ERR: wrong file type ($ft)\n";
}
if (!$this->release($accLinkFname)) {
$log .= "---: access: not exists\n";
}
return $log;
}
} // class RawMediaData
?>

View file

@ -0,0 +1,297 @@
<?php
define('RENDER_EXT', 'ogg');
require_once "LsPlaylist.php";
/**
* Renderer caller class
*
* Playlist to file rendering - PHP layer, caller to the renderer executable
*
* @author $Author: tomash $
* @version $Revision: 1949 $
* @package Campcaster
* @subpackage StorageServer
* @see LocStor
*/
class Renderer
{
/**
* Render playlist to ogg file (open handle)
*
* @param GreenBox $gb
* greenbox object reference
* @param string $plid
* playlist gunid
* @param int $owner
* local subject id, owner of token
* @return array
* token: string - render token
*/
function rnRender2FileOpen(&$gb, $plid, $owner=NULL)
{
// recall playlist:
$pl = $r = LsPlaylist::recallByGunid($gb, $plid);
if (PEAR::isError($r)) {
return $r;
}
// smil export:
$smil = $r = $pl->output2Smil();
if (PEAR::isError($r)) {
return $r;
}
// temporary file for smil:
$tmpn = tempnam($gb->bufferDir, 'plRender_');
$smilf = "$tmpn.smil";
file_put_contents($smilf, $smil);
$url = "file://$smilf";
// output file:
$outf = "$tmpn.".RENDER_EXT;
touch($outf);
// logging:
$logf = "{$gb->bufferDir}/renderer.log";
file_put_contents($logf, "--- ".date("Ymd-H:i:s")."\n", FILE_APPEND);
// open access to output file: /*gunid*/ /*parent*/
$acc = $gb->bsAccess($outf, RENDER_EXT, $plid, 'render', 0, $owner);
if ($gb->dbc->isError($acc)) {
return $acc;
}
extract($acc);
$statf = Renderer::getStatusFile($gb, $token);
file_put_contents($statf, "working");
// command:
$stServDir = dirname(__FILE__)."/..";
$renderExe = "$stServDir/bin/renderer.sh";
$command = "$renderExe -p $url -o $outf -s $statf >> $logf &";
file_put_contents($logf, "$command\n", FILE_APPEND);
$res = system($command);
if ($res === FALSE) {
return PEAR::raiseError(
'Renderer::rnRender2File: Error running renderer'
);
}
return array('token'=>$token);
}
/**
* Render playlist to ogg file (check results)
*
* @param GreenBox $gb
* GreenBox object reference
* @param string $token
* render token
* @return array
* status : string - success | working | fault
* url : string - readable url
*/
function rnRender2FileCheck(&$gb, $token)
{
$statf = Renderer::getStatusFile($gb, $token);
if (!file_exists($statf)) {
return PEAR::raiseError(
'Renderer::rnRender2FileCheck: Invalid token'
);
}
$status = trim(file_get_contents($statf));
$url = Renderer::getUrl($gb, $token);
$tmpfile= Renderer::getLocalFile($gb, $token);
return array('status'=>$status, 'url'=>$url, 'tmpfile'=>$tmpfile);
}
/**
* Render playlist to ogg file (list results)
*
* @param GreenBox $gb
* greenbox object reference
* @param string $stat
* status (optional) if this parameter is not set, then return with all unclosed backups
* @return array
* array of hasharray:
* status : string - success | working | fault
* url : string - readable url
*/
function rnRender2FileList(&$gb,$stat='') {
# open temporary dir
$tokens = $gb->getTokensByType('render');
foreach ($tokens as $token) {
$st = Renderer::rnRender2FileCheck($gb, $token);
if ( ($stat=='') || ($st['status']==$stat) ) {
$r[] = $st;
}
}
return $r;
}
/**
* Render playlist to ogg file (close handle)
*
* @param GreenBox $gb
* greenbox object reference
* @param string $token
* render token
* @return mixed
* TRUE or PEAR_Error
*/
function rnRender2FileClose(&$gb, $token)
{
$r = $gb->bsRelease($token, 'render');
if (PEAR::isError($r)) {
return $r;
}
$realOgg = $r['realFname'];
$tmpn = "{$gb->bufferDir}/".basename($realOgg, '.'.RENDER_EXT);
$smilf = "$tmpn.smil";
$statf = Renderer::getStatusFile($gb, $token);
@unlink($statf);
@unlink($realOgg);
@unlink($smilf);
@unlink($tmpn);
return TRUE;
}
/**
* Render playlist to storage as audioClip (check results)
*
* @param GreenBox $gb
* greenbox object reference
* @param string $token
* render token
* @return array
* status : string - success | working | fault
* gunid: string - global unique id of result file
*/
function rnRender2StorageCheck(&$gb, $token)
{
$r = Renderer::rnRender2FileCheck($gb, $token);
if (PEAR::isError($r)) {
return $r;
}
$status = $r['status'];
$res = array('status' => $status, 'gunid'=>'NULL');
switch ($status) {
case "fault":
$res['faultString'] = "Error runing renderer";
break;
case "success":
$r = Renderer::rnRender2StorageCore($gb, $token);
if (PEAR::isError($r)) {
return $r;
}
$res['gunid'] = $r['gunid'];
break;
default:
break;
}
return $res;
}
/**
* Render playlist to storage as audioClip (core method)
*
* @param GreenBox $gb
* greenbox object reference
* @param string $token
* render token
* @return array:
* gunid: string - global unique id of result file
*/
function rnRender2StorageCore(&$gb, $token)
{
$r = $gb->bsRelease($token, 'render');
if (PEAR::isError($r)) {
return $r;
}
$realOgg = $r['realFname'];
$owner = $r['owner'];
$gunid = $r['gunid'];
if (PEAR::isError($r)) {
return $r;
}
$parid = $r = $gb->_getHomeDirId($owner);
if (PEAR::isError($r)) return $r;
$fileName = 'rendered_playlist';
$id = $r = $gb->_idFromGunid($gunid);
if (PEAR::isError($r)) {
return $r;
}
$mdata = '';
foreach (array(
'dc:title', 'dcterms:extent', 'dc:creator', 'dc:description'
) as $item) {
$md = $r = $gb->bsGetMetadataValue($id, $item);
if (PEAR::isError($r)) {
return $r;
}
$val = ( isset($md[0]) ? ( isset($md[0]['value']) ? $md[0]['value'] : '') : '');
$mdata .= " <$item>$val</$item>\n";
}
$mdata = "<audioClip>\n <metadata>\n$mdata </metadata>\n</audioClip>\n";
//$mdata = "<audioClip>\n <metadata>\n$mdata<dcterms:extent>0</dcterms:extent>\n</metadata>\n</audioClip>\n";
$id = $r = $gb->bsPutFile($parid, $fileName, $realOgg, $mdata,
NULL, 'audioclip', 'string');
if (PEAR::isError($r)) {
return $r;
}
$ac = $r = StoredFile::recall($gb, $id);
if (PEAR::isError($r)) {
return $r;
}
return array('gunid' => $ac->gunid);
}
/**
* Return local filepath of rendered file
*
* @param Greenbox $gb
* greenbox object reference
* @param string $token
* render token
* @return array
*/
function getLocalFile(&$gb, $token)
{
$token = StoredFile::_normalizeGunid($token);
return "{$gb->accessDir}/$token.".RENDER_EXT;
}
/**
* Return filepath of render status file
*
* @param GreenBox $gb
* greenbox object reference
* @param string $token
* render token
* @return array
*/
function getStatusFile(&$gb, $token)
{
return Renderer::getLocalFile($gb, $token).".status";
}
/**
* Return remote accessible URL for rendered file
*
* @param GreenBox $gb
* greenbox object reference
* @param string $token
* render token
* @return array
*/
function getUrl(&$gb, $token)
{
$token = StoredFile::_normalizeGunid($token);
return $gb->getUrlPart()."access/$token.".RENDER_EXT;
}
} // class Renderer
?>

View file

@ -0,0 +1,414 @@
<?php
define('ACCESS_TYPE', 'restore');
/**
* @author $Author: $
* @version $Revision: $
* @package Campcaster
* @subpackage StorageServer
*/
class Restore {
/**
* string - name of logfile
*/
var $logFile;
/**
* string - session id
*/
var $sessid;
/**
* string - token
*/
var $token;
/**
* string - name of statusfile
*/
var $statusFile;
/**
* string - name of temporary directory, to here extract the backup tarball
*/
var $tmpDir;
/**
* string - loglevel
*/
var $loglevel = 'warn';
#var $loglevel = 'debug';
/**
* greenbox object reference
*/
var $gb;
/**
* Constructor
*
* @param GreenBox $gb
* greenbox object reference
*/
function Restore (&$gb) {
$this->gb =& $gb;
$this->token = null;
$this->logFile = $this->gb->bufferDir.'/'.ACCESS_TYPE.'.log';
if ($this->loglevel == 'debug') {
$this->addLogItem("-I- ".date("Ymd-H:i:s")." construct\n");
}
}
/**
* Call asyncronously the restore procedure. Restore from backup.
*
* @param string $sessid
* session id
* @param string $backup_file
* path of the backup file
* @return array
* hasharray with field:
* token string: backup token
*/
function openRestore($sessid, $backup_file) {
if ($this->loglevel=='debug') {
$this->addLogItem("-I-".date("Ymd-H:i:s")." doRestore - sessid:$sessid\n");
}
$this->sessid = $sessid;
//generate token
$this->token = StoredFile::_createGunid();
// status file -> working
$this->setEnviroment();
file_put_contents($this->statusFile, 'working');
//call the restore script in background
$command = dirname(__FILE__).'/../bin/restore.php';
$runLog = "/dev/null";
$params = "{$backup_file} {$this->statusFile} {$this->token} {$sessid}>> $runLog &";
system("$command $params");
return array('token'=>$this->token);
}
/**
* Check the status of restore
*
* @param string $token
* @return array
* hasharray with field:
* status : string - susccess | working | fault
* faultString : string - description of fault
* token : stirng - backup token
* url : string - access url
* tmpfile : string - access filename
*/
function checkRestore($token) {
if ($this->loglevel == 'debug') {
$this->addLogItem("-I- ".date("Ymd-H:i:s")." checkBackup - token:$token\n");
}
$this->token = $token;
$this->setEnviroment();
if (is_file($this->statusFile)) {
$stat = file_get_contents($this->statusFile);
if (strpos($stat,'fault|') !== false) {
list($stat,$message) = explode('|',$stat);
}
$r['status'] = $stat;
if ($stat=='fault') {
$r['faultString'] = $message;
}
$r['token'] = $token;
return $r;
} else {
return PEAR::raiseError('Restore::checkRestore: invalid token!');
}
}
/**
* Check the status of restore.
*
* @param string $token
* @return array
* hasharray with field:
* status : boolean - is susccess
*/
function closeRestore($token) {
if ($this->loglevel=='debug') {
$this->addLogItem("-I- ".date("Ymd-H:i:s")." checkBackup - token:$token\n");
}
$this->token = $token;
$this->setEnviroment();
$this->rRmDir($this->tmpDir);
unlink($this->statusFile);
return !is_file($this->statusFile);
}
/**
* Do restore in background
*
* this function is called from the asyncron commandline script
* ../bin/restore.php
*
* @param string $backupfile
* path of backupfile
* @param string $token
* restore token
* @param string $sessid
* session id
*/
function startRestore($backupfile, $token, $sessid) {
if ($this->loglevel=='debug') {
$this->addLogItem("-I- ".date("Ymd-H:i:s")." startRestore - bufile:$backupfile | token:$token\n");
}
$this->token = $token;
$this->sessid = $sessid;
$this->setEnviroment();
// extract tarball
$command = 'tar -xf '.$backupfile.' --directory '.$this->tmpDir;
$res = system($command);
#$this->addLogItem('command: '.$command."\n");
#$this->addLogItem('res: '.$res."\n");
//simple check of archive format
if (is_dir($this->tmpDir.'audioClip/') &&
is_dir($this->tmpDir.'meta-inf/') &&
is_dir($this->tmpDir.'playlist/')) {
//search metafiles
$this->metafiles = $this->getMetaFiles();
#$this->addLogItem('metafiles:'.print_r($this->metafiles,true));
//add to storage server
foreach ($this->metafiles as $info) {
$r = $this->addFileToStorage($info['file'],$info['type'],$info['id']);
if (PEAR::isError($r)) {
$this->addLogItem("-E- ".date("Ymd-H:i:s").
" startRestore - addFileToStorage \n".
"(".$put->getMessage()."/".$put->getUserInfo().")\n"
);
file_put_contents($this->statusFile, 'fault|'.$put->getMessage()."/".$put->getUserInfo());
return;
}
}
} else {
$this->addLogItem("-E- ".date("Ymd-H:i:s")." startRestore - invalid archive format\n");
file_put_contents($this->statusFile, 'fault|invalid archive format');
return;
}
file_put_contents($this->statusFile, 'success');
}
/**
* Get the metafiles.
*
* @return array
* array of hasharray with field:
* file : string - metafile path
* type : stirng - audioClip | playlist
* id : string - the backuped gunid
*/
function getMetaFiles() {
if ($this->loglevel=='debug') {
$this->addLogItem("-I- ".date("Ymd-H:i:s")." getMetaFiles - tmpDir:{$this->tmpDir}\n");
}
$audioclips = scandir($this->tmpDir.'audioClip/');
$playlists = scandir($this->tmpDir.'playlist/');
for ($i = 0; $i < count($audioclips); $i++) {
if (strpos($audioclips[$i],'xml')!==false)
$r[] = array('file' => $this->tmpDir.'audioClip/'.$audioclips[$i],
'type' => 'audioClip',
'id' => str_replace('.xml','',$audioclips[$i]));
}
for ($i = 0; $i < count($playlists); $i++) {
if (strpos($playlists[$i],'xml') !== false)
$r[] = array('file' => $this->tmpDir.'playlist/'.$playlists[$i],
'type' => 'playlist',
'id' => str_replace('.xml','',$playlists[$i]));
}
return $r;
}
/**
* Add the file to the storage server.
*
* @param string $file
* path of metafile
* @param string $type
* restore token
* @param string $sessid
* session id
*
* @return mixed
* true if success or PEAR_error
*/
function addFileToStorage($file,$type,$gunid) {
if ($this->loglevel=='debug') {
$this->addLogItem("-I- ".date("Ymd-H:i:s")." addFileToStorage - file:$file | type:$type | id:$gunid\n");
}
require_once "XmlParser.php";
$tree = XmlParser::parse($file);
$mediaFileLP = str_replace('.xml','',$file);
$mediaFileLP = ($type=='audioClip' && is_file($mediaFileLP))?$mediaFileLP:'';
$ex = $r = $this->gb->existsFile($this->sessid,$gunid);
if (PEAR::isError($r)) {
$this->addLogItem("-E- ".date("Ymd-H:i:s").
" addFileToStorage - existsFile($gunid) ".
"(".$r->getMessage()."/".$r->getUserInfo().")\n"
);
}
if (!PEAR::isError($ex) && $ex) { // file is exists in storage server
//replace it
$id = $this->gb->_idFromGunid($gunid);
$replace = $this->gb->replaceFile(
$id, # id int, virt.file's local id
$mediaFileLP, # mediaFileLP string, local path of media file
$file, # mdataFileLP string, local path of metadata file
$this->sessid); # sessid string, session id
if (PEAR::isError($replace)) {
$this->addLogItem("-E- ".date("Ymd-H:i:s").
" addFileToStorage - replaceFile Error ".
"(".$replace->getMessage()."/".$replace->getUserInfo().")\n"
);
file_put_contents($this->statusFile, 'fault|'.$replace->getMessage()."/".$replace->getUserInfo());
return $replace;
}
#$this->addLogItem("replace it \n");
} else {
// add as new
$parid = $this->gb->_getHomeDirIdFromSess($this->sessid);
#$this->addLogItem("Parid:$parid\n");
$name = $tree->children[0]->children[0]->content;
if (empty($name)) {
$name = $tree->attrs['title']->val;
}
if (empty($name)) {
$name = '???';
}
if ($this->loglevel=='debug') {
$this->addLogItem("-I- ".date("Ymd-H:i:s")." putFile\n".
"$parid, $name, $mediaFileLP, $file, {$this->sessid}, $gunid, $type \n"
);
}
$put = $this->gb->putFile(
$parid, # parent id
$name, # name of original file
$mediaFileLP, # media file if have
$file, # meta file
$this->sessid, # sessid
$gunid, # gunid
$type # type
);
# $this->addLogItem("add as new \n");
if (PEAR::isError($put)) {
$this->addLogItem("-E- ".date("Ymd-H:i:s").
" addFileToStorage - putFile Error ".
"(".$put->getMessage()."/".$put->getUserInfo().")\n"
."\n---\n".file_get_contents($file)."\n---\n"
);
file_put_contents($this->statusFile, 'fault|'.$put->getMessage()."/".$put->getUserInfo());
//$this->addLogItem("Error Object: ".print_r($put,true)."\n");
return $put;
}
}
$ac = $r = StoredFile::recallByGunid($this->gb, $gunid);
if (PEAR::isError($r)) {
return $r;
}
$res = $r = $ac->setState('ready');
if (PEAR::isError($r)) {
return $r;
}
return true;
}
/**
* Figure out the environment to the backup.
*
*/
function setEnviroment() {
if ($this->loglevel=='debug') {
$this->addLogItem("-I- ".date("Ymd-H:i:s")." setEnviroment\n");
}
$this->statusFile = $this->gb->accessDir.'/'.$this->token.'.status';
$this->tmpDir = '/tmp/ls_restore/'.$this->token.'/';
$this->rMkDir($this->tmpDir);
}
/**
* Add a line to the logfile.
*
* @param string $item
* the new row of log file
*/
function addLogItem($item) {
$f = fopen ($this->logFile,'a');
flock($f,LOCK_SH);
fwrite($f,$item);
flock($f,LOCK_UN);
fclose($f);
//echo file_get_contents($this->logFile)."<BR><BR>\n\n";
}
/**
* Delete a directory recursive
*
* @param string $dirname
* path of dir
*
* @return boolean
* is success
*/
function rRmDir($dirname) {
if (is_dir($dirname)) {
$dir_handle = opendir($dirname);
}
while ($file = readdir($dir_handle)) {
if ($file!="." && $file!="..") {
if (!is_dir($dirname."/".$file)) {
unlink ($dirname."/".$file);
} else {
Restore::rRmDir($dirname."/".$file);
}
}
}
closedir($dir_handle);
rmdir($dirname);
return true;
}
/**
* Create a directory recursive
*
* @param string $dirname
* path of dir.
* @param int $mode
* octal - rights of dir.
* @param boolean $recursive
* do it recursive.
*
* @return boolean
*/
function rMkDir($dirname,$mode=0777,$recursive=true) {
if (is_null($dirname) || $dirname === "" ) {
return false;
}
if (is_dir($dirname) || $dirname === "/" ) {
return true;
}
if ($this->rMkDir(dirname($dirname), $mode, $recursive)) {
return mkdir($dirname, $mode);
}
return false;
}
} // class Restore
?>

View file

@ -0,0 +1,315 @@
<?
define('INDCH', ' ');
require_once "XmlParser.php";
/**
* SmilPlaylist class
*
* @author $Author: tomash $
* @version $Revision: 1848 $
* @package Campcaster
* @subpackage StorageServer
*/
class SmilPlaylist {
/**
* Parse SMIL file or string
*
* @param string $data
* local path to SMIL file or SMIL string
* @param string $loc
* location: 'file'|'string'
* @return array
* reference, parse result tree (or PEAR::error)
*/
function &parse($data='', $loc='file')
{
return XmlParser::parse($data, $loc);
}
/**
* Import SMIL file to storage
*
* @param GreenBox $gb
* reference to GreenBox object
* @param string $aPath
* absolute path part of imported file (e.g. /home/user/campcaster)
* @param string $rPath
* relative path/filename part of imported file
* (e.g. playlists/playlist_1.smil)
* @param array $gunids
* hash relation from filenames to gunids
* @param string $plid
* playlist gunid
* @param int $parid
* destination folder local id
* @param int $subjid
* local subject (user) id (id of user doing the import)
* @return Playlist
*/
function &import(&$gb, $aPath, $rPath, &$gunids, $plid, $parid, $subjid=NULL)
{
$parr = compact('parid', 'subjid', 'aPath', 'plid', 'rPath');
$path = realpath("$aPath/$rPath");
if (FALSE === $path) {
return PEAR::raiseError(
"SmilPlaylist::import: file doesn't exist ($aPath/$rPath)"
);
}
$lspl = $r = SmilPlaylist::convert2lspl(
$gb, $path, $gunids, $parr);
if (PEAR::isError($r)) {
return $r;
}
require_once "Playlist.php";
$pl =& Playlist::create($gb, $plid, "imported_SMIL", $parid);
if (PEAR::isError($pl)) {
return $pl;
}
$r = $pl->lock($gb, $subjid);
if (PEAR::isError($r)) {
return $r;
}
$r = $pl->replaceMetaData($lspl, 'string', 'playlist');
if (PEAR::isError($r)) {
return $r;
}
$r = $pl->unLock($gb);
if (PEAR::isError($r)) {
return $r;
}
return $pl;
}
/**
* Import SMIL file to storage
*
* @param GreenBox $gb
* @param string $data
* local path to SMIL file
* @param hasharray $gunids
* hash relation from filenames to gunids
* @param array $parr
* array of parid, subjid, aPath, plid, rPath
* @return string
* XML of playlist in Campcaster playlist format
*/
function convert2lspl(&$gb, $data, &$gunids, $parr)
{
extract($parr);
$tree = $r = SmilPlaylist::parse($data);
if (PEAR::isError($r)) {
return $r;
}
if ($tree->name != 'smil') {
return PEAR::raiseError("SmilPlaylist::parse: smil tag expected");
}
if (isset($tree->children[1])) {
return PEAR::raiseError(sprintf(
"SmilPlaylist::parse: unexpected tag %s in tag smil",
$tree->children[1]->name
));
}
$res = SmilPlaylistBodyElement::convert2lspl(
$gb, $tree->children[0], &$gunids, $parr);
return $res;
}
} // SmilPlaylist
/**
* @author $Author$
* @version $Revision$
* @package Campcaster
* @subpackage StorageServer
*/
class SmilPlaylistBodyElement {
function convert2lspl(&$gb, &$tree, &$gunids, $parr, $ind='')
{
extract($parr);
$ind2 = $ind.INDCH;
if ($tree->name != 'body') {
return PEAR::raiseError("SmilPlaylist::parse: body tag expected");
}
if (isset($tree->children[1])) {
return PEAR::raiseError(sprintf(
"SmilPlaylist::parse: unexpected tag %s in tag body",
$tree->children[1]->name
));
}
$res = $r = SmilPlaylistParElement::convert2lspl(
$gb, $tree->children[0], &$gunids, $parr, $ind2);
if (PEAR::isError($r)) {
return $r;
}
$title = basename($rPath);
$playlength = '0';
$res = "$ind<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n".
"$ind<playlist id=\"$plid\" playlength=\"$playlength\" title=\"$title\">\n".
"$ind2<metadata/>\n".
"$res".
"$ind</playlist>\n";
return $res;
}
} // class SmilPlaylistBodyElement
/**
* @author $Author$
* @version $Revision$
* @package Campcaster
* @subpackage StorageServer
*/
class SmilPlaylistParElement {
function convert2lspl(&$gb, &$tree, &$gunids, $parr, $ind='')
{
extract($parr);
if ($tree->name != 'par') {
return PEAR::raiseError("SmilPlaylist::parse: par tag expected");
}
$res = '';
foreach ($tree->children as $i => $ch) {
$ch =& $tree->children[$i];
$r = SmilPlaylistAudioElement::convert2lspl(
$gb, $ch, &$gunids, $parr, $ind.INDCH);
if (PEAR::isError($r)) {
return $r;
}
$res .= $r;
}
return $res;
}
}
/**
* @author $Author$
* @version $Revision$
* @package Campcaster
* @subpackage StorageServer
*/
class SmilPlaylistAudioElement {
function convert2lspl(&$gb, &$tree, &$gunids, $parr, $ind='')
{
extract($parr);
$uri = $tree->attrs['src']->val;
$gunid = ( isset($gunids[basename($uri)]) ? $gunids[basename($uri)] : NULL);
$ind2 = $ind.INDCH;
if ($tree->name != 'audio') {
return PEAR::raiseError("SmilPlaylist::parse: audio tag expected");
}
if (isset($tree->children[2])) {
return PEAR::raiseError(sprintf(
"SmilPlaylist::parse: unexpected tag %s in tag audio",
$tree->children[2]->name
));
}
$res = ''; $fadeIn = 0; $fadeOut = 0;
foreach ($tree->children as $i => $ch) {
$ch =& $tree->children[$i];
$r = SmilPlaylistAnimateElement::convert2lspl(
$gb, $ch, &$gunids, $parr, $ind2);
if (PEAR::isError($r)) {
return $r;
}
switch ($r['type']) {
case "fadeIn": $fadeIn = $r['val']; break;
case "fadeOut": $fadeOut = $r['val']; break;
}
}
if ($fadeIn > 0 || $fadeOut > 0) {
$fiGunid = StoredFile::_createGunid();
$fadeIn = Playlist::_secsToPlTime($fadeIn);
$fadeOut = Playlist::_secsToPlTime($fadeOut);
$fInfo = "$ind2<fadeInfo id=\"$fiGunid\" fadeIn=\"$fadeIn\" fadeOut=\"$fadeOut\"/>\n";
} else {
$fInfo = '';
}
$plElGunid = StoredFile::_createGunid();
$acGunid = $gunid;
$type = 'audioClip';
if (preg_match("|\.([a-zA-Z0-9]+)$|", $uri, $va)) {
switch (strtolower($ext = $va[1])) {
case "lspl":
case "xml":
case "smil":
case "m3u":
$type = 'playlist';
$acId = $r = $gb->bsImportPlaylistRaw($parid, $gunid,
$aPath, $uri, $ext, $gunids, $subjid);
if (PEAR::isError($r)) {
return $r;
}
//break;
default:
$ac = $r = StoredFile::recallByGunid($gb, $gunid);
if (PEAR::isError($r)) {
return $r;
}
$r = $ac->md->getMetadataEl('dcterms:extent');
if (PEAR::isError($r)) {
return $r;
}
$playlength = $r[0]['value'];
}
}
$title = basename($tree->attrs['src']->val);
$offset = Playlist::_secsToPlTime($tree->attrs['begin']->val);
$res = "$ind<playlistElement id=\"$plElGunid\" relativeOffset=\"$offset\">\n".
"$ind2<$type id=\"$acGunid\" playlength=\"$playlength\" title=\"$title\"/>\n".
$fInfo.
"$ind</playlistElement>\n";
return $res;
}
} // class SmilPlaylistAudioElement
/**
* @author $Author$
* @version $Revision$
* @package Campcaster
* @subpackage StorageServer
*/
class SmilPlaylistAnimateElement {
function convert2lspl(&$gb, &$tree, &$gunids, $parr, $ind='')
{
extract($parr);
if ($tree->name != 'animate') {
return PEAR::raiseError("SmilPlaylist::parse: animate tag expected");
}
if ($tree->attrs['attributeName']->val == 'soundLevel' &&
$tree->attrs['from']->val == '0%' &&
$tree->attrs['to']->val == '100%' &&
$tree->attrs['calcMode']->val == 'linear' &&
$tree->attrs['fill']->val == 'freeze' &&
$tree->attrs['begin']->val == '0s' &&
preg_match("|^([0-9.]+)s$|", $tree->attrs['end']->val, $va)
) {
return array('type'=>'fadeIn', 'val'=>intval($va[1]));
}
if ($tree->attrs['attributeName']->val == 'soundLevel' &&
$tree->attrs['from']->val == '100%' &&
$tree->attrs['to']->val == '0%' &&
$tree->attrs['calcMode']->val == 'linear' &&
$tree->attrs['fill']->val == 'freeze' &&
preg_match("|^([0-9.]+)s$|", $tree->attrs['begin']->val, $vaBegin) &&
preg_match("|^([0-9.]+)s$|", $tree->attrs['end']->val, $vaEnd)
) {
return array('type'=>'fadeOut', 'val'=>($vaEnd[1] - $vaBegin[1]));
}
return PEAR::raiseError(
"SmilPlaylistAnimateElement::convert2lspl: animate parameters too general"
);
}
} // class SmilPlaylistAnimateElement
?>

View file

@ -0,0 +1,872 @@
<?php
require_once "RawMediaData.php";
require_once "MetaData.php";
require_once dirname(__FILE__)."/../../getid3/var/getid3.php";
/**
* StoredFile class
*
* Campcaster file storage support class.<br>
* Represents one virtual file in storage. Virtual file has up to two parts:
* <ul>
* <li>metada in database - represented by MetaData class</li>
* <li>binary media data in real file
* - represented by RawMediaData class</li>
* </ul>
*
* @author $Author$
* @version $Revision$
* @package Campcaster
* @subpackage StorageServer
* @see GreenBox
* @see MetaData
* @see RawMediaData
*/
class StoredFile {
/* ========================================================== constructor */
/**
* Constructor, but shouldn't be externally called
*
* @param GreenBox $gb
* @param string $gunid
* optional, globally unique id of file
* @return this
*/
function StoredFile(&$gb, $gunid=NULL)
{
$this->gb =& $gb;
$this->dbc =& $gb->dbc;
$this->filesTable = $gb->filesTable;
$this->accessTable= $gb->accessTable;
$this->gunid = $gunid;
if (is_null($this->gunid)) {
$this->gunid = $this->_createGunid();
}
$this->resDir = $this->_getResDir($this->gunid);
$this->accessDir = $this->gb->accessDir;
$this->rmd =& new RawMediaData($this->gunid, $this->resDir);
$this->md =& new MetaData($gb, $this->gunid, $this->resDir);
# return $this->gunid;
}
/* ========= 'factory' methods - should be called to construct StoredFile */
/**
* Create instance of StoredFile object and insert new file
*
* @param GreenBox $gb
* @param int $oid
* local object id in the tree
* @param string $name
* name of new file
* @param string $mediaFileLP
* local path to media file
* @param string $metadata
* local path to metadata XML file or XML string
* @param string $mdataLoc
* 'file'|'string' (optional)
* @param global $gunid
* unique id (optional) - for insert file with gunid
* @param string $ftype
* internal file type
* @param string $className
* class to be constructed (opt.)
* @return StoredFile
*/
function &insert(&$gb, $oid, $name,
$mediaFileLP='', $metadata='', $mdataLoc='file',
$gunid=NULL, $ftype=NULL, $className='StoredFile')
{
$name = pg_escape_string($name);
$ftype = pg_escape_string($ftype);
$ac =& new $className($gb, ($gunid ? $gunid : NULL));
if (PEAR::isError($ac)) {
return $ac;
}
$ac->name = $name;
$ac->id = $oid;
$ac->mime = "unKnown";
$emptyState = TRUE;
if ($ac->name=='') {
$ac->name=$ac->gunid;
}
$ac->dbc->query("BEGIN");
$res = $ac->dbc->query("
INSERT INTO {$ac->filesTable}
(id, name, gunid, mime, state, ftype, mtime)
VALUES
('$oid', '{$ac->name}', x'{$ac->gunid}'::bigint,
'{$ac->mime}', 'incomplete', '$ftype', now())
");
if (PEAR::isError($res)) {
$ac->dbc->query("ROLLBACK");
return $res;
}
// --- metadata insert:
if (is_null($metadata) || ($metadata == '') ) {
$metadata = dirname(__FILE__).'/emptyMdata.xml';
$mdataLoc = 'file';
} else {
$emptyState = FALSE;
}
if ( ($mdataLoc == 'file') && !file_exists($metadata)) {
return PEAR::raiseError("StoredFile::insert: ".
"metadata file not found ($metadata)");
}
$res = $ac->md->insert($metadata, $mdataLoc, $ftype);
if (PEAR::isError($res)) {
$ac->dbc->query("ROLLBACK");
return $res;
}
// --- media file insert:
if ($mediaFileLP != '') {
if (!file_exists($mediaFileLP)) {
return PEAR::raiseError("StoredFile::insert: ".
"media file not found ($mediaFileLP)");
}
$res = $ac->rmd->insert($mediaFileLP);
if (PEAR::isError($res)) {
$ac->dbc->query("ROLLBACK");
return $res;
}
$mime = $ac->rmd->getMime();
//$gb->debugLog("gunid={$ac->gunid}, mime=$mime");
if ($mime !== FALSE) {
$res = $ac->setMime($mime);
if (PEAR::isError($res)) {
$ac->dbc->query("ROLLBACK");
return $res;
}
}
$emptyState = FALSE;
}
if (!$emptyState) {
$res = $ac->setState('ready');
if (PEAR::isError($res)) {
$ac->dbc->query("ROLLBACK");
return $res;
}
}
$res = $ac->dbc->query("COMMIT");
if (PEAR::isError($res)) {
$ac->dbc->query("ROLLBACK");
return $res;
}
return $ac;
}
/**
* Create instance of StoreFile object and recall existing file.<br>
* Should be supplied oid XOR gunid - not both ;)
*
* @param GreenBox $gb
* @param int $oid
* optional, local object id in the tree
* @param string $gunid
* optional, global unique id of file
* @param string $className
* optional classname to recall
* @return StoredFile
*/
function &recall(&$gb, $oid='', $gunid='', $className='StoredFile')
{
$cond = ($oid != ''
? "id='".intval($oid)."'"
: "gunid=x'$gunid'::bigint"
);
$row = $gb->dbc->getRow("
SELECT id, to_hex(gunid)as gunid, mime, name, ftype
FROM {$gb->filesTable} WHERE $cond
");
if (PEAR::isError($row)) {
return $row;
}
if (is_null($row)) {
return PEAR::raiseError(
"StoredFile::recall: fileobj not exist ($oid/$gunid)",
GBERR_FOBJNEX
);
}
$gunid = StoredFile::_normalizeGunid($row['gunid']);
$ac =& new $className($gb, $gunid);
$ac->mime = $row['mime'];
$ac->name = $row['name'];
$ac->id = $row['id'];
$ac->md->setFormat($row['ftype']);
return $ac;
}
/**
* Create instance of StoreFile object and recall existing file
* by gunid.
*
* @param GreenBox $gb
* @param string $gunid
* optional, global unique id of file
* @param string $className
* optional classname to recall
* @return StoredFile
*/
function &recallByGunid(&$gb, $gunid='', $className='StoredFile')
{
return StoredFile::recall($gb, '', $gunid, $className);
}
/**
* Create instance of StoreFile object and recall existing file
* by access token.
*
* @param GreenBox $gb
* @param string $token
* access token
* @param string $className
* optional classname to recall
* @return StoredFile
*/
function recallByToken(&$gb, $token, $className='StoredFile')
{
$gunid = $gb->dbc->getOne("
SELECT to_hex(gunid)as gunid
FROM {$gb->accessTable}
WHERE token=x'$token'::bigint
");
if (PEAR::isError($gunid)) {
return $gunid;
}
if (is_null($gunid)) {
return PEAR::raiseError(
"StoredFile::recallByToken: invalid token ($token)", GBERR_AOBJNEX);
}
$gunid = StoredFile::_normalizeGunid($gunid);
return StoredFile::recall($gb, '', $gunid, $className);
}
/**
* Create instance of StoredFile object and make copy of existing file
*
* @param reference $src to source object
* @param int $nid
* new local id
* @return unknown
*/
function &copyOf(&$src, $nid)
{
$ac = StoredFile::insert(
$src->gb, $nid, $src->name, $src->_getRealRADFname(),
'', '', NULL, $src->gb->_getType($src->gunid)
);
if (PEAR::isError($ac)) {
return $ac;
}
$ac->md->replace($src->md->getMetaData(), 'string');
return $ac;
}
/* ======================================================= public methods */
/**
* Replace existing file with new data
*
* @param int $oid
* local id
* @param string $name
* name of file
* @param string $mediaFileLP
* local path to media file
* @param string $metadata
* local path to metadata XML file or XML string
* @param string $mdataLoc
* 'file'|'string'
*/
function replace($oid, $name, $mediaFileLP='', $metadata='',
$mdataLoc='file')
{
$this->dbc->query("BEGIN");
$res = $this->rename($name);
if (PEAR::isError($res)) {
$this->dbc->query("ROLLBACK");
return $res;
}
if ($mediaFileLP != '') { // media
$res = $this->replaceRawMediaData($mediaFileLP);
} else {
$res = $this->rmd->delete();
}
if (PEAR::isError($res)) {
$this->dbc->query("ROLLBACK");
return $res;
}
if ($metadata != '') { // metadata
$res = $this->replaceMetaData($metadata, $mdataLoc);
} else {
$res = $this->md->delete();
}
if (PEAR::isError($res)) {
$this->dbc->query("ROLLBACK");
return $res;
}
$res = $this->dbc->query("COMMIT");
if (PEAR::isError($res)) {
$this->dbc->query("ROLLBACK");
return $res;
}
return TRUE;
}
/**
* Increase access counter, create access token, insert access record,
* call access method of RawMediaData
*
* @param int $parent
* parent token
* @return array
* array with: access URL, access token
*/
function accessRawMediaData($parent='0')
{
$realFname = $this->_getRealRADFname();
$ext = $this->_getExt();
$res = $this->gb->bsAccess($realFname, $ext, $this->gunid, 'access', $parent);
if (PEAR::isError($res)) {
return $res;
}
$resultArray =
array('url'=>"file://{$res['fname']}", 'token'=>$res['token']);
return $resultArray;
}
/**
* Decrease access couter, delete access record,
* call release method of RawMediaData
*
* @param string $token
* access token
* @return boolean
*/
function releaseRawMediaData($token)
{
$res = $this->gb->bsRelease($token);
if (PEAR::isError($res)) {
return $res;
}
return TRUE;
}
/**
* Replace media file only with new binary file
*
* @param string $mediaFileLP
* local path to media file
*/
function replaceRawMediaData($mediaFileLP)
{
$res = $this->rmd->replace($mediaFileLP);
if (PEAR::isError($res)) {
return $res;
}
$mime = $this->rmd->getMime();
if ($mime !== FALSE) {
$res = $this->setMime($mime);
if (PEAR::isError($res)) {
return $res;
}
}
$r = $this->md->regenerateXmlFile();
if (PEAR::isError($r)) {
return $r;
}
}
/**
* Replace metadata with new XML file
*
* @param string $metadata
* local path to metadata XML file or XML string
* @param string $mdataLoc
* 'file'|'string'
* @param string $format
* metadata format for validation
* ('audioclip' | 'playlist' | 'webstream' | NULL)
* (NULL = no validation)
* @return boolean
*/
function replaceMetaData($metadata, $mdataLoc='file', $format=NULL)
{
$this->dbc->query("BEGIN");
$res = $r = $this->md->replace($metadata, $mdataLoc, $format);
if (PEAR::isError($r)) {
$this->dbc->query("ROLLBACK");
return $r;
}
$r = $this->md->regenerateXmlFile();
if (PEAR::isError($r)) {
$this->dbc->query("ROLLBACK");
return $r;
}
$res = $r = $this->dbc->query("COMMIT");
if (PEAR::isError($r)) {
return $r;
}
return TRUE;
}
/**
* Get metadata as XML string
*
* @return XML string
* @see MetaData
*/
function getMetaData()
{
return $this->md->getMetaData();
}
/**
* Analyze file with getid3 module.<br>
* Obtain some metadata stored in media file.<br>
* This method should be used for prefilling metadata input form.
*
* @return array
* @see MetaData
*/
function analyzeMediaFile()
{
$ia = $this->rmd->analyze();
return $ia;
}
/**
* Rename stored virtual file
*
* @param string $newname
* @return mixed
* true or PEAR::error
*/
function rename($newname)
{
$newname = pg_escape_string($newname);
$res = $this->dbc->query("
UPDATE {$this->filesTable} SET name='$newname', mtime=now()
WHERE gunid=x'{$this->gunid}'::bigint
");
if (PEAR::isError($res)) {
return $res;
}
return TRUE;
}
/**
* Set state of virtual file
*
* @param string $state
* 'empty'|'incomplete'|'ready'|'edited'
* @param int $editedby
* user id | 'NULL' for clear editedBy field
* (optional)
* @return boolean or error
*/
function setState($state, $editedby=NULL)
{
$state = pg_escape_string($state);
$eb = (!is_null($editedby) ? ", editedBy=$editedby" : '');
$res = $this->dbc->query("
UPDATE {$this->filesTable}
SET state='$state'$eb, mtime=now()
WHERE gunid=x'{$this->gunid}'::bigint
");
if (PEAR::isError($res)) {
return $res;
}
return TRUE;
}
/**
* Set mime-type of virtual file
*
* @param string $mime
* mime-type
* @return boolean or error
*/
function setMime($mime)
{
$mime = pg_escape_string($mime);
$res = $this->dbc->query("
UPDATE {$this->filesTable} SET mime='$mime', mtime=now()
WHERE gunid=x'{$this->gunid}'::bigint
");
if (PEAR::isError($res)) {
return $res;
}
return TRUE;
}
/**
* Delete stored virtual file
*
* @see RawMediaData
* @see MetaData
*/
function delete()
{
$res = $this->rmd->delete();
if (PEAR::isError($res)) {
return $res;
}
$res = $this->md->delete();
if (PEAR::isError($res)) {
return $res;
}
$tokens = $this->dbc->getAll("
SELECT to_hex(token)as token, ext FROM {$this->accessTable}
WHERE gunid=x'{$this->gunid}'::bigint
");
if (is_array($tokens)) {
foreach($tokens as $i=>$item){
$file = $this->_getAccessFname($item['token'], $item['ext']);
if (file_exists($file)) {
@unlink($file);
}
}
}
$res = $this->dbc->query("
DELETE FROM {$this->accessTable}
WHERE gunid=x'{$this->gunid}'::bigint
");
if (PEAR::isError($res)) {
return $res;
}
$res = $this->dbc->query("
DELETE FROM {$this->filesTable}
WHERE gunid=x'{$this->gunid}'::bigint
");
if (PEAR::isError($res)) {
return $res;
}
return TRUE;
}
/**
* Returns true if virtual file is accessed.<br>
* Static or dynamic call is possible.
*
* @param string $gunid
* optional (for static call), global unique id
*/
function isAccessed($gunid=NULL)
{
if (is_null($gunid)) {
$gunid = $this->gunid;
}
$ca = $this->dbc->getOne("
SELECT currentlyAccessing FROM {$this->filesTable}
WHERE gunid=x'$gunid'::bigint
");
if (is_null($ca)) {
return PEAR::raiseError(
"StoredFile::isAccessed: invalid gunid ($gunid)",
GBERR_FOBJNEX
);
}
return ($ca > 0);
}
/**
* Returns true if virtual file is edited
*
* @param string $playlistId
* playlist global unique ID
* @return boolean
*/
function isEdited($playlistId=NULL)
{
if (is_null($playlistId)) {
$playlistId = $this->gunid;
}
$state = $this->_getState($playlistId);
if ($state != 'edited') {
return FALSE;
}
return TRUE;
}
/**
* Returns id of user editing playlist
*
* @param string $playlistId
* playlist global unique ID
* @return null or int
* id of user editing it
*/
function isEditedBy($playlistId=NULL)
{
if (is_null($playlistId)) {
$playlistId = $this->gunid;
}
$ca = $this->dbc->getOne("
SELECT editedBy FROM {$this->filesTable}
WHERE gunid=x'$playlistId'::bigint
");
if ($this->dbc->isError($ca)) {
return $ca;
}
if (is_null($ca)) {
return $ca;
}
return intval($ca);
}
/**
* Returns local id of virtual file
*
*/
function getId()
{
return $this->id;
}
/**
* Returns true if raw media file exists
*
*/
function exists()
{
$indb = $this->dbc->getRow("
SELECT to_hex(gunid) FROM {$this->filesTable}
WHERE gunid=x'{$this->gunid}'::bigint
");
if (PEAR::isError($indb)) {
return $indb;
}
if (is_null($indb)) {
return FALSE;
}
if ($this->gb->_getType($this->gunid) == 'audioclip') {
return $this->rmd->exists();
}
return TRUE;
}
/* ==================================================== "private" methods */
/**
* Create new global unique id
*
*/
function _createGunid()
{
$ip = (isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : '');
$initString =
microtime().$ip.rand()."org.mdlf.campcaster";
$hash = md5($initString);
// non-negative int8
$hsd = substr($hash, 0, 1);
$res = dechex(hexdec($hsd)>>1).substr($hash, 1, 15);
return StoredFile::_normalizeGunid($res);
}
/**
* Create new global unique id
*
*/
function _normalizeGunid($gunid0)
{
return str_pad($gunid0, 16, "0", STR_PAD_LEFT);
}
/**
* Get local id from global id.
* Static or dynamic call is possible.
*
* @param string $gunid
* optional (for static call), global unique id of file
*/
function _idFromGunid($gunid=NULL)
{
if (is_null($gunid)) {
$gunid = $this->$gunid;
}
$id = $this->dbc->getOne("
SELECT id FROM {$this->filesTable}
WHERE gunid=x'$gunid'::bigint
");
if (is_null($id)) {
return PEAR::raiseError(
"StoredFile::_idFromGunid: no such global unique id ($gunid)"
);
}
return $id;
}
/**
* Return suitable extension.
*
* @todo make it general - is any tool for it?
*
* @return string
* file extension without a dot
*/
function _getExt()
{
$fname = $this->_getFileName();
$pos = strrpos($fname, '.');
if ($pos !== FALSE) {
$ext = substr($fname, $pos+1);
if ($ext !== FALSE) {
return $ext;
}
}
switch (strtolower($this->mime)) {
case "audio/mpeg":
$ext = "mp3";
break;
case "audio/x-wav":
case "audio/x-wave":
$ext = "wav";
break;
case "audio/x-ogg":
case "application/x-ogg":
$ext = "ogg";
break;
default:
$ext = "bin";
break;
}
return $ext;
}
/**
* Get mime-type from global id
*
* @param string $gunid
* optional, global unique id of file
* @return string
* mime-type
*/
function _getMime($gunid=NULL)
{
if (is_null($gunid)) {
$gunid = $this->gunid;
}
return $this->dbc->getOne("
SELECT mime FROM {$this->filesTable}
WHERE gunid=x'$gunid'::bigint
");
}
/**
* Get storage-internal file state
*
* @param string $gunid
* optional, global unique id of file
* @return string
* see install()
*/
function _getState($gunid=NULL)
{
if (is_null($gunid)) {
$gunid = $this->gunid;
}
return $this->dbc->getOne("
SELECT state FROM {$this->filesTable}
WHERE gunid=x'$gunid'::bigint
");
}
/**
* Get mnemonic file name
*
* @param string $gunid
* optional, global unique id of file
* @return string
* see install()
*/
function _getFileName($gunid=NULL)
{
if (is_null($gunid)) {
$gunid = $this->gunid;
}
return $this->dbc->getOne("
SELECT name FROM {$this->filesTable}
WHERE gunid=x'$gunid'::bigint
");
}
/**
* Get and optionaly create subdirectory in real filesystem for storing
* raw media data
*
*/
function _getResDir()
{
$resDir="{$this->gb->storageDir}/".substr($this->gunid, 0, 3);
#$this->gb->debugLog("$resDir");
// see Transport::_getResDir too for resDir name create code
if (!is_dir($resDir)) {
mkdir($resDir, 02775);
chmod($resDir, 02775);
}
return $resDir;
}
/**
* Get real filename of raw media data
*
* @see RawMediaData
*/
function _getRealRADFname()
{
return $this->rmd->getFname();
}
/**
* Get real filename of metadata file
*
* @see MetaData
*/
function _getRealMDFname()
{
return $this->md->getFname();
}
/**
* Create and return name for temporary symlink.
*
* @todo Should be more unique
*/
function _getAccessFname($token, $ext='EXT')
{
$token = StoredFile::_normalizeGunid($token);
return "{$this->accessDir}/$token.$ext";
}
} // class StoredFile
?>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,366 @@
<?php
define('TR_LEAVE_CLOSED', TRUE);
/**
* Auxiliary class for transport records
*
* @author $Author: tomash $
* @version $Revision: 1946 $
* @package Campcaster
* @subpackage StorageServer
*/
class TransportRecord
{
var $dbc;
var $recalled = FALSE;
var $dropped = FALSE;
/**
* Constructor
*
* @param Transport $tr object reference
* @return TransportRecord object instance
*/
function TransportRecord(&$tr)
{
$this->tr =& $tr;
$this->gb =& $tr->gb;
$this->dbc =& $tr->gb->dbc;
$this->config = $tr->gb->config;
$this->transTable = $tr->gb->config['tblNamePrefix'].'trans';
}
/**
* Factory method
*
* @param Transport $tr
* @param string $trtype
* transport type (see Transport::install)
* @param string $direction
* 'up' | 'down'
* @param array $defaults
* default parameters (optional, internal use)
* @return TransportRecord
*/
function create(&$tr, $trtype, $direction='up', $defaults=array())
{
$trec =& new TransportRecord($tr);
$trec->trtok = $trtok = $tr->_createTrtok();
$trec->row = array_merge($defaults,
array('trtype'=>$trtype, 'direction'=>$direction));
$trec->recalled = TRUE;
if (!isset($defaults['title'])) {
$defaults['title'] = $r = $trec->getTitle();
if (PEAR::isError($r)) {
return $r;
}
}
$id = $trec->dbc->nextId("{$trec->transTable}_id_seq");
$names = "id, trtok, direction, state, trtype, start, ts";
$values = "$id, '$trtok', '$direction', 'init', '$trtype', now(), now()";
foreach ($defaults as $k=>$v) {
$sqlVal = $trec->_getSqlVal($k, $v);
$names .= ", $k";
$values .= ", $sqlVal";
}
$res = $r = $trec->dbc->query("
INSERT INTO {$trec->transTable}
($names)
VALUES
($values)
");
if (PEAR::isError($r)) {
return $r;
}
return $trec;
}
/**
* Recall transport record from DB
*
* @param Transport $tr
* @param string $trtok
* transport token
* @return TransportRecord
*/
function recall(&$tr, $trtok)
{
$trec =& new TransportRecord($tr);
$trec->trtok = $trtok;
$row = $r = $trec->dbc->getRow("
SELECT
id, trtok, state, trtype, direction,
to_hex(gunid)as gunid, to_hex(pdtoken)as pdtoken,
fname, localfile, url, rtrtok, mdtrtok, uid,
expectedsize, realsize, expectedsum, realsum,
errmsg, title
FROM {$trec->transTable}
WHERE trtok='$trtok'
");
if (PEAR::isError($r)) {
return $r;
}
if (is_null($row)) {
return PEAR::raiseError("TransportRecord::recall:".
" invalid transport token ($trtok)", TRERR_TOK
);
}
$row['pdtoken'] = StoredFile::_normalizeGunid($row['pdtoken']);
$row['gunid'] = StoredFile::_normalizeGunid($row['gunid']);
$trec->row = $row;
$trec->recalled = TRUE;
return $trec;
}
/**
* Set state of transport record
*
* @param string $newState
* @param array $data
* other data fields to set
* @param string $oldState
* (opt.) check old state and do nothing if differ
* @param boolean $lock
* (opt.) check lock and do nothing if differ
* @return boolean success
*/
function setState($newState, $data=array(), $oldState=NULL, $lock=NULL)
{
$set = " state='$newState', ts=now()";
if (!is_null($lock)) {
$slock = ($lock ? 'Y' : 'N');
$nlock = (!$lock);
$snlock = ($nlock ? 'Y' : 'N');
$set .= ", lock='$snlock'";
}
foreach ($data as $k => $v) {
$set .= ", $k=".$this->_getSqlVal($k, $v);
}
$r = $this->dbc->query("
UPDATE {$this->transTable}
SET $set
WHERE trtok='{$this->trtok}'".
(is_null($oldState) ? '' : " AND state='$oldState'").
(is_null($lock) ? '' : " AND lock = '$slock'")
);
if (PEAR::isError($r)) {
return $r;
}
// return TRUE;
$affRows = $r = $this->dbc->affectedRows();
if (PEAR::isError($r)) {
return $r;
}
return ($affRows == 1);
}
/**
* Return state of transport record
*
* @return string
* state
*/
function getState()
{
if (!$this->recalled) {
return PEAR::raiseError("TransportRecord::getState:".
" not recalled ({$this->trtok})", TRERR_TOK
);
}
return $this->row['state'];
}
/**
* Set lock on transport record
*
* @param boolean $lock
* lock if true, release lock if false
* @return mixed
* true or error
*/
function setLock($lock)
{
if ($this->dropped) {
return TRUE;
}
$slock = ($lock ? 'Y' : 'N');
$nlock = (!$lock);
$snlock = ($nlock ? 'Y' : 'N');
$r = $this->dbc->query("
UPDATE {$this->transTable}
SET lock='$slock', ts=now()
WHERE trtok='{$this->trtok}' AND lock = '$snlock'"
);
if (PEAR::isError($r)) {
return $r;
}
$affRows = $r = $this->dbc->affectedRows();
if (PEAR::isError($r)) {
return $r;
}
if ($affRows != 1) {
$ltxt = ($lock ? 'lock' : 'unlock' );
return PEAR::raiseError(
"TransportRecord::setLock: can't $ltxt ({$this->trtok})"
);
}
return TRUE;
}
/**
* Return type of transport
*
* @return string
* Transport type
*/
function getTransportType()
{
if (!$this->recalled) {
return PEAR::raiseError("TransportRecord::getTransportType:".
" not recalled ({$this->trtok})", TRERR_TOK
);
}
return $this->row['trtype'];
}
/**
* Set state to failed and set error message in transport record
*
* @param string $txt
* base part of error message
* @param PEAR_Error $eo
* (opt.) error msg can be construct from it
* @return mixed
* boolean true or error
*/
function fail($txt='', $eo=NULL)
{
if (!$this->recalled) {
return PEAR::raiseError("TransportRecord::fail:".
" not recalled ({$this->trtok})", TRERR_TOK
);
}
$msg = $txt;
if (!is_null($eo)) {
$msg .= $eo->getMessage()." ".$eo->getUserInfo().
" [".$eo->getCode()."]";
}
$r = $this->setState('failed', array('errmsg'=>$msg));
if (PEAR::isError($r)) {
return $r;
}
return TRUE;
}
/**
* Close transport record
*
* @return mixed
* boolean true or error
*/
function close()
{
if (!$this->recalled) {
return PEAR::raiseError("TransportRecord::close:".
" not recalled ({$this->trtok})", TRERR_TOK
);
}
if (TR_LEAVE_CLOSED) {
$r = $this->setState('closed');
if (PEAR::isError($r)) {
return $r;
}
} else {
$r = $this->dbc->query("
DELETE FROM {$this->transTable}
WHERE trtok='{$this->trtok}'
");
if (PEAR::isError($r)) {
return $r;
}
$this->recalled = FALSE;
$this->dropped = TRUE;
}
return TRUE;
}
/**
* Add field specific envelopes to values (e.g. ' around strings)
*
* @param string $fldName
* field name
* @param mixed $fldVal
* field value
* @return string
*/
function _getSqlVal($fldName, $fldVal)
{
switch ($fldName) {
case 'realsize':
case 'expectedsize':
case 'uid':
return ("$fldVal"!='' ? "$fldVal" : "NULL");
break;
case 'gunid':
case 'pdtoken':
return "x'$fldVal'::bigint";
break;
default:
return "'$fldVal'";
break;
}
}
/**
* Get title from transported object's metadata (if exists)
*
* @return string
* the title or descriptive string
*/
function getTitle()
{
$defStr = 'unknown';
$trtype = $r = $this->getTransportType(); //contains recall check
if (PEAR::isError($r)) {
return $r;
}
switch ($trtype) {
case "audioclip":
case "playlist":
case "playlistPkg":
case "metadata":
$title = $r = $this->gb->bsGetTitle(NULL, $this->row['gunid']);
if (PEAR::isError($r)) {
if ($r->getCode()==GBERR_FOBJNEX) {
$title = $defStr;
} else {
return $r;
}
}
break;
case "searchjob":
$title = 'searchjob';
break;
case "file":
$title = ( isset($this->row['localfile']) ?
basename($this->row['localfile']) : 'regular file');
break;
default:
$title = $defStr;
}
return $title;
}
} // class TransportRecord
?>

View file

@ -0,0 +1,381 @@
<?php
define('VAL_ROOT', 110);
define('VAL_NOREQE', 111);
define('VAL_NOONEOF', 112);
define('VAL_UNKNOWNE', 113);
define('VAL_UNKNOWNA', 114);
define('VAL_NOTDEF', 115);
define('VAL_UNEXPONEOF', 116);
define('VAL_FORMAT', 117);
define('VAL_CONTENT', 118);
define('VAL_NOREQA', 119);
define('VAL_ATTRIB', 120);
define('VAL_PREDXML', 121);
/**
* Simple XML validator against structure stored in PHP hash-array hierarchy.
*
* Basic format files:
* <ul>
* <li>audioClipFormat.php</li>
* <li>webstreamFormat.php</li>
* <li>playlistFormat.php</li>
* </ul>
* It probably should be replaced by XML schema validation in the future.
*
* @author $Author$
* @version $Revision$
* @package Campcaster
* @subpackage StorageServer
*/
class Validator {
/**
* string - format type of validated document
*/
var $format = NULL;
/**
* Preloaded format tree structure
*/
var $formTree = NULL;
/**
* string - gunid of validated file for identification in mass input
*/
var $gunid = NULL;
/**
* Constructor
*
* @param string $format
* format type of validated document
* @param string $gunid
* gunid of validated file for identification in mass input
*/
function Validator($format, $gunid)
{
$format = strtolower($format);
$this->format = $format;
$this->gunid = $gunid;
$formats = array(
'audioclip' => "audioClipFormat",
'playlist' => "playlistFormat",
'webstream' => "webstreamFormat",
);
if (!isset($formats[$format])) {
return $this->_err(VAL_FORMAT);
}
$formatName = $formats[$format];
$formatFile = dirname(__FILE__)."/$formatName.php";
if (!file_exists($formatFile)) {
return $this->_err(VAL_FORMAT);
}
require $formatFile;
$this->formTree = $$formatName;
}
/**
* Validate document - only wrapper for validateNode method
*
* @param object $data
* validated object tree
* @return mixed
* TRUE or PEAR::error
*/
function validate(&$data)
{
$r = $this->validateNode($data, $this->formTree['_root']);
return $r;
}
/**
* Validate one metadata value (on insert/update)
*
* @param string $fname
* parent element name
* @param string $category
* qualif.category name
* @param string $predxml
* 'A' | 'T' (attr or tag)
* @param string $value
* validated element value
* @return mixed
* TRUE or PEAR::error
*/
function validateOneValue($fname, $category, $predxml, $value)
{
$formTree =& $this->formTree;
switch ($predxml) {
case 'T':
if (!$this->isChildInFormat($fname, $category)) {
return $this->_err(VAL_UNKNOWNE, "$category in $fname");
}
break;
case 'A':
if (!$this->isAttrInFormat($fname, $category)) {
return $this->_err(VAL_UNKNOWNA, "$category in $fname");
}
break;
case 'N':
return TRUE;
break;
default:
return $this->_err(VAL_PREDXML, $predxml);
}
if (isset($formTree[$category]['regexp'])) {
// echo "XXX {$formTree[$fname]['regexp']} / ".$node->content."\n";
if (!preg_match("|{$formTree[$category]['regexp']}|", $value)) {
return $this->_err(VAL_CONTENT, "$category/$value");
}
}
}
/**
* Validation of one element node from object tree
*
* @param object $node
* validated node
* @param string $fname
* actual name in format structure
* @return mixed
* TRUE or PEAR::error
*/
function validateNode(&$node, $fname)
{
$dname = (($node->ns? $node->ns.":" : '').$node->name);
$formTree =& $this->formTree;
if (DEBUG) {
echo"\nVAL::validateNode: 1 $dname/$fname\n";
}
// check root node name:
if ($dname != $fname) {
return $this->_err(VAL_ROOT, $fname);
}
// check if this element is defined in format:
if (!isset($formTree[$fname])) {
return $this->_err(VAL_NOTDEF, $fname);
}
// check element content
if (isset($formTree[$fname]['regexp'])) {
// echo "XXX {$formTree[$fname]['regexp']} / ".$node->content."\n";
if (!preg_match("|{$formTree[$fname]['regexp']}|", $node->content)) {
return $this->_err(VAL_CONTENT, "$fname/{$node->content}");
}
}
// validate attributes:
$ra = $this->validateAttributes($node, $fname);
if (PEAR::isError($ra)) {
return $ra;
}
// validate children:
$r = $this->validateChildren($node, $fname);
if (PEAR::isError($r)) {
return $r;
}
return TRUE;
}
/**
* Validation of attributes
*
* @param object $node
* validated node
* @param string $fname
* actual name in format structure
* @return mixed
* TRUE or PEAR::error
*/
function validateAttributes(&$node, $fname)
{
$formTree =& $this->formTree;
$attrs = array();
// check if all attrs are permitted here:
foreach ($node->attrs as $i => $attr) {
$aname = (($attr->ns? $attr->ns.":" : '').$attr->name);
$attrs[$aname] =& $node->attrs[$i];
if (!$this->isAttrInFormat($fname, $aname)) {
return $this->_err(VAL_UNKNOWNA, $aname);
}
// check attribute format
// echo "XXA $aname\n";
if (isset($formTree[$aname]['regexp'])) {
// echo "XAR {$formTree[$fname]['regexp']} / ".$node->content."\n";
if (!preg_match("|{$formTree[$aname]['regexp']}|", $attr->val)) {
return $this->_err(VAL_ATTRIB, "$aname [".var_export($attr->val,TRUE)."]");
}
}
}
// check if all required attrs are here:
if (isset($formTree[$fname]['attrs'])) {
$fattrs =& $formTree[$fname]['attrs'];
if (isset($fattrs['required'])) {
foreach ($fattrs['required'] as $i => $attr) {
if (!isset($attrs[$attr])) {
return $this->_err(VAL_NOREQA, $attr);
}
}
}
}
return TRUE;
}
/**
* Validation children nodes
*
* @param object $node
* validated node
* @param string $fname
* actual name in format structure
* @return mixed
* TRUE or PEAR::error
*/
function validateChildren(&$node, $fname)
{
$formTree =& $this->formTree;
$childs = array();
// check if all children are permitted here:
foreach ($node->children as $i => $ch) {
$chname = (($ch->ns? $ch->ns.":" : '').$ch->name);
// echo "XXE $chname\n";
if (!$this->isChildInFormat($fname, $chname)) {
return $this->_err(VAL_UNKNOWNE, $chname);
}
// call children recursive:
$r = $this->validateNode($node->children[$i], $chname);
if (PEAR::isError($r)) {
return $r;
}
$childs[$chname] = TRUE;
}
// check if all required children are here:
if (isset($formTree[$fname]['childs'])) {
$fchilds =& $formTree[$fname]['childs'];
if (isset($fchilds['required'])) {
foreach ($fchilds['required'] as $i => $ch) {
if (!isset($childs[$ch])) return $this->_err(VAL_NOREQE, $ch);
}
}
// required one from set
if (isset($fchilds['oneof'])) {
$one = FALSE;
foreach ($fchilds['oneof'] as $i => $ch) {
if (isset($childs[$ch])) {
if ($one) {
return $this->_err(VAL_UNEXPONEOF, "$ch in $fname");
}
$one = TRUE;
}
}
if (!$one) {
return $this->_err(VAL_NOONEOF);
}
}
}
return TRUE;
}
/**
* Test if child is presented in format structure
*
* @param string $fname
* node name in format structure
* @param string $chname
* child node name
* @return boolean
*/
function isChildInFormat($fname, $chname)
{
$listo = $this->isInFormatAs($fname, $chname, 'childs', 'optional');
$listr = $this->isInFormatAs($fname, $chname, 'childs', 'required');
$list1 = $this->isInFormatAs($fname, $chname, 'childs', 'oneof');
return ($listo!==FALSE || $listr!==FALSE || $list1!==FALSE);
}
/**
* Test if attribute is presented in format structure
*
* @param string $fname
* node name in format structure
* @param string $aname
* attribute name
* @return boolean
*/
function isAttrInFormat($fname, $aname)
{
$listr = $this->isInFormatAs($fname, $aname, 'attrs', 'required');
$listi = $this->isInFormatAs($fname, $aname, 'attrs', 'implied');
$listn = $this->isInFormatAs($fname, $aname, 'attrs', 'normal');
return ($listr!==FALSE || $listi!==FALSE || $listn!==FALSE);
}
/**
* Check if node/attribute is presented in format structure
*
* @param string $fname
* node name in format structure
* @param string $chname
* node/attribute name
* @param string $nType
* 'childs' | 'attrs'
* @param string $reqType
* <ul>
* <li>for elements: 'required' | 'optional' | 'oneof'</li>
* <li>for attributes: 'required' | 'implied' | 'normal'</li>
* </ul>
* @return mixed
* boolean/int (index int format array returned if found)
*/
function isInFormatAs($fname, $chname, $nType='childs', $reqType='required')
{
$formTree =& $this->formTree;
$listed = (
isset($formTree[$fname][$nType][$reqType]) ?
array_search($chname, $formTree[$fname][$nType][$reqType]) :
FALSE
);
return $listed;
}
/**
* Error exception generator
*
* @param int $errno
* erron code
* @param string $par
* optional string for more descriptive error messages
* @return PEAR_Error
*/
function _err($errno, $par='')
{
$msg = array(
VAL_ROOT => 'Wrong root element',
VAL_NOREQE => 'Required element missing',
VAL_NOONEOF => 'One-of element missing',
VAL_UNKNOWNE => 'Unknown element',
VAL_UNKNOWNA => 'Unknown attribute',
VAL_NOTDEF => 'Not defined',
VAL_UNEXPONEOF => 'Unexpected second object from one-of set',
VAL_FORMAT => 'Unknown format',
VAL_CONTENT => 'Invalid content',
VAL_NOREQA => 'Required attribute missing',
VAL_ATTRIB => 'Invalid attribute format',
VAL_PREDXML => 'Invalid predicate type',
);
return PEAR::raiseError(
"Validator: {$msg[$errno]} #$errno ($par, gunid={$this->gunid})",
$errno
);
}
} // class Validator
?>

View file

@ -0,0 +1,382 @@
<?php
/**
* @author $Author$
* @version $Revision$
* @package Campcaster
* @subpackage StorageServer
*/
require_once "XML/Util.php";
/* ================================================================== Element */
/**
* Object representation of one XML element
*
* @author $Author$
* @version $Revision$
* @package Campcaster
* @subpackage StorageServer
* @see MetaData
*/
class XmlElement {
/**
* Namespace prefix
*/
var $ns;
/**
* Element name
*/
var $name;
/**
* Attributes
*/
var $attrs = array();
/**
* Namespace definitions
*/
var $nSpaces = array();
/**
* Child nodes
*/
var $children = array();
/**
* Text content of element
*/
var $content = '';
/**
* Constructor
*
* @param string $fullname
* Fully qualified name of element
* @param array $attrs
* hash of attributes
* @param array $nSpaces
* hash of namespace definitions
* @param array $children
* hash of child nodes
* @return this
*/
function XmlElement($fullname, $attrs, $nSpaces=array(), $children=array())
{
$a = XML_Util::splitQualifiedName($fullname);
$this->ns = $a['namespace'];
$this->name = $a['localPart'];
$this->attrs = $attrs;
$this->nSpaces = $nSpaces;
$this->children = $children;
}
} // class XmlElement
/* ================================================================ Attribute */
/**
* Object representation of one XML attribute
*
* @package Campcaster
* @subpackage StorageServer
* @see MetaData
*/
class XmlAttrib {
/**
* Namespace prefix
*/
var $ns;
/**
* Attribute name
*/
var $name;
/**
* Attribute value
*/
var $val;
/**
* Constructor
*
* @param string $atns
* namespace prefix
* @param string $atnm
* attribute name
* @param string $atv
* attribute value
* @return this
*/
function XmlAttrib($atns, $atnm, $atv)
{
$this->ns = $atns;
$this->name = $atnm;
$this->val = $atv;
}
} // fn XmlAttrib
/* =================================================================== Parser */
/**
* XML parser object encapsulation
*
* @package Campcaster
* @subpackage StorageServer
* @see MetaData
*/
class XmlParser {
/**
* Tree of nodes
*/
var $tree = NULL;
/**
* Parse stack
*/
var $stack = array();
/**
* Error structure
*/
var $err = array(FALSE, '');
/**
* Constructor
*
* @param string $data
* XML string to be parsed
* @return this
*/
function XmlParser($data){
$xml_parser = xml_parser_create('UTF-8');
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, FALSE);
xml_set_object($xml_parser, $this);
xml_set_element_handler($xml_parser, "startTag", "endTag");
xml_set_character_data_handler($xml_parser, 'characterData');
$res = xml_parse($xml_parser, $data, TRUE);
if (!$res) {
$this->err = array(TRUE,
sprintf("XML error: %s at line %d\n",
xml_error_string(xml_get_error_code($xml_parser)),
xml_get_current_line_number($xml_parser)
)
);
// var_dump($data);
}
xml_parser_free($xml_parser);
}
/**
* Parse XML file or string
*
* @param string $data
* local path to XML file or XML string
* @param string $loc
* location: 'file'|'string'
* @return array
* reference, parse result tree (or PEAR::error)
*/
function &parse($data='', $loc='file')
{
switch ($loc) {
case "file":
if (!is_file($data)) {
return PEAR::raiseError(
"XmlParser::parse: file not found ($data)"
);
}
if (!is_readable($data)) {
return PEAR::raiseError(
"XmlParser::parse: can't read file ($data)"
);
}
$data = file_get_contents($data);
case "string":
$parser =& new XmlParser($data);
if ($parser->isError()) {
return PEAR::raiseError(
"SmilPlaylist::parse: ".$parser->getError()
);
}
$tree = $parser->getTree();
break;
default:
return PEAR::raiseError(
"XmlParser::parse: unsupported source location ($loc)"
);
}
return $tree;
}
/**
* Start tag handler
*
* @param resource $parser
* reference to parser resource
* @param string $fullname
* element name
* @param array $attrs
* array of attributes
* @return none
*/
function startTag($parser, $fullname, $attrs) {
$nSpaces = array();
foreach ($attrs as $atn => $atv) {
$a = XML_Util::splitQualifiedName($atn);
$atns = $a['namespace'];
$atnm = $a['localPart'];
unset($attrs[$atn]);
if ($atns == 'xmlns') {
$nSpaces[$atnm] = $atv;
} else if ($atns == NULL && $atnm == 'xmlns') {
$nSpaces[''] = $atv;
} else {
$attrs[$atn] = new XmlAttrib($atns, $atnm, $atv);
}
}
$el = new XmlElement($fullname, $attrs, $nSpaces);
array_push($this->stack, $el);
}
/**
* End tag handler
*
* @param resource $parser
* reference to parser resource
* @param string $fullname
* element name
* @return none
*/
function endTag($parser, $fullname) {
$cnt = count($this->stack);
if ($cnt > 1) {
$this->stack[$cnt-2]->children[] = $this->stack[$cnt-1];
$lastEl = array_pop($this->stack);
} else {
$this->tree = $this->stack[0];
}
}
/**
* Character data handler
*
* @param resource $parser
* reference to parser resource
* @param string $data
* @return none
*/
function characterData($parser, $data) {
$cnt = count($this->stack);
if (trim($data)!='') {
$this->stack[$cnt-1]->content .= $data;
}
}
/**
* Default handler
*
* @param resource $parser
* reference to parser resource
* @param string $data
* @return none
*/
function defaultHandler($parser, $data)
{
$cnt = count($this->stack);
//if(substr($data, 0, 1) == "&" && substr($data, -1, 1) == ";"){
// $this->stack[$cnt-1]->content .= trim($data);
//}else{
$this->stack[$cnt-1]->content .= "*** $data ***";
//}
}
/**
* Return result tree
*
* @return array
* tree structure
*/
function getTree()
{
return $this->tree;
}
/**
* Return error string
*
* @return boolean
* whether error occured
*/
function isError()
{
return $this->err[0];
}
/**
* Return error string
*
* @return string
* error message
*/
function getError()
{
return $this->err[1];
}
/* ----------------------------------- auxiliary methos for serialization */
/**
* Serialize metadata of one file
*
* @return string, serialized XML
*/
function serialize()
{
$res = '<?xml version="1.0" encoding="utf-8"?>';
$res .= $this->serializeEl($this->tree);
$res .= "\n";
return $res;
}
/**
* Serialize one metadata element
*
* @param el object, element object
* @param lvl int, level for indentation
* @return string, serialized XML
*/
function serializeEl($el, $lvl=0)
{
$ind = str_repeat(" ", $lvl);
$elNs = $el->ns;
$elName = $el->name;
$attrs = XML_Util::attributesToString($el->attrs);
$fullName = ($elNs=='' ? '' : "$elNs:")."$elName";
$res = "\n{$ind}<{$fullName}{$attrs}>";
$haveCh = (count($el->children)>0);
foreach ($el->children as $ch) {
$res .= $this->serializeEl($ch, $lvl+1);
}
$res .= XML_Util::replaceEntities("{$el->content}");
if ($haveCh) {
$res .= "\n{$ind}";
}
$res .= "</{$fullName}>";
return $res;
}
/* -------------------------------------------------------- debug methods */
/**
* Debug dump of tree
*
* @return hash, tree structure
*/
function dump()
{
var_dump($this->tree);
}
}
?>

View file

@ -0,0 +1,345 @@
<?php
/**
* @author $Author$
* @version $Revision$
*
*/
$audioClipFormat = array(
'_root'=>'audioClip',
'audioClip'=>array(
'childs'=>array(
'required'=>array('metadata'),
),
),
'metadata'=>array(
'childs'=>array(
'required'=>array(
'dc:title', 'dcterms:extent'
),
'optional'=>array(
'dc:identifier',
'dc:creator', 'dc:source', 'ls:genre',
'ls:year', 'dc:type', 'dc:description', 'dc:format',
'ls:bpm', 'ls:rating', 'ls:encoded_by', 'ls:track_num',
'ls:disc_num', 'ls:disc_num', 'dc:publisher', 'ls:composer',
'ls:bitrate', 'ls:channels', 'ls:samplerate', 'ls:encoder',
'ls:crc', 'ls:lyrics', 'ls:orchestra', 'ls:conductor',
'ls:lyricist', 'ls:originallyricist', 'ls:radiostationname',
'ls:audiofileinfourl', 'ls:artisturl', 'ls:audiosourceurl',
'ls:radiostationurl', 'ls:buycdurl', 'ls:isrcnumber',
'ls:catalognumber', 'ls:originalartist', 'dc:rights',
'ls:license', 'dc:title', 'dcterms:temporal',
'dcterms:spatial', 'dcterms:entity', 'dc:description',
'dc:creator', 'dc:subject', 'dc:type', 'dc:format',
'dc:contributor', 'dc:language', 'dc:rights',
'dcterms:isPartOf', 'dc:date',
'dc:publisher',
// extra
'dcterms:alternative', 'ls:filename', 'ls:mtime',
// added lately by sebastian
'ls:mood',
),
),
'namespaces'=>array(
'dc'=>"http://purl.org/dc/elements/1.1/",
'dcterms'=>"http://purl.org/dc/terms/",
'xbmf'=>"http://www.streamonthefly.org/xbmf",
'xsi'=>"http://www.w3.org/2001/XMLSchema-instance",
'xml'=>"http://www.w3.org/XML/1998/namespace",
),
),
'dc:identifier'=>array(
'type'=>'Text',
'auto'=>TRUE,
),
'dc:title'=>array(
'type'=>'Text',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dcterms:alternative'=>array(
'type'=>'Text',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dcterms:extent'=>array(
'type'=>'Time',
// 'regexp'=>'^\d{2}:\d{2}:\d{2}.\d{6}$',
'regexp'=>'^((\d{1,2}:)?\d{1,2}:)?\d{1,20}(.\d{1,6})?$',
),
'dc:creator'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:source'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:genre'=>array(
'type'=>'Menu',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:year'=>array(
'type'=>'Menu',
'area'=>'Music',
),
'dc:type'=>array(
'type'=>'Menu',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:description'=>array(
'type'=>'Longtext',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:format'=>array(
'type'=>'Menu',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:bpm'=>array(
'type'=>'Number',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:rating'=>array(
'type'=>'Number',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:encoded_by'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:track_num'=>array(
'type'=>'Menu',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:disc_num'=>array(
'type'=>'Menu',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:disc_num'=>array(
'type'=>'Menu',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:publisher'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:composer'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:bitrate'=>array(
'type'=>'Number',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:channels'=>array(
'type'=>'Menu',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:samplerate'=>array(
'type'=>'Menu',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:encoder'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:crc'=>array(
'type'=>'Number',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:lyrics'=>array(
'type'=>'Longtext',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:orchestra'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:conductor'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:lyricist'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:originallyricist'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:radiostationname'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:audiofileinfourl'=>array(
'type'=>'URL',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:artisturl'=>array(
'type'=>'URL',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:audiosourceurl'=>array(
'type'=>'URL',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:radiostationurl'=>array(
'type'=>'URL',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:buycdurl'=>array(
'type'=>'URL',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:isrcnumber'=>array(
'type'=>'Number',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:catalognumber'=>array(
'type'=>'Number',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:originalartist'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:rights'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:license'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:title'=>array(
'type'=>'Text',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dcterms:temporal'=>array(
'type'=>'Time/Date',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dcterms:spatial'=>array(
'type'=>'Menu',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dcterms:entity'=>array(
'type'=>'Text',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:description'=>array(
'type'=>'Longtext',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:creator'=>array(
'type'=>'Menu',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:subject'=>array(
'type'=>'Text',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:type'=>array(
'type'=>'Menu',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:format'=>array(
'type'=>'Menu',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:contributor'=>array(
'type'=>'Text',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:language'=>array(
'type'=>'Menu',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:rights'=>array(
'type'=>'Menu',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dcterms:isPartOf'=>array(
'type'=>'Text',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:date'=>array(
'type'=>'Date',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:publisher'=>array(
'type'=>'Text',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:filename'=>array(
'type'=>'Text',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:mtime'=>array(
'type'=>'Int',
// 'regexp'=>'^\d{4}(-\d{2}(-\d{2}(T\d{2}:\d{2}(:\d{2}\.\d+)?(Z)|([\+\-]?\d{2}:\d{2}))?)?)?$',
),
/*
''=>array(
'type'=>'',
'area'=>'',
'attrs'=>array(),
),
*/
);
/*
?
ls:filename Text auto
*/
?>

View file

@ -0,0 +1,168 @@
<?php
/**
* StorageServer configuration file
*
* @author $Author$
* @version $Revision$
*/
define('LS_VERSION', '1.1');
define('PHP5', version_compare( phpversion(), "5.0.0", ">=" ));
/**
* configuration structure:
*
* <dl>
* <dt>dsn<dd> datasource setting
* <dt>tblNamePrefix <dd>prefix for table names in the database
* <dt>authCookieName <dd>secret token cookie name
* <dt>AdminsGr <dd>name of admin group
* <dt>StationPrefsGr <dd>name of station preferences group
* <dt>AllGr <dd>name of 'all users' group
* <dt>TrashName <dd>name of trash folder (subfolder of the storageRoot)
* <dt>storageDir <dd>main directory for storing binary media files
* <dt>bufferDir <dd>directory for temporary files
* <dt>transDir <dd>directory for incomplete transferred files
* <dt>accessDir <dd>directory for symlinks to accessed files
* <dt>isArchive <dd>local/central flag
* <dt>validate <dd>enable/disable validator
* <dt>useTrash <dd>enable/disable safe delete (move to trash)
* <dt>storageUrlPath<dd>path-URL-part of storageServer base dir
* <dt>storageXMLRPC<dd>XMLRPC server script address relative to storageUrlPath
* <dt>storageUrlHost, storageUrlPort<dd>host and port of storageServer
* <dt>archiveUrlPath<dd>path-URL-part of archiveServer base dir
* <dt>archiveXMLRPC<dd>XMLRPC server script address relative to archiveUrlPath
* <dt>archiveUrlHost, archiveUrlPort<dd>host and port of archiveServer
* <dt>archiveAccountLogin, archiveAccountPass <dd>account info
* for login to archive
* <dt>sysSubjs<dd>system users/groups - cannot be deleted
* </dl>
*/
// these are the default values for the config
$config = array(
/* ================================================== basic configuration */
'dsn' => array(
'username' => 'test',
'password' => 'test',
'hostspec' => 'localhost',
'phptype' => 'pgsql',
'database' => 'Campcaster-test',
),
'tblNamePrefix' => 'ls_',
/* ================================================ storage configuration */
'authCookieName'=> 'lssid',
'AdminsGr' => 'Admins',
'StationPrefsGr'=> 'StationPrefs',
'AllGr' => 'All',
'TrashName' => 'trash_',
'storageDir' => realpath(dirname(__FILE__).'/../../storageServer/var/stor'),
'bufferDir' => realpath(dirname(__FILE__).'/../../storageServer/var/stor/buffer'),
'transDir' => realpath(dirname(__FILE__).'/../../storageServer/var/trans'),
'accessDir' => realpath(dirname(__FILE__).'/../../storageServer/var/access'),
'pearPath' => realpath(dirname(__FILE__).'/../../../../usr/lib/pear'),
'cronDir' => realpath(dirname(__FILE__).'/../../storageServer/var/cron'),
'isArchive' => FALSE,
'validate' => TRUE,
'useTrash' => TRUE,
/* ==================================================== URL configuration */
'storageUrlPath' => '/campcasterStorageServer',
'storageXMLRPC' => 'xmlrpc/xrLocStor.php',
'storageUrlHost' => 'localhost',
'storageUrlPort' => 80,
/* ================================================ archive configuration */
'archiveUrlPath' => '/campcasterArchiveServer',
'archiveXMLRPC' => 'xmlrpc/xrArchive.php',
'archiveUrlHost' => 'localhost',
'archiveUrlPort' => 80,
'archiveAccountLogin' => 'root',
'archiveAccountPass' => 'q',
/* ============================================== scheduler configuration */
'schedulerUrlPath' => '',
'schedulerXMLRPC' => 'RC2',
'schedulerUrlHost' => 'localhost',
'schedulerUrlPort' => 3344,
/* ==================================== aplication-specific configuration */
'objtypes' => array(
'RootNode' => array('Folder'),
'Storage' => array('Folder', 'File', 'Replica'),
'Folder' => array('Folder', 'File', 'Replica'),
'File' => array(),
'audioclip' => array(),
'playlist' => array(),
'Replica' => array(),
),
'allowedActions'=> array(
'RootNode' => array('classes', 'subjects'),
'Folder' => array('editPrivs', 'write', 'read'),
'File' => array('editPrivs', 'write', 'read'),
'audioclip' => array('editPrivs', 'write', 'read'),
'playlist' => array('editPrivs', 'write', 'read'),
'Replica' => array('editPrivs', 'write', 'read'),
'_class' => array('editPrivs', 'write', 'read'),
),
'allActions' => array(
'editPrivs', 'write', 'read', 'classes', 'subjects'
),
/* ============================================== auxiliary configuration */
'RootNode' => 'RootNode',
'tmpRootPass' => 'q',
/* =================================================== cron configuration */
# 'cronUserName' => 'www-data',
'cronUserName' => 'apache',
# 'lockfile' => dirname(__FILE__).'/cron/cron.lock',
'lockfile' => dirname(__FILE__).'/../../storageServer/var/stor/buffer/cron.lock',
'cronfile' => dirname(__FILE__).'/cron/croncall.php',
'paramdir' => dirname(__FILE__).'/cron/params',
);
$config['sysSubjs'] = array(
'root', $config['AdminsGr'], $config['AllGr'], $config['StationPrefsGr']
);
$old_ip = get_include_path();
set_include_path('.'.PATH_SEPARATOR.$config['pearPath'].PATH_SEPARATOR.$old_ip);
// see if a ~/.campcaster/storageServer.conf.php exists, and
// overwrite the settings from there if any
$this_file = null;
if(isset($_SERVER["SCRIPT_FILENAME"])){
$this_file = $_SERVER["SCRIPT_FILENAME"];
}elseif(isset($argv[0])){
$this_file = $argv[0];
}
if(!is_null($this_file)){
$fileowner_id = fileowner($this_file);
$fileowner_array = posix_getpwuid($fileowner_id);
$fileowner_homedir = $fileowner_array['dir'];
$fileowner_name = $fileowner_array['name'];
$home_conf = $fileowner_homedir . '/.campcaster/storageServer.conf.php';
if (file_exists($home_conf)) {
$default_config = $config;
$developer_name = $fileowner_name;
include $home_conf;
$user_config = $config;
$config = $user_config + $default_config;
}
}
if(!PHP5){
eval('
define("FILE_APPEND", TRUE);
function file_put_contents($f, $s, $ap=FALSE){
$fp=fopen($f, $ap==FILE_APPEND ? "a" : "w");
fwrite($fp,$s);
fclose($fp);
}
');
}
?>

View file

@ -0,0 +1,139 @@
<?php
/**
* StorageServer configuration file
* @author $Author$
* @version $Revision$
*/
define('LS_VERSION', '1.1');
define('PHP5', version_compare( phpversion(), "5.0.0", ">=" ));
/**
* configuration structure:
*
* <dl>
* <dt>dsn<dd> datasource setting
* <dt>tblNamePrefix <dd>prefix for table names in the database
* <dt>authCookieName <dd>secret token cookie name
* <dt>AdminsGr <dd>name of admin group
* <dt>StationPrefsGr <dd>name of station preferences group
* <dt>AllGr <dd>name of 'all users' group
* <dt>TrashName <dd>name of trash folder (subfolder of the storageRoot)
* <dt>storageDir <dd>main directory for storing binary media files
* <dt>bufferDir <dd>directory for temporary files
* <dt>transDir <dd>directory for incomplete transferred files
* <dt>accessDir <dd>directory for symlinks to accessed files
* <dt>isArchive <dd>local/central flag
* <dt>validate <dd>enable/disable validator
* <dt>useTrash <dd>enable/disable safe delete (move to trash)
* <dt>storageUrlPath<dd>path-URL-part of storageServer base dir
* <dt>storageXMLRPC<dd>XMLRPC server script address relative to storageUrlPath
* <dt>storageUrlHost, storageUrlPort<dd>host and port of storageServer
* <dt>archiveUrlPath<dd>path-URL-part of archiveServer base dir
* <dt>archiveXMLRPC<dd>XMLRPC server script address relative to archiveUrlPath
* <dt>archiveUrlHost, archiveUrlPort<dd>host and port of archiveServer
* <dt>archiveAccountLogin, archiveAccountPass <dd>account info
* for login to archive
* <dt>sysSubjs<dd>system users/groups - cannot be deleted
* </dl>
*/
// these are the default values for the config
$config = array(
/* ================================================== basic configuration */
'dsn' => array(
'username' => 'ls_dbuser',
'password' => 'ls_dbpassword',
'hostspec' => 'ls_dbserver',
'phptype' => 'pgsql',
'database' => 'ls_database',
),
'tblNamePrefix' => 'ls_',
/* ================================================ storage configuration */
'authCookieName'=> 'lssid',
'AdminsGr' => 'Admins',
'StationPrefsGr'=> 'StationPrefs',
'AllGr' => 'All',
'TrashName' => 'trash_',
'storageDir' => realpath(dirname(__FILE__).'/../../storageServer/var/stor'),
'bufferDir' => realpath(dirname(__FILE__).'/../../storageServer/var/stor/buffer'),
'transDir' => realpath(dirname(__FILE__).'/../../storageServer/var/trans'),
'accessDir' => realpath(dirname(__FILE__).'/../../storageServer/var/access'),
'pearPath' => 'ls_lib_dir/pear',
'cronDir' => realpath(dirname(__FILE__).'/../../storageServer/var/cron'),
'isArchive' => FALSE,
'validate' => TRUE,
'useTrash' => TRUE,
/* ==================================================== URL configuration */
'storageUrlPath' => 'ls_storageUrlPath',
'storageXMLRPC' => 'xmlrpc/xrLocStor.php',
'storageUrlHost' => 'ls_php_host',
'storageUrlPort' => ls_php_port,
/* ================================================ archive configuration */
'archiveUrlPath' => 'ls_archiveUrlPath',
'archiveXMLRPC' => 'xmlrpc/xrArchive.php',
'archiveUrlHost' => 'ls_php_host',
'archiveUrlPort' => ls_php_port,
'archiveAccountLogin' => 'root',
'archiveAccountPass' => 'q',
/* ============================================== scheduler configuration */
'schedulerUrlPath' => 'ls_scheduler_urlPrefix',
'schedulerXMLRPC' => 'ls_scheduler_xmlRpcPrefix',
'schedulerUrlHost' => 'ls_scheduler_host',
'schedulerUrlPort' => ls_scheduler_port,
/* ==================================== aplication-specific configuration */
'objtypes' => array(
'RootNode' => array('Folder'),
'Storage' => array('Folder', 'File', 'Replica'),
'Folder' => array('Folder', 'File', 'Replica'),
'File' => array(),
'audioclip' => array(),
'playlist' => array(),
'Replica' => array(),
),
'allowedActions'=> array(
'RootNode' => array('classes', 'subjects'),
'Folder' => array('editPrivs', 'write', 'read'),
'File' => array('editPrivs', 'write', 'read'),
'audioclip' => array('editPrivs', 'write', 'read'),
'playlist' => array('editPrivs', 'write', 'read'),
'Replica' => array('editPrivs', 'write', 'read'),
'_class' => array('editPrivs', 'write', 'read'),
),
'allActions' => array(
'editPrivs', 'write', 'read', 'classes', 'subjects'
),
/* ============================================== auxiliary configuration */
'RootNode' => 'RootNode',
'tmpRootPass' => 'q',
/* =================================================== cron configuration */
'cronUserName' => 'ls_apache_group',
'lockfile' => dirname(__FILE__).'/cron/cron.lock',
'cronfile' => dirname(__FILE__).'/cron/croncall.php',
'paramdir' => dirname(__FILE__).'/cron/params',
);
$config['sysSubjs'] = array(
'root', $config['AdminsGr'], $config['AllGr'], $config['StationPrefsGr']
);
$old_ip = get_include_path();
set_include_path('.'.PATH_SEPARATOR.$config['pearPath'].PATH_SEPARATOR.$old_ip);
if(!PHP5){
eval('
define("FILE_APPEND", TRUE);
function file_put_contents($f, $s, $ap=FALSE){
$fp=fopen($f, $ap==FILE_APPEND ? "a" : "w");
fwrite($fp,$s);
fclose($fp);
}
');
}
?>

View file

@ -0,0 +1,68 @@
<?php
/**
* StorageServer configuration file
* @author $Author$
* @version $Revision$
*/
/**
* configuration structure:
*
* <dl>
* <dt>dsn<dd> datasource setting
* <dt>tblNamePrefix <dd>prefix for table names in the database
* <dt>authCookieName <dd>secret token cookie name
* <dt>StationPrefsGr <dd>name of station preferences group
* <dt>AllGr <dd>name of 'all users' group
* <dt>storageDir <dd>main directory for storing binary media files
* <dt>bufferDir <dd>directory for temporary files
* <dt>transDir <dd>directory for incomplete transferred files
* <dt>accessDir <dd>directory for symlinks to accessed files
* <dt>isArchive <dd>local/central flag
* <dt>validate <dd>enable/disable validator
* <dt>storageUrlPath<dd>path-URL-part of storageServer base dir
* <dt>storageXMLRPC<dd>XMLRPC server script address relative to storageUrlPath
* <dt>storageUrlHost, storageUrlPort<dd>host and port of storageServer
* <dt>archiveUrlPath<dd>path-URL-part of archiveServer base dir
* <dt>archiveXMLRPC<dd>XMLRPC server script address relative to archiveUrlPath
* <dt>archiveUrlHost, archiveUrlPort<dd>host and port of archiveServer
* <dt>archiveAccountLogin, archiveAccountPass <dd>account info
* for login to archive
* </dl>
*/
$config = array(
/* ================================================== basic configuration */
'dsn' => array(
'username' => 'ls_dbuser',
'password' => 'ls_dbpassword',
'hostspec' => 'ls_dbserver',
'phptype' => 'pgsql',
'database' => 'ls_database',
),
/* ==================================================== URL configuration */
'storageUrlPath' => 'ls_storageUrlPath',
'storageXMLRPC' => 'xmlrpc/xrLocStor.php',
'storageUrlHost' => 'ls_php_host',
'storageUrlPort' => ls_php_port,
/* ================================================ archive configuration */
'archiveUrlPath' => 'ls_archiveUrlPath',
'archiveXMLRPC' => 'xmlrpc/xrArchive.php',
'archiveUrlHost' => 'ls_php_host',
'archiveUrlPort' => ls_php_port,
'archiveAccountLogin' => 'root',
'archiveAccountPass' => 'q',
/* ============================================== scheduler configuration */
'schedulerUrlPath' => 'ls_scheduler_urlPrefix',
'schedulerXMLRPC' => 'ls_scheduler_xmlRpcPrefix',
'schedulerUrlHost' => 'ls_scheduler_host',
'schedulerUrlPort' => ls_scheduler_port,
/* =================================================== cron configuration */
//'cronUserName' => 'www-data',
'cronUserName' => $developer_name,
);
?>

View file

@ -0,0 +1,210 @@
<?php
require_once (dirname(__FILE__).'/Crontab.php');
require_once (dirname(__FILE__).'/../conf.php');
/**
* This class can call a PHP function from crontab.
* Example:
* <pre>
* $cron = new Cron();
* $access = $cron->openCrontab('write');
* if ($access != 'write') {
* do {
* $access = $this->forceWriteable();
* } while ($access != 'write');
* }
* $cron->addCronJob('*','*','*','*','*',
* 'ClassName',
* array('first','secound','third')
* );
* $cron->closeCrontab();
* </pre>
* @package Campcaster
* @subpackage StorageServer.Cron
*/
class Cron {
/**
* @var reference Crontab object reference
*/
var $ct;
/**
* @var array This array created with getCommand() function
* @access private
*/
var $params;
/**
* @var string available values: read | write
*/
var $ctAccess = 'read';
/**
* Constructor
*/
function Cron() {
global $config;
$this->lockfile = $config['lockfile'];
$this->cronfile = $config['cronfile'];
$this->paramdir = $config['paramdir'];
$this->cronUserName = $config['cronUserName'];
}
/* ==================================================== Cronjob functions */
/**
* Add a cronjob to the crontab
*
* @access public
* @param string $m minute
* @param string $h hour
* @param string $dom day of month
* @param string $mo month
* @param string $dow day of week
* @param string $className name of class, which's execute() is called by croncall.php
* @param string $params the parameter(s)
* @return bool true if success else PEAR error.
*/
function addCronJob($m, $h, $dom, $mo, $dow, $className, $params)
{
if ($this->ctAccess == 'write') {
$this->ct->addCron($m, $h, $dom, $mo, $dow,
$this->getCommand($className, $params));
return true;
} else {
return PEAR::raiseError('CronJob::addCronJob : '.
'The crontab is not writable');
}
}
/**
* This function return with the active cronjobs
*
* @access public
* @return array array of cronjob struct
*/
function listCronJob()
{
return $this->ct->getByType(CRON_CMD);
}
/**
* Remove a cronjob.
*
* @access public
* @param int $index index of the cronjobs' array.
* @return bool true if success else PEAR error.
*/
function removeCronJob($index)
{
if ($this->ctAccess == 'write') {
$this->crontab->delEntry($index);
return true;
} else {
return PEAR::raiseError('CronJob::removeCronJob : '.
'The crontab is not writable');
}
}
/* ==================================================== Crontab functions */
/**
* Open the crontab
*
* @access public
* @param string $access only for listing 'read', for add and delete 'write'
* @return string sucessed access - available values read | write
*/
function openCrontab($access = 'read')
{
$access = strtolower($access);
$this->ct = new Crontab($this->cronUserName);
if ($access == 'write' &&
$this->isCrontabWritable() &&
$this->lockCrontab()) {
$this->ctAccess = $access;
} else {
$this->ctAccess = 'read';
}
return $this->ctAccess;
}
/**
* Close the crontab
*
* @access public
* @return bool true if everything is ok, false is the lock file can't delete
*/
function closeCrontab()
{
if ($this->ctAccess == 'write') {
$this->ct->writeCrontab();
}
return $this->ctAccess == 'write' ? $this->unlockCrontab() : true;
}
/**
* Check the crontab is writable
*
* @access private
* @return bool
*/
function isCrontabWritable()
{
return !is_file($this->lockfile);
}
/**
* Try to lock the crontab
*
* @access private
* @return bool true if the locking is success
*/
function lockCrontab()
{
return touch($this->lockfile);
}
/**
* Try to unlock the crontab
*
* @access private
* @return bool true if the unlocking is success
*/
function unlockCrontab()
{
return unlink($this->lockfile);
}
/**
* If the crontab opened with read access. This function force set
* the access to write.
*
* @access public
* @return bool true if the setting is success
*/
function forceWriteable()
{
if ($this->isCrontabWritable() && $this->lockCrontab()) {
$this->ctAccess = 'write';
return true;
}
return false;
}
/* ======================================================= Misc functions */
/**
* Get the shell command for the cronjob
*
* @param string $className name of the class what is called by croncall.php
* @param mixed $params with this parameter could be called the execute() of class
* @return string shell command
*/
function getCommand($className, $params)
{
$this->params = array (
'class' => $className,
'params' => $params
);
return $this->cronfile.' "'.str_replace('"','\"',serialize($this->params)).'"';
}
}
?>

View file

@ -0,0 +1,19 @@
<?php
/**
* Cron jobs handling abstract class
*
* @author $Author: $
* @version $Revision: $
* @package Campcaster
* @subpackage StorageServer.Cron
*/
class CronJob
{
/**
* The croncall.php call this function after the objectcreation.
*/
function execute()
{
}
}
?>

View file

@ -0,0 +1,270 @@
<?php
define('CRON_COMMENT', 0);
define('CRON_ASSIGN', 1);
define('CRON_CMD', 2);
define('CRON_SPECIAL', 3);
define('CRON_EMPTY', 4);
/**
* A class that interfaces with the crontab. (cjpa@audiophile.com)
*
* This class lets you manipulate the crontab. It lets you add delete update entries easily.
* @author $Author: $
* @version $Revision: $
* @package Campcaster
* @subpackage StorageServer.Cron
*/
class Crontab
{
// {{{ properties
/**
* @var array holds all the different lines.
* Lines are associative arrays with the following fields:
* "minute" : holds the minutes (0-59)
* "hour" : holds the hour (0-23)
* "dayofmonth" : holds the day of the month (1-31)
* "month" : the month (1-12 or the names)
* "dayofweek" : 0-7 (or the names)
*
* or a line can be a 2-value array that represents an assignment:
* "name" => "value"
* or a line can be a comment (string beginning with #)
* or it can be a special command (beginning with an @)
*/
var $crontabs;
/**
* @var string the user for whom the crontab will be manipulated
*/
var $user;
/**
* @var string Lists the type of line of each line in $crontabs.
* can be: any of the CRON_* constants.
* so $linetype[5] is the type of $crontabs[5].
*/
var $linetypes;
// }}}
/**
* Constructor
*
* Initialises $this->crontabs
*
* @param string $user the user for whom the crontab will be manipulated
*/
function Crontab($user)
{
$this->user = $user;
$this->readCrontab();
}
/**
* This reads the crontab of $this->user and parses it in $this->crontabs
*
*/
function readCrontab()
{
@exec("crontab -u {$this->user} -l", $crons, $return);
if($return != 0){
return PEAR::raiseError("*** Can't read crontab ***\n".
" Set crontab manually!\n");
}
foreach ($crons as $line)
{
$line = trim($line); // discarding all prepending spaces and tabs
// empty lines..
if (!$line)
{
$this->crontabs[] = "empty line";
$this->linetypes[] = CRON_EMPTY;
continue;
}
// checking if this is a comment
if ($line[0] == "#")
{
$this->crontabs[] = trim($line);
$this->linetypes[] = CRON_COMMENT;
continue;
}
// Checking if this is an assignment
if (ereg("(.*)=(.*)", $line, $assign))
{
$this->crontabs[] = array ("name" => $assign[1], "value" => $assign[2]);
$this->linetypes[] = CRON_ASSIGN;
continue;
}
// Checking if this is a special @-entry. check man 5 crontab for more info
if ($line[0] == '@')
{
$this->crontabs[] = split("[ \t]", $line, 2);
$this->linetypes[] = CRON_SPECIAL;
continue;
}
// It's a regular crontab-entry
$ct = split("[ \t]", $line, 6);
$this->addCron($ct[0], $ct[1], $ct[2], $ct[3], $ct[4], $ct[5], $ct[6]);
}
}
/**
* Writes the current crontab
*/
function writeCrontab()
{
global $DEBUG, $PATH;
$filename = ($DEBUG ? tempnam("$PATH/crons", "cron") : tempnam("/tmp", "cron"));
$file = fopen($filename, "w");
for ($i = 0; $i < count($this->linetypes); $i ++)
{
switch ($this->linetypes[$i])
{
case CRON_COMMENT :
$line = $this->crontabs[$i];
break;
case CRON_ASSIGN :
$line = $this->crontabs[$i][name]." = ".$this->crontabs[$i][value];
break;
case CRON_CMD :
$line = implode(" ", $this->crontabs[$i]);
break;
case CRON_SPECIAL :
$line = implode(" ", $this->crontabs[$i]);
break;
case CRON_EMPTY :
$line = "\n"; // an empty line in the crontab-file
break;
default :
unset ($line);
echo "Something very weird is going on. This line ($i) has an unknown type.\n";
break;
}
// echo "line $i : $line\n";
if ($line){
$r = @fwrite($file, $line."\n");
if($r === FALSE){
return PEAR::raiseError("*** Can't write crontab ***\n".
" Set crontab manually!\n");
}
}
}
fclose($file);
if ($DEBUG)
echo "DEBUGMODE: not updating crontab. writing to $filename instead.\n";
else
{
exec("crontab -u {$this->user} $filename", $returnar, $return);
if ($return != 0)
echo "Error running crontab ($return). $filename not deleted\n";
else
unlink($filename);
}
}
/**
* Add a item of type CRON_CMD to the end of $this->crontabs
*
* @param string $m minute
* @param string $h hour
* @param string $dom day of month
* @param string $mo month
* @param string $dow day of week
* @param string $cmd command
*
*/
function addCron($m, $h, $dom, $mo, $dow, $cmd)
{
$this->crontabs[] = array ("minute" => $m, "hour" => $h, "dayofmonth" => $dom, "month" => $mo, "dayofweek" => $dow, "command" => $cmd);
$this->linetypes[] = CRON_CMD;
}
/**
* Add a comment to the cron to the end of $this->crontabs
*
* @param string $comment comment
*/
function addComment($comment)
{
$this->crontabs[] = "# $comment\n";
$this->linetypes[] = CRON_COMMENT;
}
/**
* Add a special command (check man 5 crontab for more information)
*
* @param string $sdate special date
* string meaning
* ------ -------
* @reboot Run once, at startup.
* @yearly Run once a year, "0 0 1 1 *".
* @annually (same as @yearly)
* @monthly Run once a month, "0 0 1 * *".
* @weekly Run once a week, "0 0 * * 0".
* @daily Run once a day, "0 0 * * *".
* @midnight (same as @daily)
* @hourly Run once an hour, "0 * * * *".
* @param string $cmd command
*/
function addSpecial($sdate, $cmd)
{
$this->crontabs[] = array ("special" => $sdate, "command" => $cmd);
$this->linetypes[] = CRON_SPECIAL;
}
/**
* Add an assignment (name = value)
*
* @param string $name name of assingation
* @param string $value value
*/
function addAssign($name, $value)
{
$this->crontabs[] = array ("name" => $name, "value" => $value);
$this->linetypes[] = CRON_ASSIGN;
}
/**
* Delete a line from the arrays.
*
* @param int $index the index in $this->crontabs
*/
function delEntry($index)
{
unset ($this->crontabs[$index]);
unset ($this->linetypes[$index]);
}
/**
* Get all the lines of a certain type in an array
*
* @param string $type linetype
*/
function getByType($type)
{
if ($type < CRON_COMMENT || $type > CRON_EMPTY)
{
trigger_error("Wrong type: $type", E_USER_WARNING);
return 0;
}
$returnar = array ();
for ($i = 0; $i < count($this->linetypes); $i ++)
if ($this->linetypes[$i] == $type)
$returnar[] = $this->crontabs[$i];
return $returnar;
}
}
?>

View file

@ -0,0 +1,9 @@
#!/usr/bin/php
<?php
chdir(dirname(__FILE__));
$p = unserialize($argv[1]);
require_once (dirname(__FILE__).'/'.$p['class'].'.php');
$cronjob = new $p['class']();
$ret = $cronjob->execute($p['params']);
exit(0);
?>

View file

@ -0,0 +1,19 @@
#!/usr/bin/php
<?php
require_once dirname(__FILE__).'/../conf.php';
require_once 'DB.php';
require_once dirname(__FILE__).'/../LocStor.php';
PEAR::setErrorHandling(PEAR_ERROR_RETURN);
$dbc = DB::connect($config['dsn'], TRUE);
$dbc->setErrorHandling(PEAR_ERROR_RETURN);
$dbc->setFetchMode(DB_FETCHMODE_ASSOC);
$gb =& new LocStor($dbc, $config);
$tr =& new Transport($gb);
$r = $tr->cronMain();
if(!$r) exit(1);
exit(0);
?>

View file

@ -0,0 +1,39 @@
#!/usr/bin/php
<?php
require_once dirname(__FILE__).'/../conf.php';
require_once 'DB.php';
require_once dirname(__FILE__).'/../LocStor.php';
PEAR::setErrorHandling(PEAR_ERROR_RETURN);
$dbc = DB::connect($config['dsn'], TRUE);
$dbc->setErrorHandling(PEAR_ERROR_RETURN);
$dbc->setFetchMode(DB_FETCHMODE_ASSOC);
$gb =& new LocStor($dbc, $config);
$tr =& new Transport($gb);
list(, $trtok) = $_SERVER['argv'];
if (TR_LOG_LEVEL>1) {
$tr->trLog("transportCronJob start ($trtok)");
}
// 4-pass on job:
$cnt = 4;
for ($i = 0; $i < $cnt; $i++, sleep(1)){
// run the action:
$r = $tr->cronCallMethod($trtok);
if (PEAR::isError($r)) {
$tr->trLogPear("transportCronJob: ($trtok): ", $r);
} else {
# $tr->trLog("X transportCronJob: ".var_export($r, TRUE));
if($r!==TRUE) $tr->trLog("transportCronJob: ($trtok): nonTRUE returned");
}
#if(!$r) exit(1);
#sleep(2);
}
if (TR_LOG_LEVEL>1) {
$tr->trLog("transportCronJob end ($trtok)");
}
exit(0);
?>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<audioClip>
<metadata
xmlns="http://mdlf.org/campcaster/elements/1.0/"
xmlns:ls="http://mdlf.org/campcaster/elements/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
>
<dc:title>Empty file</dc:title>
<dcterms:extent>00:00:00.000000</dcterms:extent>
</metadata>
</audioClip>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<playlist id="0000000000000000" playlength="00:00:00.000000">
<metadata
xmlns="http://mdlf.org/campcaster/elements/1.0/"
xmlns:ls="http://mdlf.org/campcaster/elements/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
/>
</playlist>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<audioClip>
<metadata
xmlns="http://mdlf.org/campcaster/elements/1.0/"
xmlns:ls="http://mdlf.org/campcaster/elements/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
>
<ls:url></ls:url>
<dc:title>Empty file</dc:title>
<dcterms:extent>00:00:00.000000</dcterms:extent>
</metadata>
</audioClip>

View file

@ -0,0 +1,136 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE options [
<!ELEMENT options (option*) >
<!ELEMENT option (label+) >
<!ELEMENT label (#PCDATA) >
<!ATTLIST option id CDATA #REQUIRED >
<!ATTLIST label xml:lang CDATA #IMPLIED >
]>
<options>
<option id="Blues"><label>Blues</label></option>
<option id="Classic Rock"><label>Classic Rock</label></option>
<option id="Country"><label>Country</label></option>
<option id="Dance"><label>Dance</label></option>
<option id="Disco"><label>Disco</label></option>
<option id="Funk"><label>Funk</label></option>
<option id="Grunge"><label>Grunge</label></option>
<option id="Hip-Hop"><label>Hip-Hop</label></option>
<option id="Jazz"><label>Jazz</label></option>
<option id="Metal"><label>Metal</label></option>
<option id="New Age"><label>New Age</label></option>
<option id="Oldies"><label>Oldies</label></option>
<option id="Other"><label>Other</label></option>
<option id="Pop"><label>Pop</label></option>
<option id="R&amp;B"><label>R&amp;B</label></option>
<option id="Rap"><label>Rap</label></option>
<option id="Reggae"><label>Reggae</label></option>
<option id="Rock"><label>Rock</label></option>
<option id="Techno"><label>Techno</label></option>
<option id="Industrial"><label>Industrial</label></option>
<option id="Alternative"><label>Alternative</label></option>
<option id="Ska"><label>Ska</label></option>
<option id="Death Metal"><label>Death Metal</label></option>
<option id="Pranks"><label>Pranks</label></option>
<option id="Soundtrack"><label>Soundtrack</label></option>
<option id="Euro-Techno"><label>Euro-Techno</label></option>
<option id="Ambient"><label>Ambient</label></option>
<option id="Trip-Hop"><label>Trip-Hop</label></option>
<option id="Vocal"><label>Vocal</label></option>
<option id="Jazz+Funk"><label>Jazz+Funk</label></option>
<option id="Fusion"><label>Fusion</label></option>
<option id="Trance"><label>Trance</label></option>
<option id="Classical"><label>Classical</label></option>
<option id="Instrumental"><label>Instrumental</label></option>
<option id="Acid"><label>Acid</label></option>
<option id="House"><label>House</label></option>
<option id="Game"><label>Game</label></option>
<option id="Sound Clip"><label>Sound Clip</label></option>
<option id="Gospel"><label>Gospel</label></option>
<option id="Noise"><label>Noise</label></option>
<option id="AlternRock"><label>AlternRock</label></option>
<option id="Bass"><label>Bass</label></option>
<option id="Soul"><label>Soul</label></option>
<option id="Punk"><label>Punk</label></option>
<option id="Space"><label>Space</label></option>
<option id="Meditative"><label>Meditative</label></option>
<option id="Instrumental Pop"><label>Instrumental Pop</label></option>
<option id="Instrumental Rock"><label>Instrumental Rock</label></option>
<option id="Ethnic"><label>Ethnic</label></option>
<option id="Gothic"><label>Gothic</label></option>
<option id="Darkwave"><label>Darkwave</label></option>
<option id="Techno-Industrial"><label>Techno-Industrial</label></option>
<option id="Electronic"><label>Electronic</label></option>
<option id="Pop-Folk"><label>Pop-Folk</label></option>
<option id="Eurodance"><label>Eurodance</label></option>
<option id="Dream"><label>Dream</label></option>
<option id="Southern Rock"><label>Southern Rock</label></option>
<option id="Comedy"><label>Comedy</label></option>
<option id="Cult"><label>Cult</label></option>
<option id="Gangsta"><label>Gangsta</label></option>
<option id="Top 40"><label>Top 40</label></option>
<option id="Christian Rap"><label>Christian Rap</label></option>
<option id="Pop/Funk"><label>Pop/Funk</label></option>
<option id="Jungle"><label>Jungle</label></option>
<option id="Native American"><label>Native American</label></option>
<option id="Cabaret"><label>Cabaret</label></option>
<option id="New Wave"><label>New Wave</label></option>
<option id="Psychadelic"><label>Psychadelic</label></option>
<option id="Rave"><label>Rave</label></option>
<option id="Showtunes"><label>Showtunes</label></option>
<option id="Trailer"><label>Trailer</label></option>
<option id="Lo-Fi"><label>Lo-Fi</label></option>
<option id="Tribal"><label>Tribal</label></option>
<option id="Acid Punk"><label>Acid Punk</label></option>
<option id="Acid Jazz"><label>Acid Jazz</label></option>
<option id="Polka"><label>Polka</label></option>
<option id="Retro"><label>Retro</label></option>
<option id="Musical"><label>Musical</label></option>
<option id="Rock &amp; Roll"><label>Rock &amp; Roll</label></option>
<option id="Hard Rock"><label>Hard Rock</label></option>
<option id="Folk"><label>Folk</label></option>
<option id="Folk-Rock"><label>Folk-Rock</label></option>
<option id="National Folk"><label>National Folk</label></option>
<option id="Swing"><label>Swing</label></option>
<option id="Fast Fusion"><label>Fast Fusion</label></option>
<option id="Bebob"><label>Bebob</label></option>
<option id="Latin"><label>Latin</label></option>
<option id="Revival"><label>Revival</label></option>
<option id="Celtic"><label>Celtic</label></option>
<option id="Bluegrass"><label>Bluegrass</label></option>
<option id="Avantgarde"><label>Avantgarde</label></option>
<option id="Gothic Rock"><label>Gothic Rock</label></option>
<option id="Progressive Rock"><label>Progressive Rock</label></option>
<option id="Psychedelic Rock"><label>Psychedelic Rock</label></option>
<option id="Symphonic Rock"><label>Symphonic Rock</label></option>
<option id="Slow Rock"><label>Slow Rock</label></option>
<option id="Big Band"><label>Big Band</label></option>
<option id="Chorus"><label>Chorus</label></option>
<option id="Easy Listening"><label>Easy Listening</label></option>
<option id="Acoustic"><label>Acoustic</label></option>
<option id="Humour"><label>Humour</label></option>
<option id="Speech"><label>Speech</label></option>
<option id="Chanson"><label>Chanson</label></option>
<option id="Opera"><label>Opera</label></option>
<option id="Chamber Music"><label>Chamber Music</label></option>
<option id="Sonata"><label>Sonata</label></option>
<option id="Symphony"><label>Symphony</label></option>
<option id="Booty Bass"><label>Booty Bass</label></option>
<option id="Primus"><label>Primus</label></option>
<option id="Porn Groove"><label>Porn Groove</label></option>
<option id="Satire"><label>Satire</label></option>
<option id="Slow Jam"><label>Slow Jam</label></option>
<option id="Club"><label>Club</label></option>
<option id="Tango"><label>Tango</label></option>
<option id="Samba"><label>Samba</label></option>
<option id="Folklore"><label>Folklore</label></option>
<option id="Ballad"><label>Ballad</label></option>
<option id="Power Ballad"><label>Power Ballad</label></option>
<option id="Rhythmic Soul"><label>Rhythmic Soul</label></option>
<option id="Freestyle"><label>Freestyle</label></option>
<option id="Duet"><label>Duet</label></option>
<option id="Punk Rock"><label>Punk Rock</label></option>
<option id="Drum Solo"><label>Drum Solo</label></option>
<option id="A capella"><label>A capella</label></option>
<option id="Euro-House"><label>Euro-House</label></option>
<option id="Dance Hall"><label>Dance Hall</label></option>
</options>

View file

@ -0,0 +1,21 @@
<?php
/**
* @author $Author$
* @version $Revision$
*/
header ("location: html/");
exit;
/*
?>
<html><head>
<title>StorageServer module</title>
</head><body>
<h3>StorageServer module</h3>
<br>
<a href="../html/" accesskey="H"><b>H</b>TML client</a><br>
<a href="../xmlrpc/" accesskey="X"><b>X</b>mlRpc test</a><br>
<a href="../tests/" accesskey="T"><b>T</b>est</a><br>
</body></html>
<?
*/
?>

View file

@ -0,0 +1,10 @@
<?php
/*------------------------------------------------------------------------------
* This (web-callable) script returns group running httpd
*----------------------------------------------------------------------------*/
header("Content-type: text/plain");
$egid = posix_getegid();
$info = posix_getgrgid($egid);
if($_SERVER["REMOTE_ADDR"] == "127.0.0.1") echo $info['name'];
?>

View file

@ -0,0 +1,8 @@
<?php
/*------------------------------------------------------------------------------
* This script returns real dir of php scipts for debugging purposes
*----------------------------------------------------------------------------*/
header("Content-type: text/plain");
if($_SERVER["REMOTE_ADDR"] == "127.0.0.1") echo `pwd`;
?>

View file

@ -0,0 +1,10 @@
<?php
/*------------------------------------------------------------------------------
* This script returns storage root URL
*----------------------------------------------------------------------------*/
header("Content-type: text/plain");
require "../conf.php";
echo "http://{$config['storageUrlHost']}:{$config['storageUrlPort']}".
"{$config['storageUrlPath']}";
?>

View file

@ -0,0 +1,10 @@
<?php
/*------------------------------------------------------------------------------
* This script returns storage XMLRPC root URL
*----------------------------------------------------------------------------*/
header("Content-type: text/plain");
require "../conf.php";
echo "http://{$config['storageUrlHost']}:{$config['storageUrlPort']}".
"{$config['storageUrlPath']}/{$config['storageXMLRPC']}";
?>

View file

@ -0,0 +1,4 @@
<?php
header ("location: ../");
exit;
?>

View file

@ -0,0 +1,119 @@
<?php
/**
* @author $Author$
* @version $Revision$
*/
// no remote execution
$arr = array_diff_assoc($_SERVER, $_ENV);
if(isset($arr["DOCUMENT_ROOT"]) && $arr["DOCUMENT_ROOT"] != ""){
header("HTTP/1.1 400");
header("Content-type: text/plain; charset=UTF-8");
echo "400 Not executable\r\n";
exit(1);
}
require_once '../conf.php';
require_once 'DB.php';
require_once '../GreenBox.php';
require_once "../Transport.php";
require_once "../Prefs.php";
function errCallback($err)
{
if(assert_options(ASSERT_ACTIVE)==1) return;
echo "ERROR:\n";
echo "request: "; print_r($_REQUEST);
echo "gm:\n".$err->getMessage()."\ndi:\n".$err->getDebugInfo().
"\nui:\n".$err->getUserInfo()."\n";
exit(1);
}
if(!function_exists('pg_connect')){
trigger_error("PostgreSQL PHP extension required and not found.", E_USER_ERROR);
exit(2);
}
#PEAR::setErrorHandling(PEAR_ERROR_PRINT, "%s<hr>\n");
PEAR::setErrorHandling(PEAR_ERROR_RETURN);
$dbc = DB::connect($config['dsn'], TRUE);
if(PEAR::isError($dbc)){
echo $dbc->getMessage()."\n";
echo $dbc->getUserInfo()."\n";
echo "Database connection problem.\n";
echo "Check if database '{$config['dsn']['database']}' exists".
" with corresponding permissions.\n";
echo "Database access is defined by 'dsn' values in var/conf.php ".
"(in storageServer directory).\n";
exit(1);
}
$dbc->setFetchMode(DB_FETCHMODE_ASSOC);
$gb =& new GreenBox($dbc, $config, TRUE);
$tr =& new Transport($gb);
$pr =& new Prefs($gb);
//------------------------------------------------------------------------------
// install
//------------------------------------------------------------------------------
echo "#StorageServer install:\n";
echo "# Install ...\n";
#PEAR::setErrorHandling(PEAR_ERROR_PRINT, "%s<hr>\n");
PEAR::setErrorHandling(PEAR_ERROR_DIE, "%s\n");
#$dbc->setErrorHandling(PEAR_ERROR_RETURN);
$r = $gb->install();
if(PEAR::isError($r)){ echo $r->getMessage()."\n"; echo $r->getUserInfo()."\n"; exit(1); }
#if(PEAR::isError($r)){ echo $r->getUserInfo()."\n"; exit(1); }
//------------------------------------------------------------------------------
// Storage directory writability test
//------------------------------------------------------------------------------
if(!($fp = @fopen($config['storageDir']."/_writeTest", 'w'))){
echo "\n<b>make {$config['storageDir']} dir webdaemon-writeable</b>".
"\nand run install again\n\n";
exit(1);
}else{
fclose($fp); unlink($config['storageDir']."/_writeTest");
echo "#storageServer main: OK\n";
}
//------------------------------------------------------------------------------
// Submodules
//------------------------------------------------------------------------------
$dbc->setErrorHandling(PEAR_ERROR_RETURN);
echo "# Install Transport submodule ...";
$r = $tr->install();
if(PEAR::isError($r)){ echo $r->getMessage()."\n"; echo $r->getUserInfo()."\n"; exit(1); }
echo "\n";
echo "# Install Prefs submodule ...";
$r = $pr->install();
if(PEAR::isError($r)){ echo $r->getUserInfo()."\n"; exit(1); }
echo "\n";
echo "# submodules: OK\n";
//------------------------------------------------------------------------------
// Cron configuration
//------------------------------------------------------------------------------
echo "# Cron configuration ...";
require_once dirname(__FILE__).'/../cron/Cron.php';
$cron = new Cron();
$access = $r = $cron->openCrontab('write');
if ($access != 'write') {
do {
$r = $this->forceWriteable();
} while ($r);
}
$cron->ct->addCron('*/2', '*', '*', '*', '*', realpath("{$config['cronDir']}/transportCron.php"));
$r = $cron->closeCrontab();
echo "# cron config: OK\n";
echo "#storageServer: OK\n\n";
$dbc->disconnect();
?>

View file

@ -0,0 +1,65 @@
<?php
/**
* @author $Author$
* @version $Revision$
*/
// no remote execution
$arr = array_diff_assoc($_SERVER, $_ENV);
if(isset($arr["DOCUMENT_ROOT"]) && $arr["DOCUMENT_ROOT"] != ""){
header("HTTP/1.1 400");
header("Content-type: text/plain; charset=UTF-8");
echo "400 Not executable\r\n";
exit;
}
require_once '../conf.php';
require_once 'DB.php';
require_once '../GreenBox.php';
require_once "../Transport.php";
require_once "../Prefs.php";
function errCallback($err)
{
if(assert_options(ASSERT_ACTIVE)==1) return;
echo "ERROR:\n";
echo "request: "; print_r($_REQUEST);
echo "gm:\n".$err->getMessage()."\ndi:\n".$err->getDebugInfo().
"\nui:\n".$err->getUserInfo()."\n</pre>\n";
exit(1);
}
PEAR::setErrorHandling(PEAR_ERROR_PRINT, "%s<hr>\n");
$dbc = DB::connect($config['dsn'], TRUE);
if(PEAR::isError($dbc)){
echo "Database connection problem.\n";
echo "Check if database '{$config['dsn']['database']}' exists".
" with corresponding permissions.\n";
echo "Database access is defined by 'dsn' values in conf.php.\n";
exit(1);
}
echo "#StorageServer uninstall:\n";
$dbc->setFetchMode(DB_FETCHMODE_ASSOC);
$gb = &new GreenBox($dbc, $config, TRUE);
$tr =& new Transport($gb);
$pr =& new Prefs($gb);
$dbc->setErrorHandling(PEAR_ERROR_RETURN);
echo "# Uninstall Prefs submodule";
$r = $pr->uninstall();
if(PEAR::isError($r)){ echo $r->getUserInfo()."\n"; exit; }
echo "\n";
echo "# Uninstall Transport submodule ...";
$r = $tr->uninstall();
if(PEAR::isError($r)){ echo $r->getUserInfo()."\n"; exit; }
echo "\n";
echo "# Uninstall StorageServer ...\n";
$gb->uninstall();
echo "#StorageServer uninstall: OK\n";
$dbc->disconnect();
?>

View file

@ -0,0 +1,117 @@
<?php
/**
* @author $Author$
* @version $Revision$
* @package Campcaster
* @subpackage StorageServer
*/
$playlistFormat = array(
'_root'=>'playlist',
'playlist'=>array(
'childs'=>array(
// 'repeatable'=>array('playlistElement'),
'optional'=>array('metadata', 'playlistElement'),
),
'attrs'=>array(
'required'=>array('id'),
'implied'=>array('title', 'playlength'),
),
),
'playlistElement'=>array(
'childs'=>array(
'oneof'=>array('audioClip', 'playlist'),
'optional'=>array('fadeInfo'),
),
'attrs'=>array(
'required'=>array('id', 'relativeOffset'),
),
),
'audioClip'=>array(
'childs'=>array(
'optional'=>array('metadata'),
),
'attrs'=>array(
'implied'=>array('id', 'title', 'playlength', 'uri'),
),
),
'fadeInfo'=>array(
'attrs'=>array(
'required'=>array('id', 'fadeIn', 'fadeOut'),
),
),
'metadata'=>array(
'childs'=>array(
'optional'=>array(
'dc:title', 'dcterms:extent', 'dc:creator', 'dc:description',
'dcterms:alternative', 'ls:filename', 'ls:mtime',
),
),
'namespaces'=>array(
'dc'=>"http://purl.org/dc/elements/1.1/",
'dcterms'=>"http://purl.org/dc/terms/",
'xbmf'=>"http://www.streamonthefly.org/xbmf",
'xsi'=>"http://www.w3.org/2001/XMLSchema-instance",
'xml'=>"http://www.w3.org/XML/1998/namespace",
),
),
'dc:title'=>array(
'type'=>'Text',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dcterms:alternative'=>array(
'type'=>'Text',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dcterms:extent'=>array(
'type'=>'Time',
'regexp'=>'^\d{2}:\d{2}:\d{2}.\d{6}$',
),
'dc:creator'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:description'=>array(
'type'=>'Longtext',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'playlength'=>array(
'type'=>'Time',
'regexp'=>'^((\d{2}:)?\d{2}:)?\d{1,2}(.\d{6})?$',
),
'id'=>array(
'type'=>'Attribute',
'regexp'=>'^[0-9a-f]{16}$',
),
'fadeIn'=>array(
'type'=>'Attribute',
'regexp'=>'^((\d{2}:)?\d{2}:)?\d{1,2}(.\d{6})?$',
),
'fadeOut'=>array(
'type'=>'Attribute',
'regexp'=>'^((\d{2}:)?\d{2}:)?\d{1,2}(.\d{6})?$',
),
'ls:filename'=>array(
'type'=>'Text',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:mtime'=>array(
'type'=>'Int',
// 'regexp'=>'^\d{4}(-\d{2}(-\d{2}(T\d{2}:\d{2}(:\d{2}\.\d+)?(Z)|([\+\-]?\d{2}:\d{2}))?)?)?$',
),
/*
''=>array(
'childs'=>array(''),
'attrs'=>array('implied'=>array()),
),
*/
);
/*
?
ls:filename Text auto
*/
?>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<audioClip>
<metadata
xmlns="http://mdlf.org/livesupport/elements/1.0/"
xmlns:ls="http://mdlf.org/livesupport/elements/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
>
<dc:title>one</dc:title>
<dcterms:extent>00:00:11.000000</dcterms:extent>
</metadata>
</audioClip>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<audioClip>
<metadata
xmlns="http://mdlf.org/livesupport/elements/1.0/"
xmlns:ls="http://mdlf.org/livesupport/elements/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
>
<dc:title >two</dc:title>
<dcterms:extent >00:00:12.200000</dcterms:extent>
</metadata>
</audioClip>

View file

@ -0,0 +1,25 @@
#!/usr/bin/php -q
<?php
header("Content-type: text/plain");
echo "TEST\n";
#$gunid = "5716b53127c3761f92fddde3412c7773";
$gunid = $argv[1];
echo "GUNID: $gunid\n";
require_once '../conf.php';
require_once 'DB.php';
require_once '../GreenBox.php';
#$rmd =& new RawMediaData('qwerty', '../stor');
#$r = $rmd->insert('./ex1.mp3', 'mp3');
#$r = $rmd->test('./ex1.mp3', './ex2.wav', '../access/xyz.ext');
$rmd =& new RawMediaData($gunid, '../stor/'.substr($gunid, 0, 3));
$r = $rmd->analyze();
echo "r=$r (".gettype($r).")\n";
if(PEAR::isError($r)) echo"ERR: ".$r->getMessage()."\n".$r->getUserInfo()."\n";
if(is_array($r)) print_r($r);
echo"\n";
?>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,4 @@
<?php
header ("location: ../");
exit;
?>

View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<audioClip>
<metadata
xmlns="http://mdlf.org/livesupport/elements/1.0/"
xmlns:ls="http://mdlf.org/livesupport/elements/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
>
<dc:title>File Title txt</dc:title>
<dcterms:alternative>Alternative File Title ín sőmé %$#@* LÁNGŰAGÉ</dcterms:alternative>
<dc:subject>Keywords: qwe, asd, zcx</dc:subject>
<dc:description>Abstract txt</dc:description>
<dc:date>2004-05-21</dc:date>
<ls:genre>Folk</ls:genre>
<dc:format>audio/mpeg</dc:format>
<dcterms:extent>00:00:03.000000</dcterms:extent>
<!-- <dcterms:medium>online</dcterms:medium>-->
<dc:identifier>gunid here</dc:identifier>
<dcterms:spatial>Spatial Coverage</dcterms:spatial>
<dcterms:temporal>Temporal Covarage</dcterms:temporal>
<dc:creator>János Kőbor</dc:creator>
</metadata>
</audioClip>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<audioClip>
<metadata
xmlns="http://mdlf.org/livesupport/elements/1.0/"
xmlns:ls="http://mdlf.org/livesupport/elements/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
>
<dc:title>one</dc:title>
<dcterms:extent>00:00:11.000000</dcterms:extent>
</metadata>
</audioClip>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<audioClip>
<metadata
xmlns="http://mdlf.org/livesupport/elements/1.0/"
xmlns:ls="http://mdlf.org/livesupport/elements/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
>
<dc:title >two</dc:title>
<dcterms:extent >00:00:12.200000</dcterms:extent>
</metadata>
</audioClip>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<audioClip>
<metadata
xmlns="http://mdlf.org/livesupport/elements/1.0/"
xmlns:ls="http://mdlf.org/livesupport/elements/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
>
<dc:title>three</dc:title>
<dcterms:extent>00:00:11.500000</dcterms:extent>
</metadata>
</audioClip>

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<audioClip>
<metadata
xmlns="http://mdlf.org/livesupport/elements/1.0/"
xmlns:ls="http://mdlf.org/livesupport/elements/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
>
<dc:title >File2 Title txt</dc:title>
<dcterms:alternative >Alternative File2 Title txt</dcterms:alternative>
<dc:subject >Keywords: qwe, asd, zcx</dc:subject>
<dc:description >Abstract txt</dc:description>
<dc:date >2004-05-21</dc:date>
<dc:format>audio/mpeg</dc:format>
<dcterms:extent >00:10:00.000000</dcterms:extent>
<!-- <dcterms:medium >online</dcterms:medium>-->
<dc:identifier >gunid here</dc:identifier>
<dcterms:spatial >Spatial Coverage</dcterms:spatial>
<dcterms:temporal >Temporal Covarage</dcterms:temporal>
<dc:creator>John X2</dc:creator>
</metadata>
</audioClip>

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<audioClip>
<metadata
xmlns="http://mdlf.org/livesupport/elements/1.0/"
xmlns:ls="http://mdlf.org/livesupport/elements/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
>
<dc:title >Fil Title3 txt</dc:title>
<dcterms:alternative >Alternative File Title txt</dcterms:alternative>
<dcterms:extent >00:01:00.000000</dcterms:extent>
<dc:creator>John Y</dc:creator>
</metadata>
</audioClip>

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<audioClip>
<metadata
xmlns="http://mdlf.org/livesupport/elements/1.0/"
xmlns:ls="http://mdlf.org/livesupport/elements/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
>
<dc:title>File Title4 utf-8</dc:title>
<dcterms:alternative>ěščřžýáíé ĚŠČŘŽÝÁÍÉ úůÚŮ ďťňĎŤŇ é</dcterms:alternative>
<dcterms:extent>00:00:10.000000</dcterms:extent>
<dc:creator>John Y</dc:creator>
</metadata>
</audioClip>

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<playlist id="0000000000000001" playlength="01:30:00.000000"
title="My First Playlist">
<playlistElement id="0000000000000101" relativeOffset="0" >
<audioClip id="0000000000010001" playlength="01:00:00.000000"
title="one"/>
<fadeInfo fadeIn="02.000000" fadeOut="03.000000"
id="15015b4b70a054f1" />
</playlistElement>
<playlistElement id="0000000000000102" relativeOffset="01:00:00.000000" >
<audioClip id="0000000000010002" playlength="00:30:00.000000"
title="two"/>
<fadeInfo fadeIn="03.000000" fadeOut="00.000000"
id="15015b4b70a054f2" />
</playlistElement>
<metadata
xmlns="http://mdlf.org/livesupport/elements/1.0/"
xmlns:ls="http://mdlf.org/livesupport/elements/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
>
<dc:title>My First Playlist</dc:title>
<dc:creator>Me, myself and I</dc:creator>
<dcterms:extent>01:30:00.000000</dcterms:extent>
</metadata>
</playlist>

View file

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8" ?>
<playlist id="0000000000000002"
title="My Second Playlist"
playlength="00:00:29.700000" >
<playlistElement id="0000000000000101"
relativeOffset="0" >
<audioClip id="0000000000010001"
playlength="00:00:11"
title = "one"
uri="file:var/test10001.mp3" />
<fadeInfo id="0000000000009901"
fadeIn="0"
fadeOut="00:00:05" />
</playlistElement>
<playlistElement id="0000000000000102"
relativeOffset="00:00:06" >
<audioClip id="0000000000010002"
playlength="00:00:12.200000"
title = "two"
uri="file:var/test10002.mp3" />
<fadeInfo id="0000000000009902"
fadeIn="00:00:05"
fadeOut="0" />
</playlistElement>
<playlistElement id="0000000000000103"
relativeOffset="00:00:18.200000" >
<audioClip id="0000000000010003"
playlength="00:00:11.500000"
title = "three"
uri="file:var/test10003.mp3" />
<fadeInfo id="0000000000009903"
fadeIn="00:00:03"
fadeOut="00:00:03" />
</playlistElement>
<metadata xmlns="http://mdlf.org/livesupport/elements/1.0/"
xmlns:ls="http://mdlf.org/livesupport/elements/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:xml="http://www.w3.org/XML/1998/namespace" >
<dc:title>My Second Playlist</dc:title>
<dc:creator>Nobody</dc:creator>
<dcterms:extent>00:00:29.700000</dcterms:extent>
</metadata>
</playlist>

View file

@ -0,0 +1,26 @@
<?xml version="1.0"?>
<playlist id="0e22c20310212a51">
<playlistElement id="0000000000000103" relativeOffset="00:00:00.000000" >
<audioClip id="0000000000010003"
playlength="00:00:11.500000"
title = "three"
uri="file:var/test10003.mp3"
/>
</playlistElement>
<playlistElement id="0000000000000104" relativeOffset="00:00:11.500000">
<playlist id="0000000000000001"
playlength="01:30:00.000000"
title="My First Playlist">
</playlist>
</playlistElement>
<metadata
xmlns="http://mdlf.org/livesupport/elements/1.0/"
xmlns:ls="http://mdlf.org/livesupport/elements/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/"
>
<dc:title>embedded playlist</dc:title>
<dcterms:extent>01:30:11.500000</dcterms:extent>
</metadata>
</playlist>

View file

@ -0,0 +1,59 @@
<?
$sampleData = array(
array(
'type' => 'audioclip',
'media' => '../tests/test10001.mp3',
'xml' => '../tests/mdata10001.xml',
'gunid' => '0000000000010001'
),
array(
'type' => 'audioclip',
'media' => '../tests/test10002.mp3',
'xml' => '../tests/mdata10002.xml',
'gunid' => '0000000000010002'
),
array(
'type' => 'audioclip',
'media' => '../tests/test10003.mp3',
'xml' => '../tests/mdata10003.xml',
'gunid' => '0000000000010003'
),
array(
'type' => 'audioclip',
'media' => '../tests/ex1.mp3',
'xml' => '../tests/mdata1.xml',
'gunid' => '123456789abcdef1'
),
array(
'type' => 'audioclip',
'media' => '../tests/ex2.ogg',
'xml' => '../tests/mdata2.xml',
'gunid' => '123456789abcdef2'
),
array(
'type' => 'audioclip',
'media' => '../tests/ex3.wav',
'xml' => '../tests/mdata3.xml'
),
array(
'type' => 'playlist',
'xml' => '../tests/plist1.xml',
'gunid' => '0000000000000001'
),
array(
'type' => 'playlist',
'xml' => '../tests/plist2.xml',
'gunid' => '0000000000000002'
),
array(
'type' => 'playlist',
'xml' => '../tests/plistEmbedded.xml',
'gunid' => '0000000000000003'
),
array(
'type' => 'webstream',
'xml' => '../tests/wstream1.xml',
'gunid' => 'f000000000000001'
)
);
?>

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE testStorage [
<!ELEMENT testStorage (playlist*) >
<!ELEMENT playlist EMPTY >
<!ATTLIST playlist id NMTOKEN #REQUIRED >
<!ATTLIST playlist playlength NMTOKEN #REQUIRED >
]>
<testStorage>
<playlist id="1" playlength="01:30:00.00"/>
</testStorage>

View file

@ -0,0 +1,179 @@
<?php
header("Content-type: text/plain");
echo "\n# Transport test:\n";
require_once '../conf.php';
require_once 'DB.php';
require_once '../GreenBox.php';
require_once '../LocStor.php';
#PEAR::setErrorHandling(PEAR_ERROR_PRINT, "%s<hr>\n");
PEAR::setErrorHandling(PEAR_ERROR_RETURN);
$dbc = DB::connect($config['dsn'], TRUE);
$dbc->setFetchMode(DB_FETCHMODE_ASSOC);
$gb = &new GreenBox($dbc, $config);
$tr = &new Transport($gb);
$ls = &new LocStor($dbc, $config);
@unlink("{$tr->transDir}/activity.log");
@unlink("{$tr->transDir}/debug.log");
$tr->_cleanUp();
$gunid = 'a23456789abcdefb';
$mediaFile = '../tests/ex1.mp3';
$mdataFile = '../tests/mdata1.xml';
/* ========== PING ========== */
/*
echo"# Login: ".($sessid = $gb->login('root', 'q'))."\n";
echo"# Ping: ";
$r = $tr->pingToArchive();
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."\n"; exit(1); }
var_export($r); echo"\n";
echo"# logout: "; $r = $gb->logout($sessid);
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."\n"; exit(1); }
echo "$r\n";
*/
/* ========== STORE ========== */
echo"# Login: ".($sessid = $gb->login('root', 'q'))."\n";
echo"# Store: ";
$parid = $gb->_getHomeDirIdFromSess($sessid);
$oid = $r = $gb->bsPutFile($parid, "xx1.mp3", $mediaFile, $mdataFile, $gunid, 'audioclip');
if(PEAR::isError($r)){ if($r->getCode()!=GBERR_GUNID){ echo "ERROR: ".$r->getMessage()."\n"; exit(1); }}
$comm = "ls -l {$gb->storageDir}/a23"; echo `$comm`;
echo "$oid\n";
/* ========== DELETE FROM HUB ========== */
echo"# loginToArchive: ";
$r = $tr->loginToArchive();
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()." / ".$r->getUserInfo()."\n"; exit(1); }
echo "{$r['sessid']}\n";
$asessid = $r['sessid'];
echo"# deleteAudioClip on Hub: ";
$r = $tr->xmlrpcCall(
'archive.deleteAudioClip',
array(
'sessid' => $asessid,
'gunid' => $gunid,
'forced' => TRUE,
)
);
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()." / ".$r->getUserInfo()."\n"; if($r->getCode()!=800+GBERR_FILENEX) exit(1); }
else{ echo " {$r['status']}\n"; }
echo"# logoutFromArchive: ";
$r = $tr->logoutFromArchive($asessid);
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()." / ".$r->getUserInfo()."\n"; exit(1); }
var_export($r); echo"\n";
/* ========== UPLOAD ========== */
echo "# UPLOAD test:\n";
echo"# uploadAudioClip2Hub: ";
$r = $gb->upload2Hub($gunid);
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."/".$r->getUserInfo()."\n"; exit(1); }
var_export($r); echo"\n";
$trtok = $r;
echo"# logout: "; $r = $gb->logout($sessid);
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."/".$r->getUserInfo()."\n"; exit(1); }
echo "$r\n";
/*
*/
#$trtok='280a6f1c18389620';
for($state='', $nu=1; ($state!='closed' && $state!='failed' && $nu<=12); $nu++, sleep(2)){
/*
echo"# $nu: Transport: cronMain: "; $r = $tr->cronMain();
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."/".$r->getUserInfo()."\n"; exit(1); }
var_export($r); echo"\n";
*/
echo"# getTransportInfo: "; $r = $gb->getTransportInfo($trtok);
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."/".$r->getUserInfo()."\n"; exit(1); }
$state = $r['state'];
echo "# state=$state, title={$r['title']}\n";
}
if($state=='failed') exit(1);
/* === DELETE LOCAL === */
echo"# Login: ".($sessid = $gb->login('root', 'q'))."\n";
echo"# Delete: "; $r = $ls->deleteAudioClip($sessid, $gunid, TRUE);
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."\n"; exit(1); }
echo "$r\n";
echo"# logout: "; $r = $gb->logout($sessid);
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."\n"; exit(1); }
echo "$r\n";
$comm = "ls -l {$gb->storageDir}/a23"; echo `$comm`;
/*
*/
#echo"TMPEND\n"; exit;
#echo `tail -n 25 ../trans/log`; exit;
#$sleeptime=10; echo "sleep $sleeptime\n"; sleep($sleeptime);
/* === DOWNLOAD === */
echo "# DOWNLOAD test:\n";
echo"# Login: ".($sessid = $gb->login('root', 'q'))."\n";
echo"# downloadAudioClipFromHub: ";
$r = $gb->downloadFromHub($sessid, $gunid);
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."/".$r->getUserInfo()."\n"; exit(1); }
var_export($r); echo"\n";
$trtok = $r;
echo"# logout: "; $r = $gb->logout($sessid);
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."\n"; exit(1); }
echo "$r\n";
for($state='', $nu=1; ($state!='closed' && $state!='failed' && $nu<=12); $nu++, sleep(2)){
/*
echo"# $nu: Transport: cronMain: "; $r = $tr->cronMain();
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."/".$r->getUserInfo()."\n"; exit(1); }
var_export($r); echo"\n";
*/
echo"# getTransportInfo: "; $r = $gb->getTransportInfo($trtok);
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."/".$r->getUserInfo()."\n"; exit(1); }
$state = $r['state'];
echo "# state=$state, title={$r['title']}\n";
}
if($state=='failed') exit(1);
$comm = "ls -l {$gb->storageDir}/a23"; echo `$comm`;
/*
*/
/*
echo"# Login: ".($sessid = $gb->login('root', 'q'))."\n";
echo"# Delete: "; $r = $ls->deleteAudioClip($sessid, $gunid, TRUE);
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."\n"; exit(1); }
echo "$r\n";
echo"# logout: "; $r = $gb->logout($sessid);
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."\n"; exit(1); }
echo "$r\n";
*/
#echo `tail -n 20 ../trans/log`; exit;
/*
echo"# Transport loginToArchive: "; $r = $tr->loginToArchive();
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."\n"; exit(1); }
var_export($r['sessid']); echo"\n";
echo"# Transport logoutFromArchive: "; $r = $tr->logoutFromArchive($r['sessid']);
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."\n"; exit(1); }
var_export($r['status']); echo"\n";
echo"# Ping: ";
$r = $tr->pingToArchive();
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."\n"; exit(1); }
var_export($r); echo"\n";
echo"# Delete: "; $r = $gb->deleteAudioClip($sessid, $gunid);
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."\n"; exit(1); }
echo "$r\n";
*/
if(file_exists("../trans/log")) echo `tail -n 25 ../trans/log`;
echo "#Transport test: OK.\n\n"
?>

View file

@ -0,0 +1,227 @@
#!/bin/bash
#-------------------------------------------------------------------------------
# Copyright (c) 2004 Media Development Loan Fund
#
# This file is part of the Campcaster project.
# http://campcaster.campware.org/
# To report bugs, send an e-mail to bugs@campware.org
#
# Campcaster 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.
#
# Campcaster 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 Campcaster; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
# Author : $Author$
# Version : $Revision$
# Location : $URL$
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# This script call locstor.resetStorage XMLRPC method
#-------------------------------------------------------------------------------
reldir=`dirname $0`/../..
WWW_ROOT=`cd $reldir/var/install; php -q getWwwRoot.php` || exit $?
echo "#Transport test: URL: $WWW_ROOT"
#$reldir/var/xmlrpc/xr_cli_test.py -s $WWW_ROOT/xmlrpc/xrLocStor.php \
# resetStorage || exit $?
cd $reldir/var/xmlrpc
XR_CLI="php -q xr_cli_test.php -s $WWW_ROOT/xmlrpc/xrLocStor.php"
#-------------------------------------------------------------------------------
# storage related functions
#-------------------------------------------------------------------------------
login() {
echo -n "# login: "
SESSID=`$XR_CLI login root q` || \
{ ERN=$?; echo $SESSID; exit $ERN; }
echo "sessid: $SESSID"
}
storeOpenClose() {
GUNID=$1 ; shift
[[ "x$1" != "x" ]] && MEDIA="$1" || MEDIA="../tests/ex1.mp3"
shift
[[ "x$1" != "x" ]] && METADATA=`cat "$1"` || METADATA="<?xml version=\"1.0\"?>
<audioClip><metadata xmlns=\"http://www.streamonthefly.org/\"
xmlns:dc=\"http://purl.org/dc/elements/1.1/\"
xmlns:dcterms=\"http://purl.org/dc/terms/\">
<dcterms:extent>00:00:11.000000</dcterms:extent>
<dc:title>Transport test file 1</dc:title>
</metadata></audioClip>"
#echo "# store: gunid=$GUNID mediafile=$MEDIA metadata=$METADATA"
echo "# store: "
MD5=`md5sum $MEDIA`; for i in $MD5; do MD5=$i; break; done
RES=`$XR_CLI storeAudioClipOpen "$SESSID" "$GUNID" "$METADATA" "stored_file.mp3" "$MD5"` || \
{ ERN=$?; echo $RES; exit $ERN; }
unset URL
for i in $RES; do if [ -z $URL ] ; then URL=$i; else TOKEN=$i; fi; done
echo " URL = $URL"
echo " TOKEN = $TOKEN"
echo -n "# curl (PUT): "
curl -C 0 -T $MEDIA $URL || exit $?
echo "status: $?"
echo -n "# storeAudioClipClose: "
GUNID=`$XR_CLI storeAudioClipClose "$SESSID" "$TOKEN"` || \
{ ERN=$?; echo $GUNID; exit $ERN; }
echo $GUNID
}
deleteAudioClip() {
GUNID=$1 ; shift
echo -n "# deleteAudioClip: "
$XR_CLI deleteAudioClip $SESSID $GUNID 1
}
#-------------------------------------------------------------------------------
# transport related functions
#-------------------------------------------------------------------------------
getTransportInfo() {
TRTOK=$1 ; shift
echo "# getTransportInfo:"
$XR_CLI getTransportInfo $TRTOK
echo "# status: $?"
}
upload2Hub() {
GUNID=$1 ; shift
echo -n "# upload2Hub: ($GUNID)"
TRTOK=`$XR_CLI upload2Hub $SESSID $GUNID` || \
{ ERN=$?; echo $TRTOK; exit $ERN; }
echo $TRTOK
}
downloadFromHub() {
GUNID=$1 ; shift
echo -n "# downloadFromHub: ($GUNID)"
TRTOK=`$XR_CLI downloadFromHub $SESSID $GUNID` || \
{ ERN=$?; echo $TRTOK; exit $ERN; }
echo $TRTOK
}
uploadFile2Hub() {
FILE=$1 ; shift
echo -n "# uploadFile2Hub: "
TRTOK=`$XR_CLI uploadFile2Hub $SESSID $FILE` || \
{ ERN=$?; echo $TRTOK; exit $ERN; }
echo $TRTOK
}
getHubInitiatedTransfers() {
echo -n "# getHubInitiatedTransfers: "
TRTOK=`$XR_CLI getHubInitiatedTransfers $SESSID` || \
{ ERN=$?; echo $TRTOK; exit $ERN; }
echo $TRTOK
}
startHubInitiatedTransfer() {
TRTOK=$1 ; shift
echo -n "# startHubInitiatedTransfer: "
RES=`$XR_CLI startHubInitiatedTransfer $TRTOK` || \
{ ERN=$?; echo $TRTOK; exit $ERN; }
echo $RES
}
transportCron() {
echo -n "# transportCron: "
../cron/transportCron.php
echo $?
}
logout() {
echo -n "# logout: "
$XR_CLI logout $SESSID || exit $?
}
#-------------------------------------------------------------------------------
# playlist related functions
#-------------------------------------------------------------------------------
PLID="123456789abcdef8"
createPlaylistAndEdit() {
PLID=$1 ; shift
echo -n "# createPlaylist: "
$XR_CLI createPlaylist $SESSID $PLID "newPlaylist.xml" || exit $?
DATE=`date '+%H:%M:%S'`
[[ "x$1" != "x" ]] && PLAYLIST=`cat "$1"` || PLAYLIST="<?xml
version=\"1.0\" encoding=\"UTF-8\"?>
<playlist id=\"123456789abcdea1\"><metadata>
<dc:title>XY $DATE</dc:title>
<dcterms:extent>00:00:01.000000</dcterms:extent>
</metadata>
<playlistElement id=\"123456789abcdef1\" relativeOffset=\"0\">
<audioClip id=\"123456789abcdefa\"/>
</playlistElement>
<playlistElement id=\"123456789abcdef2\" relativeOffset=\"12\">
<audioClip id=\"123456789abcdefb\"/>
</playlistElement>
</playlist>"
echo -n "# editPlaylist: "
RES=`$XR_CLI editPlaylist $SESSID $PLID` || \
{ ERN=$?; echo $RES; exit $ERN; }
unset URL
for i in $RES; do if [ -z $URL ] ; then URL=$i; else TOKEN=$i; fi; done
echo $TOKEN
# deletePlaylist
if [ $DEBUG_I ]; then echo $URL; fi
if [ $DEBUG_I ]; then echo -n "Press enter ..."; read KEY; fi
if [ $DEBUG_I ]; then echo " Playlist:"; echo $PLAYLIST; fi
echo -n "# savePlaylist: "
$XR_CLI savePlaylist $SESSID $TOKEN "$PLAYLIST" || exit $?
}
deletePlaylist() {
PLID=$1 ; shift
echo -n "# deletePlaylist (${PLID}): "
$XR_CLI deletePlaylist $SESSID $PLID 1
# || exit $?
echo "# status: $?"
}
#-------------------------------------------------------------------------------
# executable part
#-------------------------------------------------------------------------------
GUNID_="a23456789abcdef3"
PLID_=$GUNID_
MEDIA_="../tests/ex1.mp3"
login
for i in 0000000000010001 0000000000010002; do echo $i
storeOpenClose $i "../tests/$i" "../tests/$i.xml"
done
deletePlaylist $PLID_
deletePlaylist $PLID_
createPlaylistAndEdit $PLID_ "../tests/0000000000000001.xml"
upload2Hub $PLID_
for i in $(seq 5); do getTransportInfo $TRTOK; sleep 1; done
#sleep 10
for i in 0000000000010001 0000000000010002; do echo $i
deleteAudioClip $i
done
deletePlaylist $PLID_
echo "STOP - press ENTER"; read key
downloadFromHub $PLID_
for i in $(seq 5); do getTransportInfo $TRTOK; sleep 1; done
logout
echo "#Transport test: OK"
exit 0

View file

@ -0,0 +1,43 @@
<?php
header("Content-type: text/plain");
echo "\n#StorageServer storeWebstream test:\n";
require_once '../conf.php';
require_once 'DB.php';
require_once '../GreenBox.php';
#PEAR::setErrorHandling(PEAR_ERROR_PRINT, "%s<hr>\n");
PEAR::setErrorHandling(PEAR_ERROR_RETURN);
$dbc = DB::connect($config['dsn'], TRUE);
$dbc->setFetchMode(DB_FETCHMODE_ASSOC);
$gb = &new GreenBox($dbc, $config);
#$gunid = "123456789abcdee0";
$gunid = "";
#$mdataFileLP = '../tests/mdata1.xml';
$mdataFileLP = NULL;
echo"# Login: ".($sessid = $gb->login('root', 'q'))."\n";
$parid = $gb->_getHomeDirId($sessid);
echo"# storeWebstream: "; $r = $gb->storeWebstream(
$parid, 'test stream', $mdataFileLP, $sessid, $gunid, 'http://localhost/y');
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()." ".$r->getUserInfo()."\n"; exit(1); }
echo ""; var_dump($r);
#$id = $gb->_idFromGunid($gunid);
$id = $r;
echo"# getMdata: "; $r = $gb->getMdata($id, $sessid);
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()." ".$r->getUserInfo()."\n"; exit(1); }
echo "\n$r\n";
echo"# deleteFile: "; $r = $gb->deleteFile($id, $sessid);
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()." ".$r->getUserInfo()."\n"; exit(1); }
echo "\n$r\n";
echo"# logout: "; $r = $gb->logout($sessid);
if(PEAR::isError($r)){ echo "ERROR: ".$r->getMessage()."\n"; exit(1); }
echo "$r\n";
echo "#storeWebstream test: OK.\n\n"
?>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<audioClip>
<metadata
xmlns="http://mdlf.org/livesupport/elements/1.0/"
xmlns:ls="http://mdlf.org/livesupport/elements/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
>
<dc:title>Webstream test 1</dc:title>
<dcterms:extent>01:30:00.000000</dcterms:extent>
<ls:url>http://localhost/y</ls:url>
</metadata>
</audioClip>

View file

@ -0,0 +1,345 @@
<?php
/**
* @author $Author$
* @version $Revision$
*/
$webstreamFormat = array(
'_root'=>'audioClip',
'audioClip'=>array(
'childs'=>array(
'required'=>array('metadata'),
),
),
'metadata'=>array(
'childs'=>array(
'required'=>array(
'dc:title', 'dcterms:extent', 'ls:url'
),
'optional'=>array(
'dc:identifier',
'dc:creator', 'dc:source', 'ls:genre',
'ls:year', 'dc:type', 'dc:description', 'dc:format',
'ls:bpm', 'ls:rating', 'ls:encoded_by', 'ls:track_num',
'ls:disc_num', 'ls:disc_num', 'dc:publisher', 'ls:composer',
'ls:bitrate', 'ls:channels', 'ls:samplerate', 'ls:encoder',
'ls:crc', 'ls:lyrics', 'ls:orchestra', 'ls:conductor',
'ls:lyricist', 'ls:originallyricist', 'ls:radiostationname',
'ls:audiofileinfourl', 'ls:artisturl', 'ls:audiosourceurl',
'ls:radiostationurl', 'ls:buycdurl', 'ls:isrcnumber',
'ls:catalognumber', 'ls:originalartist', 'dc:rights',
'ls:license', 'dc:title', 'dcterms:temporal',
'dcterms:spatial', 'dcterms:entity', 'dc:description',
'dc:creator', 'dc:subject', 'dc:type', 'dc:format',
'dc:contributor', 'dc:language', 'dc:rights',
'dcterms:isPartOf', 'dc:date',
'dc:publisher',
// extra
'dcterms:alternative', 'ls:filename', 'ls:mtime',
// added lately by sebastian
'ls:mood',
),
),
'namespaces'=>array(
'dc'=>"http://purl.org/dc/elements/1.1/",
'dcterms'=>"http://purl.org/dc/terms/",
'xbmf'=>"http://www.streamonthefly.org/xbmf",
'xsi'=>"http://www.w3.org/2001/XMLSchema-instance",
'xml'=>"http://www.w3.org/XML/1998/namespace",
),
),
'ls:url'=>array(
'type'=>'URL',
),
'dc:identifier'=>array(
'type'=>'Text',
'auto'=>TRUE,
),
'dc:title'=>array(
'type'=>'Text',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dcterms:alternative'=>array(
'type'=>'Text',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dcterms:extent'=>array(
'type'=>'Time',
'regexp'=>'^\d{2}:\d{2}:\d{2}.\d{6}$',
),
'dc:creator'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:source'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:genre'=>array(
'type'=>'Menu',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:year'=>array(
'type'=>'Menu',
'area'=>'Music',
),
'dc:type'=>array(
'type'=>'Menu',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:description'=>array(
'type'=>'Longtext',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:format'=>array(
'type'=>'Menu',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:bpm'=>array(
'type'=>'Number',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:rating'=>array(
'type'=>'Number',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:encoded_by'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:track_num'=>array(
'type'=>'Menu',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:disc_num'=>array(
'type'=>'Menu',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:disc_num'=>array(
'type'=>'Menu',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:publisher'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:composer'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:bitrate'=>array(
'type'=>'Number',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:channels'=>array(
'type'=>'Menu',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:samplerate'=>array(
'type'=>'Menu',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:encoder'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:crc'=>array(
'type'=>'Number',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:lyrics'=>array(
'type'=>'Longtext',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:orchestra'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:conductor'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:lyricist'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:originallyricist'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:radiostationname'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:audiofileinfourl'=>array(
'type'=>'URL',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:artisturl'=>array(
'type'=>'URL',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:audiosourceurl'=>array(
'type'=>'URL',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:radiostationurl'=>array(
'type'=>'URL',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:buycdurl'=>array(
'type'=>'URL',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:isrcnumber'=>array(
'type'=>'Number',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:catalognumber'=>array(
'type'=>'Number',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:originalartist'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:rights'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:license'=>array(
'type'=>'Text',
'area'=>'Music',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:title'=>array(
'type'=>'Text',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dcterms:temporal'=>array(
'type'=>'Time/Date',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dcterms:spatial'=>array(
'type'=>'Menu',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dcterms:entity'=>array(
'type'=>'Text',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:description'=>array(
'type'=>'Longtext',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:creator'=>array(
'type'=>'Menu',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:subject'=>array(
'type'=>'Text',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:type'=>array(
'type'=>'Menu',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:format'=>array(
'type'=>'Menu',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:contributor'=>array(
'type'=>'Text',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:language'=>array(
'type'=>'Menu',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:rights'=>array(
'type'=>'Menu',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dcterms:isPartOf'=>array(
'type'=>'Text',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:date'=>array(
'type'=>'Date',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'dc:publisher'=>array(
'type'=>'Text',
'area'=>'Talk',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:filename'=>array(
'type'=>'Text',
'attrs'=>array('implied'=>array('xml:lang')),
),
'ls:mtime'=>array(
'type'=>'Int',
// 'regexp'=>'^\d{4}(-\d{2}(-\d{2}(T\d{2}:\d{2}(:\d{2}\.\d+)?(Z)|([\+\-]?\d{2}:\d{2}))?)?)?$',
),
/*
''=>array(
'type'=>'',
'area'=>'',
'attrs'=>array(),
),
*/
);
/*
?
ls:filename Text auto
*/
?>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,4 @@
<?php
header ("location: xrLocStor.php");
exit;
?>

View file

@ -0,0 +1,81 @@
<?php
/**
* \file put.php
* Store PUT data as temporary file.
*
* put.php is remote callable script through HTTP PUT method.
* Requires token returned by appropriate storageServer XMLRPC call.
* Appropriate closing XMLRPC call should follow.
*
* This script accepts following HTTP GET parameter:
* <ul>
* <li>token : string, put token returned by appropriate
* XMLRPC call</li>
* </ul>
*
* On success, returns HTTP return code 200.
*
* On errors, returns HTTP return code &gt;200
* The possible error codes are:
* <ul>
* <li> 400 - Incorrect parameters passed to method</li>
* <li> 403 - Access denied</li>
* <li> 500 - Application error</li>
* </ul>
*
* @see XR_LocStor
* @author : $Author$
* @version : $Revision$
*/
require_once dirname(__FILE__).'/../conf.php';
require_once 'DB.php';
require_once dirname(__FILE__).'/../LocStor.php';
PEAR::setErrorHandling(PEAR_ERROR_RETURN);
$dbc = DB::connect($config['dsn'], TRUE);
$dbc->setFetchMode(DB_FETCHMODE_ASSOC);
$gb = &new LocStor($dbc, $config);
function http_error($code, $err){
header("HTTP/1.1 $code");
header("Content-type: text/plain; charset=UTF-8");
echo "$err\r\n";
exit;
}
if(preg_match("|^[0-9a-fA-F]{16}$|", $_REQUEST['token'])){
$token = $_REQUEST['token'];
}else{
http_error(400, "Error on token parameter. ({$_REQUEST['token']})");
}
$tc = $gb->bsCheckToken($token, 'put');
if(PEAR::isError($tc)){ http_error(500, $ex->getMessage()); }
if(!$tc){ http_error(403, "put.php: Token not valid ($token)."); }
#var_dump($tc); exit;
header("Content-type: text/plain");
#var_dump($_SERVER); var_dump($_REQUEST); exit;
$destfile = "{$config['accessDir']}/{$token}";
/* PUT data comes in on the input stream */
$putdata = @fopen("php://input", "r") or
http_error(500, "put.php: Can't read input");
/* Open a file for writing */
$fp = @fopen($destfile, "ab") or
http_error(500, "put.php: Can't write to destination file (token=$token)");
/* Read the data 1 KB at a time and write to the file */
while ($data = fread($putdata, 1024)){
fwrite($fp, $data);
}
/* Close the streams */
fclose($fp);
fclose($putdata);
header("HTTP/1.1 200");
?>

View file

@ -0,0 +1,507 @@
<?php
/**
* @author $Author$
* @version $Revision$
*/
/* ================================================================= includes */
include_once dirname(__FILE__)."/../conf.php";
require_once 'DB.php';
include_once "XML/RPC.php";
/* ================================================== method definition array */
/**
* Array with methods description
*
* Each element has method name as key and contains four subfields:
* <ul>
* <li>m</li> full method name (include optional prefix)
* <li>p</li> array of input parameter names
* <li>t</li> array of input parameter types
* <li>r</li> array of result element names (not used there at present)
* <li>e</li> array of error codes/messages (not used there at present)
* </ul>
*/
$mdefs = array(
"listMethods" => array('m'=>"system.listMethods", 'p'=>NULL, 't'=>NULL),
"AddAudioClipToPlaylistMethod" => array(
'm'=>'addAudioClipToPlaylist',
'p'=>array('sessionId'/*string*/, 'playlistId'/*string*/, 'audioClipId'/*string*/, 'relativeOffset'/*int*/),
't'=>array('string', 'string', 'string', 'int'),
'r'=>array('playlistElementId'/*string*/),
'e'=>array(
'301'=>'invalid argument format',
'302'=>'missing playlist ID argument',
'303'=>'missing audio clip ID argument',
'304'=>'missing relative offset argument',
'305'=>'playlist not found',
'306'=>'playlist has not been opened for editing',
'307'=>'audio clip does not exist',
'308'=>'two audio clips at the same relative offset',
'320'=>'missing session ID argument',
)
),
"CreatePlaylistMethod" => array(
'm'=>'createPlaylist',
'p'=>array('sessionId'/*string*/),
't'=>array('string'),
'r'=>array('playlist'/*string*/),
'e'=>array(
'201'=>'invalid argument format',
'202'=>'could not create playlist',
'220'=>'missing session ID argument',
)
),
"DeletePlaylistMethod" => array(
'm'=>'deletePlaylist',
'p'=>array('sessionId'/*string*/, 'playlistId'/*string*/),
't'=>array('string', 'string'),
'r'=>array(),
'e'=>array(
'901'=>'invalid argument format',
'902'=>'missing playlist ID argument',
'903'=>'playlist not found',
'904'=>'playlist is locked',
'905'=>'playlist could not be deleted',
'920'=>'missing session ID argument',
)
),
"DisplayAudioClipMethod" => array(
'm'=>'displayAudioClip',
'p'=>array('sessionId'/*string*/, 'audioClipId'/*string*/),
't'=>array('string', 'string'),
'r'=>array('audioClip'/*string*/),
'e'=>array(
'601'=>'invalid argument format',
'602'=>'argument is not an audio clip ID',
'603'=>'audio clip not found',
'620'=>'missing session ID argument',
)
),
"DisplayAudioClipsMethod" => array(
'm'=>'displayAudioClips',
'p'=>array('sessionId'/*string*/),
't'=>array('string'),
'r'=>array(array('audioClip'/*string*/)),
'e'=>array(
'1801'=>'invalid argument format',
'1802'=>'XML-RPC error',
'1820'=>'missing session ID argument',
)
),
"DisplayPlaylistMethod" => array(
'm'=>'displayPlaylist',
'p'=>array('sessionId'/*string*/, 'playlistId'/*string*/),
't'=>array('string', 'string'),
'r'=>array('playlist'/*string*/),
'e'=>array(
'1001'=>'invalid argument format',
'1002'=>'argument is not a playlist ID',
'1003'=>'playlist not found',
'1020'=>'missing session ID argument',
)
),
"DisplayPlaylistsMethod" => array(
'm'=>'displayPlaylists',
'p'=>array('sessionId'/*string*/),
't'=>array('string'),
'r'=>array(array('playlist'/*string*/)),
'e'=>array(
'1701'=>'invalid argument format',
'1702'=>'XML-RPC error',
'1720'=>'missing session ID argument',
)
),
"DisplayScheduleMethod" => array(
'm'=>'displaySchedule',
'p'=>array('sessionId'/*string*/, 'from'/*datetime*/, 'to'/*datetime*/),
't'=>array('string', 'dateTime.iso8601', 'dateTime.iso8601'),
'r'=>array(array('id'/*int*/, 'playlistId'/*string*/, 'start'/*datetime*/, 'end'/*datetime*/)),
'e'=>array(
'1101'=>'invalid argument format',
'1102'=>"missing or invalid 'from' argument",
'1103'=>"missing or invalid 'to' argument",
'1120'=>'missing session ID argument',
)
),
"GeneratePlayReportMethod" => array(
'm'=>'generatePlayReport',
'p'=>array('sessionId'/*string*/, 'from'/*datetime*/, 'to'/*datetime*/),
't'=>array('string', 'dateTime.iso8601', 'dateTime.iso8601'),
'r'=>array(array('audioClipId'/*string*/, 'timestamp'/*datetime*/)),
'e'=>array(
'1501'=>'invalid argument format',
'1502'=>"missing or invalid 'from' argument",
'1503'=>"missing or invalid 'to' argument",
'1520'=>'missing session ID argument',
)
),
"GetSchedulerTimeMethod" => array(
'm'=>'getSchedulerTime',
'p'=>array(),
't'=>array(),
'r'=>array('schedulerTime'/*datetime*/),
'e'=>array(
)
),
"GetVersionMethod" => array(
'm'=>'getVersion',
'p'=>array(),
't'=>array(),
'r'=>array('version'/*string*/),
'e'=>array()
),
"LoginMethod" => array(
'm'=>'login',
'p'=>array('login'/*string*/, 'password'/*string*/),
't'=>array('string', 'string'),
'r'=>array('sessionId'/*string*/),
'e'=>array(
'2001'=>'invalid argument format',
'2002'=>'missing login argument',
'2003'=>'missing password argument',
'2004'=>'the authentication server reported an error',
)
),
"LogoutMethod" => array(
'm'=>'logout',
'p'=>array('sessionId'/*string*/),
't'=>array('string'),
'r'=>array(),
'e'=>array(
'2101'=>'invalid argument format',
'2120'=>'missing session ID argument',
'2104'=>'the authentication server reported an error',
)
),
"OpenPlaylistForEditingMethod" => array(
'm'=>'openPlaylistForEditing',
'p'=>array('sessionId'/*string*/, 'playlistId'/*string*/),
't'=>array('string', 'string'),
'r'=>array('playlist'/*string*/),
'e'=>array(
'101'=>'invalid argument format',
'102'=>'argument is not a playlist ID',
'104'=>'could not open playlist for editing',
'120'=>'missing session ID argument',
)
),
"RemoveAudioClipFromPlaylistMethod" => array(
'm'=>'removeAudioClipFromPlaylist',
'p'=>array('sessionId'/*string*/, 'playlistId'/*string*/, 'playlistElementId'/*string*/),
't'=>array('string', 'string', 'string'),
'r'=>array(),
'e'=>array(
'401'=>'invalid argument format',
'402'=>'missing playlist ID argument',
'403'=>'missing relative offset argument',
'404'=>'playlist does not exist',
'405'=>'playlist has not been opened for editing',
'406'=>'no audio clip at the specified relative offset',
'420'=>'missing session ID argument',
)
),
"RemoveFromScheduleMethod" => array(
'm'=>'removeFromSchedule',
'p'=>array('sessionId'/*string*/, 'scheduleEntryId'/*string*/),
't'=>array('string', 'string'),
'r'=>array(),
'e'=>array(
'1201'=>'invalid argument format',
'1202'=>'missing schedule entry ID argument',
'1203'=>'schedule entry not found',
'1220'=>'missing session ID argument',
)
),
"RescheduleMethod" => array(
'm'=>'reschedule',
'p'=>array('sessionId'/*string*/, 'scheduleEntryId'/*string*/, 'playtime'/*datetime*/),
't'=>array('string', 'string', 'dateTime.iso8601'),
'r'=>array(),
'e'=>array(
'1301'=>'invalid argument format',
'1302'=>'missing schedule entry ID argument',
'1303'=>'missing playtime argument',
'1304'=>'schedule entry not found',
'1305'=>'could not reschedule entry',
'1320'=>'missing session ID argument',
)
),
"ResetStorageMethod" => array(
'm'=>'resetStorage',
'p'=>array(),
't'=>array(),
'r'=>array(),
'e'=>array('3001'=>'storage client reported an error'),
),
"RevertEditedPlaylistMethod" => array(
'm'=>'revertEditedPlaylist',
'p'=>array('sessionId'/*string*/, 'playlistId'/*string*/),
't'=>array('string', 'string'),
'r'=>array(),
'e'=>array(
'801'=>'invalid argument format',
'802'=>'argument is not a playlist ID',
'803'=>'playlist not found',
'804'=>'could not revert playlist',
'820'=>'missing session ID argument',
)
),
"SavePlaylistMethod" => array(
'm'=>'savePlaylist',
'p'=>array('sessionId'/*string*/, 'playlistId'/*string*/),
't'=>array('string', 'string'),
'r'=>array(),
'e'=>array(
'701'=>'invalid argument format',
'702'=>'argument is not a playlist ID',
'703'=>'playlist not found',
'705'=>'could not save playlist',
'720'=>'missing session ID argument',
)
),
"UpdateFadeInFadeOutMethod" => array(
'm'=>'updateFadeInFadeOut',
'p'=>array('sessionId'/*string*/, 'playlistId'/*string*/, 'playlistElementId'/*string*/, 'fadeIn'/*int*/, 'fadeOut'/*int*/),
't'=>array('string', 'string', 'string', 'int', 'int'),
'r'=>array(),
'e'=>array(
'1601'=>'invalid argument format',
'1602'=>'missing playlist ID argument',
'1603'=>'missing playlist element ID argument',
'1604'=>'missing fade in argument',
'1605'=>'missing fade out argument',
'1606'=>'playlist does not exist',
'1607'=>'playlist has not been opened for editing',
'1608'=>'error executing setFadeInfo() method',
'1620'=>'missing session ID argument',
)
),
"UploadPlaylistMethod" => array(
'm'=>'uploadPlaylist',
'p'=>array('sessionId'/*string*/, 'playlistId'/*string*/, 'playtime'/*datetime*/),
't'=>array('string', 'string', 'dateTime.iso8601'),
'r'=>array('scheduleEntryId'/*string*/),
'e'=>array(
'1401'=>'invalid argument format',
'1402'=>'missing playlist ID argument',
'1403'=>'missing playtime argument',
'1404'=>'playlist not found',
'1405'=>'timeframe not available',
'1406'=>'could not schedule playlist',
'1420'=>'missing session ID argument',
)
),
"ValidatePlaylistMethod" => array(
'm'=>'validatePlaylist',
'p'=>array('sessionId'/*string*/, 'playlistId'/*string*/),
't'=>array('string', 'string'),
'r'=>array('valid'/*bool*/),
'e'=>array(
'501'=>'invalid argument format',
'502'=>'missing playlist ID argument',
'503'=>'playlist does not exist',
'504'=>'playlist has not been opened for editing',
'520'=>'missing session ID argument',
)
),
"LoginGB" => array(
'm'=>'locstor.login',
'p'=>array('login'/*string*/, 'pass'/*string*/),
't'=>array('string', 'string'),
'r'=>array('sessid'/*string*/),
'e'=>array(
'2001'=>'invalid argument format',
'2002'=>'missing login argument',
'2003'=>'missing password argument',
'2004'=>'the authentication server reported an error',
)
),
"LogoutGB" => array(
'm'=>'locstor.logout',
'p'=>array('sessid'/*string*/),
't'=>array('string'),
'r'=>array('status'/*boolean*/),
'e'=>array(
'2001'=>'invalid argument format',
'2002'=>'missing login argument',
'2003'=>'missing password argument',
'2004'=>'the authentication server reported an error',
)
),
);
/* ======================================================== class definitions */
class SchedulerPhpClient{
/**
* Databases object reference
*/
var $dbc = NULL;
/**
* Array with methods description
*/
var $mdefs = array();
/**
* Confiduration array from ../conf.php
*/
var $config = array();
/**
* XMLRPC client object reference
*/
var $client = NULL;
/**
* Verbosity flag
*/
var $verbose = FALSE;
/**
* XMLRPC debug flag
*/
var $debug = 0;
/**
* Constructor - pelase DON'T CALL IT, use factory method instead
*
* @param dbc object, database object reference
* @param mdefs array, hash array with methods description
* @param config array, hash array with configuration
* @param debug int, XMLRPC debug flag
* @param verbose boolean, verbosity flag
* @return this
*/
function SchedulerPhpClient(
&$dbc, $mdefs, $config, $debug=0, $verbose=FALSE)
{
$this->dbc = $dbc;
$this->mdefs = $mdefs;
$this->config = $config;
$this->debug = $debug;
$this->verbose = $verbose;
$confPrefix = "scheduler";
# $confPrefix = "storage";
$serverPath =
"http://{$config["{$confPrefix}UrlHost"]}:{$config["{$confPrefix}UrlPort"]}".
"{$config["{$confPrefix}UrlPath"]}/{$config["{$confPrefix}XMLRPC"]}";
#$serverPath = "http://localhost:80/campcasterStorageServerCVS/xmlrpc/xrLocStor.php";
if($this->verbose) echo "serverPath: $serverPath\n";
$url = parse_url($serverPath);
$this->client = new XML_RPC_Client($url['path'], $url['host'], $url['port']);
}
/**
* Factory, create object instance
*
* In fact it doesn't create instance of SchedulerPhpClient, but
* dynamically extend this class with set of methods based on $mdefs array
* (using eval function) and instantiate resulting class
* SchedulerPhpClientCore instead.
* Each new method in this subclass accepts parameters according to $mdefs
* array, call wrapper callMethod(methodname, parameters) and return its
* result.
*
* @param dbc object, database object reference
* @param mdefs array, hash array with methods description
* @param config array, hash array with configuration
* @param debug int, XMLRPC debug flag
* @param verbose boolean, verbosity flag
* @return object, created object instance
*/
function &factory(&$dbc, $mdefs, $config, $debug=0, $verbose=FALSE){
$f = '';
foreach($mdefs as $fn=>$farr){
$f .=
' function '.$fn.'(){'."\n".
' $pars = func_get_args();'."\n".
' $r = $this->callMethod("'.$fn.'", $pars);'."\n".
' return $r;'."\n".
' }'."\n";
}
$e =
"class SchedulerPhpClientCore extends SchedulerPhpClient{\n".
"$f\n".
"}\n";
# echo $e;
if(FALSE === eval($e)) return $dbc->raiseError("Eval failed");
$spc =& new SchedulerPhpClientCore(
$dbc, $mdefs, $config, $debug, $verbose);
return $spc;
}
/**
* XMLRPC methods wrapper
* Encode XMLRPC request message, send it, receive and decode response.
*
* @param method string, method name
* @param gettedPars array, returned by func_get_args() in called method
* @return array, PHP hash with response
*/
function callMethod($method, $gettedPars)
{
$parr = array();
$XML_RPC_val = new XML_RPC_Value;
foreach($this->mdefs[$method]['p'] as $i=>$p){
$parr[$p] = new XML_RPC_Value;
$parr[$p]->addScalar($gettedPars[$i], $this->mdefs[$method]['t'][$i]);
}
$XML_RPC_val->addStruct($parr);
$fullmethod = $this->mdefs[$method]['m'];
$msg = new XML_RPC_Message($fullmethod, array($XML_RPC_val));
if($this->verbose){
echo "parr:\n";
var_dump($parr);
echo "message:\n";
echo $msg->serialize()."\n";
}
$this->client->setDebug($this->debug);
$res = $this->client->send($msg);
if($res->faultCode() > 0) {
return PEAR::raiseError(
"SchedulerPhpClient::$method:".$res->faultString()." ".
$res->faultCode()."\n", $res->faultCode(),
PEAR_ERROR_RETURN
);
}
if($this->verbose){
echo "result:\n";
echo $res->serialize();
}
$val = $res->value();
$resp = XML_RPC_decode($res->value());
return $resp;
}
}
/* ======================================================== class definitions */
/**
* Example of use:
*
* /
// db object handling:
$dbc = DB::connect($config['dsn'], TRUE);
$dbc->setFetchMode(DB_FETCHMODE_ASSOC);
$dbc->setErrorHandling(PEAR_ERROR_RETURN);
// scheduler client instantiation:
$spc =& SchedulerPhpClient::factory($dbc, $mdefs, $config);
#$spc =& SchedulerPhpClient::factory($dbc, $mdefs, $config, 0, TRUE);
if(PEAR::isError($spc)){ echo $spc->getMessage."\n"; exit; }
// call of chosen function by name according to key values in $mdefs array:
// (for testing on storageServer XMLRPC I've changes confPrefix in
// SchedulerPhpClient constructor from 'scheduler' to 'storage' value)
#$r = $spc->LoginGB('root', 'q'); var_dump($r);
#$r = $spc->LogoutGB(''); var_dump($r);
#$r = $spc->DisplayScheduleMethod($this->Base->sessid, '2005-01-01 00:00:00.000000', '2005-02-01 00:00:00.000000'); var_dump($r);
#$r = $spc->DisplayScheduleMethod('dummySessionId2-1681692777', '2005-01-01 00:00:00.000000', '2005-02-01 00:00:00.000000'); var_dump($r);
$r = $spc->DisplayScheduleMethod($this->Base->sessid, '20040101T00:00:00', '20050401T00:00:00'); var_dump($r);
#$r = $spc->LoginMethod('root', 'q'); var_dump($r);
#$r = $spc->LogoutMethod('dummySessionId3-1714636915'); var_dump($r);
#$r = $spc->listMethods(); var_dump($r);
#$r = $spc->GetSchedulerTimeMethod(); var_dump($r);
================= */
?>

View file

@ -0,0 +1,106 @@
<?php
/**
* \file simpleGet.php
* Returns stored media file identified by global unique ID.
*
* simpleGet.php is remote callable script through HTTP GET method.
* Requires valid session ID with read permission for requested file.
*
* This script accepts following HTTP GET parameters:
* <ul>
* <li>sessid : string, session ID</li>
* <li>id : string, global unique ID of requested file</li>
* </ul>
*
* On success, returns HTTP return code 200 and requested file.
*
* On errors, returns HTTP return code &gt;200
* The possible error codes are:
* <ul>
* <li> 400 - Incorrect parameters passed to method</li>
* <li> 403 - Access denied</li>
* <li> 404 - File not found</li>
* <li> 500 - Application error</li>
* </ul>
* @author $Author$
* @version $Revision$
*
*/
require_once dirname(__FILE__).'/../conf.php';
require_once 'DB.php';
require_once dirname(__FILE__).'/../LocStor.php';
$dbc = DB::connect($config['dsn'], TRUE);
$dbc->setErrorHandling(PEAR_ERROR_RETURN);
$dbc->setFetchMode(DB_FETCHMODE_ASSOC);
$locStor = &new LocStor($dbc, $config);
function http_error($code, $err){
header("HTTP/1.1 $code");
header("Content-type: text/plain; charset=UTF-8");
echo "$err\r\n";
exit;
}
// parameter checking:
if(preg_match("|^[0-9a-fA-F]{32}$|", $_REQUEST['sessid'])){
$sessid = $_REQUEST['sessid'];
}else{
http_error(400, "Error on sessid parameter. ({$_REQUEST['sessid']})");
}
if(preg_match("|^[0-9a-fA-F]{16}$|", $_REQUEST['id'])){
$gunid = $_REQUEST['id'];
}else{
http_error(400, "Error on id parameter. ({$_REQUEST['id']})");
}
// stored file recall:
$ac = StoredFile::recallByGunid($locStor, $gunid);
if($dbc->isError($ac)){
switch($ac->getCode()){
case GBERR_DENY:
http_error(403, "403 ".$ac->getMessage());
case GBERR_FILENEX:
case GBERR_FOBJNEX:
http_error(404, "404 File not found");
default:
http_error(500, "500 ".$ac->getMessage());
}
}
$lid = $locStor->_idFromGunid($gunid);
if($dbc->isError($lid)){ http_error(500, $lid->getMessage()); }
if(($res = $locStor->_authorize('read', $lid, $sessid)) !== TRUE){
http_error(403, "403 Access denied");
}
$ftype = $locStor->getObjType($lid);
if($dbc->isError($ftype)){ http_error(500, $ftype->getMessage()); }
switch($ftype){
case"audioclip":
$realFname = $ac->_getRealRADFname();
$mime = $ac->rmd->getMime();
header("Content-type: $mime");
header("Content-length: ".filesize($realFname));
readfile($realFname);
break;
case"webstream":
$url = $locStor->bsGetMetadataValue($lid, 'ls:url');
if(PEAR::isError($url)){ http_error(500, $url->getMessage()); }
$url = $url[0]['value'];
$txt = "Location: $url";
header($txt);
// echo "$txt\n";
break;
case"playlist";
// $md = $locStor->bsGetMetadata($ac->getId(), $sessid);
$md = $locStor->getAudioClip($sessid, $gunid);
// header("Content-type: text/xml");
header("Content-type: application/smil");
echo $md;
break;
default:
// var_dump($ftype);
http_error(500, "500 Unknown ftype ($ftype)");
}
?>

View file

@ -0,0 +1,536 @@
#!/bin/bash
#-------------------------------------------------------------------------------
# Copyright (c) 2004 Media Development Loan Fund
#
# This file is part of the Campcaster project.
# http://campcaster.campware.org/
# To report bugs, send an e-mail to bugs@campware.org
#
# Campcaster 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.
#
# Campcaster 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 Campcaster; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
# Author : $Author$
# Version : $Revision$
# Location : $URL$
#-------------------------------------------------------------------------------
#DEBUG=yes
#DEBUG_I=yes
if [ "x$1" != "x" ]; then
COMM=$1
shift
GUNID=$1
fi
METADATA="<?xml version=\"1.0\"?>
<audioClip>
<metadata
xmlns=\"http://mdlf.org/campcaster/elements/1.0/\"
xmlns:ls=\"http://mdlf.org/campcaster/elements/1.0/\"
xmlns:dc=\"http://purl.org/dc/elements/1.1/\"
xmlns:dcterms=\"http://purl.org/dc/terms/\"
xmlns:xml=\"http://www.w3.org/XML/1998/namespace\"
>
<dc:title>Media title testRunner</dc:title>
<dcterms:extent>00:00:03.000000</dcterms:extent>
</metadata>
</audioClip>"
METAREGEX="(<\\?xml version=\"1\\.0\"( encoding=\"UTF-8\")?\\?> )?\
<audioClip>\
<metadata\
xmlns=\"http://mdlf\\.org/campcaster/elements/1\\.0/\"\
xmlns:dc=\"http://purl\\.org/dc/elements/1\\.1/\"\
xmlns:dcterms=\"http://purl\\.org/dc/terms/\"\
xmlns:ls=\"http://mdlf\\.org/campcaster/elements/1\\.0/\"\
xmlns:xml=\"http://www\\.w3\\.org/XML/1998/namespace\"\
>\
<dc:title>Media title testRunner</dc:title>\
<dcterms:extent>00:00:03\\.000000</dcterms:extent>\
<ls:mtime>[0-9]{4}(-[0-9]{2}){2}T[0-9]{2}(:[0-9]{2}){2}([-+][0-9]{1,2}:[0-9]{2})?</ls:mtime>\
</metadata>\
</audioClip>"
echo ""
XRDIR=`dirname $0`
XMLRPC=`cd var/install; php -q getXrUrl.php` || exit $?
echo "# storageServer XMLRPC URL: $XMLRPC"
cd $XRDIR
#XR_CLI="./xr_cli_test.py -s ${XMLRPC}"
XR_CLI="php -q xr_cli_test.php -s ${XMLRPC}"
login() {
echo -n "# login: "
SESSID=`$XR_CLI login root q` || \
{ ERN=$?; echo $SESSID; exit $ERN; }
echo "sessid: $SESSID"
}
test() {
echo "# test: "
$XR_CLI test $SESSID stringForUppercase || exit $?
}
existsAudioClip() {
echo -n "# existsAudioClip (${GUNID}): "
$XR_CLI existsAudioClip $SESSID $GUNID || exit $?
}
storeAudioClip() {
if [ "x$1" = "x" ]; then MEDIA=../tests/ex1.mp3; else MEDIA=$1; fi
if [ "x$2" = "x" ]; then GUNID=""; else GUNID=$2; fi
MD5=`md5sum $MEDIA`; for i in $MD5; do MD5=$i; break; done
if [ $DEBUG_I ]; then echo "md5=$MD5"; fi
echo -n "# storeAudioClipOpen: "
RES=`$XR_CLI storeAudioClipOpen "$SESSID" "$GUNID" "$METADATA" "stored file.mp3" "$MD5"` || \
{ ERN=$?; echo $RES; exit $ERN; }
unset URL
for i in $RES; do if [ -z $URL ] ; then URL=$i; else TOKEN=$i; fi; done
echo $TOKEN
if [ $DEBUG_I ]; then echo $URL; fi
if [ $DEBUG_I ]; then echo -n "Press enter ..."; read KEY; fi
echo -n "# curl (PUT): "
curl -C 0 -T $MEDIA $URL || { ERN=$?; echo $RGUNID; exit $ERN; }
echo "status: $?"
if [ $DEBUG_I ]; then echo -n "Press enter ..."; read KEY; fi
echo -n "# storeAudioClipClose: "
RGUNID=`$XR_CLI storeAudioClipClose "$SESSID" "$TOKEN"` || \
{ ERN=$?; echo $RGUNID; exit $ERN; }
echo $RGUNID
}
accessRawAudioData() {
echo -n "# accessRawAudioData: "
RES=`$XR_CLI accessRawAudioData $SESSID $GUNID` || \
{ ERN=$?; echo $RES; exit $ERN; }
unset URL
for i in $RES; do if [ -z $URL ] ; then URL=$i; else TOKEN=$i; fi; done
echo $TOKEN
if [ $DEBUG_I ]; then echo $URL; fi
if [ $DEBUG_I ]; then echo -n "Press enter ..."; read KEY; fi
echo -n "# releaseRawAudioData: "
$XR_CLI releaseRawAudioData $TOKEN || exit $?
}
downloadRAD() {
echo -n "# downloadRawAudioDataOpen: "
RES=`$XR_CLI downloadRawAudioDataOpen $SESSID $GUNID` || \
{ ERN=$?; echo $RES; exit $ERN; }
unset URL
for i in $RES; do if [ -z $URL ] ; then URL=$i; else TOKEN=$i; fi; done
echo $TOKEN
if [ $DEBUG_I ]; then echo $URL; fi
if [ $DEBUG_I ]; then echo -n "Press enter ..."; read KEY; fi
echo -n "# curl: "
curl -Ifs $URL > /dev/null || { ERN=$?; echo $URL; exit $ERN; }
echo "status: $?"
echo -n "# downloadRawAudioDataClose: "
$XR_CLI downloadRawAudioDataClose $SESSID $TOKEN || exit $?
}
downloadMeta() {
echo -n "# downloadMetadataOpen: "
RES=`$XR_CLI downloadMetadataOpen $SESSID $GUNID` || \
{ ERN=$?; echo $RES; exit $ERN; }
unset URL
for i in $RES; do if [ -z $URL ] ; then URL=$i; else TOKEN=$i; fi; done
echo $TOKEN
if [ $DEBUG_I ]; then echo $URL; fi
if [ $DEBUG_I ]; then echo -n "Press enter ..."; read KEY; fi
echo -n "# curl: "
METAOUT=`curl -fs $URL;` || { ERN=$?; echo $RES; exit $ERN; }
echo "OK"
if [ $DEBUG_I ]; then echo $METAOUT; echo -n "Press enter ..."; read KEY; fi
echo -n "# metadata check:"
METAOUT=`echo $METAOUT | sed -e 's/\\n/ /g'`
if [[ "x$METAOUT" =~ "x$METAREGEX" ]]; then
echo " OK"
else
echo " NOT MATCH ($?)"
echo " Expected match to regex:"; echo $METAREGEX
echo " Downloaded:"; echo ${METAOUT}
exit 1
fi
echo -n "# downloadMetadataClose: "
$XR_CLI downloadMetadataClose $SESSID $TOKEN || exit $?
}
deleteAudioClip() {
echo -n "# deleteAudioClip: "
# disabled:
# $XR_CLI deleteAudioClip $SESSID $GUNID || exit $?
$XR_CLI deleteAudioClip $SESSID $GUNID 0
}
updateAudioClipMetadata() {
echo -n "#updateAudioClipMetadata: "
$XR_CLI updateAudioClipMetadata $SESSID $GUNID "$METADATA" || exit $?
}
getAudioClip() {
echo -n "#getAudioClip: "
$XR_CLI getAudioClip $SESSID $GUNID || exit $?
}
searchMetadata() {
echo -n "# searchMetadata: "
RES=`$XR_CLI searchMetadata $SESSID 'title' 'testRunner'` || \
{ ERN=$?; echo $RES; exit $ERN; }
echo $RES
}
browseCategory() {
echo -n "# browseCategory: "
RES=`$XR_CLI browseCategory $SESSID 'title' 'title' 'testRunner'` || \
{ ERN=$?; echo $RES; exit $ERN; }
echo $RES
}
storeWebstream() {
URL="http://localhost/x"
echo -n "# storeWebstream: "
RGUNID=`$XR_CLI storeWebstream "$SESSID" '' "$METADATA" "new stream" "$URL"` || \
{ ERN=$?; echo $RGUNID; exit $ERN; }
echo $RGUNID
}
PLID="123456789abcdef8"
createPlaylist() {
echo -n "# createPlaylist: "
$XR_CLI deletePlaylist $SESSID $PLID 1
$XR_CLI createPlaylist $SESSID $PLID "newPlaylist.xml" || exit $?
}
accessPlaylist() {
echo -n "# accessPlaylist: "
RES=`$XR_CLI accessPlaylist $SESSID $PLID` || \
{ ERN=$?; echo $RES; exit $ERN; }
unset URL
for i in $RES; do if [ -z $URL ] ; then URL=$i; else TOKEN=$i; fi; done
echo $TOKEN
if [ $DEBUG_I ]; then echo $URL; fi
echo "# curl: "
CURLOUT=`curl -fs $URL;` || { ERN=$?; echo $RES; exit $ERN; }
if [ $DEBUG ]; then echo $CURLOUT; fi
# echo $CURLOUT
if [ $DEBUG_I ]; then echo -n "Press enter ..."; read KEY; fi
echo "# status: $?"
if [ $DEBUG_I ]; then echo -n "Press enter ..."; read KEY; fi
echo -n "# releasePlaylist: "
$XR_CLI releasePlaylist $TOKEN || exit $?
}
editPlaylist() {
DATE=`date '+%H:%M:%S'`
PLAYLIST="<?xml version=\"1.0\" encoding=\"utf-8\"?>
<playlist id=\"123456789abcdef8\" playlength=\"01:30:00.000000\"
title=\"My First Playlist\">
<playlistElement id=\"0000000000000101\" relativeOffset=\"0\" >
<audioClip id=\"0000000000010001\" playlength=\"01:00:00.000000\"
title=\"one\"/>
</playlistElement>
<playlistElement id=\"0000000000000102\" relativeOffset=\"01:00:00.000000\" >
<audioClip id=\"0000000000010002\" playlength=\"00:30:00.000000\"
title=\"two\"/>
</playlistElement>
<metadata
xmlns=\"http://www.streamonthefly.org/\"
xmlns:dc=\"http://purl.org/dc/elements/1.1/\"
xmlns:dcterms=\"http://purl.org/dc/terms/\"
xmlns:xbmf=\"http://www.streamonthefly.org/xbmf\"
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
>
<dc:title>My First Playlist</dc:title>
<dc:creator>Me, myself and I</dc:creator>
<dcterms:extent>01:30:00.000000</dcterms:extent>
</metadata>
</playlist>
"
echo -n "# editPlaylist: "
RES=`$XR_CLI editPlaylist $SESSID $PLID` || \
{ ERN=$?; echo $RES; exit $ERN; }
unset URL
for i in $RES; do if [ -z $URL ] ; then URL=$i; else TOKEN=$i; fi; done
echo $TOKEN
# deletePlaylist
if [ $DEBUG_I ]; then echo $URL; fi
if [ $DEBUG_I ]; then echo -n "Press enter ..."; read KEY; fi
if [ $DEBUG_I ]; then echo " Playlist:"; echo $PLAYLIST; fi
echo -n "# savePlaylist: "
$XR_CLI savePlaylist $SESSID $TOKEN "$PLAYLIST" || exit $?
}
existsPlaylist() {
echo -n "# existsPlaylist (${PLID}): "
EXISTS=`$XR_CLI existsPlaylist $SESSID $PLID` || \
{ ERN=$?; echo $EXISTS; exit $ERN; }
echo $EXISTS
}
deletePlaylist() {
if [ "$EXISTS" != "FALSE" ]; then
echo -n "# deletePlaylist (${PLID}): "
# disabled:
# $XR_CLI deletePlaylist $SESSID $PLID || exit $?
$XR_CLI deletePlaylist $SESSID $PLID 0
echo "# status: $?"
fi
}
exportPlaylist() {
storeAudioClip ../tests/0000000000010001 0000000000010001
storeAudioClip ../tests/0000000000010002 0000000000010002
echo -n "# exportPlaylistOpen (${PLID}): "
# RES=`$XR_CLI exportPlaylistOpen $SESSID $PLID smil` || \
RES=`$XR_CLI exportPlaylistOpen $SESSID $PLID lspl` || \
{ ERN=$?; echo $RES; exit $ERN; }
unset URL
for i in $RES; do if [ -z $URL ] ; then URL=$i; else TOKEN=$i; fi; done
echo $TOKEN
echo -n "# curl: "
curl -Ifs $URL > /dev/null || { ERN=$?; echo $URL; exit $ERN; }
echo "status: $?"
echo -n "# exportPlaylistClose (${TOKEN}): "
RES=`$XR_CLI exportPlaylistClose $TOKEN` || \
{ ERN=$?; echo $RES; exit $ERN; }
echo $RES
}
importPlaylist() {
echo -n "# importPlaylistOpen: "
ARCHIVE=../tests/exportedPl_lspl.tar
# ARCHIVE=../tests/exportedPl_smil.tar
$XR_CLI deletePlaylist $SESSID 0000000000000001 1
$XR_CLI deletePlaylist $SESSID 0000000000000003 1
$XR_CLI deleteAudioClip $SESSID 0000000000010001 1
$XR_CLI deleteAudioClip $SESSID 0000000000010002 1
$XR_CLI deleteAudioClip $SESSID 0000000000010003 1
CHSUM=`md5sum $ARCHIVE | cut -d ' ' -f 1 `
RES=`$XR_CLI importPlaylistOpen $SESSID $CHSUM` || \
{ ERN=$?; echo $RES; exit $ERN; }
unset URL
for i in $RES; do if [ -z $URL ] ; then URL=$i; else TOKEN=$i; fi; done
echo $TOKEN
echo -n "# curl (PUT $URL): "
curl -C 0 -T $ARCHIVE $URL || { ERN=$?; echo "curl error"; exit $ERN; }
echo "status: $?"
echo -n "# importPlaylistClose (${TOKEN}): "
RES=`$XR_CLI importPlaylistClose $TOKEN` || \
{ ERN=$?; echo $RES; exit $ERN; }
echo $RES
GUNID=0000000000010001; existsAudioClip;
GUNID=0000000000010002; existsAudioClip;
GUNID=0000000000010003; existsAudioClip;
PLID=0000000000000001; existsPlaylist;
PLID=0000000000000003; existsPlaylist;
}
prefTest() {
PREFKEY="testKey"
PREFVAL="test preference value"
echo -n "# savePref ($PREFKEY): "
$XR_CLI savePref $SESSID "$PREFKEY" "$PREFVAL"|| exit $?
echo -n "# loadPref ($PREFKEY): "
VAL=`$XR_CLI loadPref $SESSID "$PREFKEY"` || \
{ ERN=$?; echo $VAL; exit $ERN; }
echo "$VAL "
if [ "x$VAL" != "x$PREFVAL" ] ; then
echo " NOT MATCH"
echo " Expected:"; echo $PREFVAL
echo " Returned:"; echo $VAL
exit 1
else
echo "# pref value check: OK"
fi
echo -n "# delPref: "
$XR_CLI delPref $SESSID "$PREFKEY"|| exit $?
if [ $DEBUG ]; then
echo -n "# loadPref: "
VAL=`$XR_CLI loadPref $SESSID "$PREFKEY"` || echo $?
else
echo $VAL
fi
}
groupPrefTest() {
PREFKEY="Station frequency"
PREFVAL="89.5 FM"
GR="StationPrefs"
echo -n "# saveGroupPref ($PREFKEY): "
$XR_CLI saveGroupPref $SESSID "$GR" "$PREFKEY" "$PREFVAL"|| exit $?
echo -n "# loadGroupPref ($PREFKEY): "
VAL=`$XR_CLI loadGroupPref $SESSID "$GR" "$PREFKEY"` || \
{ ERN=$?; echo $VAL; exit $ERN; }
echo "$VAL "
if [ "x$VAL" != "x$PREFVAL" ] ; then
echo " NOT MATCH"
echo " Expected:"; echo $PREFVAL
echo " Returned:"; echo $VAL
exit 1
else
echo "# pref value check: OK"
fi
echo -n "# saveGroupPref (clear it): "
$XR_CLI saveGroupPref $SESSID "$GR" "$PREFKEY" ""|| exit $?
}
logout() {
echo -n "# logout: "
$XR_CLI logout $SESSID || exit $?
}
searchTest() {
echo "#XMLRPC search test"
login
storeAudioClip
GUNID=$RGUNID
searchMetadata
OK="AC(1): $GUNID | PL(0): "
if [ "$RES" == "$OK" ]; then
echo "match: OK"
else
echo "results doesn't match ($OK)"; deleteAudioClip; exit 1;
fi
browseCategory
OK="RES(1): Media title testRunner"
if [ "$RES" == "$OK" ]; then
echo "match: OK"
else
echo "results doesn't match ($OK)"; deleteAudioClip; exit 1;
fi
deleteAudioClip
logout
echo "#XMLRPC: search: OK."
echo ""
}
preferenceTest(){
echo "#XMLRPC preference test"
login
prefTest
groupPrefTest
logout
echo "#XMLRPC: preference: OK."
echo ""
}
playlistTest(){
echo "#XMLRPC playlists test"
login
existsPlaylist
deletePlaylist
createPlaylist
existsPlaylist
accessPlaylist
editPlaylist
accessPlaylist
exportPlaylist
importPlaylist
deletePlaylist
existsPlaylist
logout
echo "#XMLRPC: playlists: OK."
echo ""
}
webstreamTest(){
echo "#XMLRPC webstream test"
login
storeWebstream; GUNID=$RGUNID
# GUNID="4e58a66cf6e9f539"
# downloadMeta
getAudioClip
deleteAudioClip
logout
echo "#XMLRPC: webstream: OK."
echo ""
}
storageTest(){
echo "#XMLRPC: storage test"
login
storeAudioClip
GUNID=$RGUNID
existsAudioClip
accessRawAudioData
downloadRAD
downloadMeta
deleteAudioClip
existsAudioClip
logout
echo "#XMLRPC: storage: OK."
echo ""
}
usage(){
echo "Usage: $0 [<command>] [args]"
echo -e "commands:\n test\n existsAudioClip\n accessRawAudioData"
echo -e " storeAudioClip\n deleteAudioClip\n updateAudioClipMetadata"
echo -e " getAudioClip\n searchMetadata\n"
echo -e " preferences\n playlists\n storage\n"
}
if [ "$COMM" = "test" ]; then
login
test
logout
elif [ "$COMM" = "existsAudioClip" ]; then
login
existsAudioClip
logout
elif [ "$COMM" = "accessRawAudioData" ]; then
login
accessRawAudioData
logout
elif [ "$COMM" = "storeAudioClip" ]; then
login
storeAudioClip
logout
elif [ "$COMM" = "deleteAudioClip" ]; then
login
deleteAudioClip
logout
elif [ "$COMM" = "updateAudioClipMetadata" ]; then
login
updateAudioClipMetadata
logout
elif [ "$COMM" = "getAudioClip" ]; then
login
getAudioClip
logout
elif [ "$COMM" = "searchMetadata" ]; then
searchTest
elif [ "$COMM" = "preferences" ]; then
preferenceTest
elif [ "$COMM" = "playlists" ]; then
playlistTest
elif [ "$COMM" = "webstream" ]; then
webstreamTest
elif [ "$COMM" = "storage" ]; then
storageTest
elif [ "x$COMM" = "x" ]; then
storageTest
playlistTest
preferenceTest
searchTest
elif [ "$COMM" = "help" ]; then
usage
else
echo "Unknown command"
usage
fi

View file

@ -0,0 +1,7 @@
#!/usr/bin/php -q
<?
$fp = fopen("/dev/stdin", "r");
$data = '';
while($part = fgets($fp, 1024)) $data .= $part;
echo urldecode($data);
?>

Some files were not shown because too many files have changed in this diff Show more