@@ -1437,7 +1437,8 @@ def process_notifications(new_slots: List[Dict]) -> None:
14371437
14381438 logging .info (f"Processing notifications for { len (subscriptions )} subscriptions and { len (new_slots )} slots" )
14391439
1440- # Process each slot
1440+ # Parse all slots with datetime
1441+ parsed_slots = []
14411442 for slot in new_slots :
14421443 time_str = slot .get ('time' , '' )
14431444 if not time_str :
@@ -1460,36 +1461,113 @@ def process_notifications(new_slots: List[Dict]) -> None:
14601461 if dt_object is None :
14611462 continue
14621463
1463- # Extract day name and hour (local time, no timezone conversion)
1464- day_name = dt_object .strftime ("%A" ) # Monday, Tuesday, etc.
1465- hour = dt_object .hour # 0-23
1464+ parsed_slots .append ({
1465+ 'slot' : slot ,
1466+ 'dt' : dt_object ,
1467+ 'day_name' : dt_object .strftime ("%A" ),
1468+ 'hour' : dt_object .hour
1469+ })
1470+
1471+ # Process each subscription
1472+ for sub in subscriptions :
1473+ sub_day = sub .get ('day_of_week' , '' )
1474+ start_hour = sub .get ('start_hour' , 0 )
1475+ end_hour = sub .get ('end_hour' , 23 )
1476+ chat_id = sub .get ('chat_id' , '' )
1477+
1478+ # Find all matching slots for this subscription
1479+ matching_slots = []
1480+ for parsed in parsed_slots :
1481+ if parsed ['day_name' ] == sub_day and start_hour <= parsed ['hour' ] <= end_hour :
1482+ matching_slots .append (parsed )
1483+
1484+ if not matching_slots :
1485+ continue
1486+
1487+ # Detect 2-hour slots (back-to-back hours on same court)
1488+ two_hour_slots = []
1489+ one_hour_slots = []
1490+ processed_indices = set ()
14661491
1467- # Check against each subscription
1468- for sub in subscriptions :
1469- sub_day = sub .get ('day_of_week' , '' )
1470- start_hour = sub .get ('start_hour' , 0 )
1471- end_hour = sub .get ('end_hour' , 23 )
1472- chat_id = sub .get ('chat_id' , '' )
1492+ for i , parsed1 in enumerate (matching_slots ):
1493+ if i in processed_indices :
1494+ continue
14731495
1474- # Check if day matches and hour is within range
1475- if day_name == sub_day and start_hour <= hour <= end_hour :
1476- # Match found! Send Telegram notification
1477- try :
1478- message = f"🎾 *Match Found!*\n \n { slot .get ('court' , 'Court' )} is available { day_name } at { time_str } .\n { slot .get ('link' , '#' )} "
1479-
1480- url = f"https://api.telegram.org/bot{ bot_token } /sendMessage"
1481- payload = {
1482- 'chat_id' : chat_id ,
1483- 'text' : message ,
1484- 'parse_mode' : 'Markdown'
1485- }
1486-
1487- response = requests .post (url , json = payload , timeout = 10 )
1488- response .raise_for_status ()
1496+ slot1 = parsed1 ['slot' ]
1497+ dt1 = parsed1 ['dt' ]
1498+ court1 = slot1 .get ('court' , '' )
1499+
1500+ # Check if next hour is also available on same court
1501+ next_hour = dt1 + timedelta (hours = 1 )
1502+ found_two_hour = False
1503+
1504+ for j , parsed2 in enumerate (matching_slots ):
1505+ if i != j and j not in processed_indices :
1506+ slot2 = parsed2 ['slot' ]
1507+ dt2 = parsed2 ['dt' ]
1508+ court2 = slot2 .get ('court' , '' )
14891509
1490- logging .info (f"Sent notification to chat_id { chat_id } for { slot .get ('court' )} at { time_str } " )
1491- except Exception as e :
1492- logging .error (f"Failed to send notification to chat_id { chat_id } : { e } " )
1510+ if (court1 == court2 and
1511+ dt2 .date () == next_hour .date () and
1512+ dt2 .hour == next_hour .hour ):
1513+ # Found a 2-hour slot!
1514+ end_time = dt2 + timedelta (hours = 1 )
1515+ two_hour_slots .append ({
1516+ 'court' : court1 ,
1517+ 'start_time' : dt1 ,
1518+ 'end_time' : end_time
1519+ })
1520+ processed_indices .add (i )
1521+ processed_indices .add (j )
1522+ found_two_hour = True
1523+ break
1524+
1525+ if not found_two_hour :
1526+ one_hour_slots .append ({
1527+ 'slot' : slot1 ,
1528+ 'dt' : dt1 ,
1529+ 'court' : court1
1530+ })
1531+
1532+ # Build message
1533+ if not two_hour_slots and not one_hour_slots :
1534+ continue
1535+
1536+ message_parts = ["🎾 *Match Found!*\n " ]
1537+
1538+ # Add 2-hour slots
1539+ if two_hour_slots :
1540+ message_parts .append ("*2-Hour Slots:*\n " )
1541+ for slot in two_hour_slots :
1542+ start_str = slot ['start_time' ].strftime ("%Y-%m-%d %I:%M %p" )
1543+ end_str = slot ['end_time' ].strftime ("%I:%M %p" )
1544+ message_parts .append (f"• { slot ['court' ]} : { start_str } - { end_str } \n " )
1545+ message_parts .append ("\n " )
1546+
1547+ # Add 1-hour slots
1548+ if one_hour_slots :
1549+ message_parts .append ("*1-Hour Slots:*\n " )
1550+ for slot in one_hour_slots :
1551+ time_str = slot ['dt' ].strftime ("%Y-%m-%d %I:%M %p" )
1552+ message_parts .append (f"• { slot ['court' ]} : { time_str } \n " )
1553+
1554+ # Send notification
1555+ try :
1556+ message = "" .join (message_parts )
1557+
1558+ url = f"https://api.telegram.org/bot{ bot_token } /sendMessage"
1559+ payload = {
1560+ 'chat_id' : chat_id ,
1561+ 'text' : message ,
1562+ 'parse_mode' : 'Markdown'
1563+ }
1564+
1565+ response = requests .post (url , json = payload , timeout = 10 )
1566+ response .raise_for_status ()
1567+
1568+ logging .info (f"Sent notification to chat_id { chat_id } with { len (two_hour_slots )} two-hour and { len (one_hour_slots )} one-hour slots" )
1569+ except Exception as e :
1570+ logging .error (f"Failed to send notification to chat_id { chat_id } : { e } " )
14931571
14941572 except Exception as e :
14951573 logging .error (f"Error processing notifications: { e } " )
0 commit comments