Source code for uw.local.grad.db.notification

"""Notification system implementation.

This module provides routines to record notifications and either send them
immediately, later as part of a daily digest, or not at all.  Each user can
configure what happens to various classes of their notifications.
"""

from itertools import groupby
from operator import attrgetter

from uw.emailutils import emailaddr

from ...outgoing.make_mail import mailout

from ..webui.util import get_email_address

_category = None
[docs]def find_category (cursor, category_code): """Find information about a notification category. :param cursor: DB connection cursor. :param category_code: the notification category code. Returns a row from _grad.notification_category. """ global _category if _category is None: _category = dict (cursor.execute_tuples ("select category_code, category_description from notification_category")) return _category[category_code]
notice_email = emailaddr ('Graduate Admissions Notices', 'donotreply@uwaterloo.ca')
[docs]def send_message (cursor, person_id, category_code, content): """Send a notification to a person. :param cursor: DB connection cursor. :param person_id: the identity of the notification recipient. :param category_code: the notification category code. :param content: the content of the notification message. """ message = mailout (cursor, notice_email, "Notification of " + find_category (cursor, category_code), content) message.add_recipient ('To', get_email_address (cursor, person_id)) message.done () return message.msg_id
[docs]def make_content (text, url): """Generate the content of a notification message. :param text: the brief explanatory notification text. :param url: the associated URL. The generated content is simply the notification text followed by a blank line and then the URL. """ return "%s\n\n%s\n" % (text, url)
[docs]def notify (cursor, person_ids, category_code, text, url): """Generate notifications to some people. :param cursor: DB connection cursor. :param list person_ids: the identities of the notification recipients. :param category_code: the notification category code. :param text: the brief explanatory notification text. :param url: the associated URL. """ event_id = cursor.execute_required_value ("INSERT INTO notification_event (category_code, event_text, event_url) VALUES (%(category_code)s, %(text)s, %(url)s) RETURNING event_id", category_code=category_code, text=text, url=url) for person_id in person_ids: method = cursor.execute_required_value ("SELECT pref_handling FROM notification_category_active_preference WHERE person_id=%(person_id)s AND category_code=%(category_code)s", person_id=person_id, category_code=category_code) if method=='IND': msg_id = send_message (cursor, person_id, category_code, make_content (text, url)) print("sent IND notification, msg_id=%r" % msg_id) else: msg_id = None cursor.execute_none ("INSERT INTO notification_person VALUES (%(event_id)s, %(person_id)s, %(method)s, %(msg_id)s)", event_id=event_id, person_id=person_id, method=method, msg_id=msg_id)
[docs]def send_digest_notifications (cursor): """Send previously-unsent notification digests. :param cursor: DB connection cursor. Look up unsent notifications in _grad.notification_person_tosend and generate corresponding email notifications. """ rows = cursor.execute_tuples ("select * from notification_person_tosend") for message, events in groupby (rows, attrgetter ('person_id', 'category_code')): events = list (events) msg_id = send_message (cursor, message[0], message[1], '\n'.join (make_content (row.event_text, row.event_url) for row in events)) for row in events: cursor.execute_none ("update notification_person as np set event_notified_msg_id=%(msg_id)s from notification_person_tosend as npt join notification_person_unsent as npu using (person_id, category_code, event_text, event_url) where np.event_notified_msg_id is null and (npt.event_id, npt.person_id) = (%(event_id)s, %(message)s) and (np.event_id, np.person_id) = (npu.event_id, npu.person_id)", msg_id=msg_id, event_id=row.event_id, message=message[0])