# 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:` 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": "", "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": "", "internet_references": ["", ""], "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": "...", "attachments": [ { "filename": "PD_report_CZ10022.pdf", "size_bytes": 284512, "mime_type": "application/pdf", "content_id": null, "is_inline": false } ], "headers": { "message_id": "", "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": "", "0x1042": "" }, "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]: 2026-06-01 20:15:01 | extract_message failed [8B2C...0000.msg]: ``` --- ## 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: ```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 |