Update send_node_digest_notifications.py

This commit is contained in:
Groupr 2025-10-20 19:28:03 +00:00
parent 235e7d6f9b
commit 5e0c0ef23b

View file

@ -14,7 +14,7 @@ import logging
import transaction
from pyramid.paster import bootstrap, setup_logging
from ..lib.notify import deliver_scheduled_notifications
from ..lib.notify import get_email_notifications, send_digest_notifications, filter_orphaned_notifications
from ..models import get_tm_session
from ..models.notification import NodeEventNotification
from ..models.meta import now_timestamp
@ -55,6 +55,32 @@ def should_have_been_sent(notification):
return False
def safe_deliver_scheduled_notifications(request, dbsession):
"""
Deliver scheduled notifications with protection against orphaned notifications.
"""
from datetime import datetime
# Temporarily replace request.dbsession with our transaction-managed session
old_dbsession = request.dbsession
request.dbsession = dbsession
try:
# Get daily notifications and filter out orphaned ones
notification_dict = get_email_notifications(dbsession, "daily")
filtered_dict = filter_orphaned_notifications(notification_dict)
send_digest_notifications(request, filtered_dict, "daily")
# Send weekly on Monday
if datetime.today().weekday() == 0:
notification_dict = get_email_notifications(dbsession, "weekly")
filtered_dict = filter_orphaned_notifications(notification_dict)
send_digest_notifications(request, filtered_dict, "weekly")
finally:
# Restore original dbsession
request.dbsession = old_dbsession
def get_unsent_notification_count(request):
"""
Get count of unsent notifications using a fresh database session.
@ -77,6 +103,7 @@ def get_unsent_notification_count(request):
def mark_ready_notifications_as_sent(request):
"""
Mark notifications as sent if they were ready to be delivered based on frequency rules.
Only marks non-orphaned notifications (those with valid node_event).
Args:
request: Pyramid request object
@ -88,36 +115,42 @@ def mark_ready_notifications_as_sent(request):
dbsession = get_tm_session(
request.registry["dbsession_factory"], transaction.manager
)
# Get all unsent notifications
unsent_notifications = dbsession.query(NodeEventNotification).filter(
NodeEventNotification.sent == False
).all()
total_unsent = len(unsent_notifications)
if total_unsent == 0:
return total_unsent, 0, 0
# Only mark notifications that should have been sent based on frequency
# and are not orphaned (have valid node_event)
ready_notification_ids = [
n.id for n in unsent_notifications
if should_have_been_sent(n)
n.id for n in unsent_notifications
if should_have_been_sent(n) and n.node_event is not None
]
# Count orphaned notifications separately
orphaned_count = sum(1 for n in unsent_notifications if n.node_event is None)
if orphaned_count > 0:
log.warning(f"Found {orphaned_count} orphaned notifications that will not be marked as sent")
marked_as_sent = 0
if ready_notification_ids:
marked_as_sent = dbsession.query(NodeEventNotification).filter(
NodeEventNotification.id.in_(ready_notification_ids)
).update({
'sent': True,
'sent': True,
'updated_timestamp': now_timestamp()
}, synchronize_session=False)
# Ensure changes are persisted
dbsession.flush()
transaction.commit()
left_for_later = total_unsent - marked_as_sent
return total_unsent, marked_as_sent, left_for_later
@ -142,10 +175,14 @@ def main():
log.info("No notifications to process")
return
# Deliver scheduled notifications
# Deliver scheduled notifications with orphaned notification protection
log.info("Delivering scheduled notifications...")
deliver_scheduled_notifications(request)
transaction.commit()
with transaction.manager:
dbsession = get_tm_session(
request.registry["dbsession_factory"], transaction.manager
)
safe_deliver_scheduled_notifications(request, dbsession)
transaction.commit()
# Check final state and mark ready notifications as sent
log.info("Checking for notifications that need to be marked as sent...")