* Code cleanup and eslint since -- remove unused variables, clean up RegExs, so on...

This commit is contained in:
Bryan Ashby 2018-01-15 12:22:11 -07:00
parent a106050ba3
commit ac1433e84b
112 changed files with 1375 additions and 1898 deletions

View File

@ -3,7 +3,9 @@
const miscUtil = require('./misc_util.js'); const miscUtil = require('./misc_util.js');
const ansi = require('./ansi_term.js'); const ansi = require('./ansi_term.js');
const Log = require('./logger.js').log;
// deps
const events = require('events'); const events = require('events');
const util = require('util'); const util = require('util');
const _ = require('lodash'); const _ = require('lodash');
@ -24,7 +26,7 @@ function ANSIEscapeParser(options) {
this.graphicRendition = {}; this.graphicRendition = {};
this.parseState = { this.parseState = {
re : /(?:\x1b\x5b)([\?=;0-9]*?)([ABCDHJKfhlmnpsu])/g, re : /(?:\x1b\x5b)([?=;0-9]*?)([ABCDHJKfhlmnpsu])/g, // eslint-disable-line no-control-regex
}; };
options = miscUtil.valueWithDefault(options, { options = miscUtil.valueWithDefault(options, {
@ -63,7 +65,7 @@ function ANSIEscapeParser(options) {
delete self.savedPosition; delete self.savedPosition;
self.positionUpdated(); self.positionUpdated();
// self.rowUpdated(); // self.rowUpdated();
}; };
self.clearScreen = function() { self.clearScreen = function() {
@ -71,7 +73,7 @@ function ANSIEscapeParser(options) {
self.emit('clear screen'); self.emit('clear screen');
}; };
/* /*
self.rowUpdated = function() { self.rowUpdated = function() {
self.emit('row update', self.row + self.scrollBack); self.emit('row update', self.row + self.scrollBack);
};*/ };*/
@ -142,17 +144,9 @@ function ANSIEscapeParser(options) {
} }
} }
function getProcessedMCI(mci) {
if(self.mciReplaceChar.length > 0) {
return ansi.getSGRFromGraphicRendition(self.graphicRendition, true) + new Array(mci.length + 1).join(self.mciReplaceChar);
} else {
return mci;
}
}
function parseMCI(buffer) { function parseMCI(buffer) {
// :TODO: move this to "constants" seciton @ top // :TODO: move this to "constants" seciton @ top
var mciRe = /\%([A-Z]{2})([0-9]{1,2})?(?:\(([0-9A-Za-z,]+)\))*/g; var mciRe = /%([A-Z]{2})([0-9]{1,2})?(?:\(([0-9A-Za-z,]+)\))*/g;
var pos = 0; var pos = 0;
var match; var match;
var mciCode; var mciCode;
@ -197,16 +191,12 @@ function ANSIEscapeParser(options) {
if(self.mciReplaceChar.length > 0) { if(self.mciReplaceChar.length > 0) {
const sgrCtrl = ansi.getSGRFromGraphicRendition(self.graphicRenditionForErase); const sgrCtrl = ansi.getSGRFromGraphicRendition(self.graphicRenditionForErase);
self.emit('control', sgrCtrl, 'm', sgrCtrl.slice(2).split(/[\;m]/).slice(0, 3)); self.emit('control', sgrCtrl, 'm', sgrCtrl.slice(2).split(/[;m]/).slice(0, 3));
literal(new Array(match[0].length + 1).join(self.mciReplaceChar)); literal(new Array(match[0].length + 1).join(self.mciReplaceChar));
} else { } else {
literal(match[0]); literal(match[0]);
} }
//literal(getProcessedMCI(match[0]));
//self.emit('chunk', getProcessedMCI(match[0]));
} }
} while(0 !== mciRe.lastIndex); } while(0 !== mciRe.lastIndex);
@ -220,7 +210,7 @@ function ANSIEscapeParser(options) {
self.parseState = { self.parseState = {
// ignore anything past EOF marker, if any // ignore anything past EOF marker, if any
buffer : input.split(String.fromCharCode(0x1a), 1)[0], buffer : input.split(String.fromCharCode(0x1a), 1)[0],
re : /(?:\x1b\x5b)([\?=;0-9]*?)([ABCDHJKfhlmnpsu])/g, re : /(?:\x1b\x5b)([?=;0-9]*?)([ABCDHJKfhlmnpsu])/g, // eslint-disable-line no-control-regex
stop : false, stop : false,
}; };
}; };
@ -291,13 +281,13 @@ function ANSIEscapeParser(options) {
} }
} }
parseMCI(lastBit) parseMCI(lastBit);
} }
self.emit('complete'); self.emit('complete');
}; };
/* /*
self.parse = function(buffer, savedRe) { self.parse = function(buffer, savedRe) {
// :TODO: ensure this conforms to ANSI-BBS / CTerm / bansi.txt for movement/etc. // :TODO: ensure this conforms to ANSI-BBS / CTerm / bansi.txt for movement/etc.
// :TODO: move this to "constants" section @ top // :TODO: move this to "constants" section @ top
@ -448,7 +438,7 @@ function ANSIEscapeParser(options) {
break; break;
default : default :
console.log('Unknown attribute: ' + arg); // :TODO: Log properly Log.trace( { attribute : arg }, 'Unknown attribute while parsing ANSI');
break; break;
} }
} }

View File

@ -108,9 +108,11 @@ module.exports = class ArchiveUtil {
return this.getArchiver(archType) ? true : false; return this.getArchiver(archType) ? true : false;
} }
// :TODO: implement me:
/*
detectTypeWithBuf(buf, cb) { detectTypeWithBuf(buf, cb) {
// :TODO: implement me!
} }
*/
detectType(path, cb) { detectType(path, cb) {
fs.open(path, 'r', (err, fd) => { fs.open(path, 'r', (err, fd) => {

View File

@ -52,8 +52,8 @@ exports.Client = Client;
// Resources & Standards: // Resources & Standards:
// * http://www.ansi-bbs.org/ansi-bbs-core-server.html // * http://www.ansi-bbs.org/ansi-bbs-core-server.html
// //
const RE_DSR_RESPONSE_ANYWHERE = /(?:\u001b\[)([0-9\;]+)(R)/; const RE_DSR_RESPONSE_ANYWHERE = /(?:\u001b\[)([0-9;]+)(R)/;
const RE_DEV_ATTR_RESPONSE_ANYWHERE = /(?:\u001b\[)[\=\?]([0-9a-zA-Z\;]+)(c)/; const RE_DEV_ATTR_RESPONSE_ANYWHERE = /(?:\u001b\[)[=?]([0-9a-zA-Z;]+)(c)/;
const RE_META_KEYCODE_ANYWHERE = /(?:\u001b)([a-zA-Z0-9])/; const RE_META_KEYCODE_ANYWHERE = /(?:\u001b)([a-zA-Z0-9])/;
const RE_META_KEYCODE = new RegExp('^' + RE_META_KEYCODE_ANYWHERE.source + '$'); const RE_META_KEYCODE = new RegExp('^' + RE_META_KEYCODE_ANYWHERE.source + '$');
const RE_FUNCTION_KEYCODE_ANYWHERE = new RegExp('(?:\u001b+)(O|N|\\[|\\[\\[)(?:' + [ const RE_FUNCTION_KEYCODE_ANYWHERE = new RegExp('(?:\u001b+)(O|N|\\[|\\[\\[)(?:' + [
@ -72,7 +72,7 @@ const RE_ESC_CODE_ANYWHERE = new RegExp( [
].join('|')); ].join('|'));
function Client(input, output) { function Client(/*input, output*/) {
stream.call(this); stream.call(this);
const self = this; const self = this;
@ -139,8 +139,8 @@ function Client(input, output) {
}; };
this.isMouseInput = function(data) { this.isMouseInput = function(data) {
return /\x1b\[M/.test(data) || return /\x1b\[M/.test(data) || // eslint-disable-line no-control-regex
/\u001b\[M([\x00\u0020-\uffff]{3})/.test(data) || /\u001b\[M([\x00\u0020-\uffff]{3})/.test(data) || // eslint-disable-line no-control-regex
/\u001b\[(\d+;\d+;\d+)M/.test(data) || /\u001b\[(\d+;\d+;\d+)M/.test(data) ||
/\u001b\[<(\d+;\d+;\d+)([mM])/.test(data) || /\u001b\[<(\d+;\d+;\d+)([mM])/.test(data) ||
/\u001b\[<(\d+;\d+;\d+;\d+)&w/.test(data) || /\u001b\[<(\d+;\d+;\d+;\d+)&w/.test(data) ||
@ -482,7 +482,7 @@ Client.prototype.isLocal = function() {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// :TODO: getDefaultHandler(name) -- handlers in default_handlers.js or something // :TODO: getDefaultHandler(name) -- handlers in default_handlers.js or something
Client.prototype.defaultHandlerMissingMod = function(err) { Client.prototype.defaultHandlerMissingMod = function() {
var self = this; var self = this;
function handler(err) { function handler(err) {

View File

@ -15,8 +15,6 @@ exports.ClientTerminal = ClientTerminal;
function ClientTerminal(output) { function ClientTerminal(output) {
this.output = output; this.output = output;
var self = this;
var outputEncoding = 'cp437'; var outputEncoding = 'cp437';
assert(iconv.encodingExists(outputEncoding)); assert(iconv.encodingExists(outputEncoding));

View File

@ -180,7 +180,7 @@ function renegadeToAnsi(s, client) {
// * http://wiki.synchro.net/custom:colors // * http://wiki.synchro.net/custom:colors
// //
function controlCodesToAnsi(s, client) { function controlCodesToAnsi(s, client) {
const RE = /(\|([A-Z0-9]{2})|\|)|(\@X([0-9A-F]{2}))|(\@([0-9A-F]{2})\@)|(\x03[0-9]|\x03)/g; // eslint-disable-line no-control-regex const RE = /(\|([A-Z0-9]{2})|\|)|(@X([0-9A-F]{2}))|(@([0-9A-F]{2})@)|(\x03[0-9]|\x03)/g; // eslint-disable-line no-control-regex
let m; let m;
let result = ''; let result = '';

View File

@ -62,21 +62,21 @@ exports.getModule = class CombatNetModule extends MenuModule {
rlogin.on('error', err => { rlogin.on('error', err => {
self.client.log.info(`CombatNet rlogin client error: ${err.message}`); self.client.log.info(`CombatNet rlogin client error: ${err.message}`);
restorePipeToNormal(); restorePipeToNormal();
callback(err); return callback(err);
}); });
// If we've been disconnected ... // If we've been disconnected ...
rlogin.on('disconnect', () => { rlogin.on('disconnect', () => {
self.client.log.info(`Disconnected from CombatNet`); self.client.log.info('Disconnected from CombatNet');
restorePipeToNormal(); restorePipeToNormal();
callback(null); return callback(null);
}); });
function sendToRloginBuffer(buffer) { function sendToRloginBuffer(buffer) {
rlogin.send(buffer); rlogin.send(buffer);
}; }
rlogin.on("connect", rlogin.on('connect',
/* The 'connect' event handler will be supplied with one argument, /* The 'connect' event handler will be supplied with one argument,
a boolean indicating whether or not the connection was established. */ a boolean indicating whether or not the connection was established. */
@ -92,7 +92,7 @@ exports.getModule = class CombatNetModule extends MenuModule {
); );
// If data (a Buffer) has been received from the server ... // If data (a Buffer) has been received from the server ...
rlogin.on("data", (data) => { rlogin.on('data', (data) => {
self.client.term.rawWrite(data); self.client.term.rawWrite(data);
}); });

View File

@ -653,12 +653,12 @@ function getDefaultConfig() {
// FILE_ID.DIZ - https://en.wikipedia.org/wiki/FILE_ID.DIZ // FILE_ID.DIZ - https://en.wikipedia.org/wiki/FILE_ID.DIZ
// Some groups include a FILE_ID.ANS. We try to use that over FILE_ID.DIZ if available. // Some groups include a FILE_ID.ANS. We try to use that over FILE_ID.DIZ if available.
desc : [ desc : [
'^[^/\]*FILE_ID\.ANS$', '^[^/\]*FILE_ID\.DIZ$', '^[^/\]*DESC\.SDI$', '^[^/\]*DESCRIPT\.ION$', '^[^/\]*FILE\.DES$', '^[^/\]*FILE\.SDI$', '^[^/\]*DISK\.ID$' '^[^/\]*FILE_ID\.ANS$', '^[^/\]*FILE_ID\.DIZ$', '^[^/\]*DESC\.SDI$', '^[^/\]*DESCRIPT\.ION$', '^[^/\]*FILE\.DES$', '^[^/\]*FILE\.SDI$', '^[^/\]*DISK\.ID$' // eslint-disable-line no-useless-escape
], ],
// common README filename - https://en.wikipedia.org/wiki/README // common README filename - https://en.wikipedia.org/wiki/README
descLong : [ descLong : [
'^[^/\]*\.NFO$', '^[^/\]*README\.1ST$', '^[^/\]*README\.NOW$', '^[^/\]*README\.TXT$', '^[^/\]*READ\.ME$', '^[^/\]*README$', '^[^/\]*README\.md$' '^[^/\]*\.NFO$', '^[^/\]*README\.1ST$', '^[^/\]*README\.NOW$', '^[^/\]*README\.TXT$', '^[^/\]*READ\.ME$', '^[^/\]*README$', '^[^/\]*README\.md$' // eslint-disable-line no-useless-escape
], ],
}, },

View File

@ -58,7 +58,7 @@ util.inherits(ConfigCache, events.EventEmitter);
ConfigCache.prototype.getConfigWithOptions = function(options, cb) { ConfigCache.prototype.getConfigWithOptions = function(options, cb) {
assert(_.isString(options.filePath)); assert(_.isString(options.filePath));
// var self = this; // var self = this;
var isCached = (options.filePath in this.cache); var isCached = (options.filePath in this.cache);
if(options.forceReCache || !isCached) { if(options.forceReCache || !isCached) {

View File

@ -37,7 +37,7 @@ function getModDatabasePath(moduleInfo, suffix) {
// We expect that moduleInfo defines packageName which will be the base of the modules // We expect that moduleInfo defines packageName which will be the base of the modules
// filename. An optional suffix may be supplied as well. // filename. An optional suffix may be supplied as well.
// //
const HOST_RE = /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/; const HOST_RE = /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])$/;
assert(_.isObject(moduleInfo)); assert(_.isObject(moduleInfo));
assert(_.isString(moduleInfo.packageName), 'moduleInfo must define "packageName"!'); assert(_.isString(moduleInfo.packageName), 'moduleInfo must define "packageName"!');

View File

@ -24,8 +24,8 @@ exports.moduleInfo = {
author : 'NuSkooler', author : 'NuSkooler',
}; };
const SCHEDULE_REGEXP = /(?:^|or )?(@watch\:)([^\0]+)?$/; const SCHEDULE_REGEXP = /(?:^|or )?(@watch:)([^\0]+)?$/;
const ACTION_REGEXP = /\@(method|execute)\:([^\0]+)?$/; const ACTION_REGEXP = /@(method|execute):([^\0]+)?$/;
class ScheduledEvent { class ScheduledEvent {
constructor(events, name) { constructor(events, name) {

View File

@ -586,10 +586,6 @@ function addNewFileEntry(fileEntry, filePath, cb) {
); );
} }
function updateFileEntry(fileEntry, filePath, cb) {
}
const HASH_NAMES = [ 'sha1', 'sha256', 'md5', 'crc32' ]; const HASH_NAMES = [ 'sha1', 'sha256', 'md5', 'crc32' ];
function scanFile(filePath, options, iterator, cb) { function scanFile(filePath, options, iterator, cb) {
@ -747,7 +743,9 @@ function scanFile(filePath, options, iterator, cb) {
populateFileEntryWithArchive(fileEntry, filePath, stepInfo, callIter, err => { populateFileEntryWithArchive(fileEntry, filePath, stepInfo, callIter, err => {
if(err) { if(err) {
populateFileEntryNonArchive(fileEntry, filePath, stepInfo, callIter, err => { populateFileEntryNonArchive(fileEntry, filePath, stepInfo, callIter, err => {
// :TODO: log err if(err) {
logDebug( { error : err.message }, 'Non-archive file entry population failed');
}
return callback(null); // ignore err return callback(null); // ignore err
}); });
} else { } else {
@ -756,7 +754,9 @@ function scanFile(filePath, options, iterator, cb) {
}); });
} else { } else {
populateFileEntryNonArchive(fileEntry, filePath, stepInfo, callIter, err => { populateFileEntryNonArchive(fileEntry, filePath, stepInfo, callIter, err => {
// :TODO: log err if(err) {
logDebug( { error : err.message }, 'Non-archive file entry population failed');
}
return callback(null); // ignore err return callback(null); // ignore err
}); });
} }
@ -874,7 +874,7 @@ function getDescFromFileName(fileName) {
const ext = paths.extname(fileName); const ext = paths.extname(fileName);
const name = paths.basename(fileName, ext); const name = paths.basename(fileName, ext);
return _.upperFirst(name.replace(/[\-_.+]/g, ' ').replace(/\s+/g, ' ')); return _.upperFirst(name.replace(/[-_.+]/g, ' ').replace(/\s+/g, ' '));
} }
// //

View File

@ -59,8 +59,6 @@ exports.getModule = class FileBaseDownloadQueueManager extends MenuModule {
return this.gotoMenu(this.menuConfig.config.fileTransferProtocolSelection || 'fileTransferProtocolSelection', modOpts, cb); return this.gotoMenu(this.menuConfig.config.fileTransferProtocolSelection || 'fileTransferProtocolSelection', modOpts, cb);
}, },
viewItemInfo : (formData, extraArgs, cb) => {
},
removeItem : (formData, extraArgs, cb) => { removeItem : (formData, extraArgs, cb) => {
const selectedItem = this.dlQueue.items[formData.value.queueItem]; const selectedItem = this.dlQueue.items[formData.value.queueItem];
if(!selectedItem) { if(!selectedItem) {

View File

@ -94,7 +94,7 @@ module.exports = class FileBaseFilters {
} }
cleanTags(tags) { cleanTags(tags) {
return tags.toLowerCase().replace(/,?\s+|\,/g, ' ').trim(); return tags.toLowerCase().replace(/,?\s+|,/g, ' ').trim();
} }
setActive(filterUuid) { setActive(filterUuid) {

View File

@ -284,4 +284,3 @@ exports.getModule = class FileBaseWebDownloadQueueManager extends MenuModule {
); );
} }
}; };

View File

@ -46,5 +46,5 @@ module.exports = class FNV1a {
get value() { get value() {
return this.hash & 0xffffffff; return this.hash & 0xffffffff;
} }
} };

View File

@ -179,13 +179,12 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul
self.switchFooter(function next(err) { self.switchFooter(function next(err) {
if(err) { if(err) {
// :TODO:... what now? return cb(err);
console.log(err) }
} else {
switch(self.footerMode) { switch(self.footerMode) {
case 'editor' : case 'editor' :
if(!_.isUndefined(self.viewControllers.footerEditorMenu)) { if(!_.isUndefined(self.viewControllers.footerEditorMenu)) {
//self.viewControllers.footerEditorMenu.setFocus(false);
self.viewControllers.footerEditorMenu.detachClientEvents(); self.viewControllers.footerEditorMenu.detachClientEvents();
} }
self.viewControllers.body.switchFocus(1); self.viewControllers.body.switchFocus(1);
@ -199,7 +198,6 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul
default : throw new Error('Unexpected mode'); default : throw new Error('Unexpected mode');
} }
}
return cb(null); return cb(null);
}); });
@ -534,7 +532,7 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul
art[n], art[n],
self.client, self.client,
{ font : self.menuConfig.font }, { font : self.menuConfig.font },
function displayed(err, artData) { function displayed(err) {
next(err); next(err);
} }
); );
@ -645,8 +643,7 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul
], ],
function complete(err) { function complete(err) {
if(err) { if(err) {
// :TODO: This needs properly handled! self.client.log.warn( { error : err.message }, 'FSE init error');
console.log(err)
} else { } else {
self.isReady = true; self.isReady = true;
self.finishedLoading(); self.finishedLoading();
@ -763,10 +760,7 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul
} }
], ],
function complete(err) { function complete(err) {
if(err) { return cb(err);
console.error(err)
}
cb(err);
} }
); );
} }
@ -954,7 +948,7 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul
], ],
function complete(err) { function complete(err) {
if(err) { if(err) {
console.log(err) // :TODO: needs real impl. self.client.log.warn( { error : err.message }, 'Error displaying quote builder');
} }
} }
); );

View File

@ -3,8 +3,8 @@
const _ = require('lodash'); const _ = require('lodash');
const FTN_ADDRESS_REGEXP = /^([0-9]+:)?([0-9]+)(\/[0-9]+)?(\.[0-9]+)?(@[a-z0-9\-\.]+)?$/i; const FTN_ADDRESS_REGEXP = /^([0-9]+:)?([0-9]+)(\/[0-9]+)?(\.[0-9]+)?(@[a-z0-9\-.]+)?$/i;
const FTN_PATTERN_REGEXP = /^([0-9\*]+:)?([0-9\*]+)(\/[0-9\*]+)?(\.[0-9\*]+)?(@[a-z0-9\-\.\*]+)?$/i; const FTN_PATTERN_REGEXP = /^([0-9*]+:)?([0-9*]+)(\/[0-9*]+)?(\.[0-9*]+)?(@[a-z0-9\-.*]+)?$/i;
module.exports = class Address { module.exports = class Address {
constructor(addr) { constructor(addr) {

View File

@ -426,12 +426,12 @@ function Packet(options) {
if(!err) { if(!err) {
// we read some SAUCE - don't re-process that portion into the body // we read some SAUCE - don't re-process that portion into the body
messageBodyBuffer = messageBodyBuffer.slice(0, sauceHeaderPosition) + messageBodyBuffer.slice(sauceHeaderPosition + sauce.SAUCE_SIZE); messageBodyBuffer = messageBodyBuffer.slice(0, sauceHeaderPosition) + messageBodyBuffer.slice(sauceHeaderPosition + sauce.SAUCE_SIZE);
// messageBodyBuffer = messageBodyBuffer.slice(0, sauceHeaderPosition); // messageBodyBuffer = messageBodyBuffer.slice(0, sauceHeaderPosition);
messageBodyData.sauce = theSauce; messageBodyData.sauce = theSauce;
} else { } else {
console.log(err) Log.warn( { error : err.message }, 'Found what looks like to be a SAUCE record, but failed to read');
} }
callback(null); // failure to read SAUCE is OK return callback(null); // failure to read SAUCE is OK
}); });
} else { } else {
callback(null); callback(null);
@ -497,7 +497,7 @@ function Packet(options) {
} else if(line.startsWith('--- ')) { } else if(line.startsWith('--- ')) {
// Tear Lines are tracked allowing for specialized display/etc. // Tear Lines are tracked allowing for specialized display/etc.
messageBodyData.tearLine = line; messageBodyData.tearLine = line;
} else if(/^[ ]{1,2}\* Origin\: /.test(line)) { // To spec is " * Origin: ..." } else if(/^[ ]{1,2}\* Origin: /.test(line)) { // To spec is " * Origin: ..."
messageBodyData.originLine = line; messageBodyData.originLine = line;
endOfMessage = true; // Anything past origin is not part of the message body endOfMessage = true; // Anything past origin is not part of the message body
} else if(line.startsWith('SEEN-BY:')) { } else if(line.startsWith('SEEN-BY:')) {
@ -1040,6 +1040,6 @@ Packet.prototype.write = function(path, packetHeader, messages, options) {
this.writeStream( this.writeStream(
fs.createWriteStream(path), // :TODO: specify mode/etc. fs.createWriteStream(path), // :TODO: specify mode/etc.
messages, messages,
{ packetHeader : packetHeader, terminatePacket : true } Object.assign( { packetHeader : packetHeader, terminatePacket : true }, options)
); );
}; };

View File

@ -225,11 +225,7 @@ function getVia(address) {
*/ */
const addrStr = new Address(address).toString('5D'); const addrStr = new Address(address).toString('5D');
const dateTime = moment().utc().format('YYYYMMDD.HHmmSS.SSSS.UTC'); const dateTime = moment().utc().format('YYYYMMDD.HHmmSS.SSSS.UTC');
const version = getCleanEnigmaVersion();
const version = packageJson.version
.replace(/\-/g, '.')
.replace(/alpha/,'a')
.replace(/beta/,'b');
return `${addrStr} @${dateTime} ENiGMA1/2 ${version}`; return `${addrStr} @${dateTime} ENiGMA1/2 ${version}`;
} }

View File

@ -33,4 +33,4 @@ MailPacket.prototype.write = function(options) {
// emits 'packet' event per packet constructed // emits 'packet' event per packet constructed
// //
assert(_.isArray(options.messages)); assert(_.isArray(options.messages));
} };

View File

@ -6,7 +6,7 @@ const Message = require('./message.js');
exports.getAddressedToInfo = getAddressedToInfo; exports.getAddressedToInfo = getAddressedToInfo;
const EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; const EMAIL_REGEX = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
/* /*
Input Output Input Output

View File

@ -10,7 +10,6 @@ const HorizontalMenuView = require('./horizontal_menu_view.js').HorizontalMenuV
const SpinnerMenuView = require('./spinner_menu_view.js').SpinnerMenuView; const SpinnerMenuView = require('./spinner_menu_view.js').SpinnerMenuView;
const ToggleMenuView = require('./toggle_menu_view.js').ToggleMenuView; const ToggleMenuView = require('./toggle_menu_view.js').ToggleMenuView;
const MaskEditTextView = require('./mask_edit_text_view.js').MaskEditTextView; const MaskEditTextView = require('./mask_edit_text_view.js').MaskEditTextView;
//const StatusBarView = require('./status_bar_view.js').StatusBarView;
const KeyEntryView = require('./key_entry_view.js'); const KeyEntryView = require('./key_entry_view.js');
const MultiLineEditTextView = require('./multi_line_edit_text_view.js').MultiLineEditTextView; const MultiLineEditTextView = require('./multi_line_edit_text_view.js').MultiLineEditTextView;
const getPredefinedMCIValue = require('./predefined_mci.js').getPredefinedMCIValue; const getPredefinedMCIValue = require('./predefined_mci.js').getPredefinedMCIValue;
@ -37,7 +36,7 @@ MCIViewFactory.UserViewCodes = [
'XY', 'XY',
]; ];
MCIViewFactory.prototype.createFromMCI = function(mci, cb) { MCIViewFactory.prototype.createFromMCI = function(mci) {
assert(mci.code); assert(mci.code);
assert(mci.id > 0); assert(mci.id > 0);
assert(mci.position); assert(mci.position);

View File

@ -548,7 +548,7 @@ Message.prototype.getQuoteLines = function(options, cb) {
quoteLines.push(`${lastSgr}${l}`); quoteLines.push(`${lastSgr}${l}`);
focusQuoteLines.push(`${options.ansiFocusPrefixSgr}>${lastSgr}${renderSubstr(l, 1, l.length - 1)}`); focusQuoteLines.push(`${options.ansiFocusPrefixSgr}>${lastSgr}${renderSubstr(l, 1, l.length - 1)}`);
lastSgr = (l.match(/(?:\x1b\x5b)[\?=;0-9]*m(?!.*(?:\x1b\x5b)[\?=;0-9]*m)/) || [])[0] || ''; // eslint-disable-line no-control-regex lastSgr = (l.match(/(?:\x1b\x5b)[?=;0-9]*m(?!.*(?:\x1b\x5b)[?=;0-9]*m)/) || [])[0] || ''; // eslint-disable-line no-control-regex
}); });
quoteLines[quoteLines.length - 1] += options.ansiResetSgr; quoteLines[quoteLines.length - 1] += options.ansiResetSgr;
@ -557,7 +557,7 @@ Message.prototype.getQuoteLines = function(options, cb) {
} }
); );
} else { } else {
const QUOTE_RE = /^ ((?:[A-Za-z0-9]{2}\> )+(?:[A-Za-z0-9]{2}\>)*) */; const QUOTE_RE = /^ ((?:[A-Za-z0-9]{2}> )+(?:[A-Za-z0-9]{2}>)*) */;
const quoted = []; const quoted = [];
const input = _.trimEnd(this.message).replace(/\b/g, ''); const input = _.trimEnd(this.message).replace(/\b/g, '');

View File

@ -159,18 +159,6 @@ function getMessageConferenceByTag(confTag) {
return Config.messageConferences[confTag]; return Config.messageConferences[confTag];
} }
function getMessageConfByAreaTag(areaTag) {
const confs = Config.messageConferences;
let conf;
_.forEach(confs, (v) => {
if(_.has(v, [ 'areas', areaTag ])) {
conf = v;
return false; // stop iteration
}
});
return conf;
}
function getMessageConfTagByAreaTag(areaTag) { function getMessageConfTagByAreaTag(areaTag) {
const confs = Config.messageConferences; const confs = Config.messageConferences;
return Object.keys(confs).find( (confTag) => { return Object.keys(confs).find( (confTag) => {

View File

@ -36,7 +36,7 @@ function resolvePath(path) {
function getCleanEnigmaVersion() { function getCleanEnigmaVersion() {
return packageJson.version return packageJson.version
.replace(/\-/g, '.') .replace(/-/g, '.')
.replace(/alpha/,'a') .replace(/alpha/,'a')
.replace(/beta/,'b') .replace(/beta/,'b')
; ;

View File

@ -98,9 +98,9 @@ exports.getModule = class MessageAreaListModule extends MenuModule {
}, timeout); }, timeout);
} }
updateGeneralAreaInfoViews(areaIndex) {
// :TODO: these concepts have been replaced with the {someKey} style formatting - update me! // :TODO: these concepts have been replaced with the {someKey} style formatting - update me!
/* experimental: not yet avail /*
updateGeneralAreaInfoViews(areaIndex) {
const areaInfo = self.messageAreas[areaIndex]; const areaInfo = self.messageAreas[areaIndex];
[ MciViewIds.SelAreaInfo1, MciViewIds.SelAreaInfo2 ].forEach(mciId => { [ MciViewIds.SelAreaInfo1, MciViewIds.SelAreaInfo2 ].forEach(mciId => {
@ -109,8 +109,8 @@ exports.getModule = class MessageAreaListModule extends MenuModule {
v.setFormatObject(areaInfo.area); v.setFormatObject(areaInfo.area);
} }
}); });
*/
} }
*/
mciReady(mciData, cb) { mciReady(mciData, cb) {
super.mciReady(mciData, err => { super.mciReady(mciData, err => {

View File

@ -13,12 +13,12 @@ function MessageScanTossModule() {
require('util').inherits(MessageScanTossModule, PluginModule); require('util').inherits(MessageScanTossModule, PluginModule);
MessageScanTossModule.prototype.startup = function(cb) { MessageScanTossModule.prototype.startup = function(cb) {
cb(null); return cb(null);
}; };
MessageScanTossModule.prototype.shutdown = function(cb) { MessageScanTossModule.prototype.shutdown = function(cb) {
cb(null); return cb(null);
}; };
MessageScanTossModule.prototype.record = function(message) { MessageScanTossModule.prototype.record = function(/*message*/) {
}; };

View File

@ -4,7 +4,6 @@
const View = require('./view.js').View; const View = require('./view.js').View;
const strUtil = require('./string_util.js'); const strUtil = require('./string_util.js');
const ansi = require('./ansi_term.js'); const ansi = require('./ansi_term.js');
const colorCodes = require('./color_codes.js');
const wordWrapText = require('./word_wrap.js').wordWrapText; const wordWrapText = require('./word_wrap.js').wordWrapText;
const ansiPrep = require('./ansi_prep.js'); const ansiPrep = require('./ansi_prep.js');
@ -12,11 +11,11 @@ const assert = require('assert');
const _ = require('lodash'); const _ = require('lodash');
// :TODO: Determine CTRL-* keys for various things // :TODO: Determine CTRL-* keys for various things
// See http://www.bbsdocumentary.com/library/PROGRAMS/GRAPHICS/ANSI/bansi.txt // See http://www.bbsdocumentary.com/library/PROGRAMS/GRAPHICS/ANSI/bansi.txt
// http://wiki.synchro.net/howto:editor:slyedit#edit_mode // http://wiki.synchro.net/howto:editor:slyedit#edit_mode
// http://sublime-text-unofficial-documentation.readthedocs.org/en/latest/reference/keyboard_shortcuts_win.html // http://sublime-text-unofficial-documentation.readthedocs.org/en/latest/reference/keyboard_shortcuts_win.html
/* Mystic /* Mystic
[^B] Reformat Paragraph [^O] Show this help file [^B] Reformat Paragraph [^O] Show this help file
[^I] Insert tab space [^Q] Enter quote mode [^I] Insert tab space [^Q] Enter quote mode
[^K] Cut current line of text [^V] Toggle insert/overwrite [^K] Cut current line of text [^V] Toggle insert/overwrite
@ -268,7 +267,7 @@ function MultiLineEditTextView(options) {
if(remain > 0) { if(remain > 0) {
text += ' '.repeat(remain + 1); text += ' '.repeat(remain + 1);
// text += new Array(remain + 1).join(' '); // text += new Array(remain + 1).join(' ');
} }
return text; return text;

View File

@ -3,5 +3,5 @@
exports.PluginModule = PluginModule; exports.PluginModule = PluginModule;
function PluginModule(options) { function PluginModule(/*options*/) {
} }

View File

@ -8,7 +8,9 @@ exports.readSAUCE = readSAUCE;
const SAUCE_SIZE = 128; const SAUCE_SIZE = 128;
const SAUCE_ID = new Buffer([0x53, 0x41, 0x55, 0x43, 0x45]); // 'SAUCE' const SAUCE_ID = new Buffer([0x53, 0x41, 0x55, 0x43, 0x45]); // 'SAUCE'
const COMNT_ID = new Buffer([0x43, 0x4f, 0x4d, 0x4e, 0x54]); // 'COMNT'
// :TODO read comments
//const COMNT_ID = new Buffer([0x43, 0x4f, 0x4d, 0x4e, 0x54]); // 'COMNT'
exports.SAUCE_SIZE = SAUCE_SIZE; exports.SAUCE_SIZE = SAUCE_SIZE;
// :TODO: SAUCE should be a class // :TODO: SAUCE should be a class
@ -137,7 +139,7 @@ var SAUCE_FONT_TO_ENCODING_HINT = {
}; };
['437', '720', '737', '775', '819', '850', '852', '855', '857', '858', ['437', '720', '737', '775', '819', '850', '852', '855', '857', '858',
'860', '861', '862', '863', '864', '865', '866', '869', '872'].forEach(function onPage(page) { '860', '861', '862', '863', '864', '865', '866', '869', '872'].forEach(function onPage(page) {
var codec = 'cp' + page; var codec = 'cp' + page;
SAUCE_FONT_TO_ENCODING_HINT['IBM EGA43 ' + page] = codec; SAUCE_FONT_TO_ENCODING_HINT['IBM EGA43 ' + page] = codec;
SAUCE_FONT_TO_ENCODING_HINT['IBM EGA ' + page] = codec; SAUCE_FONT_TO_ENCODING_HINT['IBM EGA ' + page] = codec;

View File

@ -1213,8 +1213,31 @@ function FTNMessageScanTossModule() {
User.getUserIdAndNameByLookup(lookupName, (err, localToUserId, localUserName) => { User.getUserIdAndNameByLookup(lookupName, (err, localToUserId, localUserName) => {
if(err) { if(err) {
//
// Couldn't find a local username. If the toUserName itself is a FTN address
// we can only assume the message is to the +op, else we'll have to fail.
//
const toUserNameAsAddress = Address.fromString(message.toUserName);
if(toUserNameAsAddress.isValid()) {
Log.info(
{ toUserName : message.toUserName, fromUserName : message.fromUserName },
'No local "to" username for FTN message. Appears to be a FTN address only; assuming addressed to SysOp'
);
User.getUserName(User.RootUserID, (err, sysOpUserName) => {
if(err) {
return callback(Errors.UnexpectedState('Failed to get SysOp user information'));
}
message.meta.System[Message.SystemMetaNames.LocalToUserID] = User.RootUserID;
message.toUserName = sysOpUserName;
return callback(null);
});
} else {
return callback(Errors.DoesNotExist(`Could not get local user ID for "${message.toUserName}": ${err.message}`)); return callback(Errors.DoesNotExist(`Could not get local user ID for "${message.toUserName}": ${err.message}`));
} }
}
// we do this after such that error cases can be preseved above // we do this after such that error cases can be preseved above
if(lookupName !== message.toUserName) { if(lookupName !== message.toUserName) {

View File

@ -232,7 +232,7 @@ exports.getModule = class SetNewScanDate extends MenuModule {
const scanDateView = vc.getView(MciViewIds.main.scanDate); const scanDateView = vc.getView(MciViewIds.main.scanDate);
// :TODO: MaskTextEditView needs some love: If setText() with input that matches the mask, we should ignore the non-mask chars! Hack in place for now // :TODO: MaskTextEditView needs some love: If setText() with input that matches the mask, we should ignore the non-mask chars! Hack in place for now
const scanDateFormat = self.scanDateFormat.replace(/[\/\-. ]/g, ''); const scanDateFormat = self.scanDateFormat.replace(/[/\-. ]/g, '');
scanDateView.setText(today.format(scanDateFormat)); scanDateView.setText(today.format(scanDateFormat));
if('message' === self.target) { if('message' === self.target) {

View File

@ -1,13 +1,12 @@
/* jslint node: true */ /* jslint node: true */
'use strict'; 'use strict';
var MenuView = require('./menu_view.js').MenuView; const MenuView = require('./menu_view.js').MenuView;
var ansi = require('./ansi_term.js'); const ansi = require('./ansi_term.js');
var strUtil = require('./string_util.js'); const strUtil = require('./string_util.js');
var util = require('util'); const util = require('util');
var assert = require('assert'); const assert = require('assert');
var _ = require('lodash');
exports.SpinnerMenuView = SpinnerMenuView; exports.SpinnerMenuView = SpinnerMenuView;

View File

@ -1,30 +0,0 @@
/* jslint node: true */
'use strict';
var userDb = require('./database.js').dbs.user;
exports.getSystemLoginHistory = getSystemLoginHistory;
function getSystemLoginHistory(numRequested, cb) {
numRequested = Math.max(1, numRequested);
var loginHistory = [];
userDb.each(
'SELECT user_id, user_name, timestamp ' +
'FROM user_login_history ' +
'ORDER BY timestamp DESC ' +
'LIMIT ' + numRequested + ';',
function historyRow(err, histEntry) {
loginHistory.push( {
userId : histEntry.user_id,
userName : histEntry.user_name,
timestamp : histEntry.timestamp,
} );
},
function complete(err, recCount) {
cb(err, loginHistory);
}
);
}

View File

@ -1,64 +0,0 @@
/* jslint node: true */
'use strict';
var View = require('./view.js').View;
var TextView = require('./text_view.js').TextView;
var assert = require('assert');
var _ = require('lodash');
function StatusBarView(options) {
View.call(this, options);
var self = this;
}
require('util').inherits(StatusBarView, View);
StatusBarView.prototype.redraw = function() {
StatusBarView.super_.prototype.redraw.call(this);
};
StatusBarView.prototype.setPanels = function(panels) {
/*
"panels" : [
{
"text" : "things and stuff",
"width" 20,
...
},
{
"width" : 40 // no text, etc... = spacer
}
]
|---------------------------------------------|
| stuff |
*/
assert(_.isArray(panels));
this.panels = [];
var tvOpts = {
cursor : 'hide',
position : { row : this.position.row, col : 0 },
};
panels.forEach(function panel(p) {
assert(_.isObject(p));
assert(_.has(p, 'width'));
if(p.text) {
this.panels.push( new TextView( { }))
} else {
this.panels.push( { width : p.width } );
}
});
};

View File

@ -293,7 +293,7 @@ function transformValue(transformerName, value) {
} }
// :TODO: Use explicit set of chars for paths & function/transforms such that } is allowed as fill/etc. // :TODO: Use explicit set of chars for paths & function/transforms such that } is allowed as fill/etc.
const REGEXP_BASIC_FORMAT = /{([^.!:}]+(?:\.[^.!:}]+)*)(?:\!([^:}]+))?(?:\:([^}]+))?}/g; const REGEXP_BASIC_FORMAT = /{([^.!:}]+(?:\.[^.!:}]+)*)(?:!([^:}]+))?(?::([^}]+))?}/g;
function getValue(obj, path) { function getValue(obj, path) {
const value = _.get(obj, path); const value = _.get(obj, path);

View File

@ -3,7 +3,6 @@
// ENiGMA½ // ENiGMA½
const miscUtil = require('./misc_util.js'); const miscUtil = require('./misc_util.js');
const ANSIEscapeParser = require('./ansi_escape_parser.js').ANSIEscapeParser;
const ANSI = require('./ansi_term.js'); const ANSI = require('./ansi_term.js');
// deps // deps
@ -198,11 +197,6 @@ function isPrintable(s) {
return !RE_NON_PRINTABLE.test(s); return !RE_NON_PRINTABLE.test(s);
} }
function stringLength(s) {
// :TODO: See https://mathiasbynens.be/notes/javascript-unicode
return s.length;
}
function stripAllLineFeeds(s) { function stripAllLineFeeds(s) {
return s.replace(/\r?\n|[\r\u2028\u2029]/g, ''); return s.replace(/\r?\n|[\r\u2028\u2029]/g, '');
} }
@ -359,7 +353,7 @@ function formatCount(count, withAbbr = false, decimals = 2) {
// :TODO: See notes in word_wrap.js about need to consolidate the various ANSI related RegExp's // :TODO: See notes in word_wrap.js about need to consolidate the various ANSI related RegExp's
//const REGEXP_ANSI_CONTROL_CODES = /(\x1b\x5b)([\?=;0-9]*?)([0-9A-ORZcf-npsu=><])/g; //const REGEXP_ANSI_CONTROL_CODES = /(\x1b\x5b)([\?=;0-9]*?)([0-9A-ORZcf-npsu=><])/g;
const REGEXP_ANSI_CONTROL_CODES = /(?:\x1b\x5b)([\?=;0-9]*?)([A-ORZcf-npsu=><])/g; // eslint-disable-line no-control-regex const REGEXP_ANSI_CONTROL_CODES = /(?:\x1b\x5b)([?=;0-9]*?)([A-ORZcf-npsu=><])/g; // eslint-disable-line no-control-regex
const ANSI_OPCODES_ALLOWED_CLEAN = [ const ANSI_OPCODES_ALLOWED_CLEAN = [
//'A', 'B', // up, down //'A', 'B', // up, down
//'C', 'D', // right, left //'C', 'D', // right, left
@ -405,194 +399,6 @@ function cleanControlCodes(input, options) {
return cleaned; return cleaned;
} }
function prepAnsi(input, options, cb) {
if(!input) {
return cb(null, '');
}
options.termWidth = options.termWidth || 80;
options.termHeight = options.termHeight || 25;
options.cols = options.cols || options.termWidth || 80;
options.rows = options.rows || options.termHeight || 'auto';
options.startCol = options.startCol || 1;
options.exportMode = options.exportMode || false;
const canvas = Array.from( { length : 'auto' === options.rows ? 25 : options.rows }, () => Array.from( { length : options.cols}, () => new Object() ) );
const parser = new ANSIEscapeParser( { termHeight : options.termHeight, termWidth : options.termWidth } );
const state = {
row : 0,
col : 0,
};
let lastRow = 0;
function ensureRow(row) {
if(Array.isArray(canvas[row])) {
return;
}
canvas[row] = Array.from( { length : options.cols}, () => new Object() );
}
parser.on('position update', (row, col) => {
state.row = row - 1;
state.col = col - 1;
lastRow = Math.max(state.row, lastRow);
});
parser.on('literal', literal => {
//
// CR/LF are handled for 'position update'; we don't need the chars themselves
//
literal = literal.replace(/\r?\n|[\r\u2028\u2029]/g, '');
for(let c of literal) {
if(state.col < options.cols && ('auto' === options.rows || state.row < options.rows)) {
ensureRow(state.row);
canvas[state.row][state.col].char = c;
if(state.sgr) {
canvas[state.row][state.col].sgr = state.sgr;
state.sgr = null;
}
}
state.col += 1;
}
});
parser.on('control', (match, opCode) => {
//
// Movement is handled via 'position update', so we really only care about
// display opCodes
//
switch(opCode) {
case 'm' :
state.sgr = (state.sgr || '') + match;
break;
default :
break;
}
});
function getLastPopulatedColumn(row) {
let col = row.length;
while(--col > 0) {
if(row[col].char || row[col].sgr) {
break;
}
}
return col;
}
parser.on('complete', () => {
let output = '';
let lastSgr = '';
let line;
canvas.slice(0, lastRow + 1).forEach(row => {
const lastCol = getLastPopulatedColumn(row) + 1;
let i;
line = '';
for(i = 0; i < lastCol; ++i) {
const col = row[i];
if(col.sgr) {
lastSgr = col.sgr;
}
line += `${col.sgr || ''}${col.char || ' '}`;
}
output += line;
if(i < row.length) {
output += `${ANSI.blackBG()}${row.slice(i).map( () => ' ').join('')}${lastSgr}`;
}
//if(options.startCol + options.cols < options.termWidth || options.forceLineTerm) {
if(options.startCol + i < options.termWidth || options.forceLineTerm) {
output += '\r\n';
}
});
if(options.exportMode) {
//
// If we're in export mode, we do some additional hackery:
//
// * Hard wrap ALL lines at <= 79 *characters* (not visible columns)
// if a line must wrap early, we'll place a ESC[A ESC[<N>C where <N>
// represents chars to get back to the position we were previously at
//
// * Replace contig spaces with ESC[<N>C as well to save... space.
//
// :TODO: this would be better to do as part of the processing above, but this will do for now
const MAX_CHARS = 79 - 8; // 79 max, - 8 for max ESC seq's we may prefix a line with
let exportOutput = '';
let m;
let afterSeq;
let wantMore;
let renderStart;
splitTextAtTerms(output).forEach(fullLine => {
renderStart = 0;
while(fullLine.length > 0) {
let splitAt;
const ANSI_REGEXP = ANSI.getFullMatchRegExp();
wantMore = true;
while((m = ANSI_REGEXP.exec(fullLine))) {
afterSeq = m.index + m[0].length;
if(afterSeq < MAX_CHARS) {
// after current seq
splitAt = afterSeq;
} else {
if(m.index < MAX_CHARS) {
// before last found seq
splitAt = m.index;
wantMore = false; // can't eat up any more
}
break; // seq's beyond this point are >= MAX_CHARS
}
}
if(splitAt) {
if(wantMore) {
splitAt = Math.min(fullLine.length, MAX_CHARS - 1);
}
} else {
splitAt = Math.min(fullLine.length, MAX_CHARS - 1);
}
const part = fullLine.slice(0, splitAt);
fullLine = fullLine.slice(splitAt);
renderStart += renderStringLength(part);
exportOutput += `${part}\r\n`;
if(fullLine.length > 0) { // more to go for this line?
exportOutput += `${ANSI.up()}${ANSI.right(renderStart)}`;
} else {
exportOutput += ANSI.up();
}
}
});
return cb(null, exportOutput);
}
return cb(null, output);
});
parser.parse(input);
}
function isAnsiLine(line) { function isAnsiLine(line) {
return isAnsi(line);// || renderStringLength(line) < line.length; return isAnsi(line);// || renderStringLength(line) < line.length;
} }
@ -622,6 +428,7 @@ function isFormattedLine(line) {
return false; return false;
} }
// :TODO: rename to containsAnsi()
function isAnsi(input) { function isAnsi(input) {
if(!input || 0 === input.length) { if(!input || 0 === input.length) {
return false; return false;
@ -647,7 +454,7 @@ function isAnsi(input) {
*/ */
// :TODO: if a similar method is kept, use exec() until threshold // :TODO: if a similar method is kept, use exec() until threshold
const ANSI_DET_REGEXP = /(?:\x1b\x5b)[\?=;0-9]*?[ABCDEFGHJKLMSTfhlmnprsu]/g; // eslint-disable-line no-control-regex const ANSI_DET_REGEXP = /(?:\x1b\x5b)[?=;0-9]*?[ABCDEFGHJKLMSTfhlmnprsu]/g; // eslint-disable-line no-control-regex
const m = input.match(ANSI_DET_REGEXP) || []; const m = input.match(ANSI_DET_REGEXP) || [];
return m.length >= 4; // :TODO: do this reasonably, e.g. a percent or soemthing return m.length >= 4; // :TODO: do this reasonably, e.g. a percent or soemthing
} }

View File

@ -110,7 +110,7 @@ function validateEmailAvail(data, cb) {
// //
// See http://stackoverflow.com/questions/7786058/find-the-regex-used-by-html5-forms-for-validation // See http://stackoverflow.com/questions/7786058/find-the-regex-used-by-html5-forms-for-validation
// //
const emailRegExp = /[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9-]+(.[a-z0-9-]+)*/; const emailRegExp = /[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-z0-9-]+(.[a-z0-9-]+)*/;
if(!emailRegExp.test(data)) { if(!emailRegExp.test(data)) {
return cb(new Error('Invalid email address')); return cb(new Error('Invalid email address'));
} }

View File

@ -44,7 +44,7 @@ function TextView(options) {
this.textMaskChar = options.textMaskChar; this.textMaskChar = options.textMaskChar;
} }
/* /*
this.drawText = function(s) { this.drawText = function(s) {
// //

View File

@ -1,94 +0,0 @@
/* jslint node: true */
'use strict';
var View = require('./view.js').View;
var miscUtil = require('./misc_util.js');
var strUtil = require('./string_util.js');
var ansi = require('./ansi_term.js');
var util = require('util');
var assert = require('assert');
exports.TickerTextView = TickerTextView;
function TickerTextView(options) {
View.call(this, options);
var self = this;
this.text = options.text || '';
this.tickerStyle = options.tickerStyle || 'rightToLeft';
assert(this.tickerStyle in TickerTextView.TickerStyles);
// :TODO: Ticker |text| should have ANSI stripped before calculating any lengths/etc.
// strUtil.ansiTextLength(s)
// strUtil.pad(..., ignoreAnsi)
// strUtil.stylizeString(..., ignoreAnsi)
this.tickerState = {};
switch(this.tickerStyle) {
case 'rightToLeft' :
this.tickerState.pos = this.position.row + this.dimens.width;
break;
}
self.onTickerInterval = function() {
switch(self.tickerStyle) {
case 'rightToLeft' : self.updateRightToLeftTicker(); break;
}
};
self.updateRightToLeftTicker = function() {
// if pos < start
// drawRemain()
// if pos + remain > end
// drawRemain(0, spaceFor)
// else
// drawString() + remainPading
};
}
util.inherits(TickerTextView, View);
TickerTextView.TickerStyles = {
leftToRight : 1,
rightToLeft : 2,
bounce : 3,
slamLeft : 4,
slamRight : 5,
slamBounce : 6,
decrypt : 7,
typewriter : 8,
};
Object.freeze(TickerTextView.TickerStyles);
/*
TickerTextView.TICKER_STYLES = [
'leftToRight',
'rightToLeft',
'bounce',
'slamLeft',
'slamRight',
'slamBounce',
'decrypt',
'typewriter',
];
*/
TickerTextView.prototype.controllerAttached = function() {
// :TODO: call super
};
TickerTextView.prototype.controllerDetached = function() {
// :TODO: call super
};
TickerTextView.prototype.setText = function(text) {
this.text = strUtil.stylizeString(text, this.textStyle);
if(!this.dimens || !this.dimens.width) {
this.dimens.width = Math.ceil(this.text.length / 2);
}
};

View File

@ -1,13 +1,11 @@
/* jslint node: true */ /* jslint node: true */
'use strict'; 'use strict';
var MenuView = require('./menu_view.js').MenuView; const MenuView = require('./menu_view.js').MenuView;
var ansi = require('./ansi_term.js'); const strUtil = require('./string_util.js');
var strUtil = require('./string_util.js');
var util = require('util'); const util = require('util');
var assert = require('assert'); const assert = require('assert');
var _ = require('lodash');
exports.ToggleMenuView = ToggleMenuView; exports.ToggleMenuView = ToggleMenuView;

View File

@ -1,11 +1,10 @@
/* jslint node: true */ /* jslint node: true */
'use strict'; 'use strict';
var userDb = require('./database.js').dbs.user; const userDb = require('./database.js').dbs.user;
var Config = require('./config.js').config;
var async = require('async'); const async = require('async');
var _ = require('lodash'); const _ = require('lodash');
exports.getGroupsForUser = getGroupsForUser; exports.getGroupsForUser = getGroupsForUser;
exports.addUserToGroup = addUserToGroup; exports.addUserToGroup = addUserToGroup;
@ -13,23 +12,22 @@ exports.addUserToGroups = addUserToGroups;
exports.removeUserFromGroup = removeUserFromGroup; exports.removeUserFromGroup = removeUserFromGroup;
function getGroupsForUser(userId, cb) { function getGroupsForUser(userId, cb) {
var sql = const sql =
'SELECT group_name ' + `SELECT group_name
'FROM user_group_member ' + FROM user_group_member
'WHERE user_id=?;'; WHERE user_id=?;`;
var groups = []; const groups = [];
userDb.each(sql, [ userId ], function rowData(err, row) { userDb.each(sql, [ userId ], (err, row) => {
if(err) { if(err) {
cb(err); return cb(err);
return;
} else {
groups.push(row.group_name);
} }
groups.push(row.group_name);
}, },
function complete() { () => {
cb(null, groups); return cb(null, groups);
}); });
} }
@ -40,31 +38,31 @@ function addUserToGroup(userId, groupName, transOrDb, cb) {
} }
transOrDb.run( transOrDb.run(
'REPLACE INTO user_group_member (group_name, user_id) ' + `REPLACE INTO user_group_member (group_name, user_id)
'VALUES(?, ?);', VALUES(?, ?);`,
[ groupName, userId ], [ groupName, userId ],
function complete(err) { err => {
cb(err); return cb(err);
} }
); );
} }
function addUserToGroups(userId, groups, transOrDb, cb) { function addUserToGroups(userId, groups, transOrDb, cb) {
async.each(groups, function item(groupName, next) { async.each(groups, (groupName, nextGroupName) => {
addUserToGroup(userId, groupName, transOrDb, next); return addUserToGroup(userId, groupName, transOrDb, nextGroupName);
}, function complete(err) { }, err => {
cb(err); return cb(err);
}); });
} }
function removeUserFromGroup(userId, groupName, cb) { function removeUserFromGroup(userId, groupName, cb) {
userDb.run( userDb.run(
'DELETE FROM user_group_member ' + `DELETE FROM user_group_member
'WHERE group_name=? AND user_id=?;', WHERE group_name=? AND user_id=?;`,
[ groupName, userId ], [ groupName, userId ],
function complete(err) { err => {
cb(err); return cb(err);
} }
); );
} }

View File

@ -166,20 +166,6 @@ function ViewController(options) {
var propAsset; var propAsset;
var propValue; var propValue;
function callModuleMethod(path) {
if('' === paths.extname(path)) {
path += '.js';
}
try {
var methodMod = require(path);
// :TODO: fix formData & extraArgs
return methodMod[propAsset.asset](self.client.currentMenuModule, {}, {} );
} catch(e) {
self.client.log.error( { error : e.toString(), methodName : propAsset.asset }, 'Failed to execute asset method');
}
}
for(var propName in conf) { for(var propName in conf) {
propAsset = asset.getViewPropertyAsset(conf[propName]); propAsset = asset.getViewPropertyAsset(conf[propName]);
if(propAsset) { if(propAsset) {
@ -211,7 +197,7 @@ function ViewController(options) {
} }
} else { } else {
if(_.isString(propAsset.location)) { if(_.isString(propAsset.location)) {
// :TODO: clean this code up!
} else { } else {
if('systemMethod' === propAsset.type) { if('systemMethod' === propAsset.type) {
// :TODO: // :TODO:

View File

@ -13,7 +13,6 @@ const Log = require('./logger.js').log;
// deps // deps
const async = require('async'); const async = require('async');
const _ = require('lodash');
const crypto = require('crypto'); const crypto = require('crypto');
const fs = require('graceful-fs'); const fs = require('graceful-fs');
const url = require('url'); const url = require('url');
@ -128,7 +127,11 @@ class WebPasswordReset {
}; };
sendMail(message, (err, info) => { sendMail(message, (err, info) => {
// :TODO: Log me! if(err) {
Log.warn( { error : err.message }, 'Failed sending password reset email' );
} else {
Log.debug( { info : info }, 'Successfully sent password reset email');
}
return callback(err); return callback(err);
}); });

View File

@ -1,11 +1,13 @@
/* jslint node: true */ /* jslint node: true */
'use strict'; 'use strict';
var assert = require('assert');
var _ = require('lodash');
const renderStringLength = require('./string_util.js').renderStringLength; const renderStringLength = require('./string_util.js').renderStringLength;
exports.wordWrapText = wordWrapText2; // deps
const assert = require('assert');
const _ = require('lodash');
exports.wordWrapText = wordWrapText;
const SPACE_CHARS = [ const SPACE_CHARS = [
' ', '\f', '\n', '\r', '\v', ' ', '\f', '\n', '\r', '\v',
@ -16,7 +18,7 @@ const SPACE_CHARS = [
const REGEXP_WORD_WRAP = new RegExp(`\t|[${SPACE_CHARS.join('')}]`, 'g'); const REGEXP_WORD_WRAP = new RegExp(`\t|[${SPACE_CHARS.join('')}]`, 'g');
function wordWrapText2(text, options) { function wordWrapText(text, options) {
assert(_.isObject(options)); assert(_.isObject(options));
assert(_.isNumber(options.width)); assert(_.isNumber(options.width));
@ -99,119 +101,3 @@ function wordWrapText2(text, options) {
return result; return result;
} }
function wordWrapText(text, options) {
//
// options.*:
// width : word wrap width
// tabHandling : expand (default=expand)
// tabWidth : tab width if tabHandling is 'expand' (default=4)
// tabChar : character to use for tab expansion
//
assert(_.isObject(options), 'Missing options!');
assert(_.isNumber(options.width), 'Missing options.width!');
options.tabHandling = options.tabHandling || 'expand';
if(!_.isNumber(options.tabWidth)) {
options.tabWidth = 4;
}
options.tabChar = options.tabChar || ' ';
//
// Notes
// * Sublime Text 3 for example considers spaces after a word
// part of said word. For example, "word " would be wraped
// in it's entirity.
//
// * Tabs in Sublime Text 3 are also treated as a word, so, e.g.
// "\t" may resolve to " " and must fit within the space.
//
// * If a word is ultimately too long to fit, break it up until it does.
//
// RegExp below is JavaScript '\s' minus the '\t'
//
var re = new RegExp(
'\t|[ \f\n\r\v\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006' +
'\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000]', 'g');
var m;
var wordStart = 0;
var results = { wrapped : [ '' ] };
var i = 0;
var word;
var wordLen;
function expandTab(col) {
var remainWidth = options.tabWidth - (col % options.tabWidth);
return new Array(remainWidth).join(options.tabChar);
}
// :TODO: support wrapping pipe code text (e.g. ignore color codes, expand MCI codes)
function addWord() {
word.match(new RegExp('.{0,' + options.width + '}', 'g')).forEach(function wrd(w) {
//wordLen = self.getStringLength(w);
if(results.wrapped[i].length + w.length > options.width) {
//if(results.wrapped[i].length + wordLen > width) {
if(0 === i) {
results.firstWrapRange = { start : wordStart, end : wordStart + w.length };
//results.firstWrapRange = { start : wordStart, end : wordStart + wordLen };
}
// :TODO: Must handle len of |w| itself > options.width & split how ever many times required (e.g. handle paste)
results.wrapped[++i] = w;
} else {
results.wrapped[i] += w;
}
});
}
while((m = re.exec(text)) !== null) {
word = text.substring(wordStart, re.lastIndex - 1);
switch(m[0].charAt(0)) {
case ' ' :
word += m[0];
break;
case '\t' :
//
// Expand tab given position
//
// Nice info here: http://c-for-dummies.com/blog/?p=424
//
if('expand' === options.tabHandling) {
word += expandTab(results.wrapped[i].length + word.length) + options.tabChar;
} else {
word += m[0];
}
break;
}
addWord();
wordStart = re.lastIndex + m[0].length - 1;
}
//
// Remainder
//
word = text.substring(wordStart);
addWord();
return results;
}
//const input = 'Hello, |04World! This |08i|02s a test it is \x1b[20Conly a test of the emergency broadcast system. What you see is not a joke!';
//const input = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five enturies, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.";
/*
const iconv = require('iconv-lite');
const input = iconv.decode(require('graceful-fs').readFileSync('/home/nuskooler/Downloads/msg_out.txt'), 'cp437');
const opts = {
width : 80,
};
console.log(wordWrapText2(input, opts).wrapped, 'utf8')
*/