http://wonko.com/post/ruby_script_to_sync_email_from_any_imap_server_to_gmail
---------------------------------------
#startting code
#!/usr/bin/env ruby
require 'net/imap'
# Source server connection info.
SOURCE_NAME = 'username@example.com'
SOURCE_HOST = 'mail.example.com'
SOURCE_PORT = 143
SOURCE_SSL = false
SOURCE_USER = 'username'
SOURCE_PASS = 'password'
# Destination server connection info.
DEST_NAME = 'username@gmail.com'
DEST_HOST = 'imap.gmail.com'
DEST_PORT = 993
DEST_SSL = true
DEST_USER = 'username@gmail.com'
DEST_PASS = 'password'
# Mapping of source folders to destination folders. The key is the name of the
# folder on the source server, the value is the name on the destination server.
# Any folder not specified here will be ignored. If a destination folder does
# not exist, it will be created.
FOLDERS = {
'INBOX' => 'INBOX',
'sourcefolder' => 'gmailfolder'
}
# Maximum number of messages to select at once.
UID_BLOCK_SIZE = 1024
# Utility methods.
def dd(message)
puts "[#{DEST_NAME}] #{message}"
end
def ds(message)
puts "[#{SOURCE_NAME}] #{message}"
end
def uid_fetch_block(server, uids, *args)
pos = 0
while pos < uids.size
server.uid_fetch(uids[pos, UID_BLOCK_SIZE], *args).each {|data| yield data }
pos += UID_BLOCK_SIZE
end
end
@failures = 0
@existing = 0
@synced = 0
# Connect and log into both servers.
ds 'Connecting...'
source = Net::IMAP.new(SOURCE_HOST, SOURCE_PORT, SOURCE_SSL)
ds 'Logging in...'
source.login(SOURCE_USER, SOURCE_PASS)
dd 'Connecting...'
dest = Net::IMAP.new(DEST_HOST, DEST_PORT, DEST_SSL)
dd 'Logging in...'
dest.login(DEST_USER, DEST_PASS)
# Loop through folders and copy messages.
FOLDERS.each do |source_folder, dest_folder|
# Open source folder in read-only mode.
begin
ds "Selecting folder '#{source_folder}'..."
source.examine(source_folder)
rescue => e
ds "Error: select failed: #{e}"
next
end
# Open (or create) destination folder in read-write mode.
begin
dd "Selecting folder '#{dest_folder}'..."
dest.select(dest_folder)
rescue => e
begin
dd "Folder not found; creating..."
dest.create(dest_folder)
dest.select(dest_folder)
rescue => ee
dd "Error: could not create folder: #{e}"
next
end
end
# Build a lookup hash of all message ids present in the destination folder.
dest_info = {}
dd 'Analyzing existing messages...'
uids = dest.uid_search(['ALL'])
if uids.length > 0
uid_fetch_block(dest, uids, ['ENVELOPE']) do |data|
dest_info[data.attr['ENVELOPE'].message_id] = true
end
end
dd "Found #{uids.length} messages"
# Loop through all messages in the source folder.
uids = source.uid_search(['ALL'])
ds "Found #{uids.length} messages"
if uids.length > 0
uid_fetch_block(source, uids, ['ENVELOPE']) do |data|
mid = data.attr['ENVELOPE'].message_id
# If this message is already in the destination folder, skip it.
if dest_info[mid]
@existing += 1
next
end
# Download the full message body from the source folder.
ds "Downloading message #{mid}..."
msg = source.uid_fetch(data.attr['UID'], ['RFC822', 'FLAGS',
'INTERNALDATE']).first
# Append the message to the destination folder, preserving flags and
# internal timestamp.
dd "Storing message #{mid}..."
tries = 0
begin
tries += 1
dest.append(dest_folder, msg.attr['RFC822'], msg.attr['FLAGS'],
msg.attr['INTERNALDATE'])
@synced += 1
rescue Net::IMAP::NoResponseError => ex
if tries < 10
dd "Error: #{ex.message}. Retrying..."
sleep 1 * tries
retry
else
@failures += 1
dd "Error: #{ex.message}. Tried and failed #{tries} times; giving up on this message."
end
end
end
end
source.close
dest.close
end
puts "Finished. Message counts: #{@existing} untouched, #{@synced} transferred, #{@failures} failures."
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.