Merge branch '2.2.x' into 2.2.x-saas

Conflicts:
	airtime_mvc/application/controllers/PreferenceController.php
	airtime_mvc/application/controllers/ScheduleController.php
	airtime_mvc/application/forms/EmailServerPreferences.php
	airtime_mvc/application/forms/GeneralPreferences.php
	airtime_mvc/application/forms/LiveStreamingPreferences.php
	airtime_mvc/application/forms/Preferences.php
	airtime_mvc/application/forms/SupportSettings.php
	airtime_mvc/application/models/Schedule.php
	airtime_mvc/application/views/scripts/form/preferences.phtml
	airtime_mvc/application/views/scripts/form/preferences_email_server.phtml
	airtime_mvc/application/views/scripts/form/preferences_livestream.phtml
	airtime_mvc/application/views/scripts/form/support-setting.phtml
	airtime_mvc/application/views/scripts/menu.phtml
	airtime_mvc/application/views/scripts/schedule/add-
show-form.phtml
This commit is contained in:
Martin Konecny 2012-11-06 17:23:32 -05:00
commit 272e428fa7
19 changed files with 118 additions and 53 deletions

View File

@ -176,7 +176,7 @@ class LibraryController extends Zend_Controller_Action
if ($isAdminOrPM || $obj->getCreatorId() == $user->getId()) { if ($isAdminOrPM || $obj->getCreatorId() == $user->getId()) {
if ($obj_sess->type === "playlist") { if ($obj_sess->type === "playlist") {
$menu["pl_add"] = array("name"=> "Add to Playlist", "icon" => "add-playlist", "icon" => "copy"); $menu["pl_add"] = array("name"=> "Add to Playlist", "icon" => "add-playlist", "icon" => "copy");
} elseif ($obj_sess->type === "block") { } elseif ($obj_sess->type === "block" && $obj->isStatic()) {
$menu["pl_add"] = array("name"=> "Add to Smart Block", "icon" => "add-playlist", "icon" => "copy"); $menu["pl_add"] = array("name"=> "Add to Smart Block", "icon" => "add-playlist", "icon" => "copy");
} }
} }

View File

@ -513,7 +513,7 @@ class PlaylistController extends Zend_Controller_Action
} catch (BlockNotFoundException $e) { } catch (BlockNotFoundException $e) {
$this->playlistNotFound('block', true); $this->playlistNotFound('block', true);
} catch (Exception $e) { } catch (Exception $e) {
//Logging::info($e); Logging::info($e);
$this->playlistUnknownError($e); $this->playlistUnknownError($e);
} }
} }

View File

