Merge branch 'devel' of dev.sourcefabric.org:airtime into devel

This commit is contained in:
Paul Baranowski 2012-01-09 16:27:49 -05:00
commit 4ba77212d8
88 changed files with 3911 additions and 343 deletions

View File

@ -119,5 +119,19 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
$frontController->registerPlugin($debug);
}
}
protected function _initRouter()
{
$front = Zend_Controller_Front::getInstance();
$router = $front->getRouter();
$router->addRoute(
'password-change',
new Zend_Controller_Router_Route('password-change/:user_id/:token', array(
'module' => 'default',
'controller' => 'auth',
'action' => 'password-change',
)));
}
}

View File

@ -23,7 +23,8 @@ $ccAcl->add(new Zend_Acl_Resource('library'))
->add(new Zend_Acl_Resource('search'))
->add(new Zend_Acl_Resource('dashboard'))
->add(new Zend_Acl_Resource('preference'))
->add(new Zend_Acl_Resource('recorder'));
->add(new Zend_Acl_Resource('recorder'))
->add(new Zend_Acl_Resource('auth'));
/** Creating permissions */
$ccAcl->allow('G', 'index')
@ -31,6 +32,7 @@ $ccAcl->allow('G', 'index')
->allow('G', 'error')
->allow('G', 'nowplaying')
->allow('G', 'api')
->allow('G', 'auth')
//->allow('G', 'plupload', array('upload-recorded'))
->allow('G', 'recorder')
->allow('G', 'schedule')

View File

@ -8,7 +8,9 @@
* that the user can customize these.
*/
$ini = parse_ini_file('/etc/airtime/airtime.conf', true);
$configFile = isset($_SERVER['AIRTIME_CONF']) ? $_SERVER['AIRTIME_CONF'] : "/etc/airtime/airtime.conf";
$ini = parse_ini_file($configFile, true);
$dbhost = $ini['database']['host'];
$dbname = $ini['database']['dbname'];

View File

@ -113,6 +113,13 @@ return array (
'BaseCcSubjsPeer' => 'airtime/om/BaseCcSubjsPeer.php',
'BaseCcSubjs' => 'airtime/om/BaseCcSubjs.php',
'BaseCcSubjsQuery' => 'airtime/om/BaseCcSubjsQuery.php',
'CcSubjsTokenTableMap' => 'airtime/map/CcSubjsTokenTableMap.php',
'CcSubjsTokenPeer' => 'airtime/CcSubjsTokenPeer.php',
'CcSubjsToken' => 'airtime/CcSubjsToken.php',
'CcSubjsTokenQuery' => 'airtime/CcSubjsTokenQuery.php',
'BaseCcSubjsTokenPeer' => 'airtime/om/BaseCcSubjsTokenPeer.php',
'BaseCcSubjsToken' => 'airtime/om/BaseCcSubjsToken.php',
'BaseCcSubjsTokenQuery' => 'airtime/om/BaseCcSubjsTokenQuery.php',
'CcCountryTableMap' => 'airtime/map/CcCountryTableMap.php',
'CcCountryPeer' => 'airtime/CcCountryPeer.php',
'CcCountry' => 'airtime/CcCountry.php',

View File

@ -23,7 +23,9 @@ $CC_CONFIG = array(
'phingPath' => dirname(__FILE__).'/../../library/phing'
);
$CC_CONFIG = Config::loadConfig($CC_CONFIG);
$configFile = isset($_SERVER['AIRTIME_CONF']) ? $_SERVER['AIRTIME_CONF'] : "/etc/airtime/airtime.conf";
Config::loadConfig($configFile);
// Add database table names
$CC_CONFIG['playListTable'] = $CC_CONFIG['tblNamePrefix'].'playlist';
@ -56,8 +58,11 @@ set_include_path('.'.PATH_SEPARATOR.$CC_CONFIG['pearPath']
.PATH_SEPARATOR.$old_include_path);
class Config {
public static function loadConfig($CC_CONFIG) {
$values = parse_ini_file('/etc/airtime/airtime.conf', true);
public static function loadConfig($p_path) {
global $CC_CONFIG;
$filename = $p_path;
$values = parse_ini_file($filename, true);
// Name of the web server user
$CC_CONFIG['webServerUser'] = $values['general']['web_server_user'];
@ -77,7 +82,5 @@ class Config {
$CC_CONFIG['soundcloud-connection-retries'] = $values['soundcloud']['connection_retries'];
$CC_CONFIG['soundcloud-connection-wait'] = $values['soundcloud']['time_between_retries'];
return $CC_CONFIG;
}
}

View File

@ -23,8 +23,7 @@ class ApiController extends Zend_Controller_Action
->addActionContext('get-stream-setting', 'json')
->addActionContext('status', 'json')
->addActionContext('register-component', 'json')
->addActionContext('update-liquidsoap-error', 'json')
->addActionContext('update-liquidsoap-connection', 'json')
->addActionContext('update-liquidsoap-status', 'json')
->addActionContext('library-init', 'json')
->addActionContext('live-chat', 'json')
->initContext();
@ -780,22 +779,14 @@ class ApiController extends Zend_Controller_Action
Application_Model_ServiceRegister::Register($component, $remoteAddr);
}
public function updateLiquidsoapErrorAction(){
public function updateLiquidsoapStatusAction(){
$request = $this->getRequest();
$error_msg = $request->getParam('error_msg');
$msg = $request->getParam('msg');
$stream_id = $request->getParam('stream_id');
$boot_time = $request->getParam('boot_time');
Application_Model_StreamSetting::setLiquidsoapError($stream_id, $error_msg, $boot_time);
}
public function updateLiquidsoapConnectionAction(){
$request = $this->getRequest();
$stream_id = $request->getParam('stream_id');
$boot_time = $request->getParam('boot_time');
// setting error_msg as "" when there is no error_msg
Application_Model_StreamSetting::setLiquidsoapError($stream_id, "OK", $boot_time);
Application_Model_StreamSetting::setLiquidsoapError($stream_id, $msg, $boot_time);
}
/**

View File

@ -0,0 +1,90 @@
<?php
class AuthController extends Zend_Controller_Action
{
public function init()
{
}
public function passwordRestoreAction()
{
//uses separate layout without a navigation.
$this->_helper->layout->setLayout('bare');
$form = new Application_Form_PasswordRestore();
$request = $this->getRequest();
if ($request->isPost() && $form->isValid($request->getPost())) {
$user = CcSubjsQuery::create()
->filterByDbEmail($form->email->getValue())
->findOne();
if (!empty($user)) {
$auth = new Application_Model_Auth();
$auth->sendPasswordRestoreLink($user, $this->view);
$this->_helper->redirector('password-restore-after', 'auth');
}
else {
$form->email->addError($this->view->translate("Given email not found."));
}
}
$this->view->form = $form;
}
public function passwordRestoreAfterAction()
{
//uses separate layout without a navigation.
$this->_helper->layout->setLayout('bare');
}
public function passwordChangeAction()
{
//uses separate layout without a navigation.
$this->_helper->layout->setLayout('bare');
$request = $this->getRequest();
$token = $request->getParam("token", false);
$user_id = $request->getParam("user_id", 0);
$form = new Application_Form_PasswordChange();
$auth = new Application_Model_Auth();
$user = CcSubjsQuery::create()->findPK($user_id);
//check validity of token
if (!$auth->checkToken($user_id, $token, 'password.restore')) {
echo "token not valid";
//$this->_helper->redirector('index', 'login');
}
if ($request->isPost() && $form->isValid($request->getPost())) {
$user->setDbPass(md5($form->password->getValue()));
$user->save();
$auth->invalidateTokens($user, 'password.restore');
$zend_auth = Zend_Auth::getInstance();
$zend_auth->clearIdentity();
$authAdapter = Application_Model_Auth::getAuthAdapter();
$authAdapter->setIdentity($user->getDbLogin())
->setCredential($form->password->getValue());
$result = $zend_auth->authenticate($authAdapter);
//all info about this user from the login table omit only the password
$userInfo = $authAdapter->getResultRowObject(null, 'password');
//the default storage is a session with namespace Zend_Auth
$authStorage = $zend_auth->getStorage();
$authStorage->write($userInfo);
$this->_helper->redirector('index', 'nowplaying');
}
$this->view->form = $form;
}
}

View File

@ -43,7 +43,7 @@ class LoginController extends Zend_Controller_Action
if(Application_Model_Subjects::getLoginAttempts($username) >= 3 && $form->getElement('captcha') == NULL){
$form->addRecaptcha();
}else{
$authAdapter = $this->getAuthAdapter();
$authAdapter = Application_Model_Auth::getAuthAdapter();
//pass to the adapter the submitted username and password
$authAdapter->setIdentity($username)
@ -92,25 +92,6 @@ class LoginController extends Zend_Controller_Action
Zend_Auth::getInstance()->clearIdentity();
$this->_redirect('login/index');
}
/**
* Gets the adapter for authentication against a database table
*
* @return object
*/
protected function getAuthAdapter()
{
$dbAdapter = Zend_Db_Table::getDefaultAdapter();
$authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
$authAdapter->setTableName('cc_subjs')
->setIdentityColumn('login')
->setCredentialColumn('pass')
->setCredentialTreatment('MD5(?)');
return $authAdapter;
}
}

View File

@ -33,7 +33,6 @@ class PreferenceController extends Zend_Controller_Action
Application_Model_Preference::SetHeadTitle($values["preferences_general"]["stationName"], $this->view);
Application_Model_Preference::SetDefaultFade($values["preferences_general"]["stationDefaultFade"]);
Application_Model_Preference::SetStreamLabelFormat($values["preferences_general"]["streamFormat"]);
Application_Model_Preference::SetAllow3rdPartyApi($values["preferences_general"]["thirdPartyApi"]);
Application_Model_Preference::SetTimezone($values["preferences_general"]["timezone"]);
Application_Model_Preference::SetWeekStartDay($values["preferences_general"]["weekStartDay"]);
@ -134,6 +133,7 @@ class PreferenceController extends Zend_Controller_Action
$baseUrl = $request->getBaseUrl();
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/preferences/streamsetting.js','text/javascript');
$this->view->headScript()->appendFile($baseUrl.'/js/meioMask/jquery.meio.mask.js','text/javascript');
// get current settings
$temp = Application_Model_StreamSetting::getStreamSetting();
@ -180,6 +180,7 @@ class PreferenceController extends Zend_Controller_Action
}
if ($request->isPost()) {
$post_data = $request->getPost();
$error = false;
$values = array();
for($i=1; $i<=$num_of_stream; $i++){
@ -197,8 +198,10 @@ class PreferenceController extends Zend_Controller_Action
$values['output_sound_device'] = $form->getValue('output_sound_device');
}
$values['icecast_vorbis_metadata'] = $form->getValue('icecast_vorbis_metadata');
$values['output_sound_device_type'] = $form->getValue('output_sound_device_type');
}
if(!$error){
Application_Model_StreamSetting::setStreamSetting($values);

View File

@ -238,7 +238,7 @@ class ScheduleController extends Zend_Controller_Action
'title' => 'Cancel Current Show');
}
if ($epochNow < $showStartDateHelper->getTimestamp()) {
if ($epochNow < $showStartDateHelper->getTimestamp()) {
if ($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) {
@ -246,13 +246,15 @@ class ScheduleController extends Zend_Controller_Action
'callback' => 'window["beginEditShow"]'), 'title' => 'Edit Show');
$menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/delete-show'.$params,
'callback' => 'window["scheduleRefetchEvents"]'), 'title' => 'Delete This Instance');
$menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/cancel-show'.$params,
'callback' => 'window["scheduleRefetchEvents"]'), 'title' => 'Delete This Instance and All Following');
if ($show->getShow()->isRepeating() || $show->getShow()->isRebroadcast()) {
$menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/cancel-show'.$params,
'callback' => 'window["scheduleRefetchEvents"]'), 'title' => 'Delete This Instance and All Following');
}
}
}
}
//returns format jjmenu is looking for.
die(json_encode($menu));
//returns format jjmenu is looking for.
die(json_encode($menu));
}
public function scheduleShowAction()
@ -441,7 +443,10 @@ class ScheduleController extends Zend_Controller_Action
"Rebroadcast of show \"$originalShowName\" from "
.$originalDateTime->format("l, F jS")." at ".$originalDateTime->format("G:i");
}
$this->view->showContent = $show->getShowListContent();
$this->view->showLength = $show->getShowLength();
$this->view->timeFilled = $show->getTimeScheduled();
$this->view->percentFilled = $show->getPercentScheduled();
$this->view->showContent = $show->getShowListContent();
$this->view->dialog = $this->view->render('schedule/show-content-dialog.phtml');
unset($this->view->showContent);
}

View File

@ -110,7 +110,7 @@ class Zend_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract
{
$controller = strtolower($request->getControllerName());
if ($controller == 'api'){
if (in_array($controller, array("api", "auth"))){
$this->setRoleName("G");
}

View File

@ -7,7 +7,9 @@ class RabbitMqPlugin extends Zend_Controller_Plugin_Abstract
if (Application_Model_RabbitMq::$doPush) {
$md = array('schedule' => Application_Model_Schedule::GetScheduledPlaylists());
Application_Model_RabbitMq::SendMessageToPypo("update_schedule", $md);
Application_Model_RabbitMq::SendMessageToShowRecorder("update_schedule");
if (!isset($_SERVER['AIRTIME_SRV'])){
Application_Model_RabbitMq::SendMessageToShowRecorder("update_schedule");
}
}
}
}

View File

@ -52,6 +52,7 @@ class Application_Form_AddShowRepeats extends Zend_Form_SubForm
$this->addElement('checkbox', 'add_show_no_end', array(
'label' => 'No End?',
'required' => false,
'checked' => true,
));
}

View File

@ -11,7 +11,7 @@ class Application_Form_GeneralPreferences extends Zend_Form_SubForm
$defaultFade = Application_Model_Preference::GetDefaultFade();
if($defaultFade == ""){
$defaultFade = '00:00:00.000000';
$defaultFade = '00:00:00.500000';
}
//Station name
@ -41,15 +41,6 @@ class Application_Form_GeneralPreferences extends Zend_Form_SubForm
)
));
$stream_format = new Zend_Form_Element_Radio('streamFormat');
$stream_format->setLabel('Stream Label:');
$stream_format->setMultiOptions(array("Artist - Title",
"Show - Artist - Title",
"Station name - Show name"));
$stream_format->setValue(Application_Model_Preference::GetStreamLabelFormat());
$stream_format->setDecorators(array('ViewHelper'));
$this->addElement($stream_format);
$third_party_api = new Zend_Form_Element_Radio('thirdPartyApi');
$third_party_api->setLabel('Allow Remote Websites To Access "Schedule" Info?<br> (Enable this to make front-end widgets work.)');
$third_party_api->setMultiOptions(array("Disabled",

View File

@ -0,0 +1,35 @@
<?php
/**
*/
class Application_Form_PasswordChange extends Zend_Form
{
public function init()
{
$this->addElement('password', 'password', array(
'label' => 'Password',
'required' => true,
'filters' => array('stringTrim'),
'validators' => array(
array('stringLength', false, array(6, 80)),
),
));
$this->addElement('password', 'password_confirm', array(
'label' => 'Password Confirmation',
'required' => true,
'filters' => array('stringTrim'),
'validators' => array(
new Zend_Validate_Callback(function ($value, $context) {
return $value == $context['password'];
}),
),
'errorMessages' => array("Password confirmation does not match your password."),
));
$this->addElement('submit', 'submit', array(
'label' => 'Set password',
'ignore' => true,
));
}
}

View File

@ -0,0 +1,23 @@
<?php
/**
*/
class Application_Form_PasswordRestore extends Zend_Form
{
public function init()
{
$this->addElement('text', 'email', array(
'label' => 'E-mail',
'required' => true,
'filters' => array(
'stringTrim',
),
));
$this->addElement('submit', 'submit', array(
'label' => 'Restore password',
'ignore' => true,
'class' => 'ui-button ui-state-default'
));
}
}

View File

@ -56,11 +56,22 @@ class Application_Form_StreamSetting extends Zend_Form
$icecast_vorbis_metadata->setAttrib("readonly", true);
}
$this->addElement($icecast_vorbis_metadata);
$stream_format = new Zend_Form_Element_Radio('streamFormat');
$stream_format->setLabel('Stream Label:');
$stream_format->setMultiOptions(array("Artist - Title",
"Show - Artist - Title",
"Station name - Show name"));
$stream_format->setValue(Application_Model_Preference::GetStreamLabelFormat());
$stream_format->setDecorators(array('ViewHelper'));
$this->addElement($stream_format);
}
public function isValid($data){
$this->populate(array("output_sound_device"=>$data['output_sound_device'], "icecast_vorbis_metadata"=>$data['icecast_vorbis_metadata'],
"output_sound_device_type"=>$data['output_sound_device_type']));
if($data['output_sound_device']){
$this->populate(array("output_sound_device"=>$data['output_sound_device'], "icecast_vorbis_metadata"=>$data['icecast_vorbis_metadata'],
"output_sound_device_type"=>$data['output_sound_device_type'], "streamFormat"=>$data['streamFormat']));
}
return true;
}
}

View File

