Merge branch 'master' of ssh://numinibsd/git/base/enigma-bbs
This commit is contained in:
commit
ab596842d6
|
@ -2,15 +2,27 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
//
|
//
|
||||||
// ANSI Terminal Support
|
// ANSI Terminal Support Resources
|
||||||
//
|
//
|
||||||
// Resources:
|
// ANSI-BBS
|
||||||
// * http://ansi-bbs.org/
|
// * http://ansi-bbs.org/
|
||||||
|
//
|
||||||
|
// CTerm / SyncTERM
|
||||||
|
// * https://github.com/protomouse/synchronet/blob/master/src/conio/cterm.txt
|
||||||
|
//
|
||||||
|
// BananaCom
|
||||||
|
// * http://www.bbsdocumentary.com/library/PROGRAMS/GRAPHICS/ANSI/bansi.txt
|
||||||
|
//
|
||||||
|
// ANSI.SYS
|
||||||
// * http://www.bbsdocumentary.com/library/PROGRAMS/GRAPHICS/ANSI/ansisys.txt
|
// * http://www.bbsdocumentary.com/library/PROGRAMS/GRAPHICS/ANSI/ansisys.txt
|
||||||
|
// * http://academic.evergreen.edu/projects/biophysics/technotes/program/ansi_esc.htm
|
||||||
|
//
|
||||||
|
// General
|
||||||
// * http://en.wikipedia.org/wiki/ANSI_escape_code
|
// * http://en.wikipedia.org/wiki/ANSI_escape_code
|
||||||
// * https://github.com/chjj/term.js/blob/master/src/term.js
|
|
||||||
// * http://www.inwap.com/pdp10/ansicode.txt
|
// * http://www.inwap.com/pdp10/ansicode.txt
|
||||||
//
|
//
|
||||||
|
// Other Implementations
|
||||||
|
// * https://github.com/chjj/term.js/blob/master/src/term.js
|
||||||
|
|
||||||
// ENiGMA½
|
// ENiGMA½
|
||||||
const miscUtil = require('./misc_util.js');
|
const miscUtil = require('./misc_util.js');
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
// ENiGMA½
|
// ENiGMA½
|
||||||
const Config = require('./config.js').config;
|
const Config = require('./config.js').config;
|
||||||
|
const stringFormat = require('./string_format.js');
|
||||||
|
|
||||||
// base/modules
|
// base/modules
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
@ -124,7 +125,7 @@ module.exports = class ArchiveUtil {
|
||||||
|
|
||||||
let args = _.clone(archiver.compressArgs); // don't muck with orig
|
let args = _.clone(archiver.compressArgs); // don't muck with orig
|
||||||
for(let i = 0; i < args.length; ++i) {
|
for(let i = 0; i < args.length; ++i) {
|
||||||
args[i] = args[i].format({
|
args[i] = stringFormat(args[i], {
|
||||||
archivePath : archivePath,
|
archivePath : archivePath,
|
||||||
fileList : files.join(' '),
|
fileList : files.join(' '),
|
||||||
});
|
});
|
||||||
|
@ -144,7 +145,7 @@ module.exports = class ArchiveUtil {
|
||||||
|
|
||||||
let args = _.clone(archiver.decompressArgs); // don't muck with orig
|
let args = _.clone(archiver.decompressArgs); // don't muck with orig
|
||||||
for(let i = 0; i < args.length; ++i) {
|
for(let i = 0; i < args.length; ++i) {
|
||||||
args[i] = args[i].format({
|
args[i] = stringFormat(args[i], {
|
||||||
archivePath : archivePath,
|
archivePath : archivePath,
|
||||||
extractPath : extractPath,
|
extractPath : extractPath,
|
||||||
});
|
});
|
||||||
|
|
21
core/bbs.js
21
core/bbs.js
|
@ -128,10 +128,10 @@ function initialize(cb) {
|
||||||
if(err) {
|
if(err) {
|
||||||
console.error('Could not create path: ' + conf.config.paths[pathKey] + ': ' + err.toString());
|
console.error('Could not create path: ' + conf.config.paths[pathKey] + ': ' + err.toString());
|
||||||
}
|
}
|
||||||
next(err);
|
return next(err);
|
||||||
});
|
});
|
||||||
}, function dirCreationComplete(err) {
|
}, function dirCreationComplete(err) {
|
||||||
callback(err);
|
return callback(err);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function basicInit(callback) {
|
function basicInit(callback) {
|
||||||
|
@ -142,22 +142,19 @@ function initialize(cb) {
|
||||||
|
|
||||||
process.on('SIGINT', shutdownSystem);
|
process.on('SIGINT', shutdownSystem);
|
||||||
|
|
||||||
// Init some extensions
|
return callback(null);
|
||||||
require('string-format').extend(String.prototype, require('./string_util.js').stringFormatExtensions);
|
|
||||||
|
|
||||||
callback(null);
|
|
||||||
},
|
},
|
||||||
function initDatabases(callback) {
|
function initDatabases(callback) {
|
||||||
database.initializeDatabases(callback);
|
return database.initializeDatabases(callback);
|
||||||
},
|
},
|
||||||
function initStatLog(callback) {
|
function initStatLog(callback) {
|
||||||
require('./stat_log.js').init(callback);
|
return require('./stat_log.js').init(callback);
|
||||||
},
|
},
|
||||||
function initThemes(callback) {
|
function initThemes(callback) {
|
||||||
// Have to pull in here so it's after Config init
|
// Have to pull in here so it's after Config init
|
||||||
require('./theme.js').initAvailableThemes(function onThemesInit(err, themeCount) {
|
require('./theme.js').initAvailableThemes(function onThemesInit(err, themeCount) {
|
||||||
logger.log.info({ themeCount : themeCount }, 'Themes initialized');
|
logger.log.info({ themeCount : themeCount }, 'Themes initialized');
|
||||||
callback(err);
|
return callback(err);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function loadSysOpInformation(callback) {
|
function loadSysOpInformation(callback) {
|
||||||
|
@ -204,10 +201,10 @@ function initialize(cb) {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
function initMCI(callback) {
|
function initMCI(callback) {
|
||||||
require('./predefined_mci.js').init(callback);
|
return require('./predefined_mci.js').init(callback);
|
||||||
},
|
},
|
||||||
function readyMessageNetworkSupport(callback) {
|
function readyMessageNetworkSupport(callback) {
|
||||||
require('./msg_network.js').startup(callback);
|
return require('./msg_network.js').startup(callback);
|
||||||
},
|
},
|
||||||
function readyEventScheduler(callback) {
|
function readyEventScheduler(callback) {
|
||||||
const EventSchedulerModule = require('./event_scheduler.js').EventSchedulerModule;
|
const EventSchedulerModule = require('./event_scheduler.js').EventSchedulerModule;
|
||||||
|
@ -218,7 +215,7 @@ function initialize(cb) {
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
function onComplete(err) {
|
function onComplete(err) {
|
||||||
cb(err);
|
return cb(err);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -292,7 +292,17 @@ function getDefaultConfig() {
|
||||||
},
|
},
|
||||||
|
|
||||||
logging : {
|
logging : {
|
||||||
level : 'debug'
|
level : 'debug',
|
||||||
|
|
||||||
|
rotatingFile : { // set to 'disabled' or false to disable
|
||||||
|
type : 'rotating-file',
|
||||||
|
fileName : 'enigma-bbs.log',
|
||||||
|
period : '1d',
|
||||||
|
count : 3,
|
||||||
|
level : 'debug',
|
||||||
|
}
|
||||||
|
|
||||||
|
// :TODO: syslog - https://github.com/mcavage/node-bunyan-syslog
|
||||||
},
|
},
|
||||||
|
|
||||||
debug : {
|
debug : {
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
/* jslint node: true */
|
/* jslint node: true */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
|
||||||
|
const stringFormat = require('./string_format.js');
|
||||||
|
|
||||||
const events = require('events');
|
const events = require('events');
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const pty = require('ptyw.js');
|
const pty = require('ptyw.js');
|
||||||
|
@ -100,7 +103,7 @@ Door.prototype.run = function() {
|
||||||
let args = _.clone(self.exeInfo.args); // we need a copy so the original is not modified
|
let args = _.clone(self.exeInfo.args); // we need a copy so the original is not modified
|
||||||
|
|
||||||
for(let i = 0; i < args.length; ++i) {
|
for(let i = 0; i < args.length; ++i) {
|
||||||
args[i] = self.exeInfo.args[i].format({
|
args[i] = stringFormat(self.exeInfo.args[i], {
|
||||||
dropFile : self.exeInfo.dropFile,
|
dropFile : self.exeInfo.dropFile,
|
||||||
node : self.exeInfo.node.toString(),
|
node : self.exeInfo.node.toString(),
|
||||||
srvPort : sockServer ? sockServer.address().port.toString() : '-1',
|
srvPort : sockServer ? sockServer.address().port.toString() : '-1',
|
||||||
|
|
43
core/fse.js
43
core/fse.js
|
@ -2,17 +2,16 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// ENiGMA½
|
// ENiGMA½
|
||||||
const MenuModule = require('../core/menu_module.js').MenuModule;
|
const MenuModule = require('./menu_module.js').MenuModule;
|
||||||
const ViewController = require('../core/view_controller.js').ViewController;
|
const ViewController = require('./view_controller.js').ViewController;
|
||||||
const ansi = require('../core/ansi_term.js');
|
const ansi = require('./ansi_term.js');
|
||||||
const theme = require('../core/theme.js');
|
const theme = require('./theme.js');
|
||||||
const Message = require('../core/message.js');
|
const Message = require('./message.js');
|
||||||
const getMessageAreaByTag = require('../core/message_area.js').getMessageAreaByTag;
|
const updateMessageAreaLastReadId = require('./message_area.js').updateMessageAreaLastReadId;
|
||||||
const updateMessageAreaLastReadId = require('../core/message_area.js').updateMessageAreaLastReadId;
|
const getUserIdAndName = require('./user.js').getUserIdAndName;
|
||||||
const getUserIdAndName = require('../core/user.js').getUserIdAndName;
|
const cleanControlCodes = require('./string_util.js').cleanControlCodes;
|
||||||
const cleanControlCodes = require('../core/string_util.js').cleanControlCodes;
|
|
||||||
const StatLog = require('./stat_log.js');
|
const StatLog = require('./stat_log.js');
|
||||||
|
const stringFormat = require('./string_format.js');
|
||||||
|
|
||||||
// deps
|
// deps
|
||||||
const async = require('async');
|
const async = require('async');
|
||||||
|
@ -851,6 +850,21 @@ function FullScreenEditorModule(options) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.getQuoteByHeader = function() {
|
||||||
|
let quoteFormat = this.menuConfig.config.quoteFormats;
|
||||||
|
if(Array.isArray(quoteFormat)) {
|
||||||
|
quoteFormat = quoteFormat[ Math.floor(Math.random() * quoteFormat.length) ];
|
||||||
|
} else if(!_.isString(quoteFormat)) {
|
||||||
|
quoteFormat = 'On {dateTime} {userName} said...';
|
||||||
|
}
|
||||||
|
|
||||||
|
const dtFormat = this.menuConfig.config.quoteDateTimeFormat || self.client.currentTheme.helpers.getDateTimeFormat();
|
||||||
|
return stringFormat(quoteFormat, {
|
||||||
|
dateTime : moment(self.replyToMessage.modTimestamp).format(dtFormat),
|
||||||
|
userName : self.replyToMessage.fromUserName,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
this.menuMethods = {
|
this.menuMethods = {
|
||||||
//
|
//
|
||||||
// Validation stuff
|
// Validation stuff
|
||||||
|
@ -917,14 +931,7 @@ function FullScreenEditorModule(options) {
|
||||||
|
|
||||||
if(self.newQuoteBlock) {
|
if(self.newQuoteBlock) {
|
||||||
self.newQuoteBlock = false;
|
self.newQuoteBlock = false;
|
||||||
|
quoteMsgView.addText(self.getQuoteByHeader());
|
||||||
// :TODO: Make date/time format avail as FSE config -- also the line itself!
|
|
||||||
var dtFormat = self.client.currentTheme.helpers.getDateTimeFormat();
|
|
||||||
quoteMsgView.addText(
|
|
||||||
'On {0} {1} said...'.format(
|
|
||||||
moment(self.replyToMessage.modTimestamp).format(dtFormat),
|
|
||||||
self.replyToMessage.fromUserName)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var quoteText = self.viewControllers.quoteBuilder.getView(3).getItem(formData.value.quote);
|
var quoteText = self.viewControllers.quoteBuilder.getView(3).getItem(formData.value.quote);
|
||||||
|
|
105
core/logger.js
105
core/logger.js
|
@ -1,63 +1,74 @@
|
||||||
/* jslint node: true */
|
/* jslint node: true */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var bunyan = require('bunyan');
|
// deps
|
||||||
var paths = require('path');
|
const bunyan = require('bunyan');
|
||||||
var fs = require('fs');
|
const paths = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
const _ = require('lodash');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = class Log {
|
||||||
init : function() {
|
|
||||||
var Config = require('./config.js').config;
|
|
||||||
//var ringBufferLimit = miscUtil.valueWithDefault(config.logRingBufferLimit, 100);
|
|
||||||
var logPath = Config.paths.logs;
|
|
||||||
|
|
||||||
//
|
static init() {
|
||||||
// Create something a bit more friendly if the log directory cannot be used
|
const Config = require('./config.js').config;
|
||||||
//
|
const logPath = Config.paths.logs;
|
||||||
// :TODO: this seems cheesy...
|
|
||||||
var logPathError;
|
const err = this.checkLogPath(logPath);
|
||||||
try {
|
if(err) {
|
||||||
var pathStat = fs.statSync(logPath);
|
console.error(err.message); // eslint-disable-line no-console
|
||||||
if(!pathStat.isDirectory()) {
|
return process.exit();
|
||||||
logPathError = logPath + ' is not a directory!';
|
|
||||||
}
|
|
||||||
} catch(e) {
|
|
||||||
if('ENOENT' === e.code) {
|
|
||||||
logPathError = 'No such file or directory: ' + logPath;
|
|
||||||
} else {
|
|
||||||
logPathError = e.message;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(logPathError) {
|
const logStreams = [];
|
||||||
console.error(logPathError);
|
if(_.isObject(Config.logging.rotatingFile)) {
|
||||||
process.exit();
|
Config.logging.rotatingFile.path = paths.join(logPath, Config.logging.rotatingFile.fileName);
|
||||||
|
logStreams.push(Config.logging.rotatingFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
var logFile = paths.join(logPath, 'enigma-bbs.log');
|
const serializers = {
|
||||||
|
err : bunyan.stdSerializers.err, // handle 'err' fields with stack/etc.
|
||||||
|
};
|
||||||
|
|
||||||
// :TODO: make this configurable --
|
// try to remove sensitive info by default, e.g. 'password' fields
|
||||||
// user should be able to configure rotations, levels to file vs ringBuffer,
|
[ 'formData', 'formValue' ].forEach(keyName => {
|
||||||
// completely disable logging, etc.
|
serializers[keyName] = (fd) => Log.hideSensitive(fd);
|
||||||
|
});
|
||||||
|
|
||||||
this.log = bunyan.createLogger({
|
this.log = bunyan.createLogger({
|
||||||
name : 'ENiGMA½ BBS',
|
name : 'ENiGMA½ BBS',
|
||||||
streams : [
|
streams : logStreams,
|
||||||
{
|
serializers : serializers,
|
||||||
type : 'rotating-file',
|
|
||||||
path : logFile,
|
|
||||||
period : Config.logging.period || '1d',
|
|
||||||
count : 3,
|
|
||||||
level : Config.logging.level || 'debug',
|
|
||||||
}
|
|
||||||
/*,
|
|
||||||
{
|
|
||||||
type : 'raw',
|
|
||||||
stream : ringBuffer,
|
|
||||||
level : 'trace'
|
|
||||||
}*/
|
|
||||||
],
|
|
||||||
serializers: { err : bunyan.stdSerializers.err } // handle 'err' fields with stack/etc.
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static checkLogPath(logPath) {
|
||||||
|
try {
|
||||||
|
if(!fs.statSync(logPath).isDirectory()) {
|
||||||
|
return new Error(`${logPath} is not a directory`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
} catch(e) {
|
||||||
|
if('ENOENT' === e.code) {
|
||||||
|
return new Error(`${logPath} does not exist`);
|
||||||
|
}
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static hideSensitive(obj) {
|
||||||
|
try {
|
||||||
|
//
|
||||||
|
// Use a regexp -- we don't know how nested fields we want to seek and destroy may be
|
||||||
|
//
|
||||||
|
return JSON.parse(
|
||||||
|
JSON.stringify(obj).replace(/"(password)"\s?:\s?"([^"]+)"/, (match, valueName) => {
|
||||||
|
return `"${valueName}":"********"`;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} catch(e) {
|
||||||
|
// be safe and return empty obj!
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -66,7 +66,7 @@ var SPECIAL_KEY_MAP_DEFAULT = {
|
||||||
'line feed' : [ 'return' ],
|
'line feed' : [ 'return' ],
|
||||||
exit : [ 'esc' ],
|
exit : [ 'esc' ],
|
||||||
backspace : [ 'backspace' ],
|
backspace : [ 'backspace' ],
|
||||||
'delete' : [ 'del' ],
|
delete : [ 'del' ],
|
||||||
tab : [ 'tab' ],
|
tab : [ 'tab' ],
|
||||||
up : [ 'up arrow' ],
|
up : [ 'up arrow' ],
|
||||||
down : [ 'down arrow' ],
|
down : [ 'down arrow' ],
|
||||||
|
@ -802,7 +802,6 @@ function MultiLineEditTextView(options) {
|
||||||
self.emitEditPosition();
|
self.emitEditPosition();
|
||||||
};
|
};
|
||||||
|
|
||||||
//this.keyPressClearLine = function() {
|
|
||||||
this.keyPressDeleteLine = function() {
|
this.keyPressDeleteLine = function() {
|
||||||
if(self.textLines.length > 0) {
|
if(self.textLines.length > 0) {
|
||||||
self.removeCharactersFromText(
|
self.removeCharactersFromText(
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
// ENiGMA½
|
// ENiGMA½
|
||||||
const msgArea = require('./message_area.js');
|
const msgArea = require('./message_area.js');
|
||||||
const MenuModule = require('./menu_module.js').MenuModule;
|
const MenuModule = require('./menu_module.js').MenuModule;
|
||||||
const ViewController = require('../core/view_controller.js').ViewController;
|
const ViewController = require('./view_controller.js').ViewController;
|
||||||
|
const stringFormat = require('./string_format.js');
|
||||||
|
|
||||||
// deps
|
// deps
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
|
@ -121,15 +122,6 @@ function NewScanModule(options) {
|
||||||
const sortedAreas = msgArea.getSortedAvailMessageAreasByConfTag(conf.confTag, { client : self.client } );
|
const sortedAreas = msgArea.getSortedAvailMessageAreasByConfTag(conf.confTag, { client : self.client } );
|
||||||
const currentArea = sortedAreas[self.currentScanAux.area];
|
const currentArea = sortedAreas[self.currentScanAux.area];
|
||||||
|
|
||||||
function getFormatObj() {
|
|
||||||
return {
|
|
||||||
confName : conf.conf.name,
|
|
||||||
confDesc : conf.conf.desc,
|
|
||||||
areaName : currentArea.area.name,
|
|
||||||
areaDesc : currentArea.area.desc
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Scan and update index until we find something. If results are found,
|
// Scan and update index until we find something. If results are found,
|
||||||
// we'll goto the list module & show them.
|
// we'll goto the list module & show them.
|
||||||
|
@ -147,7 +139,12 @@ function NewScanModule(options) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
function updateStatusScanStarted(callback) {
|
function updateStatusScanStarted(callback) {
|
||||||
self.updateScanStatus(self.scanStartFmt.format(getFormatObj()));
|
self.updateScanStatus(stringFormat(self.scanStartFmt, {
|
||||||
|
confName : conf.conf.name,
|
||||||
|
confDesc : conf.conf.desc,
|
||||||
|
areaName : currentArea.area.name,
|
||||||
|
areaDesc : currentArea.area.desc
|
||||||
|
}));
|
||||||
return callback(null);
|
return callback(null);
|
||||||
},
|
},
|
||||||
function getNewMessagesCountInArea(callback) {
|
function getNewMessagesCountInArea(callback) {
|
||||||
|
|
|
@ -9,6 +9,7 @@ var ServerModule = require('../server_module.js').ServerModule;
|
||||||
var userLogin = require('../user_login.js').userLogin;
|
var userLogin = require('../user_login.js').userLogin;
|
||||||
var enigVersion = require('../../package.json').version;
|
var enigVersion = require('../../package.json').version;
|
||||||
var theme = require('../theme.js');
|
var theme = require('../theme.js');
|
||||||
|
const stringFormat = require('../string_format.js');
|
||||||
|
|
||||||
var ssh2 = require('ssh2');
|
var ssh2 = require('ssh2');
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
|
@ -106,11 +107,11 @@ function SSHClient(clientConn) {
|
||||||
if(err) {
|
if(err) {
|
||||||
interactivePrompt.prompt = 'Access denied\n' + ctx.username + '\'s password: ';
|
interactivePrompt.prompt = 'Access denied\n' + ctx.username + '\'s password: ';
|
||||||
} else {
|
} else {
|
||||||
var newUserNameList = '"' + (Config.users.newUserNames || []).join(', ') + '"';
|
const newUserNameList = _.has(Config, 'users.newUserNames') && Config.users.newUserNames.length > 0 ?
|
||||||
interactivePrompt.prompt =
|
Config.users.newUserNames.map(newName => '"' + newName + '"').join(', ') :
|
||||||
'Access denied\n' +
|
'(No new user names enabled!)';
|
||||||
artInfo.data.format( { newUserNames : newUserNameList } ) +
|
|
||||||
'\n' + ctx.username + '\'s password: ';
|
interactivePrompt.prompt = `Access denied\n${stringFormat(artInfo.data, { newUserNames : newUserNameList })}\n${ctx.username}'s password'`;
|
||||||
}
|
}
|
||||||
return ctx.prompt(interactivePrompt, retryPrompt);
|
return ctx.prompt(interactivePrompt, retryPrompt);
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
const EnigError = require('./enig_error.js').EnigError;
|
const EnigError = require('./enig_error.js').EnigError;
|
||||||
const pad = require('./string_util.js').pad;
|
const pad = require('./string_util.js').pad;
|
||||||
const stylizeString = require('./string_util.js').stylizeString;
|
const stylizeString = require('./string_util.js').stylizeString;
|
||||||
|
const renderStringLength = require('./string_util.js').renderStringLength;
|
||||||
|
const renderSubstr = require('./string_util.js').renderSubstr;
|
||||||
|
|
||||||
// deps
|
// deps
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
|
@ -124,7 +126,7 @@ function getPadAlign(align) {
|
||||||
function formatString(value, tokens) {
|
function formatString(value, tokens) {
|
||||||
const fill = tokens.fill || (tokens['0'] ? '0' : ' ');
|
const fill = tokens.fill || (tokens['0'] ? '0' : ' ');
|
||||||
const align = tokens.align || (tokens['0'] ? '=' : '<');
|
const align = tokens.align || (tokens['0'] ? '=' : '<');
|
||||||
const precision = Number(tokens.precision || value.length); // :TODO: consider pipe/ANSI length
|
const precision = Number(tokens.precision || renderStringLength(value) + 1);
|
||||||
|
|
||||||
if('' !== tokens.type && 's' !== tokens.type) {
|
if('' !== tokens.type && 's' !== tokens.type) {
|
||||||
throw new ValueError(`Unknown format code "${tokens.type}" for String object`);
|
throw new ValueError(`Unknown format code "${tokens.type}" for String object`);
|
||||||
|
@ -146,7 +148,7 @@ function formatString(value, tokens) {
|
||||||
throw new ValueError('"=" alignment not allowed in string format specifier');
|
throw new ValueError('"=" alignment not allowed in string format specifier');
|
||||||
}
|
}
|
||||||
|
|
||||||
return pad(value.slice(0, precision), parseInt(tokens.width), fill, getPadAlign(align));
|
return pad(renderSubstr(value, 0, precision), Number(tokens.width), fill, getPadAlign(align));
|
||||||
}
|
}
|
||||||
|
|
||||||
const FormatNumRegExp = {
|
const FormatNumRegExp = {
|
||||||
|
@ -167,7 +169,10 @@ function formatNumberHelper(n, precision, type) {
|
||||||
case 'x' : return n.toString(16);
|
case 'x' : return n.toString(16);
|
||||||
case 'e' : return n.toExponential(precision).replace(FormatNumRegExp.ExponentRep, '$&0');
|
case 'e' : return n.toExponential(precision).replace(FormatNumRegExp.ExponentRep, '$&0');
|
||||||
case 'f' : return n.toFixed(precision);
|
case 'f' : return n.toFixed(precision);
|
||||||
case 'g' : return n.toPrecision(precision || 1);
|
case 'g' :
|
||||||
|
// we don't want useless trailing zeros. parseFloat -> back to string fixes this for us
|
||||||
|
return parseFloat(n.toPrecision(precision || 1)).toString();
|
||||||
|
|
||||||
case '%' : return formatNumberHelper(n * 100, precision, 'f') + '%';
|
case '%' : return formatNumberHelper(n * 100, precision, 'f') + '%';
|
||||||
case '' : return formatNumberHelper(n, precision, 'd');
|
case '' : return formatNumberHelper(n, precision, 'd');
|
||||||
|
|
||||||
|
@ -276,7 +281,7 @@ const REGEXP_BASIC_FORMAT = /{([^.!:}]+(?:\.[^.!:}]+)*)(?:\!([^:}]+))?(?:\:([^}]
|
||||||
|
|
||||||
function getValue(obj, path) {
|
function getValue(obj, path) {
|
||||||
const value = _.get(obj, path);
|
const value = _.get(obj, path);
|
||||||
if(value) {
|
if(!_.isUndefined(value)) {
|
||||||
return _.isFunction(value) ? value() : value;
|
return _.isFunction(value) ? value() : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,9 +291,16 @@ function getValue(obj, path) {
|
||||||
module.exports = function format(fmt, obj) {
|
module.exports = function format(fmt, obj) {
|
||||||
|
|
||||||
const re = REGEXP_BASIC_FORMAT;
|
const re = REGEXP_BASIC_FORMAT;
|
||||||
|
|
||||||
let match;
|
let match;
|
||||||
let pos;
|
let pos;
|
||||||
let out = '';
|
let out = '';
|
||||||
|
let objPath ;
|
||||||
|
let transformer;
|
||||||
|
let formatSpec;
|
||||||
|
let value;
|
||||||
|
let tokens;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
pos = re.lastIndex;
|
pos = re.lastIndex;
|
||||||
match = re.exec(fmt);
|
match = re.exec(fmt);
|
||||||
|
@ -298,16 +310,16 @@ module.exports = function format(fmt, obj) {
|
||||||
out += fmt.slice(pos, match.index);
|
out += fmt.slice(pos, match.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
const objPath = match[1];
|
objPath = match[1];
|
||||||
const transformer = match[2];
|
transformer = match[2];
|
||||||
const formatSpec = match[3];
|
formatSpec = match[3];
|
||||||
|
|
||||||
let value = getValue(obj, objPath);
|
value = getValue(obj, objPath);
|
||||||
if(transformer) {
|
if(transformer) {
|
||||||
value = transformValue(transformer, value);
|
value = transformValue(transformer, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
const tokens = tokenizeFormatSpec(formatSpec || '');
|
tokens = tokenizeFormatSpec(formatSpec || '');
|
||||||
|
|
||||||
if(!isNaN(parseInt(value))) {
|
if(!isNaN(parseInt(value))) {
|
||||||
out += formatNumber(value, tokens);
|
out += formatNumber(value, tokens);
|
||||||
|
|
|
@ -195,45 +195,6 @@ function stringFromNullTermBuffer(buf, encoding) {
|
||||||
return iconv.decode(buf.slice(0, nullPos), encoding || 'utf-8');
|
return iconv.decode(buf.slice(0, nullPos), encoding || 'utf-8');
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Extend String.format's object syntax with some modifiers
|
|
||||||
// e.g.: '{username!styleL33t}'.format( { username : 'Leet User' } ) -> "L33t U53r"
|
|
||||||
//
|
|
||||||
var stringFormatExtensions = {
|
|
||||||
styleUpper : function(s) {
|
|
||||||
return stylizeString(s, 'upper');
|
|
||||||
},
|
|
||||||
styleLower : function(s) {
|
|
||||||
return stylizeString(s, 'lower');
|
|
||||||
},
|
|
||||||
styleTitle : function(s) {
|
|
||||||
return stylizeString(s, 'title');
|
|
||||||
},
|
|
||||||
styleFirstLower : function(s) {
|
|
||||||
return stylizeString(s, 'first lower');
|
|
||||||
},
|
|
||||||
styleSmallVowels : function(s) {
|
|
||||||
return stylizeString(s, 'small vowels');
|
|
||||||
},
|
|
||||||
styleBigVowels : function(s) {
|
|
||||||
return stylizeString(s, 'big vowels');
|
|
||||||
},
|
|
||||||
styleSmallI : function(s) {
|
|
||||||
return stylizeString(s, 'small i');
|
|
||||||
},
|
|
||||||
styleMixed : function(s) {
|
|
||||||
return stylizeString(s, 'mixed');
|
|
||||||
},
|
|
||||||
styleL33t : function(s) {
|
|
||||||
return stylizeString(s, 'l33t');
|
|
||||||
}
|
|
||||||
|
|
||||||
// :TODO: Add padding/etc. modifiers.
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.stringFormatExtensions = stringFormatExtensions;
|
|
||||||
|
|
||||||
|
|
||||||
// :TODO: Add other codes from ansi_escape_parser
|
// :TODO: Add other codes from ansi_escape_parser
|
||||||
const ANSI_REGEXP = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g;
|
const ANSI_REGEXP = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g;
|
||||||
const PIPE_REGEXP = /\|[A-Z\d]{2}/g;
|
const PIPE_REGEXP = /\|[A-Z\d]{2}/g;
|
||||||
|
@ -244,7 +205,7 @@ const ANSI_OR_PIPE_REGEXP = new RegExp(ANSI_REGEXP.source + '|' + PIPE_REGEXP.so
|
||||||
//
|
//
|
||||||
function renderSubstr(str, start, length) {
|
function renderSubstr(str, start, length) {
|
||||||
start = start || 0;
|
start = start || 0;
|
||||||
length = length || str.length - start;
|
length = Math.max(0, (length || str.length - start) - 1);
|
||||||
|
|
||||||
const re = ANSI_REGEXP;
|
const re = ANSI_REGEXP;
|
||||||
let pos;
|
let pos;
|
||||||
|
|
|
@ -240,14 +240,6 @@ TextView.prototype.setText = function(text) {
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TextView.prototype.setFormatObject = function(obj) {
|
|
||||||
if(!_.isObject(obj) || !this.text) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setText(this.text.format(obj));
|
|
||||||
};
|
|
||||||
|
|
||||||
TextView.prototype.clearText = function() {
|
TextView.prototype.clearText = function() {
|
||||||
this.setText('');
|
this.setText('');
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,7 +16,7 @@ exports.userLogin = userLogin;
|
||||||
function userLogin(client, username, password, cb) {
|
function userLogin(client, username, password, cb) {
|
||||||
client.user.authenticate(username, password, function authenticated(err) {
|
client.user.authenticate(username, password, function authenticated(err) {
|
||||||
if(err) {
|
if(err) {
|
||||||
client.log.info( { username : username }, 'Failed login attempt: %s', err);
|
client.log.info( { username : username, error : err.message }, 'Failed login attempt');
|
||||||
|
|
||||||
// :TODO: if username exists, record failed login attempt to properties
|
// :TODO: if username exists, record failed login attempt to properties
|
||||||
// :TODO: check Config max failed logon attempts/etc. - set err.maxAttempts = true
|
// :TODO: check Config max failed logon attempts/etc. - set err.maxAttempts = true
|
||||||
|
|
|
@ -6,6 +6,7 @@ var MCIViewFactory = require('./mci_view_factory.js').MCIViewFactory;
|
||||||
var menuUtil = require('./menu_util.js');
|
var menuUtil = require('./menu_util.js');
|
||||||
var asset = require('./asset.js');
|
var asset = require('./asset.js');
|
||||||
var ansi = require('./ansi_term.js');
|
var ansi = require('./ansi_term.js');
|
||||||
|
const Log = require('./logger.js');
|
||||||
|
|
||||||
// deps
|
// deps
|
||||||
var events = require('events');
|
var events = require('events');
|
||||||
|
@ -328,7 +329,14 @@ function ViewController(options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.client.log.trace( { formValue : formValue, actionValue : actionValue }, 'Action match');
|
self.client.log.trace(
|
||||||
|
{
|
||||||
|
formValue : formValue,
|
||||||
|
actionValue : actionValue
|
||||||
|
},
|
||||||
|
'Action match'
|
||||||
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ const ViewController = require('../core/view_controller.js').ViewController;
|
||||||
const ansi = require('../core/ansi_term.js');
|
const ansi = require('../core/ansi_term.js');
|
||||||
const theme = require('../core/theme.js');
|
const theme = require('../core/theme.js');
|
||||||
const getUserName = require('../core/user.js').getUserName;
|
const getUserName = require('../core/user.js').getUserName;
|
||||||
|
const stringFormat = require('../core/string_format.js');
|
||||||
|
|
||||||
// deps
|
// deps
|
||||||
const async = require('async');
|
const async = require('async');
|
||||||
|
@ -99,7 +100,6 @@ function BBSListModule(options) {
|
||||||
self.setViewText(MciViewIds.view[mciName], '');
|
self.setViewText(MciViewIds.view[mciName], '');
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// :TODO: we really need pipe code support for TextView!!
|
|
||||||
const youSubmittedFormat = config.youSubmittedFormat || '{submitter} (You!)';
|
const youSubmittedFormat = config.youSubmittedFormat || '{submitter} (You!)';
|
||||||
|
|
||||||
Object.keys(SELECTED_MCI_NAME_TO_ENTRY).forEach(mciName => {
|
Object.keys(SELECTED_MCI_NAME_TO_ENTRY).forEach(mciName => {
|
||||||
|
@ -107,7 +107,7 @@ function BBSListModule(options) {
|
||||||
if(MciViewIds.view[mciName]) {
|
if(MciViewIds.view[mciName]) {
|
||||||
|
|
||||||
if('SelectedBBSSubmitter' == mciName && entry.submitterUserId == self.client.user.userId) {
|
if('SelectedBBSSubmitter' == mciName && entry.submitterUserId == self.client.user.userId) {
|
||||||
self.setViewText(MciViewIds.view.SelectedBBSSubmitter, youSubmittedFormat.format(entry));
|
self.setViewText(MciViewIds.view.SelectedBBSSubmitter, stringFormat(youSubmittedFormat, entry));
|
||||||
} else {
|
} else {
|
||||||
self.setViewText(MciViewIds.view[mciName], t);
|
self.setViewText(MciViewIds.view[mciName], t);
|
||||||
}
|
}
|
||||||
|
@ -120,8 +120,8 @@ function BBSListModule(options) {
|
||||||
const listFormat = config.listFormat || '{bbsName}';
|
const listFormat = config.listFormat || '{bbsName}';
|
||||||
const focusListFormat = config.focusListFormat || '{bbsName}';
|
const focusListFormat = config.focusListFormat || '{bbsName}';
|
||||||
|
|
||||||
entriesView.setItems(self.entries.map( e => listFormat.format(e) ) );
|
entriesView.setItems(self.entries.map( e => stringFormat(listFormat, e) ) );
|
||||||
entriesView.setFocusItems(self.entries.map( e => focusListFormat.format(e) ) );
|
entriesView.setFocusItems(self.entries.map( e => stringFormat(focusListFormat, e) ) );
|
||||||
};
|
};
|
||||||
|
|
||||||
this.displayBBSList = function(clearScreen, cb) {
|
this.displayBBSList = function(clearScreen, cb) {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var MenuModule = require('../core/menu_module.js').MenuModule;
|
var MenuModule = require('../core/menu_module.js').MenuModule;
|
||||||
|
const stringFormat = require('../core/string_format.js');
|
||||||
|
|
||||||
// deps
|
// deps
|
||||||
const async = require('async');
|
const async = require('async');
|
||||||
|
@ -86,10 +87,10 @@ function ErcClientModule(options) {
|
||||||
try {
|
try {
|
||||||
if(data.userName) {
|
if(data.userName) {
|
||||||
// user message
|
// user message
|
||||||
text = self.chatEntryFormat.format(data);
|
text = stringFormat(self.chatEntryFormat, data);
|
||||||
} else {
|
} else {
|
||||||
// system message
|
// system message
|
||||||
text = self.systemEntryFormat.format(data);
|
text = stringFormat(self.systemEntryFormat, data);
|
||||||
}
|
}
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
return self.client.log.warn( { error : e.message }, 'ERC: chatEntryFormat error');
|
return self.client.log.warn( { error : e.message }, 'ERC: chatEntryFormat error');
|
||||||
|
|
|
@ -8,6 +8,7 @@ const StatLog = require('../core/stat_log.js');
|
||||||
const getUserName = require('../core/user.js').getUserName;
|
const getUserName = require('../core/user.js').getUserName;
|
||||||
const loadProperties = require('../core/user.js').loadProperties;
|
const loadProperties = require('../core/user.js').loadProperties;
|
||||||
const isRootUserId = require('../core/user.js').isRootUserId;
|
const isRootUserId = require('../core/user.js').isRootUserId;
|
||||||
|
const stringFormat = require('../core/string_format.js');
|
||||||
|
|
||||||
// deps
|
// deps
|
||||||
const moment = require('moment');
|
const moment = require('moment');
|
||||||
|
@ -123,12 +124,9 @@ LastCallersModule.prototype.mciReady = function(mciData, cb) {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
function populateList(callback) {
|
function populateList(callback) {
|
||||||
const listFormat = self.menuConfig.config.listFormat || '{userName} - {location} - {affils} - {ts}';
|
const listFormat = self.menuConfig.config.listFormat || '{userName} - {location} - {affiliation} - {ts}';
|
||||||
|
|
||||||
callersView.setItems(_.map(loginHistory, ce => listFormat.format(ce) ) );
|
callersView.setItems(_.map(loginHistory, ce => stringFormat(listFormat, ce) ) );
|
||||||
|
|
||||||
// :TODO: This is a hack until pipe codes are better implemented
|
|
||||||
callersView.focusItems = callersView.items;
|
|
||||||
|
|
||||||
callersView.redraw();
|
callersView.redraw();
|
||||||
return callback(null);
|
return callback(null);
|
||||||
|
|
|
@ -8,6 +8,7 @@ const messageArea = require('../core/message_area.js');
|
||||||
const displayThemeArt = require('../core/theme.js').displayThemeArt;
|
const displayThemeArt = require('../core/theme.js').displayThemeArt;
|
||||||
const displayThemedPause = require('../core/theme.js').displayThemedPause;
|
const displayThemedPause = require('../core/theme.js').displayThemedPause;
|
||||||
const resetScreen = require('../core/ansi_term.js').resetScreen;
|
const resetScreen = require('../core/ansi_term.js').resetScreen;
|
||||||
|
const stringFormat = require('../core/string_format.js');
|
||||||
|
|
||||||
// deps
|
// deps
|
||||||
const async = require('async');
|
const async = require('async');
|
||||||
|
@ -152,7 +153,7 @@ MessageAreaListModule.prototype.mciReady = function(mciData, cb) {
|
||||||
const areaListView = vc.getView(MCICodesIDs.AreaList);
|
const areaListView = vc.getView(MCICodesIDs.AreaList);
|
||||||
let i = 1;
|
let i = 1;
|
||||||
areaListView.setItems(_.map(self.messageAreas, v => {
|
areaListView.setItems(_.map(self.messageAreas, v => {
|
||||||
return listFormat.format({
|
return stringFormat(listFormat, {
|
||||||
index : i++,
|
index : i++,
|
||||||
areaTag : v.area.areaTag,
|
areaTag : v.area.areaTag,
|
||||||
name : v.area.name,
|
name : v.area.name,
|
||||||
|
@ -162,7 +163,7 @@ MessageAreaListModule.prototype.mciReady = function(mciData, cb) {
|
||||||
|
|
||||||
i = 1;
|
i = 1;
|
||||||
areaListView.setFocusItems(_.map(self.messageAreas, v => {
|
areaListView.setFocusItems(_.map(self.messageAreas, v => {
|
||||||
return focusListFormat.format({
|
return stringFormat(focusListFormat, {
|
||||||
index : i++,
|
index : i++,
|
||||||
areaTag : v.area.areaTag,
|
areaTag : v.area.areaTag,
|
||||||
name : v.area.name,
|
name : v.area.name,
|
||||||
|
|
|
@ -123,3 +123,7 @@ AreaViewFSEModule.prototype.restoreSavedState = function(savedState) {
|
||||||
this.messageIndex = savedState.messageIndex;
|
this.messageIndex = savedState.messageIndex;
|
||||||
this.messageTotal = savedState.messageTotal;
|
this.messageTotal = savedState.messageTotal;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
AreaViewFSEModule.prototype.getMenuResult = function() {
|
||||||
|
return this.messageIndex;
|
||||||
|
};
|
||||||
|
|
|
@ -8,6 +8,7 @@ const messageArea = require('../core/message_area.js');
|
||||||
const displayThemeArt = require('../core/theme.js').displayThemeArt;
|
const displayThemeArt = require('../core/theme.js').displayThemeArt;
|
||||||
const displayThemedPause = require('../core/theme.js').displayThemedPause;
|
const displayThemedPause = require('../core/theme.js').displayThemedPause;
|
||||||
const resetScreen = require('../core/ansi_term.js').resetScreen;
|
const resetScreen = require('../core/ansi_term.js').resetScreen;
|
||||||
|
const stringFormat = require('../core/string_format.js');
|
||||||
|
|
||||||
// deps
|
// deps
|
||||||
const async = require('async');
|
const async = require('async');
|
||||||
|
@ -121,7 +122,7 @@ MessageConfListModule.prototype.mciReady = function(mciData, cb) {
|
||||||
const confListView = vc.getView(MCICodeIDs.ConfList);
|
const confListView = vc.getView(MCICodeIDs.ConfList);
|
||||||
let i = 1;
|
let i = 1;
|
||||||
confListView.setItems(_.map(self.messageConfs, v => {
|
confListView.setItems(_.map(self.messageConfs, v => {
|
||||||
return listFormat.format({
|
return stringFormat(listFormat, {
|
||||||
index : i++,
|
index : i++,
|
||||||
confTag : v.conf.confTag,
|
confTag : v.conf.confTag,
|
||||||
name : v.conf.name,
|
name : v.conf.name,
|
||||||
|
@ -131,7 +132,7 @@ MessageConfListModule.prototype.mciReady = function(mciData, cb) {
|
||||||
|
|
||||||
i = 1;
|
i = 1;
|
||||||
confListView.setFocusItems(_.map(self.messageConfs, v => {
|
confListView.setFocusItems(_.map(self.messageConfs, v => {
|
||||||
return focusListFormat.format({
|
return stringFormat(focusListFormat, {
|
||||||
index : i++,
|
index : i++,
|
||||||
confTag : v.conf.confTag,
|
confTag : v.conf.confTag,
|
||||||
name : v.conf.name,
|
name : v.conf.name,
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
const MenuModule = require('../core/menu_module.js').MenuModule;
|
const MenuModule = require('../core/menu_module.js').MenuModule;
|
||||||
const ViewController = require('../core/view_controller.js').ViewController;
|
const ViewController = require('../core/view_controller.js').ViewController;
|
||||||
const messageArea = require('../core/message_area.js');
|
const messageArea = require('../core/message_area.js');
|
||||||
|
const stringFormat = require('../core/string_format.js');
|
||||||
|
|
||||||
// deps
|
// deps
|
||||||
const async = require('async');
|
const async = require('async');
|
||||||
|
@ -209,11 +210,11 @@ MessageListModule.prototype.mciReady = function(mciData, cb) {
|
||||||
// which items are requested (e.g. their format at least) *as-needed* vs trying to get the format for all of them at once
|
// which items are requested (e.g. their format at least) *as-needed* vs trying to get the format for all of them at once
|
||||||
|
|
||||||
msgListView.setItems(_.map(self.messageList, listEntry => {
|
msgListView.setItems(_.map(self.messageList, listEntry => {
|
||||||
return listFormat.format(listEntry);
|
return stringFormat(listFormat, listEntry);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
msgListView.setFocusItems(_.map(self.messageList, listEntry => {
|
msgListView.setFocusItems(_.map(self.messageList, listEntry => {
|
||||||
return focusListFormat.format(listEntry);
|
return stringFormat(focusListFormat, listEntry);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
msgListView.on('index update', function indexUpdated(idx) {
|
msgListView.on('index update', function indexUpdated(idx) {
|
||||||
|
|
|
@ -154,7 +154,6 @@ function OnelinerzModule(options) {
|
||||||
} );
|
} );
|
||||||
}));
|
}));
|
||||||
|
|
||||||
entriesView.focusItems = entriesView.items; // :TODO: this is a hack
|
|
||||||
entriesView.redraw();
|
entriesView.redraw();
|
||||||
|
|
||||||
return callback(null);
|
return callback(null);
|
||||||
|
|
|
@ -8,6 +8,7 @@ const theme = require('../core/theme.js');
|
||||||
const resetScreen = require('../core/ansi_term.js').resetScreen;
|
const resetScreen = require('../core/ansi_term.js').resetScreen;
|
||||||
const StatLog = require('../core/stat_log.js');
|
const StatLog = require('../core/stat_log.js');
|
||||||
const renderStringLength = require('../core/string_util.js').renderStringLength;
|
const renderStringLength = require('../core/string_util.js').renderStringLength;
|
||||||
|
const stringFormat = require('../core/string_format.js');
|
||||||
|
|
||||||
// deps
|
// deps
|
||||||
const async = require('async');
|
const async = require('async');
|
||||||
|
@ -158,8 +159,8 @@ exports.getModule = class RumorzModule extends MenuModule {
|
||||||
const listFormat = config.listFormat || '{rumor}';
|
const listFormat = config.listFormat || '{rumor}';
|
||||||
const focusListFormat = config.focusListFormat || listFormat;
|
const focusListFormat = config.focusListFormat || listFormat;
|
||||||
|
|
||||||
entriesView.setItems(entries.map( e => listFormat.format( { rumor : e.log_value } ) ) );
|
entriesView.setItems(entries.map( e => stringFormat(listFormat, { rumor : e.log_value } ) ) );
|
||||||
entriesView.setFocusItems(entries.map(e => focusListFormat.format( { rumor : e.log_value } ) ) );
|
entriesView.setFocusItems(entries.map(e => stringFormat(focusListFormat, { rumor : e.log_value } ) ) );
|
||||||
entriesView.redraw();
|
entriesView.redraw();
|
||||||
|
|
||||||
return callback(null);
|
return callback(null);
|
||||||
|
|
Binary file not shown.
|
@ -5,10 +5,10 @@ var MenuModule = require('../core/menu_module.js').MenuModule;
|
||||||
//var userDb = require('../core/database.js').dbs.user;
|
//var userDb = require('../core/database.js').dbs.user;
|
||||||
var getUserList = require('../core/user.js').getUserList;
|
var getUserList = require('../core/user.js').getUserList;
|
||||||
var ViewController = require('../core/view_controller.js').ViewController;
|
var ViewController = require('../core/view_controller.js').ViewController;
|
||||||
|
const stringFormat = require('../core/string_format.js');
|
||||||
|
|
||||||
var moment = require('moment');
|
var moment = require('moment');
|
||||||
var async = require('async');
|
var async = require('async');
|
||||||
var assert = require('assert');
|
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -92,11 +92,11 @@ UserListModule.prototype.mciReady = function(mciData, cb) {
|
||||||
}
|
}
|
||||||
|
|
||||||
userListView.setItems(_.map(userList, function formatUserEntry(ue) {
|
userListView.setItems(_.map(userList, function formatUserEntry(ue) {
|
||||||
return listFormat.format(getUserFmtObj(ue));
|
return stringFormat(listFormat, getUserFmtObj(ue));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
userListView.setFocusItems(_.map(userList, function formatUserEntry(ue) {
|
userListView.setFocusItems(_.map(userList, function formatUserEntry(ue) {
|
||||||
return focusListFormat.format(getUserFmtObj(ue));
|
return stringFormat(focusListFormat, getUserFmtObj(ue));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
userListView.redraw();
|
userListView.redraw();
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
const MenuModule = require('../core/menu_module.js').MenuModule;
|
const MenuModule = require('../core/menu_module.js').MenuModule;
|
||||||
const ViewController = require('../core/view_controller.js').ViewController;
|
const ViewController = require('../core/view_controller.js').ViewController;
|
||||||
const getActiveNodeList = require('../core/client_connections.js').getActiveNodeList;
|
const getActiveNodeList = require('../core/client_connections.js').getActiveNodeList;
|
||||||
|
const stringFormat = require('../core/string_format.js');
|
||||||
|
|
||||||
// deps
|
// deps
|
||||||
const async = require('async');
|
const async = require('async');
|
||||||
|
@ -63,7 +64,7 @@ WhosOnlineModule.prototype.mciReady = function(mciData, cb) {
|
||||||
});
|
});
|
||||||
oe.userName = nonAuthUser;
|
oe.userName = nonAuthUser;
|
||||||
}
|
}
|
||||||
return listFormat.format(oe);
|
return stringFormat(listFormat, oe);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
onlineListView.focusItems = onlineListView.items;
|
onlineListView.focusItems = onlineListView.items;
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
"ptyw.js": "^0.3.7",
|
"ptyw.js": "^0.3.7",
|
||||||
"sqlite3": "^3.1.1",
|
"sqlite3": "^3.1.1",
|
||||||
"ssh2": "^0.4.13",
|
"ssh2": "^0.4.13",
|
||||||
"string-format": "davidchambers/string-format#mini-language",
|
|
||||||
"temp": "^0.8.3",
|
"temp": "^0.8.3",
|
||||||
"inquirer" : "^1.1.0",
|
"inquirer" : "^1.1.0",
|
||||||
"fs-extra" : "0.26.x",
|
"fs-extra" : "0.26.x",
|
||||||
|
|
Loading…
Reference in New Issue