From 3056d6c742237d596956897158a149ddf604979e Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Sat, 2 Jan 2016 18:34:12 -0700 Subject: [PATCH 1/4] Add some note --- core/ansi_term.js | 71 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/core/ansi_term.js b/core/ansi_term.js index be9f7e43..b4c584e5 100644 --- a/core/ansi_term.js +++ b/core/ansi_term.js @@ -26,6 +26,7 @@ exports.clearScreen = clearScreen; exports.resetScreen = resetScreen; exports.normal = normal; exports.goHome = goHome; +//exports.deleteLine = deleteLine; exports.disableVT100LineWrapping = disableVT100LineWrapping; exports.setSyncTERMFont = setSyncTERMFont; exports.getSyncTERMFontFromAlias = getSyncTERMFontFromAlias; @@ -52,10 +53,52 @@ var CONTROL = { nextLine : 'E', prevLine : 'F', horizAbsolute : 'G', + + // + // CSI [ p1 ] J + // Erase in Page / Erase Data + // Defaults: p1 = 0 + // Erases from the current screen according to the value of p1 + // 0 - Erase from the current position to the end of the screen. + // 1 - Erase from the current position to the start of the screen. + // 2 - Erase entire screen. As a violation of ECMA-048, also moves + // the cursor to position 1/1 as a number of BBS programs assume + // this behaviour. + // Erased characters are set to the current attribute. + // + // Support: + // * SyncTERM: Works as expected + // * NetRunner: Always clears a screen *height* (e.g. 25) regardless of p1 + // and screen remainder + // eraseData : 'J', + eraseLine : 'K', insertLine : 'L', + + // + // CSI [ p1 ] M + // Delete Line(s) / "ANSI" Music + // Defaults: p1 = 1 + // Deletes the current line and the p1 - 1 lines after it scrolling the + // first non-deleted line up to the current line and filling the newly + // empty lines at the end of the screen with the current attribute. + // If "ANSI" Music is fully enabled (CSI = 2 M), performs "ANSI" music + // instead. + // See "ANSI" MUSIC section for more details. + // + // Support: + // * SyncTERM: Works as expected + // * NetRunner: + // + // General Notes: + // See also notes in bansi.txt and cterm.txt about the various + // incompatibilities & oddities around this sequence. ANSI-BBS + // states that it *should* work with any value of p1. + // deleteLine : 'M', + ansiMusic : 'M', + scrollUp : 'S', scrollDown : 'T', setScrollRegion : 'r', @@ -385,6 +428,32 @@ function goHome() { return exports.goto(); // no params = home = 1,1 } +// +// Delete line(s) +// This method acts like ESC[ p1 M but should work +// for all terminals via using eraseLine and movement +// +/* +function deleteLine(count) { + count = count || 1; + + console.log(exports.eraseLine) + var seq = exports.eraseLine(2); // 2 = entire line + var i; + for(i = 1; i < count; ++i) { + seq += + '\n' + // down a line + exports.eraseLine(2); // erase it + } + + // now, move back up any we lines we went down + if(count > 1) { + seq += exports.up(count - 1); + } + return seq; +} +*/ + // // See http://www.termsys.demon.co.uk/vtANSI_BBS.htm // @@ -410,5 +479,5 @@ function setEmulatedBaudRate(rate) { 115200 : 11, }[rate] || 0; return 0 === speed ? exports.emulationSpeed() : exports.emulationSpeed(1, speed); -}; +} From 484ccdc0141e93efcc8c5aaaec58109bc0932d09 Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Sat, 2 Jan 2016 18:34:50 -0700 Subject: [PATCH 2/4] Fix to/from user ID meta --- core/message.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/message.js b/core/message.js index 11dcbf83..4b99fcfc 100644 --- a/core/message.js +++ b/core/message.js @@ -33,7 +33,7 @@ function Message(options) { this.viewCount = options.viewCount || 0; this.meta = { - system : {}, // we'll always have this one + System : {}, // we'll always have this one }; if(_.isObject(options.meta)) { @@ -125,11 +125,11 @@ Message.FtnPropertyNames = { // Note: kludges are stored with their names as-is Message.prototype.setLocalToUserId = function(userId) { - this.meta.system.local_to_user_id = userId; + this.meta.System.local_to_user_id = userId; }; Message.prototype.setLocalFromUserId = function(userId) { - this.meta.system.local_from_user_id = userId; + this.meta.System.local_from_user_id = userId; }; Message.prototype.load = function(options, cb) { From a4cd689697c764b61c808d306c3f1c66f0c03ab8 Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Sat, 2 Jan 2016 18:35:13 -0700 Subject: [PATCH 3/4] Updated new scan WIP --- core/new_scan.js | 93 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 71 insertions(+), 22 deletions(-) diff --git a/core/new_scan.js b/core/new_scan.js index 222abce9..cc855b34 100644 --- a/core/new_scan.js +++ b/core/new_scan.js @@ -5,6 +5,7 @@ var msgArea = require('./message_area.js'); var Message = require('./message.js'); var MenuModule = require('./menu_module.js').MenuModule; +var ViewController = require('../core/view_controller.js').ViewController; var async = require('async'); @@ -21,8 +22,8 @@ exports.getModule = NewScanModule; * * Update message ID when reading (this should be working!) * * New scan all areas * * User configurable new scan: Area selection (avail from messages area) - * - * + * * Add status TL/VM (either/both should update if present) + * * */ @@ -33,14 +34,36 @@ function NewScanModule(options) { var self = this; var config = this.menuConfig.config; - this.currentStep = 'privateMail'; + this.currentStep = 'messageAreas'; + this.currentScanAux = 0; // Message.WellKnownAreaNames.Private - this.newScanMessageArea = function(areaName, cb) { + + this.newScanMessageArea = function(cb) { + var availMsgAreas = msgArea.getAvailableMessageAreas( { includePrivate : true } ); + var currentArea = availMsgAreas[self.currentScanAux]; + + // + // Scan and update index until we find something. If results are found, + // we'll goto the list module & show them. + // async.waterfall( [ + function checkAndUpdateIndex(callback) { + // Advance to next area if possible + if(availMsgAreas.length >= self.currentScanAux + 1) { + self.currentScanAux += 1; + callback(null); + } else { + callback(new Error('No more areas')); + } + }, + function updateStatus(callback) { + // :TODO: Update status text + callback(null); + }, function newScanAreaAndGetMessages(callback) { msgArea.getNewMessagesInAreaForUser( - self.client.user.userId, areaName, function msgs(err, msgList) { + self.client.user.userId, currentArea.name, function msgs(err, msgList) { callback(err, msgList); } ); @@ -49,52 +72,78 @@ function NewScanModule(options) { if(msgList && msgList.length > 0) { var nextModuleOpts = { extraArgs: { - messageAreaName : areaName, + messageAreaName : currentArea.name, messageList : msgList, } }; self.gotoMenu(config.newScanMessageList || 'newScanMessageList', nextModuleOpts); } else { - callback(null); + self.newScanMessageArea(cb); } } ], - function complete(err) { - cb(err); - } + cb ); }; + } require('util').inherits(NewScanModule, MenuModule); NewScanModule.prototype.getSaveState = function() { return { - currentStep : this.currentStep, + currentStep : this.currentStep, + currentScanAux : this.currentScanAux, }; }; NewScanModule.prototype.restoreSavedState = function(savedState) { - this.currentStep = savedState.currentStep; + this.currentStep = savedState.currentStep; + this.currentScanAux = savedState.currentScanAux; }; NewScanModule.prototype.mciReady = function(mciData, cb) { - var self = this; + var self = this; + var vc = self.viewControllers.allViews = new ViewController( { client : self.client } ); // :TODO: display scan step/etc. - switch(this.currentStep) { - case 'privateMail' : - self.currentStep = 'finished'; - self.newScanMessageArea(Message.WellKnownAreaNames.Private, cb); - break; - - default : - cb(null); - } + async.series( + [ + function callParentMciReady(callback) { + NewScanModule.super_.prototype.mciReady.call(self, mciData, callback); + }, + function loadFromConfig(callback) { + var loadOpts = { + callingMenu : self, + mciMap : mciData.menu, + noInput : true, + }; + vc.loadFromMenuConfig(loadOpts, callback); + }, + function performCurrentStepScan(callback) { + switch(self.currentStep) { + case 'messageAreas' : + self.newScanMessageArea(function scanComplete(err) { + callback(null); // finished + }); + break; + + default : + callback(null); + } + } + ], + function complete(err) { + if(err) { + self.client.log.error( { error : err.toString() }, 'Error during new scan'); + } + cb(err); + } + ); }; /* From 443d4c16d424545856a58886f5ab020ec9598071 Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Sun, 3 Jan 2016 15:50:56 -0700 Subject: [PATCH 4/4] Start of oputil.js --- oputil.js | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 oputil.js diff --git a/oputil.js b/oputil.js new file mode 100644 index 00000000..1faaf88d --- /dev/null +++ b/oputil.js @@ -0,0 +1,130 @@ +/* jslint node: true */ +'use strict'; + +// ENiGMA½ +var config = require('./core/config.js'); +var db = require('./core/database.js'); + +var _ = require('lodash'); +var async = require('async'); + +var argv = require('minimist')(process.argv.slice(2)); + +var ExitCodes = { + SUCCESS : 0, + ERROR : -1, + BAD_COMMAND : -2, + BAD_ARGS : -3, +} + +function printUsage(command) { + var usage; + + switch(command) { + case '' : + usage = + 'usage: oputil.js [--version] [--help]\n' + + ' []' + + '\n' + + 'global args:\n' + + ' --config PATH : specify config path'; + break; + + case 'user' : + usage = + 'usage: optutil.js user --user USERNAME \n' + + '\n' + + 'valid args:\n' + + ' --user USERNAME : specify username\n' + + ' --password PASS : reset password to PASS'; + break; + } + + console.error(usage); +} + +function initConfig(cb) { + var configPath = argv.config ? argv.config : config.getDefaultPath(); + + config.init(configPath, cb); +} + +function handleUserCommand() { + if(true === argv.help || !_.isString(argv.user) || 0 === argv.user.length) { + process.exitCode = ExitCodes.ERROR; + return printUsage('user'); + } + + if(_.isString(argv.password)) { + if(0 === argv.password.length) { + process.exitCode = ExitCodes.BAD_ARGS; + return console.error('Invalid password'); + } + + var user; + async.waterfall( + [ + function init(callback) { + initConfig(callback); + }, + function initDb(callback) { + db.initializeDatabases(callback); + }, + function getUser(callback) { + user = require('./core/user.js'); + user.getUserIdAndName(argv.user, function userNameAndId(err, username, userId) { + if(err) { + process.exitCode = ExitCodes.BAD_ARGS; + callback(new Error('Failed to retrieve user')); + } else { + callback(null, userId); + } + }); + }, + function setNewPass(userId, callback) { + var u = new user.User(); + u.userId = userId; + u.setNewAuthCredentials(argv.password, function credsSet(err) { + if(err) { + process.exitCode = ExitCodes.ERROR; + callback(new Error('Failed setting password')); + } else { + callback(null); + } + }); + } + ], + function complete(err) { + if(err) { + console.error(err.message); + } else { + console.info('Password set'); + } + } + ); + } +} + +function main() { + + process.exitCode = ExitCodes.SUCCESS; + + if(0 === argv._.length || + 'help' === argv._[0]) + { + printUsage(''); + process.exit(ExitCodes.SUCCESS); + } + + switch(argv._[0]) { + case 'user' : + handleUserCommand(); + break; + + default: + printUsage(''); + process.exitCode = ExitCodes.BAD_COMMAND; + } +} + +main(); \ No newline at end of file