This commit is contained in:
2026-06-16 14:32:00 +02:00
parent 4a665b90fa
commit 91d7f03f2b
39 changed files with 31 additions and 18762 deletions
+11 -1
View File
@@ -58,7 +58,7 @@ Bearer token: `13e1bb01-9fd5-44a8-8ce9-4ee27133d340`
| Endpoint | Přijímá | Chování |
|---|---|---|
| `POST /upload` | `.msg` / `.emsg` | `.emsg` Fernet dešifruje → uloží `.msg` do `/msgs`, přeskočí pokud existuje; volitelně import do Graphu |
| `POST /upload` | `.msg` / `.emsg` | `.emsg` Fernet dešifruje → uloží `.msg` do `/msgs`, přeskočí pokud existuje; volitelně import do Graphu. **v2.4:** form pole `overwrite=1` → existující `.msg` **přepíše** (re-upload změněného e-mailu z `jnj_mailbox_sync >= v1.3`); při overwrite se Graph re-import nedělá |
| `POST /upload-db` | `.db` / `.db.xz.enc` | **v2.1:** `.db.xz.enc` Fernet dešifruje + lzma rozbalí → plain `.db`; pak smaže staré `.db` v `/msgs/db` a uloží. Plain `.db` bere i nadále (zpětná kompatibilita) |
| `POST /upload-dropbox` | cokoliv | Nahraje do Dropboxu (overwrite) |
@@ -68,6 +68,16 @@ Bearer token: `13e1bb01-9fd5-44a8-8ce9-4ee27133d340`
> (stdlib) — ověřeno v kontejneru. Nasazení = jen restart (app.py je bind-mount),
> bez rebuildu.
> **v2.4 (2026-06-16):** `/upload` — nové form pole `overwrite=1`. Když `.msg`
> už v `/msgs` existuje, místo `{"status":"exists"}` ho **přepíše** a vrátí
> `{"status":"overwritten"}`. Bez pole zůstává původní idempotentní skip (žádná
> regrese). Slouží pro re-upload **změněného** e-mailu z `jnj_mailbox_sync >= v1.3`
> (detekce změny obsahu — např. dopsaná chyba `SendAsDenied` do neodeslané Sent
> položky). Při overwrite se **Graph re-import nedělá** (klient posílá `folder=""`,
> takže nevznikne duplikát v Graph zrcadle); přepsaný soubor má novější mtime →
> Tower (`jnj_tower_ingest`) ho přeparsuje a upsertne dokument v Mongu dle `_id`.
> Nasazení = jen `docker restart` (bind-mount).
> **v2.3 (2026-06-10):** `/item/{token}` — při `Accept: application/json`
> (klient `janssenpc_file_receive >= v1.2`) vrací `{"data": "<fernet_b64>"}`
> místo binární přílohy. Důvod: JNJ filtr (Zscaler/SiteMinder) blokoval binární
+20 -6
View File
@@ -1,6 +1,12 @@
# app.py | v2.3 | 2026-06-10
# app.py | v2.4 | 2026-06-16
# FastAPI server pro příjem .msg a .db souborů, upload do Dropboxu a import do Graph API.
# Endpointy: /upload (.msg/.emsg → /msgs + Graph import),
# v2.4: /upload + form pole overwrite=1 — když .msg už existuje, PŘEPÍŠE ho (jinak
# jako dřív vrátí "exists"). Slouží pro re-upload změněného e-mailu z
# jnj_mailbox_sync >= v1.3 (detekce změny obsahu, např. dopsaná chyba
# SendAsDenied). Při overwrite se NEdělá Graph re-import (klient posílá
# folder="" → žádný duplikát v Graph zrcadle; jen se obnoví soubor v /msgs,
# Tower si ho přeparsuje a aktualizuje dokument v Mongu).
# Endpointy: /upload (.msg/.emsg → /msgs + Graph import; overwrite=1 přepíše),
# /upload-db (.db NEBO .db.xz.enc → Fernet desifruj + lzma rozbal → /msgs/db),
# /upload-dropbox (→ Dropbox /!!!Days/Downloads Z230),
# /message-delete, /message-update (sync: smazání, přečtení, přesun složky),
@@ -336,6 +342,7 @@ async def upload_msg(
file: UploadFile = File(...),
authorization: str = Header(None),
folder: str = Form(""),
overwrite: str = Form(""),
):
if authorization != f"Bearer {TOKEN}":
raise HTTPException(status_code=401, detail="Unauthorized")
@@ -347,7 +354,12 @@ async def upload_msg(
# Ukládáme vždy jako .msg
msg_filename = file.filename[:-5] + ".msg" if is_encrypted else file.filename
dest = SAVE_DIR / msg_filename
if dest.exists():
existed = dest.exists()
do_overwrite = overwrite in ("1", "true", "True", "yes")
# v2.4: bez overwrite zustava puvodni idempotentni skip; s overwrite=1
# prepiseme (re-upload zmeneneho e-mailu z jnj_mailbox_sync >= v1.3).
if existed and not do_overwrite:
return {"status": "exists", "file": msg_filename}
content = await file.read()
@@ -357,13 +369,15 @@ async def upload_msg(
with dest.open("wb") as f:
f.write(content)
# Import to Graph API if folder was provided by client
# Graph import jen pri PRVNIM ulozeni a kdyz klient poslal folder.
# Pri overwrite (re-upload) se Graph re-import NEdela — predesle by vznikl
# duplikat v Graph zrcadle; Tower si soubor preparsuje sam (upsert dle _id).
graph_id = None
if folder:
if folder and not existed:
graph_id = _import_msg_to_graph(dest, folder)
return {
"status": "saved",
"status": "overwritten" if (existed and do_overwrite) else "saved",
"file": msg_filename,
"graph_id": graph_id,
}