Merge branch 'master' of dev.sourcefabric.org:campcaster

This commit is contained in:
naomiaro 2011-03-31 21:03:06 -04:00
commit 7a49137edd
62 changed files with 1367 additions and 647 deletions

24
CREDITS
View File

@ -2,11 +2,30 @@
CREDITS
=======
Version 1.7.0
-------------
Naomi Aro (naomi.aro@sourcefabric.org)
Role: Software Developer
Martin Konecny (martin.konecny@sourcefabric.org)
Role: Software Developer
Ofir Gal (ofir.gal@sourcefabric.org)
Role: QA
Daniel James
Role: Documentor & QA
Paul Baranowski (paul.baranowski@sourcefabric.org)
Role: Project Manager
Version 1.6.1
-------------
Version 1.6.1 fixes a problem with playout being interrupted after 48
hours. It also fixes some security issues.
Version 1.6.0
-------------
This version marks a major change to the project, completely replacing the
@ -27,11 +46,14 @@ Naomi Aro (naomi.aro@sourcefabric.org)
- Conversion to Propel DB backend
Martin Konecny (martin.konecny@sourcefabric.org)
Role:Software Developer
Role: Software Developer
Highlights:
- New User Interface
- Scheduler/Backend
Ofir Gal (ofir.gal@sourcefabric.org)
Role: QA
Daniel James
Role: Documentor & QA

35
INSTALL
View File

@ -1,23 +1,22 @@
--------------------------------------------------------------------------------
Airtime is the open radio software for scheduling and remote station management.
Home page: http://airtime.sourcefabric.org/
Copyright (c) 2010-2011 Sourcefabric O.P.S.
Installation instructions are here:
http://wiki.sourcefabric.org/x/BQBF
This file is part of the Airtime project.
http://airtime.sourcefabric.org/
Here is the manual:
http://new.flossmanuals.net/airtime/index
To report bugs, visit our bug tracker at:
http://dev.sourcefabric.org/browse/CC
Visit our community support forum here:
http://forum.sourcefabric.org/index.php/f/14/
To report bugs, visit our bug tracker at:
http://dev.sourcefabric.org/browse/CC
For commercial support, see:
http://sourcefabric.org/en/services/about/347/Support.htm
or send an e-mail to contact@sourcefabric.org
Visit our community support forum here:
http://forum.sourcefabric.org/index.php/f/14/
For commercial support, see http://sourcefabric.org/en/services/about/347/Support.htm
or send an e-mail to contact@sourcefabric.org
If you are a developer and want to hack on Airtime, go here:
http://wiki.sourcefabric.org/display/CC
--------------------------------------------------------------------------------
Please see this page for install instructions:
http://wiki.sourcefabric.org/display/CC/Installing+Airtime+%28v1.6%29
If you are a developer, see this page:
http://wiki.sourcefabric.org/display/CC

View File

@ -29,8 +29,19 @@ Linked code:
- License: LGPLv3
* Soundcloud php api wrapper
- https://github.com/mptre/php-soundcloud/blob/master/Services/Soundcloud.php
- Web site: https://github.com/mptre/php-soundcloud/blob/master/Services/Soundcloud.php
- License: MIT
- Compatible with the GPL: Yes. See http://www.gnu.org/licenses/license-list.html
* Kombu
- Web site: http://pypi.python.org/pypi/kombu/
- License: New BSD
- Compatible with GPLv3? Yes.
* PHP-AMQPLIB
- Web site: https://github.com/tnc/php-amqplib
- License: LGPLv2.1
- Compatible with GPLv3? Yes
----------------
Non-linked code:

2
README
View File

@ -4,6 +4,8 @@
Airtime is an open source application that provides remote automation
of a radio station.
Home page: http://airtime.sourcefabric.org/
Major features:
* Web-based remote station management. Authorized personnel can add
program material, create playlists, and schedule programming all via

View File

@ -8,13 +8,6 @@ return array (
'BaseCcAccessPeer' => 'airtime/om/BaseCcAccessPeer.php',
'BaseCcAccess' => 'airtime/om/BaseCcAccess.php',
'BaseCcAccessQuery' => 'airtime/om/BaseCcAccessQuery.php',
'CcBackupTableMap' => 'airtime/map/CcBackupTableMap.php',
'CcBackupPeer' => 'airtime/CcBackupPeer.php',
'CcBackup' => 'airtime/CcBackup.php',
'CcBackupQuery' => 'airtime/CcBackupQuery.php',
'BaseCcBackupPeer' => 'airtime/om/BaseCcBackupPeer.php',
'BaseCcBackup' => 'airtime/om/BaseCcBackup.php',
'BaseCcBackupQuery' => 'airtime/om/BaseCcBackupQuery.php',
'CcFilesTableMap' => 'airtime/map/CcFilesTableMap.php',
'CcFilesPeer' => 'airtime/CcFilesPeer.php',
'CcFiles' => 'airtime/CcFiles.php',
@ -113,11 +106,4 @@ return array (
'BaseCcSubjsPeer' => 'airtime/om/BaseCcSubjsPeer.php',
'BaseCcSubjs' => 'airtime/om/BaseCcSubjs.php',
'BaseCcSubjsQuery' => 'airtime/om/BaseCcSubjsQuery.php',
'CcTransTableMap' => 'airtime/map/CcTransTableMap.php',
'CcTransPeer' => 'airtime/CcTransPeer.php',
'CcTrans' => 'airtime/CcTrans.php',
'CcTransQuery' => 'airtime/CcTransQuery.php',
'BaseCcTransPeer' => 'airtime/om/BaseCcTransPeer.php',
'BaseCcTrans' => 'airtime/om/BaseCcTrans.php',
'BaseCcTransQuery' => 'airtime/om/BaseCcTransQuery.php',
);

View File

@ -1,98 +1,56 @@
<?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.7.0-alpha');
define('AIRTIME_COPYRIGHT_DATE', '2010-2011');
define('AIRTIME_REST_VERSION', '1.1');
// These are the default values for the config.
global $CC_CONFIG;
$values = load_airtime_config();
// **********************************
// ***** START CUSTOMIZING HERE *****
// **********************************
// Set the location where you want to store all of your audio files.
//
// For example:
// $baseFilesDir = '/home/john/radio-files';
$baseFilesDir = __DIR__.'/../../files';
$CC_CONFIG = array(
// Set the URL of your installation
'storageUrlHost' => 'localhost',
'storageUrlPort' => 80,
// Name of the web server user
'webServerUser' => 'www-data',
'webServerUser' => $values['general']['webServerUser'],
'rabbitmq' => array("host" => "127.0.0.1",
"port" => "5672",
"user" => "guest",
"password" => "guest",
"vhost" => "/"),
'rabbitmq' => $values['rabbitmq'],
// ***********************************************************************
// STOP CUSTOMIZING HERE
//
// You don't need to touch anything below this point.
// ***********************************************************************
'baseFilesDir' => $baseFilesDir,
'baseFilesDir' => $values['general']['baseFilesDir'],
// main directory for storing binary media files
'storageDir' => "$baseFilesDir/stor",
'storageDir' => $values['general']['baseFilesDir']."/stor",
// Database config
'dsn' => $values['database'],
'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' => $values['api_key'],
'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',
// name of admin group
//'AdminsGr' => 'Admins',
// name of station preferences group
// 'StationPrefsGr'=> 'StationPrefs',
// name of 'all users' group
//'AllGr' => 'All',
/* ==================================== application-specific configuration */
// 'objtypes' => array(
// 'Storage' => array(/*'Folder',*/ 'File' /*, 'Replica'*/),
// 'File' => array(),
// 'audioclip' => array(),
// 'playlist' => array(),
// ),
// 'allowedActions'=> array(
// 'File' => array('editPrivs', 'write', 'read'),
// 'audioclip' => array('editPrivs', 'write', 'read'),
// 'playlist' => array('editPrivs', 'write', 'read'),
// ),
// 'allActions' => array(
// 'editPrivs', 'write', 'read', 'subjects'
// ),
/* =================================================== cron configuration */
'cronUserName' => 'www-data',
# 'lockfile' => dirname(__FILE__).'/cron/cron.lock',
'lockfile' => dirname(__FILE__).'/stor/buffer/cron.lock',
'cronfile' => dirname(__FILE__).'/cron/croncall.php',
'paramdir' => dirname(__FILE__).'/cron/params',
// 'systemPrefId' => "0", // ID for system prefs in prefs table
);
// Add database table names
@ -119,11 +77,6 @@ $CC_CONFIG['permSequence'] = $CC_CONFIG['permTable'].'_id';
$CC_CONFIG['subjSequence'] = $CC_CONFIG['subjTable'].'_id';
$CC_CONFIG['smembSequence'] = $CC_CONFIG['smembTable'].'_id';
// System users/groups - they cannot be deleted
//$CC_CONFIG['sysSubjs'] = array(
// 'root', /*$CC_CONFIG['AdminsGr'],*/ /*$CC_CONFIG['AllGr'],*/ $CC_CONFIG['StationPrefsGr']
//);
// Add libs to the PHP path
$old_include_path = get_include_path();
set_include_path('.'.PATH_SEPARATOR.$CC_CONFIG['pearPath']
@ -131,15 +84,6 @@ set_include_path('.'.PATH_SEPARATOR.$CC_CONFIG['pearPath']
.PATH_SEPARATOR.$old_include_path);
function load_airtime_config(){
$ini_array = parse_ini_file(dirname(__FILE__).'/../../build/airtime.conf', true);
return array(
'database' => array(
'username' => $ini_array['database']['dbuser'],
'password' => $ini_array['database']['dbpass'],
'hostspec' => $ini_array['database']['host'],
'phptype' => 'pgsql',
'database' => $ini_array['database']['dbname']),
'api_key' => array($ini_array['general']['api_key'])
);
$ini_array = parse_ini_file('/etc/airtime/airtime.conf', true);
return $ini_array;
}

View File

@ -103,27 +103,55 @@ class ApiController extends Zend_Controller_Action
exit;
}
public function liveInfoAction(){
global $CC_CONFIG;
public function liveInfoAction()
{
if (Application_Model_Preference::GetAllow3rdPartyApi()){
// disable the view and the layout
$this->view->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
// disable the view and the layout
$this->view->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
$result = Schedule::GetPlayOrderRange(0, 1);
$result = Schedule::GetPlayOrderRange(0, 1);
$date = new Application_Model_DateHelper;
$timeNow = $date->getDate();
$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;
}
}
$date = new Application_Model_DateHelper;
$timeNow = $date->getDate();
$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).')';
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()
@ -254,11 +282,27 @@ class ApiController extends Zend_Controller_Action
if(Application_Model_Preference::GetDoSoundCloudUpload())
{
$show = new Show($show_inst->getShowId());
$description = $show->getDescription();
for($i=0; $i<$CC_CONFIG['soundcloud-connection-retries']; $i++) {
$soundcloud = new ATSoundcloud();
$soundcloud->uploadTrack($file->getRealFilePath(), $file->getName(), $description);
$show = new Show($show_inst->getShowId());
$description = $show->getDescription();
$hosts = $show->getHosts();
try {
$soundcloud = new ATSoundcloud();
$soundcloud_id = $soundcloud->uploadTrack($file->getRealFilePath(), $file->getName(), $description, $hosts);
$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

@ -28,7 +28,7 @@ class PlaylistController extends Zend_Controller_Action
private function getPlaylist()
{
$pl_sess = $this->pl_sess;
if(isset($pl_sess->id)) {
$pl = Playlist::Recall($pl_sess->id);
@ -43,7 +43,7 @@ class PlaylistController extends Zend_Controller_Action
private function changePlaylist($pl_id)
{
$pl_sess = $this->pl_sess;
if(isset($pl_sess->id)) {
$pl = Playlist::Recall($pl_sess->id);
@ -51,13 +51,13 @@ class PlaylistController extends Zend_Controller_Action
$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;
}
@ -78,7 +78,7 @@ class PlaylistController extends Zend_Controller_Action
$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->_helper->viewRenderer->setResponseSegment('spl');
$this->view->pl = $this->getPlaylist();
}
@ -88,10 +88,10 @@ class PlaylistController extends Zend_Controller_Action
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$pl = new Playlist();
$pl_id = $pl->create("Untitled Playlist");
$pl->create("Untitled Playlist");
$pl->setPLMetaData('dc:creator', $userInfo->login);
$this->changePlaylist($pl_id);
$this->changePlaylist($pl->getId());
$form = new Application_Form_PlaylistMetadata();
$this->view->fieldset = $form;
$this->view->form = $this->view->render('playlist/new.phtml');
@ -105,25 +105,25 @@ class PlaylistController extends Zend_Controller_Action
$pl_id = $this->_getParam('id', null);
//not a new playlist
if(!is_null($pl_id)) {
$this->changePlaylist($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);
$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);
}
@ -132,7 +132,7 @@ class PlaylistController extends Zend_Controller_Action
$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');
}
@ -140,13 +140,13 @@ class PlaylistController extends Zend_Controller_Action
public function editAction()
{
$pl_id = $this->_getParam('id', null);
if(!is_null($pl_id)) {
$this->changePlaylist($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);
@ -158,7 +158,7 @@ class PlaylistController extends Zend_Controller_Action
$pos = $this->_getParam('pos', null);
if (!is_null($id)) {
$pl = $this->getPlaylist();
$res = $pl->addAudioClip($id, $pos);
@ -181,7 +181,7 @@ class PlaylistController extends Zend_Controller_Action
{
$oldPos = $this->_getParam('oldPos');
$newPos = $this->_getParam('newPos');
$pl = $this->getPlaylist();
$pl->moveAudioClip($oldPos, $newPos);
@ -197,7 +197,7 @@ class PlaylistController extends Zend_Controller_Action
public function deleteItemAction()
{
$positions = $this->_getParam('pos', array());
if (!is_array($positions))
$positions = array($positions);
@ -208,7 +208,7 @@ class PlaylistController extends Zend_Controller_Action
$pl = $this->getPlaylist();
foreach ($positions as $pos) {
$pl->delAudioClip($pos);
$pl->delAudioClip($pos);
}
$this->view->pl = $pl;
@ -274,7 +274,7 @@ class PlaylistController extends Zend_Controller_Action
{
$id = $this->_getParam('id', null);
$pl = Playlist::Recall($id);
if ($pl !== FALSE) {
Playlist::Delete($id);
@ -291,7 +291,7 @@ class PlaylistController extends Zend_Controller_Action
public function deleteActiveAction()
{
$pl = $this->getPlaylist();
$pl = $this->getPlaylist();
Playlist::Delete($pl->getId());
$pl_sess = $this->pl_sess;
@ -304,7 +304,7 @@ class PlaylistController extends Zend_Controller_Action
{
$pl = $this->getPlaylist();
$this->closePlaylist($pl);
$this->view->html = $this->view->render('playlist/index.phtml');
}

View File

@ -30,11 +30,13 @@ class PreferenceController extends Zend_Controller_Action
Application_Model_Preference::SetHeadTitle($values["stationName"], $this->view);
Application_Model_Preference::SetDefaultFade($values["stationDefaultFade"]);
Application_Model_Preference::SetStreamLabelFormat($values["streamFormat"]);
Application_Model_Preference::SetAllow3rdPartyApi($values["thirdPartyApi"]);
Application_Model_Preference::SetDoSoundCloudUpload($values["UseSoundCloud"]);
Application_Model_Preference::SetSoundCloudUser($values["SoundCloudUser"]);
Application_Model_Preference::SetSoundCloudPassword($values["SoundCloudPassword"]);
Application_Model_Preference::SetSoundCloudPassword($values["SoundCloudPassword"]);
Application_Model_Preference::SetSoundCloudTags($values["SoundCloudTags"]);
$this->view->statusMsg = "Preferences Updated.";
$this->view->statusMsg = "<div class='success'>Preferences updated.</div>";
}
$this->view->form = $form;

View File

@ -176,11 +176,11 @@ class ScheduleController extends Zend_Controller_Action
if (strtotime($show->getShowStart()) <= strtotime($today_timestamp) &&
strtotime($today_timestamp) < strtotime($show->getShowEnd())) {
strtotime($today_timestamp) < strtotime($show->getShowEnd()) &&
$user->isAdmin()) {
$menu[] = array('action' => array('type' => 'fn',
//'url' => '/Schedule/cancel-current-show'.$params,
'callback' => "window['confirmCancelShow']($id)"),
'title' => 'Cancel Current Show');
'callback' => "window['confirmCancelShow']($id)"),
'title' => 'Cancel Current Show');
}
if (strtotime($today_timestamp) < strtotime($show->getShowStart())) {
@ -319,6 +319,17 @@ class ScheduleController extends Zend_Controller_Action
$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);
@ -397,8 +408,8 @@ class ScheduleController extends Zend_Controller_Action
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$user = new User($userInfo->id);
if($user->isAdmin()) {
Show::addShow($data);
if ($user->isAdmin()) {
Show::create($data);
}
//send back a new form for the user.

View File

@ -89,7 +89,28 @@ class Application_Form_EditAudioMD extends Zend_Form
'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',
'label' => 'Cancel',
'onclick' => 'javascript:document.location="/Library"',
'decorators' => array(
'ViewHelper'
)
));
$this->addDisplayGroup(array('submit', 'cancel'), 'submitButtons', array(
'decorators' => array(
'FormElements',
array('HtmlTag', array('tag' => 'dd', 'class' => 'element')),
),
));
}

View File

@ -42,6 +42,13 @@ class Application_Form_Preferences extends Zend_Form
$stream_format->setValue(Application_Model_Preference::GetStreamLabelFormat());
$this->addElement($stream_format);
$third_party_api = new Zend_Form_Element_Radio('thirdPartyApi');
$third_party_api->setLabel('Allow Remote Websites To Access Show Schedule Info');
$third_party_api->setMultiOptions(array("Disabled",
"Enabled"));
$third_party_api->setValue(Application_Model_Preference::GetAllow3rdPartyApi());
$this->addElement($third_party_api);
$this->addElement('checkbox', 'UseSoundCloud', array(
'label' => 'Automatically Upload Recorded Shows To SoundCloud',
@ -59,7 +66,7 @@ class Application_Form_Preferences extends Zend_Form
));
//SoundCloud Password
$this->addElement('text', 'SoundCloudPassword', array(
$this->addElement('password', 'SoundCloudPassword', array(
'class' => 'input_text',
'label' => 'SoundCloud Password:',
'required' => false,
@ -67,6 +74,14 @@ class Application_Form_Preferences extends Zend_Form
'value' => Application_Model_Preference::GetSoundCloudPassword()
));
// Add the description element
$this->addElement('textarea', 'SoundCloudTags', array(
'label' => 'space separated SoundCloud Tags',
'required' => false,
'class' => 'input_text_area',
'value' => Application_Model_Preference::GetSoundCloudTags()
));
$this->addElement('submit', 'submit', array(
'class' => 'ui-button ui-state-default',
'ignore' => true,

View File

@ -102,27 +102,9 @@ class Playlist {
return $res;
}
public static function Insert($p_values)
public static function Delete($id)
{
// Create the StoredPlaylist object
$storedPlaylist = new Playlist();
$storedPlaylist->name = isset($p_values['filename']) ? $p_values['filename'] : date("H:i:s");
$storedPlaylist->mtime = new DateTime("now");
$pl = new CcPlaylist();
$pl->setDbName($storedPlaylist->name);
$pl->setDbState("incomplete");
$pl->setDbMtime($storedPlaylist->mtime);
$pl->save();
$storedPlaylist->id = $pl->getDbId();
$storedPlaylist->setState('ready');
return $storedPlaylist->id;
}
public static function Delete($id) {
$pl = CcPlaylistQuery::create()->findPK($id);
if($pl === NULL)
return FALSE;
@ -207,7 +189,7 @@ class Playlist {
return $this->name;
}
$pl = CcPlaylistQuery::create()->findPK($id);
if($pl === NULL)
if ($pl === NULL)
return FALSE;
return $pl->getDbName();
@ -395,18 +377,27 @@ class Playlist {
}
/**
* Create instance of Playlist object and insert empty file
* Create instance of a Playlist object.
*
* @param string $fname
* name of new file
* @return instance of Playlist object
* @param string $p_fname
* Name of the playlist
* @return Playlist
*/
public function create($fname=NULL)
public function create($p_fname=NULL)
{
$values = array("filename" => $fname);
$pl_id = Playlist::Insert($values);
$this->id = $pl_id;
return $this->id;
$this->name = !empty($p_fname) ? $p_fname : date("H:i:s");
$this->mtime = new DateTime("now");
$pl = new CcPlaylist();
$pl->setDbName($this->name);
$pl->setDbState("incomplete");
$pl->setDbMtime($this->mtime);
$pl->save();
$this->id = $pl->getDbId();
$this->setState('ready');
return $this;
}
/**

View File

@ -117,12 +117,34 @@ class Application_Model_Preference
}
public static function SetSoundCloudPassword($password) {
Application_Model_Preference::SetValue("soundcloud_password", $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 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

@ -27,6 +27,8 @@ class ScheduleGroup {
/**
* 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
@ -40,7 +42,7 @@ class ScheduleGroup {
* Return PEAR_Error if the item could not be added.
* Error code 555 is a scheduling conflict.
*/
public function add($show_instance, $p_datetime, $p_audioFileId = null, $p_playlistId = null, $p_options = null) {
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)) {
@ -64,7 +66,7 @@ class ScheduleGroup {
$sql = "INSERT INTO ".$CC_CONFIG["scheduleTable"]
." (instance_id, starts, ends, clip_length, group_id, file_id, cue_out)"
." VALUES ($show_instance, TIMESTAMP '$p_datetime', "
." VALUES ($p_showInstance, TIMESTAMP '$p_datetime', "
." (TIMESTAMP '$p_datetime' + INTERVAL '$length'),"
." '$length',"
." {$this->groupId}, $p_audioFileId, '$length')";
@ -103,7 +105,7 @@ class ScheduleGroup {
$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 ($show_instance, $p_playlistId, TIMESTAMP '$itemStartTime', "
." 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']}')";
@ -466,6 +468,30 @@ class Schedule {
{
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"
@ -473,6 +499,7 @@ class Schedule {
." 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'"
@ -628,17 +655,24 @@ class Schedule {
* @param string $p_toDateTime
* In the format "YYYY-MM-DD-HH-mm-SS"
*/
public static function GetScheduledPlaylists()
public static function GetScheduledPlaylists($p_fromDateTime = null, $p_toDateTime = null)
{
global $CC_CONFIG, $CC_DBC;
$t1 = new DateTime();
$range_start = $t1->format("Y-m-d H:i:s");
$t2 = new DateTime();
$t2->add(new DateInterval("PT24H"));
$range_end = $t2->format("Y-m-d H:i:s");
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();

View File

@ -58,6 +58,29 @@ class Show {
$show->setDbBackgroundColor($backgroundColor);
}
public function getId()
{
return $this->_showId;
}
public function getHosts()
{
global $CC_DBC;
$sql = "SELECT first_name, last_name
FROM cc_show_hosts LEFT JOIN cc_subjs ON cc_show_hosts.subjs_id = cc_subjs.id
WHERE show_id = {$this->_showId}";
$hosts = $CC_DBC->GetAll($sql);
$res = array();
foreach($hosts as $host) {
$res[] = $host['first_name']." ".$host['last_name'];
}
return $res;
}
public function cancelShow($day_timestamp)
{
global $CC_DBC;
@ -75,8 +98,17 @@ class Show {
RabbitMq::PushSchedule();
}
//end dates are non inclusive.
public static function addShow($data)
/**
* Create a show.
*
* Note: end dates are non inclusive.
*
* @param array $data
* @return int
* Show ID
*/
public static function create($data)
{
$con = Propel::getConnection(CcShowPeer::DATABASE_NAME);
@ -88,11 +120,11 @@ class Show {
$r = $con->query($sql);
$startDow = $r->fetchColumn(0);
if($data['add_show_no_end']) {
if ($data['add_show_no_end']) {
$endDate = NULL;
$data['add_show_repeats'] = 1;
}
else if($data['add_show_repeats']) {
else if ($data['add_show_repeats']) {
$sql = "SELECT date '{$data['add_show_end_date']}' + INTERVAL '1 day' ";
$r = $con->query($sql);
$endDate = $r->fetchColumn(0);
@ -104,15 +136,15 @@ class Show {
}
//only want the day of the week from the start date.
if(!$data['add_show_repeats']) {
if (!$data['add_show_repeats']) {
$data['add_show_day_check'] = array($startDow);
}
else if($data['add_show_repeats'] && $data['add_show_day_check'] == "") {
else if ($data['add_show_repeats'] && $data['add_show_day_check'] == "") {
$data['add_show_day_check'] = array($startDow);
}
//find repeat type or set to a non repeating show.
if($data['add_show_repeats']) {
if ($data['add_show_repeats']) {
$repeat_type = $data["add_show_repeat_type"];
}
else {
@ -129,7 +161,7 @@ class Show {
$showId = $show->getDbId();
if($data['add_show_record']){
if ($data['add_show_record']){
$isRecorded = 1;
}
else {
@ -137,7 +169,7 @@ class Show {
}
//don't set day for monthly repeat type, it's invalid.
if($data['add_show_repeats'] && $data["add_show_repeat_type"] == 2) {
if ($data['add_show_repeats'] && $data["add_show_repeat_type"] == 2) {
$showDay = new CcShowDays();
$showDay->setDbFirstShow($data['add_show_start_date']);
$showDay->setDbLastShow($endDate);
@ -150,7 +182,7 @@ class Show {
}
else {
foreach ($data['add_show_day_check'] as $day) {
if($startDow !== $day){
if ($startDow !== $day){
if ($startDow > $day)
$daysAdd = 6 - $startDow + 1 + $day;
@ -165,7 +197,7 @@ class Show {
$start = $data['add_show_start_date'];
}
if(strtotime($start) < strtotime($endDate) || is_null($endDate)) {
if (strtotime($start) < strtotime($endDate) || is_null($endDate)) {
$showDay = new CcShowDays();
$showDay->setDbFirstShow($start);
$showDay->setDbLastShow($endDate);
@ -181,11 +213,11 @@ class Show {
}
//adding rows to cc_show_rebroadcast
if($data['add_show_record'] && $data['add_show_rebroadcast'] && $repeat_type != -1) {
if ($data['add_show_record'] && $data['add_show_rebroadcast'] && $repeat_type != -1) {
for($i=1; $i<=5; $i++) {
for ($i=1; $i<=5; $i++) {
if($data['add_show_rebroadcast_date_'.$i]) {
if ($data['add_show_rebroadcast_date_'.$i]) {
$showRebroad = new CcShowRebroadcast();
$showRebroad->setDbDayOffset($data['add_show_rebroadcast_date_'.$i]);
$showRebroad->setDbStartTime($data['add_show_rebroadcast_time_'.$i]);
@ -194,11 +226,11 @@ class Show {
}
}
}
else if($data['add_show_record'] && $data['add_show_rebroadcast'] && $repeat_type == -1){
else if ($data['add_show_record'] && $data['add_show_rebroadcast'] && $repeat_type == -1){
for($i=1; $i<=5; $i++) {
for ($i=1; $i<=5; $i++) {
if($data['add_show_rebroadcast_absolute_date_'.$i]) {
if ($data['add_show_rebroadcast_absolute_date_'.$i]) {
$sql = "SELECT date '{$data['add_show_rebroadcast_absolute_date_'.$i]}' - date '{$data['add_show_start_date']}' ";
$r = $con->query($sql);
$offset_days = $r->fetchColumn(0);
@ -212,7 +244,7 @@ class Show {
}
}
if(is_array($data['add_show_hosts'])) {
if (is_array($data['add_show_hosts'])) {
//add selected hosts to cc_show_hosts table.
foreach ($data['add_show_hosts'] as $host) {
$showHost = new CcShowHosts();
@ -222,10 +254,19 @@ class Show {
}
}
Show::populateShowUntilLastGeneratedDate($showId);
Show::populateShowUntil($showId);
RabbitMq::PushSchedule();
return $showId;
}
/**
* @param string $start_timestamp
* In the format "YYYY-MM-DD HH:mm:ss"
* @param string $end_timestamp
* In the format "YYYY-MM-DD HH:mm:ss"
* @param unknown_type $excludeInstance
* @param boolean $onlyRecord
*/
public static function getShows($start_timestamp, $end_timestamp, $excludeInstance=NULL, $onlyRecord=FALSE)
{
global $CC_DBC;
@ -283,7 +324,7 @@ class Show {
$next_date = $first_show." ".$start_time;
if(strtotime($next_date) < strtotime($end_timestamp)) {
if (strtotime($next_date) < strtotime($end_timestamp)) {
$start = $next_date;
@ -327,7 +368,8 @@ class Show {
//for a show with repeat_type == 0,1,2
private static function populateRepeatingShow($show_id, $next_pop_date, $first_show, $last_show,
$start_time, $duration, $day, $record, $end_timestamp, $interval) {
$start_time, $duration, $day, $record, $end_timestamp, $interval)
{
global $CC_DBC;
if(isset($next_pop_date)) {
@ -404,53 +446,86 @@ class Show {
}
}
//used to catch up a newly added show
private static function populateShowUntilLastGeneratedDate($show_id) {
global $CC_DBC;
$showsPopUntil = Application_Model_Preference::GetShowsPopulatedUntil();
$sql = "SELECT * FROM cc_show_days WHERE show_id = {$show_id}";
/**
* Generate repeating show instances for a single show up to the given date.
* If no date is given, use the one in the user's preferences, which is stored
* automatically by FullCalendar as the furthest date in the future the user
* has looked at.
*
* @param int $p_showId
* @param string $p_date
* In the format "YYYY-MM-DD HH:mm:ss"
*/
public static function populateShowUntil($p_showId, $p_date = NULL)
{
global $CC_DBC;
if (is_null($p_date)) {
$p_date = Application_Model_Preference::GetShowsPopulatedUntil();
if ($p_date == "") {
$today_timestamp = date("Y-m-d");
Application_Model_Preference::SetShowsPopulatedUntil($today_timestamp);
}
}
$sql = "SELECT * FROM cc_show_days WHERE show_id = {$p_showId}";
$res = $CC_DBC->GetAll($sql);
foreach($res as $row) {
foreach ($res as $row) {
Show::populateShow($row["repeat_type"], $row["show_id"], $row["next_pop_date"], $row["first_show"],
$row["last_show"], $row["start_time"], $row["duration"], $row["day"], $row["record"], $showsPopUntil);
$row["last_show"], $row["start_time"], $row["duration"], $row["day"], $row["record"], $p_date);
}
}
public static function populateShowsUntil($pop_timestamp, $end_timestamp) {
/**
* Generate all the repeating shows in the given range.
*
* @param string $p_startTimestamp
* In the format "YYYY-MM-DD HH:mm:ss"
* @param string $p_endTimestamp
* In the format "YYYY-MM-DD HH:mm:ss"
*/
public static function populateAllShowsInRange($p_startTimestamp, $p_endTimestamp)
{
global $CC_DBC;
if($pop_timestamp != "") {
if ($p_startTimestamp != "") {
$sql = "SELECT * FROM cc_show_days
WHERE last_show IS NULL
OR first_show < '{$end_timestamp}' AND last_show > '{$pop_timestamp}'";
WHERE last_show IS NULL
OR first_show < '{$p_endTimestamp}' AND last_show > '{$p_startTimestamp}'";
}
else {
$today_timestamp = date("Y-m-d");
$sql = "SELECT * FROM cc_show_days
WHERE last_show IS NULL
OR first_show < '{$end_timestamp}' AND last_show > '{$today_timestamp}'";
WHERE last_show IS NULL
OR first_show < '{$p_endTimestamp}' AND last_show > '{$today_timestamp}'";
}
$res = $CC_DBC->GetAll($sql);
foreach($res as $row) {
foreach ($res as $row) {
Show::populateShow($row["repeat_type"], $row["show_id"], $row["next_pop_date"], $row["first_show"],
$row["last_show"], $row["start_time"], $row["duration"], $row["day"], $row["record"], $end_timestamp);
$row["last_show"], $row["start_time"], $row["duration"], $row["day"], $row["record"], $p_endTimestamp);
}
}
public static function getFullCalendarEvents($start, $end, $editable=false) {
/**
*
* @param string $start
* In the format "YYYY-MM-DD HH:mm:ss"
* @param string $end
* In the format "YYYY-MM-DD HH:mm:ss"
* @param boolean $editable
*/
public static function getFullCalendarEvents($start, $end, $editable=false)
{
$events = array();
$showsPopUntil = Application_Model_Preference::GetShowsPopulatedUntil();
//if fullcalendar is requesting shows past our previous populated until date, generate shows up until this point.
if($showsPopUntil == "" || strtotime($showsPopUntil) < strtotime($end)) {
Show::populateShowsUntil($showsPopUntil, $end);
if ($showsPopUntil == "" || strtotime($showsPopUntil) < strtotime($end)) {
Show::populateAllShowsInRange($showsPopUntil, $end);
Application_Model_Preference::SetShowsPopulatedUntil($end);
}
@ -458,7 +533,7 @@ class Show {
$today_timestamp = date("Y-m-d H:i:s");
foreach ($shows as $show) {
if($editable && strtotime($today_timestamp) < strtotime($show["starts"]))
if ($editable && strtotime($today_timestamp) < strtotime($show["starts"]))
$events[] = Show::makeFullCalendarEvent($show, array("editable" => true));
else
$events[] = Show::makeFullCalendarEvent($show);
@ -549,6 +624,19 @@ class ShowInstance {
return $showInstance->getDbEnds();
}
public function setSoundCloudFileId($p_soundcloud_id)
{
$showInstance = CcShowInstancesQuery::create()->findPK($this->_instanceId);
$showInstance->setDbSoundCloudId($p_soundcloud_id)
->save();
}
public function getSoundCloudFileId()
{
$showInstance = CcShowInstancesQuery::create()->findPK($this->_instanceId);
return $showInstance->getDbSoundCloudId();
}
public function setShowStart($start)
{
$showInstance = CcShowInstancesQuery::create()->findPK($this->_instanceId);
@ -665,6 +753,10 @@ class ShowInstance {
RabbitMq::PushSchedule();
}
/**
* Get the group ID for this show.
*
*/
private function getLastGroupId()
{
global $CC_DBC;
@ -673,13 +765,18 @@ class ShowInstance {
return $res;
}
/**
* Add a playlist as the last item of the current show.
*
* @param int $plId
* Playlist ID.
*/
public function addPlaylistToShow($plId)
{
$sched = new ScheduleGroup();
$lastGroupId = $this->getLastGroupId();
if(is_null($lastGroupId)) {
if (is_null($lastGroupId)) {
$groupId = $sched->add($this->_instanceId, $this->getShowStart(), null, $plId);
}
else {
@ -688,14 +785,18 @@ class ShowInstance {
RabbitMq::PushSchedule();
}
public function addFileToShow($file_id)
/**
* Add a media file as the last item in the show.
*
* @param int $file_id
*/
public function addFileToShow($file_id)
{
$sched = new ScheduleGroup();
$lastGroupId = $this->getLastGroupId();
if(is_null($lastGroupId)) {
$groupId = $sched->add($this->_instanceId, $this->getShowStart(), $file_id);
if (is_null($lastGroupId)) {
$groupId = $sched->add($this->_instanceId, $this->getShowStart(), $file_id);
}
else {
$groupId = $sched->addFileAfter($this->_instanceId, $lastGroupId, $file_id);
@ -703,12 +804,18 @@ class ShowInstance {
RabbitMq::PushSchedule();
}
public function scheduleShow($plIds) {
foreach($plIds as $plId) {
$this->addPlaylistToShow($plId);
}
}
/**
* Add the given playlists to the show.
*
* @param array $plIds
* An array of playlist IDs.
*/
public function scheduleShow($plIds)
{
foreach ($plIds as $plId) {
$this->addPlaylistToShow($plId);
}
}
public function removeGroupFromShow($group_id)
{
@ -871,10 +978,6 @@ class Show_DAL {
{
global $CC_CONFIG, $CC_DBC;
$timestamp = explode(" ", $timeNow);
$date = $timestamp[0];
$time = $timestamp[1];
$sql = "SELECT si.starts as start_timestamp, si.ends as end_timestamp, s.name, s.id, si.id as instance_id, si.record"
." FROM $CC_CONFIG[showInstances] si, $CC_CONFIG[showTable] s"
." WHERE si.show_id = s.id"
@ -930,7 +1033,31 @@ class Show_DAL {
." OR (si.starts < TIMESTAMP '$timeNow' + INTERVAL '$end seconds' AND si.ends > TIMESTAMP '$timeNow' + INTERVAL '$end seconds'))"
//checking for st.starts IS NULL so that the query also returns shows that do not have any items scheduled.
." AND (st.starts < si.ends OR st.starts IS NULL)"
." ORDER BY st.starts";
." ORDER BY si.starts, st.starts";
return $CC_DBC->GetAll($sql);
}
public static function GetShowsByDayOfWeek($day){
//DOW FROM TIMESTAMP
//The day of the week (0 - 6; Sunday is 0) (for timestamp values only)
//SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40');
//Result: 5
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT"
." si.starts as show_starts,"
." si.ends as show_ends,"
." s.name as show_name,"
." s.url as url"
." FROM $CC_CONFIG[showInstances] si"
." LEFT JOIN $CC_CONFIG[showTable] s"
." ON si.show_id = s.id"
." WHERE EXTRACT(DOW FROM si.starts) = $day"
." AND EXTRACT(WEEK FROM si.starts) = EXTRACT(WEEK FROM localtimestamp)";
//echo $sql;
return $CC_DBC->GetAll($sql);
}

View File

@ -32,26 +32,31 @@ class ATSoundcloud {
{
if($this->getToken())
{
$tags = join(" ", $tags);
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[description]' => $description,
'track[downloadable]' => true,
);
try {
$response = json_decode(
$this->_soundcloud->post('tracks', $track_data),
true
);
}
catch (Services_Soundcloud_Invalid_Http_Response_Code_Exception $e) {
echo $e->getMessage();
}
}
$response = json_decode(
$this->_soundcloud->post('tracks', $track_data),
true
);
return $response["id"];
}
}
}

View File

@ -1481,9 +1481,7 @@ class StoredFile {
public function getFileUrl()
{
global $CC_CONFIG;
return "http://".$CC_CONFIG["storageUrlHost"]
.$CC_CONFIG["apiPath"]."get-media/file/"
.$this->gunid.".".$this->getFileExtension();
return $this->gunid.".".$this->getFileExtension();
}
/**

View File

@ -47,7 +47,7 @@ class CcShowDaysTableMap extends TableMap {
$this->addColumn('REPEAT_TYPE', 'DbRepeatType', 'TINYINT', true, null, null);
$this->addColumn('NEXT_POP_DATE', 'DbNextPopDate', 'DATE', false, null, null);
$this->addForeignKey('SHOW_ID', 'DbShowId', 'INTEGER', 'cc_show', 'ID', true, null, null);
$this->addColumn('RECORD', 'DbRecord', 'TINYINT', false, null, null);
$this->addColumn('RECORD', 'DbRecord', 'TINYINT', false, null, 0);
// validators
} // initialize()

View File

@ -46,6 +46,7 @@ class CcShowInstancesTableMap extends TableMap {
$this->addColumn('REBROADCAST', 'DbRebroadcast', 'TINYINT', false, null, 0);
$this->addForeignKey('INSTANCE_ID', 'DbOriginalShow', 'INTEGER', 'cc_show_instances', 'ID', false, null, null);
$this->addForeignKey('FILE_ID', 'DbRecordedFile', 'INTEGER', 'cc_files', 'ID', false, null, null);
$this->addColumn('SOUNDCLOUD_ID', 'DbSoundCloudId', 'INTEGER', false, null, null);
// validators
} // initialize()

View File

@ -80,6 +80,7 @@ abstract class BaseCcShowDays extends BaseObject implements Persistent
/**
* The value for the record field.
* Note: this column has a database default value of: 0
* @var int
*/
protected $record;
@ -103,6 +104,27 @@ abstract class BaseCcShowDays extends BaseObject implements Persistent
*/
protected $alreadyInValidation = false;
/**
* Applies default values to this object.
* This method should be called from the object's constructor (or
* equivalent initialization method).
* @see __construct()
*/
public function applyDefaultValues()
{
$this->record = 0;
}
/**
* Initializes internal state of BaseCcShowDays object.
* @see applyDefaults()
*/
public function __construct()
{
parent::__construct();
$this->applyDefaultValues();
}
/**
* Get the [id] column value.
*
@ -607,7 +629,7 @@ abstract class BaseCcShowDays extends BaseObject implements Persistent
$v = (int) $v;
}
if ($this->record !== $v) {
if ($this->record !== $v || $this->isNew()) {
$this->record = $v;
$this->modifiedColumns[] = CcShowDaysPeer::RECORD;
}
@ -625,6 +647,10 @@ abstract class BaseCcShowDays extends BaseObject implements Persistent
*/
public function hasOnlyDefaultValues()
{
if ($this->record !== 0) {
return false;
}
// otherwise, everything was equal, so return TRUE
return true;
} // hasOnlyDefaultValues()
@ -1357,6 +1383,7 @@ abstract class BaseCcShowDays extends BaseObject implements Persistent
$this->alreadyInSave = false;
$this->alreadyInValidation = false;
$this->clearAllReferences();
$this->applyDefaultValues();
$this->resetModified();
$this->setNew(true);
$this->setDeleted(false);

View File

@ -74,6 +74,12 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent
*/
protected $file_id;
/**
* The value for the soundcloud_id field.
* @var int
*/
protected $soundcloud_id;
/**
* @var CcShow
*/
@ -261,6 +267,16 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent
return $this->file_id;
}
/**
* Get the [soundcloud_id] column value.
*
* @return int
*/
public function getDbSoundCloudId()
{
return $this->soundcloud_id;
}
/**
* Set the value of [id] column.
*
@ -491,6 +507,26 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent
return $this;
} // setDbRecordedFile()
/**
* Set the value of [soundcloud_id] column.
*
* @param int $v new value
* @return CcShowInstances The current object (for fluent API support)
*/
public function setDbSoundCloudId($v)
{
if ($v !== null) {
$v = (int) $v;
}
if ($this->soundcloud_id !== $v) {
$this->soundcloud_id = $v;
$this->modifiedColumns[] = CcShowInstancesPeer::SOUNDCLOUD_ID;
}
return $this;
} // setDbSoundCloudId()
/**
* Indicates whether the columns in this object are only set to default values.
*
@ -539,6 +575,7 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent
$this->rebroadcast = ($row[$startcol + 5] !== null) ? (int) $row[$startcol + 5] : null;
$this->instance_id = ($row[$startcol + 6] !== null) ? (int) $row[$startcol + 6] : null;
$this->file_id = ($row[$startcol + 7] !== null) ? (int) $row[$startcol + 7] : null;
$this->soundcloud_id = ($row[$startcol + 8] !== null) ? (int) $row[$startcol + 8] : null;
$this->resetModified();
$this->setNew(false);
@ -547,7 +584,7 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent
$this->ensureConsistency();
}
return $startcol + 8; // 8 = CcShowInstancesPeer::NUM_COLUMNS - CcShowInstancesPeer::NUM_LAZY_LOAD_COLUMNS).
return $startcol + 9; // 9 = CcShowInstancesPeer::NUM_COLUMNS - CcShowInstancesPeer::NUM_LAZY_LOAD_COLUMNS).
} catch (Exception $e) {
throw new PropelException("Error populating CcShowInstances object", $e);
@ -968,6 +1005,9 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent
case 7:
return $this->getDbRecordedFile();
break;
case 8:
return $this->getDbSoundCloudId();
break;
default:
return null;
break;
@ -1000,6 +1040,7 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent
$keys[5] => $this->getDbRebroadcast(),
$keys[6] => $this->getDbOriginalShow(),
$keys[7] => $this->getDbRecordedFile(),
$keys[8] => $this->getDbSoundCloudId(),
);
if ($includeForeignObjects) {
if (null !== $this->aCcShow) {
@ -1066,6 +1107,9 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent
case 7:
$this->setDbRecordedFile($value);
break;
case 8:
$this->setDbSoundCloudId($value);
break;
} // switch()
}
@ -1098,6 +1142,7 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent
if (array_key_exists($keys[5], $arr)) $this->setDbRebroadcast($arr[$keys[5]]);
if (array_key_exists($keys[6], $arr)) $this->setDbOriginalShow($arr[$keys[6]]);
if (array_key_exists($keys[7], $arr)) $this->setDbRecordedFile($arr[$keys[7]]);
if (array_key_exists($keys[8], $arr)) $this->setDbSoundCloudId($arr[$keys[8]]);
}
/**
@ -1117,6 +1162,7 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent
if ($this->isColumnModified(CcShowInstancesPeer::REBROADCAST)) $criteria->add(CcShowInstancesPeer::REBROADCAST, $this->rebroadcast);
if ($this->isColumnModified(CcShowInstancesPeer::INSTANCE_ID)) $criteria->add(CcShowInstancesPeer::INSTANCE_ID, $this->instance_id);
if ($this->isColumnModified(CcShowInstancesPeer::FILE_ID)) $criteria->add(CcShowInstancesPeer::FILE_ID, $this->file_id);
if ($this->isColumnModified(CcShowInstancesPeer::SOUNDCLOUD_ID)) $criteria->add(CcShowInstancesPeer::SOUNDCLOUD_ID, $this->soundcloud_id);
return $criteria;
}
@ -1185,6 +1231,7 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent
$copyObj->setDbRebroadcast($this->rebroadcast);
$copyObj->setDbOriginalShow($this->instance_id);
$copyObj->setDbRecordedFile($this->file_id);
$copyObj->setDbSoundCloudId($this->soundcloud_id);
if ($deepCopy) {
// important: temporarily setNew(false) because this affects the behavior of
@ -1676,6 +1723,7 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent
$this->rebroadcast = null;
$this->instance_id = null;
$this->file_id = null;
$this->soundcloud_id = null;
$this->alreadyInSave = false;
$this->alreadyInValidation = false;
$this->clearAllReferences();

View File

@ -26,7 +26,7 @@ abstract class BaseCcShowInstancesPeer {
const TM_CLASS = 'CcShowInstancesTableMap';
/** The total number of columns. */
const NUM_COLUMNS = 8;
const NUM_COLUMNS = 9;
/** The number of lazy-loaded columns. */
const NUM_LAZY_LOAD_COLUMNS = 0;
@ -55,6 +55,9 @@ abstract class BaseCcShowInstancesPeer {
/** the column name for the FILE_ID field */
const FILE_ID = 'cc_show_instances.FILE_ID';
/** the column name for the SOUNDCLOUD_ID field */
const SOUNDCLOUD_ID = 'cc_show_instances.SOUNDCLOUD_ID';
/**
* An identiy map to hold any loaded instances of CcShowInstances objects.
* This must be public so that other peer classes can access this when hydrating from JOIN
@ -71,12 +74,12 @@ abstract class BaseCcShowInstancesPeer {
* e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id'
*/
private static $fieldNames = array (
BasePeer::TYPE_PHPNAME => array ('DbId', 'DbStarts', 'DbEnds', 'DbShowId', 'DbRecord', 'DbRebroadcast', 'DbOriginalShow', 'DbRecordedFile', ),
BasePeer::TYPE_STUDLYPHPNAME => array ('dbId', 'dbStarts', 'dbEnds', 'dbShowId', 'dbRecord', 'dbRebroadcast', 'dbOriginalShow', 'dbRecordedFile', ),
BasePeer::TYPE_COLNAME => array (self::ID, self::STARTS, self::ENDS, self::SHOW_ID, self::RECORD, self::REBROADCAST, self::INSTANCE_ID, self::FILE_ID, ),
BasePeer::TYPE_RAW_COLNAME => array ('ID', 'STARTS', 'ENDS', 'SHOW_ID', 'RECORD', 'REBROADCAST', 'INSTANCE_ID', 'FILE_ID', ),
BasePeer::TYPE_FIELDNAME => array ('id', 'starts', 'ends', 'show_id', 'record', 'rebroadcast', 'instance_id', 'file_id', ),
BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, )
BasePeer::TYPE_PHPNAME => array ('DbId', 'DbStarts', 'DbEnds', 'DbShowId', 'DbRecord', 'DbRebroadcast', 'DbOriginalShow', 'DbRecordedFile', 'DbSoundCloudId', ),
BasePeer::TYPE_STUDLYPHPNAME => array ('dbId', 'dbStarts', 'dbEnds', 'dbShowId', 'dbRecord', 'dbRebroadcast', 'dbOriginalShow', 'dbRecordedFile', 'dbSoundCloudId', ),
BasePeer::TYPE_COLNAME => array (self::ID, self::STARTS, self::ENDS, self::SHOW_ID, self::RECORD, self::REBROADCAST, self::INSTANCE_ID, self::FILE_ID, self::SOUNDCLOUD_ID, ),
BasePeer::TYPE_RAW_COLNAME => array ('ID', 'STARTS', 'ENDS', 'SHOW_ID', 'RECORD', 'REBROADCAST', 'INSTANCE_ID', 'FILE_ID', 'SOUNDCLOUD_ID', ),
BasePeer::TYPE_FIELDNAME => array ('id', 'starts', 'ends', 'show_id', 'record', 'rebroadcast', 'instance_id', 'file_id', 'soundcloud_id', ),
BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, )
);
/**
@ -86,12 +89,12 @@ abstract class BaseCcShowInstancesPeer {
* e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0
*/
private static $fieldKeys = array (
BasePeer::TYPE_PHPNAME => array ('DbId' => 0, 'DbStarts' => 1, 'DbEnds' => 2, 'DbShowId' => 3, 'DbRecord' => 4, 'DbRebroadcast' => 5, 'DbOriginalShow' => 6, 'DbRecordedFile' => 7, ),
BasePeer::TYPE_STUDLYPHPNAME => array ('dbId' => 0, 'dbStarts' => 1, 'dbEnds' => 2, 'dbShowId' => 3, 'dbRecord' => 4, 'dbRebroadcast' => 5, 'dbOriginalShow' => 6, 'dbRecordedFile' => 7, ),
BasePeer::TYPE_COLNAME => array (self::ID => 0, self::STARTS => 1, self::ENDS => 2, self::SHOW_ID => 3, self::RECORD => 4, self::REBROADCAST => 5, self::INSTANCE_ID => 6, self::FILE_ID => 7, ),
BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'STARTS' => 1, 'ENDS' => 2, 'SHOW_ID' => 3, 'RECORD' => 4, 'REBROADCAST' => 5, 'INSTANCE_ID' => 6, 'FILE_ID' => 7, ),
BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'starts' => 1, 'ends' => 2, 'show_id' => 3, 'record' => 4, 'rebroadcast' => 5, 'instance_id' => 6, 'file_id' => 7, ),
BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, )
BasePeer::TYPE_PHPNAME => array ('DbId' => 0, 'DbStarts' => 1, 'DbEnds' => 2, 'DbShowId' => 3, 'DbRecord' => 4, 'DbRebroadcast' => 5, 'DbOriginalShow' => 6, 'DbRecordedFile' => 7, 'DbSoundCloudId' => 8, ),
BasePeer::TYPE_STUDLYPHPNAME => array ('dbId' => 0, 'dbStarts' => 1, 'dbEnds' => 2, 'dbShowId' => 3, 'dbRecord' => 4, 'dbRebroadcast' => 5, 'dbOriginalShow' => 6, 'dbRecordedFile' => 7, 'dbSoundCloudId' => 8, ),
BasePeer::TYPE_COLNAME => array (self::ID => 0, self::STARTS => 1, self::ENDS => 2, self::SHOW_ID => 3, self::RECORD => 4, self::REBROADCAST => 5, self::INSTANCE_ID => 6, self::FILE_ID => 7, self::SOUNDCLOUD_ID => 8, ),
BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'STARTS' => 1, 'ENDS' => 2, 'SHOW_ID' => 3, 'RECORD' => 4, 'REBROADCAST' => 5, 'INSTANCE_ID' => 6, 'FILE_ID' => 7, 'SOUNDCLOUD_ID' => 8, ),
BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'starts' => 1, 'ends' => 2, 'show_id' => 3, 'record' => 4, 'rebroadcast' => 5, 'instance_id' => 6, 'file_id' => 7, 'soundcloud_id' => 8, ),
BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, )
);
/**
@ -171,6 +174,7 @@ abstract class BaseCcShowInstancesPeer {
$criteria->addSelectColumn(CcShowInstancesPeer::REBROADCAST);
$criteria->addSelectColumn(CcShowInstancesPeer::INSTANCE_ID);
$criteria->addSelectColumn(CcShowInstancesPeer::FILE_ID);
$criteria->addSelectColumn(CcShowInstancesPeer::SOUNDCLOUD_ID);
} else {
$criteria->addSelectColumn($alias . '.ID');
$criteria->addSelectColumn($alias . '.STARTS');
@ -180,6 +184,7 @@ abstract class BaseCcShowInstancesPeer {
$criteria->addSelectColumn($alias . '.REBROADCAST');
$criteria->addSelectColumn($alias . '.INSTANCE_ID');
$criteria->addSelectColumn($alias . '.FILE_ID');
$criteria->addSelectColumn($alias . '.SOUNDCLOUD_ID');
}
}

View File

@ -14,6 +14,7 @@
* @method CcShowInstancesQuery orderByDbRebroadcast($order = Criteria::ASC) Order by the rebroadcast column
* @method CcShowInstancesQuery orderByDbOriginalShow($order = Criteria::ASC) Order by the instance_id column
* @method CcShowInstancesQuery orderByDbRecordedFile($order = Criteria::ASC) Order by the file_id column
* @method CcShowInstancesQuery orderByDbSoundCloudId($order = Criteria::ASC) Order by the soundcloud_id column
*
* @method CcShowInstancesQuery groupByDbId() Group by the id column
* @method CcShowInstancesQuery groupByDbStarts() Group by the starts column
@ -23,6 +24,7 @@
* @method CcShowInstancesQuery groupByDbRebroadcast() Group by the rebroadcast column
* @method CcShowInstancesQuery groupByDbOriginalShow() Group by the instance_id column
* @method CcShowInstancesQuery groupByDbRecordedFile() Group by the file_id column
* @method CcShowInstancesQuery groupByDbSoundCloudId() Group by the soundcloud_id column
*
* @method CcShowInstancesQuery leftJoin($relation) Adds a LEFT JOIN clause to the query
* @method CcShowInstancesQuery rightJoin($relation) Adds a RIGHT JOIN clause to the query
@ -59,6 +61,7 @@
* @method CcShowInstances findOneByDbRebroadcast(int $rebroadcast) Return the first CcShowInstances filtered by the rebroadcast column
* @method CcShowInstances findOneByDbOriginalShow(int $instance_id) Return the first CcShowInstances filtered by the instance_id column
* @method CcShowInstances findOneByDbRecordedFile(int $file_id) Return the first CcShowInstances filtered by the file_id column
* @method CcShowInstances findOneByDbSoundCloudId(int $soundcloud_id) Return the first CcShowInstances filtered by the soundcloud_id column
*
* @method array findByDbId(int $id) Return CcShowInstances objects filtered by the id column
* @method array findByDbStarts(string $starts) Return CcShowInstances objects filtered by the starts column
@ -68,6 +71,7 @@
* @method array findByDbRebroadcast(int $rebroadcast) Return CcShowInstances objects filtered by the rebroadcast column
* @method array findByDbOriginalShow(int $instance_id) Return CcShowInstances objects filtered by the instance_id column
* @method array findByDbRecordedFile(int $file_id) Return CcShowInstances objects filtered by the file_id column
* @method array findByDbSoundCloudId(int $soundcloud_id) Return CcShowInstances objects filtered by the soundcloud_id column
*
* @package propel.generator.airtime.om
*/
@ -411,6 +415,37 @@ abstract class BaseCcShowInstancesQuery extends ModelCriteria
return $this->addUsingAlias(CcShowInstancesPeer::FILE_ID, $dbRecordedFile, $comparison);
}
/**
* Filter the query on the soundcloud_id column
*
* @param int|array $dbSoundCloudId The value to use as filter.
* Accepts an associative array('min' => $minValue, 'max' => $maxValue)
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return CcShowInstancesQuery The current query, for fluid interface
*/
public function filterByDbSoundCloudId($dbSoundCloudId = null, $comparison = null)
{
if (is_array($dbSoundCloudId)) {
$useMinMax = false;
if (isset($dbSoundCloudId['min'])) {
$this->addUsingAlias(CcShowInstancesPeer::SOUNDCLOUD_ID, $dbSoundCloudId['min'], Criteria::GREATER_EQUAL);
$useMinMax = true;
}
if (isset($dbSoundCloudId['max'])) {
$this->addUsingAlias(CcShowInstancesPeer::SOUNDCLOUD_ID, $dbSoundCloudId['max'], Criteria::LESS_EQUAL);
$useMinMax = true;
}
if ($useMinMax) {
return $this;
}
if (null === $comparison) {
$comparison = Criteria::IN;
}
}
return $this->addUsingAlias(CcShowInstancesPeer::SOUNDCLOUD_ID, $dbSoundCloudId, $comparison);
}
/**
* Filter the query by a related CcShow object
*

View File

@ -0,0 +1,98 @@
<?php
set_include_path(__DIR__.'/..' . PATH_SEPARATOR . get_include_path());
set_include_path(__DIR__.'/../../../library' . PATH_SEPARATOR . get_include_path());
require_once __DIR__.'/../Shows.php';
require_once __DIR__.'/../StoredFile.php';
require_once __DIR__.'/../Playlist.php';
require_once __DIR__.'/../Schedule.php';
require_once __DIR__.'/../Preference.php';
require_once __DIR__.'/../RabbitMq.php';
require_once __DIR__.'/../../configs/conf.php';
require_once __DIR__.'/../../../install/include/AirtimeIni.php';
require_once __DIR__.'/../../../install/include/AirtimeInstall.php';
require_once __DIR__.'/../../../library/propel/runtime/lib/Propel.php';
Propel::init(__DIR__.'/../../configs/airtime-conf.php');
AirtimeInstall::DbConnect(true);
// Create a playlist
$playlist = new Playlist();
$playlist->create("Calendar Load test playlist ".uniqid());
// Add a file
$values = array("filepath" => __DIR__."/test10001.mp3");
$storedFile = StoredFile::Insert($values, false);
$result = $playlist->addAudioClip($storedFile->getId());
// Add a file
$values = array("filepath" => __DIR__."/test10002.mp3");
$storedFile2 = StoredFile::Insert($values, false);
$result = $playlist->addAudioClip($storedFile2->getId());
$result = $playlist->addAudioClip($storedFile2->getId());
echo "Created playlist ".$playlist->getName()." with ID ".$playlist->getId()."\n";
// Create the shows
$data = array();
$currentDate = date("Y\\-m\\-d");
$year = date("Y");
$month = date("m");
$day = date("d");
$nextDay = $currentDate;
#echo $currentDate;
$currentHour = date("H");
$setHour = $currentHour + 1;
$showNumber = 1;
for ($days=1; $days<100; $days=$days+1)
{
// Adding shows until the end of the day
while ($setHour < 24)
{
echo 'Adding show: '.$nextDay. ' '.$setHour.":00\n";
$data['add_show_name'] = 'automated show '.$showNumber;
$data['add_show_start_date'] = $nextDay;
$data['add_show_start_time'] = $setHour.':00';
$showNumber = $showNumber + 1;
$data['add_show_duration'] = '1:00';
$data['add_show_no_end'] = 0;
$data['add_show_repeats'] = 0;
$data['add_show_description'] = 'automated show';
$data['add_show_url'] = 'http://www.OfirGal.com';
$data['add_show_color'] = "";
$data['add_show_background_color'] = "";
$data['add_show_record'] = 0;
$data['add_show_hosts'] ="";
$showId = Show::create($data);
Show::populateShowUntil($showId, "2012-01-01 00:00:00");
// populating the show with a playlist
$show = new ShowInstance($showId);
$show->scheduleShow(array($playlist->getId()));
$setHour = $setHour + 1;
}
// set the next day
$setHour = 0;
if ($day<30) {
$day = $day + 1;
} else {
$day = 1;
if ($month<12)
{
$month = $month + 1;
} else {
$month = 1;
$year = $year + 1;
}
}
$nextDay = $year."-".$month."-".$day;
}

View File

@ -1,7 +1,7 @@
<div id="schedule-add-show" class="tabs ui-widget ui-widget-content block-shadow alpha-block padded">
<div class="button-bar">
<a href="#" id="add-show-close" class="icon-link"><span class="ui-icon ui-icon-circle-close"></span>Close</a>
<button aria-disabled="false" role="button" id="add-show-submit" class="right-floated ui-button ui-widget ui-state-default ui-button-text-icon-primary">
<button aria-disabled="false" role="button" class="add-show-submit right-floated ui-button ui-widget ui-state-default ui-button-text-icon-primary">
<span class="ui-icon ui-icon-plusthick"></span>
<span class="ui-button-text">Add this show</span>
</button>
@ -30,5 +30,11 @@
<div id="schedule-show-style" class="collapsible-content">
<?php echo $this->style; ?>
</div>
<div class="button-bar">
<button aria-disabled="false" role="button" class="add-show-submit right-floated ui-button ui-widget ui-state-default ui-button-text-icon-primary">
<span class="ui-icon ui-icon-plusthick"></span>
<span class="ui-button-text">Add this show</span>
</button>
</div>
</div>

View File

@ -1,4 +1,5 @@
<div id="show_content_dialog">
<div><?php echo $this->additionalShowInfo; ?></div>
<table width="100%" border="0" cellspacing="0" cellpadding="0" class="datatable">
<tr>
<th>Start</th>

View File

@ -4,6 +4,18 @@ dbname = airtime
dbuser = airtime
dbpass = airtime
[rabbitmq]
host = 127.0.0.1
port = 5672
user = guest
password = guest
vhost = /
[general]
api_key = AAA
webServerUser = www-data
baseFilesDir = x
[soundcloud]
connection_retries = 3
time_between_retries = 60

View File

@ -24,13 +24,6 @@
<index-column name="token"/>
</index>
</table>
<table name="cc_backup" phpName="CcBackup">
<column name="token" phpName="Token" type="VARCHAR" size="64" primaryKey="true" required="true"/>
<column name="sessionid" phpName="Sessionid" type="VARCHAR" size="64" required="true"/>
<column name="status" phpName="Status" type="VARCHAR" size="32" required="true"/>
<column name="fromtime" phpName="Fromtime" type="TIMESTAMP" required="true"/>
<column name="totime" phpName="Totime" type="TIMESTAMP" required="true"/>
</table>
<table name="cc_files" phpName="CcFiles">
<column name="id" phpName="DbId" type="INTEGER" primaryKey="true" autoIncrement="true" required="true"/>
<column name="gunid" phpName="DbGunid" type="char" size="32" required="true"/>
@ -138,6 +131,7 @@
<column name="rebroadcast" phpName="DbRebroadcast" type="TINYINT" required="false" defaultValue="0"/>
<column name="instance_id" phpName="DbOriginalShow" type="INTEGER" required="false"/>
<column name="file_id" phpName="DbRecordedFile" type="INTEGER" required="false"/>
<column name="soundcloud_id" phpName="DbSoundCloudId" type="INTEGER" required="false"/>
<foreign-key foreignTable="cc_show" name="cc_show_fkey" onDelete="CASCADE">
<reference local="show_id" foreign="id"/>
</foreign-key>
@ -158,7 +152,7 @@
<column name="repeat_type" phpName="DbRepeatType" type="TINYINT" required="true"/>
<column name="next_pop_date" phpName="DbNextPopDate" type="DATE" required="false"/>
<column name="show_id" phpName="DbShowId" type="INTEGER" required="true"/>
<column name="record" phpName="DbRecord" type="TINYINT" required="false"/>
<column name="record" phpName="DbRecord" type="TINYINT" required="false" defaultValue="0"/>
<foreign-key foreignTable="cc_show" name="cc_show_fkey" onDelete="CASCADE">
<reference local="show_id" foreign="id"/>
</foreign-key>
@ -295,45 +289,4 @@
<unique-column name="login"/>
</unique>
</table>
<table name="cc_trans" phpName="CcTrans">
<column name="id" phpName="Id" type="INTEGER" primaryKey="true" autoIncrement="true" required="true"/>
<column name="trtok" phpName="Trtok" type="CHAR" size="16" required="true"/>
<column name="direction" phpName="Direction" type="VARCHAR" size="128" required="true"/>
<column name="state" phpName="State" type="VARCHAR" size="128" required="true"/>
<column name="trtype" phpName="Trtype" type="VARCHAR" size="128" required="true"/>
<column name="lock" phpName="Lock" type="CHAR" size="1" required="true" defaultValue="N"/>
<column name="target" phpName="Target" type="VARCHAR" size="255" required="false" defaultValue="NULL"/>
<column name="rtrtok" phpName="Rtrtok" type="CHAR" size="16" required="false" defaultValue="NULL"/>
<column name="mdtrtok" phpName="Mdtrtok" type="CHAR" size="16" required="false"/>
<column name="gunid" phpName="Gunid" type="char" size="32" required="false"/>
<column name="pdtoken" phpName="Pdtoken" type="BIGINT" required="false"/>
<column name="url" phpName="Url" type="VARCHAR" size="255" required="false"/>
<column name="localfile" phpName="Localfile" type="VARCHAR" size="255" required="false"/>
<column name="fname" phpName="Fname" type="VARCHAR" size="255" required="false"/>
<column name="title" phpName="Title" type="VARCHAR" size="255" required="false"/>
<column name="expectedsum" phpName="Expectedsum" type="CHAR" size="32" required="false"/>
<column name="realsum" phpName="Realsum" type="CHAR" size="32" required="false"/>
<column name="expectedsize" phpName="Expectedsize" type="INTEGER" required="false"/>
<column name="realsize" phpName="Realsize" type="INTEGER" required="false"/>
<column name="uid" phpName="Uid" type="INTEGER" required="false"/>
<column name="errmsg" phpName="Errmsg" type="VARCHAR" size="255" required="false"/>
<column name="jobpid" phpName="Jobpid" type="INTEGER" required="false"/>
<column name="start" phpName="Start" type="TIMESTAMP" required="false"/>
<column name="ts" phpName="Ts" type="TIMESTAMP" required="false"/>
<index name="cc_trans_gunid_idx">
<index-column name="gunid"/>
</index>
<unique name="cc_trans_id_idx">
<unique-column name="id"/>
</unique>
<index name="cc_trans_state_idx">
<index-column name="state"/>
</index>
<unique name="cc_trans_token_idx">
<unique-column name="pdtoken"/>
</unique>
<unique name="cc_trans_trtok_idx">
<unique-column name="trtok"/>
</unique>
</table>
</database>

View File

@ -30,27 +30,6 @@ CREATE INDEX "cc_access_parent_idx" ON "cc_access" ("parent");
CREATE INDEX "cc_access_token_idx" ON "cc_access" ("token");
-----------------------------------------------------------------------------
-- cc_backup
-----------------------------------------------------------------------------
DROP TABLE "cc_backup" CASCADE;
CREATE TABLE "cc_backup"
(
"token" VARCHAR(64) NOT NULL,
"sessionid" VARCHAR(64) NOT NULL,
"status" VARCHAR(32) NOT NULL,
"fromtime" TIMESTAMP NOT NULL,
"totime" TIMESTAMP NOT NULL,
PRIMARY KEY ("token")
);
COMMENT ON TABLE "cc_backup" IS '';
SET search_path TO public;
-----------------------------------------------------------------------------
-- cc_files
-----------------------------------------------------------------------------
@ -190,6 +169,7 @@ CREATE TABLE "cc_show_instances"
"rebroadcast" INT2 default 0,
"instance_id" INTEGER,
"file_id" INTEGER,
"soundcloud_id" INTEGER,
PRIMARY KEY ("id")
);
@ -215,7 +195,7 @@ CREATE TABLE "cc_show_days"
"repeat_type" INT2 NOT NULL,
"next_pop_date" DATE,
"show_id" INTEGER NOT NULL,
"record" INT2,
"record" INT2 default 0,
PRIMARY KEY ("id")
);
@ -440,53 +420,6 @@ COMMENT ON TABLE "cc_subjs" IS '';
SET search_path TO public;
-----------------------------------------------------------------------------
-- cc_trans
-----------------------------------------------------------------------------
DROP TABLE "cc_trans" CASCADE;
CREATE TABLE "cc_trans"
(
"id" serial NOT NULL,
"trtok" CHAR(16) NOT NULL,
"direction" VARCHAR(128) NOT NULL,
"state" VARCHAR(128) NOT NULL,
"trtype" VARCHAR(128) NOT NULL,
"lock" CHAR(1) default 'N' NOT NULL,
"target" VARCHAR(255),
"rtrtok" CHAR(16),
"mdtrtok" CHAR(16),
"gunid" CHAR(32),
"pdtoken" INT8,
"url" VARCHAR(255),
"localfile" VARCHAR(255),
"fname" VARCHAR(255),
"title" VARCHAR(255),
"expectedsum" CHAR(32),
"realsum" CHAR(32),
"expectedsize" INTEGER,
"realsize" INTEGER,
"uid" INTEGER,
"errmsg" VARCHAR(255),
"jobpid" INTEGER,
"start" TIMESTAMP,
"ts" TIMESTAMP,
PRIMARY KEY ("id"),
CONSTRAINT "cc_trans_id_idx" UNIQUE ("id"),
CONSTRAINT "cc_trans_token_idx" UNIQUE ("pdtoken"),
CONSTRAINT "cc_trans_trtok_idx" UNIQUE ("trtok")
);
COMMENT ON TABLE "cc_trans" IS '';
SET search_path TO public;
CREATE INDEX "cc_trans_gunid_idx" ON "cc_trans" ("gunid");
CREATE INDEX "cc_trans_state_idx" ON "cc_trans" ("state");
ALTER TABLE "cc_access" ADD CONSTRAINT "cc_access_owner_fkey" FOREIGN KEY ("owner") REFERENCES "cc_subjs" ("id");
ALTER TABLE "cc_files" ADD CONSTRAINT "cc_files_editedby_fkey" FOREIGN KEY ("editedby") REFERENCES "cc_subjs" ("id");

View File

@ -1,3 +1,5 @@
#!/bin/sh
echo
echo "This will tail the pypo-liquidsoap log file."
echo "Type in password for pypo user (default password is 'pypo'):"
su -l pypo -c "tail -F /etc/service/pypo-liquidsoap/log/main/current"

View File

@ -1,3 +1,7 @@
#!/bin/sh
echo
echo "This will tail the recorder log file."
echo "Type in password for pypo user (default password is 'pypo'):"
su -l pypo -c "tail -F /etc/service/recorder/log/main/current"

View File

@ -1,3 +1,7 @@
#!/bin/sh
echo
echo "This will output the pypo log file."
echo "Type in password for pypo user (default password is 'pypo'):"
su -l pypo -c "less /etc/service/pypo/log/main/current"

View File

@ -1,3 +1,7 @@
#!/bin/sh
echo
echo "This will tail the pypo log file."
echo "Type in password for pypo user (default password is 'pypo'):"
su -l pypo -c "tail -F /etc/service/pypo/log/main/current"

View File

@ -1,21 +0,0 @@
<?php
namespace DoctrineMigrations;
use Doctrine\DBAL\Migrations\AbstractMigration,
Doctrine\DBAL\Schema\Schema;
class Version20110308003959 extends AbstractMigration
{
public function up(Schema $schema)
{
$table = $schema->getTable("cc_show_instances");
$table->addColumn("record", "boolean", array( 'notnull' => 0, 'default' => 0));
}
public function down(Schema $schema)
{
$table = $schema->getTable("cc_show_instances");
$table->dropColumn("record");
}
}

View File

@ -0,0 +1,96 @@
<?php
namespace DoctrineMigrations;
use Doctrine\DBAL\Migrations\AbstractMigration,
Doctrine\DBAL\Schema\Schema,
Doctrine\DBAL\Schema\Table,
Doctrine\DBAL\Schema\Column,
Doctrine\DBAL\Types\Type;
class Version20110331111708 extends AbstractMigration
{
public function up(Schema $schema)
{
//start cc_show_instances modifications
$show_instances_table = $schema->getTable('cc_show_instances');
$show_instances_table->addColumn('record', 'smallint', array('notnull' => 0, 'default' => 0));
$show_instances_table->addColumn('rebroadcast', 'smallint', array('notnull' => 0, 'default' => 0));
$show_instances_table->addColumn('instance_id', 'integer', array('notnull' => 0));
$show_instances_table->addColumn('file_id', 'integer', array('notnull' => 0));
$show_instances_table->addColumn('soundcloud_id', 'integer', array('notnull' => 0));
$show_instances_table->addNamedForeignKeyConstraint('cc_original_show_instance_fkey', $show_instances_table, array('instance_id'), array('id'), array('onDelete' => 'CASCADE'));
$files_table = $schema->getTable('cc_files');
$show_instances_table->addNamedForeignKeyConstraint('cc_recorded_file_fkey', $files_table, array('file_id'), array('id'), array('onDelete' => 'CASCADE'));
//end cc_show_instances modifications
//start cc_show_days modifications
$show_days_table = $schema->getTable('cc_show_days');
$show_days_table->addColumn('record', 'smallint', array( 'notnull' => 0, 'default' => 0));
//end cc_show_days modifications
//start cc_show modifications
$show_table = $schema->getTable('cc_show');
$show_table->addColumn('url', 'string', array('notnull' => 0, 'length' => 255));
//end cc_show modifications
//start cc_schedule modifications
$schedule_table = $schema->getTable('cc_schedule');
$playlist_id_col = $schedule_table->getColumn('playlist_id');
$playlist_id_col->setNotnull(false);
//end cc_schedule modifications
//create cc_show_rebroadcast table
$cc_show_rebroadcast_table = $schema->createTable('cc_show_rebroadcast');
$cc_show_rebroadcast_table->addColumn('id', 'integer', array('unsigned' => true, 'autoincrement' => true));
$cc_show_rebroadcast_table->addColumn('day_offset', 'string', array('length' => 255));
$cc_show_rebroadcast_table->addColumn('start_time', 'datetime', array('notnull' => 1));
$cc_show_rebroadcast_table->addColumn('show_id', 'integer', array('notnull' => 1));
$cc_show_rebroadcast_table->setPrimaryKey(array('id'));
//end create cc_show_rebroadcast table
}
public function down(Schema $schema)
{
//start cc_show_instances modifications
$show_instances_table = $schema->getTable('cc_show_instances');
$show_instances_table->dropColumn('record');
$show_instances_table->dropColumn('rebroadcast');
$show_instances_table->dropColumn('instance_id');
$show_instances_table->dropColumn('file_id');
$show_instances_table->dropColumn('soundcloud_id');
//end cc_show_instances modifications
//start cc_show_days modifications
$show_days_table = $schema->getTable('cc_show_days');
$show_days_table->dropColumn('record');
//end cc_show_days modifications
//start cc_show modifications
$show_table = $schema->getTable('cc_show');
$show_table->dropColumn('url');
//end cc_show modifications
//start cc_schedule modifications
$schedule_table = $schema->getTable('cc_schedule');
$playlist_id_col = $schedule_table->getColumn('playlist_id');
$playlist_id_col->setNotnull(true);
//end cc_schedule modifications
//drop cc_show_rebroadcast table
$schema->dropTable('cc_show_rebroadcast');
//end drop cc_show_rebroadcast table
}
}

View File

@ -5,56 +5,47 @@
* @license http://www.gnu.org/licenses/gpl.txt
*/
// Do not allow remote execution
$arr = array_diff_assoc($_SERVER, $_ENV);
if (isset($arr["DOCUMENT_ROOT"]) && ($arr["DOCUMENT_ROOT"] != "") ) {
header("HTTP/1.1 400");
header("Content-type: text/plain; charset=UTF-8");
echo "400 Not executable\r\n";
exit(1);
}
require_once(dirname(__FILE__).'/../application/configs/conf.php');
require_once(dirname(__FILE__).'/installInit.php');
echo "******************************** Install Begin *********************************".PHP_EOL;
AirtimeInstall::ExitIfNotRoot();
AirtimeInstall::CreateApiKey();
AirtimeInstall::UpdateIniValue('../build/build.properties', 'project.home', realpath(__dir__.'/../'));
require_once(dirname(__FILE__).'/include/AirtimeIni.php');
AirtimeIni::ExitIfNotRoot();
AirtimeIni::CreateIniFile();
AirtimeIni::UpdateIniFiles();
require_once(dirname(__FILE__).'/../application/configs/conf.php');
require_once(dirname(__FILE__).'/include/AirtimeInstall.php');
echo PHP_EOL."*** Installing Airtime ".AIRTIME_VERSION." ***".PHP_EOL;
echo PHP_EOL."*** Database Installation ***".PHP_EOL;
echo "* Creating Airtime Database User".PHP_EOL;
echo "* Creating Airtime database user".PHP_EOL;
AirtimeInstall::CreateDatabaseUser();
echo "* Creating Airtime Database".PHP_EOL;
echo "* Creating Airtime database".PHP_EOL;
AirtimeInstall::CreateDatabase();
AirtimeInstall::DbConnect(true);
echo "* Install Postgresql Scripting Language".PHP_EOL;
echo "* Installing Postgresql scripting language".PHP_EOL;
AirtimeInstall::InstallPostgresScriptingLanguage();
echo "* Creating Database Tables".PHP_EOL;
echo "* Creating database tables".PHP_EOL;
AirtimeInstall::CreateDatabaseTables();
echo "* Storage Directory Setup".PHP_EOL;
echo "* Storage directory setup".PHP_EOL;
AirtimeInstall::SetupStorageDirectory($CC_CONFIG);
echo "* Setting Dir Permissions".PHP_EOL;
echo "* Giving Apache permission to access the storage directory".PHP_EOL;
AirtimeInstall::ChangeDirOwnerToWebserver($CC_CONFIG["storageDir"]);
echo "* Creating /usr/bin symlinks".PHP_EOL;
AirtimeInstall::CreateSymlinks($CC_CONFIG["storageDir"]);
echo "* Importing Sample Audio Clips".PHP_EOL;
echo "* Importing sample audio clips".PHP_EOL;
system(__DIR__."/../utils/airtime-import --copy ../audio_samples/ > /dev/null");
echo "* Python eggs Setup".PHP_EOL;
AirtimeInstall::SetUpPythonEggs();
echo PHP_EOL."*** Pypo Installation ***".PHP_EOL;
system("python ".__DIR__."/../python_apps/pypo/install/pypo-install.py");

View File

@ -5,23 +5,18 @@
* @license http://www.gnu.org/licenses/gpl.txt
*/
// Do not allow remote execution.
$arr = array_diff_assoc($_SERVER, $_ENV);
if (isset($arr["DOCUMENT_ROOT"]) && ($arr["DOCUMENT_ROOT"] != "") ) {
header("HTTP/1.1 400");
header("Content-type: text/plain; charset=UTF-8");
echo "400 Not executable".PHP_EOL;
exit;
}
require_once(dirname(__FILE__).'/include/AirtimeIni.php');
// Need to check that we are superuser before running this.
AirtimeIni::ExitIfNotRoot();
require_once(dirname(__FILE__).'/../application/configs/conf.php');
require_once(dirname(__FILE__).'/installInit.php');
require_once(dirname(__FILE__).'/include/AirtimeInstall.php');
// Need to check that we are superuser before running this.
AirtimeInstall::ExitIfNotRoot();
AirtimeInstall::RemoveSymlinks();
echo "Uninstalling Airtime ".AIRTIME_VERSION.PHP_EOL;
echo "******************************* Uninstall Begin ********************************".PHP_EOL;
//------------------------------------------------------------------------
// Delete the database
@ -80,7 +75,7 @@ if ($results == 0) {
// Delete files
//------------------------------------------------------------------------
AirtimeInstall::DeleteFilesRecursive($CC_CONFIG['storageDir']);
AirtimeIni::RemoveIniFiles();
$command = "python ".__DIR__."/../python_apps/pypo/install/pypo-uninstall.py";
system($command);

View File

@ -6,27 +6,23 @@
* @license http://www.gnu.org/licenses/gpl.txt
*/
// Do not allow remote execution
$arr = array_diff_assoc($_SERVER, $_ENV);
if (isset($arr["DOCUMENT_ROOT"]) && ($arr["DOCUMENT_ROOT"] != "") ) {
header("HTTP/1.1 400");
header("Content-type: text/plain; charset=UTF-8");
echo "400 Not executable\r\n";
exit(1);
}
require_once(dirname(__FILE__).'/include/AirtimeIni.php');
require_once(dirname(__FILE__).'/include/AirtimeInstall.php');
require_once(dirname(__FILE__).'/installInit.php');
AirtimeInstall::ExitIfNotRoot();
AirtimeIni::ExitIfNotRoot();
echo "******************************** Update Begin *********************************".PHP_EOL;
AirtimeInstall::UpdateIniValue('../build/build.properties', 'project.home', realpath(__dir__.'/../'));
AirtimeIni::CreateIniFile();
AirtimeIni::UpdateIniFiles();
echo PHP_EOL."*** Updating Database Tables ***".PHP_EOL;
AirtimeInstall::MigrateTables(__DIR__);
echo PHP_EOL."*** Updating Pypo ***".PHP_EOL;
system("python ".__DIR__."/../pypo/install/pypo-install.py");
system("python ".__DIR__."/../python_apps/pypo/install/pypo-install.py");
echo PHP_EOL."*** Recorder Installation ***".PHP_EOL;
system("python ".__DIR__."/../python_apps/show-recorder/install/recorder-install.py");
echo "******************************* Update Complete *******************************".PHP_EOL;

View File

@ -0,0 +1,169 @@
<?php
/**
* @package Newscoop
* @subpackage Subscriptions
* @copyright 2011 Sourcefabric o.p.s.
* @license http://www.gnu.org/licenses/gpl-3.0.txt
*/
// Do not allow remote execution
$arr = array_diff_assoc($_SERVER, $_ENV);
if (isset($arr["DOCUMENT_ROOT"]) && ($arr["DOCUMENT_ROOT"] != "") ) {
header("HTTP/1.1 400");
header("Content-type: text/plain; charset=UTF-8");
echo "400 Not executable\r\n";
exit(1);
}
//make sure user has Postgresql PHP extension installed.
if (!function_exists('pg_connect')) {
trigger_error("PostgreSQL PHP extension required and not found.", E_USER_ERROR);
exit(2);
}
class AirtimeIni{
/**
* This function creates the /etc/airtime configuration folder
* and copies the default config files to it.
*/
static function CreateIniFile()
{
if (!file_exists("/etc/airtime/")){
if (!mkdir("/etc/airtime/", 0755, true)){
echo "Could not create /etc/airtime/ directory. Exiting.";
exit(1);
}
}
if (!copy(__DIR__."/../../build/airtime.conf", "/etc/airtime/airtime.conf")){
echo "Could not copy airtime.conf to /etc/airtime/. Exiting.";
exit(1);
}
if (!copy(__DIR__."/../../python_apps/pypo/pypo.cfg", "/etc/airtime/pypo.cfg")){
echo "Could not copy pypo.cfg to /etc/airtime/. Exiting.";
exit(1);
}
if (!copy(__DIR__."/../../python_apps/show-recorder/recorder.cfg", "/etc/airtime/recorder.cfg")){
echo "Could not copy recorder.cfg to /etc/airtime/. Exiting.";
exit(1);
}
if (!copy(__DIR__."/../../python_apps/pypo/scripts/liquidsoap.cfg", "/etc/airtime/liquidsoap.cfg")){
echo "Could not copy liquidsoap.cfg to /etc/airtime/. Exiting.";
exit(1);
}
}
/**
* This function removes /etc/airtime and the configuration
* files present within it.
*/
static function RemoveIniFiles()
{
if (file_exists("/etc/airtime/airtime.conf")){
unlink("/etc/airtime/airtime.conf");
}
if (file_exists("/etc/airtime/pypo.cfg")){
unlink("/etc/airtime/pypo.cfg");
}
if (file_exists("/etc/airtime/recorder.cfg")){
unlink("/etc/airtime/recorder.cfg");
}
if (file_exists("/etc/airtime/liquidsoap.cfg")){
unlink("/etc/airtime/liquidsoap.cfg");
}
if (file_exists("etc/airtime")){
rmdir("/etc/airtime/");
}
}
/**
* Ensures that the user is running this PHP script with root
* permissions. If not running with root permissions, causes the
* script to exit.
*/
static function ExitIfNotRoot()
{
// Need to check that we are superuser before running this.
if(exec("whoami") != "root"){
echo "Must be root user.\n";
exit(1);
}
}
/**
* This function generates a random string.
*
* The random string uses two parameters: $p_len and $p_chars. These
* parameters do not need to be provided, in which case defaults are
* used.
*
* @param string $p_len
* How long should the generated string be.
* @param string $p_chars
* String containing chars that should be used for generating.
* @return string
* The generated random string.
*/
static function GenerateRandomString($p_len=20, $p_chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
{
$string = '';
for ($i = 0; $i < $p_len; $i++)
{
$pos = mt_rand(0, strlen($p_chars)-1);
$string .= $p_chars{$pos};
}
return $string;
}
/**
* This function updates an INI style config file.
*
* A property and the value the property should be changed to are
* supplied. If the property is not found, then no changes are made.
*
* @param string $p_filename
* The path the to the file.
* @param string $p_property
* The property to look for in order to change its value.
* @param string $p_value
* The value the property should be changed to.
*
*/
static function UpdateIniValue($p_filename, $p_property, $p_value)
{
$lines = file($p_filename);
$n=count($lines);
for ($i=0; $i<$n; $i++) {
if (strlen($lines[$i]) > strlen($p_property))
if ($p_property == substr($lines[$i], 0, strlen($p_property))){
$lines[$i] = "$p_property = $p_value\n";
}
}
$fp=fopen($p_filename, 'w');
for($i=0; $i<$n; $i++){
fwrite($fp, $lines[$i]);
}
fclose($fp);
}
/**
* After the configuration files have been copied to /etc/airtime,
* this function will update them to values unique to this
* particular installation.
*/
static function UpdateIniFiles()
{
$api_key = AirtimeIni::GenerateRandomString();
AirtimeIni::UpdateIniValue('/etc/airtime/airtime.conf', 'api_key', $api_key);
AirtimeIni::UpdateIniValue('/etc/airtime/airtime.conf', 'baseFilesDir', realpath(__DIR__.'/../../').'/files');
AirtimeIni::UpdateIniValue('/etc/airtime/pypo.cfg', 'api_key', "'$api_key'");
AirtimeIni::UpdateIniValue('/etc/airtime/recorder.cfg', 'api_key', "'$api_key'");
AirtimeIni::UpdateIniValue(__DIR__.'/../../build/build.properties', 'project.home', realpath(__dir__.'/../../'));
}
}

View File

@ -1,11 +1,7 @@
<?php
if (!function_exists('pg_connect')) {
trigger_error("PostgreSQL PHP extension required and not found.", E_USER_ERROR);
exit(2);
}
require_once(dirname(__FILE__).'/../library/pear/DB.php');
require_once(dirname(__FILE__).'/../application/configs/conf.php');
require_once(dirname(__FILE__).'/../../library/pear/DB.php');
require_once(dirname(__FILE__).'/../../application/configs/conf.php');
class AirtimeInstall {
@ -64,52 +60,6 @@ class AirtimeInstall {
chmod($filePath, $fileperms);
}
private static function GenerateRandomString($len=20, $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
{
$string = '';
for ($i = 0; $i < $len; $i++)
{
$pos = mt_rand(0, strlen($chars)-1);
$string .= $chars{$pos};
}
return $string;
}
public static function CreateApiKey()
{
$api_key = AirtimeInstall::GenerateRandomString();
AirtimeInstall::UpdateIniValue(__DIR__.'/../build/airtime.conf', 'api_key', $api_key);
AirtimeInstall::UpdateIniValue(__DIR__.'/../python_apps/pypo/config.cfg', 'api_key', "'$api_key'");
AirtimeInstall::UpdateIniValue(__DIR__.'/../python_apps/show-recorder/config.cfg', 'api_key', "'$api_key'");
}
public static function ExitIfNotRoot()
{
// Need to check that we are superuser before running this.
if(exec("whoami") != "root"){
echo "Must be root user.\n";
exit(1);
}
}
public static function UpdateIniValue($filename, $property, $value)
{
$lines = file($filename);
$n=count($lines);
for ($i=0; $i<$n; $i++) {
if (strlen($lines[$i]) > strlen($property))
if ($property == substr($lines[$i], 0, strlen($property))){
$lines[$i] = "$property = $value\n";
}
}
$fp=fopen($filename, 'w');
for($i=0; $i<$n; $i++){
fwrite($fp, $lines[$i]);
}
fclose($fp);
}
public static function SetupStorageDirectory($CC_CONFIG)
{
global $CC_CONFIG, $CC_DBC;
@ -145,9 +95,15 @@ class AirtimeInstall {
@exec($command, $output, $results);
if ($results == 0) {
echo "* User {$CC_CONFIG['dsn']['username']} created.".PHP_EOL;
echo "* Database user '{$CC_CONFIG['dsn']['username']}' created.".PHP_EOL;
} else {
echo "* Could not create user {$CC_CONFIG['dsn']['username']}: $output".PHP_EOL;
if (count($output) > 0) {
echo "* Could not create user '{$CC_CONFIG['dsn']['username']}': ".PHP_EOL;
echo implode(PHP_EOL, $output);
}
else {
echo "* Database user '{$CC_CONFIG['dsn']['username']}' already exists.".PHP_EOL;
}
}
}
@ -160,7 +116,13 @@ class AirtimeInstall {
if ($results == 0) {
echo "* Database '{$CC_CONFIG['dsn']['database']}' created.".PHP_EOL;
} else {
echo "* Could not create database '{$CC_CONFIG['dsn']['database']}': $output".PHP_EOL;
if (count($output) > 0) {
echo "* Could not create database '{$CC_CONFIG['dsn']['database']}': ".PHP_EOL;
echo implode(PHP_EOL, $output);
}
else {
echo "* Database '{$CC_CONFIG['dsn']['database']}' already exists.".PHP_EOL;
}
}
}
@ -181,7 +143,7 @@ class AirtimeInstall {
public static function CreateDatabaseTables()
{
// Put Propel sql files in Database
$command = __DIR__."/../library/propel/generator/bin/propel-gen ../build/ insert-sql 2>propel-error.log";
$command = __DIR__."/../../library/propel/generator/bin/propel-gen ../build/ insert-sql 2>propel-error.log";
@exec($command, $output, $results);
}
@ -191,13 +153,6 @@ class AirtimeInstall {
system($command);
}
public static function SetUpPythonEggs()
{
//install poster streaming upload
$command = "sudo easy_install poster";
@exec($command);
}
public static function DeleteFilesRecursive($p_path)
{
$command = "rm -rf $p_path";
@ -207,10 +162,10 @@ class AirtimeInstall {
public static function CreateSymlinks(){
AirtimeInstall::RemoveSymlinks();
$dir = realpath(__DIR__."/../utils/airtime-import");
$dir = realpath(__DIR__."/../../utils/airtime-import");
exec("ln -s $dir /usr/bin/airtime-import");
$dir = realpath(__DIR__."/../utils/airtime-clean-storage");
$dir = realpath(__DIR__."/../../utils/airtime-clean-storage");
exec("ln -s $dir /usr/bin/airtime-clean-storage");
}
@ -218,6 +173,4 @@ class AirtimeInstall {
exec("rm -f /usr/bin/airtime-import");
exec("rm -f /usr/bin/airtime-clean-storage");
}
}

View File

@ -4,8 +4,10 @@
var defaults = {
updatePeriod: 20, //seconds
sourceDomain: "http://localhost/", //where to get show status from
text: {onAirToday:"On air today"}
};
var options = $.extend(defaults, options);
options.sourceDomain = addEndingBackslash(options.sourceDomain);
return this.each(function() {
var obj = $(this);
@ -29,7 +31,7 @@
}
tableString = "";
tableString += "<h3>On air today</h3>";
tableString += "<h3>"+options.text.onAirToday+"</h3>";
tableString += "<table width='100%' border='0' cellspacing='0' cellpadding='0' class='widget widget no-playing-list small'>"+
"<tbody>";
@ -40,7 +42,7 @@
tableString +=
"<tr>" +
"<td class='time'>"+shows[i].getRange()+"</td>" +
"<td><a href='#'>"+shows[i].getName()+"</a> <a href='#' class='listen'>Listen</a></td>" +
"<td><a href='#'>"+shows[i].getName()+"</a></td>" +
"</tr>";
}
@ -54,11 +56,14 @@
updateWidget();
}
function airtimeScheduleJsonpError(jqXHR, textStatus, errorThrown){
}
function getServerData(){
$.ajax({ url: options.sourceDomain + "api/live-info/", dataType:"jsonp", success:function(data){
processData(data);
}, error:function(jqXHR, textStatus, errorThrown){}});
setTimeout(getServerData, defaults.updatePeriod*1000);
}, error:airtimeScheduleJsonpError});
setTimeout(getServerData, options.updatePeriod*1000);
}
});
};
@ -71,9 +76,11 @@
var defaults = {
updatePeriod: 5, //seconds
sourceDomain: "http://localhost/", //where to get show status from
audioStreamSource: "" //where to get audio stream from
audioStreamSource: "http://localhost:8000/airtime.mp3", //where to get audio stream from
text: {listenLive:"Listen WADR Live", onAirNow:"On Air Now", offline:"Offline", current:"Current", next:"Next"}
};
var options = $.extend(defaults, options);
options.sourceDomain = addEndingBackslash(options.sourceDomain);
return this.each(function() {
var obj = $(this);
@ -84,7 +91,7 @@
var currentShow = sd.getCurrentShow();
var nextShows = sd.getNextShows();
var showStatus = "Offline";
var showStatus = options.text.offline;
var currentShowName = "";
var timeElapsed = "";
var timeRemaining = "";
@ -93,7 +100,7 @@
var nextShowRange = "";
if (currentShow.length > 0){
showStatus = "On Air Now";
showStatus = options.text.onAirNow;
currentShowName = currentShow[0].getName();
timeElapsed = sd.getShowTimeElapsed(currentShow[0]);
@ -106,14 +113,14 @@
}
obj.empty();
obj.append("<a id='listenWadrLive'><span>Listen WADR Live</span></a>");
obj.append("<a id='listenWadrLive' href='"+options.audioStreamSource+"'><span>"+options.text.listenLive+"</span></a>");
obj.append("<h4>"+showStatus+" &gt;&gt;</h4>");
obj.append("<ul class='widget no-playing-bar'>" +
"<li class='current'>Current: "+currentShowName+
"<li class='current'>"+options.text.current+": "+currentShowName+
"<span id='time-elapsed' class='time-elapsed'>"+timeElapsed+"</span>" +
"<span id='time-remaining' class='time-remaining'>"+timeRemaining+"</span>"+
"</li>" +
"<li class='next'>Next: "+nextShowName+"<span>"+nextShowRange+"</span></li>" +
"<li class='next'>"+options.text.next+": "+nextShowName+"<span>"+nextShowRange+"</span></li>" +
"</ul>");
//refresh the UI to update the elapsed/remaining time
@ -125,16 +132,121 @@
updateWidget();
}
function airtimeScheduleJsonpError(jqXHR, textStatus, errorThrown){
}
function getServerData(){
$.ajax({ url: options.sourceDomain + "api/live-info/", dataType:"jsonp", success:function(data){
processData(data);
}, error:function(jqXHR, textStatus, errorThrown){}});
setTimeout(getServerData, defaults.updatePeriod*1000);
}, error:airtimeScheduleJsonpError});
setTimeout(getServerData, options.updatePeriod*1000);
}
});
};
})(jQuery);
(function($){
$.fn.airtimeWeekSchedule = function(options) {
var defaults = {
sourceDomain: "http://localhost/", //where to get show status from
updatePeriod: 600,
dowText: {monday:"Monday", tuesday:"Tuesday", wednesday:"Wednesday", thursday:"Thursday", friday:"Friday", saturday:"Saturday", sunday:"Sunday"},
miscText: {time:"Time", programName:"Program Name", details:"Details", readMore:"Read More"}
};
var options = $.extend(defaults, options);
options.sourceDomain = addEndingBackslash(options.sourceDomain);
return this.each(function() {
var obj = $(this);
obj.empty();
obj.attr("class", "ui-tabs");
var dow = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"];
var html = '<ul>';
for (var i=0; i<dow.length; i++){
html += '<li><a href="#'+dow[i]+'">'+options.dowText[dow[i]]+'</a></li>';
}
html += '</ul>';
for (var i=0; i<dow.length; i++){
html += '<div id="'+dow[i]+'" class="ui-tabs-hide"></div>'
}
obj.append(html);
getServerData();
function updateWidget(data){
for (var i=0; i<dow.length; i++){
var html =
'<table class="widget widget no-playing-list">'+
'<colgroup>'+
'<col width="150" />'+
'<col width="350" />'+
'<col width="240" />'+
'</colgroup>'+
'<thead>'+
'<tr>'+
'<td>'+options.miscText.time+'</td>'+
'<td>'+options.miscText.programName+'</td>'+
'<td>'+options.miscText.details+'</td>'+
'</tr>'+
'</thead>'+
'<tfoot>'+
'<tr>'+
'<td></td>'+
'</tr>'+
'</tfoot>'+
'<tbody>';
var daySchedule = data[dow[i]];
for (var j=0; j<daySchedule.length; j++){
var url = daySchedule[j].url;
html +=
'<tr>'+
'<td>'+getTime(daySchedule[j].show_starts)+ " - " + getTime(daySchedule[j].show_ends)+'</td>'+
'<td>'+
'<h4>'+daySchedule[j].show_name+'</h4>'+
'</td>'+
'<td>'+
'<ul>'+
'<li>'+(url.length > 0 ? '<a href="'+url+'">'+options.miscText.readMore+'</a>':'')+'</li>'+
'</ul>'+
'</td>'+
'</tr>';
}
html +=
'</tbody>'+
'</table>';
$("#"+dow[i]).empty();
$("#"+dow[i]).append(html);
}
}
function processData(data){
updateWidget(data);
}
function airtimeScheduleJsonpError(jqXHR, textStatus, errorThrown){
}
function getServerData(){
$.ajax({ url: options.sourceDomain + "api/week-info/", dataType:"jsonp", success:function(data){
processData(data);
}, error:airtimeScheduleJsonpError});
setTimeout(getServerData, options.updatePeriod*1000);
}
});
};
})(jQuery);
function addEndingBackslash(str){
if (str.charAt(str.length-1) != '/')
return str+'/';
else return str;
}
/* ScheduleData class BEGIN */
function ScheduleData(data){
this.data = data;
@ -263,5 +375,5 @@ function convertDateToPosixTime(s){
} else
sec = time[2];
return Date.UTC(year, month, day, hour, minute, sec, msec);
return Date.UTC(year, month-1, day, hour, minute, sec, msec);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -1513,4 +1513,4 @@ padding: 0;
.ui-datepicker {
display:none;
}
}

View File

@ -1211,6 +1211,10 @@ ul.errors {
margin:0;
}
.formrow-repeat ul.errors {
width:278px;
}
ul.errors li {
color:#902d2d;
font-size:11px;
@ -1440,7 +1444,7 @@ div.success{
list-style-type:none;
margin:0 0 7px 0;
padding:0;
height:26px;
/*height:26px;*/
display:block;
}
.formrow-repeat li .ui-button-icon-only {
@ -1501,7 +1505,10 @@ div.success{
.small-icon.rebroadcast {
background:url(images/icon_rebroadcast.png) no-repeat 0 0;
}
.small-icon.soundcloud {
background:url(images/icon_soundcloud.png) no-repeat 0 0;
width:21px;
}
.medium-icon {
display:block;
width:25px;
@ -1511,8 +1518,23 @@ div.success{
}
.medium-icon.recording {
background:url(images/icon_record_m.png) no-repeat 0 0;
width:20px;
}
.medium-icon.rebroadcast {
background:url(images/icon_rebroadcast_m.png) no-repeat 0 0;
}
.medium-icon.soundcloud {
background:url(images/icon_soundcloud_m.png) no-repeat 0 0;
width:21px;
}
.medium-icon.nowplaying, .medium-icon.finishedplaying {
background:url(images/icon_nowplaying_m.png) no-repeat 0 0;
width:12px;
height:9px;
float:left;
margin-left:6px;
margin-right:0;
}
.medium-icon.finishedplaying {
background:url(images/icon_finishedplaying_m.png) no-repeat 0 0;
}

View File

@ -181,8 +181,15 @@ function setAddShowEvents() {
makeAddShowButton();
});
form.find("#add-show-submit")
form.find(".add-show-submit")
.click(function(event){
var addShowButton = $(this);
if (!addShowButton.hasClass("disabled")){
addShowButton.addClass("disabled");
} else {
return;
}
event.preventDefault();
var data = $("form").serializeArray();
@ -203,6 +210,7 @@ function setAddShowEvents() {
var end_date = $("#add_show_end_date").val();
$.post("/Schedule/add-show", {format: "json", data: data, hosts: hosts, days: days}, function(json){
addShowButton.removeClass("disabled");
if(json.form) {
$("#add-show-form")
.empty()

View File

@ -134,7 +134,7 @@ function convertDateToPosixTime(s){
} else
sec = time[2];
return Date.UTC(year, month, day, hour, minute, sec, msec);
return Date.UTC(year, month-1, day, hour, minute, sec, msec);
}
function getFileExt(filename){

View File

@ -117,7 +117,7 @@ class AirTimeApiClient(ApiClientInterface):
def __get_airtime_version(self, verbose = True):
logger = logging.getLogger()
url = self.config["base_url"] + self.config["api_base"] + self.config["version_url"]
url = "http://%s:%s/%s/%s" % (self.config["base_url"], str(self.config["base_port"]), self.config["api_base"], self.config["version_url"])
logger.debug("Trying to contact %s", url)
url = url.replace("%%api_key%%", self.config["api_key"])
@ -198,7 +198,8 @@ class AirTimeApiClient(ApiClientInterface):
logger = logging.getLogger()
# Construct the URL
export_url = self.config["base_url"] + self.config["api_base"] + self.config["export_url"]
#export_url = self.config["base_url"] + self.config["api_base"] + self.config["export_url"]
export_url = "http://%s:%s/%s/%s" % (self.config["base_url"], str(self.config["base_port"]), self.config["api_base"], self.config["export_url"])
logger.info("Fetching schedule from %s", export_url)
export_url = export_url.replace('%%api_key%%', self.config["api_key"])
@ -215,12 +216,15 @@ class AirTimeApiClient(ApiClientInterface):
return status, response
def get_media(self, src, dst):
def get_media(self, uri, dst):
logger = logging.getLogger()
try:
src = "http://%s:%s/%s/%s" % \
(self.config["base_url"], str(self.config["base_port"]), self.config["api_base"], self.config["get_media_url"])
src = src.replace("%%file%%", uri)
logger.info("try to download from %s to %s", src, dst)
src = src + "/api_key/" + self.config["api_key"]
src = src.replace("%%api_key%%", self.config["api_key"])
# check if file exists already before downloading again
filename, headers = urllib.urlretrieve(src, dst)
except Exception, e:
@ -234,7 +238,9 @@ class AirTimeApiClient(ApiClientInterface):
logger = logging.getLogger()
playlist = schedule[pkey]
schedule_id = playlist["schedule_id"]
url = self.config["base_url"] + self.config["api_base"] + self.config["update_item_url"]
#url = self.config["base_url"] + self.config["api_base"] + self.config["update_item_url"]
url = "http://%s:%s/%s/%s" % (self.config["base_url"], str(self.config["base_port"]), self.config["api_base"], self.config["update_item_url"])
url = url.replace("%%schedule_id%%", str(schedule_id))
logger.debug(url)
url = url.replace("%%api_key%%", self.config["api_key"])
@ -261,7 +267,8 @@ class AirTimeApiClient(ApiClientInterface):
response = ''
try:
schedule_id = data
url = self.config["base_url"] + self.config["api_base"] + self.config["update_start_playing_url"]
#url = self.config["base_url"] + self.config["api_base"] + self.config["update_start_playing_url"]
url = "http://%s:%s/%s/%s" % (self.config["base_url"], str(self.config["base_port"]), self.config["api_base"], self.config["update_start_playing_url"])
url = url.replace("%%media_id%%", str(media_id))
url = url.replace("%%schedule_id%%", str(schedule_id))
logger.debug(url)
@ -288,9 +295,10 @@ class AirTimeApiClient(ApiClientInterface):
def get_shows_to_record(self):
logger = logging.getLogger()
response = ''
response = None
try:
url = self.config["base_url"] + self.config["api_base"] + self.config["show_schedule_url"]
url = "http://%s:%s/%s/%s" % (self.config["base_url"], str(self.config["base_port"]), self.config["api_base"], self.config["show_schedule_url"])
#url = self.config["base_url"] + self.config["api_base"] + self.config["show_schedule_url"]
logger.debug(url)
url = url.replace("%%api_key%%", self.config["api_key"])
@ -301,23 +309,40 @@ class AirTimeApiClient(ApiClientInterface):
except Exception, e:
logger.error("Exception: %s", e)
return response[u'shows']
return response
def upload_recorded_show(self, data, headers):
logger = logging.getLogger()
response = ''
try:
url = self.config["base_url"] + self.config["api_base"] + self.config["upload_file_url"]
logger.debug(url)
url = url.replace("%%api_key%%", self.config["api_key"])
request = urllib2.Request(url, data, headers)
response = urllib2.urlopen(request).read().strip()
retries = int(self.config["upload_retries"])
retries_wait = int(self.config["upload_wait"])
logger.info("uploaded show result %s", response)
except Exception, e:
logger.error("Exception: %s", e)
#url = self.config["base_url"] + self.config["api_base"] + self.config["upload_file_url"]
url = "http://%s:%s/%s/%s" % (self.config["base_url"], str(self.config["base_port"]), self.config["api_base"], self.config["upload_file_url"])
logger.debug(url)
url = url.replace("%%api_key%%", self.config["api_key"])
for i in range(0, retries):
logger.debug("Upload attempt: %s", i+1)
try:
request = urllib2.Request(url, data, headers)
response = urllib2.urlopen(request).read().strip()
logger.info("uploaded show result %s", response)
break
except urllib2.HTTPError, e:
logger.error("Http error code: %s", e.code)
except urllib2.URLError, e:
logger.error("Server is down: %s", e.args)
except Exception, e:
logger.error("Exception: %s", e)
#wait some time before next retry
time.sleep(retries_wait)
return response
@ -368,7 +393,9 @@ class ObpApiClient():
logger = logging.getLogger()
# lookup OBP version
url = self.config["base_url"] + self.config["api_base"]+ self.config["version_url"]
#url = self.config["base_url"] + self.config["api_base"]+ self.config["version_url"]
url = "http://%s:%s/%s/%s" % (self.config["base_url"], str(self.config["base_port"]), self.config["api_base"], self.config["version_url"])
try:
logger.debug("Trying to contact %s", url)
@ -427,7 +454,8 @@ class ObpApiClient():
range['end'] = end
# Construct the URL
export_url = self.config["base_url"] + self.config["api_base"] + self.config["export_url"]
#export_url = self.config["base_url"] + self.config["api_base"] + self.config["export_url"]
export_url = "http://%s:%s/%s/%s" % (self.config["base_url"], str(self.config["base_port"]), self.config["api_base"], self.config["export_url"])
# Insert the start and end times into the URL
export_url = export_url.replace('%%api_key%%', self.config["api_key"])
@ -465,7 +493,8 @@ class ObpApiClient():
def notify_scheduled_item_start_playing(self, pkey, schedule):
#def update_scheduled_item(self, item_id, value):
logger = logging.getLogger()
url = self.config["base_url"] + self.config["api_base"] + self.config["update_item_url"]
#url = self.config["base_url"] + self.config["api_base"] + self.config["update_item_url"]
url = "http://%s:%s/%s/%s" % (self.config["base_url"], str(self.config["base_port"]), self.config["api_base"], self.config["update_item_url"])
url = url.replace("%%item_id%%", str(schedule[pkey]["id"]))
url = url.replace("%%played%%", "1")
@ -495,7 +524,8 @@ class ObpApiClient():
playlist_id = data["playlist_id"]
transmission_id = data["transmission_id"]
url = self.config["base_url"] + self.config["api_base"] + self.config["update_start_playing_url"]
#url = self.config["base_url"] + self.config["api_base"] + self.config["update_start_playing_url"]
url = "http://%s:%s/%s/%s" % (self.config["base_url"], str(self.config["base_port"]), self.config["api_base"], self.config["update_start_playing_url"])
url = url.replace("%%playlist_type%%", str(playlist_type))
url = url.replace("%%export_source%%", str(export_source))
url = url.replace("%%media_id%%", str(media_id))
@ -521,7 +551,8 @@ class ObpApiClient():
def generate_range_dp(self):
logger = logging.getLogger()
url = self.config["base_url"] + self.config["api_base"] + self.config["generate_range_url"]
#url = self.config["base_url"] + self.config["api_base"] + self.config["generate_range_url"]
url = "http://%s:%s/%s/%s" % (self.config["base_url"], str(self.config["base_port"]), self.config["api_base"], self.config["generate_range_url"])
try:
response = urllib.urlopen(url, self.api_auth)

View File

@ -31,7 +31,7 @@ import unittest
logging.config.fileConfig("logging-api-validator.cfg")
try:
config = ConfigObj('config.cfg')
config = ConfigObj('/etc/airtime/pypo.cfg')
except Exception, e:
print 'Error loading config file: ', e
sys.exit()

View File

@ -63,7 +63,7 @@ logging.config.fileConfig("logging.cfg")
# loading config file
try:
config = ConfigObj('config.cfg')
config = ConfigObj('/etc/airtime/pypo.cfg')
except Exception, e:
print 'Error loading config file: ', e
sys.exit()

View File

@ -58,7 +58,7 @@ logging.config.fileConfig("logging.cfg")
# loading config file
try:
config = ConfigObj('config.cfg')
config = ConfigObj('/etc/airtime/pypo.cfg')
except Exception, e:
print 'error: ', e

View File

@ -18,7 +18,8 @@ file_dir = '/opt/pypo/files/'
tmp_dir = '/opt/pypo/tmp/'
# Hostname
base_url = 'http://localhost/'
base_url = 'localhost'
base_port = 80
############################################
# Liquidsoap settings #
@ -77,7 +78,7 @@ cue_style = 'pre'
api_key = 'AAA'
# Path to the base of the API
api_base = 'api/'
api_base = 'api'
# URL to get the version number of the server API
version_url = 'version/api_key/%%api_key%%'
@ -85,7 +86,9 @@ version_url = 'version/api_key/%%api_key%%'
# Schedule export path.
# %%from%% - starting date/time in the form YYYY-MM-DD-hh-mm
# %%to%% - starting date/time in the form YYYY-MM-DD-hh-mm
export_url = 'schedule/api_key/%%api_key%%'
export_url = 'schedule/api_key/%%api_key%%'
get_media_url = 'get-media/file/%%file%%/api_key/%%api_key%%'
# Update whether a schedule group has begun playing.
update_item_url = 'notify-schedule-group-play/api_key/%%api_key%%/schedule_id/%%schedule_id%%'

View File

@ -27,7 +27,7 @@ logging.config.fileConfig("logging.cfg")
# loading config file
try:
config = ConfigObj('config.cfg')
config = ConfigObj('/etc/airtime/pypo.cfg')
LS_HOST = config['ls_host']
LS_PORT = config['ls_port']
POLL_INTERVAL = int(config['poll_interval'])
@ -84,9 +84,12 @@ class PypoFetch(Thread):
pypo_timezone = (process.communicate()[0]).strip(' \r\n\t')
if server_timezone != pypo_timezone:
logger.error("Server and pypo timezone offsets do not match. Audio playback may not start when expected!")
logger.error("Server timezone offset: %s", server_timezone)
logger.error("Pypo timezone offset: %s", pypo_timezone)
logger.error("ERROR: Airtime server and pypo timezone offsets do not match. Audio playback will not start when expected!!!")
logger.error(" * Server timezone offset: %s", server_timezone)
logger.error(" * Pypo timezone offset: %s", pypo_timezone)
logger.error(" * To fix this, you need to set the 'date.timezone' value in your php.ini file and restart apache.")
logger.error(" * See this page for more info (v1.7): http://wiki.sourcefabric.org/x/BQBF")
logger.error(" * and also the 'FAQ and Support' page underneath it.")
"""
Process the schedule
@ -208,12 +211,8 @@ class PypoFetch(Thread):
(self.cache_dir, str(pkey), str(media['id']), str(float(media['cue_in']) / 1000), str(float(media['cue_out']) / 1000), str(fileExt))
do_cue = True
# check if it is a remote file, if yes download
if media['uri'][0:4] == 'http':
self.handle_remote_file(media, dst, do_cue)
else:
logger.debug("invalid media uri: %s", media['uri'])
# download media file
self.handle_remote_file(media, dst, do_cue)
if True == os.access(dst, os.R_OK):
# check filesize (avoid zero-byte files)

View File

@ -20,7 +20,7 @@ logging.config.fileConfig("logging.cfg")
# loading config file
try:
config = ConfigObj('config.cfg')
config = ConfigObj('/etc/airtime/pypo.cfg')
LS_HOST = config['ls_host']
LS_PORT = config['ls_port']
PUSH_INTERVAL = 2

View File

@ -1,9 +1,6 @@
###########################################
# liquidsoap config file #
###########################################
# This config assumes that there are
# two instances of LS running
# the "scheduler" & the "fallback" instance
###########################################
@ -13,13 +10,6 @@
log_file = "/var/log/pypo/<script>.log"
log_level = 3
# archive directory
archive_dir = "/opt/pypo/archive/"
# list pointing to the current couchcaster mountpoint
couchcaster_list = "http://vdeb.openbroadcast.ch/mod/ml/api/pypo/current_couchcaster"
###########################################
# stream settings #
###########################################
@ -27,22 +17,22 @@ icecast_host = "127.0.0.1"
icecast_port = 8000
icecast_pass = "hackme"
# mountpoints
###########################################
# webstream mountpoint names #
###########################################
mount_point_mp3 = "airtime.mp3"
mount_point_vorbis = "airtime.ogg"
# mount intra is used for scheduler >>> fallback stream
mount_intra = "pypo_intra"
# intra-LS streaming (no icecast here)
intra_host = "127.0.0.1"
intra_port = 9000
intra_pass = "hackme"
###########################################
# webstream metadata settings #
###########################################
icecast_url = "http://airtime.sourcefabric.org"
icecast_description = "Airtime Radio!"
icecast_genre = "genre"
###########################################
#liquidsoap output settings #
###########################################
output_sound_device = false
output_icecast_vorbis = false
output_icecast_mp3 = true

View File

@ -1,5 +1,5 @@
%include "library/pervasives.liq"
%include "ls_config.liq"
%include "/etc/airtime/liquidsoap.cfg"
set("log.file.path", log_file)
set("log.stdout", true)

View File

@ -1,7 +1,8 @@
api_client = "airtime"
# Hostname
base_url = 'http://localhost/'
base_url = 'localhost'
base_port = 80
# base path to store recordered shows at
base_recorded_files = '/home/pypo/Music/'
@ -10,7 +11,7 @@ base_recorded_files = '/home/pypo/Music/'
api_key = 'AAA'
# Path to the base of the API
api_base = 'api/'
api_base = 'api'
# URL to get the version number of the server API
version_url = 'version/api_key/%%api_key%%'
@ -20,3 +21,9 @@ show_schedule_url = 'recorded-shows/format/json/api_key/%%api_key%%'
# URL to upload the recorded show's file to Airtime
upload_file_url = 'upload-recorded/format/json/api_key/%%api_key%%'
#number of retries to upload file if connection problem
upload_retries = 3
#time to wait between attempts to upload file if connection problem (in seconds)
upload_wait = 60

View File

@ -32,7 +32,7 @@ except Exception, e:
# loading config file
try:
config = ConfigObj('config.cfg')
config = ConfigObj('/etc/airtime/recorder.cfg')
except Exception, e:
print 'Error loading config file: ', e
sys.exit()
@ -62,6 +62,7 @@ class ShowRecorder(Thread):
filepath = "%s%s.%s" % (config["base_recorded_files"], filename, self.filetype)
command = "ecasound -i alsa -o %s -t:%s" % (filepath, length)
#-ge:0.1,0.1,0,-1
args = command.split(" ")
print "starting record"
@ -145,6 +146,10 @@ class Record():
def get_shows(self):
shows = self.api_client.get_shows_to_record()
if shows is not None:
shows = shows[u'shows']
else:
shows = []
if len(shows):
self.process_shows(shows)

View File

@ -1,3 +0,0 @@
<?php
DROP TABLE cc_backup;
DROP TABLE cc_trans;