/* SRD Website ```````````````````````````````````````````````````````````````````````````````` This is a webapp for serving an RPG SRD in a publicly available format constructed from a collection of md and configuration files in a git repository located at `srd`. */ /* ==== REQUIRES ============================================================ */ const express = require('express') const doT = require('dot') const path = require('path') const fs = require('fs') /* ==== CONFIGURATION ======================================================= */ const exp = express() const app = { config: { srd: 'srd', plugins: {}, }, live: { dictionary: {}, conf: {}, menu: '', }, express: exp, } const pub = __dirname + '/public' const views = __dirname + '/views' const routes = __dirname + '/routes' const dot = doT.process({'path': views}) try { app.config = {...app.config, ...require(__dirname + '/config.js')} } catch(err) { if (err.code === 'MODULE_NOT_FOUND') { console.error('missing config') } } exp.use(express.static(pub)) exp.use(express.static(path.join(__dirname, app.config.srd))) exp.engine('dot', (template, options, cb) => { return cb(null, dot[path.parse(template).name](options)) }) exp.set('views', views) exp.set('view engine', 'dot') /* ==== PLUGINS ============================================================= */ const plugins = [] try { fs.readdirSync('plugins').forEach(f => { let plugin_path = path.resolve('plugins', f) if (fs.lstatSync(plugin_path).isDirectory()) { console.log('plugin preload:', f) try { let plugin = { defaults: null, config: {}, log: (...args) => { console.log.apply(console, [f+':', ...args]) }, error: (...args) => { console.error.apply(console, [f+':', ...args]) }, module: require(plugin_path), } if (app.config.plugins[f]) { plugin.config = app.config.plugins[f] } plugin.defaults = o => { plugin.config = {...o, ...plugin.config} } console.log('...ok') plugins.push(plugin) } catch(err) { if (err.code === 'MODULE_NOT_FOUND') { console.error('plugin', plugin_path, 'is not a valid module') } else { console.error('...fail: ', err) } } } }) if (plugins.length === 0) { console.warn('no plugins found'); } } catch(err) { if (err.code === 'ENOENT') { console.warn('no plugins directory') } else { console.error('plugins', err) } } /* ==== CMDLINE ============================================================= */ const port = 7331 process.argv.forEach((val, index, array) => { let parts = val.split('=') let key = '' let value = '' if (parts[0].substr(0, 2) == '--') { key = parts[0].substr(2) value = parts[1] } if (key == 'port') { if (value != '') { port = Number(value) } } }) /* ==== RUN ================================================================= */ const server = exp.listen(port, async () => { const host = server.address().address const port = server.address().port for (let plugin of plugins) { try { await plugin.module(plugin, app) } catch(err) { console.error('plugin', err) } } }) process.on('SIGINT', () => { process.exit() }) process.on('exit', () => { fs.writeFileSync(path.join(__dirname + '/config.js'), 'module.exports = ' + JSON.stringify(app.config, null, '\t')) })