8.2 KiB
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 (nebofilename:<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:
"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):
"U:\PythonProject\Janssen\.venv\Scripts\python.exe" "U:\PythonProject\Janssen\EmailsImport\parse_emails_v1.0.py" --skip-existing
Test na malém vzorku:
"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
{
"_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:
db["vbuzalka@its.jnj.com"].find({
$text: { $search: "UCO3001" },
has_attachments: true
}).sort({ received_at: -1 })
Emaily od konkrétního odesílatele:
db["vbuzalka@its.jnj.com"].find({
"sender.email": /covance/i
}).sort({ received_at: -1 })
Celé konverzační vlákno:
db["vbuzalka@its.jnj.com"].find({
conversation_topic: "Protocol deviation CZ10022"
}).sort({ received_at: 1 })
Označené emaily (follow up):
db["vbuzalka@its.jnj.com"].find({ flag_status: 1 })
Vysoká priorita s přílohou:
db["vbuzalka@its.jnj.com"].find({
importance: 2,
has_attachments: true
}).sort({ received_at: -1 })
Statistiky podle odesílatele (top 20):
db["vbuzalka@its.jnj.com"].aggregate([
{ $group: { _id: "$sender.email", count: { $sum: 1 } } },
{ $sort: { count: -1 } },
{ $limit: 20 }
])
Emaily s PDF přílohou:
db["vbuzalka@its.jnj.com"].find({
"attachments.mime_type": "application/pdf"
})
Hledání v těle emailu:
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 | 2–5 GB |
Závislosti
extract-msg==0.55.0
pymongo
python-dateutil
Instalace do venv:
"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 |