QWiki/acts/default.js

132 lines
4.8 KiB
JavaScript

var fs = require('fs');
module.exports = function(qwiki) {
qwiki.rule('', '@@CONTENT@@', function(req, res, instance, next) {
var area = req.area;
if (area == '') {
area = 'front';
}
// instance.pos, instance.offset, instance.indices
var cache_path = 'cache/'+area+'.html';
qwiki.readFile(res, cache_path, function(type, err) {
if (type == 'FNF') {
// cache does not exist - is there a wiki source?
var wiki_path = 'wiki/'+area+'.qwk';
fs.stat(wiki_path, function(err, stats) {
// TODO: stats.isFile()
if (err && err.code == 'ENOENT') {
// the wiki entry does not exist
res.write(area + ' does not exist yet');
next();
} else if (err) {
// error while statting wiki entry
res.write(area + ': ' + err.code);
next();
} else {
// wiki entry exists!
fs.readFile(wiki_path, function(err, data) {
if (err) {
res.write(area + ': ' + err.code);
next();
} else {
qwiki.convertAndSave(area, (req.area in qwiki.wiki_index.pages ? qwiki.wiki_index.pages[req.area].format : qwiki.getDefault('format')), data, function() {
qwiki.readFile(res, wiki_path, function(type, err) {
if (type == 'FNF') {
res.write('error while creating cache');
next();
} else if (err) {
res.write(area + ': ' + err.code);
next();
} else {
next();
}
});
});
}
});
}
});
} else if (err) {
res.write(area + ': ' + err.code);
next();
} else {
next();
}
});
});
qwiki.rule('', '@@TITLE@@', function(req, res, instance, next) {
res.write('qwiki ' + req.area);
next();
});
qwiki.rule('', '@@PAGE@@', function(req, res, instance, next) {
res.write(req.area);
next();
});
qwiki.rule('', '@@CONTROLS@@', function(req, res, instance, next) {
res.write('<li><a href="'+req.area+'/edit"><img src="/edit.png">Edit</a></li><li><a href="'+req.area+'/new"><img src="/new.png">New Page</a></li><li><a href="'+req.area+'/upload"><img src="/upload.png">Upload</a></li><li><a href="./index"><img src="/file_dir.png">Index</a></li>');
next();
});
qwiki.rule('', '@@CRUMBS@@', function(req, res, instance, next) {
var parts = req.area.split('/');
var path = '';
parts[0] = '>';
for (var i = 0; i < parts.length; i++) {
path += (i == 0 ? '/' : parts[i]);
res.write('<li><a href="'+path+'">'+parts[i]+'</a></li>');
path += (i == 0 ? '' : '/');
}
next();
});
qwiki.rule('', '@@FOOTER@@', function(req, res, instance, next) {
res.write('<a href="http://kettek.net/qwiki">QWiki</a> Copyright 2016 <a href="http://kettek.net">kts of kettek</a>');
next();
});
qwiki.act('', function(req, res) {
var ext = qwiki.getExt(req.area);
var mimetype = qwiki.getMIMEtype(qwiki.getExt(req.area));
if (mimetype == '') mimetype = 'application/octet-stream';
if (ext != '') { // write file on disk directly
var path = 'wiki/'+req.area;
fs.stat(path, function(err, stat) {
if (err == null) {
// TODO: etags should actually be based on binary data(CRC32, etc.), not last modified
// TODO: files should not be stat()`d each call, but should be cached and updated when the file updates (how? browser-based upload interface?)
var mtime = stat.mtime.getTime();
if (!(path in qwiki.etags) || qwiki.etags[path] != mtime) {
qwiki.etags[path] = mtime;
}
if ('if-none-match' in req.headers && req.headers['if-none-match'] == qwiki.etags[path]) {
res.writeHead(304, "Not Modified");
res.end();
} else {
res.writeHead(200, "OK", {
"Content-Type": mimetype,
"Content-Length": stat.size,
"ETag": mtime
});
var rs = fs.createReadStream(path);
rs.on('data', function(chunk) {
res.write(chunk);
});
rs.on('end', function() {
res.end();
});
}
} else if (err.code == 'ENOENT') {
res.writeHead(404);
res.end();
} else {
console.log(err);
res.write(err.message);
res.end();
}
});
} else { // no mimetype/ext, it must be a wiki entry
res.writeHead(200, "OK", {
"Content-Type": "text/html",
});
qwiki.parsePage('', '', req, res);
}
});
};