Skip to content
Snippets Groups Projects
Commit 494c0a83 authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

Merge branch 'dd_msg_reader_headers_refinement' into 'master'

DDMsgReader: When viewing message headers, now shows all available message header values

See merge request !288
parents 28ba58eb d540b1f6
No related branches found
No related tags found
2 merge requests!463MRC mods by Codefenix (2024-10-20),!288DDMsgReader: When viewing message headers, now shows all available message header values
...@@ -128,6 +128,9 @@ ...@@ -128,6 +128,9 @@
* Bug fix: When getting header lines to view, ensure the header lines * Bug fix: When getting header lines to view, ensure the header lines
* are not too wide for the user's terminal. Header lines that are too * are not too wide for the user's terminal. Header lines that are too
* long will be split into no more than 2 lines. * long will be split into no more than 2 lines.
* 2023-04-25 Eric Oulashin Version 1.73a
* Refactored the functions for getting message header lines. Also, now
* all message header information is retrieved.
*/ */
   
"use strict"; "use strict";
...@@ -228,13 +231,14 @@ require("dd_lightbar_menu.js", "DDLightbarMenu"); ...@@ -228,13 +231,14 @@ require("dd_lightbar_menu.js", "DDLightbarMenu");
require("html2asc.js", 'html2asc'); require("html2asc.js", 'html2asc');
require("attr_conv.js", "convertAttrsToSyncPerSysCfg"); require("attr_conv.js", "convertAttrsToSyncPerSysCfg");
require("graphic.js", 'Graphic'); require("graphic.js", 'Graphic');
require("smbdefs.js", "SMB_POLL_ANSWER");
load('822header.js'); load('822header.js');
var ansiterm = require("ansiterm_lib.js", 'expand_ctrl_a'); var ansiterm = require("ansiterm_lib.js", 'expand_ctrl_a');
   
   
// Reader version information // Reader version information
var READER_VERSION = "1.73"; var READER_VERSION = "1.73a";
var READER_DATE = "2023-04-17"; var READER_DATE = "2023-04-25";
   
// Keyboard key codes for displaying on the screen // Keyboard key codes for displaying on the screen
var UP_ARROW = ascii(24); var UP_ARROW = ascii(24);
...@@ -491,13 +495,10 @@ var gFileAttachDir = backslash(system.node_dir + "DDMsgReader_Attachments"); ...@@ -491,13 +495,10 @@ var gFileAttachDir = backslash(system.node_dir + "DDMsgReader_Attachments");
if (file_exists(gFileAttachDir)) if (file_exists(gFileAttachDir))
deltree(gFileAttachDir); deltree(gFileAttachDir);
   
// See if the avatar support files are available, and load them if so // See if the avatar support file is available, and load is if so
var gAvatar = null; var gAvatar = null;
if (file_exists(backslash(system.exec_dir) + "load/smbdefs.js") && file_exists(backslash(system.exec_dir) + "load/avatar_lib.js")) if (file_exists(backslash(system.exec_dir) + "load/avatar_lib.js"))
{
require("smbdefs.js", "SMB_POLL_ANSWER");
gAvatar = load({}, "avatar_lib.js"); gAvatar = load({}, "avatar_lib.js");
}
   
