From 00deb3fe72dda04ed9cafcbbef9d468373b7cfdd Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Thu, 11 Jan 2018 21:39:14 -0700 Subject: [PATCH] * Add concept of external flavor to import/exported mails, e.g. 'ftn' * Add to/from remote user meta for opaqe addrs, e.g. 'ftn' flavor can use FTN-style addresses * Allow replys from inbox to a NetMail --- core/fse.js | 54 ++++++++++++++++++------------ core/message.js | 22 ++++++++++++ core/new_scan.js | 5 +-- core/oputil/oputil_message_base.js | 12 ++----- core/scanner_tossers/ftn_bso.js | 49 +++++++++++++++++---------- 5 files changed, 93 insertions(+), 49 deletions(-) diff --git a/core/fse.js b/core/fse.js index 4a6c8eb1..d84de1e9 100644 --- a/core/fse.js +++ b/core/fse.js @@ -411,30 +411,42 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul return callback(null); }, function populateLocalUserInfo(callback) { - if(self.isPrivateMail()) { - self.message.setLocalFromUserId(self.client.user.userId); - - if(self.toUserId > 0) { - self.message.setLocalToUserId(self.toUserId); - callback(null); - } else { - // we need to look it up - User.getUserIdAndNameByLookup(self.message.toUserName, function userInfo(err, toUserId) { - if(err) { - callback(err); - } else { - self.message.setLocalToUserId(toUserId); - callback(null); - } - }); - } - } else { - callback(null); + if(!self.isPrivateMail()) { + return callback(null); } + + // :TODO: shouldn't local from user ID be set for all mail? + self.message.setLocalFromUserId(self.client.user.userId); + + if(self.toUserId > 0) { + self.message.setLocalToUserId(self.toUserId); + return callback(null); + } + + // + // If the message we're replying to is from a remote user + // don't try to look up the local user ID. Instead, mark the mail + // for export with the remote to address. + // + if(self.replyToMessage.isFromRemoteUser()) { + self.message.setRemoteToUser(self.replyToMessage.meta.System[Message.SystemMetaNames.RemoteFromUser]); + self.message.setExternalFlavor(self.replyToMessage.meta.System[Message.SystemMetaNames.ExternalFlavor]); + return callback(null); + } + + // we need to look it up + User.getUserIdAndNameByLookup(self.message.toUserName, (err, toUserId) => { + if(err) { + return callback(err); + } + + self.message.setLocalToUserId(toUserId); + return callback(null); + }); } ], - function complete(err) { - cb(err, self.message); + err => { + return cb(err, self.message); } ); } diff --git a/core/message.js b/core/message.js index 7fb57d20..360b211a 100644 --- a/core/message.js +++ b/core/message.js @@ -76,6 +76,10 @@ function Message(options) { this.isPrivate = function() { return Message.isPrivateAreaTag(this.areaTag); }; + + this.isFromRemoteUser = function() { + return null !== _.get(this, 'meta.System.remote_from_user', null); + }; } Message.WellKnownAreaTags = { @@ -93,6 +97,14 @@ Message.SystemMetaNames = { LocalFromUserID : 'local_from_user_id', StateFlags0 : 'state_flags0', // See Message.StateFlags0 ExplicitEncoding : 'explicit_encoding', // Explicitly set encoding when exporting/etc. + ExternalFlavor : 'external_flavor', // "Flavor" of message - imported from or to be exported to. See Message.ExternalFlavors + RemoteToUser : 'remote_to_user', // Opaque value depends on external system, e.g. FTN address + RemoteFromUser : 'remote_from_user', // Opaque value depends on external system, e.g. FTN address +}; + +// Types for Message.SystemMetaNames.ExternalFlavor meta +Message.ExternalFlavors = { + FTN : 'ftn', // FTN style }; Message.StateFlags0 = { @@ -133,6 +145,16 @@ Message.prototype.setLocalFromUserId = function(userId) { this.meta.System[Message.SystemMetaNames.LocalFromUserID] = userId; }; +Message.prototype.setRemoteToUser = function(remoteTo) { + this.meta.System = this.meta.System || {}; + this.meta.System[Message.SystemMetaNames.RemoteToUser] = remoteTo; +}; + +Message.prototype.setExternalFlavor = function(flavor) { + this.meta.System = this.meta.System || {}; + this.meta.System[Message.SystemMetaNames.ExternalFlavor] = flavor; +}; + Message.createMessageUUID = function(areaTag, modTimestamp, subject, body) { assert(_.isString(areaTag)); assert(_.isDate(modTimestamp) || moment.isMoment(modTimestamp)); diff --git a/core/new_scan.js b/core/new_scan.js index a75a5b2d..f3e851fb 100644 --- a/core/new_scan.js +++ b/core/new_scan.js @@ -170,6 +170,7 @@ exports.getModule = class NewScanModule extends MenuModule { const filterCriteria = { newerThanFileId : FileBaseFilters.getFileBaseLastViewedFileIdByUser(this.client.user), areaTag : getAvailableFileAreaTags(this.client), + order : 'ascending', // oldest first }; FileEntry.findFiles( @@ -179,11 +180,11 @@ exports.getModule = class NewScanModule extends MenuModule { return cb(err ? err : Errors.DoesNotExist('No more new files')); } - FileBaseFilters.setFileBaseLastViewedFileIdForUser( this.client.user, fileIds[0] ); + FileBaseFilters.setFileBaseLastViewedFileIdForUser( this.client.user, fileIds[fileIds.length - 1] ); const menuOpts = { extraArgs : { - fileList : fileIds, + fileList : fileIds, }, }; diff --git a/core/oputil/oputil_message_base.js b/core/oputil/oputil_message_base.js index 2ab93104..b1c6673e 100644 --- a/core/oputil/oputil_message_base.js +++ b/core/oputil/oputil_message_base.js @@ -90,18 +90,13 @@ function areaFix() { message : messageBody, areaTag : Message.WellKnownAreaTags.Private, // mark private meta : { - FtnProperty : { - [ Message.FtnPropertyNames.FtnDestZone ] : ftnAddr.zone, - [ Message.FtnPropertyNames.FtnDestNetwork ] : ftnAddr.net, - [ Message.FtnPropertyNames.FtnDestNode ] : ftnAddr.node, + System : { + [ Message.SystemMetaNames.RemoteToUser ] : ftnAddr.toString(), // where to send it + [ Message.SystemMetaNames.ExternalFlavor ] : Message.ExternalFlavors.FTN, // on FTN-style network } } }); - if(ftnAddr.point) { - message.meta.FtnProperty[Message.FtnPropertyNames.FtnDestPoint] = ftnAddr.point; - } - if(0 !== fromUserId) { message.setLocalFromUserId(fromUserId); } @@ -109,7 +104,6 @@ function areaFix() { return callback(null, message); }, function persistMessage(message, callback) { - // :TODO: Persist message in private outgoing (sysop out box) (TBD: implementation) message.persist(err => { if(!err) { console.log('AreaFix message persisted and will be exported at next scheduled scan'); diff --git a/core/scanner_tossers/ftn_bso.js b/core/scanner_tossers/ftn_bso.js index bba0c313..c7e3edc9 100644 --- a/core/scanner_tossers/ftn_bso.js +++ b/core/scanner_tossers/ftn_bso.js @@ -45,12 +45,8 @@ exports.moduleInfo = { /* :TODO: * Support (approx) max bundle size - * Support NetMail - * NetMail needs explicit isNetMail() check - * NetMail filename / location / etc. is still unknown - need to post on groups & get real answers * Validate packet passwords!!!! => secure vs insecure landing areas - */ exports.getModule = FTNMessageScanTossModule; @@ -878,12 +874,7 @@ function FTNMessageScanTossModule() { } }, function discoverUplink(callback) { - const dstAddr = new Address({ - zone : parseInt(message.meta.FtnProperty.ftn_dest_zone), - net : parseInt(message.meta.FtnProperty.ftn_dest_network), - node : parseInt(message.meta.FtnProperty.ftn_dest_node), - point : parseInt(message.meta.FtnProperty.ftn_dest_point) || null, // point is optional - }); + const dstAddr = new Address(message.meta.System[Message.SystemMetaNames.RemoteToUser]); return self.getAcceptableNetMailNetworkInfoFromAddress(dstAddr, (err, config, routeAddress, networkName) => { if(err) { @@ -1152,6 +1143,9 @@ function FTNMessageScanTossModule() { function basicSetup(callback) { message.areaTag = config.localAreaTag; + // indicate this was imported from FTN + message.meta.System[Message.SystemMetaNames.ExternalFlavor] = Message.ExternalFlavors.FTN; + // // If we *allow* dupes (disabled by default), then just generate // a random UUID. Otherwise, don't assign the UUID just yet. It will be @@ -1177,6 +1171,22 @@ function FTNMessageScanTossModule() { return callback(null); } + // + // Create a meta value for the *remote* from user. In the case here with FTN, + // their fully qualified FTN from address + // + const intlKludge = _.get(message, 'meta.FtnKludge.INTL'); + if(intlKludge && intlKludge.length > 0) { + let fromAddress = intlKludge.split(' ')[0]; + + const fromPointKludge = _.get(message, 'meta.FtnKludge.FMPT'); + if(fromPointKludge) { + fromAddress += `.${fromPointKludge}`; + } + + message.meta.System[Message.SystemMetaNames.RemoteFromUser] = fromAddress; + } + const lookupName = self.getLocalUserNameFromAlias(message.toUserName); User.getUserIdAndNameByLookup(lookupName, (err, localToUserId, localUserName) => { @@ -1911,8 +1921,7 @@ function FTNMessageScanTossModule() { this.performNetMailExport = function(cb) { // // Select all messages with a |message_id| > |lastScanId| in the private area - // that also *do not* have a local user ID meta value but *do* have a FTN dest - // network meta value. + // that are schedule for export to FTN-style networks. // // Just like EchoMail, we additionally exclude messages with the System state_flags0 // which will be present for imported or already exported messages @@ -1927,12 +1936,18 @@ function FTNMessageScanTossModule() { WHERE area_tag = '${Message.WellKnownAreaTags.Private}' AND message_id > ? AND (SELECT COUNT(message_id) FROM message_meta - WHERE message_id = m.message_id AND meta_category = 'System' AND - (meta_name = 'state_flags0' OR meta_name='local_to_user_id')) = 0 + WHERE message_id = m.message_id + AND meta_category = 'System' + AND (meta_name = 'state_flags0' OR meta_name = 'local_to_user_id') + ) = 0 AND (SELECT COUNT(message_id) FROM message_meta - WHERE message_id = m.message_id AND meta_category='FtnProperty' AND meta_name='ftn_dest_network') = 1 + WHERE message_id = m.message_id + AND meta_category = 'System' + AND meta_name = '${Message.SystemMetaNames.ExternalFlavor}' + AND meta_value = '${Message.ExternalFlavors.FTN}' + ) = 1 ORDER BY message_id; `; @@ -1967,8 +1982,8 @@ function FTNMessageScanTossModule() { this.isNetMailMessage = function(message) { return message.isPrivate() && - null === _.get(message.meta, 'System.LocalToUserID', null) && - null !== _.get(message.meta, 'FtnProperty.ftn_dest_network', null) + null === _.get(message, 'meta.System.LocalToUserID', null) && + Message.ExternalFlavors.FTN === _.get(message, 'meta.System.external_flavor', null) ; }; }