Tumblr support
This commit is contained in:
parent
94a739bd80
commit
859f347974
2
.gitignore
vendored
2
.gitignore
vendored
@ -2,4 +2,4 @@ chrome-app*
|
|||||||
.project
|
.project
|
||||||
.settings
|
.settings
|
||||||
node_modules
|
node_modules
|
||||||
|
Thumbs.db
|
||||||
|
@ -1 +1 @@
|
|||||||
CACHE MANIFEST
# v16
CACHE:
index.html
css/main-min.css
js/main-min.js
js/require.js
img/ajax-loader.gif
img/glyphicons-halflings.png
img/glyphicons-halflings-white.png
img/icons.png
img/stackedit-32.ico
img/stackedit-promo.png
NETWORK:
*
|
CACHE MANIFEST
# v17
CACHE:
index.html
css/main-min.css
js/main-min.js
js/require.js
img/ajax-loader.gif
img/glyphicons-halflings.png
img/glyphicons-halflings-white.png
img/icons.png
img/stackedit-32.ico
img/stackedit-promo.png
NETWORK:
*
|
||||||
|
BIN
img/icons.png
BIN
img/icons.png
Binary file not shown.
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.1 KiB |
28
index.html
28
index.html
@ -97,6 +97,8 @@
|
|||||||
class="icon-github"></i> GitHub</a></li>
|
class="icon-github"></i> GitHub</a></li>
|
||||||
<li><a href="#" class="action-publish-gdrive"><i
|
<li><a href="#" class="action-publish-gdrive"><i
|
||||||
class="icon-gdrive"></i> Google Drive</a></li>
|
class="icon-gdrive"></i> Google Drive</a></li>
|
||||||
|
<li><a href="#" class="action-publish-tumblr"><i
|
||||||
|
class="icon-tumblr"></i> Tumblr</a></li>
|
||||||
</ul></li>
|
</ul></li>
|
||||||
<li><a href="#" data-toggle="modal"
|
<li><a href="#" data-toggle="modal"
|
||||||
data-target="#modal-manage-publish" class="action-reset-input"><i
|
data-target="#modal-manage-publish" class="action-reset-input"><i
|
||||||
@ -315,22 +317,38 @@
|
|||||||
placeholder="http://exemple.blogger.com/">
|
placeholder="http://exemple.blogger.com/">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group modal-publish-blogger">
|
<div class="control-group modal-publish-tumblr">
|
||||||
<label class="control-label" for="input-publish-blogger-postid">Update
|
<label class="control-label" for="input-publish-tumblr-hostname">Blog
|
||||||
|
hostname</label>
|
||||||
|
<div class="controls">
|
||||||
|
<input type="text" id="input-publish-tumblr-hostname"
|
||||||
|
placeholder="exemple.tumblr.com">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group modal-publish-blogger modal-publish-tumblr">
|
||||||
|
<label class="control-label" for="input-publish-postid">Update
|
||||||
existing post ID (optional)</label>
|
existing post ID (optional)</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<input type="text" id="input-publish-blogger-postid"
|
<input type="text" id="input-publish-postid"
|
||||||
placeholder="Post ID">
|
placeholder="Post ID">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group modal-publish-blogger">
|
<div class="control-group modal-publish-blogger">
|
||||||
<label class="control-label" for="input-publish-blogger-labels">Labels
|
<label class="control-label" for="input-publish-labels">Labels
|
||||||
(comma separated)</label>
|
(comma separated)</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<input type="text" id="input-publish-blogger-labels"
|
<input type="text" id="input-publish-labels"
|
||||||
placeholder="Label1, Label2">
|
placeholder="Label1, Label2">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="control-group modal-publish-tumblr">
|
||||||
|
<label class="control-label" for="input-publish-tags">Tags
|
||||||
|
(comma separated)</label>
|
||||||
|
<div class="controls">
|
||||||
|
<input type="text" id="input-publish-tags"
|
||||||
|
placeholder="Tag1, Tag2">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="control-group modal-publish-dropbox">
|
<div class="control-group modal-publish-dropbox">
|
||||||
<label class="control-label" for="input-publish-dropbox-path">File
|
<label class="control-label" for="input-publish-dropbox-path">File
|
||||||
path</label>
|
path</label>
|
||||||
|
@ -32,9 +32,9 @@ define(["jquery", "core", "google-helper"], function($, core, googleHelper) {
|
|||||||
if(blogUrl !== undefined) {
|
if(blogUrl !== undefined) {
|
||||||
publishAttributes.blogUrl = core.checkUrl(blogUrl);
|
publishAttributes.blogUrl = core.checkUrl(blogUrl);
|
||||||
}
|
}
|
||||||
publishAttributes.postId = $("#input-publish-blogger-postid").val() || undefined;
|
publishAttributes.postId = $("#input-publish-postid").val() || undefined;
|
||||||
publishAttributes.labelList = [];
|
publishAttributes.labelList = [];
|
||||||
var labels = $("#input-publish-blogger-labels").val() || undefined;
|
var labels = $("#input-publish-labels").val() || undefined;
|
||||||
if(labels !== undefined) {
|
if(labels !== undefined) {
|
||||||
publishAttributes.labelList = _.chain(labels.split(","))
|
publishAttributes.labelList = _.chain(labels.split(","))
|
||||||
.map(function(label) {
|
.map(function(label) {
|
||||||
|
@ -16,6 +16,7 @@ var PROVIDER_BLOGGER = "blogger";
|
|||||||
var PROVIDER_DROPBOX = "dropbox";
|
var PROVIDER_DROPBOX = "dropbox";
|
||||||
var PROVIDER_GDRIVE = "gdrive";
|
var PROVIDER_GDRIVE = "gdrive";
|
||||||
var PROVIDER_GITHUB = "github";
|
var PROVIDER_GITHUB = "github";
|
||||||
|
var PROVIDER_TUMBLR = "tumblr";
|
||||||
var WELCOME_DOCUMENT_TITLE = "Welcome document";
|
var WELCOME_DOCUMENT_TITLE = "Welcome document";
|
||||||
|
|
||||||
// Use by Google's client.js
|
// Use by Google's client.js
|
||||||
@ -32,6 +33,7 @@ var GOOGLE_KEY = "AIzaSyAeCU8CGcSkn0z9js6iocHuPBX4f_mMWkw";
|
|||||||
var GOOGLE_CLIENT_ID = '241271498917-lev37kef013q85avc91am1gccg5g8lrb.apps.googleusercontent.com';
|
var GOOGLE_CLIENT_ID = '241271498917-lev37kef013q85avc91am1gccg5g8lrb.apps.googleusercontent.com';
|
||||||
var GITHUB_CLIENT_ID = 'e47fef6055344579799d';
|
var GITHUB_CLIENT_ID = 'e47fef6055344579799d';
|
||||||
var GATEKEEPER_URL = "http://stackedit-gatekeeper-localhost.herokuapp.com/";
|
var GATEKEEPER_URL = "http://stackedit-gatekeeper-localhost.herokuapp.com/";
|
||||||
|
var TUMBLR_PROXY_URL = "http://stackedit-tumblr-proxy-local.herokuapp.com/";
|
||||||
|
|
||||||
if(location.hostname.indexOf("benweet.github.io") === 0) {
|
if(location.hostname.indexOf("benweet.github.io") === 0) {
|
||||||
BASE_URL = "http://benweet.github.io/stackedit/";
|
BASE_URL = "http://benweet.github.io/stackedit/";
|
||||||
@ -39,4 +41,5 @@ if(location.hostname.indexOf("benweet.github.io") === 0) {
|
|||||||
GOOGLE_CLIENT_ID = '241271498917-jpto9lls9fqnem1e4h6ppds9uob8rpvu.apps.googleusercontent.com';
|
GOOGLE_CLIENT_ID = '241271498917-jpto9lls9fqnem1e4h6ppds9uob8rpvu.apps.googleusercontent.com';
|
||||||
GITHUB_CLIENT_ID = 'fa0d09514da8377ee32e';
|
GITHUB_CLIENT_ID = 'fa0d09514da8377ee32e';
|
||||||
GATEKEEPER_URL = "http://stackedit-gatekeeper.herokuapp.com/";
|
GATEKEEPER_URL = "http://stackedit-gatekeeper.herokuapp.com/";
|
||||||
|
TUMBLR_PROXY_URL = "http://stackedit-tumblr-proxy.herokuapp.com/";
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ define(["jquery", "core", "dropbox-helper"], function($, core, dropboxHelper) {
|
|||||||
|
|
||||||
dropboxProvider.importFiles = function() {
|
dropboxProvider.importFiles = function() {
|
||||||
dropboxHelper.picker(function(error, paths) {
|
dropboxHelper.picker(function(error, paths) {
|
||||||
if(error) {
|
if(error || paths.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var importPaths = [];
|
var importPaths = [];
|
||||||
|
@ -40,7 +40,7 @@ define(["jquery", "core", "google-helper", "underscore"], function($, core, goog
|
|||||||
|
|
||||||
gdriveProvider.importFiles = function() {
|
gdriveProvider.importFiles = function() {
|
||||||
googleHelper.picker(function(error, ids) {
|
googleHelper.picker(function(error, ids) {
|
||||||
if(ids === undefined) {
|
if(error || ids.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var importIds = [];
|
var importIds = [];
|
||||||
|
@ -75,7 +75,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
localStorage.removeItem("githubCode");
|
localStorage.removeItem("githubCode");
|
||||||
task.chain(getToken);
|
task.chain(getToken);
|
||||||
}
|
}
|
||||||
});
|
}, 500);
|
||||||
}
|
}
|
||||||
function getToken() {
|
function getToken() {
|
||||||
$.getJSON(GATEKEEPER_URL + "authenticate/" + code, function(data) {
|
$.getJSON(GATEKEEPER_URL + "authenticate/" + code, function(data) {
|
||||||
@ -156,6 +156,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
errorMsg = "Could not publish on GitHub.";
|
errorMsg = "Could not publish on GitHub.";
|
||||||
if (error.error === 401 || error.error === 403) {
|
if (error.error === 401 || error.error === 403) {
|
||||||
github = undefined;
|
github = undefined;
|
||||||
|
localStorage.removeItem("githubToken");
|
||||||
errorMsg = "Access to GitHub account is not authorized.";
|
errorMsg = "Access to GitHub account is not authorized.";
|
||||||
task.retry(new Error(errorMsg), 1);
|
task.retry(new Error(errorMsg), 1);
|
||||||
return;
|
return;
|
||||||
|
2
js/main-min.js
vendored
2
js/main-min.js
vendored
File diff suppressed because one or more lines are too long
@ -1,4 +1,4 @@
|
|||||||
define(["jquery", "core", "github-provider", "blogger-provider", "dropbox-provider", "gdrive-provider", "underscore"], function($, core) {
|
define(["jquery", "core", "github-provider", "blogger-provider", "dropbox-provider", "gdrive-provider", "tumblr-provider", "underscore"], function($, core) {
|
||||||
|
|
||||||
var publisher = {};
|
var publisher = {};
|
||||||
|
|
||||||
|
164
js/tumblr-helper.js
Normal file
164
js/tumblr-helper.js
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||||
|
|
||||||
|
var oauthParams = undefined;
|
||||||
|
|
||||||
|
var tumblrHelper = {};
|
||||||
|
|
||||||
|
// Only used to check the offline status
|
||||||
|
function connect(task) {
|
||||||
|
task.onRun(function() {
|
||||||
|
if(core.isOffline === true) {
|
||||||
|
task.error(new Error("Operation not available in offline mode."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
task.chain();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to authenticate with Oauth
|
||||||
|
function authenticate(task) {
|
||||||
|
var authWindow = undefined;
|
||||||
|
var intervalId = undefined;
|
||||||
|
task.onRun(function() {
|
||||||
|
if (oauthParams !== undefined) {
|
||||||
|
task.chain();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var serializedOauthParams = localStorage["tumblrOauthParams"];
|
||||||
|
if(serializedOauthParams !== undefined) {
|
||||||
|
oauthParams = JSON.parse(serializedOauthParams);
|
||||||
|
task.chain();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
core.showMessage("Please make sure the Tumblr authorization popup is not blocked by your browser.");
|
||||||
|
var errorMsg = "Failed to retrieve a token from Tumblr.";
|
||||||
|
// We add time for user to enter his credentials
|
||||||
|
task.timeout = ASYNC_TASK_LONG_TIMEOUT;
|
||||||
|
var oauth_object = undefined;
|
||||||
|
function getOauthToken() {
|
||||||
|
$.getJSON(TUMBLR_PROXY_URL + "request_token", function(data) {
|
||||||
|
if(data.oauth_token !== undefined) {
|
||||||
|
oauth_object = data;
|
||||||
|
task.chain(getVerifier);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
task.error(new Error(errorMsg));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function getVerifier() {
|
||||||
|
localStorage.removeItem("tumblrVerifier");
|
||||||
|
authWindow = core.popupWindow(
|
||||||
|
'tumblr-oauth-client.html?oauth_token=' + oauth_object.oauth_token,
|
||||||
|
'stackedit-tumblr-oauth', 800, 600);
|
||||||
|
authWindow.focus();
|
||||||
|
intervalId = setInterval(function() {
|
||||||
|
if(authWindow.closed === true) {
|
||||||
|
clearInterval(intervalId);
|
||||||
|
authWindow = undefined;
|
||||||
|
intervalId = undefined;
|
||||||
|
oauth_object.oauth_verifier = localStorage["tumblrVerifier"];
|
||||||
|
if(oauth_object.oauth_verifier === undefined) {
|
||||||
|
task.error(new Error(errorMsg));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
localStorage.removeItem("tumblrVerifier");
|
||||||
|
task.chain(getAccessToken);
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
function getAccessToken() {
|
||||||
|
$.getJSON(TUMBLR_PROXY_URL + "access_token", oauth_object, function(data) {
|
||||||
|
if(data.access_token !== undefined && data.access_token_secret !== undefined) {
|
||||||
|
localStorage["tumblrOauthParams"] = JSON.stringify(data);
|
||||||
|
oauthParams = data;
|
||||||
|
task.chain();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
task.error(new Error(errorMsg));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
task.chain(getOauthToken);
|
||||||
|
});
|
||||||
|
task.onError(function() {
|
||||||
|
if(intervalId !== undefined) {
|
||||||
|
clearInterval(intervalId);
|
||||||
|
}
|
||||||
|
if(authWindow !== undefined) {
|
||||||
|
authWindow.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
tumblrHelper.upload = function(blogHostname, postId, tags, format, title, content, callback) {
|
||||||
|
callback = callback || core.doNothing;
|
||||||
|
var task = asyncRunner.createTask();
|
||||||
|
connect(task);
|
||||||
|
authenticate(task);
|
||||||
|
task.onRun(function() {
|
||||||
|
var data = $.extend({
|
||||||
|
blog_hostname: blogHostname,
|
||||||
|
post_id: postId,
|
||||||
|
tags: tags,
|
||||||
|
format: format,
|
||||||
|
title: title,
|
||||||
|
content: content
|
||||||
|
}, oauthParams);
|
||||||
|
$.ajax({
|
||||||
|
url : TUMBLR_PROXY_URL + "post",
|
||||||
|
data: data,
|
||||||
|
type: "POST",
|
||||||
|
dataType : "json",
|
||||||
|
timeout : AJAX_TIMEOUT
|
||||||
|
}).done(function(post, textStatus, jqXHR) {
|
||||||
|
postId = post.id;
|
||||||
|
task.chain();
|
||||||
|
}).fail(function(jqXHR) {
|
||||||
|
var error = {
|
||||||
|
code: jqXHR.status,
|
||||||
|
message: jqXHR.statusText
|
||||||
|
};
|
||||||
|
// Handle error
|
||||||
|
if(error.code === 404 && postId !== undefined) {
|
||||||
|
error = 'Post ' + postId + ' not found on Blogger.|removePublish';
|
||||||
|
}
|
||||||
|
handleError(error, task);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
task.onSuccess(function() {
|
||||||
|
callback(undefined, postId);
|
||||||
|
});
|
||||||
|
task.onError(function(error) {
|
||||||
|
callback(error);
|
||||||
|
});
|
||||||
|
asyncRunner.addTask(task);
|
||||||
|
};
|
||||||
|
|
||||||
|
function handleError(error, task) {
|
||||||
|
var errorMsg = undefined;
|
||||||
|
if (error) {
|
||||||
|
console.error(error);
|
||||||
|
// Try to analyze the error
|
||||||
|
if (typeof error === "string") {
|
||||||
|
errorMsg = error;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
errorMsg = "Could not publish on Tumblr.";
|
||||||
|
if (error.code === 401 || error.code === 403) {
|
||||||
|
oauthParams = undefined;
|
||||||
|
localStorage.removeItem("tumblrOauthParams");
|
||||||
|
errorMsg = "Access to Tumblr account is not authorized.";
|
||||||
|
task.retry(new Error(errorMsg), 1);
|
||||||
|
return;
|
||||||
|
} else if (error.code <= 0) {
|
||||||
|
core.setOffline();
|
||||||
|
errorMsg = "|stopPublish";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
task.error(new Error(errorMsg));
|
||||||
|
}
|
||||||
|
|
||||||
|
return tumblrHelper;
|
||||||
|
});
|
43
js/tumblr-provider.js
Normal file
43
js/tumblr-provider.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
define(["jquery", "core", "tumblr-helper"], function($, core, tumblrHelper) {
|
||||||
|
|
||||||
|
var tumblrProvider = {
|
||||||
|
providerId: PROVIDER_TUMBLR,
|
||||||
|
providerName: "Tumblr"
|
||||||
|
};
|
||||||
|
|
||||||
|
tumblrProvider.publish = function(publishAttributes, title, content, callback) {
|
||||||
|
tumblrHelper.upload(
|
||||||
|
publishAttributes.blogHostname,
|
||||||
|
publishAttributes.postId,
|
||||||
|
publishAttributes.tags,
|
||||||
|
publishAttributes.format == "markdown" ? "markdown" : "html",
|
||||||
|
title,
|
||||||
|
content,
|
||||||
|
function(error, postId) {
|
||||||
|
if(error) {
|
||||||
|
callback(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
publishAttributes.postId = postId;
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
tumblrProvider.newPublishAttributes = function(event) {
|
||||||
|
var publishAttributes = {};
|
||||||
|
publishAttributes.blogHostname = core
|
||||||
|
.getInputValue(
|
||||||
|
$("#input-publish-tumblr-hostname"),
|
||||||
|
event,
|
||||||
|
/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/);
|
||||||
|
publishAttributes.postId = $("#input-publish-postid").val() || undefined;
|
||||||
|
publishAttributes.tags = $("#input-publish-tags").val() || undefined;
|
||||||
|
if(event.isPropagationStopped()) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return publishAttributes;
|
||||||
|
};
|
||||||
|
|
||||||
|
return tumblrProvider;
|
||||||
|
});
|
26
tumblr-oauth-client.html
Normal file
26
tumblr-oauth-client.html
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<script type="text/javascript">
|
||||||
|
function getParameter(name) {
|
||||||
|
var regex = new RegExp(name + "=(.+?)(&|$)");
|
||||||
|
try {
|
||||||
|
return decodeURI(regex.exec(location.search)[1]);
|
||||||
|
} catch (e) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var oauth_token = getParameter("oauth_token");
|
||||||
|
var oauth_verifier = getParameter("oauth_verifier");
|
||||||
|
if (oauth_token && !oauth_verifier) {
|
||||||
|
window.location.href = "http://www.tumblr.com/oauth/authorize?oauth_token="
|
||||||
|
+ oauth_token;
|
||||||
|
} else {
|
||||||
|
if (oauth_verifier) {
|
||||||
|
localStorage["tumblrVerifier"] = oauth_verifier;
|
||||||
|
}
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user