duffyduckandClaude Opus 5.5 1b4f6ed34e redesign filter page: rule test, match stats, warnings, toggle
- Rule tester (POST /api/filters/test): evaluates an unsaved rule
  read-only against the newest matching mails in the source folder,
  using an IMAP SEARCH on the first text condition to narrow candidates.
  Shows matches, near misses with the failing condition, and whether
  any candidate had an attachment at all (would have caught the
  Klarmobil and it-moench misconfigurations immediately).
- Per-rule match_count / last_match_at (new migration), incremented by
  the scheduler on every match and shown in the list.
- PATCH /api/filters/{id}/enabled toggles a rule without resetting its
  processed state (a full PUT re-evaluates every mail for that rule).
- New filter list: cards with enable switch, priority, condition and
  action chips, match stats, and warnings (display name in from/to,
  "am (exakt)" date, duplicates, empty values, invalid regex, move
  without folder). Quick filters for active/inactive/warnings/never
  matched; copy-as-template; remembered account selection.
- Edit dialog: wider layout, live warnings, integrated test panel,
  sensible defaults for new rules (from + date after Jan 1 + move).
- Light global refresh: nav with active item, page background, cards.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 09:48:12 +02:00
2026-03-19 13:02:44 +01:00

IMAP Mail Filter Service

Ein Docker-basierter Service, der E-Mail-Filterregeln unabhängig vom Mail-Client ausführt. Egal ob du Evolution, Thunderbird oder einen anderen Client nutzt — die Filter laufen einfach weiter.

Features

  • Mehrere IMAP-Konten verwalten
  • Filterregeln mit flexiblen Bedingungen (Von, An, Betreff, Text)
  • Matching: enthält, exakt, Regex — jeweils mit Negierung
  • Aktionen: Verschieben, Weiterleiten, Löschen, Als gelesen markieren
  • Web-UI zur Verwaltung von Konten und Regeln
  • YAML Import/Export für portable Konfiguration
  • Passwort-Verschlüsselung mit Fernet
  • Konfigurierbares Polling-Intervall pro Konto

Schnellstart

1. .env erstellen

cp .env.example .env

Encryption-Key generieren und in die .env eintragen:

python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"

Falls cryptography noch nicht installiert ist:

pip install cryptography
python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"

Den ausgegebenen Key in die .env eintragen:

ENCRYPTION_KEY=dein-generierter-key-hier

2. Mit Docker starten

docker-compose up --build

Der Service ist dann unter http://localhost:8080 erreichbar.

3. Ohne Docker (lokal)

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
uvicorn app.main:app --reload

Erreichbar unter http://localhost:8000.

Benutzung

Web-UI

  • Dashboard (/) — Übersicht aller Konten mit Status und Quick-Actions
  • Konten (/accounts) — IMAP-Konten anlegen, bearbeiten, Verbindungstest
  • Filter (/filters) — Filterregeln pro Konto erstellen und verwalten
  • YAML (/yaml) — Konfiguration exportieren und importieren

REST-API

Endpunkt Beschreibung
GET /api/accounts/ Alle Konten auflisten
POST /api/accounts/ Neues Konto anlegen
PUT /api/accounts/{id} Konto bearbeiten
DELETE /api/accounts/{id} Konto löschen
POST /api/accounts/{id}/test IMAP-Verbindungstest
POST /api/accounts/{id}/poll-now Sofort nach neuen Mails prüfen
GET /api/filters/account/{id} Filterregeln eines Kontos
POST /api/filters/ Neue Filterregel
PUT /api/filters/{id} Filterregel bearbeiten
DELETE /api/filters/{id} Filterregel löschen
GET /api/yaml/export Konfiguration als YAML
POST /api/yaml/import YAML-Datei importieren

YAML-Konfiguration

Filterregeln können auch direkt als YAML definiert werden. Passwörter lassen sich als Umgebungsvariablen referenzieren:

accounts:
  - name: "Arbeit"
    imap_host: "imap.example.com"
    imap_port: 993
    use_ssl: true
    username: "user@example.com"
    password: "${WORK_IMAP_PW}"
    poll_interval_seconds: 120
    filters:
      - name: "Newsletter sortieren"
        priority: 10
        source_folder: "INBOX"
        stop_processing: true
        conditions:
          - field: "from"
            match_type: "contains"
            value: "newsletter@"
        actions:
          - action_type: "move"
            parameter: "Newsletter"

Beim Start wird config/filters.yaml automatisch importiert (konfigurierbar via YAML_SYNC_ON_STARTUP).

Umgebungsvariablen

Variable Standard Beschreibung
ENCRYPTION_KEY (leer) Fernet-Key für Passwort-Verschlüsselung
LOG_LEVEL INFO Log-Level (DEBUG, INFO, WARNING, ERROR)
YAML_SYNC_ON_STARTUP true YAML-Datei beim Start importieren
DATABASE_URL sqlite:///data/mailfilter.db Datenbank-Pfad

Datenbank-Migrationen

Die Datenbank wird automatisch beim Start per Alembic migriert — Konten und Filterregeln bleiben bei Updates erhalten.

Falls du lokal entwickelst und das Schema änderst:

# Neue Migration erstellen (nach Änderung an db_models.py)
.venv/bin/alembic revision --autogenerate -m "beschreibung der änderung"

# Migration anwenden
.venv/bin/alembic upgrade head

# Migrationsstatus prüfen
.venv/bin/alembic current

Im Docker passiert das automatisch beim Container-Start.

Projektstruktur

├── app/
│   ├── main.py              # FastAPI App + Web-Routen
│   ├── config.py             # Konfiguration via Umgebungsvariablen
│   ├── database.py           # SQLAlchemy Setup
│   ├── models/db_models.py   # Datenbank-Modelle
│   ├── schemas/schemas.py    # API Request/Response Schemas
│   ├── routers/              # REST-API Endpunkte
│   ├── services/
│   │   ├── imap_client.py    # IMAP-Verbindung und Mail-Aktionen
│   │   ├── filter_engine.py  # Regelauswertung
│   │   ├── scheduler.py      # Polling-Scheduler
│   │   ├── yaml_service.py   # YAML Import/Export
│   │   └── encryption.py     # Passwort-Verschlüsselung
│   ├── templates/            # Jinja2 HTML-Templates
│   └── static/               # CSS + JS
├── alembic/                   # Datenbank-Migrationen
│   ├── env.py
│   └── versions/              # Migrations-Skripte
├── config/filters.yaml       # YAML-Filterkonfiguration
├── data/                     # SQLite-Datenbank (Docker Volume)
├── docker-compose.yml
├── Dockerfile
└── requirements.txt

Tests

source .venv/bin/activate
python -m pytest tests/ -v
S
Description
No description provided
Readme
365 KiB
Languages
Python 61.5%
HTML 37%
CSS 0.6%
Shell 0.4%
Mako 0.3%
Other 0.2%