Add sorter progress counters
The prompts used to arrive at this change since the previous commit User asked to add a counter to verplaats_bestaand. Any special observations that may be relevant for version management for this version. Be brief. Dry runs now show planned move counters, and execution summaries distinguish planned, moved, no-match, skipped, and failed messages. No mailbox-affecting scripts were run.
This commit is contained in:
@@ -76,6 +76,9 @@ Scripts using shared IMAP folder handling:
|
|||||||
- `MAP_RENAMES` is intentionally empty.
|
- `MAP_RENAMES` is intentionally empty.
|
||||||
- Source folders are selected by shared `list_folders()` plus `mail_routes.is_source_folder()`.
|
- Source folders are selected by shared `list_folders()` plus `mail_routes.is_source_folder()`.
|
||||||
- Step 2 routes all eligible source folders, not just `INBOX`.
|
- Step 2 routes all eligible source folders, not just `INBOX`.
|
||||||
|
- Step 2 now reports counters per folder and in total: planned moves, actual moves when executing, no-match messages, skipped messages, and fetch/move failures.
|
||||||
|
- Dry runs now report `Gepland` counters instead of misleadingly showing zero moved.
|
||||||
|
- Step 3 invoice-quarter sorting also reports planned/moved/failure counters.
|
||||||
- Move success requires both `UID COPY` and `UID STORE +FLAGS \Deleted` to return `OK`.
|
- Move success requires both `UID COPY` and `UID STORE +FLAGS \Deleted` to return `OK`.
|
||||||
- Step 3 no longer treats `INBOX.Facturen - verwerkt` as a source.
|
- Step 3 no longer treats `INBOX.Facturen - verwerkt` as a source.
|
||||||
- IMAP mailbox names are consistently quoted and encoded through `imap_utils.quote_mailbox()`.
|
- IMAP mailbox names are consistently quoted and encoded through `imap_utils.quote_mailbox()`.
|
||||||
|
|||||||
+51
-6
@@ -131,7 +131,10 @@ def stap2_bronmappen_routing(mail, log: dict, dry: bool):
|
|||||||
print(f" {len(bron_mappen)} bronmappen")
|
print(f" {len(bron_mappen)} bronmappen")
|
||||||
|
|
||||||
totaal_verplaatst = 0
|
totaal_verplaatst = 0
|
||||||
|
totaal_gepland = 0
|
||||||
totaal_geen_match = 0
|
totaal_geen_match = 0
|
||||||
|
totaal_overgeslagen = 0
|
||||||
|
totaal_mislukt = 0
|
||||||
al_verwerkt = set(log.get("stap2_verwerkt", []))
|
al_verwerkt = set(log.get("stap2_verwerkt", []))
|
||||||
|
|
||||||
for bron in bron_mappen:
|
for bron in bron_mappen:
|
||||||
@@ -151,16 +154,23 @@ def stap2_bronmappen_routing(mail, log: dict, dry: bool):
|
|||||||
ids = [uid for uid in data[0].split() if uid]
|
ids = [uid for uid in data[0].split() if uid]
|
||||||
|
|
||||||
verplaatst = 0
|
verplaatst = 0
|
||||||
|
gepland = 0
|
||||||
geen_match = 0
|
geen_match = 0
|
||||||
|
overgeslagen = 0
|
||||||
|
mislukt = 0
|
||||||
|
verwerkt = 0
|
||||||
|
|
||||||
for uid in ids:
|
for uid in ids:
|
||||||
|
verwerkt += 1
|
||||||
uid_str = uid.decode()
|
uid_str = uid.decode()
|
||||||
log_key = f"{bron}:{uid_str}"
|
log_key = f"{bron}:{uid_str}"
|
||||||
if log_key in al_verwerkt:
|
if log_key in al_verwerkt:
|
||||||
|
overgeslagen += 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
status, data = mail.uid("FETCH", uid, "(BODY.PEEK[HEADER.FIELDS (FROM SUBJECT DATE)])")
|
status, data = mail.uid("FETCH", uid, "(BODY.PEEK[HEADER.FIELDS (FROM SUBJECT DATE)])")
|
||||||
if status != "OK" or not data or not data[0]:
|
if status != "OK" or not data or not data[0]:
|
||||||
|
mislukt += 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
msg = email.message_from_bytes(data[0][1])
|
msg = email.message_from_bytes(data[0][1])
|
||||||
@@ -179,10 +189,12 @@ def stap2_bronmappen_routing(mail, log: dict, dry: bool):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
if bron == doel:
|
if bron == doel:
|
||||||
|
overgeslagen += 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
gepland += 1
|
||||||
if dry:
|
if dry:
|
||||||
print(f" [DRY] {bron} → {doel} | {subject[:60]}")
|
print(f" [DRY {verwerkt}/{len(ids)}] {bron} → {doel} | {subject[:60]}")
|
||||||
else:
|
else:
|
||||||
ok = move_message(mail, uid, bron, doel, dry=False)
|
ok = move_message(mail, uid, bron, doel, dry=False)
|
||||||
if ok:
|
if ok:
|
||||||
@@ -191,16 +203,41 @@ def stap2_bronmappen_routing(mail, log: dict, dry: bool):
|
|||||||
if verplaatst % 50 == 0:
|
if verplaatst % 50 == 0:
|
||||||
mail.expunge()
|
mail.expunge()
|
||||||
_save_log(log)
|
_save_log(log)
|
||||||
|
else:
|
||||||
|
mislukt += 1
|
||||||
|
|
||||||
if not dry:
|
if not dry:
|
||||||
mail.expunge()
|
mail.expunge()
|
||||||
_save_log(log)
|
_save_log(log)
|
||||||
|
|
||||||
totaal_verplaatst += verplaatst
|
totaal_verplaatst += verplaatst
|
||||||
|
totaal_gepland += gepland
|
||||||
totaal_geen_match += geen_match
|
totaal_geen_match += geen_match
|
||||||
print(f" Verplaatst: {verplaatst} | Geen match: {geen_match}")
|
totaal_overgeslagen += overgeslagen
|
||||||
|
totaal_mislukt += mislukt
|
||||||
|
if dry:
|
||||||
|
print(
|
||||||
|
f" Gepland: {gepland} | Geen match: {geen_match}"
|
||||||
|
f" | Overgeslagen: {overgeslagen} | Fouten: {mislukt}"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
print(
|
||||||
|
f" Gepland: {gepland} | Verplaatst: {verplaatst}"
|
||||||
|
f" | Geen match: {geen_match} | Overgeslagen: {overgeslagen}"
|
||||||
|
f" | Fouten: {mislukt}"
|
||||||
|
)
|
||||||
|
|
||||||
print(f" Totaal verplaatst: {totaal_verplaatst} | Totaal geen match: {totaal_geen_match}")
|
if dry:
|
||||||
|
print(
|
||||||
|
f" Totaal gepland: {totaal_gepland} | Totaal geen match: {totaal_geen_match}"
|
||||||
|
f" | Totaal overgeslagen: {totaal_overgeslagen} | Totaal fouten: {totaal_mislukt}"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
print(
|
||||||
|
f" Totaal gepland: {totaal_gepland} | Totaal verplaatst: {totaal_verplaatst}"
|
||||||
|
f" | Totaal geen match: {totaal_geen_match} | Totaal overgeslagen: {totaal_overgeslagen}"
|
||||||
|
f" | Totaal fouten: {totaal_mislukt}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# ── stap 3: facturen per kwartaal ────────────────────────────────────────────
|
# ── stap 3: facturen per kwartaal ────────────────────────────────────────────
|
||||||
@@ -228,27 +265,35 @@ def stap3_facturen(mail, log: dict, dry: bool):
|
|||||||
continue
|
continue
|
||||||
ids = [uid for uid in data[0].split() if uid]
|
ids = [uid for uid in data[0].split() if uid]
|
||||||
verplaatst = 0
|
verplaatst = 0
|
||||||
|
gepland = 0
|
||||||
|
mislukt = 0
|
||||||
|
|
||||||
for uid in ids:
|
for index, uid in enumerate(ids, start=1):
|
||||||
status, data = mail.uid("FETCH", uid, "(BODY.PEEK[HEADER.FIELDS (DATE SUBJECT)])")
|
status, data = mail.uid("FETCH", uid, "(BODY.PEEK[HEADER.FIELDS (DATE SUBJECT)])")
|
||||||
if status != "OK" or not data or not data[0]:
|
if status != "OK" or not data or not data[0]:
|
||||||
|
mislukt += 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
msg = email.message_from_bytes(data[0][1])
|
msg = email.message_from_bytes(data[0][1])
|
||||||
date_str = msg.get("Date", "")
|
date_str = msg.get("Date", "")
|
||||||
doel = PREFIX + quarter_folder(date_str)
|
doel = PREFIX + quarter_folder(date_str)
|
||||||
|
gepland += 1
|
||||||
|
|
||||||
if dry:
|
if dry:
|
||||||
dt_kort = date_str[:16] if date_str else "?"
|
dt_kort = date_str[:16] if date_str else "?"
|
||||||
print(f" [DRY] {dt_kort} → {doel}")
|
print(f" [DRY {index}/{len(ids)}] {dt_kort} → {doel}")
|
||||||
else:
|
else:
|
||||||
ok = move_message(mail, uid, bron, doel, dry=False)
|
ok = move_message(mail, uid, bron, doel, dry=False)
|
||||||
if ok:
|
if ok:
|
||||||
verplaatst += 1
|
verplaatst += 1
|
||||||
|
else:
|
||||||
|
mislukt += 1
|
||||||
|
|
||||||
if not dry:
|
if not dry:
|
||||||
mail.expunge()
|
mail.expunge()
|
||||||
print(f" {verplaatst}/{n} verplaatst")
|
print(f" Gepland: {gepland} | Verplaatst: {verplaatst} | Fouten: {mislukt}")
|
||||||
|
else:
|
||||||
|
print(f" Gepland: {gepland} | Fouten: {mislukt}")
|
||||||
|
|
||||||
|
|
||||||
# ── log ──────────────────────────────────────────────────────────────────────
|
# ── log ──────────────────────────────────────────────────────────────────────
|
||||||
|
|||||||
Reference in New Issue
Block a user