@m_seki の

I like ruby tooから引っ越し

1日20秒でできるnet/imap入門

*1
メーリングリストを複数のメールアドレス*2で購読しちゃうことあるじゃん?そうすると同じメールを複数受け取っちゃうんだよね。最終的にはApple MailでひとつのIMAPのフォルダに放り込むんだけど、同じメールがまぎれちゃう。

で、ですね。net/imapを使ってあるフォルダに入ってる重複したメールを削除してみました。net/imapもはじめてだけど、IMAPプロトコル自体はじめてだったので手こずった...。

メッセージの一意性はMessage-Idでいいはずなんだけど、開発中の都合でSubjectも使いました。定数KEYからSubjectを抜けばMessage-Idだけで判断するはず。

重複を探す作戦は最初は辞書を使ったんだけど、並び替えてから同じ行を見つけるコントロールブレイクというかuniq風というか古典的な手順に書き換えました。

require 'net/imap'
require 'enumerator'

KEY = 'BODY[HEADER.FIELDS (Message-Id Subject)]'

imap = Net::IMAP.new('サーバ')  # この辺は適当に変える
imap.login('アカウント', 'パスワード') #
imap.select('フォルダ') #
ary = imap.search('ALL')
data = imap.fetch(Range.new(ary[0], ary[-1]), "(UID #{KEY})")

data.sort_by {|rec| rec.attr[KEY]}.each_cons(2) do |prev, curr|
  if prev.attr[KEY] == curr.attr[KEY]
    p imap.uid_store(curr.attr['UID'], "+FLAGS", [:Deleted])
  end
end

imap.expunge
imap.disconnect

参考にしたページ

うっかり参考にするのを忘れたけどレシピ本群にも出てるのかな。Ruby 逆引きレシピ すぐに美味しいサンプル&テクニック 232 (PROGRAMMER’S RECIPE)は買いだめされてるって噂を聞いたけど。

Rubyレシピブック 第3版 303の技Ruby逆引きハンドブックRuby 逆引きレシピ すぐに美味しいサンプル&テクニック 232 (PROGRAMMER’S RECIPE)