Googlemail-Backup mit IMAP
Wie schon erwähnt, bin ich auf der Suche nach der perfekten Lösung, meine Googlemail-E-Mails zu sichern. Und ich denke ich habe sie gefunden: ein Ruby-Script, das die Synchronisation zwischen meinem Googlemail-Account und einem zweiten IMAP-Account übernimmt. Synchronisation ist dabei vielleicht das falsche Wort, es ist eher ein Backup, was den zweiten IMAP-Account auf dem gleichen Stand wie den Googlemail-Account hält.
Die Basis für das Script kommt von Ryan Grove. Ich habe das Löschen von Nachrichten und die Ordner-Auflistung hinzugefügt.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | #!/usr/bin/env ruby require 'net/imap' # Source server connection info. SOURCE_HOST = 'imap.googlemail.com' SOURCE_PORT = 993 SOURCE_SSL = true SOURCE_USER = 'EMAIL@googlemail.com' SOURCE_PASS = 'PASSWORT' # Destination server connection info. DEST_HOST = 'imap.SERVER.com' DEST_PORT = 143 DEST_SSL = false DEST_USER = 'USER' DEST_PASS = 'PASSWORT' # List of all Folder that should not be synced FOLDERS_EXCLUDE = [ '[Google Mail]', '[Google Mail]/Sent Mail', '[Google Mail]/Spam', '[Google Mail]/Trash' ] # 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) # Getting the folders to sync folders = Array.new source.list("", "%").each do |mailbox| if FOLDERS_EXCLUDE.include?(mailbox.name) == false folders << mailbox.name end if mailbox.attr.include?(Net::IMAP::NOSELECT) source.list("", "#{mailbox.name}/%").each do |mailboxChild| if FOLDERS_EXCLUDE.include?(mailboxChild.name) == false folders << mailboxChild.name end end end end #puts folders # Loop through folders and copy messages. folders.each do |foldername| # Open source folder in read-only mode. begin ds "selecting folder '#{foldername}'..." source.examine(foldername) rescue => e ds "error: select failed: #{e}" next end # Open (or create) destination folder in read-write mode. begin dd "selecting folder '#{foldername}'..." dest.select(foldername) rescue => e begin dd "folder not found; creating..." dest.create(foldername) dest.select(foldername) 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 # Loop through all messages in the source folder. uids = source.uid_search(['ALL']) if uids.length > 0 source.uid_fetch(uids, ['ENVELOPE']).each do |data| 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}..." 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}..." dest.append(foldername, msg.attr['RFC822'], msg.attr['FLAGS'], msg.attr['INTERNALDATE']) end end # Build a lookup hash of all message ids present in the source folder. source_info = {} dd 'analyzing source messages...' uids = source.uid_search(['ALL']) if uids.length > 0 source.uid_fetch(uids, ['ENVELOPE']).each do |data| source_info[data.attr['ENVELOPE'].message_id] = true end end # Loop through all messages in the source folder. uids = dest.uid_search(['ALL']) if uids.length > 0 dest.uid_fetch(uids, ['ENVELOPE']).each do |data| mid = data.attr['ENVELOPE'].message_id # If this message is already in the destination folder, skip it. next if source_info[mid] # Setting flag for deletion ds "deleting message #{mid}..." dest.store(data.seqno, "+FLAGS", [:Deleted]) end end dest.expunge source.close dest.close end puts 'done' |
Kategorien: Blog |

16.10.2008 um 11:54
[...] winnie: 31 Days of iPhone Apps, Googlemail Backup mit IMAP [...]
11.12.2008 um 14:59
Hi Winnie!
Ich habs im Cast schon kurz gehört und grad nach der heutigen BitsundSo Folge nochmal hier gelsen.
Du kannst den selben Effekt auch wunderbar mit dem Imapfilter erreichen (http://imapfilter.hellug.gr/) der auch wunderbar auf BSD läuft.
Bei mir filtert er auf dem FreeBSD Mailserver die Mails in Unterordner. Er unterstützt aber auch mehrere Mailserver. Damit ist das Backup 1 Zeile auf der Shell.
LG Marius