Files
janssen/EmailsImport/parse_emails_v1.0.md

323 lines
8.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# parse_emails_v1.0
**Název:** parse_emails_v1.0.py
**Verze:** 1.0
**Datum:** 2026-06-01
**Autor:** vladimir.buzalka
---
## Účel
Jednorázový import všech `.msg` souborů do MongoDB. Z každého souboru extrahuje **všechny dostupné vlastnosti** — podobně jako EXIF u fotek.
- **DB:** `emaily`
- **Kolekce:** `vbuzalka@its.jnj.com`
- `_id` = Internet Message-ID (nebo `filename:<stem>` jako fallback)
- Bezpečné přerušit a opakovat — upsert podle `_id`
---
## Zdroje dat
Výhradně `.msg` soubory — žádná závislost na SQLite ani jiné DB.
| Z každého .msg se extrahuje |
|---|
| Předmět, normalized subject |
| Odesílatel (email, jméno, SMTP adresa) |
| Příjemci To/CC/BCC — strukturovaně `[{type, email, name}]` |
| Čas doručení a odeslání (UTC) |
| Tělo plaintext + HTML (max 2 MB) |
| Přílohy — metadata: jméno, velikost, MIME typ, inline flag |
| Internet headers — X-Originating-IP, Received, DKIM, X-Mailer, ... |
| MAPI: důležitost, citlivost, příznak, konverzační vlákno, kategorie |
| In-Reply-To, References — pro rekonstrukci vlákna |
| Všechny raw MAPI properties jako `{0xXXXX: value}` |
---
## Konfigurace
Konstanty přímo v kódu:
| Konstanta | Hodnota |
|---|---|
| `MSGS_DIR` | `\\tower\JNJEMAILS` |
| `MONGO_URI` | `mongodb://192.168.1.76:27017` |
| `MONGO_DB` | `emaily` |
| `MONGO_COL` | `vbuzalka@its.jnj.com` |
| `BATCH_SIZE` | 200 dokumentů na jeden bulk_write |
| `LOG_FILE` | `parse_emails_errors.log` (vedle skriptu) |
---
## Spouštění
**Venv:** `U:\PythonProject\Janssen\.venv\Scripts\python.exe`
**1. spuštění — kompletní import:**
```cmd
"U:\PythonProject\Janssen\.venv\Scripts\python.exe" "U:\PythonProject\Janssen\EmailsImport\parse_emails_v1.0.py"
```
**Pokračování po přerušení (druhý den):**
```cmd
"U:\PythonProject\Janssen\.venv\Scripts\python.exe" "U:\PythonProject\Janssen\EmailsImport\parse_emails_v1.0.py" --skip-existing
```
**Test na malém vzorku:**
```cmd
"U:\PythonProject\Janssen\.venv\Scripts\python.exe" "U:\PythonProject\Janssen\EmailsImport\parse_emails_v1.0.py" --limit 50 --no-indexes
```
### Všechny parametry
| Parametr | Popis |
|---|---|
| `--skip-existing` | Načte seznam hotových souborů z MongoDB a přeskočí je. Použij pro pokračování po přerušení. |
| `--limit N` | Zpracuje jen prvních N souborů. Vhodné pro test. |
| `--no-indexes` | Nevytváří indexy na konci. Použij pokud je přerušíš uprostřed — indexy vytvoř ručně až je vše hotové. |
---
## Průběh na konzoli
Každý email na jednom řádku:
```
1/69371 OK RE: Protocol deviation CZ10022 jan.novak@its.jnj.com
2/69371 OK UCO3001: Draft FUL pro DD5-CZ10022 monitor@4gclinical.com
3/69371 ERR ? ?
```
Každých 500 emailů oddělovač s průběhem:
```
────────────────────────────────────────────────────────────────────────────────
Průběh: ok=498 err=2 0.4 msg/s ETA 47h12m
────────────────────────────────────────────────────────────────────────────────
```
Na konci souhrn:
```
====================================================
Vysledek: ok=69300 | skip=0 | err=71
Celkovy cas: 47h 23m 10s
Dokumentu v kolekci: 69300
```
---
## Struktura dokumentu v MongoDB
```json
{
"_id": "<message-id@domain>",
"filename": "7A3F...0000.msg",
"subject": "RE: Protocol deviation CZ10022",
"normalized_subject": "Protocol deviation CZ10022",
"importance": 1,
"sensitivity": 0,
"flag_status": 0,
"read_receipt_requested": false,
"delivery_receipt_requested": false,
"has_attachments": true,
"attachment_count": 1,
"message_size_bytes": 284512,
"conversation_topic": "Protocol deviation CZ10022",
"conversation_index": "AcqX...",
"in_reply_to": "<prev-id@domain>",
"internet_references": ["<ref1@domain>", "<ref2@domain>"],
"categories": ["UCO3001"],
"received_at": "2026-05-15T09:23:11",
"sent_at": "2026-05-15T09:21:44",
"sender": {
"email": "jan.novak@its.jnj.com",
"name": "Novák Jan",
"smtp": "jan.novak@its.jnj.com"
},
"to": "vladimir.buzalka@its.jnj.com",
"cc": "petra.free@its.jnj.com",
"bcc": "",
"display_to": "Buzalka Vladimir",
"display_cc": "Free Petra",
"recipients": [
{ "type": "to", "email": "vbuzalka@its.jnj.com", "name": "Buzalka Vladimir" },
{ "type": "cc", "email": "petra.free@its.jnj.com", "name": "Free Petra" }
],
"body_text": "Dobrý den,\n\nposílám...",
"body_html": "<html>...",
"attachments": [
{
"filename": "PD_report_CZ10022.pdf",
"size_bytes": 284512,
"mime_type": "application/pdf",
"content_id": null,
"is_inline": false
}
],
"headers": {
"message_id": "<xxx@domain>",
"x_originating_ip": "10.24.1.55",
"x_mailer": "Microsoft Outlook 16.0",
"received": ["from SMTP01...", "from EX2019..."],
"x_spam_status": "No"
},
"mapi": {
"0x0017": 1,
"0x0036": 0,
"0x0070": "Protocol deviation CZ10022",
"0x1035": "<message-id@domain>",
"0x1042": "<prev-id@domain>"
},
"parsed_at": "2026-06-01T20:00:00"
}
```
---
## Hodnotové kódy
| Pole | Hodnota | Význam |
|---|---|---|
| `importance` | 0 | Nízká |
| | 1 | Normální |
| | 2 | Vysoká |
| `sensitivity` | 0 | Normální |
| | 1 | Osobní |
| | 2 | Soukromé |
| | 3 | Důvěrné |
| `flag_status` | 0 | Bez příznaku |
| | 1 | Označeno (follow up) |
| | 2 | Dokončeno |
---
## MongoDB indexy
Automaticky vytvořeny na konci importu (`--no-indexes` přeskočí):
| Index | Pole |
|---|---|
| Chronologický | `received_at`, `sent_at` |
| Odesílatel | `sender.email` |
| Soubor | `filename` (unique) |
| Konverzace | `conversation_topic` |
| Filtry | `has_attachments`, `categories`, `importance`, `flag_status` |
| Full-text | `subject` + `body_text` + `to` + `cc` (text index `text_search`) |
---
## Ukázkové dotazy (MongoDB shell / MCP)
**Emaily o UCO3001 s přílohou:**
```javascript
db["vbuzalka@its.jnj.com"].find({
$text: { $search: "UCO3001" },
has_attachments: true
}).sort({ received_at: -1 })
```
**Emaily od konkrétního odesílatele:**
```javascript
db["vbuzalka@its.jnj.com"].find({
"sender.email": /covance/i
}).sort({ received_at: -1 })
```
**Celé konverzační vlákno:**
```javascript
db["vbuzalka@its.jnj.com"].find({
conversation_topic: "Protocol deviation CZ10022"
}).sort({ received_at: 1 })
```
**Označené emaily (follow up):**
```javascript
db["vbuzalka@its.jnj.com"].find({ flag_status: 1 })
```
**Vysoká priorita s přílohou:**
```javascript
db["vbuzalka@its.jnj.com"].find({
importance: 2,
has_attachments: true
}).sort({ received_at: -1 })
```
**Statistiky podle odesílatele (top 20):**
```javascript
db["vbuzalka@its.jnj.com"].aggregate([
{ $group: { _id: "$sender.email", count: { $sum: 1 } } },
{ $sort: { count: -1 } },
{ $limit: 20 }
])
```
**Emaily s PDF přílohou:**
```javascript
db["vbuzalka@its.jnj.com"].find({
"attachments.mime_type": "application/pdf"
})
```
**Hledání v těle emailu:**
```javascript
db["vbuzalka@its.jnj.com"].find({
$text: { $search: "inactivation notification" }
})
```
---
## Chybový log
Soubory které selhaly jsou zalogrovány do `parse_emails_errors.log` vedle skriptu:
```
2026-06-01 20:14:33 | open failed [7A3F...0000.msg]: <důvod>
2026-06-01 20:15:01 | extract_message failed [8B2C...0000.msg]: <důvod>
```
---
## Výkon
| Parametr | Hodnota |
|---|---|
| Počet souborů | ~69 000 |
| Rychlost | ~0.4 msg/s (síť SMB + htmlBody dekódování) |
| Odhadovaný čas | 48 hodin (přes noc, s pokračováním) |
| Batch size | 200 dokumentů / bulk_write |
| Odhadovaná velikost DB | 25 GB |
---
## Závislosti
```
extract-msg==0.55.0
pymongo
python-dateutil
```
Instalace do venv:
```cmd
"U:\PythonProject\Janssen\.venv\Scripts\pip.exe" install extract-msg pymongo python-dateutil
```
---
## Historie verzí
| Verze | Datum | Změna |
|---|---|---|
| 1.0 | 2026-06-01 | Iniciální verze |