Metadata-Version: 2.3
Name: amelis2dame
Version: 0.2.1
Summary: A library and CLI tool to fetch and decrypt S/MIME encrypted emails and extract PDF attachments.
Keywords: email,smime,decryption,imap,attachments
Author: Christian Gonzalez
Author-email: Christian Gonzalez <office@nerdocs.at>
License: GPL-3.0-or-later
Requires-Dist: imapclient
Requires-Dist: python-dotenv
Requires-Dist: cryptography
Requires-Dist: endesive
Requires-Dist: pypdf
Requires-Dist: pydifact-aek>=0.1.1
Requires-Python: >=3.13
Project-URL: Homepage, https://gitlab.com/nerdocs/amelis2dame
Project-URL: Repository, https://gitlab.com/nerdocs/amelis2dame
Project-URL: Issues, https://gitlab.com/nerdocs/amelis2dame/-/work_items
Description-Content-Type: text/markdown

# amelis2dame

A CLI tool and Python library that connects to an IMAP mailbox, fetches S/MIME encrypted emails, decrypts them using a P12/PFX certificate, extracts PDF attachments, and optionally converts them to AEK-EDIFACT (DAME) documents.

## Features

- Connect to any IMAP server and filter emails by subject keyword
- Decrypt S/MIME encrypted emails using P12/PFX certificates (RSA-OAEP)
- Deduplicate emails with the same subject (keeps the most recent)
- Extract PDF attachments to a configurable output directory
- Rename PDFs using data extracted from the PDF content
- Convert PDFs to AEK-EDIFACT (.bef) DAME documents
- Flexible post-processing: mark as seen, delete, or move to a folder
- Configure via `.env` file, custom config file, or CLI arguments

## Requirements

- Python 3.13+
- Linux/Debian system packages: `libssl-dev swig python3-dev gcc`

## Quick Start

### 1. Install system dependencies (Linux/Debian)

```bash
sudo apt-get install libssl-dev swig python3-dev gcc
```

### 2. Install amelis2dame

```bash
pip install amelis2dame
```

### 3. Create your configuration file

```bash
cp .env.example .env
```

Edit `.env` with your IMAP credentials and certificate path:

```ini
IMAP_SERVER=imap.example.com
IMAP_PORT=993
EMAIL_ACCOUNT=you@example.com
EMAIL_PASSWORD=your_imap_password

P12_CERTIFICATE_PATH=./certificate.p12
PFX_PASSWORD=your_certificate_password

SAVE_DIRECTORY=./output
SUBJECT_KEYWORD=Auftrag
```

### 4. Run

```bash
amelis2dame
```

PDFs are extracted to `./output/` by default.

## Configuration

Configuration is loaded in this priority order: **CLI argument > config file > `.env` file > default**.

### Configuration file

By default, amelis2dame looks for a `.env` file in the current working directory.
Use `--config` to point to a different file:

```bash
amelis2dame --config /etc/amelis2dame/production.env
```

### All configuration options

| Variable | CLI flag | Default | Description |
|---|---|---|---|
| `IMAP_SERVER` | `--imap-server` | — | IMAP server hostname |
| `IMAP_PORT` | `--imap-port` | `993` | IMAP server port |
| `EMAIL_ACCOUNT` | `--imap-user` | — | IMAP login username |
| `EMAIL_PASSWORD` | `--imap-pass` | — | IMAP password |
| `P12_CERTIFICATE_PATH` | `--cert` | — | Path to P12/PFX certificate |
| `PFX_PASSWORD` | `--password` | `""` | Certificate password |
| `SAVE_DIRECTORY` | `--output` | `./output` | Output directory for PDFs |
| `SUBJECT_KEYWORD` | `--subject` | `Auftrag` | Subject keyword filter |
| `EMAIL_ACTION` | `--email-action` | `mark_seen` | Action after processing |
| `DUPLICATE_ACTION` | `--duplicate-action` | `mark_seen` | Action for older duplicates |
| `RENAME_PATTERN` | `--rename` | — | PDF rename pattern (see below) |

The `.env.example` file in the repository contains all options with comments.

## Usage

### Run with `.env` config

```bash
amelis2dame
```

### Override specific settings

```bash
amelis2dame --subject "Invoice" --output ./invoices
```

### Use a custom config file

```bash
amelis2dame --config /path/to/custom.env
```

### Full CLI — no config file needed

```bash
amelis2dame \
  --imap-server imap.example.com \
  --imap-port 993 \
  --imap-user you@example.com \
  --imap-pass secret \
  --cert certificate.p12 \
  --password pfx_pass \
  --subject "Auftrag" \
  --output ./output \
  --email-action delete \
  --duplicate-action "move:Archive"
```

### Verbose output

```bash
amelis2dame -v
```

### Show help

```bash
amelis2dame --help
```

## Post-processing actions

After an email is processed, amelis2dame performs one of the following actions.
This applies to both `EMAIL_ACTION` (successfully processed emails) and `DUPLICATE_ACTION` (older emails with the same subject).

