Harden mail move audit logging
The prompts used to arrive at this change since the previous commit Read restart_prompt.md first, then continue from there. Any special observations that may be relevant for version management for this version. Be brief. No mailbox-affecting scripts were run by Codex. A generated dry-run transcript appeared locally as verplaats_bestaand.log and is now ignored via *.log.
This commit is contained in:
+75
-14
@@ -88,39 +88,69 @@ def kopieer_map(
|
||||
doel: imaplib.IMAP4_SSL,
|
||||
folder: str,
|
||||
log: dict,
|
||||
) -> tuple[int, int]:
|
||||
) -> tuple[int, int, int]:
|
||||
"""
|
||||
Kopieer berichten van bron-folder naar doel-folder.
|
||||
Geeft (gekopieerd, overgeslagen) terug.
|
||||
Geeft (gekopieerd, overgeslagen, mislukt) terug.
|
||||
"""
|
||||
# Selecteer bronmap
|
||||
status, data = bron.select(quote_mailbox(folder), readonly=True)
|
||||
if status != "OK":
|
||||
print(f" Kan bronmap niet openen: {folder}")
|
||||
return 0, 0
|
||||
log.setdefault("fouten", []).append({
|
||||
"folder": folder,
|
||||
"actie": "select_bron",
|
||||
"status": status,
|
||||
"response": repr(data),
|
||||
})
|
||||
return 0, 0, 1
|
||||
|
||||
totaal = int(data[0])
|
||||
if totaal == 0:
|
||||
return 0, 0
|
||||
return 0, 0, 0
|
||||
|
||||
# Haal alle bron-UIDs op
|
||||
status, data = bron.search(None, "ALL")
|
||||
if status != "OK" or not data[0]:
|
||||
return 0, 0
|
||||
log.setdefault("fouten", []).append({
|
||||
"folder": folder,
|
||||
"actie": "search_bron",
|
||||
"status": status,
|
||||
"response": repr(data),
|
||||
})
|
||||
return 0, 0, 1
|
||||
ids = data[0].split()
|
||||
|
||||
# Zorg dat doelmap bestaat
|
||||
doel.create(quote_mailbox(folder)) # negeer fout als al bestaat
|
||||
create_status, create_data = doel.create(quote_mailbox(folder))
|
||||
if create_status not in {"OK", "NO"}:
|
||||
log.setdefault("fouten", []).append({
|
||||
"folder": folder,
|
||||
"actie": "create_doel",
|
||||
"status": create_status,
|
||||
"response": repr(create_data),
|
||||
})
|
||||
return 0, 0, 1
|
||||
select_status, select_data = doel.select(quote_mailbox(folder), readonly=True)
|
||||
if select_status != "OK":
|
||||
log.setdefault("fouten", []).append({
|
||||
"folder": folder,
|
||||
"actie": "select_doel_na_create",
|
||||
"status": select_status,
|
||||
"response": repr(select_data),
|
||||
})
|
||||
return 0, 0, 1
|
||||
|
||||
# Welke Message-IDs staan al in de doelmap?
|
||||
bestaande = haal_bestaande_message_ids(doel, folder)
|
||||
|
||||
gekopieerd = 0
|
||||
overgeslagen = 0
|
||||
mislukt = 0
|
||||
|
||||
for i, uid in enumerate(ids, 1):
|
||||
# Voortgang op één regel
|
||||
print(f"\r {folder}: {i}/{totaal} ({gekopieerd} gekopieerd, {overgeslagen} skip) ",
|
||||
print(f"\r {folder}: {i}/{totaal} ({gekopieerd} gekopieerd, {overgeslagen} skip, {mislukt} fout) ",
|
||||
end="", flush=True)
|
||||
|
||||
# Haal volledige bericht op + vlaggen + datum
|
||||
@@ -128,6 +158,14 @@ def kopieer_map(
|
||||
uid, "(FLAGS INTERNALDATE BODY.PEEK[])"
|
||||
)
|
||||
if status != "OK" or not data:
|
||||
mislukt += 1
|
||||
log.setdefault("fouten", []).append({
|
||||
"folder": folder,
|
||||
"uid": uid.decode(errors="replace"),
|
||||
"actie": "fetch_bron",
|
||||
"status": status,
|
||||
"response": repr(data),
|
||||
})
|
||||
continue
|
||||
|
||||
# Parse fetch-response
|
||||
@@ -144,6 +182,14 @@ def kopieer_map(
|
||||
internaldate = parse_internaldate(item[0])
|
||||
|
||||
if not raw_message:
|
||||
mislukt += 1
|
||||
log.setdefault("fouten", []).append({
|
||||
"folder": folder,
|
||||
"uid": uid.decode(errors="replace"),
|
||||
"actie": "fetch_lege_body",
|
||||
"status": status,
|
||||
"response": repr(data),
|
||||
})
|
||||
continue
|
||||
|
||||
# Controleer Message-ID voor deduplicatie
|
||||
@@ -159,7 +205,7 @@ def kopieer_map(
|
||||
|
||||
# Schrijf naar doelmap
|
||||
flag_str = "(" + " ".join(flags) + ")" if flags else "()"
|
||||
status, _ = doel.append(
|
||||
status, append_data = doel.append(
|
||||
quote_mailbox(folder),
|
||||
flag_str,
|
||||
internaldate,
|
||||
@@ -170,14 +216,22 @@ def kopieer_map(
|
||||
if mid:
|
||||
bestaande.add(mid)
|
||||
else:
|
||||
pass # stil doorgaan bij incidentele fout
|
||||
mislukt += 1
|
||||
log.setdefault("fouten", []).append({
|
||||
"folder": folder,
|
||||
"uid": uid.decode(errors="replace"),
|
||||
"actie": "append_doel",
|
||||
"message_id": mid,
|
||||
"status": status,
|
||||
"response": repr(append_data),
|
||||
})
|
||||
|
||||
# Even pauzeren elke 50 berichten om server te ontlasten
|
||||
if gekopieerd % 50 == 0 and gekopieerd > 0:
|
||||
time.sleep(0.2)
|
||||
|
||||
print(f"\r {folder}: {totaal}/{totaal} → {gekopieerd} gekopieerd, {overgeslagen} al aanwezig ")
|
||||
return gekopieerd, overgeslagen
|
||||
print(f"\r {folder}: {totaal}/{totaal} → {gekopieerd} gekopieerd, {overgeslagen} al aanwezig, {mislukt} fout ")
|
||||
return gekopieerd, overgeslagen, mislukt
|
||||
|
||||
|
||||
# ── log ───────────────────────────────────────────────────────────────────────
|
||||
@@ -247,6 +301,7 @@ def run():
|
||||
|
||||
totaal_gekopieerd = log.get("totaal_gekopieerd", 0)
|
||||
totaal_overgeslagen = 0
|
||||
totaal_mislukt = 0
|
||||
|
||||
for i, folder in enumerate(alle_mappen, 1):
|
||||
print(f"[{i}/{len(alle_mappen)}] {folder}")
|
||||
@@ -255,12 +310,17 @@ def run():
|
||||
print(f" ✓ al volledig gekopieerd, overgeslagen.\n")
|
||||
continue
|
||||
|
||||
gekopieerd, overgeslagen = kopieer_map(bron, doel, folder, log)
|
||||
gekopieerd, overgeslagen, mislukt = kopieer_map(bron, doel, folder, log)
|
||||
totaal_gekopieerd += gekopieerd
|
||||
totaal_overgeslagen += overgeslagen
|
||||
totaal_mislukt += mislukt
|
||||
|
||||
log["voltooide_mappen"] = list(al_klaar | {folder})
|
||||
al_klaar.add(folder)
|
||||
if mislukt == 0:
|
||||
log["voltooide_mappen"] = list(al_klaar | {folder})
|
||||
al_klaar.add(folder)
|
||||
else:
|
||||
log["voltooide_mappen"] = list(al_klaar)
|
||||
print(f" ! niet als voltooid gemarkeerd door {mislukt} fout(en)")
|
||||
log["totaal_gekopieerd"] = totaal_gekopieerd
|
||||
log["laatste_run"] = datetime.now().isoformat()
|
||||
save_log(log)
|
||||
@@ -273,6 +333,7 @@ def run():
|
||||
print(f"Klaar.")
|
||||
print(f" Gekopieerd : {totaal_gekopieerd}")
|
||||
print(f" Al aanwezig : {totaal_overgeslagen}")
|
||||
print(f" Fouten : {totaal_mislukt}")
|
||||
print(f" Log : {LOG_FILE}")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user