summaryrefslogtreecommitdiff
path: root/lib/response.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lib/response.js211
1 files changed, 211 insertions, 0 deletions
diff --git a/lib/response.js b/lib/response.js
new file mode 100644
index 00000000..458ed01f
--- /dev/null
+++ b/lib/response.js
@@ -0,0 +1,211 @@
+//response
+//external modules
+var ejs = require('ejs');
+var fs = require('fs');
+var path = require('path');
+var uuid = require('node-uuid');
+var markdownpdf = require("markdown-pdf");
+var LZString = require('lz-string');
+
+//core
+var config = require("../config.js");
+
+//others
+var db = require("./db.js");
+var Note = require("./note.js");
+
+//public
+var response = {
+ errorForbidden: function (res) {
+ res.status(403).send("Forbidden, oh no.")
+ },
+ errorNotFound: function (res) {
+ responseError(res, "404", "Not Found", "oops.")
+ },
+ errorInternalError: function (res) {
+ responseError(res, "500", "Internal Error", "wtf.")
+ },
+ errorServiceUnavailable: function (res) {
+ res.status(503).send("I'm busy right now, try again later.")
+ },
+ newNote: newNote,
+ showFeatures: showFeatures,
+ showNote: showNote,
+ noteActions: noteActions
+};
+
+function responseError(res, code, detail, msg) {
+ res.writeHead(code, {
+ 'Content-Type': 'text/html'
+ });
+ var content = ejs.render(fs.readFileSync(config.errorpath, 'utf8'), {
+ cache: !config.debug,
+ filename: config.errorpath,
+ code: code,
+ detail: detail,
+ msg: msg
+ });
+ res.write(content);
+ res.end();
+}
+
+function responseHackMD(res) {
+ res.writeHead(200, {
+ 'Content-Type': 'text/html'
+ });
+ var content = ejs.render(fs.readFileSync(config.hackmdpath, 'utf8'), {
+ cache: !config.debug,
+ filename: config.hackmdpath
+ });
+ res.write(content);
+ res.end();
+}
+
+function newNote(req, res, next) {
+ var newId = uuid.v4();
+ var body = fs.readFileSync(config.defaultnotepath, 'utf8');
+ body = LZString.compressToBase64(body);
+ var owner = null;
+ if (req.isAuthenticated()) {
+ owner = req.session.passport.user;
+ }
+ db.newToDB(newId, owner, body, function (err, result) {
+ if (err) {
+ responseError(res, "500", "Internal Error", "wtf.");
+ return;
+ }
+ res.redirect("/" + LZString.compressToBase64(newId));
+ });
+}
+
+function showFeatures(req, res, next) {
+ db.readFromDB(config.featuresnotename, function (err, data) {
+ if (err) {
+ var body = fs.readFileSync(config.defaultfeaturespath, 'utf8');
+ body = LZString.compressToBase64(body);
+ db.newToDB(config.featuresnotename, null, body, function (err, result) {
+ if (err) {
+ responseError(res, "500", "Internal Error", "wtf.");
+ return;
+ }
+ responseHackMD(res);
+ });
+ } else {
+ responseHackMD(res);
+ }
+ });
+}
+
+function showNote(req, res, next) {
+ var noteId = req.params.noteId;
+ if (!Note.checkNoteIdValid(noteId)) {
+ responseError(res, "404", "Not Found", "oops.");
+ return;
+ }
+ responseHackMD(res);
+}
+
+function actionPretty(req, res, noteId) {
+ db.readFromDB(noteId, function (err, data) {
+ if (err) {
+ responseError(res, "404", "Not Found", "oops.");
+ return;
+ }
+ var body = data.rows[0].content;
+ var template = config.prettypath;
+ var compiled = ejs.compile(fs.readFileSync(template, 'utf8'));
+ var origin = "//" + req.headers.host;
+ var html = compiled({
+ url: origin,
+ body: body
+ });
+ var buf = html;
+ res.writeHead(200, {
+ 'Content-Type': 'text/html; charset=UTF-8',
+ 'Cache-Control': 'private',
+ 'Content-Length': buf.length
+ });
+ res.end(buf);
+ });
+}
+
+function actionDownload(req, res, noteId) {
+ db.readFromDB(noteId, function (err, data) {
+ if (err) {
+ responseError(res, "404", "Not Found", "oops.");
+ return;
+ }
+ var body = LZString.decompressFromBase64(data.rows[0].content);
+ var title = Note.getNoteTitle(body);
+ res.writeHead(200, {
+ 'Content-Type': 'text/markdown; charset=UTF-8',
+ 'Cache-Control': 'private',
+ 'Content-disposition': 'attachment; filename=' + title + '.md',
+ 'Content-Length': body.length
+ });
+ res.end(body);
+ });
+}
+
+function actionPDF(req, res, noteId) {
+ db.readFromDB(noteId, function (err, data) {
+ if (err) {
+ responseError(res, "404", "Not Found", "oops.");
+ return;
+ }
+ var body = LZString.decompressFromBase64(data.rows[0].content);
+ var title = Note.getNoteTitle(body);
+
+ if (!fs.existsSync(config.tmppath)) {
+ fs.mkdirSync(config.tmppath);
+ }
+ var path = config.tmppath + Date.now() + '.pdf';
+ markdownpdf().from.string(body).to(path, function () {
+ var stream = fs.createReadStream(path);
+ var filename = title;
+ // Be careful of special characters
+ filename = encodeURIComponent(filename);
+ // Ideally this should strip them
+ res.setHeader('Content-disposition', 'attachment; filename="' + filename + '.pdf"');
+ res.setHeader('Cache-Control', 'private');
+ res.setHeader('Content-Type', 'application/pdf; charset=UTF-8');
+ stream.pipe(res);
+ fs.unlink(path);
+ });
+ });
+}
+
+function noteActions(req, res, next) {
+ var noteId = req.params.noteId;
+ if (noteId != config.featuresnotename) {
+ if (!Note.checkNoteIdValid(noteId)) {
+ responseError(res, "404", "Not Found", "oops.");
+ return;
+ }
+ noteId = LZString.decompressFromBase64(noteId);
+ if (!noteId) {
+ responseError(res, "404", "Not Found", "oops.");
+ return;
+ }
+ }
+ var action = req.params.action;
+ switch (action) {
+ case "pretty":
+ actionPretty(req, res, noteId);
+ break;
+ case "download":
+ actionDownload(req, res, noteId);
+ break;
+ case "pdf":
+ actionPDF(req, res, noteId);
+ break;
+ default:
+ if (noteId != config.featuresnotename)
+ res.redirect('/' + LZString.compressToBase64(noteId));
+ else
+ res.redirect('/' + noteId);
+ break;
+ }
+}
+
+module.exports = response; \ No newline at end of file