New MCI codes & user status flags support additions
* New MCI and WFC properties for user new private and "addressed to" mail * Additional support for user status flags in connection lists, etc.
This commit is contained in:
parent
6502f3b55e
commit
868e14aa8e
|
@ -248,10 +248,11 @@
|
||||||
|
|
||||||
mainMenuWaitingForCaller: {
|
mainMenuWaitingForCaller: {
|
||||||
config: {
|
config: {
|
||||||
|
quickLogTimestampFormat: "|01|02MM|08/|02DD hh:mm:ssa"
|
||||||
nowDateTimeFormat: "|00|11dddd|08, |11MMMM Do YYYY |08/ |11h|08:|11mm|08:|11ss|03a"
|
nowDateTimeFormat: "|00|11dddd|08, |11MMMM Do YYYY |08/ |11h|08:|11mm|08:|11ss|03a"
|
||||||
lastLoginDateTimeFormat: "|00|10ddd hh|08:|10mm|02a"
|
lastLoginDateTimeFormat: "|00|10ddd hh|08:|10mm|02a"
|
||||||
|
|
||||||
mainInfoFormat10: "|00|11{now} {currentUserName} |08- |03mail|08: "
|
mainInfoFormat10: "|00|11{now} {currentUserName} |08- |03mail|08: |11{newPrivateMail}|03 prv|08, |11{newMessagesAddrTo}|03 addr to"
|
||||||
mainInfoFormat11: "|00|10{callsToday:>5}"
|
mainInfoFormat11: "|00|10{callsToday:>5}"
|
||||||
mainInfoFormat12: "|00|10{postsToday:>5}"
|
mainInfoFormat12: "|00|10{postsToday:>5}"
|
||||||
mainInfoFormat13: "|00|10{uploadsToday:>2} |08/ |10{uploadBytesToday!sizeWithoutAbbr} |02{uploadBytesToday!sizeAbbr}"
|
mainInfoFormat13: "|00|10{uploadsToday:>2} |08/ |10{uploadBytesToday!sizeWithoutAbbr} |02{uploadBytesToday!sizeAbbr}"
|
||||||
|
|
|
@ -163,6 +163,7 @@ exports.getModule = class AbracadabraModule extends MenuModule {
|
||||||
this.client.term.write(ansi.resetScreen());
|
this.client.term.write(ansi.resetScreen());
|
||||||
|
|
||||||
const exeInfo = {
|
const exeInfo = {
|
||||||
|
name : this.config.name,
|
||||||
cmd : this.config.cmd,
|
cmd : this.config.cmd,
|
||||||
cwd : this.config.cwd || paths.dirname(this.config.cmd),
|
cwd : this.config.cwd || paths.dirname(this.config.cmd),
|
||||||
args : this.config.args,
|
args : this.config.args,
|
||||||
|
|
|
@ -141,7 +141,7 @@ function shutdownSystem() {
|
||||||
[
|
[
|
||||||
function closeConnections(callback) {
|
function closeConnections(callback) {
|
||||||
const ClientConns = require('./client_connections.js');
|
const ClientConns = require('./client_connections.js');
|
||||||
const activeConnections = ClientConns.getActiveConnections();
|
const activeConnections = ClientConns.getActiveConnections(ClientConns.AllConnections);
|
||||||
let i = activeConnections.length;
|
let i = activeConnections.length;
|
||||||
while(i--) {
|
while(i--) {
|
||||||
const activeTerm = activeConnections[i].term;
|
const activeTerm = activeConnections[i].term;
|
||||||
|
|
|
@ -21,7 +21,16 @@ exports.getConnectionByNodeId = getConnectionByNodeId;
|
||||||
const clientConnections = [];
|
const clientConnections = [];
|
||||||
exports.clientConnections = clientConnections;
|
exports.clientConnections = clientConnections;
|
||||||
|
|
||||||
function getActiveConnections(options = { authUsersOnly: true, visibleOnly: true }) {
|
const AllConnections = { authUsersOnly: false, visibleOnly: false, availOnly: false };
|
||||||
|
exports.AllConnections = AllConnections;
|
||||||
|
|
||||||
|
const UserVisibleConnections = { authUsersOnly: false, visibleOnly: true, availOnly: false };
|
||||||
|
exports.UserVisibleConnections = UserVisibleConnections;
|
||||||
|
|
||||||
|
const UserMessageableConnections = { authUsersOnly: true, visibleOnly: true, availOnly: true };
|
||||||
|
exports.UserMessageableConnections = UserMessageableConnections;
|
||||||
|
|
||||||
|
function getActiveConnections(options = { authUsersOnly: true, visibleOnly: true, availOnly: false }) {
|
||||||
return clientConnections.filter(conn => {
|
return clientConnections.filter(conn => {
|
||||||
if (options.authUsersOnly && !conn.user.isAuthenticated()) {
|
if (options.authUsersOnly && !conn.user.isAuthenticated()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -29,13 +38,15 @@ function getActiveConnections(options = { authUsersOnly: true, visibleOnly: true
|
||||||
if (options.visibleOnly && !conn.user.isVisible()) {
|
if (options.visibleOnly && !conn.user.isVisible()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (options.availOnly && !conn.user.isAvailable()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
//return ((options.authUsersOnly && conn.user.isAuthenticated()) || !options.authUsersOnly);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getActiveConnectionList(options = { authUsersOnly: true, visibleOnly: true }) {
|
function getActiveConnectionList(options = { authUsersOnly: true, visibleOnly: true, availOnly: false }) {
|
||||||
const now = moment();
|
const now = moment();
|
||||||
|
|
||||||
return _.map(getActiveConnections(options), ac => {
|
return _.map(getActiveConnections(options), ac => {
|
||||||
|
@ -149,9 +160,9 @@ function removeClient(client) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getConnectionByUserId(userId) {
|
function getConnectionByUserId(userId) {
|
||||||
return getActiveConnections().find( ac => userId === ac.user.userId );
|
return getActiveConnections(AllConnections).find( ac => userId === ac.user.userId );
|
||||||
}
|
}
|
||||||
|
|
||||||
function getConnectionByNodeId(nodeId) {
|
function getConnectionByNodeId(nodeId) {
|
||||||
return getActiveConnections().find( ac => nodeId == ac.node );
|
return getActiveConnections(AllConnections).find( ac => nodeId == ac.node );
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ module.exports = class Door {
|
||||||
|
|
||||||
this.client.log.info(
|
this.client.log.info(
|
||||||
{ cmd : exeInfo.cmd, args, io : this.io },
|
{ cmd : exeInfo.cmd, args, io : this.io },
|
||||||
'Executing external door process'
|
`Executing external door (${exeInfo.name})`
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -598,7 +598,7 @@ exports.MenuModule = class MenuModule extends PluginModule {
|
||||||
|
|
||||||
if(options.appendMultiLine && (textView instanceof MultiLineEditTextView)) {
|
if(options.appendMultiLine && (textView instanceof MultiLineEditTextView)) {
|
||||||
textView.addText(text);
|
textView.addText(text);
|
||||||
} else {
|
} else if (textView.getData() != text) {
|
||||||
textView.setText(text);
|
textView.setText(text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ exports.filterMessageListByReadACS = filterMessageListByReadACS;
|
||||||
exports.tempChangeMessageConfAndArea = tempChangeMessageConfAndArea;
|
exports.tempChangeMessageConfAndArea = tempChangeMessageConfAndArea;
|
||||||
exports.getMessageListForArea = getMessageListForArea;
|
exports.getMessageListForArea = getMessageListForArea;
|
||||||
exports.getNewMessageCountInAreaForUser = getNewMessageCountInAreaForUser;
|
exports.getNewMessageCountInAreaForUser = getNewMessageCountInAreaForUser;
|
||||||
|
exports.getNewMessageCountAddressedToUser = getNewMessageCountAddressedToUser;
|
||||||
exports.getNewMessagesInAreaForUser = getNewMessagesInAreaForUser;
|
exports.getNewMessagesInAreaForUser = getNewMessagesInAreaForUser;
|
||||||
exports.getMessageIdNewerThanTimestampByArea = getMessageIdNewerThanTimestampByArea;
|
exports.getMessageIdNewerThanTimestampByArea = getMessageIdNewerThanTimestampByArea;
|
||||||
exports.getMessageAreaLastReadId = getMessageAreaLastReadId;
|
exports.getMessageAreaLastReadId = getMessageAreaLastReadId;
|
||||||
|
@ -489,6 +490,26 @@ function getNewMessageCountInAreaForUser(userId, areaTag, cb) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// New message count -- for all areas available to the user
|
||||||
|
// that are addressed to that user (ie: matching username)
|
||||||
|
// Does NOT Include private messages.
|
||||||
|
function getNewMessageCountAddressedToUser(client, cb) {
|
||||||
|
const areaTags = getAllAvailableMessageAreaTags(client).filter(areaTag => areaTag !== Message.WellKnownAreaTags.Private);
|
||||||
|
|
||||||
|
let newMessageCount = 0;
|
||||||
|
async.forEach(areaTags, (areaTag, nextAreaTag) => {
|
||||||
|
getMessageAreaLastReadId(client.user.userId, areaTag, (_, lastMessageId) => {
|
||||||
|
lastMessageId = lastMessageId || 0;
|
||||||
|
getNewMessageCountInAreaForUser(client.user.userId, areaTag, (err, count) => {
|
||||||
|
newMessageCount += count;
|
||||||
|
return nextAreaTag(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, () => {
|
||||||
|
return cb(null, newMessageCount);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function getNewMessagesInAreaForUser(userId, areaTag, cb) {
|
function getNewMessagesInAreaForUser(userId, areaTag, cb) {
|
||||||
getMessageAreaLastReadId(userId, areaTag, (err, lastMessageId) => {
|
getMessageAreaLastReadId(userId, areaTag, (err, lastMessageId) => {
|
||||||
lastMessageId = lastMessageId || 0;
|
lastMessageId = lastMessageId || 0;
|
||||||
|
@ -509,6 +530,7 @@ function getNewMessagesInAreaForUser(userId, areaTag, cb) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function getMessageListForArea(client, areaTag, filter, cb)
|
function getMessageListForArea(client, areaTag, filter, cb)
|
||||||
{
|
{
|
||||||
if(!cb && _.isFunction(filter)) {
|
if(!cb && _.isFunction(filter)) {
|
||||||
|
|
|
@ -6,6 +6,7 @@ const { MenuModule } = require('./menu_module.js');
|
||||||
const {
|
const {
|
||||||
getActiveConnectionList,
|
getActiveConnectionList,
|
||||||
getConnectionByNodeId,
|
getConnectionByNodeId,
|
||||||
|
UserMessageableConnections,
|
||||||
} = require('./client_connections.js');
|
} = require('./client_connections.js');
|
||||||
const UserInterruptQueue = require('./user_interrupt_queue.js');
|
const UserInterruptQueue = require('./user_interrupt_queue.js');
|
||||||
const { getThemeArt } = require('./theme.js');
|
const { getThemeArt } = require('./theme.js');
|
||||||
|
@ -204,7 +205,7 @@ exports.getModule = class NodeMessageModule extends MenuModule {
|
||||||
location : 'N/A',
|
location : 'N/A',
|
||||||
affils : 'N/A',
|
affils : 'N/A',
|
||||||
timeOn : 'N/A',
|
timeOn : 'N/A',
|
||||||
}].concat(getActiveConnectionList()
|
}].concat(getActiveConnectionList(UserMessageableConnections)
|
||||||
.map(node => Object.assign(node, { text : -1 == node.node ? '-ALL-' : node.node.toString() } ))
|
.map(node => Object.assign(node, { text : -1 == node.node ? '-ALL-' : node.node.toString() } ))
|
||||||
).filter(node => node.node !== this.client.node); // remove our client's node
|
).filter(node => node.node !== this.client.node); // remove our client's node
|
||||||
this.nodeList.sort( (a, b) => a.node - b.node ); // sort by node
|
this.nodeList.sort( (a, b) => a.node - b.node ); // sort by node
|
||||||
|
|
|
@ -186,6 +186,12 @@ const PREDEFINED_MCI_GENERATORS = {
|
||||||
const minutes = client.user.properties[UserProps.MinutesOnlineTotalCount] || 0;
|
const minutes = client.user.properties[UserProps.MinutesOnlineTotalCount] || 0;
|
||||||
return moment.duration(minutes, 'minutes').humanize();
|
return moment.duration(minutes, 'minutes').humanize();
|
||||||
},
|
},
|
||||||
|
NM : function userNewMessagesAddressedToCount(client) {
|
||||||
|
return StatLog.getUserStatNumByClient(client, UserProps.NewAddressedToMessageCount);
|
||||||
|
},
|
||||||
|
NP : function userNewPrivateMailCount(client) {
|
||||||
|
return StatLog.getUserStatNumByClient(client, UserProps.NewPrivateMailCount);
|
||||||
|
},
|
||||||
|
|
||||||
//
|
//
|
||||||
// Date/Time
|
// Date/Time
|
||||||
|
@ -243,7 +249,7 @@ const PREDEFINED_MCI_GENERATORS = {
|
||||||
return moment.duration(process.uptime(), 'seconds').humanize();
|
return moment.duration(process.uptime(), 'seconds').humanize();
|
||||||
},
|
},
|
||||||
NV : function nodeVersion() { return process.version; },
|
NV : function nodeVersion() { return process.version; },
|
||||||
AN : function activeNodes() { return clientConnections.getActiveConnections().length.toString(); },
|
AN : function activeNodes() { return clientConnections.getActiveConnections(clientConnections.UserVisibleConnections).length.toString(); },
|
||||||
|
|
||||||
TC : function totalCalls() { return StatLog.getSystemStat(SysProps.LoginCount).toLocaleString(); },
|
TC : function totalCalls() { return StatLog.getSystemStat(SysProps.LoginCount).toLocaleString(); },
|
||||||
TT : function totalCallsToday() {
|
TT : function totalCallsToday() {
|
||||||
|
|
|
@ -7,6 +7,8 @@ const {
|
||||||
} = require('./database.js');
|
} = require('./database.js');
|
||||||
const Errors = require('./enig_error.js');
|
const Errors = require('./enig_error.js');
|
||||||
const SysProps = require('./system_property.js');
|
const SysProps = require('./system_property.js');
|
||||||
|
const UserProps = require('./user_property');
|
||||||
|
const Message = require('./message');
|
||||||
|
|
||||||
// deps
|
// deps
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
|
@ -152,13 +154,25 @@ class StatLog {
|
||||||
}
|
}
|
||||||
|
|
||||||
getUserStat(user, statName) {
|
getUserStat(user, statName) {
|
||||||
return user.properties[statName];
|
return user.getProperty(statName);
|
||||||
|
}
|
||||||
|
|
||||||
|
getUserStatByClient(client, statName) {
|
||||||
|
const stat = this.getUserStat(client.user, statName);
|
||||||
|
this._refreshUserStat(client, statName);
|
||||||
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
getUserStatNum(user, statName) {
|
getUserStatNum(user, statName) {
|
||||||
return parseInt(this.getUserStat(user, statName)) || 0;
|
return parseInt(this.getUserStat(user, statName)) || 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getUserStatNumByClient(client, statName, ttlSeconds=10) {
|
||||||
|
const stat = this.getUserStatNum(client.user, statName);
|
||||||
|
this._refreshUserStat(client, statName, ttlSeconds);
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
incrementUserStat(user, statName, incrementBy, cb) {
|
incrementUserStat(user, statName, incrementBy, cb) {
|
||||||
incrementBy = incrementBy || 1;
|
incrementBy = incrementBy || 1;
|
||||||
|
|
||||||
|
@ -391,6 +405,49 @@ class StatLog {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_refreshUserStat(client, statName, ttlSeconds) {
|
||||||
|
switch(statName) {
|
||||||
|
case UserProps.NewPrivateMailCount:
|
||||||
|
this._wrapUserRefreshWithCachedTTL(client, statName, this._refreshUserPrivateMailCount, ttlSeconds);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UserProps.NewAddressedToMessageCount:
|
||||||
|
this._wrapUserRefreshWithCachedTTL(client, statName, this._refreshUserNewAddressedToMessageCount, ttlSeconds);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_wrapUserRefreshWithCachedTTL(client, statName, updateMethod, ttlSeconds) {
|
||||||
|
client.statLogRefreshCache = client.statLogRefreshCache || new Map();
|
||||||
|
|
||||||
|
const now = Math.floor(Date.now() / 1000);
|
||||||
|
const old = client.statLogRefreshCache.get(statName) || 0;
|
||||||
|
if (now < old + ttlSeconds) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateMethod(client);
|
||||||
|
client.statLogRefreshCache.set(statName, now);
|
||||||
|
}
|
||||||
|
|
||||||
|
_refreshUserPrivateMailCount(client) {
|
||||||
|
const MsgArea = require('./message_area');
|
||||||
|
MsgArea.getNewMessageCountInAreaForUser(client.user.userId, Message.WellKnownAreaTags.Private, (err, count) => {
|
||||||
|
if (!err) {
|
||||||
|
client.user.setProperty(UserProps.NewPrivateMailCount, count);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_refreshUserNewAddressedToMessageCount(client) {
|
||||||
|
const MsgArea = require('./message_area');
|
||||||
|
MsgArea.getNewMessageCountAddressedToUser(client, (err, count) => {
|
||||||
|
if(!err) {
|
||||||
|
client.user.setProperty(UserProps.NewAddressedToMessageCount, count);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
_findLogEntries(logTable, filter, cb) {
|
_findLogEntries(logTable, filter, cb) {
|
||||||
filter = filter || {};
|
filter = filter || {};
|
||||||
if(!_.isString(filter.logName)) {
|
if(!_.isString(filter.logName)) {
|
||||||
|
|
|
@ -29,6 +29,11 @@ module.exports = class UserInterruptQueue
|
||||||
omitNodes = [ opts.omit ];
|
omitNodes = [ opts.omit ];
|
||||||
}
|
}
|
||||||
omitNodes = omitNodes.map(n => _.isNumber(n) ? n : n.node);
|
omitNodes = omitNodes.map(n => _.isNumber(n) ? n : n.node);
|
||||||
|
const connOpts = {
|
||||||
|
authUsersOnly: true,
|
||||||
|
visibleOnly: true,
|
||||||
|
availOnly: true,
|
||||||
|
};
|
||||||
opts.clients = getActiveConnections(true).filter(ac => !omitNodes.includes(ac.node));
|
opts.clients = getActiveConnections(true).filter(ac => !omitNodes.includes(ac.node));
|
||||||
}
|
}
|
||||||
if(!Array.isArray(opts.clients)) {
|
if(!Array.isArray(opts.clients)) {
|
||||||
|
|
|
@ -65,5 +65,7 @@ module.exports = {
|
||||||
AuthFactor2OTPSecret : 'auth_factor2_otp_secret', // Secret used in conjunction with OTP 2FA
|
AuthFactor2OTPSecret : 'auth_factor2_otp_secret', // Secret used in conjunction with OTP 2FA
|
||||||
AuthFactor2OTPBackupCodes : 'auth_factor2_otp_backup', // JSON array of backup codes
|
AuthFactor2OTPBackupCodes : 'auth_factor2_otp_backup', // JSON array of backup codes
|
||||||
|
|
||||||
|
NewPrivateMailCount : 'new_private_mail_count', // non-persistent
|
||||||
|
NewAddressedToMessageCount : 'new_addr_to_msg_count', // non-persistent
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
11
core/wfc.js
11
core/wfc.js
|
@ -1,7 +1,10 @@
|
||||||
// ENiGMA½
|
// ENiGMA½
|
||||||
const { MenuModule } = require('./menu_module');
|
const { MenuModule } = require('./menu_module');
|
||||||
|
|
||||||
const { getActiveConnectionList } = require('./client_connections');
|
const {
|
||||||
|
getActiveConnectionList,
|
||||||
|
AllConnections
|
||||||
|
} = require('./client_connections');
|
||||||
const StatLog = require('./stat_log');
|
const StatLog = require('./stat_log');
|
||||||
const SysProps = require('./system_property');
|
const SysProps = require('./system_property');
|
||||||
const UserProps = require('./user_property');
|
const UserProps = require('./user_property');
|
||||||
|
@ -36,6 +39,7 @@ const MciViewIds = {
|
||||||
// Secure + 2FA + root user + 'wfc' group.
|
// Secure + 2FA + root user + 'wfc' group.
|
||||||
const DefaultACS = 'SCAF2ID1GM[wfc]';
|
const DefaultACS = 'SCAF2ID1GM[wfc]';
|
||||||
const MainStatRefreshTimeMs = 5000; // 5s
|
const MainStatRefreshTimeMs = 5000; // 5s
|
||||||
|
const MailCountTTLSeconds = 10;
|
||||||
|
|
||||||
exports.getModule = class WaitingForCallerModule extends MenuModule {
|
exports.getModule = class WaitingForCallerModule extends MenuModule {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
|
@ -217,11 +221,12 @@ exports.getModule = class WaitingForCallerModule extends MenuModule {
|
||||||
lastLoginDate : moment(lastLoginStats.timestamp).format(this.getDateFormat()),
|
lastLoginDate : moment(lastLoginStats.timestamp).format(this.getDateFormat()),
|
||||||
lastLoginTime : moment(lastLoginStats.timestamp).format(this.getTimeFormat()),
|
lastLoginTime : moment(lastLoginStats.timestamp).format(this.getTimeFormat()),
|
||||||
lastLogin : moment(lastLoginStats.timestamp).format(this._dateTimeFormat('lastLogin')),
|
lastLogin : moment(lastLoginStats.timestamp).format(this._dateTimeFormat('lastLogin')),
|
||||||
|
|
||||||
totalMemoryBytes : sysMemStats.totalBytes || 0,
|
totalMemoryBytes : sysMemStats.totalBytes || 0,
|
||||||
freeMemoryBytes : sysMemStats.freeBytes || 0,
|
freeMemoryBytes : sysMemStats.freeBytes || 0,
|
||||||
systemAvgLoad : sysLoadStats.average || 0,
|
systemAvgLoad : sysLoadStats.average || 0,
|
||||||
systemCurrentLoad : sysLoadStats.current || 0,
|
systemCurrentLoad : sysLoadStats.current || 0,
|
||||||
|
newPrivateMail : StatLog.getUserStatNumByClient(this.client, UserProps.NewPrivateMailCount, MailCountTTLSeconds),
|
||||||
|
newMessagesAddrTo : StatLog.getUserStatNumByClient(this.client, UserProps.NewAddressedToMessageCount, MailCountTTLSeconds),
|
||||||
};
|
};
|
||||||
|
|
||||||
return cb(null);
|
return cb(null);
|
||||||
|
@ -233,7 +238,7 @@ exports.getModule = class WaitingForCallerModule extends MenuModule {
|
||||||
return cb(null);
|
return cb(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
const nodeStatusItems = getActiveConnectionList({authUsersOnly: false, visibleOnly: false})
|
const nodeStatusItems = getActiveConnectionList(AllConnections)
|
||||||
.slice(0, nodeStatusView.dimens.height)
|
.slice(0, nodeStatusView.dimens.height)
|
||||||
.map(ac => {
|
.map(ac => {
|
||||||
// Handle pre-authenticated
|
// Handle pre-authenticated
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
|
|
||||||
// ENiGMA½
|
// ENiGMA½
|
||||||
const { MenuModule } = require('./menu_module.js');
|
const { MenuModule } = require('./menu_module.js');
|
||||||
const { getActiveConnectionList } = require('./client_connections.js');
|
const {
|
||||||
|
getActiveConnectionList,
|
||||||
|
UserVisibleConnections } = require('./client_connections.js');
|
||||||
const { Errors } = require('./enig_error.js');
|
const { Errors } = require('./enig_error.js');
|
||||||
|
|
||||||
// deps
|
// deps
|
||||||
|
@ -43,7 +45,7 @@ exports.getModule = class WhosOnlineModule extends MenuModule {
|
||||||
return cb(Errors.MissingMci(`Missing online list MCI ${MciViewIds.onlineList}`));
|
return cb(Errors.MissingMci(`Missing online list MCI ${MciViewIds.onlineList}`));
|
||||||
}
|
}
|
||||||
|
|
||||||
const onlineList = getActiveConnectionList().slice(0, onlineListView.height).map(
|
const onlineList = getActiveConnectionList(UserVisibleConnections).slice(0, onlineListView.height).map(
|
||||||
oe => Object.assign(oe, { text : oe.userName, timeOn : _.upperFirst(oe.timeOn.humanize()) })
|
oe => Object.assign(oe, { text : oe.userName, timeOn : _.upperFirst(oe.timeOn.humanize()) })
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -105,6 +105,8 @@ There are many predefined MCI codes that can be used anywhere on the system (pla
|
||||||
| `LD` | Date of last caller |
|
| `LD` | Date of last caller |
|
||||||
| `TU` | Total number of users on the system |
|
| `TU` | Total number of users on the system |
|
||||||
| `NT` | Total *new* users *today* |
|
| `NT` | Total *new* users *today* |
|
||||||
|
| `NM` | Count of new messages **address to the current user** across all message areas in which they have access |
|
||||||
|
| `NP` | Count of new private mail to the current user |
|
||||||
|
|
||||||
Some additional special case codes also exist:
|
Some additional special case codes also exist:
|
||||||
|
|
||||||
|
|
|
@ -78,4 +78,6 @@ The following MCI codes are available:
|
||||||
* `totalMemoryBytes`: Total system memory in bytes.
|
* `totalMemoryBytes`: Total system memory in bytes.
|
||||||
* `freeMemoryBytes`: Free system memory in bytes.
|
* `freeMemoryBytes`: Free system memory in bytes.
|
||||||
* `systemAvgLoad`: System average load.
|
* `systemAvgLoad`: System average load.
|
||||||
* `systemCurrentLoad`: System current load.
|
* `systemCurrentLoad`: System current load.
|
||||||
|
* `newPrivateMail`: Number of new **privae** mail for current user.
|
||||||
|
* `newMessagesAddrTo`: Number of new messages **addressed to the current user**.
|
Loading…
Reference in New Issue