Merge branch 'cc-5709-airtime-analyzer-cloud-storage' into cc-5709-airtime-analyzer-cloud-storage-saas

Conflicts:
	airtime_mvc/application/Bootstrap.php
	airtime_mvc/application/configs/ACL.php
	airtime_mvc/application/controllers/ApiController.php
	airtime_mvc/application/controllers/plugins/Acl_plugin.php
	airtime_mvc/application/forms/GeneralPreferences.php
	airtime_mvc/application/modules/rest/controllers/MediaController.php
	airtime_mvc/application/views/scripts/form/preferences_general.phtml
	airtime_mvc/application/views/scripts/form/support-setting.phtml
	airtime_mvc/build/sql/schema.sql
This commit is contained in:
drigato 2015-01-23 11:32:45 -05:00
commit ca9750f415
46 changed files with 771 additions and 595 deletions

18
CREDITS
View File

@ -2,7 +2,24 @@
CREDITS
=======
<<<<<<< HEAD
Version 2.5.3
=======
Version 2.5.2
Albert Santoni (albert.santoni@sourcefabric.org)
Denise Rigato (denise.rigato@sourcefabric.org)
Cliff Wang (cliff.wang@sourcefabric.org)
Nareg Asmarian (nareg.asmarian@sourcefabric.org)
Daniel James (daniel.james@sourcefabric.org)
Community Contributors:
Robbt E
Version 2.5.1
>>>>>>> 2.5.x
Albert Santoni (albert.santoni@sourcefabric.org)
Role: Developer Team Lead
@ -25,6 +42,7 @@ Community Contributors:
John Chewter
Version 2.5.0
-------------

2
README
View File

@ -43,7 +43,7 @@ For installation from git on Debian wheezy, run:
Quick links to our resources
----------------------------
User manuals: http://www.sourcefabric.org/en/airtime/manuals/
User manual: http://sourcefabric.booktype.pro/airtime-25-for-broadcasters/
Forums and mailing lists: http://forum.sourcefabric.org
Bug tracker: http://dev.sourcefabric.org
Source code: http://github.com/sourcefabric/Airtime

View File

@ -18,11 +18,13 @@ require_once 'Preference.php';
require_once 'Locale.php';
require_once "DateHelper.php";
require_once "LocaleHelper.php";
require_once "HTTPHelper.php";
require_once "OsPath.php";
require_once "Database.php";
require_once "Timezone.php";
require_once "Auth.php";
require_once __DIR__.'/forms/helpers/ValidationTypes.php';
require_once __DIR__.'/forms/helpers/CustomDecorators.php';
require_once __DIR__.'/controllers/plugins/RabbitMqPlugin.php';
require_once __DIR__.'/controllers/plugins/Maintenance.php';
require_once __DIR__.'/modules/rest/controllers/ShowController.php';

View File

@ -443,5 +443,59 @@ class Application_Common_DateHelper
return $res;
}
/**
* Returns date fields from give start and end teimstamp strings
* if no start or end parameter is passed start will be set to 1
* in the past and end to now
*
* @param string startTimestamp Y-m-d H:i:s
* @param string endTImestamp Y-m-d H:i:s
* @param string timezone (ex UTC) of the start and end parameters
* @return array (start DateTime, end DateTime) in UTC timezone
*/
public static function getStartEnd($startTimestamp, $endTimestamp, $timezone)
{
$prefTimezone = Application_Model_Preference::GetTimezone();
$utcTimezone = new DateTimeZone("UTC");
$utcNow = new DateTime("now", $utcTimezone);
if (empty($timezone)) {
$userTimezone = new DateTimeZone($prefTimezone);
} else {
$userTimezone = new DateTimeZone($timezone);
}
// default to 1 day
if (empty($startTimestamp) || empty($endTimestamp)) {
$startsDT = clone $utcNow;
$startsDT->sub(new DateInterval("P1D"));
$endsDT = clone $utcNow;
} else {
try {
$startsDT = new DateTime($startTimestamp, $userTimezone);
$startsDT->setTimezone($utcTimezone);
$endsDT = new DateTime($endTimestamp, $userTimezone);
$endsDT->setTimezone($utcTimezone);
if ($startsDT > $endsDT) {
throw new Exception("start greater than end");
}
}
catch (Exception $e) {
Logging::info($e);
Logging::info($e->getMessage());
$startsDT = clone $utcNow;
$startsDT->sub(new DateInterval("P1D"));
$endsDT = clone $utcNow;
}
}
return array($startsDT, $endsDT);
}
}

View File

@ -0,0 +1,20 @@
<?php
class Application_Common_HTTPHelper
{
/**
* Returns start and end DateTime vars from given
* HTTP Request object
*
* @param Request
* @return array(start DateTime, end DateTime)
*/
public static function getStartEndFromRequest($request)
{
return Application_Common_DateHelper::getStartEnd(
$request->getParam("start", null),
$request->getParam("end", null),
$request->getParam("timezone", null)
);
}
}

View File

@ -32,9 +32,10 @@ $ccAcl->add(new Zend_Acl_Resource('library'))
->add(new Zend_Acl_Resource('webstream'))
->add(new Zend_Acl_Resource('locale'))
->add(new Zend_Acl_Resource('upgrade'))
->add(new Zend_Acl_Resource('downgrade'))
->add(new Zend_Acl_Resource('rest:media'))
->add(new Zend_Acl_Resource('billing'))
->add(new Zend_Acl_Resource('provisioning'));
/** Creating permissions */
$ccAcl->allow('G', 'index')
@ -51,6 +52,8 @@ $ccAcl->allow('G', 'index')
->allow('G', 'locale')
->allow('G', 'upgrade')
->allow('G', 'provisioning')
->allow('G', 'downgrade')
->allow('G', 'rest:media')
->allow('H', 'preference', 'is-import-in-progress')
->allow('H', 'usersettings')
->allow('H', 'plupload')

View File

@ -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://www.sourcefabric.org/en/airtime/manuals/');
define('USER_MANUAL_URL' , 'http://sourcefabric.booktype.pro/airtime-25-for-broadcasters/');
define('LICENSE_VERSION' , 'GNU AGPL v.3');
define('LICENSE_URL' , 'http://www.gnu.org/licenses/agpl-3.0-standalone.html');

View File