// User twitlist filename (and settings filename) // User twitlist filename (and settings filename)
var gUserTwitListFilename = backslash(system.data_dir + "user") + format("%04d", user.number) + ".DDMsgReader_twitlist"; var gUserTwitListFilename = backslash(system.data_dir + "user") + format("%04d", user.number) + ".DDMsgReader_twitlist";
...@@ -854,6 +855,7 @@ function DigDistMsgReader(pSubBoardCode, pScriptArgs) ...@@ -854,6 +855,7 @@ function DigDistMsgReader(pSubBoardCode, pScriptArgs)
this.PromptAndDeleteOrUndeleteMessage = DigDistMsgReader_PromptAndDeleteOrUndeleteMessage; this.PromptAndDeleteOrUndeleteMessage = DigDistMsgReader_PromptAndDeleteOrUndeleteMessage;
this.PromptAndDeleteOrUndeleteSelectedMessages = DigDistMsgReader_PromptAndDeleteOrUndeleteSelectedMessages; this.PromptAndDeleteOrUndeleteSelectedMessages = DigDistMsgReader_PromptAndDeleteOrUndeleteSelectedMessages;
this.GetExtdMsgHdrInfo = DigDistMsgReader_GetExtdMsgHdrInfo; this.GetExtdMsgHdrInfo = DigDistMsgReader_GetExtdMsgHdrInfo;
this.GetMsgHdrFieldListText = DigDistMsgReader_GetMsgHdrFieldListText;
this.GetMsgInfoForEnhancedReader = DigDistMsgReader_GetMsgInfoForEnhancedReader; this.GetMsgInfoForEnhancedReader = DigDistMsgReader_GetMsgInfoForEnhancedReader;
this.GetLastReadMsgIdxAndNum = DigDistMsgReader_GetLastReadMsgIdxAndNum; this.GetLastReadMsgIdxAndNum = DigDistMsgReader_GetLastReadMsgIdxAndNum;
this.GetScanPtrMsgIdx = DigDistMsgReader_GetScanPtrMsgIdx; this.GetScanPtrMsgIdx = DigDistMsgReader_GetScanPtrMsgIdx;
...@@ -1028,6 +1030,7 @@ function DigDistMsgReader(pSubBoardCode, pScriptArgs) ...@@ -1028,6 +1030,7 @@ function DigDistMsgReader(pSubBoardCode, pScriptArgs)
invalidMsgNumText: "\x01n\x01y\x01hInvalid message number: %d", invalidMsgNumText: "\x01n\x01y\x01hInvalid message number: %d",
readMsgNumPromptText: "\x01n\x01g\x01h\x01i* \x01n\x01cRead message #: \x01h", readMsgNumPromptText: "\x01n\x01g\x01h\x01i* \x01n\x01cRead message #: \x01h",
msgHasBeenDeletedText: "\x01n\x01h\x01g* \x01yMessage #\x01w%d \x01yhas been deleted.", msgHasBeenDeletedText: "\x01n\x01h\x01g* \x01yMessage #\x01w%d \x01yhas been deleted.",
noHdrLinesForThisMsgText: "\x01n\x01h\x01yThere are no header lines for this message.",
noKludgeLinesForThisMsgText: "\x01n\x01h\x01yThere are no kludge lines for this message.", noKludgeLinesForThisMsgText: "\x01n\x01h\x01yThere are no kludge lines for this message.",
searchingPersonalMailText: "\x01w\x01hSearching personal mail\x01n", searchingPersonalMailText: "\x01w\x01hSearching personal mail\x01n",
searchTextPromptText: "\x01cEnter the search text\x01g\x01h:\x01n\x01c ", searchTextPromptText: "\x01cEnter the search text\x01g\x01h:\x01n\x01c ",
...@@ -5564,7 +5567,8 @@ function DigDistMsgReader_ReadMessageEnhanced_Scrollable(msgHeader, allowChgMsgA ...@@ -5564,7 +5567,8 @@ function DigDistMsgReader_ReadMessageEnhanced_Scrollable(msgHeader, allowChgMsgA
   
// Get an array of the extended header info/kludge lines and then // Get an array of the extended header info/kludge lines and then
// allow the user to scroll through them. // allow the user to scroll through them.
var extdHdrInfoLines = this.GetExtdMsgHdrInfo(msgHeader, (retObj.lastKeypress == this.enhReaderKeys.showKludgeLines)); var onlyKludgeLines = (retObj.lastKeypress == this.enhReaderKeys.showKludgeLines);
var extdHdrInfoLines = this.GetExtdMsgHdrInfo(this.subBoardCode, msgHeader.number, onlyKludgeLines);
if (extdHdrInfoLines.length > 0) if (extdHdrInfoLines.length > 0)
{ {
if (this.userSettings.useEnhReaderScrollbar) if (this.userSettings.useEnhReaderScrollbar)
...@@ -5598,8 +5602,9 @@ function DigDistMsgReader_ReadMessageEnhanced_Scrollable(msgHeader, allowChgMsgA ...@@ -5598,8 +5602,9 @@ function DigDistMsgReader_ReadMessageEnhanced_Scrollable(msgHeader, allowChgMsgA
} }
else else
{ {
// There are no kludge lines for this message // There are no header/kludge lines for this message
this.DisplayEnhReaderError(replaceAtCodesInStr(this.text.noKludgeLinesForThisMsgText), msgInfo.messageLines, topMsgLineIdx, msgLineFormatStr); var msgText = onlyKludgeLines ? this.text.noKludgeLinesForThisMsgText : this.text.noHdrLinesForThisMsgText;
this.DisplayEnhReaderError(replaceAtCodesInStr(msgText), msgInfo.messageLines, topMsgLineIdx, msgLineFormatStr);
console.gotoxy(originalCurPos); console.gotoxy(originalCurPos);
writeMessage = false; writeMessage = false;
} }
...@@ -6770,7 +6775,7 @@ function DigDistMsgReader_ReadMessageEnhanced_Traditional(msgHeader, allowChgMsg ...@@ -6770,7 +6775,7 @@ function DigDistMsgReader_ReadMessageEnhanced_Traditional(msgHeader, allowChgMsg
console.crlf(); console.crlf();
// Get an array of the extended header info/kludge lines and then // Get an array of the extended header info/kludge lines and then
// display them. // display them.
var extdHdrInfoLines = this.GetExtdMsgHdrInfo(msgHeader, (retObj.lastKeypress == this.enhReaderKeys.showKludgeLines)); var extdHdrInfoLines = this.GetExtdMsgHdrInfo(this.subBoardCode, msgHeader.number, (retObj.lastKeypress == this.enhReaderKeys.showKludgeLines));
if (extdHdrInfoLines.length > 0) if (extdHdrInfoLines.length > 0)
{ {
console.crlf(); console.crlf();
...@@ -8597,6 +8602,7 @@ function DigDistMsgReader_ReadConfigFile() ...@@ -8597,6 +8602,7 @@ function DigDistMsgReader_ReadConfigFile()
(setting == "invalidMsgNumText") || (setting == "invalidMsgNumText") ||
(setting == "readMsgNumPromptText") || (setting == "readMsgNumPromptText") ||
(setting == "msgHasBeenDeletedText") || (setting == "msgHasBeenDeletedText") ||
(setting == "noHdrLinesForThisMsgText") ||
(setting == "noKludgeLinesForThisMsgText") || (setting == "noKludgeLinesForThisMsgText") ||
(setting == "searchingPersonalMailText") || (setting == "searchingPersonalMailText") ||
(setting == "searchingSubBoardAbovePromptText") || (setting == "searchingSubBoardAbovePromptText") ||
...@@ -9302,8 +9308,8 @@ function DigDistMsgReader_GetMsgHdrByAbsoluteNum(pMsgNum, pExpandFields, pGetVot ...@@ -9302,8 +9308,8 @@ function DigDistMsgReader_GetMsgHdrByAbsoluteNum(pMsgNum, pExpandFields, pGetVot
var msgbase = new MsgBase(this.subBoardCode); var msgbase = new MsgBase(this.subBoardCode);
if (msgbase.open()) if (msgbase.open())
{ {
var expandFields = (typeof(pExpandFields) == "boolean" ? pExpandFields : false); var expandFields = (typeof(pExpandFields) === "boolean" ? pExpandFields : false);
var getVoteInfo = (typeof(pGetVoteInfo) == "boolean" ? pGetVoteInfo : false); var getVoteInfo = (typeof(pGetVoteInfo) === "boolean" ? pGetVoteInfo : false);
msgHdr = msgbase.get_msg_header(false, pMsgNum, expandFields, getVoteInfo); msgHdr = msgbase.get_msg_header(false, pMsgNum, expandFields, getVoteInfo);
msgbase.close(); msgbase.close();
} }
...@@ -9311,6 +9317,22 @@ function DigDistMsgReader_GetMsgHdrByAbsoluteNum(pMsgNum, pExpandFields, pGetVot ...@@ -9311,6 +9317,22 @@ function DigDistMsgReader_GetMsgHdrByAbsoluteNum(pMsgNum, pExpandFields, pGetVot
msgHdr = getBogusMsgHdr(); msgHdr = getBogusMsgHdr();
return msgHdr; return msgHdr;
} }
function DumpMsgHdr(pSubCode, pMsgNum, pExpandFields, pGetVoteInfo)
{
var hdrLines = [];
var msgHdr = null;
var msgbase = new MsgBase(pSubCode);
if (msgbase.open())
{
var expandFields = (typeof(pExpandFields) === "boolean" ? pExpandFields : false);
var getVoteInfo = (typeof(pGetVoteInfo) === "boolean" ? pGetVoteInfo : false);
msgHdr = msgbase.get_msg_header(false, pMsgNum, expandFields, getVoteInfo);
if (msgHdr != null)
hdrLines = msgbase.dump_msg_header(msgHdr);
msgbase.close();
}
return hdrLines;
}
   
// For the DigDistMsgReader class: Takes an absolute message number and returns // For the DigDistMsgReader class: Takes an absolute message number and returns
// its message index (offset). On error, returns -1. // its message index (offset). On error, returns -1.
...@@ -12081,7 +12103,7 @@ function DigDistMsgReader_ListSubBoardsInMsgGroup_Traditional(pGrpIndex, pMarkIn ...@@ -12081,7 +12103,7 @@ function DigDistMsgReader_ListSubBoardsInMsgGroup_Traditional(pGrpIndex, pMarkIn
this.WriteSubBrdListHdrLine(grpIndex); this.WriteSubBrdListHdrLine(grpIndex);
console.crlf(); console.crlf();
printf(this.subBoardListHdrPrintfStr, "Sub #", "Name", "# Posts", "Latest date & time"); printf(this.subBoardListHdrPrintfStr, "Sub #", "Name", "# Posts", "Latest date & time");
console.print("\x01n"); console.attributes = "N";
   
// List each sub-board in the message group. // List each sub-board in the message group.
var searchText = (typeof(pSearchText) == "string" ? pSearchText.toUpperCase() : ""); var searchText = (typeof(pSearchText) == "string" ? pSearchText.toUpperCase() : "");
...@@ -12538,27 +12560,46 @@ function DigDistMsgReader_BuildSubBoardPrintfInfoForGrp(pGrpIndex) ...@@ -12538,27 +12560,46 @@ function DigDistMsgReader_BuildSubBoardPrintfInfoForGrp(pGrpIndex)
// retrieves will only be retrieved if they exist in the given message header. // retrieves will only be retrieved if they exist in the given message header.
// //
// Parameters: // Parameters:
// pMsgHdr: A message header // pSubCodeOrMsgbase: An internal sub-board code of the messagebase, or a MsgBase object representing
// the sub-board the message is in (assumed to be open)
// pMsgNum: The message number of the message headers to retrieve
// pKludgeOnly: Boolean - Whether or not to only get the kludge lines. If false, // pKludgeOnly: Boolean - Whether or not to only get the kludge lines. If false,
// then all header fields will be retrieved. // then all header fields will be retrieved.
// pUseColors: Optional boolean: Whether or not to add colors to the strings. Defaults to true.
// pWordWrap: Optional boolean: Whether or not to word-wrap the header lines to the user's
// terminal width. Defaults to true.
// pPrependHdrLabelLines: Optional boolean - Whether or not to prepend a couple lines labeling
// that these are header/kludge lines. Defaults to true.
// //
// Return value: An array of strings containing the extended message header information // Return value: An array of strings containing the extended message header information
function DigDistMsgReader_GetExtdMsgHdrInfo(pMsgHdr, pKludgeOnly) function DigDistMsgReader_GetExtdMsgHdrInfo(pSubCodeOrMsgbase, pMsgNum, pKludgeOnly, pUseColors, pWordWrap, pPrependHdrLabelLines)
{ {
// If pMsgHdr is not valid, then just return an empty array. if (typeof(pMsgNum) !== "number")
if (typeof(pMsgHdr) != "object")
return []; return [];
   
// Get the message header with fields expanded so we can get the most info possible. // Get the message header with fields expanded so we can get the most info possible.
var msgHdr = this.GetMsgHdrByAbsoluteNum(pMsgHdr.number, true, true); var msgHdr = null;
if (typeof(pSubCodeOrMsgbase) === "string")
{
var msgbase = new MsgBase(pSubCodeOrMsgbase);
if (msgbase.open())
{
msgHdr = msgbase.get_msg_header(false, pMsgNum, true, true);
msgbase.close();
}
}
else if (typeof(pSubCodeOrMsgbase) === "object" && pSubCodeOrMsgbase.hasOwnProperty("get_msg_header") && pSubCodeOrMsgbase.is_open)
msgHdr = pSubCodeOrMsgbase.get_msg_header(false, pMsgNum, true, true);
if (msgHdr == null) if (msgHdr == null)
return []; return [];
// The message header retrieved that way might not have vote information, // The message header retrieved that way might not have vote information,
// so copy any additional header information from this.hdrsForCurrentSubBoard // so copy any additional header information from this.hdrsForCurrentSubBoard
// if there's a header there for this message. // if there's a header there for this message.
if (this.hdrsForCurrentSubBoardByMsgNum.hasOwnProperty(pMsgHdr.number)) if (this.hdrsForCurrentSubBoardByMsgNum.hasOwnProperty(pMsgNum))
{ {
var tmpHdrIdx = this.hdrsForCurrentSubBoardByMsgNum[pMsgHdr.number]; var tmpHdrIdx = this.hdrsForCurrentSubBoardByMsgNum[pMsgNum];
if (this.hdrsForCurrentSubBoard.hasOwnProperty(tmpHdrIdx)) if (this.hdrsForCurrentSubBoard.hasOwnProperty(tmpHdrIdx))
{ {
for (var hdrProp in this.hdrsForCurrentSubBoard[tmpHdrIdx]) for (var hdrProp in this.hdrsForCurrentSubBoard[tmpHdrIdx])
...@@ -12569,29 +12610,207 @@ function DigDistMsgReader_GetExtdMsgHdrInfo(pMsgHdr, pKludgeOnly) ...@@ -12569,29 +12610,207 @@ function DigDistMsgReader_GetExtdMsgHdrInfo(pMsgHdr, pKludgeOnly)
} }
} }
   
var kludgeOnly = (typeof(pKludgeOnly) == "boolean" ? pKludgeOnly : false);
var useColors = (typeof(pUseColors) === "boolean" ? pUseColors : true);
var wordWrap = (typeof(pWordWrap) === "boolean" ? pWordWrap : true);
var prependHdrLabelLines = (typeof(pPrependHdrLabelLines) === "boolean" ? pPrependHdrLabelLines : true);
var msgHdrInfoLines = []; var msgHdrInfoLines = [];
   
var hdrInfoLineFields = []; var formatStr;
var kludgeOnly = (typeof(pKludgeOnly) == "boolean" ? pKludgeOnly : false); if (useColors)
formatStr = "\x01n" + this.colors.hdrLineLabelColor + "%s: \x01n" + this.colors.hdrLineValueColor + "%-s";
else
formatStr = "%s: %-s";
// Make an array of objects with 'prop' and 'textArray' fields; this array will be sorted by prop
var msgInfoObjs = [];
for (var prop in msgHdr)
{
if (prop == "field_list")
{
//var fieldListLines = this.GetMsgHdrFieldListText(msgHdr[prop], true);
//for (var i = 0; i < fieldListLines.length; ++i)
// msgHdrInfoLines.push(fieldListLines[i]);
var fieldListObj = GetMsgHdrFieldListObj(msgHdr.field_list);
var fieldListKeys = Object.keys(msgHdr);
fieldListKeys.sort();
for (var fieldListProp in fieldListObj)
//for (var fieldListKeyIdx = 0; fieldListKeyIdx < fieldListKeys.length; ++fieldListKeyIdx)
{
//var fieldListProp = fieldListKeys[fieldListKeyIdx];
//msgHdrInfoLines.push(format(formatStr, fieldListProp, fieldListObj[fieldListProp]));
if (Array.isArray(fieldListObj[fieldListProp]))
{
var tmpTxtLines = [];
if (fieldListObj[fieldListProp].length > 0)
{
//msgHdrInfoLines.push(format(formatStr, fieldListProp, fieldListObj[fieldListProp][0]));
tmpTxtLines.push(format(formatStr, fieldListProp, fieldListObj[fieldListProp][0]));
for (var i = 1; i < fieldListObj[fieldListProp].length; ++i)
{
//msgHdrInfoLines.push(fieldListObj[fieldListProp][i]);
tmpTxtLines.push(fieldListObj[fieldListProp][i]);
}
}
msgInfoObjs.push({
'prop': fieldListProp,
'textArray': tmpTxtLines
});
}
else
{
//msgHdrInfoLines.push(format(formatStr, fieldListProp, fieldListObj[fieldListProp]));
msgInfoObjs.push({
'prop': fieldListProp,
'textArray': [ format(formatStr, fieldListProp, fieldListObj[fieldListProp]) ]
})
}
}
}
else
{
var addIt = kludgeOnly ? MsgHdrPropIsKludgeLine(prop) : true;
if (addIt)
{
// Remove underscores from the property for the label
var propLabel = prop.replace(/_/g, " ");
// Apply good-looking capitalization to the property label
if ((propLabel == "id") || (propLabel == "ftn tid"))
propLabel = propLabel.toUpperCase();
else if (propLabel == "ftn area")
propLabel = "FTN Area";
else if (propLabel == "ftn pid")
propLabel = "Program ID";
else if (propLabel == "thread id")
propLabel = "Thread ID";
else if (propLabel == "attr")
propLabel = "Attributes";
else if (propLabel == "auxattr")
propLabel = "Auxiliary attributes";
else if (propLabel == "netattr")
propLabel = "Network attributes";
else
propLabel = capitalizeFirstChar(propLabel);
// Value
var propValue = "";
if (typeof(msgHdr[prop]) === "function") // Such as get_rfc822_header
continue;
if (prop == "when_written_time") //itemValue = system.timestr(msgHdr.when_written_time);
propValue = system.timestr(msgHdr.when_written_time) + " " + system.zonestr(msgHdr.when_written_zone);
else if (prop == "when_imported_time") //propValue = system.timestr(msgHdr.when_imported_time);
propValue = system.timestr(msgHdr.when_imported_time) + " " + system.zonestr(msgHdr.when_imported_zone);
else if ((prop == "when_imported_zone") || (prop == "when_written_zone"))
propValue = system.zonestr(msgHdr[prop]);
else if (prop == "attr")
propValue = makeMainMsgAttrStr(msgHdr[prop], "None");
else if (prop == "auxattr")
propValue = makeAuxMsgAttrStr(msgHdr[prop], "None");
else if (prop == "netattr")
propValue = makeNetMsgAttrStr(msgHdr[prop], "None");
else
propValue = msgHdr[prop];
if (typeof(propValue) === "string")
{
// Replace tabs with spaces, and strip CRLF characters
// TODO: Should CRLF characters actually be split into separate lines?
propValue = propValue.trim().replace(/\t/g, " ").replace(/[^\x20-\x7E]/g, '');
propValue = propValue.replace(/\r\n/g, "");
propValue = propValue.replace(/\n/g, "").replace(/\r/g, "");
}
//msgHdrInfoLines.push(format(formatStr, propLabel, propValue));
msgInfoObjs.push({
'prop': propLabel,
'textArray': [ format(formatStr, propLabel, propValue) ]
})
}
}
}
// Sort the header lines alphabetically
msgInfoObjs.sort(function(pA, pB)
{
if (pA.prop < pB.prop)
return -1;
else if (pA.prop == pB.prop)
return 0;
else
return 1;
});
for (var i = 0; i < msgInfoObjs.length; ++i)
{
for (var j = 0; j < msgInfoObjs[i].textArray.length; ++j)
msgHdrInfoLines.push(msgInfoObjs[i].textArray[j]);
}
// Free some memory
for (var prop in msgInfoObjs)
delete msgInfoObjs[prop];
// If the caller wants to word-wrap, make sure the header lines aren't too long for the
// user's terminal. And leave a column for the scrollbar.
var hdrInfoLinesWrapped;
if (wordWrap)
{
hdrInfoLinesWrapped = [];
var maxLen = console.screen_columns - 1;
var colorFormatStr = "\x01n" + this.colors.hdrLineLabelColor + "%-s: \x01n" + this.colors.hdrLineValueColor + "%-s";
for (var i = 0; i < msgHdrInfoLines.length; ++i)
{
//var wrappedLines = word_wrap(msgHdrInfoLines[i], maxLen).split("\n");
var wrappedLines = lfexpand(word_wrap(msgHdrInfoLines[i], maxLen)).split("\r\n");
for (var wrappedI = 0; wrappedI < wrappedLines.length; ++wrappedI)
{
if (wrappedLines[wrappedI].length == 0) continue;
hdrInfoLinesWrapped.push(wrappedLines[wrappedI]);
}
}
}
else // No word wrapping
hdrInfoLinesWrapped = msgHdrInfoLines;
// If some info lines were added, then insert a header line & blank line to
// the beginning of the array, and remove the last empty line from the array.
if (hdrInfoLinesWrapped.length > 0)
{
if (prependHdrLabelLines)
{
if (kludgeOnly) if (kludgeOnly)
{ {
hdrInfoLineFields.push({ field: "ftn_msgid", label: "MSG ID:" }); hdrInfoLinesWrapped.splice(0, 0, "\x01n\x01c\x01hMessage Information/Kludge Lines\x01n");
hdrInfoLineFields.push({ field: "X-FTN-MSGID", label: "MSG ID:" }); hdrInfoLinesWrapped.splice(1, 0, "\x01n\x01g\x01h--------------------------------\x01n");
hdrInfoLineFields.push({ field: "ftn_reply", label: "Reply ID:" }); }
hdrInfoLineFields.push({ field: "X-FTN-REPLY", label: "Reply ID:" }); else
hdrInfoLineFields.push({ field: "ftn_area", label: "Area tag:" }); {
hdrInfoLineFields.push({ field: "X-FTN-AREA", label: "Area tag:" }); hdrInfoLinesWrapped.splice(0, 0, "\x01n\x01c\x01hMessage Headers\x01n");
hdrInfoLineFields.push({ field: "ftn_flags", label: "Flags:" }); hdrInfoLinesWrapped.splice(1, 0, "\x01n\x01g\x01h---------------\x01n");
hdrInfoLineFields.push({ field: "ftn_pid", label: "Program ID:" }); }
hdrInfoLineFields.push({ field: "ftn_tid", label: "Tosser ID:" }); }
hdrInfoLineFields.push({ field: "X-FTN-TID", label: "Tosser ID:" }); if (hdrInfoLinesWrapped[hdrInfoLinesWrapped.length-1].length == 0)
hdrInfoLineFields.push({ field: "X-FTN-Kludge", label: "Kludge:" }); hdrInfoLinesWrapped.pop();
hdrInfoLineFields.push({ field: "X-FTN-SEEN-BY", label: "Seen-By:" });
hdrInfoLineFields.push({ field: "X-FTN-PATH", label: "Path:" });
hdrInfoLineFields.push({ field: "when_written_time", label: "When written time:" });
hdrInfoLineFields.push({ field: "when_imported_time", label: "When imported time:" });
} }
   
return hdrInfoLinesWrapped;
}
// For the DDMsgReader class: Helper for GetExtdMsgHdrInfo() - Gets
// text lines for the field_list property in a message header
//
// Parameters:
// pHdrFieldList: The value of the field_list property in a message header
// pUseColors: Boolean - Whether or not to add attribute codes to the lines
//
// Return value: An array with text lines for the field list, with colors
// for displaying message header information
function DigDistMsgReader_GetMsgHdrFieldListText(pHdrFieldList, pUseColors)
{
var textLines = [];
// This function returns the number of non-blank lines in a header info array. // This function returns the number of non-blank lines in a header info array.
// //
// Return value: An object with the following properties: // Return value: An object with the following properties:
...@@ -12648,21 +12867,12 @@ function DigDistMsgReader_GetExtdMsgHdrInfo(pMsgHdr, pKludgeOnly) ...@@ -12648,21 +12867,12 @@ function DigDistMsgReader_GetExtdMsgHdrInfo(pMsgHdr, pKludgeOnly)
return itemCount; return itemCount;
} }
   
// Get the header fields var fieldsAndValues = {};
var addTheField = true;
var customFieldLabel = "";
var propCounter = 1;
for (var prop in msgHdr)
{
addTheField = true;
customFieldLabel = "";
   
if (prop == "field_list")
{
var hdrFieldLabel = ""; var hdrFieldLabel = "";
var lastHdrFieldLabel = null; var lastHdrFieldLabel = null;
var addBlankLineAfterIdx = -1; var addBlankLineAfterIdx = -1;
for (var fieldI = 0; fieldI < msgHdr.field_list.length; ++fieldI) for (var fieldI = 0; fieldI < pHdrFieldList.length; ++fieldI)
{ {
// TODO: Some field types can be in the array multiple times but only // TODO: Some field types can be in the array multiple times but only
// the last is valid. For those, only get the last one: // the last is valid. For those, only get the last one:
...@@ -12673,8 +12883,13 @@ function DigDistMsgReader_GetExtdMsgHdrInfo(pMsgHdr, pKludgeOnly) ...@@ -12673,8 +12883,13 @@ function DigDistMsgReader_GetExtdMsgHdrInfo(pMsgHdr, pKludgeOnly)
// 36 (Reply To extended) // 36 (Reply To extended)
// 37 (Reply To position) // 37 (Reply To position)
// 38 (Reply To Organization) // 38 (Reply To Organization)
hdrFieldLabel = "\x01n" + this.colors.hdrLineLabelColor + msgHdrFieldListTypeToLabel(msgHdr.field_list[fieldI].type) + "\x01n"; if (pUseColors)
var infoLineWrapped = msgHdr.field_list[fieldI].data; hdrFieldLabel = "\x01n" + this.colors.hdrLineLabelColor + msgHdrFieldListTypeToLabel(pHdrFieldList[fieldI].type) + "\x01n";
else
hdrFieldLabel = msgHdrFieldListTypeToLabel(pHdrFieldList[fieldI].type);
hdrFieldLabel = hdrFieldLabel.replace(/\t/g, " ");
fieldsAndValues[hdrFieldLabel] = true; // TODO: Change to the actual text
var infoLineWrapped = pHdrFieldList[fieldI].data;
var infoLineWrappedArray = lfexpand(infoLineWrapped).split("\r\n"); var infoLineWrappedArray = lfexpand(infoLineWrapped).split("\r\n");
var hdrArrayNonBlankLines = findHdrFieldDataArrayNonBlankLines(infoLineWrappedArray); var hdrArrayNonBlankLines = findHdrFieldDataArrayNonBlankLines(infoLineWrappedArray);
if (hdrArrayNonBlankLines.numNonBlankLines > 0) if (hdrArrayNonBlankLines.numNonBlankLines > 0)
...@@ -12682,16 +12897,21 @@ function DigDistMsgReader_GetExtdMsgHdrInfo(pMsgHdr, pKludgeOnly) ...@@ -12682,16 +12897,21 @@ function DigDistMsgReader_GetExtdMsgHdrInfo(pMsgHdr, pKludgeOnly)
if (hdrArrayNonBlankLines.numNonBlankLines == 1) if (hdrArrayNonBlankLines.numNonBlankLines == 1)
{ {
var addExtraBlankLineAtEnd = false; var addExtraBlankLineAtEnd = false;
var hdrItem = "\x01n" + this.colors.hdrLineValueColor + infoLineWrappedArray[hdrArrayNonBlankLines.firstNonBlankLineIdx] + "\x01n"; var hdrItem = "";
if (pUseColors)
hdrItem = "\x01n" + this.colors.hdrLineValueColor + infoLineWrappedArray[hdrArrayNonBlankLines.firstNonBlankLineIdx] + "\x01n";
else
hdrItem = infoLineWrappedArray[hdrArrayNonBlankLines.firstNonBlankLineIdx];
hdrItem = hdrItem.replace(/\t/g, " ");
// If the header field label is different, then add it to the // If the header field label is different, then add it to the
// header info lines // header info lines
if ((lastHdrFieldLabel == null) || (hdrFieldLabel != lastHdrFieldLabel)) if ((lastHdrFieldLabel == null) || (hdrFieldLabel != lastHdrFieldLabel))
{ {
var numFieldItemsWithSameType = fieldListCountSameTypes(msgHdr.field_list, fieldI); var numFieldItemsWithSameType = fieldListCountSameTypes(pHdrFieldList, fieldI);
if (numFieldItemsWithSameType > 1) if (numFieldItemsWithSameType > 1)
{ {
msgHdrInfoLines.push(""); textLines.push("");
msgHdrInfoLines.push(hdrFieldLabel); textLines.push(hdrFieldLabel);
addExtraBlankLineAtEnd = true; addExtraBlankLineAtEnd = true;
addBlankLineAfterIdx = fieldI + numFieldItemsWithSameType - 1; addBlankLineAfterIdx = fieldI + numFieldItemsWithSameType - 1;
} }
...@@ -12701,19 +12921,22 @@ function DigDistMsgReader_GetExtdMsgHdrInfo(pMsgHdr, pKludgeOnly) ...@@ -12701,19 +12921,22 @@ function DigDistMsgReader_GetExtdMsgHdrInfo(pMsgHdr, pKludgeOnly)
numFieldItemsWithSameType = -1; numFieldItemsWithSameType = -1;
} }
} }
if (strip_ctrl(hdrItem).length < this.msgAreaWidth) textLines.push(hdrItem);
msgHdrInfoLines.push(hdrItem); /*
if (console.strlen((hdrItem) < this.msgAreaWidth)
textLines.push(hdrItem);
else else
{ {
// If the header field label is different, then add a blank line // If the header field label is different, then add a blank line
// to the header info lines // to the header info lines
if ((lastHdrFieldLabel == null) || (hdrFieldLabel != lastHdrFieldLabel)) if ((lastHdrFieldLabel == null) || (hdrFieldLabel != lastHdrFieldLabel))
msgHdrInfoLines.push(""); textLines.push("");
msgHdrInfoLines.push(hdrFieldLabel); textLines.push(hdrFieldLabel);
msgHdrInfoLines.push(infoLineWrappedArray[hdrArrayNonBlankLines.firstNonBlankLineIdx]); //textLines.push(infoLineWrappedArray[hdrArrayNonBlankLines.firstNonBlankLineIdx]);
if ((lastHdrFieldLabel == null) || (hdrFieldLabel != lastHdrFieldLabel)) if ((lastHdrFieldLabel == null) || (hdrFieldLabel != lastHdrFieldLabel))
msgHdrInfoLines.push(""); textLines.push("");
} }
*/
} }
else else
{ {
...@@ -12721,165 +12944,158 @@ function DigDistMsgReader_GetExtdMsgHdrInfo(pMsgHdr, pKludgeOnly) ...@@ -12721,165 +12944,158 @@ function DigDistMsgReader_GetExtdMsgHdrInfo(pMsgHdr, pKludgeOnly)
// header info lines // header info lines
if ((lastHdrFieldLabel == null) || (hdrFieldLabel != lastHdrFieldLabel)) if ((lastHdrFieldLabel == null) || (hdrFieldLabel != lastHdrFieldLabel))
{ {
msgHdrInfoLines.push(""); textLines.push("");
msgHdrInfoLines.push(hdrFieldLabel); textLines.push(hdrFieldLabel);
} }
var infoLineWrapped = msgHdr.field_list[fieldI].data; var infoLineWrapped = pHdrFieldList[fieldI].data;
var infoLineWrappedArray = lfexpand(infoLineWrapped).split("\r\n"); var infoLineWrappedArray = lfexpand(infoLineWrapped).split("\r\n");
var preAttrs = pUseColors ? "\x01n" + this.colors.hdrLineValueColor : "";
var postAttrs = pUseColors ? "\x01n" : "";
for (var lineIdx = 0; lineIdx < infoLineWrappedArray.length; ++lineIdx) for (var lineIdx = 0; lineIdx < infoLineWrappedArray.length; ++lineIdx)
{ {
if (infoLineWrappedArray[lineIdx].length > 0) if (infoLineWrappedArray[lineIdx].length > 0)
msgHdrInfoLines.push(infoLineWrappedArray[lineIdx]); textLines.push(preAttrs + infoLineWrappedArray[lineIdx] + postAttrs);
} }
// If the header field label is different, then add a blank line to the // If the header field label is different, then add a blank line to the
// header info lines // header info lines
if ((lastHdrFieldLabel == null) || (hdrFieldLabel != lastHdrFieldLabel)) if ((lastHdrFieldLabel == null) || (hdrFieldLabel != lastHdrFieldLabel))
msgHdrInfoLines.push(""); textLines.push("");
} }
if (addBlankLineAfterIdx == fieldI) if (addBlankLineAfterIdx == fieldI)
msgHdrInfoLines.push(""); textLines.push("");
} }
lastHdrFieldLabel = hdrFieldLabel; lastHdrFieldLabel = hdrFieldLabel;
} }
}
else // For each line, replace tabs with spaces, remove any unprintable characters,
{ // and in case any line has any CRLF characters, split the lines on CRLF
// See if we should add this field for (var i = 0; i < textLines.length; ++i)
addTheField = true;
if (hdrInfoLineFields.length > 0)
{ {
addTheField = false; textLines[i] = textLines[i].replace(/\t/g, " ");
for (var infoLineFieldIdx = 0; infoLineFieldIdx < hdrInfoLineFields.length; ++infoLineFieldIdx) //textLines[i] = textLines[i].replace(/\r|\n/g, "");
var array = textLines[i].split("\r\n");
if (array.length > 1)
{ {
if (prop == hdrInfoLineFields[infoLineFieldIdx].field) textLines[i] = array[0];
for (var array2Idx = 1; array2Idx < array.length; ++array2Idx)
{ {
addTheField = true; if (array[array2Idx].length > 0)
customFieldLabel = hdrInfoLineFields[infoLineFieldIdx].label; textLines.splice(i+array2Idx, 0, array[array2Idx]);
break;
} }
} }
//textLines[i] = textLines[i].replace(/[^\x20-\x7E]/g, ''); // Remove unprintable characters
} }
if (!addTheField)
continue;
   
var propLabel = ""; return textLines;
if (customFieldLabel.length > 0)
propLabel = "\x01n" + this.colors.hdrLineLabelColor + customFieldLabel + "\x01n";
else
{
// Remove underscores from the property for the label
propLabel = prop.replace(/_/g, " ");
// Apply good-looking capitalization to the property label
if ((propLabel == "id") || (propLabel == "ftn tid"))
propLabel = propLabel.toUpperCase();
else if (propLabel == "ftn area")
propLabel = "FTN Area";
else if (propLabel == "ftn pid")
propLabel = "Program ID";
else if (propLabel == "thread id")
propLabel = "Thread ID";
else if (propLabel == "attr")
propLabel = "Attributes";
else if (propLabel == "auxattr")
propLabel = "Auxiliary attributes";
else if (propLabel == "netattr")
propLabel = "Network attributes";
else
propLabel = capitalizeFirstChar(propLabel);
// Add the label color and trailing colon to the label text
propLabel = "\x01n" + this.colors.hdrLineLabelColor + propLabel + ":\x01n";
} }
var infoLineWrapped = word_wrap(msgHdr[prop], this.msgAreaWidth); // Helper for GetExtdMsgHdrInfo() - For the "field_list"
var infoLineWrappedArray = lfexpand(infoLineWrapped).split("\r\n"); // property of a message header, this gathers the field labels & values into an
var itemValue = ""; // object (where the object properties are the labels)
for (var lineIdx = 0; lineIdx < infoLineWrappedArray.length; ++lineIdx) //
// Parameters:
// pHdrFieldArray: The value of the field_list property in a message header
// (this is normally an array of objects containing 'type' and
// 'data' properties)
//
// Return value: An object where the properties are the field labels, and the
// value for each is usually an array of strings
function GetMsgHdrFieldListObj(pHdrFieldArray)
{ {
if (infoLineWrappedArray[lineIdx].length > 0) if (!Array.isArray(pHdrFieldArray))
return {};
// This function returns the number of non-blank lines in a header info array.
//
// Return value: An object with the following properties:
// numNonBlankLines: The number of non-blank lines in the array
// firstNonBlankLineIdx: The index of the first non-blank line
// lastNonBlankLineIdx: The index of the last non-blank line
function findHdrFieldDataArrayNonBlankLines(pHdrArray)
{ {
// Set itemValue to the value that should be displayed var retObj = {
if (typeof(msgHdr[prop]) === "function") // Such as get_rfc822_header numNonBlankLines: 0,
continue; firstNonBlankLineIdx: -1,
else if (prop == "when_written_time") //itemValue = system.timestr(msgHdr.when_written_time); lastNonBlankLineIdx: -1
itemValue = system.timestr(msgHdr.when_written_time) + " " + system.zonestr(msgHdr.when_written_zone); };
else if (prop == "when_imported_time") //itemValue = system.timestr(msgHdr.when_imported_time);
itemValue = system.timestr(msgHdr.when_imported_time) + " " + system.zonestr(msgHdr.when_imported_zone);
else if ((prop == "when_imported_zone") || (prop == "when_written_zone"))
itemValue = system.zonestr(msgHdr[prop]);
else if (prop == "attr")
itemValue = makeMainMsgAttrStr(msgHdr[prop], "None");
else if (prop == "auxattr")
itemValue = makeAuxMsgAttrStr(msgHdr[prop], "None");
else if (prop == "netattr")
itemValue = makeNetMsgAttrStr(msgHdr[prop], "None");
else
itemValue = infoLineWrappedArray[lineIdx];
// Add the value color to the value text
itemValue = "\x01n" + this.colors.hdrLineValueColor + itemValue + "\x01n";
   
var hdrItem = propLabel + " " + itemValue; for (var lineIdx = 0; lineIdx < pHdrArray.length; ++lineIdx)
if (strip_ctrl(hdrItem).length < this.msgAreaWidth)
msgHdrInfoLines.push(hdrItem);
else
{ {
// If this isn't the first header property, then add an empty if (pHdrArray[lineIdx].length > 0)
// line to the info lines array for spacing
if (propCounter > 1)
msgHdrInfoLines.push("");
msgHdrInfoLines.push(propLabel);
// In case the item value is too long to fit into the
// message reading area, split it and add all the split lines.
var itemValueWrapped = word_wrap(itemValue, this.msgAreaWidth);
var itemValueWrappedArray = lfexpand(itemValueWrapped).split("\r\n");
for (var lineIdx2 = 0; lineIdx2 < itemValueWrappedArray.length; ++lineIdx2)
{ {
if (itemValueWrappedArray[lineIdx2].length > 0) ++retObj.numNonBlankLines;
msgHdrInfoLines.push(itemValueWrappedArray[lineIdx2]); if (retObj.firstNonBlankLineIdx == -1)
} retObj.firstNonBlankLineIdx = lineIdx;
retObj.lastNonBlankLineIdx = lineIdx;
// If this isn't the first header property, then add an empty
// line to the info lines array for spacing
if (propCounter > 1)
msgHdrInfoLines.push("");
}
}
} }
} }
   
++propCounter; return retObj;
} }
   
// If some info lines were added, then insert a header line & blank line to var fieldListObj = {};
// the beginning of the array, and remove the last empty line from the array. for (var fieldI = 0; fieldI < pHdrFieldArray.length; ++fieldI)
if (msgHdrInfoLines.length > 0)
{ {
if (kludgeOnly) // TODO: Some field types can be in the array multiple times but only
// the last is valid. For those, only get the last one:
// 32 (Reply To)
// 33 (Reply To agent)
// 34 (Reply To net type)
// 35 (Reply To net address)
// 36 (Reply To extended)
// 37 (Reply To position)
// 38 (Reply To Organization)
var hdrFieldLabel = msgHdrFieldListTypeToLabel(pHdrFieldArray[fieldI].type, false);
hdrFieldLabel = hdrFieldLabel.replace(/\t/g, " ");
// Add the data to fieldListObj, with the label as the property
//fieldListObj[hdrFieldLabel] = pHdrFieldArray[fieldI].data.replace(/\t/g, " ");
// Make the data an array of strings, split based on CRLF characters
var infoLineWrappedArray = lfexpand(pHdrFieldArray[fieldI].data).replace(/\t/g, " ").split("\r\n");
// If any of the strings starts with a date/time ("WhenExported" or "WhenImported"),
// then format it so that the date & time are more readable
for (var i = 0; i < infoLineWrappedArray.length; ++i)
{
if ((infoLineWrappedArray[i].indexOf("WhenExported") == 0 || infoLineWrappedArray[i].indexOf("WhenImported") == 0) && infoLineWrappedArray[i].length >= 28)
{ {
msgHdrInfoLines.splice(0, 0, "\x01n\x01c\x01hMessage Information/Kludge Lines\x01n"); //system.timestr(msgHdr.when_imported_time) + " " + system.zonestr(msgHdr.when_imported_zone)
msgHdrInfoLines.splice(1, 0, "\x01n\x01g\x01h--------------------------------\x01n"); var firstPart = infoLineWrappedArray[i].substr(0, 14);
var yearStr = infoLineWrappedArray[i].substr(14, 4);
var monthStr = infoLineWrappedArray[i].substr(18, 2);
var dayStr = infoLineWrappedArray[i].substr(20, 2);
var hourStr = infoLineWrappedArray[i].substr(22, 2);
var minStr = infoLineWrappedArray[i].substr(24, 2);
var secStr = infoLineWrappedArray[i].substr(26, 2);
var remaining = infoLineWrappedArray[i].substr(28);
infoLineWrappedArray[i] = format("%s%s-%s-%s %s:%s:%s %s", firstPart, yearStr, monthStr, dayStr, hourStr, minStr, secStr, remaining);
} }
}
if (!fieldListObj.hasOwnProperty(hdrFieldLabel))
fieldListObj[hdrFieldLabel] = infoLineWrappedArray;
else else
{ {
msgHdrInfoLines.splice(0, 0, "\x01n\x01c\x01hMessage Headers\x01n"); // Append to the data already there
msgHdrInfoLines.splice(1, 0, "\x01n\x01g\x01h---------------\x01n"); fieldListObj[hdrFieldLabel].push("");
for (var i = 0; i < infoLineWrappedArray.length; ++i)
fieldListObj[hdrFieldLabel].push(infoLineWrappedArray[i]);
} }
if (msgHdrInfoLines[msgHdrInfoLines.length-1].length == 0)
msgHdrInfoLines.pop();
} }
   
// Make sure the header lines aren't too long for the user's terminal. return fieldListObj;
// Leave a column for the scrollbar.
var maxLen = console.screen_columns - 1;
var hdrInfoLinesWrapped = [];
for (var i = 0; i < msgHdrInfoLines.length; ++i)
{
var wrappedLines = word_wrap(msgHdrInfoLines[i], maxLen).split("\n");
for (var wrappedI = 0; wrappedI < wrappedLines.length; ++wrappedI)
{
if (console.strlen(wrappedLines[wrappedI]) > 0)
hdrInfoLinesWrapped.push(wrappedLines[wrappedI]);
}
} }
return hdrInfoLinesWrapped;
// Returns whether a message header property name can be considered a "kludge line"
function MsgHdrPropIsKludgeLine(pPropName)
{
if (typeof(pPropName) !== "string" || pPropName.length == 0)
return false;
var propNameUpper = pPropName.toUpperCase();
return (propNameUpper == "FTN_MSGID" || propNameUpper == "X-FTN-MSGID" || propNameUpper == "FTN_REPLY" ||
propNameUpper == "X-FTN-REPLY" || propNameUpper == "FTN_AREA" || propNameUpper == "X-FTN-AREA" ||
propNameUpper == "FTN_FLAGS" || propNameUpper == "FTN_PID" || propNameUpper == "FTN_TID" ||
propNameUpper == "X-FTN-TID" || propNameUpper == "X-FTN-KLUDGE" ||
propNameUpper == "X-FTN-SEEN-BY" || propNameUpper == "X-FTN-PATH" ||
propNameUpper == "WHEN_WRITTEN_TIME" || propNameUpper == "WHEN_IMPORTED_TIME");
} }
   
// For the DigDistMsgReader class: Gets & prepares message information for // For the DigDistMsgReader class: Gets & prepares message information for
...@@ -14666,32 +14882,15 @@ function DigDistMsgReader_SaveMsgToFile(pMsgHdr, pFilename) ...@@ -14666,32 +14882,15 @@ function DigDistMsgReader_SaveMsgToFile(pMsgHdr, pFilename)
if (msgbase.open()) if (msgbase.open())
{ {
var msgBody = msgbase.get_msg_body(false, pMsgHdr.number, false, false, true, true); var msgBody = msgbase.get_msg_body(false, pMsgHdr.number, false, false, true, true);
var hdrLines = this.GetExtdMsgHdrInfo(msgbase, pMsgHdr.number, false, false, false, false);
msgbase.close(); msgbase.close();
   
var messageSaveFile = new File(pFilename); var messageSaveFile = new File(pFilename);
if (messageSaveFile.open("w")) if (messageSaveFile.open("w"))
{ {
// Write some header information to the file // Write the header information to the file
if (pMsgHdr.hasOwnProperty("from")) for (var i = 0; i < hdrLines.length; ++i)
messageSaveFile.writeln("From: " + pMsgHdr.from); messageSaveFile.writeln(hdrLines[i]);
if (pMsgHdr.hasOwnProperty("to"))
messageSaveFile.writeln(" To: " + pMsgHdr.to);
if (pMsgHdr.hasOwnProperty("subject"))
messageSaveFile.writeln("Subj: " + pMsgHdr.subject);
/*
if (pMsgHdr.hasOwnProperty("when_written_time"))
messageSaveFile.writeln(strftime("Date: %Y-%m-%d %H:%M:%S", msgHeader.when_written_time));
*/
if (pMsgHdr.hasOwnProperty("date"))
messageSaveFile.writeln("Date: " + pMsgHdr.date);
if (pMsgHdr.hasOwnProperty("from_net_addr"))
messageSaveFile.writeln("From net address: " + pMsgHdr.from_net_addr);
if (pMsgHdr.hasOwnProperty("to_net_addr"))
messageSaveFile.writeln("To net address: " + pMsgHdr.to_net_addr);
if (pMsgHdr.hasOwnProperty("id"))
messageSaveFile.writeln("ID: " + pMsgHdr.id);
if (pMsgHdr.hasOwnProperty("reply_id"))
messageSaveFile.writeln("Reply ID: " + pMsgHdr.reply_id);
messageSaveFile.writeln("==============================="); messageSaveFile.writeln("===============================");
   
// If the message body has ANSI, then use the Graphic object to strip it // If the message body has ANSI, then use the Graphic object to strip it
...@@ -18302,102 +18501,54 @@ function quoteStrWithSpaces(pStr) ...@@ -18302,102 +18501,54 @@ function quoteStrWithSpaces(pStr)
// Return value: A text label for the field (a string) // Return value: A text label for the field (a string)
function msgHdrFieldListTypeToLabel(pFieldListType, pIncludeTrailingColon) function msgHdrFieldListTypeToLabel(pFieldListType, pIncludeTrailingColon)
{ {
// The page at this URL lists the header field types: var fieldTypeLabel = "";
// http://synchro.net/docs/smb.html#Header Field Types:
var fieldTypeLabel = "Unknown (" + pFieldListType.toString() + ")";
switch (pFieldListType) switch (pFieldListType)
{ {
case 0: // Sender case SMB_COMMENT:
fieldTypeLabel = "Sender"; fieldTypeLabel = "Comment";
break; break
case 1: // Sender Agent case SMB_POLL_ANSWER:
fieldTypeLabel = "Sender Agent"; fieldTypeLabel = "Poll answer";
break;
case 2: // Sender net type
fieldTypeLabel = "Sender Net Type";
break;
case 3: // Sender Net Address
fieldTypeLabel = "Sender Net Address";
break;
case 4: // Sender Agent Extension
fieldTypeLabel = "Sender Agent Extension";
break;
case 5: // Sending agent (Sender POS)
fieldTypeLabel = "Sender Agent";
break;
case 6: // Sender organization
fieldTypeLabel = "Sender Organization";
break; break;
case 16: // Author case 0x64: // SMB_GROUP
fieldTypeLabel = "Author"; fieldTypeLabel = "Group";
break; break;
case 17: // Author Agent case FIDOCTRL:
fieldTypeLabel = "Author Agent"; fieldTypeLabel = "FIDO control";
break; break;
case 18: // Author Net Type case FIDOSEENBY:
fieldTypeLabel = "Author Net Type"; fieldTypeLabel = "Seen-by";
break;
case 19: // Author Net Address
fieldTypeLabel = "Author Net Address";
break;
case 20: // Author Extension
fieldTypeLabel = "Author Extension";
break;
case 21: // Author Agent (Author POS)
fieldTypeLabel = "Author Agent";
break;
case 22: // Author Organization
fieldTypeLabel = "Author Organization";
break;
case 32: // Reply To
fieldTypeLabel = "Reply To";
break;
case 33: // Reply To agent
fieldTypeLabel = "Reply To Agent";
break;
case 34: // Reply To net type
fieldTypeLabel = "Reply To net type";
break;
case 35: // Reply To net address
fieldTypeLabel = "Reply To net address";
break; break;
case 36: // Reply To extension case FIDOPATH:
fieldTypeLabel = "Reply To (extended)"; fieldTypeLabel = "FIDO Path";
break; break;
case 37: // Reply To position case RFC822HEADER:
fieldTypeLabel = "Reply To position"; fieldTypeLabel = "RFCC822 Header";
break; break;
case 38: // Reply To organization (0x26 hex) case 0xB3: // RFC822TO
fieldTypeLabel = "Reply To organization"; fieldTypeLabel = "RFC822 To";
break; break;
case 48: // Recipient (0x30 hex) case 0xB6: // RFC822CC
fieldTypeLabel = "Recipient"; fieldTypeLabel = "RFC822 CC";
break; break;
case 162: // Seen-by case 0xB7: // RFC822ORG
fieldTypeLabel = "Seen-by"; fieldTypeLabel = "RFC822 Org";
break; break;
case 163: // Path case 0xB4: // RFC822FROM
fieldTypeLabel = "Path"; fieldTypeLabel = "RFC822 From";
break; break;
case 176: // RFCC822 Header case 0xB5: // RFC822REPLYTO
fieldTypeLabel = "RFCC822 Header"; fieldTypeLabel = "RFC822 Reply To";
break; break;
case 177: // RFC822 MSGID case 0xB8: // RFC822SUBJECT
fieldTypeLabel = "RFC822 MSGID"; fieldTypeLabel = "RFC822 Subject";
break; break;
case 178: // RFC822 REPLYID case SMTPRECEIVED:
fieldTypeLabel = "RFC822 REPLYID"; fieldTypeLabel = "SMTP Received";
break; break;
case 240: // UNKNOWN case 0xF1: // UNKNOWNASCII
fieldTypeLabel = "UNKNOWN";
break;
case 241: // UNKNOWNASCII
fieldTypeLabel = "UNKNOWN (ASCII)"; fieldTypeLabel = "UNKNOWN (ASCII)";
break; break;
case 255:
fieldTypeLabel = "UNUSED";
break;
default: default:
fieldTypeLabel = "Unknown (" + pFieldListType.toString() + ")"; fieldTypeLabel = "Unknown (" + pFieldListType.toString() + ")";
break; break;
...@@ -21700,6 +21851,7 @@ function clearScreenRectangle(pX, pY, pWidth, pHeight) ...@@ -21700,6 +21851,7 @@ function clearScreenRectangle(pX, pY, pWidth, pHeight)
} }
} }
   
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
   
// For debugging: Writes some text on the screen at a given location with a given pause. // For debugging: Writes some text on the screen at a given location with a given pause.
......
Digital Distortion Message Reader Digital Distortion Message Reader
Version 1.73 Version 1.73a
Release date: 2023-04-17 Release date: 2023-04-25
by by
......
...@@ -5,6 +5,9 @@ Revision History (change log) ...@@ -5,6 +5,9 @@ Revision History (change log)
============================= =============================
Version Date Description Version Date Description
------- ---- ----------- ------- ---- -----------
1.73a 2023-04-25 For viewing message headers, now all message header
information is displayed & sorted alphabetically by field
name (same with saving a message to a file).
1.73 2023-04-17 Bug fix: When getting header lines to view, ensure the 1.73 2023-04-17 Bug fix: When getting header lines to view, ensure the
header lines are not too wide for the user's terminal. header lines are not too wide for the user's terminal.
Header lines that are too long will be split into no more Header lines that are too long will be split into no more
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment