红宝石IMAP“变化”,因为上次检查(Ruby IMAP “changes” since last

2019-07-28 21:35发布

我正在使用Ruby和Rails的IMAP客户端上。 我可以成功地导入邮件,邮箱和更多...然而,最初的导入后,我怎么能发现自从我上次同步发生的任何变化?

目前我储存的UID和UID有效性的值在数据库中,比较它们,并适当地进行搜索。 这工作,但它不检测已删除的邮件或更改信息标志等。

我必须每天来检测这些变化的时间把所有的消息? 如何做其他的IMAP客户端这么快做(即Apple Mail和邮箱)。 我的剧本已经采取每个账户10+秒的极少数的电子邮件地址:

# select ourself as the current mailbox
@imap_connection.examine(self.location)

# grab all new messages and update them in the database
# if the uid's are still valid, we will just fetch the newest UIDs
# otherwise, we need to search when we last synced, which is slower :(
if self.uid_validity.nil? || uid_validity == self.uid_validity
  # for some IMAP servers, if a mailbox is empty, a uid_fetch will fail, so then
  begin
    messages = @imap_connection.uid_fetch(uid_range, ['UID', 'RFC822', 'FLAGS'])
  rescue
    # gmail cries if the folder is empty
    uids = @imap_connection.uid_search(['ALL'])
    messages = @imap_connection.uid_fetch(uids, ['UID', 'RFC822', 'FLAGS']) unless uids.empty?
  end

  messages.each do |imap_message|
    Message.create_from_imap!(imap_message, self.id)
  end unless messages.nil?
else
  query = self.last_synced.nil? ? ['All'] : ['SINCE', Net::IMAP.format_datetime(self.last_synced)]
  @imap_connection.search(query).each do |message_id|
    imap_message = @imap_connection.fetch(message_id, ['RFC822', 'FLAGS', 'UID'])[0]

    # don't mark the messages as read
    #@imap_connection.store(message_id, '-FLAGS', [:Seen])

    Message.create_from_imap!(imap_message, self.id)
  end
end

# now assume all UIDs are valid
self.uid_validity = uid_validity

# now remember that we just fetched all those messages
self.last_synced = Time.now
self.save!

Answer 1:

有一个IMAP扩展快速标志变化再同步 ( RFC-4551 )。 有了这个扩展,可以搜索自上次同步已更改的所有消息(基于某种时间戳)。 然而,据我知道这个扩展未得到广泛的支持。

有描述IMAP客户端应该怎么做同步(信息性RFC RFC-4549 ,第4.3节)。 该文建议发出以下两个命令:

tag1 UID FETCH <lastseenuid+1>:* <descriptors>
tag2 UID FETCH 1:<lastseenuid> FLAGS

所述第一命令用于获取所有未知邮件的所需的信息(在不知道多少邮件有)。 第二个命令是用于将标志为已看到邮件同步。

AFAIK这种方法被广泛使用。 因此,许多IMAP服务器包含为了快速提供此信息的优化。 通常,网络带宽是限制因素。



Answer 2:

IMAP协议是脑死亡这种方式,很遗憾。 IDLE真的应该能够同时连接到返回的东西这种,例如。 上述抓取FLAGS建议是做到这一点的唯一途径。

有一两件事要小心的,但是,是的UID仅适用于每规范中的一个给定的会话。 你不应该存储它们,即使一些服务器坚持他们。



文章来源: Ruby IMAP “changes” since last check