var fs = require('fs'); module.exports = function(qwiki) { qwiki.rule('', '@@CONTENT@@', function(req, res, instance, next) { if (req.area == '/' || req.area == '') { qwiki.rules['updates']['@@CONTENT@@'](req, res, instance, next); return; } else { for (var listing in qwiki.listings) { if (req.area.substring(1, listing.length+1) == listing) { req.listing = listing; qwiki.rules['listing']['@@CONTENT@@'](req, res, instance, next); return; } } } // instance.pos, instance.offset, instance.indices var cache_path = 'cache/'+req.area+'.html'; res.write('
'); res.write('
'); qwiki.readFile(res, cache_path, function(type, err) { if (type == 'FNF') { // cache does not exist - is there a wiki source? var wiki_path = 'wiki/'+req.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(req.area + ' does not exist yet'); res.write('
'); next(); } else if (err) { // error while statting wiki entry res.write(req.area + ': ' + err.code); res.write(''); next(); } else { // wiki entry exists! fs.readFile(wiki_path, function(err, data) { if (err) { res.write(req.area + ': ' + err.code); res.write(''); next(); } else { qwiki.convertAndSave(req.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'); res.write(''); next(); } else if (err) { res.write(req.area + ': ' + err.code); res.write(''); next(); } else { res.write(''); next(); } }); }); } }); } }); } else if (err) { res.write(req.area + ': ' + err.code); res.write(''); next(); } else { res.write(''); 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('', '@@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('
  • '+parts[i]+'
  • '); path += (i == 0 ? '' : '/'); } next(); }); qwiki.rule('', '@@FOOTER@@', function(req, res, instance, next) { res.write('qwiki Copyright 2015 kts of kettek'); next(); }); qwiki.rule('', '@@QAT@@', function(req, res, instance, next) { var d = new Date; d.setHours(0, 0, 0, 0, 0); res.write(qwiki.qats[d % (qwiki.qats.length-1)].render); 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; } res.setHeader("Access-Control-Allow-Origin", "*"); //res.header("Access-Control-Allow-Credentials", "true"); res.setHeader("Access-Control-Allow-Headers", "Origin,Content-Type, Authorization, x-id, Content-Length, X-Requested-With"); res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); 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 { var path = 'wiki/'+req.area+'.qwk'; fs.stat(path, function(err, stat) { if (err == null) { res.writeHead(200, "OK", { "Content-Type": "text/html", }); qwiki.parsePage('', '', req, res); } else { var path = 'wiki/'+req.area+'/index.html'; fs.stat(path, function(err, stat) { if (err == null) { if (req.url[req.url.length-1] !== '/') { res.writeHead(302, { 'Location': req.url+'/' }); res.end(); } else { var rstream = fs.createReadStream(path); rstream.on('error', function(err) { res.writeHead(500); res.end(); }); res.statusCode = 200; rstream.pipe(res); } } else { res.writeHead(200, "OK", { "Content-Type": "text/html", }); qwiki.parsePage('', '', req, res); } }); } }); } }); };