Support for Dropbox publishing

This commit is contained in:
benweet 2013-04-16 16:02:24 +01:00
parent 7667b91873
commit 51ba5930af
8 changed files with 315 additions and 270 deletions

View File

@ -88,6 +88,8 @@
<ul class="dropdown-menu">
<li><a href="#" class="action-publish-blogger"><i
class="icon-blogger"></i> Blogger</a></li>
<li><a href="#" class="action-publish-dropbox"><i
class="icon-dropbox"></i> Dropbox</a></li>
<li><a href="#" class="action-publish-github"><i
class="icon-github"></i> GitHub</a></li>
</ul></li>
@ -269,7 +271,7 @@
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-hidden="true">&times;</button>
<h3 class="modal-publish-github">Publish on GitHub</h3>
<h3>Publish on <span class="publish-provider-name"></span></h3>
</div>
<div class="modal-body">
<div class="form-horizontal">
@ -311,6 +313,13 @@
placeholder="Post ID">
</div>
</div>
<div class="control-group modal-publish-dropbox">
<label class="control-label" for="input-publish-dropbox-path">File path</label>
<div class="controls">
<input type="text" id="input-publish-dropbox-path"
placeholder="/path/to/My Document.html">
</div>
</div>
<div class="control-group">
<div class="control-label">Format</div>
<div class="controls">

View File

@ -106,10 +106,16 @@ define(["underscore"], function() {
asyncTaskRunner.runTask();
};
// Change current task timeout
asyncTaskRunner.setCurrentTaskTimeout = function(timeout) {
if(currentTask !== undefined) {
currentTask.timeout = timeout;
}
};
asyncTaskRunner.init = function(coreModule) {
core = coreModule;
};
return asyncTaskRunner;
});

View File

@ -15,8 +15,9 @@ var USER_IDLE_THRESHOLD = 300000;
var SYNC_PROVIDER_GDRIVE = "sync.gdrive.";
var SYNC_PROVIDER_DROPBOX = "sync.dropbox.";
var PROVIDER_TYPE_PUBLISH_FLAG = 1;
var PROVIDER_GITHUB = "github";
var PROVIDER_BLOGGER = "blogger";
var PROVIDER_DROPBOX = "dropbox";
var PROVIDER_GITHUB = "github";
// Use by Google's client.js
var delayedFunction = undefined;

View File

