From f9ace200757029456f307184153ab49cbf915c9c Mon Sep 17 00:00:00 2001 From: Duncan Sommerville Date: Mon, 21 Sep 2015 17:03:46 -0400 Subject: [PATCH] Simplify third-party/celery/soundcloud implementation --- .../application/common/CeleryManager.php | 7 +- airtime_mvc/application/configs/constants.php | 5 + .../controllers/LocaleController.php | 4 + .../services/SoundcloudService.php | 102 ++++++++++++------ .../services/ThirdPartyCeleryService.php | 99 +++-------------- .../services/ThirdPartyService.php | 59 ---------- .../public/js/airtime/library/library.js | 7 +- 7 files changed, 100 insertions(+), 183 deletions(-) diff --git a/airtime_mvc/application/common/CeleryManager.php b/airtime_mvc/application/common/CeleryManager.php index 07ab7fa42..d2c41d79d 100644 --- a/airtime_mvc/application/common/CeleryManager.php +++ b/airtime_mvc/application/common/CeleryManager.php @@ -182,12 +182,7 @@ class CeleryManager { protected static function _processTaskMessage($task, $message) { $ref = $task->getThirdPartyTrackReferences(); // ThirdPartyTrackReferences join $service = CeleryServiceFactory::getService($ref->getDbService()); - if ($message->status == CELERY_SUCCESS_STATUS - && $task->getDbName() == $service->getCeleryDeleteTaskName()) { - $service->removeTrackReference($ref->getDbFileId()); - } else { - $service->updateTrackReference($ref->getDbId(), json_decode($message->result), $message->status); - } + $service->updateTrackReference($task, $ref->getDbId(), json_decode($message->result), $message->status); } /** diff --git a/airtime_mvc/application/configs/constants.php b/airtime_mvc/application/configs/constants.php index 868e4d5ca..e1863d49c 100644 --- a/airtime_mvc/application/configs/constants.php +++ b/airtime_mvc/application/configs/constants.php @@ -122,6 +122,11 @@ define('CELERY_FAILED_STATUS', 'FAILED'); // Celery Services define('SOUNDCLOUD_SERVICE_NAME', 'soundcloud'); +// Celery Task Types +define('UPLOAD', 'upload'); +define('DOWNLOAD', 'download'); +define('DELETE', 'delete'); + // Podcast Types define('STATION_PODCAST', 0); define('IMPORTED_PODCAST', 1); diff --git a/airtime_mvc/application/controllers/LocaleController.php b/airtime_mvc/application/controllers/LocaleController.php index 81cebc183..41c7cd2e9 100644 --- a/airtime_mvc/application/controllers/LocaleController.php +++ b/airtime_mvc/application/controllers/LocaleController.php @@ -108,6 +108,10 @@ class LocaleController extends Zend_Controller_Action "Are you sure you want to delete the selected item?" => _("Are you sure you want to delete the selected item?"), "Uploading in progress..." => _("Uploading in progress..."), "Retrieving data from the server..." => _("Retrieving data from the server..."), + // SOUNDCLOUD + "Are you sure? SoundCloud stats and comments for this track will be permanently removed." => "Are you sure? SoundCloud stats and comments for this track will be permanently removed.", + "Your track is being deleted from SoundCloud" => "Your track is being deleted from SoundCloud", + "Your track is being uploaded and will appear on SoundCloud in a couple of minutes" => "Your track is being uploaded and will appear on SoundCloud in a couple of minutes", "The soundcloud id for this file is: " => _("The soundcloud id for this file is: "), "There was an error while uploading to soundcloud." => _("There was an error while uploading to soundcloud."), "Error code: " => _("Error code: "), diff --git a/airtime_mvc/application/services/SoundcloudService.php b/airtime_mvc/application/services/SoundcloudService.php index aba8d2b98..a7c647a6c 100644 --- a/airtime_mvc/application/services/SoundcloudService.php +++ b/airtime_mvc/application/services/SoundcloudService.php @@ -25,20 +25,11 @@ class Application_Service_SoundcloudService extends Application_Service_ThirdPar */ protected static $_CELERY_EXCHANGE_NAME = 'soundcloud'; - /** - * @var string celery task name for third party uploads - */ - protected static $_CELERY_UPLOAD_TASK_NAME = 'soundcloud-upload'; - - /** - * @var string celery task name for third party uploads - */ - protected static $_CELERY_DOWNLOAD_TASK_NAME = 'soundcloud-download'; - - /** - * @var string celery task name for third party deletions - */ - protected static $_CELERY_DELETE_TASK_NAME = 'soundcloud-delete'; + protected static $_CELERY_TASKS = [ + UPLOAD => 'soundcloud-upload', + DOWNLOAD => 'soundcloud-download', + DELETE => 'soundcloud-delete' + ]; /** * @var array Application_Model_Preference functions for SoundCloud and their @@ -66,18 +57,6 @@ class Application_Service_SoundcloudService extends Application_Service_ThirdPar } } - /** - * Given a SoundCloud track identifier, download a track from SoundCloud. - * - * If no track identifier is given, download all tracks for the currently - * authenticated SoundCloud user. - * - * @param int|null $trackId a SoundCloud track identifier - */ - public function download($trackId = null) { - parent::download($trackId); - } - /** * Build a parameter array for the track being uploaded to SoundCloud * @@ -126,20 +105,76 @@ class Application_Service_SoundcloudService extends Application_Service_ThirdPar return $trackArray; } + /** + * Upload the file with the given identifier to SoundCloud + * + * @param int $fileId the local CcFiles identifier + */ + public function upload($fileId) { + $file = Application_Model_StoredFile::RecallById($fileId); + $data = array( + 'data' => $this->_getUploadData($file), + 'token' => $this->_accessToken, + 'file_path' => $file->getFilePaths()[0] + ); + $this->_executeTask(static::$_CELERY_TASKS[UPLOAD], $data, $fileId); + } + + /** + * Given a track identifier, download a track from SoundCloud + * + * If no identifier is given, download all the user's tracks + * + * @param int $trackId a track identifier + */ + public function download($trackId = null) { + $namespace = new Zend_Session_Namespace('csrf_namespace'); + $csrfToken = $namespace->authtoken; + $data = array( + 'callback_url' => 'http' . (empty($_SERVER['HTTPS']) ? '' : 's') . '://' . $_SERVER['HTTP_HOST'] . '/media/post?csrf_token=' . $csrfToken, + 'token' => $this->_accessToken, + 'track_id' => $trackId + ); + // FIXME + Logging::warn("FIXME: we can't create a task reference without a valid file ID"); + $this->_executeTask(static::$_CELERY_TASKS[DOWNLOAD], $data, null); + } + + /** + * Delete the file with the given identifier from SoundCloud + * + * @param int $fileId the local CcFiles identifier + * + * @throws ServiceNotFoundException when a $fileId with no corresponding + * service identifier is given + */ + public function delete($fileId) { + $serviceId = $this->getServiceId($fileId); + if ($serviceId == 0) { + throw new ServiceNotFoundException("No service ID found for file with ID $fileId"); + } + $data = array( + 'token' => $this->_accessToken, + 'track_id' => $serviceId + ); + $this->_executeTask(static::$_CELERY_TASKS[DELETE], $data, $fileId); + } + /** * Update a ThirdPartyTrackReferences object for a completed upload * * TODO: should we have a database layer class to handle Propel operations? * - * @param $trackId int ThirdPartyTrackReferences identifier - * @param $track object third-party service track object - * @param $status string Celery task status + * @param $task CeleryTasks the completed CeleryTasks object + * @param $trackId int ThirdPartyTrackReferences identifier + * @param $track object third-party service track object + * @param $status string Celery task status * * @throws Exception * @throws PropelException */ - public function updateTrackReference($trackId, $track, $status) { - parent::updateTrackReference($trackId, $track, $status); + public function updateTrackReference($task, $trackId, $track, $status) { + parent::updateTask($task, $status); $ref = ThirdPartyTrackReferencesQuery::create() ->findOneByDbId($trackId); if (is_null($ref)) { @@ -148,6 +183,11 @@ class Application_Service_SoundcloudService extends Application_Service_ThirdPar $ref->setDbService(static::$_SERVICE_NAME); // Only set the SoundCloud fields if the task was successful if ($status == CELERY_SUCCESS_STATUS) { + // If the task was to delete the file from SoundCloud, remove the reference + if ($task->getDbName() == static::$_CELERY_TASKS[DELETE]) { + $this->removeTrackReference($ref->getDbFileId()); + return; + } $utc = new DateTimeZone("UTC"); $ref->setDbUploadTime(new DateTime("now", $utc)); // TODO: fetch any additional SoundCloud parameters we want to store diff --git a/airtime_mvc/application/services/ThirdPartyCeleryService.php b/airtime_mvc/application/services/ThirdPartyCeleryService.php index 8ecf512ff..434841de3 100644 --- a/airtime_mvc/application/services/ThirdPartyCeleryService.php +++ b/airtime_mvc/application/services/ThirdPartyCeleryService.php @@ -10,19 +10,9 @@ abstract class Application_Service_ThirdPartyCeleryService extends Application_S protected static $_CELERY_EXCHANGE_NAME; /** - * @var string celery task name for third-party uploads + * @var array map of celery identifiers to their task names */ - protected static $_CELERY_UPLOAD_TASK_NAME; - - /** - * @var string celery task name for third-party uploads - */ - protected static $_CELERY_DOWNLOAD_TASK_NAME; - - /** - * @var string celery task name for third-party deletion - */ - protected static $_CELERY_DELETE_TASK_NAME; + protected static $_CELERY_TASKS; /** * Execute a Celery task with the given name and data parameters @@ -48,59 +38,6 @@ abstract class Application_Service_ThirdPartyCeleryService extends Application_S } } - /** - * Upload the file with the given identifier to a third-party service - * - * @param int $fileId the local CcFiles identifier - */ - public function upload($fileId) { - $file = Application_Model_StoredFile::RecallById($fileId); - $data = array( - 'data' => $this->_getUploadData($file), - 'token' => $this->_accessToken, - 'file_path' => $file->getFilePaths()[0] - ); - $this->_executeTask(static::$_CELERY_UPLOAD_TASK_NAME, $data, $fileId); - } - - /** - * Given a track identifier, download a track from a third-party service. - * - * @param int $trackId a track identifier - */ - public function download($trackId) { - $namespace = new Zend_Session_Namespace('csrf_namespace'); - $csrfToken = $namespace->authtoken; - $data = array( - 'callback_url' => 'http' . (empty($_SERVER['HTTPS']) ? '' : 's') . '://' . $_SERVER['HTTP_HOST'] . '/media/post?csrf_token=' . $csrfToken, - 'token' => $this->_accessToken, - 'track_id' => $trackId - ); - // FIXME - Logging::warn("FIXME: we can't create a task reference without a valid file ID"); - $this->_executeTask(static::$_CELERY_DOWNLOAD_TASK_NAME, $data, null); - } - - /** - * Delete the file with the given identifier from a third-party service - * - * @param int $fileId the local CcFiles identifier - * - * @throws ServiceNotFoundException when a $fileId with no corresponding - * service identifier is given - */ - public function delete($fileId) { - $serviceId = $this->getServiceId($fileId); - if ($serviceId == 0) { - throw new ServiceNotFoundException("No service ID found for file with ID $fileId"); - } - $data = array( - 'token' => $this->_accessToken, - 'track_id' => $serviceId - ); - $this->_executeTask(static::$_CELERY_DELETE_TASK_NAME, $data, $fileId); - } - /** * Create a CeleryTasks object for a pending task * TODO: should we have a database layer class to handle Propel operations? @@ -129,36 +66,28 @@ abstract class Application_Service_ThirdPartyCeleryService extends Application_S * Update a CeleryTasks object for a completed task * TODO: should we have a database layer class to handle Propel operations? * - * @param $trackId int ThirdPartyTrackReferences identifier - * @param $track object third-party service track object - * @param $status string Celery task status + * @param $task CeleryTasks the completed CeleryTasks object + * @param $status string Celery task status * * @throws Exception * @throws PropelException */ - public function updateTrackReference($trackId, $track, $status) { - $task = CeleryTasksQuery::create() - ->findOneByDbTrackReference($trackId); + public function updateTask($task, $status) { $task->setDbStatus($status); $task->save(); } /** - * Field accessor for $_CELERY_DELETE_TASK_NAME + * Update a ThirdPartyTrackReferences object for a completed upload * - * @return string the Celery task name for deleting tracks from this service + * @param $task CeleryTasks the completed CeleryTasks object + * @param $trackId int ThirdPartyTrackReferences identifier + * @param $track object third-party service track object + * @param $status string Celery task status + * + * @throws Exception + * @throws PropelException */ - public function getCeleryDeleteTaskName() { - return static::$_CELERY_DELETE_TASK_NAME; - } - - /** - * Build a parameter array for the file being uploaded to a third party service - * - * @param $file Application_Model_StoredFile the file being uploaded - * - * @return array the track array to send to the third party service - */ - abstract protected function _getUploadData($file); + abstract function updateTrackReference($task, $trackId, $track, $status); } \ No newline at end of file diff --git a/airtime_mvc/application/services/ThirdPartyService.php b/airtime_mvc/application/services/ThirdPartyService.php index 466838db5..b5600c7bd 100644 --- a/airtime_mvc/application/services/ThirdPartyService.php +++ b/airtime_mvc/application/services/ThirdPartyService.php @@ -10,21 +10,11 @@ class ServiceNotFoundException extends Exception {} */ abstract class Application_Service_ThirdPartyService { - /** - * @var string service access token for accessing third-party API - */ - protected $_accessToken; - /** * @var string service name to store in ThirdPartyTrackReferences database */ protected static $_SERVICE_NAME; - /** - * @var string base URI for third-party tracks - */ - protected static $_THIRD_PARTY_TRACK_URI; - /** * Create a ThirdPartyTrackReferences object for a track that's been uploaded * to an external service @@ -104,53 +94,4 @@ abstract class Application_Service_ThirdPartyService { return false; } - /** - * Given a CcFiles identifier for a file that's been uploaded to a third-party service, - * return a link to the remote file - * - * @param int $fileId the cc_files identifier - * - * @return string the link to the remote file - */ - public function getLinkToFile($fileId) { - $serviceId = $this->getServiceId($fileId); - return empty($serviceId) ? '' : static::$_THIRD_PARTY_TRACK_URI . $serviceId; - } - - /** - * Upload the file with the given identifier to a third-party service - * - * @param int $fileId the cc_files identifier - */ - abstract function upload($fileId); - - /** - * Download the file with the given identifier from a third-party service - * - * @param int $trackId the third-party service track identifier - */ - abstract function download($trackId); - - /** - * Delete the file with the given identifier from a third-party service - * - * @param int $fileId the cc_files identifier - * - * @throws ServiceNotFoundException when a $fileId with no corresponding - * service identifier is given - */ - abstract function delete($fileId); - - /** - * Update a ThirdPartyTrackReferences object for a completed task - * - * @param $trackId int ThirdPartyTrackReferences identifier - * @param $track object third-party service track object - * @param $status string Celery task status - * - * @throws Exception - * @throws PropelException - */ - abstract function updateTrackReference($trackId, $track, $status); - } \ No newline at end of file diff --git a/airtime_mvc/public/js/airtime/library/library.js b/airtime_mvc/public/js/airtime/library/library.js index 003e82824..67ee7fc67 100644 --- a/airtime_mvc/public/js/airtime/library/library.js +++ b/airtime_mvc/public/js/airtime/library/library.js @@ -1199,8 +1199,11 @@ var AIRTIME = (function(AIRTIME) { if (soundcloud.remove !== undefined) { callback = function() { - alert($.i18n._("Your track is being deleted from SoundCloud")); - $.post(soundcloud.remove.url, function(){}); + if (confirm($.i18n._("Are you sure? SoundCloud stats and comments for this track will be permanently removed."))) { + alert($.i18n._("Your track is being deleted from SoundCloud")); + $.post(soundcloud.remove.url, function () { + }); + } }; soundcloud.remove.callback = callback; }