CC-2166: Packaging Improvements. Moved the Zend app into airtime_mvc. It is now installed to /var/www/airtime. Storage is now set to /srv/airtime/stor. Utils are now installed to /usr/lib/airtime/utils/. Added install/airtime-dircheck.php as a simple test to see if everything is install/uninstalled correctly.

This commit is contained in:
Paul Baranowski 2011-04-14 18:55:04 -04:00
parent 514777e8d2
commit b11cbd8159
4546 changed files with 138 additions and 51 deletions

View file

@ -0,0 +1,88 @@
<?php
require_once __DIR__."/configs/navigation.php";
require_once __DIR__."/configs/ACL.php";
require_once 'propel/runtime/lib/Propel.php';
Propel::init(__DIR__."/configs/airtime-conf.php");
//DateTime in PHP 5.3.0+ need a default timezone set.
$tz = ini_get('date.timezone') ? ini_get('date.timezone') : 'UTC';
date_default_timezone_set($tz);
require_once __DIR__."/configs/constants.php";
require_once __DIR__."/configs/conf.php";
require_once 'DB.php';
require_once 'Soundcloud.php';
require_once 'Playlist.php';
require_once 'StoredFile.php';
require_once 'Schedule.php';
require_once 'Shows.php';
require_once 'Users.php';
require_once 'RabbitMq.php';
require_once 'DateHelper.php';
require_once __DIR__.'/controllers/plugins/RabbitMqPlugin.php';
global $CC_CONFIG, $CC_DBC;
$dsn = $CC_CONFIG['dsn'];
$CC_DBC = DB::connect($dsn, FALSE);
if (PEAR::isError($CC_DBC)) {
echo "ERROR: ".$CC_DBC->getMessage()." ".$CC_DBC->getUserInfo()."\n";
exit(1);
}
$CC_DBC->setFetchMode(DB_FETCHMODE_ASSOC);
//Zend_Session::start();
Zend_Validate::setDefaultNamespaces("Zend");
$front = Zend_Controller_Front::getInstance();
$front->registerPlugin(new RabbitMqPlugin());
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initDoctype()
{
$this->bootstrap('view');
$view = $this->getResource('view');
$view->doctype('XHTML1_STRICT');
}
protected function _initHeadLink()
{
$view = $this->getResource('view');
$view->headLink()->appendStylesheet('/css/redmond/jquery-ui-1.8.8.custom.css');
$this->view->headLink()->appendStylesheet('/css/pro_dropdown_3.css');
$this->view->headLink()->appendStylesheet('/css/styles.css');
}
protected function _initHeadScript()
{
$view = $this->getResource('view');
$view->headScript()->appendFile('/js/libs/jquery-1.5.2.min.js','text/javascript');
$view->headScript()->appendFile('/js/libs/jquery-ui-1.8.11.custom.min.js','text/javascript');
$view->headScript()->appendFile('/js/libs/jquery.stickyPanel.js','text/javascript');
$view->headScript()->appendFile('/js/qtip/jquery.qtip-1.0.0.min.js','text/javascript');
//scripts for now playing bar
$this->view->headScript()->appendFile('/js/playlist/helperfunctions.js','text/javascript');
$this->view->headScript()->appendFile('/js/playlist/playlist.js','text/javascript');
$view->headScript()->appendFile('/js/airtime/common/common.js','text/javascript');
}
protected function _initViewHelpers()
{
$view = $this->getResource('view');
$view->addHelperPath('../application/views/helpers', 'Airtime_View_Helper');
}
protected function _initTitle()
{
$view = $this->getResource('view');
$view->headTitle(Application_Model_Preference::GetHeadTitle());
}
}

View file

@ -0,0 +1,49 @@
<?php
require_once 'Acl_plugin.php';
$ccAcl = new Zend_Acl();
$ccAcl->addRole(new Zend_Acl_Role('G'))
->addRole(new Zend_Acl_Role('H'), 'G')
->addRole(new Zend_Acl_Role('A'), 'H');
$ccAcl->add(new Zend_Acl_Resource('library'))
->add(new Zend_Acl_Resource('index'))
->add(new Zend_Acl_Resource('user'))
->add(new Zend_Acl_Resource('error'))
->add(new Zend_Acl_Resource('login'))
->add(new Zend_Acl_Resource('playlist'))
->add(new Zend_Acl_Resource('plupload'))
->add(new Zend_Acl_Resource('schedule'))
->add(new Zend_Acl_Resource('api'))
->add(new Zend_Acl_Resource('nowplaying'))
->add(new Zend_Acl_Resource('search'))
->add(new Zend_Acl_Resource('dashboard'))
->add(new Zend_Acl_Resource('preference'))
->add(new Zend_Acl_Resource('recorder'));
/** Creating permissions */
$ccAcl->allow('G', 'index')
->allow('G', 'login')
->allow('G', 'error')
->allow('G', 'nowplaying')
->allow('G', 'api')
//->allow('G', 'plupload', array('upload-recorded'))
->allow('G', 'recorder')
->allow('G', 'schedule')
->allow('G', 'dashboard')
//->allow('H', 'plupload', array('plupload', 'upload', 'index'))
->allow('H', 'plupload')
->allow('H', 'library')
->allow('H', 'search')
->allow('H', 'playlist')
->allow('A', 'user')
->allow('A', 'preference');
$aclPlugin = new Zend_Controller_Plugin_Acl($ccAcl);
Zend_View_Helper_Navigation_HelperAbstract::setDefaultAcl($ccAcl);
$front = Zend_Controller_Front::getInstance();
$front->registerPlugin($aclPlugin);

View file

@ -0,0 +1,20 @@
<?php
// This file generated by Propel 1.5.2 convert-conf target
// from XML runtime conf file /home/naomiaro/dev-campcaster/campcaster/build/runtime-conf.xml
$conf = array (
'datasources' =>
array (
'airtime' =>
array (
'adapter' => 'pgsql',
'connection' =>
array (
'dsn' => 'pgsql:host=localhost;port=5432;dbname=airtime;user=airtime;password=airtime',
),
),
'default' => 'airtime',
),
'generator_version' => '1.5.2',
);
$conf['classmap'] = include(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'classmap-airtime-conf.php');
return $conf;

View file

