基于Mozilla ThunderBird的扩展开发(三)---如何获取邮件的完整信息

 

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

20080506.bmp

Mozilla扩展系列链接:

1浅谈基于MozillaThunderBird的扩展开发

2基于Mozilla平台的扩展开发(续)----XPCOM组件篇

3基于Mozilla ThunderBird的扩展开发(三)---如何获取邮件的完整信息

 


    如果你没有读过 ThunderBird 的源代码,也许会和我一样想当然地认为里面肯定有某个数据结构用于存储邮件的正文和附件等信息,但如果你读过了代码,那么也会和我一样感到遗憾,居然没有这样完整的数据结构!里面有一个表示邮件头的 XPCOM 组件 nsIMsgHdr mozilla 这帮人却没有定义一个用来表示邮件(包括邮件头,正文,附件等信息)的组件 ” nsIMsg” 呢,问题更进一步,你会发现它里面采用了一个 gDBView, 一个 msgWindow, 这两个对象的具体含义这里就不多说了,反正是让我们想获取到邮件的完整信息这件事更加困难了。

      好的,那我现在就要结合自己的实际开发讲解下如何去获取指定邮件的完整信息了,let’s go!


      首先要明确的是你要获取的邮件是离线的(存储在本地)还是在线的(在服务器上),要实现这个判断,我们可以用如下代码:

ExpandedBlockStart.gif ContractedBlock.gif if  (mail.folder.hasMsgOffline(mail.messageKey))  dot.gif {
InBlock.gif       readOffline(mail);
//从本地读
ExpandedBlockStart.gifContractedBlock.gif
   }
  else   dot.gif {
InBlock.gif       readOnline(mail);
//从服务器读
ExpandedBlockEnd.gif
   }
 
None.gif

      如果邮件在本地,我们可以直接让它所在的文件夹给我们一个代表整个邮件的输入流对象,要完成这个工作,你得创建一个nsIInputStream,它的作用是用来包含邮件信息,nsIMsgFoldergetOfflineFileStream方法可以返回这样一个流对象,这个方法有一个输入参数(表示邮件key,两个输出参数.

ExpandedBlockStart.gif ContractedBlock.gif function  readOffline(mail)  dot.gif {
InBlock.gif        
var key = mail.messageKey;
InBlock.gif        
var offset = new Object();
InBlock.gif        
var messageSize = new Object();
InBlock.gif        
var is;
          var bodyAndHdr;

ExpandedSubBlockStart.gifContractedSubBlock.gif        
trydot.gif{ is = mail.folder.getOfflineFileStream(key,offset,messageSize); }
ExpandedSubBlockStart.gifContractedSubBlock.gif        
catch(e)dot.gif{ alert("message: "+e.message); }
ExpandedSubBlockStart.gifContractedSubBlock.gif        
trydot.gif{
InBlock.gif            
var sis = factory.createInstance(
InBlock.gif                Components.interfaces.nsIScriptableInputStream
InBlock.gif            );
InBlock.gif            sis.init(is);
InBlock.gif            
 bodyAndHdr = sis.read(mail.messageSize);
               sis.close();
               is.close();
ExpandedSubBlockStart.gifContractedSubBlock.gif       
             }
 catch(e)dot.gif{ alert("message: "+e.message); }
InBlock.gif        doSomethingWith(bodyAndHdr);
ExpandedBlockEnd.gif    }

None.gif

      如果你要在线读取邮件,那就有点复杂了,因为你得让IMAP服务器端告诉你邮件的信息,而这是一个异步的事件,也就是你发出指令,然后等待来自服务器的反馈信息。因此你得监听来自服务器端的反馈信息。

      首先,我们获取邮件的URI,这可以通过其所在的文件夹获得,然后我们查找邮件服务提供者---IMAP,POP等,让它来处理邮件信息:

ExpandedBlockStart.gif ContractedBlock.gif function  readOnline(folder, mail)  dot.gif {
InBlock.gif        
var key = mail.messageKey;
InBlock.gif        
var uri = mail.folder.generateMessageURI(key);
InBlock.gif        
var messenger = Components.classes['@mozilla.org/messenger;1']
InBlock.gif                        .createInstance();
InBlock.gif        messenger 
= messenger.QueryInterface(
InBlock.gif                        Components.interfaces.nsIMessenger
InBlock.gif                    );
ExpandedBlockEnd.gif        
var messageService = messenger.messageServiceFromURI(uri);//邮件服务提供者

None.gif

   ok,现在我们已经有一个处理邮件URI的邮件服务提供者了,接下来就可以通过它一个方法CopyMessage来从服务器端获取邮件了,并且可以将邮件放入一个输入流中,从而使得我们可以传入一个nsIStreamListener来监听这个输入流是否有数据到来。

None.gif var  aurl  =   new  Object();
None.gif        messageService.CopyMessage(uri,
None.gif            myStreamListener, 
false null , msgWindow, aurl);
None.gif    }
None.gif

   输入流监听器会负责处理来自服务器端的数据的:

ExpandedBlockStart.gif ContractedBlock.gif var  myStreamListener  =   dot.gif {
InBlock.gif         onDataAvailable: 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
function(request, context, inputStream, offset, count)dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif                
try dot.gif{
InBlock.gif                    
var sis= Components.
InBlock.gif                             classes[
"@mozilla.org/scriptableinputstream;1"]
InBlock.gif                             .createInstance(
InBlock.gif                                Components.interfaces.nsIScriptableInputStream
InBlock.gif                             );
InBlock.gif                    sis.init(inputStream);
InBlock.gif                    bodyAndHdr 
+= sis.read(count);
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockStart.gifContractedSubBlock.gif                
catch(ex) dot.gif{ alert("exception caught: "+ex.message+"\n"); }
ExpandedSubBlockEnd.gif         }
,
ExpandedSubBlockStart.gifContractedSubBlock.gif         onStartRequest: 
function(request, context) dot.gif{ },
ExpandedSubBlockStart.gifContractedSubBlock.gif         onStopRequest: 
function(aRequest, aContext, aStatusCode) dot.gif{
InBlock.gif             doSomethingWith(bodyAndHdr);
ExpandedSubBlockEnd.gif         }

ExpandedBlockEnd.gif    }
;
None.gif

onDataAvailable函数会一直被调用,直到服务器告诉我们已经拿到整个邮件的信息了,此时,onStopRequest就会被调用,从而让我们开始处理邮件信息。

     

   好了,这样我们就可以取得邮件的完整信息了,接下来要做的就是对邮件的解析了,这个我还在研究,以后有机会再和大家分享心得。

附:还有另外一种思路可以获取邮件的正文信息,有时间我再写篇文章介绍。

 

 Reference:

1http://simon-cozens.org:81/programmer/articles/thunderbird-js.pod

2http://thunderbirddocs.blogspot.com/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值