Merge branch 'saas-dev' of github.com:sourcefabric/Airtime into saas-dev
This commit is contained in:
commit
b8dd7f0df3
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
class Application_Common_TuneIn
|
||||
{
|
||||
public static function sendMetadataToTunein($title, $artist)
|
||||
{
|
||||
$credQryStr = self::getCredentialsQueryString();
|
||||
$metadataQryStr = "&title=".$title."&artist=".$artist."&commercial=false";
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, TUNEIN_API_URL . $credQryStr . $metadataQryStr);
|
||||
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
|
||||
|
||||
curl_exec($ch);
|
||||
if (curl_error($ch)) {
|
||||
Logging::error("Failed to reach TuneIn: ". curl_errno($ch)." - ". curl_error($ch) . " - " . curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));
|
||||
}
|
||||
curl_close($ch);
|
||||
|
||||
}
|
||||
|
||||
private static function getCredentialsQueryString() {
|
||||
$tuneInStationID = Application_Model_Preference::getTuneinStationId();
|
||||
$tuneInPartnerID = Application_Model_Preference::getTuneinPartnerId();
|
||||
$tuneInPartnerKey = Application_Model_Preference::getTuneinPartnerKey();
|
||||
|
||||
return "?partnerId=".$tuneInPartnerID."&partnerKey=".$tuneInPartnerKey."&id=".$tuneInStationID;
|
||||
}
|
||||
|
||||
public static function updateOfflineMetadata() {
|
||||
$credQryStr = self::getCredentialsQueryString();
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, TUNEIN_API_URL . $credQryStr . "&commercial=true");
|
||||
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
|
||||
|
||||
curl_exec($ch);
|
||||
if (curl_error($ch)) {
|
||||
Logging::error("Failed to reach TuneIn: ". curl_errno($ch)." - ". curl_error($ch) . " - " . curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));
|
||||
}
|
||||
curl_close($ch);
|
||||
}
|
||||
|
||||
}
|
|
@ -92,3 +92,7 @@ define('SENTRY_CONFIG_PATH', '/etc/airtime-saas/sentry.airtime_web.ini');
|
|||
//Provisioning status
|
||||
define('PROVISIONING_STATUS_SUSPENDED' , 'Suspended');
|
||||
define('PROVISIONING_STATUS_ACTIVE' , 'Active');
|
||||
|
||||
//TuneIn integration
|
||||
define("TUNEIN_API_URL", "http://air.radiotime.com/Playing.ashx");
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
require_once('TuneIn.php');
|
||||
|
||||
class ApiController extends Zend_Controller_Action
|
||||
{
|
||||
|
@ -615,6 +616,14 @@ class ApiController extends Zend_Controller_Action
|
|||
$file = Application_Model_StoredFile::RecallById($file_id);
|
||||
$now = new DateTime("now", new DateTimeZone("UTC"));
|
||||
$file->setLastPlayedTime($now);
|
||||
|
||||
// Push metadata to TuneIn
|
||||
if (Application_Model_Preference::getTuneinEnabled()) {
|
||||
$filePropelOrm = $file->getPropelOrm();
|
||||
$title = urlencode($filePropelOrm->getDbTrackTitle());
|
||||
$artist = urlencode($filePropelOrm->getDbArtistName());
|
||||
Application_Common_TuneIn::sendMetadataToTunein($title, $artist);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// webstream
|
||||
|
|
|
@ -56,14 +56,19 @@ class PreferenceController extends Zend_Controller_Action
|
|||
Application_Model_Preference::SetStationLogo($imagePath);
|
||||
}
|
||||
|
||||
Application_Model_Preference::SetUploadToSoundcloudOption($values["UploadToSoundcloudOption"]);
|
||||
Application_Model_Preference::setTuneinEnabled($values["enable_tunein"]);
|
||||
Application_Model_Preference::setTuneinStationId($values["tunein_station_id"]);
|
||||
Application_Model_Preference::setTuneinPartnerKey($values["tunein_partner_key"]);
|
||||
Application_Model_Preference::setTuneinPartnerId($values["tunein_partner_id"]);
|
||||
|
||||
/*Application_Model_Preference::SetUploadToSoundcloudOption($values["UploadToSoundcloudOption"]);
|
||||
Application_Model_Preference::SetSoundCloudDownloadbleOption($values["SoundCloudDownloadbleOption"]);
|
||||
Application_Model_Preference::SetSoundCloudUser($values["SoundCloudUser"]);
|
||||
Application_Model_Preference::SetSoundCloudPassword($values["SoundCloudPassword"]);
|
||||
Application_Model_Preference::SetSoundCloudTags($values["SoundCloudTags"]);
|
||||
Application_Model_Preference::SetSoundCloudGenre($values["SoundCloudGenre"]);
|
||||
Application_Model_Preference::SetSoundCloudTrackType($values["SoundCloudTrackType"]);
|
||||
Application_Model_Preference::SetSoundCloudLicense($values["SoundCloudLicense"]);
|
||||
Application_Model_Preference::SetSoundCloudLicense($values["SoundCloudLicense"]);*/
|
||||
|
||||
$this->view->statusMsg = "<div class='success'>". _("Preferences updated.")."</div>";
|
||||
$this->view->form = $form;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
require_once('TuneIn.php');
|
||||
|
||||
$filepath = realpath (dirname(__FILE__));
|
||||
require_once($filepath."/../modules/rest/controllers/MediaController.php");
|
||||
|
@ -297,6 +298,13 @@ class ScheduleController extends Zend_Controller_Action
|
|||
public function getCurrentPlaylistAction()
|
||||
{
|
||||
$range = Application_Model_Schedule::GetPlayOrderRangeOld();
|
||||
|
||||
// If there is no current track playing update TuneIn so it doesn't
|
||||
// display outdated metadata
|
||||
if (is_null($range["current"]) && Application_Model_Preference::getTuneinEnabled()) {
|
||||
Application_Common_TuneIn::updateOfflineMetadata();
|
||||
}
|
||||
|
||||
$show = Application_Model_Show::getCurrentShow();
|
||||
|
||||
/* Convert all UTC times to localtime before sending back to user. */
|
||||
|
|
|
@ -21,6 +21,10 @@ class Application_Form_Preferences extends Zend_Form
|
|||
|
||||
$this->addSubForm($general_pref, 'preferences_general');
|
||||
|
||||
//tunein form
|
||||
$tuneinPreferences = new Application_Form_TuneInPreferences();
|
||||
$this->addSubForm($tuneinPreferences, 'preferences_tunein');
|
||||
|
||||
$soundcloud_pref = new Application_Form_SoundcloudPreferences();
|
||||
$this->addSubForm($soundcloud_pref, 'preferences_soundcloud');
|
||||
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
<?php
|
||||
require_once 'customvalidators/ConditionalNotEmpty.php';
|
||||
|
||||
class Application_Form_TuneInPreferences extends Zend_Form_SubForm
|
||||
{
|
||||
public function init()
|
||||
{
|
||||
$this->setDecorators(array(
|
||||
array('ViewScript', array('viewScript' => 'form/preferences_tunein.phtml'))
|
||||
));
|
||||
|
||||
$enableTunein = new Zend_Form_Element_Checkbox("enable_tunein");
|
||||
$enableTunein->setDecorators(array(
|
||||
'ViewHelper',
|
||||
'Errors',
|
||||
'Label'
|
||||
));
|
||||
$enableTunein->addDecorator('Label', array('class' => 'enable-tunein'));
|
||||
$enableTunein->setLabel(_("Push metadata to your station on TuneIn?"));
|
||||
$enableTunein->setValue(Application_Model_Preference::getTuneinEnabled());
|
||||
$enableTunein->setAttrib("class", "block-display");
|
||||
$this->addElement($enableTunein);
|
||||
|
||||
$tuneinStationId = new Zend_Form_Element_Text("tunein_station_id");
|
||||
$tuneinStationId->setLabel(_("Station ID:"));
|
||||
$tuneinStationId->setValue(Application_Model_Preference::getTuneinStationId());
|
||||
$tuneinStationId->setAttrib("class", "input_text");
|
||||
$this->addElement($tuneinStationId);
|
||||
|
||||
$tuneinPartnerKey = new Zend_Form_Element_Text("tunein_partner_key");
|
||||
$tuneinPartnerKey->setLabel(_("Partner Key:"));
|
||||
$tuneinPartnerKey->setValue(Application_Model_Preference::getTuneinPartnerKey());
|
||||
$tuneinPartnerKey->setAttrib("class", "input_text");
|
||||
$this->addElement($tuneinPartnerKey);
|
||||
|
||||
$tuneinPartnerId = new Zend_Form_Element_Text("tunein_partner_id");
|
||||
$tuneinPartnerId->setLabel(_("Partner Id:"));
|
||||
$tuneinPartnerId->setValue(Application_Model_Preference::getTuneinPartnerId());
|
||||
$tuneinPartnerId->setAttrib("class", "input_text");
|
||||
$this->addElement($tuneinPartnerId);
|
||||
}
|
||||
|
||||
public function isValid($data)
|
||||
{
|
||||
$valid = true;
|
||||
// Make request to TuneIn API to test the settings are valid.
|
||||
// TuneIn does not have an API to make test requests to check if
|
||||
// the credentials are correct. Therefore we will make a request
|
||||
// with the commercial flag set to true, which removes the metadata
|
||||
// from the station on TuneIn. After that, and if the test request
|
||||
// succeeds, we will make another request with the real metadata.
|
||||
if ($data["enable_tunein"]) {
|
||||
$credentialsQryStr = "?partnerId=".$data["tunein_partner_id"]."&partnerKey=".$data["tunein_partner_key"]."&id=".$data["tunein_station_id"];
|
||||
$commercialFlagQryStr = "&commercial=true";
|
||||
|
||||
$metadata = Application_Model_Schedule::getCurrentPlayingTrack();
|
||||
|
||||
if (is_null($metadata)) {
|
||||
$qryStr = $credentialsQryStr . $commercialFlagQryStr;
|
||||
} else {
|
||||
$metadata["artist"] = empty($metadata["artist"]) ? "n/a" : $metadata["artist"];
|
||||
$metadata["title"] = empty($metadata["title"]) ? "n/a" : $metadata["title"];
|
||||
$metadataQryStr = "&artist=" . $metadata["artist"] . "&title=" . $metadata["title"];
|
||||
|
||||
$qryStr = $credentialsQryStr . $metadataQryStr;
|
||||
}
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, TUNEIN_API_URL . $qryStr);
|
||||
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
|
||||
|
||||
$xmlData = curl_exec($ch);
|
||||
if (curl_error($ch)) {
|
||||
Logging::error("Failed to reach TuneIn: ". curl_errno($ch)." - ". curl_error($ch) . " - " . curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));
|
||||
if (curl_error($ch) == "The requested URL returned error: 403 Forbidden") {
|
||||
$this->getElement("enable_tunein")->setErrors(array(_("Invalid TuneIn Settings. Please ensure your TuneIn settings are correct and try again.")));
|
||||
|
||||
$valid = false;
|
||||
}
|
||||
}
|
||||
curl_close($ch);
|
||||
|
||||
if ($valid) {
|
||||
$xmlObj = new SimpleXMLElement($xmlData);
|
||||
if (!$xmlObj || $xmlObj->head->status != "200") {
|
||||
$valid = false;
|
||||
} else if ($xmlObj->head->status == "200") {
|
||||
$valid = true;
|
||||
|
||||
// Make another request to TuneIn to update the metadata right away
|
||||
// and to turn off the commercial flag.
|
||||
|
||||
/*$metadata = Application_Model_Schedule::getCurrentPlayingTrack();
|
||||
|
||||
if (!is_null($metadata)) {
|
||||
|
||||
Logging::info($metadata);
|
||||
// Replace empty strings with "n/a" since the TuneIn API will complain
|
||||
// and return an error that title and/or artist is not set.
|
||||
$metadata["artist"] = empty($metadata["artist"]) ? "n/a" : $metadata["artist"];
|
||||
$metadata["title"] = empty($metadata["title"]) ? "n/a" : $metadata["title"];
|
||||
Logging::info($metadata);
|
||||
|
||||
$metadataQryStr = "&artist=" . $metadata["artist"] . "&title=" . $metadata["title"];
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, TUNEIN_API_URL . $qry_str . "&commercial=false" . $metadataQryStr);
|
||||
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
|
||||
|
||||
$xmlData = curl_exec($ch);
|
||||
Logging::info($xmlData);
|
||||
if (curl_error($ch)) {
|
||||
Logging::error("Failed to reach TuneIn: " . curl_errno($ch) . " - " . curl_error($ch) . " - " . curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));
|
||||
}
|
||||
|
||||
curl_close($ch);
|
||||
$xmlObj = new SimpleXMLElement($xmlData);
|
||||
if (!$xmlObj || $xmlObj->head->status != "200") {
|
||||
Logging::error("Failed updating metadata on TuneIn");
|
||||
}
|
||||
}*/
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$valid = true;
|
||||
}
|
||||
|
||||
if (!$valid) {
|
||||
// Set values to what the user entered since the form is invalid so they
|
||||
// don't have to enter in the values again and can see what they entered.
|
||||
$this->getElement("enable_tunein")->setValue($data["enable_tunein"]);
|
||||
$this->getElement("tunein_partner_key")->setValue($data["tunein_partner_key"]);
|
||||
$this->getElement("tunein_partner_id")->setValue($data["tunein_partner_id"]);
|
||||
$this->getElement("tunein_station_id")->setValue($data["tunein_station_id"]);
|
||||
}
|
||||
|
||||
return $valid;
|
||||
}
|
||||
}
|
|
@ -1453,4 +1453,44 @@ class Application_Model_Preference
|
|||
{
|
||||
return self::getValue("provisioning_status");
|
||||
}
|
||||
|
||||
public static function setTuneinEnabled($value)
|
||||
{
|
||||
self::setValue("tunein_enabled", $value);
|
||||
}
|
||||
|
||||
public static function getTuneinEnabled()
|
||||
{
|
||||
return self::getValue("tunein_enabled");
|
||||
}
|
||||
|
||||
public static function setTuneinPartnerKey($value)
|
||||
{
|
||||
self::setValue("tunein_partner_key", $value);
|
||||
}
|
||||
|
||||
public static function getTuneinPartnerKey()
|
||||
{
|
||||
return self::getValue("tunein_partner_key");
|
||||
}
|
||||
|
||||
public static function setTuneinPartnerId($value)
|
||||
{
|
||||
self::setValue("tunein_partner_id", $value);
|
||||
}
|
||||
|
||||
public static function getTuneinPartnerId()
|
||||
{
|
||||
return self::getValue("tunein_partner_id");
|
||||
}
|
||||
|
||||
public static function setTuneinStationId($value)
|
||||
{
|
||||
self::setValue("tunein_station_id", $value);
|
||||
}
|
||||
|
||||
public static function getTuneinStationId()
|
||||
{
|
||||
return self::getValue("tunein_station_id");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,29 @@ SQL;
|
|||
|
||||
return $real_streams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array with 2 elements: artist and title name of the track that is currently playing.
|
||||
* Elements will be set to null if metadata is not set for those fields.
|
||||
*
|
||||
* Returns null if no track is currently playing.
|
||||
*
|
||||
* Data is based on GetPlayOrderRange() in this class.
|
||||
*/
|
||||
public static function getCurrentPlayingTrack()
|
||||
{
|
||||
$currentScheduleInfo = self::GetPlayOrderRange();
|
||||
if (empty($currentScheduleInfo["tracks"]["current"])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$currentTrackArray = explode(" - ", $currentScheduleInfo["tracks"]["current"]["name"]);
|
||||
$currentTrackMetadata = array(
|
||||
"artist" => empty($currentTrackArray[0]) ? null : urlencode($currentTrackArray[0]),
|
||||
"title" => empty($currentTrackArray[1]) ? null : urlencode($currentTrackArray[1])
|
||||
);
|
||||
return $currentTrackMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns data related to the scheduled items.
|
||||
|
|
|
@ -2,20 +2,22 @@
|
|||
<?php echo $this->element->getElement('csrf') ?>
|
||||
|
||||
<?php echo $this->element->getSubform('preferences_general') ?>
|
||||
<?php //No soundcloud stuff on Airtime Pro -- Albert ?>
|
||||
|
||||
<h3 class="collapsible-header" id="soundcloud-heading"><span class="arrow-icon"></span><?php echo _("SoundCloud Settings") ?></h3>
|
||||
|
||||
<div class="collapsible-content" id="soundcloud-settings">
|
||||
<?php echo $this->element->getSubform('preferences_soundcloud') ?>
|
||||
<h3 class="collapsible-header" id="tunein-pref-heading"><span class="arrow-icon"></span><?php echo _("TuneIn Settings"); ?></h3>
|
||||
<div class="collapsible-content" id="tunein-settings">
|
||||
<?php echo $this->element->getSubform('preferences_tunein') ?>
|
||||
</div>
|
||||
|
||||
|
||||
<?php //No soundcloud stuff on Airtime Pro -- Albert ?>
|
||||
|
||||
<h3 class="collapsible-header" id="dangerous-heading"><span class="arrow-icon"></span><?php echo _("Dangerous Options") ?></h3>
|
||||
<div class="collapsible-content" id="dangerous-settings">
|
||||
<?php echo $this->element->getSubform('preferences_danger') ?>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<?php echo $this->element->submit->render() ?>
|
||||
|
||||
</form>
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
<fieldset class="padded">
|
||||
<dl class="zend_form">
|
||||
|
||||
<?php if($this->element->getElement("enable_tunein")->hasErrors()) {
|
||||
echo $this->element->getElement('enable_tunein')->renderErrors();
|
||||
}
|
||||
?>
|
||||
<?php echo $this->element->getElement('enable_tunein')->renderViewHelper() ?>
|
||||
<?php echo $this->element->getElement('enable_tunein')->renderLabel() ?>
|
||||
|
||||
<?php echo $this->element->getElement('tunein_station_id')->render() ?>
|
||||
|
||||
<?php echo $this->element->getElement('tunein_partner_id')->render() ?>
|
||||
|
||||
<?php echo $this->element->getElement('tunein_partner_key')->render() ?>
|
||||
|
||||
</dl>
|
||||
</fieldset>
|
|
@ -3257,3 +3257,7 @@ dd .stream-status {
|
|||
padding-bottom: 0px;
|
||||
padding-top: 13px;
|
||||
}
|
||||
|
||||
.enable-tunein {
|
||||
font-weight:bold;
|
||||
}
|
||||
|
|
|
@ -58,6 +58,30 @@ function setMailServerInputReadonly() {
|
|||
setMsAuthenticationFieldsReadonly(requiresAuthCB);
|
||||
}
|
||||
|
||||
function setTuneInSettingsListener() {
|
||||
var enableTunein = $("#enable_tunein");
|
||||
enableTunein.click(function(event){
|
||||
setTuneInSettingsReadonly();
|
||||
});
|
||||
}
|
||||
|
||||
function setTuneInSettingsReadonly() {
|
||||
var enableTunein = $("#enable_tunein");
|
||||
var stationId = $("#tunein_station_id");
|
||||
var partnerKey = $("#tunein_partner_key");
|
||||
var partnerId = $("#tunein_partner_id");
|
||||
|
||||
if (enableTunein.is(':checked')) {
|
||||
stationId.removeAttr("readonly");
|
||||
partnerKey.removeAttr("readonly");
|
||||
partnerId.removeAttr("readonly");
|
||||
} else {
|
||||
stationId.attr("readonly", "readonly");
|
||||
partnerKey.attr("readonly", "readonly");
|
||||
partnerId.attr("readonly", "readonly");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable/disable mail server authentication fields
|
||||
*/
|
||||
|
@ -131,6 +155,10 @@ $(document).ready(function() {
|
|||
return false;
|
||||
}).next().hide();
|
||||
|
||||
if ($("#tunein-settings").find(".errors").length > 0) {
|
||||
$(".collapsible-content#tunein-settings").show();
|
||||
}
|
||||
|
||||
/* No longer using AJAX for this form. Zend + our code makes it needlessly hard to deal with. -- Albert
|
||||
$('#pref_save').live('click', function() {
|
||||
var data = $('#pref_form').serialize();
|
||||
|
@ -154,4 +182,6 @@ $(document).ready(function() {
|
|||
setConfigureMailServerListener();
|
||||
setEnableSystemEmailsListener();
|
||||
setCollapsibleWidgetJsCode();
|
||||
setTuneInSettingsReadonly();
|
||||
setTuneInSettingsListener();
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue