Files
janssen/EmailsImport/jnj_tower_ingest_v1.4.md
T
2026-06-16 14:32:28 +02:00

3.8 KiB

jnj_tower_ingest v1.4.0

Soubor: jnj_tower_ingest_v1.4.py Datum: 2026-06-16 Autor: vladimir.buzalka Běží: Docker kontejner python-runner na Unraid Tower (192.168.1.76), u MongoDB.

Co to je

Sjednocený Tower-side ingest JNJ e-mailů — fáze v jednom běhu (cron */5):

Fáze Co dělá
1. PARSE .msg z /mnt/JNJEMAILS → tělo do Mongo emaily."vbuzalka@its.jnj.com". Inkrementálně přes mtime watermark. Přílohy do SeaweedFS (v1.3). + v1.4: detekce neodeslaného e-mailu.
2. SYNC nejnovější SQLite (read-only) → zrcadlo jnj_messages + jnj_folder/stav do emaily. NULL-safe.
RECONCILE (volitelně --reconcile) v1.4: smaže provizorní no-ID Sent duplikáty, ke kterým existuje dvojče s reálným Message-ID.
3. ENRICH sdílený 5_enrich_fulltext_emails --mailbox → PG fulltext. Jen při nových dokumentech.

Pořadí parse → sync → (reconcile) → enrich. Klíč = Internet Message-ID = Mongo _id.

Novinka v1.4 (a) — detekce NEODESLANÉHO e-mailu

PARSE při čtení těla hledá stopy chyby odeslání (SendAsDenied, „could not be sent", TransportSend operation has failed, MapiExceptionSendAsDenied). Když je najde, dokument dostane:

  • send_failed: true
  • send_error: "SendAsDenied (ec=1244) 0x80070005-…" (vytažený kód, pokud je)

Dotaz na neodeslané: { send_failed: true }.

Pozn.: chybové tělo se v .msg objeví poté, co ho Outlook do položky dopíše; na Tower ho přinese re-upload z jnj_mailbox_sync v1.3 (+ overwrite na app.py v2.4). Archivní kopie zachycená před selháním chybu nenese.

Novinka v1.4 (b) — fáze RECONCILE (smaž provizorní duplikáty)

Sent položka bez Message-ID (_id začíná filename:/entryid:) je jen přechodný snímek (zachycený dřív, než Exchange doplnil Message-ID). Když k ní existuje dvojče s reálným Message-ID — stejní to příjemci + stejný normalized_subject + received_at do 24 h — je provizorní kopie redundantní a smaže se. Neodeslané (bez dvojčete) zůstanou (a mají send_failed).

  • Match je na stabilním obsahu (e-mailové adresy + normalizovaný předmět + čas), ne na EntryID (ten se mezi provizorní a finální kopií liší).
  • Běží jen s --reconcile (default vypnuto — bezpečné pro cron).
  • S --dry-run jen vypíše plán (nic nemaže). Bez --dry-run + s --reconcile maže.

Argumenty

--dry-run, --full, --limit N, --reindex, --force, --parse-only / --sync-only / --enrich-only, --no-enrich, --enrich-always, --reconcile (nově).

Spouštění

# Běžný inkrementální běh (cron) — reconcile NEběží:
docker exec python-runner python3 /scripts/jnj_tower_ingest_v1.4.py

# RECONCILE — nejdřív plán (nic nemaže):
docker exec -it python-runner python3 /scripts/jnj_tower_ingest_v1.4.py --reconcile --dry-run --sync-only

# RECONCILE — ostře (po kontrole plánu):
docker exec -it python-runner python3 /scripts/jnj_tower_ingest_v1.4.py --reconcile --sync-only

(--sync-only --reconcile = jen sync + úklid duplikátů, bez parse/enrich; reconcile potřebuje jnj_folder ze sync. Pro samostatný úklid lze i bez --sync-only.)

Revert

jnj_tower_ingest_v1.3.py (bez send_failed + reconcile), starší v Trash/.

Historie verzí

  • 1.0.0 — sjednocení parse + sync (mtime watermark).
  • 1.1.0 — + fáze ENRICH.
  • 1.2.0 — SYNC NULL-safe.
  • 1.3.0 — PARSE: přílohy do SeaweedFS.
  • 1.4.0 — (a) PARSE detekuje neodeslaný e-mail → send_failed + send_error. (b) Fáze RECONCILE (--reconcile): smaže provizorní no-ID Sent kopie s ID-dvojčetem (match to+předmět+čas, ne EntryID); neodeslané ponechá.