Fix SoundCloud and TaskManager bugs, switch tasks to use acks_late, and provide feedback from SoundCloud context menu items

This commit is contained in:
Duncan Sommerville 2015-06-18 18:18:48 -04:00
parent 17983167ed
commit 76a7aa9a24
6 changed files with 50 additions and 10 deletions

View File

@ -22,7 +22,7 @@ final class TaskManager {
* @var int TASK_INTERVAL_SECONDS how often, in seconds, to run the TaskManager tasks, * @var int TASK_INTERVAL_SECONDS how often, in seconds, to run the TaskManager tasks,
* if they need to be run * if they need to be run
*/ */
const TASK_INTERVAL_SECONDS = 60; const TASK_INTERVAL_SECONDS = 30;
/** /**
* @var $con PDO Propel connection object * @var $con PDO Propel connection object
@ -67,6 +67,11 @@ final class TaskManager {
try { try {
$lock = $this->_getLock(); $lock = $this->_getLock();
if ($lock && microtime(true) < $lock['valstr'] + self::TASK_INTERVAL_SECONDS) { if ($lock && microtime(true) < $lock['valstr'] + self::TASK_INTERVAL_SECONDS) {
// Fun fact: Propel caches the database connection and uses it persistently
// (thus why calling Propel::getConnection explicitly and passing a connection
// parameter is often not necessary when making Propel queries). Long story short,
// if we don't use commit() here, we end up blocking other queries made within this request
$this->_con->commit();
return; return;
} }
$this->_updateLock($lock); $this->_updateLock($lock);

View File

@ -278,9 +278,17 @@ class LibraryController extends Zend_Controller_Action
$serviceId = $soundcloudService->getServiceId($id); $serviceId = $soundcloudService->getServiceId($id);
if (!is_null($file) && $serviceId != 0) { if (!is_null($file) && $serviceId != 0) {
$menu["soundcloud"]["items"]["view"] = array("name" => _("View track"), "icon" => "soundcloud", "url" => $baseUrl."soundcloud/view-on-sound-cloud/id/{$id}"); $menu["soundcloud"]["items"]["view"] = array("name" => _("View track"), "icon" => "soundcloud", "url" => $baseUrl."soundcloud/view-on-sound-cloud/id/{$id}");
$menu["soundcloud"]["items"]["upload"] = array("name" => _("Remove track"), "icon" => "soundcloud", "url" => $baseUrl."soundcloud/delete/id/{$id}"); $menu["soundcloud"]["items"]["remove"] = array("name" => _("Remove track"), "icon" => "soundcloud", "url" => $baseUrl."soundcloud/delete/id/{$id}");
} else { } else {
$menu["soundcloud"]["items"]["upload"] = array("name" => _("Upload track"), "icon" => "soundcloud", "url" => $baseUrl."soundcloud/upload/id/{$id}"); // If a reference exists for this file ID, that means the user has uploaded the track
// but we haven't yet gotten a response from Celery, so disable the menu item
if ($soundcloudService->referenceExists($id)) {
$menu["soundcloud"]["items"]["upload"] = array("name" => _("Upload track"), "icon" => "soundcloud",
"url" => $baseUrl."soundcloud/upload/id/{$id}", "disabled" => true);
} else {
$menu["soundcloud"]["items"]["upload"] = array("name" => _("Upload track"), "icon" => "soundcloud",
"url" => $baseUrl."soundcloud/upload/id/{$id}");
}
} }
} }

View File

@ -74,6 +74,8 @@ class CcFiles extends BaseCcFiles {
/** Used to create a CcFiles object from an array containing metadata and a file uploaded by POST. /** Used to create a CcFiles object from an array containing metadata and a file uploaded by POST.
* This is used by our Media REST API! * This is used by our Media REST API!
* @param $fileArray An array containing metadata for a CcFiles object. * @param $fileArray An array containing metadata for a CcFiles object.
*
* @return object the sanitized response
* @throws Exception * @throws Exception
*/ */
public static function createFromUpload($fileArray) public static function createFromUpload($fileArray)
@ -94,7 +96,7 @@ class CcFiles extends BaseCcFiles {
$tempFilePath = $_FILES['file']['tmp_name']; $tempFilePath = $_FILES['file']['tmp_name'];
try { try {
self::createAndImport($fileArray, $tempFilePath, $originalFilename); return self::createAndImport($fileArray, $tempFilePath, $originalFilename);
} catch (Exception $e) { } catch (Exception $e) {
if (file_exists($tempFilePath)) { if (file_exists($tempFilePath)) {
unlink($tempFilePath); unlink($tempFilePath);

View File

@ -74,7 +74,7 @@ abstract class ThirdPartyService {
* Given a CcFiles identifier for a file that's been uploaded to a third-party service, * Given a CcFiles identifier for a file that's been uploaded to a third-party service,
* return the third-party identifier for the remote file * return the third-party identifier for the remote file
* *
* @param int $fileId the local CcFiles identifier * @param int $fileId the cc_files identifier
* *
* @return string the service foreign identifier * @return string the service foreign identifier
*/ */
@ -85,11 +85,25 @@ abstract class ThirdPartyService {
return empty($ref) ? '' : $ref->getDbForeignId(); return empty($ref) ? '' : $ref->getDbForeignId();
} }
/**
* Check if a reference exists for a given CcFiles identifier
*
* @param int $fileId the cc_files identifier
*
* @return string the service foreign identifier
*/
public function referenceExists($fileId) {
$ref = ThirdPartyTrackReferencesQuery::create()
->filterByDbService(static::$_SERVICE_NAME)
->findOneByDbFileId($fileId); // There shouldn't be duplicates!
return !empty($ref);
}
/** /**
* Given a CcFiles identifier for a file that's been uploaded to a third-party service, * Given a CcFiles identifier for a file that's been uploaded to a third-party service,
* return a link to the remote file * return a link to the remote file
* *
* @param int $fileId CcFiles identifier * @param int $fileId the cc_files identifier
* *
* @return string the link to the remote file * @return string the link to the remote file
*/ */
@ -101,14 +115,14 @@ abstract class ThirdPartyService {
/** /**
* Upload the file with the given identifier to a third-party service * Upload the file with the given identifier to a third-party service
* *
* @param int $fileId CcFiles identifier * @param int $fileId the cc_files identifier
*/ */
abstract function upload($fileId); abstract function upload($fileId);
/** /**
* Delete the file with the given identifier from a third-party service * Delete the file with the given identifier from a third-party service
* *
* @param int $fileId the local CcFiles identifier * @param int $fileId the cc_files identifier
* *
* @throws ServiceNotFoundException when a $fileId with no corresponding * @throws ServiceNotFoundException when a $fileId with no corresponding
* service identifier is given * service identifier is given

View File

@ -1016,11 +1016,22 @@ var AIRTIME = (function(AIRTIME) {
if (soundcloud.upload !== undefined) { if (soundcloud.upload !== undefined) {
callback = function() { callback = function() {
alert($.i18n._("Your track is being uploaded to SoundCloud"));
$.post(soundcloud.upload.url, function(){}); $.post(soundcloud.upload.url, function(){});
}; };
soundcloud.upload.callback = callback; soundcloud.upload.callback = callback;
} }
// define an upload to soundcloud callback.
if (soundcloud.remove !== undefined) {
callback = function() {
alert($.i18n._("Your track is being deleted from SoundCloud"));
$.post(soundcloud.remove.url, function(){});
};
soundcloud.remove.callback = callback;
}
// define a view on soundcloud callback // define a view on soundcloud callback
if (soundcloud.view !== undefined) { if (soundcloud.view !== undefined) {

View File

@ -9,7 +9,7 @@ celery = Celery()
logger = get_task_logger(__name__) logger = get_task_logger(__name__)
@celery.task(name='soundcloud-upload') @celery.task(name='soundcloud-upload', acks_late=True)
def soundcloud_upload(data, token, file_path): def soundcloud_upload(data, token, file_path):
""" """
Upload a file to SoundCloud Upload a file to SoundCloud
@ -33,7 +33,7 @@ def soundcloud_upload(data, token, file_path):
data['asset_data'].close() data['asset_data'].close()
return json.dumps(track.fields()) return json.dumps(track.fields())
@celery.task(name='soundcloud-delete') @celery.task(name='soundcloud-delete', acks_late=True)
def soundcloud_delete(token, track_id): def soundcloud_delete(token, track_id):
""" """
Delete a file from SoundCloud Delete a file from SoundCloud