@ -128,7 +128,7 @@ $pages = array(
),
array(
'label' => _('User Manual'),
'uri' => "http://www.sourcefabric.org/en/airtime/manuals/",
'uri' => "http://sourcefabric.booktype.pro/airtime-25-for-broadcasters/",
'target' => "_blank"
),
array(

View File

@ -5,8 +5,17 @@ class ApiController extends Zend_Controller_Action
public function init()
{
$ignoreAuth = array("live-info", "live-info-v2", "week-info",
"station-metadata", "station-logo", "show-logo");
$ignoreAuth = array("live-info",
"live-info-v2",
"week-info",
"station-metadata",
"station-logo",
"show-history-feed",
"item-history-feed",
"shows",
"show-tracks",
"show-schedules"
);
$params = $this->getRequest()->getParams();
if (!in_array($params['action'], $ignoreAuth)) {
@ -266,10 +275,10 @@ class ApiController extends Zend_Controller_Action
$utcTimeEnd = $end->format("Y-m-d H:i:s");
$result = array(
"env" => APPLICATION_ENV,
"schedulerTime" => $utcTimeNow,
"currentShow" => Application_Model_Show::getCurrentShow($utcTimeNow),
"nextShow" => Application_Model_Show::getNextShows($utcTimeNow, $limit, $utcTimeEnd)
"env" => APPLICATION_ENV,
"schedulerTime" => $utcTimeNow,
"currentShow" => Application_Model_Show::getCurrentShow($utcTimeNow),
"nextShow" => Application_Model_Show::getNextShows($utcTimeNow, $limit, $utcTimeEnd)
);
} else {
$result = Application_Model_Schedule::GetPlayOrderRangeOld($limit);
@ -479,9 +488,9 @@ class ApiController extends Zend_Controller_Action
$shows,
array("starts", "ends", "start_timestamp","end_timestamp"),
$timezone
);
);
$result[$dow[$i]] = $shows;
$result[$dow[$i]] = $shows;
}
// XSS exploit prevention
@ -1412,4 +1421,175 @@ class ApiController extends Zend_Controller_Action
Application_Model_StreamSetting::SetListenerStatError($k, $v);
}
}
/**
* display played items for a given time range and show instance_id
*
* @return json array
*/
public function itemHistoryFeedAction()
{
try {
$request = $this->getRequest();
$params = $request->getParams();
$instance = $request->getParam("instance_id", null);
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($request);
$historyService = new Application_Service_HistoryService();
$results = $historyService->getPlayedItemData($startsDT, $endsDT, $params, $instance);
$this->_helper->json->sendJson($results['history']);
}
catch (Exception $e) {
Logging::info($e);
Logging::info($e->getMessage());
}
}
/**
* display show schedules for a given time range and show instance_id
*
* @return json array
*/
public function showHistoryFeedAction()
{
try {
$request = $this->getRequest();
$params = $request->getParams();
$userId = $request->getParam("user_id", null);
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($request);
$historyService = new Application_Service_HistoryService();
$shows = $historyService->getShowList($startsDT, $endsDT, $userId);
$this->_helper->json->sendJson($shows);
}
catch (Exception $e) {
Logging::info($e);
Logging::info($e->getMessage());
}
}
/**
* display show info (without schedule) for given show_id
*
* @return json array
*/
public function showsAction()
{
try {
$request = $this->getRequest();
$params = $request->getParams();
$showId = $request->getParam("show_id", null);
$results = array();
if (empty($showId)) {
$shows = CcShowQuery::create()->find();
foreach($shows as $show) {
$results[] = $show->getShowInfo();
}
} else {
$show = CcShowQuery::create()->findPK($showId);
$results[] = $show->getShowInfo();
}
$this->_helper->json->sendJson($results);
}
catch (Exception $e) {
Logging::info($e);
Logging::info($e->getMessage());
}
}
/**
* display show schedule for given show_id
*
* @return json array
*/
public function showSchedulesAction()
{
try {
$request = $this->getRequest();
$params = $request->getParams();
$showId = $request->getParam("show_id", null);
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($request);
if ((!isset($showId)) || (!is_numeric($showId))) {
//if (!isset($showId)) {
$this->_helper->json->sendJson(
array("jsonrpc" => "2.0", "error" => array("code" => 400, "message" => "missing invalid type for required show_id parameter. use type int.".$showId))
);
}
$shows = Application_Model_Show::getShows($startsDT, $endsDT, FALSE, $showId);
// is this a valid show?
if (empty($shows)) {
$this->_helper->json->sendJson(
array("jsonrpc" => "2.0", "error" => array("code" => 204, "message" => "no content for requested show_id"))
);
}
$this->_helper->json->sendJson($shows);
}
catch (Exception $e) {
Logging::info($e);
Logging::info($e->getMessage());
}
}
/**
* displays track listing for given instance_id
*
* @return json array
*/
public function showTracksAction()
{
$baseUrl = Application_Common_OsPath::getBaseDir();
$prefTimezone = Application_Model_Preference::GetTimezone();
$instanceId = $this->_getParam('instance_id');
if ((!isset($instanceId)) || (!is_numeric($instanceId))) {
$this->_helper->json->sendJson(
array("jsonrpc" => "2.0", "error" => array("code" => 400, "message" => "missing invalid type for required instance_id parameter. use type int"))
);
}
$showInstance = new Application_Model_ShowInstance($instanceId);
$showInstanceContent = $showInstance->getShowListContent($prefTimezone);
// is this a valid show instance with content?
if (empty($showInstanceContent)) {
$this->_helper->json->sendJson(
array("jsonrpc" => "2.0", "error" => array("code" => 204, "message" => "no content for requested instance_id"))
);
}
$result = array();
$position = 0;
foreach ($showInstanceContent as $track) {
$elementMap = array(
'title' => isset($track['track_title']) ? $track['track_title'] : "",
'artist' => isset($track['creator']) ? $track['creator'] : "",
'position' => $position,
'id' => ++$position,
'mime' => isset($track['mime'])?$track['mime']:"",
'starts' => isset($track['starts']) ? $track['starts'] : "",
'length' => isset($track['length']) ? $track['length'] : "",
'file_id' => ($track['type'] == 0) ? $track['item_id'] : $track['filepath']
);
$result[] = $elementMap;
}
$this->_helper->json($result);
}
}

View File

@ -10,49 +10,6 @@ class ListenerstatController extends Zend_Controller_Action
->initContext();
}
private function getStartEnd()
{
$request = $this->getRequest();
$userTimezone = new DateTimeZone(Application_Model_Preference::GetUserTimezone());
$utcTimezone = new DateTimeZone("UTC");
$utcNow = new DateTime("now", $utcTimezone);
$start = $request->getParam("start");
$end = $request->getParam("end");
if (empty($start) || empty($end)) {
$startsDT = clone $utcNow;
$startsDT->sub(new DateInterval("P1D"));
$endsDT = clone $utcNow;
}
else {
try {
$startsDT = new DateTime($start, $userTimezone);
$startsDT->setTimezone($utcTimezone);
$endsDT = new DateTime($end, $userTimezone);
$endsDT->setTimezone($utcTimezone);
if ($startsDT > $endsDT) {
throw new Exception("start greater than end");
}
}
catch (Exception $e) {
Logging::info($e);
Logging::info($e->getMessage());
$startsDT = clone $utcNow;
$startsDT->sub(new DateInterval("P1D"));
$endsDT = clone $utcNow;
}
}
return array($startsDT, $endsDT);
}
public function indexAction()
{
$CC_CONFIG = Config::getConfig();
@ -69,7 +26,7 @@ class ListenerstatController extends Zend_Controller_Action
$this->view->headLink()->appendStylesheet($baseUrl.'css/jquery.ui.timepicker.css?'.$CC_CONFIG['airtime_version']);
list($startsDT, $endsDT) = $this->getStartEnd();
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($request);
$userTimezone = new DateTimeZone(Application_Model_Preference::GetUserTimezone());
$startsDT->setTimezone($userTimezone);
$endsDT->setTimezone($userTimezone);
@ -98,7 +55,7 @@ class ListenerstatController extends Zend_Controller_Action
}
public function getDataAction(){
list($startsDT, $endsDT) = $this->getStartEnd();
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($this->getRequest());
$data = Application_Model_ListenerStat::getDataPointsWithinRange($startsDT->format("Y-m-d H:i:s"), $endsDT->format("Y-m-d H:i:s"));
$this->_helper->json->sendJson($data);

View File

@ -19,56 +19,13 @@ class PlayouthistoryController extends Zend_Controller_Action
->initContext();
}
private function getStartEnd()
{
$request = $this->getRequest();
$userTimezone = new DateTimeZone(Application_Model_Preference::GetUserTimezone());
$utcTimezone = new DateTimeZone("UTC");
$utcNow = new DateTime("now", $utcTimezone);
$start = $request->getParam("start");
$end = $request->getParam("end");
if (empty($start) || empty($end)) {
$startsDT = clone $utcNow;
$startsDT->sub(new DateInterval("P1D"));
$endsDT = clone $utcNow;
}
else {
try {
$startsDT = new DateTime($start, $userTimezone);
$startsDT->setTimezone($utcTimezone);
$endsDT = new DateTime($end, $userTimezone);
$endsDT->setTimezone($utcTimezone);
if ($startsDT > $endsDT) {
throw new Exception("start greater than end");
}
}
catch (Exception $e) {
Logging::info($e);
Logging::info($e->getMessage());
$startsDT = clone $utcNow;
$startsDT->sub(new DateInterval("P1D"));
$endsDT = clone $utcNow;
}
}
return array($startsDT, $endsDT);
}
public function indexAction()
{
$CC_CONFIG = Config::getConfig();
$baseUrl = Application_Common_OsPath::getBaseDir();
list($startsDT, $endsDT) = $this->getStartEnd();
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($this->getRequest());
$userTimezone = new DateTimeZone(Application_Model_Preference::GetUserTimezone());
$startsDT->setTimezone($userTimezone);
$endsDT->setTimezone($userTimezone);
@ -123,7 +80,7 @@ class PlayouthistoryController extends Zend_Controller_Action
$params = $request->getParams();
$instance = $request->getParam("instance_id", null);
list($startsDT, $endsDT) = $this->getStartEnd();
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($request);
$historyService = new Application_Service_HistoryService();
$r = $historyService->getFileSummaryData($startsDT, $endsDT, $params);
@ -146,7 +103,7 @@ class PlayouthistoryController extends Zend_Controller_Action
$params = $request->getParams();
$instance = $request->getParam("instance_id", null);
list($startsDT, $endsDT) = $this->getStartEnd();
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($request);
$historyService = new Application_Service_HistoryService();
$r = $historyService->getPlayedItemData($startsDT, $endsDT, $params, $instance);
@ -169,7 +126,7 @@ class PlayouthistoryController extends Zend_Controller_Action
$params = $request->getParams();
$instance = $request->getParam("instance_id", null);
list($startsDT, $endsDT) = $this->getStartEnd();
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($request);
$historyService = new Application_Service_HistoryService();
$shows = $historyService->getShowList($startsDT, $endsDT);

View File

@ -244,49 +244,6 @@ class ShowbuilderController extends Zend_Controller_Action
$this->view->dialog = $this->view->render('showbuilder/builderDialog.phtml');
}
private function getStartEnd()
{
$request = $this->getRequest();
$userTimezone = new DateTimeZone(Application_Model_Preference::GetUserTimezone());
$utcTimezone = new DateTimeZone("UTC");
$utcNow = new DateTime("now", $utcTimezone);
$start = $request->getParam("start");
$end = $request->getParam("end");
if (empty($start) || empty($end)) {
$startsDT = clone $utcNow;
$startsDT->sub(new DateInterval("P1D"));
$endsDT = clone $utcNow;
}
else {
try {
$startsDT = new DateTime($start, $userTimezone);
$startsDT->setTimezone($utcTimezone);
$endsDT = new DateTime($end, $userTimezone);
$endsDT->setTimezone($utcTimezone);
if ($startsDT > $endsDT) {
throw new Exception("start greater than end");
}
}
catch (Exception $e) {
Logging::info($e);
Logging::info($e->getMessage());
$startsDT = clone $utcNow;
$startsDT->sub(new DateInterval("P1D"));
$endsDT = clone $utcNow;
}
}
return array($startsDT, $endsDT);
}
public function checkBuilderFeedAction()
{
$request = $this->getRequest();
@ -295,7 +252,7 @@ class ShowbuilderController extends Zend_Controller_Action
$timestamp = intval($request->getParam("timestamp", -1));
$instances = $request->getParam("instances", array());
list($startsDT, $endsDT) = $this->getStartEnd();
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($request);
$opts = array("myShows" => $my_shows, "showFilter" => $show_filter);
$showBuilder = new Application_Model_ShowBuilder($startsDT, $endsDT, $opts);
@ -315,7 +272,7 @@ class ShowbuilderController extends Zend_Controller_Action
$show_instance_filter = intval($request->getParam("showInstanceFilter", 0));
$my_shows = intval($request->getParam("myShows", 0));
list($startsDT, $endsDT) = $this->getStartEnd();
list($startsDT, $endsDT) = Application_Common_HTTPHelper::getStartEndFromRequest($request);
$opts = array("myShows" => $my_shows,
"showFilter" => $show_filter,

View File

@ -111,16 +111,16 @@ class Zend_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract
$controller = strtolower($request->getControllerName());
Application_Model_Auth::pinSessionToClient(Zend_Auth::getInstance());
//Ignore authentication for all access to the rest API. We do auth via API keys for this
//and/or by OAuth.
if (strtolower($request->getModuleName()) == "rest")
{
return;
}
if (in_array($controller, array("api", "auth", "locale", "upgrade", 'whmcs-login', "provisioning"))) {
$this->setRoleName("G");
} elseif (!Zend_Auth::getInstance()->hasIdentity()) {
// If we don't have an identity and we're making a RESTful request,
// we need to do API key verification
if ($request->getModuleName() == "rest") {
$this->verifyAuth();
return;
}
if ($controller !== 'login') {
@ -143,7 +143,19 @@ class Zend_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract
}
}
} else {
// If we have an identity and we're making a RESTful request,
// we need to check the CSRF token
if ($request->_action != "get" && $request->getModuleName() == "rest") {
$tokenValid = $this->verifyCSRFToken($request->getParam("csrf_token"));
if (!$tokenValid) {
$this->getResponse()
->setHttpResponseCode(401)
->appendBody("ERROR: CSRF token mismatch.");
return;
}
}
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$this->setRoleName($userInfo->type);
@ -169,6 +181,40 @@ class Zend_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract
}
}
private function verifyAuth() {
if ($this->verifyAPIKey()) {
return true;
}
$this->getResponse()
->setHttpResponseCode(401)
->appendBody("ERROR: Incorrect API key.");
return false;
}
private function verifyCSRFToken($token) {
$current_namespace = new Zend_Session_Namespace('csrf_namespace');
$observed_csrf_token = $token;
$expected_csrf_token = $current_namespace->authtoken;
Logging::error("Observed: " . $observed_csrf_token);
Logging::error("Expected: " . $expected_csrf_token);
return ($observed_csrf_token == $expected_csrf_token);
}
private function verifyAPIKey() {
// The API key is passed in via HTTP "basic authentication":
// http://en.wikipedia.org/wiki/Basic_access_authentication
$CC_CONFIG = Config::getConfig();
// Decode the API key that was passed to us in the HTTP request.
$authHeader = $this->getRequest()->getHeader("Authorization");
$encodedRequestApiKey = substr($authHeader, strlen("Basic "));
$encodedStoredApiKey = base64_encode($CC_CONFIG["apiKey"][0] . ":");
return ($encodedRequestApiKey === $encodedStoredApiKey);
}
/**
* Deny Access Function
* Redirects to errorPage, this can be called from an action using the action helper

View File

@ -209,8 +209,12 @@ class Application_Form_AddShowWhen extends Zend_Form_SubForm
$interval = 'P21D';
} elseif ($formData["add_show_repeat_type"] == 5) {
$interval = 'P28D';
} elseif ($formData["add_show_repeat_type"] == 2) {
} elseif ($formData["add_show_repeat_type"] == 2 && $formData["add_show_monthly_repeat_type"] == 2) {
$interval = 'P1M';
} elseif ($formData["add_show_repeat_type"] == 2 && $formData["add_show_monthly_repeat_type"] == 3) {
list($weekNumberOfMonth, $dayOfWeek) =
Application_Service_ShowService::getMonthlyWeeklyRepeatInterval(
new DateTime($start_time, $showTimezone));
}
/* Check first show
@ -274,12 +278,26 @@ class Application_Form_AddShowWhen extends Zend_Form_SubForm
$this->getElement('add_show_duration')->setErrors(array(_('Cannot schedule overlapping shows')));
break 1;
} else {
$repeatShowStart->setTimezone($showTimezone);
$repeatShowEnd->setTimezone($showTimezone);
$repeatShowStart->add(new DateInterval($interval));
$repeatShowEnd->add(new DateInterval($interval));
$repeatShowStart->setTimezone($utc);
$repeatShowEnd->setTimezone($utc);
if ($formData["add_show_repeat_type"] == 2 && $formData["add_show_monthly_repeat_type"] == 3) {
$monthlyWeeklyStart = new DateTime($repeatShowStart->format("Y-m"),
new DateTimeZone("UTC"));
$monthlyWeeklyStart->add(new DateInterval("P1M"));
$repeatShowStart = clone Application_Service_ShowService::getNextMonthlyWeeklyRepeatDate(
$monthlyWeeklyStart,
$formData["add_show_timezone"],
$formData['add_show_start_time'],
$weekNumberOfMonth,
$dayOfWeek);
$repeatShowEnd = clone $repeatShowStart;
$repeatShowEnd->add(new DateInterval("PT".$hours."H".$minutes."M"));
} else {
$repeatShowStart->setTimezone($showTimezone);
$repeatShowEnd->setTimezone($showTimezone);
$repeatShowStart->add(new DateInterval($interval));
$repeatShowEnd->add(new DateInterval($interval));
$repeatShowStart->setTimezone($utc);
$repeatShowEnd->setTimezone($utc);
}
}
}
}

View File

@ -5,6 +5,8 @@ class Application_Form_GeneralPreferences extends Zend_Form_SubForm
public function init()
{
$maxLens = Application_Model_Show::getMaxLengths();
$notEmptyValidator = Application_Form_Helper_ValidationTypes::overrideNotEmptyValidator();
$rangeValidator = Application_Form_Helper_ValidationTypes::overrideBetweenValidator(0, 59.9);
$this->setDecorators(array(
@ -13,83 +15,84 @@ class Application_Form_GeneralPreferences extends Zend_Form_SubForm
$defaultFadeIn = Application_Model_Preference::GetDefaultFadeIn();
$defaultFadeOut = Application_Model_Preference::GetDefaultFadeOut();
//Station name
$this->addElement('text', 'stationName', array(
'class' => 'input_text',
'label' => _('Station Name'),
'required' => false,
'filters' => array('StringTrim'),
'class' => 'input_text',
'label' => _('Station Name'),
'required' => false,
'filters' => array('StringTrim'),
'value' => Application_Model_Preference::GetStationName(),
'decorators' => array(
'ViewHelper'
)
));
//Default station fade in
// Station description
$stationDescription = new Zend_Form_Element_Textarea("stationDescription");
$stationDescription->setLabel(_('Station Description'));
$stationDescription->setValue(Application_Model_Preference::GetStationDescription());
$stationDescription->setRequired(false);
$stationDescription->setValidators(array(array('StringLength', false, array(0, $maxLens['description']))));
$stationDescription->setAttrib('rows', 4);
$this->addElement($stationDescription);
//Default station crossfade duration
$this->addElement('text', 'stationDefaultCrossfadeDuration', array(
'class' => 'input_text',
'label' => _('Default Crossfade Duration (s):'),
'required' => true,
'filters' => array('StringTrim'),
'validators' => array(
array(
$rangeValidator,
$notEmptyValidator,
'regex', false, array('/^[0-9]{1,2}(\.\d{1})?$/', 'messages' => _('enter a time in seconds 0{.0}'))
)
),
'value' => Application_Model_Preference::GetDefaultCrossfadeDuration(),
'decorators' => array(
'ViewHelper'
)
'class' => 'input_text',
'label' => _('Default Crossfade Duration (s):'),
'required' => true,
'filters' => array('StringTrim'),
'validators' => array(
$rangeValidator,
$notEmptyValidator,
array('regex', false, array('/^[0-9]+(\.\d+)?$/', 'messages' => _('Please enter a time in seconds (eg. 0.5)')))
),
'value' => Application_Model_Preference::GetDefaultCrossfadeDuration(),
));
//Default station fade in
$this->addElement('text', 'stationDefaultFadeIn', array(
'class' => 'input_text',
'label' => _('Default Fade In (s):'),
'required' => true,
'filters' => array('StringTrim'),
'class' => 'input_text',
'label' => _('Default Fade In (s):'),
'required' => true,
'filters' => array('StringTrim'),
'validators' => array(
array(
$rangeValidator,
$notEmptyValidator,
'regex', false, array('/^[0-9]{1,2}(\.\d{1})?$/', 'messages' => _('enter a time in seconds 0{.0}'))
)
$rangeValidator,
$notEmptyValidator,
array('regex', false, array('/^[0-9]+(\.\d+)?$/', 'messages' => _('Please enter a time in seconds (eg. 0.5)')))
),
'value' => $defaultFadeIn,
'decorators' => array(
'ViewHelper'
)
));
//Default station fade out
$this->addElement('text', 'stationDefaultFadeOut', array(
'class' => 'input_text',
'label' => _('Default Fade Out (s):'),
'required' => true,
'filters' => array('StringTrim'),
'validators' => array(
array(
$rangeValidator,
$notEmptyValidator,
'regex', false, array('/^[0-9]{1,2}(\.\d{1})?$/', 'messages' => _('enter a time in seconds 0{.0}'))
)
),
'value' => $defaultFadeOut,
'decorators' => array(
'ViewHelper'
)
'class' => 'input_text',
'label' => _('Default Fade Out (s):'),
'required' => true,
'filters' => array('StringTrim'),
'validators' => array(
$rangeValidator,
$notEmptyValidator,
array('regex', false, array('/^[0-9]+(\.\d+)?$/', 'messages' => _('Please enter a time in seconds (eg. 0.5)')))
),
'value' => $defaultFadeOut,
));
$third_party_api = new Zend_Form_Element_Radio('thirdPartyApi');
$third_party_api->setLabel(
sprintf(_('Allow Remote Websites To Access "Schedule" Info?%s (Enable this to make front-end widgets work.)'), '<br>'));
$third_party_api->setMultiOptions(array(_("Disabled"),
_("Enabled")));
$third_party_api->setLabel(_('Public Airtime API'));
$third_party_api->setDescription(_('Required for embeddable schedule widget.'));
$third_party_api->setMultiOptions(array(
_("Disabled"),
_("Enabled"),
));
$third_party_api->setValue(Application_Model_Preference::GetAllow3rdPartyApi());
$third_party_api->setDecorators(array('ViewHelper'));
$third_party_api->setDescription(_('Enabling this feature will allow Airtime to provide schedule data
to external widgets that can be embedded in your website. Enable this
feature to reveal the embeddable code.'));
$third_party_api->setSeparator(' '); //No <br> between radio buttons
//$third_party_api->addDecorator(new Zend_Form_Decorator_Label(array('tag' => 'dd', 'class' => 'radio-inline-list')));
$third_party_api->addDecorator('HtmlTag', array('tag' => 'dd',
'id'=>"thirdPartyApi-element",
'class' => 'radio-inline-list',
));
$this->addElement($third_party_api);
//
// Add the description element
@ -107,10 +110,9 @@ class Application_Form_GeneralPreferences extends Zend_Form_SubForm
));
$locale = new Zend_Form_Element_Select("locale");
$locale->setLabel(_("Default Interface Language"));
$locale->setLabel(_("Default Language"));
$locale->setMultiOptions(Application_Model_Locale::getLocales());
$locale->setValue(Application_Model_Preference::GetDefaultLocale());
$locale->setDecorators(array('ViewHelper'));
$this->addElement($locale);
/* Form Element for setting the Timezone */
@ -118,7 +120,6 @@ class Application_Form_GeneralPreferences extends Zend_Form_SubForm
$timezone->setLabel(_("Station Timezone"));
$timezone->setMultiOptions(Application_Common_Timezone::getTimezones());
$timezone->setValue(Application_Model_Preference::GetDefaultTimezone());
$timezone->setDecorators(array('ViewHelper'));
$this->addElement($timezone);
/* Form Element for setting which day is the start of the week */
@ -126,7 +127,6 @@ class Application_Form_GeneralPreferences extends Zend_Form_SubForm
$week_start_day->setLabel(_("Week Starts On"));
$week_start_day->setMultiOptions($this->getWeekStartDays());
$week_start_day->setValue(Application_Model_Preference::GetWeekStartDay());
$week_start_day->setDecorators(array('ViewHelper'));
$this->addElement($week_start_day);
}