@ -83,10 +83,13 @@ class Application_Form_StreamSettingSubForm extends Zend_Form_SubForm{
$host = new Zend_Form_Element_Text('host');
$host->setLabel("Server")
->setValue(isset($setting[$prefix.'_host'])?$setting[$prefix.'_host']:"")
->setValidators(array(
array('regex', false, array('/^[0-9a-zA-Z-_.]+$/', 'messages' => 'Invalid character entered'))))
->setDecorators(array('ViewHelper'));
if($disable_all){
$host->setAttrib("disabled", "disabled");
}
$host->setAttrib('alt', 'domain');
$this->addElement($host);
$port = new Zend_Form_Element_Text('port');
@ -103,10 +106,13 @@ class Application_Form_StreamSettingSubForm extends Zend_Form_SubForm{
$pass = new Zend_Form_Element_Text('pass');
$pass->setLabel("Password")
->setValue(isset($setting[$prefix.'_pass'])?$setting[$prefix.'_pass']:"")
->setValidators(array(
array('regex', false, array('/^[^ &<>]+$/', 'messages' => 'Invalid character entered'))))
->setDecorators(array('ViewHelper'));
if($disable_all){
$pass->setAttrib("disabled", "disabled");
}
$pass->setAttrib('alt', 'regular_text');
$this->addElement($pass);
$genre = new Zend_Form_Element_Text('genre');
@ -121,10 +127,13 @@ class Application_Form_StreamSettingSubForm extends Zend_Form_SubForm{
$url = new Zend_Form_Element_Text('url');
$url->setLabel("URL")
->setValue(isset($setting[$prefix.'_url'])?$setting[$prefix.'_url']:"")
->setValidators(array(
array('regex', false, array('/^[0-9a-zA-Z\-_.:\/]+$/', 'messages' => 'Invalid character entered'))))
->setDecorators(array('ViewHelper'));
if($disable_all){
$url->setAttrib("disabled", "disabled");
}
$url->setAttrib('alt', 'url');
$this->addElement($url);
$description = new Zend_Form_Element_Text('description');
@ -139,19 +148,25 @@ class Application_Form_StreamSettingSubForm extends Zend_Form_SubForm{
$mount = new Zend_Form_Element_Text('mount');
$mount->setLabel("Mount Point")
->setValue(isset($setting[$prefix.'_mount'])?$setting[$prefix.'_mount']:"")
->setValidators(array(
array('regex', false, array('/^[^ &<>]+$/', 'messages' => 'Invalid character entered'))))
->setDecorators(array('ViewHelper'));
if($disable_all){
$mount->setAttrib("disabled", "disabled");
}
$mount->setAttrib('alt', 'regular_text');
$this->addElement($mount);
$user = new Zend_Form_Element_Text('user');
$user->setLabel("Username")
->setValue(isset($setting[$prefix.'_user'])?$setting[$prefix.'_user']:"")
->setValidators(array(
array('regex', false, array('/^[^ &<>]+$/', 'messages' => 'Invalid character entered'))))
->setDecorators(array('ViewHelper'));
if($disable_all){
$user->setAttrib("disabled", "disabled");
}
$user->setAttrib('alt', 'regular_text');
$this->addElement($user);
$liquidsopa_error_msg = '<div class="stream-status status-info"><h3>Getting information from the server...</h3></div>';

View File

@ -0,0 +1,101 @@
<?php
class Application_Model_Auth {
const TOKEN_LIFETIME = 'P2D'; // DateInterval syntax
private function generateToken($action, $user_id)
{
$salt = "pro";
$token = self::generateRandomString();
$info = new CcSubjsToken();
$info->setDbUserId($user_id);
$info->setDbAction($action);
$info->setDbToken(sha1($token.$salt));
$info->setDbCreated(gmdate('Y-m-d H:i:s'));
$info->save();
return $token;
}
public function sendPasswordRestoreLink($user, $view)
{
$token = $this->generateToken('password.restore', $user->getDbId());
$e_link_protocol = empty($_SERVER['HTTPS']) ? "http" : "https";
$e_link_base = $_SERVER['SERVER_NAME'];
$e_link_path = $view->url(array('user_id' => $user->getDbId(),
'token' => $token
),
'password-change');
$message = "Click this link: {$e_link_protocol}://{$e_link_base}{$e_link_path}";
Application_Model_Email::send('Airtime Password Reset', $message, $user->getDbEmail());
}
public function invalidateTokens($user, $action)
{
CcSubjsTokenQuery::create()
->filterByDbAction($action)
->filterByDbUserId($user->getDbId())
->delete();
}
public function checkToken($user_id, $token, $action)
{
$salt = "pro";
$token_info = CcSubjsTokenQuery::create()
->filterByDbAction($action)
->filterByDbUserId($user_id)
->filterByDbToken(sha1($token.$salt))
->findOne();
if (empty($token_info)) {
return false;
}
$now = new DateTime();
$token_life = new DateInterval(self::TOKEN_LIFETIME);
$token_created = new DateTime($token_info->getDbCreated(), new DateTimeZone("UTC"));
return $now->sub($token_life)->getTimestamp() < $token_created->getTimestamp();
}
/**
* Gets the adapter for authentication against a database table
*
* @return object
*/
public static function getAuthAdapter()
{
$dbAdapter = Zend_Db_Table::getDefaultAdapter();
$authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
$authAdapter->setTableName('cc_subjs')
->setIdentityColumn('login')
->setCredentialColumn('pass')
->setCredentialTreatment('MD5(?)');
return $authAdapter;
}
/**
* Get random string
*
* @param int $length
* @param string $allowed_chars
* @return string
*/
final public function generateRandomString($length = 12, $allowed_chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
{
$string = '';
for ($i = 0; $i < $length; $i++) {
$string .= $allowed_chars[mt_rand(0, strlen($allowed_chars) - 1)];
}
return $string;
}
}

View File

@ -217,7 +217,7 @@ class Application_Model_DateHelper
* @param int $p_time
* The time interval in format HH:MM:SS.mm we wish to
* convert to seconds.
* @return int
* @return float
* The input parameter converted to seconds.
*/
public static function calculateLengthInSeconds($p_time){
@ -235,6 +235,9 @@ class Application_Model_DateHelper
list($hours, $minutes, $seconds) = explode(":", $hhmmss);
// keep ms in 3 digits
$ms = substr($ms, 0, 3);
$totalSeconds = $hours*3600 + $minutes*60 + $seconds + $ms/1000;
return $totalSeconds;

View File

@ -0,0 +1,36 @@
<?php
class Application_Model_Email {
/**
* Send email
*
* @param string $subject
* @param string $message
* @param mixed $tos
* @return void
*/
public static function send($subject, $message, $tos, $from = null)
{
/*
$configMail = array( 'auth' => 'login',
'username' => 'user@gmail.com',
'password' => 'password',
'ssl' => 'ssl',
'port' => 465
);
$mailTransport = new Zend_Mail_Transport_Smtp('smtp.gmail.com',$configMail);
*/
$mail = new Zend_Mail('utf-8');
$mail->setSubject($subject);
$mail->setBodyText($message);
$mail->setFrom(isset($from) ? $from : 'naomi.aro@sourcefabric.org');
foreach ((array) $tos as $to) {
$mail->addTo($to);
}
$mail->send();
}
}

View File

@ -24,7 +24,8 @@ class Application_Model_Nowplaying
$itemStarts = $itemStartDateTime->format("Y-m-d H:i:s");
$itemEnds = $itemEndDateTime->format("Y-m-d H:i:s");
$status = ($dbRow['show_ends'] < $dbRow['item_ends']) ? "x" : "";
// Allow show to exceed 1 second per CC-3183
$status = ($showEnds < $itemEnds) ? "x" : "";
$type = "a";
$type .= ($itemEndDateTime->getTimestamp() > $epochNow && $itemStartDateTime->getTimestamp() <= $epochNow) ? "c" : "";

View File

@ -121,7 +121,7 @@ class Application_Model_Preference
* A row from cc_show_days table
*/
public static function SetShowsPopulatedUntil($dateTime) {
self::SetValue("shows_populated_until", $dateTime->format("Y-m-d"));
self::SetValue("shows_populated_until", $dateTime->format("Y-m-d H:i:s"));
}
/**

View File

@ -21,7 +21,8 @@ class Application_Model_RabbitMq
$conn = new AMQPConnection($CC_CONFIG["rabbitmq"]["host"],
$CC_CONFIG["rabbitmq"]["port"],
$CC_CONFIG["rabbitmq"]["user"],
$CC_CONFIG["rabbitmq"]["password"]);
$CC_CONFIG["rabbitmq"]["password"],
$CC_CONFIG["rabbitmq"]["vhost"]);
$channel = $conn->channel();
$channel->access_request($CC_CONFIG["rabbitmq"]["vhost"], false, false, true, true);

View File

@ -121,7 +121,7 @@ class Application_Model_Show {
global $CC_DBC;
if ($deltaDay > 0) {
return "shows can have a max length of 24 hours.";
return "Shows can have a max length of 24 hours.";
}
$hours = $deltaMin/60;

View File

@ -192,10 +192,6 @@ class Application_Model_ShowInstance {
$newDateTime = clone $dateTime;
Logging::log("deltaDay: {$deltaDay}");
Logging::log("deltaMin: {$deltaMin}");
Logging::log("addDeltas: original time {$newDateTime->format('Y-m-d H:i:s')}");
$days = abs($deltaDay);
$mins = abs($deltaMin);
@ -216,8 +212,6 @@ class Application_Model_ShowInstance {
$newDateTime->sub($minInterval);
}
Logging::log("addDeltas: modified time {$newDateTime->format('Y-m-d H:i:s')}");
return $newDateTime;
}
@ -252,6 +246,21 @@ class Application_Model_ShowInstance {
return "Can't move show into past";
}
if ($this->isRecorded()) {
//rebroadcasts should start at max 1 hour after a recorded show has ended.
$minRebroadcastStart = self::addDeltas($newEndsDateTime, 0, 60);
//check if we are moving a recorded show less than 1 hour before any of its own rebroadcasts.
$rebroadcasts = CcShowInstancesQuery::create()
->filterByDbOriginalShow($this->_instanceId)
->filterByDbStarts($minRebroadcastStart->format('Y-m-d H:i:s'), Criteria::LESS_THAN)
->find();
if (count($rebroadcasts) > 0) {
return "Can't move a recorded show less than 1 hour before its rebroadcasts.";
}
}
if ($this->isRebroadcast()) {
try {

View File

@ -411,9 +411,11 @@ class Application_Model_StoredFile {
public function getFilePath()
{
$music_dir = Application_Model_MusicDir::getDirByPK($this->_file->getDbDirectory());
$directory = $music_dir->getDirectory();
$filepath = $this->_file->getDbFilepath();
return $music_dir->getDirectory().$filepath;
return $directory.$filepath;
}
/**
@ -810,12 +812,9 @@ class Application_Model_StoredFile {
$contentType = $_SERVER["CONTENT_TYPE"];
// create temp file name (CC-3086)
$command = "mktemp --tmpdir=".$p_targetDir;
$tempFilePath= exec($command);
if($tempFilePath == ""){
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Unable to create tmp file."}, "id" : "id"}');
}
// we are not using mktemp command anymore.
// plupload support unique_name feature.
$tempFilePath= $p_targetDir . DIRECTORY_SEPARATOR . $fileName;
if (strpos($contentType, "multipart") !== false) {
if (isset($_FILES['file']['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name'])) {
@ -880,8 +879,13 @@ class Application_Model_StoredFile {
$audio_stor = $stor . DIRECTORY_SEPARATOR . $fileName;
$r = @copy($audio_file, $audio_stor);
$r = @unlink($audio_file);
Logging::log("copyFileToStor: moving file $audio_file to $audio_stor");
//Martin K.: changed to rename: Much less load + quicker since this is an atomic operation
$r = @rename($audio_file, $audio_stor);
//$r = @copy($audio_file, $audio_stor);
//$r = @unlink($audio_file);
}
public static function getFileCount()

View File

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

View File

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

View File

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

View File

@ -65,6 +65,7 @@ class CcSubjsTableMap extends TableMap {
$this->addRelation('CcPlaylist', 'CcPlaylist', RelationMap::ONE_TO_MANY, array('id' => 'editedby', ), null, null);
$this->addRelation('CcPref', 'CcPref', RelationMap::ONE_TO_MANY, array('id' => 'subjid', ), 'CASCADE', null);
$this->addRelation('CcSess', 'CcSess', RelationMap::ONE_TO_MANY, array('id' => 'userid', ), 'CASCADE', null);
$this->addRelation('CcSubjsToken', 'CcSubjsToken', RelationMap::ONE_TO_MANY, array('id' => 'user_id', ), 'CASCADE', null);
} // buildRelations()
} // CcSubjsTableMap

View File

@ -0,0 +1,57 @@
<?php
/**
* This class defines the structure of the 'cc_subjs_token' table.
*
*
*
* This map class is used by Propel to do runtime db structure discovery.
* For example, the createSelectSql() method checks the type of a given column used in an
* ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive
* (i.e. if it's a text column type).
*
* @package propel.generator.airtime.map
*/
class CcSubjsTokenTableMap extends TableMap {
/**
* The (dot-path) name of this class
*/
const CLASS_NAME = 'airtime.map.CcSubjsTokenTableMap';
/**
* Initialize the table attributes, columns and validators
* Relations are not initialized by this method since they are lazy loaded
*
* @return void
* @throws PropelException
*/
public function initialize()
{
// attributes
$this->setName('cc_subjs_token');
$this->setPhpName('CcSubjsToken');
$this->setClassname('CcSubjsToken');
$this->setPackage('airtime');
$this->setUseIdGenerator(true);
$this->setPrimaryKeyMethodInfo('cc_subjs_token_id_seq');
// columns
$this->addPrimaryKey('ID', 'DbId', 'INTEGER', true, null, null);
$this->addForeignKey('USER_ID', 'DbUserId', 'INTEGER', 'cc_subjs', 'ID', true, null, null);
$this->addColumn('ACTION', 'DbAction', 'VARCHAR', true, 255, null);
$this->addColumn('TOKEN', 'DbToken', 'VARCHAR', true, 40, null);
$this->addColumn('CREATED', 'DbCreated', 'TIMESTAMP', true, null, null);
// validators
} // initialize()
/**
* Build the RelationMap objects for this table relationships
*/
public function buildRelations()
{
$this->addRelation('CcSubjs', 'CcSubjs', RelationMap::MANY_TO_ONE, array('user_id' => 'id', ), 'CASCADE', null);
} // buildRelations()
} // CcSubjsTokenTableMap

View File

@ -137,6 +137,11 @@ abstract class BaseCcSubjs extends BaseObject implements Persistent
*/
protected $collCcSesss;
/**
* @var array CcSubjsToken[] Collection to store aggregation of CcSubjsToken objects.
*/
protected $collCcSubjsTokens;
/**
* Flag to prevent endless save loop, if this object is referenced
* by another object which falls in this transaction.
@ -793,6 +798,8 @@ abstract class BaseCcSubjs extends BaseObject implements Persistent
$this->collCcSesss = null;
$this->collCcSubjsTokens = null;
} // if (deep)
}
@ -982,6 +989,14 @@ abstract class BaseCcSubjs extends BaseObject implements Persistent
}
}
if ($this->collCcSubjsTokens !== null) {
foreach ($this->collCcSubjsTokens as $referrerFK) {
if (!$referrerFK->isDeleted()) {
$affectedRows += $referrerFK->save($con);
}
}
}
$this->alreadyInSave = false;
}
@ -1109,6 +1124,14 @@ abstract class BaseCcSubjs extends BaseObject implements Persistent
}
}
if ($this->collCcSubjsTokens !== null) {
foreach ($this->collCcSubjsTokens as $referrerFK) {
if (!$referrerFK->validate($columns)) {
$failureMap = array_merge($failureMap, $referrerFK->getValidationFailures());
}
}
}
$this->alreadyInValidation = false;
}
@ -1459,6 +1482,12 @@ abstract class BaseCcSubjs extends BaseObject implements Persistent
}
}
foreach ($this->getCcSubjsTokens() as $relObj) {
if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves
$copyObj->addCcSubjsToken($relObj->copy($deepCopy));
}
}
} // if ($deepCopy)
@ -2317,6 +2346,115 @@ abstract class BaseCcSubjs extends BaseObject implements Persistent
}
}
/**
* Clears out the collCcSubjsTokens collection
*
* This does not modify the database; however, it will remove any associated objects, causing
* them to be refetched by subsequent calls to accessor method.
*
* @return void
* @see addCcSubjsTokens()
*/
public function clearCcSubjsTokens()
{
$this->collCcSubjsTokens = null; // important to set this to NULL since that means it is uninitialized
}
/**
* Initializes the collCcSubjsTokens collection.
*
* By default this just sets the collCcSubjsTokens collection to an empty array (like clearcollCcSubjsTokens());
* however, you may wish to override this method in your stub class to provide setting appropriate
* to your application -- for example, setting the initial array to the values stored in database.
*
* @return void
*/
public function initCcSubjsTokens()
{
$this->collCcSubjsTokens = new PropelObjectCollection();
$this->collCcSubjsTokens->setModel('CcSubjsToken');
}
/**
* Gets an array of CcSubjsToken objects which contain a foreign key that references this object.
*
* If the $criteria is not null, it is used to always fetch the results from the database.
* Otherwise the results are fetched from the database the first time, then cached.
* Next time the same method is called without $criteria, the cached collection is returned.
* If this CcSubjs is new, it will return
* an empty collection or the current collection; the criteria is ignored on a new object.
*
* @param Criteria $criteria optional Criteria object to narrow the query
* @param PropelPDO $con optional connection object
* @return PropelCollection|array CcSubjsToken[] List of CcSubjsToken objects
* @throws PropelException
*/
public function getCcSubjsTokens($criteria = null, PropelPDO $con = null)
{
if(null === $this->collCcSubjsTokens || null !== $criteria) {
if ($this->isNew() && null === $this->collCcSubjsTokens) {
// return empty collection
$this->initCcSubjsTokens();
} else {
$collCcSubjsTokens = CcSubjsTokenQuery::create(null, $criteria)
->filterByCcSubjs($this)
->find($con);
if (null !== $criteria) {
return $collCcSubjsTokens;
}
$this->collCcSubjsTokens = $collCcSubjsTokens;
}
}
return $this->collCcSubjsTokens;
}
/**
* Returns the number of related CcSubjsToken objects.
*
* @param Criteria $criteria
* @param boolean $distinct
* @param PropelPDO $con
* @return int Count of related CcSubjsToken objects.
* @throws PropelException
*/
public function countCcSubjsTokens(Criteria $criteria = null, $distinct = false, PropelPDO $con = null)
{
if(null === $this->collCcSubjsTokens || null !== $criteria) {
if ($this->isNew() && null === $this->collCcSubjsTokens) {
return 0;
} else {
$query = CcSubjsTokenQuery::create(null, $criteria);
if($distinct) {
$query->distinct();
}
return $query
->filterByCcSubjs($this)
->count($con);
}
} else {
return count($this->collCcSubjsTokens);
}
}
/**
* Method called to associate a CcSubjsToken object to this object
* through the CcSubjsToken foreign key attribute.
*
* @param CcSubjsToken $l CcSubjsToken
* @return void
* @throws PropelException
*/
public function addCcSubjsToken(CcSubjsToken $l)
{
if ($this->collCcSubjsTokens === null) {
$this->initCcSubjsTokens();
}
if (!$this->collCcSubjsTokens->contains($l)) { // only add it if the **same** object is not already associated
$this->collCcSubjsTokens[]= $l;
$l->setCcSubjs($this);
}
}
/**
* Clears the current object and sets all attributes to their default values
*/
@ -2390,6 +2528,11 @@ abstract class BaseCcSubjs extends BaseObject implements Persistent
$o->clearAllReferences($deep);
}
}
if ($this->collCcSubjsTokens) {
foreach ((array) $this->collCcSubjsTokens as $o) {
$o->clearAllReferences($deep);
}
}
} // if ($deep)
$this->collCcAccesss = null;
@ -2399,6 +2542,7 @@ abstract class BaseCcSubjs extends BaseObject implements Persistent
$this->collCcPlaylists = null;
$this->collCcPrefs = null;
$this->collCcSesss = null;
$this->collCcSubjsTokens = null;
}
/**

View File

@ -405,6 +405,9 @@ abstract class BaseCcSubjsPeer {
// Invalidate objects in CcSessPeer instance pool,
// since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule.
CcSessPeer::clearInstancePool();
// Invalidate objects in CcSubjsTokenPeer instance pool,
// since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule.
CcSubjsTokenPeer::clearInstancePool();
}
/**

View File

@ -64,6 +64,10 @@
* @method CcSubjsQuery rightJoinCcSess($relationAlias = '') Adds a RIGHT JOIN clause to the query using the CcSess relation
* @method CcSubjsQuery innerJoinCcSess($relationAlias = '') Adds a INNER JOIN clause to the query using the CcSess relation
*
* @method CcSubjsQuery leftJoinCcSubjsToken($relationAlias = '') Adds a LEFT JOIN clause to the query using the CcSubjsToken relation
* @method CcSubjsQuery rightJoinCcSubjsToken($relationAlias = '') Adds a RIGHT JOIN clause to the query using the CcSubjsToken relation
* @method CcSubjsQuery innerJoinCcSubjsToken($relationAlias = '') Adds a INNER JOIN clause to the query using the CcSubjsToken relation
*
* @method CcSubjs findOne(PropelPDO $con = null) Return the first CcSubjs matching the query
* @method CcSubjs findOneOrCreate(PropelPDO $con = null) Return the first CcSubjs matching the query, or a new CcSubjs object populated from the query conditions when no match is found
*
@ -935,6 +939,70 @@ abstract class BaseCcSubjsQuery extends ModelCriteria
->useQuery($relationAlias ? $relationAlias : 'CcSess', 'CcSessQuery');
}
/**
* Filter the query by a related CcSubjsToken object
*
* @param CcSubjsToken $ccSubjsToken the related object to use as filter
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return CcSubjsQuery The current query, for fluid interface
*/
public function filterByCcSubjsToken($ccSubjsToken, $comparison = null)
{
return $this
->addUsingAlias(CcSubjsPeer::ID, $ccSubjsToken->getDbUserId(), $comparison);
}
/**
* Adds a JOIN clause to the query using the CcSubjsToken relation
*
* @param string $relationAlias optional alias for the relation
* @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'
*
* @return CcSubjsQuery The current query, for fluid interface
*/
public function joinCcSubjsToken($relationAlias = '', $joinType = Criteria::INNER_JOIN)
{
$tableMap = $this->getTableMap();
$relationMap = $tableMap->getRelation('CcSubjsToken');
// create a ModelJoin object for this join
$join = new ModelJoin();
$join->setJoinType($joinType);
$join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias);
if ($previousJoin = $this->getPreviousJoin()) {
$join->setPreviousJoin($previousJoin);
}
// add the ModelJoin to the current object
if($relationAlias) {
$this->addAlias($relationAlias, $relationMap->getRightTable()->getName());
$this->addJoinObject($join, $relationAlias);
} else {
$this->addJoinObject($join, 'CcSubjsToken');
}
return $this;
}
/**
* Use the CcSubjsToken relation CcSubjsToken object
*
* @see useQuery()
*
* @param string $relationAlias optional alias for the relation,
* to be used as main alias in the secondary query
* @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'
*
* @return CcSubjsTokenQuery A secondary query class using the current class as primary query
*/
public function useCcSubjsTokenQuery($relationAlias = '', $joinType = Criteria::INNER_JOIN)
{
return $this
->joinCcSubjsToken($relationAlias, $joinType)
->useQuery($relationAlias ? $relationAlias : 'CcSubjsToken', 'CcSubjsTokenQuery');
}
/**
* Exclude object from result
*

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,988 @@
<?php
/**
* Base static class for performing query and update operations on the 'cc_subjs_token' table.
*
*
*
* @package propel.generator.airtime.om
*/
abstract class BaseCcSubjsTokenPeer {
/** the default database name for this class */
const DATABASE_NAME = 'airtime';
/** the table name for this class */
const TABLE_NAME = 'cc_subjs_token';
/** the related Propel class for this table */
const OM_CLASS = 'CcSubjsToken';
/** A class that can be returned by this peer. */
const CLASS_DEFAULT = 'airtime.CcSubjsToken';
/** the related TableMap class for this table */
const TM_CLASS = 'CcSubjsTokenTableMap';
/** The total number of columns. */
const NUM_COLUMNS = 5;
/** The number of lazy-loaded columns. */
const NUM_LAZY_LOAD_COLUMNS = 0;
/** the column name for the ID field */
const ID = 'cc_subjs_token.ID';
/** the column name for the USER_ID field */
const USER_ID = 'cc_subjs_token.USER_ID';
/** the column name for the ACTION field */
const ACTION = 'cc_subjs_token.ACTION';
/** the column name for the TOKEN field */
const TOKEN = 'cc_subjs_token.TOKEN';
/** the column name for the CREATED field */
const CREATED = 'cc_subjs_token.CREATED';
/**
* An identiy map to hold any loaded instances of CcSubjsToken objects.
* This must be public so that other peer classes can access this when hydrating from JOIN
* queries.
* @var array CcSubjsToken[]
*/
public static $instances = array();
/**
* holds an array of fieldnames
*
* first dimension keys are the type constants
* e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id'
*/
private static $fieldNames = array (
BasePeer::TYPE_PHPNAME => array ('DbId', 'DbUserId', 'DbAction', 'DbToken', 'DbCreated', ),
BasePeer::TYPE_STUDLYPHPNAME => array ('dbId', 'dbUserId', 'dbAction', 'dbToken', 'dbCreated', ),
BasePeer::TYPE_COLNAME => array (self::ID, self::USER_ID, self::ACTION, self::TOKEN, self::CREATED, ),
BasePeer::TYPE_RAW_COLNAME => array ('ID', 'USER_ID', 'ACTION', 'TOKEN', 'CREATED', ),
BasePeer::TYPE_FIELDNAME => array ('id', 'user_id', 'action', 'token', 'created', ),
BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, )
);
/**
* holds an array of keys for quick access to the fieldnames array
*
* first dimension keys are the type constants
* e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0
*/
private static $fieldKeys = array (
BasePeer::TYPE_PHPNAME => array ('DbId' => 0, 'DbUserId' => 1, 'DbAction' => 2, 'DbToken' => 3, 'DbCreated' => 4, ),
BasePeer::TYPE_STUDLYPHPNAME => array ('dbId' => 0, 'dbUserId' => 1, 'dbAction' => 2, 'dbToken' => 3, 'dbCreated' => 4, ),
BasePeer::TYPE_COLNAME => array (self::ID => 0, self::USER_ID => 1, self::ACTION => 2, self::TOKEN => 3, self::CREATED => 4, ),
BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'USER_ID' => 1, 'ACTION' => 2, 'TOKEN' => 3, 'CREATED' => 4, ),
BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'user_id' => 1, 'action' => 2, 'token' => 3, 'created' => 4, ),
BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, )
);
/**
* Translates a fieldname to another type
*
* @param string $name field name
* @param string $fromType One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME
* BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM
* @param string $toType One of the class type constants
* @return string translated name of the field.
* @throws PropelException - if the specified name could not be found in the fieldname mappings.
*/
static public function translateFieldName($name, $fromType, $toType)
{
$toNames = self::getFieldNames($toType);
$key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null;
if ($key === null) {
throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true));
}
return $toNames[$key];
}
/**
* Returns an array of field names.
*
* @param string $type The type of fieldnames to return:
* One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME
* BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM
* @return array A list of field names
*/
static public function getFieldNames($type = BasePeer::TYPE_PHPNAME)
{
if (!array_key_exists($type, self::$fieldNames)) {
throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. ' . $type . ' was given.');
}
return self::$fieldNames[$type];
}
/**
* Convenience method which changes table.column to alias.column.
*
* Using this method you can maintain SQL abstraction while using column aliases.
* <code>
* $c->addAlias("alias1", TablePeer::TABLE_NAME);
* $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN);
* </code>
* @param string $alias The alias for the current table.
* @param string $column The column name for current table. (i.e. CcSubjsTokenPeer::COLUMN_NAME).
* @return string
*/
public static function alias($alias, $column)
{
return str_replace(CcSubjsTokenPeer::TABLE_NAME.'.', $alias.'.', $column);
}
/**
* Add all the columns needed to create a new object.
*
* Note: any columns that were marked with lazyLoad="true" in the
* XML schema will not be added to the select list and only loaded
* on demand.
*
* @param Criteria $criteria object containing the columns to add.
* @param string $alias optional table alias
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function addSelectColumns(Criteria $criteria, $alias = null)
{
if (null === $alias) {
$criteria->addSelectColumn(CcSubjsTokenPeer::ID);
$criteria->addSelectColumn(CcSubjsTokenPeer::USER_ID);
$criteria->addSelectColumn(CcSubjsTokenPeer::ACTION);
$criteria->addSelectColumn(CcSubjsTokenPeer::TOKEN);
$criteria->addSelectColumn(CcSubjsTokenPeer::CREATED);
} else {
$criteria->addSelectColumn($alias . '.ID');
$criteria->addSelectColumn($alias . '.USER_ID');
$criteria->addSelectColumn($alias . '.ACTION');
$criteria->addSelectColumn($alias . '.TOKEN');
$criteria->addSelectColumn($alias . '.CREATED');
}
}
/**
* Returns the number of rows matching criteria.
*
* @param Criteria $criteria
* @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead.
* @param PropelPDO $con
* @return int Number of matching rows.
*/
public static function doCount(Criteria $criteria, $distinct = false, PropelPDO $con = null)
{
// we may modify criteria, so copy it first
$criteria = clone $criteria;
// We need to set the primary table name, since in the case that there are no WHERE columns
// it will be impossible for the BasePeer::createSelectSql() method to determine which
// tables go into the FROM clause.
$criteria->setPrimaryTableName(CcSubjsTokenPeer::TABLE_NAME);
if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) {
$criteria->setDistinct();
}
if (!$criteria->hasSelectClause()) {
CcSubjsTokenPeer::addSelectColumns($criteria);
}
$criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count
$criteria->setDbName(self::DATABASE_NAME); // Set the correct dbName
if ($con === null) {
$con = Propel::getConnection(CcSubjsTokenPeer::DATABASE_NAME, Propel::CONNECTION_READ);
}
// BasePeer returns a PDOStatement
$stmt = BasePeer::doCount($criteria, $con);
if ($row = $stmt->fetch(PDO::FETCH_NUM)) {
$count = (int) $row[0];
} else {
$count = 0; // no rows returned; we infer that means 0 matches.
}
$stmt->closeCursor();
return $count;
}
/**
* Method to select one object from the DB.
*
* @param Criteria $criteria object used to create the SELECT statement.
* @param PropelPDO $con
* @return CcSubjsToken
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doSelectOne(Criteria $criteria, PropelPDO $con = null)
{
$critcopy = clone $criteria;
$critcopy->setLimit(1);
$objects = CcSubjsTokenPeer::doSelect($critcopy, $con);
if ($objects) {
return $objects[0];
}
return null;
}
/**
* Method to do selects.
*
* @param Criteria $criteria The Criteria object used to build the SELECT statement.
* @param PropelPDO $con
* @return array Array of selected Objects
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doSelect(Criteria $criteria, PropelPDO $con = null)
{
return CcSubjsTokenPeer::populateObjects(CcSubjsTokenPeer::doSelectStmt($criteria, $con));
}
/**
* Prepares the Criteria object and uses the parent doSelect() method to execute a PDOStatement.
*
* Use this method directly if you want to work with an executed statement durirectly (for example
* to perform your own object hydration).
*
* @param Criteria $criteria The Criteria object used to build the SELECT statement.
* @param PropelPDO $con The connection to use
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
* @return PDOStatement The executed PDOStatement object.
* @see BasePeer::doSelect()
*/
public static function doSelectStmt(Criteria $criteria, PropelPDO $con = null)
{
if ($con === null) {
$con = Propel::getConnection(CcSubjsTokenPeer::DATABASE_NAME, Propel::CONNECTION_READ);
}
if (!$criteria->hasSelectClause()) {
$criteria = clone $criteria;
CcSubjsTokenPeer::addSelectColumns($criteria);
}
// Set the correct dbName
$criteria->setDbName(self::DATABASE_NAME);
// BasePeer returns a PDOStatement
return BasePeer::doSelect($criteria, $con);
}
/**
* Adds an object to the instance pool.
*
* Propel keeps cached copies of objects in an instance pool when they are retrieved
* from the database. In some cases -- especially when you override doSelect*()
* methods in your stub classes -- you may need to explicitly add objects
* to the cache in order to ensure that the same objects are always returned by doSelect*()
* and retrieveByPK*() calls.
*
* @param CcSubjsToken $value A CcSubjsToken object.
* @param string $key (optional) key to use for instance map (for performance boost if key was already calculated externally).
*/
public static function addInstanceToPool(CcSubjsToken $obj, $key = null)
{
if (Propel::isInstancePoolingEnabled()) {
if ($key === null) {
$key = (string) $obj->getDbId();
} // if key === null
self::$instances[$key] = $obj;
}
}
/**
* Removes an object from the instance pool.
*
* Propel keeps cached copies of objects in an instance pool when they are retrieved
* from the database. In some cases -- especially when you override doDelete
* methods in your stub classes -- you may need to explicitly remove objects
* from the cache in order to prevent returning objects that no longer exist.
*
* @param mixed $value A CcSubjsToken object or a primary key value.
*/
public static function removeInstanceFromPool($value)
{
if (Propel::isInstancePoolingEnabled() && $value !== null) {
if (is_object($value) && $value instanceof CcSubjsToken) {
$key = (string) $value->getDbId();
} elseif (is_scalar($value)) {
// assume we've been passed a primary key
$key = (string) $value;
} else {
$e = new PropelException("Invalid value passed to removeInstanceFromPool(). Expected primary key or CcSubjsToken object; got " . (is_object($value) ? get_class($value) . ' object.' : var_export($value,true)));
throw $e;
}
unset(self::$instances[$key]);
}
} // removeInstanceFromPool()
/**
* Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table.
*
* For tables with a single-column primary key, that simple pkey value will be returned. For tables with
* a multi-column primary key, a serialize()d version of the primary key will be returned.
*
* @param string $key The key (@see getPrimaryKeyHash()) for this instance.
* @return CcSubjsToken Found object or NULL if 1) no instance exists for specified key or 2) instance pooling has been disabled.
* @see getPrimaryKeyHash()
*/
public static function getInstanceFromPool($key)
{
if (Propel::isInstancePoolingEnabled()) {
if (isset(self::$instances[$key])) {
return self::$instances[$key];
}
}
return null; // just to be explicit
}
/**
* Clear the instance pool.
*
* @return void
*/
public static function clearInstancePool()
{
self::$instances = array();
}
/**
* Method to invalidate the instance pool of all tables related to cc_subjs_token
* by a foreign key with ON DELETE CASCADE
*/
public static function clearRelatedInstancePool()
{
}
/**
* Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table.
*
* For tables with a single-column primary key, that simple pkey value will be returned. For tables with
* a multi-column primary key, a serialize()d version of the primary key will be returned.
*
* @param array $row PropelPDO resultset row.
* @param int $startcol The 0-based offset for reading from the resultset row.
* @return string A string version of PK or NULL if the components of primary key in result array are all null.
*/
public static function getPrimaryKeyHashFromRow($row, $startcol = 0)
{
// If the PK cannot be derived from the row, return NULL.
if ($row[$startcol] === null) {
return null;
}
return (string) $row[$startcol];
}
/**
* Retrieves the primary key from the DB resultset row
* For tables with a single-column primary key, that simple pkey value will be returned. For tables with
* a multi-column primary key, an array of the primary key columns will be returned.
*
* @param array $row PropelPDO resultset row.
* @param int $startcol The 0-based offset for reading from the resultset row.
* @return mixed The primary key of the row
*/
public static function getPrimaryKeyFromRow($row, $startcol = 0)
{
return (int) $row[$startcol];
}
/**
* The returned array will contain objects of the default type or
* objects that inherit from the default.
*
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function populateObjects(PDOStatement $stmt)
{
$results = array();
// set the class once to avoid overhead in the loop
$cls = CcSubjsTokenPeer::getOMClass(false);
// populate the object(s)
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
$key = CcSubjsTokenPeer::getPrimaryKeyHashFromRow($row, 0);
if (null !== ($obj = CcSubjsTokenPeer::getInstanceFromPool($key))) {
// We no longer rehydrate the object, since this can cause data loss.
// See http://www.propelorm.org/ticket/509
// $obj->hydrate($row, 0, true); // rehydrate
$results[] = $obj;
} else {
$obj = new $cls();
$obj->hydrate($row);
$results[] = $obj;
CcSubjsTokenPeer::addInstanceToPool($obj, $key);
} // if key exists
}
$stmt->closeCursor();
return $results;
}
/**
* Populates an object of the default type or an object that inherit from the default.
*
* @param array $row PropelPDO resultset row.
* @param int $startcol The 0-based offset for reading from the resultset row.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
* @return array (CcSubjsToken object, last column rank)
*/
public static function populateObject($row, $startcol = 0)
{
$key = CcSubjsTokenPeer::getPrimaryKeyHashFromRow($row, $startcol);
if (null !== ($obj = CcSubjsTokenPeer::getInstanceFromPool($key))) {
// We no longer rehydrate the object, since this can cause data loss.
// See http://www.propelorm.org/ticket/509
// $obj->hydrate($row, $startcol, true); // rehydrate
$col = $startcol + CcSubjsTokenPeer::NUM_COLUMNS;
} else {
$cls = CcSubjsTokenPeer::OM_CLASS;
$obj = new $cls();
$col = $obj->hydrate($row, $startcol);
CcSubjsTokenPeer::addInstanceToPool($obj, $key);
}
return array($obj, $col);
}
/**
* Returns the number of rows matching criteria, joining the related CcSubjs table
*
* @param Criteria $criteria
* @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead.
* @param PropelPDO $con
* @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN
* @return int Number of matching rows.
*/
public static function doCountJoinCcSubjs(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN)
{
// we're going to modify criteria, so copy it first
$criteria = clone $criteria;
// We need to set the primary table name, since in the case that there are no WHERE columns
// it will be impossible for the BasePeer::createSelectSql() method to determine which
// tables go into the FROM clause.
$criteria->setPrimaryTableName(CcSubjsTokenPeer::TABLE_NAME);
if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) {
$criteria->setDistinct();
}
if (!$criteria->hasSelectClause()) {
CcSubjsTokenPeer::addSelectColumns($criteria);
}
$criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count
// Set the correct dbName
$criteria->setDbName(self::DATABASE_NAME);
if ($con === null) {
$con = Propel::getConnection(CcSubjsTokenPeer::DATABASE_NAME, Propel::CONNECTION_READ);
}
$criteria->addJoin(CcSubjsTokenPeer::USER_ID, CcSubjsPeer::ID, $join_behavior);
$stmt = BasePeer::doCount($criteria, $con);
if ($row = $stmt->fetch(PDO::FETCH_NUM)) {
$count = (int) $row[0];
} else {
$count = 0; // no rows returned; we infer that means 0 matches.
}
$stmt->closeCursor();
return $count;
}
/**
* Selects a collection of CcSubjsToken objects pre-filled with their CcSubjs objects.
* @param Criteria $criteria
* @param PropelPDO $con
* @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN
* @return array Array of CcSubjsToken objects.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doSelectJoinCcSubjs(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN)
{
$criteria = clone $criteria;
// Set the correct dbName if it has not been overridden
if ($criteria->getDbName() == Propel::getDefaultDB()) {
$criteria->setDbName(self::DATABASE_NAME);
}
CcSubjsTokenPeer::addSelectColumns($criteria);
$startcol = (CcSubjsTokenPeer::NUM_COLUMNS - CcSubjsTokenPeer::NUM_LAZY_LOAD_COLUMNS);
CcSubjsPeer::addSelectColumns($criteria);
$criteria->addJoin(CcSubjsTokenPeer::USER_ID, CcSubjsPeer::ID, $join_behavior);
$stmt = BasePeer::doSelect($criteria, $con);
$results = array();
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
$key1 = CcSubjsTokenPeer::getPrimaryKeyHashFromRow($row, 0);
if (null !== ($obj1 = CcSubjsTokenPeer::getInstanceFromPool($key1))) {
// We no longer rehydrate the object, since this can cause data loss.
// See http://www.propelorm.org/ticket/509
// $obj1->hydrate($row, 0, true); // rehydrate
} else {
$cls = CcSubjsTokenPeer::getOMClass(false);
$obj1 = new $cls();
$obj1->hydrate($row);
CcSubjsTokenPeer::addInstanceToPool($obj1, $key1);
} // if $obj1 already loaded
$key2 = CcSubjsPeer::getPrimaryKeyHashFromRow($row, $startcol);
if ($key2 !== null) {
$obj2 = CcSubjsPeer::getInstanceFromPool($key2);
if (!$obj2) {
$cls = CcSubjsPeer::getOMClass(false);
$obj2 = new $cls();
$obj2->hydrate($row, $startcol);
CcSubjsPeer::addInstanceToPool($obj2, $key2);
} // if obj2 already loaded
// Add the $obj1 (CcSubjsToken) to $obj2 (CcSubjs)
$obj2->addCcSubjsToken($obj1);
} // if joined row was not null
$results[] = $obj1;
}
$stmt->closeCursor();
return $results;
}
/**
* Returns the number of rows matching criteria, joining all related tables
*
* @param Criteria $criteria
* @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead.
* @param PropelPDO $con
* @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN
* @return int Number of matching rows.
*/
public static function doCountJoinAll(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN)
{
// we're going to modify criteria, so copy it first
$criteria = clone $criteria;
// We need to set the primary table name, since in the case that there are no WHERE columns
// it will be impossible for the BasePeer::createSelectSql() method to determine which
// tables go into the FROM clause.
$criteria->setPrimaryTableName(CcSubjsTokenPeer::TABLE_NAME);
if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) {
$criteria->setDistinct();
}
if (!$criteria->hasSelectClause()) {
CcSubjsTokenPeer::addSelectColumns($criteria);
}
$criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count
// Set the correct dbName
$criteria->setDbName(self::DATABASE_NAME);
if ($con === null) {
$con = Propel::getConnection(CcSubjsTokenPeer::DATABASE_NAME, Propel::CONNECTION_READ);
}
$criteria->addJoin(CcSubjsTokenPeer::USER_ID, CcSubjsPeer::ID, $join_behavior);
$stmt = BasePeer::doCount($criteria, $con);
if ($row = $stmt->fetch(PDO::FETCH_NUM)) {
$count = (int) $row[0];
} else {
$count = 0; // no rows returned; we infer that means 0 matches.
}
$stmt->closeCursor();
return $count;
}
/**
* Selects a collection of CcSubjsToken objects pre-filled with all related objects.
*
* @param Criteria $criteria
* @param PropelPDO $con
* @param String $join_behavior the type of joins to use, defaults to Criteria::LEFT_JOIN
* @return array Array of CcSubjsToken objects.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doSelectJoinAll(Criteria $criteria, $con = null, $join_behavior = Criteria::LEFT_JOIN)
{
$criteria = clone $criteria;
// Set the correct dbName if it has not been overridden
if ($criteria->getDbName() == Propel::getDefaultDB()) {
$criteria->setDbName(self::DATABASE_NAME);
}
CcSubjsTokenPeer::addSelectColumns($criteria);
$startcol2 = (CcSubjsTokenPeer::NUM_COLUMNS - CcSubjsTokenPeer::NUM_LAZY_LOAD_COLUMNS);
CcSubjsPeer::addSelectColumns($criteria);
$startcol3 = $startcol2 + (CcSubjsPeer::NUM_COLUMNS - CcSubjsPeer::NUM_LAZY_LOAD_COLUMNS);
$criteria->addJoin(CcSubjsTokenPeer::USER_ID, CcSubjsPeer::ID, $join_behavior);
$stmt = BasePeer::doSelect($criteria, $con);
$results = array();
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
$key1 = CcSubjsTokenPeer::getPrimaryKeyHashFromRow($row, 0);
if (null !== ($obj1 = CcSubjsTokenPeer::getInstanceFromPool($key1))) {
// We no longer rehydrate the object, since this can cause data loss.
// See http://www.propelorm.org/ticket/509
// $obj1->hydrate($row, 0, true); // rehydrate
} else {
$cls = CcSubjsTokenPeer::getOMClass(false);
$obj1 = new $cls();
$obj1->hydrate($row);
CcSubjsTokenPeer::addInstanceToPool($obj1, $key1);
} // if obj1 already loaded
// Add objects for joined CcSubjs rows
$key2 = CcSubjsPeer::getPrimaryKeyHashFromRow($row, $startcol2);
if ($key2 !== null) {
$obj2 = CcSubjsPeer::getInstanceFromPool($key2);
if (!$obj2) {
$cls = CcSubjsPeer::getOMClass(false);
$obj2 = new $cls();
$obj2->hydrate($row, $startcol2);
CcSubjsPeer::addInstanceToPool($obj2, $key2);
} // if obj2 loaded
// Add the $obj1 (CcSubjsToken) to the collection in $obj2 (CcSubjs)
$obj2->addCcSubjsToken($obj1);
} // if joined row not null
$results[] = $obj1;
}
$stmt->closeCursor();
return $results;
}
/**
* Returns the TableMap related to this peer.
* This method is not needed for general use but a specific application could have a need.
* @return TableMap
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function getTableMap()
{
return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME);
}
/**
* Add a TableMap instance to the database for this peer class.
*/
public static function buildTableMap()
{
$dbMap = Propel::getDatabaseMap(BaseCcSubjsTokenPeer::DATABASE_NAME);
if (!$dbMap->hasTable(BaseCcSubjsTokenPeer::TABLE_NAME))
{
$dbMap->addTableObject(new CcSubjsTokenTableMap());
}
}
/**
* The class that the Peer will make instances of.
*
* If $withPrefix is true, the returned path
* uses a dot-path notation which is tranalted into a path
* relative to a location on the PHP include_path.
* (e.g. path.to.MyClass -> 'path/to/MyClass.php')
*
* @param boolean $withPrefix Whether or not to return the path with the class name
* @return string path.to.ClassName
*/
public static function getOMClass($withPrefix = true)
{
return $withPrefix ? CcSubjsTokenPeer::CLASS_DEFAULT : CcSubjsTokenPeer::OM_CLASS;
}
/**
* Method perform an INSERT on the database, given a CcSubjsToken or Criteria object.
*
* @param mixed $values Criteria or CcSubjsToken object containing data that is used to create the INSERT statement.
* @param PropelPDO $con the PropelPDO connection to use
* @return mixed The new primary key.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doInsert($values, PropelPDO $con = null)
{
if ($con === null) {
$con = Propel::getConnection(CcSubjsTokenPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
}
if ($values instanceof Criteria) {
$criteria = clone $values; // rename for clarity
} else {
$criteria = $values->buildCriteria(); // build Criteria from CcSubjsToken object
}
if ($criteria->containsKey(CcSubjsTokenPeer::ID) && $criteria->keyContainsValue(CcSubjsTokenPeer::ID) ) {
throw new PropelException('Cannot insert a value for auto-increment primary key ('.CcSubjsTokenPeer::ID.')');
}
// Set the correct dbName
$criteria->setDbName(self::DATABASE_NAME);
try {
// use transaction because $criteria could contain info
// for more than one table (I guess, conceivably)
$con->beginTransaction();
$pk = BasePeer::doInsert($criteria, $con);
$con->commit();
} catch(PropelException $e) {
$con->rollBack();
throw $e;
}
return $pk;
}
/**
* Method perform an UPDATE on the database, given a CcSubjsToken or Criteria object.
*
* @param mixed $values Criteria or CcSubjsToken object containing data that is used to create the UPDATE statement.
* @param PropelPDO $con The connection to use (specify PropelPDO connection object to exert more control over transactions).
* @return int The number of affected rows (if supported by underlying database driver).
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doUpdate($values, PropelPDO $con = null)
{
if ($con === null) {
$con = Propel::getConnection(CcSubjsTokenPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
}
$selectCriteria = new Criteria(self::DATABASE_NAME);
if ($values instanceof Criteria) {
$criteria = clone $values; // rename for clarity
$comparison = $criteria->getComparison(CcSubjsTokenPeer::ID);
$value = $criteria->remove(CcSubjsTokenPeer::ID);
if ($value) {
$selectCriteria->add(CcSubjsTokenPeer::ID, $value, $comparison);
} else {
$selectCriteria->setPrimaryTableName(CcSubjsTokenPeer::TABLE_NAME);
}
} else { // $values is CcSubjsToken object
$criteria = $values->buildCriteria(); // gets full criteria
$selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s)
}
// set the correct dbName
$criteria->setDbName(self::DATABASE_NAME);
return BasePeer::doUpdate($selectCriteria, $criteria, $con);
}
/**
* Method to DELETE all rows from the cc_subjs_token table.
*
* @return int The number of affected rows (if supported by underlying database driver).
*/
public static function doDeleteAll($con = null)
{
if ($con === null) {
$con = Propel::getConnection(CcSubjsTokenPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
}
$affectedRows = 0; // initialize var to track total num of affected rows
try {
// use transaction because $criteria could contain info
// for more than one table or we could emulating ON DELETE CASCADE, etc.
$con->beginTransaction();
$affectedRows += BasePeer::doDeleteAll(CcSubjsTokenPeer::TABLE_NAME, $con, CcSubjsTokenPeer::DATABASE_NAME);
// Because this db requires some delete cascade/set null emulation, we have to
// clear the cached instance *after* the emulation has happened (since
// instances get re-added by the select statement contained therein).
CcSubjsTokenPeer::clearInstancePool();
CcSubjsTokenPeer::clearRelatedInstancePool();
$con->commit();
return $affectedRows;
} catch (PropelException $e) {
$con->rollBack();
throw $e;
}
}
/**
* Method perform a DELETE on the database, given a CcSubjsToken or Criteria object OR a primary key value.
*
* @param mixed $values Criteria or CcSubjsToken object or primary key or array of primary keys
* which is used to create the DELETE statement
* @param PropelPDO $con the connection to use
* @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows
* if supported by native driver or if emulated using Propel.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doDelete($values, PropelPDO $con = null)
{
if ($con === null) {
$con = Propel::getConnection(CcSubjsTokenPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
}
if ($values instanceof Criteria) {
// invalidate the cache for all objects of this type, since we have no
// way of knowing (without running a query) what objects should be invalidated
// from the cache based on this Criteria.
CcSubjsTokenPeer::clearInstancePool();
// rename for clarity
$criteria = clone $values;
} elseif ($values instanceof CcSubjsToken) { // it's a model object
// invalidate the cache for this single object
CcSubjsTokenPeer::removeInstanceFromPool($values);
// create criteria based on pk values
$criteria = $values->buildPkeyCriteria();
} else { // it's a primary key, or an array of pks
$criteria = new Criteria(self::DATABASE_NAME);
$criteria->add(CcSubjsTokenPeer::ID, (array) $values, Criteria::IN);
// invalidate the cache for this object(s)
foreach ((array) $values as $singleval) {
CcSubjsTokenPeer::removeInstanceFromPool($singleval);
}
}
// Set the correct dbName
$criteria->setDbName(self::DATABASE_NAME);
$affectedRows = 0; // initialize var to track total num of affected rows
try {
// use transaction because $criteria could contain info
// for more than one table or we could emulating ON DELETE CASCADE, etc.
$con->beginTransaction();
$affectedRows += BasePeer::doDelete($criteria, $con);
CcSubjsTokenPeer::clearRelatedInstancePool();
$con->commit();
return $affectedRows;
} catch (PropelException $e) {
$con->rollBack();
throw $e;
}
}
/**
* Validates all modified columns of given CcSubjsToken object.
* If parameter $columns is either a single column name or an array of column names
* than only those columns are validated.
*
* NOTICE: This does not apply to primary or foreign keys for now.
*
* @param CcSubjsToken $obj The object to validate.
* @param mixed $cols Column name or array of column names.
*
* @return mixed TRUE if all columns are valid or the error message of the first invalid column.
*/
public static function doValidate(CcSubjsToken $obj, $cols = null)
{
$columns = array();
if ($cols) {
$dbMap = Propel::getDatabaseMap(CcSubjsTokenPeer::DATABASE_NAME);
$tableMap = $dbMap->getTable(CcSubjsTokenPeer::TABLE_NAME);
if (! is_array($cols)) {
$cols = array($cols);
}
foreach ($cols as $colName) {
if ($tableMap->containsColumn($colName)) {
$get = 'get' . $tableMap->getColumn($colName)->getPhpName();
$columns[$colName] = $obj->$get();
}
}
} else {
}
return BasePeer::doValidate(CcSubjsTokenPeer::DATABASE_NAME, CcSubjsTokenPeer::TABLE_NAME, $columns);
}
/**
* Retrieve a single object by pkey.
*
* @param int $pk the primary key.
* @param PropelPDO $con the connection to use
* @return CcSubjsToken
*/
public static function retrieveByPK($pk, PropelPDO $con = null)
{
if (null !== ($obj = CcSubjsTokenPeer::getInstanceFromPool((string) $pk))) {
return $obj;
}
if ($con === null) {
$con = Propel::getConnection(CcSubjsTokenPeer::DATABASE_NAME, Propel::CONNECTION_READ);
}
$criteria = new Criteria(CcSubjsTokenPeer::DATABASE_NAME);
$criteria->add(CcSubjsTokenPeer::ID, $pk);
$v = CcSubjsTokenPeer::doSelect($criteria, $con);
return !empty($v) > 0 ? $v[0] : null;
}
/**
* Retrieve multiple objects by pkey.
*
* @param array $pks List of primary keys
* @param PropelPDO $con the connection to use
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function retrieveByPKs($pks, PropelPDO $con = null)
{
if ($con === null) {
$con = Propel::getConnection(CcSubjsTokenPeer::DATABASE_NAME, Propel::CONNECTION_READ);
}
$objs = null;
if (empty($pks)) {
$objs = array();
} else {
$criteria = new Criteria(CcSubjsTokenPeer::DATABASE_NAME);
$criteria->add(CcSubjsTokenPeer::ID, $pks, Criteria::IN);
$objs = CcSubjsTokenPeer::doSelect($criteria, $con);
}
return $objs;
}
} // BaseCcSubjsTokenPeer
// This is the static code needed to register the TableMap for this table with the main Propel class.
//
BaseCcSubjsTokenPeer::buildTableMap();

View File

@ -0,0 +1,355 @@
<?php
/**
* Base class that represents a query for the 'cc_subjs_token' table.
*
*
*
* @method CcSubjsTokenQuery orderByDbId($order = Criteria::ASC) Order by the id column
* @method CcSubjsTokenQuery orderByDbUserId($order = Criteria::ASC) Order by the user_id column
* @method CcSubjsTokenQuery orderByDbAction($order = Criteria::ASC) Order by the action column
* @method CcSubjsTokenQuery orderByDbToken($order = Criteria::ASC) Order by the token column
* @method CcSubjsTokenQuery orderByDbCreated($order = Criteria::ASC) Order by the created column
*
* @method CcSubjsTokenQuery groupByDbId() Group by the id column
* @method CcSubjsTokenQuery groupByDbUserId() Group by the user_id column
* @method CcSubjsTokenQuery groupByDbAction() Group by the action column
* @method CcSubjsTokenQuery groupByDbToken() Group by the token column
* @method CcSubjsTokenQuery groupByDbCreated() Group by the created column
*
* @method CcSubjsTokenQuery leftJoin($relation) Adds a LEFT JOIN clause to the query
* @method CcSubjsTokenQuery rightJoin($relation) Adds a RIGHT JOIN clause to the query
* @method CcSubjsTokenQuery innerJoin($relation) Adds a INNER JOIN clause to the query
*
* @method CcSubjsTokenQuery leftJoinCcSubjs($relationAlias = '') Adds a LEFT JOIN clause to the query using the CcSubjs relation
* @method CcSubjsTokenQuery rightJoinCcSubjs($relationAlias = '') Adds a RIGHT JOIN clause to the query using the CcSubjs relation
* @method CcSubjsTokenQuery innerJoinCcSubjs($relationAlias = '') Adds a INNER JOIN clause to the query using the CcSubjs relation
*
* @method CcSubjsToken findOne(PropelPDO $con = null) Return the first CcSubjsToken matching the query
* @method CcSubjsToken findOneOrCreate(PropelPDO $con = null) Return the first CcSubjsToken matching the query, or a new CcSubjsToken object populated from the query conditions when no match is found
*
* @method CcSubjsToken findOneByDbId(int $id) Return the first CcSubjsToken filtered by the id column
* @method CcSubjsToken findOneByDbUserId(int $user_id) Return the first CcSubjsToken filtered by the user_id column
* @method CcSubjsToken findOneByDbAction(string $action) Return the first CcSubjsToken filtered by the action column
* @method CcSubjsToken findOneByDbToken(string $token) Return the first CcSubjsToken filtered by the token column
* @method CcSubjsToken findOneByDbCreated(string $created) Return the first CcSubjsToken filtered by the created column
*
* @method array findByDbId(int $id) Return CcSubjsToken objects filtered by the id column
* @method array findByDbUserId(int $user_id) Return CcSubjsToken objects filtered by the user_id column
* @method array findByDbAction(string $action) Return CcSubjsToken objects filtered by the action column
* @method array findByDbToken(string $token) Return CcSubjsToken objects filtered by the token column
* @method array findByDbCreated(string $created) Return CcSubjsToken objects filtered by the created column
*
* @package propel.generator.airtime.om
*/
abstract class BaseCcSubjsTokenQuery extends ModelCriteria
{
/**
* Initializes internal state of BaseCcSubjsTokenQuery object.
*
* @param string $dbName The dabase name
* @param string $modelName The phpName of a model, e.g. 'Book'
* @param string $modelAlias The alias for the model in this query, e.g. 'b'
*/
public function __construct($dbName = 'airtime', $modelName = 'CcSubjsToken', $modelAlias = null)
{
parent::__construct($dbName, $modelName, $modelAlias);
}
/**
* Returns a new CcSubjsTokenQuery object.
*
* @param string $modelAlias The alias of a model in the query
* @param Criteria $criteria Optional Criteria to build the query from
*
* @return CcSubjsTokenQuery
*/
public static function create($modelAlias = null, $criteria = null)
{
if ($criteria instanceof CcSubjsTokenQuery) {
return $criteria;
}
$query = new CcSubjsTokenQuery();
if (null !== $modelAlias) {
$query->setModelAlias($modelAlias);
}
if ($criteria instanceof Criteria) {
$query->mergeWith($criteria);
}
return $query;
}
/**
* Find object by primary key
* Use instance pooling to avoid a database query if the object exists
* <code>
* $obj = $c->findPk(12, $con);
* </code>
* @param mixed $key Primary key to use for the query
* @param PropelPDO $con an optional connection object
*
* @return CcSubjsToken|array|mixed the result, formatted by the current formatter
*/
public function findPk($key, $con = null)
{
if ((null !== ($obj = CcSubjsTokenPeer::getInstanceFromPool((string) $key))) && $this->getFormatter()->isObjectFormatter()) {
// the object is alredy in the instance pool
return $obj;
} else {
// the object has not been requested yet, or the formatter is not an object formatter
$criteria = $this->isKeepQuery() ? clone $this : $this;
$stmt = $criteria
->filterByPrimaryKey($key)
->getSelectStatement($con);
return $criteria->getFormatter()->init($criteria)->formatOne($stmt);
}
}
/**
* Find objects by primary key
* <code>
* $objs = $c->findPks(array(12, 56, 832), $con);
* </code>
* @param array $keys Primary keys to use for the query
* @param PropelPDO $con an optional connection object
*
* @return PropelObjectCollection|array|mixed the list of results, formatted by the current formatter
*/
public function findPks($keys, $con = null)
{
$criteria = $this->isKeepQuery() ? clone $this : $this;
return $this
->filterByPrimaryKeys($keys)
->find($con);
}
/**
* Filter the query by primary key
*
* @param mixed $key Primary key to use for the query
*
* @return CcSubjsTokenQuery The current query, for fluid interface
*/
public function filterByPrimaryKey($key)
{
return $this->addUsingAlias(CcSubjsTokenPeer::ID, $key, Criteria::EQUAL);
}
/**
* Filter the query by a list of primary keys
*
* @param array $keys The list of primary key to use for the query
*
* @return CcSubjsTokenQuery The current query, for fluid interface
*/
public function filterByPrimaryKeys($keys)
{
return $this->addUsingAlias(CcSubjsTokenPeer::ID, $keys, Criteria::IN);
}
/**
* Filter the query on the id column
*
* @param int|array $dbId 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 CcSubjsTokenQuery The current query, for fluid interface
*/
public function filterByDbId($dbId = null, $comparison = null)
{
if (is_array($dbId) && null === $comparison) {
$comparison = Criteria::IN;
}
return $this->addUsingAlias(CcSubjsTokenPeer::ID, $dbId, $comparison);
}
/**
* Filter the query on the user_id column
*
* @param int|array $dbUserId 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 CcSubjsTokenQuery The current query, for fluid interface
*/
public function filterByDbUserId($dbUserId = null, $comparison = null)
{
if (is_array($dbUserId)) {
$useMinMax = false;
if (isset($dbUserId['min'])) {
$this->addUsingAlias(CcSubjsTokenPeer::USER_ID, $dbUserId['min'], Criteria::GREATER_EQUAL);
$useMinMax = true;
}
if (isset($dbUserId['max'])) {
$this->addUsingAlias(CcSubjsTokenPeer::USER_ID, $dbUserId['max'], Criteria::LESS_EQUAL);
$useMinMax = true;
}
if ($useMinMax) {
return $this;
}
if (null === $comparison) {
$comparison = Criteria::IN;
}
}
return $this->addUsingAlias(CcSubjsTokenPeer::USER_ID, $dbUserId, $comparison);
}
/**
* Filter the query on the action column
*
* @param string $dbAction The value to use as filter.
* Accepts wildcards (* and % trigger a LIKE)
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return CcSubjsTokenQuery The current query, for fluid interface
*/
public function filterByDbAction($dbAction = null, $comparison = null)
{
if (null === $comparison) {
if (is_array($dbAction)) {
$comparison = Criteria::IN;
} elseif (preg_match('/[\%\*]/', $dbAction)) {
$dbAction = str_replace('*', '%', $dbAction);
$comparison = Criteria::LIKE;
}
}
return $this->addUsingAlias(CcSubjsTokenPeer::ACTION, $dbAction, $comparison);
}
/**
* Filter the query on the token column
*
* @param string $dbToken The value to use as filter.
* Accepts wildcards (* and % trigger a LIKE)
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return CcSubjsTokenQuery The current query, for fluid interface
*/
public function filterByDbToken($dbToken = null, $comparison = null)
{
if (null === $comparison) {
if (is_array($dbToken)) {
$comparison = Criteria::IN;
} elseif (preg_match('/[\%\*]/', $dbToken)) {
$dbToken = str_replace('*', '%', $dbToken);
$comparison = Criteria::LIKE;
}
}
return $this->addUsingAlias(CcSubjsTokenPeer::TOKEN, $dbToken, $comparison);
}
/**
* Filter the query on the created column
*
* @param string|array $dbCreated 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 CcSubjsTokenQuery The current query, for fluid interface
*/
public function filterByDbCreated($dbCreated = null, $comparison = null)
{
if (is_array($dbCreated)) {
$useMinMax = false;
if (isset($dbCreated['min'])) {
$this->addUsingAlias(CcSubjsTokenPeer::CREATED, $dbCreated['min'], Criteria::GREATER_EQUAL);
$useMinMax = true;
}
if (isset($dbCreated['max'])) {
$this->addUsingAlias(CcSubjsTokenPeer::CREATED, $dbCreated['max'], Criteria::LESS_EQUAL);
$useMinMax = true;
}
if ($useMinMax) {
return $this;
}
if (null === $comparison) {
$comparison = Criteria::IN;
}
}
return $this->addUsingAlias(CcSubjsTokenPeer::CREATED, $dbCreated, $comparison);
}
/**
* Filter the query by a related CcSubjs object
*
* @param CcSubjs $ccSubjs the related object to use as filter
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return CcSubjsTokenQuery The current query, for fluid interface
*/
public function filterByCcSubjs($ccSubjs, $comparison = null)
{
return $this
->addUsingAlias(CcSubjsTokenPeer::USER_ID, $ccSubjs->getDbId(), $comparison);
}
/**
* Adds a JOIN clause to the query using the CcSubjs relation
*
* @param string $relationAlias optional alias for the relation
* @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'
*
* @return CcSubjsTokenQuery The current query, for fluid interface
*/
public function joinCcSubjs($relationAlias = '', $joinType = Criteria::INNER_JOIN)
{
$tableMap = $this->getTableMap();
$relationMap = $tableMap->getRelation('CcSubjs');
// create a ModelJoin object for this join
$join = new ModelJoin();
$join->setJoinType($joinType);
$join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias);
if ($previousJoin = $this->getPreviousJoin()) {
$join->setPreviousJoin($previousJoin);
}
// add the ModelJoin to the current object
if($relationAlias) {
$this->addAlias($relationAlias, $relationMap->getRightTable()->getName());
$this->addJoinObject($join, $relationAlias);
} else {
$this->addJoinObject($join, 'CcSubjs');
}
return $this;
}
/**
* Use the CcSubjs relation CcSubjs object
*
* @see useQuery()
*
* @param string $relationAlias optional alias for the relation,
* to be used as main alias in the secondary query
* @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'
*
* @return CcSubjsQuery A secondary query class using the current class as primary query
*/
public function useCcSubjsQuery($relationAlias = '', $joinType = Criteria::INNER_JOIN)
{
return $this
->joinCcSubjs($relationAlias, $joinType)
->useQuery($relationAlias ? $relationAlias : 'CcSubjs', 'CcSubjsQuery');
}
/**
* Exclude object from result
*
* @param CcSubjsToken $ccSubjsToken Object to remove from the list of results
*
* @return CcSubjsTokenQuery The current query, for fluid interface
*/
public function prune($ccSubjsToken = null)
{
if ($ccSubjsToken) {
$this->addUsingAlias(CcSubjsTokenPeer::ID, $ccSubjsToken->getDbId(), Criteria::NOT_EQUAL);
}
return $this;
}
} // BaseCcSubjsTokenQuery