@ -0,0 +1,28 @@
[production]
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
includePaths.library = APPLICATION_PATH "/../library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"
appnamespace = "Application"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.frontController.params.displayExceptions = 0
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"
resources.view[] =
resources.db.adapter = "Pdo_Pgsql"
resources.db.params.charset = "utf8"
resources.db.params.host = "localhost"
resources.db.params.username = "airtime"
resources.db.params.password = "airtime"
resources.db.params.dbname = "airtime"
[staging : production]
[testing : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.frontController.params.displayExceptions = 1

View file

@ -0,0 +1,109 @@
<?php
// This file generated by Propel 1.5.2 convert-conf target
return array (
'CcAccessTableMap' => 'airtime/map/CcAccessTableMap.php',
'CcAccessPeer' => 'airtime/CcAccessPeer.php',
'CcAccess' => 'airtime/CcAccess.php',
'CcAccessQuery' => 'airtime/CcAccessQuery.php',
'BaseCcAccessPeer' => 'airtime/om/BaseCcAccessPeer.php',
'BaseCcAccess' => 'airtime/om/BaseCcAccess.php',
'BaseCcAccessQuery' => 'airtime/om/BaseCcAccessQuery.php',
'CcFilesTableMap' => 'airtime/map/CcFilesTableMap.php',
'CcFilesPeer' => 'airtime/CcFilesPeer.php',
'CcFiles' => 'airtime/CcFiles.php',
'CcFilesQuery' => 'airtime/CcFilesQuery.php',
'BaseCcFilesPeer' => 'airtime/om/BaseCcFilesPeer.php',
'BaseCcFiles' => 'airtime/om/BaseCcFiles.php',
'BaseCcFilesQuery' => 'airtime/om/BaseCcFilesQuery.php',
'CcPermsTableMap' => 'airtime/map/CcPermsTableMap.php',
'CcPermsPeer' => 'airtime/CcPermsPeer.php',
'CcPerms' => 'airtime/CcPerms.php',
'CcPermsQuery' => 'airtime/CcPermsQuery.php',
'BaseCcPermsPeer' => 'airtime/om/BaseCcPermsPeer.php',
'BaseCcPerms' => 'airtime/om/BaseCcPerms.php',
'BaseCcPermsQuery' => 'airtime/om/BaseCcPermsQuery.php',
'CcShowTableMap' => 'airtime/map/CcShowTableMap.php',
'CcShowPeer' => 'airtime/CcShowPeer.php',
'CcShow' => 'airtime/CcShow.php',
'CcShowQuery' => 'airtime/CcShowQuery.php',
'BaseCcShowPeer' => 'airtime/om/BaseCcShowPeer.php',
'BaseCcShow' => 'airtime/om/BaseCcShow.php',
'BaseCcShowQuery' => 'airtime/om/BaseCcShowQuery.php',
'CcShowInstancesTableMap' => 'airtime/map/CcShowInstancesTableMap.php',
'CcShowInstancesPeer' => 'airtime/CcShowInstancesPeer.php',
'CcShowInstances' => 'airtime/CcShowInstances.php',
'CcShowInstancesQuery' => 'airtime/CcShowInstancesQuery.php',
'BaseCcShowInstancesPeer' => 'airtime/om/BaseCcShowInstancesPeer.php',
'BaseCcShowInstances' => 'airtime/om/BaseCcShowInstances.php',
'BaseCcShowInstancesQuery' => 'airtime/om/BaseCcShowInstancesQuery.php',
'CcShowDaysTableMap' => 'airtime/map/CcShowDaysTableMap.php',
'CcShowDaysPeer' => 'airtime/CcShowDaysPeer.php',
'CcShowDays' => 'airtime/CcShowDays.php',
'CcShowDaysQuery' => 'airtime/CcShowDaysQuery.php',
'BaseCcShowDaysPeer' => 'airtime/om/BaseCcShowDaysPeer.php',
'BaseCcShowDays' => 'airtime/om/BaseCcShowDays.php',
'BaseCcShowDaysQuery' => 'airtime/om/BaseCcShowDaysQuery.php',
'CcShowRebroadcastTableMap' => 'airtime/map/CcShowRebroadcastTableMap.php',
'CcShowRebroadcastPeer' => 'airtime/CcShowRebroadcastPeer.php',
'CcShowRebroadcast' => 'airtime/CcShowRebroadcast.php',
'CcShowRebroadcastQuery' => 'airtime/CcShowRebroadcastQuery.php',
'BaseCcShowRebroadcastPeer' => 'airtime/om/BaseCcShowRebroadcastPeer.php',
'BaseCcShowRebroadcast' => 'airtime/om/BaseCcShowRebroadcast.php',
'BaseCcShowRebroadcastQuery' => 'airtime/om/BaseCcShowRebroadcastQuery.php',
'CcShowHostsTableMap' => 'airtime/map/CcShowHostsTableMap.php',
'CcShowHostsPeer' => 'airtime/CcShowHostsPeer.php',
'CcShowHosts' => 'airtime/CcShowHosts.php',
'CcShowHostsQuery' => 'airtime/CcShowHostsQuery.php',
'BaseCcShowHostsPeer' => 'airtime/om/BaseCcShowHostsPeer.php',
'BaseCcShowHosts' => 'airtime/om/BaseCcShowHosts.php',
'BaseCcShowHostsQuery' => 'airtime/om/BaseCcShowHostsQuery.php',
'CcPlaylistTableMap' => 'airtime/map/CcPlaylistTableMap.php',
'CcPlaylistPeer' => 'airtime/CcPlaylistPeer.php',
'CcPlaylist' => 'airtime/CcPlaylist.php',
'CcPlaylistQuery' => 'airtime/CcPlaylistQuery.php',
'BaseCcPlaylistPeer' => 'airtime/om/BaseCcPlaylistPeer.php',
'BaseCcPlaylist' => 'airtime/om/BaseCcPlaylist.php',
'BaseCcPlaylistQuery' => 'airtime/om/BaseCcPlaylistQuery.php',
'CcPlaylistcontentsTableMap' => 'airtime/map/CcPlaylistcontentsTableMap.php',
'CcPlaylistcontentsPeer' => 'airtime/CcPlaylistcontentsPeer.php',
'CcPlaylistcontents' => 'airtime/CcPlaylistcontents.php',
'CcPlaylistcontentsQuery' => 'airtime/CcPlaylistcontentsQuery.php',
'BaseCcPlaylistcontentsPeer' => 'airtime/om/BaseCcPlaylistcontentsPeer.php',
'BaseCcPlaylistcontents' => 'airtime/om/BaseCcPlaylistcontents.php',
'BaseCcPlaylistcontentsQuery' => 'airtime/om/BaseCcPlaylistcontentsQuery.php',
'CcPrefTableMap' => 'airtime/map/CcPrefTableMap.php',
'CcPrefPeer' => 'airtime/CcPrefPeer.php',
'CcPref' => 'airtime/CcPref.php',
'CcPrefQuery' => 'airtime/CcPrefQuery.php',
'BaseCcPrefPeer' => 'airtime/om/BaseCcPrefPeer.php',
'BaseCcPref' => 'airtime/om/BaseCcPref.php',
'BaseCcPrefQuery' => 'airtime/om/BaseCcPrefQuery.php',
'CcScheduleTableMap' => 'airtime/map/CcScheduleTableMap.php',
'CcSchedulePeer' => 'airtime/CcSchedulePeer.php',
'CcSchedule' => 'airtime/CcSchedule.php',
'CcScheduleQuery' => 'airtime/CcScheduleQuery.php',
'BaseCcSchedulePeer' => 'airtime/om/BaseCcSchedulePeer.php',
'BaseCcSchedule' => 'airtime/om/BaseCcSchedule.php',
'BaseCcScheduleQuery' => 'airtime/om/BaseCcScheduleQuery.php',
'CcSessTableMap' => 'airtime/map/CcSessTableMap.php',
'CcSessPeer' => 'airtime/CcSessPeer.php',
'CcSess' => 'airtime/CcSess.php',
'CcSessQuery' => 'airtime/CcSessQuery.php',
'BaseCcSessPeer' => 'airtime/om/BaseCcSessPeer.php',
'BaseCcSess' => 'airtime/om/BaseCcSess.php',
'BaseCcSessQuery' => 'airtime/om/BaseCcSessQuery.php',
'CcSmembTableMap' => 'airtime/map/CcSmembTableMap.php',
'CcSmembPeer' => 'airtime/CcSmembPeer.php',
'CcSmemb' => 'airtime/CcSmemb.php',
'CcSmembQuery' => 'airtime/CcSmembQuery.php',
'BaseCcSmembPeer' => 'airtime/om/BaseCcSmembPeer.php',
'BaseCcSmemb' => 'airtime/om/BaseCcSmemb.php',
'BaseCcSmembQuery' => 'airtime/om/BaseCcSmembQuery.php',
'CcSubjsTableMap' => 'airtime/map/CcSubjsTableMap.php',
'CcSubjsPeer' => 'airtime/CcSubjsPeer.php',
'CcSubjs' => 'airtime/CcSubjs.php',
'CcSubjsQuery' => 'airtime/CcSubjsQuery.php',
'BaseCcSubjsPeer' => 'airtime/om/BaseCcSubjsPeer.php',
'BaseCcSubjs' => 'airtime/om/BaseCcSubjs.php',
'BaseCcSubjsQuery' => 'airtime/om/BaseCcSubjsQuery.php',
);

View file

@ -0,0 +1,89 @@
<?php
/* THIS FILE IS NOT MEANT FOR CUSTOMIZING.
* PLEASE EDIT THE FOLLOWING TO CHANGE YOUR CONFIG:
* /etc/airtime/airtime.conf
* /etc/airtime/pypo.cfg
* /etc/airtime/recorder.cfg
*/
define('AIRTIME_VERSION', '1.8.0-alpha');
define('AIRTIME_COPYRIGHT_DATE', '2010-2011');
define('AIRTIME_REST_VERSION', '1.1');
global $CC_CONFIG;
$values = load_airtime_config();
$CC_CONFIG = array(
// Name of the web server user
'webServerUser' => $values['general']['web_server_user'],
'rabbitmq' => $values['rabbitmq'],
'baseFilesDir' => $values['general']['base_files_dir'],
// main directory for storing binary media files
'storageDir' => $values['general']['base_files_dir']."/stor",
// Database config
'dsn' => array(
'username' => $values['database']['dbuser'],
'password' => $values['database']['dbpass'],
'hostspec' => $values['database']['host'],
'phptype' => 'pgsql',
'database' => $values['database']['dbname']),
// prefix for table names in the database
'tblNamePrefix' => 'cc_',
/* ================================================ storage configuration */
'apiKey' => array($values['general']['api_key']),
'apiPath' => '/api/',
'soundcloud-client-id' => '2CLCxcSXYzx7QhhPVHN4A',
'soundcloud-client-secret' => 'pZ7beWmF06epXLHVUP1ufOg2oEnIt9XhE8l8xt0bBs',
'soundcloud-connection-retries' => $values['soundcloud']['connection_retries'],
'soundcloud-connection-wait' => $values['soundcloud']['time_between_retries'],
"rootDir" => __DIR__."/../..",
'pearPath' => dirname(__FILE__).'/../../library/pear',
'zendPath' => dirname(__FILE__).'/../../library/Zend',
'phingPath' => dirname(__FILE__).'/../../library/phing',
);
// Add database table names
$CC_CONFIG['playListTable'] = $CC_CONFIG['tblNamePrefix'].'playlist';
$CC_CONFIG['playListContentsTable'] = $CC_CONFIG['tblNamePrefix'].'playlistcontents';
$CC_CONFIG['filesTable'] = $CC_CONFIG['tblNamePrefix'].'files';
$CC_CONFIG['accessTable'] = $CC_CONFIG['tblNamePrefix'].'access';
$CC_CONFIG['permTable'] = $CC_CONFIG['tblNamePrefix'].'perms';
$CC_CONFIG['sessTable'] = $CC_CONFIG['tblNamePrefix'].'sess';
$CC_CONFIG['subjTable'] = $CC_CONFIG['tblNamePrefix'].'subjs';
$CC_CONFIG['smembTable'] = $CC_CONFIG['tblNamePrefix'].'smemb';
$CC_CONFIG['prefTable'] = $CC_CONFIG['tblNamePrefix'].'pref';
$CC_CONFIG['scheduleTable'] = $CC_CONFIG['tblNamePrefix'].'schedule';
$CC_CONFIG['playListTimeView'] = $CC_CONFIG['tblNamePrefix'].'playlisttimes';
$CC_CONFIG['showSchedule'] = $CC_CONFIG['tblNamePrefix'].'show_schedule';
$CC_CONFIG['showDays'] = $CC_CONFIG['tblNamePrefix'].'show_days';
$CC_CONFIG['showTable'] = $CC_CONFIG['tblNamePrefix'].'show';
$CC_CONFIG['showInstances'] = $CC_CONFIG['tblNamePrefix'].'show_instances';
$CC_CONFIG['playListSequence'] = $CC_CONFIG['playListTable'].'_id';
$CC_CONFIG['filesSequence'] = $CC_CONFIG['filesTable'].'_id';
$CC_CONFIG['prefSequence'] = $CC_CONFIG['prefTable'].'_id';
$CC_CONFIG['permSequence'] = $CC_CONFIG['permTable'].'_id';
$CC_CONFIG['subjSequence'] = $CC_CONFIG['subjTable'].'_id';
$CC_CONFIG['smembSequence'] = $CC_CONFIG['smembTable'].'_id';
// Add libs to the PHP path
$old_include_path = get_include_path();
set_include_path('.'.PATH_SEPARATOR.$CC_CONFIG['pearPath']
.PATH_SEPARATOR.$CC_CONFIG['zendPath']
.PATH_SEPARATOR.$old_include_path);
function load_airtime_config(){
$ini_array = parse_ini_file('/etc/airtime/airtime.conf', true);
return $ini_array;
}

View file

@ -0,0 +1,22 @@
<?php
// Metadata Keys
define('UI_MDATA_KEY_TITLE', 'dc:title');
define('UI_MDATA_KEY_CREATOR', 'dc:creator');
define('UI_MDATA_KEY_SOURCE', 'dc:source');
define('UI_MDATA_KEY_DURATION', 'dcterms:extent');
define('UI_MDATA_KEY_URL', 'ls:url');
define('UI_MDATA_KEY_FORMAT', 'dc:format');
define('UI_MDATA_KEY_DESCRIPTION', 'dc:description');
define('UI_MDATA_KEY_CHANNELS', 'ls:channels');
define('UI_MDATA_KEY_SAMPLERATE', 'ls:samplerate');
define('UI_MDATA_KEY_BITRATE', 'ls:bitrate');
define('UI_MDATA_KEY_ENCODER', 'ls:encoder');
define('UI_MDATA_KEY_FILENAME', 'ls:filename');
define('UI_MDATA_VALUE_FORMAT_FILE', 'File');
define('UI_MDATA_VALUE_FORMAT_STREAM', 'live stream');
// Session Keys
define('UI_PLAYLIST_SESSNAME', 'PLAYLIST');

View file

@ -0,0 +1,73 @@
<?php
/*
* Navigation container (config/array)
* Each element in the array will be passed to
* Zend_Navigation_Page::factory() when constructing
* the navigation container below.
*/
$pages = array(
array(
'label' => 'Now Playing',
'module' => 'default',
'controller' => 'Nowplaying',
'action' => 'index',
'resource' => 'nowplaying'
),
array(
'label' => 'Add Media',
'module' => 'default',
'controller' => 'Plupload',
'action' => 'plupload',
'resource' => 'plupload'
),
array(
'label' => 'Playlist Builder',
'module' => 'default',
'controller' => 'Library',
'action' => 'index',
'resource' => 'library'
),
array(
'label' => 'Calendar',
'module' => 'default',
'controller' => 'Schedule',
'action' => 'index',
'resource' => 'schedule'
),
array(
'label' => 'Configure',
'uri' => '#',
'resource' => 'preference',
'pages' => array(
array(
'label' => 'Preferences',
'module' => 'default',
'controller' => 'Preference'
),
array(
'label' => 'Manage Users',
'module' => 'default',
'controller' => 'user',
'action' => 'add-user',
'resource' => 'user'
)
)
),
array(
'label' => 'Help',
'module' => 'default',
'controller' => 'dashboard',
'action' => 'help',
'resource' => 'dashboard'
)
);
// Create container from array
$container = new Zend_Navigation($pages);
$container->id = "nav";
//store it in the registry:
Zend_Registry::set('Zend_Navigation', $container);

View file

@ -0,0 +1,319 @@
<?php
class ApiController extends Zend_Controller_Action
{
public function init()
{
/* Initialize action controller here */
$context = $this->_helper->getHelper('contextSwitch');
$context->addActionContext('version', 'json')
->addActionContext('recorded-shows', 'json')
->addActionContext('upload-recorded', 'json')
->initContext();
}
public function indexAction()
{
// action body
}
/**
* Returns Airtime version. i.e "1.7.0 alpha"
*
* First checks to ensure the correct API key was
* supplied, then returns AIRTIME_VERSION as defined
* in application/conf.php
*
* @return void
*
*/
public function versionAction()
{
global $CC_CONFIG;
// disable the view and the layout
$this->view->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
$api_key = $this->_getParam('api_key');
if (!in_array($api_key, $CC_CONFIG["apiKey"]))
{
header('HTTP/1.0 401 Unauthorized');
print 'You are not allowed to access this resource.';
exit;
}
$jsonStr = json_encode(array("version"=>AIRTIME_VERSION));
echo $jsonStr;
}
/**
* Allows remote client to download requested media file.
*
* @return void
* The given value increased by the increment amount.
*/
public function getMediaAction()
{
global $CC_CONFIG;
// disable the view and the layout
$this->view->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
$api_key = $this->_getParam('api_key');
if(!in_array($api_key, $CC_CONFIG["apiKey"]))
{
header('HTTP/1.0 401 Unauthorized');
print 'You are not allowed to access this resource.';
exit;
}
$filename = $this->_getParam("file");
$file_id = substr($filename, 0, strpos($filename, "."));
if (ctype_alnum($file_id) && strlen($file_id) == 32) {
$media = StoredFile::RecallByGunid($file_id);
if ($media != null && !PEAR::isError($media)) {
$filepath = $media->getRealFilePath();
if(!is_file($filepath))
{
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
//print 'Resource in database, but not in storage. Sorry.';
exit;
}
// !! binary mode !!
$fp = fopen($filepath, 'rb');
// possibly use fileinfo module here in the future.
// http://www.php.net/manual/en/book.fileinfo.php
$ext = pathinfo($filename, PATHINFO_EXTENSION);
if ($ext == "ogg")
header("Content-Type: audio/ogg");
else if ($ext == "mp3")
header("Content-Type: audio/mpeg");
header("Content-Length: " . filesize($filepath));
fpassthru($fp);
return;
}
}
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
exit;
}
public function liveInfoAction()
{
if (Application_Model_Preference::GetAllow3rdPartyApi()){
// disable the view and the layout
$this->view->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
$result = Schedule::GetPlayOrderRange(0, 1);
$date = new DateHelper;
$timeNow = $date->getTimestamp();
$result = array("env"=>APPLICATION_ENV,
"schedulerTime"=>gmdate("Y-m-d H:i:s"),
"currentShow"=>Show_DAL::GetCurrentShow($timeNow),
"nextShow"=>Show_DAL::GetNextShows($timeNow, 5),
"timezone"=> date("T"),
"timezoneOffset"=> date("Z"));
//echo json_encode($result);
header("Content-type: text/javascript");
echo $_GET['callback'].'('.json_encode($result).')';
} else {
header('HTTP/1.0 401 Unauthorized');
print 'You are not allowed to access this resource. ';
exit;
}
}
public function weekInfoAction()
{
if (Application_Model_Preference::GetAllow3rdPartyApi()){
// disable the view and the layout
$this->view->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
$dow = array("sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday");
$result = array();
for ($i=0; $i<7; $i++){
$result[$dow[$i]] = Show_DAL::GetShowsByDayOfWeek($i);
}
header("Content-type: text/javascript");
echo $_GET['callback'].'('.json_encode($result).')';
} else {
header('HTTP/1.0 401 Unauthorized');
print 'You are not allowed to access this resource. ';
exit;
}
}
public function scheduleAction()
{
global $CC_CONFIG;
// disable the view and the layout
$this->view->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
$api_key = $this->_getParam('api_key');
if(!in_array($api_key, $CC_CONFIG["apiKey"]))
{
header('HTTP/1.0 401 Unauthorized');
print 'You are not allowed to access this resource. ';
exit;
}
PEAR::setErrorHandling(PEAR_ERROR_RETURN);
$result = Schedule::GetScheduledPlaylists();
echo json_encode($result);
}
public function notifyMediaItemStartPlayAction()
{
global $CC_CONFIG;
// disable the view and the layout
$this->view->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
$api_key = $this->_getParam('api_key');
if(!in_array($api_key, $CC_CONFIG["apiKey"]))
{
header('HTTP/1.0 401 Unauthorized');
print 'You are not allowed to access this resource.';
exit;
}
$schedule_group_id = $this->_getParam("schedule_id");
$media_id = $this->_getParam("media_id");
$result = Schedule::UpdateMediaPlayedStatus($media_id);
if (!PEAR::isError($result)) {
echo json_encode(array("status"=>1, "message"=>""));
} else {
echo json_encode(array("status"=>0, "message"=>"DB Error:".$result->getMessage()));
}
}
public function notifyScheduleGroupPlayAction()
{
global $CC_CONFIG;
// disable the view and the layout
$this->view->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
$api_key = $this->_getParam('api_key');
if(!in_array($api_key, $CC_CONFIG["apiKey"]))
{
header('HTTP/1.0 401 Unauthorized');
print 'You are not allowed to access this resource.';
exit;
}
PEAR::setErrorHandling(PEAR_ERROR_RETURN);
$schedule_group_id = $this->_getParam("schedule_id");
if (is_numeric($schedule_group_id)) {
$sg = new ScheduleGroup($schedule_group_id);
if ($sg->exists()) {
$result = $sg->notifyGroupStartPlay();
if (!PEAR::isError($result)) {
echo json_encode(array("status"=>1, "message"=>""));
exit;
} else {
echo json_encode(array("status"=>0, "message"=>"DB Error:".$result->getMessage()));
exit;
}
} else {
echo json_encode(array("status"=>0, "message"=>"Schedule group does not exist: ".$schedule_group_id));
exit;
}
} else {
echo json_encode(array("status"=>0, "message"=>"Incorrect or non-numeric arguments given."));
exit;
}
}
public function recordedShowsAction()
{
global $CC_CONFIG;
$api_key = $this->_getParam('api_key');
if (!in_array($api_key, $CC_CONFIG["apiKey"]))
{
header('HTTP/1.0 401 Unauthorized');
print 'You are not allowed to access this resource.';
exit;
}
$today_timestamp = date("Y-m-d H:i:s");
$now = new DateTime($today_timestamp);
$end_timestamp = $now->add(new DateInterval("PT2H"));
$end_timestamp = $end_timestamp->format("Y-m-d H:i:s");
$this->view->shows = Show::getShows($today_timestamp, $end_timestamp, $excludeInstance=NULL, $onlyRecord=TRUE);
}
public function uploadRecordedAction()
{
global $CC_CONFIG;
$api_key = $this->_getParam('api_key');
if (!in_array($api_key, $CC_CONFIG["apiKey"]))
{
header('HTTP/1.0 401 Unauthorized');
print 'You are not allowed to access this resource.';
exit;
}
$upload_dir = ini_get("upload_tmp_dir");
$file = StoredFile::uploadFile($upload_dir);
$show_instance = $this->_getParam('show_instance');
$show_inst = new ShowInstance($show_instance);
$show_inst->setRecordedFile($file->getId());
$show_name = $show_inst->getName();
$show_genre = $show_inst->getGenre();
$show_start_time = $show_inst->getShowStart();
if(Application_Model_Preference::GetDoSoundCloudUpload())
{
for($i=0; $i<$CC_CONFIG['soundcloud-connection-retries']; $i++) {
$show = new Show($show_inst->getShowId());
$description = $show->getDescription();
$hosts = $show->getHosts();
$tags = array_merge($hosts, array($show_name));
try {
$soundcloud = new ATSoundcloud();
$soundcloud_id = $soundcloud->uploadTrack($file->getRealFilePath(), $file->getName(), $description, $tags, $show_start_time, $show_genre);
$show_inst->setSoundCloudFileId($soundcloud_id);
break;
}
catch (Services_Soundcloud_Invalid_Http_Response_Code_Exception $e) {
$code = $e->getHttpCode();
if(!in_array($code, array(0, 100))) {
break;
}
}
sleep($CC_CONFIG['soundcloud-connection-wait']);
}
}
$this->view->id = $file->getId();
}
}

View file

@ -0,0 +1,27 @@
<?php
class DashboardController extends Zend_Controller_Action
{
public function init()
{
/* Initialize action controller here */
}
public function indexAction()
{
// action body
}
public function helpAction()
{
// action body
}
}

View file

@ -0,0 +1,58 @@
<?php
class ErrorController extends Zend_Controller_Action
{
public function errorAction()
{
$errors = $this->_getParam('error_handler');
switch ($errors->type) {
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE:
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
// 404 error -- controller or action not found
$this->getResponse()->setHttpResponseCode(404);
$this->view->message = 'Page not found';
break;
default:
// application error
$this->getResponse()->setHttpResponseCode(500);
$this->view->message = 'Application error';
break;
}
// Log exception, if logger available
if ($log = $this->getLog()) {
$log->crit($this->view->message, $errors->exception);
}
// conditionally display exceptions
if ($this->getInvokeArg('displayExceptions') == true) {
$this->view->exception = $errors->exception;
}
$this->view->request = $errors->request;
}
public function getLog()
{
$bootstrap = $this->getInvokeArg('bootstrap');
if (!$bootstrap->hasPluginResource('Log')) {
return false;
}
$log = $bootstrap->getResource('Log');
return $log;
}
public function deniedAction()
{
// action body
}
}

View file

@ -0,0 +1,28 @@
<?php
class IndexController extends Zend_Controller_Action
{
public function init()
{
}
public function indexAction()
{
$this->_forward('index', 'login');
}
public function mainAction()
{
$this->_helper->layout->setLayout('layout');
}
}

View file

@ -0,0 +1,195 @@
<?php
class LibraryController extends Zend_Controller_Action
{
protected $pl_sess = null;
protected $search_sess = null;
public function init()
{
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('contents', 'json')
->addActionContext('delete', 'json')
->addActionContext('context-menu', 'json')
->addActionContext('get-file-meta-data', 'html')
->initContext();
$this->pl_sess = new Zend_Session_Namespace(UI_PLAYLIST_SESSNAME);
$this->search_sess = new Zend_Session_Namespace("search");
}
public function indexAction()
{
$this->view->headScript()->appendFile('/js/contextmenu/jjmenu.js','text/javascript');
$this->view->headScript()->appendFile('/js/jplayer/jquery.jplayer.min.js');
$this->view->headScript()->appendFile('/js/datatables/js/jquery.dataTables.js','text/javascript');
$this->view->headScript()->appendFile('/js/airtime/library/library.js','text/javascript');
$this->view->headScript()->appendFile('/js/airtime/library/advancedsearch.js','text/javascript');
$this->view->headLink()->appendStylesheet('/css/media_library.css');
$this->view->headLink()->appendStylesheet('/css/contextmenu.css');
$this->_helper->layout->setLayout('library');
$this->_helper->viewRenderer->setResponseSegment('library');
$form = new Application_Form_AdvancedSearch();
$form->addGroup(1, 1);
$this->search_sess->next_group = 2;
$this->search_sess->next_row[1] = 2;
$this->view->form = $form;
$this->view->md = $this->search_sess->md;
$this->_helper->actionStack('index', 'playlist');
}
public function contextMenuAction()
{
$id = $this->_getParam('id');
$type = $this->_getParam('type');
$params = '/format/json/id/#id#/type/#type#';
$pl_sess = $this->pl_sess;
if($type === "au") {
$menu[] = array('action' => array('type' => 'ajax', 'url' => '/Library/delete'.$params, 'callback' => 'window["deleteAudioClip"]'),
'title' => 'Delete');
if(isset($pl_sess->id)) {
$menu[] = array('action' => array('type' => 'ajax', 'url' => '/Playlist/add-item'.$params, 'callback' => 'window["setSPLContent"]'),
'title' => 'Add to Playlist');
}
$menu[] = array('action' => array('type' => 'gourl', 'url' => '/Library/edit-file-md/id/#id#'),
'title' => 'Edit Metadata');
}
else if($type === "pl") {
if(!isset($pl_sess->id) || $pl_sess->id !== $id) {
$menu[] = array('action' =>
array('type' => 'ajax',
'url' => '/Playlist/edit'.$params,
'callback' => 'window["openDiffSPL"]'),
'title' => 'Edit');
}
else if(isset($pl_sess->id) && $pl_sess->id === $id) {
$menu[] = array('action' =>
array('type' => 'ajax',
'url' => '/Playlist/close'.$params,
'callback' => 'window["noOpenPL"]'),
'title' => 'Close');
}
$menu[] = array('action' => array('type' => 'ajax', 'url' => '/Playlist/metadata/format/json/id/#id#', 'callback' => 'window["createPlaylistMetaForm"]'),
'title' => 'Edit Metadata');
$menu[] = array('action' => array('type' => 'ajax', 'url' => '/Playlist/delete'.$params, 'callback' => 'window["deletePlaylist"]'),
'title' => 'Delete');
}
//returns format jjmenu is looking for.
die(json_encode($menu));
}
public function deleteAction()
{
$id = $this->_getParam('id');
if (!is_null($id)) {
$file = StoredFile::Recall($id);
if (PEAR::isError($file)) {
$this->view->message = $file->getMessage();
return;
}
else if(is_null($file)) {
$this->view->message = "file doesn't exist";
return;
}
$res = $file->delete();
if (PEAR::isError($res)) {
$this->view->message = $res->getMessage();
return;
}
}
$this->view->id = $id;
}
public function contentsAction()
{
$post = $this->getRequest()->getPost();
$datatables = StoredFile::searchFilesForPlaylistBuilder($post);
die(json_encode($datatables));
}
public function editFileMdAction()
{
$request = $this->getRequest();
$form = new Application_Form_EditAudioMD();
$file_id = $this->_getParam('id', null);
$file = StoredFile::Recall($file_id);
if ($request->isPost()) {
if ($form->isValid($request->getPost())) {
$formdata = $form->getValues();
$file->replaceDbMetadata($formdata);
$this->_helper->redirector('index');
}
}
$form->populate($file->md);
$this->view->form = $form;
}
public function getFileMetaDataAction()
{
$id = $this->_getParam('id');
$type = $this->_getParam('type');
if($type == "au") {
$file = StoredFile::Recall($id);
$this->view->type = $type;
$this->view->md = $file->md;
}
else if($type == "pl") {
$file = Playlist::Recall($id);
$this->view->type = $type;
$this->view->md = $file->getAllPLMetaData();
$this->view->contents = $file->getContents();
}
}
}

View file

@ -0,0 +1,95 @@
<?php
class LoginController extends Zend_Controller_Action
{
public function init()
{
/* Initialize action controller here */
}
public function indexAction()
{
if(Zend_Auth::getInstance()->hasIdentity())
{
$this->_redirect('Nowplaying');
}
//uses separate layout without a navigation.
$this->_helper->layout->setLayout('login');
$request = $this->getRequest();
$form = new Application_Form_Login();
$message = "Please enter your user name and password";
if($request->isPost())
{
if($form->isValid($request->getPost()))
{
$authAdapter = $this->getAuthAdapter();
//get the username and password from the form
$username = $form->getValue('username');
$password = $form->getValue('password');
//pass to the adapter the submitted username and password
$authAdapter->setIdentity($username)
->setCredential($password);
$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($authAdapter);
if($result->isValid())
{
//all info about this user from the login table omit only the password
$userInfo = $authAdapter->getResultRowObject(null, 'password');
//the default storage is a session with namespace Zend_Auth
$authStorage = $auth->getStorage();
$authStorage->write($userInfo);
$this->_redirect('Nowplaying');
}
else
{
$message = "Wrong username or password provided. Please try again.";
}
}
}
$this->view->message = $message;
$this->view->form = $form;
$this->view->airtimeVersion = AIRTIME_VERSION;
$this->view->airtimeCopyright = AIRTIME_COPYRIGHT_DATE;
}
public function logoutAction()
{
Zend_Auth::getInstance()->clearIdentity();
$this->_redirect('login/index');
}
/**
* Gets the adapter for authentication against a database table
*
* @return object
*/
protected function getAuthAdapter()
{
$dbAdapter = Zend_Db_Table::getDefaultAdapter();
$authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
$authAdapter->setTableName('cc_subjs')
->setIdentityColumn('login')
->setCredentialColumn('pass')
->setCredentialTreatment('MD5(?)');
return $authAdapter;
}
}

View file

@ -0,0 +1,48 @@
<?php
class NowplayingController extends Zend_Controller_Action
{
public function init()
{
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('get-data-grid-data', 'json')
->initContext();
}
public function indexAction()
{
$this->view->headScript()->appendFile('/js/datatables/js/jquery.dataTables.min.js','text/javascript');
$this->view->headScript()->appendFile('/js/playlist/nowplayingdatagrid.js','text/javascript');
$this->view->headScript()->appendFile('/js/playlist/nowview.js','text/javascript');
}
public function getDataGridDataAction()
{
$viewType = $this->_request->getParam('view');
$dateString = $this->_request->getParam('date');
$this->view->entries = Application_Model_Nowplaying::GetDataGridData($viewType, $dateString);
}
public function livestreamAction()
{
//use bare bones layout (no header bar or menu)
$this->_helper->layout->setLayout('bare');
}
public function dayViewAction()
{
$this->view->headScript()->appendFile('/js/datatables/js/jquery.dataTables.min.js','text/javascript');
$this->view->headScript()->appendFile('/js/playlist/nowplayingdatagrid.js','text/javascript');
$this->view->headScript()->appendFile('/js/playlist/dayview.js','text/javascript');
}
}

View file

@ -0,0 +1,362 @@
<?php
class PlaylistController extends Zend_Controller_Action
{
protected $pl_sess = null;
public function init()
{
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('add-item', 'json')
->addActionContext('delete-item', 'json')
->addActionContext('set-fade', 'json')
->addActionContext('set-cue', 'json')
->addActionContext('move-item', 'json')
->addActionContext('close', 'json')
->addActionContext('new', 'json')
->addActionContext('metadata', 'json')
->addActionContext('edit', 'json')
->addActionContext('delete-active', 'json')
->addActionContext('delete', 'json')
->addActionContext('set-playlist-fades', 'json')
->initContext();
$this->pl_sess = new Zend_Session_Namespace(UI_PLAYLIST_SESSNAME);
}
private function getPlaylist()
{
$pl_sess = $this->pl_sess;
if(isset($pl_sess->id)) {
$pl = Playlist::Recall($pl_sess->id);
if($pl === FALSE) {
unset($pl_sess->id);
return;
}
return $pl;
}
}
private function changePlaylist($pl_id)
{
$pl_sess = $this->pl_sess;
if(isset($pl_sess->id)) {
$pl = Playlist::Recall($pl_sess->id);
if($pl !== FALSE) {
$this->closePlaylist($pl);
}
}
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$pl = Playlist::Recall($pl_id);
if($pl === FALSE) {
return FALSE;
}
$pl->lock($userInfo->id);
$pl_sess->id = $pl_id;
}
private function closePlaylist($pl)
{
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$res = $pl->unlock($userInfo->id);
$pl_sess = $this->pl_sess;
unset($pl_sess->id);
return $res;
}
public function indexAction()
{
$this->view->headScript()->appendFile('/js/airtime/library/spl.js','text/javascript');
$this->view->headLink()->appendStylesheet('/css/playlist_builder.css');
$this->_helper->viewRenderer->setResponseSegment('spl');
$this->view->pl = $this->getPlaylist();
}
public function newAction()
{
$pl_sess = $this->pl_sess;
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$pl = new Playlist();
$pl->create("Untitled Playlist");
$pl->setPLMetaData('dc:creator', $userInfo->login);
$this->changePlaylist($pl->getId());
$form = new Application_Form_PlaylistMetadata();
$this->view->fieldset = $form;
$this->view->form = $this->view->render('playlist/new.phtml');
}
public function metadataAction()
{
$request = $this->getRequest();
$form = new Application_Form_PlaylistMetadata();
$pl_id = $this->_getParam('id', null);
//not a new playlist
if(!is_null($pl_id)) {
$this->changePlaylist($pl_id);
$pl = $this->getPlaylist();
$title = $pl->getPLMetaData(UI_MDATA_KEY_TITLE);
$desc = $pl->getPLMetaData(UI_MDATA_KEY_DESCRIPTION);
$data = array( 'title' => $title, 'description' => $desc);
$form->populate($data);
}
if ($request->isPost()) {
$title = $this->_getParam('title', null);
$description = $this->_getParam('description', null);
$pl = $this->getPlaylist();
if($title)
$pl->setName($title);
if(isset($description)) {
$pl->setPLMetaData(UI_MDATA_KEY_DESCRIPTION, $description);
}
$this->view->pl = $pl;
$this->view->html = $this->view->render('playlist/index.phtml');
unset($this->view->pl);
}
$this->view->fieldset = $form;
$this->view->form = $this->view->render('playlist/new.phtml');
}
public function editAction()
{
$pl_id = $this->_getParam('id', null);
if(!is_null($pl_id)) {
$this->changePlaylist($pl_id);
}
$pl = $this->getPlaylist();
$this->view->pl = $pl;
$this->view->html = $this->view->render('playlist/index.phtml');
unset($this->view->pl);
}
public function addItemAction()
{
$id = $this->_getParam('id');
$pos = $this->_getParam('pos', null);
if (!is_null($id)) {
$pl = $this->getPlaylist();
$res = $pl->addAudioClip($id, $pos);
if (PEAR::isError($res)) {
$this->view->message = $res->getMessage();
}
$this->view->pl = $pl;
$this->view->html = $this->view->render('playlist/update.phtml');
$this->view->name = $pl->getName();
$this->view->length = $pl->getLength();
unset($this->view->pl);
return;
}
$this->view->message = "a file is not chosen";
}
public function moveItemAction()
{
$oldPos = $this->_getParam('oldPos');
$newPos = $this->_getParam('newPos');
$pl = $this->getPlaylist();
$pl->moveAudioClip($oldPos, $newPos);
$this->view->pl = $pl;
$this->view->html = $this->view->render('playlist/update.phtml');
$this->view->name = $pl->getName();
$this->view->length = $pl->getLength();
unset($this->view->pl);
}
public function deleteItemAction()
{
$positions = $this->_getParam('pos', array());
if (!is_array($positions))
$positions = array($positions);
//so the automatic updating of playlist positioning doesn't affect removal.
sort($positions);
$positions = array_reverse($positions);
$pl = $this->getPlaylist();
foreach ($positions as $pos) {
$pl->delAudioClip($pos);
}
$this->view->pl = $pl;
$this->view->html = $this->view->render('playlist/update.phtml');
$this->view->name = $pl->getName();
$this->view->length = $pl->getLength();
unset($this->view->pl);
}
public function setCueAction()
{
$request = $this->getRequest();
$pos = $this->_getParam('pos');
$pl = $this->getPlaylist();
if($request->isPost()) {
$cueIn = $this->_getParam('cueIn', null);
$cueOut = $this->_getParam('cueOut', null);
$response = $pl->changeClipLength($pos, $cueIn, $cueOut);
$this->view->response = $response;
return;
}
$cues = $pl->getCueInfo($pos);
$this->view->pos = $pos;
$this->view->cueIn = $cues[0];
$this->view->cueOut = $cues[1];
$this->view->origLength = $cues[2];
$this->view->html = $this->view->render('playlist/set-cue.phtml');
}
public function setFadeAction()
{
$request = $this->getRequest();
$pos = $this->_getParam('pos');
$pl = $this->getPlaylist();
if($request->isPost()) {
$fadeIn = $this->_getParam('fadeIn', null);
$fadeOut = $this->_getParam('fadeOut', null);
$response = $pl->changeFadeInfo($pos, $fadeIn, $fadeOut);
$this->view->response = $response;
return;
}
$this->view->pos = intval($pos);
$fades = $pl->getFadeInfo($pos+1);
$this->view->fadeIn = $fades[0];
$fades = $pl->getFadeInfo($pos);
$this->view->fadeOut = $fades[1];
$this->view->html = $this->view->render('playlist/set-fade.phtml');
}
public function deleteAction()
{
$id = $this->_getParam('id', null);
$pl = Playlist::Recall($id);
if ($pl !== FALSE) {
Playlist::Delete($id);
$pl_sess = $this->pl_sess;
if($pl_sess->id === $id){
unset($pl_sess->id);
}
}
$this->view->id = $id;
}
public function deleteActiveAction()
{
$pl = $this->getPlaylist();
Playlist::Delete($pl->getId());
$pl_sess = $this->pl_sess;
unset($pl_sess->id);
$this->view->html = $this->view->render('playlist/index.phtml');
}
public function closeAction()
{
$pl = $this->getPlaylist();
$this->closePlaylist($pl);
$this->view->html = $this->view->render('playlist/index.phtml');
}
public function setPlaylistFadesAction()
{
$request = $this->getRequest();
$pl = $this->getPlaylist();
if($request->isPost()) {
$fadeIn = $this->_getParam('fadeIn', null);
$fadeOut = $this->_getParam('fadeOut', null);
if($fadeIn)
$response = $pl->changeFadeInfo(0, $fadeIn, $fadeOut);
else if($fadeOut)
$response = $pl->changeFadeInfo($pl->getSize(), $fadeIn, $fadeOut);
$this->view->response = $response;
return;
}
$fades = $pl->getFadeInfo(0);
$this->view->fadeIn = $fades[0];
$fades = $pl->getFadeInfo($pl->getSize());
$this->view->fadeOut = $fades[1];
}
}

View file

@ -0,0 +1,44 @@
<?php
class PluploadController extends Zend_Controller_Action
{
public function init()
{
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('upload', 'json')
->addActionContext('upload-recorded', 'json')
->initContext();
}
public function indexAction()
{
// action body
}
public function uploadAction()
{
$upload_dir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload";
$file = StoredFile::uploadFile($upload_dir);
die('{"jsonrpc" : "2.0", "id" : '.$file->getId().' }');
}
public function pluploadAction()
{
$this->view->headScript()->appendFile('/js/plupload/plupload.full.min.js','text/javascript');
$this->view->headScript()->appendFile('/js/plupload/jquery.plupload.queue.min.js','text/javascript');
$this->view->headScript()->appendFile('/js/airtime/library/plupload.js','text/javascript');
$this->view->headLink()->appendStylesheet('/css/plupload.queue.css');
}
}

View file

@ -0,0 +1,48 @@
<?php
class PreferenceController extends Zend_Controller_Action
{
public function init()
{
/* Initialize action controller here */
}
public function indexAction()
{
$this->view->headScript()->appendFile('/js/airtime/preferences/preferences.js','text/javascript');
$request = $this->getRequest();
$this->view->statusMsg = "";
$form = new Application_Form_Preferences();
if ($request->isPost()) {
if ($form->isValid($request->getPost())) {
$values = $form->getValues();
Application_Model_Preference::SetHeadTitle($values["preferences_general"]["stationName"], $this->view);
Application_Model_Preference::SetDefaultFade($values["preferences_general"]["stationDefaultFade"]);
Application_Model_Preference::SetStreamLabelFormat($values["preferences_general"]["streamFormat"]);
Application_Model_Preference::SetAllow3rdPartyApi($values["preferences_general"]["thirdPartyApi"]);
Application_Model_Preference::SetDoSoundCloudUpload($values["preferences_soundcloud"]["UseSoundCloud"]);
Application_Model_Preference::SetSoundCloudUser($values["preferences_soundcloud"]["SoundCloudUser"]);
Application_Model_Preference::SetSoundCloudPassword($values["preferences_soundcloud"]["SoundCloudPassword"]);
Application_Model_Preference::SetSoundCloudTags($values["preferences_soundcloud"]["SoundCloudTags"]);
Application_Model_Preference::SetSoundCloudGenre($values["preferences_soundcloud"]["SoundCloudGenre"]);
Application_Model_Preference::SetSoundCloudTrackType($values["preferences_soundcloud"]["SoundCloudTrackType"]);
Application_Model_Preference::SetSoundCloudLicense($values["preferences_soundcloud"]["SoundCloudLicense"]);
$this->view->statusMsg = "<div class='success'>Preferences updated.</div>";
}
}
$this->view->form = $form;
}
}

View file

@ -0,0 +1,695 @@
<?php
class ScheduleController extends Zend_Controller_Action
{
protected $sched_sess = null;
public function init()
{
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('event-feed', 'json')
->addActionContext('make-context-menu', 'json')
->addActionContext('add-show-dialog', 'json')
->addActionContext('add-show', 'json')
->addActionContext('move-show', 'json')
->addActionContext('resize-show', 'json')
->addActionContext('delete-show', 'json')
->addActionContext('schedule-show', 'json')
->addActionContext('schedule-show-dialog', 'json')
->addActionContext('show-content-dialog', 'json')
->addActionContext('clear-show', 'json')
->addActionContext('get-current-playlist', 'json')
->addActionContext('find-playlists', 'json')
->addActionContext('remove-group', 'json')
->addActionContext('edit-show', 'json')
->addActionContext('add-show', 'json')
->addActionContext('cancel-show', 'json')
->addActionContext('get-form', 'json')
->addActionContext('upload-to-sound-cloud', 'json')
->initContext();
$this->sched_sess = new Zend_Session_Namespace("schedule");
}
public function indexAction()
{
$this->view->headScript()->appendFile('/js/contextmenu/jjmenu.js','text/javascript');
$this->view->headScript()->appendFile('/js/datatables/js/jquery.dataTables.js','text/javascript');
$this->view->headScript()->appendFile('/js/fullcalendar/fullcalendar.js','text/javascript');
$this->view->headScript()->appendFile('/js/timepicker/jquery.ui.timepicker-0.0.6.js','text/javascript');
$this->view->headScript()->appendFile('/js/colorpicker/js/colorpicker.js','text/javascript');
$this->view->headScript()->appendFile('/js/airtime/schedule/full-calendar-functions.js','text/javascript');
$this->view->headScript()->appendFile('/js/airtime/schedule/add-show.js','text/javascript');
$this->view->headScript()->appendFile('/js/airtime/schedule/schedule.js','text/javascript');
$this->view->headLink()->appendStylesheet('/css/jquery-ui-timepicker.css');
$this->view->headLink()->appendStylesheet('/css/fullcalendar.css');
$this->view->headLink()->appendStylesheet('/css/colorpicker/css/colorpicker.css');
$this->view->headLink()->appendStylesheet('/css/add-show.css');
$this->view->headLink()->appendStylesheet('/css/contextmenu.css');
$formWhat = new Application_Form_AddShowWhat();
$formWho = new Application_Form_AddShowWho();
$formWhen = new Application_Form_AddShowWhen();
$formRepeats = new Application_Form_AddShowRepeats();
$formStyle = new Application_Form_AddShowStyle();
$formRecord = new Application_Form_AddShowRR();
$formAbsoluteRebroadcast = new Application_Form_AddShowAbsoluteRebroadcastDates();
$formRebroadcast = new Application_Form_AddShowRebroadcastDates();
$formWhat->removeDecorator('DtDdWrapper');
$formWho->removeDecorator('DtDdWrapper');
$formWhen->removeDecorator('DtDdWrapper');
$formRepeats->removeDecorator('DtDdWrapper');
$formStyle->removeDecorator('DtDdWrapper');
$formRecord->removeDecorator('DtDdWrapper');
$this->view->what = $formWhat;
$this->view->when = $formWhen;
$this->view->repeats = $formRepeats;
$this->view->who = $formWho;
$this->view->style = $formStyle;
$this->view->rr = $formRecord;
$this->view->absoluteRebroadcast = $formAbsoluteRebroadcast;
$this->view->rebroadcast = $formRebroadcast;
$this->view->addNewShow = true;
$formWhat->populate(array('add_show_id' => '-1'));
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$user = new User($userInfo->id);
$this->view->isAdmin = $user->isAdmin();
}
public function eventFeedAction()
{
$start = $this->_getParam('start', null);
$end = $this->_getParam('end', null);
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$user = new User($userInfo->id);
if($user->isAdmin())
$editable = true;
else
$editable = false;
$this->view->events = Show::getFullCalendarEvents($start, $end, $editable);
}
public function moveShowAction()
{
$deltaDay = $this->_getParam('day');
$deltaMin = $this->_getParam('min');
$showInstanceId = $this->_getParam('showInstanceId');
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$user = new User($userInfo->id);
if($user->isAdmin()) {
$show = new ShowInstance($showInstanceId);
$error = $show->moveShow($deltaDay, $deltaMin);
}
if(isset($error))
$this->view->error = $error;
}
public function resizeShowAction()
{
$deltaDay = $this->_getParam('day');
$deltaMin = $this->_getParam('min');
$showInstanceId = $this->_getParam('showInstanceId');
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$user = new User($userInfo->id);
if($user->isAdmin()) {
$show = new ShowInstance($showInstanceId);
$error = $show->resizeShow($deltaDay, $deltaMin);
}
if(isset($error))
$this->view->error = $error;
}
public function deleteShowAction()
{
$showInstanceId = $this->_getParam('id');
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$user = new User($userInfo->id);
if($user->isAdmin()) {
$show = new ShowInstance($showInstanceId);
$show->deleteShow();
}
}
public function uploadToSoundCloudAction()
{
global $CC_CONFIG;
$show_instance = $this->_getParam('id');
$show_inst = new ShowInstance($show_instance);
$file = $show_inst->getRecordedFile();
if(is_null($file)) {
$this->view->error = "Recorded file does not exist";
return;
}
$show_name = $show_inst->getName();
$show_genre = $show_inst->getGenre();
$show_start_time = $show_inst->getShowStart();
if(Application_Model_Preference::GetDoSoundCloudUpload())
{
for($i=0; $i<$CC_CONFIG['soundcloud-connection-retries']; $i++) {
$show = new Show($show_inst->getShowId());
$description = $show->getDescription();
$hosts = $show->getHosts();
$tags = array_merge($hosts, array($show_name));
try {
$soundcloud = new ATSoundcloud();
$soundcloud_id = $soundcloud->uploadTrack($file->getRealFilePath(), $file->getName(), $description, $tags, $show_start_time, $show_genre);
$show_inst->setSoundCloudFileId($soundcloud_id);
$this->view->soundcloud_id = $soundcloud_id;
break;
}
catch (Services_Soundcloud_Invalid_Http_Response_Code_Exception $e) {
$code = $e->getHttpCode();
if(!in_array($code, array(0, 100))) {
break;
}
}
sleep($CC_CONFIG['soundcloud-connection-wait']);
}
}
}
public function makeContextMenuAction()
{
$id = $this->_getParam('id');
$today_timestamp = date("Y-m-d H:i:s");
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$user = new User($userInfo->id);
$show = new ShowInstance($id);
$params = '/format/json/id/#id#';
if (strtotime($today_timestamp) < strtotime($show->getShowStart())) {
if (($user->isHost($show->getShowId()) || $user->isAdmin()) && !$show->isRecorded() && !$show->isRebroadcast()) {
$menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/schedule-show-dialog'.$params,
'callback' => 'window["buildScheduleDialog"]'), 'title' => 'Add / Remove Content');
$menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/clear-show'.$params,
'callback' => 'window["scheduleRefetchEvents"]'), 'title' => 'Remove All Content');
}
}
if(!$show->isRecorded()) {
$menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/show-content-dialog'.$params,
'callback' => 'window["buildContentDialog"]'), 'title' => 'Show Content');
}
if (strtotime($show->getShowEnd()) <= strtotime($today_timestamp)
&& is_null($show->getSoundCloudFileId())
&& Application_Model_Preference::GetDoSoundCloudUpload()) {
$menu[] = array('action' => array('type' => 'fn',
'callback' => "window['uploadToSoundCloud']($id)"),
'title' => 'Upload to Soundcloud');
}
if (strtotime($show->getShowStart()) <= strtotime($today_timestamp) &&
strtotime($today_timestamp) < strtotime($show->getShowEnd()) &&
$user->isAdmin() && !$show->isRecorded()) {
$menu[] = array('action' => array('type' => 'fn',
'callback' => "window['confirmCancelShow']($id)"),
'title' => 'Cancel Current Show');
}
if (strtotime($today_timestamp) < strtotime($show->getShowStart())) {
if ($user->isAdmin()) {
$menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/edit-show/format/json/id/'.$id,
'callback' => 'window["beginEditShow"]'), 'title' => 'Edit Show');
//$menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/cancel-show'.$params,
// 'callback' => 'window["scheduleRefetchEvents"]'), 'title' => 'Edit This Instance and All Following');
$menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/delete-show'.$params,
'callback' => 'window["scheduleRefetchEvents"]'), 'title' => 'Delete This Instance');
$menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/cancel-show'.$params,
'callback' => 'window["scheduleRefetchEvents"]'), 'title' => 'Delete This Instance and All Following');
}
}
//returns format jjmenu is looking for.
die(json_encode($menu));
}
public function scheduleShowAction()
{
$showInstanceId = $this->sched_sess->showInstanceId;
$search = $this->_getParam('search', null);
$plId = $this->_getParam('plId');
if($search == "") {
$search = null;
}
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$user = new User($userInfo->id);
$show = new ShowInstance($showInstanceId);
if($user->isHost($show->getShowId()) || $user->isAdmin()) {
$show->scheduleShow(array($plId));
}
$this->view->showContent = $show->getShowContent();
$this->view->timeFilled = $show->getTimeScheduled();
$this->view->percentFilled = $show->getPercentScheduled();
$this->view->chosen = $this->view->render('schedule/scheduled-content.phtml');
unset($this->view->showContent);
}
public function clearShowAction()
{
$showInstanceId = $this->_getParam('id');
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$user = new User($userInfo->id);
$show = new ShowInstance($showInstanceId);
if($user->isHost($show->getShowId()) || $user->isAdmin())
$show->clearShow();
}
public function getCurrentPlaylistAction()
{
$this->view->entries = Schedule::GetPlayOrderRange();
}
public function findPlaylistsAction()
{
$post = $this->getRequest()->getPost();
$show = new ShowInstance($this->sched_sess->showInstanceId);
$playlists = $show->searchPlaylistsForShow($post);
//for datatables
die(json_encode($playlists));
}
public function removeGroupAction()
{
$showInstanceId = $this->sched_sess->showInstanceId;
$group_id = $this->_getParam('groupId');
$search = $this->_getParam('search', null);
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$user = new User($userInfo->id);
$show = new ShowInstance($showInstanceId);
if($user->isHost($show->getShowId()) || $user->isAdmin()) {
$show->removeGroupFromShow($group_id);
}
$this->view->showContent = $show->getShowContent();
$this->view->timeFilled = $show->getTimeScheduled();
$this->view->percentFilled = $show->getPercentScheduled();
$this->view->chosen = $this->view->render('schedule/scheduled-content.phtml');
unset($this->view->showContent);
}
public function scheduleShowDialogAction()
{
$showInstanceId = $this->_getParam('id');
$this->sched_sess->showInstanceId = $showInstanceId;
$show = new ShowInstance($showInstanceId);
$start_timestamp = $show->getShowStart();
$end_timestamp = $show->getShowEnd();
//check to make sure show doesn't overlap.
if(Show::getShows($start_timestamp, $end_timestamp, array($showInstanceId))) {
$this->view->error = "cannot schedule an overlapping show.";
return;
}
$start = explode(" ", $start_timestamp);
$end = explode(" ", $end_timestamp);
$startTime = explode(":", $start[1]);
$endTime = explode(":", $end[1]);
$dateInfo_s = getDate(strtotime($start_timestamp));
$dateInfo_e = getDate(strtotime($end_timestamp));
$this->view->showContent = $show->getShowContent();
$this->view->timeFilled = $show->getTimeScheduled();
$this->view->showName = $show->getName();
$this->view->showLength = $show->getShowLength();
$this->view->percentFilled = $show->getPercentScheduled();
$this->view->s_wday = $dateInfo_s['weekday'];
$this->view->s_month = $dateInfo_s['month'];
$this->view->s_day = $dateInfo_s['mday'];
$this->view->e_wday = $dateInfo_e['weekday'];
$this->view->e_month = $dateInfo_e['month'];
$this->view->e_day = $dateInfo_e['mday'];
$this->view->startTime = sprintf("%d:%02d", $startTime[0], $startTime[1]);
$this->view->endTime = sprintf("%d:%02d", $endTime[0], $endTime[1]);
$this->view->chosen = $this->view->render('schedule/scheduled-content.phtml');
$this->view->dialog = $this->view->render('schedule/schedule-show-dialog.phtml');
unset($this->view->showContent);
}
public function showContentDialogAction()
{
$showInstanceId = $this->_getParam('id');
$show = new ShowInstance($showInstanceId);
$originalShowId = $show->isRebroadcast();
if (!is_null($originalShowId)){
$originalShow = new ShowInstance($originalShowId);
$originalShowName = $originalShow->getName();
$originalShowStart = $originalShow->getShowStart();
$timestamp = strtotime($originalShowStart);
$this->view->additionalShowInfo =
"Rebroadcast of show \"$originalShowName\" from "
.date("l, F jS", $timestamp)." at ".date("G:i", $timestamp);
}
$this->view->showContent = $show->getShowListContent();
$this->view->dialog = $this->view->render('schedule/show-content-dialog.phtml');
unset($this->view->showContent);
}
public function editShowAction()
{
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$user = new User($userInfo->id);
if(!$user->isAdmin()) {
return;
}
$showInstanceId = $this->_getParam('id');
$formWhat = new Application_Form_AddShowWhat();
$formWho = new Application_Form_AddShowWho();
$formWhen = new Application_Form_AddShowWhen();
$formRepeats = new Application_Form_AddShowRepeats();
$formStyle = new Application_Form_AddShowStyle();
$formRecord = new Application_Form_AddShowRR();
$formAbsoluteRebroadcast = new Application_Form_AddShowAbsoluteRebroadcastDates();
$formRebroadcast = new Application_Form_AddShowRebroadcastDates();
$formWhat->removeDecorator('DtDdWrapper');
$formWho->removeDecorator('DtDdWrapper');
$formWhen->removeDecorator('DtDdWrapper');
$formRepeats->removeDecorator('DtDdWrapper');
$formStyle->removeDecorator('DtDdWrapper');
$formRecord->removeDecorator('DtDdWrapper');
$formAbsoluteRebroadcast->removeDecorator('DtDdWrapper');
$formRebroadcast->removeDecorator('DtDdWrapper');
$this->view->what = $formWhat;
$this->view->when = $formWhen;
$this->view->repeats = $formRepeats;
$this->view->who = $formWho;
$this->view->style = $formStyle;
$this->view->rr = $formRecord;
$this->view->absoluteRebroadcast = $formAbsoluteRebroadcast;
$this->view->rebroadcast = $formRebroadcast;
$this->view->addNewShow = false;
$showInstance = new ShowInstance($showInstanceId);
$show = new Show($showInstance->getShowId());
$formWhat->populate(array('add_show_id' => $show->getId(),
'add_show_name' => $show->getName(),
'add_show_url' => $show->getUrl(),
'add_show_genre' => $show->getGenre(),
'add_show_description' => $show->getDescription()));
$formWhen->populate(array('add_show_start_date' => $show->getStartDate(),
'add_show_start_time' => Show::removeSecondsFromTime($show->getStartTime()),
'add_show_duration' => $show->getDuration(),
'add_show_repeats' => $show->isRepeating() ? 1 : 0));
$days = array();
$showDays = CcShowDaysQuery::create()->filterByDbShowId($showInstance->getShowId())->find();
foreach($showDays as $showDay){
array_push($days, $showDay->getDbDay());
}
$formRepeats->populate(array('add_show_repeat_type' => $show->getRepeatType(),
'add_show_day_check' => $days,
'add_show_end_date' => $show->getRepeatingEndDate(),
'add_show_no_end' => ($show->getRepeatingEndDate() == '')));
$formRecord->populate(array('add_show_record' => $show->isRecorded(),
'add_show_rebroadcast' => $show->isRebroadcast()));
$formRecord->getElement('add_show_record')->setOptions(array('disabled' => true));
$rebroadcastsRelative = $show->getRebroadcastsRelative();
$rebroadcastFormValues = array();
$i = 1;
foreach ($rebroadcastsRelative as $rebroadcast){
$rebroadcastFormValues["add_show_rebroadcast_date_$i"] = $rebroadcast['day_offset'];
$rebroadcastFormValues["add_show_rebroadcast_time_$i"] = Show::removeSecondsFromTime($rebroadcast['start_time']);
$i++;
}
$formRebroadcast->populate($rebroadcastFormValues);
$rebroadcastsAbsolute = $show->getRebroadcastsAbsolute();
$rebroadcastAbsoluteFormValues = array();
$i = 1;
foreach ($rebroadcastsAbsolute as $rebroadcast){
$rebroadcastAbsoluteFormValues["add_show_rebroadcast_date_absolute_$i"] = $rebroadcast['start_date'];
$rebroadcastAbsoluteFormValues["add_show_rebroadcast_time_absolute_$i"] = Show::removeSecondsFromTime($rebroadcast['start_time']);
$i++;
}
$formAbsoluteRebroadcast->populate($rebroadcastAbsoluteFormValues);
$hosts = array();
$showHosts = CcShowHostsQuery::create()->filterByDbShow($showInstance->getShowId())->find();
foreach($showHosts as $showHost){
array_push($hosts, $showHost->getDbHost());
}
$formWho->populate(array('add_show_hosts' => $hosts));
$formStyle->populate(array('add_show_background_color' => $show->getBackgroundColor(),
'add_show_color' => $show->getColor()));
$this->view->newForm = $this->view->render('schedule/add-show-form.phtml');
$this->view->entries = 5;
}
public function getFormAction(){
$formWhat = new Application_Form_AddShowWhat();
$formWho = new Application_Form_AddShowWho();
$formWhen = new Application_Form_AddShowWhen();
$formRepeats = new Application_Form_AddShowRepeats();
$formStyle = new Application_Form_AddShowStyle();
$formRecord = new Application_Form_AddShowRR();
$formAbsoluteRebroadcast = new Application_Form_AddShowAbsoluteRebroadcastDates();
$formRebroadcast = new Application_Form_AddShowRebroadcastDates();
$formWhat->removeDecorator('DtDdWrapper');
$formWho->removeDecorator('DtDdWrapper');
$formWhen->removeDecorator('DtDdWrapper');
$formRepeats->removeDecorator('DtDdWrapper');
$formStyle->removeDecorator('DtDdWrapper');
$formRecord->removeDecorator('DtDdWrapper');
$this->view->what = $formWhat;
$this->view->when = $formWhen;
$this->view->repeats = $formRepeats;
$this->view->who = $formWho;
$this->view->style = $formStyle;
$this->view->rr = $formRecord;
$this->view->absoluteRebroadcast = $formAbsoluteRebroadcast;
$this->view->rebroadcast = $formRebroadcast;
$this->view->addNewShow = true;
$formWhat->populate(array('add_show_id' => '-1'));
$this->view->form = $this->view->render('schedule/add-show-form.phtml');
}
public function addShowAction()
{
$js = $this->_getParam('data');
$data = array();
//need to convert from serialized jQuery array.
foreach($js as $j){
$data[$j["name"]] = $j["value"];
}
$data['add_show_hosts'] = $this->_getParam('hosts');
$data['add_show_day_check'] = $this->_getParam('days');
if($data['add_show_day_check'] == "") {
$data['add_show_day_check'] = null;
}
$formWhat = new Application_Form_AddShowWhat();
$formWho = new Application_Form_AddShowWho();
$formWhen = new Application_Form_AddShowWhen();
$formRepeats = new Application_Form_AddShowRepeats();
$formStyle = new Application_Form_AddShowStyle();
$formRecord = new Application_Form_AddShowRR();
$formAbsoluteRebroadcast = new Application_Form_AddShowAbsoluteRebroadcastDates();
$formRebroadcast = new Application_Form_AddShowRebroadcastDates();
$formWhat->removeDecorator('DtDdWrapper');
$formWho->removeDecorator('DtDdWrapper');
$formWhen->removeDecorator('DtDdWrapper');
$formRepeats->removeDecorator('DtDdWrapper');
$formStyle->removeDecorator('DtDdWrapper');
$formRecord->removeDecorator('DtDdWrapper');
$formAbsoluteRebroadcast->removeDecorator('DtDdWrapper');
$formRebroadcast->removeDecorator('DtDdWrapper');
$this->view->what = $formWhat;
$this->view->when = $formWhen;
$this->view->repeats = $formRepeats;
$this->view->who = $formWho;
$this->view->style = $formStyle;
$this->view->rr = $formRecord;
$this->view->absoluteRebroadcast = $formAbsoluteRebroadcast;
$this->view->rebroadcast = $formRebroadcast;
$this->view->addNewShow = true;
$what = $formWhat->isValid($data);
$when = $formWhen->isValid($data);
if($when) {
$when = $formWhen->checkReliantFields($data);
}
if($data["add_show_repeats"]) {
$repeats = $formRepeats->isValid($data);
if($repeats) {
$repeats = $formRepeats->checkReliantFields($data);
}
$formAbsoluteRebroadcast->reset();
//make it valid, results don't matter anyways.
$rebroadAb = 1;
if ($data["add_show_rebroadcast"]) {
$rebroad = $formRebroadcast->isValid($data);
if($rebroad) {
$rebroad = $formRebroadcast->checkReliantFields($data);
}
}
else {
$rebroad = 1;
}
}
else {
$formRebroadcast->reset();
//make it valid, results don't matter anyways.
$repeats = 1;
$rebroad = 1;
if ($data["add_show_rebroadcast"]) {
$rebroadAb = $formAbsoluteRebroadcast->isValid($data);
if($rebroadAb) {
$rebroadAb = $formAbsoluteRebroadcast->checkReliantFields($data);
}
}
else {
$rebroadAb = 1;
}
}
$who = $formWho->isValid($data);
$style = $formStyle->isValid($data);
$record = $formRecord->isValid($data);
if ($what && $when && $repeats && $who && $style && $record && $rebroadAb && $rebroad) {
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$user = new User($userInfo->id);
if ($user->isAdmin()) {
Show::create($data);
}
//send back a new form for the user.
$formWhat->reset();
$formWhat->populate(array('add_show_id' => '-1'));
$formWho->reset();
$formWhen->reset();
$formWhen->populate(array('add_show_start_date' => date("Y-m-d"),
'add_show_start_time' => '0:00',
'add_show_duration' => '1:00'));
$formRepeats->reset();
$formRepeats->populate(array('add_show_end_date' => date("Y-m-d")));
$formStyle->reset();
$formRecord->reset();
$formAbsoluteRebroadcast->reset();
$formRebroadcast->reset();
$this->view->newForm = $this->view->render('schedule/add-show-form.phtml');
}
else {
$this->view->form = $this->view->render('schedule/add-show-form.phtml');
}
}
public function cancelShowAction()
{
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$user = new User($userInfo->id);
if($user->isAdmin()) {
$showInstanceId = $this->_getParam('id');
$showInstance = new ShowInstance($showInstanceId);
$show = new Show($showInstance->getShowId());
$show->cancelShow($showInstance->getShowStart());
}
}
public function cancelCurrentShowAction()
{
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$user = new User($userInfo->id);
if($user->isAdmin()) {
$showInstanceId = $this->_getParam('id');
$show = new ShowInstance($showInstanceId);
$show->clearShow();
$show->deleteShow();
}
}
}

View file

@ -0,0 +1,90 @@
<?php
class SearchController extends Zend_Controller_Action
{
protected $search_sess = null;
private function addGroup($group_id) {
$form = new Application_Form_AdvancedSearch();
$form->addGroup($group_id, 1);
$group = $form->getSubForm('group_'.$group_id);
return $group->__toString();
}
private function addFieldToGroup($group_id, $row_id) {
$form = new Application_Form_AdvancedSearch();
$form->addGroup($group_id);
$group = $form->getSubForm('group_'.$group_id);
$group->addRow($row_id);
return $group->__toString();
}
public function init()
{
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('newfield', 'json')
->addActionContext('newgroup', 'json')
->addActionContext('index', 'json')
->addActionContext('display', 'json')
->initContext();
$this->search_sess = new Zend_Session_Namespace("search");
}
public function indexAction()
{
$data = $this->_getParam('data');
$form = new Application_Form_AdvancedSearch();
// Form has been submitted
$form->preValidation($data);
//if (!$form->isValid($data)) {
//$this->view->form = $form->__toString();
//return;
//}
// valid form was submitted set as search criteria.
$this->search_sess->md = $data;
}
public function displayAction()
{
}
public function newfieldAction()
{
$group_id = $this->_getParam('group', 1);
$row_id = $this->search_sess->next_row[$group_id];
$this->view->html = $this->addFieldToGroup($group_id, $row_id);
$this->view->row = $row_id;
$this->search_sess->next_row[$group_id] = $row_id + 1;
}
public function newgroupAction()
{
$group_id = $this->search_sess->next_group;
$this->view->html = $this->addGroup($group_id);
$this->search_sess->next_group = $group_id + 1;
$this->search_sess->next_row[$group_id] = 2;
}
}

