Discuz! Board

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 3130|回复: 5
打印 上一主题 下一主题

imap草稿箱相关逻辑

[复制链接]

388

主题

602

帖子

2218

积分

金牌会员

Rank: 6Rank: 6

积分
2218
跳转到指定楼层
楼主
发表于 2016-4-8 20:59:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 hechengjin 于 2016-4-8 21:30 编辑

1.编辑草稿协议跟踪  红色为客户端发送  蓝色为服务器返回
a.追加一封邮件

6 append "&g0l6P1k5-" (\Draft) {1144}
+ Ready for argument
FCC: imap://bolttest2%40sina.com@imap.sina.com/&XfJT0ZAB-
X-Identity-Key: id1
X-Account-Key: id1
From: =?UTF-8?B?SEVDSEVOR0pJTiBb5L2V5oiQ6L+bXQ==?= <test2@sina.com>
To: xxx1@firemail.cn
Cc: xxx2@kingsoft.com
Subject: 2
Message-ID: <5707A8D5.6090506@sina.com>
Date: Fri, 8 Apr 2016 20:49:25 +0800
X-Mozilla-Draft-Info: internal/draft; vcard=0; receipt=0; DSN=0; uuencode=0;
attachmentreminder=0
MIME-Version: 1.0
Content-Type: multipart/alternative;
boundary="------------050306010304050604070800"


This is a multi-part message in MIME format.


--------------050306010304050604070800
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit


2


- .........FIREMAIL...... -


--------------050306010304050604070800
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 8bit


<html><body><span style="font-family:SimSun;"><span style="font-size:14px;"><span style="color:#000000;"><span style="background-color:#FFFFFF;">2<br></span></span></span></span><pre class="moz-signature">- .........FIREMAIL...... -</pre></body></html>


--------------050306010304050604070800--

* 2 EXISTS
* 1 RECENT
6 OK APPEND completed



b.  获取新追加的草稿的状态标志
9 UID fetch 125:* (FLAGS)                                        //125是根据上面的124计算出来的
* 2 FETCH (UID 125 FLAGS (\Draft))                         //即UID为125的标记为草稿状态的未读邮件(因为不包含\Seen标志)9 OK UID FETCH completed

c.获取邮件头信息
10 UID fetch 125 (UID RFC822.SIZE FLAGS BODY.PEEK[HEADER.FIELDS (From To Cc Bcc Subject Date Message-ID Priority X-Priority References Newsgroups In-Reply-To Content-Type Reply-To)])
* 1 FETCH (UID 125 RFC822.SIZE 1339 FLAGS (\Draft) BODY[HEADER.FIELDS (FROM TO CC BCC SUBJECT DATE MESSAGE-ID PRIORITY X-PRIORITY REFERENCES NEWSGROUPS IN-REPLY-TO CONTENT-TYPE REPLY-TO)] {306}
From: =?UTF-8?B?SEVDSEVOR0pJTiBb5L2V5oiQ6L+bXQ==?= <bolttest2@sina.com>
To: hechengjin@wps.cn
Cc: hechengjin@kingsoft.com
Subject: 2
Message-ID: <5707A8D5.6090506@sina.com>
Date: Fri, 8 Apr 2016 20:49:25 +0800
Content-Type: multipart/alternative;
boundary="------------050306010304050604070800"


)
10 OK UID FETCH completed

d.标志此邮件为已读

13 uid store 125 +Flags (\Seen)
* 2 FETCH (UID 125 FLAGS (\Seen \Draft))
* 0 RECENT
13 OK UID STORE completed



上面没有发现从服务器拉取正文的过程,但客户端却已经显示了正文?  正文中如果有字段不对(多了抄送等),则只与本地处理保存时有关

而保存下一封草稿时,又会获取上一封的正文,这之后,上一封的正文就显示正确了和服务器上的一致了

如下获取一个邮件的正文


37 UID fetch 127 (UID RFC822.SIZE BODY.PEEK[])
* 2 FETCH (UID 127 RFC822.SIZE 1313 BODY[] {1118}
FCC: imap://bolttest2%40sina.com@imap.sina.com/&XfJT0ZAB-
X-Identity-Key: id1
X-Account-Key: id1
From: =?UTF-8?B?SEVDSEVOR0pJTiBb5L2V5oiQ6L+bXQ==?= <test2@sina.com>
To: xxxx@wps.cn
Subject: 22
Message-ID: <5707AF42.2000701@sina.com>
Date: Fri, 8 Apr 2016 21:16:50 +0800
X-Mozilla-Draft-Info: internal/draft; vcard=0; receipt=0; DSN=0; uuencode=0;
attachmentreminder=0
MIME-Version: 1.0
Content-Type: multipart/alternative;
boundary="------------040206020607050109080409"


This is a multi-part message in MIME format.


--------------040206020607050109080409
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit


22


- .........Firemail...... -


--------------040206020607050109080409
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 8bit


<html><body><span style="font-family:SimSun;"><span style="font-size:14px;"><span style="color:#000000;"><span style="background-color:#FFFFFF;">22<br></span></span></span></span><pre class="moz-signature">- .........Firemail...... -</pre></body></html>


--------------040206020607050109080409--
)
37 OK UID FETCH completed






回复

使用道具 举报

388

主题

602

帖子

2218

积分

金牌会员

Rank: 6Rank: 6

积分
2218
沙发
 楼主| 发表于 2016-4-8 21:33:40 | 只看该作者
本帖最后由 hechengjin 于 2016-4-8 22:00 编辑

在同步服务器上草稿之前,本地存草稿的处理compose.html
id="saveDraftButton"
compose.js
  1. function saveDraft (event) {
  2.   sendEmail(null, Ci.nsIMsgCompDeliverMode.SaveAsDraft)
  3.   if (gSendStatus) {
  4.     gEditorContentChanged = false
  5.     gComposeHeaderChanged = false
  6.     attachmentOperation.setAttachmentChanged(false)
  7.   }
  8. }
复制代码
  1. function sendEmail (event, deliverMode = Ci.nsIMsgCompDeliverMode.Now) {  // SaveAsDraft
  2.   spawn(function * () {
  3.     genericSendEmail(composeWindow, deliverMode)
  4.     gSendStatus = true
  5.   })
  6. }
复制代码
  1. function genericSendEmail (composeWindow, deliverMode) {
  2.   let editIframe = document.querySelector('.ke-edit-iframe')
  3.   let sendListener = {
  4.     QueryInterface: XPCOMUtils.generateQI([
  5.       Ci.nsIMsgSendListener,
  6.       Ci.nsISupports
  7.     ]),
  8.     onStopSending: function (aMsgID, aStatus, aMsg, aReturnFile) {
  9.       if (aStatus === 0) {
  10.         if (composeWindow) {
  11.           composeWindow.close()
  12.         }
  13.       } else {
  14.         windowActions.show.call(top)
  15.       }
  16.     }
  17.   }

  18.   let stateListener = {
  19.     QueryInterface: XPCOMUtils.generateQI([
  20.       Ci.nsIMsgComposeStateListener,
  21.       Ci.nsISupports
  22.     ]),
  23.     SaveInFolderDone: function (aFolderName) {
  24.       // Resume savedraft button.
  25.       document.querySelector('#saveDraftButton').onclick = saveDraft
  26.     },
  27.     ComposeProcessDone: function (aResult) {
  28.       if (aResult !== 0) {
  29.         windowActions.show.call(top)
  30.       }
  31.     }
  32.   }
  33.   let params = top.params
  34.   let draftId = params.composeFields.draftId
  35.   if (gMsgCompose) {
  36.     draftId = gMsgCompose.compFields.draftId
  37.   // TODO, update gSendMsgHdrList
  38.   }
  39.   let sendParams = {
  40.     to: getToList(),
  41.     cc: getCcList(),
  42.     bcc: getBccList(),
  43.     subject: getSubject(),
  44.     identity: getSelectedIdentity(),
  45.     attachments: attachmentOperation.getAttachments(),
  46.     draftId: draftId,
  47.     hdrs: gSendMsgHdrList
  48.   }

  49.   if (deliverMode === Ci.nsIMsgCompDeliverMode.Now ||
  50.     deliverMode === Ci.nsIMsgCompDeliverMode.Later ||
  51.     deliverMode === Ci.nsIMsgCompDeliverMode.Background) {
  52.     windowActions.hide.call(top)
  53.   }
  54.   gMsgCompose = MailServices.send.sendMessage(sendParams,
  55.     {
  56.       deliverType: deliverMode,
  57.       compType: gComposeType
  58.     }, {
  59.       match: function (x) {
  60.         x.editor(editIframe)
  61.       }
  62.     }, {
  63.       progressListener: null,
  64.       sendListener: sendListener,
  65.       stateListener: stateListener
  66.     }, {
  67.       msgWindow: MailServices.msgWindow,
  68.       popOut: popOut,
  69.       archive: archive
  70.     }
  71.   )
  72. }
复制代码
当服务器上的邮件头下载后,与本地的伪邮件头对比后,触发msgKeyChanged事件

回复 支持 反对

使用道具 举报

388

主题

602

帖子

2218

积分

金牌会员

Rank: 6Rank: 6

积分
2218
板凳
 楼主| 发表于 2016-4-9 17:59:46 | 只看该作者
跟踪下面smtp过程,问题应该不在smtp,而在imap

  1.   
  2.   
  3.   
  4.   XPCOMUtils.jsm
  5.   
  6.    defineLazyGetter: function XPCU_defineLazyGetter(aObject, aName, aLambda)  // aName:'send'
  7.   {
  8.     Object.defineProperty(aObject, aName, {
  9.       get: function () {
  10.         delete aObject[aName];
  11.         return aObject[aName] = aLambda.apply(aObject);
  12.       },
  13.       configurable: true,
  14.       enumerable: true
  15.     });
  16.   },
  17.   
  18.   
  19.   
  20.   MailServices.js
  21.   
  22. XPCOMUtils.defineLazyGetter(MailServices, 'send', function () {
  23.   return Cu.import('resource://conversations/modules/stdlib/send.js', {})
  24. })


  25. src\app\conversations\modules\stdlib\send.js
  26. function sendMessage(aParams,
  27.     { deliverType, compType },
  28.     aBody,
  29.     { progressListener, sendListener, stateListener },
  30.     options) {
  31.     let popOut = options && options.popOut; // false
  32.     let fields = Cc["@mozilla.org/messengercompose/composefields;1"]
  33.                   .createInstance(Ci.nsIMsgCompFields);
  34.     if ("cc" in aParams)
  35.       fields.cc = aParams.cc;
  36.     lds.fcc = defaultFcc;  
  37.     console.log('-------------compType',compType) //New 0 https://dxr.mozilla.org/comm-central/source/mailnews/compose/public/nsIMsgComposeParams.idl#16
  38.    
  39.    
  40.     let params = Cc["@mozilla.org/messengercompose/composeparams;1"]
  41.                   .createInstance(Ci.nsIMsgComposeParams);
  42.     params.composeFields = fields;
  43.     params.identity = identity;
  44.     params.type = compType;
  45.     params.sendListener = sendListener;
  46.     let msgHdr = hdrs[0];
  47.     if(msgHdr && msgHdr.folder != null) {
  48.       params.origMsgHdr = msgHdr;
  49.       params.originalMsgURI = msgHdrGetUri(msgHdr);
  50.     }              
  51.     fields.characterSet = "UTF-8";
  52.     fields.body = body;
  53.     gMsgCompose.SendMsg(deliverType, identity, identity.key, options && options.msgWindow, progress);
  54. }

  55. \mailnews\compose\src\nsMsgCompose.cpp
  56. NS_IMETHODIMP nsMsgCompose::SendMsg(MSG_DeliverMode deliverMode, nsIMsgIdentity *identity, const char *accountKey, nsIMsgWindow *aMsgWindow, nsIMsgProgress *progress)
  57. {
  58. rv = _SendMsg(deliverMode, identity, accountKey);
  59. }
  60. nsresult nsMsgCompose::_SendMsg(MSG_DeliverMode deliverMode, nsIMsgIdentity *identity,
  61.                                 const char *accountKey)
  62. {
  63. rv = mMsgSend->CreateAndSendMessage(
  64.                     m_composeHTML ? m_editor.get() : nullptr,
  65.                     identity,
  66.                     accountKey,
  67.                     m_compFields,
  68.                     false,
  69.                     false,
  70.                     (nsMsgDeliverMode)deliverMode,
  71.                     nullptr,
  72.                     m_composeHTML ? TEXT_HTML : TEXT_PLAIN,
  73.                     bodyString,
  74.                     nullptr,
  75.                     nullptr,
  76.                     m_window,
  77.                     mProgress,
  78.                     sendListener,
  79.                     mSmtpPassword.get(),
  80.                     mOriginalMsgURI,
  81.                     mType);
  82. }

  83. \mailnews\compose\src\nsMsgSend.cpp
  84. NS_IMETHODIMP
  85. nsMsgComposeAndSend::CreateAndSendMessage(
  86.               nsIEditor                         *aEditor,
  87.               nsIMsgIdentity                    *aUserIdentity,
  88.               const char                        *aAccountKey,
  89.               nsIMsgCompFields                  *fields,
  90.               bool                              digest_p,
  91.               bool                              dont_deliver_p,
  92.               nsMsgDeliverMode                  mode,
  93.               nsIMsgDBHdr                       *msgToReplace,
  94.               const char                        *attachment1_type,
  95.               const nsACString                  &attachment1_body,
  96.               nsIArray *attachments,
  97.               nsIArray *preloaded_attachments,
  98.               nsIDOMWindow                      *parentWindow,
  99.               nsIMsgProgress                    *progress,
  100.               nsIMsgSendListener                *aListener,
  101.               const char                        *password,
  102.               const nsACString                  &aOriginalMsgURI,
  103.               MSG_ComposeType                   aType
  104.               )
  105. {
  106.   rv = Init(aUserIdentity, aAccountKey, (nsMsgCompFields *)fields, nullptr,
  107.           digest_p, dont_deliver_p, mode, msgToReplace,
  108.           attachment1_type, attachment1_body,
  109.           attachments, preloaded_attachments,
  110.           password, aOriginalMsgURI, aType);
  111. }

  112. nsresult
  113. nsMsgComposeAndSend::Init(
  114.               nsIMsgIdentity  *aUserIdentity,
  115.               const char *aAccountKey,
  116.               nsMsgCompFields *fields,
  117.               nsIFile      *sendFile,
  118.               bool digest_p,
  119.               bool dont_deliver_p,
  120.               nsMsgDeliverMode mode,
  121.               nsIMsgDBHdr *msgToReplace,
  122.               const char *attachment1_type,
  123.               const nsACString &attachment1_body,
  124.               nsIArray *attachments,
  125.               nsIArray *preloaded_attachments,
  126.               const char *password,
  127.               const nsACString &aOriginalMsgURI,
  128.               MSG_ComposeType aType)
  129. {
  130. rv = InitCompositionFields(fields, aOriginalMsgURI, aType);
  131. if (sendFile)
  132.   {
  133.     mTempFile = sendFile;
  134.     return NS_OK;
  135.   }
  136.    return HackAttachments(attachments, preloaded_attachments);
  137. }

  138. nsresult
  139. nsMsgComposeAndSend::HackAttachments(nsIArray *attachments,
  140.                                      nsIArray *preloadedAttachments)
  141. {
  142.   // If no attachments - finish now (this will call the done_callback).
  143.   if (needToCallGatherMimeAttachments)  //发送前什么时候生成的临时文件? nsemail.eml  mTempFile  C:\Users\hechengjin\AppData\Local\Temp\nsemail.html
  144.     return GatherMimeAttachments();
  145. }


  146. nsMsgComposeAndSend::GatherMimeAttachments()
  147. {
  148.   rv = nsMsgCreateTempFile("nsemail.html", getter_AddRefs(mHTMLFile));
  149.   rv = nsMsgCreateTempFile("nsemail.eml", getter_AddRefs(mTempFile));
  150.   
  151.   //文件中内容 cc都没有问题
  152.   
  153. }
