enigma-bbs/core/oputil/oputil_config.js

259 lines
5.9 KiB
JavaScript

/* jslint node: true */
/* eslint-disable no-console */
'use strict';
// ENiGMA½
const resolvePath = require('../../core/misc_util.js').resolvePath;
const printUsageAndSetExitCode = require('./oputil_common.js').printUsageAndSetExitCode;
const ExitCodes = require('./oputil_common.js').ExitCodes;
const argv = require('./oputil_common.js').argv;
const getDefaultConfigPath = require('./oputil_common.js').getDefaultConfigPath;
const getHelpFor = require('./oputil_help.js').getHelpFor;
// deps
const async = require('async');
const inq = require('inquirer');
const mkdirsSync = require('fs-extra').mkdirsSync;
const fs = require('fs');
const hjson = require('hjson');
const paths = require('path');
exports.handleConfigCommand = handleConfigCommand;
function getAnswers(questions, cb) {
inq.prompt(questions).then( answers => {
return cb(answers);
});
}
const QUESTIONS = {
Intro : [
{
name : 'createNewConfig',
message : 'Create a new configuration?',
type : 'confirm',
default : false,
},
{
name : 'configPath',
message : 'Configuration path:',
default : argv.config ? argv.config : 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 askNewConfigQuestions(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 = {
name : 'Another Sample Conference',
desc : 'Another conf sample. Change me!',
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() {
if(true === argv.help) {
return printUsageAndSetExitCode(getHelpFor('Config'), ExitCodes.ERROR);
}
if(argv.new) {
askNewConfigQuestions( (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());
}
});
} else {
return printUsageAndSetExitCode(getHelpFor('Config'), ExitCodes.ERROR);
}
}