Add CentralLogging stack, Covance/EDC sources, email import + IWRS scripts
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
# inbox_full_sync_v1.0
|
||||
|
||||
**Název:** inbox_full_sync_v1.0.py
|
||||
**Verze:** 1.0.4
|
||||
**Datum:** 2026-06-01
|
||||
**Autor:** vladimir.buzalka
|
||||
|
||||
---
|
||||
|
||||
## Účel
|
||||
|
||||
Jednorázový skript pro úplný přenos Inboxu 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 celý **Inbox** včetně všech podsložek rekurzivně
|
||||
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
|
||||
|
||||
**Online Archive se nepřenáší** — `GetDefaultFolder(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` |
|
||||
|
||||
---
|
||||
|
||||
## 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 |
|
||||
| `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 |
|
||||
| `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 (sender/received/entry_id/size) |
|
||||
Reference in New Issue
Block a user