MozillaZine

Accessing MsgHdr Values

Talk about add-ons and extension development.
dataspace
 
Posts: 7
Joined: June 17th, 2019, 7:14 am

Post Posted June 25th, 2019, 11:43 am

What would the best way to read in the encoded/plaintext string of the "content-type" value in the header for a message? The nsIMsgDBHdr interface doesn't contain a specific method to retrieve this value, and using getStringProperty doesn't seem to retrieve it, as
Code: Select all
   console.log(msgHdr.getStringProperty("content-type"));

just logs an empty line, although I could definitely be using it wrong. Is there another method for this in the nsIMsgDBHdr interface, or would it be possible to read in the decoded MIME header as a stream, and then parse it line by line?

Thanks so much! Sorry for the double post so soon.

morat
 
Posts: 3439
Joined: February 3rd, 2009, 6:29 pm

Post Posted June 25th, 2019, 12:18 pm

Try these:

Code: Select all
alert(currentHeaderData["content-type"].headerValue);

Code: Select all
var msgHdr = gFolderDisplay.selectedMessage;
var msgUri = msgHdr.folder.getUriForMsg(msgHdr);
var msgService = messenger.messageServiceFromURI(msgUri);
var scriptableInputStream = Components.classes["@mozilla.org/scriptableinputstream;1"].
  createInstance(Components.interfaces.nsIScriptableInputStream);
var syncStreamListener = Components.classes["@mozilla.org/network/sync-stream-listener;1"].
  createInstance(Components.interfaces.nsISyncStreamListener);
scriptableInputStream.init(syncStreamListener);
var messageUri = msgService.streamHeaders(msgUri, syncStreamListener, null /*urlListener*/);
var data = new String();
var count = scriptableInputStream.available();
while (count) {
  data = data + scriptableInputStream.read(count);
  count = scriptableInputStream.available();
}
scriptableInputStream.close();
var re = new RegExp("Content-Type: (.*)");
var m = data.match(re);
var header = m && m[1];
alert(header);

P.S.

Here is how to show the properties of the selected message.

Code: Select all
var msgHdr = gFolderDisplay.selectedMessage;
var properties = msgHdr.propertyEnumerator;
var out = new Array();
while (properties.hasMore()) {
  var property = properties.getNext();
  out.push(property);
}
alert(out.join("\n"));

dataspace
 
Posts: 7
Joined: June 17th, 2019, 7:14 am

Post Posted June 26th, 2019, 7:42 am

Thanks for the reply! This is exactly what I was trying to find. As a followup, how do we access the currentHeaderData var given a selected msgHdr? Additionally, the content-type doesn't show up in the printed array of properties. Is there DB query/modification possible to change that?

morat
 
Posts: 3439
Joined: February 3rd, 2009, 6:29 pm

Post Posted June 26th, 2019, 10:59 am

If you want the header from a random message, then use the stream listener.

The currentHeaderData object stores the header of the current message.

dataspace
 
Posts: 7
Joined: June 17th, 2019, 7:14 am

Post Posted June 27th, 2019, 7:54 am

Streaming the message successfully retrieved the content type. Thanks so much!

dataspace
 
Posts: 7
Joined: June 17th, 2019, 7:14 am

Post Posted July 11th, 2019, 8:04 am

A quick followup about scriptable input streams: when implemented with the selected message header (var msgHdr = gFolderDisplay.selectedMessage), the stream works without error and prints the correct values. However, when implemented with the message header for the incoming message (var newMsgHdr = item.QueryInterface(Components.interfaces.nsIMsgDBHdr)), the stream times out on the line

Code: Select all
var count = scriptableInputStream.available();

Upon logging both objects for debugging, the objects are displayed as having the same properties in the sidebar, but the raw text differs slightly:

For the selected message header:
XPCWrappedNative_NoHelper { flags: Getter, folder: Getter, recipients: Getter, ccList: Getter, messageKey: Getter, getStringProperty: getStringProperty(), label: Getter, author: Getter, isRead: Getter, messageId: Getter, 40 more… }

vs. for the incoming message header:
XPCWrappedNative_NoHelper { QueryInterface: QueryInterface(), getProperty: getProperty(), setProperty: setProperty(), setStringProperty: setStringProperty(), getStringProperty: getStringProperty(), getUint32Property: getUint32Property(), setUint32Property: setUint32Property(), isRead: Getter, isFlagged: Getter, isKilled: Getter, 40 more… }

The nsIMsgDBHdr getter methods work for both objects, so I'm not sure why the input stream available() method times out when trying to fetch the bytes of the second message. My suspicion is that the different functions that return them wrapped in slightly different ways, but beyond that, I'm stumped. Any ideas as to why this might be happening or what the fix could be?

morat
 
Posts: 3439
Joined: February 3rd, 2009, 6:29 pm

Post Posted July 15th, 2019, 6:46 am

Try this:

Code: Select all
- scriptableInputStream.init(syncStreamListener);
+ scriptableInputStream.init(syncStreamListener.inputStream);

Code: Select all
- var data = new String();
- var count = scriptableInputStream.available();
- while (count) {
-   data = data + scriptableInputStream.read(count);
-   count = scriptableInputStream.available();
- }
+ const MAX_MESSAGE_LENGTH = 65536;
+ var data = scriptableInputStream.read(MAX_MESSAGE_LENGTH);

i.e.

Code: Select all
var msgHdr = gFolderDisplay.selectedMessage;
var msgUri = msgHdr.folder.getUriForMsg(msgHdr);
var msgService = messenger.messageServiceFromURI(msgUri);
var scriptableInputStream = Components.classes["@mozilla.org/scriptableinputstream;1"].
  createInstance(Components.interfaces.nsIScriptableInputStream);
var syncStreamListener = Components.classes["@mozilla.org/network/sync-stream-listener;1"].
  createInstance(Components.interfaces.nsISyncStreamListener);
scriptableInputStream.init(syncStreamListener.inputStream);
var messageUri = msgService.streamHeaders(msgUri, syncStreamListener, null /*urlListener*/);
const MAX_MESSAGE_LENGTH = 65536;
var data = scriptableInputStream.read(MAX_MESSAGE_LENGTH);
scriptableInputStream.close();
var re = new RegExp("Content-Type: (.*)");
var m = data.match(re);
var header = m && m[1];
alert(header);

Reference
http://dxr.mozilla.org/comm-release/source/mailnews/base/public/nsIMsgMessageService.idl (streamMessage and streamHeaders methods)
http://dxr.mozilla.org/comm-release/search?q=nsISyncStreamListener+ext%3Ajs (nsISyncStreamListener examples)
http://dxr.mozilla.org/comm-release/source/mail/config/version.txt

You could try passing true for the streamHeaders method optional aLocalOnly param if the headers are in the offline store.

Return to Extension Development


Who is online

Users browsing this forum: No registered users and 1 guest