255 lines
7.3 KiB
JavaScript
Executable File
255 lines
7.3 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
var fs = require('fs');
|
|
var m_path = require('path');
|
|
var util = require('util');
|
|
var QCore = require('./QCore.js');
|
|
/* qwiki
|
|
Node.js based Implementation of the proposed qwiki document
|
|
*/
|
|
/*********************************
|
|
* QWiki *
|
|
*********************************/
|
|
var QWiki = function() {
|
|
QCore.call(this);
|
|
this.initialize();
|
|
}; util.inherits(QWiki, QCore);
|
|
/* QWiki.initialize()
|
|
Checks for and creates the following directories:
|
|
* wiki/
|
|
* cache/
|
|
* tmp/
|
|
|
|
Checks for and copies the following directories/files:
|
|
* index.html
|
|
* acts/
|
|
*/
|
|
QWiki.prototype.listen = function(port, cb) {
|
|
this.loadWikiIndex();
|
|
this.constructor.super_.prototype.listen.call(this, port, cb);
|
|
};
|
|
QWiki.prototype.initialize = function() {
|
|
// check if QWiki instance is running in a different directory than the module,
|
|
// and if so, copy over default files
|
|
var cwd = process.cwd();
|
|
if (cwd !== __dirname) {
|
|
console.log('Running from: ' + cwd);
|
|
// TODO: copy acts/, wiki/, and index.html from __dirname to cwd if not existing
|
|
} else {
|
|
console.log('Running from: ' + __dirname);
|
|
}
|
|
// make wiki directory
|
|
try {
|
|
var stats = fs.statSync('wiki');
|
|
if (!stats.isDirectory()) {
|
|
console.log('error, "wiki" is not a directory');
|
|
}
|
|
} catch (err) {
|
|
if (err.code == 'ENOENT') {
|
|
fs.mkdirSync('wiki');
|
|
console.log('Created "wiki/" -- this is where the wiki source files are stored');
|
|
} else {
|
|
console.log('error while loading wiki directory');
|
|
}
|
|
}
|
|
// make cache directory
|
|
try {
|
|
var stats = fs.statSync('cache');
|
|
if (!stats.isDirectory()) {
|
|
console.log('error, "cache" is not a directory');
|
|
}
|
|
} catch (err) {
|
|
if (err.code == 'ENOENT') {
|
|
fs.mkdirSync('cache');
|
|
console.log('Created "cache/" -- this is where processed wiki pages are stored as HTML');
|
|
} else {
|
|
console.log('error while loading cache');
|
|
}
|
|
}
|
|
// make tmp directory
|
|
try {
|
|
var stats = fs.statSync('tmp');
|
|
if (!stats.isDirectory()) {
|
|
console.log('error, "tmp" is not a directory');
|
|
}
|
|
} catch (err) {
|
|
if (err.code == 'ENOENT') {
|
|
fs.mkdirSync('tmp');
|
|
console.log('Created "tmp/" -- this is where uploaded files are temporarily stored');
|
|
} else {
|
|
console.log('error while loading tmp directory');
|
|
}
|
|
}
|
|
|
|
};
|
|
QWiki.prototype.loadWikiIndex = function() {
|
|
var self = this;
|
|
try {
|
|
this.wiki_index = JSON.parse(fs.readFileSync('index.json'));
|
|
} catch (e) {
|
|
this.wiki_index = { pages: {} };
|
|
console.log(e);
|
|
}
|
|
var wiki_index = this.wiki_index;
|
|
console.log('loaded indices for ' + Object.keys(this.wiki_index.pages).length + ' pages');
|
|
QCore.prototype.readFiles('wiki', function(err, file, is_dir) {
|
|
var wiki_file = file.replace('wiki/', '');
|
|
if (is_dir) {
|
|
if (wiki_file in wiki_index.pages) {
|
|
if (wiki_index.pages[wiki_file].dir != true) wiki_index.pages[wiki_file].dir = true;
|
|
} else {
|
|
wiki_index.pages[wiki_file] = { dir: true };
|
|
}
|
|
} else {
|
|
if (QCore.prototype.getExt(file) == 'qwk') {
|
|
if (wiki_file in wiki_index.pages) {
|
|
} else {
|
|
var name = wiki_file.slice(0, -4);
|
|
wiki_index.pages[name] = { format: 'md' }; // TODO: this.config.default_type
|
|
}
|
|
} else {
|
|
if (wiki_file in wiki_index.pages) {
|
|
} else {
|
|
wiki_index.pages[wiki_file] = { format: 'file' };
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
QWiki.prototype.formats = {
|
|
raw: {
|
|
name: 'raw',
|
|
fullname: 'Raw',
|
|
convert: function(source) {
|
|
return source;
|
|
},
|
|
},
|
|
html: {
|
|
name: 'html',
|
|
fullname: 'HTML',
|
|
convert: function(source) {
|
|
return source;
|
|
}
|
|
}
|
|
};
|
|
QWiki.prototype.addFormat = function(name, fullname, convertor_cb, pre_cb, post_cb) {
|
|
this.formats[name] = {
|
|
'name': name,
|
|
'fullname': fullname,
|
|
'convert': convertor_cb,
|
|
'pre': pre_cb,
|
|
'post': post_cb
|
|
};
|
|
};
|
|
QWiki.prototype.convertAndSave = function(path, name, source, cb) {
|
|
if (typeof cb === 'undefined') cb = function() {};
|
|
if (!(name in this.formats)) {
|
|
name = 'raw';
|
|
}
|
|
console.log('converting to ' + name + ' with path ' + path);
|
|
var converted = this.formats[name].convert(source);
|
|
QCore.prototype.r_mkdir(m_path.dirname('cache/'+path+'.html'), 0777, function() {
|
|
fs.writeFile('cache/'+path+'.html', converted, function(err) {
|
|
if (err) {
|
|
console.log('error writing "cache'+ path + '.html"');
|
|
} else {
|
|
console.log('wrote "cache' + path + '.html"');
|
|
}
|
|
cb();
|
|
});
|
|
});
|
|
};
|
|
QWiki.prototype.deleteCache = function(wiki_page, cb) {
|
|
fs.unlink('cache/'+wiki_page+'.html', cb);
|
|
};
|
|
QWiki.prototype.createCache = function(wiki_page, source, cb) {
|
|
if (typeof cb === 'undefined') cb = function() {};
|
|
var format = this.defaults.format;
|
|
if (typeof this.wiki_index.pages[wiki_page] !== 'undefined') {
|
|
format = this.wiki_index.pages[wiki_page].format;
|
|
}
|
|
if (!(format in this.formats)) {
|
|
format = 'raw';
|
|
}
|
|
console.log('createCache: caching ' + wiki_page + ' as ' + format);
|
|
|
|
var converted = this.formats[format].convert(source);
|
|
|
|
var path = 'cache/' + wiki_page + '.html';
|
|
|
|
QCore.prototype.r_mkdir(m_path.dirname(path), 0777, function() {
|
|
fs.writeFile(path, converted, function(err) {
|
|
if (err) {
|
|
console.log('createCache: error writing "' + path + '"');
|
|
} else {
|
|
console.log('createCache: created "' + path + '"');
|
|
}
|
|
cb(err);
|
|
});
|
|
});
|
|
};
|
|
QWiki.prototype.deletePage = function(wiki_page, cb) {
|
|
fs.unlink('wiki/'+wiki_page+'.qwk', cb);
|
|
};
|
|
QWiki.prototype.savePage = function(wiki_page, content, cb) {
|
|
var self = this;
|
|
var path = 'wiki/' + wiki_page + '.qwk';
|
|
QCore.prototype.r_mkdir(m_path.dirname(path), 0777, function() {
|
|
console.log('savePage: writing ' + path);
|
|
self.deleteCache(wiki_page, function() {
|
|
fs.writeFile(path, content, function(err) {
|
|
console.log('savePage: wrote ' + path);
|
|
cb(err);
|
|
});
|
|
});
|
|
});
|
|
};
|
|
QWiki.prototype.deleteFile = function(file, cb) {
|
|
fs.unlink('wiki/'+file, cb);
|
|
};
|
|
|
|
if (require.main === module) {
|
|
var port = 8080;
|
|
process.argv.forEach(function (val, index, array) {
|
|
var parts = val.split('=');
|
|
var key = '';
|
|
var value = '';
|
|
if (parts[0].substr(0, 2) == '--') {
|
|
key = parts[0].substr(2);
|
|
value = parts[1];
|
|
}
|
|
if (key == 'port') {
|
|
if (value == '') {
|
|
console.log(key + ' needs a value');
|
|
} else {
|
|
port = Number(value);
|
|
}
|
|
}
|
|
});
|
|
|
|
var qwiki = new QWiki();
|
|
|
|
qwiki.addMIMEtype('png', 'image/png');
|
|
qwiki.addMIMEtype('jpg', 'image/jpg');
|
|
qwiki.addMIMEtype('svg', 'image/svg+xml');
|
|
qwiki.addMIMEtype('css', 'text/css');
|
|
|
|
var m_markdownit = require('markdown-it')({
|
|
typographer: true
|
|
});
|
|
m_markdownit.use(require('markdown-it-anchor'));
|
|
m_markdownit.use(require('markdown-it-table-of-contents'), {includeLevel: "2-8"});
|
|
m_markdownit.use(require('markdown-it-deflist'));
|
|
m_markdownit.use(require('markdown-it-header-sections'));
|
|
m_markdownit.use(require('markdown-it-sup'));
|
|
qwiki.addFormat('md', 'Markdown', function(source) {
|
|
// source is a Buffer, but render seems to need a String
|
|
return m_markdownit.render(source.toString());
|
|
});
|
|
|
|
qwiki.setDefault('format', 'md');
|
|
|
|
qwiki.listen(port);
|
|
}
|
|
|
|
module.exports = QWiki;
|