Supported export to gist
This commit is contained in:
parent
0f87fd4493
commit
ff2fc76491
5 changed files with 145 additions and 2 deletions
2
app.js
2
app.js
|
@ -244,6 +244,8 @@ app.get('/auth/github/callback',
|
|||
function (req, res) {
|
||||
res.redirect('/');
|
||||
});
|
||||
//github callback actions
|
||||
app.get('/auth/github/callback/:noteId/:action', response.githubActions);
|
||||
//dropbox auth
|
||||
app.get('/auth/dropbox',
|
||||
passport.authenticate('dropbox-oauth2'),
|
||||
|
|
135
lib/response.js
135
lib/response.js
|
@ -9,6 +9,8 @@ var LZString = require('lz-string');
|
|||
var S = require('string');
|
||||
var shortId = require('shortid');
|
||||
var metaMarked = require('meta-marked');
|
||||
var querystring = require('querystring');
|
||||
var request = require('request');
|
||||
|
||||
//core
|
||||
var config = require("../config.js");
|
||||
|
@ -56,7 +58,8 @@ var response = {
|
|||
showPublishSlide: showPublishSlide,
|
||||
showIndex: showIndex,
|
||||
noteActions: noteActions,
|
||||
publishNoteActions: publishNoteActions
|
||||
publishNoteActions: publishNoteActions,
|
||||
githubActions: githubActions
|
||||
};
|
||||
|
||||
function responseError(res, code, detail, msg) {
|
||||
|
@ -362,6 +365,28 @@ function actionPDF(req, res, noteId) {
|
|||
});
|
||||
}
|
||||
|
||||
function actionGist(req, res, noteId) {
|
||||
db.readFromDB(noteId, function (err, data) {
|
||||
if (err) {
|
||||
return response.errorNotFound(res);
|
||||
}
|
||||
var owner = data.rows[0].owner;
|
||||
Note.findOrNewNote(noteId, owner, function (err, note) {
|
||||
if (err) {
|
||||
return response.errorNotFound(res);
|
||||
}
|
||||
var data = {
|
||||
client_id: config.github.clientID,
|
||||
redirect_uri: config.getserverurl() + '/auth/github/callback/' + LZString.compressToBase64(noteId) + '/gist',
|
||||
scope: "gist",
|
||||
state: shortId.generate()
|
||||
};
|
||||
var query = querystring.stringify(data);
|
||||
res.redirect("https://github.com/login/oauth/authorize?" + query);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function noteActions(req, res, next) {
|
||||
var noteId = req.params.noteId;
|
||||
if (noteId != config.featuresnotename) {
|
||||
|
@ -402,6 +427,9 @@ function noteActions(req, res, next) {
|
|||
case "pdf":
|
||||
actionPDF(req, res, noteId);
|
||||
break;
|
||||
case "gist":
|
||||
actionGist(req, res, noteId);
|
||||
break;
|
||||
default:
|
||||
if (noteId != config.featuresnotename)
|
||||
res.redirect('/' + LZString.compressToBase64(noteId));
|
||||
|
@ -444,6 +472,111 @@ function publishNoteActions(req, res, next) {
|
|||
}
|
||||
}
|
||||
|
||||
function githubActions(req, res, next) {
|
||||
var noteId = req.params.noteId;
|
||||
if (noteId != config.featuresnotename) {
|
||||
if (!Note.checkNoteIdValid(noteId)) {
|
||||
return response.errorNotFound(res);
|
||||
}
|
||||
noteId = LZString.decompressFromBase64(noteId);
|
||||
if (!noteId) {
|
||||
return response.errorNotFound(res);
|
||||
}
|
||||
}
|
||||
Note.findNote(noteId, function (err, note) {
|
||||
if (err || !note) {
|
||||
return response.errorNotFound(res);
|
||||
}
|
||||
db.readFromDB(note.id, function (err, data) {
|
||||
if (err) {
|
||||
return response.errorNotFound(res);
|
||||
}
|
||||
var notedata = data.rows[0];
|
||||
//check view permission
|
||||
if (note.permission == 'private') {
|
||||
if (!req.isAuthenticated() || notedata.owner != req.user._id)
|
||||
return response.errorForbidden(res);
|
||||
}
|
||||
var action = req.params.action;
|
||||
switch (action) {
|
||||
case "gist":
|
||||
githubActionGist(req, res, noteId);
|
||||
break;
|
||||
default:
|
||||
if (noteId != config.featuresnotename)
|
||||
res.redirect('/' + LZString.compressToBase64(noteId));
|
||||
else
|
||||
res.redirect('/' + noteId);
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function githubActionGist(req, res, noteId) {
|
||||
db.readFromDB(noteId, function (err, data) {
|
||||
if (err) {
|
||||
return response.errorNotFound(res);
|
||||
}
|
||||
var notedata = data.rows[0];
|
||||
var code = req.query.code;
|
||||
var state = req.query.state;
|
||||
if (!code || !state) {
|
||||
return response.errorForbidden(res);
|
||||
} else {
|
||||
var data = {
|
||||
client_id: config.github.clientID,
|
||||
client_secret: config.github.clientSecret,
|
||||
code: code,
|
||||
state: state
|
||||
}
|
||||
var auth_url = 'https://github.com/login/oauth/access_token';
|
||||
request({
|
||||
url: auth_url,
|
||||
method: "POST",
|
||||
json: data
|
||||
}, function (error, httpResponse, body) {
|
||||
if (!error && httpResponse.statusCode == 200) {
|
||||
var access_token = body.access_token;
|
||||
if (access_token) {
|
||||
var content = LZString.decompressFromBase64(notedata.content);
|
||||
var title = notedata.title;
|
||||
var decodedTitle = LZString.decompressFromBase64(title);
|
||||
if (decodedTitle) title = decodedTitle;
|
||||
var filename = title.replace('/', ' ') + '.md';
|
||||
var gist = {
|
||||
"files": {}
|
||||
};
|
||||
gist.files[filename] = {
|
||||
"content": content
|
||||
};
|
||||
var gist_url = "https://api.github.com/gists";
|
||||
request({
|
||||
url: gist_url,
|
||||
headers: {
|
||||
'User-Agent': 'HackMD',
|
||||
'Authorization': 'token ' + access_token
|
||||
},
|
||||
method: "POST",
|
||||
json: gist
|
||||
}, function (error, httpResponse, body) {
|
||||
if (!error && httpResponse.statusCode == 201) {
|
||||
res.redirect(body.html_url);
|
||||
} else {
|
||||
return response.errorForbidden(res);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return response.errorForbidden(res);
|
||||
}
|
||||
} else {
|
||||
return response.errorForbidden(res);
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function showPublishSlide(req, res, next) {
|
||||
var shortid = req.params.shortid;
|
||||
if (shortId.isValid(shortid)) {
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
"passport.socketio": "^3.6.1",
|
||||
"pg": "4.x",
|
||||
"randomcolor": "^0.4.3",
|
||||
"request": "^2.69.0",
|
||||
"shortid": "2.2.4",
|
||||
"socket.io": "1.4.4",
|
||||
"string": "^3.3.1",
|
||||
|
|
|
@ -311,7 +311,8 @@ var ui = {
|
|||
html: $(".ui-download-html")
|
||||
},
|
||||
export: {
|
||||
dropbox: $(".ui-save-dropbox")
|
||||
dropbox: $(".ui-save-dropbox"),
|
||||
gist: $(".ui-save-gist")
|
||||
},
|
||||
import: {
|
||||
dropbox: $(".ui-import-dropbox"),
|
||||
|
@ -857,6 +858,8 @@ ui.toolbar.export.dropbox.click(function () {
|
|||
};
|
||||
Dropbox.save(options);
|
||||
});
|
||||
//export to gist
|
||||
ui.toolbar.export.gist.attr("href", url + "/gist");
|
||||
//import from dropbox
|
||||
ui.toolbar.import.dropbox.click(function () {
|
||||
var options = {
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
<li class="dropdown-header">Export</li>
|
||||
<li role="presentation"><a role="menuitem" class="ui-save-dropbox" tabindex="-1" href="#" target="_self"><i class="fa fa-dropbox fa-fw"></i> Dropbox</a>
|
||||
</li>
|
||||
<li role="presentation"><a role="menuitem" class="ui-save-gist" tabindex="-1" href="#" target="_blank"><i class="fa fa-github fa-fw"></i> Gist</a>
|
||||
</li>
|
||||
<li class="divider"></li>
|
||||
<li class="dropdown-header">Import</li>
|
||||
<li role="presentation"><a role="menuitem" class="ui-import-dropbox" tabindex="-1" href="#" target="_self"><i class="fa fa-dropbox fa-fw"></i> Dropbox</a>
|
||||
|
@ -110,6 +112,8 @@
|
|||
<li class="divider"></li>
|
||||
<li class="dropdown-header">Export</li>
|
||||
<li role="presentation"><a role="menuitem" class="ui-save-dropbox" tabindex="-1" href="#" target="_self"><i class="fa fa-dropbox fa-fw"></i> Dropbox</a>
|
||||
</li>
|
||||
<li role="presentation"><a role="menuitem" class="ui-save-gist" tabindex="-1" href="#" target="_blank"><i class="fa fa-github fa-fw"></i> Gist</a>
|
||||
</li>
|
||||
<li class="divider"></li>
|
||||
<li class="dropdown-header">Import</li>
|
||||
|
|
Loading…
Reference in a new issue