Spaces:
Running
Running
| """ | |
| 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()) | |