Files
janssen/EmailsImport/inbox_full_sync_v1.1.md
T

6.2 KiB

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:
    • InboxGetDefaultFolder(6)
    • Sent ItemsGetDefaultFolder(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:

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ů:

SELECT id, script, version, started_at, finished_at,
       transferred, skipped, errors
FROM runs ORDER BY started_at DESC

Chyby z posledního běhu:

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