Mu4e

Wie archiviert man 300.000 E-Mails?

12.11.2017

Früher habe ich eine Zeit lang mutt und gnus benutzt, um E-Mails zu lesen. Mutt ist ein Mailprogramm für die Kommandozeile. Mit Neomutt ist gerade ein Nachfolger dieses beliebten Programms erschienen. Gnus ist vermutlich der beste Newsreader, den es je gab. Ich habe ihn früher sowohl für News als auch für Mail benutzt. Seit dem Ende des Usenets kann gnus seine Stärken aber nicht mehr richtig ausfahren. Seine E-Mail-Funktionen waren immer ein wenig umständlich implementiert.

Doch das ist schon lange Vergangenheit. Heute nutze ich Thunderbird. Im Großen und Ganzen bin ich mit dem Programm auch zufrieden. Ab und zu probiere ich andere Mailer wie KMail, Evolution oder Claws aus, um nach wenigen Tagen festzustellen, dass ich mit ihnen nicht warm werde.

Thunderbird, KMail bzw. KOrganizer und Evolution haben auch Kalender- und Adressbuchfunktionen, die über CardDAV und CalDAV mit Online-Diensten synchronisiert werden können. Thunderbird und Evolution konnte ich für Mailbox.org konfigurieren. KOrganizer funktioniert dagegen mit der OX-Suite von Mailbox.org nicht.

All diese Programme sind nur bedingt geeignet, um in einem größeren E-Mail-Konvolut nach bestimmten Nachrichten zu suchen. Deshalb habe ich mich nach Programmen umgesehen, die für die E-Mail-Suche konzipiert wurden. Zwei habe ich genauer unter die Lupe genommen.

  1. Notmuch
  2. mu4e

Vermutlich gibt es noch eine Reihe anderer Programme, die E-Mails indizieren und durchsuchbar machen, aber meine Zeitressourcen sind begrenzt.

Offlineimap

Beide Programme gehen davon aus, dass alle Nachrichten im Maildir-Format lokal vorhanden sind. Das war bei mir natürlich nicht der Fall, da ich wie heutzutage fast alle IMAP nutze.

Bevor ich also daran gehen konnte, die Programme selbst zu testen, musste ich eine Lösung finden, die meine IMAP-Konten mit lokalen Maildir-Ordnern synchronisiert. Im Umfeld von mutt wurde ich auch schnell fündig: Offlineimap.

Das Programm ist schon etwas älter. Wird aber immer noch gepflegt. Auf der Website des Programm wird man von der verwirrenden Nachricht empfangen, dass man die Entwicklung von Offlineimap zugunsten von imapfw aufgegeben habe. Da ich aber nirgends eine funktionierende Beispiel-Konfiguration für imapfw finden konnte, habe ich doch Offlineimap genommen.

Die Konfiguration von Offlineimap ist recht einfach. Ich hatte lediglich Schwierigkeiten, einen Weg zu finden, meine Passwörter nicht in der Konfiguration zu benutzen. Im Web findet man dazu verwirrend viele Lösungsvorschläge. Da ich für meine Passworte den Unix Passwordstore benutze, habe ich schließlich die unten skizzierte Lösung genommen.

Meine Konfiguration von Offlineimap sieht folgendermaßen aus:

[general]
accounts = Job, Privat
pythonfile = /.offlineimap.py

Im Abschnitt general werden die E-Mailkonten, die abgearbeitet werden müssen, aufgezählt. Außerdem gebe ich hier eine Python-Datei an, die später für das Auslesen der Passwörter aus meinem Passwordstore benötigt wird.

Dann wird definiert, wie die einzelnen E-Mailkonten aufgebaut sind.

[Account Job]
localrepository = Job-local
remoterepository = Job-remote
# postsynchook = ~/.scripts/notmuch-hook.sh 

[Account Privat]
localrepository = Privat-local
remoterepository = Privat-remote 
# postsynchook = ~/.scripts/notmuch-hook.sh 

Sie bestehen aus einem lokalen und einem entfernten Repository. Die auskommentierte Zeile brauche ich nicht mehr. Sie sorgte ursprünglich dafür, dass nach der Synchronisation der Mailindexer Notmuch aufgerufen wird.

Anschließend werden die lokalen und die entfernten Repositories definiert. Zunächst die lokalen:

[Repository Job-local]
type = Maildir
localfolders = ~/Maildir/job

