Files
claudetools/temp/bardach_ops_4_verify.py
Mike Swanson fa15b03180 sync: Auto-sync from ACG-M-L5090 at 2026-03-10 19:11:00
Synced files:
- Quote wizard frontend (all components, hooks, types, config)
- API updates (config, models, routers, schemas, services)
- Client work (bg-builders, gurushow)
- Scripts (BGB Lesley termination, CIPP, Datto, migration)
- Temp files (Bardach contacts, VWP investigation, misc)
- Credentials and session logs
- Email service, PHP API, session logs

Machine: ACG-M-L5090
Timestamp: 2026-03-10 19:11:00

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 19:59:08 -07:00

141 lines
4.9 KiB
Python

"""
Final Verification: Count remaining Temp contacts and summarize all operations.
"""
import json
import subprocess
import urllib.parse
TENANT_ID = "dd4a82e8-85a3-44ac-8800-07945ab4d95f"
CLIENT_ID = "fabb3421-8b34-484b-bc17-e46de9703418"
CLIENT_SECRET = "~QJ8Q~NyQSs4OcGqHZyPrA2CVnq9KBfKiimntbMO"
SCOPE = "https://graph.microsoft.com/.default"
USER = "barbara@bardach.net"
TEMP_FOLDER_ID = None # Will be resolved dynamically
def get_token():
url = f"https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token"
data = (
f"client_id={CLIENT_ID}"
f"&scope={urllib.parse.quote(SCOPE)}"
f"&client_secret={urllib.parse.quote(CLIENT_SECRET)}"
f"&grant_type=client_credentials"
)
result = subprocess.run(
["curl", "-s", "-X", "POST", url,
"-H", "Content-Type: application/x-www-form-urlencoded",
"-d", data],
capture_output=True, text=True
)
resp = json.loads(result.stdout)
if "access_token" not in resp:
print(f"[ERROR] Token acquisition failed: {resp}")
raise Exception("Failed to get token")
return resp["access_token"]
def count_temp_contacts(token):
"""Count contacts in Temp folder using $count."""
url = (
f"https://graph.microsoft.com/v1.0/users/{USER}"
f"/contactFolders/{TEMP_FOLDER_ID}/contacts?$count=true&$top=1&$select=id"
)
result = subprocess.run(
["curl", "-s", "-X", "GET", url,
"-H", f"Authorization: Bearer {token}",
"-H", "ConsistencyLevel: eventual"],
capture_output=True, text=True
)
resp = json.loads(result.stdout)
count = resp.get("@odata.count")
if count is not None:
return count
# Fallback: page through all
print("[INFO] @odata.count not available, paging through contacts...")
total = 0
page_url = (
f"https://graph.microsoft.com/v1.0/users/{USER}"
f"/contactFolders/{TEMP_FOLDER_ID}/contacts?$top=100&$select=id"
)
while page_url:
result = subprocess.run(
["curl", "-s", "-X", "GET", page_url,
"-H", f"Authorization: Bearer {token}"],
capture_output=True, text=True
)
resp = json.loads(result.stdout)
contacts = resp.get("value", [])
total += len(contacts)
page_url = resp.get("@odata.nextLink")
if total % 500 == 0 and total > 0:
print(f" ...counted {total} so far")
return total
def main():
print("=" * 60)
print("FINAL VERIFICATION")
print("=" * 60)
token = get_token()
print("[OK] Token acquired")
# Find Temp folder ID
global TEMP_FOLDER_ID
url = f"https://graph.microsoft.com/v1.0/users/{USER}/contactFolders"
result = subprocess.run(
["curl", "-s", "-X", "GET", url,
"-H", f"Authorization: Bearer {token}"],
capture_output=True, text=True
)
folders = json.loads(result.stdout).get("value", [])
for f in folders:
if "temp" in f.get("displayName", "").lower():
TEMP_FOLDER_ID = f["id"]
print(f"[INFO] Found Temp folder: '{f['displayName']}' -> {TEMP_FOLDER_ID[:40]}...")
break
if not TEMP_FOLDER_ID:
print("[ERROR] Could not find Temp contact folder!")
for f in folders:
print(f" Folder: {f.get('displayName')} -> {f['id'][:40]}...")
return
# Count remaining Temp contacts
print("\n[INFO] Counting remaining Temp contacts...")
remaining = count_temp_contacts(token)
print(f"[INFO] Remaining Temp contacts: {remaining}")
print(f"[INFO] Expected: ~3,888 (matches_with_extras)")
# Load operation results
print("\n--- OPERATION SUMMARIES ---")
for op_file, label in [
("D:/ClaudeTools/temp/bardach_op1_delete_exact.json", "Op1: Delete Exact Matches"),
("D:/ClaudeTools/temp/bardach_op2_move_unique.json", "Op2: Move Unique Contacts"),
("D:/ClaudeTools/temp/bardach_op3_delete_blank.json", "Op3: Delete Blank Contacts"),
]:
try:
with open(op_file, "r") as f:
r = json.load(f)
print(f"\n {label}:")
print(f" Total: {r['total']}")
print(f" Successes: {r['successes']}")
print(f" Failures: {r['failures']}")
if r.get("elapsed_seconds"):
print(f" Time: {r['elapsed_seconds']}s")
if r.get("method"):
print(f" Method: {r['method']}")
except FileNotFoundError:
print(f"\n {label}: [NOT FOUND] {op_file}")
except Exception as e:
print(f"\n {label}: [ERROR] {e}")
print(f"\n{'=' * 60}")
print(f"Remaining Temp contacts: {remaining}")
diff = remaining - 3888
if abs(diff) < 10:
print(f"[OK] Close to expected (~3,888), difference: {diff}")
else:
print(f"[WARNING] Difference from expected (3,888): {diff}")
print("=" * 60)
if __name__ == "__main__":
main()