View File

@ -2,7 +2,7 @@
require_once(dirname(__FILE__).'/../StoredFile.php');
$dsn = $CC_CONFIG['dsn'];
$CC_DBC = DB::connect($dsn, TRUE);
$CC_DBC = DB::connect($dsn, FALSE);
if (PEAR::isError($CC_DBC)) {
echo "ERROR: ".$CC_DBC->getMessage()." ".$CC_DBC->getUserInfo()."\n";
exit(1);

View File

@ -0,0 +1 @@
<div><?php echo $this->form ?></div>

View File

@ -0,0 +1 @@
<div>Email sent</div>

View File

@ -0,0 +1 @@
<div><?php echo $this->form ?></div>

View File

@ -1,8 +1,8 @@
<div class="text-content">
<h2>About</h2>
<p>
<a href="http://airtime.sourcefabric.org">Airtime</a> <?php echo $this->airtime_version ?>, the open radio software for scheduling and remote station management.<br>
© 2011 <a href="http://www.sourcefabric.org">Sourcefabric</a> o.p.s 2011. Airtime is distributed under the <a href="http://www.gnu.org/licenses/gpl-3.0-standalone.html">GNU GPL v.3</a>
<a href="http://airtime.sourcefabric.org" target="_blank">Airtime</a> <?php echo $this->airtime_version ?>, the open radio software for scheduling and remote station management.<br>
© 2011 <a href="http://www.sourcefabric.org" target="_blank">Sourcefabric</a> o.p.s 2011. Airtime is distributed under the <a href="http://www.gnu.org/licenses/gpl-3.0-standalone.html" target="_blank">GNU GPL v.3</a>
</p>
</div>
<br>

View File

@ -27,29 +27,6 @@
</ul>
<?php endif; ?>
</dd>
<dt id="streamFormat-label" class="block-display">
<label class="optional"><?php echo $this->element->getElement('streamFormat')->getLabel() ?></label>
</dt>
<dd id="streamFormat-element" class="block-display radio-inline-list">
<?php $i=0;
$value = $this->element->getElement('streamFormat')->getValue();
?>
<?php foreach ($this->element->getElement('streamFormat')->getMultiOptions() as $radio) : ?>
<label for="streamFormat-<?php echo $i ?>">
<input type="radio" value="<?php echo $i ?>" id="streamFormat-<?php echo $i ?>" name="streamFormat" <?php if($i == $value){echo 'checked="checked"';}?> >
<?php echo $radio ?>
</input>
</label>
<?php $i = $i + 1; ?>
<?php endforeach; ?>
<?php if($this->element->getElement('streamFormat')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach($this->element->getElement('streamFormat')->getMessages() as $error): ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
<dt id="thirdPartyApi-label" class="block-display">
<label class="optional"><?php echo $this->element->getElement('thirdPartyApi')->getLabel() ?></label>
</dt>

View File

@ -15,6 +15,7 @@
<div><span>Copyright:</span><span><?php echo ($this->md["MDATA_KEY_COPYRIGHT"]);?></span></div>
<div><span>Isrc Number:</span><span><?php echo ($this->md["MDATA_KEY_ISRC"]);?></span></div>
<div><span>Website:</span><span><?php echo ($this->md["MDATA_KEY_URL"]);?></span></div>
<div><span>Language:</span><span><?php echo ($this->md["MDATA_KEY_LANGUAGE"]);?></span></div>
<?php endif; ?>

View File

@ -5,18 +5,7 @@
<div id="simpleSearch">
<div id="import_status" style="visibility:hidden">File import in progress...</div>
<table id="library_display" cellpadding="0" cellspacing="0" class="datatable">
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>Creator</th>
<th>Album</th>
<th>Genre</th>
<th>Length</th>
<th>Type</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<!--

View File

@ -42,6 +42,29 @@
<dd id="vorbisMetadata-element">
<?php echo $this->form->getElement('icecast_vorbis_metadata') ?>
</dd>
<dt id="streamFormat-label" class="block-display">
<label class="optional"><?php echo $this->form->getElement('streamFormat')->getLabel() ?></label>
</dt>
<dd id="streamFormat-element" class="block-display radio-inline-list">
<?php $i=0;
$value = $this->form->getElement('streamFormat')->getValue();
?>
<?php foreach ($this->form->getElement('streamFormat')->getMultiOptions() as $radio) : ?>
<label for="streamFormat-<?php echo $i ?>">
<input type="radio" value="<?php echo $i ?>" id="streamFormat-<?php echo $i ?>" name="streamFormat" <?php if($i == $value){echo 'checked="checked"';}?> >
<?php echo $radio ?>
</input>
</label>
<?php $i = $i + 1; ?>
<?php endforeach; ?>
<?php if($this->form->getElement('streamFormat')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach($this->form->getElement('streamFormat')->getMessages() as $error): ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
</dl>
</fieldset>
<?php

View File

@ -24,4 +24,10 @@
<?php $i=$i+1; ?>
<?php endforeach; ?>
</table>
<br/>
<div id="show_time_info">
<span id="show_time_filled" class="time"><?php echo $this->timeFilled; ?></span>
<div id="show_progressbar"></div>
<span id="show_length" class="time"><?php echo $this->showLength; ?></span>
</div>
</div>

View File

@ -325,6 +325,19 @@
<unique-column name="login"/>
</unique>
</table>
<table name="cc_subjs_token" phpName="CcSubjsToken">
<column name="id" phpName="DbId" type="INTEGER" primaryKey="true" autoIncrement="true" required="true"/>
<column name="user_id" phpName="DbUserId" type="INTEGER" required="true"/>
<column name="action" phpName="DbAction" type="VARCHAR" size="255" required="true"/>
<column name="token" phpName="DbToken" type="VARCHAR" size="40" required="true"/>
<column name="created" phpName="DbCreated" type="TIMESTAMP" required="true"/>
<unique name="cc_subjs_token_idx">
<unique-column name="token"/>
</unique>
<foreign-key foreignTable="cc_subjs" name="cc_subjs_token_userid_fkey" onDelete="CASCADE">
<reference local="user_id" foreign="id"/>
</foreign-key>
</table>
<table name="cc_country" phpName="CcCountry">
<column name="isocode" phpName="DbIsoCode" primaryKey="true" type="CHAR" size="3" required="true"/>
<column name="name" phpName="DbName" type="VARCHAR" size="255" required="true"/>

View File

@ -448,6 +448,28 @@ CREATE TABLE "cc_subjs"
COMMENT ON TABLE "cc_subjs" IS '';
SET search_path TO public;
-----------------------------------------------------------------------------
-- cc_subjs_token
-----------------------------------------------------------------------------
DROP TABLE "cc_subjs_token" CASCADE;
CREATE TABLE "cc_subjs_token"
(
"id" serial NOT NULL,
"user_id" INTEGER NOT NULL,
"action" VARCHAR(255) NOT NULL,
"token" VARCHAR(40) NOT NULL,
"created" TIMESTAMP NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "cc_subjs_token_idx" UNIQUE ("token")
);
COMMENT ON TABLE "cc_subjs_token" IS '';
SET search_path TO public;
-----------------------------------------------------------------------------
-- cc_country
@ -557,3 +579,5 @@ ALTER TABLE "cc_schedule" ADD CONSTRAINT "cc_show_inst_fkey" FOREIGN KEY ("insta
ALTER TABLE "cc_schedule" ADD CONSTRAINT "cc_show_file_fkey" FOREIGN KEY ("file_id") REFERENCES "cc_files" ("id") ON DELETE CASCADE;
ALTER TABLE "cc_sess" ADD CONSTRAINT "cc_sess_userid_fkey" FOREIGN KEY ("userid") REFERENCES "cc_subjs" ("id") ON DELETE CASCADE;
ALTER TABLE "cc_subjs_token" ADD CONSTRAINT "cc_subjs_token_userid_fkey" FOREIGN KEY ("user_id") REFERENCES "cc_subjs" ("id") ON DELETE CASCADE;

View File

@ -3,6 +3,7 @@ php_value upload_max_filesize 500M
php_value request_order "GPC"
php_value session.gc_probability 0
php_value phar.readonly Off
php_value session.auto_start 0
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]

View File

@ -25,7 +25,10 @@
}
#side_playlist button {
font-size: 12px;
float: left;
font-size: 12px;
height: 28px;
margin: 0 7px 20px 0;
}
#side_playlist input,

View File

@ -1158,6 +1158,9 @@ h2#scheduled_playlist_name span {
}
.ui-button-icon-only.crossfade-main-button, .ui-button-icons-only.crossfade-main-button {
float: left;
height: 26px;
margin: 0 0 20px 0;
padding-right: 8px;
}
.ui-button-icon-only.crossfade-main-button .ui-button-text, .ui-button-icons-only.crossfade-main-button .ui-button-text {

View File

@ -315,12 +315,12 @@ function createDataTable(data) {
"fnDrawCallback": dtDrawCallback,
"aoColumns": [
/* Id */ { "sName": "id", "bSearchable": false, "bVisible": false },
/* Title */ { "sName": "track_title" },
/* Creator */ { "sName": "artist_name" },
/* Album */ { "sName": "album_title" },
/* Genre */ { "sName": "genre" },
/* Length */ { "sName": "length" },
/* Type */ { "sName": "ftype", "bSearchable": false }
/* Title */ { "sTitle": "Title", "sName": "track_title" },
/* Creator */ { "sTitle": "Creator", "sName": "artist_name" },
/* Album */ { "sTitle": "Album", "sName": "album_title" },
/* Genre */ { "sTitle": "Genre", "sName": "genre" },
/* Length */ { "sTitle": "Length", "sName": "length" },
/* Type */ { "sTitle": "Type", "sName": "ftype", "bSearchable": false }
],
"aaSorting": [[2,'asc']],
"sPaginationType": "full_numbers",

View File

@ -6,6 +6,7 @@ $(document).ready(function() {
runtimes : 'gears, html5, html4',
url : '/Plupload/upload/format/json',
chunk_size: '5mb',
unique_names: 'true',
multiple_queues : 'true',
filters : [
{title: "Audio Files", extensions: "ogg,mp3"}
@ -52,7 +53,6 @@ $(document).ready(function() {
uploadProgress = false;
});
$(window).bind('beforeunload', function(){
if(uploadProgress){
if(!confirm("You are currently uploading files.\nGoing to another screen will cancel the upload process.\nAre you sure you want to cancel the upload process and go to the screen you clicked on?")){

View File

@ -38,7 +38,7 @@ function changeCueIn(event) {
span = $(this);
pos = span.parent().attr("id").split("_").pop();
url = "/Playlist/set-cue";
cueIn = span.text().trim();
cueIn = $.trim(span.text());
li = span.parent().parent().parent().parent();
unqid = li.attr("unqid");
@ -71,7 +71,7 @@ function changeCueOut(event) {
span = $(this);
pos = span.parent().attr("id").split("_").pop();
url = "/Playlist/set-cue";
cueOut = span.text().trim();
cueOut = $.trim(span.text());
li = span.parent().parent().parent().parent();
unqid = li.attr("unqid");
@ -104,7 +104,7 @@ function changeFadeIn(event) {
span = $(this);
pos = span.parent().attr("id").split("_").pop();
url = "/Playlist/set-fade";
fadeIn = span.text().trim();
fadeIn = $.trim(span.text());
li = span.parent().parent().parent().parent();
unqid = li.attr("unqid");
@ -136,7 +136,7 @@ function changeFadeOut(event) {
span = $(this);
pos = span.parent().attr("id").split("_").pop();
url = "/Playlist/set-fade";
fadeOut = span.text().trim();
fadeOut = $.trim(span.text());
li = span.parent().parent().parent().parent();
unqid = li.attr("unqid");
@ -476,7 +476,7 @@ function setUpSPL() {
span = $(this);
url = "/Playlist/set-playlist-fades";
fadeIn = span.text().trim();
fadeIn = $.trim(span.text());
if(!isTimeValid(fadeIn)){
showError(span, "please put in a time '00:00:00 (.000000)'");
@ -502,7 +502,7 @@ function setUpSPL() {
span = $(this);
url = "/Playlist/set-playlist-fades";
fadeOut = span.text().trim();
fadeOut = $.trim(span.text());
if(!isTimeValid(fadeOut)){
showError(span, "please put in a time '00:00:00 (.000000)'");

View File

@ -174,5 +174,18 @@ $(document).ready(function() {
showErrorSections()
setInterval('checkLiquidsoapStatus()', 1000)
$.mask.rules = {
'@': /[^ &<>]/,
'u': /[0-9a-zA-Z-_.:/]/,
'd': /[0-9a-zA-Z-_.]/
}
// add masking on the fields that don't allow special chars
$.mask.masks = $.extend($.mask.masks,{
regular_text:{ mask: '@', type:'repeat', 'maxLength': 256, selectCharsOnFocus: false, autoTab: false, fixedChars : '[(),:/]'},
url:{ mask: 'u', type:'repeat', 'maxLength': 261, selectCharsOnFocus: false, autoTab: false, fixedChars : '[(),]'},
domain:{ mask: 'd', type:'repeat', 'maxLength': 261, selectCharsOnFocus: false, autoTab: false, fixedChars : '[(),:/]'}
})
$('input:text').setMask()
});

View File

@ -11,8 +11,6 @@ function startDpSelect(dateText, inst) {
time = dateText.split("-");
date = new Date(time[0], time[1] - 1, time[2]);
$("#add_show_end_date").datepicker("option", "minDate", date);
$('input[name^="add_show_rebroadcast_absolute_date"]').datepicker("option", "minDate", date);
if (inst.input)
inst.input.trigger('change');
}
@ -33,7 +31,9 @@ function createDateInput(el, onSelect) {
el.datepicker({
minDate: adjustDateToServerDate(new Date(), timezoneOffset),
onSelect: onSelect,
dateFormat: 'yy-mm-dd'
dateFormat: 'yy-mm-dd',
closeText: 'Close',
showButtonPanel: true
});
}
@ -180,7 +180,7 @@ function setAddShowEvents() {
form.find("#add_show_start_time").timepicker({
amPmText: ['', ''],
defaultTime: '00:00'
defaultTime: '00:00',
});
form.find("#add_show_end_time").timepicker({
amPmText: ['', '']
@ -188,7 +188,9 @@ function setAddShowEvents() {
form.find('input[name^="add_show_rebroadcast_date_absolute"]').datepicker({
minDate: adjustDateToServerDate(new Date(), timezoneOffset),
dateFormat: 'yy-mm-dd'
dateFormat: 'yy-mm-dd',
closeText: 'Close',
showButtonPanel: true
});
form.find('input[name^="add_show_rebroadcast_time"]').timepicker({
amPmText: ['', ''],
@ -442,13 +444,7 @@ function showErrorSections() {
}
$(document).ready(function() {
$.mask.masks = $.extend($.mask.masks,{
date:{ mask: '9999-19-39'},
time:{ mask: '29:69'}
})
$('input:text').setMask()
//setAddShowEvents();
setAddShowEvents();
});
//Alert the error and reload the page
@ -475,15 +471,3 @@ $(window).resize(function(){
$("#schedule_calendar").fullCalendar('render');
});
$(window).load(function() {
$.mask.masks = $.extend($.mask.masks,{
date:{ mask: '9999-19-39'},
time:{ mask: '29:69'}
})
$('input:text').setMask()
setAddShowEvents();
});

View File

@ -37,6 +37,13 @@ function openAddShowForm() {
$add_show_name.select();
});
}
$.mask.masks = $.extend($.mask.masks,{
date:{ mask: '9999-19-39', selectCharsOnFocus: true, autoTab: false},
time:{ mask: '29:69', selectCharsOnFocus: true, autoTab: false}
})
$('input:text').setMask()
}
function makeAddShowButton(){
@ -116,23 +123,34 @@ function dayClick(date, allDay, jsEvent, view) {
$(span).remove();
}
// 1 hr
var duration = 60 * 60* 1000;
// get current duration value on the form
var duration_string = $.trim($("#add_show_duration").val());
var duration_info = duration_string.split(" ");
var duration_h = 0;
var duration_m = 0;
if(duration_info[0] != null){
duration_h = parseInt(duration_info[0], 10);
}
if(duration_info[1] != null){
duration_m = parseInt(duration_info[1], 10);
}
// duration in milisec
var duration = (duration_h * 60 * 60 * 1000) + (duration_m * 60 * 1000);
var endDateTime = new Date(selected.getTime() + duration);
// get start time value on the form
var startTime_string = $("#add_show_start_time").val();
var startTime_info = startTime_string.split(':');
var startTime = (parseInt(startTime_info[0],10) * 60 * 60 * 1000) + (parseInt(startTime_info[1], 10) * 60 * 1000);
// calculate endDateTime
var endDateTime = new Date(selected.getTime() + startTime + duration);
chosenDate = selected.getFullYear() + '-' + pad(selected.getMonth()+1,2) + '-' + pad(selected.getDate(),2);
chosenTime = pad(selected.getHours(),2) + ':' + pad(selected.getMinutes(),2);
var endDateFormat = endDateTime.getFullYear() + '-' + pad(endDateTime.getMonth()+1,2) + '-' + pad(endDateTime.getDate(),2);
var endTimeFormat = pad(endDateTime.getHours(),2) + ':' + pad(endDateTime.getMinutes(),2);
$("#add_show_start_date").val(chosenDate);
$("#add_show_end_date_no_repeat").val(endDateFormat);
$("#add_show_end_date").datepicker("option", "minDate", endDateFormat);
$("#add_show_end_date").val(endDateFormat);
$("#add_show_start_time").val(chosenTime);
$("#add_show_end_time").val(endTimeFormat);
$("#add_show_duration").val('1h');
$("#schedule-show-when").show();
openAddShowForm();

View File

@ -220,6 +220,10 @@ function buildContentDialog(json){
}
var dialog = $(json.dialog);
dialog.find("#show_progressbar").progressbar({
value: json.percentFilled
});
var viewportwidth;
var viewportheight;

View File

@ -0,0 +1,56 @@
# This file is contributed by Eugene MechanisM
# Link to the post:
# http://forum.sourcefabric.org/discussion/13563/first-step-to-run-airtime-via-nginx-based-on-airtime-2.0-beta-files
upstream php5-fpm {
ip_hash;
server unix:/var/run/airtime.php.sock;
}
server {
listen 80;
server_name airtime; #change to your host
include mime.types;
root /usr/share/airtime/public;
access_log /var/log/airtime.access.log;
error_log /var/log/airtime.error.log;
index index.php;
include fastcgi_params;
client_max_body_size 1G;
location ~* ^.+\.(css|js|jpg|jpeg|gif|png|ico|gz|svg|svgz|ttf|otf|woff|eot|mp4|ogg|ogv|webm)$ {
expires max;
access_log off;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
location / {
if (-e $request_filename){
set $rule_0 1;
}
if ($request_filename ~ "-l"){
set $rule_0 1;
}
if (-d $request_filename){
set $rule_0 1;
}
rewrite ^/.*$ /index.php last;
try_files $uri $uri/ index.php;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass php5-fpm;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location ~ /\.ht {
deny all;
}
}

View File

@ -0,0 +1,251 @@
# NGINX changes are contributed by Eugene MechanisM
# Link to the post:
# http://forum.sourcefabric.org/discussion/13563/first-step-to-run-airtime-via-nginx-based-on-airtime-2.0-beta-files
; Start a new pool named 'airtime'.
; the variable $pool can we used in any directive and will be replaced by the
; pool name ('airtime' here)
[airtime]
; Per pool prefix
; It only applies on the following directives:
; - 'slowlog'
; - 'listen' (unixsocket)
; - 'chroot'
; - 'chdir'
; - 'php_values'
; - 'php_admin_values'
; When not set, the global prefix (or /usr) applies instead.
; Note: This directive can also be relative to the global prefix.
; Default Value: none
;prefix = /path/to/pools/$pool
; The address on which to accept FastCGI requests.
; Valid syntaxes are:
; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific address on
; a specific port;
; 'port' - to listen on a TCP socket to all addresses on a
; specific port;
; '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = '/var/run/airtime.php.sock'
; Set listen(2) backlog. A value of '-1' means unlimited.
; Default Value: 128 (-1 on FreeBSD and OpenBSD)
;listen.backlog = -1
; List of ipv4 addresses of FastCGI clients which are allowed to connect.
; Equivalent to the FCGI_WEB_SERVER_ADDRS environment variable in the original
; PHP FCGI (5.2.2+). Makes sense only with a tcp listening socket. Each address
; must be separated by a comma. If this value is left blank, connections will be
; accepted from any ip address.
; Default Value: any
;listen.allowed_clients = 127.0.0.1
; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server. Many
; BSD-derived systems allow connections regardless of permissions.
; Default Values: user and group are set as the running user
; mode is set to 0666
;listen.owner = www-data
;listen.group = www-data
;listen.mode = 0666
; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
; will be used.
user = www-data
group = www-data
; Choose how the process manager will control the number of child processes.
; Possible Values:
; static - a fixed number (pm.max_children) of child processes;
; dynamic - the number of child processes are set dynamically based on the
; following directives:
; pm.max_children - the maximum number of children that can
; be alive at the same time.
; pm.start_servers - the number of children created on startup.
; pm.min_spare_servers - the minimum number of children in 'idle'
; state (waiting to process). If the number
; of 'idle' processes is less than this
; number then some children will be created.
; pm.max_spare_servers - the maximum number of children in 'idle'
; state (waiting to process). If the number
; of 'idle' processes is greater than this
; number then some children will be killed.
; Note: This value is mandatory.
pm = dynamic
; The number of child processes to be created when pm is set to 'static' and the
; maximum number of child processes to be created when pm is set to 'dynamic'.
; This value sets the limit on the number of simultaneous requests that will be
; served. Equivalent to the ApacheMaxClients directive with mpm_prefork.
; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP
; CGI.
; Note: Used when pm is set to either 'static' or 'dynamic'
; Note: This value is mandatory.
pm.max_children = 10
; The number of child processes created on startup.
; Note: Used only when pm is set to 'dynamic'
; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2
pm.start_servers = 4
; The desired minimum number of idle server processes.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
pm.min_spare_servers = 2
; The desired maximum number of idle server processes.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
pm.max_spare_servers = 6
; The number of requests each child process should execute before respawning.
; This can be useful to work around memory leaks in 3rd party libraries. For
; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS.
; Default Value: 0
;pm.max_requests = 500
; The URI to view the FPM status page. If this value is not set, no URI will be
; recognized as a status page. By default, the status page shows the following
; information:
; accepted conn - the number of request accepted by the pool;
; pool - the name of the pool;
; process manager - static or dynamic;
; idle processes - the number of idle processes;
; active processes - the number of active processes;
; total processes - the number of idle + active processes.
; max children reached - number of times, the process limit has been reached,
; when pm tries to start more children (works only for
; pm 'dynamic')
; The values of 'idle processes', 'active processes' and 'total processes' are
; updated each second. The value of 'accepted conn' is updated in real time.
; Example output:
; accepted conn: 12073
; pool: www
; process manager: static
; idle processes: 35
; active processes: 65
; total processes: 100
; max children reached: 1
; By default the status page output is formatted as text/plain. Passing either
; 'html' or 'json' as a query string will return the corresponding output
; syntax. Example:
; http://www.foo.bar/status
; http://www.foo.bar/status?json
; http://www.foo.bar/status?html
; Note: The value must start with a leading slash (/). The value can be
; anything, but it may not be a good idea to use the .php extension or it
; may conflict with a real PHP file.
; Default Value: not set
;pm.status_path = /status
; The ping URI to call the monitoring page of FPM. If this value is not set, no
; URI will be recognized as a ping page. This could be used to test from outside
; that FPM is alive and responding, or to
; - create a graph of FPM availability (rrd or such);
; - remove a server from a group if it is not responding (load balancing);
; - trigger alerts for the operating team (24/7).
; Note: The value must start with a leading slash (/). The value can be
; anything, but it may not be a good idea to use the .php extension or it
; may conflict with a real PHP file.
; Default Value: not set
;ping.path = /ping
; This directive may be used to customize the response of a ping request. The
; response is formatted as text/plain with a 200 response code.
; Default Value: pong
;ping.response = pong
; The timeout for serving a single request after which the worker process will
; be killed. This option should be used when the 'max_execution_time' ini option
; does not stop script execution for some reason. A value of '0' means 'off'.
; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)
; Default Value: 0
;request_terminate_timeout = 0
; The timeout for serving a single request after which a PHP backtrace will be
; dumped to the 'slowlog' file. A value of '0s' means 'off'.
; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)
; Default Value: 0
;request_slowlog_timeout = 0
; The log file for slow requests
; Default Value: not set
; Note: slowlog is mandatory if request_slowlog_timeout is set
;slowlog = log/$pool.log.slow
; Set open file descriptor rlimit.
; Default Value: system defined value
;rlimit_files = 1024
; Set max core size rlimit.
; Possible Values: 'unlimited' or an integer greater or equal to 0
; Default Value: system defined value
;rlimit_core = 0
; Chroot to this directory at the start. This value must be defined as an
; absolute path. When this value is not set, chroot is not used.
; Note: you can prefix with '$prefix' to chroot to the pool prefix or one
; of its subdirectories. If the pool prefix is not set, the global prefix
; will be used instead.
; Note: chrooting is a great security feature and should be used whenever
; possible. However, all PHP paths will be relative to the chroot
; (error_log, sessions.save_path, ...).
; Default Value: not set
;chroot =
; Chdir to this directory at the start.
; Note: relative path can be used.
; Default Value: current directory or / when chroot
chdir = /
; Redirect worker stdout and stderr into main error log. If not set, stdout and
; stderr will be redirected to /dev/null according to FastCGI specs.
; Note: on highloaded environement, this can cause some delay in the page
; process time (several ms).
; Default Value: no
;catch_workers_output = yes
; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
; the current environment.
; Default Value: clean env
;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp
; Additional php.ini defines, specific to this pool of workers. These settings
; overwrite the values previously defined in the php.ini. The directives are the
; same as the PHP SAPI:
; php_value/php_flag - you can set classic ini defines which can
; be overwritten from PHP call 'ini_set'.
; php_admin_value/php_admin_flag - these directives won't be overwritten by
; PHP call 'ini_set'
; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no.
; Defining 'extension' will load the corresponding shared extension from
; extension_dir. Defining 'disable_functions' or 'disable_classes' will not
; overwrite previously defined php.ini values, but will append the new value
; instead.
; Note: path INI options can be relative and will be expanded with the prefix
; (pool, global or /usr)
; Default Value: nothing is defined by default except the values in php.ini and
; specified at startup with the -d argument
;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com
;php_flag[display_errors] = off
;php_admin_value[error_log] = /var/log/fpm-php.www.log
;php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 32M
php_admin_value[error_log] = /var/log/airtime.php-fpm.error.log
php_admin_value[post_max_size] = 500M
php_admin_value[upload_max_filesize] = 500M
php_admin_value[request_order] = GPC
php_admin_value[session.gc_probability] = 0
php_admin_value[phar.readonly] = off
php_admin_value[upload_tmp_dir] = /tmp

View File

@ -24,7 +24,7 @@ echo "----------------------------------------------------"
dist=`lsb_release -is`
if [ "$dist" -eq "Debian" ]; then
if [ "$dist" = "Debian" ]; then
grep "deb http://www.debian-multimedia.org squeeze main non-free" /etc/apt/sources.list
if [ "$?" -ne "0" ]; then
echo "deb http://www.debian-multimedia.org squeeze main non-free" >> /etc/apt/sources.list
@ -39,7 +39,7 @@ php-pear php5-gd postgresql odbc-postgresql python2.6 libsoundtouch-ocaml \
libtaglib-ocaml libao-ocaml libmad-ocaml ecasound \
libesd0 libportaudio2 libsamplerate0 rabbitmq-server patch \
php5-curl mpg123 monit python-virtualenv multitail libcamomile-ocaml-data \
libvorbis-ocaml libpulse0
libvorbis-ocaml libpulse0 vorbis-tools
#install packages with --force-yes option (this is useful in the case
#of Debian, where these packages are unauthorized)

View File

@ -0,0 +1,115 @@
#!/bin/bash
#
# Auto install script for airtime on Ubuntu
#
# NGINX changes are contributed by Eugene MechanisM
# Link to the post:
# http://forum.sourcefabric.org/discussion/13563/first-step-to-run-airtime-via-nginx-based-on-airtime-2.0-beta-files
exec > >(tee install_log.txt)
exec 2>&1
if [ "$(id -u)" != "0" ]; then
echo "Please run as root user."
exit 1
fi
#Current dir
# Absolute path to this script, e.g. /home/user/bin/foo.sh
SCRIPT=`readlink -f $0`
# Absolute path this script is in, thus /home/user/bin
SCRIPTPATH=`dirname $SCRIPT`
#Prerequisite
echo "----------------------------------------------------"
echo " 1. Install Packages"
echo "----------------------------------------------------"
dist=`lsb_release -is`
if [ "$dist" -eq "Debian" ]; then
grep "deb http://www.debian-multimedia.org squeeze main non-free" /etc/apt/sources.list
if [ "$?" -ne "0" ]; then
echo "deb http://www.debian-multimedia.org squeeze main non-free" >> /etc/apt/sources.list
fi
fi
apt-get update
# Updated package list
apt-get -y install tar gzip curl nginx php5-pgsql php5-fpm \
php-pear php5-gd postgresql odbc-postgresql python2.6 libsoundtouch-ocaml \
libtaglib-ocaml libao-ocaml libmad-ocaml ecasound \
libesd0 libportaudio2 libsamplerate0 rabbitmq-server patch \
php5-curl mpg123 monit python-virtualenv multitail libcamomile-ocaml-data \
libvorbis-ocaml libpulse0 vorbis-tools
#install packages with --force-yes option (this is useful in the case
#of Debian, where these packages are unauthorized)
apt-get -y --force-yes install libmp3lame-dev lame icecast2
if [ "$?" -ne "0" ]; then
echo ""
echo "There was a problem with apt-get. Please check the above error and try again."
echo ""
exit 1
fi
# Install phing
pear channel-discover pear.phing.info
pear install phing/phing-2.4.2
# NGINX Config File
echo "----------------------------------------------------"
echo "2.1 NGINX Config File"
echo "----------------------------------------------------"
if [ ! -f /etc/nginx/sites-available/airtime ]; then
cp $SCRIPTPATH/../nginx/airtime-vhost /etc/nginx/sites-available/airtime
ln -s /etc/nginx/sites-available/airtime /etc/nginx/sites-enabled/airtime
service nginx reload
else
echo "NGINX config for Airtime already exists..."
fi
# php-fpm Airtime pool file
echo "----------------------------------------------------"
echo "2.2 Airtime php pool file"
echo "----------------------------------------------------"
if [ ! -f /etc/php5/fpm/pool.d/airtime.conf ]; then
cp $SCRIPTPATH/../php5-fpm/airtime.conf /etc/php5/fpm/pool.d/airtime.conf
service php5-fpm reload
else
echo "Airtime php pool file already exists..."
fi
# Enable Icecast
echo "----------------------------------------------------"
echo "3. Enable Icecast"
echo "----------------------------------------------------"
cd /etc/default/
sed -i 's/ENABLE=false/ENABLE=true/g' icecast2
service icecast2 start
echo ""
# Enable Monit
echo "----------------------------------------------------"
echo "4. Enable Monit"
echo "----------------------------------------------------"
cd /etc/default/
sed -i 's/startup=0/startup=1/g' monit
grep -q "include /etc/monit/conf.d" /etc/monit/monitrc
RETVAL=$?
if [ $RETVAL -ne 0 ] ; then
mkdir -p /etc/monit/conf.d
echo "include /etc/monit/conf.d/*" >> /etc/monit/monitrc
fi
# Run Airtime Install
echo "----------------------------------------------------"
echo "5. Run Airtime Install"
echo "----------------------------------------------------"
cd $SCRIPTPATH/../../install_minimal
./airtime-install

View File

@ -17,15 +17,17 @@ fi
showhelp () {
echo "Usage: airtime-install [options]
--help|-h Displays usage information.
--overwrite|-o Overwrite any existing config files.
--preserve|-p Keep any existing config files.
--no-db|-n Turn off database install.
--reinstall|-r Force a fresh install of this Airtime Version
--media-monitor|-m Install only media-monitor
--pypo|-p Install only pypo and liquidsoap
--show-recorder|-s Install only show-recorder
--web|-w Install only files for web-server"
--help|-h Displays usage information.
--overwrite|-o Overwrite any existing config files.
--preserve|-p Keep any existing config files.
--no-db|-n Turn off database install.
--reinstall|-r Force a fresh install of this Airtime Version
--media-monitor|-m Install only media-monitor
--pypo|-p Install only pypo and liquidsoap
--show-recorder|-s Install only show-recorder
--web|-w Install only files for web-server
--liquidsoap-keep-alive|-l Keep Liquidsoap alive when upgrading
--disable-auto-start-services|-d Disable auto-starting Airtime services"
}
overwrite="f"
@ -36,8 +38,10 @@ mediamonitor="f"
pypo="f"
showrecorder="f"
web="f"
liquidsoap_keep_alive="f"
disable_auto_start_services="f"
set -- $(getopt -l help,overwrite,preserve,no-db,reinstall,media-monitor,pypo,show-recorder,web "hopnrmysw" "$@")
set -- $(getopt -l help,overwrite,preserve,no-db,reinstall,media-monitor,pypo,show-recorder,web,liquidsoap-keep-alive,disable-auto-start-services "hopnrmyswld" "$@")
while [ $# -gt 0 ]
do
case "$1" in
@ -50,6 +54,8 @@ do
(-y|--pypo) pypo="t";;
(-s|--show-recorder) showrecorder="t";;
(-w|--web) web="t";;
(-l|--liquidsoap-keep-alive) liquidsoap_keep_alive="t";;
(-d|--disable-auto-start-services) disable_auto_start_services="t";;
(--) shift; break;;
(-*) echo "$0: error - unrecognized option $1" 1>&2; exit 1;;
@ -103,6 +109,8 @@ export reinstall
export nodb
export overwrite
export preserve
export liquidsoap_keep_alive
export disable_auto_start_services
set +e
test "$mediamonitor" = "t" -o "$pypo" = "t" -o "$showrecorder" = "t"

View File

@ -67,6 +67,11 @@ class AirtimeInstall
$sql = "SELECT valstr FROM cc_pref WHERE keystr = 'system_version'";
$version = $CC_DBC->GetOne($sql);
if (PEAR::isError($version)) {
// no pref table something is wrong.
return null;
}
if ($version == '') {
$sql = "SELECT * FROM cc_show_rebroadcast LIMIT 1";
$result = $CC_DBC->GetOne($sql);

View File

@ -39,7 +39,7 @@ if [ ! -e /etc/airtime/airtime.conf ]; then
cp $AIRTIMEROOT/airtime_mvc/build/airtime.conf /etc/airtime
fi
echo "* Creating /etc/airtime"
echo "* Creating /etc/monit/conf.d/monit-airtime-generic.cfg"
mkdir -p /etc/monit/conf.d/
if [ ! -e /etc/monit/conf.d/monit-airtime-generic.cfg ]; then
cp $AIRTIMEROOT/python_apps/monit/monit-airtime-generic.cfg /etc/monit/conf.d/

View File

@ -53,15 +53,17 @@ sleep 1
set +e
if [ "$mediamonitor" = "t" ]; then
monit monitor airtime-media-monitor
fi
if [ "$pypo" = "t" ]; then
monit monitor airtime-playout
monit monitor airtime-liquidsoap
fi
if [ "$showrecorder" = "t" ]; then
monit monitor airtime-show-recorder
if [ "$disable_auto_start_services" = "f" ]; then
if [ "$mediamonitor" = "t" ]; then
monit monitor airtime-media-monitor
fi
if [ "$pypo" = "t" ]; then
monit monitor airtime-playout
monit monitor airtime-liquidsoap
fi
if [ "$showrecorder" = "t" ]; then
monit monitor airtime-show-recorder
fi
fi
monit monitor rabbitmq-server

View File

@ -125,6 +125,10 @@ class UpgradeCommon{
echo "Could not copy recorder.cfg to /etc/airtime/. Exiting.";
exit(1);
}
if (!copy(__DIR__."/media-monitor.cfg.$suffix", self::CONF_FILE_MEDIAMONITOR)){
echo "Could not copy meadia-monitor.cfg to /etc/airtime/. Exiting.";
exit(1);
}
if (!copy(__DIR__."/api_client.cfg.$suffix", self::CONF_FILE_API_CLIENT)){
echo "Could not copy api_client.cfg to /etc/monit/conf.d/. Exiting.";
exit(1);

View File

@ -92,11 +92,8 @@ generate_range_url = 'generate_range_dp.php'
# URL to tell Airtime we want to get stream setting
get_stream_setting = 'get-stream-setting/format/json/api_key/%%api_key%%/'
#URL to update liquidsoap error msg
update_liquidsoap_error = 'update-liquidsoap-error/format/json/api_key/%%api_key%%/error_msg/%%error_msg%%/stream_id/%%stream_id%%/boot_time/%%boot_time%%'
#URL to update liquidsoap connection
update_liquidsoap_connection = 'update-liquidsoap-connection/format/json/api_key/%%api_key%%/stream_id/%%stream_id%%/boot_time/%%boot_time%%'
#URL to update liquidsoap status
update_liquidsoap_status = 'update-liquidsoap-status/format/json/api_key/%%api_key%%/msg/%%msg%%/stream_id/%%stream_id%%/boot_time/%%boot_time%%'
##############
# OBP config #

View File

@ -92,11 +92,8 @@ generate_range_url = 'generate_range_dp.php'
# URL to tell Airtime we want to get stream setting
get_stream_setting = 'get-stream-setting/format/json/api_key/%%api_key%%/'
#URL to update liquidsoap error msg
update_liquidsoap_error = 'update-liquidsoap-error/format/json/api_key/%%api_key%%/error_msg/%%error_msg%%/stream_id/%%stream_id%%/boot_time/%%boot_time%%'
#URL to update liquidsoap connection
update_liquidsoap_connection = 'update-liquidsoap-connection/format/json/api_key/%%api_key%%/stream_id/%%stream_id%%/boot_time/%%boot_time%%'
#URL to update liquidsoap status
update_liquidsoap_status = 'update-liquidsoap-status/format/json/api_key/%%api_key%%/msg/%%msg%%/stream_id/%%stream_id%%/boot_time/%%boot_time%%'
##############
# OBP config #

View File

@ -571,29 +571,15 @@ class AirTimeApiClient(ApiClientInterface):
except Exception, e:
logger.error("Exception: %s", e)
def notify_liquidsoap_error(self, error_msg, stream_id, time):
def notify_liquidsoap_status(self, msg, stream_id, time):
logger = logging.getLogger()
try:
url = "http://%s:%s/%s/%s" % (self.config["base_url"], str(self.config["base_port"]), self.config["api_base"], self.config["update_liquidsoap_error"])
url = url.replace("%%api_key%%", self.config["api_key"])
error_msg = error_msg.replace('/', ' ')
encoded_msg = urllib.quote(error_msg, '')
url = url.replace("%%error_msg%%", encoded_msg)
url = url.replace("%%stream_id%%", stream_id)
url = url.replace("%%boot_time%%", time)
logger.debug(url)
req = urllib2.Request(url)
response = urllib2.urlopen(req).read()
except Exception, e:
logger.error("Exception: %s", e)
def notify_liquidsoap_connection(self, stream_id, time):
logger = logging.getLogger()
try:
url = "http://%s:%s/%s/%s" % (self.config["base_url"], str(self.config["base_port"]), self.config["api_base"], self.config["update_liquidsoap_connection"])
url = "http://%s:%s/%s/%s" % (self.config["base_url"], str(self.config["base_port"]), self.config["api_base"], self.config["update_liquidsoap_status"])
url = url.replace("%%api_key%%", self.config["api_key"])
msg = msg.replace('/', ' ')
encoded_msg = urllib.quote(msg, '')
url = url.replace("%%msg%%", encoded_msg)
url = url.replace("%%stream_id%%", stream_id)
url = url.replace("%%boot_time%%", time)
logger.debug(url)

View File

@ -42,8 +42,9 @@ try:
sys.exit(1)
#copy monit files
shutil.copy('%s/../monit-airtime-media-monitor.cfg'%current_script_dir, '/etc/monit/conf.d/')
shutil.copy('%s/../../monit/monit-airtime-generic.cfg'%current_script_dir, '/etc/monit/conf.d/')
if os.environ["disable_auto_start_services"] == "f":
shutil.copy('%s/../monit-airtime-media-monitor.cfg'%current_script_dir, '/etc/monit/conf.d/')
#create log dir
create_dir(config['log_dir'])

View File

@ -6,15 +6,17 @@ if os.geteuid() != 0:
sys.exit(1)
try:
#update-rc.d init script
p = Popen("update-rc.d airtime-media-monitor defaults >/dev/null 2>&1", shell=True)
sts = os.waitpid(p.pid, 0)[1]
#Start media-monitor daemon
print "* Waiting for media-monitor processes to start..."
p = Popen("/etc/init.d/airtime-media-monitor stop", shell=True)
sts = os.waitpid(p.pid, 0)[1]
p = Popen("/etc/init.d/airtime-media-monitor start-no-monit", shell=True)
sts = os.waitpid(p.pid, 0)[1]
if os.environ["disable_auto_start_services"] == "f":
#update-rc.d init script
p = Popen("update-rc.d airtime-media-monitor defaults >/dev/null 2>&1", shell=True)
sts = os.waitpid(p.pid, 0)[1]
#Start media-monitor daemon
print "* Waiting for media-monitor processes to start..."
p = Popen("/etc/init.d/airtime-media-monitor stop", shell=True)
sts = os.waitpid(p.pid, 0)[1]
p = Popen("/etc/init.d/airtime-media-monitor start-no-monit", shell=True)
sts = os.waitpid(p.pid, 0)[1]
except Exception, e:
print e

View File

@ -3,8 +3,3 @@
set httpd port 2812
allow admin:monit
check process rabbitmq-server
with pidfile "/var/run/rabbitmq.pid"
start program = "/bin/bash -c '/etc/init.d/rabbitmq-server start; /usr/lib/airtime/utils/rabbitmq-update-pid.sh'"
stop program = "/etc/init.d/rabbitmq-server stop"

View File

@ -1,11 +1,7 @@
set daemon 10 # Poll at 5 second intervals
#set logfile syslog facility log_daemon
set logfile /var/log/monit.log
set httpd port 2812
allow admin:monit
check process rabbitmq-server
with pidfile "/var/run/rabbitmq.pid"
start program = "/bin/bash -c '/etc/init.d/rabbitmq-server start; sed "s/.*,\(.*\)\}.*/\1/" /var/lib/rabbitmq/pids > /var/run/rabbitmq.pid'"
start program = "/bin/bash -c '/etc/init.d/rabbitmq-server start; /usr/lib/airtime/utils/rabbitmq-update-pid.sh'"
stop program = "/etc/init.d/rabbitmq-server stop"

View File

@ -34,6 +34,14 @@ liquidsoap_stop () {
rm -f $PIDFILE1
}
stop_pypo () {
monit unmonitor airtime-playout >/dev/null 2>&1
# Send TERM after 5 seconds, wait at most 30 seconds.
start-stop-daemon --stop --oknodo --retry TERM/5/0/30 --quiet --pidfile $PIDFILE0
rm -f $PIDFILE0
}
start () {
start-stop-daemon --start --background --quiet --chuid $USERID:$GROUPID --make-pidfile --pidfile $PIDFILE0 --startas $DAEMON0
monit monitor airtime-playout >/dev/null 2>&1
@ -124,6 +132,12 @@ case "${1:-''}" in
start-liquidsoap
echo "Done."
;;
'pypo-stop')
# restart commands here
echo -n "Restarting Pypo: "
stop_pypo
echo "Done."
;;
*) # no parameter specified
echo "Usage: $SELF start|stop|restart|status"
exit 1

View File

@ -42,9 +42,11 @@ try:
sys.exit(1)
#copy monit files
shutil.copy('%s/../monit-airtime-playout.cfg'%current_script_dir, '/etc/monit/conf.d/')
shutil.copy('%s/../monit-airtime-liquidsoap.cfg'%current_script_dir, '/etc/monit/conf.d/')
shutil.copy('%s/../../monit/monit-airtime-generic.cfg'%current_script_dir, '/etc/monit/conf.d/')
shutil.copy('%s/../../monit/monit-airtime-rabbitmq-server.cfg'%current_script_dir, '/etc/monit/conf.d/')
if os.environ["disable_auto_start_services"] == "f":
shutil.copy('%s/../monit-airtime-liquidsoap.cfg'%current_script_dir, '/etc/monit/conf.d/')
shutil.copy('%s/../monit-airtime-playout.cfg'%current_script_dir, '/etc/monit/conf.d/')
#create pypo log dir
create_dir(config['pypo_log_dir'])

View File

@ -3,8 +3,8 @@ import shutil
from subprocess import Popen, PIPE
import sys
import os
sys.path.append('/usr/lib/airtime/api_clients/')
import api_client
sys.path.append('/usr/lib/airtime/')
from api_clients import api_client
from configobj import ConfigObj
if os.geteuid() != 0:
@ -54,7 +54,7 @@ def generate_liquidsoap_config(ss):
temp = "0"
buffer += temp
buffer += "\n"
fh.write(buffer)
fh.write(api_client.encode_to(buffer))
fh.write("log_file = \"/var/log/airtime/pypo-liquidsoap/<script>.log\"\n");
fh.close()
@ -87,26 +87,33 @@ try:
print "Unsupported system architecture."
sys.exit(1)
#initialize init.d scripts
p = Popen("update-rc.d airtime-playout defaults >/dev/null 2>&1", shell=True)
sts = os.waitpid(p.pid, 0)[1]
#generate liquidsoap config file
#access the DB and generate liquidsoap.cfg under /etc/airtime/
api_client = api_client.api_client_factory(config)
ss = api_client.get_stream_setting()
ac = api_client.api_client_factory(config)
ss = ac.get_stream_setting()
if ss is not None:
generate_liquidsoap_config(ss)
else:
print "Unable to connect to the Airtime server."
#restart airtime-playout
print "* Waiting for pypo processes to start..."
p = Popen("/etc/init.d/airtime-playout stop", shell=True)
sts = os.waitpid(p.pid, 0)[1]
p = Popen("/etc/init.d/airtime-playout start-no-monit", shell=True)
sts = os.waitpid(p.pid, 0)[1]
if os.environ["disable_auto_start_services"] == "f":
#initialize init.d scripts
p = Popen("update-rc.d airtime-playout defaults >/dev/null 2>&1", shell=True)
sts = os.waitpid(p.pid, 0)[1]
#restart airtime-playout
print "* Waiting for pypo processes to start..."
if os.environ["liquidsoap_keep_alive"] == "f":
print " * Restarting any previous Liquidsoap instances"
p = Popen("/etc/init.d/airtime-playout stop", shell=True)
sts = os.waitpid(p.pid, 0)[1]
else:
print " * Keeping any previous Liquidsoap instances running"
p = Popen("/etc/init.d/airtime-playout pypo-stop", shell=True)
sts = os.waitpid(p.pid, 0)[1]
p = Popen("/etc/init.d/airtime-playout start-no-monit", shell=True)
sts = os.waitpid(p.pid, 0)[1]
except Exception, e:
print e

View File

@ -37,15 +37,17 @@ def to_live(old,new) =
end
def output_to(output_type, type, bitrate, host, port, pass, mount_point, url, description, genre, user, s, stream) =
def output_to(output_type, type, bitrate, host, port, pass, mount_point, url, description, genre, user, s, stream, connected) =
def on_error(msg)
system("/usr/lib/airtime/pypo/bin/liquidsoap_scripts/notify.sh --error='#{msg}' --stream-id=#{stream} --time=#{time}")
log("/usr/lib/airtime/pypo/bin/liquidsoap_scripts/notify.sh --error='#{msg}' --stream-id=#{stream} --time=#{time}")
connected := "false"
system("/usr/lib/airtime/pypo/bin/liquidsoap_scripts/notify.sh --error='#{msg}' --stream-id=#{stream} --time=#{!time}")
log("/usr/lib/airtime/pypo/bin/liquidsoap_scripts/notify.sh --error='#{msg}' --stream-id=#{stream} --time=#{!time}")
5.
end
def on_connect()
system("/usr/lib/airtime/pypo/bin/liquidsoap_scripts/notify.sh --connect --stream-id=#{stream} --time=#{time}")
log("/usr/lib/airtime/pypo/bin/liquidsoap_scripts/notify.sh --connect --stream-id=#{stream} --time=#{time}")
connected := "true"
system("/usr/lib/airtime/pypo/bin/liquidsoap_scripts/notify.sh --connect --stream-id=#{stream} --time=#{!time}")
log("/usr/lib/airtime/pypo/bin/liquidsoap_scripts/notify.sh --connect --stream-id=#{stream} --time=#{!time}")
end
if output_type == "icecast" then
user_ref = ref user
@ -136,7 +138,8 @@ def output_to(output_type, type, bitrate, host, port, pass, mount_point, url, de
if url == "" then
url_ref := "N/A"
end
output.shoutcast = output.shoutcast(host = host,
output.shoutcast = output.shoutcast(id = "shoutcast_stream_#{stream}",
host = host,
port = port,
password = pass,
fallible = true,

View File

@ -6,7 +6,7 @@ set("log.stdout", true)
set("server.telnet", true)
set("server.telnet.port", 1234)
time = gettimeofday()
time = ref string_of(gettimeofday())
queue = audio_to_stereo(request.queue(id="queue", length=0.5))
queue = cue_cut(queue)
@ -17,6 +17,13 @@ stream_metadata_type = ref 0
station_name = ref ''
show_name = ref ''
s1_connected = ref ''
s2_connected = ref ''
s3_connected = ref ''
s1_namespace = ref ''
s2_namespace = ref ''
s3_namespace = ref ''
%include "ls_lib.liq"
server.register(namespace="vars", "pypo_data", fun (s) -> begin pypo_data := s "Done" end)
@ -24,6 +31,8 @@ server.register(namespace="vars", "web_stream_enabled", fun (s) -> begin web_str
server.register(namespace="vars", "stream_metadata_type", fun (s) -> begin stream_metadata_type := int_of_string(s) s end)
server.register(namespace="vars", "show_name", fun (s) -> begin show_name := s s end)
server.register(namespace="vars", "station_name", fun (s) -> begin station_name := s s end)
server.register(namespace="vars", "bootup_time", fun (s) -> begin time := s s end)
server.register(namespace="streams", "connection_status", fun (s) -> begin "1:#{!s1_connected},2:#{!s2_connected},3:#{!s3_connected}" end)
default = amplify(0.00001, noise())
@ -100,19 +109,34 @@ if output_sound_device then
end
if s1_enable == true then
#output_to(output_type, type, bitrate, host, port, pass, mount_point, url, description, genre, s)
output_to(s1_output, s1_type, s1_bitrate, s1_host, s1_port, s1_pass, s1_mount, s1_url, s1_description, s1_genre, s1_user, s, "1")
if s1_output == 'shoutcast' then
s1_namespace := "shoutcast_stream_1"
else
s1_namespace := s1_mount
end
server.register(namespace=!s1_namespace, "connected", fun (s) -> begin !s1_connected end)
output_to(s1_output, s1_type, s1_bitrate, s1_host, s1_port, s1_pass, s1_mount, s1_url, s1_description, s1_genre, s1_user, s, "1", s1_connected)
end
if s2_enable == true then
#output_to(output_type, type, bitrate, host, port, pass, mount_point, url, description, genre, s)
output_to(s2_output, s2_type, s2_bitrate, s2_host, s2_port, s2_pass, s2_mount, s2_url, s2_description, s2_genre, s2_user, s, "2")
if s2_output == 'shoutcast' then
s2_namespace := "shoutcast_stream_2"
else
s2_namespace := s2_mount
end
server.register(namespace=!s2_namespace, "connected", fun (s) -> begin !s2_connected end)
output_to(s2_output, s2_type, s2_bitrate, s2_host, s2_port, s2_pass, s2_mount, s2_url, s2_description, s2_genre, s2_user, s, "2", s2_connected)
end
if s3_enable == true then
#output_to(output_type, type, bitrate, host, port, pass, mount_point, url, description, genre, s)
output_to(s3_output, s3_type, s3_bitrate, s3_host, s3_port, s3_pass, s3_mount, s3_url, s3_description, s3_genre, s3_user, s, "3")
if s3_output == 'shoutcast' then
s3_namespace := "shoutcast_stream_3"
else
s3_namespace := s3_mount
end
server.register(namespace=!s3_namespace, "connected", fun (s) -> begin !s3_connected end)
output_to(s3_output, s3_type, s3_bitrate, s3_host, s3_port, s3_pass, s3_mount, s3_url, s3_description, s3_genre, s3_user, s, "3", s3_connected)
end
ignore(output.dummy(blank()))

View File

@ -82,24 +82,14 @@ class Notify:
logger.debug("Response: "+json.dumps(response))
# @pram time: time that LS started
def notify_liquidsoap_error(self, error_msg, stream_id, time):
def notify_liquidsoap_status(self, msg, stream_id, time):
logger = logging.getLogger()
logger.debug('#################################################')
logger.debug('# Calling server to update liquidsoap error #')
logger.debug('# Calling server to update liquidsoap status #')
logger.debug('#################################################')
logger.debug('error msg = '+ str(error_msg))
response = self.api_client.notify_liquidsoap_error(error_msg, stream_id, time)
logger.debug("Response: "+json.dumps(response))
# @pram time: time that LS started
def notify_liquidsoap_connection(self, stream_id, time):
logger = logging.getLogger()
logger.debug('#################################################')
logger.debug('# Calling server to update liquidsoap connection#')
logger.debug('#################################################')
response = self.api_client.notify_liquidsoap_connection(stream_id, time)
logger.debug('msg = '+ str(msg))
response = self.api_client.notify_liquidsoap_status(msg, stream_id, time)
logger.debug("Response: "+json.dumps(response))
if __name__ == '__main__':
@ -115,13 +105,13 @@ if __name__ == '__main__':
if options.error and options.stream_id:
try:
n = Notify()
n.notify_liquidsoap_error(options.error, options.stream_id, options.time)
n.notify_liquidsoap_status(options.error, options.stream_id, options.time)
except Exception, e:
print e
elif options.connect and options.stream_id:
try:
n = Notify()
n.notify_liquidsoap_connection(options.stream_id, options.time)
n.notify_liquidsoap_status("OK", options.stream_id, options.time)
except Exception, e:
print e
else:

View File

@ -204,7 +204,7 @@ class PypoFetch(Thread):
temp = "0"
buffer += temp
buffer += "\n"
fh.write(buffer)
fh.write(api_client.encode_to(buffer))
fh.write("log_file = \"/var/log/airtime/pypo-liquidsoap/<script>.log\"\n");
fh.close()
# restarting pypo.
@ -216,6 +216,41 @@ class PypoFetch(Thread):
self.process_schedule(self.schedule_data, "scheduler", False)
else:
logger.info("No change detected in setting...")
self.update_liquidsoap_connection_status()
"""
updates the status of liquidsoap connection to the streaming server
This fucntion updates the bootup time variable in liquidsoap script
"""
def update_liquidsoap_connection_status(self):
logger = logging.getLogger('fetch')
tn = telnetlib.Telnet(LS_HOST, LS_PORT)
# update the boot up time of liquidsoap. Since liquidsoap is not restarting,
# we are manually adjusting the bootup time variable so the status msg will get
# updated.
current_time = time.time()
boot_up_time_command = "vars.bootup_time "+str(current_time)+"\n"
tn.write(boot_up_time_command)
tn.write("streams.connection_status\n")
tn.write('exit\n')
output = tn.read_all()
output_list = output.split("\r\n")
stream_info = output_list[2]
# streamin info is in the form of:
# eg. s1:true,2:true,3:false
streams = stream_info.split(",")
logger.info(streams)
fake_time = current_time + 1
for s in streams:
info = s.split(':')
stream_id = info[0]
status = info[1]
if(status == "true"):
self.api_client.notify_liquidsoap_status("OK", stream_id, str(fake_time))
def set_export_source(self, export_source):
logger = logging.getLogger('fetch')

View File

@ -43,8 +43,9 @@ try:
#copy monit files
shutil.copy('%s/../monit-airtime-show-recorder.cfg'%current_script_dir, '/etc/monit/conf.d/')
shutil.copy('%s/../../monit/monit-airtime-generic.cfg'%current_script_dir, '/etc/monit/conf.d/')
if os.environ["disable_auto_start_services"] == "f":
shutil.copy('%s/../monit-airtime-show-recorder.cfg'%current_script_dir, '/etc/monit/conf.d/')
#create temporary media-storage directory
#print "Creating temporary media storage directory"

View File

@ -7,15 +7,16 @@ if os.geteuid() != 0:
sys.exit(1)
try:
#register init.d script
p = Popen("update-rc.d airtime-show-recorder defaults >/dev/null 2>&1", shell=True)
sts = os.waitpid(p.pid, 0)[1]
if os.environ["disable_auto_start_services"] == "f":
#register init.d script
p = Popen("update-rc.d airtime-show-recorder defaults >/dev/null 2>&1", shell=True)
sts = os.waitpid(p.pid, 0)[1]
#start daemon
print "* Waiting for show-recorder processes to start..."
p = Popen("/etc/init.d/airtime-show-recorder stop", shell=True)
sts = os.waitpid(p.pid, 0)[1]
p = Popen("/etc/init.d/airtime-show-recorder start-no-monit", shell=True)
sts = os.waitpid(p.pid, 0)[1]
#start daemon
print "* Waiting for show-recorder processes to start..."
p = Popen("/etc/init.d/airtime-show-recorder stop", shell=True)
sts = os.waitpid(p.pid, 0)[1]
p = Popen("/etc/init.d/airtime-show-recorder start-no-monit", shell=True)
sts = os.waitpid(p.pid, 0)[1]
except Exception, e:
print e

View File

@ -25,3 +25,6 @@ record_samplerate = 44100
record_channels = 2
record_sample_size = 16
#can be either ogg|mp3, mp3 recording requires installation of the package "lame"
record_file_type = 'ogg'

View File

@ -55,12 +55,11 @@ def getDateTimeObj(time):
class ShowRecorder(Thread):
def __init__ (self, show_instance, show_name, filelength, start_time, filetype):
def __init__ (self, show_instance, show_name, filelength, start_time):
Thread.__init__(self)
self.api_client = api_client.api_client_factory(config)
self.filelength = filelength
self.start_time = start_time
self.filetype = filetype
self.show_instance = show_instance
self.show_name = show_name
self.logger = logging.getLogger('root')
@ -70,7 +69,13 @@ class ShowRecorder(Thread):
length = str(self.filelength)+".0"
filename = self.start_time
filename = filename.replace(" ", "-")
filepath = "%s%s.%s" % (config["base_recorded_files"], filename, self.filetype)
if config["record_file_type"] in ["mp3", "ogg"]:
filetype = config["record_file_type"]
else:
filetype = "ogg";
filepath = "%s%s.%s" % (config["base_recorded_files"], filename, filetype)
br = config["record_bitrate"]
sr = config["record_samplerate"]
@ -263,7 +268,7 @@ class CommandListener():
start_time_formatted = '%(year)d-%(month)02d-%(day)02d %(hour)02d:%(min)02d:%(sec)02d' % \
{'year': start_time_on_server.year, 'month': start_time_on_server.month, 'day': start_time_on_server.day,\
'hour': start_time_on_server.hour, 'min': start_time_on_server.minute, 'sec': start_time_on_server.second}
self.sr = ShowRecorder(show_instance, show_name, show_length.seconds, start_time_formatted, filetype="mp3")
self.sr = ShowRecorder(show_instance, show_name, show_length.seconds, start_time_formatted)
self.sr.start()
#remove show from shows to record.

View File

@ -79,7 +79,7 @@ if(Application_Model_Preference::GetSupportFeedback() == '1'){
// Get latest version from stat server and store to db
if(Application_Model_Preference::GetPlanLevel() == 'disabled'){
$url = 'http://stat.sourcefabric.org/airtime_latest_version';
$url = 'http://stat.sourcefabric.org/airtime-stats/airtime_latest_version';
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);