[Repository Privat-local]
type = Maildir
localfolders = ~/Maildir/privat

Die lokalen Repositories sind vom Typ Maildir und befinden sich in den Ordnern ~/Maildir/job und ~/Maildir/privat.

Die Definition der entfernten Repositories ist länger.

[Repository Job-remote]
type = IMAP
remotehost = imap.host1
remoteuser = "juh-job"
remotepasseval = passwd('job')
sslcacertfile = /etc/ssl/certs/ca-certificates.crt

[Repository Job-remote]
type = IMAP
remotehost = imap.host2
remoteuser = "juh-privat"
remotepasseval = passwd('privat')
sslcacertfile = /etc/ssl/certs/ca-certificates.crt

Diesmal ist der Typ IMAP. Danach werden der IMAP-Host, der IMAP-Benutzer und das IMAP-Passwort festgelegt. Das Passwort kann auch direkt eingegeben werden. Dann lautet die entsprechende Zeile:

remotepass = geheimesPasswort

Ich werte aber die Funktion passwd aus, die in der Pythondatei definiert wird, deren Pfad oben unter [general] zu finden ist. Die Datei enthält nur eine einfache Funktion:

#!/usr/bin/python2

from subprocess import check_output

def passwd(account):
    return check_output('pass mail/{0}'.format(account),
                        shell=True).splitlines()[0]

Die Funktion passwd ruft das Programm pass mit dem entsprechenden Pfad zu dem gewünschten Mail-Passwort auf und gibt das Passwort zurück.

Die letzte Zeile in der Konfiguration der entfernten Repositories setzt den Pfad zu einer Zertifikatsdatei. Ich habe die Angabe aus einem Beispiel übernommen. Bei mir hat diese Konfiguration nicht auf Anhieb funktioniert. Erst nach mehrmaligem Aufruf lief es dann plötzlich. Warum, ist mir schleierhaft. Aber ich kenne mich mit Zertifikaten auch nicht aus. Unter Debian musste ich jedenfalls nichts nachinstallieren.

Nun kann man mit dem Befehl offlineimap die Mails synchronisieren.

$ offlineimap

Das erstmalige Herunterladen der Nachrichten dauert selbstverständlich länger. Danach geht es recht flott.

Die Idee mit dem Mail-Archiv

Nun habe ich aber keine zwei Mailkonten, sondern sieben, sodass der Befehl offlineimap doch eine geraume Zeit benötigt, um alle sieben Konten abzufragen. Für meine Ansprüche dauert das zu lange. Ich möchte direkt und ohne Zeitverzug auf ein E-Mail-Konto zugreifen. Mutt kann mit lokalen Nachrichten deutlich schneller arbeiten als mit Nachrichten auf einem IMAP-Server. Aber Thunderbird versteckt das Nachladen von Nachrichten im Hintergrund, sodass man kaum merkt, dass man mit IMAP-Konten arbeitet. Ich war mir also nach der Einrichtung nicht mehr sicher, ob dies eine Lösung auf Dauer sein wird.

Doch dann kam mir die Idee, mit Hilfe von Offlineimap meine E-Mails zu archivieren. Damit hätte ich auch gleich ein Backup meiner Nachrichten. Außerdem könnte ich bei dieser Gelegenheit auch gleich die verstreuten Backups meiner E-Mails unter einer Lösung verfügbar machen. Meine Backups gehen zurück bis ins Jahr 1997. Sehr unsystematisch habe ich – meistens jahrgangsweise – ein Backup erstellt und auf CD abgespeichert. Der größte Teil der Archive liegt im mbox-Format vor. Einige Zeiträume sind aber auch im Gnus-Format gespeichert.

Mit dem Programm mb2md kann man zumindest die mbox-Dateien in Maildir-Nachrichten konvertieren. Also habe ich mich einen Tag hingesetzt bzw. bin aufgestanden und in den Keller gegangen, die alten CDs mit meinen E-Mail-Archiven von früher hochzuholen und zu importieren.

In den 20 Jahren seit 1997 haben sich über 300.000 Nachrichten angesammelt. Der größte Teil davon sind Mailinglisten-Nachrichten, die ich vermutlich nicht archivieren werde. Aber trotzdem habe ich erst einmal alles importiert.

Und dann habe ich Notmuch diesen Wust indizieren lassen.

Too much for Notmuch

