auf dot_env umgestellt
This commit is contained in:
@@ -1,131 +1,144 @@
|
||||
# README: ICS-Importer für mailbox.org unter Linux
|
||||
# ICS-Importer für mailbox.org unter Linux
|
||||
|
||||
Dieses Projekt durchsucht ein mailbox.org-Postfach per IMAP nach `.ics`-Anhängen und importiert enthaltene Termine anschließend per CalDAV in einen mailbox.org-Kalender. mailbox.org dokumentiert Thunderbird/IMAP für E-Mail und CalDAV für Kalender; die CalDAV-URL des Zielkalenders wird in mailbox.org im Kalender über **Eigenschaften** angezeigt. [kb.mailbox](https://kb.mailbox.org/de/privat/e-mail/e-mail-einrichtung-mit-mozilla-thunderbird/)
|
||||
Dieses Projekt durchsucht ein mailbox.org-Postfach per IMAP nach E-Mails mit `.ics`-Anhängen und importiert enthaltene Termine automatisch per CalDAV in einen mailbox.org-Kalender.[cite:55][cite:45]
|
||||
|
||||
## Überblick
|
||||
|
||||
Der technische Ablauf ist bewusst einfach gehalten:
|
||||
|
||||
1. Das Python-Skript verbindet sich per IMAP mit mailbox.org und durchsucht einen Ordner, standardmäßig `INBOX`.[cite:56][cite:55]
|
||||
2. Es erkennt `.ics`-Anhänge, berechnet einen Hash als Duplikat-Schutz und verarbeitet nur neue Anhänge.
|
||||
3. Die Termine werden per CalDAV in den gewünschten mailbox.org-Kalender geschrieben, dessen URL in mailbox.org über die Kalendereigenschaften ermittelt wird.[cite:45][cite:51]
|
||||
4. Die Ausführung erfolgt manuell oder stündlich per Cron.
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
Benötigt werden ein Linux-System, Python 3, `pipenv`, ein mailbox.org-Konto sowie Zugangsdaten für IMAP und CalDAV. Wenn bei mailbox.org die Zwei-Faktor-Authentifizierung aktiv ist, sollen für externe Anwendungen App-Passwörter beziehungsweise Applikationspasswörter verwendet werden. [kb.mailbox](https://kb.mailbox.org/de/business/adressbuch-und-kalender/caldav-bei-thunderbird/)
|
||||
Benötigt werden:
|
||||
|
||||
## Projektinhalt
|
||||
- Linux
|
||||
- Python 3
|
||||
- `pipenv`
|
||||
- Ein mailbox.org-Konto
|
||||
- Zugriff auf IMAP und CalDAV
|
||||
- Bei aktiver Zwei-Faktor-Authentifizierung ein App- bzw. Applikationspasswort für externe Anwendungen.[cite:63][cite:45]
|
||||
|
||||
Die typische Struktur des Projekts sieht so aus:
|
||||
## Projektstruktur
|
||||
|
||||
```text
|
||||
ics-importer/
|
||||
├── ics_mail_importer.py
|
||||
├── config.ini.example
|
||||
├── config.ini
|
||||
├── ics_mail_importer_env.py
|
||||
├── .env.example
|
||||
├── .env
|
||||
├── imported_uids.txt
|
||||
├── ics_importer.log
|
||||
└── cron.log
|
||||
├── cron.log
|
||||
└── README.md
|
||||
```
|
||||
|
||||
`ics_mail_importer.py` ist das Hauptskript, `config.ini` enthält die Zugangsdaten, `imported_uids.txt` dient als Duplikat-Schutz, und `cron.log` kann die Ausgabe des Cron-Jobs aufnehmen. Der Duplikat-Schutz ist sinnvoll, weil bei wiederkehrender IMAP-Prüfung sonst identische ICS-Anhänge mehrfach verarbeitet würden. [github](https://github.com/Vilhjalmr26/import_ics)
|
||||
## Installation
|
||||
|
||||
## Installation mit pipenv
|
||||
Projektverzeichnis anlegen und Abhängigkeiten installieren:
|
||||
|
||||
In das Projektverzeichnis wechseln und die Python-Abhängigkeiten installieren:
|
||||
```bash
|
||||
mkdir -p ~/ics-importer
|
||||
cd ~/ics-importer
|
||||
pipenv install python-dotenv caldav icalendar
|
||||
```
|
||||
|
||||
`python-dotenv` liest Schlüssel-Wert-Paare aus einer `.env`-Datei und stellt sie als Umgebungsvariablen bereit.[cite:162][cite:164]
|
||||
|
||||
## Konfiguration mit `.env`
|
||||
|
||||
Eine `.env.example` kann als Vorlage verwendet werden:
|
||||
|
||||
```dotenv
|
||||
IMAP_HOST=imap.mailbox.org
|
||||
IMAP_PORT=993
|
||||
IMAP_USERNAME=ihr-name@mailbox.org
|
||||
IMAP_PASSWORD=IHR_PASSWORT_ODER_APP_PASSWORT
|
||||
IMAP_FOLDER=INBOX
|
||||
IMAP_UNSEEN_ONLY=true
|
||||
IMAP_MARK_AS_READ=false
|
||||
|
||||
CALDAV_URL=https://dav.mailbox.org/caldav/IHR_KALENDER_ID
|
||||
CALDAV_USERNAME=ihr-name@mailbox.org
|
||||
CALDAV_PASSWORD=IHR_PASSWORT_ODER_APP_PASSWORT
|
||||
```
|
||||
|
||||
Die IMAP-Standardwerte für mailbox.org sind `imap.mailbox.org`, Port `993`, SSL/TLS und die vollständige E-Mail-Adresse als Benutzername.[cite:56][cite:55]
|
||||
|
||||
Die vollständige CalDAV-URL des Zielkalenders wird in mailbox.org im Kalender über **Eigenschaften** angezeigt; für Thunderbird und andere Clients wird `https://dav.mailbox.org/caldav/XXX` verwendet, wobei `XXX` die individuelle Kalender-ID ist.[cite:45][cite:51]
|
||||
|
||||
`.env` lokal anlegen und schützen:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
chmod 600 .env
|
||||
nano .env
|
||||
```
|
||||
|
||||
## Bedeutung der Variablen
|
||||
|
||||
| Variable | Bedeutung |
|
||||
| --- | --- |
|
||||
| `IMAP_HOST` | mailbox.org IMAP-Server, normalerweise `imap.mailbox.org`.[cite:56] |
|
||||
| `IMAP_PORT` | IMAP-SSL-Port, normalerweise `993`.[cite:56] |
|
||||
| `IMAP_USERNAME` | mailbox.org-E-Mail-Adresse.[cite:55] |
|
||||
| `IMAP_PASSWORD` | Passwort oder E-Mail-App-Passwort bei aktiver 2FA.[cite:63] |
|
||||
| `IMAP_FOLDER` | Zu durchsuchender Ordner, meist `INBOX`. |
|
||||
| `IMAP_UNSEEN_ONLY` | Wenn `true`, werden nur ungelesene Mails geprüft. |
|
||||
| `IMAP_MARK_AS_READ` | Wenn `true`, werden verarbeitete Mails als gelesen markiert. |
|
||||
| `CALDAV_URL` | Vollständige CalDAV-URL des Zielkalenders.[cite:45] |
|
||||
| `CALDAV_USERNAME` | mailbox.org-E-Mail-Adresse als CalDAV-Benutzername.[cite:45] |
|
||||
| `CALDAV_PASSWORD` | Passwort oder Applikationspasswort bei aktiver 2FA.[cite:63][cite:45] |
|
||||
|
||||
## Python-Skript
|
||||
|
||||
Das Skript `ics_mail_importer_env.py` nutzt `python-dotenv`, `imaplib`, `email`, `icalendar` und `caldav`. `python-dotenv` ist speziell dafür gedacht, Werte aus einer `.env`-Datei zu laden und als Umgebungsvariablen verfügbar zu machen.[cite:162][cite:164]
|
||||
|
||||
Beispielhafter Programmstart:
|
||||
|
||||
```bash
|
||||
cd ~/ics-importer
|
||||
pipenv install caldav icalendar
|
||||
pipenv run python3 ics_mail_importer_env.py
|
||||
```
|
||||
|
||||
`caldav` wird für den Zugriff auf den CalDAV-Kalender benötigt, während `icalendar` ICS-Dateien parst; für das Mail-Lesen werden Standardbibliotheken wie `imaplib` und `email` verwendet. [github](https://github.com/python-caldav/caldav)
|
||||
Das Skript erzeugt oder nutzt dabei unter anderem diese Dateien:
|
||||
|
||||
Den Interpreter-Pfad des Pipenv-Umfelds kann man mit folgendem Befehl prüfen:
|
||||
- `ics_importer.log` für die Programmausgabe
|
||||
- `imported_uids.txt` für den Duplikat-Schutz
|
||||
- optional `cron.log`, wenn die Cron-Ausgabe dorthin umgeleitet wird
|
||||
|
||||
## Erster Testlauf
|
||||
|
||||
Vor dem Cron-Einsatz sollte das Skript immer einmal manuell gestartet werden:
|
||||
|
||||
```bash
|
||||
pipenv run python3 ics_mail_importer_env.py
|
||||
```
|
||||
|
||||
Wenn die Zugangsdaten korrekt sind, verbindet sich das Skript mit IMAP, liest passende Anhänge und importiert neue Termine in den angegebenen CalDAV-Kalender.[cite:55][cite:45]
|
||||
|
||||
## Cron-Einrichtung
|
||||
|
||||
Den Python-Pfad des Pipenv-Umfelds ermitteln:
|
||||
|
||||
```bash
|
||||
cd ~/ics-importer
|
||||
pipenv --py
|
||||
```
|
||||
|
||||
Pipenv dokumentiert virtuelle Umgebungen und deren Interpreter-Pfade explizit; dieser Pfad ist später für Cron praktisch. [pipenv.pypa](https://pipenv.pypa.io/en/latest/virtualenv.html)
|
||||
|
||||
## Konfiguration
|
||||
|
||||
Die Vorlage kopieren und bearbeiten:
|
||||
|
||||
```bash
|
||||
cp config.ini.example config.ini
|
||||
nano config.ini
|
||||
```
|
||||
|
||||
Beispielinhalt:
|
||||
|
||||
```ini
|
||||
[imap]
|
||||
host = imap.mailbox.org
|
||||
port = 993
|
||||
username = ihr-name@mailbox.org
|
||||
password = IHR_PASSWORT_ODER_APP_PASSWORT
|
||||
folder = INBOX
|
||||
unseen_only = true
|
||||
mark_as_read = false
|
||||
|
||||
[caldav]
|
||||
url = https://dav.mailbox.org/caldav/IHR_KALENDER_ID
|
||||
username = ihr-name@mailbox.org
|
||||
password = IHR_PASSWORT_ODER_APP_PASSWORT
|
||||
```
|
||||
|
||||
Die IMAP-Einstellungen orientieren sich an mailbox.org für Thunderbird, und die CalDAV-URL des gewünschten Kalenders wird laut mailbox.org im Kalenderbereich über die Eigenschaften des Kalenders ermittelt. [kb.mailbox](https://kb.mailbox.org/de/privat/e-mail/e-mail-einrichtung-mit-mozilla-thunderbird/)
|
||||
|
||||
### Bedeutung der wichtigsten Optionen
|
||||
|
||||
| Schlüssel | Bedeutung |
|
||||
|---|---|
|
||||
| `imap.host` | IMAP-Server von mailbox.org: `imap.mailbox.org`. [kb.mailbox](https://kb.mailbox.org/de/privat/e-mail/e-mail-einrichtung-mit-mozilla-thunderbird/) |
|
||||
| `imap.port` | Standardport für IMAP über SSL: `993`. [kb.mailbox](https://kb.mailbox.org/de/privat/e-mail/e-mail-einrichtung-mit-mozilla-thunderbird/) |
|
||||
| `imap.folder` | Zu prüfender Ordner, meist `INBOX`. |
|
||||
| `imap.unseen_only` | Wenn `true`, werden nur ungelesene Nachrichten gesucht; das reduziert unnötige Prüfungen. |
|
||||
| `imap.mark_as_read` | Wenn `true`, markiert das Skript verarbeitete Nachrichten als gelesen. |
|
||||
| `caldav.url` | Vollständige CalDAV-URL des Zielkalenders aus mailbox.org. [kb.mailbox](https://kb.mailbox.org/de/business/adressbuch-und-kalender/caldav-bei-thunderbird/) |
|
||||
| `caldav.username` | Meist die mailbox.org-E-Mail-Adresse. [kb.mailbox](https://kb.mailbox.org/de/business/adressbuch-und-kalender/caldav-bei-thunderbird/) |
|
||||
| `caldav.password` | Passwort oder App-/Applikationspasswort bei aktiver 2FA. [kb.mailbox](https://kb.mailbox.org/de/business/adressbuch-und-kalender/caldav-bei-thunderbird/) |
|
||||
|
||||
## Erster Testlauf
|
||||
|
||||
Das Skript kann manuell getestet werden mit:
|
||||
|
||||
```bash
|
||||
cd ~/ics-importer
|
||||
pipenv run python3 ics_mail_importer.py
|
||||
```
|
||||
|
||||
Dabei werden neue `.ics`-Anhänge gesucht, importiert und im Log protokolliert. Python-Lösungen für IMAP-Anhangsextraktion und ICS-zu-CalDAV-Import folgen genau diesem Muster aus Mail-Abruf, Parsing und Import. [stackoverflow](https://stackoverflow.com/questions/6225763/downloading-multiple-attachments-using-imaplib)
|
||||
|
||||
## Stündliche Ausführung mit Cron
|
||||
|
||||
Die eigene User-Crontab wird mit `crontab -e` bearbeitet; User-Crontabs liegen auf Debian-/Raspberry-Pi-ähnlichen Systemen typischerweise unter `/var/spool/cron/crontabs/`, sollen aber nicht direkt bearbeitet werden. [cronitor](https://cronitor.io/guides/five-places-for-cron-jobs)
|
||||
|
||||
Für eine Ausführung **stündlich zur vollen Stunde** sieht der Eintrag so aus:
|
||||
Stündlicher Cron-Eintrag:
|
||||
|
||||
```cron
|
||||
0 * * * * /home/hans/.local/share/virtualenvs/ics-importer-wOz4rK-o/bin/python /home/hans/ics-importer/ics_mail_importer.py >> /home/hans/ics-importer/cron.log 2>&1
|
||||
0 * * * * /home/hans/.local/share/virtualenvs/ics-importer-wOz4rK-o/bin/python /home/hans/ics-importer/ics_mail_importer_env.py >> /home/hans/ics-importer/cron.log 2>&1
|
||||
```
|
||||
|
||||
Alternativ ist auch `@hourly` möglich; beide Varianten entsprechen einer stündlichen Ausführung, wobei die klassische Cron-Syntax mit `0 * * * *` die Ausführung zur Minute 0 jeder Stunde beschreibt. [wiki.ubuntuusers](https://wiki.ubuntuusers.de/Cron/)
|
||||
Die User-Crontab wird mit `crontab -e` gepflegt; die direkte Bearbeitung der Crontab-Dateien ist nicht empfehlenswert. Für stündliche Jobs sind sowohl `0 * * * *` als auch `@hourly` übliche Varianten.[cite:321][cite:55]
|
||||
|
||||
### Cron-Eintrag ohne eigenes Umleitungslog
|
||||
## Logrotation
|
||||
|
||||
Wenn die zusätzliche Datei `cron.log` nicht gewünscht ist, kann die Umleitung weggelassen werden:
|
||||
|
||||
```cron
|
||||
0 * * * * /home/hans/.local/share/virtualenvs/ics-importer-wOz4rK-o/bin/python /home/hans/ics-importer/ics_mail_importer.py
|
||||
```
|
||||
|
||||
## Logrotation für `cron.log`
|
||||
|
||||
Für benutzerdefinierte Logs ist `logrotate` der übliche Weg unter Linux. Eine eigene Datei unter `/etc/logrotate.d/` ist dafür die gängige Methode. [dash0](https://www.dash0.com/guides/log-rotation-linux-logrotate)
|
||||
|
||||
Beispiel:
|
||||
|
||||
```bash
|
||||
sudo nano /etc/logrotate.d/ics-importer
|
||||
```
|
||||
|
||||
Inhalt:
|
||||
Wenn `cron.log` mitgeschrieben wird, sollte die Datei per `logrotate` rotiert werden. Eine typische Konfiguration unter `/etc/logrotate.d/ics-importer` sieht so aus:
|
||||
|
||||
```conf
|
||||
/home/hans/ics-importer/cron.log {
|
||||
@@ -139,29 +152,61 @@ Inhalt:
|
||||
}
|
||||
```
|
||||
|
||||
Diese Konfiguration rotiert wöchentlich, behält vier alte Versionen, komprimiert alte Logs und legt nach der Rotation eine neue Datei mit passenden Rechten an. [putorius](https://www.putorius.net/rotating-custom-logs-with-logrotate-on.html)
|
||||
Damit wird das Log wöchentlich rotiert, vier Versionen bleiben erhalten und ältere Logs werden komprimiert.
|
||||
|
||||
Zum Testen der Konfiguration:
|
||||
## mailbox.org in Thunderbird
|
||||
|
||||
```bash
|
||||
sudo logrotate -d /etc/logrotate.d/ics-importer
|
||||
sudo logrotate -f /etc/logrotate.d/ics-importer
|
||||
```
|
||||
Für das eigentliche Projekt ist Thunderbird nicht zwingend nötig, aber mailbox.org empfiehlt für E-Mail in Thunderbird IMAP und für Kalender CalDAV.[cite:55][cite:45]
|
||||
|
||||
## Einfügen in vim-nox
|
||||
### IMAP in Thunderbird
|
||||
|
||||
Wenn `crontab -e` mit Vim geöffnet wird, kann im Insert-Modus oft direkt mit `Strg+Shift+V` aus dem Terminal-Zwischenspeicher eingefügt werden. Wenn Vim mit Clipboard-Unterstützung gebaut wurde, ist im Normal-Modus auch `"+p` zum Einfügen aus der System-Zwischenablage möglich. [reddit](https://www.reddit.com/r/vim/comments/q0fsw4/how_do_i_paste_clipboard_contents_into_vim/)
|
||||
Thunderbird erkennt mailbox.org in der Regel automatisch; empfohlen wird IMAP statt POP3.[cite:55][cite:63]
|
||||
|
||||
## Sicherheitshinweise
|
||||
### CalDAV in Thunderbird
|
||||
|
||||
`config.ini` enthält Zugangsdaten und sollte nicht weitergegeben oder in öffentliche Repositories eingecheckt werden. Bei aktivierter Zwei-Faktor-Authentifizierung empfiehlt mailbox.org für externe Anwendungen App-Passwörter beziehungsweise Applikationspasswörter anstelle des normalen Passworts. [kb.mailbox](https://kb.mailbox.org/de/business/adressbuch-und-kalender/caldav-bei-thunderbird/)
|
||||
Kalender lassen sich in Thunderbird über **Datei → Neu → Kalender → Im Netzwerk → CalDAV** einbinden. Als URL dient die vollständige mailbox.org-CalDAV-Adresse des Kalenders.[cite:45][cite:51]
|
||||
|
||||
In manchen Setups muss in Thunderbird zusätzlich `calendar.network.multirealm` auf `true` gesetzt werden, damit die Authentifizierung sauber funktioniert.[cite:45][cite:51]
|
||||
|
||||
## Sicherheit
|
||||
|
||||
`.env` enthält Zugangsdaten im Klartext und darf nicht in ein öffentliches Repository eingecheckt werden. `python-dotenv` ist für lokale Konfigurationsdateien gedacht, ersetzt aber kein Secret-Management-System.[cite:162][cite:164]
|
||||
|
||||
Empfehlungen:
|
||||
|
||||
- `.env` nur lokal speichern
|
||||
- `chmod 600 .env` setzen
|
||||
- `.env` in `.gitignore` eintragen
|
||||
- Bei aktiver 2FA App-/Applikationspasswörter statt des Hauptpassworts verwenden.[cite:63][cite:45]
|
||||
|
||||
## Fehlersuche
|
||||
|
||||
Wenn der Cron-Job nicht läuft, sind die häufigsten Ursachen ein falscher Python-Pfad, fehlende Rechte auf Dateien oder abweichende Umgebungsvariablen unter Cron. Cron-Jobs sollten deshalb mit absoluten Pfaden arbeiten, und ein separates Log wie `cron.log` macht Fehler schnell sichtbar. [betterstack](https://betterstack.com/community/guides/logging/how-to-manage-log-files-with-logrotate-on-ubuntu-20-04/)
|
||||
### IMAP funktioniert nicht
|
||||
|
||||
Wenn Termine nicht importiert werden, sollte zuerst geprüft werden, ob die IMAP-Anmeldung funktioniert, ob tatsächlich `.ics`-Anhänge im ausgewählten Ordner vorhanden sind und ob die CalDAV-URL exakt zum Zielkalender gehört. mailbox.org beschreibt, dass die Kalenderadresse direkt aus den Kalendereigenschaften des jeweiligen Kalenders übernommen werden soll. [kb.mailbox](https://kb.mailbox.org/de/privat/e-mail/e-mail-einrichtung-mit-mozilla-thunderbird/)
|
||||
Prüfen:
|
||||
|
||||
- `IMAP_HOST=imap.mailbox.org`
|
||||
- `IMAP_PORT=993`
|
||||
- vollständige E-Mail-Adresse als Benutzername
|
||||
- korrektes Passwort oder App-Passwort bei aktiver 2FA.[cite:56][cite:63]
|
||||
|
||||
### CalDAV funktioniert nicht
|
||||
|
||||
Prüfen:
|
||||
|
||||
- vollständige CalDAV-URL aus den Kalendereigenschaften in mailbox.org
|
||||
- korrekter Benutzername
|
||||
- korrektes Passwort bzw. Applikationspasswort bei aktiver 2FA.[cite:45][cite:51]
|
||||
|
||||
### Cron führt das Skript nicht aus
|
||||
|
||||
Prüfen:
|
||||
|
||||
- absoluter Python-Pfad aus `pipenv --py`
|
||||
- absoluter Skriptpfad
|
||||
- Schreibrechte für `cron.log`
|
||||
- manueller Testlauf funktioniert bereits
|
||||
|
||||
## Empfohlener Betriebsmodus
|
||||
|
||||
Für dieses Setup ist ein stündlicher Cron-Job mit aktiviertem Duplikat-Schutz und `unseen_only = true` ein pragmatischer Standard. Das reduziert unnötige IMAP-Abfragen und passt gut zu einem Postfach, in dem Termine typischerweise per Mail-Anhang eingehen. [naschenweng](https://www.naschenweng.eu/2025/03/29/%F0%9F%93%85-sync-ics-feeds-to-your-caldav-calendar-with-emojis-deduplication-and-docker/)
|
||||
Für die meisten Setups ist `IMAP_UNSEEN_ONLY=true` sinnvoll, damit nur neue bzw. ungelesene Mails geprüft werden. In Verbindung mit dem Hash-basierten Duplikat-Schutz verhindert das unnötige Doppelimporte und reduziert die Last auf dem Postfach.
|
||||
Reference in New Issue
Block a user