z230
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user