View file

@ -0,0 +1,101 @@
<?php
class UserController extends Zend_Controller_Action
{
public function init()
{
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('get-hosts', 'json')
->addActionContext('get-user-data-table-info', 'json')
->addActionContext('get-user-data', 'json')
->addActionContext('remove-user', 'json')
->initContext();
}
public function indexAction()
{
}
public function addUserAction()
{
$this->view->headScript()->appendFile('/js/datatables/js/jquery.dataTables.js','text/javascript');
$this->view->headScript()->appendFile('/js/airtime/user/user.js','text/javascript');
$request = $this->getRequest();
$form = new Application_Form_AddUser();
$this->view->successMessage = "";
if ($request->isPost()) {
if ($form->isValid($request->getPost())) {
$formdata = $form->getValues();
if ($form->validateLogin($formdata)){
$user = new User($formdata['user_id']);
$user->setFirstName($formdata['first_name']);
$user->setLastName($formdata['last_name']);
$user->setLogin($formdata['login']);
if ($formdata['password'] != "xxxxxx")
$user->setPassword($formdata['password']);
$user->setType($formdata['type']);
$user->setEmail($formdata['email']);
$user->setSkype($formdata['skype']);
$user->setJabber($formdata['jabber']);
$user->save();
$form->reset();
if (strlen($formdata['user_id']) == 0){
$this->view->successMessage = "<div class='success'>User added successfully!</div>";
} else {
$this->view->successMessage = "<div class='success'>User updated successfully!</div>";
}
}
}
}
$this->view->form = $form;
}
public function getHostsAction()
{
$search = $this->_getParam('term');
$this->view->hosts = User::getHosts($search);
}
public function getUserDataTableInfoAction()
{
$post = $this->getRequest()->getPost();
$users = User::getUsersDataTablesInfo($post);
die(json_encode($users));
}
public function getUserDataAction()
{
$id = $this->_getParam('id');
$this->view->entries = User::GetUserData($id);
}
public function removeUserAction()
{
// action body
$id = $this->_getParam('id');
$user = new User($id);
$this->view->entries = $user->delete();
}
}

View file

@ -0,0 +1,177 @@
<?php
class Zend_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract
{
/**
* @var Zend_Acl
**/
protected $_acl;
/**
* @var string
**/
protected $_roleName;
/**
* @var array
**/
protected $_errorPage;
/**
* Constructor
*
* @param mixed $aclData
* @param $roleName
* @return void
**/
public function __construct(Zend_Acl $aclData, $roleName = 'G')
{
$this->_errorPage = array('module' => 'default',
'controller' => 'error',
'action' => 'denied');
$this->_roleName = $roleName;
if (null !== $aclData) {
$this->setAcl($aclData);
}
}
/**
* Sets the ACL object
*
* @param mixed $aclData
* @return void
**/
public function setAcl(Zend_Acl $aclData)
{
$this->_acl = $aclData;
}
/**
* Returns the ACL object
*
* @return Zend_Acl
**/
public function getAcl()
{
return $this->_acl;
}
/**
* Returns the ACL role used
*
* @return string
* @author
**/
public function getRoleName()
{
return $this->_roleName;
}
public function setRoleName($type)
{
$this->_roleName = $type;
}
/**
* Sets the error page
*
* @param string $action
* @param string $controller
* @param string $module
* @return void
**/
public function setErrorPage($action, $controller = 'error', $module = null)
{
$this->_errorPage = array('module' => $module,
'controller' => $controller,
'action' => $action);
}
/**
* Returns the error page
*
* @return array
**/
public function getErrorPage()
{
return $this->_errorPage;
}
/**
* Predispatch
* Checks if the current user identified by roleName has rights to the requested url (module/controller/action)
* If not, it will call denyAccess to be redirected to errorPage
*
* @return void
**/
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$controller = strtolower($request->getControllerName());
if ($controller == 'api'){
$this->setRoleName("G");
}
else if (!Zend_Auth::getInstance()->hasIdentity()){
if ($controller !== 'login') {
if ($request->isXmlHttpRequest()) {
$url = 'http://'.$request->getHttpHost().'/login';
$json = Zend_Json::encode(array('auth' => false, 'url' => $url));
// Prepare response
$this->getResponse()
->setHttpResponseCode(401)
->setBody($json)
->sendResponse();
//redirectAndExit() cleans up, sends the headers and stops the script
Zend_Controller_Action_HelperBroker::getStaticHelper('redirector')->redirectAndExit();
}
else {
$r = Zend_Controller_Action_HelperBroker::getStaticHelper('redirector');
$r->gotoSimpleAndExit('index', 'login', $request->getModuleName());
}
}
}
else {
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$this->setRoleName($userInfo->type);
Zend_View_Helper_Navigation_HelperAbstract::setDefaultAcl($this->_acl);
Zend_View_Helper_Navigation_HelperAbstract::setDefaultRole($this->_roleName);
$resourceName = '';
if ($request->getModuleName() != 'default') {
$resourceName .= strtolower($request->getModuleName()) . ':';
}
$resourceName .= $controller;
/** Check if the controller/action can be accessed by the current user */
if (!$this->getAcl()->isAllowed($this->_roleName, $resourceName, $request->getActionName())) {
/** Redirect to access denied page */
$this->denyAccess();
}
}
}
/**
* Deny Access Function
* Redirects to errorPage, this can be called from an action using the action helper
*
* @return void
**/
public function denyAccess()
{
$this->_request->setModuleName($this->_errorPage['module']);
$this->_request->setControllerName($this->_errorPage['controller']);
$this->_request->setActionName($this->_errorPage['action']);
}
}

View file

@ -0,0 +1,9 @@
<?php
class RabbitMqPlugin extends Zend_Controller_Plugin_Abstract
{
public function dispatchLoopShutdown()
{
RabbitMq::PushScheduleFinal();
}
}

View file

@ -0,0 +1,73 @@
<?php
class Application_Form_AddShowAbsoluteRebroadcastDates extends Zend_Form_SubForm
{
public function init()
{
$this->setDecorators(array(
array('ViewScript', array('viewScript' => 'form/add-show-rebroadcast-absolute.phtml'))
));
for($i=1; $i<=10; $i++) {
$text = new Zend_Form_Element_Text("add_show_rebroadcast_date_absolute_$i");
$text->setAttrib('class', 'input_text');
$text->addFilter('StringTrim');
$text->addValidator('date', false, array('YYYY-MM-DD'));
$text->setRequired(false);
$text->setDecorators(array('ViewHelper'));
$this->addElement($text);
$text = new Zend_Form_Element_Text("add_show_rebroadcast_time_absolute_$i");
$text->setAttrib('class', 'input_text');
$text->addFilter('StringTrim');
$text->addValidator('date', false, array('HH:mm'));
$text->addValidator('regex', false, array('/^[0-9:]+$/', 'messages' => 'Invalid character entered'));
$text->setRequired(false);
$text->setDecorators(array('ViewHelper'));
$this->addElement($text);
}
}
public function checkReliantFields($formData) {
$valid = true;
for($i=1; $i<=10; $i++) {
$day = $formData['add_show_rebroadcast_date_absolute_'.$i];
if(trim($day) == "") {
continue;
}
$time = $formData['add_show_rebroadcast_time_absolute_'.$i];
if (trim($time) == ""){
$this->getElement('add_show_rebroadcast_time_absolute_'.$i)->setErrors(array("Time must be specified"));
$valid = false;
}
$show_start_time = $formData['add_show_start_date']."".$formData['add_show_start_time'];
$show_end = new DateTime($show_start_time);
$duration = $formData['add_show_duration'];
$duration = explode(":", $duration);
$show_end->add(new DateInterval("PT$duration[0]H"));
$show_end->add(new DateInterval("PT$duration[1]M"));
$show_end->add(new DateInterval("PT1H"));//min time to wait until a rebroadcast
$rebroad_start = $day."".$formData['add_show_rebroadcast_time_absolute_'.$i];
$rebroad_start = new DateTime($rebroad_start);
if($rebroad_start < $show_end) {
$this->getElement('add_show_rebroadcast_time_absolute_'.$i)->setErrors(array("Must wait at least 1 hour to rebroadcast"));
$valid = false;
}
}
return $valid;
}
}

View file

@ -0,0 +1,23 @@
<?php
class Application_Form_AddShowRR extends Zend_Form_SubForm
{
public function init()
{
// Add record element
$this->addElement('checkbox', 'add_show_record', array(
'label' => 'Record?',
'required' => false,
));
// Add record element
$this->addElement('checkbox', 'add_show_rebroadcast', array(
'label' => 'Rebroadcast?',
'required' => false,
));
}
}

View file

@ -0,0 +1,82 @@
<?php
class Application_Form_AddShowRebroadcastDates extends Zend_Form_SubForm
{
public function init()
{
$this->setDecorators(array(
array('ViewScript', array('viewScript' => 'form/add-show-rebroadcast.phtml'))
));
$relativeDates = array();
$relativeDates[""] = "";
for($i=0; $i<=30; $i++) {
$relativeDates["$i days"] = "+$i days";
}
for($i=1; $i<=10; $i++) {
$select = new Zend_Form_Element_Select("add_show_rebroadcast_date_$i");
$select->setAttrib('class', 'input_select');
$select->setMultiOptions($relativeDates);
$select->setRequired(false);
$select->setDecorators(array('ViewHelper'));
$this->addElement($select);
$text = new Zend_Form_Element_Text("add_show_rebroadcast_time_$i");
$text->setAttrib('class', 'input_text');
$text->addFilter('StringTrim');
$text->addValidator('date', false, array('HH:mm'));
$text->addValidator('regex', false, array('/^[0-9:]+$/', 'messages' => 'Invalid character entered'));
$text->setRequired(false);
$text->setDecorators(array('ViewHelper'));
$this->addElement($text);
}
}
public function checkReliantFields($formData) {
$valid = true;
for($i=1; $i<=5; $i++) {
$days = $formData['add_show_rebroadcast_date_'.$i];
if(trim($days) == "") {
continue;
}
$time = $formData['add_show_rebroadcast_time_'.$i];
if (trim($time) == ""){
$this->getElement('add_show_rebroadcast_time_'.$i)->setErrors(array("Time must be specified"));
$valid = false;
}
$days = explode(" ", $days);
$day = $days[0];
$show_start_time = $formData['add_show_start_date']."".$formData['add_show_start_time'];
$show_end = new DateTime($show_start_time);
$duration = $formData['add_show_duration'];
$duration = explode(":", $duration);
$show_end->add(new DateInterval("PT$duration[0]H"));
$show_end->add(new DateInterval("PT$duration[1]M"));
$show_end->add(new DateInterval("PT1H"));//min time to wait until a rebroadcast
$rebroad_start = $formData['add_show_start_date']."".$formData['add_show_rebroadcast_time_'.$i];
$rebroad_start = new DateTime($rebroad_start);
$rebroad_start->add(new DateInterval("P".$day."D"));
if($rebroad_start < $show_end) {
$this->getElement('add_show_rebroadcast_time_'.$i)->setErrors(array("Must wait at least 1 hour to rebroadcast"));
$valid = false;
}
}
return $valid;
}
}

View file

@ -0,0 +1,77 @@
<?php
class Application_Form_AddShowRepeats extends Zend_Form_SubForm
{
public function init()
{
//Add type select
$this->addElement('select', 'add_show_repeat_type', array(
'required' => true,
'label' => 'Repeat Type:',
'class' => ' input_select',
'multiOptions' => array(
"0" => "weekly",
"1" => "bi-weekly",
"2" => "monthly"
),
));
// Add days checkboxes
$this->addElement(
'multiCheckbox',
'add_show_day_check',
array(
'label' => 'Select Days:',
'required' => false,
'multiOptions' => array(
"0" => "Sun",
"1" => "Mon",
"2" => "Tue",
"3" => "Wed",
"4" => "Thu",
"5" => "Fri",
"6" => "Sat",
),
));
// Add end date element
$this->addElement('text', 'add_show_end_date', array(
'label' => 'Date End:',
'class' => 'input_text',
'value' => date("Y-m-d"),
'required' => false,
'filters' => array('StringTrim'),
'validators' => array(
'NotEmpty',
array('date', false, array('YYYY-MM-DD'))
)
));
// Add no end element
$this->addElement('checkbox', 'add_show_no_end', array(
'label' => 'No End?',
'required' => false,
));
}
public function checkReliantFields($formData) {
if (!$formData['add_show_no_end']){
$start_timestamp = $formData['add_show_start_date'];
$end_timestamp = $formData['add_show_end_date'];
$start_epoch = strtotime($start_timestamp);
$end_epoch = strtotime($end_timestamp);
if($end_epoch < $start_epoch) {
$this->getElement('add_show_end_date')->setErrors(array('End date must be after start date'));
return false;
}
}
return true;
}
}

View file

@ -0,0 +1,39 @@
<?php
class Application_Form_AddShowStyle extends Zend_Form_SubForm
{
public function init()
{
// Add show background-color input
$this->addElement('text', 'add_show_background_color', array(
'label' => 'Background Colour:',
'class' => 'input_text',
'filters' => array('StringTrim')
));
$bg = $this->getElement('add_show_background_color');
$bg->setDecorators(array(array('ViewScript', array(
'viewScript' => 'form/add-show-style.phtml',
'class' => 'big'
))));
// Add show color input
$this->addElement('text', 'add_show_color', array(
'label' => 'Text Colour:',
'class' => 'input_text',
'filters' => array('StringTrim')
));
$c = $this->getElement('add_show_color');
$c->setDecorators(array(array('ViewScript', array(
'viewScript' => 'form/add-show-style.phtml',
'class' => 'big'
))));
}
}

View file

@ -0,0 +1,58 @@
<?php
class Application_Form_AddShowWhat extends Zend_Form_SubForm
{
public function init()
{
// Hidden element to indicate whether the show is new or
// whether we are updating an existing show.
$this->addElement('hidden', 'add_show_id', array(
'decorators' => array('ViewHelper')
));
// Add name element
$this->addElement('text', 'add_show_name', array(
'label' => 'Name:',
'class' => 'input_text',
'required' => true,
'filters' => array('StringTrim'),
'validators' => array('NotEmpty')
));
// Add URL element
$this->addElement('text', 'add_show_url', array(
'label' => 'URL:',
'class' => 'input_text',
'required' => false,
'filters' => array('StringTrim'),
'validators' => array('NotEmpty')
));
// Add genre element
$this->addElement('text', 'add_show_genre', array(
'label' => 'Genre:',
'class' => 'input_text',
'required' => false,
'filters' => array('StringTrim')
));
// Add the description element
$this->addElement('textarea', 'add_show_description', array(
'label' => 'Description:',
'required' => false,
'class' => 'input_text_area'
));
$descText = $this->getElement('add_show_description');
$descText->setDecorators(array(array('ViewScript', array(
'viewScript' => 'form/add-show-block.phtml',
'class' => 'block-display'
))));
}
}

