AIDA / scripts /delete_shadow_users.py
destinyebuka's picture
fyp
2bcedf3
Raw
History Blame Contribute Delete
2.73 kB
"""
delete_shadow_users.py
======================
One-time utility to wipe all shadow users (and their listings) from MongoDB.
Run from the AIDA/ directory:
python scripts/delete_shadow_users.py
Pass --dry-run to preview what would be deleted without actually deleting:
python scripts/delete_shadow_users.py --dry-run
"""
import asyncio
import logging
import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from app.database import connect_db, get_db, disconnect_db
logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s")
logger = logging.getLogger(__name__)
DRY_RUN = "--dry-run" in sys.argv
async def run():
await connect_db()
try:
db = await get_db()
# ── 1. Find all shadow users ──────────────────────────────────────
shadow_cursor = db.users.find(
{"account_type": "shadow"},
{"_id": 1, "display_name": 1, "whatsapp_number": 1},
)
shadow_users = await shadow_cursor.to_list(length=None)
if not shadow_users:
logger.info("No shadow users found β€” nothing to delete.")
return
logger.info(f"Found {len(shadow_users)} shadow user(s):")
for u in shadow_users:
logger.info(
f" β€’ {u.get('display_name', 'β€”')} | {u.get('whatsapp_number', 'β€”')} | id={u['_id']}"
)
if DRY_RUN:
logger.info("\n[DRY RUN] No changes made. Remove --dry-run to execute.")
return
# ── 2. Collect their IDs ──────────────────────────────────────────
ids = [str(u["_id"]) for u in shadow_users]
# ── 3. Delete their listings ─────────────────────────────────────
listings_result = await db.listings.delete_many({"owner_id": {"$in": ids}})
logger.info(f"Deleted {listings_result.deleted_count} listing(s) owned by shadow users.")
# ── 4. Delete the shadow users themselves ─────────────────────────
from bson import ObjectId
oids = [u["_id"] for u in shadow_users]
users_result = await db.users.delete_many({"_id": {"$in": oids}})
logger.info(f"Deleted {users_result.deleted_count} shadow user(s).")
logger.info("\nβœ… Done. All shadow users and their listings have been removed.")
finally:
await disconnect_db()
if __name__ == "__main__":
asyncio.run(run())