| Action | Effect |
|---|---|
| `mark_seen` | Mark the email as read (default) |
| `delete` | Permanently delete the email |
| `move:FolderName` | Move to the specified IMAP folder |

Example with folder move:

```ini
EMAIL_ACTION=move:Processed
DUPLICATE_ACTION=delete
```

## PDF renaming

Set a `RENAME_PATTERN` (or `--rename`) to rename extracted PDFs using data extracted from the PDF content.

```ini
RENAME_PATTERN="{last_name}_{first_name}_{birth_date}_{barcode_number}.pdf"
```

Available variables:

| Variable | Description |
|---|---|
| `{last_name}` | Last name from PDF |
| `{first_name}` | First name from PDF |
| `{birth_date}` | Birth date (DD.MM.YYYY) |
| `{barcode_number}` | Barcode / sample ID |
| `{samplecollectiondate}` | Sample collection date (DD.MM.YYYY) |
| `{receipt_datetime}` | Receipt date and time (DD.MM.YYYY HH:MM) |
| `{finalreport}` | Final report date (DD.MM.YYYY) |
| `{samplecollectiondate_yyyymmdd}` | Sample collection date (YYYYMMDD) |
| `{receipt_datetime_yyyymmdd}` | Receipt date (YYYYMMDD) |
| `{finalreport_yyyymmdd}` | Final report date (YYYYMMDD) |

Example patterns:

```ini
# Classic: surname_firstname_birthdate_barcode
RENAME_PATTERN="{last_name}_{first_name}_{birth_date}_{barcode_number}.pdf"

# Date-prefixed for chronological sorting
RENAME_PATTERN="{finalreport_yyyymmdd}_{last_name}_{barcode_number}.pdf"

# Lab-style with sample date
RENAME_PATTERN="Lab_{barcode_number}_{samplecollectiondate_yyyymmdd}.pdf"
```

Leave `RENAME_PATTERN` empty (or omit `--rename`) to keep original filenames.

## DAME / AEK-EDIFACT output

amelis2dame can convert extracted PDFs into AEK-EDIFACT (`.bef`) DAME documents.
Both `--dame-sender` and `--dame-receiver` must be specified together.
The original PDF is replaced by the generated `.bef` file.

```bash
amelis2dame \
  --dame-sender "YOUR_SENDER_ID" \
  --dame-receiver "RECEIVER_ID"
```

Or in the `.env` file:

```ini
DAME_SENDER=YOUR_SENDER_ID
DAME_RECEIVER=RECEIVER_ID
```

## Workflow

When run, amelis2dame:

1. Connects to the IMAP server
2. Fetches emails matching the subject keyword
3. Deduplicates by subject — keeps the most recent, applies `DUPLICATE_ACTION` to older ones
4. Decrypts each S/MIME encrypted message
5. Extracts PDF attachments to `SAVE_DIRECTORY`
6. Optionally renames PDFs using `RENAME_PATTERN`
7. Optionally converts PDFs to DAME (`.bef`) documents
8. Applies `EMAIL_ACTION` to the processed email

## Security

- Never commit your `.env`, `.p12`, or `.pfx` files to version control. Add them to `.gitignore`.
- Restrict file permissions on certificates and config files: `chmod 600 .env certificate.p12`
- Use app-specific passwords for IMAP where available.
- The certificate's private key is only held in memory during decryption.

## Development

### Setup

```bash
sudo apt-get install libssl-dev swig python3-dev gcc
git clone https://gitlab.com/nerdocs/amelis2dame.git
cd amelis2dame
uv sync
```

### Commands

```bash
# Format code
black src/

# Run tests
pytest

# Run tests with coverage
pytest --cov=amelis2dame --cov-report=term-missing

# Verbose tests
pytest -v
```

## Architecture

The library lives in `src/amelis2dame/`:

| Module | Responsibility |
|---|---|
| `certificate.py` | Load and validate P12/PFX certificates |
| `imap.py` | IMAP connection, fetch, and email actions |
| `smime.py` | S/MIME decryption |
| `attachment.py` | Extract PDF attachments from decrypted messages |
| `pdf_parser.py` | Extract data from PDFs and apply rename patterns |
| `dame.py` | Generate AEK-EDIFACT (.bef) DAME documents |
| `cli.py` | CLI entry point and orchestration |

### Use as a library

```python
from amelis2dame import SMIMECertificate, MailboxClient, decrypt_email, extract_attachments

cert = SMIMECertificate.from_p12("certificate.p12", "password")

with MailboxClient("imap.example.com", 993, "user@example.com", "pass") as mailbox:
    emails = mailbox.fetch_emails(subject="Auftrag")
    for email_id, msg in emails:
        decrypted = decrypt_email(msg, cert)
        if decrypted:
            saved = extract_attachments(decrypted, "./output")
```

## License

GPL-3.0-or-later

## Links

- Repository: https://gitlab.com/nerdocs/amelis2dame
- Issues: https://gitlab.com/nerdocs/amelis2dame/-/work_items