View file

@ -0,0 +1,86 @@
<?php
class Application_Form_AddShowWhen extends Zend_Form_SubForm
{
public function init()
{
//$this->setDisableLoadDefaultDecorators(true);
//$this->removeDecorator('DtDdWrapper');
// Add start date element
$this->addElement('text', 'add_show_start_date', array(
'label' => 'Date Start:',
'class' => 'input_text',
'required' => true,
'value' => date("Y-m-d"),
'filters' => array('StringTrim'),
'validators' => array(
'NotEmpty',
array('date', false, array('YYYY-MM-DD'))
)
));
// Add start time element
$this->addElement('text', 'add_show_start_time', array(
'label' => 'Start Time:',
'class' => 'input_text',
'required' => true,
'value' => '0:00',
'filters' => array('StringTrim'),
'validators' => array(
'NotEmpty',
array('date', false, array('HH:mm')),
array('regex', false, array('/^[0-9:]+$/', 'messages' => 'Invalid character entered'))
)
));
// Add duration element
$this->addElement('text', 'add_show_duration', array(
'label' => 'Duration:',
'class' => 'input_text',
'value' => '1:00',
'required' => true,
'filters' => array('StringTrim'),
'validators' => array(
'NotEmpty',
array('regex', false,
array('/^\d+:[0-5][0-9]$/',
'messages' => 'enter a duration: HH:mm'))
)
));
// Add repeats element
$this->addElement('checkbox', 'add_show_repeats', array(
'label' => 'Repeats?',
'required' => false,
));
}
public function checkReliantFields($formData) {
$valid = true;
$now_timestamp = date("Y-m-d H:i:s");
$start_timestamp = $formData['add_show_start_date']."".$formData['add_show_start_time'];
$now_epoch = strtotime($now_timestamp);
$start_epoch = strtotime($start_timestamp);
if($start_epoch < $now_epoch) {
$this->getElement('add_show_start_time')->setErrors(array('Cannot create show in the past'));
$valid = false;
}
if(strtotime("00:00") == strtotime($formData["add_show_duration"])) {
$this->getElement('add_show_duration')->setErrors(array('Cannot have duration 00:00'));
$valid = false;
}
return $valid;
}
}

View file

@ -0,0 +1,32 @@
<?php
class Application_Form_AddShowWho extends Zend_Form_SubForm
{
public function init()
{
// Add hosts autocomplete
$this->addElement('text', 'add_show_hosts_autocomplete', array(
'label' => 'Search Users:',
'class' => 'input_text ui-autocomplete-input',
'required' => false
));
$options = array();
$hosts = User::getHosts();
foreach ($hosts as $host) {
$options[$host['value']] = $host['label'];
}
//Add hosts selection
$hosts = new Zend_Form_Element_MultiCheckbox('add_show_hosts');
$hosts->setLabel('Hosts:')
->setMultiOptions($options);
$this->addElement($hosts);
}
}

View file

@ -0,0 +1,103 @@
<?php
class Application_Form_AddUser extends Zend_Form
{
public function init()
{
/*
$this->addElementPrefixPath('Application_Validate',
'../application/validate',
'validate');
* */
$hidden = new Zend_Form_Element_Hidden('user_id');
$hidden->setDecorators(array('ViewHelper'));
$this->addElement($hidden);
$login = new Zend_Form_Element_Text('login');
$login->setLabel('Username:');
$login->setAttrib('class', 'input_text');
$login->setRequired(true);
$login->addFilter('StringTrim');
//$login->addValidator('UserNameValidate');
$this->addElement($login);
$password = new Zend_Form_Element_Password('password');
$password->setLabel('Password:');
$password->setAttrib('class', 'input_text');
$password->setRequired(true);
$password->addFilter('StringTrim');
$password->addValidator('NotEmpty');
$this->addElement($password);
$firstName = new Zend_Form_Element_Text('first_name');
$firstName->setLabel('Firstname:');
$firstName->setAttrib('class', 'input_text');
$firstName->setRequired(true);
$firstName->addFilter('StringTrim');
$firstName->addValidator('NotEmpty');
$this->addElement($firstName);
$lastName = new Zend_Form_Element_Text('last_name');
$lastName->setLabel('Lastname:');
$lastName->setAttrib('class', 'input_text');
$lastName->setRequired(true);
$lastName->addFilter('StringTrim');
$lastName->addValidator('NotEmpty');
$this->addElement($lastName);
$email = new Zend_Form_Element_Text('email');
$email->setLabel('Email:');
$email->setAttrib('class', 'input_text');
$email->addFilter('StringTrim');
$email->addValidator('EmailAddress');
$this->addElement($email);
$skype = new Zend_Form_Element_Text('skype');
$skype->setLabel('Skype:');
$skype->setAttrib('class', 'input_text');
$skype->addFilter('StringTrim');
$this->addElement($skype);
$jabber = new Zend_Form_Element_Text('jabber');
$jabber->setLabel('Jabber:');
$jabber->setAttrib('class', 'input_text');
$jabber->addFilter('StringTrim');
$jabber->addValidator('EmailAddress');
$this->addElement($jabber);
$select = new Zend_Form_Element_Select('type');
$select->setLabel('User Type:');
$select->setAttrib('class', 'input_select');
$select->setAttrib('style', 'width: 40%');
$select->setMultiOptions(array(
"G" => "Guest",
"H" => "Host",
"A" => "Admin"
));
$select->setRequired(true);
$this->addElement($select);
$submit = new Zend_Form_Element_Submit('submit');
$submit->setAttrib('class', 'ui-button ui-state-default right-floated');
$submit->setIgnore(true);
$submit->setLabel('Submit');
$this->addElement($submit);
}
public function validateLogin($data){
if (strlen($data['user_id']) == 0){
$count = CcSubjsQuery::create()->filterByDbLogin($data['login'])->count();
if ($count != 0){
$this->getElement('login')->setErrors(array("login name is not unique."));
return false;
}
}
return true;
}
}

View file

@ -0,0 +1,65 @@
<?php
class Application_Form_AdvancedSearch extends Zend_Form
{
public function init()
{
// Add the add button
$this->addElement('button', 'search_add_group', array(
'ignore' => true,
'label' => 'Add',
'order' => '-2'
));
$this->getElement('search_add_group')->removeDecorator('DtDdWrapper');
// Add the submit button
$this->addElement('button', 'search_submit', array(
'ignore' => true,
'label' => 'Submit',
'order' => '-1'
));
$this->getElement('search_submit')->removeDecorator('DtDdWrapper');
}
public function addGroup($group_id, $row_id=null) {
$this->addSubForm(new Application_Form_AdvancedSearchGroup(), 'group_'.$group_id, $group_id);
$this->getSubForm('group_'.$group_id)->removeDecorator('DtDdWrapper');
if(!is_null($row_id)) {
$subGroup = $this->getSubForm('group_'.$group_id);
$subGroup->addRow($row_id);
}
}
public function preValidation(array $data) {
function findId($name) {
$t = explode("_", $name);
return $t[1];
}
function findFields($field) {
return strpos($field, 'group') !== false;
}
$groups = array_filter(array_keys($data), 'findFields');
foreach ($groups as $group) {
$group_id = findId($group);
$this->addGroup($group_id);
$subGroup = $this->getSubForm($group);
foreach (array_keys($data[$group]) as $row) {
$row_id = findId($row);
$subGroup->addRow($row_id, $data[$group][$row]);
}
}
}
}

View file

@ -0,0 +1,37 @@
<?php
class Application_Form_AdvancedSearchGroup extends Zend_Form_SubForm
{
public function init()
{
// Add the add button
$this->addElement('button', 'search_add_row', array(
'ignore' => true,
'label' => 'Add',
'order' => '-2'
));
$this->getElement('search_add_row')->removeDecorator('DtDdWrapper');
// Add the add button
$this->addElement('button', 'search_remove_group', array(
'ignore' => true,
'label' => 'Remove',
'order' => '-1'
));
$this->getElement('search_remove_group')->removeDecorator('DtDdWrapper');
}
public function addRow($row_id, $data=null) {
$this->addSubForm(new Application_Form_AdvancedSearchRow(), 'row_'.$row_id, $row_id);
$row = $this->getSubForm('row_'.$row_id);
$row->removeDecorator('DtDdWrapper');
if(!is_null($data)) {
$row->setDefaults($data);
}
}
}

View file

@ -0,0 +1,70 @@
<?php
class Application_Form_AdvancedSearchRow extends Zend_Form_SubForm
{
public function init()
{
$this->addElement(
'select',
'metadata',
array(
'required' => true,
'multiOptions' => array(
"dc:title" => "Title",
"dc:format" => "Format",
"dc:creator" => "Artist/Creator",
"dc:source" => "Album",
"ls:bitrate" => "Bitrate",
"ls:samplerate" => "Samplerate",
"dcterms:extent" => "Length",
"dc:description" => "Comments",
"dc:type" => "Genre",
"ls:channels" => "channels",
"ls:year" => "Year",
"ls:track_num" => "track_number",
"ls:mood" => "mood",
"ls:bpm" => "BPM",
"ls:rating" => "rating",
"ls:encoded_by" => "encoded_by",
"dc:publisher" => "label",
"ls:composer" => "Composer",
"ls:encoder" => "Encoder",
"ls:lyrics" => "lyrics",
"ls:orchestra" => "orchestra",
"ls:conductor" => "conductor",
"ls:lyricist" => "lyricist",
"ls:originallyricist" => "original_lyricist",
"ls:isrcnumber" => "isrc_number",
"dc:language" => "Language",
),
)
);
$this->getElement('metadata')->removeDecorator('Label')->removeDecorator('HtmlTag');
$this->addElement(
'select',
'match',
array(
'required' => true,
'multiOptions' => array(
"0" => "partial",
"1" => "=",
"2" => "<",
"3" => "<=",
"4" => ">",
"5" => ">=",
"6" => "!=",
),
)
);
$this->getElement('match')->removeDecorator('Label')->removeDecorator('HtmlTag');
$this->addElement('text', 'search', array(
'required' => true,
));
$this->getElement('search')->removeDecorator('Label')->removeDecorator('HtmlTag');
}
}

View file

@ -0,0 +1,118 @@
<?php
class Application_Form_EditAudioMD extends Zend_Form
{
public function init()
{
// Set the method for the display form to POST
$this->setMethod('post');
// Add title field
$this->addElement('text', 'track_title', array(
'label' => 'Title:',
'required' => true,
'class' => 'input_text',
'filters' => array('StringTrim'),
'validators' => array(
'NotEmpty',
)
));
// Add artist field
$this->addElement('text', 'artist_name', array(
'label' => 'Artist:',
'required' => true,
'class' => 'input_text',
'filters' => array('StringTrim'),
'validators' => array(
'NotEmpty',
)
));
// Add album field
$this->addElement('text', 'album_title', array(
'label' => 'Album:',
'class' => 'input_text',
'filters' => array('StringTrim')
));
// Add genre field
$this->addElement('text', 'genre', array(
'label' => 'Genre:',
'class' => 'input_text',
'filters' => array('StringTrim')
));
// Add year field
$this->addElement('text', 'year', array(
'label' => 'Year:',
'class' => 'input_text',
'filters' => array('StringTrim'),
'validators' => array(
array('date', false, array('YYYY-MM-DD')),
array('date', false, array('YYYY-MM')),
array('date', false, array('YYYY'))
)
));
// Add label field
$this->addElement('text', 'label', array(
'label' => 'Label:',
'class' => 'input_text',
'filters' => array('StringTrim')
));
// Add composer field
$this->addElement('text', 'composer', array(
'label' => 'Composer:',
'class' => 'input_text',
'filters' => array('StringTrim')
));
// Add mood field
$this->addElement('text', 'mood', array(
'label' => 'Mood:',
'class' => 'input_text',
'filters' => array('StringTrim')
));
// Add language field
$this->addElement('text', 'language', array(
'label' => 'Language:',
'class' => 'input_text',
'filters' => array('StringTrim')
));
// Add the submit button
$this->addElement('submit', 'submit', array(
'ignore' => true,
'class' => 'ui-button ui-state-default',
'label' => 'Submit',
'decorators' => array(
'ViewHelper'
)
));
// Add the submit button
$this->addElement('button', 'cancel', array(
'ignore' => true,
'class' => 'ui-button ui-state-default ui-button-text-only md-cancel',
'label' => 'Cancel',
'onclick' => 'javascript:document.location="/Library"',
'decorators' => array(
'ViewHelper'
)
));
$this->addDisplayGroup(array('submit', 'cancel'), 'submitButtons', array(
'decorators' => array(
'FormElements',
'DtDdWrapper'
)
));
}
}

View file

@ -0,0 +1,65 @@
<?php
class Application_Form_GeneralPreferences extends Zend_Form_SubForm
{
public function init()
{
$this->setDecorators(array(
array('ViewScript', array('viewScript' => 'form/preferences_general.phtml'))
));
//Station name
$this->addElement('text', 'stationName', array(
'class' => 'input_text',
'label' => 'Station Name:',
'required' => true,
'filters' => array('StringTrim'),
'validators' => array('NotEmpty'),
'value' => Application_Model_Preference::GetValue("station_name"),
'decorators' => array(
'ViewHelper'
)
));
$defaultFade = Application_Model_Preference::GetDefaultFade();
if($defaultFade == ""){
$defaultFade = '00:00:00.000000';
}
//Default station fade
$this->addElement('text', 'stationDefaultFade', array(
'class' => 'input_text',
'label' => 'Default Fade:',
'required' => false,
'filters' => array('StringTrim'),
'validators' => array(array('regex', false,
array('/^[0-2][0-3]:[0-5][0-9]:[0-5][0-9](\.\d{1,6})?$/',
'messages' => 'enter a time 00:00:00{.000000}'))),
'value' => $defaultFade,
'decorators' => array(
'ViewHelper'
)
));
$stream_format = new Zend_Form_Element_Radio('streamFormat');
$stream_format->setLabel('Stream Label:');
$stream_format->setMultiOptions(array("Artist - Title",
"Show - Artist - Title",
"Station name - Show name"));
$stream_format->setValue(Application_Model_Preference::GetStreamLabelFormat());
$stream_format->setDecorators(array('ViewHelper'));
$this->addElement($stream_format);
$third_party_api = new Zend_Form_Element_Radio('thirdPartyApi');
$third_party_api->setLabel('Allow Remote Websites To Access "Schedule" Info?<br> (Enable this to make front-end widgets work.)');
$third_party_api->setMultiOptions(array("Disabled",
"Enabled"));
$third_party_api->setValue(Application_Model_Preference::GetAllow3rdPartyApi());
$third_party_api->setDecorators(array('ViewHelper'));
$this->addElement($third_party_api);
}
}

View file

@ -0,0 +1,44 @@
<?php
class Application_Form_Login extends Zend_Form
{
public function init()
{
// Set the method for the display form to POST
$this->setMethod('post');
// Add username element
$this->addElement('text', 'username', array(
'label' => 'Username:',
'class' => 'input_text',
'required' => true,
'filters' => array('StringTrim'),
'validators' => array(
'NotEmpty',
)
));
// Add password element
$this->addElement('password', 'password', array(
'label' => 'Password:',
'class' => 'input_text',
'required' => true,
'filters' => array('StringTrim'),
'validators' => array(
'NotEmpty',
)
));
// Add the submit button
$this->addElement('submit', 'submit', array(
'ignore' => true,
'label' => 'Login',
'class' => 'ui-button ui-widget ui-state-default ui-button-text-only'
));
}
}

View file

@ -0,0 +1,33 @@
<?php
class Application_Form_PlaylistMetadata extends Zend_Form_SubForm
{
public function init()
{
// Add username element
$this->addElement('text', 'title', array(
'label' => 'Title:',
'class' => 'input_text',
'required' => false,
'filters' => array('StringTrim'),
'validators' => array(
'NotEmpty',
)
));
// Add the comment element
$this->addElement('textarea', 'description', array(
'label' => 'Description:',
'class' => 'input_text_area',
'required' => false,
));
// Add the comment element
$this->addElement('button', 'new_playlist_submit', array(
'label' => 'Submit',
'ignore' => true
));
}
}

View file

@ -0,0 +1,30 @@
<?php
class Application_Form_Preferences extends Zend_Form
{
public function init()
{
$this->setAction('/Preference');
$this->setMethod('post');
$this->setDecorators(array(
array('ViewScript', array('viewScript' => 'form/preferences.phtml'))
));
$general_pref = new Application_Form_GeneralPreferences();
$this->addSubForm($general_pref, 'preferences_general');
$soundcloud_pref = new Application_Form_SoundcloudPreferences();
$this->addSubForm($soundcloud_pref, 'preferences_soundcloud');
$this->addElement('submit', 'submit', array(
'class' => 'ui-button ui-state-default right-floated',
'ignore' => true,
'label' => 'Submit',
'decorators' => array(
'ViewHelper'
)
));
}
}

View file

@ -0,0 +1,13 @@
<?php
class Application_Form_ScheduleShow extends Zend_Form
{
public function init()
{
/* Form Elements & Other Definitions Here ... */
}
}

View file

@ -0,0 +1,115 @@
<?php
class Application_Form_SoundcloudPreferences extends Zend_Form_SubForm
{
public function init()
{
$this->setDecorators(array(
array('ViewScript', array('viewScript' => 'form/preferences_soundcloud.phtml'))
));
//enable soundcloud uploads
$this->addElement('checkbox', 'UseSoundCloud', array(
'label' => 'Upload Recorded Shows To SoundCloud',
'required' => false,
'value' => Application_Model_Preference::GetDoSoundCloudUpload(),
'decorators' => array(
'ViewHelper'
)
));
//SoundCloud Username
$this->addElement('text', 'SoundCloudUser', array(
'class' => 'input_text',
'label' => 'SoundCloud Email:',
'required' => false,
'filters' => array('StringTrim'),
'value' => Application_Model_Preference::GetSoundCloudUser(),
'decorators' => array(
'ViewHelper'
)
));
//SoundCloud Password
$this->addElement('password', 'SoundCloudPassword', array(
'class' => 'input_text',
'label' => 'SoundCloud Password:',
'required' => false,
'filters' => array('StringTrim'),
'value' => Application_Model_Preference::GetSoundCloudPassword(),
'decorators' => array(
'ViewHelper'
)
));
// Add the description element
$this->addElement('textarea', 'SoundCloudTags', array(
'label' => 'SoundCloud Tags: (separate tags with spaces)',
'required' => false,
'class' => 'input_text_area',
'value' => Application_Model_Preference::GetSoundCloudTags(),
'decorators' => array(
'ViewHelper'
)
));
//SoundCloud default genre
$this->addElement('text', 'SoundCloudGenre', array(
'class' => 'input_text',
'label' => 'Default Genre:',
'required' => false,
'filters' => array('StringTrim'),
'value' => Application_Model_Preference::GetSoundCloudGenre(),
'decorators' => array(
'ViewHelper'
)
));
$select = new Zend_Form_Element_Select('SoundCloudTrackType');
$select->setLabel('Default Track Type:');
$select->setAttrib('class', 'input_select');
$select->setMultiOptions(array(
"" => "",
"original" => "Original",
"remix" => "Remix",
"live" => "Live",
"recording" => "Recording",
"spoken" => "Spoken",
"podcast" => "Podcast",
"demo" => "Demo",
"in progress" => "Work in progress",
"stem" => "Stem",
"loop" => "Loop",
"sound effect" => "Sound Effect",
"sample" => "One Shot Sample",
"other" => "Other"
));
$select->setRequired(false);
$select->setValue(Application_Model_Preference::GetSoundCloudTrackType());
$select->setDecorators(array('ViewHelper'));
$this->addElement($select);
$select = new Zend_Form_Element_Select('SoundCloudLicense');
$select->setLabel('Default License:');
$select->setAttrib('class', 'input_select');
$select->setMultiOptions(array(
"" => "",
"no-rights-reserved" => "The work is in the public domain",
"all-rights-reserved" => "All rights are reserved",
"cc-by" => "Creative Commons Attribution",
"cc-by-nc" => "Creative Commons Attribution Noncommercial",
"cc-by-nd" => "Creative Commons Attribution No Derivative Works",
"cc-by-sa" => "Creative Commons Attribution Share Alike",
"cc-by-nc-nd" => "Creative Commons Attribution Noncommercial Non Derivate Works",
"cc-by-nc-sa" => "Creative Commons Attribution Noncommercial Share Alike"
));
$select->setRequired(false);
$select->setValue(Application_Model_Preference::GetSoundCloudLicense());
$select->setDecorators(array('ViewHelper'));
$this->addElement($select);
}
}

View file

@ -0,0 +1,10 @@
<?php echo $this->doctype() ?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Livestream</title>
</head>
<body>
<div id="content"><?php echo $this->layout()->content ?></div>
</body>
</html>

View file

@ -0,0 +1,23 @@
<?php echo $this->doctype() ?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<?php echo $this->headTitle() ?>
<?php echo $this->headScript() ?>
<?php echo $this->headLink() ?>
</head>
<body>
<div id="Panel">
<div class="logo"></div>
<?php echo $this->partial('partialviews/header.phtml', array("user" => $this->loggedInAs())) ?>
<?php $partial = array('menu.phtml', 'default');
$this->navigation()->menu()->setPartial($partial); ?>
<?php echo $this->navigation()->menu() ?>
</div>
<div class="wrapper" id="content"><?php echo $this->layout()->content ?></div>
</body>
</html>

View file

@ -0,0 +1,26 @@
<?php echo $this->doctype() ?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<?php echo $this->headTitle() ?>
<?php echo $this->headScript() ?>
<?php echo $this->headLink() ?>
</head>
<body>
<div id="Panel">
<div class="logo"></div>
<?php echo $this->partial('partialviews/header.phtml', array("user" => $this->loggedInAs())) ?>
<?php $partial = array('menu.phtml', 'default');
$this->navigation()->menu()->setPartial($partial); ?>
<?php echo $this->navigation()->menu() ?>
</div>
<div class="wrapper">
<div id="side_playlist" class="ui-widget ui-widget-content block-shadow alpha-block"><?php echo $this->layout()->spl ?></div>
<div id="library_content" class="tabs ui-widget ui-widget-content block-shadow omega-block padded"><?php echo $this->layout()->library ?></div>
</div>
</body>
</html>

