# PROJ-19: Mailpiler → archivmail Migrationstool ## Status: Deployed **Created:** 2026-03-17 **Last Updated:** 2026-03-17 ## Dependencies - Requires: PROJ-5 (Speicherung & Indexierung) - Requires: PROJ-15 (CLI Import) ## User Stories - Als Admin möchte ich alle E-Mails aus einem bestehenden mailpiler-Archiv nach archivmail migrieren, damit ich die Plattform wechseln kann ohne E-Mails zu verlieren. - Als Admin möchte ich den Fortschritt der Migration in Echtzeit sehen. - Als Admin möchte ich Duplikate automatisch überspringen, damit bei Teil-Migrationen oder Wiederholungsläufen keine Daten doppelt archiviert werden. ## Acceptance Criteria - [x] Methode 1: `pilerexport`-Wrapper – ruft das mailpiler-eigene Export-Tool auf, importiert die EML-Dateien - [x] Methode 2: Direkt – liest `.m`-Dateien aus dem mailpiler Store-Verzeichnis, entschlüsselt (AES-256-CBC) und dekomprimiert (zlib) - [x] Automatische Methodenwahl (`--method auto`): pilerexport → direct - [x] Fortschrittsanzeige (importiert / übersprungen / Fehler) - [x] `--dry-run` Modus - [x] JSON-Ausgabe für Skripting - [x] Datums-Filter (`--date-from`, `--date-to`) für pilerexport-Methode ## Aufruf ```bash # Auf dem mailpiler-Server (pilerexport-Methode, empfohlen): archivmail import-piler \ --config /etc/archivmail/config.yml \ --method pilerexport # Mit Datumsfilter: archivmail import-piler \ --config /etc/archivmail/config.yml \ --date-from 2020-01-01 \ --date-to 2024-12-31 # Direkte Methode (kein mailpiler nötig, kein MySQL nötig): archivmail import-piler \ --config /etc/archivmail/config.yml \ --method direct \ --store-dir /var/piler/store \ --key-file /var/piler/store/piler.key # Nur Simulation (kein Speichern): archivmail import-piler --dry-run # JSON-Ausgabe für Skripte: archivmail import-piler --json ``` ## Technische Details | Aspekt | Detail | |--------|--------| | pilerexport-Ausgabe | EML-Dateien im temp-Verzeichnis, jede `.eml` = eine E-Mail | | mailpiler-Dateiformat | `{storedir}/**/{piler_id}.m` – AES-256-CBC verschlüsselt, zlib komprimiert | | Entschlüsselung | Erste 16 Bytes = IV, Rest = CBC-Ciphertext, Key aus `piler.key` (32 Bytes) | | Dekomprimierung | zlib (ohne AES falls kein Key vorhanden) | | Duplikat-Erkennung | Storage.Save() + IsIndexed() – identische Inhalts-Hashes werden übersprungen | | Keine ext. Abhängigkeiten | Nur Go stdlib (compress/zlib, crypto/aes) + vorhandene archivmail-Pakete |