2013-05-27 19:45:33 +00:00
|
|
|
define([
|
|
|
|
"jquery",
|
|
|
|
"underscore",
|
|
|
|
"core",
|
|
|
|
"extension-manager",
|
|
|
|
"async-runner"
|
|
|
|
], function($, _, core, extensionMgr, asyncRunner) {
|
2013-04-07 15:22:13 +00:00
|
|
|
|
2013-05-29 19:55:23 +00:00
|
|
|
var client = undefined;
|
|
|
|
var authenticated = false;
|
2013-04-07 15:22:13 +00:00
|
|
|
|
2013-05-29 19:55:23 +00:00
|
|
|
var dropboxHelper = {};
|
2013-04-07 15:22:13 +00:00
|
|
|
|
2013-05-29 19:55:23 +00:00
|
|
|
// Try to connect dropbox by downloading client.js
|
|
|
|
function connect(task) {
|
|
|
|
task.onRun(function() {
|
|
|
|
if(core.isOffline === true) {
|
|
|
|
client = undefined;
|
|
|
|
task.error(new Error("Operation not available in offline mode.|stopPublish"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(client !== undefined) {
|
|
|
|
task.chain();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
$.ajax({
|
|
|
|
url: "lib/dropbox.min.js",
|
|
|
|
dataType: "script",
|
|
|
|
timeout: AJAX_TIMEOUT
|
|
|
|
}).done(function() {
|
|
|
|
client = new Dropbox.Client({
|
|
|
|
key: DROPBOX_APP_KEY,
|
|
|
|
secret: DROPBOX_APP_SECRET
|
|
|
|
});
|
|
|
|
client.authDriver(new Dropbox.Drivers.Popup({
|
|
|
|
receiverUrl: BASE_URL + "dropbox-oauth-receiver.html",
|
|
|
|
rememberUser: true
|
|
|
|
}));
|
|
|
|
task.chain();
|
|
|
|
}).fail(function(jqXHR) {
|
|
|
|
var error = {
|
|
|
|
status: jqXHR.status,
|
|
|
|
responseText: jqXHR.statusText
|
|
|
|
};
|
|
|
|
handleError(error, task);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
2013-04-07 15:22:13 +00:00
|
|
|
|
2013-05-29 19:55:23 +00:00
|
|
|
// Try to authenticate with Oauth
|
|
|
|
function authenticate(task) {
|
|
|
|
task.onRun(function() {
|
|
|
|
if(authenticated === true) {
|
|
|
|
task.chain();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var immediate = true;
|
|
|
|
function localAuthenticate() {
|
|
|
|
if(immediate === false) {
|
|
|
|
extensionMgr.onMessage("Please make sure the Dropbox authorization popup is not blocked by your browser.");
|
|
|
|
// If not immediate we add time for user to enter his
|
|
|
|
// credentials
|
|
|
|
task.timeout = ASYNC_TASK_LONG_TIMEOUT;
|
|
|
|
}
|
|
|
|
client.reset();
|
|
|
|
client.authenticate({
|
|
|
|
interactive: !immediate
|
|
|
|
}, function(error, client) {
|
|
|
|
// Success
|
|
|
|
if(client.authState === Dropbox.Client.DONE) {
|
|
|
|
authenticated = true;
|
|
|
|
task.chain();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// If immediate did not work retry without immediate flag
|
|
|
|
if(immediate === true) {
|
|
|
|
immediate = false;
|
|
|
|
task.chain(localAuthenticate);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Error
|
|
|
|
task.error(new Error("Access to Dropbox account is not authorized."));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
task.chain(localAuthenticate);
|
|
|
|
});
|
|
|
|
}
|
2013-04-07 15:22:13 +00:00
|
|
|
|
2013-05-29 19:55:23 +00:00
|
|
|
dropboxHelper.upload = function(path, content, callback) {
|
|
|
|
var result = undefined;
|
|
|
|
var task = asyncRunner.createTask();
|
|
|
|
connect(task);
|
|
|
|
authenticate(task);
|
|
|
|
task.onRun(function() {
|
|
|
|
client.writeFile(path, content, function(error, stat) {
|
|
|
|
if(!error) {
|
|
|
|
result = stat;
|
|
|
|
task.chain();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Handle error
|
|
|
|
if(error.status === 400) {
|
|
|
|
error = 'Could not upload document into path "' + path + '".';
|
|
|
|
}
|
|
|
|
handleError(error, task);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
task.onSuccess(function() {
|
|
|
|
callback(undefined, result);
|
|
|
|
});
|
|
|
|
task.onError(function(error) {
|
|
|
|
callback(error);
|
|
|
|
});
|
|
|
|
asyncRunner.addTask(task);
|
|
|
|
};
|
2013-04-07 15:22:13 +00:00
|
|
|
|
2013-05-29 19:55:23 +00:00
|
|
|
dropboxHelper.checkChanges = function(lastChangeId, callback) {
|
|
|
|
var changes = [];
|
|
|
|
var newChangeId = lastChangeId || 0;
|
|
|
|
var task = asyncRunner.createTask();
|
|
|
|
connect(task);
|
|
|
|
authenticate(task);
|
|
|
|
task.onRun(function() {
|
|
|
|
function retrievePageOfChanges() {
|
|
|
|
client.pullChanges(newChangeId, function(error, pullChanges) {
|
|
|
|
if(error) {
|
|
|
|
handleError(error, task);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Retrieve success
|
|
|
|
newChangeId = pullChanges.cursor();
|
|
|
|
if(pullChanges.changes !== undefined) {
|
|
|
|
changes = changes.concat(pullChanges.changes);
|
|
|
|
}
|
|
|
|
if(pullChanges.shouldPullAgain) {
|
|
|
|
task.chain(retrievePageOfChanges);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
task.chain();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
task.chain(retrievePageOfChanges);
|
|
|
|
});
|
|
|
|
task.onSuccess(function() {
|
|
|
|
callback(undefined, changes, newChangeId);
|
|
|
|
});
|
|
|
|
task.onError(function(error) {
|
|
|
|
callback(error);
|
|
|
|
});
|
|
|
|
asyncRunner.addTask(task);
|
|
|
|
};
|
2013-04-07 15:22:13 +00:00
|
|
|
|
2013-05-29 19:55:23 +00:00
|
|
|
dropboxHelper.downloadMetadata = function(paths, callback) {
|
|
|
|
var result = [];
|
|
|
|
var task = asyncRunner.createTask();
|
|
|
|
connect(task);
|
|
|
|
authenticate(task);
|
|
|
|
task.onRun(function() {
|
|
|
|
function recursiveDownloadMetadata() {
|
|
|
|
if(paths.length === 0) {
|
|
|
|
task.chain();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var path = paths[0];
|
|
|
|
client.stat(path, function(error, stat) {
|
|
|
|
if(stat) {
|
|
|
|
result.push(stat);
|
|
|
|
paths.shift();
|
|
|
|
task.chain(recursiveDownloadMetadata);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
handleError(error, task);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
task.chain(recursiveDownloadMetadata);
|
|
|
|
});
|
|
|
|
task.onSuccess(function() {
|
|
|
|
callback(undefined, result);
|
|
|
|
});
|
|
|
|
task.onError(function(error) {
|
|
|
|
callback(error);
|
|
|
|
});
|
|
|
|
asyncRunner.addTask(task);
|
|
|
|
};
|
2013-04-07 15:22:13 +00:00
|
|
|
|
2013-05-29 19:55:23 +00:00
|
|
|
dropboxHelper.downloadContent = function(objects, callback) {
|
|
|
|
var result = [];
|
|
|
|
var task = asyncRunner.createTask();
|
|
|
|
connect(task);
|
|
|
|
authenticate(task);
|
|
|
|
task.onRun(function() {
|
|
|
|
function recursiveDownloadContent() {
|
|
|
|
if(objects.length === 0) {
|
|
|
|
task.chain();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var object = objects[0];
|
|
|
|
result.push(object);
|
|
|
|
var file = undefined;
|
|
|
|
// object may be a file
|
|
|
|
if(object.isFile === true) {
|
|
|
|
file = object;
|
|
|
|
}
|
|
|
|
// object may be a change
|
|
|
|
else if(object.wasRemoved !== undefined) {
|
|
|
|
file = object.stat;
|
|
|
|
}
|
|
|
|
if(!file) {
|
|
|
|
objects.shift();
|
|
|
|
task.chain(recursiveDownloadContent);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
client.readFile(file.path, function(error, data) {
|
|
|
|
if(data) {
|
|
|
|
file.content = data;
|
|
|
|
objects.shift();
|
|
|
|
task.chain(recursiveDownloadContent);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
handleError(error, task);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
task.chain(recursiveDownloadContent);
|
|
|
|
});
|
|
|
|
task.onSuccess(function() {
|
|
|
|
callback(undefined, result);
|
|
|
|
});
|
|
|
|
task.onError(function(error) {
|
|
|
|
callback(error);
|
|
|
|
});
|
|
|
|
asyncRunner.addTask(task);
|
|
|
|
};
|
2013-04-27 23:16:38 +00:00
|
|
|
|
2013-05-29 19:55:23 +00:00
|
|
|
function handleError(error, task) {
|
|
|
|
var errorMsg = true;
|
|
|
|
if(error) {
|
|
|
|
logger.error(error);
|
|
|
|
// Try to analyze the error
|
|
|
|
if(typeof error === "string") {
|
|
|
|
errorMsg = error;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
errorMsg = "Dropbox error (" + error.status + ": " + error.responseText + ").";
|
2013-04-07 15:22:13 +00:00
|
|
|
|
2013-05-29 19:55:23 +00:00
|
|
|
if(error.status === 401 || error.status === 403) {
|
|
|
|
authenticated = false;
|
|
|
|
errorMsg = "Access to Dropbox account is not authorized.";
|
|
|
|
task.retry(new Error(errorMsg), 1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if(error.status === 400 && error.responseText.indexOf("oauth_nonce") !== -1) {
|
|
|
|
// A bug I guess...
|
|
|
|
_.each(_.keys(localStorage), function(key) {
|
|
|
|
// We have to remove the Oauth cache from the
|
|
|
|
// localStorage
|
|
|
|
if(key.indexOf("dropbox-auth") === 0) {
|
|
|
|
localStorage.removeItem(key);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
authenticated = false;
|
|
|
|
task.retry(new Error(errorMsg), 1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if(error.status <= 0) {
|
|
|
|
client = undefined;
|
|
|
|
authenticated = false;
|
|
|
|
core.setOffline();
|
|
|
|
errorMsg = "|stopPublish";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
task.error(new Error(errorMsg));
|
|
|
|
}
|
|
|
|
|
|
|
|
var pickerLoaded = false;
|
|
|
|
function loadPicker(task) {
|
|
|
|
task.onRun(function() {
|
|
|
|
if(pickerLoaded === true) {
|
|
|
|
task.chain();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
$.ajax({
|
|
|
|
url: "https://www.dropbox.com/static/api/1/dropbox.js",
|
|
|
|
dataType: "script",
|
|
|
|
timeout: AJAX_TIMEOUT
|
|
|
|
}).done(function() {
|
|
|
|
pickerLoaded = true;
|
|
|
|
task.chain();
|
|
|
|
}).fail(function(jqXHR) {
|
|
|
|
var error = {
|
|
|
|
status: jqXHR.status,
|
|
|
|
responseText: jqXHR.statusText
|
|
|
|
};
|
|
|
|
handleError(error, task);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
dropboxHelper.picker = function(callback) {
|
|
|
|
var paths = [];
|
|
|
|
var task = asyncRunner.createTask();
|
|
|
|
// Add some time for user to choose his files
|
|
|
|
task.timeout = ASYNC_TASK_LONG_TIMEOUT;
|
|
|
|
connect(task);
|
|
|
|
loadPicker(task);
|
|
|
|
task.onRun(function() {
|
|
|
|
var options = {};
|
|
|
|
options.multiselect = true;
|
|
|
|
options.linkType = "direct";
|
|
|
|
options.success = function(files) {
|
|
|
|
for ( var i = 0; i < files.length; i++) {
|
|
|
|
var path = files[i].link;
|
|
|
|
path = path.replace(/.*\/view\/[^\/]*/, "");
|
|
|
|
paths.push(decodeURI(path));
|
|
|
|
}
|
|
|
|
task.chain();
|
2013-04-20 00:14:20 +00:00
|
|
|
};
|
|
|
|
options.cancel = function() {
|
2013-05-29 19:55:23 +00:00
|
|
|
task.chain();
|
2013-04-20 00:14:20 +00:00
|
|
|
};
|
2013-05-29 19:55:23 +00:00
|
|
|
Dropbox.choose(options);
|
|
|
|
extensionMgr.onMessage("Please make sure the Dropbox chooser popup is not blocked by your browser.");
|
|
|
|
});
|
|
|
|
task.onSuccess(function() {
|
|
|
|
callback(undefined, paths);
|
|
|
|
});
|
|
|
|
task.onError(function(error) {
|
|
|
|
callback(error);
|
|
|
|
});
|
|
|
|
asyncRunner.addTask(task);
|
|
|
|
};
|
2013-04-07 15:22:13 +00:00
|
|
|
|
2013-05-29 19:55:23 +00:00
|
|
|
return dropboxHelper;
|
2013-04-07 15:22:13 +00:00
|
|
|
});
|