@ -12,28 +12,20 @@ define(["jquery", "async-runner"], function($, asyncTaskRunner) {
// Try to connect dropbox by downloading client.js
function connect(callback) {
callback = callback || core.doNothing;
var asyncTask = {};
asyncTask.run = function() {
if(core.isOffline === true) {
client = undefined;
core.showMessage("Operation not available in offline mode.");
asyncTask.error();
return;
}
if (client !== undefined) {
asyncTask.success();
return;
}
$.ajax({
url : "lib/dropbox.min.js",
dataType : "script", timeout : AJAX_TIMEOUT
}).done(function() {
asyncTask.success();
}).fail(function() {
asyncTask.error();
});
};
asyncTask.onSuccess = function() {
if(core.isOffline === true) {
client = undefined;
core.showMessage("Operation not available in offline mode.");
callback(true);
return;
}
if (client !== undefined) {
callback();
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
@ -43,12 +35,10 @@ define(["jquery", "async-runner"], function($, asyncTaskRunner) {
rememberUser: true
}));
callback();
};
asyncTask.onError = function() {
}).fail(function() {
core.setOffline();
callback();
};
asyncTaskRunner.addTask(asyncTask);
callback(true);
});
}
// Try to authenticate with Oauth
@ -57,61 +47,51 @@ define(["jquery", "async-runner"], function($, asyncTaskRunner) {
if (immediate === undefined) {
immediate = true;
}
connect(function() {
if (client === undefined) {
connect(function(error) {
if (error) {
callback(error);
return;
}
if (authenticated === true) {
callback();
return;
}
var asyncTask = {};
asyncTask.run = function() {
if (authenticated === true) {
asyncTask.success();
if (immediate === false) {
core.showMessage("Please make sure the Dropbox authorization popup is not blocked by your browser.");
asyncTaskRunner.setCurrentTaskTimeout(AUTH_POPUP_TIMEOUT);
}
client.authenticate({interactive: !immediate}, function(error, client) {
if (client.authState === Dropbox.Client.DONE) {
callback();
return;
}
if (immediate === false) {
core.showMessage("Please make sure the Dropbox authorization popup is not blocked by your browser.");
}
client.authenticate({interactive: !immediate}, function(error, client) {
if (client.authState !== Dropbox.Client.DONE) {
// Handle error
asyncTask.error();
return;
}
asyncTask.success();
});
};
asyncTask.onSuccess = function() {
callback();
};
asyncTask.onError = function() {
// If immediate did not work retry without immediate flag
if (client !== undefined && immediate === true) {
authenticate(callback, false);
return;
}
callback();
};
asyncTaskRunner.addTask(asyncTask);
// Notify error
callback(true);
});
});
}
dropboxHelper.upload = function(path, content, callback) {
callback = callback || core.doNothing;
authenticate(function() {
if (client === undefined) {
callback();
return;
}
var syncIndex = undefined;
var asyncTask = {};
asyncTask.run = function() {
authenticate(function(error) {
if (error) {
handleError(error, asyncTask, callback);
return;
}
var fileSyncIndex = undefined;
var asyncTask = {};
asyncTask.run = function() {
client.writeFile(path, content, function(error, stat) {
if (!error) {
fileSyncIndex = SYNC_PROVIDER_DROPBOX + encodeURIComponent(stat.path.toLowerCase());
localStorage[fileSyncIndex + ".version"] = stat.versionTag;
syncIndex = SYNC_PROVIDER_DROPBOX + encodeURIComponent(stat.path.toLowerCase());
localStorage[syncIndex + ".version"] = stat.versionTag;
asyncTask.success();
return;
}
@ -121,154 +101,168 @@ define(["jquery", "async-runner"], function($, asyncTaskRunner) {
}
handleError(error, asyncTask, callback);
});
};
asyncTask.onSuccess = function() {
callback(fileSyncIndex);
};
asyncTask.onError = function() {
callback();
};
asyncTaskRunner.addTask(asyncTask);
});
});
};
asyncTask.onSuccess = function() {
callback(undefined, syncIndex);
};
asyncTask.onError = function() {
callback(true);
};
asyncTaskRunner.addTask(asyncTask);
};
dropboxHelper.checkUpdates = function(lastChangeId, callback) {
callback = callback || core.doNothing;
authenticate(function() {
if (client === undefined) {
callback();
return;
}
var changes = [];
var newChangeId = lastChangeId || 0;
var changes = [];
var newChangeId = lastChangeId || 0;
var asyncTask = {};
asyncTask.run = function() {
function retrievePageOfChanges(changeId) {
var shouldPullAgain = false;
var asyncTask = {};
asyncTask.run = function() {
client.pullChanges(changeId, function(error, pullChanges) {
if (pullChanges && pullChanges.cursorTag) {
// Retrieve success
newChangeId = pullChanges.cursor();
shouldPullAgain = pullChanges.shouldPullAgain;
if(pullChanges.changes !== undefined) {
for(var i=0; i<pullChanges.changes.length; i++) {
var item = pullChanges.changes[i];
var version = localStorage[SYNC_PROVIDER_DROPBOX
+ encodeURIComponent(item.path.toLowerCase()) + ".version"];
if(version && (item.wasRemoved || item.stat.versionTag != version)) {
changes.push(item);
}
}
}
asyncTask.success();
return;
}
// Handle error
if(asyncTask.finished === true) {
return;
}
authenticate(function(error) {
if (error) {
handleError(error, asyncTask, callback);
});
};
asyncTask.onSuccess = function() {
if (shouldPullAgain === true) {
retrievePageOfChanges(newChangeId);
} else {
callback(changes, newChangeId);
}
};
asyncTask.onError = function() {
callback();
};
asyncTaskRunner.addTask(asyncTask);
}
retrievePageOfChanges(newChangeId);
});
};
dropboxHelper.downloadMetadata = function(paths, callback, result) {
callback = callback || core.doNothing;
result = result || [];
if(paths.length === 0) {
callback(result);
return;
}
authenticate(function() {
if (client === undefined) {
callback();
return;
}
var path = paths.pop();
var asyncTask = {};
asyncTask.run = function() {
client.stat(path, function(error, stat) {
if(stat) {
result.push(stat);
asyncTask.success();
return;
}
handleError(error, asyncTask, callback);
client.pullChanges(changeId, function(error, pullChanges) {
if (error) {
handleError(error, asyncTask, callback);
return;
}
// Retrieve success
newChangeId = pullChanges.cursor();
if(pullChanges.changes !== undefined) {
for(var i=0; i<pullChanges.changes.length; i++) {
var item = pullChanges.changes[i];
var version = localStorage[SYNC_PROVIDER_DROPBOX
+ encodeURIComponent(item.path.toLowerCase()) + ".version"];
if(version && (item.wasRemoved || item.stat.versionTag != version)) {
changes.push(item);
}
}
}
if (pullChanges.shouldPullAgain) {
retrievePageOfChanges(newChangeId);
} else {
asyncTask.success();
}
});
});
};
asyncTask.onSuccess = function() {
dropboxHelper.downloadMetadata(paths, callback, result);
};
asyncTask.onError = function() {
callback();
};
asyncTaskRunner.addTask(asyncTask);
});
}
retrievePageOfChanges(newChangeId);
};
asyncTask.onSuccess = function() {
callback(undefined, changes, newChangeId);
};
asyncTask.onError = function() {
callback(true);
};
asyncTaskRunner.addTask(asyncTask);
};
dropboxHelper.downloadMetadata = function(paths, callback) {
callback = callback || core.doNothing;
result = result || [];
var path = paths.pop();
var asyncTask = {};
asyncTask.run = function() {
function recursiveDownloadMetadata() {
if(asyncTask.finished === true) {
return;
}
if(paths.length === 0) {
asyncTask.success();
return;
}
authenticate(function(error) {
if (error) {
handleError(error, asyncTask, callback);
return;
}
client.stat(path, function(error, stat) {
if(stat) {
result.push(stat);
recursiveDownloadMetadata();
return;
}
handleError(error, asyncTask, callback);
});
});
}
recursiveDownloadMetadata();
};
asyncTask.onSuccess = function() {
callback(undefined, result);
};
asyncTask.onError = function() {
callback(true);
};
asyncTaskRunner.addTask(asyncTask);
};
dropboxHelper.downloadContent = function(objects, callback, result) {
callback = callback || core.doNothing;
result = result || [];
if(objects.length === 0) {
callback(result);
return;
}
var object = objects.pop();
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) {
this.downloadContent(objects, callback, result);
return;
}
authenticate(function() {
if (client === undefined) {
callback();
return;
}
var asyncTask = {};
asyncTask.run = function() {
var asyncTask = {};
asyncTask.run = function() {
client.readFile(file.path, function(error, data) {
if(data) {
file.content = data;
asyncTask.success();
function recursiveDownloadContent() {
if(asyncTask.finished === true) {
return;
}
if(objects.length === 0) {
asyncTask.success();
return;
}
var object = objects.pop();
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) {
recursiveDownloadContent();
return;
}
authenticate(function(error) {
if (error) {
handleError(error, asyncTask, callback);
return;
}
handleError(error, asyncTask, callback);
client.readFile(file.path, function(error, data) {
if(data) {
file.content = data;
recursiveDownloadContent();
return;
}
handleError(error, asyncTask, callback);
});
});
};
asyncTask.onSuccess = function() {
dropboxHelper.downloadContent(objects, callback, result);
};
asyncTask.onError = function() {
callback();
};
asyncTaskRunner.addTask(asyncTask);
});
}
recursiveDownloadContent();
};
asyncTask.onSuccess = function() {
callback(undefined, result);
};
asyncTask.onError = function() {
callback(true);
};
asyncTaskRunner.addTask(asyncTask);
};
function handleError(error, asyncTask, callback) {
@ -277,7 +271,7 @@ define(["jquery", "async-runner"], function($, asyncTaskRunner) {
if (errorMsg !== undefined) {
core.showError(errorMsg);
}
callback();
callback(errorMsg);
};
if (error) {
console.error(error);
@ -302,83 +296,83 @@ define(["jquery", "async-runner"], function($, asyncTaskRunner) {
var pickerLoaded = false;
function loadPicker(callback) {
connect(function() {
if (client === undefined) {
if (pickerLoaded === true) {
callback();
return;
}
connect(function(error) {
if (error) {
pickerLoaded = false;
callback();
callback(error);
return;
}
var asyncTask = {};
asyncTask.run = function() {
if (pickerLoaded === true) {
asyncTask.success();
return;
}
$.ajax({
url : "https://www.dropbox.com/static/api/1/dropbox.js",
dataType : "script", timeout : AJAX_TIMEOUT
}).done(function() {
asyncTask.success();
}).fail(function() {
asyncTask.error();
});
};
asyncTask.onSuccess = function() {
$.ajax({
url : "https://www.dropbox.com/static/api/1/dropbox.js",
dataType : "script", timeout : AJAX_TIMEOUT
}).done(function() {
pickerLoaded = true;
callback();
};
asyncTask.onError = function() {
core.setOffline();
callback();
};
asyncTaskRunner.addTask(asyncTask);
}).fail(function() {
callback(true);
});
});
}
dropboxHelper.picker = function(callback) {
callback = callback || core.doNothing;
loadPicker(function() {
if (pickerLoaded === false) {
callback();
return;
}
var options = {};
options.multiselect = true;
options.linkType = "direct";
options.success = function(files) {
var paths = [];
for(var i=0; i<files.length; i++) {
var path = files[i].link;
path = path.replace(/.*\/view\/[^\/]*/, "");
paths.push(decodeURI(path));
var paths = [];
var asyncTask = {};
asyncTask.run = function() {
loadPicker(function(error) {
if (error) {
handleError(error, asyncTask, callback);
return;
}
callback(paths);
};
options.cancel = function() {
callback();
};
Dropbox.choose(options);
core.showMessage("Please make sure the Dropbox chooser popup is not blocked by your browser.");
});
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));
}
asyncTask.success();
};
options.cancel = function() {
asyncTask.error();
};
Dropbox.choose(options);
core.showMessage("Please make sure the Dropbox chooser popup is not blocked by your browser.");
});
};
asyncTask.onSuccess = function() {
callback(undefined, paths);
};
asyncTask.onError = function() {
callback(true);
};
asyncTaskRunner.addTask(asyncTask);
};
dropboxHelper.importFiles = function(paths) {
dropboxHelper.downloadMetadata(paths, function(result) {
if(result === undefined) {
dropboxHelper.downloadMetadata(paths, function(error, result) {
if(error) {
return;
}
dropboxHelper.downloadContent(result, function(result) {
if(result === undefined) {
dropboxHelper.downloadContent(result, function(error, result) {
if(error) {
return;
}
for(var i=0; i<result.length; i++) {
var file = result[i];
fileSyncIndex = SYNC_PROVIDER_DROPBOX + encodeURIComponent(file.path.toLowerCase());
localStorage[fileSyncIndex + ".version"] = file.versionTag;
syncIndex = SYNC_PROVIDER_DROPBOX + encodeURIComponent(file.path.toLowerCase());
localStorage[syncIndex + ".version"] = file.versionTag;
var contentCRC = core.crc32(file.content);
localStorage[fileSyncIndex + ".contentCRC"] = contentCRC;
var fileIndex = fileManager.createFile(file.name, file.content, [fileSyncIndex]);
localStorage[syncIndex + ".contentCRC"] = contentCRC;
var fileIndex = fileManager.createFile(file.name, file.content, [syncIndex]);
fileManager.selectFile(fileIndex);
core.showMessage('"' + file.name + '" imported successfully from Dropbox.');
}

36
js/dropbox-provider.js Normal file
View File

@ -0,0 +1,36 @@
define(["jquery", "dropbox-helper"], function($, dropboxHelper) {
// Dependencies
var core = undefined;
var dropboxProvider = {
providerType: PROVIDER_TYPE_PUBLISH_FLAG,
providerId: PROVIDER_DROPBOX,
providerName: "Dropbox",
defaultPublishFormat: "template"
};
dropboxProvider.publish = function(publishAttributes, title, content, callback) {
var path = dropboxHelper.checkPath(publishAttributes.path);
if(path === undefined) {
callback(true);
return;
}
dropboxHelper.upload(path, content, callback);
};
dropboxProvider.newPublishAttributes = function(event) {
var publishAttributes = {};
publishAttributes.path = core.getInputValue($("#input-publish-dropbox-path"), event);
if(event.isPropagationStopped()) {
return undefined;
}
return publishAttributes;
};
dropboxProvider.init = function(coreModule) {
core = coreModule;
};
return dropboxProvider;
});

View File

@ -301,8 +301,8 @@ define(["jquery", "google-helper", "dropbox-helper", "github-helper", "synchroni
var fileIndex = fileManager.getCurrentFileIndex();
var content = localStorage[fileIndex + ".content"];
var title = localStorage[fileIndex + ".title"];
dropboxHelper.upload(path, content, function(syncIndex) {
if (syncIndex === undefined) {
dropboxHelper.upload(path, content, function(error, syncIndex) {
if (error) {
return;
}
var contentCRC = core.crc32(content);
@ -315,8 +315,8 @@ define(["jquery", "google-helper", "dropbox-helper", "github-helper", "synchroni
});
}
function importDropbox(paths) {
if(paths === undefined) {
function importDropbox(error, paths) {
if(error) {
return;
}
var importPaths = [];

View File

@ -1,4 +1,4 @@
define(["jquery", "github-provider", "blogger-provider", "underscore"], function($) {
define(["jquery", "github-provider", "blogger-provider", "dropbox-provider", "underscore"], function($) {
// Dependencies
var core = undefined;
@ -131,6 +131,7 @@ define(["jquery", "github-provider", "blogger-provider", "underscore"], function
function initNewLocation(provider) {
var defaultPublishFormat = provider.defaultPublishFormat || "markdown";
newLocationProvider = provider;
$(".publish-provider-name").text(provider.providerName);
// Show/hide controls depending on provider
$('div[class*=" modal-publish-"]').hide().filter(".modal-publish-" + provider.providerId).show();

View File

@ -89,16 +89,14 @@ define(["jquery", "google-helper", "dropbox-helper"], function($, googleHelper,
} else if (fileSyncIndex.indexOf(SYNC_PROVIDER_DROPBOX) === 0) {
var path = fileSyncIndex.substring(SYNC_PROVIDER_DROPBOX.length);
path = decodeURIComponent(path);
dropboxHelper.upload(path, uploadContent, function(result) {
if (result !== undefined) {
localStorage[fileSyncIndex + ".contentCRC"] = uploadContentCRC;
locationUp(callback);
dropboxHelper.upload(path, uploadContent, function(error, result) {
if (error) {
// If error we abort the synchronization (retry later)
callback(error);
return;
}
// If error we abort the synchronization (retry later)
callback("abort");
return;
localStorage[fileSyncIndex + ".contentCRC"] = uploadContentCRC;
locationUp(callback);
});
} else {
// This should never happen
@ -236,14 +234,14 @@ define(["jquery", "google-helper", "dropbox-helper"], function($, googleHelper,
return;
}
var lastChangeId = localStorage[SYNC_PROVIDER_DROPBOX + "lastChangeId"];
dropboxHelper.checkUpdates(lastChangeId, function(changes, newChangeId) {
if (changes === undefined) {
callback("error");
dropboxHelper.checkUpdates(lastChangeId, function(error, changes, newChangeId) {
if (error) {
callback(error);
return;
}
dropboxHelper.downloadContent(changes, function(changes) {
if (changes === undefined) {
callback("error");
dropboxHelper.downloadContent(changes, function(error, changes) {
if (error) {
callback(error);
return;
}
var updateFileTitles = false;