Files
2026-06-08 07:20:37 +02:00

130 lines
4.0 KiB
Python

"""
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()