复制代码
回复 支持 反对

使用道具 举报

388

主题

602

帖子

2218

积分

金牌会员

Rank: 6Rank: 6

积分
2218
地板
 楼主| 发表于 2016-4-10 07:59:06 | 只看该作者
imap逻辑跟踪
  1. 跟踪imap消息头中为什么会有 上次的cc的联系人?


  2. msgsClassified

  3. msgAdded

  4. msgKeyChanged

  5. 上面三个事件的关系,为什么上面三个事件都会带上上次写信时的cc?

  6. 正常情况下追加完邮件,fetch到标题头解析完后触发msgAdded
  7. nsImapMailFolder::ParseMsgHdrs(nsIImapProtocol * aProtocol, nsIImapHeaderXferInfo * aHdrXferInfo)
  8. nsImapMailFolder::NormalEndHeaderParseStream(nsIImapProtocol * aProtocol, nsIImapUrl * imapUrl)
  9. {
  10.   notifier->NotifyMsgKeyChanged(pseudoKey, newMsgHdr);
  11.   notifier->NotifyMsgAdded(newMsgHdr);
  12. }

  13. 在这之前 msgKeyChanged 事件已经发生,如上

  14. 而在msgKeyChanged之前 msgsClassified已经发生,如下:

  15.   
  16.         nsImapMailFolder::SetUrlState(nsIImapProtocol * aProtocol, nsIMsgMailNewsUrl * aUrl, bool isRunning, bool aSuspend, nsresult statusCode)
  17.         nsMsgMailNewsUrl::SetUrlState(bool aRunningUrl, nsresult aExitCode)
  18.         nsImapMailFolder::OnStopRunningUrl(nsIURI * aUrl, nsresult aExitCode) {
  19.     nsIImapUrl::nsImapAppendDraftFromFile:
  20.   }
  21.         nsImapMailFolder::OnCopyCompleted(nsISupports * srcSupport, nsresult rv) {
  22.      (void) CopyFileToOfflineStore(srcFile, m_copyState->m_appendUID);  //即追加到imap服务器后,就复制到本地存储了,用于显示了,不用再从imap上拉取下来
  23.   }
  24.   nsImapMailFolder::CopyFileToOfflineStore(nsIFile * srcFile, unsigned int msgKey){
  25.    //没有与服务器同步前生成伪头部
  26.    nsCOMPtr<nsIMsgDBHdr> fakeHdr;
  27.   rv = mDatabase->CreateNewHdr(msgKey, getter_AddRefs(fakeHdr));
  28.   fakeHdr->SetUint32Property("pseudoHdr", 1);
  29.   nsCString ccList;
  30.         fakeHdr->GetCcList(getter_Copies(ccList));
  31.         printf("***************====fakeHdr->ccList %s %d\n", ccList.get(), ccList.Length());
  32.    
  33.   }
  34.   
  35.   mailnews\db\msgdb\src\nsMsgDatabase.cpp
  36.   NS_IMETHODIMP nsMsgDatabase::CreateNewHdr(nsMsgKey key, nsIMsgDBHdr **pnewHdr)
  37. {
  38.   nsresult  err = NS_OK;
  39.   nsIMdbRow    *hdrRow;

  40.   if (key != nsMsgKey_None)
  41.   {
  42.   allMsgHdrsTableOID.mOid_Scope = m_hdrRowScopeToken;
  43.   allMsgHdrsTableOID.mOid_Id = key;  // presumes 0 is valid key value

  44.   err = m_mdbStore->GetRow(GetEnv(), &allMsgHdrsTableOID, &hdrRow);
  45.   if (!hdrRow)
  46.     err  = m_mdbStore->NewRowWithOid(GetEnv(), &allMsgHdrsTableOID, &hdrRow);
  47.   }
  48.   else //const nsMsgKey nsMsgKey_None = 0xffffffff;
  49.   {
  50.     // Mork will assign an ID to the new row, generally the next available ID.
  51.     err  = m_mdbStore->NewRow(GetEnv(), m_hdrRowScopeToken, &hdrRow);
  52.     if (hdrRow)
  53.     {
  54.       struct mdbOid oid;
  55.       hdrRow->GetOid(GetEnv(), &oid);
  56.       key = oid.mOid_Id;  //本地产生一个假的key,后面再变会真的与服务器一致  //Message-ID: <5708CC42.4080109@sina.com> 根据newMessageId关联这个msghdr  nsDataHashtable<nsCStringHashKey, nsMsgKey> m_pseudoHdrs;  typedef unsigned long nsMsgKey;
  57.     }
  58.   }
  59.   if (NS_FAILED(err))
  60.     return err;
  61.   err = CreateMsgHdr(hdrRow, key, pnewHdr);
  62.   return err;
  63. }

  64. nsMsgDatabase::CreateMsgHdr(nsIMdbRow* hdrRow, nsMsgKey key, nsIMsgDBHdr* *result)
  65. {
  66. // 主要是这个key是上一个的key   如果是一个伪key则是本地数据库的key加1,如果原来是100,现在这个草稿是101, 当这个草稿与服务器同步完成后,这个key变成了1001,101又恢复使用?
  67.   nsresult rv = GetHdrFromUseCache(key, result);
  68.   if (NS_SUCCEEDED(rv) && *result)
  69.   {
  70.   //这里就会记录上次的cc内容了
  71.     hdrRow->Release();
  72.     return rv;
  73.   }

  74.   nsMsgHdr *msgHdr = new nsMsgHdr(this, hdrRow);
  75.   if(!msgHdr)
  76.     return NS_ERROR_OUT_OF_MEMORY;
  77.   msgHdr->SetMessageKey(key);
  78.   // don't need to addref here; GetHdrFromUseCache addrefs.
  79.   *result = msgHdr;

  80.   AddHdrToCache(msgHdr, key);

  81.   return NS_OK;
  82.   
  83.   
  84.   
  85.   nsCOMPtr<nsIMsgDBHdr> newMsgHdr;// https://dxr.mozilla.org/comm-central/source/mailnews/base/public/nsIMsgHdr.idl#14  attribute nsMsgKey messageKey; attribute string ccList; NS_IMETHOD GetCcList(char * *aCcList) = 0;
  86. }

  87. nsresult nsMsgDatabase::GetHdrFromUseCache(nsMsgKey key, nsIMsgDBHdr* *result)
  88. {

  89. //简单的修改方法不要添加进缓存表中了(即 m_bCacheHeaders 改为 false)   -----结论:感觉这并不是一个bug而只是方便你不用再重复输入。
  90.   if (m_headersInUse)
  91.   {
  92.     PLDHashEntryHdr *entry =
  93.       PL_DHashTableSearch(m_headersInUse, (const void *)(uintptr_t) key);
  94.     if (entry)
  95.     {
  96.       MsgHdrHashElement* element = static_cast<MsgHdrHashElement*>(entry);
  97.       *result = element->mHdr;
  98.     }
  99.     if (*result)
  100.     {
  101.       NS_ADDREF(*result);
  102.       rv = NS_OK;
  103.     }
  104.   }
  105.   return rv;
  106. }