View file

@ -0,0 +1,14 @@
<?php echo $this->doctype() ?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<?php echo $this->headTitle() ?>
<?php echo $this->headScript() ?>
<?php echo $this->headLink() ?>
</head>
<body>
<div id="login-page"><?php echo $this->layout()->content ?></div>
</body>
</html>

View file

@ -0,0 +1,20 @@
<?php echo $this->doctype() ?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<?php echo $this->headTitle() ?>
<?php echo $this->headScript() ?>
<?php echo $this->headLink() ?>
</head>
<body>
<div id="nowplayingbar"><?php echo $this->partial('partialviews/header.phtml', array("user" => $this->loggedInAs())) ?></div>
<div id="nav"><?php echo $this->navigation()->menu()->setRenderInvisible(true) ?></div>
<div class="wrapper">
<div id="search"><?php echo $this->layout()->search ?></div>
<div id="library_content"><?php echo $this->layout()->library ?></div>
<div id="side_playlist"><?php echo $this->layout()->spl ?></div>
</div>
</body>
</html>

View file

@ -0,0 +1,168 @@
<?php
require_once('Subjects.php');
define('USE_ALIB_CLASSES', TRUE);
define('ALIBERR_NOTLOGGED', 30);
define('ALIBERR_NOTEXISTS', 31);
/**
* Authentication/authorization class
*
* @package Airtime
* @subpackage Alib
* @copyright 2010 Sourcefabric O.P.S.
* @license http://www.gnu.org/licenses/gpl.txt
*/
class Alib {
/* ======================================================= public methods */
/* ----------------------------------------------- session/authentication */
/* -------------------------------------------------------- authorization */
/**
* Remove permission record
*
* @param int $permid
* local permission id
* @param int $subj
* local user/group id
* @param int $obj
* local object id
* @return boolean|PEAR_Error
*/
public static function RemovePerm($permid=NULL, $subj=NULL, $obj=NULL)
{
global $CC_CONFIG, $CC_DBC;
$ca = array();
if ($permid) {
$ca[] = "permid=$permid";
}
if ($subj) {
$ca[] = "subj=$subj";
}
if ($obj) {
$ca[] = "obj=$obj";
}
$cond = join(" AND ", $ca);
if (!$cond) {
return TRUE;
}
$sql = "DELETE FROM ".$CC_CONFIG['permTable']." WHERE $cond";
return $CC_DBC->query($sql);
} // fn removePerm
/* ---------------------------------------------------------- object tree */
/* --------------------------------------------------------- users/groups */
/* ------------------------------------------------------------- sessions */
/**
* Get login from session id (token)
*
* @param string $sessid
* @return string|PEAR_Error
*/
public static function GetSessLogin($sessid)
{
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT login FROM ".$CC_CONFIG['sessTable']." WHERE sessid='$sessid'";
$r = $CC_DBC->getOne($sql);
if (PEAR::isError($r)) {
return $r;
}
if (is_null($r)){
return PEAR::raiseError("Alib::GetSessLogin:".
" invalid session id ($sessid)",
ALIBERR_NOTEXISTS, PEAR_ERROR_RETURN);
}
return $r;
} // fn GetSessLogin
/**
* Get user id from session id.
*
* @param string $p_sessid
* @return int|PEAR_Error
*/
public static function GetSessUserId($p_sessid)
{
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT userid FROM ".$CC_CONFIG['sessTable']." WHERE sessid='$p_sessid'";
$r = $CC_DBC->getOne($sql);
if (PEAR::isError($r)) {
return $r;
}
if (is_null($r)) {
return PEAR::raiseError("Alib::getSessUserId:".
" invalid session id ($p_sessid)",
ALIBERR_NOTEXISTS, PEAR_ERROR_RETURN);
}
return $r;
} // fn getSessUserId
/* --------------------------------------------------------- info methods */
/**
* Get all permissions on object.
*
* @param int $id
* @return array|null|PEAR_Error
*/
public static function GetObjPerms($id)
{
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT s.login, p.* FROM ".$CC_CONFIG['permTable']." p, ".$CC_CONFIG['subjTable']." s"
." WHERE s.id=p.subj AND p.obj=$id";
return $CC_DBC->getAll($sql);
} // fn GetObjPerms
/**
* Get all permissions of subject.
*
* @param int $sid
* @return array
*/
public static function GetSubjPerms($sid)
{
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT *"
." FROM ".$CC_CONFIG['permTable']
." WHERE p.subj=$sid";
$a1 = $CC_DBC->getAll($sql);
return $a1;
} // fn GetSubjPerms
/* ------------------------ info methods related to application structure */
/* (this part should be added/rewritten to allow defining/modifying/using
* application structure)
* (only very simple structure definition - in $CC_CONFIG - supported now)
*/
/* ====================================================== private methods */
/**
* Create new session id. Return the new session ID.
*
* @return string
*/
private static function _createSessid()
{
global $CC_CONFIG, $CC_DBC;
for ($c = 1; $c > 0; ){
$sessid = md5(uniqid(rand()));
$sql = "SELECT count(*) FROM ".$CC_CONFIG['sessTable']
." WHERE sessid='$sessid'";
$c = $CC_DBC->getOne($sql);
if (PEAR::isError($c)) {
return $c;
}
}
return $sessid;
} // fn _createSessid
} // class Alib

View file

@ -0,0 +1,87 @@
<?php
class DateHelper
{
private $_timestamp;
function __construct()
{
$this->_timestamp = date("U");
}
/**
* Get time of object construction in the format
* YYYY-MM-DD HH:mm:ss
*/
function getTimestamp()
{
return date("Y-m-d H:i:s", $this->_timestamp);
}
/**
* Get time of object construction in the format
* HH:mm:ss
*/
function getTime()
{
return date("H:i:s", $this->_timestamp);
}
/**
* Set the internal timestamp of the object.
*/
function setDate($dateString)
{
$this->_timestamp = strtotime($dateString);
}
/**
*
* Enter description here ...
*/
function getNowDayStartDiff()
{
$dayStartTS = strtotime(date("Y-m-d", $this->_timestamp));
return $this->_timestamp - $dayStartTS;
}
function getNowDayEndDiff()
{
$dayEndTS = strtotime(date("Y-m-d", $this->_timestamp+(86400)));
return $dayEndTS - $this->_timestamp;
}
function getEpochTime()
{
return $this->_timestamp;
}
public static function TimeDiff($time1, $time2)
{
return strtotime($time2) - strtotime($time1);
}
public static function ConvertMSToHHMMSSmm($time)
{
$hours = floor($time / 3600000);
$time -= 3600000*$hours;
$minutes = floor($time / 60000);
$time -= 60000*$minutes;
$seconds = floor($time / 1000);
$time -= 1000*$seconds;
$ms = $time;
if (strlen($hours) == 1)
$hours = "0".$hours;
if (strlen($minutes) == 1)
$minutes = "0".$minutes;
if (strlen($seconds) == 1)
$seconds = "0".$seconds;
return $hours.":".$minutes.":".$seconds.".".$ms;
}
}

View file

@ -0,0 +1,146 @@
<?php
class Application_Model_Nowplaying
{
public static function FindBeginningOfShow($rows){
$numRows = count($rows);
$newCopy = array();
for ($i=0; $i<$numRows; $i++){
$currentRow = $rows[$i];
if ($i == 0 || ($i != 0 && $currentRow['instance_id'] != $rows[$i-1]['instance_id'])){
//$currentRow is first instance of a show.
$group = $currentRow;
$group['group'] = 'x';
$group['item_starts'] = $group['show_starts'];
$group['item_ends'] = $group['show_ends'];
array_push($newCopy, $group);
}
array_push($newCopy, $currentRow);
}
return $newCopy;
}
public static function FindGapAtEndOfShow($rows){
$numRows = count($rows);
$newCopy = array();
for ($i=0; $i<$numRows; $i++){
$currentRow = $rows[$i];
array_push($newCopy, $currentRow);
if ($i+1 == $numRows || ($i+1 !=$numRows && $currentRow['instance_id'] != $rows[$i+1]['instance_id'])){
//$row is the last instance in the show.
if ($currentRow['item_ends'] == ""){
//show is empty and has no scheduled items in it. Therefore
//the gap is the entire length of the show.
$currentRow['item_ends'] = $currentRow['show_starts'];
}
$diff = strtotime($currentRow['show_ends']) - strtotime($currentRow['item_ends']);
if ($diff > 0){
//gap at the end of show. Lets create a "gap" row
$gap = $currentRow;
$gap['gap'] = '';
$gap['item_starts'] = $diff;
array_push($newCopy, $gap);
}
}
}
return $newCopy;
}
public static function FilterRowsByDate($rows, $date, $startCutoff, $endCutoff){
$dateNow = new DateHelper;
$timeNow = $dateNow->getTimestamp();
$data = array();
//iterate over each show, and calculate information for it.
$numItems = count($rows);
for ($i=0; $i<$numItems; $i++){
$item = $rows[$i];
if ((strtotime($item['item_ends']) > $date->getEpochTime() - $startCutoff
&& strtotime($item['item_starts']) < $date->getEpochTime() + $endCutoff) || array_key_exists("group", $item) || array_key_exists("gap", $item)){
if (array_key_exists("group", $item)){
$type = "g";
} else if (array_key_exists("gap", $item)){
$type = "b";
} else if (strtotime($item['item_ends']) < strtotime($timeNow)){
$type = "p";
} else if (strtotime($item['item_starts']) < strtotime($timeNow) && strtotime($timeNow) < strtotime($item['item_ends'])
&& strtotime($item['show_starts']) < strtotime($timeNow) && strtotime($timeNow) < strtotime($item['show_ends'])){
$type = "c";
} else {
$type = "n";
}
$over = "";
if (strtotime($item['item_ends']) > strtotime($item['show_ends']))
$over = "x";
array_push($data, array($type, $item["item_starts"], $item["item_starts"], $item["item_ends"], $item["clip_length"], $item["track_title"], $item["artist_name"], $item["album_title"], $item["playlist_name"], $item["show_name"], $over, $item["instance_id"]));
}
}
return $data;
}
public static function HandleRebroadcastShows($rows){
$newCopy = array();
$numRows = count($rows);
for ($i=0; $i<$numRows; $i++){
$currentRow = $rows[$i];
if ($currentRow["rebroadcast"] == 1 && !array_key_exists("group", $currentRow)){
$newRow = $currentRow;
unset($newRow['group']);
$newRow['item_starts'] = $newRow['show_starts'];
$newRow['item_ends'] = $newRow['show_ends'];
array_push($newCopy, $newRow);
} else {
array_push($newCopy, $currentRow);
}
}
return $newCopy;
}
public static function GetDataGridData($viewType, $dateString){
if ($viewType == "now"){
$date = new DateHelper;
$timeNow = $date->getTimestamp();
$startCutoff = 60;
$endCutoff = 86400; //60*60*24 - seconds in a day
} else {
$date = new DateHelper;
$time = $date->getTime();
$date->setDate($dateString." ".$time);
$timeNow = $date->getTimestamp();
$startCutoff = $date->getNowDayStartDiff();
$endCutoff = $date->getNowDayEndDiff();
}
$rows = Show_DAL::GetShowsInRange($timeNow, $startCutoff, $endCutoff);
$rows = Application_Model_Nowplaying::FindBeginningOfShow($rows);
$rows = Application_Model_Nowplaying::HandleRebroadcastShows($rows);
$rows = Application_Model_Nowplaying::FindGapAtEndOfShow($rows);
//$rows = FindGapsBetweenShows()
$data = Application_Model_Nowplaying::FilterRowsByDate($rows, $date, $startCutoff, $endCutoff);
$date = new DateHelper;
$timeNow = $date->getTimestamp();
return array("currentShow"=>Show_DAL::GetCurrentShow($timeNow), "rows"=>$data);
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,193 @@
<?php
class Application_Model_Preference
{
public static function SetValue($key, $value){
global $CC_CONFIG, $CC_DBC;
//called from a daemon process
if(!Zend_Auth::getInstance()->hasIdentity()) {
$id = NULL;
}
else {
$auth = Zend_Auth::getInstance();
$id = $auth->getIdentity()->id;
}
$key = pg_escape_string($key);
$value = pg_escape_string($value);
//Check if key already exists
$sql = "SELECT COUNT(*) FROM cc_pref"
." WHERE keystr = '$key'";
$result = $CC_DBC->GetOne($sql);
if ($result == 1 && is_null($id)){
$sql = "UPDATE cc_pref"
." SET subjid = NULL, valstr = '$value'"
." WHERE keystr = '$key'";
}
else if ($result == 1 && !is_null($id)){
$sql = "UPDATE cc_pref"
." SET subjid = $id, valstr = '$value'"
." WHERE keystr = '$key'";
}
else if(is_null($id)) {
$sql = "INSERT INTO cc_pref (keystr, valstr)"
." VALUES ('$key', '$value')";
}
else {
$sql = "INSERT INTO cc_pref (subjid, keystr, valstr)"
." VALUES ($id, '$key', '$value')";
}
return $CC_DBC->query($sql);
}
public static function GetValue($key){
global $CC_CONFIG, $CC_DBC;
//Check if key already exists
$sql = "SELECT COUNT(*) FROM cc_pref"
." WHERE keystr = '$key'";
$result = $CC_DBC->GetOne($sql);
if ($result == 0)
return "";
else {
$sql = "SELECT valstr FROM cc_pref"
." WHERE keystr = '$key'";
$result = $CC_DBC->GetOne($sql);
return $result;
}
}
public static function GetHeadTitle(){
/* Caches the title name as a session variable so we dont access
* the database on every page load. */
$defaultNamespace = new Zend_Session_Namespace('title_name');
if (isset($defaultNamespace->title)) {
$title = $defaultNamespace->title;
} else {
$title = Application_Model_Preference::GetValue("station_name");
$defaultNamespace->title = $title;
}
if (strlen($title) > 0)
$title .= " - ";
return $title."Airtime";
}
public static function SetHeadTitle($title, $view){
Application_Model_Preference::SetValue("station_name", $title);
$defaultNamespace = new Zend_Session_Namespace('title_name');
$defaultNamespace->title = $title;
RabbitMq::PushSchedule();
//set session variable to new station name so that html title is updated.
//should probably do this in a view helper to keep this controller as minimal as possible.
$view->headTitle()->exchangeArray(array()); //clear headTitle ArrayObject
$view->headTitle(Application_Model_Preference::GetHeadTitle());
}
public static function SetShowsPopulatedUntil($timestamp) {
Application_Model_Preference::SetValue("shows_populated_until", $timestamp);
}
public static function GetShowsPopulatedUntil() {
return Application_Model_Preference::GetValue("shows_populated_until");
}
public static function SetDefaultFade($fade) {
Application_Model_Preference::SetValue("default_fade", $fade);
}
public static function GetDefaultFade() {
return Application_Model_Preference::GetValue("default_fade");
}
public static function SetStreamLabelFormat($type){
Application_Model_Preference::SetValue("stream_label_format", $type);
RabbitMq::PushSchedule();
}
public static function GetStreamLabelFormat(){
return Application_Model_Preference::getValue("stream_label_format");
}
public static function GetStationName(){
return Application_Model_Preference::getValue("station_name");
}
public static function SetDoSoundCloudUpload($upload) {
Application_Model_Preference::SetValue("soundcloud_upload", $upload);
}
public static function GetDoSoundCloudUpload() {
return Application_Model_Preference::GetValue("soundcloud_upload");
}
public static function SetSoundCloudUser($user) {
Application_Model_Preference::SetValue("soundcloud_user", $user);
}
public static function GetSoundCloudUser() {
return Application_Model_Preference::GetValue("soundcloud_user");
}
public static function SetSoundCloudPassword($password) {
if (strlen($password) > 0)
Application_Model_Preference::SetValue("soundcloud_password", $password);
}
public static function GetSoundCloudPassword() {
return Application_Model_Preference::GetValue("soundcloud_password");
}
public static function SetSoundCloudTags($tags) {
Application_Model_Preference::SetValue("soundcloud_tags", $tags);
}
public static function GetSoundCloudTags() {
return Application_Model_Preference::GetValue("soundcloud_tags");
}
public static function SetSoundCloudGenre($genre) {
Application_Model_Preference::SetValue("soundcloud_genre", $genre);
}
public static function GetSoundCloudGenre() {
return Application_Model_Preference::GetValue("soundcloud_genre");
}
public static function SetSoundCloudTrackType($track_type) {
Application_Model_Preference::SetValue("soundcloud_tracktype", $track_type);
}
public static function GetSoundCloudTrackType() {
return Application_Model_Preference::GetValue("soundcloud_tracktype");
}
public static function SetSoundCloudLicense($license) {
Application_Model_Preference::SetValue("soundcloud_license", $license);
}
public static function GetSoundCloudLicense() {
return Application_Model_Preference::GetValue("soundcloud_license");
}
public static function SetAllow3rdPartyApi($bool) {
Application_Model_Preference::SetValue("third_party_api", $bool);
}
public static function GetAllow3rdPartyApi() {
$val = Application_Model_Preference::GetValue("third_party_api");
if (strlen($val) == 0){
return "0";
} else {
return $val;
}
}
}

View file

@ -0,0 +1,401 @@
<?php
/**
* Preference storage class.
*
* @package Airtime
* @subpackage StorageServer
* @copyright 2010 Sourcefabric O.P.S.
* @license http://www.gnu.org/licenses/gpl.txt
* @see StoredFile
*/
/* ================== Prefs ================== */
class Prefs {
/**
* Constructor
*/
public function __construct()
{
}
/* ======================================================= 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 = Alib::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 = Alib::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 = Alib::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 $group
* group name
* @param string $key
* preference key
* @param boolean $returnErrorIfKeyNotExists
* If set to true and the key doesnt exist, return a PEAR error.
* @return string
* preference value
*/
function loadGroupPref($group, $key, $returnErrorIfKeyNotExists = true)
{
// if sessid is would be used here fix Transport::cronCallMethod !
$subjid = Subjects::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) {
if ($returnErrorIfKeyNotExists) {
return PEAR::raiseError(
"Prefs::loadGroupPref: invalid preference key", GBERR_PREF);
} else {
return '';
}
}
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 = Alib::GetSessUserId($sessid);
if (PEAR::isError($uid)) {
return $uid;
}
if (is_null($uid)) {
return PEAR::raiseError(
"Prefs::saveGroupPref: invalid session id", GBERR_SESS);
}
$gid = Subjects::GetSubjId($group);
if (PEAR::isError($gid)) {
return $gid;
}
if (is_null($gid)) {
return PEAR::raiseError(
"Prefs::saveGroupPref: invalid group name", GBERR_SESS);
}
$memb = Subjects::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 = Alib::GetSessUserId($sessid);
if (PEAR::isError($uid)) {
return $uid;
}
if (is_null($uid)) {
return PEAR::raiseError(
"Prefs::delGroupPref: invalid session id", GBERR_SESS);
}
$gid = Subjects::GetSubjId($group);
if (PEAR::isError($gid)) {
return $gid;
}
if (is_null($gid)) {
return PEAR::raiseError(
"Prefs::delGroupPref: invalid group name", GBERR_SESS);
}
$memb = Subjects::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
*/
public static function Insert($subjid, $keystr, $valstr='')
{
global $CC_CONFIG, $CC_DBC;
$id = $CC_DBC->nextId($CC_CONFIG['prefSequence']);
if (PEAR::isError($id)) {
return $id;
}
$r = $CC_DBC->query("
INSERT INTO ".$CC_CONFIG['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)
{
global $CC_CONFIG, $CC_DBC;
$val = $CC_DBC->getOne("
SELECT valstr FROM ".$CC_CONFIG['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)
{
global $CC_CONFIG, $CC_DBC;
$res = $CC_DBC->getAll("
SELECT keystr FROM ".$CC_CONFIG['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='')
{
global $CC_CONFIG, $CC_DBC;
$r = $CC_DBC->query("
UPDATE ".$CC_CONFIG['prefTable']." SET
valstr='$newvalstr'
WHERE subjid=$subjid AND keystr='$keystr'
");
if (PEAR::isError($r)) {
return $r;
}
if ($CC_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)
{
global $CC_CONFIG, $CC_DBC;
$r = $CC_DBC->query("
DELETE FROM ".$CC_CONFIG['prefTable']."
WHERE subjid=$subjid AND keystr='$keystr'
");
if (PEAR::isError($r)) {
return $r;
}
if ($CC_DBC->affectedRows() < 1) {
return FALSE;
}
return TRUE;
}
} // class Prefs

View file

@ -0,0 +1,44 @@
<?php
require_once 'php-amqplib/amqp.inc';
class RabbitMq
{
static private $doPush = FALSE;
/**
* Sets a flag to push the schedule at the end of the request.
*/
public static function PushSchedule() {
RabbitMq::$doPush = TRUE;
}
/**
* Push the current schedule to RabbitMQ, to be picked up by Pypo.
* Will push the schedule in the range from 24 hours ago to 24 hours
* in the future.
*/
public static function PushScheduleFinal()
{
global $CC_CONFIG;
if (RabbitMq::$doPush) {
$conn = new AMQPConnection($CC_CONFIG["rabbitmq"]["host"],
$CC_CONFIG["rabbitmq"]["port"],
$CC_CONFIG["rabbitmq"]["user"],
$CC_CONFIG["rabbitmq"]["password"]);
$channel = $conn->channel();
$channel->access_request($CC_CONFIG["rabbitmq"]["vhost"], false, false, true, true);
$EXCHANGE = 'airtime-schedule';
$channel->exchange_declare($EXCHANGE, 'direct', false, true);
$data = json_encode(Schedule::GetScheduledPlaylists());
$msg = new AMQPMessage($data, array('content_type' => 'text/plain'));
$channel->basic_publish($msg, $EXCHANGE);
$channel->close();
$conn->close();
}
}
}

View file

@ -0,0 +1,684 @@
<?php
require_once("StoredFile.php");
class ScheduleGroup {
private $groupId;
public function __construct($p_groupId = null) {
$this->groupId = $p_groupId;
}
/**
* Return true if the schedule group exists in the DB.
* @return boolean
*/
public function exists() {
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT COUNT(*) FROM ".$CC_CONFIG['scheduleTable']
." WHERE group_id=".$this->groupId;
$result = $CC_DBC->GetOne($sql);
if (PEAR::isError($result)) {
return $result;
}
return $result != "0";
}
/**
* Add a music clip or playlist to the schedule.
*
* @param int $p_showInstance
* ID of the show.
* @param $p_datetime
* In the format YYYY-MM-DD HH:MM:SS.mmmmmm
* @param $p_audioFileId
* (optional, either this or $p_playlistId must be set) DB ID of the audio file
* @param $p_playlistId
* (optional, either this of $p_audioFileId must be set) DB ID of the playlist
* @param $p_options
* Does nothing at the moment.
*
* @return int|PEAR_Error
* Return PEAR_Error if the item could not be added.
* Error code 555 is a scheduling conflict.
*/
public function add($p_showInstance, $p_datetime, $p_audioFileId = null, $p_playlistId = null, $p_options = null) {
global $CC_CONFIG, $CC_DBC;
if (!is_null($p_audioFileId)) {
// Schedule a single audio track
// Load existing track
$track = StoredFile::Recall($p_audioFileId);
if (is_null($track)) {
return new PEAR_Error("Could not find audio track.");
}
// Check if there are any conflicts with existing entries
$metadata = $track->getMetadata();
$length = trim($metadata["length"]);
if (empty($length)) {
return new PEAR_Error("Length is empty.");
}
// Insert into the table
$this->groupId = $CC_DBC->GetOne("SELECT nextval('schedule_group_id_seq')");
$sql = "INSERT INTO ".$CC_CONFIG["scheduleTable"]
." (instance_id, starts, ends, clip_length, group_id, file_id, cue_out)"
." VALUES ($p_showInstance, TIMESTAMP '$p_datetime', "
." (TIMESTAMP '$p_datetime' + INTERVAL '$length'),"
." '$length',"
." {$this->groupId}, $p_audioFileId, '$length')";
$result = $CC_DBC->query($sql);
if (PEAR::isError($result)) {
//var_dump($sql);
return $result;
}
}
elseif (!is_null($p_playlistId)){
// Schedule a whole playlist
// Load existing playlist
$playlist = Playlist::Recall($p_playlistId);
if (is_null($playlist)) {
return new PEAR_Error("Could not find playlist.");
}
// Check if there are any conflicts with existing entries
$length = trim($playlist->getLength());
//var_dump($length);
if (empty($length)) {
return new PEAR_Error("Length is empty.");
}
// Insert all items into the schedule
$this->groupId = $CC_DBC->GetOne("SELECT nextval('schedule_group_id_seq')");
$itemStartTime = $p_datetime;
$plItems = $playlist->getContents();
//var_dump($plItems);
foreach ($plItems as $row) {
$trackLength = $row["cliplength"];
//var_dump($trackLength);
$sql = "INSERT INTO ".$CC_CONFIG["scheduleTable"]
." (instance_id, playlist_id, starts, ends, group_id, file_id,"
." clip_length, cue_in, cue_out, fade_in, fade_out)"
." VALUES ($p_showInstance, $p_playlistId, TIMESTAMP '$itemStartTime', "
." (TIMESTAMP '$itemStartTime' + INTERVAL '$trackLength'),"
." '{$this->groupId}', '{$row['file_id']}', '$trackLength', '{$row['cuein']}',"
." '{$row['cueout']}', '{$row['fadein']}','{$row['fadeout']}')";
$result = $CC_DBC->query($sql);
if (PEAR::isError($result)) {
//var_dump($sql);
return $result;
}
$itemStartTime = $CC_DBC->getOne("SELECT TIMESTAMP '$itemStartTime' + INTERVAL '$trackLength'");
}
}
RabbitMq::PushSchedule();
return $this->groupId;
}
public function addFileAfter($show_instance, $p_groupId, $p_audioFileId) {
global $CC_CONFIG, $CC_DBC;
// Get the end time for the given entry
$sql = "SELECT MAX(ends) FROM ".$CC_CONFIG["scheduleTable"]
." WHERE group_id=$p_groupId";
$startTime = $CC_DBC->GetOne($sql);
return $this->add($show_instance, $startTime, $p_audioFileId);
}
public function addPlaylistAfter($show_instance, $p_groupId, $p_playlistId) {
global $CC_CONFIG, $CC_DBC;
// Get the end time for the given entry
$sql = "SELECT MAX(ends) FROM ".$CC_CONFIG["scheduleTable"]
." WHERE group_id=$p_groupId";
$startTime = $CC_DBC->GetOne($sql);
return $this->add($show_instance, $startTime, null, $p_playlistId);
}
/**
* Remove the group from the schedule.
* Note: does not check if it is in the past, you can remove anything.
*
* @return boolean
* TRUE on success, false if there is no group ID defined.
*/
public function remove() {
global $CC_CONFIG, $CC_DBC;
if (is_null($this->groupId) || !is_numeric($this->groupId)) {
return false;
}
$sql = "DELETE FROM ".$CC_CONFIG["scheduleTable"]
." WHERE group_id = ".$this->groupId;
//echo $sql;
$retVal = $CC_DBC->query($sql);
RabbitMq::PushSchedule();
return $retVal;
}
/**
* Return the number of items in this group.
* @return string
*/
public function count() {
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT COUNT(*) FROM {$CC_CONFIG['scheduleTable']}"
." WHERE group_id={$this->groupId}";
return $CC_DBC->GetOne($sql);
}
/*
* Return the list of items in this group as a 2D array.
* @return array
*/
public function getItems() {
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT "
." st.id,"
." st.file_id,"
." st.cue_in,"
." st.cue_out,"
." st.clip_length,"
." st.fade_in,"
." st.fade_out"
." FROM $CC_CONFIG[scheduleTable] as st"
." LEFT JOIN $CC_CONFIG[showInstances] as si"
." ON st.instance_id = si.id"
." WHERE st.group_id=$this->groupId"
." AND st.starts < si.ends";
return $CC_DBC->GetAll($sql);
}
public function notifyGroupStartPlay() {
global $CC_CONFIG, $CC_DBC;
$sql = "UPDATE ".$CC_CONFIG['scheduleTable']
." SET schedule_group_played=TRUE"
." WHERE group_id=".$this->groupId;
$retVal = $CC_DBC->query($sql);
return $retVal;
}
public function notifyMediaItemStartPlay($p_fileId) {
global $CC_CONFIG, $CC_DBC;
$sql = "UPDATE ".$CC_CONFIG['scheduleTable']
." SET media_item_played=TRUE"
." WHERE group_id=".$this->groupId
." AND file_id=".pg_escape_string($p_fileId);
$retVal = $CC_DBC->query($sql);
return $retVal;
}
}
class Schedule {
function __construct() {
}
/**
* Return true if there is nothing in the schedule for the given start time
* up to the length of time after that.
*
* @param string $p_datetime
* In the format YYYY-MM-DD HH:MM:SS.mmmmmm
* @param string $p_length
* In the format HH:MM:SS.mmmmmm
* @return boolean|PEAR_Error
*/
public static function isScheduleEmptyInRange($p_datetime, $p_length) {
global $CC_CONFIG, $CC_DBC;
if (empty($p_length)) {
return new PEAR_Error("Schedule::isSchedulerEmptyInRange: param p_length is empty.");
}
$sql = "SELECT COUNT(*) FROM ".$CC_CONFIG["scheduleTable"]
." WHERE (starts >= '$p_datetime') "
." AND (ends <= (TIMESTAMP '$p_datetime' + INTERVAL '$p_length'))";
//$_SESSION["debug"] = $sql;
//echo $sql;
$count = $CC_DBC->GetOne($sql);
//var_dump($count);
return ($count == '0');
}
/**
* Return TRUE if file is going to be played in the future.
*
* @param string $p_fileId
*/
public function IsFileScheduledInTheFuture($p_fileId)
{
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT COUNT(*) FROM ".$CC_CONFIG["scheduleTable"]
." WHERE file_id = {$p_fileId} AND starts > NOW()";
$count = $CC_DBC->GetOne($sql);
if (is_numeric($count) && ($count != '0')) {
return TRUE;
} else {
return FALSE;
}
}
/**
* Returns array indexed by:
* "playlistId"/"playlist_id" (aliases to the same thing)
* "start"/"starts" (aliases to the same thing) as YYYY-MM-DD HH:MM:SS.nnnnnn
* "end"/"ends" (aliases to the same thing) as YYYY-MM-DD HH:MM:SS.nnnnnn
* "group_id"/"id" (aliases to the same thing)
* "clip_length" (for audio clips this is the length of the audio clip,
* for playlists this is the length of the entire playlist)
* "name" (playlist only)
* "creator" (playlist only)
* "file_id" (audioclip only)
* "count" (number of items in the playlist, always 1 for audioclips.
* Note that playlists with one item will also have count = 1.
*
* @param string $p_fromDateTime
* In the format YYYY-MM-DD HH:MM:SS.nnnnnn
* @param string $p_toDateTime
* In the format YYYY-MM-DD HH:MM:SS.nnnnnn
* @param boolean $p_playlistsOnly
* Retrieve playlists as a single item.
* @return array
* Returns empty array if nothing found
*/
public static function GetItems($p_currentDateTime, $p_toDateTime, $p_playlistsOnly = true)
{
global $CC_CONFIG, $CC_DBC;
$rows = array();
if (!$p_playlistsOnly) {
$sql = "SELECT * FROM ".$CC_CONFIG["scheduleTable"]
." WHERE (starts >= TIMESTAMP '$p_currentDateTime') "
." AND (ends <= TIMESTAMP '$p_toDateTime')";
$rows = $CC_DBC->GetAll($sql);
foreach ($rows as &$row) {
$row["count"] = "1";
$row["playlistId"] = $row["playlist_id"];
$row["start"] = $row["starts"];
$row["end"] = $row["ends"];
$row["id"] = $row["group_id"];
}
} else {
$sql = "SELECT MIN(st.name) AS name,"
." MIN(pt.creator) AS creator,"
." st.group_id, "
." SUM(st.clip_length) AS clip_length,"
." MIN(st.file_id) AS file_id,"
." COUNT(*) as count,"
." MIN(st.playlist_id) AS playlist_id,"
." MIN(st.starts) AS starts,"
." MAX(st.ends) AS ends,"
." MIN(sh.name) AS show_name,"
." MIN(si.starts) AS show_start,"
." MAX(si.ends) AS show_end"
." FROM $CC_CONFIG[scheduleTable] as st"
." LEFT JOIN $CC_CONFIG[playListTable] as pt"
." ON st.playlist_id = pt.id"
." LEFT JOIN $CC_CONFIG[showInstances] as si"
." ON st.instance_id = si.id"
." LEFT JOIN $CC_CONFIG[showTable] as sh"
." ON si.show_id = sh.id"
." WHERE (st.ends >= TIMESTAMP '$p_currentDateTime')"
." AND (st.ends <= TIMESTAMP '$p_toDateTime')"
//next line makes sure that we aren't returning items that
//are past the show's scheduled timeslot.
." AND (st.starts < si.ends)"
." GROUP BY st.group_id"
." ORDER BY starts";
$rows = $CC_DBC->GetAll($sql);
if (!PEAR::isError($rows)) {
foreach ($rows as &$row) {
$row["playlistId"] = $row["playlist_id"];
$row["start"] = $row["starts"];
$row["end"] = $row["ends"];
$row["id"] = $row["group_id"];
}
}
}
return $rows;
}
/**
* Returns data related to the scheduled items.
*
* @param int $prev
* @param int $next
* @return date
*/
public static function GetPlayOrderRange($prev = 1, $next = 1)
{
if (!is_int($prev) || !is_int($next)){
//must enter integers to specify ranges
return array();
}
global $CC_CONFIG;
$date = new DateHelper;
$timeNow = $date->getTimestamp();
return array("env"=>APPLICATION_ENV,
"schedulerTime"=>gmdate("Y-m-d H:i:s"),
"previous"=>Schedule::GetScheduledItemData($timeNow, -1, $prev, "24 hours"),
"current"=>Schedule::GetScheduledItemData($timeNow, 0),
"next"=>Schedule::GetScheduledItemData($timeNow, 1, $next, "48 hours"),
"currentShow"=>Show_DAL::GetCurrentShow($timeNow),
"nextShow"=>Show_DAL::GetNextShows($timeNow, 1),
"timezone"=> date("T"),
"timezoneOffset"=> date("Z"),
"apiKey"=>$CC_CONFIG['apiKey'][0]);
}
/**
* Builds an SQL Query for accessing scheduled item information from
* the database.
*
* @param int $timeNow
* @param int $timePeriod
* @param int $count
* @param String $interval
* @return date
*
* $timeNow is the the currentTime in the format "Y-m-d H:i:s".
* For example: 2011-02-02 22:00:54
*
* $timePeriod can be either negative, zero or positive. This is used
* to indicate whether we want items from the past, present or future.
*
* $count indicates how many results we want to limit ourselves to.
*
* $interval is used to indicate how far into the past or future we
* want to search the database. For example "5 days", "18 hours", "60 minutes",
* "30 seconds" etc.
*/
public static function GetScheduledItemData($timeStamp, $timePeriod=0, $count = 0, $interval="0 hours")
{
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT DISTINCT"
." pt.name,"
." ft.track_title,"
." ft.artist_name,"
." ft.album_title,"
." st.starts,"
." st.ends,"
." st.clip_length,"
." st.media_item_played,"
." st.group_id,"
." show.name as show_name,"
." st.instance_id"
." FROM $CC_CONFIG[scheduleTable] st"
." LEFT JOIN $CC_CONFIG[filesTable] ft"
." ON st.file_id = ft.id"
." LEFT JOIN $CC_CONFIG[playListTable] pt"
." ON st.playlist_id = pt.id"
." LEFT JOIN $CC_CONFIG[showInstances] si"
." ON st.instance_id = si.id"
." LEFT JOIN $CC_CONFIG[showTable] show"
." ON si.show_id = show.id"
." WHERE st.starts < si.ends";
/*
$sql = "SELECT DISTINCT pt.name, ft.track_title, ft.artist_name, ft.album_title, st.starts, st.ends, st.clip_length, st.media_item_played, st.group_id, show.name as show_name, st.instance_id"
." FROM $CC_CONFIG[scheduleTable] st, $CC_CONFIG[filesTable] ft, $CC_CONFIG[playListTable] pt, $CC_CONFIG[showInstances] si, $CC_CONFIG[showTable] show"
." WHERE st.playlist_id = pt.id"
." AND st.file_id = ft.id"
." AND st.instance_id = si.id"
." AND si.show_id = show.id"
." AND st.starts < si.ends";
*/
if ($timePeriod < 0){
$sql .= " AND st.ends < TIMESTAMP '$timeStamp'"
." AND st.ends > (TIMESTAMP '$timeStamp' - INTERVAL '$interval')"
." ORDER BY st.starts DESC"
." LIMIT $count";
} else if ($timePeriod == 0){
$sql .= " AND st.starts <= TIMESTAMP '$timeStamp'"
." AND st.ends >= TIMESTAMP '$timeStamp'";
} else if ($timePeriod > 0){
$sql .= " AND st.starts > TIMESTAMP '$timeStamp'"
." AND st.starts < (TIMESTAMP '$timeStamp' + INTERVAL '$interval')"
." ORDER BY st.starts"
." LIMIT $count";
}
$rows = $CC_DBC->GetAll($sql);
return $rows;
}
public static function GetShowInstanceItems($instance_id)
{
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT DISTINCT pt.name, ft.track_title, ft.artist_name, ft.album_title, st.starts, st.ends, st.clip_length, st.media_item_played, st.group_id, show.name as show_name, st.instance_id"
." FROM $CC_CONFIG[scheduleTable] st, $CC_CONFIG[filesTable] ft, $CC_CONFIG[playListTable] pt, $CC_CONFIG[showInstances] si, $CC_CONFIG[showTable] show"
." WHERE st.playlist_id = pt.id"
." AND st.file_id = ft.id"
." AND st.instance_id = si.id"
." AND si.show_id = show.id"
." AND instance_id = $instance_id"
." ORDER BY st.starts";
$rows = $CC_DBC->GetAll($sql);
return $rows;
}
public static function UpdateMediaPlayedStatus($p_id)
{
global $CC_CONFIG, $CC_DBC;
$sql = "UPDATE ".$CC_CONFIG['scheduleTable']
." SET media_item_played=TRUE"
." WHERE id=$p_id";
$retVal = $CC_DBC->query($sql);
return $retVal;
}
/**
* Convert a time string in the format "YYYY-MM-DD HH:mm:SS"
* to "YYYY-MM-DD-HH-mm-SS".
*
* @param string $p_time
* @return string
*/
private static function AirtimeTimeToPypoTime($p_time)
{
$p_time = substr($p_time, 0, 19);
$p_time = str_replace(" ", "-", $p_time);
$p_time = str_replace(":", "-", $p_time);
return $p_time;
}
/**
* Convert a time string in the format "YYYY-MM-DD-HH-mm-SS" to
* "YYYY-MM-DD HH:mm:SS".
*
* @param string $p_time
* @return string
*/
private static function PypoTimeToAirtimeTime($p_time)
{
$t = explode("-", $p_time);
return $t[0]."-".$t[1]."-".$t[2]." ".$t[3].":".$t[4].":00";
}
/**
* Return true if the input string is in the format YYYY-MM-DD-HH-mm
*
* @param string $p_time
* @return boolean
*/
public static function ValidPypoTimeFormat($p_time)
{
$t = explode("-", $p_time);
if (count($t) != 5) {
return false;
}
foreach ($t as $part) {
if (!is_numeric($part)) {
return false;
}
}
return true;
}
/**
* Converts a time value as a string (with format HH:MM:SS.mmmmmm) to
* millisecs.
*
* @param string $p_time
* @return int
*/
public static function WallTimeToMillisecs($p_time)
{
$t = explode(":", $p_time);
$millisecs = 0;
if (strpos($t[2], ".")) {
$secParts = explode(".", $t[2]);
$millisecs = $secParts[1];
$millisecs = substr($millisecs, 0, 3);
$millisecs = intval($millisecs);
$seconds = intval($secParts[0]);
} else {
$seconds = intval($t[2]);
}
$ret = $millisecs + ($seconds * 1000) + ($t[1] * 60 * 1000) + ($t[0] * 60 * 60 * 1000);
return $ret;
}
/**
* Compute the difference between two times in the format "HH:MM:SS.mmmmmm".
* Note: currently only supports calculating millisec differences.
*
* @param string $p_time1
* @param string $p_time2
* @return double
*/
private static function TimeDiff($p_time1, $p_time2)
{
$parts1 = explode(".", $p_time1);
$parts2 = explode(".", $p_time2);
$diff = 0;
if ( (count($parts1) > 1) && (count($parts2) > 1) ) {
$millisec1 = substr($parts1[1], 0, 3);
$millisec1 = str_pad($millisec1, 3, "0");
$millisec1 = intval($millisec1);
$millisec2 = substr($parts2[1], 0, 3);
$millisec2 = str_pad($millisec2, 3, "0");
$millisec2 = intval($millisec2);
$diff = abs($millisec1 - $millisec2)/1000;
}
return $diff;
}
/**
* Export the schedule in json formatted for pypo (the liquidsoap scheduler)
*
* @param string $p_fromDateTime
* In the format "YYYY-MM-DD-HH-mm-SS"
* @param string $p_toDateTime
* In the format "YYYY-MM-DD-HH-mm-SS"
*/
public static function GetScheduledPlaylists($p_fromDateTime = null, $p_toDateTime = null)
{
global $CC_CONFIG, $CC_DBC;
if (is_null($p_fromDateTime)) {
$t1 = new DateTime();
$range_start = $t1->format("Y-m-d H:i:s");
} else {
$range_start = Schedule::PypoTimeToAirtimeTime($p_fromDateTime);
}
if (is_null($p_fromDateTime)) {
$t2 = new DateTime();
$t2->add(new DateInterval("PT24H"));
$range_end = $t2->format("Y-m-d H:i:s");
} else {
$range_end = Schedule::PypoTimeToAirtimeTime($p_toDateTime);
}
// Scheduler wants everything in a playlist
$data = Schedule::GetItems($range_start, $range_end, true);
$playlists = array();
if (is_array($data)){
foreach ($data as $dx){
$start = $dx['start'];
//chop off subseconds
$start = substr($start, 0, 19);
//Start time is the array key, needs to be in the format "YYYY-MM-DD-HH-mm-ss"
$pkey = Schedule::AirtimeTimeToPypoTime($start);
$timestamp = strtotime($start);
$playlists[$pkey]['source'] = "PLAYLIST";
$playlists[$pkey]['x_ident'] = $dx['group_id'];
$playlists[$pkey]['subtype'] = '1'; // Just needs to be between 1 and 4 inclusive
$playlists[$pkey]['timestamp'] = $timestamp;
$playlists[$pkey]['duration'] = $dx['clip_length'];
$playlists[$pkey]['played'] = '0';
$playlists[$pkey]['schedule_id'] = $dx['group_id'];
$playlists[$pkey]['show_name'] = $dx['show_name'];
$playlists[$pkey]['show_start'] = Schedule::AirtimeTimeToPypoTime($dx['show_start']);
$playlists[$pkey]['show_end'] = Schedule::AirtimeTimeToPypoTime($dx['show_end']);
$playlists[$pkey]['user_id'] = 0;
$playlists[$pkey]['id'] = $dx['group_id'];
$playlists[$pkey]['start'] = Schedule::AirtimeTimeToPypoTime($dx["start"]);
$playlists[$pkey]['end'] = Schedule::AirtimeTimeToPypoTime($dx["end"]);
}
}
foreach ($playlists as &$playlist)
{
$scheduleGroup = new ScheduleGroup($playlist["schedule_id"]);
$items = $scheduleGroup->getItems();
$medias = array();
$playlist['subtype'] = '1';
foreach ($items as $item)
{
$storedFile = StoredFile::Recall($item["file_id"]);
$uri = $storedFile->getFileUrl();
// For pypo, a cueout of zero means no cueout
$cueOut = "0";
if (Schedule::TimeDiff($item["cue_out"], $item["clip_length"]) > 0.001) {
$cueOut = Schedule::WallTimeToMillisecs($item["cue_out"]);
}
$medias[] = array(
'row_id' => $item["id"],
'id' => $storedFile->getGunid(),
'uri' => $uri,
'fade_in' => Schedule::WallTimeToMillisecs($item["fade_in"]),
'fade_out' => Schedule::WallTimeToMillisecs($item["fade_out"]),
'fade_cross' => 0,
'cue_in' => Schedule::WallTimeToMillisecs($item["cue_in"]),
'cue_out' => $cueOut,
'export_source' => 'scheduler'
);
}
$playlist['medias'] = $medias;
}
$result = array();
$result['status'] = array('range' => array('start' => $range_start, 'end' => $range_end),
'version' => AIRTIME_REST_VERSION);
$result['playlists'] = $playlists;
$result['check'] = 1;
$result['stream_metadata'] = array();
$result['stream_metadata']['format'] = Application_Model_Preference::GetStreamLabelFormat();
$result['stream_metadata']['station_name'] = Application_Model_Preference::GetStationName();
$result['server_timezone'] = date('O');
return $result;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,312 @@
<?
define('INDCH', ' ');
require_once("XmlParser.php");
/**
* SmilPlaylist class
*
* @package Airtime
* @subpackage StorageServer
* @copyright 2010 Sourcefabric O.P.S.
* @license http://www.gnu.org/licenses/gpl.txt
*/
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)
*/
private static 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/airtime)
* @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 $subjid
* local subject (user) id (id of user doing the import)
* @return Playlist
*/
public static function &import(&$gb, $aPath, $rPath, &$gunids, $plid, $subjid=NULL)
{
$parr = compact('subjid', 'aPath', 'plid', 'rPath');
$path = realpath("$aPath/$rPath");
if (FALSE === $path) {
return PEAR::raiseError(
"SmilPlaylist::import: file doesn't exist ($aPath/$rPath)"
);
}
$lspl = SmilPlaylist::convert2lspl($gb, $path, $gunids, $parr);
if (PEAR::isError($lspl)) {
return $lspl;
}
require_once("Playlist.php");
$pl =& Playlist::create($gb, $plid, "imported_SMIL");
if (PEAR::isError($pl)) {
return $pl;
}
$r = $pl->lock($gb, $subjid);
if (PEAR::isError($r)) {
return $r;
}
$r = $pl->setMetadata($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 subjid, aPath, plid, rPath
* @return string
* XML of playlist in Airtime playlist format
*/
public static function convert2lspl(&$gb, $data, &$gunids, $parr)
{
extract($parr);
$tree = SmilPlaylist::parse($data);
if (PEAR::isError($tree)) {
return $tree;
}
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
/**
* @package Airtime
* @subpackage StorageServer
* @copyright 2010 Sourcefabric O.P.S.
* @license http://www.gnu.org/licenses/gpl.txt
*/
class SmilPlaylistBodyElement {
public static 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 = SmilPlaylistParElement::convert2lspl(
$gb, $tree->children[0], &$gunids, $parr, $ind2);
if (PEAR::isError($res)) {
return $res;
}
$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
/**
* @package Airtime
* @subpackage StorageServer
* @copyright 2010 Sourcefabric O.P.S.
* @license http://www.gnu.org/licenses/gpl.txt
*/
class SmilPlaylistParElement {
public static 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;
}
}
/**
* @package Airtime
* @subpackage StorageServer
* @copyright 2010 Sourcefabric O.P.S.
* @license http://www.gnu.org/licenses/gpl.txt
*/
class SmilPlaylistAudioElement {
public static 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::secondsToPlaylistTime($fadeIn);
$fadeOut = Playlist::secondsToPlaylistTime($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 = $gb->bsImportPlaylistRaw($gunid,
$aPath, $uri, $ext, $gunids, $subjid);
if (PEAR::isError($acId)) {
return $r;
}
//break;
default:
$ac = StoredFile::RecallByGunid($gunid);
if (is_null($ac) || PEAR::isError($ac)) {
return $ac;
}
$r = $ac->md->getMetadataElement('dcterms:extent');
if (PEAR::isError($r)) {
return $r;
}
$playlength = $r[0]['value'];
}
}
$title = basename($tree->attrs['src']->val);
$offset = Playlist::secondsToPlaylistTime($tree->attrs['begin']->val);
$clipStart = Playlist::secondsToPlaylistTime($tree->attrs['clipStart']->val);
$clipEnd = Playlist::secondsToPlaylistTime($tree->attrs['clipEnd']->val);
$clipLength = Playlist::secondsToPlaylistTime($tree->attrs['clipLength']->val);
$res = "$ind<playlistElement id=\"$plElGunid\" relativeOffset=\"$offset\" clipStart=\"$clipStart\" clipEnd=\"$clipEnd\" clipLength=\"$clipLength\">\n".
"$ind2<$type id=\"$acGunid\" playlength=\"$playlength\" title=\"$title\"/>\n".
$fInfo.
"$ind</playlistElement>\n";
return $res;
}
} // class SmilPlaylistAudioElement
/**
* @package Airtime
* @subpackage StorageServer
* @copyright 2010 Sourcefabric O.P.S.
* @license http://www.gnu.org/licenses/gpl.txt
*/
class SmilPlaylistAnimateElement {
public static 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,94 @@
<?php
require_once 'soundcloud-api/Services/Soundcloud.php';
class ATSoundcloud {
private $_soundcloud;
public function __construct()
{
global $CC_CONFIG;
$this->_soundcloud = new Services_Soundcloud($CC_CONFIG['soundcloud-client-id'], $CC_CONFIG['soundcloud-client-secret']);
}
private function getToken()
{
$username = Application_Model_Preference::GetSoundCloudUser();
$password = Application_Model_Preference::GetSoundCloudPassword();
if($username === "" || $password === "")
{
return false;
}
$token = $this->_soundcloud->accessTokenResourceOwner($username, $password);
return $token;
}
public function uploadTrack($filepath, $filename, $description, $tags=array(), $release=null, $genre=null)
{
if($this->getToken())
{
if(count($tags)) {
$tags = join(" ", $tags);
$tags = $tags." ".Application_Model_Preference::GetSoundCloudTags();
}
else {
$tags = Application_Model_Preference::GetSoundCloudTags();
}
$track_data = array(
'track[sharing]' => 'private',
'track[title]' => $filename,
'track[asset_data]' => '@' . $filepath,
'track[tag_list]' => $tags,
'track[description]' => $description,
'track[downloadable]' => true,
);
if(isset($release)) {
$release = str_replace(" ", "-", $release);
$release = str_replace(":", "-", $release);
//YYYY-MM-DD-HH-mm-SS
$release = explode("-", $release);
$track_data['track[release_year]'] = $release[0];
$track_data['track[release_month]'] = $release[1];
$track_data['track[release_day]'] = $release[2];
}
if (isset($genre) && $genre != "") {
$track_data['track[genre]'] = $genre;
}
else {
$default_genre = Application_Model_Preference::GetSoundCloudTrackType();
if ($genre != "") {
$track_data['track[genre]'] = $default_genre;
}
}
$track_type = Application_Model_Preference::GetSoundCloudTrackType();
if ($track_type != "") {
$track_data['track[track_type]'] = $track_type;
}
$license = Application_Model_Preference::GetSoundCloudLicense();
if ($license != "") {
$track_data['track[license]'] = $license;
}
$response = json_decode(
$this->_soundcloud->post('tracks', $track_data),
true
);
return $response["id"];
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,123 @@
<?php
define('ALIBERR_NOTGR', 20);
define('ALIBERR_BADSMEMB', 21);
/**
* Subj class
*
* users + groups
* with "linearized recursive membership" ;)
* (allow adding users to groups or groups to groups)
*
* @package Airtime
* @subpackage Alib
* @copyright 2010 Sourcefabric O.P.S.
* @license http://www.gnu.org/licenses/gpl.txt
*/
class Subjects {
/* ======================================================= public methods */
/**
* Check login and password
*
* @param string $login
* @param string $pass
* optional
* @return boolean|int|PEAR_Error
*/
public static function Authenticate($login, $pass='')
{
global $CC_CONFIG, $CC_DBC;
$cpass = md5($pass);
$sql = "SELECT id FROM ".$CC_CONFIG['subjTable']
." WHERE login='$login' AND pass='$cpass' AND type='U'";
$id = $CC_DBC->getOne($sql);
if (PEAR::isError($id)) {
return $id;
}
return (is_null($id) ? FALSE : $id);
} // fn authenticate
/**
* Change user password
*
* @param string $login
* @param string $oldpass
* old password (optional for 'superuser mode')
* @param string $pass
* optional
* @param boolean $passenc
* optional, password already encrypted if true
* @return boolean|PEAR_Error
*/
public static function Passwd($login, $oldpass=null, $pass='', $passenc=FALSE)
{
global $CC_CONFIG, $CC_DBC;
if (!$passenc) {
$cpass = md5($pass);
} else {
$cpass = $pass;
}
if (!is_null($oldpass)) {
$oldcpass = md5($oldpass);
$oldpCond = "AND pass='$oldcpass'";
} else {
$oldpCond = '';
}
$sql = "UPDATE ".$CC_CONFIG['subjTable']." SET pass='$cpass'"
." WHERE login='$login' $oldpCond AND type='U'";
$r = $CC_DBC->query($sql);
if (PEAR::isError($r)) {
return $r;
}
return TRUE;
} // fn passwd
/* --------------------------------------------------------------- groups */
/* --------------------------------------------------------- info methods */
/**
* Get subject id from login
*
* @param string $login
* @return int|PEAR_Error
*/
public static function GetSubjId($login)
{
global $CC_CONFIG;
global $CC_DBC;
$sql = "SELECT id FROM ".$CC_CONFIG['subjTable']
." WHERE login='$login'";
return $CC_DBC->getOne($sql);
} // fn getSubjId
/**
* Return true if uid is [id]direct member of gid
*
* @param int $uid
* local user id
* @param int $gid
* local group id
* @return boolean
*/
public static function IsMemberOf($uid, $gid)
{
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT count(*)as cnt"
." FROM ".$CC_CONFIG['smembTable']
." WHERE uid='$uid' AND gid='$gid'";
$res = $CC_DBC->getOne($sql);
if (PEAR::isError($res)) {
return $res;
}
return (intval($res) > 0);
} // fn isMemberOf
} // class Subjects

View file

@ -0,0 +1,184 @@
<?php
class User {
private $_userInstance;
public function __construct($userId)
{
if (strlen($userId)==0){
$this->_userInstance = $this->createUser();
} else {
$this->_userInstance = CcSubjsQuery::create()->findPK($userId);
}
}
public function getId() {
return $this->_userInstance->getDbId();
}
public function isHost($showId) {
$userId = $this->_userInstance->getDbId();
return CcShowHostsQuery::create()->filterByDbShow($showId)->filterByDbHost($userId)->count() > 0;
}
public function isAdmin() {
return $this->_userInstance->getDbType() === 'A';
}
public function setLogin($login){
$user = $this->_userInstance;
$user->setDbLogin($login);
}
public function setPassword($password){
$user = $this->_userInstance;
$user->setDbPass(md5($password));
}
public function setFirstName($firstName){
$user = $this->_userInstance;
$user->setDbFirstName($firstName);
}
public function setLastName($lastName){
$user = $this->_userInstance;
$user->setDbLastName($lastName);
}
public function setType($type){
$user = $this->_userInstance;
$user->setDbType($type);
}
public function setEmail($email){
$user = $this->_userInstance;
$user->setDbEmail($email);
}
public function setSkype($skype){
$user = $this->_userInstance;
$user->setDbSkypeContact($skype);
}
public function setJabber($jabber){
$user = $this->_userInstance;
$user->setDbJabberContact($jabber);
}
public function getLogin(){
$user = $this->_userInstance;
return $user->getDbLogin();
}
public function getPassword(){
$user = $this->_userInstance;
return $user->getDbPass();
}
public function getFirstName(){
$user = $this->_userInstance;
return $user->getDbFirstName();
}
public function getLastName(){
$user = $this->_userInstance;
return $user->getDbLastName();
}
public function getType(){
$user = $this->_userInstance;
return $user->getDbType();
}
public function getEmail(){
$user = $this->_userInstance;
return $user->getDbEmail();
}
public function getSkype(){
$user = $this->_userInstance;
return $user->getDbSkypeContact();
}
public function getJabber(){
$user = $this->_userInstance;
return $user->getDbJabberContact();
}
public function save(){
$this->_userInstance->save();
}
public function delete(){
if (!$this->_userInstance->isDeleted())
$this->_userInstance->delete();
}
private function createUser() {
$user = new CcSubjs();
return $user;
}
public static function getUsers($type, $search=NULL) {
global $CC_DBC;
$sql;
$sql_gen = "SELECT id AS value, login AS label FROM cc_subjs ";
$sql = $sql_gen;
if(is_array($type)) {
for($i=0; $i<count($type); $i++) {
$type[$i] = "type = '{$type[$i]}'";
}
$sql_type = join(" OR ", $type);
}
else {
$sql_type = "type = {$type}";
}
$sql = $sql_gen ." WHERE (". $sql_type.") ";
if(!is_null($search)) {
$like = "login ILIKE '%{$search}%'";
$sql = $sql . " AND ".$like;
}
$sql = $sql ." ORDER BY login";
return $CC_DBC->GetAll($sql);
}
public static function getHosts($search=NULL) {
return User::getUsers(array('H'), $search);
}
public static function getUsersDataTablesInfo($datatables_post) {
$fromTable = "cc_subjs";
return StoredFile::searchFiles($fromTable, $datatables_post);
}
public static function getUserData($id){
global $CC_DBC;
$sql = "SELECT login, first_name, last_name, type, id, email, skype_contact, jabber_contact"
." FROM cc_subjs"
." WHERE id = $id";
return $CC_DBC->GetRow($sql);
}
public static function GetUserID($login){
$user = CcSubjsQuery::create()->findOneByDbLogin($login);
if (is_null($user)){
return -1;
} else {
return $user->getDbId();
}
}
}

View file

@ -0,0 +1,398 @@
<?php
/**
* @package Airtime
* @subpackage StorageServer
*/
require_once "XML/Util.php";
/* ================================================================== Element */
/**
* Object representation of one XML element
*
* @package Airtime
* @subpackage StorageServer
* @copyright 2010 Sourcefabric O.P.S.
* @license http://www.gnu.org/licenses/gpl.txt
* @see MetaData
*/
class XmlElement {
/**
* Namespace prefix
* @var string
*/
public $ns;
/**
* Element name
* @var string
*/
public $name;
/**
* Attributes
* @var array
*/
public $attrs = array();
/**
* Namespace definitions
* @var array
*/
public $nSpaces = array();
/**
* Child nodes
* @var array
*/
public $children = array();
/**
* Text content of element
* @var string
*/
public $content = '';
/**
* @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
*/
public function __construct($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 Airtime
* @subpackage StorageServer
* @copyright 2010 Sourcefabric O.P.S.
* @license http://www.gnu.org/licenses/gpl.txt
* @see MetaData
*/
class XmlAttrib {
/**
* Namespace prefix
* @var string
*/
public $ns;
/**
* Attribute name
* @var string
*/
public $name;
/**
* Attribute value
* @var string
*/
public $val;
/**
* @param string $atns
* namespace prefix
* @param string $atnm
* attribute name
* @param string $atv
* attribute value
*/
public function __construct($atns, $atnm, $atv)
{
$this->ns = $atns;
$this->name = $atnm;
$this->val = $atv;
}
} // fn XmlAttrib
/* =================================================================== Parser */
/**
* XML parser object encapsulation
*
* @package Airtime
* @subpackage StorageServer
* @copyright 2010 Sourcefabric O.P.S.
* @license http://www.gnu.org/licenses/gpl.txt
* @see MetaData
*/
class XmlParser {
/**
* Tree of nodes
* @var array
*/
private $tree = NULL;
/**
* Parse stack
* @var array
*/
private $stack = array();
/**
* Error structure
* @var array
*/
private $err = array(FALSE, '');
/**
* @param string $data
* XML string to be parsed
*/
public function __construct($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(
"XmlParser::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,18 @@
<?php
/**
* Skeleton subclass for representing a row from the 'cc_access' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcAccess extends BaseCcAccess {
} // CcAccess

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_access' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcAccessPeer extends BaseCcAccessPeer {
} // CcAccessPeer

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_access' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcAccessQuery extends BaseCcAccessQuery {
} // CcAccessQuery

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for representing a row from the 'cc_backup' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcBackup extends BaseCcBackup {
} // CcBackup

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_backup' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcBackupPeer extends BaseCcBackupPeer {
} // CcBackupPeer

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_backup' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcBackupQuery extends BaseCcBackupQuery {
} // CcBackupQuery

View file

@ -0,0 +1,31 @@
<?php
require_once('Common.php');
/**
* Skeleton subclass for representing a row from the 'cc_files' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.campcaster
*/
class CcFiles extends BaseCcFiles {
public function getDbLength()
{
return $this->length;
}
public function setDbLength($time)
{
$this->length = $time;
//$this->modifiedColumns[] = CcPlaylistcontentsPeer::LENGTH;
return Common::setTimeInSub($this, 'LENGTH', $time);
}
} // CcFiles

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_files' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcFilesPeer extends BaseCcFilesPeer {
} // CcFilesPeer

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_files' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcFilesQuery extends BaseCcFilesQuery {
} // CcFilesQuery

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for representing a row from the 'cc_perms' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcPerms extends BaseCcPerms {
} // CcPerms

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_perms' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcPermsPeer extends BaseCcPermsPeer {
} // CcPermsPeer

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_perms' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcPermsQuery extends BaseCcPermsQuery {
} // CcPermsQuery

View file

@ -0,0 +1,48 @@
<?php
/**
* Skeleton subclass for representing a row from the 'cc_playlist' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.campcaster
*/
class CcPlaylist extends BaseCcPlaylist {
public function computeLastPosition()
{
$con = Propel::getConnection(CcPlaylistPeer::DATABASE_NAME);
$sql = 'SELECT MAX('.CcPlaylistcontentsPeer::POSITION.') AS pos'
. ' FROM ' .CcPlaylistcontentsPeer::TABLE_NAME
. ' WHERE ' .CcPlaylistcontentsPeer::PLAYLIST_ID. ' = :p1';
$stmt = $con->prepare($sql);
$stmt->bindValue(':p1', $this->getDbId());
$stmt->execute();
return $stmt->fetchColumn();
}
public function computeLength()
{
$con = Propel::getConnection(CcPlaylistPeer::DATABASE_NAME);
$sql = 'SELECT SUM('.CcPlaylistcontentsPeer::CLIPLENGTH.') AS length'
. ' FROM ' .CcPlaylistcontentsPeer::TABLE_NAME
. ' WHERE ' .CcPlaylistcontentsPeer::PLAYLIST_ID. ' = :p1';
$stmt = $con->prepare($sql);
$stmt->bindValue(':p1', $this->getDbId());
$stmt->execute();
return $stmt->fetchColumn();
}
} // CcPlaylist

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_playlist' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcPlaylistPeer extends BaseCcPlaylistPeer {
} // CcPlaylistPeer

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_playlist' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcPlaylistQuery extends BaseCcPlaylistQuery {
} // CcPlaylistQuery

View file

@ -0,0 +1,81 @@
<?php
require_once('Common.php');
/**
* Skeleton subclass for representing a row from the 'cc_playlistcontents' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.campcaster
*/
class CcPlaylistcontents extends BaseCcPlaylistcontents {
public function getDbFadein()
{
return $this->fadein;
}
public function setDbFadein($time)
{
$this->fadein = $time;
//$this->modifiedColumns[] = CcPlaylistcontentsPeer::FADEIN;
Common::setTimeInSub($this, 'FADEIN', $time);
}
public function getDbFadeout()
{
return $this->fadeout;
}
public function setDbFadeout($time)
{
$this->fadeout = $time;
//$this->modifiedColumns[] = CcPlaylistcontentsPeer::FADEOUT;
Common::setTimeInSub($this, 'FADEOUT', $time);
}
public function getDbCuein()
{
return $this->cuein;
}
public function setDbCuein($time)
{
$this->cuein = $time;
//$this->modifiedColumns[] = CcPlaylistcontentsPeer::CUEIN;
Common::setTimeInSub($this, 'CUEIN', $time);
}
public function getDbCueout()
{
return $this->cueout;
}
public function setDbCueout($time)
{
$this->cueout = $time;
//$this->modifiedColumns[] = CcPlaylistcontentsPeer::CUEOUT;
Common::setTimeInSub($this, 'CUEOUT', $time);
}
public function getDbCliplength()
{
return $this->cliplength;
}
public function setDbCliplength($time)
{
$this->cliplength = $time;
//$this->modifiedColumns[] = CcPlaylistcontentsPeer::CLIPLENGTH;
Common::setTimeInSub($this, 'CLIPLENGTH', $time);
}
} // CcPlaylistcontents

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_playlistcontents' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcPlaylistcontentsPeer extends BaseCcPlaylistcontentsPeer {
} // CcPlaylistcontentsPeer

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_playlistcontents' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcPlaylistcontentsQuery extends BaseCcPlaylistcontentsQuery {
} // CcPlaylistcontentsQuery

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for representing a row from the 'cc_pref' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcPref extends BaseCcPref {
} // CcPref

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_pref' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcPrefPeer extends BaseCcPrefPeer {
} // CcPrefPeer

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_pref' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcPrefQuery extends BaseCcPrefQuery {
} // CcPrefQuery

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for representing a row from the 'cc_schedule' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcSchedule extends BaseCcSchedule {
} // CcSchedule

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_schedule' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcSchedulePeer extends BaseCcSchedulePeer {
} // CcSchedulePeer

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_schedule' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcScheduleQuery extends BaseCcScheduleQuery {
} // CcScheduleQuery

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for representing a row from the 'cc_sess' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcSess extends BaseCcSess {
} // CcSess

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_sess' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcSessPeer extends BaseCcSessPeer {
} // CcSessPeer

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_sess' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcSessQuery extends BaseCcSessQuery {
} // CcSessQuery

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for representing a row from the 'cc_show' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcShow extends BaseCcShow {
} // CcShow

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for representing a row from the 'cc_show_days' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcShowDays extends BaseCcShowDays {
} // CcShowDays

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_show_days' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcShowDaysPeer extends BaseCcShowDaysPeer {
} // CcShowDaysPeer

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_show_days' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcShowDaysQuery extends BaseCcShowDaysQuery {
} // CcShowDaysQuery

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for representing a row from the 'cc_show_hosts' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcShowHosts extends BaseCcShowHosts {
} // CcShowHosts

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_show_hosts' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcShowHostsPeer extends BaseCcShowHostsPeer {
} // CcShowHostsPeer

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_show_hosts' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcShowHostsQuery extends BaseCcShowHostsQuery {
} // CcShowHostsQuery

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for representing a row from the 'cc_show_instances' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcShowInstances extends BaseCcShowInstances {
} // CcShowInstances

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_show_instances' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcShowInstancesPeer extends BaseCcShowInstancesPeer {
} // CcShowInstancesPeer

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_show_instances' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcShowInstancesQuery extends BaseCcShowInstancesQuery {
} // CcShowInstancesQuery

View file

@ -0,0 +1,18 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_show' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcShowPeer extends BaseCcShowPeer {
} // CcShowPeer

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