Spaces:
Running
Running
| #!/usr/bin/env python3 | |
| """ | |
| Backfill script to send missed alert notifications | |
| Processes all active alerts and notifies users about matching listings they missed | |
| """ | |
| import asyncio | |
| import sys | |
| from pathlib import Path | |
| # Add parent directory to path | |
| sys.path.insert(0, str(Path(__file__).parent.parent)) | |
| from app.database import connect_db, disconnect_db, get_db | |
| from app.services.alert_service import process_new_listing | |
| from bson import ObjectId | |
| import logging | |
| logging.basicConfig(level=logging.INFO) | |
| logger = logging.getLogger(__name__) | |
| async def backfill_alert_notifications(): | |
| """Process all active listings against all active alerts""" | |
| try: | |
| # Connect to database | |
| await connect_db() | |
| db = await get_db() | |
| # Get all active alerts | |
| alerts = await db.search_alerts.find({"is_active": True}).to_list(length=None) | |
| logger.info(f"Found {len(alerts)} active alerts") | |
| if not alerts: | |
| logger.info("No active alerts to process") | |
| return | |
| # Get all active listings | |
| listings = await db.listings.find({"status": "active"}).to_list(length=None) | |
| logger.info(f"Found {len(listings)} active listings") | |
| if not listings: | |
| logger.info("No active listings to process") | |
| return | |
| # Process each listing against all alerts | |
| notification_count = 0 | |
| for listing in listings: | |
| logger.info(f"Processing listing: {listing.get('title')} ({listing.get('_id')})") | |
| try: | |
| # Use the existing process_new_listing function which: | |
| # - Checks all active alerts | |
| # - Filters out owner's own alerts | |
| # - Only notifies if last_notified_at is old enough | |
| matches = await process_new_listing(listing) | |
| if matches > 0: | |
| notification_count += matches | |
| logger.info(f" ✅ Sent {matches} notification(s)") | |
| except Exception as e: | |
| logger.error(f" ❌ Error processing listing {listing.get('_id')}: {e}") | |
| continue | |
| logger.info(f"\n{'='*60}") | |
| logger.info(f"Backfill complete!") | |
| logger.info(f"Processed {len(listings)} listings") | |
| logger.info(f"Sent {notification_count} total notifications") | |
| logger.info(f"{'='*60}\n") | |
| except Exception as e: | |
| logger.error(f"Backfill failed: {e}") | |
| raise | |
| finally: | |
| await disconnect_db() | |
| if __name__ == "__main__": | |
| logger.info("Starting alert notification backfill...") | |
| asyncio.run(backfill_alert_notifications()) | |