Spaces:
Running
Running
File size: 4,823 Bytes
1abc143 5abadff 1abc143 5abadff 1abc143 5abadff 1abc143 5abadff 1abc143 5abadff 1abc143 5abadff 1abc143 5abadff 1abc143 5abadff 1abc143 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
#!/usr/bin/env python3
"""
One-time Backfill Script: Send notifications for existing listings matching alerts.
This script:
1. Fetches all active search_alerts
2. Fetches all published listings
3. Checks each listing against each alert
4. Sends DM notifications for matches (avoiding duplicates)
Usage:
cd python-Backend/lojiz-backend/AIDA
python -m scripts.backfill_alerts
Or run as standalone:
python scripts/backfill_alerts.py
"""
import asyncio
import sys
import os
# Add parent directory to path for imports
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from datetime import datetime
from typing import List, Dict, Any
async def run_backfill():
"""Main backfill function."""
# Import after path setup
from app.database import get_db, connect_db, disconnect_db
from app.models.search_alert import SearchAlert
from app.services.alert_service import check_listing_matches_alert, notify_user_of_match
print("="*60)
print(" ALERT BACKFILL SCRIPT")
print("="*60)
print(f"Started at: {datetime.now().isoformat()}")
print()
# Initialize DB Connection
await connect_db()
try:
db = await get_db()
# 1. Fetch all active alerts
print(" Fetching active search alerts...")
alerts_cursor = db.search_alerts.find({"is_active": True})
alerts = [SearchAlert(**doc) async for doc in alerts_cursor]
print(f" Found {len(alerts)} active alerts")
if not alerts:
print(" No active alerts found. Nothing to backfill.")
return
# Print alert summary
for alert in alerts:
print(f" - User {alert.user_id}: '{alert.user_query}'")
print()
# 2. Fetch all published listings
print(" Fetching published listings...")
listings_cursor = db.listings.find({"status": "active"})
listings = await listings_cursor.to_list(length=1000) # Limit for safety
print(f" Found {len(listings)} active listings")
print()
if not listings:
print(" No active listings found. Nothing to match.")
return
# 3. Check each listing against each alert
print(" Checking matches...")
matches_found = 0
notifications_sent = 0
skipped_duplicates = 0
for listing in listings:
listing_id = str(listing["_id"])
listing_title = listing.get("title", "Untitled")
listing_location = listing.get("location", "Unknown")
for alert in alerts:
# Check if this alert already received notification for this listing
# (We store notified listing IDs in alert to prevent duplicate notifications)
notified_listings = alert.notified_listing_ids or []
if listing_id in notified_listings:
skipped_duplicates += 1
continue
# Check if listing matches alert criteria
if await check_listing_matches_alert(listing, alert):
matches_found += 1
print(f" MATCH: '{listing_title}' ({listing_location}) -> User {alert.user_id}")
try:
# Send notification
await notify_user_of_match(alert, listing)
notifications_sent += 1
# Mark listing as notified for this alert (prevent duplicates)
await db.search_alerts.update_one(
{"_id": alert.id},
{"$addToSet": {"notified_listing_ids": listing_id}}
)
print(f" Notification sent!")
except Exception as e:
print(f" Failed to notify: {e}")
# 4. Summary
print()
print("="*60)
print(" BACKFILL SUMMARY")
print("="*60)
print(f" Alerts processed: {len(alerts)}")
print(f" Listings checked: {len(listings)}")
print(f" Matches found: {matches_found}")
print(f" Notifications sent: {notifications_sent}")
print(f" Duplicates skipped: {skipped_duplicates}")
print()
print(f"Completed at: {datetime.now().isoformat()}")
print("="*60)
finally:
await disconnect_db()
if __name__ == "__main__":
print("\n" + " Starting Alert Backfill Script..." + "\n")
asyncio.run(run_backfill())
print("\n" + " Script completed!" + "\n")
|