Merge branch 'saas-dev' into saas-speedy
This commit is contained in:
commit
8b380086c3
32 changed files with 4981 additions and 1287 deletions
|
@ -78,9 +78,9 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
|
|||
|
||||
$view->headScript()->appendScript("var baseUrl = '$baseUrl';");
|
||||
$this->_initTranslationGlobals($view);
|
||||
|
||||
|
||||
$user = Application_Model_User::GetCurrentUser();
|
||||
if (!is_null($user)){
|
||||
if (!is_null($user)) {
|
||||
$userType = $user->getType();
|
||||
} else {
|
||||
$userType = "";
|
||||
|
@ -91,14 +91,15 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
|
|||
/**
|
||||
* Create a global namespace to hold a session token for CSRF prevention
|
||||
*/
|
||||
protected function _initCsrfNamespace() {
|
||||
protected function _initCsrfNamespace()
|
||||
{
|
||||
$csrf_namespace = new Zend_Session_Namespace('csrf_namespace');
|
||||
// Check if the token exists
|
||||
if (!$csrf_namespace->authtoken) {
|
||||
// If we don't have a token, regenerate it and set a 2 hour timeout
|
||||
// Should we log the user out here if the token is expired?
|
||||
$csrf_namespace->authtoken = sha1(uniqid(rand(),1));
|
||||
$csrf_namespace->setExpirationSeconds(2*60*60);
|
||||
$csrf_namespace->authtoken = sha1(uniqid(rand(), 1));
|
||||
$csrf_namespace->setExpirationSeconds(2 * 60 * 60);
|
||||
}
|
||||
|
||||
//Here we are closing the session for writing because otherwise no requests
|
||||
|
@ -106,13 +107,14 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
|
|||
//of the application (page load times are more consistent, no lock contention).
|
||||
session_write_close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ideally, globals should be written to a single js file once
|
||||
* from a php init function. This will save us from having to
|
||||
* Ideally, globals should be written to a single js file once
|
||||
* from a php init function. This will save us from having to
|
||||
* reinitialize them every request
|
||||
*/
|
||||
private function _initTranslationGlobals() {
|
||||
private function _initTranslationGlobals()
|
||||
{
|
||||
$view = $this->getResource('view');
|
||||
$view->headScript()->appendScript("var PRODUCT_NAME = '" . PRODUCT_NAME . "';");
|
||||
$view->headScript()->appendScript("var USER_MANUAL_URL = '" . USER_MANUAL_URL . "';");
|
||||
|
@ -127,13 +129,13 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
|
|||
|
||||
$baseUrl = Application_Common_OsPath::getBaseDir();
|
||||
|
||||
$view->headLink()->appendStylesheet($baseUrl.'css/bootstrap.css?'.$CC_CONFIG['airtime_version']);
|
||||
$view->headLink()->appendStylesheet($baseUrl.'css/redmond/jquery-ui-1.8.8.custom.css?'.$CC_CONFIG['airtime_version']);
|
||||
$view->headLink()->appendStylesheet($baseUrl.'css/pro_dropdown_3.css?'.$CC_CONFIG['airtime_version']);
|
||||
$view->headLink()->appendStylesheet($baseUrl.'css/qtip/jquery.qtip.min.css?'.$CC_CONFIG['airtime_version']);
|
||||
$view->headLink()->appendStylesheet($baseUrl.'css/styles.css?'.$CC_CONFIG['airtime_version']);
|
||||
$view->headLink()->appendStylesheet($baseUrl.'css/masterpanel.css?'.$CC_CONFIG['airtime_version']);
|
||||
$view->headLink()->appendStylesheet($baseUrl.'css/tipsy/jquery.tipsy.css?'.$CC_CONFIG['airtime_version']);
|
||||
$view->headLink()->appendStylesheet($baseUrl . 'css/bootstrap.css?' . $CC_CONFIG['airtime_version']);
|
||||
$view->headLink()->appendStylesheet($baseUrl . 'css/redmond/jquery-ui-1.8.8.custom.css?' . $CC_CONFIG['airtime_version']);
|
||||
$view->headLink()->appendStylesheet($baseUrl . 'css/pro_dropdown_3.css?' . $CC_CONFIG['airtime_version']);
|
||||
$view->headLink()->appendStylesheet($baseUrl . 'css/qtip/jquery.qtip.min.css?' . $CC_CONFIG['airtime_version']);
|
||||
$view->headLink()->appendStylesheet($baseUrl . 'css/styles.css?' . $CC_CONFIG['airtime_version']);
|
||||
$view->headLink()->appendStylesheet($baseUrl . 'css/masterpanel.css?' . $CC_CONFIG['airtime_version']);
|
||||
$view->headLink()->appendStylesheet($baseUrl . 'css/tipsy/jquery.tipsy.css?' . $CC_CONFIG['airtime_version']);
|
||||
}
|
||||
|
||||
protected function _initHeadScript()
|
||||
|
@ -144,72 +146,73 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
|
|||
|
||||
$baseUrl = Application_Common_OsPath::getBaseDir();
|
||||
|
||||
$view->headScript()->appendFile($baseUrl.'js/libs/jquery-1.8.3.min.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl.'js/libs/jquery-ui-1.8.24.min.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl.'js/bootstrap/bootstrap.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl . 'js/libs/jquery-1.8.3.min.js?' . $CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl . 'js/libs/jquery-ui-1.8.24.min.js?' . $CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl . 'js/bootstrap/bootstrap.js?' . $CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
|
||||
$view->headScript()->appendFile($baseUrl.'js/libs/underscore-min.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl . 'js/libs/underscore-min.js?' . $CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
|
||||
$view->headScript()->appendFile($baseUrl.'js/libs/jquery.stickyPanel.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl.'js/qtip/jquery.qtip.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl.'js/jplayer/jquery.jplayer.min.js?'.$CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl.'js/sprintf/sprintf-0.7-beta1.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl.'js/cookie/jquery.cookie.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl.'js/i18n/jquery.i18n.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl.'locale/general-translation-table?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl.'locale/datatables-translation-table?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
// $view->headScript()->appendFile($baseUrl . 'js/libs/jquery.stickyPanel.js?' . $CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl . 'js/qtip/jquery.qtip.js?' . $CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl . 'js/jplayer/jquery.jplayer.min.js?' . $CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl . 'js/sprintf/sprintf-0.7-beta1.js?' . $CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl . 'js/cookie/jquery.cookie.js?' . $CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl . 'js/i18n/jquery.i18n.js?' . $CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl . 'locale/general-translation-table?' . $CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl . 'locale/datatables-translation-table?' . $CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
$view->headScript()->appendScript("$.i18n.setDictionary(general_dict)");
|
||||
$view->headScript()->appendScript("var baseUrl='$baseUrl'");
|
||||
|
||||
//These timezones are needed to adjust javascript Date objects on the client to make sense to the user's set timezone
|
||||
//or the server's set timezone.
|
||||
|
||||
//These timezones are needed to adjust javascript Date objects on the client to make sense to the user's set timezone
|
||||
//or the server's set timezone.
|
||||
$serverTimeZone = new DateTimeZone(Application_Model_Preference::GetDefaultTimezone());
|
||||
$now = new DateTime("now", $serverTimeZone);
|
||||
$offset = $now->format("Z") * -1;
|
||||
$view->headScript()->appendScript("var serverTimezoneOffset = {$offset}; //in seconds");
|
||||
|
||||
if (class_exists("Zend_Auth", false) && Zend_Auth::getInstance()->hasIdentity()) {
|
||||
$userTimeZone = new DateTimeZone(Application_Model_Preference::GetUserTimezone());
|
||||
$now = new DateTime("now", $userTimeZone);
|
||||
$offset = $now->format("Z") * -1;
|
||||
$view->headScript()->appendScript("var userTimezoneOffset = {$offset}; //in seconds");
|
||||
}
|
||||
|
||||
//scripts for now playing bar
|
||||
$view->headScript()->appendFile($baseUrl.'js/airtime/airtime_bootstrap.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl.'js/airtime/dashboard/helperfunctions.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl.'js/airtime/dashboard/dashboard.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl.'js/airtime/dashboard/versiontooltip.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl.'js/tipsy/jquery.tipsy.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
|
||||
$view->headScript()->appendFile($baseUrl.'js/airtime/common/common.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl.'js/airtime/common/audioplaytest.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
if (class_exists("Zend_Auth", false) && Zend_Auth::getInstance()->hasIdentity()) {
|
||||
$userTimeZone = new DateTimeZone(Application_Model_Preference::GetUserTimezone());
|
||||
$now = new DateTime("now", $userTimeZone);
|
||||
$offset = $now->format("Z") * -1;
|
||||
$view->headScript()->appendScript("var userTimezoneOffset = {$offset}; //in seconds");
|
||||
}
|
||||
|
||||
//scripts for now playing bar
|
||||
$view->headScript()->appendFile($baseUrl . 'js/airtime/airtime_bootstrap.js?' . $CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl . 'js/airtime/dashboard/helperfunctions.js?' . $CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl . 'js/airtime/dashboard/dashboard.js?' . $CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl . 'js/airtime/dashboard/versiontooltip.js?' . $CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl . 'js/tipsy/jquery.tipsy.js?' . $CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
|
||||
$view->headScript()->appendFile($baseUrl . 'js/airtime/common/common.js?' . $CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl . 'js/airtime/common/audioplaytest.js?' . $CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
|
||||
$user = Application_Model_User::getCurrentUser();
|
||||
if (!is_null($user)){
|
||||
if (!is_null($user)) {
|
||||
$userType = $user->getType();
|
||||
} else {
|
||||
$userType = "";
|
||||
}
|
||||
|
||||
|
||||
$view->headScript()->appendScript("var userType = '$userType';");
|
||||
|
||||
if (array_key_exists('REQUEST_URI', $_SERVER)) { //Doesn't exist for unit tests
|
||||
if (strpos($_SERVER['REQUEST_URI'], $baseUrl.'Dashboard/stream-player') === false
|
||||
&& strpos($_SERVER['REQUEST_URI'], $baseUrl.'audiopreview/audio-preview') === false
|
||||
&& strpos($_SERVER['REQUEST_URI'], $baseUrl.'audiopreview/playlist-preview') === false
|
||||
&& strpos($_SERVER['REQUEST_URI'], $baseUrl.'audiopreview/block-preview') === false) {
|
||||
if (strpos($_SERVER['REQUEST_URI'], $baseUrl . 'Dashboard/stream-player') === false
|
||||
&& strpos($_SERVER['REQUEST_URI'], $baseUrl . 'audiopreview/audio-preview') === false
|
||||
&& strpos($_SERVER['REQUEST_URI'], $baseUrl . 'audiopreview/playlist-preview') === false
|
||||
&& strpos($_SERVER['REQUEST_URI'], $baseUrl . 'audiopreview/block-preview') === false
|
||||
) {
|
||||
$plan_level = strval(Application_Model_Preference::GetPlanLevel());
|
||||
// Since the Hobbyist plan doesn't come with Live Chat support, don't enable it
|
||||
if (Application_Model_Preference::GetLiveChatEnabled() && $plan_level !== 'hobbyist') {
|
||||
$client_id = strval(Application_Model_Preference::GetClientId());
|
||||
$station_url = $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
|
||||
$view->headScript()->appendScript("var livechat_client_id = '$client_id';\n".
|
||||
"var livechat_plan_type = '$plan_level';\n".
|
||||
"var livechat_station_url = 'http://$station_url';");
|
||||
$view->headScript()->appendFile($baseUrl . 'js/airtime/common/livechat.js?'.$CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
$view->headScript()->appendScript("var livechat_client_id = '$client_id';\n" .
|
||||
"var livechat_plan_type = '$plan_level';\n" .
|
||||
"var livechat_station_url = 'http://$station_url';");
|
||||
$view->headScript()->appendFile($baseUrl . 'js/airtime/common/livechat.js?' . $CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -222,6 +225,8 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
|
|||
{
|
||||
$view = $this->getResource('view');
|
||||
$view->addHelperPath('../application/views/helpers', 'Airtime_View_Helper');
|
||||
|
||||
$view->assign('suspended', (Application_Model_Preference::getProvisioningStatus() == PROVISIONING_STATUS_SUSPENDED));
|
||||
}
|
||||
|
||||
protected function _initTitle()
|
||||
|
@ -260,7 +265,7 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
|
|||
$front = Zend_Controller_Front::getInstance();
|
||||
$router = $front->getRouter();
|
||||
$front->setBaseUrl(Application_Common_OsPath::getBaseDir());
|
||||
|
||||
|
||||
$router->addRoute(
|
||||
'password-change',
|
||||
new Zend_Controller_Router_Route('password-change/:user_id/:token', array(
|
||||
|
|
|
@ -11,7 +11,7 @@ define('COMPANY_SITE_URL' , 'http://sourcefabric.org/');
|
|||
define('WHOS_USING_URL' , 'http://sourcefabric.org/en/airtime/whosusing');
|
||||
define('TERMS_AND_CONDITIONS_URL' , 'http://www.sourcefabric.org/en/about/policy/');
|
||||
define('PRIVACY_POLICY_URL' , 'http://www.sourcefabric.org/en/about/policy/');
|
||||
define('USER_MANUAL_URL' , 'http://sourcefabric.booktype.pro/airtime-25-for-broadcasters/');
|
||||
define('USER_MANUAL_URL' , 'http://sourcefabric.booktype.pro/airtime-pro-for-broadcasters');
|
||||
|
||||
define('LICENSE_VERSION' , 'GNU AGPL v.3');
|
||||
define('LICENSE_URL' , 'http://www.gnu.org/licenses/agpl-3.0-standalone.html');
|
||||
|
@ -87,4 +87,8 @@ define("WHMCS_API_URL", "https://account.sourcefabric.com/includes/api.php");
|
|||
define("SUBDOMAIN_WHMCS_CUSTOM_FIELD_NAME", "Choose your domain");
|
||||
|
||||
//Sentry error logging
|
||||
define('SENTRY_CONFIG_PATH', '/etc/airtime-saas/sentry.airtime_web.ini');
|
||||
define('SENTRY_CONFIG_PATH', '/etc/airtime-saas/sentry.airtime_web.ini');
|
||||
|
||||
//Provisioning status
|
||||
define('PROVISIONING_STATUS_SUSPENDED' , 'Suspended');
|
||||
define('PROVISIONING_STATUS_ACTIVE' , 'Active');
|
||||
|
|
|
@ -134,7 +134,7 @@ $pages = array(
|
|||
),
|
||||
array(
|
||||
'label' => _('User Manual'),
|
||||
'uri' => "http://sourcefabric.booktype.pro/airtime-25-for-broadcasters/",
|
||||
'uri' => "http://sourcefabric.booktype.pro/airtime-pro-for-broadcasters",
|
||||
'target' => "_blank"
|
||||
),
|
||||
array(
|
||||
|
|
|
@ -13,7 +13,6 @@ class DashboardController extends Zend_Controller_Action
|
|||
|
||||
public function indexAction()
|
||||
{
|
||||
// action body
|
||||
}
|
||||
|
||||
public function disconnectSourceAction()
|
||||
|
|
|
@ -32,12 +32,15 @@ class ProvisioningController extends Zend_Controller_Action
|
|||
|
||||
try {
|
||||
// This is hacky and should be genericized
|
||||
if ($_POST['station_name']) {
|
||||
if (isset($_POST['station_name'])) {
|
||||
Application_Model_Preference::SetStationName($_POST['station_name']);
|
||||
}
|
||||
if ($_POST['description']) {
|
||||
if (isset($_POST['description'])) {
|
||||
Application_Model_Preference::SetStationDescription($_POST['description']);
|
||||
}
|
||||
if (isset($_POST['provisioning_status'])) {
|
||||
Application_Model_Preference::setProvisioningStatus($_POST['provisioning_status']);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$this->getResponse()
|
||||
->setHttpResponseCode(400)
|
||||
|
|
|
@ -20,7 +20,12 @@ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
|||
<!-- End Google Tag Manager -->
|
||||
|
||||
<?php echo $this->partial('partialviews/trialBox.phtml', array("is_trial"=>$this->isTrial(), "trial_remain"=> $this->trialRemaining())) ?>
|
||||
<div id="Panel">
|
||||
|
||||
<div id="Panel" class="sticky">
|
||||
<?php if($this->suspended) : ?>
|
||||
<?php echo $this->partial('partialviews/suspended.phtml'); ?>
|
||||
<?php else : ?>
|
||||
|
||||
<?php echo $this->versionNotify();
|
||||
$sss = $this->SourceSwitchStatus();
|
||||
$scs = $this->SourceConnectionStatus();
|
||||
|
@ -61,8 +66,10 @@ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
|||
<?php echo $this->navigation()->menu() ?>
|
||||
<div style="clear:both;"></div>
|
||||
</div>
|
||||
<?php endif; //suspended ?>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="wrapper" id="content"><?php echo $this->layout()->content ?></div>
|
||||
|
||||
<script id="tmpl-pl-cues" type="text/template">
|
||||
|
|
|
@ -1441,4 +1441,16 @@ class Application_Model_Preference
|
|||
|
||||
self::setDiskUsage($currentDiskUsage + $filesize);
|
||||
}
|
||||
|
||||
|
||||
public static function setProvisioningStatus($status)
|
||||
{
|
||||
//See constants.php for the list of valid values. eg. PROVISIONING_STATUS_ACTIVE
|
||||
self::setValue("provisioning_status", $status);
|
||||
}
|
||||
|
||||
public static function getProvisioningStatus()
|
||||
{
|
||||
return self::getValue("provisioning_status");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,13 +64,6 @@ SQL;
|
|||
{
|
||||
//Everything in this function must be done in UTC. You will get a swift kick in the pants if you mess that up.
|
||||
|
||||
if (!is_int($p_prev) || !is_int($p_next)) {
|
||||
//must enter integers to specify ranges
|
||||
Logging::info("Invalid range parameters: $p_prev or $p_next");
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
// when timeEnd is unspecified, return to the default behaviour - set a range of 48 hours from current time
|
||||
if (!$utcTimeEnd) {
|
||||
$end = new DateTime();
|
||||
|
|
|
@ -150,23 +150,27 @@ class Application_Service_CalendarService
|
|||
$menu["edit"] = array(
|
||||
"name" => _("Edit This Instance"),
|
||||
"icon" => "edit",
|
||||
"url" => $baseUrl."Schedule/populate-repeating-show-instance-form");
|
||||
"url" => $baseUrl . "Schedule/populate-repeating-show-instance-form"
|
||||
);
|
||||
} else {
|
||||
$menu["edit"] = array(
|
||||
"name" => _("Edit"),
|
||||
"icon" => "edit",
|
||||
"items" => array());
|
||||
"items" => array()
|
||||
);
|
||||
|
||||
$menu["edit"]["items"]["all"] = array(
|
||||
"name" => _("Edit Show"),
|
||||
"icon" => "edit",
|
||||
"url" => $baseUrl."Schedule/populate-show-form");
|
||||
"url" => $baseUrl . "Schedule/populate-show-form"
|
||||
);
|
||||
|
||||
$menu["edit"]["items"]["instance"] = array(
|
||||
"name" => _("Edit This Instance"),
|
||||
"icon" => "edit",
|
||||
"url" => $baseUrl."Schedule/populate-repeating-show-instance-form");
|
||||
}
|
||||
"url" => $baseUrl . "Schedule/populate-repeating-show-instance-form"
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$menu["edit"] = array(
|
||||
"name"=> _("Edit Show"),
|
||||
|
|
|
@ -153,14 +153,19 @@ class Application_Service_ShowFormService
|
|||
if ($ccShowDay->isShowStartInPast()) {
|
||||
//for a non-repeating show, we should never allow user to change the start time.
|
||||
//for a repeating show, we should allow because the form works as repeating template form
|
||||
if (!$ccShowDay->isRepeating()) {
|
||||
$form->disableStartDateAndTime();
|
||||
|
||||
// Removing this - if there is no future instance, this will throw an error.
|
||||
// If there is a future instance, then we get a WHEN block representing the next instance
|
||||
// which may be confusing.
|
||||
/*if (!$ccShowDay->isRepeating()) {
|
||||
$form->disableStartDateAndTime();
|
||||
} else {
|
||||
list($showStart, $showEnd) = $this->getNextFutureRepeatShowTime();
|
||||
if ($this->hasShowStarted($showStart)) {
|
||||
$form->disableStartDateAndTime();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
$form->populate(
|
||||
|
@ -410,9 +415,8 @@ class Application_Service_ShowFormService
|
|||
|
||||
//if the show is repeating, set the start date to the next
|
||||
//repeating instance in the future
|
||||
if ($this->ccShow->isRepeating()) {
|
||||
list($originalShowStartDateTime,) = $this->getNextFutureRepeatShowTime();
|
||||
} else {
|
||||
$originalShowStartDateTime = $this->getCurrentOrNextInstanceStartTime();
|
||||
if (!$originalShowStartDateTime) {
|
||||
$originalShowStartDateTime = $dt;
|
||||
}
|
||||
|
||||
|
@ -421,26 +425,30 @@ class Application_Service_ShowFormService
|
|||
|
||||
/**
|
||||
*
|
||||
* Returns 2 DateTime objects, in the user's local time,
|
||||
* of the next future repeat show instance start and end time
|
||||
* Returns a DateTime object, in the user's local time,
|
||||
* of the current or next show instance start time
|
||||
*
|
||||
* Returns null if there is no next future repeating show instance
|
||||
*/
|
||||
public function getNextFutureRepeatShowTime()
|
||||
public function getCurrentOrNextInstanceStartTime()
|
||||
{
|
||||
$ccShowInstance = CcShowInstancesQuery::create()
|
||||
->filterByDbShowId($this->ccShow->getDbId())
|
||||
->filterByDbModifiedInstance(false)
|
||||
->filterByDbStarts(gmdate("Y-m-d H:i:s"), Criteria::GREATER_THAN)
|
||||
->filterByDbStarts(gmdate("Y-m-d"), Criteria::GREATER_EQUAL)
|
||||
->orderByDbStarts()
|
||||
->findOne();
|
||||
|
||||
if (!$ccShowInstance) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$starts = new DateTime($ccShowInstance->getDbStarts(), new DateTimeZone("UTC"));
|
||||
$ends = new DateTime($ccShowInstance->getDbEnds(), new DateTimeZone("UTC"));
|
||||
$showTimezone = $this->ccShow->getFirstCcShowDay()->getDbTimezone();
|
||||
|
||||
$starts->setTimezone(new DateTimeZone($showTimezone));
|
||||
$ends->setTimezone(new DateTimeZone($showTimezone));
|
||||
|
||||
return array($starts, $ends);
|
||||
return $starts;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -238,8 +238,8 @@
|
|||
}
|
||||
|
||||
// variables for updating the player's metadata
|
||||
var time_to_next_track_starts;
|
||||
var metadataTimer;
|
||||
var time_to_next_track_starts = 0;
|
||||
var metadataTimer = null;
|
||||
|
||||
// Fetches the streams metadata from the Airtime live-info API
|
||||
// and attaches it to the player UI.
|
||||
|
@ -252,7 +252,12 @@
|
|||
success: function(data) {
|
||||
|
||||
if (data.current === null) {
|
||||
$("p.now_playing").html("Offline");
|
||||
if (data.currentShow != null && data.currentShow.length != 0) {
|
||||
// Master/show source have no current track but they do have a current show.
|
||||
$("p.now_playing").html(data.currentShow[0].name);
|
||||
} else {
|
||||
$("p.now_playing").html("Offline");
|
||||
}
|
||||
time_to_next_track_starts = 20000;
|
||||
} else {
|
||||
var artist = data.current.name.split(" - ")[0];
|
||||
|
@ -260,6 +265,12 @@
|
|||
$("p.now_playing").html(artist + "<span>" + track + "</span>");
|
||||
|
||||
var current_track_end_time = new Date(data.current.ends);
|
||||
if (current_track_end_time == "Invalid Date" || isNaN(current_track_end_time)) {
|
||||
// If the conversion didn't work (since the String is not in ISO format)
|
||||
// then change it to be ISO-compliant. This is somewhat hacky and may break
|
||||
// if the date string format in live-info changes!
|
||||
current_track_end_time = new Date((data.current.ends).replace(" ", "T"));
|
||||
}
|
||||
var current_time = new Date();
|
||||
//convert current_time to UTC to match the timezone of time_to_next_track_starts
|
||||
current_time = new Date(current_time.getTime() + current_time.getTimezoneOffset() * 60 * 1000);
|
||||
|
@ -271,9 +282,14 @@
|
|||
} else {
|
||||
$("ul.schedule_list").find("li").html(data.next.name);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
//Preventative code if the local and remote clocks are out of sync.
|
||||
if (isNaN(time_to_next_track_starts) || time_to_next_track_starts < 0) {
|
||||
time_to_next_track_starts = 0;
|
||||
}
|
||||
|
||||
// Add 3 seconds to the timeout so Airtime has time to update the metadata before we fetch it
|
||||
metadataTimer = setTimeout(attachStreamMetadataToPlayer, time_to_next_track_starts+3000);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,30 @@
|
|||
|
||||
<?php //echo $this->element->getElement('player_display_track_metadata'); ?>
|
||||
|
||||
<table id="player_compatibility_chart">
|
||||
<th colspan="5">Stream Compatibility</th>
|
||||
<tr>
|
||||
<td colspan="3">Desktop</td>
|
||||
<td colspan="2">Mobile</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Firefox</td>
|
||||
<td>Chrome</td>
|
||||
<td>Internet Explorer</td>
|
||||
<td>Android 5 - Chrome</td>
|
||||
<td>iOS 7 - Safari</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Yes (Flash)</td>
|
||||
<td>Yes (Flash)</td>
|
||||
<td>Yes (Flash)</td>
|
||||
<td>MP3/OGG* only</td>
|
||||
<td>MP3/AAC only</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="5">* Chrome on Android is known to take about 4 seconds to buffer a 128 kbps MP3 stream. Lower bitrates take longer to buffer.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
</dl>
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<div class="suspension_notice">
|
||||
<H2>Station Suspended</H2>
|
||||
<p>
|
||||
<?php echo(_pro(sprintf('Your station is suspended due to an <b>unpaid invoice</b>. To restore your station, <a href="%s">please pay any overdue invoices</a>.', '/billing/invoices'))); ?>
|
||||
</p>
|
||||
<p>
|
||||
<?php echo(_pro(sprintf('Suspended stations will be <b>removed</b> if an invoice is unpaid for 30 days. If you believe this suspension was in error, <a href="%s">please contact support</a>.', 'https://sourcefabricberlin.zendesk.com/anonymous_requests/new'))); ?>
|
||||
</p>
|
||||
</div>
|
|
@ -5,7 +5,10 @@
|
|||
</style>
|
||||
<?php if ($this->quotaLimitReached) { ?>
|
||||
<div class="errors quota-reached">
|
||||
Disk quota exceeded. You cannot upload files until you <a href="http://www.sourcefabric.org/en/airtime" target="_blank">upgrade your storage</a>.
|
||||
Disk quota exceeded. You cannot upload files until you
|
||||
<a target="_parent" href=<?php $baseUrl = Application_Common_OsPath::getBaseDir(); echo $baseUrl . "billing/upgrade"?>>
|
||||
upgrade your storage
|
||||
</a>.
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
BIN
airtime_mvc/locale/tr/LC_MESSAGES/airtime.mo
Normal file
BIN
airtime_mvc/locale/tr/LC_MESSAGES/airtime.mo
Normal file
Binary file not shown.
3908
airtime_mvc/locale/tr/LC_MESSAGES/airtime.po
Normal file
3908
airtime_mvc/locale/tr/LC_MESSAGES/airtime.po
Normal file
File diff suppressed because it is too large
Load diff
|
@ -59,4 +59,26 @@
|
|||
}
|
||||
|
||||
|
||||
table#player_compatibility_chart{
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 5px;
|
||||
color: #3b3b3b;
|
||||
}
|
||||
|
||||
#player_compatibility_chart th, tr, td {
|
||||
border-bottom: 1px solid #999;
|
||||
border-right: 1px solid #999 !important;
|
||||
background-color: #ccc;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#player_compatibility_chart th
|
||||
{
|
||||
color: #5b5b5b;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -262,6 +262,9 @@ table.datatable tr.sb-header.odd:hover td, table.datatable tr.sb-header.even:hov
|
|||
margin: 0;
|
||||
padding: 10px 0 0 0;
|
||||
overflow: hidden;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.ui-dialog .lib_content {
|
||||
|
@ -281,4 +284,4 @@ table.datatable tr.sb-header.odd:hover td, table.datatable tr.sb-header.even:hov
|
|||
|
||||
.ui-dialog .sb_content .padded {
|
||||
padding: 5px 10px 5px 16px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -141,8 +141,22 @@ select {
|
|||
* html .clearfix, * html li { height: 1%;}
|
||||
.clearfix, #side_playlist li { display: block; }
|
||||
|
||||
|
||||
/* Master Panel */
|
||||
|
||||
.sticky {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 1000;
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
.push {
|
||||
width: 100%;
|
||||
height: 139px;
|
||||
}
|
||||
|
||||
#sticky {
|
||||
position:fixed;
|
||||
height:130px;
|
||||
|
@ -150,7 +164,6 @@ select {
|
|||
left:0;
|
||||
}
|
||||
|
||||
|
||||
#master-panel {
|
||||
background:#3d3d3d url(images/masterpanel_bg.png) repeat-x 0 0;
|
||||
height:100px;
|
||||
|
@ -427,7 +440,10 @@ select {
|
|||
|
||||
|
||||
.wrapper {
|
||||
margin: 0 5px 0 5px;
|
||||
position: absolute;
|
||||
top: 141px;
|
||||
left: 10px;
|
||||
right: 10px;
|
||||
padding:10px 0 0 0;
|
||||
}
|
||||
|
||||
|
@ -1182,10 +1198,10 @@ input[type="checkbox"] {
|
|||
left:0;
|
||||
margin-bottom:140px;
|
||||
}*/
|
||||
.sticky {
|
||||
padding:0;
|
||||
width:100%;
|
||||
}
|
||||
/*.sticky {*/
|
||||
/*padding:0;*/
|
||||
/*width:100%;*/
|
||||
/*}*/
|
||||
|
||||
.floated-panel {
|
||||
margin-top:0;
|
||||
|
@ -3217,3 +3233,18 @@ dd .stream-status {
|
|||
{
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.suspension_notice
|
||||
{
|
||||
text-align: center;
|
||||
background-color: #D27A7A;
|
||||
height: 143px;
|
||||
font-size: 16px;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
.suspension_notice h2
|
||||
{
|
||||
padding-bottom: 0px;
|
||||
padding-top: 13px;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
$(document).ready(function() {
|
||||
|
||||
$("#Panel").stickyPanel({
|
||||
topPadding: 1,
|
||||
afterDetachCSSClass: "floated-panel",
|
||||
savePanelSpace: true
|
||||
});
|
||||
|
||||
/* Removed as this is now (hopefully) unnecessary */
|
||||
//$("#Panel").stickyPanel({
|
||||
// topPadding: 1,
|
||||
// afterDetachCSSClass: "floated-panel",
|
||||
// savePanelSpace: true
|
||||
//});
|
||||
|
||||
//this statement tells the browser to fade out any success message after 5 seconds
|
||||
setTimeout(function(){$(".success").fadeOut("slow", function(){$(this).empty()});}, 5000);
|
||||
|
@ -52,8 +52,8 @@ var i18n_days_short = [
|
|||
$.i18n._("We"),
|
||||
$.i18n._("Th"),
|
||||
$.i18n._("Fr"),
|
||||
$.i18n._("Sa"),
|
||||
]
|
||||
$.i18n._("Sa")
|
||||
];
|
||||
|
||||
function adjustDateToServerDate(date, serverTimezoneOffset){
|
||||
//date object stores time in the browser's localtime. We need to artificially shift
|
||||
|
|
|
@ -1445,7 +1445,7 @@ var AIRTIME = (function(AIRTIME){
|
|||
initialEvents();
|
||||
setUpPlaylist();
|
||||
};
|
||||
|
||||
|
||||
function setWidgetSize() {
|
||||
viewport = AIRTIME.utilities.findViewportDimensions();
|
||||
widgetHeight = viewport.height - 185;
|
||||
|
@ -1458,7 +1458,7 @@ var AIRTIME = (function(AIRTIME){
|
|||
.find(".dataTables_scrolling")
|
||||
.css("max-height", libTableHeight)
|
||||
.end()
|
||||
.width(Math.floor(width * 0.55));
|
||||
.width(Math.floor(width * 0.54));
|
||||
|
||||
$pl.height(widgetHeight)
|
||||
.width(Math.floor(width * 0.45));
|
||||
|
|
|
@ -53,8 +53,8 @@ AIRTIME = (function(AIRTIME) {
|
|||
function setWidgetSize() {
|
||||
viewport = AIRTIME.utilities.findViewportDimensions();
|
||||
widgetHeight = viewport.height - 180;
|
||||
screenWidth = Math.floor(viewport.width - 40);
|
||||
|
||||
screenWidth = Math.floor(viewport.width - 50);
|
||||
|
||||
var libTableHeight = widgetHeight - 175,
|
||||
builderTableHeight = widgetHeight - 95,
|
||||
oTable;
|
||||
|
@ -77,9 +77,9 @@ AIRTIME = (function(AIRTIME) {
|
|||
|
||||
if ($lib.filter(':visible').length > 0) {
|
||||
|
||||
$lib.width(Math.floor(screenWidth * 0.48));
|
||||
$lib.width(Math.floor(screenWidth * 0.47));
|
||||
|
||||
$builder.width(Math.floor(screenWidth * 0.48))
|
||||
$builder.width(Math.floor(screenWidth * 0.47))
|
||||
.find("#sb_edit")
|
||||
.remove()
|
||||
.end()
|
||||
|
|
|
@ -60,6 +60,9 @@ class AirtimeAnalyzerServer:
|
|||
#Disable most pika/rabbitmq logging:
|
||||
pika_logger = logging.getLogger('pika')
|
||||
pika_logger.setLevel(logging.CRITICAL)
|
||||
|
||||
boto_logger = logging.getLogger('auth')
|
||||
boto_logger.setLevel(logging.CRITICAL)
|
||||
|
||||
# Set up logging
|
||||
logFormatter = logging.Formatter("%(asctime)s [%(module)s] [%(levelname)-5.5s] %(message)s")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue