5545f05eee
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
177 lines
6.2 KiB
Markdown
177 lines
6.2 KiB
Markdown
# inbox_full_sync_v1.1
|
|
|
|
**Název:** inbox_full_sync_v1.1.py
|
|
**Verze:** 1.1.0
|
|
**Datum:** 2026-06-08
|
|
**Autor:** vladimir.buzalka
|
|
|
|
---
|
|
|
|
## Účel
|
|
|
|
Jednorázový skript pro úplný přenos **Inboxu i Sent Items** z JNJ Outlooku (MAPI) do osobní schránky `vladimir.buzalka@buzalka.cz` přes Microsoft Graph API.
|
|
|
|
Spouštět ručně jako záchranná síť nebo iniciální sync. Bezpečné opakovat — duplicity se automaticky přeskočí.
|
|
|
|
---
|
|
|
|
## Co dělá
|
|
|
|
1. Připojí se k Outlooku přes MAPI (`win32com`)
|
|
2. Projde rekurzivně obě výchozí složky včetně všech podsložek:
|
|
- **Inbox** — `GetDefaultFolder(6)`
|
|
- **Sent Items** — `GetDefaultFolder(5)`
|
|
3. Pro každý email zkontroluje SQLite DB — pokud už je přenesen, přeskočí ho
|
|
4. Nový email uloží jako `.msg` do temp složky, **zašifruje** (Fernet/AES) a odešle jako `.emsg` na `msgs.buzalka.cz/upload`
|
|
5. Server (`app.py`) dešifruje, parsuje `.msg`, importuje do Graph API a vrátí `graph_id`
|
|
6. Záznam se uloží do DB (`messages`, `log`)
|
|
7. Každých 100 přenesených emailů + na konci uploaduje DB na server
|
|
|
|
Složky k synchronizaci jsou v konstantě `SYNC_FOLDERS = [(6, "Inbox"), (5, "Sent Items")]`.
|
|
|
|
**Online Archive se nepřenáší** — `GetDefaultFolder(5/6)` vrátí pouze primární schránku.
|
|
|
|
---
|
|
|
|
## Šifrování (Zscaler bypass)
|
|
|
|
JNJ síť používá **Zscaler DLP** — blokuje upload souborů s medicínským obsahem (ECG reporty, klinická data) na externí URL.
|
|
|
|
Řešení: soubor se před odesláním zašifruje pomocí **Fernet** (AES-128 CBC + HMAC). Zscaler vidí pouze šifrovaný bináč a nerozpozná obsah.
|
|
|
|
- Šifrovací klíč se odvozuje z `TOKEN` přes SHA-256 — žádná extra konstanta, obě strany derivují klíč samostatně
|
|
- Soubor se odesílá s příponou `.emsg` místo `.msg`
|
|
- Server (app.py v1.6+) automaticky detekuje `.emsg`, dešifruje a dále zpracuje standardně
|
|
|
|
---
|
|
|
|
## Konfigurace
|
|
|
|
Konstanty jsou přímo v kódu:
|
|
|
|
| Konstanta | Hodnota |
|
|
|---|---|
|
|
| `TOKEN` | Bearer token pro msgs.buzalka.cz (slouží i jako základ šifrovacího klíče) |
|
|
| `UPLOAD_URL` | `https://msgs.buzalka.cz/upload` |
|
|
| `DB_UPLOAD_URL` | `https://msgs.buzalka.cz/upload-db` |
|
|
| `DB_PATH` | `C:\Users\vbuzalka\SQLITE\jnjemails.db` |
|
|
| `LOG_PATH` | `C:\Users\vbuzalka\SQLITE\inbox_full_sync_errors.log` |
|
|
| `SYNC_FOLDERS` | `[(6, "Inbox"), (5, "Sent Items")]` |
|
|
|
|
---
|
|
|
|
## Závislosti
|
|
|
|
- Python 3.10+, Windows
|
|
- Outlook musí být spuštěn
|
|
- `pywin32`, `requests`, `cryptography`
|
|
- Server `msgs.buzalka.cz` musí běžet (app.py v1.6+)
|
|
|
|
---
|
|
|
|
## SQLite DB (`jnjemails.db`)
|
|
|
|
### Tabulka `messages`
|
|
Jeden záznam na každý přenesený email.
|
|
|
|
| Sloupec | Popis |
|
|
|---|---|
|
|
| `message_id` | Internet Message-ID (nebo `entryid:...` jako fallback) |
|
|
| `entry_id` | Outlook EntryID — pro zpětné dohledání v MAPI |
|
|
| `graph_id` | ID zprávy v Graph API — pro sync operace |
|
|
| `is_read` | Stav přečtení při přenosu (0/1) |
|
|
| `jnj_folder` | Složka v JNJ při přenosu (Inbox i Sent Items podstrom) |
|
|
| `source` | Vždy `inbox_full_sync` |
|
|
|
|
### Tabulka `runs`
|
|
Jeden záznam na každý běh skriptu.
|
|
|
|
| Sloupec | Popis |
|
|
|---|---|
|
|
| `script` | `inbox_full_sync` |
|
|
| `version` | verze skriptu |
|
|
| `started_at` / `finished_at` | časy běhu |
|
|
| `transferred` | počet nově přenesených emailů |
|
|
| `skipped` | počet přeskočených (již v DB) |
|
|
| `errors` | počet chyb |
|
|
|
|
### Tabulka `log`
|
|
Flat event log — každý console výstup i interní událost jako řádek.
|
|
|
|
| Sloupec | Popis |
|
|
|---|---|
|
|
| `run_id` | FK na `runs.id` |
|
|
| `level` | `INFO` / `ERROR` |
|
|
| `event` | typ události (viz níže) |
|
|
| `subject` | předmět emailu (pokud relevantní) |
|
|
| `folder` | složka (pokud relevantní) |
|
|
| `graph_id` | Graph ID (pokud relevantní) |
|
|
| `detail` | pro `upload_saved`: `size=XKB`; pro `upload_error`: `error=... \| size=XKB \| body=... \| sender=... \| received=... \| entry_id=... \| message_id=...` |
|
|
|
|
#### Události (`log.event`)
|
|
|
|
| Event | Popis |
|
|
|---|---|
|
|
| `run_start` | start skriptu |
|
|
| `mailbox` | název schránky + kořenová složka (Inbox / Sent Items) |
|
|
| `folder_start` | vstup do složky (detail = počet položek) |
|
|
| `folder_done` | konec složky (detail = přeneseno/skip) |
|
|
| `upload_saved` | nový email úspěšně přenesen (detail = size=XKB) |
|
|
| `upload_exists` | email již v DB, přeskočen |
|
|
| `upload_error` | chyba při uploadu — detail obsahuje sender, received, entry_id, message_id pro dohledání v Outlooku |
|
|
| `progress` | každých 100 přenesených emailů |
|
|
| `db_upload` | úspěšný upload DB na server |
|
|
| `db_upload_error` | chyba uploadu DB |
|
|
| `run_done` | konec skriptu (detail = souhrn) |
|
|
|
|
---
|
|
|
|
## Užitečné dotazy
|
|
|
|
**Poslední běh — kompletní log:**
|
|
```sql
|
|
SELECT r.script, r.version, r.started_at,
|
|
l.level, l.event, l.subject, l.folder, l.detail, l.created_at
|
|
FROM log l JOIN runs r ON r.id = l.run_id
|
|
WHERE l.run_id = (SELECT MAX(id) FROM runs)
|
|
ORDER BY l.created_at
|
|
```
|
|
|
|
**Přehled všech běhů:**
|
|
```sql
|
|
SELECT id, script, version, started_at, finished_at,
|
|
transferred, skipped, errors
|
|
FROM runs ORDER BY started_at DESC
|
|
```
|
|
|
|
**Chyby z posledního běhu:**
|
|
```sql
|
|
SELECT l.event, l.subject, l.folder, l.detail, l.created_at
|
|
FROM log l
|
|
WHERE l.run_id = (SELECT MAX(id) FROM runs)
|
|
AND l.level = 'ERROR'
|
|
ORDER BY l.created_at
|
|
```
|
|
|
|
---
|
|
|
|
## Návaznost
|
|
|
|
- Sdílí DB s `janssenpc_email_send_new_v1.5.py` — záznamy jsou kompatibilní
|
|
- Emaily přenesené tímto skriptem mají `graph_id` a jsou od té chvíle hlídány sync průchodem v1.5
|
|
- Server endpoint: `msgs.buzalka.cz/upload` musí vracet `graph_id` (app.py v1.6+)
|
|
- nginx `client_max_body_size` nastaven na **200M** (SWAG `msgreceiver.subdomain.conf`)
|
|
|
|
---
|
|
|
|
## Historie verzí
|
|
|
|
| Verze | Datum | Změna |
|
|
|---|---|---|
|
|
| 1.0.0 | 2026-06-01 | Základní funkce: Inbox full scan, dedup přes DB, entry_id/graph_id/is_read |
|
|
| 1.0.1 | 2026-06-01 | DB upload každých 100 emailů + finální upload |
|
|
| 1.0.2 | 2026-06-01 | SQLite tabulky runs + log |
|
|
| 1.0.3 | 2026-06-01 | Kompletní konzolový výstup zrcadlen do log tabulky, skipped counter |
|
|
| 1.0.4 | 2026-06-01 | Šifrování Fernet (.emsg) pro bypass Zscaler DLP; rozšířený error detail |
|
|
| 1.1.0 | 2026-06-08 | Synchronizace i složky **Sent Items** (`GetDefaultFolder(5)`) vedle Inboxu |
|