summaryrefslogtreecommitdiffstats
path: root/lib/main.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/main.js')
-rw-r--r--lib/main.js236
1 files changed, 161 insertions, 75 deletions
diff --git a/lib/main.js b/lib/main.js
index 6e2f36a..191dbaa 100644
--- a/lib/main.js
+++ b/lib/main.js
@@ -1,103 +1,189 @@
var http = require('http'),
-router = require('choreographer').router(),
+fs = require('fs'),
+path = require('path'),
+bee = require('beeline'),
qs = require('querystring'),
-uuid = require(__dirname + '/uuid'),
hl = require(__dirname + '/highlight'),
-kyoto = require('kyoto');
+tmpl = require(__dirname + '/templates'),
+pasteInit = require(__dirname + '/paste');
-var db = new kyoto.open(__dirname + '/../db/pastes.kch', 'a+', kyotoOpen);
+var config = {
+ port: 8080,
+ database: __dirname + '/../db/pastes.kch'
+};
-function generateId(callback) {
- var id = uuid.generate(14);
- db.get(id, function(err, value) {
- if (value) {
- generateId();
- }
- else {
- callback(id);
- }
+var paste;
+
+function _200(res, contentType, data) {
+ res.writeHead(200, {'Content-Type': contentType});
+ res.write(data);
+ res.end('\n');
+}
+
+function _404(res) {
+ res.writeHead(404, {'Content-Type': 'text/plain'});
+ res.end('404: Not found.\n');
+}
+
+function _500(res, err) {
+ res.writeHead(404, {'Content-Type': 'text/plain'});
+ res.write('500: Internal Server Error');
+
+ if (err) {
+ res.write(':\n');
+ res.write(JSON.stringify(err));
+ }
+
+ res.end('\n');
+}
+
+function parsePost(req, callback) {
+ var content = '';
+
+ req.on('data', function(chunk) {
+ content += chunk;
+ });
+
+ req.on('end', function() {
+ var post = qs.parse(content);
+ callback(post);
});
}
-function getPaste(plain, req, res, paste) {
- db.get(paste, function(err, value) {
- if (err) {
- res.writeHead(404, {'Content-Type': 'text/plain'});
- res.end('404: ' + req.url + ' not found:\n' + err + '\n');
- }
- else {
- var data = JSON.parse(value);
- if (plain) {
- res.writeHead(200, {'Content-Type': 'text/plain'});
- res.write(data.content);
+function getContentType(ext) {
+ contentType = {
+ '.css': 'text/css',
+ '.js': 'text/javascript',
+ '.png': 'image/png'
+ };
+
+ if (contentType[ext]) {
+ return contentType[ext];
+ }
+ else {
+ return 'unknown';
+ }
+}
+
+function checkPath(file, base) {
+ var normFile = path.normalize(file);
+ var normBase = path.normalize(base);
+
+ if (normFile.indexOf(normBase) === 0) {
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+function serveStaticFiles(res, filepath) {
+ var base = path.join(__dirname, '..', 'static');
+ var file = path.join(base, filepath);
+
+ if (checkPath(file, base)) {
+ path.exists(file, function(exists) {
+ if (exists) {
+ var ext = path.extname(file);
+ var contentType = getContentType(ext);
+
+ fs.readFile(file, function (err, data) {
+ if (err) {
+ _500(res, err);
+ }
+ else {
+ _200(res, contentType, data);
+ }
+ });
}
else {
- res.writeHead(200, {'Content-Type': 'text/html'});
- res.write(hl.highlight(data.content, data.language));
+ _404(res);
}
- res.end('\n');
- }
- });
+ });
+ }
+ else {
+ _404(res);
+ }
}
-router
- .get('/plain/*', function(req, res, paste) {
- getPaste(true, req, res, paste);
- })
- .get('/get/*', function(req, res, paste) {
- getPaste(false, req, res, paste);
- })
- .get('/', function(req, res) {
- })
- .post('/add', function(req, res) {
- var content = '';
-
- req.on('data', function(chunk) {
- content += chunk;
+var router = bee.route({
+ "/": function(req, res) {
+ tmpl.renderHtml('submit-form.tmpl', {}, res);
+ },
+
+ "r`^/plain/([^/]+)$`": function(req, res, id) {
+ paste.get(id[0], function(data) {
+ if (data) {
+ _200(res, 'text/plain', data.content);
+ }
+ else {
+ _404(res);
+ }
+ });
+ },
+
+ "r`^/get/([^/]+)$`": function(req, res, id) {
+ paste.get(id[0], function(data) {
+ if (data) {
+ data.styles = [{name: '/static/highlight/github.css'}];
+ data.content = hl.highlight(data.content, data.language);
+
+ tmpl.renderHtml('paste.tmpl', data, res);
+ }
+ else {
+ _404(res);
+ }
});
+ },
- req.on('end', function() {
- var post = qs.parse(content);
+ "r`^/static/(.+)$`": function(req, res, filepath) {
+ serveStaticFiles(res, filepath[0]);
+ },
- generateId(function(id) {
- var data = {
- content: post.content,
- language: post.language,
- time: Date()
- };
- db.set(id, JSON.stringify(data), function(err) {
+ "/add": {
+ POST: function(req, res) {
+ parsePost(req, function(post) {
+ paste.add(post, function(err, id) {
if (err) {
- res.writeHead(500, {'Content-Type': 'text/plain'});
- res.write(err);
- res.end('\n');
+ _500(res, err);
}
else {
console.log('new paste: %s', id);
- res.writeHead(200, {'Content-Type': 'text/plain'});
- res.write(id);
- res.end('\n');
+ tmpl.renderHtml('newPaste.tmpl', {id: id}, res);
}
});
});
- });
- })
- .notFound(function(req, res) {
- res.writeHead(404, {'Content-Type': 'text/plain'});
- res.end('404: ' + req.url + ' not found.\n');
- });
-
+ },
-function kyotoOpen(err) {
- if (err) throw err;
+ GET: function(req, res) {
+ _404(res);
+ }
+ },
- http.createServer(router).listen(8080);
- console.log('Listening on port 8080...');
-}
+ "`404`": function(req, res) {
+ _404(res);
+ },
-process.on('uncaughtException', function(exeption) {
- process.exit(1);
+ "`503`": function(req, res, err) {
+ _500(res, err);
+ }
});
-process.on('exit', function() {
- db.close(function(err) { console.log(err); });
-});
+var server = function(port) {
+ port = port || config.port;
+
+ pasteInit.init(config, function(func) {
+ paste = func;
+
+ http.createServer(router).listen(port);
+ console.log('Listening on port %d...', port);
+ });
+};
+
+if (typeof module == "object" && typeof require == "function") {
+ exports.server = server;
+ exports.config = config;
+}
+if (module === require.main) {
+ server();
+}