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

This commit is contained in:
Rudi Grinberg 2012-08-28 16:22:51 -04:00
commit 0517e674bd
19 changed files with 254 additions and 74 deletions

View File

@ -891,7 +891,6 @@ class ApiController extends Zend_Controller_Action
* out a message to pypo that a potential change has been made. */
public function rabbitmqDoPushAction()
{
$request = $this->getRequest();
Logging::info("Notifying RabbitMQ to send message to pypo");
Application_Model_RabbitMq::PushSchedule();

View File

@ -64,7 +64,7 @@ class PlaylistController extends Zend_Controller_Action
unset($this->view->obj);
}
private function createFullResponse($obj = null, $isJson = false)
private function createFullResponse($obj = null, $isJson = false, $formIsValid = false)
{
$isBlock = false;
$viewPath = 'playlist/playlist.phtml';
@ -80,11 +80,12 @@ class PlaylistController extends Zend_Controller_Action
if ($isBlock) {
$form = new Application_Form_SmartBlockCriteria();
$form->removeDecorator('DtDdWrapper');
$form->startForm($obj->getId());
$form->startForm($obj->getId(), $formIsValid);
$this->view->form = $form;
$this->view->obj = $obj;
$this->view->id = $obj->getId();
if ($isJson) {
return $this->view->render($viewPath);
} else {
@ -460,7 +461,7 @@ class PlaylistController extends Zend_Controller_Action
$bl = new Application_Model_Block($params['obj_id']);
if ($form->isValid($params)) {
$bl->saveSmartBlockCriteria($params['data']);
$result['html'] = $this->createFullResponse($bl, true);
$result['html'] = $this->createFullResponse($bl, true, true);
$result['result'] = 0;
} else {
$this->view->obj = $bl;
@ -486,7 +487,7 @@ class PlaylistController extends Zend_Controller_Action
if ($form->isValid($params)) {
$result = $bl->generateSmartBlock($params['data']);
try {
die(json_encode(array("result"=>0, "html"=>$this->createFullResponse($bl, true))));
die(json_encode(array("result"=>0, "html"=>$this->createFullResponse($bl, true, true))));
} catch (PlaylistNotFoundException $e) {
$this->playlistNotFound('block');
} catch (Exception $e) {

View File

@ -50,6 +50,7 @@ class PreferenceController extends Zend_Controller_Action
Application_Model_Preference::SetMailServerEmailAddress($values["preferences_email_server"]["email"]);
Application_Model_Preference::SetMailServerPassword($values["preferences_email_server"]["ms_password"]);
Application_Model_Preference::SetMailServerPort($values["preferences_email_server"]["port"]);
Application_Model_Preference::SetMailServerRequiresAuth($values["preferences_email_server"]["msRequiresAuth"]);
}
Application_Model_Preference::SetAutoUploadRecordedShowToSoundcloud($values["preferences_soundcloud"]["UseSoundCloud"]);

View File

@ -102,7 +102,7 @@ class WebstreamController extends Zend_Controller_Action
$hasPermission = true;
}
if ($user->isHost()) {
if (!$hasPermission && $user->isHost()) {
if ($webstream_id != -1) {
$webstream = CcWebstreamQuery::create()->findPK($webstream_id);
//we are updating a playlist. Ensure that if the user is a host/dj, that he has the correct permission.

View File

@ -41,6 +41,15 @@ class Application_Form_EmailServerPreferences extends Zend_Form_SubForm
'viewHelper'
)
));
$this->addElement('checkbox', 'msRequiresAuth', array(
'label' => 'Requires Authentication',
'required' => false,
'value' => Application_Model_Preference::GetMailServerRequiresAuth(),
'decorators' => array(
'viewHelper'
)
));
$this->addElement('text', 'mailServer', array(
'class' => 'input_text',
@ -50,7 +59,9 @@ class Application_Form_EmailServerPreferences extends Zend_Form_SubForm
'decorators' => array('viewHelper'),
'allowEmpty' => false,
'validators' => array(
new ConditionalNotEmpty(array('configureMailServer'=>'1'))
new ConditionalNotEmpty(array(
'configureMailServer' => '1'
))
)
));
@ -62,7 +73,10 @@ class Application_Form_EmailServerPreferences extends Zend_Form_SubForm
'decorators' => array('viewHelper'),
'allowEmpty' => false,
'validators' => array(
new ConditionalNotEmpty(array('configureMailServer'=>'1'))
new ConditionalNotEmpty(array(
'configureMailServer' => '1',
'msRequiresAuth' => '1'
))
)
));
@ -74,7 +88,10 @@ class Application_Form_EmailServerPreferences extends Zend_Form_SubForm
'decorators' => array('viewHelper'),
'allowEmpty' => false,
'validators' => array(
new ConditionalNotEmpty(array('configureMailServer'=>'1'))
new ConditionalNotEmpty(array(
'configureMailServer' => '1',
'msRequiresAuth' => '1'
))
),
'renderPassword' => true
));

View File

@ -88,7 +88,7 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
}
public function startForm($p_blockId)
public function startForm($p_blockId, $p_isValid = false)
{
// load type
$out = CcBlockQuery::create()->findPk($p_blockId);
@ -236,7 +236,13 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
//getting block content candidate count that meets criteria
$bl = new Application_Model_Block($p_blockId);
$files = $bl->getListofFilesMeetCriteria();
if ($p_isValid) {
$files = $bl->getListofFilesMeetCriteria();
$showPoolCount = true;
} else {
$files = null;
$showPoolCount = false;
}
$generate = new Zend_Form_Element_Button('generate_button');
$generate->setAttrib('class', 'ui-button ui-state-default sp-button');
@ -256,7 +262,8 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm
$this->setDecorators(array(
array('ViewScript', array('viewScript' => 'form/smart-block-criteria.phtml', "openOption"=> $openSmartBlockOption,
'criteriasLength' => count($this->criteriaOptions), 'poolCount' => $files['count'], 'modRowMap' => $modRowMap))
'criteriasLength' => count($this->criteriaOptions), 'poolCount' => $files['count'], 'modRowMap' => $modRowMap,
'showPoolCount' => $showPoolCount))
));
}

View File

@ -13,23 +13,31 @@ class Application_Model_Email
public static function send($subject, $message, $tos, $from = null)
{
$mailServerConfigured = Application_Model_Preference::GetMailServerConfigured() == true ? true : false;
$mailServerRequiresAuth = Application_Model_Preference::GetMailServerRequiresAuth() == true ? true : false;
$success = true;
if ($mailServerConfigured) {
$username = Application_Model_Preference::GetMailServerEmailAddress();
$password = Application_Model_Preference::GetMailServerPassword();
$mailServer = Application_Model_Preference::GetMailServer();
$mailServerPort = Application_Model_Preference::GetMailServerPort();
if (!empty($mailServerPort)) {
$port = Application_Model_Preference::GetMailServerPort();
}
$config = array(
'auth' => 'login',
'ssl' => 'ssl',
'username' => $username,
'password' => $password
);
if ($mailServerRequiresAuth) {
$username = Application_Model_Preference::GetMailServerEmailAddress();
$password = Application_Model_Preference::GetMailServerPassword();
$config = array(
'auth' => 'login',
'ssl' => 'ssl',
'username' => $username,
'password' => $password
);
} else {
$config = array(
'ssl' => 'ssl'
);
}
if (isset($port)) {
$config['port'] = $port;

View File

@ -1089,6 +1089,16 @@ class Application_Model_Preference
{
return self::getValue("mail_server_port");
}
public static function SetMailServerRequiresAuth($value)
{
self::setValue("mail_server_requires_auth", $value, false);
}
public static function GetMailServerRequiresAuth()
{
return self::getValue("mail_server_requires_auth");
}
/* User specific preferences end */
public static function ShouldShowPopUp()

View File

@ -40,7 +40,7 @@ class Application_Model_User
->filterByDbHost($userId)->count() > 0;
}
public function isHost($showId)
public function isHost()
{
return $this->isUserType(UTYPE_HOST);
}

View File

@ -111,10 +111,30 @@ class Application_Model_Webstream implements Application_Model_LibraryEditable
$di = null;
$length = $parameters["length"];
$result = preg_match("/^([0-9]{1,2})h ([0-5]?[0-9])m$/", $length, $matches);
if ($result == 1 && count($matches) == 3) {
$result = preg_match("/^(?:([0-9]{1,2})h)?\s*(?:([0-6]?[0-9])m)?$/", $length, $matches);
$invalid_date_interval = false;
if ($result == 1 && count($matches) == 2) {
$hours = $matches[1];
$minutes = 0;
} else if ($result == 1 && count($matches) == 3) {
$hours = $matches[1];
$minutes = $matches[2];
} else {
$invalid_date_interval = true;
}
if (!$invalid_date_interval) {
if (!is_numeric($hours)) {
$hours = 0;
}
if (!is_numeric($minutes)) {
$minutes = 0;
}
$di = new DateInterval("PT{$hours}H{$minutes}M");
$totalMinutes = $di->h * 60 + $di->i;
@ -150,7 +170,7 @@ class Application_Model_Webstream implements Application_Model_LibraryEditable
//TODO: return url
$mediaUrl = self::getMediaUrl($url, $mime, $content_length_found);
if (preg_match("/xspf\+xml/", $mime)) {
if (preg_match("/(x-mpegurl)|(xspf\+xml)/", $mime)) {
list($mime, $content_length_found) = self::discoverStreamMime($mediaUrl);
}
} catch (Exception $e) {
@ -224,17 +244,46 @@ class Application_Model_Webstream implements Application_Model_LibraryEditable
throw new Exception("Could not parse XSPF playlist");
}
private static function getM3uUrl($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// grab URL and pass it to the browser
//TODO: What if invalid url?
$content = curl_exec($ch);
Logging::info($content);
curl_close($ch);
//split into lines:
$delim = "\n";
if (strpos($content, "\r\n") !== false) {
$delim = "\r\n";
}
$lines = explode("$delim", $content);
#$lines = preg_split('/$\R?^/m', $content);
if (count($lines) > 0) {
return $lines[0];
}
throw new Exception("Could not parse M3U playlist");
}
private static function getMediaUrl($url, $mime, $content_length_found)
{
if (preg_match("/(mpeg|ogg)/", $mime)) {
if (preg_match("/x-mpegurl/", $mime)) {
$media_url = self::getM3uUrl($url);
} else if (preg_match("/xspf\+xml/", $mime)) {
$media_url = self::getXspfUrl($url);
} else if (preg_match("/(mpeg|ogg)/", $mime)) {
if ($content_length_found) {
throw new Exception("Invalid webstream - This appears to be a file download.");
}
$media_url = $url;
} else if (preg_match("/x-mpegurl/", $mime)) {
$media_url = $url;
} else if (preg_match("/xspf\+xml/", $mime)) {
$media_url = self::getXspfUrl($url);
} else {
throw new Exception("Unrecognized stream type: $mime");
}

View File

@ -44,7 +44,13 @@
<label class="required" for="mailServer"><?php echo $this->element->getElement('mailServer')->getLabel() ?>
<span class="info-text-small">(Required)</span>:
</label>
<label class="required" for="msRequiresAuth">
<?php echo $this->element->getElement('msRequiresAuth') ?>
<?php echo $this->element->getElement('msRequiresAuth')->getLabel() ?>
</label>
</dt>
<dd id="mailServer-element" class="block-display">
<?php echo $this->element->getElement('mailServer') ?>
<?php if($this->element->getElement('mailServer')->hasErrors()) : ?>
@ -56,6 +62,14 @@
<?php endif; ?>
</dd>
<dt id="port-label" class="block-display">
<label class="required" for="port"><?php echo $this->element->getElement('port')->getLabel() ?>:
</label>
</dt>
<dd id="port-element" class="block-display">
<?php echo $this->element->getElement('port') ?>
</dd>
<dt id="email-label" class="block-display">
<label class="required" for="email"><?php echo $this->element->getElement('email')->getLabel() ?>
<span class="info-text-small">(Required)</span>:
@ -88,14 +102,6 @@
<?php endif; ?>
</dd>
<dt id="port-label" class="block-display">
<label class="required" for="port"><?php echo $this->element->getElement('port')->getLabel() ?>:
</label>
</dt>
<dd id="port-element" class="block-display">
<?php echo $this->element->getElement('port') ?>
</dd>
<?php } ?>
</dl>

View File

@ -66,32 +66,35 @@
<?php endif; ?>
<br />
</dd>
<div class='sp_text_font sp_text_font_bold'>
<span id='sp_pool_count' class='sp_text_font sp_text_font_bold'>
<?php
if ($this->poolCount > 1) {
echo $this->poolCount;
?>
files meet the criteria
</span>
<span class='checked-icon sp-checked-icon' id='sp_pool_count_icon'></span>
<?php
} else if ($this->poolCount == 1) {
echo $this->poolCount;
?>
file meets the criteria
</span>
<span class='checked-icon sp-checked-icon' id='sp_pool_count_icon'></span>
<?php
} else {
?>
0 files meet the criteria
</span>
<span class='sp-warning-icon' id='sp_pool_count_icon'></span>
<?php
}
?>
</div>
<?php if ($this->showPoolCount) { ?>
<div class='sp_text_font sp_text_font_bold'>
<span id='sp_pool_count' class='sp_text_font sp_text_font_bold'>
<?php
if ($this->poolCount > 1) {
echo $this->poolCount;
?>
files meet the criteria
</span>
<span class='checked-icon sp-checked-icon' id='sp_pool_count_icon'></span>
<?php
} else if ($this->poolCount == 1) {
echo $this->poolCount;
?>
file meets the criteria
</span>
<span class='checked-icon sp-checked-icon' id='sp_pool_count_icon'></span>
<?php
} else {
?>
0 files meet the criteria
</span>
<span class='sp-warning-icon' id='sp_pool_count_icon'></span>
<?php
}
?>
</div>
<?php } ?>
</dl>

View File

@ -20,14 +20,19 @@ function setConfigureMailServerListener() {
var configMailServer = $("#configureMailServer");
configMailServer.click(function(event){
setMailServerInputReadonly();
})
});
var msRequiresAuth = $("#msRequiresAuth");
msRequiresAuth.click(function(event){
setMsAuthenticationFieldsReadonly($(this));
});
}
function setEnableSystemEmailsListener() {
var enableSystemEmails = $("#enableSystemEmail");
enableSystemEmails.click(function(event){
setSystemFromEmailReadonly();
})
});
}
function setSystemFromEmailReadonly() {
@ -43,19 +48,36 @@ function setSystemFromEmailReadonly() {
function setMailServerInputReadonly() {
var configMailServer = $("#configureMailServer");
var mailServer = $("#mailServer");
var email = $("#email");
var password = $("#ms_password");
var port = $("#port");
if ($(configMailServer).is(':checked')) {
var requiresAuthCB = $("#msRequiresAuth");
if (configMailServer.is(':checked')) {
mailServer.removeAttr("readonly");
email.removeAttr("readonly");
password.removeAttr("readonly");
port.removeAttr("readonly");
requiresAuthCB.parent().show();
} else {
mailServer.attr("readonly", "readonly");
port.attr("readonly", "readonly");
requiresAuthCB.parent().hide();
}
setMsAuthenticationFieldsReadonly(requiresAuthCB);
}
/*
* Enable/disable mail server authentication fields
*/
function setMsAuthenticationFieldsReadonly(ele) {
var email = $("#email");
var password = $("#ms_password");
var configureMailServer = $("#configureMailServer");
if (ele.is(':checked') && configureMailServer.is(':checked')) {
email.removeAttr("readonly");
password.removeAttr("readonly");
} else if (ele.not(':checked') || configureMailServer.not(':checked')) {
email.attr("readonly", "readonly");
password.attr("readonly", "readonly");
port.attr("readonly", "readonly");
}
}

View File

@ -117,3 +117,6 @@ get_files_without_replay_gain = 'get-files-without-replay-gain/api_key/%%api_key
update_replay_gain_value = 'update-replay-gain-value/api_key/%%api_key%%'
notify_webstream_data = 'notify-webstream-data/api_key/%%api_key%%/media_id/%%media_id%%/format/json'
notify_liquidsoap_started = 'rabbitmq-do-push/api_key/%%api_key%%/format/json'

View File

@ -229,6 +229,22 @@ class AirtimeApiClient():
except Exception, e:
logger.error("%s", e)
def notify_liquidsoap_started(self):
logger = self.logger
try:
url = "http://%s:%s/%s/%s" % (self.config["base_url"], \
str(self.config["base_port"]), \
self.config["api_base"], \
self.config["notify_liquidsoap_started"])
url = url.replace("%%api_key%%", self.config["api_key"])
self.get_response_from_server(url)
except Exception, e:
logger.error("Exception: %s", str(e))
"""
This is a callback from liquidsoap, we use this to notify about the
currently playing *song*. We get passed a JSON string which we handed to

View File

@ -55,6 +55,18 @@ case "${1:-''}" in
start
echo "Done."
;;
'status')
if [ -f "/var/run/airtime-liquidsoap.pid" ]; then
pid=`cat /var/run/airtime-liquidsoap.pid`
if [ -d "/proc/$pid" ]; then
echo "Liquidsoap is running"
exit 0
fi
fi
echo "Liquidsoap is not running"
exit 1
;;
'start-no-monit')
# restart commands here
echo -n "Starting $NAME: "

View File

@ -25,6 +25,18 @@ export PYTHONPATH=${api_client_path}:$PYTHONPATH
export LC_ALL=`cat /etc/default/locale | grep "LANG=" | cut -d= -f2 | tr -d "\n\""`
export TERM=xterm
#If Pypo is starting from scratch let's restart Liquidsoap as well. This is so
#that the Liquidsoap queue #is emptied and we can start from a known state.
/etc/init.d/airtime-liquidsoap status
status="$?"
if [ "$status" == "0" ]; then
/etc/init.d/airtime-liquidsoap restart
else
/etc/init.d/airtime-liquidsoap start
fi
exec python ${pypo_path}${pypo_script} > /var/log/airtime/pypo/py-interpreter.log 2>&1
# EOF

View File

@ -323,4 +323,6 @@ if s3_enable == true then
output_to(s3_output, s3_type, s3_bitrate, s3_host, s3_port, s3_pass, s3_mount, s3_url, s3_description, s3_genre, s3_user, s, "3", s3_connected, s3_description)
end
#ignore(output.dummy(blank()))
command = "/usr/lib/airtime/pypo/bin/liquidsoap_scripts/notify.sh --liquidsoap-started &"
log(command)
system(command)

View File

@ -42,6 +42,8 @@ parser.add_option("-t", "--time", help="Liquidsoap boot up time", action="store"
parser.add_option("-x", "--source-name", help="source connection name", metavar="source_name")
parser.add_option("-y", "--source-status", help="source connection status", metavar="source_status")
parser.add_option("-w", "--webstream", help="JSON metadata associated with webstream", metavar="json_data")
parser.add_option("-n", "--liquidsoap-started", help="notify liquidsoap started", metavar="json_data", action="store_true", default=True)
# parse options
(options, args) = parser.parse_args()
@ -67,6 +69,11 @@ class Notify:
def __init__(self):
self.api_client = api_client.AirtimeApiClient()
def notify_liquidsoap_started(self):
logger = logging.getLogger("notify")
logger.debug("Notifying server that Liquidsoap has started")
self.api_client.notify_liquidsoap_started()
def notify_media_start_playing(self, data, media_id):
logger = logging.getLogger("notify")
@ -105,7 +112,6 @@ class Notify:
logger.debug('#################################################')
response = self.api_client.notify_webstream_data(data, media_id)
pass
if __name__ == '__main__':
print
@ -140,6 +146,12 @@ if __name__ == '__main__':
n.notify_webstream_data(options.webstream, options.media_id)
except Exception, e:
print e
elif options.liquidsoap_started:
try:
n = Notify()
n.notify_liquidsoap_started()
except Exception, e:
print e
else:
if not options.data:
print "NOTICE: 'data' command-line argument not given."