mirror of
https://github.com/NuSkooler/enigma-bbs.git
synced 2025-06-08 21:54:36 +02:00
Merge branch 'master' of ssh://numinibsd/git/base/enigma-bbs
This commit is contained in:
commit
e9bdf1f68f
4 changed files with 274 additions and 26 deletions
|
@ -26,6 +26,7 @@ exports.clearScreen = clearScreen;
|
||||||
exports.resetScreen = resetScreen;
|
exports.resetScreen = resetScreen;
|
||||||
exports.normal = normal;
|
exports.normal = normal;
|
||||||
exports.goHome = goHome;
|
exports.goHome = goHome;
|
||||||
|
//exports.deleteLine = deleteLine;
|
||||||
exports.disableVT100LineWrapping = disableVT100LineWrapping;
|
exports.disableVT100LineWrapping = disableVT100LineWrapping;
|
||||||
exports.setSyncTERMFont = setSyncTERMFont;
|
exports.setSyncTERMFont = setSyncTERMFont;
|
||||||
exports.getSyncTERMFontFromAlias = getSyncTERMFontFromAlias;
|
exports.getSyncTERMFontFromAlias = getSyncTERMFontFromAlias;
|
||||||
|
@ -52,10 +53,52 @@ var CONTROL = {
|
||||||
nextLine : 'E',
|
nextLine : 'E',
|
||||||
prevLine : 'F',
|
prevLine : 'F',
|
||||||
horizAbsolute : 'G',
|
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',
|
eraseData : 'J',
|
||||||
|
|
||||||
eraseLine : 'K',
|
eraseLine : 'K',
|
||||||
insertLine : 'L',
|
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',
|
deleteLine : 'M',
|
||||||
|
ansiMusic : 'M',
|
||||||
|
|
||||||
scrollUp : 'S',
|
scrollUp : 'S',
|
||||||
scrollDown : 'T',
|
scrollDown : 'T',
|
||||||
setScrollRegion : 'r',
|
setScrollRegion : 'r',
|
||||||
|
@ -385,6 +428,32 @@ function goHome() {
|
||||||
return exports.goto(); // no params = home = 1,1
|
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
|
// See http://www.termsys.demon.co.uk/vtANSI_BBS.htm
|
||||||
//
|
//
|
||||||
|
@ -410,5 +479,5 @@ function setEmulatedBaudRate(rate) {
|
||||||
115200 : 11,
|
115200 : 11,
|
||||||
}[rate] || 0;
|
}[rate] || 0;
|
||||||
return 0 === speed ? exports.emulationSpeed() : exports.emulationSpeed(1, speed);
|
return 0 === speed ? exports.emulationSpeed() : exports.emulationSpeed(1, speed);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ function Message(options) {
|
||||||
this.viewCount = options.viewCount || 0;
|
this.viewCount = options.viewCount || 0;
|
||||||
|
|
||||||
this.meta = {
|
this.meta = {
|
||||||
system : {}, // we'll always have this one
|
System : {}, // we'll always have this one
|
||||||
};
|
};
|
||||||
|
|
||||||
if(_.isObject(options.meta)) {
|
if(_.isObject(options.meta)) {
|
||||||
|
@ -125,11 +125,11 @@ Message.FtnPropertyNames = {
|
||||||
// Note: kludges are stored with their names as-is
|
// Note: kludges are stored with their names as-is
|
||||||
|
|
||||||
Message.prototype.setLocalToUserId = function(userId) {
|
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) {
|
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) {
|
Message.prototype.load = function(options, cb) {
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
var msgArea = require('./message_area.js');
|
var msgArea = require('./message_area.js');
|
||||||
var Message = require('./message.js');
|
var Message = require('./message.js');
|
||||||
var MenuModule = require('./menu_module.js').MenuModule;
|
var MenuModule = require('./menu_module.js').MenuModule;
|
||||||
|
var ViewController = require('../core/view_controller.js').ViewController;
|
||||||
|
|
||||||
var async = require('async');
|
var async = require('async');
|
||||||
|
|
||||||
|
@ -21,8 +22,8 @@ exports.getModule = NewScanModule;
|
||||||
* * Update message ID when reading (this should be working!)
|
* * Update message ID when reading (this should be working!)
|
||||||
* * New scan all areas
|
* * New scan all areas
|
||||||
* * User configurable new scan: Area selection (avail from messages area)
|
* * 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 self = this;
|
||||||
var config = this.menuConfig.config;
|
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(
|
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) {
|
function newScanAreaAndGetMessages(callback) {
|
||||||
msgArea.getNewMessagesInAreaForUser(
|
msgArea.getNewMessagesInAreaForUser(
|
||||||
self.client.user.userId, areaName, function msgs(err, msgList) {
|
self.client.user.userId, currentArea.name, function msgs(err, msgList) {
|
||||||
callback(err, msgList);
|
callback(err, msgList);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -49,52 +72,78 @@ function NewScanModule(options) {
|
||||||
if(msgList && msgList.length > 0) {
|
if(msgList && msgList.length > 0) {
|
||||||
var nextModuleOpts = {
|
var nextModuleOpts = {
|
||||||
extraArgs: {
|
extraArgs: {
|
||||||
messageAreaName : areaName,
|
messageAreaName : currentArea.name,
|
||||||
messageList : msgList,
|
messageList : msgList,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.gotoMenu(config.newScanMessageList || 'newScanMessageList', nextModuleOpts);
|
self.gotoMenu(config.newScanMessageList || 'newScanMessageList', nextModuleOpts);
|
||||||
} else {
|
} else {
|
||||||
callback(null);
|
self.newScanMessageArea(cb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
function complete(err) {
|
cb
|
||||||
cb(err);
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
require('util').inherits(NewScanModule, MenuModule);
|
require('util').inherits(NewScanModule, MenuModule);
|
||||||
|
|
||||||
NewScanModule.prototype.getSaveState = function() {
|
NewScanModule.prototype.getSaveState = function() {
|
||||||
return {
|
return {
|
||||||
currentStep : this.currentStep,
|
currentStep : this.currentStep,
|
||||||
|
currentScanAux : this.currentScanAux,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
NewScanModule.prototype.restoreSavedState = function(savedState) {
|
NewScanModule.prototype.restoreSavedState = function(savedState) {
|
||||||
this.currentStep = savedState.currentStep;
|
this.currentStep = savedState.currentStep;
|
||||||
|
this.currentScanAux = savedState.currentScanAux;
|
||||||
};
|
};
|
||||||
|
|
||||||
NewScanModule.prototype.mciReady = function(mciData, cb) {
|
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.
|
// :TODO: display scan step/etc.
|
||||||
|
|
||||||
switch(this.currentStep) {
|
async.series(
|
||||||
case 'privateMail' :
|
[
|
||||||
self.currentStep = 'finished';
|
function callParentMciReady(callback) {
|
||||||
self.newScanMessageArea(Message.WellKnownAreaNames.Private, cb);
|
NewScanModule.super_.prototype.mciReady.call(self, mciData, callback);
|
||||||
break;
|
},
|
||||||
|
function loadFromConfig(callback) {
|
||||||
default :
|
var loadOpts = {
|
||||||
cb(null);
|
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);
|
||||||
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
130
oputil.js
Normal file
130
oputil.js
Normal file
|
@ -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…
Add table
Add a link
Reference in a new issue