复制代码
回复 支持 反对

使用道具 举报

388

主题

602

帖子

2218

积分

金牌会员

Rank: 6Rank: 6

积分
2218
5#
 楼主| 发表于 2016-4-11 09:47:06 | 只看该作者
  1. imap调用逻辑整理
  2. 1.imap执行追加邮件到服务器后 append "&g0l6P1k5-" (\Draft) {1144}
  3. OnCopyCompleted -> CopyFileToOfflineStore
  4. mDatabase->CreateNewHdr(msgKey, getter_AddRefs(fakeHdr));
  5. //https://dxr.mozilla.org/comm-central/source/mailnews/base/public/nsIMsgHdr.idl#14
  6. msgKey:nsMsgKey_None = 0xffffffff;   -----attribute nsMsgKey messageKey;
  7. Message-ID: <5707A8D5.6090506@sina.com>   ------attribute string messageId;
  8. /*
  9.     nsCString ccList;
  10.                         fakeHdr->GetCcList(getter_Copies(ccList));
  11.                         nsCString messageId;
  12.                         fakeHdr->GetMessageId(getter_Copies(messageId));
  13.                         printf("------CopyFileToOfflineStore NotifyMsgsClassified  messageKey:%d nsMsgKey_None:%d messageId:%s fakeHdr->ccList:%s\n", msgKey, nsMsgKey_None, messageId.get(), ccList.get());
  14.     */
  15. messages->AppendElement(fakeHdr, false);
  16. notifier->NotifyMsgsClassified(messages, false, false);
  17. 触发前端 msgsClassified -->addMessageByMsgHdr
  18.   let exists = this.getMessageItem(item.primaryKey)
  19.     console.log(`===addMessageByMsgHdr exists:${exists} primaryKey:${item.primaryKey} messageKey:${msgHdr.messageKey} folderID:${folderID} messageId:${msgHdr.messageId}`)
  20.     if (exists) {
  21.       return
  22.     }

  23. 然后把PseudoKey与messageId的对应关联记录到内存中
  24. mailnews\imap\src\nsImapOfflineSync.cpp
  25. //对离线处理完的任务进行清理
  26. nsresult nsImapOfflineSync::ProcessNextOperation(){
  27.   imapFolder->AddMoveResultPseudoKey(curKey);
  28. }
  29. NS_IMETHODIMP nsImapMailFolder::AddMoveResultPseudoKey(nsMsgKey aMsgKey){
  30.    printf("------AddMoveResultPseudoKey messageId:%s aMsgKey:%d\n", messageId.get(), aMsgKey);
  31. }

  32. 2.获取服务端对应的真正的key后触发msgKeyChanged (messageId作为关联字段)【这个事件中直接把原来的记录删除,再重新添加】,去然后再触发msgAdded事件
  33. NormalEndHeaderParseStream {
  34.   m_pseudoHdrs.Get(newMessageId, &pseudoKey);  //根据messageId找到对应的pseudoKey   什麽時候添加進來的呢? printf("------AddMoveResultPseudoKey messageId:%s aMsgKey:%d", messageId.get(), aMsgKey);
  35.   if (notifier && pseudoKey != nsMsgKey_None)
  36.   {
  37.   
  38.       nsMsgKey newKey = nsMsgKey_None;
  39.                         newMsgHdr->GetMessageKey(&newKey); // =m_curMsgUid
  40.                         printf("------NormalEndHeaderParseStream NotifyMsgKeyChanged pseudoKey:%d newKey:%d newMessageId:%s\n", pseudoKey, newKey, newMessageId.get());
  41.     notifier->NotifyMsgKeyChanged(pseudoKey, newMsgHdr);
  42.     m_pseudoHdrs.Remove(newMessageId);
  43.   }
  44.   mDatabase->AddNewHdrToDB(newMsgHdr, true);
  45.   if (notifier) {
  46.       nsMsgKey newKey = nsMsgKey_None;
  47.                         newMsgHdr->GetMessageKey(&newKey);
  48.                         printf("------NormalEndHeaderParseStream NotifyMsgAdded Key:%d newMessageId:%s\n", newKey, newMessageId.get());
  49.       notifier->NotifyMsgAdded(newMsgHdr);
  50.   }
  51.    
  52. }

  53. 3对邮件进行完过滤后再调用一次msgsClassified
  54. nsresult nsMsgDBFolder::NotifyHdrsNotBeingClassified(){
  55.    notifier->NotifyMsgsClassified(msgHdrsNotBeingClassified,
  56.                                         // no classification is being performed
  57.                                         false, false);
  58. }

  59. 总结:问题原因是因为伪Key采用了上一封邮件的Key,所以造成关联错误
  60. 这里修改方法在上一封Key基础上增加一个数字,防止重复,
  61. nsImapMailFolder::OnCopyCompleted(nsISupports *srcSupport, nsresult rv)
  62. {
  63.    (void) CopyFileToOfflineStore(srcFile, m_copyState->m_appendUID + 10);
  64. 日志如下:


  65. 2016-04-10 19:29:21     Conversations.Send      DEBUG   [Exception... "Failure a
  66. rg 0 [nsIMsgCompose.initEditor]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  loc
  67. ation: "JS frame :: resource://conversations/modules/stdlib/send.js :: sendMessa
  68. ge/<.editor :: line 456"  data: no]
  69. 2016-04-10 19:29:21     Conversations.Send      DEBUG   This message might be co
  70. nvertible: 4
  71. --1----CopyFileToOfflineStore msgKey:1515870820
  72. --2----CopyFileToOfflineStore msgKey:1515870820
  73. ------CopyFileToOfflineStore NotifyMsgsClassified  messageKey:1515870820 nsMsgKe
  74. y_None:-1 messageId:570A3912.4030306@sina.com fakeHdr->ccList:chenlong3@kingsoft
  75. .com
  76. console.log: ===msgsClassified ccList:chenlong3@kingsoft.com, messageKey:1515870
  77. 820  messageId:570A3912.4030306@sina.com
  78. console.log: ===addMessageByMsgHdr exists:undefined primaryKey:87415216740 messa
  79. geKey:1515870820 folderID:20 messageId:570A3912.4030306@sina.com
  80. ------AddMoveResultPseudoKey messageId:570A3912.4030306@sina.com aMsgKey:1515870
  81. 820
  82. ------NormalEndHeaderParseStream NotifyMsgKeyChanged pseudoKey:1515870820 newKey
  83. :206 newMessageId:570A3912.4030306@sina.com
  84. console.log: ===msgKeyChanged old messageKey:1515870820, new ccList:chenlong3@ki
  85. ngsoft.com, messageKey:206, messageId:570A3912.4030306@sina.com
  86. console.log: ===deleteMessageByMessageID primaryKey:87415216740
  87. console.log: ===addMessageByMsgHdr exists:undefined primaryKey:85899346126 messa
  88. geKey:206 folderID:20 messageId:570A3912.4030306@sina.com
  89. ------NormalEndHeaderParseStream NotifyMsgAdded Key:206 newMessageId:570A3912.40
  90. 30306@sina.com
  91. console.log: ===msgAdded, ccList:chenlong3@kingsoft.com messageKey:206 messageId
  92. :570A3912.4030306@sina.com
  93. console.log: ===addMessageByMsgHdr exists:[object Object] primaryKey:85899346126
  94. messageKey:206 folderID:20 messageId:570A3912.4030306@sina.com
  95. ---------NotifyHdrsNotBeingClassified
  96. console.log: ===msgsClassified ccList:chenlong3@kingsoft.com, messageKey:206  me
  97. ssageId:570A3912.4030306@sina.com
  98. console.log: ===addMessageByMsgHdr exists:[object Object] primaryKey:85899346126
  99. messageKey:206 folderID:20 messageId:570A3912.4030306@sina.com
  100. console.log: less has finished. css generated in 160ms
  101. console.log: Create finished
  102. console.log: fontFace is:SimSun
  103. console.log: fontSize is:14px
  104. console.log: WinJS init finished
  105. 2016-04-10 19:29:57     Conversations.Send      DEBUG   [Exception... "Failure a
  106. rg 0 [nsIMsgCompose.initEditor]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  loc
  107. ation: "JS frame :: resource://conversations/modules/stdlib/send.js :: sendMessa
  108. ge/<.editor :: line 456"  data: no]
  109. 2016-04-10 19:29:57     Conversations.Send      DEBUG   This message might be co
  110. nvertible: 4
  111. --1----CopyFileToOfflineStore msgKey:216
  112. --2----CopyFileToOfflineStore msgKey:216
  113. ------CopyFileToOfflineStore NotifyMsgsClassified  messageKey:216 nsMsgKey_None:
  114. -1 messageId:570A3936.2000001@sina.com fakeHdr->ccList:
  115. console.log: ===msgsClassified ccList:, messageKey:216  messageId:570A3936.20000
  116. 01@sina.com
  117. console.log: ===addMessageByMsgHdr exists:undefined primaryKey:85899346136 messa
  118. geKey:216 folderID:20 messageId:570A3936.2000001@sina.com
  119. ------AddMoveResultPseudoKey messageId:570A3936.2000001@sina.com aMsgKey:216
  120. ------NormalEndHeaderParseStream NotifyMsgKeyChanged pseudoKey:216 newKey:207 ne
  121. wMessageId:570A3936.2000001@sina.com
  122. console.log: ===msgKeyChanged old messageKey:216, new ccList:, messageKey:207, m
  123. essageId:570A3936.2000001@sina.com
  124. console.log: ===deleteMessageByMessageID primaryKey:85899346136
  125. console.log: ===addMessageByMsgHdr exists:undefined primaryKey:85899346127 messa
  126. geKey:207 folderID:20 messageId:570A3936.2000001@sina.com
  127. ------NormalEndHeaderParseStream NotifyMsgAdded Key:207 newMessageId:570A3936.20
  128. 00001@sina.com
  129. console.log: ===msgAdded, ccList: messageKey:207 messageId:570A3936.2000001@sina
  130. .com
  131. console.log: ===addMessageByMsgHdr exists:[object Object] primaryKey:85899346127
  132. messageKey:207 folderID:20 messageId:570A3936.2000001@sina.com
  133. ---------NotifyHdrsNotBeingClassified
  134. console.log: ===msgsClassified ccList:, messageKey:207  messageId:570A3936.20000
  135. 01@sina.com
  136. console.log: ===addMessageByMsgHdr exists:[object Object] primaryKey:85899346127
  137. messageKey:207 folderID:20 messageId:570A3936.2000001@sina.com
  138. console.log: *****start search:filterFolderIDs,recipientDisplay,folderID,listVie
  139. w,sortType,sortOrder,threaded; unread:undefined; starred:undefined; folderID:21;
  140. filterFolderIDs:20,24,19,23,22,21,25,26,18,27,28
  141. console.log: searchView.applyWhere finished false
  142. console.log: The search keywors []
  143. console.log: *****start search:filterFolderIDs,recipientDisplay,folderID,listVie
  144. w,sortType,sortOrder,threaded; unread:undefined; starred:undefined; folderID:20;
  145. filterFolderIDs:20,24,19,23,22,21,25,26,18,27,28
  146. console.log: searchView.applyWhere finished false
  147. console.log: The search keywors []
  148. console.log: The time consumed to init 114
  149. console.log: The time consumed to init 105
  150. console.log: The time consumed to init 99
复制代码
回复 支持 反对

使用道具 举报

388

主题

602

帖子

2218

积分

金牌会员

Rank: 6Rank: 6

积分
2218
6#
 楼主| 发表于 2016-4-19 12:29:26 | 只看该作者
本帖最后由 hechengjin 于 2016-4-19 12:36 编辑

负面影响 :由于离线保存的Key进行了改变,在copy完成后,进行邮件过滤时,根据原来的key则找不到对应的邮件
nsImapMailFolder::SetAppendMsgUid(nsMsgKey aKey,
                                  nsIImapUrl * aUrl){
else if (mailCopyState->m_listener) // CopyFileMessage();
                                        // Draft/Template goes here
    {
      mailCopyState->m_appendUID = aKey;
      mailCopyState->m_listener->SetMessageKey(aKey);
    }

}

CopyListener::SetMessageKey(nsMsgKey aMessageKey)
{
  if (mComposeAndSend)
      mComposeAndSend->SetMessageKey(aMessageKey);
  return NS_OK;
}



nsMsgComposeAndSend::FilterSentMessage(){
nsCOMPtr<nsIMsgDBHdr> msgHdr;
  rv = folder->GetMessageHeader(m_messageKey, getter_AddRefs(msgHdr));
  if (NS_FAILED(rv))
    return rv;
}



回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|firemail ( 粤ICP备15085507号-1 )

GMT+8, 2024-11-26 02:05 , Processed in 0.073406 second(s), 18 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表