2011-09-02 (Fri) [長年日記]
_ IMAPサーバ上のメールのアーカイブ
最近はMUAとしてWanderlustを使っているのだが、メールをexpireして別のフォルダに移動する時に時間がかかり、また、いつ終わるかが予測できないのが不便だったため、簡単なRubyスクリプトで処理するようにしてみた。
$ imaparchive --mailbox work imap.netlab.jp Password: archiving 18360 messages to archive/work-20110602... work: 100% |oooooooooooooooooooooooooooooooooooooooo| Time: 00:47:00 Done
といった感じで、3か月以上前のメール(既読、かつ、削除されてないもの)を、IMAP上の別のフォルダ(archive/<mailbox名>-<日付>)に移動する。内容は以下のとおり(Ruby 1.9前提、ぜんぜんテストしてないので注意)。
#!/usr/bin/env ruby require "optparse" require "net/imap" require "io/console" require "ostruct" require "date" require "pp" require "progressbar" def get_password io = IO.console io.print("Password: ") io.flush s = io.noecho { io.gets.chomp } io.puts return s end conf = OpenStruct.new conf.user = ENV["USER"] conf.mailbox = "INBOX" conf.imap_options = {} conf.archive_prefix = "archive/" conf.months = 3 opt_parser = OptionParser.new do |opts| opts.banner = "Usage: imaparchive [options] <hostname>" opts.on("-u", "--user=USER", "Username") do |u| conf.user = u end opts.on("-m", "--mailbox=MAILBOX", "Mailbox name") do |mbx| conf.mailbox = mbx end opts.on("-a", "--archive-prefix=PREFIX", "Archive prefix") do |prefix| conf.archive_prefix = prefix end opts.on("-m", "--months=N", "Keep messages for N months") do |prefix| conf.months = 3 end opts.on("-s", "--[no-]ssl", "Use imaps") do |val| conf.imap_options[:ssl] = val end end opt_parser.parse! if ARGV.length == 0 STDERR.print(opt_parser.help) exit 1 end conf.host = ARGV[0] conf.user = ENV["USER"] conf.password = get_password imap = Net::IMAP.new(conf.host, conf.imap_options) imap.login(conf.user, conf.password) imap.select(conf.mailbox) date = Date.today << conf.months uids = imap.uid_search(["BEFORE", Net::IMAP.format_date(date), "SEEN", "NOT", "DELETED"]) if uids.empty? exit end archive_mailbox = conf.archive_prefix + File.basename(conf.mailbox) + date.strftime("-%Y%m%d") unless imap.list("", archive_mailbox) imap.create(archive_mailbox) end puts "archiving #{uids.length} messages to #{archive_mailbox}..." pbar = ProgressBar.new(conf.mailbox, uids.length) uids.each do |uid| imap.uid_copy(uid, archive_mailbox) imap.uid_store(uid, "+FLAGS", [:Deleted]) pbar.inc end pbar.finish imap.expunge puts "Done"