Friday, July 10, 2009

Imapsync

sync any mail from gmail id

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.