Nachdem ich von GMail zu einam anderen Anbieter gewechselt habe, wollte ich mir ein Offline-Archiv meines GMail-Accounts anlegen. Um das gut durchsuchbar zu machen, eignet sich Notmuch. Damit ist die Suchfunktion sehr mächtig und dje Labels in GMail lassen sich ganz gut als Tags von notmuch abbilden. Dazu müssen sie aber erst mal konvertiert werden. Wie das geht, erkläre ich in diesem Blogpost.

Voraussetzungen

Die Mails müssen alle lokal in einem Maildir vorliegen und jede Mail muss einen Header-Eintrag X-Keywords haben. Außerdem müssen alle Mails bereits bei notmuch indiziert sein. Das geht so:

Mails herunterladen

Um meine etwa 20000 Mails herunterzuladen (bei GMail hat man eben viel Speicher…), verwende ich offlineimap. Um neben der Übertragung der Labels dennoch unnötiges Duplizieren zu sparen, synchronisiere ich nur den „Alle Nachrichten“-Ordner.

Hintergrund: normaleweise bildet GMail seine Labels im IMAP als Ordner ab. Trägt eine Mail ein Label, existiert sie im gleichnamigen Unterordner, wenn man per IMAP auf das Postfach schaut. Trägt eine Mail mehrere Labels, existiert in jedem gleichnamigen Unterordner ein Duplikat. Außerdem gibt es immer zumindest ein weiteres Duplikat im Ordner Alle Nachrichten. Das ist für unsere Zwecke natürlich Quatsch – wir brauchen jede Mail nur einmal und die Tags bearbeiten wir ohnehin über notmuch und nicht über Ordner. Also folgendes Setup:

[Account gmail]
localrepository = gmail-local
remoterepository = gmail-remote
synclabels = yes
labelsheader = X-Keywords

[Repository gmail-local]
type = GmailMaildir
localfolders = ~/mail/gmail

[Repository gmail-remote]
type = Gmail
remoteuser = [email protected]
remotepass = EXAMPLE
ssl = yes
sslcacertfile = /etc/ssl/certs/ca-certificates.crt
folderfilter = lambda folder: folder.startswith('[Gmail]/All')

Hier wird also wirklich nur der eine Ordner synchronisiert, außerdem werden die Labels abgefragt und in den entsprechenden Header notiert. Einstellungen, bei denen EXAMPLE steht und der Pfad bei localfolders sind natürlich anzupassen.

Jetzt muss man sich etwas Zeit nehmen; der Download aller E-Mails dauert natürlich je nach Volumen recht lange. Der Vorgang wird gestartet durch einfachen Aufruf:

offlineimap

Notmuch einrichten

Ich habe eine eigene Konfigurationsdatei für notmuch angelegt, mit der ich nur im Archiv suche. Meine normalen Mails sind davon getrennt. Die Konfiguration ist ziemlich einfach:

[database]
path=/home/EXAMPLE/mail/gmail

[user]
name=EXAMPLE
[email protected]

[new]
tags=archive

[search]
exclude_tags=deleted,spam

[maildirs]
synchronize_flags=true

Hier sind wieder alle Vorkommen von EXAMPLE anzupassen. Neuen Mails, d.h. allen Mails, wird das Label archive zugewiesen. new, unread, inbox etc möchte ich im Archiv nicht.

Nun kann man, unter Angabe des Pfads zur Konfiguration von notmuch, die Datenbank initialisieren:

NOTMUCH_CONFIG=~/.notmuch-archiv notmuch new

Nun werden erst mal alle E-Mails in die Datenbank eingelesen und indiziert. Sie liegen dann dort schon vor, die Labels kommen aber erst im nächsten Schritt.

Labels zu Tags konvertieren

Nachdem die nötigen Voraussetzungen geschaffen wurden, ist die Ausgangssituation:

  1. Alle Mails des Ordners [Gmail]/Alle Nachrichten liegen auf der lokalen Festplatte
  2. Jede Mail trägt eine mit Kommas getrennte Liste ihrer Labels in einem Header-Attribut
  3. Die Mails sind in der Datenbank von notmuch, die labels wurden aber noch nicht eingelesen.

Um die Labels einzulesen, habe ich ein Script programmiert, welches die Python-API von notmuch nutzt, um in jeder Mail die Header nachzusehen und gegebenenfalls die dort hinterlegten Labels als Tags abzuspeichern: gmail2notmuch. Das Script braucht also als Voraussetzung Python und zweitens die Python-Bindings für notmuch. Unter Debian und Ubuntu sind die leicht zu installieren:

sudo apt-get install notmuch-python

Jetzt kann das Script aufgerufen werden:

git clone https://github.com/very-emmazing/gmail2notmuch.git
cd gmail2notmuch
./gmail2notmuch ~/.notmuch-archiv

Der Vorgang kann eine kurze Weile dauern, der Code ist sicherlich nicht auf optimale Rechenzeit und Nutzungsweise der API programmiert. Für 20000 Mails hat es andererseits bei mir aber auch keine ganze Minute gedauert.

Ist das Script durchgelaufen, sollten alle Einträge in der Datenbank mit den Labels aus GMail als Tag versehen sein.