74 lines
3.9 KiB
Markdown
74 lines
3.9 KiB
Markdown
# jnj_mailbox_sync v1.3.0
|
|
|
|
**Soubor:** `jnj_mailbox_sync_v1.3.py`
|
|
**Datum:** 2026-06-16
|
|
**Autor:** vladimir.buzalka
|
|
**Běží:** JNJ stroj (Outlook MAPI), Python z Thonny.
|
|
|
|
## Co to je
|
|
|
|
Synchronizace JNJ Outlooku (MAPI) → osobní schránka (přes msgreceiver) + bookkeeping
|
|
v SQLite (`C:\Users\vbuzalka\SQLITE\jnjemails.db`). Sleduje přesuny e-mailů mezi
|
|
složkami a příznak „už není ve schránce" — bez opětovného přenosu těla.
|
|
Skenované složky: **Inbox + Sent Items + Deleted Items** (vč. podsložek).
|
|
|
|
## Novinka v1.3 — detekce změny obsahu (re-upload změněného e-mailu)
|
|
|
|
**Problém:** e-mail **bez Message-ID** (typicky **NEODESLANÝ** Sent kvůli `SendAsDenied`,
|
|
nebo čerstvě odeslaný, kde Exchange ještě nedoplnil Message-ID) má **stabilní EntryID**.
|
|
Když do něj Outlook **po zachycení** dopíše chybu odeslání, obsah se změní, ale identita
|
|
(`entryid:<EID>`) zůstane → starý sync to vyhodnotil jako „známé, beze změny" a
|
|
aktualizovaný (chybový) e-mail už domů **nepřenesl**. Naproti tomu úspěšně odeslaný
|
|
e-mail dostane **nové EntryID + Message-ID**, takže se zachytil jako nový. Vznikla
|
|
asymetrie: failed-update se ztrácel.
|
|
|
|
**Řešení:** identita zůstává (Message-ID / `entryid:`), ale navíc se sleduje **verzní otisk**
|
|
= `PR_LAST_MODIFICATION_TIME` (`0x30080040`). U **známé položky bez Message-ID**
|
|
(`mid` začíná `entryid:`) se otisk porovná; když se posunul, e-mail se znovu uloží
|
|
(`SaveAs`) a nahraje s `overwrite=1` → server přepíše původní `.msg` na místě → Tower ho
|
|
přeparsuje → dokument v Mongu se aktualizuje (vč. těla s chybou).
|
|
|
|
- Hlídání je **levné** — druhé čtení property jen u známých no-ID položek (desítky kusů);
|
|
položky s Message-ID jsou finalizované a nesledují se.
|
|
- Re-upload běží jen v režimech, které smějí nahrávat (**capture, full-update**), a posílá se
|
|
s `folder=""` → server **nedělá** Graph re-import (žádný duplikát v Graph zrcadle).
|
|
- **Vyžaduje msgreceiver app.py ≥ v2.4** (overwrite na `/upload`). Bez něj se re-upload chová
|
|
jako starý skip (nepřepíše, ale nic nerozbije) — pořadí nasazení server → JNJ bez výpadku.
|
|
|
|
## Nové sloupce SQLite
|
|
|
|
- `messages.last_mod_time` — PR_LAST_MODIFICATION_TIME při posledním zachycení (otisk).
|
|
- `messages.content_uploads` — kolikrát se tělo nahrálo (1 = jen první zachycení).
|
|
- `runs.content_updated` — kolik e-mailů se v běhu re-uploadlo kvůli změně obsahu.
|
|
|
|
(Migrace přes stávající `ALTER TABLE` smyčku — staré `jnjemails.db` se doplní automaticky.)
|
|
|
|
## Argumenty
|
|
|
|
`--mode {capture,update-paths,full-update}` (default capture), `--days N`
|
|
(0 = celé), `--dry-run`, `--limit N`, `--no-db-upload`.
|
|
|
|
## Spouštění (JNJ stroj, plné cesty)
|
|
|
|
```
|
|
"C:\Users\vbuzalka\AppData\Local\Programs\Thonny\python.exe" "c:\Users\vbuzalka\OneDrive - JNJ\##JNJPrenos\Python\jnj_mailbox_sync_v1.3.py" --mode full-update --days 60
|
|
```
|
|
|
|
`full-update --days 60` = dorovná chybějící + **re-uploadne změněné** (chybové) Sent položky
|
|
za poslední 60 dní. To je doporučený běh pro „aktualizovat i neodeslané".
|
|
|
|
## Revert
|
|
|
|
Stará verze: `Trash/jnj_mailbox_sync_v1.2.py` (bez detekce změny). Server v2.4 zůstává
|
|
zpětně kompatibilní (overwrite je opt-in), takže revert na JNJ straně nevyžaduje zásah na serveru.
|
|
|
|
## Historie
|
|
|
|
- **1.0.0** — režimy capture/update-paths/full-update, sledování přesunů, updated_at.
|
|
- **1.1.0** — + Deleted Items do skenovaných složek.
|
|
- **1.2.0** — upload SQLite komprimován (lzma/xz max) + šifrován (Fernet) → `.db.xz.enc`.
|
|
- **1.3.0** — + detekce změny obsahu přes `PR_LAST_MODIFICATION_TIME`: známé no-ID
|
|
položky, které se po zachycení změnily (např. dopsaná chyba `SendAsDenied`), se znovu
|
|
nahrávají s `overwrite=1`. Nové sloupce `last_mod_time`, `content_uploads`,
|
|
`runs.content_updated`. Vyžaduje app.py ≥ v2.4.
|