# 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 | 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 |