Um es kurz zu machen. Notmuch hat das nicht geschafft. Das Programm hat auf halbem Wege schlapp gemacht.

Auf der Homepage von Notmuch verspricht der Entwickler, dass für Notmuch auch ganz viele E-Mails not much seien. Meine Erfahrungen sind leider anders.

In der Testphase, als ich nur die aktuellen E-Mails von meinen Konten synchronisiert habe, funktionierte alles noch recht performant. Als ich aber die alten Mails eingespielt hatte, kam Notmuch nicht mehr mit. Die 11 Minuten Restlaufzeit in dem Screenshot wuchsen nach knapp der Hälfte der E-Mails auf über anderthalb Stunden an. Dabei legte Notmuch den gesamten Rechner lahm und schien nach rund 150.000 Nachrichten nicht mehr richtig vorwärts zu kommen.

Ich habe die Sache nicht groß untersucht. Denn Notmuch war überdies auch noch schwer in neomutt zu integrieren. Ohne Integrierung in ein Mailprogramm kann man seine Mails zwar durchsuchen, aber beantworten kann man die gefundene Nachricht nicht.

Der folgende Schnipsel aus meiner Mutt-Konfiguration zeigt zum Beispiel die Einrichtung von virtuellen Mailboxen, in denen man Nachrichten nach bestimmten Kriterien gefiltert anzeigen kann.

virtual-mailboxes "unified inbox"   "notmuch://?query=tag:inbox&limit=1000"
virtual-mailboxes "unread"          "notmuch://?query=tag:new"
virtual-mailboxes "archive"         "notmuch://?query=tag:archive"
virtual-mailboxes "sent"            "notmuch://?query=tag:sent"
virtual-mailboxes "newsletter"      "notmuch://?query=tag:newsletter"
virtual-mailboxes "mailing list"    "notmuch://?query=tag:mailing_list"

Das hört sich nett an. Aber das Zurückspeichern von geänderten Tags erschien mir schon in der Testphase mit ein paar Tausend Nachrichten ziemlich langsam vonstatten zu gehen. Ich habe es daher mit Notmuch und Mutt nicht weiter versucht.

Mailindexer mu und das E-Mail-Programm mu4e

Neben Notmuch habe ich aber auch mu ausprobiert. Dieser Indexer mu kam mit den über 300.000 E-Mails problemlos zurecht. Der erste Aufbau des Indexes benötigte zwar ebenfalls einige Stunden, aber alle weiteren Indizierungsläufe waren dann nur noch eine Frage von wenigen Sekunden.

Das Beste an mu ist aber das E-Mail-Programm mu4e. Mu4e ist ein Mailprogramm für Emacs, das im Grunde eine Implementierung des Indexers mu in Emacs darstellt.

Wenn man das Programm startet, sieht man diesen Startscreen:

Die Basisbefehle lauten j, s und C. Mit j kann man einen Maildir-Ordner öffnen. Mit s formuliert man eine Suchanfrage an den Index. Und mit C schreibt man eine Nachricht.

Durch die Eingabe von s debian listet Mu4e alle Nachrichten auf, in denen der Begriff ›debian‹ vorkommt.

Besonders praktisch sind die Lesezeichen (Bookmarks), mit denen man zu vordefinierten Suchen springt. Die Tastenfolge b u listet beispielsweise alle ungelesenen Nachrichten auf.

Eigene Bookmarks können in der Konfigurationsdatei .emacs definiert werden. Mit den folgenden Zeilen erstellt man ein Lesezeichen für Nachrichten, die Anhänge wie Word-Dokumente oder PDF-Dateien enthalten.

add-to-list 'mu4e-bookmarks
         (make-mu4e-bookmark
          :name "Anhänge: DOC/PDF"
          :query "mime:application/vnd*"
          :key ?a))

Nach dem Neuladen der Konfiguration wird das Lesezeichen auf dem Startbildschirm angezeigt.

Um Mu4e als E-Mailprogramm nutzen zu können, muss man natürlich seine Konten in der Konfiguration eintragen. Um mit mehreren Konten arbeiten zu können, besitzt Mu4e sogenannte Kontexte. Man kann mehrere Kontexte definieren, passend zu den entsprechenden E-Mail-Konten, die man hat. Hier eine Beispieldefinition für ein berufliches und ein privates E-Mail-Konto:

