# Saved Outlook `.msg` Email Archives → PDF Learning Materials

Use this when the user provides a ZIP of saved Outlook emails (`.msg`) and wants contained PDF learning/workbook material extracted into a local/Drive learning structure.

## Reliable workflow

1. **Download and inspect the ZIP**
   - Confirm entry count and extension distribution before extraction.
   - Example: use Python `zipfile` to count `.msg`, `.eml`, `.pdf`, etc.
2. **Use a disposable venv for `.msg` parsing**
   - `uv venv .venv && . .venv/bin/activate && uv pip install extract-msg`
   - Parse with `extract_msg.Message(path)`.
3. **Extract attachments, including nested `.msg`**
   - Outlook emails may contain another `.msg` as an attachment. Handle nested messages recursively.
   - Attachment `.data` can be bytes or already a `Message` object; support both.
4. **Deduplicate by SHA-256**
   - Email lesson archives often resend the same PDFs across messages.
   - Save only unique file hashes; inventory duplicate rows with `duplicate_of` pointing to the saved original.
5. **Preserve provenance in filenames and CSV**
   - Useful naming: `YYYY-MM-DD__Email-subject__Original-attachment-name.pdf`.
   - Create `00_Inventar_Anhaenge.csv` with at least: message date, subject, sender, original message filename, attachment name/ext, size, sha256, status, saved path, duplicate_of.
6. **Verify PDFs cheaply**
   - Count saved files and check each PDF starts with `%PDF` and has non-zero size.
   - Do not claim success from extraction alone.
7. **Upload/resume to Google Drive when needed**
   - Create target root folder plus subfolders such as `PDFs/`, `Weitere_Anhaenge_DOCX/`, `Weitere_Anhaenge_Sonstige/`.
   - For many files, list existing Drive children once per folder and compare names locally instead of running one search query per filename.
   - Retry upload failures; transient `no route to host` can happen mid-batch.

## Recommended output structure

```text
<Subject-or-Source>_Email_Anhaenge/
├── PDFs/
├── Weitere_Anhaenge_DOCX/
├── Weitere_Anhaenge_Sonstige/
├── 00_Inventar_Anhaenge.csv
├── 00_Zusammenfassung.json
└── README.md
```

## Pitfalls

- Filenames can contain apostrophes, curly quotes, accents, slashes, colons, or very long subjects. Sanitize path-hostile characters but keep enough original wording for recognition.
- Do not build Drive search queries from raw filenames containing `'`; either escape carefully or avoid per-file search by listing folder children once.
- Network hiccups during large Drive uploads are not proof of auth failure. Resume by comparing existing child names and uploading missing files.
- If `extract-msg` is absent, install it in a local `uv` venv for the job; do not modify system Python.