@ -65,13 +65,12 @@ class PreferenceController extends Zend_Controller_Action
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/preferences/support-setting.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'/js/airtime/preferences/support-setting.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
$this->view->statusMsg = ""; $this->view->statusMsg = "";
$isSass = Application_Model_Preference::GetPlanLevel() == 'disabled'?false:true;
$form = new Application_Form_SupportSettings(); $form = new Application_Form_SupportSettings();
if ($request->isPost()) { if ($request->isPost()) {
$values = $request->getPost(); $values = $request->getPost();
if ($form->isValid($values)) { if ($form->isValid($values)) {
if (!$isSass && $values["Publicise"] != 1) { if ($values["Publicise"] != 1) {
Application_Model_Preference::SetSupportFeedback($values["SupportFeedback"]); Application_Model_Preference::SetSupportFeedback($values["SupportFeedback"]);
Application_Model_Preference::SetPublicise($values["Publicise"]); Application_Model_Preference::SetPublicise($values["Publicise"]);
if (isset($values["Privacy"])) { if (isset($values["Privacy"])) {
@ -82,10 +81,8 @@ class PreferenceController extends Zend_Controller_Action
Application_Model_Preference::SetPhone($values["Phone"]); Application_Model_Preference::SetPhone($values["Phone"]);
Application_Model_Preference::SetEmail($values["Email"]); Application_Model_Preference::SetEmail($values["Email"]);
Application_Model_Preference::SetStationWebSite($values["StationWebSite"]); Application_Model_Preference::SetStationWebSite($values["StationWebSite"]);
if (!$isSass) {
Application_Model_Preference::SetSupportFeedback($values["SupportFeedback"]); Application_Model_Preference::SetSupportFeedback($values["SupportFeedback"]);
Application_Model_Preference::SetPublicise($values["Publicise"]); Application_Model_Preference::SetPublicise($values["Publicise"]);
}
$form->Logo->receive(); $form->Logo->receive();
$imagePath = $form->Logo->getFileName(); $imagePath = $form->Logo->getFileName();
@ -94,7 +91,7 @@ class PreferenceController extends Zend_Controller_Action
Application_Model_Preference::SetStationCity($values["City"]); Application_Model_Preference::SetStationCity($values["City"]);
Application_Model_Preference::SetStationDescription($values["Description"]); Application_Model_Preference::SetStationDescription($values["Description"]);
Application_Model_Preference::SetStationLogo($imagePath); Application_Model_Preference::SetStationLogo($imagePath);
if (!$isSass && isset($values["Privacy"])) { if (isset($values["Privacy"])) {
Application_Model_Preference::SetPrivacyPolicyCheck($values["Privacy"]); Application_Model_Preference::SetPrivacyPolicyCheck($values["Privacy"]);
} }
} }

View File

@ -105,7 +105,6 @@ class Application_Form_SupportSettings extends Zend_Form
$upload->setAttrib('accept', 'image/*'); $upload->setAttrib('accept', 'image/*');
$this->addElement($upload); $this->addElement($upload);
if (!$isSass) {
//enable support feedback //enable support feedback
$this->addElement('checkbox', 'SupportFeedback', array( $this->addElement('checkbox', 'SupportFeedback', array(
'label' => 'Send support feedback', 'label' => 'Send support feedback',
@ -146,7 +145,6 @@ class Application_Form_SupportSettings extends Zend_Form
$checkboxPrivacy->setLabel("By checking this box, I agree to Sourcefabric's <a id=\"link_to_privacy\" href=\"http://www.sourcefabric.org/en/about/policy/\" onclick=\"window.open(this.href); return false;\">privacy policy</a>.") $checkboxPrivacy->setLabel("By checking this box, I agree to Sourcefabric's <a id=\"link_to_privacy\" href=\"http://www.sourcefabric.org/en/about/policy/\" onclick=\"window.open(this.href); return false;\">privacy policy</a>.")
->setDecorators(array('ViewHelper')); ->setDecorators(array('ViewHelper'));
$this->addElement($checkboxPrivacy); $this->addElement($checkboxPrivacy);
}
// submit button // submit button
$submit = new Zend_Form_Element_Submit("submit"); $submit = new Zend_Form_Element_Submit("submit");
@ -161,7 +159,6 @@ class Application_Form_SupportSettings extends Zend_Form
public function isValid ($data) public function isValid ($data)
{ {
$isValid = parent::isValid($data); $isValid = parent::isValid($data);
if (!$this->isSass) {
if ($data['Publicise'] != 1) { if ($data['Publicise'] != 1) {
$isValid = true; $isValid = true;
} }
@ -172,7 +169,6 @@ class Application_Form_SupportSettings extends Zend_Form
$isValid = false; $isValid = false;
} }
} }
}
return $isValid; return $isValid;
} }

View File

@ -210,10 +210,23 @@ FROM cc_blockcontents AS pc
LEFT JOIN cc_files AS f ON pc.file_id=f.id LEFT JOIN cc_files AS f ON pc.file_id=f.id
LEFT JOIN cc_block AS bl ON pc.block_id = bl.id LEFT JOIN cc_block AS bl ON pc.block_id = bl.id
WHERE pc.block_id = :block_id WHERE pc.block_id = :block_id
ORDER BY pc.position
SQL; SQL;
$rows = Application_Common_Database::prepareAndExecute($sql, array(':block_id'=>$this->id)); if ($filterFiles) {
$sql .= <<<SQL
AND f.file_exists = :file_exists
SQL;
}
$sql .= <<<SQL
ORDER BY pc.position
SQL;
$params = array(':block_id'=>$this->id);
if ($filterFiles) {
$params[':file_exists'] = $filterFiles;
}
$rows = Application_Common_Database::prepareAndExecute($sql, $params);
$offset = 0; $offset = 0;
foreach ($rows as &$row) { foreach ($rows as &$row) {
@ -310,6 +323,7 @@ SQL;
$hour = "00"; $hour = "00";
$mins = "00"; $mins = "00";
if ($modifier == "minutes") { if ($modifier == "minutes") {
$mins = $value;
if ($value >59) { if ($value >59) {
$hour = intval($value/60); $hour = intval($value/60);
$mins = $value%60; $mins = $value%60;
@ -1177,7 +1191,7 @@ SQL;
$sizeOfInsert = count($insertList); $sizeOfInsert = count($insertList);
// if block is not full and reapeat_track is check, fill up more // if block is not full and reapeat_track is check, fill up more
while (!$isBlockFull && $repeat == 1) { while (!$isBlockFull && $repeat == 1 && $sizeOfInsert > 0) {
$randomEleKey = array_rand(array_slice($insertList, 0, $sizeOfInsert)); $randomEleKey = array_rand(array_slice($insertList, 0, $sizeOfInsert));
$insertList[] = $insertList[$randomEleKey]; $insertList[] = $insertList[$randomEleKey];
$totalTime += $insertList[$randomEleKey]['length']; $totalTime += $insertList[$randomEleKey]['length'];

View File

@ -176,6 +176,14 @@ class Application_Model_Playlist implements Application_Model_LibraryEditable
FROM cc_playlistcontents AS pc FROM cc_playlistcontents AS pc
JOIN cc_files AS f ON pc.file_id=f.id JOIN cc_files AS f ON pc.file_id=f.id
WHERE pc.playlist_id = :playlist_id1 WHERE pc.playlist_id = :playlist_id1
SQL;
if ($filterFiles) {
$sql .= <<<SQL
AND f.file_exists = :file_exists
SQL;
}
$sql .= <<<SQL
AND TYPE = 0) AND TYPE = 0)
UNION ALL UNION ALL
(SELECT pc.id AS id, (SELECT pc.id AS id,
@ -220,7 +228,13 @@ class Application_Model_Playlist implements Application_Model_LibraryEditable
ORDER BY temp.position; ORDER BY temp.position;
SQL; SQL;
$rows = Application_Common_Database::prepareAndExecute($sql, array(':playlist_id1'=>$this->id, ':playlist_id2'=>$this->id, ':playlist_id3'=>$this->id)); $params = array(
':playlist_id1'=>$this->id, ':playlist_id2'=>$this->id, ':playlist_id3'=>$this->id);
if ($filterFiles) {
$params[':file_exists'] = $filterFiles;
}
$rows = Application_Common_Database::prepareAndExecute($sql, $params);
$offset = 0; $offset = 0;
foreach ($rows as &$row) { foreach ($rows as &$row) {

View File

@ -193,7 +193,8 @@ class Application_Model_Scheduler
} }
} else { } else {
$dynamicFiles = $bl->getListOfFilesUnderLimit(); $dynamicFiles = $bl->getListOfFilesUnderLimit();
foreach ($dynamicFiles as $fileId=>$f) { foreach ($dynamicFiles as $f) {
$fileId = $f['id'];
$file = CcFilesQuery::create()->findPk($fileId); $file = CcFilesQuery::create()->findPk($fileId);
if (isset($file) && $file->getDbFileExists()) { if (isset($file) && $file->getDbFileExists()) {
$data["id"] = $file->getDbId(); $data["id"] = $file->getDbId();
@ -250,7 +251,8 @@ class Application_Model_Scheduler
} }
} else { } else {
$dynamicFiles = $bl->getListOfFilesUnderLimit(); $dynamicFiles = $bl->getListOfFilesUnderLimit();
foreach ($dynamicFiles as $fileId=>$f) { foreach ($dynamicFiles as $f) {
$fileId = $f['id'];
$file = CcFilesQuery::create()->findPk($fileId); $file = CcFilesQuery::create()->findPk($fileId);
if (isset($file) && $file->getDbFileExists()) { if (isset($file) && $file->getDbFileExists()) {
$data["id"] = $file->getDbId(); $data["id"] = $file->getDbId();
@ -445,7 +447,6 @@ class Application_Model_Scheduler
} else { } else {
$sched = new CcSchedule(); $sched = new CcSchedule();
} }
Logging::info($file);
$sched->setDbStarts($nextStartDT) $sched->setDbStarts($nextStartDT)
->setDbEnds($endTimeDT) ->setDbEnds($endTimeDT)
->setDbCueIn($file['cuein']) ->setDbCueIn($file['cuein'])

View File

@ -359,9 +359,26 @@ SQL;
Application_Model_RabbitMq::SendMessageToMediaMonitor("file_delete", $data); Application_Model_RabbitMq::SendMessageToMediaMonitor("file_delete", $data);
} }
// set file_exists falg to false // set file_exists flag to false
$this->_file->setDbFileExists(false); $this->_file->setDbFileExists(false);
$this->_file->save(); $this->_file->save();
// need to explicitly update any playlist's and block's length
// that contains the file getting deleted
$fileId = $this->_file->getDbId();
$plRows = CcPlaylistcontentsQuery::create()->filterByDbFileId()->find();
foreach ($plRows as $row) {
$pl = CcPlaylistQuery::create()->filterByDbId($row->getDbPlaylistId($fileId))->findOne();
$pl->setDbLength($pl->computeDbLength(Propel::getConnection(CcPlaylistPeer::DATABASE_NAME)));
$pl->save();
}
$blRows = CcBlockcontentsQuery::create()->filterByDbFileId($fileId)->find();
foreach ($blRows as $row) {
$bl = CcBlockQuery::create()->filterByDbId($row->getDbBlockId())->findOne();
$bl->setDbLength($bl->computeDbLength(Propel::getConnection(CcBlockPeer::DATABASE_NAME)));
$bl->save();
}
} }
/** /**

View File

@ -86,8 +86,14 @@ class CcBlock extends BaseCcBlock {
*/ */
public function computeDbLength(PropelPDO $con) public function computeDbLength(PropelPDO $con)
{ {
$stmt = $con->prepare('SELECT SUM(cliplength) FROM "cc_blockcontents" WHERE cc_blockcontents.BLOCK_ID = :p1'); $sql = <<<SQL
$stmt->bindValue(':p1', $this->getDbId()); SELECT SUM(cliplength) FROM cc_blockcontents as bc
JOIN cc_files as f ON bc.file_id = f.id
WHERE BLOCK_ID = :b1
AND f.file_exists = true
SQL;
$stmt = $con->prepare($sql);
$stmt->bindValue(':b1', $this->getDbId());
$stmt->execute(); $stmt->execute();
$length = $stmt->fetchColumn(); $length = $stmt->fetchColumn();

View File

@ -87,7 +87,13 @@ class CcPlaylist extends BaseCcPlaylist {
*/ */
public function computeDbLength(PropelPDO $con) public function computeDbLength(PropelPDO $con)
{ {
$stmt = $con->prepare('SELECT SUM(cliplength) FROM "cc_playlistcontents" WHERE cc_playlistcontents.PLAYLIST_ID = :p1'); $sql = <<<SQL
SELECT SUM(cliplength) FROM cc_playlistcontents as pc
JOIN cc_files as f ON pc.file_id = f.id
WHERE PLAYLIST_ID = :p1
AND f.file_exists = true
SQL;
$stmt = $con->prepare($sql);
$stmt->bindValue(':p1', $this->getDbId()); $stmt->bindValue(':p1', $this->getDbId());
$stmt->execute(); $stmt->execute();
$length = $stmt->fetchColumn(); $length = $stmt->fetchColumn();

View File

@ -4,7 +4,7 @@
<h3 class="collapsible-header" id="soundcloud-heading"><span class="arrow-icon"></span>SoundCloud Settings</h3> <h3 class="collapsible-header" id="soundcloud-heading"><span class="arrow-icon"></span>SoundCloud Settings</h3>
<div class="collapsible-content" id="soundcloud-settings" style="display: none;"> <div class="collapsible-content" id="soundcloud-settings">
<?php echo $this->element->getSubform('preferences_soundcloud') ?> <?php echo $this->element->getSubform('preferences_soundcloud') ?>
</div> </div>

View File

@ -29,16 +29,22 @@
</dd> </dd>
<dd id='sp_criteria-element' class='criteria-element'> <dd id='sp_criteria-element' class='criteria-element'>
<?php for ($i = 0; $i < $this->criteriasLength; $i++) {?> <?php for ($i = 0; $i < $this->criteriasLength; $i++) {
// modRowMap holds the number of modifier rows for each criteria element
// i.e. if we have 'Album contains 1' and 'Album contains 2' the modRowMap
// for Album is 2
?>
<?php for ($j = 0; $j < $this->modRowMap[$i]; $j++) { <?php for ($j = 0; $j < $this->modRowMap[$i]; $j++) {
// determine if logic label should be 'and' or 'or'
if ($this->modRowMap[$i] > 1 && $j != $this->modRowMap[$i]-1) $logicLabel = 'or'; if ($this->modRowMap[$i] > 1 && $j != $this->modRowMap[$i]-1) $logicLabel = 'or';
else $logicLabel = 'and'; else $logicLabel = 'and';
$disabled = $this->element->getElement("sp_criteria_field_".$i."_".$j)->getAttrib('disabled') == 'disabled'?true:false; $disabled = $this->element->getElement("sp_criteria_field_".$i."_".$j)->getAttrib('disabled') == 'disabled'?true:false;
// determine if the next row is disabled and only display the logic label if it isn't // determine if the next row is disabled and only display the logic label if it isn't
if ($j == $this->modRowMap[$i]-1 && $i < 25) { if ($j == $this->modRowMap[$i]-1 && $i < 25) {
$n = $i+1; $n = $i+1;
$nextIndex = $n."_0"; $nextIndex = $n."_0";
} elseif ($j+1 < $this->modRowMap[$i]-1) { } elseif ($j+1 <= $this->modRowMap[$i]-1) {
$n = $j+1; $n = $j+1;
$nextIndex = $i."_".$n; $nextIndex = $i."_".$n;

View File

@ -9,11 +9,11 @@
<li id='lib-new-ws'><a href="#">New Webstream</a></li> <li id='lib-new-ws'><a href="#">New Webstream</a></li>
</ul> </ul>
</div> </div>
<?php if (isset($this->obj)) : ?>
<div class="btn-group pull-right"> <div class="btn-group pull-right">
<button class="btn btn-inverse" type="submit" id="webstream_save" name="submit">Save</button> <button class="btn btn-inverse" type="submit" id="webstream_save" name="submit">Save</button>
</div> </div>
<?php if (isset($this->obj)) : ?>
<div class="btn-group pull-right"> <div class="btn-group pull-right">
<button id="ws_delete" class="btn" <?php if ($this->action == "new"): ?>style="display:none;"<?php endif; ?>aria-disabled="false">Delete</button> <button id="ws_delete" class="btn" <?php if ($this->action == "new"): ?>style="display:none;"<?php endif; ?>aria-disabled="false">Delete</button>
</div> </div>

View File

@ -8,10 +8,16 @@ var AIRTIME = (function(AIRTIME) {
mod = AIRTIME.library; mod = AIRTIME.library;
mod.checkAddButton = function() { mod.checkAddButton = function() {
var selected = mod.getChosenItemsLength(), sortable = $('#spl_sortable'), check = false;
// make sure audioclips are selected and a playlist is currently open. var selected = mod.getChosenItemsLength(),
if (selected !== 0 && sortable.length !== 0) { sortable = $('#spl_sortable:visible'),
check = false,
blockType = $('input[name=sp_type]:checked', '#smart-block-form').val();
// make sure audioclips are selected and a playlist or static block is currently open.
// static blocks have value of 0
// dynamic blocks have value of 1
if (selected !== 0 && (sortable.length !== 0 || blockType === "0")) {
check = true; check = true;
} }
@ -96,6 +102,10 @@ var AIRTIME = (function(AIRTIME) {
return container; return container;
}, },
cursor : 'pointer', cursor : 'pointer',
cursorAt: {
top: 30,
left: 100
},
connectToSortable : '#spl_sortable' connectToSortable : '#spl_sortable'
}); });
}; };

View File

@ -201,7 +201,8 @@ function setSmartBlockEvents() {
/********** CHANGE PLAYLIST TYPE **********/ /********** CHANGE PLAYLIST TYPE **********/
form.find('dd[id="sp_type-element"]').live("change", function(){ form.find('dd[id="sp_type-element"]').live("change", function(){
setupUI(); setupUI();
AIRTIME.library.checkAddButton();
}); });
/********** CRITERIA CHANGE **********/ /********** CRITERIA CHANGE **********/

View File

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os import os
import abc import abc
import re
import media.monitor.pure as mmp import media.monitor.pure as mmp
import media.monitor.owners as owners import media.monitor.owners as owners
from media.monitor.pure import LazyProperty from media.monitor.pure import LazyProperty
@ -101,6 +102,12 @@ class BaseEvent(Loggable):
self.path = os.path.normpath(raw_event.pathname) self.path = os.path.normpath(raw_event.pathname)
else: self.path = raw_event else: self.path = raw_event
self.owner = owners.get_owner(self.path) self.owner = owners.get_owner(self.path)
owner_re = re.search('stor/imported/(?P<owner>\d+)/', self.path)
if owner_re:
self.logger.info("matched path: %s" % self.path)
self.owner = owner_re.group('owner')
else:
self.logger.info("did not match path: %s" % self.path)
self._pack_hook = lambda: None # no op self._pack_hook = lambda: None # no op
# into another event # into another event

View File

@ -5,26 +5,22 @@ log = get_logger()
owners = {} owners = {}
def reset_owners(): def reset_owners():
""" """ Wipes out all file => owner associations """
Wipes out all file => owner associations
"""
global owners global owners
owners = {} owners = {}
def get_owner(f): def get_owner(f):
""" """ Get the owner id of the file 'f' """
Get the owner id of the file 'f' o = owners[f] if f in owners else -1
""" log.info("Received owner for %s. Owner: %s" % (f, o))
return owners[f] if f in owners else -1 return o
def add_file_owner(f,owner): def add_file_owner(f,owner):
""" """ Associate file f with owner. If owner is -1 then do we will not record
Associate file f with owner. If owner is -1 then do we will not record it it because -1 means there is no owner. Returns True if f is being stored
because -1 means there is no owner. Returns True if f is being stored after after the function. False otherwise. """
the function. False otherwise.
"""
if owner == -1: return False if owner == -1: return False
if f in owners: if f in owners:
if owner != owners[f]: # check for fishiness if owner != owners[f]: # check for fishiness
@ -35,16 +31,12 @@ def add_file_owner(f,owner):
return True return True
def has_owner(f): def has_owner(f):
""" """ True if f is owned by somebody. False otherwise. """
True if f is owned by somebody. False otherwise.
"""
return f in owners return f in owners
def remove_file_owner(f): def remove_file_owner(f):
""" """ Try and delete any association made with file f. Returns true if
Try and delete any association made with file f. Returns true if the the the the association was actually deleted. False otherwise. """
association was actually deleted. False otherwise.
"""
if f in owners: if f in owners:
del owners[f] del owners[f]
return True return True

View File

@ -52,8 +52,6 @@ class RequestSync(Loggable):
self.logger.info("ApiController.php probably crashed, we \ self.logger.info("ApiController.php probably crashed, we \
diagnose this from the fact that it did not return \ diagnose this from the fact that it did not return \
valid json") valid json")
self.logger.info("Trying again after %f seconds" %
self.request_wait)
except Exception as e: self.unexpected_exception(e) except Exception as e: self.unexpected_exception(e)
else: self.logger.info("Request was successful") else: self.logger.info("Request was successful")
self.watcher.flag_done() # poor man's condition variable self.watcher.flag_done() # poor man's condition variable

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import unittest import unittest
import media.monitor.owners as owners from media.monitor import owners
class TestMMP(unittest.TestCase): class TestMMP(unittest.TestCase):
def setUp(self): def setUp(self):