View File

@ -10,9 +10,6 @@ class Application_Form_LiveStreamingPreferences extends Zend_Form_SubForm
$isStreamConfigable = Application_Model_Preference::GetEnableStreamConf() == "true";
$defaultFade = Application_Model_Preference::GetDefaultTransitionFade();
if ($defaultFade == "") {
$defaultFade = '00.000000';
}
// automatic trasition on source disconnection
$auto_transition = new Zend_Form_Element_Checkbox("auto_transition");
@ -32,8 +29,8 @@ class Application_Form_LiveStreamingPreferences extends Zend_Form_SubForm
$transition_fade = new Zend_Form_Element_Text("transition_fade");
$transition_fade->setLabel(_("Switch Transition Fade (s)"))
->setFilters(array('StringTrim'))
->addValidator('regex', false, array('/^[0-9]{1,2}(\.\d{1,6})?$/',
'messages' => _('enter a time in seconds 00{.000000}')))
->addValidator('regex', false, array('/^[0-9]{1,2}(\.\d{1,3})?$/',
'messages' => _('enter a time in seconds 0{.000}')))
->setValue($defaultFade)
->setDecorators(array('ViewHelper'));
$this->addElement($transition_fade);

View File

@ -4,6 +4,7 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
private $criteriaOptions;
private $stringCriteriaOptions;
private $numericCriteriaOptions;
private $sortOptions;
private $limitOptions;
/* We need to know if the criteria value will be a string
@ -122,6 +123,17 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
}
return $this->limitOptions;
}
private function getSortOptions()
{
if (!isset($this->sortOptions)) {
$this->sortOptions = array(
"random" => _("random"),
"newest" => _("newest"),
"oldest" => _("oldest")
);
}
return $this->sortOptions;
}
public function init()
@ -288,6 +300,15 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
}
$this->addElement($repeatTracks);
$sort = new Zend_Form_Element_Select('sp_sort_options');
$sort->setAttrib('class', 'sp_input_select')
->setDecorators(array('viewHelper'))
->setMultiOptions($this->getSortOptions());
if (isset($storedCrit["sort"])) {
$sort->setValue($storedCrit["sort"]["value"]);
}
$this->addElement($sort);
$limit = new Zend_Form_Element_Select('sp_limit_options');
$limit->setAttrib('class', 'sp_input_select')
->setDecorators(array('viewHelper'))
@ -344,7 +365,7 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
public function preValidation($params)
{
$data = Application_Model_Block::organizeSmartPlyalistCriteria($params['data']);
$data = Application_Model_Block::organizeSmartPlaylistCriteria($params['data']);
// add elelments that needs to be added
// set multioption for modifier according to criteria_field
$modRowMap = array();

View File

@ -0,0 +1,2 @@
<?php

View File

@ -21,9 +21,9 @@
$companySiteAnchor = "<a href='" . COMPANY_SITE_URL . "'>"
. $company
. "</a>";
echo sprintf(_('%1$s copyright &copy; %2$s All rights reserved.%3$s'
. 'Maintained and distributed under the %4$s by %5$s'),
PRODUCT_NAME, $company, "<br>",
echo sprintf(_('%1$s copyright &copy; %2$s All rights reserved.<br />'
. 'Maintained and distributed under the %3$s by %4$s'),
PRODUCT_NAME, $company,
$licenseSiteAnchor,
$companySiteAnchor);
?>

View File

@ -1156,7 +1156,7 @@ SQL;
*/
public function saveSmartBlockCriteria($p_criteria)
{
$data = $this->organizeSmartPlyalistCriteria($p_criteria);
$data = $this->organizeSmartPlaylistCriteria($p_criteria);
// saving dynamic/static flag
$blockType = $data['etc']['sp_type'] == 0 ? 'static':'dynamic';
$this->saveType($blockType);
@ -1224,6 +1224,16 @@ SQL;
}
}
// insert sort info
$qry = new CcBlockcriteria();
$qry->setDbCriteria("sort")
->setDbModifier("N/A")
->setDbValue($p_criteriaData['etc']['sp_sort_options'])
->setDbBlockId($this->id)
->save();
// insert limit info
$qry = new CcBlockcriteria();
$qry->setDbCriteria("limit")
@ -1231,7 +1241,8 @@ SQL;
->setDbValue($p_criteriaData['etc']['sp_limit_value'])
->setDbBlockId($this->id)
->save();
// insert repeate track option
$qry = new CcBlockcriteria();
$qry->setDbCriteria("repeat_tracks")
@ -1352,6 +1363,7 @@ SQL;
"isrc_number" => _("ISRC"),
"label" => _("Label"),
"language" => _("Language"),
"utime" => _("Upload Time"),
"mtime" => _("Last Modified"),
"lptime" => _("Last Played"),
"length" => _("Length"),
@ -1399,6 +1411,8 @@ SQL;
"display_modifier"=>_($modifier));
} else if($criteria == "repeat_tracks") {
$storedCrit["repeat_tracks"] = array("value"=>$value);
} else if($criteria == "sort") {
$storedCrit["sort"] = array("value"=>$value);
} else {
$storedCrit["crit"][$criteria][] = array(
"criteria"=>$criteria,
@ -1507,8 +1521,20 @@ SQL;
// check if file exists
$qry->add("file_exists", "true", Criteria::EQUAL);
$qry->add("hidden", "false", Criteria::EQUAL);
if (isset($storedCrit['sort'])) {
$sortTracks = $storedCrit['sort']['value'];
}
if ($sortTracks == 'newest') {
$qry->addDescendingOrderByColumn('utime');
}
else if ($sortTracks == 'oldest') {
$qry->addAscendingOrderByColumn('utime');
}
else {
$qry->addAscendingOrderByColumn('random()');
}
}
// construct limit restriction
$limits = array();
@ -1537,9 +1563,8 @@ SQL;
Logging::info($e);
}
}
public static function organizeSmartPlyalistCriteria($p_criteria)
{
public static function organizeSmartPlaylistCriteria($p_criteria)
{
$fieldNames = array('sp_criteria_field', 'sp_criteria_modifier', 'sp_criteria_value', 'sp_criteria_extra');
$output = array();
foreach ($p_criteria as $ele) {

View File

@ -263,7 +263,7 @@ class Application_Model_Preference
if ($fade === "") {
// the default value of the fade is 00.5
return "00.5";
return "0.5";
}
return $fade;
@ -279,8 +279,8 @@ class Application_Model_Preference
$fade = self::getValue("default_fade_out");
if ($fade === "") {
// the default value of the fade is 00.5
return "00.5";
// the default value of the fade is 0.5
return "0.5";
}
return $fade;
@ -291,33 +291,6 @@ class Application_Model_Preference
self::setValue("default_fade", $fade);
}
public static function GetDefaultFade()
{
$fade = self::getValue("default_fade");
if ($fade === "") {
// the default value of the fade is 00.5
return "00.5";
}
// we need this function to work with 2.0 version on default_fade value in cc_pref
// it has 00:00:00.000000 format where in 2.1 we have 00.000000 format
if (preg_match("/([0-9]{2}):([0-9]{2}):([0-9]{2}).([0-9]{6})/", $fade, $matches) == 1 && count($matches) == 5) {
$out = 0;
$out += intval($matches[1] * 3600);
$out += intval($matches[2] * 60);
$out += intval($matches[3]);
$out .= ".$matches[4]";
$fade = $out;
}
$fade = number_format($fade, 1, '.', '');
//fades need 2 leading zeros for DateTime conversion
$fade = str_pad($fade, 4, "0", STR_PAD_LEFT);
return $fade;
}
public static function SetDefaultTransitionFade($fade)
{
self::setValue("default_transition_fade", $fade);
@ -330,7 +303,7 @@ class Application_Model_Preference
public static function GetDefaultTransitionFade()
{
$transition_fade = self::getValue("default_transition_fade");
return ($transition_fade == "") ? "00.000000" : $transition_fade;
return ($transition_fade == "") ? "0.000" : $transition_fade;
}
public static function SetStreamLabelFormat($type)

View File

@ -862,9 +862,11 @@ SQL;
* In UTC time.
* @param unknown_type $excludeInstance
* @param boolean $onlyRecord
* @param int $showId
* limits the results to instances of a given showId only
* @return array
*/
public static function getShows($start_timestamp, $end_timestamp, $onlyRecord=FALSE)
public static function getShows($start_timestamp, $end_timestamp, $onlyRecord=FALSE, $showId=null)
{
self::createAndFillShowInstancesPastPopulatedUntilDate($end_timestamp);
@ -898,13 +900,21 @@ SQL;
//only want shows that are starting at the time or later.
$start_string = $start_timestamp->format("Y-m-d H:i:s");
$end_string = $end_timestamp->format("Y-m-d H:i:s");
$params = array();
if ($showId) {
$sql .= " AND (si1.show_id = :show_id)";
$params[':show_id'] = $showId;
}
if ($onlyRecord) {
$sql .= " AND (si1.starts >= :start::TIMESTAMP AND si1.starts < :end::TIMESTAMP)";
$sql .= " AND (si1.record = 1)";
return Application_Common_Database::prepareAndExecute( $sql,
array( ':start' => $start_string,
':end' => $end_string ), 'all');
$params[':start'] = $start_string;
$params[':end'] = $end_string;
return Application_Common_Database::prepareAndExecute( $sql, $params, 'all');
} else {
$sql .= " ". <<<SQL
@ -913,15 +923,16 @@ AND ((si1.starts >= :start1::TIMESTAMP AND si1.starts < :end1::TIMESTAMP)
OR (si1.starts <= :start3::TIMESTAMP AND si1.ends >= :end3::TIMESTAMP))
ORDER BY si1.starts
SQL;
return Application_Common_Database::prepareAndExecute( $sql,
array(
$params = array_merge($params, array(
'start1' => $start_string,
'start2' => $start_string,
'start3' => $start_string,
'end1' => $end_string,
'end2' => $end_string,
'end3' => $end_string
), 'all');
)
);
return Application_Common_Database::prepareAndExecute( $sql, $params, 'all');
}
}
@ -1016,10 +1027,10 @@ SQL;
//for putting the now playing icon on the show.
if ($now > $startsDT && $now < $endsDT) {
$event["nowPlaying"] = true;
$event["nowPlaying"] = true;
}
else {
$event["nowPlaying"] = false;
$event["nowPlaying"] = false;
}
//event colouring
@ -1048,9 +1059,9 @@ SQL;
**/
private static function getPercentScheduled($p_starts, $p_ends, $p_time_filled)
{
$utcTimezone = new DatetimeZone("UTC");
$startDt = new DateTime($p_starts, $utcTimezone);
$endDt = new DateTime($p_ends, $utcTimezone);
$utcTimezone = new DatetimeZone("UTC");
$startDt = new DateTime($p_starts, $utcTimezone);
$endDt = new DateTime($p_ends, $utcTimezone);
$durationSeconds = intval($endDt->format("U")) - intval($startDt->format("U"));
$time_filled = Application_Common_DateHelper::playlistTimeToSeconds($p_time_filled);
if ($durationSeconds != 0) { //Prevent division by zero if the show duration somehow becomes zero.
@ -1457,4 +1468,5 @@ SQL;
return array($start, $end);
}
}

View File

@ -555,7 +555,7 @@ SQL;
}
public function getShowListContent()
public function getShowListContent($timezone = null)
{
$con = Propel::getConnection();
@ -606,9 +606,14 @@ SQL;
':instance_id2' => $this->_instanceId
));
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
$userTimezone = Application_Model_Preference::GetUserTimezone();
$displayTimezone = new DateTimeZone($userTimezone);
if (isset($timezone)) {
$displayTimezone = new DateTimeZone($timezone);
} else {
$userTimezone = Application_Model_Preference::GetUserTimezone();
$displayTimezone = new DateTimeZone($userTimezone);
}
$utcTimezone = new DateTimeZone("UTC");
foreach ($results as &$row) {

View File

@ -88,11 +88,19 @@ class Application_Model_Webstream implements Application_Model_LibraryEditable
public static function deleteStreams($p_ids, $p_userId)
{
$leftOver = self::streamsNotOwnedByUser($p_ids, $p_userId);
if (count($leftOver) == 0) {
CcWebstreamQuery::create()->findPKs($p_ids)->delete();
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$user = new Application_Model_User($userInfo->id);
$isAdminOrPM = $user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER));
if (!$isAdminOrPM) {
$leftOver = self::streamsNotOwnedByUser($p_ids, $p_userId);
if (count($leftOver) == 0) {
CcWebstreamQuery::create()->findPKs($p_ids)->delete();
} else {
throw new WebstreamNoPermissionException;
}
} else {
throw new WebstreamNoPermissionException;
CcWebstreamQuery::create()->findPKs($p_ids)->delete();
}
}

View File

@ -304,4 +304,23 @@ class CcShow extends BaseCcShow {
->filterByDbId($instanceId, Criteria::NOT_EQUAL)
->find();
}
public function getShowInfo()
{
$info = array();
if ($this->getDbId() == null) {
return $info;
} else {
$info['name'] = $this->getDbName();
$info['id'] = $this->getDbId();
$info['url'] = $this->getDbUrl();
$info['genre'] = $this->getDbGenre();
$info['description'] = $this->getDbDescription();
$info['color'] = $this->getDbColor();
$info['background_color'] = $this->getDbBackgroundColor();
$info['linked'] = $this->getDbLinked();
return $info;
}
}
} // CcShow

