From 15bebc62679664b0e120445b1695b7c52dde98bc Mon Sep 17 00:00:00 2001 From: Duncan Sommerville Date: Wed, 13 May 2015 15:55:36 -0400 Subject: [PATCH 01/15] Dangerous options subform on Preferences page and Delete all tracks button --- .../controllers/PreferenceController.php | 65 +++++++++++++++++++ .../forms/DangerousPreferences.php | 21 ++++++ airtime_mvc/application/forms/Preferences.php | 3 + airtime_mvc/application/models/StoredFile.php | 1 + .../views/scripts/form/preferences.phtml | 12 ++++ .../scripts/form/preferences_danger.phtml | 14 ++++ airtime_mvc/public/css/styles.css | 27 +++++--- .../js/airtime/preferences/preferences.js | 31 +++++---- 8 files changed, 151 insertions(+), 23 deletions(-) create mode 100644 airtime_mvc/application/forms/DangerousPreferences.php create mode 100644 airtime_mvc/application/views/scripts/form/preferences_danger.phtml diff --git a/airtime_mvc/application/controllers/PreferenceController.php b/airtime_mvc/application/controllers/PreferenceController.php index b06a9e1ed..e5734a6b3 100644 --- a/airtime_mvc/application/controllers/PreferenceController.php +++ b/airtime_mvc/application/controllers/PreferenceController.php @@ -454,4 +454,69 @@ class PreferenceController extends Zend_Controller_Action } $this->_helper->json->sendJson($out); } + + public function deleteAllFilesAction() + { + $this->view->layout()->disableLayout(); + $this->_helper->viewRenderer->setNoRender(true); + + // Only admin users should get here through ACL permissioning + // Only allow POST requests + $method = $_SERVER['REQUEST_METHOD']; + if (!($method == 'POST')) { + $this->getResponse() + ->setHttpResponseCode(405) + ->appendBody(_("Request method not accepted") . ": $method"); + return; + } + + $user = Application_Model_User::getCurrentUser(); + $playlists = $blocks = $streams = []; + + $allPlaylists = CcPlaylistQuery::create()->find(); + foreach ($allPlaylists as $p) { + $playlists[] = $p->getDbId(); + } + + $allBlocks = CcBlockQuery::create()->find(); + foreach ($allBlocks as $b) { + $blocks[] = $b->getDbId(); + } + + $allStreams = CcWebstreamQuery::create()->find(); + foreach ($allStreams as $s) { + $streams[] = $s->getDbId(); + } + + // Delete all playlists, blocks, and streams + Application_Model_Playlist::deletePlaylists($playlists, $user->getId()); + Application_Model_Block::deleteBlocks($blocks, $user->getId()); + Application_Model_Webstream::deleteStreams($streams, $user->getId()); + + try { + // Delete all the cloud files + $CC_CONFIG = Config::getConfig(); + + foreach ($CC_CONFIG["supportedStorageBackends"] as $storageBackend) { + $proxyStorageBackend = new ProxyStorageBackend($storageBackend); + $proxyStorageBackend->deleteAllCloudFileObjects(); + } + } catch(Exception $e) { + Logging::info($e->getMessage()); + } + + // Delete all files from the database + $files = CcFilesQuery::create()->find(); + foreach ($files as $file) { + $storedFile = new Application_Model_StoredFile($file, null); + $storedFile->delete(); + } + + /* TODO: delete hard copies of files? */ + + $this->getResponse() + ->setHttpResponseCode(200) + ->appendBody("OK"); + } + } diff --git a/airtime_mvc/application/forms/DangerousPreferences.php b/airtime_mvc/application/forms/DangerousPreferences.php new file mode 100644 index 000000000..28d203405 --- /dev/null +++ b/airtime_mvc/application/forms/DangerousPreferences.php @@ -0,0 +1,21 @@ +setDecorators(array( + array('ViewScript', array('viewScript' => 'form/preferences_danger.phtml')) + )); + + $clearLibrary = new Zend_Form_Element_Button('clear_library'); + $clearLibrary->setLabel(_('Delete All Tracks in Library')); + //$submit->removeDecorator('Label'); + $clearLibrary->setAttribs(array('class'=>'btn centered')); + $clearLibrary->setAttrib('onclick', 'deleteAllFiles();'); + $clearLibrary->removeDecorator('DtDdWrapper'); + + $this->addElement($clearLibrary); + } + +} diff --git a/airtime_mvc/application/forms/Preferences.php b/airtime_mvc/application/forms/Preferences.php index 3e5158413..30a11e933 100644 --- a/airtime_mvc/application/forms/Preferences.php +++ b/airtime_mvc/application/forms/Preferences.php @@ -24,6 +24,9 @@ class Application_Form_Preferences extends Zend_Form $soundcloud_pref = new Application_Form_SoundcloudPreferences(); $this->addSubForm($soundcloud_pref, 'preferences_soundcloud'); + $danger_pref = new Application_Form_DangerousPreferences(); + $this->addSubForm($danger_pref, 'preferences_danger'); + $submit = new Zend_Form_Element_Submit('submit'); $submit->setLabel(_('Save')); //$submit->removeDecorator('Label'); diff --git a/airtime_mvc/application/models/StoredFile.php b/airtime_mvc/application/models/StoredFile.php index 8e3dd7a59..51baf2e20 100644 --- a/airtime_mvc/application/models/StoredFile.php +++ b/airtime_mvc/application/models/StoredFile.php @@ -401,6 +401,7 @@ SQL; //or from the cloud if ($this->_file->getDbImportStatus() == CcFiles::IMPORT_STATUS_SUCCESS) { try { + Logging::info("DELETING PHYSICAL FILE " . $this->_file->getDbTrackTitle()); $this->_file->deletePhysicalFile(); } catch (Exception $e) diff --git a/airtime_mvc/application/views/scripts/form/preferences.phtml b/airtime_mvc/application/views/scripts/form/preferences.phtml index 0ffe1ea9d..cef632f57 100644 --- a/airtime_mvc/application/views/scripts/form/preferences.phtml +++ b/airtime_mvc/application/views/scripts/form/preferences.phtml @@ -4,6 +4,18 @@ element->getSubform('preferences_general') ?> +

+ +
+ element->getSubform('preferences_soundcloud') ?> +
+ +

+
+ element->getSubform('preferences_danger') ?> +
+ +
element->submit->render() ?> diff --git a/airtime_mvc/application/views/scripts/form/preferences_danger.phtml b/airtime_mvc/application/views/scripts/form/preferences_danger.phtml new file mode 100644 index 000000000..7ea8a78d1 --- /dev/null +++ b/airtime_mvc/application/views/scripts/form/preferences_danger.phtml @@ -0,0 +1,14 @@ +
+
+ +
+

+ Warning: These functions will have permanent and lasting effects + on your Airtime station. Think carefully before using them! +

+
+ + element->getElement('clear_library')->render() ?> + +
+
diff --git a/airtime_mvc/public/css/styles.css b/airtime_mvc/public/css/styles.css index b80cbfe8e..8bb4c4ba9 100644 --- a/airtime_mvc/public/css/styles.css +++ b/airtime_mvc/public/css/styles.css @@ -1788,7 +1788,7 @@ ul.errors { width:278px; } -ul.errors li { +ul.errors li, .warning { color:#902d2d; font-size:11px; padding:2px 4px; @@ -1798,6 +1798,11 @@ ul.errors li { list-style: none; } +.warning-label { + font-size: medium; + text-align: center; +} + div.success{ color:#3B5323; font-size:11px; @@ -2255,14 +2260,9 @@ dd.radio-inline-list, .preferences dd.radio-inline-list, .stream-config dd.radio .radio-inline-list label { margin-right:12px; } -.preferences.simple-formblock dd.block-display { - width: 100%; -} - -.preferences.simple-formblock dd.block-display select, .stream-config.simple-formblock dd.block-display select { - width: 100%; -} -.preferences dd.block-display .input_select, .stream-config dd.block-display .input_select { +.preferences.simple-formblock dd.block-display, + .preferences.simple-formblock dd.block-display select, .stream-config.simple-formblock dd.block-display select, + .preferences dd.block-display .input_select, .stream-config dd.block-display .input_select { width: 100%; } .preferences dd.block-display .input_text_area, .preferences dd.block-display .input_text @@ -2284,6 +2284,15 @@ dd.radio-inline-list, .preferences dd.radio-inline-list, .stream-config dd.radio margin-bottom: 4px; } +.preferences #Logo-img-container { + margin-top: 30px; +} + +.centered { + margin: 0 auto; + display: block; +} + #show_time_info { font-size:12px; height:30px; diff --git a/airtime_mvc/public/js/airtime/preferences/preferences.js b/airtime_mvc/public/js/airtime/preferences/preferences.js index 1dffe24d2..8894020bc 100644 --- a/airtime_mvc/public/js/airtime/preferences/preferences.js +++ b/airtime_mvc/public/js/airtime/preferences/preferences.js @@ -1,18 +1,13 @@ function showErrorSections() { - if($("#soundcloud-settings .errors").length > 0) { - $("#soundcloud-settings").show(); - $(window).scrollTop($("#soundcloud-settings .errors").position().top); - } - - if($("#email-server-settings .errors").length > 0) { - $("#email-server-settings").show(); - $(window).scrollTop($("#email-server-settings .errors").position().top); - } - - if($("#livestream-settings .errors").length > 0) { - $("#livestream-settings").show(); - $(window).scrollTop($("#livestream-settings .errors").position().top); - } + var selector = $("[id$=-settings]"); + selector.each(function(i) { + var el = $(this); + var errors = el.find(".errors"); + if (errors.length > 0) { + el.show(); + $(window).scrollTop(errors.position().top); + } + }); } function setConfigureMailServerListener() { @@ -120,6 +115,14 @@ function removeLogo() { location.reload(); } +function deleteAllFiles() { + var resp = confirm($.i18n._("Are you sure you want to delete all the tracks in your library?")) + if (resp) { + $.post(baseUrl+'Preference/delete-all-files', function(json){}); + location.reload(); + } +} + $(document).ready(function() { $('.collapsible-header').live('click',function() { From cf24c141fd1079ff1e594a42958d3ca11ba3a769 Mon Sep 17 00:00:00 2001 From: drigato Date: Wed, 13 May 2015 16:05:37 -0400 Subject: [PATCH 02/15] SAAS-772: Send metadata to Tunein This is pretty much working for scheduled metadata - just to need to test with a TuneIn account. --- airtime_mvc/application/common/TuneIn.php | 29 ++++++++++++ airtime_mvc/application/configs/constants.php | 4 ++ .../application/controllers/ApiController.php | 9 ++++ .../controllers/PreferenceController.php | 9 +++- airtime_mvc/application/forms/Preferences.php | 4 ++ .../application/forms/TuneInPreferences.php | 44 +++++++++++++++++++ airtime_mvc/application/models/Preference.php | 40 +++++++++++++++++ .../views/scripts/form/preferences.phtml | 5 +++ .../scripts/form/preferences_tunein.phtml | 11 +++++ .../js/airtime/preferences/preferences.js | 26 +++++++++++ 10 files changed, 179 insertions(+), 2 deletions(-) create mode 100644 airtime_mvc/application/common/TuneIn.php create mode 100644 airtime_mvc/application/forms/TuneInPreferences.php create mode 100644 airtime_mvc/application/views/scripts/form/preferences_tunein.phtml diff --git a/airtime_mvc/application/common/TuneIn.php b/airtime_mvc/application/common/TuneIn.php new file mode 100644 index 000000000..54dedc516 --- /dev/null +++ b/airtime_mvc/application/common/TuneIn.php @@ -0,0 +1,29 @@ +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 diff --git a/airtime_mvc/application/controllers/PreferenceController.php b/airtime_mvc/application/controllers/PreferenceController.php index b06a9e1ed..e4615c02d 100644 --- a/airtime_mvc/application/controllers/PreferenceController.php +++ b/airtime_mvc/application/controllers/PreferenceController.php @@ -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 = "
". _("Preferences updated.")."
"; $this->view->form = $form; diff --git a/airtime_mvc/application/forms/Preferences.php b/airtime_mvc/application/forms/Preferences.php index 3e5158413..3226d558d 100644 --- a/airtime_mvc/application/forms/Preferences.php +++ b/airtime_mvc/application/forms/Preferences.php @@ -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'); diff --git a/airtime_mvc/application/forms/TuneInPreferences.php b/airtime_mvc/application/forms/TuneInPreferences.php new file mode 100644 index 000000000..d97a557e9 --- /dev/null +++ b/airtime_mvc/application/forms/TuneInPreferences.php @@ -0,0 +1,44 @@ +setDecorators(array( + array('ViewScript', array('viewScript' => 'form/preferences_tunein.phtml')) + )); + + $enableTunein = new Zend_Form_Element_Checkbox("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); + + // TODO: figure out how to make this validator work + $validator = new ConditionalNotEmpty(array( + 'enable_tunein' => 1 + )); + + $tuneinStationId = new Zend_Form_Element_Text("tunein_station_id"); + $tuneinStationId->setLabel(_("Station ID:")); + $tuneinStationId->setValue(Application_Model_Preference::getTuneinStationId()); + $tuneinStationId->setAttrib("class", "input_text"); + $tuneinStationId->addValidator($validator); + $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"); + $tuneinPartnerKey->addValidator($validator); + $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"); + $tuneinPartnerId->addValidator($validator); + $this->addElement($tuneinPartnerId); + } +} \ No newline at end of file diff --git a/airtime_mvc/application/models/Preference.php b/airtime_mvc/application/models/Preference.php index 64263b94c..1387d326b 100644 --- a/airtime_mvc/application/models/Preference.php +++ b/airtime_mvc/application/models/Preference.php @@ -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"); + } } diff --git a/airtime_mvc/application/views/scripts/form/preferences.phtml b/airtime_mvc/application/views/scripts/form/preferences.phtml index 0ffe1ea9d..9029a5c17 100644 --- a/airtime_mvc/application/views/scripts/form/preferences.phtml +++ b/airtime_mvc/application/views/scripts/form/preferences.phtml @@ -4,6 +4,11 @@ element->getSubform('preferences_general') ?> +

+
+ element->getSubform('preferences_tunein') ?> +
+ element->submit->render() ?> diff --git a/airtime_mvc/application/views/scripts/form/preferences_tunein.phtml b/airtime_mvc/application/views/scripts/form/preferences_tunein.phtml new file mode 100644 index 000000000..a3cdb0d83 --- /dev/null +++ b/airtime_mvc/application/views/scripts/form/preferences_tunein.phtml @@ -0,0 +1,11 @@ +
+
+ element->getElement('enable_tunein')->render() ?> + + element->getElement('tunein_station_id')->render() ?> + + element->getElement('tunein_partner_key')->render() ?> + + element->getElement('tunein_partner_id')->render() ?> +
+
\ No newline at end of file diff --git a/airtime_mvc/public/js/airtime/preferences/preferences.js b/airtime_mvc/public/js/airtime/preferences/preferences.js index 1dffe24d2..d1aea4091 100644 --- a/airtime_mvc/public/js/airtime/preferences/preferences.js +++ b/airtime_mvc/public/js/airtime/preferences/preferences.js @@ -63,6 +63,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 */ @@ -151,4 +175,6 @@ $(document).ready(function() { setConfigureMailServerListener(); setEnableSystemEmailsListener(); setCollapsibleWidgetJsCode(); + setTuneInSettingsReadonly(); + setTuneInSettingsListener(); }); From 9d822b6e8b269ff68e5d90b3acb3385b0d362ef6 Mon Sep 17 00:00:00 2001 From: Duncan Sommerville Date: Wed, 13 May 2015 17:58:02 -0400 Subject: [PATCH 03/15] Only use API authentication (not session) when validating termination requests --- .../application/controllers/ProvisioningController.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/airtime_mvc/application/controllers/ProvisioningController.php b/airtime_mvc/application/controllers/ProvisioningController.php index cda59e0db..06ee7a2ab 100644 --- a/airtime_mvc/application/controllers/ProvisioningController.php +++ b/airtime_mvc/application/controllers/ProvisioningController.php @@ -57,13 +57,16 @@ class ProvisioningController extends Zend_Controller_Action /** * Delete the Airtime Pro station's files from Amazon S3 + * + * FIXME: When we deploy this next time, we should ensure that + * this function can only be accessed with POST requests! */ public function terminateAction() { $this->view->layout()->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); - if (!RestAuth::verifyAuth(true, true, $this)) { + if (!RestAuth::verifyAuth(true, false, $this)) { return; } From bff04820f2ec121d7d6ad520941706bdc3f76379 Mon Sep 17 00:00:00 2001 From: Duncan Sommerville Date: Wed, 13 May 2015 17:58:11 -0400 Subject: [PATCH 04/15] Add quiet flag to StoredFile delete to avoid unnecessary sentry errors when clearing library --- .../application/controllers/PreferenceController.php | 6 +++--- airtime_mvc/application/models/StoredFile.php | 11 +++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/airtime_mvc/application/controllers/PreferenceController.php b/airtime_mvc/application/controllers/PreferenceController.php index e5734a6b3..0d7543a37 100644 --- a/airtime_mvc/application/controllers/PreferenceController.php +++ b/airtime_mvc/application/controllers/PreferenceController.php @@ -509,11 +509,11 @@ class PreferenceController extends Zend_Controller_Action $files = CcFilesQuery::create()->find(); foreach ($files as $file) { $storedFile = new Application_Model_StoredFile($file, null); - $storedFile->delete(); + // Delete the files quietly to avoid getting Sentry errors for + // every S3 file we delete. + $storedFile->delete(true); } - /* TODO: delete hard copies of files? */ - $this->getResponse() ->setHttpResponseCode(200) ->appendBody("OK"); diff --git a/airtime_mvc/application/models/StoredFile.php b/airtime_mvc/application/models/StoredFile.php index 51baf2e20..32d6ec371 100644 --- a/airtime_mvc/application/models/StoredFile.php +++ b/airtime_mvc/application/models/StoredFile.php @@ -375,7 +375,7 @@ SQL; * Deletes the physical file from the local file system or from the cloud * */ - public function delete() + public function delete($quiet=false) { // Check if the file is scheduled to be played in the future if (Application_Model_Schedule::IsFileScheduledInTheFuture($this->_file->getCcFileId())) { @@ -401,13 +401,16 @@ SQL; //or from the cloud if ($this->_file->getDbImportStatus() == CcFiles::IMPORT_STATUS_SUCCESS) { try { - Logging::info("DELETING PHYSICAL FILE " . $this->_file->getDbTrackTitle()); $this->_file->deletePhysicalFile(); } catch (Exception $e) { - //Just log the exception and continue. - Logging::error($e); + if ($quiet) { + Logging::info($e); + } else { + //Just log the exception and continue. + Logging::error($e); + } } } From 70735e7baeb1f91fd5a3e196555231c68c9d2f03 Mon Sep 17 00:00:00 2001 From: Duncan Sommerville Date: Thu, 14 May 2015 10:51:53 -0400 Subject: [PATCH 05/15] Retun 200 from ProvisioningHelper when a database exists to accommodate recreating terminated stations --- .../application/common/ProvisioningHelper.php | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/airtime_mvc/application/common/ProvisioningHelper.php b/airtime_mvc/application/common/ProvisioningHelper.php index 580c20e52..605617105 100644 --- a/airtime_mvc/application/common/ProvisioningHelper.php +++ b/airtime_mvc/application/common/ProvisioningHelper.php @@ -10,7 +10,7 @@ class ProvisioningHelper // Parameter values private $dbuser, $dbpass, $dbname, $dbhost, $dbowner, $apikey; private $instanceId; - private $station_name, $description; + private $stationName, $description; public function __construct($apikey) { @@ -40,18 +40,14 @@ class ProvisioningHelper if ($this->dbhost && !empty($this->dbhost)) { $this->setNewDatabaseConnection(); - //if ($this->checkDatabaseExists()) { - // throw new Exception("ERROR: Airtime database already exists"); - //} - if (!$this->checkDatabaseExists()) { - throw new Exception("ERROR: $this->dbname database does not exist."); + throw new DatabaseDoesNotExistException("ERROR: $this->dbname database does not exist."); } //We really want to do this check because all the Propel-generated SQL starts with "DROP TABLE IF EXISTS". //If we don't check, then a second call to this API endpoint would wipe all the tables! if ($this->checkTablesExist()) { - throw new Exception("ERROR: airtime tables already exists"); + throw new DatabaseAlreadyExistsException(); } $this->createDatabaseTables(); @@ -63,11 +59,19 @@ class ProvisioningHelper //All we need to do is create the database tables. $this->initializePrefs(); - } catch (Exception $e) { + } catch (DatabaseDoesNotExistException $e) { http_response_code(400); Logging::error($e->getMessage()); echo $e->getMessage() . PHP_EOL; return; + } catch (DatabaseAlreadyExistsException $e) { + // When we recreate a terminated instance, the process will fail + // if we return a 40x response here. In order to circumvent this, + // just return a 200; we still avoid dropping the existing tables + http_response_code(200); + Logging::info($e->getMessage()); + echo $e->getMessage() . PHP_EOL; + return; } http_response_code(201); @@ -108,7 +112,7 @@ class ProvisioningHelper $this->dbowner = $_POST['dbowner']; $this->instanceId = $_POST['instanceid']; - $this->station_name = $_POST['station_name']; + $this->stationName = $_POST['station_name']; $this->description = $_POST['description']; } @@ -194,8 +198,8 @@ class ProvisioningHelper * Initialize preference values passed from the dashboard (if any exist) */ private function initializePrefs() { - if ($this->station_name) { - Application_Model_Preference::SetStationName($this->station_name); + if ($this->stationName) { + Application_Model_Preference::SetStationName($this->stationName); } if ($this->description) { Application_Model_Preference::SetStationDescription($this->description); @@ -203,3 +207,14 @@ class ProvisioningHelper } } + +class DatabaseAlreadyExistsException extends Exception { + private static $_defaultMessage = "ERROR: airtime tables already exists"; + public function __construct($message = null, $code = 0, Exception $previous = null) { + $message = _((is_null($message) ? self::$_defaultMessage : $message)); + parent::__construct($message, $code, $previous); + } +} + +class DatabaseDoesNotExistException extends Exception {} + From b023f191e3e36fece00fd7209aea0c7bf0c17fe6 Mon Sep 17 00:00:00 2001 From: drigato Date: Thu, 14 May 2015 13:13:33 -0400 Subject: [PATCH 06/15] SAAS-772: Send metadata to Tunein Added form validation by making a test request to the TuneIn API with the user-entered values --- .../application/forms/TuneInPreferences.php | 54 +++++++++++++++---- .../scripts/form/preferences_tunein.phtml | 8 ++- airtime_mvc/public/css/styles.css | 4 ++ .../js/airtime/preferences/preferences.js | 4 ++ 4 files changed, 60 insertions(+), 10 deletions(-) diff --git a/airtime_mvc/application/forms/TuneInPreferences.php b/airtime_mvc/application/forms/TuneInPreferences.php index d97a557e9..5eb729aca 100644 --- a/airtime_mvc/application/forms/TuneInPreferences.php +++ b/airtime_mvc/application/forms/TuneInPreferences.php @@ -10,35 +10,71 @@ class Application_Form_TuneInPreferences extends Zend_Form_SubForm )); $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); - // TODO: figure out how to make this validator work - $validator = new ConditionalNotEmpty(array( - 'enable_tunein' => 1 - )); - $tuneinStationId = new Zend_Form_Element_Text("tunein_station_id"); $tuneinStationId->setLabel(_("Station ID:")); $tuneinStationId->setValue(Application_Model_Preference::getTuneinStationId()); $tuneinStationId->setAttrib("class", "input_text"); - $tuneinStationId->addValidator($validator); $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"); - $tuneinPartnerKey->addValidator($validator); $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"); - $tuneinPartnerId->addValidator($validator); $this->addElement($tuneinPartnerId); } -} \ No newline at end of file + + public function isValid($data) + { + // Make request to TuneIn API to test the settings are valid + if ($data["enable_tunein"]) { + $qry_str = "?partnerId=".$data["tunein_partner_id"]."&partnerKey=".$data["tunein_partner_key"]."&id=".$data["tunein_station_id"] + ."&title=&artist="; + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, TUNEIN_API_URL . $qry_str); + curl_setopt($ch, CURLOPT_FAILONERROR, 1); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_TIMEOUT, 30); + + $jsonData = 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."))); + + // 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 false; + } + } + curl_close($ch); + + $arr = json_decode($jsonData, true); + Logging::info($arr); + } else { + return true; + } + } +} diff --git a/airtime_mvc/application/views/scripts/form/preferences_tunein.phtml b/airtime_mvc/application/views/scripts/form/preferences_tunein.phtml index a3cdb0d83..f7ae2bc84 100644 --- a/airtime_mvc/application/views/scripts/form/preferences_tunein.phtml +++ b/airtime_mvc/application/views/scripts/form/preferences_tunein.phtml @@ -1,6 +1,12 @@
- element->getElement('enable_tunein')->render() ?> + + element->getElement("enable_tunein")->hasErrors()) { + echo $this->element->getElement('enable_tunein')->renderErrors(); + } + ?> + element->getElement('enable_tunein')->renderViewHelper() ?> + element->getElement('enable_tunein')->renderLabel() ?> element->getElement('tunein_station_id')->render() ?> diff --git a/airtime_mvc/public/css/styles.css b/airtime_mvc/public/css/styles.css index b80cbfe8e..8fc43eda6 100644 --- a/airtime_mvc/public/css/styles.css +++ b/airtime_mvc/public/css/styles.css @@ -3248,3 +3248,7 @@ dd .stream-status { padding-bottom: 0px; padding-top: 13px; } + +.enable-tunein { + font-weight:bold; +} \ No newline at end of file diff --git a/airtime_mvc/public/js/airtime/preferences/preferences.js b/airtime_mvc/public/js/airtime/preferences/preferences.js index d1aea4091..0491d335c 100644 --- a/airtime_mvc/public/js/airtime/preferences/preferences.js +++ b/airtime_mvc/public/js/airtime/preferences/preferences.js @@ -152,6 +152,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(); From 82c801cb799edb37720a90022d988782f1a537cd Mon Sep 17 00:00:00 2001 From: Duncan Sommerville Date: Fri, 15 May 2015 15:15:49 -0400 Subject: [PATCH 07/15] Add on_metadata wrapper to liquidsoap master/show sources --- python_apps/pypo/liquidsoap_scripts/ls_script.liq | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python_apps/pypo/liquidsoap_scripts/ls_script.liq b/python_apps/pypo/liquidsoap_scripts/ls_script.liq index ccc3a0776..b751838b3 100644 --- a/python_apps/pypo/liquidsoap_scripts/ls_script.liq +++ b/python_apps/pypo/liquidsoap_scripts/ls_script.liq @@ -282,6 +282,8 @@ else s end +# Send metadata notifications when using master source +s = on_metadata(notify_queue, s) # Attach a skip command to the source s: #add_skip_command(s) From 415a0d21f96c5396b11b427499e8b0dfd515c2ae Mon Sep 17 00:00:00 2001 From: Duncan Sommerville Date: Fri, 15 May 2015 15:46:45 -0400 Subject: [PATCH 08/15] Add on_metadata wrapper to liquidsoap master/show sources --- python_apps/pypo/liquidsoap_scripts/ls_script.liq | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python_apps/pypo/liquidsoap_scripts/ls_script.liq b/python_apps/pypo/liquidsoap_scripts/ls_script.liq index b751838b3..fb3452181 100644 --- a/python_apps/pypo/liquidsoap_scripts/ls_script.liq +++ b/python_apps/pypo/liquidsoap_scripts/ls_script.liq @@ -249,6 +249,7 @@ s = if dj_live_stream_port != 0 and dj_live_stream_mp != "" then on_connect=live_dj_connect, on_disconnect=live_dj_disconnect)) + dj_live = on_metadata(notify_queue, dj_live) ignore(output.dummy(dj_live, fallible=true)) switch(id="show_schedule_noise_switch", @@ -271,6 +272,7 @@ s = if master_live_stream_port != 0 and master_live_stream_mp != "" then on_connect=master_dj_connect, on_disconnect=master_dj_disconnect)) + master_dj = on_metadata(notify_queue, master_dj) ignore(output.dummy(master_dj, fallible=true)) switch(id="master_show_schedule_noise_switch", From 4451c49c067a79ce180aa033e6f9949e5c7ab999 Mon Sep 17 00:00:00 2001 From: drigato Date: Tue, 19 May 2015 14:39:05 -0400 Subject: [PATCH 09/15] SAAS-772: Send metadata to Tunein This is pretty much working except with master source metadata --- airtime_mvc/application/common/TuneIn.php | 13 ++- .../application/forms/TuneInPreferences.php | 84 +++++++++++++++---- airtime_mvc/application/models/Schedule.php | 23 +++++ .../scripts/form/preferences_tunein.phtml | 3 +- 4 files changed, 99 insertions(+), 24 deletions(-) diff --git a/airtime_mvc/application/common/TuneIn.php b/airtime_mvc/application/common/TuneIn.php index 54dedc516..1dcfdf742 100644 --- a/airtime_mvc/application/common/TuneIn.php +++ b/airtime_mvc/application/common/TuneIn.php @@ -4,12 +4,12 @@ class Application_Common_TuneIn { public static function sendMetadataToTunein($title, $artist) { - $tuneInStationID = null; - $tuneInPartnerKey = null; - $tuneInPartnerID = null; + $tuneInStationID = Application_Model_Preference::getTuneinStationId(); + $tuneInPartnerID = Application_Model_Preference::getTuneinPartnerId(); + $tuneInPartnerKey = Application_Model_Preference::getTuneinPartnerKey(); $qry_str = "?partnerId=".$tuneInPartnerID."&partnerKey=".$tuneInPartnerKey."&id=".$tuneInStationID - ."&title=".$title."&artist=".$artist; + ."&title=".$title."&artist=".$artist."&commercial=false"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, TUNEIN_API_URL . $qry_str); @@ -17,13 +17,12 @@ class Application_Common_TuneIn curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 30); - $jsonData = curl_exec($ch); + 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); - $arr = json_decode($jsonData, true); - Logging::info($arr); } + } diff --git a/airtime_mvc/application/forms/TuneInPreferences.php b/airtime_mvc/application/forms/TuneInPreferences.php index 5eb729aca..6ee52588a 100644 --- a/airtime_mvc/application/forms/TuneInPreferences.php +++ b/airtime_mvc/application/forms/TuneInPreferences.php @@ -42,39 +42,91 @@ class Application_Form_TuneInPreferences extends Zend_Form_SubForm public function isValid($data) { - // Make request to TuneIn API to test the settings are valid + $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"]) { - $qry_str = "?partnerId=".$data["tunein_partner_id"]."&partnerKey=".$data["tunein_partner_key"]."&id=".$data["tunein_station_id"] - ."&title=&artist="; + $qry_str = "?partnerId=".$data["tunein_partner_id"]."&partnerKey=".$data["tunein_partner_key"]."&id=".$data["tunein_station_id"]; + $commercialFlagQryStr = "&commercial=true"; $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, TUNEIN_API_URL . $qry_str); + curl_setopt($ch, CURLOPT_URL, TUNEIN_API_URL . $qry_str . $commercialFlagQryStr); curl_setopt($ch, CURLOPT_FAILONERROR, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 30); - $jsonData = curl_exec($ch); + $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."))); - // 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 false; + $valid = false; } } curl_close($ch); - $arr = json_decode($jsonData, true); - Logging::info($arr); + 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 { - return true; + $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; } } diff --git a/airtime_mvc/application/models/Schedule.php b/airtime_mvc/application/models/Schedule.php index 2993dc03d..66d00661b 100644 --- a/airtime_mvc/application/models/Schedule.php +++ b/airtime_mvc/application/models/Schedule.php @@ -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. diff --git a/airtime_mvc/application/views/scripts/form/preferences_tunein.phtml b/airtime_mvc/application/views/scripts/form/preferences_tunein.phtml index f7ae2bc84..d5fd34dd5 100644 --- a/airtime_mvc/application/views/scripts/form/preferences_tunein.phtml +++ b/airtime_mvc/application/views/scripts/form/preferences_tunein.phtml @@ -10,8 +10,9 @@ element->getElement('tunein_station_id')->render() ?> + element->getElement('tunein_partner_id')->render() ?> + element->getElement('tunein_partner_key')->render() ?> - element->getElement('tunein_partner_id')->render() ?>
\ No newline at end of file From c3457ae03fb39f784dd9b664405cf1afa989d9c7 Mon Sep 17 00:00:00 2001 From: drigato Date: Tue, 19 May 2015 15:19:09 -0400 Subject: [PATCH 10/15] tunein testing --- airtime_mvc/application/common/TuneIn.php | 2 ++ .../application/forms/TuneInPreferences.php | 20 +++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/airtime_mvc/application/common/TuneIn.php b/airtime_mvc/application/common/TuneIn.php index 1dcfdf742..46f81a2bd 100644 --- a/airtime_mvc/application/common/TuneIn.php +++ b/airtime_mvc/application/common/TuneIn.php @@ -25,4 +25,6 @@ class Application_Common_TuneIn } + public static function updateOfflineMetadata() + } diff --git a/airtime_mvc/application/forms/TuneInPreferences.php b/airtime_mvc/application/forms/TuneInPreferences.php index 6ee52588a..7eee0d56f 100644 --- a/airtime_mvc/application/forms/TuneInPreferences.php +++ b/airtime_mvc/application/forms/TuneInPreferences.php @@ -50,11 +50,23 @@ class Application_Form_TuneInPreferences extends Zend_Form_SubForm // 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"]) { - $qry_str = "?partnerId=".$data["tunein_partner_id"]."&partnerKey=".$data["tunein_partner_key"]."&id=".$data["tunein_station_id"]; + $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 . $qry_str . $commercialFlagQryStr); + 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); @@ -80,7 +92,7 @@ class Application_Form_TuneInPreferences extends Zend_Form_SubForm // Make another request to TuneIn to update the metadata right away // and to turn off the commercial flag. - $metadata = Application_Model_Schedule::getCurrentPlayingTrack(); + /*$metadata = Application_Model_Schedule::getCurrentPlayingTrack(); if (!is_null($metadata)) { @@ -110,7 +122,7 @@ class Application_Form_TuneInPreferences extends Zend_Form_SubForm if (!$xmlObj || $xmlObj->head->status != "200") { Logging::error("Failed updating metadata on TuneIn"); } - } + }*/ } } From 2da4e264e56b9a57df5a6c998ecface1735d7edf Mon Sep 17 00:00:00 2001 From: drigato Date: Tue, 19 May 2015 15:42:07 -0400 Subject: [PATCH 11/15] SAAS-772: Send metadata to Tunein Update metadata when station goes offline --- airtime_mvc/application/common/TuneIn.php | 34 ++++++++++++++----- .../controllers/ScheduleController.php | 8 +++++ 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/airtime_mvc/application/common/TuneIn.php b/airtime_mvc/application/common/TuneIn.php index 46f81a2bd..6040fb184 100644 --- a/airtime_mvc/application/common/TuneIn.php +++ b/airtime_mvc/application/common/TuneIn.php @@ -4,15 +4,11 @@ class Application_Common_TuneIn { public static function sendMetadataToTunein($title, $artist) { - $tuneInStationID = Application_Model_Preference::getTuneinStationId(); - $tuneInPartnerID = Application_Model_Preference::getTuneinPartnerId(); - $tuneInPartnerKey = Application_Model_Preference::getTuneinPartnerKey(); - - $qry_str = "?partnerId=".$tuneInPartnerID."&partnerKey=".$tuneInPartnerKey."&id=".$tuneInStationID - ."&title=".$title."&artist=".$artist."&commercial=false"; + $credQryStr = self::getCredentialsQueryString(); + $metadataQryStr = "&title=".$title."&artist=".$artist."&commercial=false"; $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, TUNEIN_API_URL . $qry_str); + 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); @@ -25,6 +21,28 @@ class Application_Common_TuneIn } - public static function updateOfflineMetadata() + 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); + } } diff --git a/airtime_mvc/application/controllers/ScheduleController.php b/airtime_mvc/application/controllers/ScheduleController.php index 452788b23..0df1c389c 100644 --- a/airtime_mvc/application/controllers/ScheduleController.php +++ b/airtime_mvc/application/controllers/ScheduleController.php @@ -1,4 +1,5 @@ Date: Tue, 19 May 2015 15:51:04 -0400 Subject: [PATCH 12/15] Fix bad merge that added soundcloud settings back into preferences page --- airtime_mvc/application/views/scripts/form/preferences.phtml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/airtime_mvc/application/views/scripts/form/preferences.phtml b/airtime_mvc/application/views/scripts/form/preferences.phtml index f7e4db149..d200bf627 100644 --- a/airtime_mvc/application/views/scripts/form/preferences.phtml +++ b/airtime_mvc/application/views/scripts/form/preferences.phtml @@ -10,11 +10,6 @@ -

- -
- element->getSubform('preferences_soundcloud') ?> -

From ae3fef383ef8ec404b1fdf7d898f0790f731038b Mon Sep 17 00:00:00 2001 From: Albert Santoni Date: Tue, 19 May 2015 16:20:51 -0400 Subject: [PATCH 13/15] Removed station_domain from messages to airtime_analyzer, unused. --- airtime_mvc/application/models/RabbitMq.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/airtime_mvc/application/models/RabbitMq.php b/airtime_mvc/application/models/RabbitMq.php index 5daf227a2..fa05f3986 100644 --- a/airtime_mvc/application/models/RabbitMq.php +++ b/airtime_mvc/application/models/RabbitMq.php @@ -112,12 +112,7 @@ class Application_Model_RabbitMq $data['original_filename'] = $originalFilename; $data['callback_url'] = $callbackUrl; $data['api_key'] = $apiKey; - // Pass station name to the analyzer so we can set it with the file's - // metadata before uploading it to the cloud. This isn't a requirement - // for cloud storage, but put there as a safeguard, since all Airtime - // Pro stations will share the same bucket. - $data['station_domain'] = $stationDomain = Application_Model_Preference::GetStationName(); - + // We add a prefix to the resource name so files are not all placed // under the root folder. We do this in case we need to restore a // customer's file/s; File restoration is done via the S3 Browser From e5a8f14a9abaf17e442c9ea2e32c3e6b9680b19f Mon Sep 17 00:00:00 2001 From: drigato Date: Wed, 20 May 2015 07:05:26 -0400 Subject: [PATCH 14/15] Commented out request to tunein when station is offline --- airtime_mvc/application/controllers/ScheduleController.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/airtime_mvc/application/controllers/ScheduleController.php b/airtime_mvc/application/controllers/ScheduleController.php index 0df1c389c..51b86c124 100644 --- a/airtime_mvc/application/controllers/ScheduleController.php +++ b/airtime_mvc/application/controllers/ScheduleController.php @@ -301,9 +301,10 @@ class ScheduleController extends Zend_Controller_Action // 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()) { + //TODO: find a better solution for this so we don't spam the station on TuneIn + /*if (is_null($range["current"]) && Application_Model_Preference::getTuneinEnabled()) { Application_Common_TuneIn::updateOfflineMetadata(); - } + }*/ $show = Application_Model_Show::getCurrentShow(); From 3052e1f23bb5a5c122c76ceb3d77088ea3f3edf0 Mon Sep 17 00:00:00 2001 From: Duncan Sommerville Date: Thu, 21 May 2015 10:17:05 -0400 Subject: [PATCH 15/15] Changed Preferences and Stream Settings pages to use new-style csrf token generation --- .../controllers/PreferenceController.php | 11 ++++++++--- airtime_mvc/application/forms/Preferences.php | 17 +++++++++++------ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/airtime_mvc/application/controllers/PreferenceController.php b/airtime_mvc/application/controllers/PreferenceController.php index 1a67b556d..3e7618e9f 100644 --- a/airtime_mvc/application/controllers/PreferenceController.php +++ b/airtime_mvc/application/controllers/PreferenceController.php @@ -181,9 +181,14 @@ class PreferenceController extends Zend_Controller_Action $num_of_stream = intval(Application_Model_Preference::GetNumOfStreams()); $form = new Application_Form_StreamSetting(); - $form->addElement('hash', 'csrf', array( - 'salt' => 'unique' - )); + // $form->addElement('hash', 'csrf', array( + // 'salt' => 'unique' + // )); + + $csrf_namespace = new Zend_Session_Namespace('csrf_namespace'); + $csrf_element = new Zend_Form_Element_Hidden('csrf'); + $csrf_element->setValue($csrf_namespace->authtoken)->setRequired('true')->removeDecorator('HtmlTag')->removeDecorator('Label'); + $form->addElement($csrf_element); $form->setSetting($setting); $form->startFrom(); diff --git a/airtime_mvc/application/forms/Preferences.php b/airtime_mvc/application/forms/Preferences.php index 7973e6ddb..d410ed3c6 100644 --- a/airtime_mvc/application/forms/Preferences.php +++ b/airtime_mvc/application/forms/Preferences.php @@ -12,12 +12,17 @@ class Application_Form_Preferences extends Zend_Form $general_pref = new Application_Form_GeneralPreferences(); - $this->addElement('hash', 'csrf', array( - 'salt' => 'unique', - 'decorators' => array( - 'ViewHelper' - ) - )); + // $this->addElement('hash', 'csrf', array( + // 'salt' => 'unique', + // 'decorators' => array( + // 'ViewHelper' + // ) + // )); + + $csrf_namespace = new Zend_Session_Namespace('csrf_namespace'); + $csrf_element = new Zend_Form_Element_Hidden('csrf'); + $csrf_element->setValue($csrf_namespace->authtoken)->setRequired('true')->removeDecorator('HtmlTag')->removeDecorator('Label'); + $this->addElement($csrf_element); $this->addSubForm($general_pref, 'preferences_general');