Created
February 15, 2011 02:02
-
-
Save entp/826969 to your computer and use it in GitHub Desktop.
Downloads all the messages in your imap mailbox and saves them as files.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'net/imap' | |
class ImapWrapper | |
attr_reader :imap | |
module Constants | |
RFC822 = 'RFC822'.freeze | |
IDATE = 'INTERNALDATE'.freeze | |
M_ID = "BODY[HEADER.FIELDS (MESSAGE-ID)]".freeze | |
SUBJECT = "BODY[HEADER.FIELDS (SUBJECT)]".freeze | |
TO = "BODY[HEADER.FIELDS (TO)]".freeze | |
BODY = "BODY[TEXT]".freeze | |
FROM = "BODY[HEADER.FIELDS (FROM)]".freeze | |
SIZE = "RFC822.SIZE".freeze | |
UID = "UID".freeze | |
FLAGS = "+FLAGS".freeze | |
def clean_message_id(s) | |
s.sub! /^[^<]+</, '' | |
s.sub! />.*$/, '' | |
s.strip! | |
s | |
end | |
end | |
include Constants | |
def initialize(user, pass, purge_messages = false, verbose = false) | |
@purge_messages = purge_messages | |
@verbose = verbose | |
@imap = Net::IMAP.new('imap.gmail.com', 993, true) | |
@imap.login(user, pass) | |
end | |
def verbose? | |
@verbose | |
end | |
def purge_messages? | |
@purge_messages | |
end | |
def each_message(mailbox, query, attributes, options = {}, &block) | |
each_uid(mailbox, query) do |all_uids| | |
while uids = paginated(all_uids, options) | |
fetch(uids, attributes).each do |data| | |
if block && data.attr | |
uid = data.attr[UID] | |
block.call(uid, data.attr) | |
end | |
end | |
end | |
end | |
end | |
def each_message_id(mailbox, query, &block) | |
each_message(mailbox, query, M_ID, :per_page => 30) do |uid, data| | |
id = data[M_ID] | |
id.sub! /^[^<]+</, '' | |
id.sub! />.*$/, '' | |
id.strip! | |
block.call(uid, id) if block | |
end | |
end | |
def fetch(uid, attributes) | |
if attributes.respond_to?(:join) | |
attributes = "(#{attributes * " "})" | |
end | |
@imap.uid_fetch(uid, attributes) || [] | |
rescue | |
puts "Error fetching #{uid.inspect}" | |
puts $!.inspect | |
end | |
def copy_to(uid, mailbox) | |
@imap.uid_copy uid, mailbox | |
end | |
def move_to(uid, mailbox) | |
copy_to uid, mailbox | |
purge uid | |
end | |
def store(uid, attr, flags) | |
@imap.uid_store(uid, attr, flags) | |
end | |
def purge(uid) | |
puts "PURGING: #{uid.inspect}" if verbose? | |
store uid, FLAGS, [:Deleted] | |
end | |
def mailboxes | |
@imap.list('', '*').map { |m| m.name } | |
end | |
def close | |
puts "EXPUNGE!" if purge_messages? | |
@imap.expunge if purge_messages? | |
@imap.logout | |
end | |
def mailbox(name) | |
@imap.select(name) | |
end | |
private | |
# :limit => ONLY send this many back | |
# :per_page => return items in pages | |
def paginated(array, options = {}) | |
page = [] | |
page_size = options[:limit] || options[:per_page] || 10 | |
page_size.times { page << array.shift } | |
page.compact! | |
if options[:limit] then array.clear end | |
page.empty? ? nil : page | |
end | |
def each_uid(mailbox_name, query, &block) | |
mailbox(mailbox_name) | |
uids = @imap.uid_search(query) | |
puts "#{uids.size} uid(s) found..." if verbose? | |
block.call(uids.dup) if block && uids.size > 0 | |
uids | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
IMAP = { :user => "you@gmail.com", :pass => "yourpassword" } | |
namespace :imap do | |
wrapper = nil | |
task :connect do | |
dir = "#{File.dirname(__FILE__)}/../../../../" | |
require 'imap_wrapper' | |
include ImapWrapper::Constants | |
wrapper = ImapWrapper.new(IMAP[:user], IMAP[:pass], ENV['PURGE'], ENV['VERBOSE']) | |
mbox = ENV['MBOX'] || "INBOX" | |
dest = ENV['TO'] || "reprocessed" | |
FileUtils.mkdir_p(File.join(File.dirname(__FILE__), "queue")) | |
wrapper.each_message(mbox, "ALL", [M_ID, RFC822], :per_page => 100) do |uid, data| | |
raw = data[RFC822] | |
path = File.join("queue", "#{uid}.eml") | |
File.open(path, 'w') { |f| f << raw } | |
puts "Wrote #{path} (#{raw.size})" | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment