From 2e9586dee6ec156e2a57a05f0b695adfd95dbb74 Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Mon, 11 Apr 2016 22:13:16 -0600 Subject: [PATCH] oputil.js config --new: Creates a new/sample config --- oputil.js | 249 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 244 insertions(+), 5 deletions(-) diff --git a/oputil.js b/oputil.js index 5087b9b1..70f4bc1f 100755 --- a/oputil.js +++ b/oputil.js @@ -4,12 +4,19 @@ 'use strict'; // ENiGMA½ -var config = require('./core/config.js'); -var db = require('./core/database.js'); +const config = require('./core/config.js'); +const db = require('./core/database.js'); +const resolvePath = require('./core/misc_util.js').resolvePath; -var _ = require('lodash'); -var async = require('async'); -var assert = require('assert'); +// deps +const _ = require('lodash'); +const async = require('async'); +const assert = require('assert'); +const inq = require('inquirer'); +const mkdirsSync = require('fs-extra').mkdirsSync; +const fs = require('fs'); +const hjson = require('hjson'); +const paths = require('path'); var argv = require('minimist')(process.argv.slice(2)); @@ -116,6 +123,234 @@ function handleUserCommand() { } } +function getAnswers(questions, cb) { + inq.prompt(questions, cb); +} + +function getDefaultConfigPath() { + return resolvePath('~/.config/enigma-bbs/config2.hjson'); +} + +const QUESTIONS = { + Intro : [ + { + name : 'createNewConfig', + message : 'Create a new configuration?', + type : 'confirm', + default : false, + }, + { + name : 'configPath', + message : 'Configuration path:', + default : getDefaultConfigPath(), + when : answers => answers.createNewConfig + }, + ], + + OverwriteConfig : [ + { + name : 'overwriteConfig', + message : 'Config file exists. Overwrite?', + type : 'confirm', + default : false, + } + ], + + Basic : [ + { + name : 'boardName', + message : 'BBS name:', + default : 'New ENiGMA½ BBS', + }, + ], + + Misc : [ + { + name : 'loggingLevel', + message : 'Logging level:', + type : 'list', + choices : [ 'Error', 'Warn', 'Info', 'Debug', 'Trace' ], + default : 2, + filter : s => s.toLowerCase(), + }, + { + name : 'sevenZipExe', + message : '7-Zip executable:', + type : 'list', + choices : [ '7z', '7za', 'None' ] + } + ], + + MessageConfAndArea : [ + { + name : 'msgConfName', + message : 'First message conference:', + default : 'Local', + }, + { + name : 'msgConfDesc', + message : 'Conference description:', + default : 'Local Areas', + }, + { + name : 'msgAreaName', + message : 'First area in message conference:', + default : 'General', + }, + { + name : 'msgAreaDesc', + message : 'Area description:', + default : 'General chit-chat', + } + ] +}; + +function makeMsgConfAreaName(s) { + return s.toLowerCase().replace(/\s+/g, '_'); +} + +function askQuestions(cb) { + + const ui = new inq.ui.BottomBar(); + + let configPath; + let config; + + async.waterfall( + [ + function intro(callback) { + getAnswers(QUESTIONS.Intro, answers => { + if(!answers.createNewConfig) { + return callback('exit'); + } + + // adjust for ~ and the like + configPath = resolvePath(answers.configPath); + + const configDir = paths.dirname(configPath); + mkdirsSync(configDir); + + // + // Check if the file exists and can be written to + // + fs.access(configPath, fs.F_OK | fs.W_OK, err => { + if(err) { + if('EACCES' === err.code) { + ui.log.write(`${configPath} cannot be written to`); + callback('exit'); + } else if('ENOENT' === err.code) { + callback(null, false); + } + } else { + callback(null, true); // exists + writable + } + }); + }); + }, + function promptOverwrite(needPrompt, callback) { + if(needPrompt) { + getAnswers(QUESTIONS.OverwriteConfig, answers => { + callback(answers.overwriteConfig ? null : 'exit'); + }); + } else { + callback(null); + } + }, + function basic(callback) { + getAnswers(QUESTIONS.Basic, answers => { + config = { + general : { + boardName : answers.boardName, + }, + }; + + callback(null); + }); + }, + function msgConfAndArea(callback) { + getAnswers(QUESTIONS.MessageConfAndArea, answers => { + config.messageConferences = {}; + + const confName = makeMsgConfAreaName(answers.msgConfName); + const areaName = makeMsgConfAreaName(answers.msgAreaName); + + config.messageConferences[confName] = { + name : answers.msgConfName, + desc : answers.msgConfDesc, + sort : 1, + default : true, + }; + + config.messageConferences.another_sample_conf = { + name : 'Another Sample Conference', + desc : 'Another conference example. Change me!', + sort : 2, + }; + + config.messageConferences[confName].areas = {}; + config.messageConferences[confName].areas[areaName] = { + name : answers.msgAreaName, + desc : answers.msgAreaDesc, + sort : 1, + default : true, + }; + + config.messageConferences.another_sample_conf = { + areas : { + another_sample_area : { + name : 'Another Sample Area', + desc : 'Another area example. Change me!', + sort : 2 + } + } + }; + + callback(null); + }); + }, + function misc(callback) { + getAnswers(QUESTIONS.Misc, answers => { + if('None' !== answers.sevenZipExe) { + config.archivers = { + zip : { + compressCmd : answers.sevenZipExe, + decompressCmd : answers.sevenZipExe, + } + }; + } + + config.logging = { + level : answers.loggingLevel, + }; + + callback(null); + }); + } + ], + err => { + cb(err, configPath, config); + } + ); +} + +function handleConfigCommand() { + askQuestions( (err, configPath, config) => { + if(err) { + return; + } + + config = hjson.stringify(config, { bracesSameLine : true, spaces : '\t' } ); + + try { + fs.writeFileSync(configPath, config, 'utf8'); + console.info('Configuration generated'); + } catch(e) { + console.error('Exception attempting to create config: ' + e.toString()); + } + }); + +} + function main() { process.exitCode = ExitCodes.SUCCESS; @@ -135,6 +370,10 @@ function main() { case 'user' : handleUserCommand(); break; + + case 'config' : + handleConfigCommand(); + break; default: printUsage('');