(setq mu4e-contexts
 `( ,(make-mu4e-context
     :name "Job"
     :match-func (lambda (msg) (when msg
       (mu4e-message-contact-field-matches msg 
                            :to "jan.ulrich@hasecke.com")))
     :vars '(
       (mu4e-trash-folder . "/job/INBOX.Trash")
       (mu4e-refile-folder . "/job/INBOX.Archives")
       (mu4e-sent-folder . "/job/INBOX.Sent")
       ( user-mail-address      . "jan.ulrich@hasecke.com"  )
       ( user-full-name         . "Jan Ulrich Hasecke" )
       (smtpmail-smtp-server . "imap.host1")
       (smtpmail-smtp-user . "job")
       (smtpmail-smtp-service . "587")
       ))
   ,(make-mu4e-context
     :name "Privat"
     :match-func (lambda (msg) (when msg
       (string-prefix-p "/privat" (mu4e-message-field msg :maildir))))
     :vars '(
       (mu4e-trash-folder . "/privat/INBOX.Trash")
       (mu4e-refile-folder . "/privat/INBOX.Archives")
       (mu4e-sent-folder . "/privat/INBOX.Sent")
       ( user-mail-address      . "juh@example.com"  )
       ( user-full-name         . "Jan Ulrich Hasecke" )
       (smtpmail-smtp-server . "imap.host2")
       (smtpmail-smtp-user . "privat")
       (smtpmail-smtp-service . "587")
       ))
   ))

Im Netz schwirren ältere Konfigurationen herum, die sich auf frühere Versionen von Mu4e beziehen, in denen es die Kontext-Funktion noch nicht gab. Ich musste etwas herumprobieren, bis ich endlich die richtige Konfiguration heraus hatte. Die Dokumentation ist m.E. auch keine große Hilfe für Einsteiger.

Mu4e verwaltet Passwörter in der Datei .authinfo. In .emacs braucht man kein Passwort anzugeben. Es wird automatisch abgefragt und in .authinfo für künftige Aufrufe gespeichert. Wie man die Passwörter verschlüsselt in Mu4e einbindet, habe ich bisher nicht herausgefunden.

Doch kommen wir zum Startbildschirm zurück. Mit der Taste U ruft man via offlineimap neue Mails ab und starte anschließend den Indexer. Bei sieben Konten dauert dies – wie oben bereits erwähnt – fast anderthalb Minuten, sodass ich mir noch nicht sicher bin, ob Mu4e sich für den täglichen Gebrauch eignet. Vielleicht sollte man offlineimap über cron im Hintergrund aufrufen, sodass man mit U bloß noch den Index aktualisieren muss.

Aber durch Mu4e habe ich nun alle Mails von 1997 bis 2017 schnell auffindbar archiviert. Sie liegen in einem vereinheitlichten Format vor und können auch schnell zwecks Backup auf eine externe Platte gespiegelt werden. Das Auffinden älterer E-Mails ist in Sekundenbruchteilen erledigt.

Fazit

Was habe ich erreicht?

  1. Ich habe ein lokales Backup meiner IMAP-Konten.
  2. Ich habe ein einheitliches E-Mail-Archiv aller E-Mails von 1997 bis heute.
  3. Ich kann das gesamte Archiv mit Mu4e bequem durchsuchen.
  4. Ich habe mit Mu4e ein Mailprogramm, mit dem ich viele Arbeitsschritte schneller erledige als mit Thunderbird.
  5. Die Nachrichten von meinen IMAP-Servern sind lokal gespiegelt. Um sie zu archivieren und auf dem Server zu löschen, muss ich sie bloß in einen separaten Archiv-Ordner im Maildir-Verzeichnis kopieren. Damit habe ich endlich einen halbwegs geordneten Archivierungs-Workflow.

Was funktioniert noch nicht?

  1. Einige Backups sind im Gnus-Format. Um sie zu konvertieren, muss ich mich noch einmal in Gnus einarbeiten.
  2. Die Nachrichten auf meinem Mailbox.org-Konto sind verschlüsselt. Sie werden zwar problemlos entschlüsselt, aber auf meinem Desktop-Rechner in Mu4e nicht sofort angezeigt. Erst beim zweiten Aufruf einer Nachricht wird der Text des verschlüsselten Anhangs angezeigt. Auf meinem Notebook (ebenfalls ausgestattet mit Debian Stretch) funktioniert dagegen alles problemlos.