Emails von IMAP nach IMAP
Um Emails von einem EMAP- Postfach auf ein anderes zu transferieren, kann man natürlich einfach per Drag and Drop seine Ordner in seinem Email-Client wie Evolution oder Thunderbird von einem Account auf den anderen zerren. Es ist aber leider nicht gerade unproblematisch, sehr viele Emails zu kopieren.
Zum Glück gibt es unter UNIX das Programm imapsync.
imapsync --host1 mail.physik.fu-berlin.de --port1 993 --user1 username --ssl1 --noauthmd5 --host2 imap.gmail.com --port2 993 --user2 gmailuser --ssl2
Damit sieht man genau, was passiert. Allerdings konnte auch dieses Programm meine Mails nicht vollständig übertragen. Ich lasse es sehr oft laufen und jedesmal werden weitere Mails kopiert. Das ist nicht gerade das, was ich erwarte.
Aber währe da nicht Ruby, würde ich es bestimmt nicht auf die solide Tour versucht haben: Ein kleines Ruby-Skript, was ich auf wonko.com gefunden habe.
#!/usr/bin/env ruby
# from http://wonko.com/post/ruby_script_to_sync_email_from_any_imap_server_to_gmail
# little change by Johannes J. Schmidt
require 'net/imap'
# Source server connection info.
SOURCE_HOST = 'mail.physik.fu-berlin.de'
SOURCE_PORT = 993
SOURCE_SSL = true
SOURCE_USER = 'username'
SOURCE_PASS = 'pass'
# Destination server connection info.
DEST_HOST = 'imap.gmail.com'
DEST_PORT = 993
DEST_SSL = true
DEST_USER = 'username'
DEST_PASS = 'pass'
# 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" => "physik/inbox"
# 'INBOX' => 'INBOX',
# 'sourcefolder' => 'gmailfolder'
}
def progress(total, cnt)
out = "%.2f" % ((100.0*cnt)/total)
out << "% "
out << "(%d/%d)" % [cnt, total]
out
end
# Utility methods.
def dd(message)
puts "[#{DEST_HOST}] #{message}"
end
def ds(message)
puts "[#{SOURCE_HOST}] #{message}"
end
# 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 "slecting 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
dest.uid_fetch(uids, ['ENVELOPE']).each do |data|
dest_info[data.attr['ENVELOPE'].message_id] = true
end
end
copied_cnt = uids.length
dd "%d Messages in Destinationfolder '%s'" % [copied_cnt, dest_folder]
# Loop through all messages in the source folder.
uids = source.uid_search(['ALL'])
dd "%d Messages in Sourcefolder '%s'" % [uids.length, source_folder]
todo = uids.length - copied_cnt
puts "Will copy %d messages." % todo
if uids.length > 0
source.uid_fetch(uids, ['ENVELOPE']).each_with_index do |data, i|
mid = data.attr['ENVELOPE'].message_id
# If this message is already in the destination folder, skip it.
next if dest_info[mid]
# Download the full message body from the source folder.
#ds "downloading message #{mid}...", progress(todo, i)
msg = source.uid_fetch(data.attr['UID'], ['RFC822', 'FLAGS',
'INTERNALDATE']).first
puts "#{progress(uids.length, i)} #{msg.attr['INTERNALDATE']} #{mid}"
# Append the message to the destination folder, preserving flags and
# internal timestamp.
#dd "storing message #{mid}...", progress(todo, i)
dest.append(dest_folder, msg.attr['RFC822'], msg.attr['FLAGS'],
msg.attr['INTERNALDATE'])
end
end
source.close
dest.close
end
puts 'done'
Schön, auch dieses Progrämmlein bricht immer wieder ab.
Mal sehen, was noch kommt, ich bleibe am Ball und werde berichten.
Nach langem Warten sind nun doch einige Mails gedoppelt worden, leider. Ich hoffe, es fehlt nicht die wichtige Mail.
Grüße von
Johannes
webwalk