Merge branch 'master' of ssh://numinibsd/git/base/enigma-bbs
This commit is contained in:
commit
e9bdf1f68f
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,22 +72,21 @@ 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);
|
||||
|
@ -72,29 +94,56 @@ require('util').inherits(NewScanModule, MenuModule);
|
|||
NewScanModule.prototype.getSaveState = function() {
|
||||
return {
|
||||
currentStep : this.currentStep,
|
||||
currentScanAux : this.currentScanAux,
|
||||
};
|
||||
};
|
||||
|
||||
NewScanModule.prototype.restoreSavedState = function(savedState) {
|
||||
this.currentStep = savedState.currentStep;
|
||||
this.currentScanAux = savedState.currentScanAux;
|
||||
};
|
||||
|
||||
NewScanModule.prototype.mciReady = function(mciData, cb) {
|
||||
|
||||
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);
|
||||
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 :
|
||||
cb(null);
|
||||
callback(null);
|
||||
}
|
||||
|
||||
}
|
||||
],
|
||||
function complete(err) {
|
||||
if(err) {
|
||||
self.client.log.error( { error : err.toString() }, 'Error during new scan');
|
||||
}
|
||||
cb(err);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -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' +
|
||||
' <command> [<args>]' +
|
||||
'\n' +
|
||||
'global args:\n' +
|
||||
' --config PATH : specify config path';
|
||||
break;
|
||||
|
||||
case 'user' :
|
||||
usage =
|
||||
'usage: optutil.js user --user USERNAME <args>\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();
|
Loading…
Reference in New Issue