View File

@ -33,11 +33,6 @@ class Rest_MediaController extends Zend_Rest_Controller
public function indexAction()
{
if (!$this->verifyAuth(true, true))
{
return;
}
$files_array = array();
foreach (CcFilesQuery::create()->find() as $file)
{
@ -57,11 +52,6 @@ class Rest_MediaController extends Zend_Rest_Controller
public function downloadAction()
{
if (!$this->verifyAuth(true, true))
{
return;
}
$id = $this->getId();
if (!$id) {
return;
@ -84,11 +74,6 @@ class Rest_MediaController extends Zend_Rest_Controller
public function getAction()
{
if (!$this->verifyAuth(true, true))
{
return;
}
$id = $this->getId();
if (!$id) {
return;
@ -107,20 +92,6 @@ class Rest_MediaController extends Zend_Rest_Controller
public function postAction()
{
/* If the user presents a valid API key, we don't check CSRF tokens.
CSRF tokens are only used for session based authentication.
*/
if(!$this->verifyAPIKey()){
if(!$this->verifyCSRFToken($this->_getParam('csrf_token'))){
return;
}
}
if (!$this->verifyAuth(true, true))
{
return;
}
//If we do get an ID on a POST, then that doesn't make any sense
//since POST is only for creating.
if ($id = $this->_getParam('id', false)) {
@ -181,11 +152,6 @@ class Rest_MediaController extends Zend_Rest_Controller
public function putAction()
{
if (!$this->verifyAuth(true, true))
{
return;
}
$id = $this->getId();
if (!$id) {
return;
@ -275,11 +241,6 @@ class Rest_MediaController extends Zend_Rest_Controller
public function deleteAction()
{
if (!$this->verifyAuth(true, true))
{
return;
}
$id = $this->getId();
if (!$id) {
return;
@ -308,80 +269,6 @@ class Rest_MediaController extends Zend_Rest_Controller
return $id;
}
private function verifyCSRFToken($token){
$current_namespace = new Zend_Session_Namespace('csrf_namespace');
$observed_csrf_token = $token;
$expected_csrf_token = $current_namespace->authtoken;
if($observed_csrf_token == $expected_csrf_token){
return true;
}else{
return false;
}
}
private function verifyAuth($checkApiKey, $checkSession)
{
// Session takes precedence over API key for now:
if ($checkSession && $this->verifySession()) {
// CSRF token validation only applies to session based authorization.
if(!$this->verifyCSRFToken($this->_getParam('csrf_token'))){
$resp = $this->getResponse();
$resp->setHttpResponseCode(401);
$resp->appendBody("ERROR: Token Missmatch.");
return false;
}
return true;
}
if ($checkApiKey && $this->verifyAPIKey())
{
return true;
}
$resp = $this->getResponse();
$resp->setHttpResponseCode(401);
$resp->appendBody("ERROR: Incorrect API key.");
return false;
}
private function verifyAPIKey()
{
//The API key is passed in via HTTP "basic authentication":
// http://en.wikipedia.org/wiki/Basic_access_authentication
$CC_CONFIG = Config::getConfig();
//Decode the API key that was passed to us in the HTTP request.
$authHeader = $this->getRequest()->getHeader("Authorization");
$encodedRequestApiKey = substr($authHeader, strlen("Basic "));
$encodedStoredApiKey = base64_encode($CC_CONFIG["apiKey"][0] . ":");
if ($encodedRequestApiKey === $encodedStoredApiKey)
{
return true;
} else {
return false;
}
return false;
}
private function verifySession()
{
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity())
{
return true;
}
return false;
//Token checking stub code. We'd need to change LoginController.php to generate a token too, but
//but luckily all the token code already exists and works.
//$auth = new Application_Model_Auth();
//$auth->checkToken(Application_Model_Preference::getUserId(), $token);
}
private function fileNotFoundResponse()
{
$resp = $this->getResponse();
@ -489,7 +376,7 @@ class Rest_MediaController extends Zend_Rest_Controller
private function getOwnerId()
{
try {
if ($this->verifySession()) {
if (Zend_Auth::getInstance()->hasIdentity()) {
$service_user = new Application_Service_UserService();
return $service_user->getCurrentUser()->getDbId();
} else {

View File

@ -204,30 +204,34 @@ class Application_Service_HistoryService
//------------------------------------------------------------------------
//Using Datatables parameters to sort the data.
$numOrderColumns = $opts["iSortingCols"];
$orderBys = array();
if (empty($opts["iSortingCols"])) {
$orderBys = array();
} else {
$numOrderColumns = $opts["iSortingCols"];
$orderBys = array();
for ($i = 0; $i < $numOrderColumns; $i++) {
for ($i = 0; $i < $numOrderColumns; $i++) {
$colNum = $opts["iSortCol_".$i];
$key = $opts["mDataProp_".$colNum];
$sortDir = $opts["sSortDir_".$i];
$colNum = $opts["iSortCol_".$i];
$key = $opts["mDataProp_".$colNum];
$sortDir = $opts["sSortDir_".$i];
if (in_array($key, $required)) {
if (in_array($key, $required)) {
$orderBys[] = "history_range.{$key} {$sortDir}";
}
else if (in_array($key, $filemd_keys)) {
$orderBys[] = "history_range.{$key} {$sortDir}";
}
else if (in_array($key, $filemd_keys)) {
$orderBys[] = "file_info.{$key} {$sortDir}";
}
else if (in_array($key, $general_keys)) {
$orderBys[] = "file_info.{$key} {$sortDir}";
}
else if (in_array($key, $general_keys)) {
$orderBys[] = "{$key}_filter.{$key} {$sortDir}";
}
else {
//throw new Exception("Error: $key is not part of the template.");
}
$orderBys[] = "{$key}_filter.{$key} {$sortDir}";
}
else {
//throw new Exception("Error: $key is not part of the template.");
}
}
}
if (count($orderBys) > 0) {
@ -241,7 +245,7 @@ class Application_Service_HistoryService
//---------------------------------------------------------------
//using Datatables parameters to add limits/offsets
$displayLength = intval($opts["iDisplayLength"]);
$displayLength = empty($opts["iDisplayLength"]) ? -1 : intval($opts["iDisplayLength"]);
//limit the results returned.
if ($displayLength !== -1) {
$mainSqlQuery.=
@ -275,14 +279,14 @@ class Application_Service_HistoryService
foreach ($fields as $index=>$field) {
if ($field["type"] == TEMPLATE_BOOLEAN) {
$boolCast[] = $field["name"];
$boolCast[] = $field;
}
}
foreach ($rows as $index => &$result) {
foreach ($boolCast as $name) {
$result[$name] = (bool) $result[$name];
foreach ($boolCast as $field) {
$result[$field['label']] = (bool) $result[$field['name']];
}
//need to display the results in the station's timezone.
@ -311,7 +315,7 @@ class Application_Service_HistoryService
}
return array(
"sEcho" => intval($opts["sEcho"]),
"sEcho" => empty($opts["sEcho"]) ? null : intval($opts["sEcho"]),
//"iTotalDisplayRecords" => intval($totalDisplayRows),
"iTotalDisplayRecords" => intval($totalRows),
"iTotalRecords" => intval($totalRows),
@ -445,9 +449,13 @@ class Application_Service_HistoryService
);
}
public function getShowList($startDT, $endDT)
public function getShowList($startDT, $endDT, $userId = null)
{
$user = Application_Model_User::getCurrentUser();
if (empty($userId)) {
$user = Application_Model_User::getCurrentUser();
} else {
$user = new Application_Model_User($userId);
}
$shows = Application_Model_Show::getShows($startDT, $endDT);
Logging::info($startDT->format("Y-m-d H:i:s"));
@ -456,7 +464,7 @@ class Application_Service_HistoryService
Logging::info($shows);
//need to filter the list to only their shows
if ($user->isHost()) {
if ((!empty($user)) && ($user->isHost())) {
$showIds = array();
@ -1524,4 +1532,4 @@ class Application_Service_HistoryService
throw $e;
}
}
}
}

View File

@ -1133,7 +1133,7 @@ SQL;
$start = $this->getNextRepeatingPopulateStartDateTime($showDay);
if (is_null($repeatInterval)&& $repeatType == REPEAT_MONTHLY_WEEKLY) {
$repeatInterval = $this->getMonthlyWeeklyRepeatInterval($start, $timezone);
$repeatInterval = self::getMonthlyWeeklyRepeatInterval($start, $timezone);
}
//DatePeriod in user's local time
@ -1236,7 +1236,7 @@ SQL;
// We will only need this if the repeat type is MONTHLY_WEEKLY
list($weekNumberOfMonth, $dayOfWeek) =
$this->getMonthlyWeeklyRepeatInterval(
self::getMonthlyWeeklyRepeatInterval(
new DateTime($first_show, new DateTimeZone($timezone)));
$this->repeatType = $showDay->getDbRepeatType();
@ -1296,7 +1296,7 @@ SQL;
$monthlyWeeklyStart = new DateTime($utcStartDateTime->format("Y-m"),
new DateTimeZone("UTC"));
$monthlyWeeklyStart->add(new DateInterval("P1M"));
$start = $this->getNextMonthlyWeeklyRepeatDate(
$start = self::getNextMonthlyWeeklyRepeatDate(
$monthlyWeeklyStart,
$timezone,
$showDay->getDbStartTime(),
@ -1318,7 +1318,7 @@ SQL;
* @param string $showStart
* @param string $timezone user's local timezone
*/
private function getMonthlyWeeklyRepeatInterval($showStart)
public static function getMonthlyWeeklyRepeatInterval($showStart)
{
$start = clone $showStart;
$dayOfMonth = $start->format("j");
@ -1393,7 +1393,7 @@ SQL;
* @param string (i.e. 'first', 'second') $weekNumberOfMonth
* @param string (i.e. 'Monday') $dayOfWeek
*/
private function getNextMonthlyWeeklyRepeatDate(
public static function getNextMonthlyWeeklyRepeatDate(
$start,
$timezone,
$startTime,

View File

@ -1,156 +1,23 @@
<fieldset class="padded">
<dl class="zend_form">
<dt id="stationName-label" class="block-display">
<label class="required" for="stationName"><?php echo $this->element->getElement('stationName')->getLabel() ?>:
</label>
</dt>
<dd id="stationName-element" class="block-display">
<?php echo $this->element->getElement('stationName') ?>
<?php if($this->element->getElement('stationName')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach($this->element->getElement('stationName')->getMessages() as $error): ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
<dt id="stationDefaultFadeIn-label" class="block-display">
<label class="optional" for="stationDefaultFadeIn"><?php echo $this->element->getElement('stationDefaultFadeIn')->getLabel() ?></label>
</dt>
<dd id="stationDefaultFadeIn-element" class="block-display">
<?php echo $this->element->getElement('stationDefaultFadeIn') ?>
<?php if($this->element->getElement('stationDefaultFadeIn')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach($this->element->getElement('stationDefaultFadeIn')->getMessages() as $error): ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
<dt id="stationDefaultFadeOut-label" class="block-display">
<label class="optional" for="stationDefaultFadeOut"><?php echo $this->element->getElement('stationDefaultFadeOut')->getLabel() ?></label>
</dt>
<dd id="stationDefaultFadeOut-element" class="block-display">
<?php echo $this->element->getElement('stationDefaultFadeOut') ?>
<?php if($this->element->getElement('stationDefaultFadeOut')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach($this->element->getElement('stationDefaultFadeOut')->getMessages() as $error): ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
<dt id="stationDefaultCrossfadeDuration-label" class="block-display">
<label class="optional" for="stationDefaultCrossfadeDuration"><?php echo $this->element->getElement('stationDefaultCrossfadeDuration')->getLabel() ?></label>
</dt>
<dd id="stationDefaultCrossfadeDuration-element" class="block-display">
<?php echo $this->element->getElement('stationDefaultCrossfadeDuration') ?>
<?php if($this->element->getElement('stationDefaultCrossfadeDuration')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach($this->element->getElement('stationDefaultCrossfadeDuration')->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() ?>
<span class="icecast_metadata_help_icon" id="thirdPartyApiInfo"></span>
</label>
</dt>
<dd id="thirdPartyApi-element" class="block-display radio-inline-list">
<?php $i=0;
$value = $this->element->getElement('thirdPartyApi')->getValue();
?>
<?php echo $this->element->getElement('stationName')->render() ?>
<?php foreach ($this->element->getElement('thirdPartyApi')->getMultiOptions() as $radio) : ?>
<label for="thirdPartyApi-<?php echo $i ?>">
<input type="radio" value="<?php echo $i ?>" id="thirdPartyApi-<?php echo $i ?>" name="thirdPartyApi" <?php if($i == $value){echo 'checked="checked"';}?>>
<?php echo $radio ?>
</input>
</label>
<?php $i = $i + 1; ?>
<?php endforeach; ?>
<?php if($this->element->getElement('thirdPartyApi')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach($this->element->getElement('thirdPartyApi')->getMessages() as $error): ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
<?php echo $this->element->getElement('stationDescription')->render() ?>
<dt id="widgetCode-label" style="display:none;" class="block-display">
<label class="optional" for="widgetCode"><?php echo $this->element->getElement('widgetCode')->getLabel() ?></label>
</dt>
<dd id="widgetCode-element" style="display:none;" class="block-display clearfix">
<?php echo $this->element->getElement('widgetCode') ?>
<?php if($this->element->getElement('widgetCode')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach($this->element->getElement('widgetCode')->getMessages() as $error): ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
<dt id="locale-label" class="block-display">
<label class="required" for="locale"><?php echo $this->element->getElement('locale')->getLabel() ?>:
</label>
</dt>
<dd id="locale-element" class="block-display">
<?php echo $this->element->getElement('locale') ?>
<?php if($this->element->getElement('locale')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach($this->element->getElement('locale')->getMessages() as $error): ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
<?php echo $this->element->getElement('locale')->render() ?>
<dt id="timezone-label" class="block-display">
<label class="required" for="timezone"><?php echo $this->element->getElement('timezone')->getLabel() ?>:
<span class="info-text-small"><?php _("(Required)") ?></span>
</label>
</dt>
<dd id="timezone-element" class="block-display">
<?php echo $this->element->getElement('timezone') ?>
<?php if($this->element->getElement('timezone')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach($this->element->getElement('timezone')->getMessages() as $error): ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
<?php echo $this->element->getElement('timezone')->render() ?>
<!-- Week Start Day option -->
<dt id="weekStartDay-label" class="block-display">
<label class="required" for="timezone"><?php echo $this->element->getElement('weekStartDay')->getLabel() ?>:
</label>
</dt>
<dd id="weekStartDay-element" class="block-display">
<?php $i=0;
$value = $this->element->getElement('weekStartDay')->getValue();
?>
<select id="weekStartDay" name="weekStartDay">
<?php foreach ($this->element->getElement('weekStartDay')->getMultiOptions() as $option) : ?>
<option value="<?php echo $i ?>" <?php if($i == $value){echo 'selected="selected"';}?> >
<?php echo $option ?>
</option>
<?php $i = $i + 1; ?>
<?php endforeach; ?>
</select>
<?php echo $this->element->getElement('weekStartDay')->render() ?>
<?php echo $this->element->getElement('stationDefaultFadeIn')->render() ?>
<?php echo $this->element->getElement('stationDefaultFadeOut')->render() ?>
<?php echo $this->element->getElement('stationDefaultCrossfadeDuration')->render() ?>
<?php echo $this->element->getElement('thirdPartyApi')->render() ?>
<?php if($this->element->getElement('weekStartDay')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach($this->element->getElement('weekStartDay')->getMessages() as $error): ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
</dl>
</fieldset>

View File

@ -3,10 +3,10 @@
<fieldset>
<dl class="zend_form">
<dt class="block-display info-text">
<?php echo sprintf(_('Help %1$s improve by letting us know how you are using it. This info '
.'will be collected regularly in order to enhance your user experience.%2$s'
.'Click \'Yes, help %1$s\' and we\'ll make sure the features you use are '
.'constantly improving.'), PRODUCT_NAME, "<br /><br />") ?>
<?php echo sprintf(_("Help improve %s by letting us know how you're using it. This information"
." will be collected regularly in order to enhance your user experience.<br />"
."Click the box below and we'll make sure the features you use are constantly improving."),
PRODUCT_NAME)?>
</dt>
<dd id="SupportFeedback-element" class="block-display">
<label class="optional" for="SupportFeedback">

View File

@ -95,7 +95,18 @@
<?php endif; ?>
<br />
</dd>
<dd id='sp_sort-element'>
<span class='sp_text_font'>Sort tracks by</span>
<?php echo $this->element->getElement('sp_sort_options') ?>
<?php if($this->element->getElement("sp_sort_options")->hasErrors()) : ?>
<?php foreach($this->element->getElement("sp_sort_options")->getMessages() as $error): ?>
<span class='errors sp-errors'>
<?php echo $error; ?>
</span>
<?php endforeach; ?>
<?php endif; ?>
<br />
</dd>
<dd id='sp_limit-element'>
<span class='sp_text_font'><?php echo $this->element->getElement('sp_limit_value')->getLabel() ?></span>
<?php echo $this->element->getElement('sp_limit_value')?>

View File

@ -1,5 +1,51 @@
<fieldset class="padded">
<dl id="public-info" style="display:<?php echo "block"?>;">
<dl class="zend_form">
<dd id="SupportFeedback-element" style="width:90%;">
<div class="info-text">
<?php echo sprintf(_("Help improve %s by letting us know how you're using it. This information"
." will be collected regularly in order to enhance your user experience.<br />"
."Click the box below and we'll make sure the features you use are constantly improving."),
PRODUCT_NAME)?>
</div>
<label class="optional" for="SupportFeedback">
<?php echo $this->element->getElement('SupportFeedback') ?>
<strong><?php echo $this->element->getElement('SupportFeedback')->getLabel() ?></strong>
</label>
<?php if($this->element->getElement('SupportFeedback')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach($this->element->getElement('SupportFeedback')->getMessages() as $error): ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
<dd id="publicize-element" style="width:90%;">
<div class="info-text">
<?php
$whosUsingAnchor = "<a id='link_to_whos_using' href='" . WHOS_USING_URL . "' onclick='window.open(this.href); return false'>"
. COMPANY_SITE
. "</a>";
echo sprintf(_("Click the box below to promote your station on %s."), $whosUsingAnchor)
?>
</div>
<label class="optional" for="Publicise">
<?php echo $this->element->getElement('Publicise') ?>
<strong><?php echo $this->element->getElement('Publicise')->getLabel() ?></strong>
</label>
<?php if($this->element->getElement('Publicise')->hasErrors()) : ?>
<ul class='errors'>
<?php foreach($this->element->getElement('Publicise')->getMessages() as $error): ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</dd>
</dl>
<div class="info-text" style="clear: both;padding: 4px 0 4px 15px;">
<?php echo _("(In order to promote your station, 'Send support feedback' must be enabled).")?><br /><br />
</div>
<dl id="public-info" style="display:<?php echo "none"?>;">
<dt id="stationName-label" class="block-display">
<label class="required" for="stationName"><?php echo $this->element->getElement('stationName')->getLabel() ?>
<span class="info-text-small"><?php echo _("(Required)")?></span>:

View File

@ -185,7 +185,11 @@ CREATE TABLE "cc_show_instances"
PRIMARY KEY ("id")
);
-----------------------------------------------------------------------
COMMENT ON TABLE "cc_show_instances" IS '';
SET search_path TO public;
-----------------------------------------------------------------------------
-- cc_show_days
-----------------------------------------------------------------------

View File

@ -10,10 +10,11 @@ body {
}
html, body {
height: 100%;
background: #7f7f7f;
}
#login-page {
background: #1f1f1f url(images/login_page_bg.png) no-repeat center 0;`
background: #1f1f1f url(images/login_page_bg.png) no-repeat center 0;
margin: 0;
padding: 0;
height:100%;
@ -1002,7 +1003,28 @@ input[type="checkbox"] {
display:block;
}
dt.block-display, dd.block-display {
#pref_form dt, #pref_form dd,
#pref_form textarea {
display:block;
float:none;
margin-left:0;
padding-left:0;
width: 100%;
}
#pref_form textarea {
width: 98.5%;
}
#pref_form select {
width: 100%;
}
#pref_form p.description {
color: #3b3b3b;
font-size: 12px;
float: left;
}
dt.block-display, dd.block-display {
display:block;
float:none;
margin-left:0;

View File

@ -1059,7 +1059,10 @@ var AIRTIME = (function(AIRTIME){
"<i class='icon-white icon-ban-circle'></i></button></div>");
}
$toolbar.append($menu);
if (localStorage.getItem('user-type') != 'G') {
$toolbar.append($menu);
}
$menu = undefined;
$('#timeline-sa').click(function(){mod.selectAll();});

View File

@ -24,7 +24,7 @@ class CuePointAnalyzer(Analyzer):
the unit test on the short m4a file fails. With the new setting, it gets the correct cue-in time and
all the unit tests pass.
'''
command = [CuePointAnalyzer.SILAN_EXECUTABLE, '-b', '-F', '0.99', '-f', 'JSON', filename]
command = [CuePointAnalyzer.SILAN_EXECUTABLE, '-b', '-F', '0.99', '-f', 'JSON', '-t', '1.0', filename]
try:
results_json = subprocess.check_output(command, stderr=subprocess.STDOUT, close_fds=True)
silan_results = json.loads(results_json)

View File

@ -27,7 +27,7 @@ setup(name='airtime_analyzer',
'nose',
'coverage',
'mock',
'python-daemon',
'python-daemon==1.6',
'requests',
'apache-libcloud',
'rgain',

54
utils/upgrade.py Executable file
View File

@ -0,0 +1,54 @@
#!/usr/bin/python
import ConfigParser
import argparse
import requests
from urlparse import urlparse
import sys
CONFIG_PATH='/etc/airtime/airtime.conf'
GENERAL_CONFIG_SECTION = "general"
def read_config_file(config_path):
"""Parse the application's config file located at config_path."""
config = ConfigParser.SafeConfigParser()
try:
config.readfp(open(config_path))
except IOError as e:
print "Failed to open config file at " + config_path + ": " + e.strerror
exit(-1)
except Exception:
print e.strerror
exit(-1)
return config
if __name__ == '__main__':
config = read_config_file(CONFIG_PATH)
api_key = config.get(GENERAL_CONFIG_SECTION, 'api_key')
base_url = config.get(GENERAL_CONFIG_SECTION, 'base_url')
base_dir = config.get(GENERAL_CONFIG_SECTION, 'base_dir')
action = "upgrade"
airtime_url = ""
parser = argparse.ArgumentParser()
parser.add_argument('--downgrade', help='Downgrade the station', action="store_true")
parser.add_argument('station_url', help='station URL', nargs='?', default='')
args = parser.parse_args()
if args.downgrade:
action = "downgrade"
if airtime_url == "":
airtime_url = "http://%s%s" % (base_url, base_dir)
# Add http:// if you were lazy and didn't pass a scheme to this script
url = urlparse(airtime_url)
if not url.scheme:
airtime_url = "http://%s" % airtime_url
print "Requesting %s..." % action
r = requests.get("%s/%s" % (airtime_url, action), auth=(api_key, ''))
print r.text
r.raise_for_status()