* Code cleanup and eslint since -- remove unused variables, clean up RegExs, so on...
This commit is contained in:
parent
a106050ba3
commit
ac1433e84b
|
@ -3,7 +3,9 @@
|
|||
|
||||
const miscUtil = require('./misc_util.js');
|
||||
const ansi = require('./ansi_term.js');
|
||||
const Log = require('./logger.js').log;
|
||||
|
||||
// deps
|
||||
const events = require('events');
|
||||
const util = require('util');
|
||||
const _ = require('lodash');
|
||||
|
@ -24,7 +26,7 @@ function ANSIEscapeParser(options) {
|
|||
this.graphicRendition = {};
|
||||
|
||||
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, {
|
||||
|
@ -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) {
|
||||
// :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 match;
|
||||
var mciCode;
|
||||
|
@ -197,16 +191,12 @@ function ANSIEscapeParser(options) {
|
|||
if(self.mciReplaceChar.length > 0) {
|
||||
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));
|
||||
} else {
|
||||
literal(match[0]);
|
||||
}
|
||||
|
||||
//literal(getProcessedMCI(match[0]));
|
||||
|
||||
//self.emit('chunk', getProcessedMCI(match[0]));
|
||||
}
|
||||
|
||||
} while(0 !== mciRe.lastIndex);
|
||||
|
@ -220,7 +210,7 @@ function ANSIEscapeParser(options) {
|
|||
self.parseState = {
|
||||
// ignore anything past EOF marker, if any
|
||||
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,
|
||||
};
|
||||
};
|
||||
|
@ -291,7 +281,7 @@ function ANSIEscapeParser(options) {
|
|||
}
|
||||
}
|
||||
|
||||
parseMCI(lastBit)
|
||||
parseMCI(lastBit);
|
||||
}
|
||||
|
||||
self.emit('complete');
|
||||
|
@ -448,7 +438,7 @@ function ANSIEscapeParser(options) {
|
|||
break;
|
||||
|
||||
default :
|
||||
console.log('Unknown attribute: ' + arg); // :TODO: Log properly
|
||||
Log.trace( { attribute : arg }, 'Unknown attribute while parsing ANSI');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,9 +108,11 @@ module.exports = class ArchiveUtil {
|
|||
return this.getArchiver(archType) ? true : false;
|
||||
}
|
||||
|
||||
// :TODO: implement me:
|
||||
/*
|
||||
detectTypeWithBuf(buf, cb) {
|
||||
// :TODO: implement me!
|
||||
}
|
||||
*/
|
||||
|
||||
detectType(path, cb) {
|
||||
fs.open(path, 'r', (err, fd) => {
|
||||
|
|
|
@ -52,8 +52,8 @@ exports.Client = Client;
|
|||
// Resources & Standards:
|
||||
// * http://www.ansi-bbs.org/ansi-bbs-core-server.html
|
||||
//
|
||||
const RE_DSR_RESPONSE_ANYWHERE = /(?:\u001b\[)([0-9\;]+)(R)/;
|
||||
const RE_DEV_ATTR_RESPONSE_ANYWHERE = /(?:\u001b\[)[\=\?]([0-9a-zA-Z\;]+)(c)/;
|
||||
const RE_DSR_RESPONSE_ANYWHERE = /(?:\u001b\[)([0-9;]+)(R)/;
|
||||
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 = new RegExp('^' + RE_META_KEYCODE_ANYWHERE.source + '$');
|
||||
const RE_FUNCTION_KEYCODE_ANYWHERE = new RegExp('(?:\u001b+)(O|N|\\[|\\[\\[)(?:' + [
|
||||
|
@ -72,7 +72,7 @@ const RE_ESC_CODE_ANYWHERE = new RegExp( [
|
|||
].join('|'));
|
||||
|
||||
|
||||
function Client(input, output) {
|
||||
function Client(/*input, output*/) {
|
||||
stream.call(this);
|
||||
|
||||
const self = this;
|
||||
|
@ -139,8 +139,8 @@ function Client(input, output) {
|
|||
};
|
||||
|
||||
this.isMouseInput = function(data) {
|
||||
return /\x1b\[M/.test(data) ||
|
||||
/\u001b\[M([\x00\u0020-\uffff]{3})/.test(data) ||
|
||||
return /\x1b\[M/.test(data) || // eslint-disable-line no-control-regex
|
||||
/\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+)([mM])/.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
|
||||
Client.prototype.defaultHandlerMissingMod = function(err) {
|
||||
Client.prototype.defaultHandlerMissingMod = function() {
|
||||
var self = this;
|
||||
|
||||
function handler(err) {
|
||||
|
|
|
@ -15,8 +15,6 @@ exports.ClientTerminal = ClientTerminal;
|
|||
function ClientTerminal(output) {
|
||||
this.output = output;
|
||||
|
||||
var self = this;
|
||||
|
||||
var outputEncoding = 'cp437';
|
||||
assert(iconv.encodingExists(outputEncoding));
|
||||
|
||||
|
|
|
@ -180,7 +180,7 @@ function renegadeToAnsi(s, client) {
|
|||
// * http://wiki.synchro.net/custom:colors
|
||||
//
|
||||
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 result = '';
|
||||
|
|
|
@ -62,21 +62,21 @@ exports.getModule = class CombatNetModule extends MenuModule {
|
|||
rlogin.on('error', err => {
|
||||
self.client.log.info(`CombatNet rlogin client error: ${err.message}`);
|
||||
restorePipeToNormal();
|
||||
callback(err);
|
||||
return callback(err);
|
||||
});
|
||||
|
||||
// If we've been disconnected ...
|
||||
rlogin.on('disconnect', () => {
|
||||
self.client.log.info(`Disconnected from CombatNet`);
|
||||
self.client.log.info('Disconnected from CombatNet');
|
||||
restorePipeToNormal();
|
||||
callback(null);
|
||||
return callback(null);
|
||||
});
|
||||
|
||||
function sendToRloginBuffer(buffer) {
|
||||
rlogin.send(buffer);
|
||||
};
|
||||
}
|
||||
|
||||
rlogin.on("connect",
|
||||
rlogin.on('connect',
|
||||
/* The 'connect' event handler will be supplied with one argument,
|
||||
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 ...
|
||||
rlogin.on("data", (data) => {
|
||||
rlogin.on('data', (data) => {
|
||||
self.client.term.rawWrite(data);
|
||||
});
|
||||
|
||||
|
|
|
@ -653,12 +653,12 @@ function getDefaultConfig() {
|
|||
// 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.
|
||||
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
|
||||
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
|
||||
],
|
||||
},
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ function getModDatabasePath(moduleInfo, suffix) {
|
|||
// We expect that moduleInfo defines packageName which will be the base of the modules
|
||||
// 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(_.isString(moduleInfo.packageName), 'moduleInfo must define "packageName"!');
|
||||
|
|
|
@ -24,8 +24,8 @@ exports.moduleInfo = {
|
|||
author : 'NuSkooler',
|
||||
};
|
||||
|
||||
const SCHEDULE_REGEXP = /(?:^|or )?(@watch\:)([^\0]+)?$/;
|
||||
const ACTION_REGEXP = /\@(method|execute)\:([^\0]+)?$/;
|
||||
const SCHEDULE_REGEXP = /(?:^|or )?(@watch:)([^\0]+)?$/;
|
||||
const ACTION_REGEXP = /@(method|execute):([^\0]+)?$/;
|
||||
|
||||
class ScheduledEvent {
|
||||
constructor(events, name) {
|
||||
|
|
|
@ -586,10 +586,6 @@ function addNewFileEntry(fileEntry, filePath, cb) {
|
|||
);
|
||||
}
|
||||
|
||||
function updateFileEntry(fileEntry, filePath, cb) {
|
||||
|
||||
}
|
||||
|
||||
const HASH_NAMES = [ 'sha1', 'sha256', 'md5', 'crc32' ];
|
||||
|
||||
function scanFile(filePath, options, iterator, cb) {
|
||||
|
@ -747,7 +743,9 @@ function scanFile(filePath, options, iterator, cb) {
|
|||
populateFileEntryWithArchive(fileEntry, filePath, stepInfo, callIter, err => {
|
||||
if(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
|
||||
});
|
||||
} else {
|
||||
|
@ -756,7 +754,9 @@ function scanFile(filePath, options, iterator, cb) {
|
|||
});
|
||||
} else {
|
||||
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
|
||||
});
|
||||
}
|
||||
|
@ -874,7 +874,7 @@ function getDescFromFileName(fileName) {
|
|||
const ext = paths.extname(fileName);
|
||||
const name = paths.basename(fileName, ext);
|
||||
|
||||
return _.upperFirst(name.replace(/[\-_.+]/g, ' ').replace(/\s+/g, ' '));
|
||||
return _.upperFirst(name.replace(/[-_.+]/g, ' ').replace(/\s+/g, ' '));
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -59,8 +59,6 @@ exports.getModule = class FileBaseDownloadQueueManager extends MenuModule {
|
|||
|
||||
return this.gotoMenu(this.menuConfig.config.fileTransferProtocolSelection || 'fileTransferProtocolSelection', modOpts, cb);
|
||||
},
|
||||
viewItemInfo : (formData, extraArgs, cb) => {
|
||||
},
|
||||
removeItem : (formData, extraArgs, cb) => {
|
||||
const selectedItem = this.dlQueue.items[formData.value.queueItem];
|
||||
if(!selectedItem) {
|
||||
|
|
|
@ -94,7 +94,7 @@ module.exports = class FileBaseFilters {
|
|||
}
|
||||
|
||||
cleanTags(tags) {
|
||||
return tags.toLowerCase().replace(/,?\s+|\,/g, ' ').trim();
|
||||
return tags.toLowerCase().replace(/,?\s+|,/g, ' ').trim();
|
||||
}
|
||||
|
||||
setActive(filterUuid) {
|
||||
|
|
|
@ -284,4 +284,3 @@ exports.getModule = class FileBaseWebDownloadQueueManager extends MenuModule {
|
|||
);
|
||||
}
|
||||
};
|
||||
|
|
@ -46,5 +46,5 @@ module.exports = class FNV1a {
|
|||
get value() {
|
||||
return this.hash & 0xffffffff;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
20
core/fse.js
20
core/fse.js
|
@ -179,13 +179,12 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul
|
|||
|
||||
self.switchFooter(function next(err) {
|
||||
if(err) {
|
||||
// :TODO:... what now?
|
||||
console.log(err)
|
||||
} else {
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
switch(self.footerMode) {
|
||||
case 'editor' :
|
||||
if(!_.isUndefined(self.viewControllers.footerEditorMenu)) {
|
||||
//self.viewControllers.footerEditorMenu.setFocus(false);
|
||||
self.viewControllers.footerEditorMenu.detachClientEvents();
|
||||
}
|
||||
self.viewControllers.body.switchFocus(1);
|
||||
|
@ -199,7 +198,6 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul
|
|||
|
||||
default : throw new Error('Unexpected mode');
|
||||
}
|
||||
}
|
||||
|
||||
return cb(null);
|
||||
});
|
||||
|
@ -534,7 +532,7 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul
|
|||
art[n],
|
||||
self.client,
|
||||
{ font : self.menuConfig.font },
|
||||
function displayed(err, artData) {
|
||||
function displayed(err) {
|
||||
next(err);
|
||||
}
|
||||
);
|
||||
|
@ -645,8 +643,7 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul
|
|||
],
|
||||
function complete(err) {
|
||||
if(err) {
|
||||
// :TODO: This needs properly handled!
|
||||
console.log(err)
|
||||
self.client.log.warn( { error : err.message }, 'FSE init error');
|
||||
} else {
|
||||
self.isReady = true;
|
||||
self.finishedLoading();
|
||||
|
@ -763,10 +760,7 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul
|
|||
}
|
||||
],
|
||||
function complete(err) {
|
||||
if(err) {
|
||||
console.error(err)
|
||||
}
|
||||
cb(err);
|
||||
return cb(err);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -954,7 +948,7 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul
|
|||
],
|
||||
function complete(err) {
|
||||
if(err) {
|
||||
console.log(err) // :TODO: needs real impl.
|
||||
self.client.log.warn( { error : err.message }, 'Error displaying quote builder');
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
const _ = require('lodash');
|
||||
|
||||
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_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;
|
||||
|
||||
module.exports = class Address {
|
||||
constructor(addr) {
|
||||
|
|
|
@ -429,9 +429,9 @@ function Packet(options) {
|
|||
// messageBodyBuffer = messageBodyBuffer.slice(0, sauceHeaderPosition);
|
||||
messageBodyData.sauce = theSauce;
|
||||
} 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 {
|
||||
callback(null);
|
||||
|
@ -497,7 +497,7 @@ function Packet(options) {
|
|||
} else if(line.startsWith('--- ')) {
|
||||
// Tear Lines are tracked allowing for specialized display/etc.
|
||||
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;
|
||||
endOfMessage = true; // Anything past origin is not part of the message body
|
||||
} else if(line.startsWith('SEEN-BY:')) {
|
||||
|
@ -1040,6 +1040,6 @@ Packet.prototype.write = function(path, packetHeader, messages, options) {
|
|||
this.writeStream(
|
||||
fs.createWriteStream(path), // :TODO: specify mode/etc.
|
||||
messages,
|
||||
{ packetHeader : packetHeader, terminatePacket : true }
|
||||
Object.assign( { packetHeader : packetHeader, terminatePacket : true }, options)
|
||||
);
|
||||
};
|
||||
|
|
|
@ -225,11 +225,7 @@ function getVia(address) {
|
|||
*/
|
||||
const addrStr = new Address(address).toString('5D');
|
||||
const dateTime = moment().utc().format('YYYYMMDD.HHmmSS.SSSS.UTC');
|
||||
|
||||
const version = packageJson.version
|
||||
.replace(/\-/g, '.')
|
||||
.replace(/alpha/,'a')
|
||||
.replace(/beta/,'b');
|
||||
const version = getCleanEnigmaVersion();
|
||||
|
||||
return `${addrStr} @${dateTime} ENiGMA1/2 ${version}`;
|
||||
}
|
||||
|
|
|
@ -33,4 +33,4 @@ MailPacket.prototype.write = function(options) {
|
|||
// emits 'packet' event per packet constructed
|
||||
//
|
||||
assert(_.isArray(options.messages));
|
||||
}
|
||||
};
|
|
@ -6,7 +6,7 @@ const Message = require('./message.js');
|
|||
|
||||
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
|
||||
|
|
|
@ -10,7 +10,6 @@ const HorizontalMenuView = require('./horizontal_menu_view.js').HorizontalMenuV
|
|||
const SpinnerMenuView = require('./spinner_menu_view.js').SpinnerMenuView;
|
||||
const ToggleMenuView = require('./toggle_menu_view.js').ToggleMenuView;
|
||||
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 MultiLineEditTextView = require('./multi_line_edit_text_view.js').MultiLineEditTextView;
|
||||
const getPredefinedMCIValue = require('./predefined_mci.js').getPredefinedMCIValue;
|
||||
|
@ -37,7 +36,7 @@ MCIViewFactory.UserViewCodes = [
|
|||
'XY',
|
||||
];
|
||||
|
||||
MCIViewFactory.prototype.createFromMCI = function(mci, cb) {
|
||||
MCIViewFactory.prototype.createFromMCI = function(mci) {
|
||||
assert(mci.code);
|
||||
assert(mci.id > 0);
|
||||
assert(mci.position);
|
||||
|
|
|
@ -548,7 +548,7 @@ Message.prototype.getQuoteLines = function(options, cb) {
|
|||
quoteLines.push(`${lastSgr}${l}`);
|
||||
|
||||
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;
|
||||
|
@ -557,7 +557,7 @@ Message.prototype.getQuoteLines = function(options, cb) {
|
|||
}
|
||||
);
|
||||
} 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 input = _.trimEnd(this.message).replace(/\b/g, '');
|
||||
|
||||
|
|
|
@ -159,18 +159,6 @@ function getMessageConferenceByTag(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) {
|
||||
const confs = Config.messageConferences;
|
||||
return Object.keys(confs).find( (confTag) => {
|
||||
|
|
|
@ -36,7 +36,7 @@ function resolvePath(path) {
|
|||
|
||||
function getCleanEnigmaVersion() {
|
||||
return packageJson.version
|
||||
.replace(/\-/g, '.')
|
||||
.replace(/-/g, '.')
|
||||
.replace(/alpha/,'a')
|
||||
.replace(/beta/,'b')
|
||||
;
|
||||
|
|
|
@ -98,9 +98,9 @@ exports.getModule = class MessageAreaListModule extends MenuModule {
|
|||
}, timeout);
|
||||
}
|
||||
|
||||
updateGeneralAreaInfoViews(areaIndex) {
|
||||
// :TODO: these concepts have been replaced with the {someKey} style formatting - update me!
|
||||
/* experimental: not yet avail
|
||||
/*
|
||||
updateGeneralAreaInfoViews(areaIndex) {
|
||||
const areaInfo = self.messageAreas[areaIndex];
|
||||
|
||||
[ MciViewIds.SelAreaInfo1, MciViewIds.SelAreaInfo2 ].forEach(mciId => {
|
||||
|
@ -109,8 +109,8 @@ exports.getModule = class MessageAreaListModule extends MenuModule {
|
|||
v.setFormatObject(areaInfo.area);
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
*/
|
||||
|
||||
mciReady(mciData, cb) {
|
||||
super.mciReady(mciData, err => {
|
||||
|
|
|
@ -13,12 +13,12 @@ function MessageScanTossModule() {
|
|||
require('util').inherits(MessageScanTossModule, PluginModule);
|
||||
|
||||
MessageScanTossModule.prototype.startup = function(cb) {
|
||||
cb(null);
|
||||
return cb(null);
|
||||
};
|
||||
|
||||
MessageScanTossModule.prototype.shutdown = function(cb) {
|
||||
cb(null);
|
||||
return cb(null);
|
||||
};
|
||||
|
||||
MessageScanTossModule.prototype.record = function(message) {
|
||||
MessageScanTossModule.prototype.record = function(/*message*/) {
|
||||
};
|
|
@ -4,7 +4,6 @@
|
|||
const View = require('./view.js').View;
|
||||
const strUtil = require('./string_util.js');
|
||||
const ansi = require('./ansi_term.js');
|
||||
const colorCodes = require('./color_codes.js');
|
||||
const wordWrapText = require('./word_wrap.js').wordWrapText;
|
||||
const ansiPrep = require('./ansi_prep.js');
|
||||
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
|
||||
exports.PluginModule = PluginModule;
|
||||
|
||||
function PluginModule(options) {
|
||||
function PluginModule(/*options*/) {
|
||||
}
|
||||
|
|
|
@ -8,7 +8,9 @@ exports.readSAUCE = readSAUCE;
|
|||
|
||||
const SAUCE_SIZE = 128;
|
||||
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;
|
||||
// :TODO: SAUCE should be a class
|
||||
|
|
|
@ -1213,8 +1213,31 @@ function FTNMessageScanTossModule() {
|
|||
|
||||
User.getUserIdAndNameByLookup(lookupName, (err, localToUserId, localUserName) => {
|
||||
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}`));
|
||||
}
|
||||
}
|
||||
|
||||
// we do this after such that error cases can be preseved above
|
||||
if(lookupName !== message.toUserName) {
|
||||
|
|
|
@ -232,7 +232,7 @@ exports.getModule = class SetNewScanDate extends MenuModule {
|
|||
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
|
||||
const scanDateFormat = self.scanDateFormat.replace(/[\/\-. ]/g, '');
|
||||
const scanDateFormat = self.scanDateFormat.replace(/[/\-. ]/g, '');
|
||||
scanDateView.setText(today.format(scanDateFormat));
|
||||
|
||||
if('message' === self.target) {
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
/* jslint node: true */
|
||||
'use strict';
|
||||
|
||||
var MenuView = require('./menu_view.js').MenuView;
|
||||
var ansi = require('./ansi_term.js');
|
||||
var strUtil = require('./string_util.js');
|
||||
const MenuView = require('./menu_view.js').MenuView;
|
||||
const ansi = require('./ansi_term.js');
|
||||
const strUtil = require('./string_util.js');
|
||||
|
||||
var util = require('util');
|
||||
var assert = require('assert');
|
||||
var _ = require('lodash');
|
||||
const util = require('util');
|
||||
const assert = require('assert');
|
||||
|
||||
exports.SpinnerMenuView = SpinnerMenuView;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
);
|
||||
}
|
|
@ -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 } );
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
|
@ -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.
|
||||
const REGEXP_BASIC_FORMAT = /{([^.!:}]+(?:\.[^.!:}]+)*)(?:\!([^:}]+))?(?:\:([^}]+))?}/g;
|
||||
const REGEXP_BASIC_FORMAT = /{([^.!:}]+(?:\.[^.!:}]+)*)(?:!([^:}]+))?(?::([^}]+))?}/g;
|
||||
|
||||
function getValue(obj, path) {
|
||||
const value = _.get(obj, path);
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
// ENiGMA½
|
||||
const miscUtil = require('./misc_util.js');
|
||||
const ANSIEscapeParser = require('./ansi_escape_parser.js').ANSIEscapeParser;
|
||||
const ANSI = require('./ansi_term.js');
|
||||
|
||||
// deps
|
||||
|
@ -198,11 +197,6 @@ function isPrintable(s) {
|
|||
return !RE_NON_PRINTABLE.test(s);
|
||||
}
|
||||
|
||||
function stringLength(s) {
|
||||
// :TODO: See https://mathiasbynens.be/notes/javascript-unicode
|
||||
return s.length;
|
||||
}
|
||||
|
||||
function stripAllLineFeeds(s) {
|
||||
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
|
||||
//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 = [
|
||||
//'A', 'B', // up, down
|
||||
//'C', 'D', // right, left
|
||||
|
@ -405,194 +399,6 @@ function cleanControlCodes(input, options) {
|
|||
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) {
|
||||
return isAnsi(line);// || renderStringLength(line) < line.length;
|
||||
}
|
||||
|
@ -622,6 +428,7 @@ function isFormattedLine(line) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// :TODO: rename to containsAnsi()
|
||||
function isAnsi(input) {
|
||||
if(!input || 0 === input.length) {
|
||||
return false;
|
||||
|
@ -647,7 +454,7 @@ function isAnsi(input) {
|
|||
*/
|
||||
|
||||
// :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) || [];
|
||||
return m.length >= 4; // :TODO: do this reasonably, e.g. a percent or soemthing
|
||||
}
|
||||
|
|
|
@ -110,7 +110,7 @@ function validateEmailAvail(data, cb) {
|
|||
//
|
||||
// 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)) {
|
||||
return cb(new Error('Invalid email address'));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
|
@ -1,13 +1,11 @@
|
|||
/* jslint node: true */
|
||||
'use strict';
|
||||
|
||||
var MenuView = require('./menu_view.js').MenuView;
|
||||
var ansi = require('./ansi_term.js');
|
||||
var strUtil = require('./string_util.js');
|
||||
const MenuView = require('./menu_view.js').MenuView;
|
||||
const strUtil = require('./string_util.js');
|
||||
|
||||
var util = require('util');
|
||||
var assert = require('assert');
|
||||
var _ = require('lodash');
|
||||
const util = require('util');
|
||||
const assert = require('assert');
|
||||
|
||||
exports.ToggleMenuView = ToggleMenuView;
|
||||
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
/* jslint node: true */
|
||||
'use strict';
|
||||
|
||||
var userDb = require('./database.js').dbs.user;
|
||||
var Config = require('./config.js').config;
|
||||
const userDb = require('./database.js').dbs.user;
|
||||
|
||||
var async = require('async');
|
||||
var _ = require('lodash');
|
||||
const async = require('async');
|
||||
const _ = require('lodash');
|
||||
|
||||
exports.getGroupsForUser = getGroupsForUser;
|
||||
exports.addUserToGroup = addUserToGroup;
|
||||
|
@ -13,23 +12,22 @@ exports.addUserToGroups = addUserToGroups;
|
|||
exports.removeUserFromGroup = removeUserFromGroup;
|
||||
|
||||
function getGroupsForUser(userId, cb) {
|
||||
var sql =
|
||||
'SELECT group_name ' +
|
||||
'FROM user_group_member ' +
|
||||
'WHERE user_id=?;';
|
||||
const sql =
|
||||
`SELECT group_name
|
||||
FROM user_group_member
|
||||
WHERE user_id=?;`;
|
||||
|
||||
var groups = [];
|
||||
const groups = [];
|
||||
|
||||
userDb.each(sql, [ userId ], function rowData(err, row) {
|
||||
userDb.each(sql, [ userId ], (err, row) => {
|
||||
if(err) {
|
||||
cb(err);
|
||||
return;
|
||||
} else {
|
||||
groups.push(row.group_name);
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
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(
|
||||
'REPLACE INTO user_group_member (group_name, user_id) ' +
|
||||
'VALUES(?, ?);',
|
||||
`REPLACE INTO user_group_member (group_name, user_id)
|
||||
VALUES(?, ?);`,
|
||||
[ groupName, userId ],
|
||||
function complete(err) {
|
||||
cb(err);
|
||||
err => {
|
||||
return cb(err);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function addUserToGroups(userId, groups, transOrDb, cb) {
|
||||
|
||||
async.each(groups, function item(groupName, next) {
|
||||
addUserToGroup(userId, groupName, transOrDb, next);
|
||||
}, function complete(err) {
|
||||
cb(err);
|
||||
async.each(groups, (groupName, nextGroupName) => {
|
||||
return addUserToGroup(userId, groupName, transOrDb, nextGroupName);
|
||||
}, err => {
|
||||
return cb(err);
|
||||
});
|
||||
}
|
||||
|
||||
function removeUserFromGroup(userId, groupName, cb) {
|
||||
userDb.run(
|
||||
'DELETE FROM user_group_member ' +
|
||||
'WHERE group_name=? AND user_id=?;',
|
||||
`DELETE FROM user_group_member
|
||||
WHERE group_name=? AND user_id=?;`,
|
||||
[ groupName, userId ],
|
||||
function complete(err) {
|
||||
cb(err);
|
||||
err => {
|
||||
return cb(err);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -166,20 +166,6 @@ function ViewController(options) {
|
|||
var propAsset;
|
||||
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) {
|
||||
propAsset = asset.getViewPropertyAsset(conf[propName]);
|
||||
if(propAsset) {
|
||||
|
@ -211,7 +197,7 @@ function ViewController(options) {
|
|||
}
|
||||
} else {
|
||||
if(_.isString(propAsset.location)) {
|
||||
|
||||
// :TODO: clean this code up!
|
||||
} else {
|
||||
if('systemMethod' === propAsset.type) {
|
||||
// :TODO:
|
||||
|
|
|
@ -13,7 +13,6 @@ const Log = require('./logger.js').log;
|
|||
|
||||
// deps
|
||||
const async = require('async');
|
||||
const _ = require('lodash');
|
||||
const crypto = require('crypto');
|
||||
const fs = require('graceful-fs');
|
||||
const url = require('url');
|
||||
|
@ -128,7 +127,11 @@ class WebPasswordReset {
|
|||
};
|
||||
|
||||
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);
|
||||
});
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
/* jslint node: true */
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var _ = require('lodash');
|
||||
const renderStringLength = require('./string_util.js').renderStringLength;
|
||||
|
||||
exports.wordWrapText = wordWrapText2;
|
||||
// deps
|
||||
const assert = require('assert');
|
||||
const _ = require('lodash');
|
||||
|
||||
exports.wordWrapText = wordWrapText;
|
||||
|
||||
const SPACE_CHARS = [
|
||||
' ', '\f', '\n', '\r', '\v',
|
||||
|
@ -16,7 +18,7 @@ const SPACE_CHARS = [
|
|||
|
||||
const REGEXP_WORD_WRAP = new RegExp(`\t|[${SPACE_CHARS.join('')}]`, 'g');
|
||||
|
||||
function wordWrapText2(text, options) {
|
||||
function wordWrapText(text, options) {
|
||||
assert(_.isObject(options));
|
||||
assert(_.isNumber(options.width));
|
||||
|
||||
|
@ -99,119 +101,3 @@ function wordWrapText2(text, options) {
|
|||
|
||||
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')
|
||||
*/
|
Loading…
Reference in New Issue