Emails von IMAP nach IMAP

Allgemeines — Johannes am 27. September 2008

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.

Hier ist das Originalskript

#!/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

0 Comments

Noch keine Kommentare

RSS Feed für Kommentare zu diesem Artikel.

Entschuldige, das Kommentarformular ist zurzeit geschlossen.

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License.
(c) 2012 webwalk | powered by WordPress with Baeh quiet Barecity