4

私はRubyとRailsを使用してIMAPクライアントに取り組んでいます。メッセージやメールボックスなどを正常にインポートできます...ただし、最初のインポート後に、最後の同期以降に発生した変更を検出するにはどうすればよいですか?

現在、UIDとUIDの有効性の値をデータベースに保存し、それらを比較して、適切に検索しています。これは機能しますが、削除されたメッセージやメッセージフラグの変更などは検出されません。

これらの変更を検出するために、毎回すべてのメッセージをプルする必要がありますか?他のIMAPクライアント(つまり、Apple MailとPostbox)はどのようにそれをすばやく実行しますか。私のスクリプトは、メールアドレスが非常に少ないアカウントごとにすでに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!
4

2 に答える 2

12

Quick Flag Changes ResynchronizationRFC-4551 )用のIMAP拡張機能があります。この拡張機能を使用すると、最後の同期以降に変更されたすべてのメッセージを検索できます(ある種のタイムスタンプに基づく)。ただし、私が知る限り、この拡張機能は広くサポートされていません。

IMAPクライアントが同期を実行する方法を説明する情報RFCがあります(RFC-4549、セクション4.3)。このテキストでは、次の2つのコマンドを発行することを推奨しています。

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

最初のコマンドは、すべての不明なメールに必要な情報を取得するために使用されます(メールの数がわからない場合)。2番目のコマンドは、すでに表示されているメールのフラグを同期するために使用されます。

AFAIKこの方法は広く使用されています。したがって、多くのIMAPサーバーには、この情報を迅速に提供するための最適化が含まれています。通常、ネットワーク帯域幅が制限要因です。

于 2012-04-11T17:36:35.763 に答える
1

残念ながら、IMAPプロトコルはこのように脳死しています。IDLEは、たとえば、接続中にこの種のものを実際に返すことができるはずです。上記のFETCHFLAGSの提案は、それを行う唯一の方法です。

ただし、注意すべき点の1つは、UIDは仕様に従って特定のセッションでのみ有効であるということです。一部のサーバーがそれらを永続化する場合でも、それらを保存しないでください。

于 2012-08-24T03:56:50.683 に答える