""" wipe_jnj_mailbox.py | 2026-06-08 Vyčistí složku Inbox/JNJ ve schránce vladimir.buzalka@buzalka.cz PŘED testem mirroru. - Zachová samotnou složku Inbox/JNJ - Trvale smaže (permanentDelete — obchází Deleted Items) všechny zprávy v JNJ i ve všech podsložkách - Smaže všechny podsložky JNJ (Inbox, Sent Items, Deleted Items, ...) Výsledek: Inbox/JNJ existuje a je prázdná. Mirror si podsložky vytvoří znovu. """ import sys import msal import requests sys.stdout.reconfigure(encoding="utf-8") GRAPH_TENANT_ID = "7d269944-37a4-43a1-8140-c7517dc426e9" GRAPH_CLIENT_ID = "4b222bfd-78c9-4239-a53f-43006b3ed07f" GRAPH_CLIENT_SECRET = "Txg8Q~MjhocuopxsJyJBhPmDfMxZ2r5WpTFj1dfk" GRAPH_MAILBOX = "vladimir.buzalka@buzalka.cz" GRAPH_URL = "https://graph.microsoft.com/v1.0" _token = None def token(): global _token app = msal.ConfidentialClientApplication( GRAPH_CLIENT_ID, authority=f"https://login.microsoftonline.com/{GRAPH_TENANT_ID}", client_credential=GRAPH_CLIENT_SECRET, ) res = app.acquire_token_for_client(scopes=["https://graph.microsoft.com/.default"]) if "access_token" not in res: raise RuntimeError(f"auth failed: {res}") _token = res["access_token"] return _token def H(): return {"Authorization": f"Bearer {_token or token()}"} def get_jnj_id(): r = requests.get(f"{GRAPH_URL}/users/{GRAPH_MAILBOX}/mailFolders/Inbox/childFolders?$top=100", headers=H(), timeout=20).json() for f in r.get("value", []): if f["displayName"] == "JNJ": return f["id"] return None def child_folders(fid): out = [] url = f"{GRAPH_URL}/users/{GRAPH_MAILBOX}/mailFolders/{fid}/childFolders?$top=100" while url: r = requests.get(url, headers=H(), timeout=20).json() out += r.get("value", []) url = r.get("@odata.nextLink") return out def all_descendants(root_id): """Vrať [(id, displayName)] root + všech podsložek (BFS).""" result = [(root_id, "JNJ")] i = 0 while i < len(result): fid = result[i][0] i += 1 for f in child_folders(fid): result.append((f["id"], f["displayName"])) return result def wipe_messages(fid, name): deleted = 0 while True: r = requests.get( f"{GRAPH_URL}/users/{GRAPH_MAILBOX}/mailFolders/{fid}/messages?$select=id&$top=100", headers=H(), timeout=30).json() msgs = r.get("value", []) if not msgs: break for m in msgs: pd = requests.post( f"{GRAPH_URL}/users/{GRAPH_MAILBOX}/messages/{m['id']}/permanentDelete", headers=H(), timeout=20) if pd.status_code in (200, 204): deleted += 1 else: # fallback: běžné smazání requests.delete(f"{GRAPH_URL}/users/{GRAPH_MAILBOX}/messages/{m['id']}", headers=H(), timeout=20) deleted += 1 print(f" {name}: smazáno {deleted} zpráv") return deleted def main(): print("=== wipe_jnj_mailbox ===") token() jnj_id = get_jnj_id() if not jnj_id: print("Složka Inbox/JNJ neexistuje — není co mazat.") return folders = all_descendants(jnj_id) print(f"Nalezeno složek pod JNJ (vč. JNJ): {len(folders)}\n") print("Mažu zprávy (trvale)...") total = 0 for fid, name in folders: total += wipe_messages(fid, name) # smaž podsložky JNJ (ne samotnou JNJ) print("\nMažu podsložky JNJ...") subs = child_folders(jnj_id) for f in subs: r = requests.delete(f"{GRAPH_URL}/users/{GRAPH_MAILBOX}/mailFolders/{f['id']}", headers=H(), timeout=20) print(f" podsložka {f['displayName']}: {'smazána' if r.status_code in (200,204) else 'CHYBA '+str(r.status_code)}") print(f"\n=== Hotovo: smazáno {total} zpráv, Inbox/JNJ je prázdná ===") if __name__ == "__main__": main()