From 2af807de18a76ae4e0de47def93efc876d0c5c1f Mon Sep 17 00:00:00 2001
From: Tanner Prestegard <tanner.prestegard@ligo.org>
Date: Tue, 11 Dec 2018 09:39:01 -0600
Subject: [PATCH] Cleanup and bugfixes for email alerts

---
 gracedb/alerts/email.py | 185 +---------------------------------------
 gracedb/alerts/main.py  |  10 ++-
 2 files changed, 9 insertions(+), 186 deletions(-)

diff --git a/gracedb/alerts/email.py b/gracedb/alerts/email.py
index f39999acb..f2ffc108d 100644
--- a/gracedb/alerts/email.py
+++ b/gracedb/alerts/email.py
@@ -1,18 +1,10 @@
 from __future__ import absolute_import
-import json
 import logging
-import os
-import socket
-from subprocess import Popen, PIPE, STDOUT
-import sys
 
 from django.core.mail import EmailMessage
 from django.conf import settings
 
 from core.time_utils import gpsToUtc
-from events.models import Event
-from events.permission_utils import is_external
-from search.query.labels import filter_for_labels
 
 # Set up logger
 log = logging.getLogger(__name__)
@@ -39,73 +31,7 @@ def prepareSummary(event):
     Component masses: %.2f, %.2f """ % (si.mass1, si.mass2)
     return summary
 
-# The serialized object passed in here will normally be an EventLog or EMBB log entry
-def issueAlertForUpdate(event, description, doxmpp, filename="", serialized_object=None):
-    if doxmpp:
-        issueXMPPAlert(event, filename, "update", description, serialized_object)
-    # XXX No emails or phone calls for this.  Argh.
-
-# The only kind of serialized object relevant for a Label is an event.
-def issueAlertForLabel(event, label, doxmpp, serialized_event=None, event_url=None):
-    if doxmpp:
-        issueXMPPAlert(event, "", "label", label, serialized_event)
-    # Email
-    profileRecips = []
-    phoneRecips = []
-    pipeline = event.pipeline
-    # Triggers on given label matching pipeline OR with no pipeline (wildcard type)
-    triggers = label.trigger_set.filter(pipelines=pipeline)
-    triggers = triggers | label.trigger_set.filter(pipelines=None)
-    for trigger in triggers:
-        if len(trigger.label_query) > 0:
-            # construct a queryset containing only this event
-            qs = Event.objects.filter(id=event.id)
-            qs = filter_for_labels(qs, trigger.label_query)
-            # If the label query cleans out our query set, we'll continue
-            # without adding the recipient.
-            if qs.count() == 0:
-                continue
-
-        for recip in trigger.contacts.all():
-            if recip.email:
-                profileRecips.append(recip.email)
-            if recip.phone:
-                phoneRecips.append(recip)
-
-    if event.search:
-        subject = "[gracedb] %s / %s / %s / %s" % (label.name, event.pipeline.name, event.search.name, event.graceid)
-    else:
-        subject = "[gracedb] %s / %s / %s" % (label.name, event.pipeline.name, event.graceid)
-
-    message = "A %s event with graceid %s was labeled with %s" % \
-              (event.pipeline.name, event.graceid, label.name)
-    if event_url:
-        message += '\n\n%s' % event_url
-
-    if event.group.name == "Test":
-        fromaddress = settings.ALERT_TEST_EMAIL_FROM
-        toaddresses = settings.ALERT_TEST_EMAIL_TO
-        bccaddresses = []
-        message += "\n\nWould have sent email to: %s" % str(profileRecips)
-        message += "\n\nWould have called/texted: {0}" \
-            .format(str([c.phone for c in phoneRecips]))
-        phoneRecips = []
-    else:
-        fromaddress = settings.ALERT_EMAIL_FROM
-        toaddresses =  []
-        bccaddresses = profileRecips
-
-    if settings.SEND_EMAIL_ALERTS and (toaddresses or bccaddresses):
-        if not toaddresses:
-            toaddresses = ["(undisclosed recipients)"]
-        email = EmailMessage(subject, message, fromaddress, toaddresses, bccaddresses)
-        email.send()
-
-    # Make phone calls.
-    if settings.SEND_PHONE_ALERTS and phoneRecips:
-        make_twilio_calls(event, phoneRecips, "label", label=label)
-
-def issueEmailAlert(event, event_url):
+def issue_email_alerts(event, event_url):
 
     # Check settings switch for turning off email alerts
     if not settings.SEND_EMAIL_ALERTS:
@@ -162,112 +88,3 @@ Event Summary:
 
     email = EmailMessage(subject, message, fromaddress, toaddresses, bccaddresses)
     email.send()
-
-def issuePhoneAlert(event):
-
-    # Check settings switch for turning off phone alerts
-    if not settings.SEND_PHONE_ALERTS:
-        return
-
-    # The right way of doing this is to make the email alerts filter-able
-    # by search. But this is a low priority dev task. For now, we simply 
-    # short-circuit in case this is an MDC event.
-    if event.search and event.search.name == 'MDC':
-        return
-
-    # Gather recipients
-    phoneRecips = []
-    if event.group.name != 'Test':
-        pipeline = event.pipeline
-        triggers = pipeline.trigger_set.filter(labels=None)
-        for trigger in triggers:
-            for recip in trigger.contacts.all():
-                if ((event.far and event.far < trigger.farThresh)
-                    or not trigger.farThresh):
-                    if recip.phone:
-                        phoneRecips.append(recip)
-
-    # Make phone calls.
-    if phoneRecips:
-        make_twilio_calls(event, phoneRecips, "create")
-
-def issueXMPPAlert(event, location, alert_type="new", description="", serialized_object=None):
-    
-    # Check settings switch for turning off XMPP alerts
-    if not settings.SEND_XMPP_ALERTS:
-        return
-
-    nodename = "%s_%s" % (event.group.name, event.pipeline.name)
-    nodename = nodename.lower()
-    nodenames = [ nodename, ]
-    if event.search:
-        nodename = nodename + "_%s" % event.search.name.lower()
-        nodenames.append(nodename)
-
-    log.debug('issueXMPPAlert: %s' % event.graceid)
-
-    # Create the output dictionary and serialize as JSON.
-    lva_data = {
-        'file': location,
-        'uid': event.graceid,
-        'alert_type': alert_type,
-        # The following string cast is necessary because sometimes 
-        # description is a label object!
-        'description': str(description),
-        'labels': [label.name for label in event.labels.all()]
-    }
-    if serialized_object:
-        lva_data['object'] = serialized_object
-    msg = json.dumps(lva_data)
-    log.debug("issueXMPPAlert: writing message %s" % msg)
-
-    if settings.USE_LVALERT_OVERSEER:
-        manager = Manager()
-
-    for server in settings.ALERT_XMPP_SERVERS:
-        port = settings.LVALERT_OVERSEER_PORTS[server]
-        for nodename in nodenames:
-            
-            if settings.USE_LVALERT_OVERSEER:
-                # Calculate unique message_id and log
-                message_id = sha1(nodename + msg).hexdigest()
-                log.info("issueXMPPAlert: sending %s,%s,%s to node %s" % (event.graceid, alert_type, message_id, nodename))
-
-                rdict = manager.dict()
-                msg_dict = {'node_name': nodename, 'message': msg, 'action': 'push'}
-                p = Process(target=send_to_overseer, args=(msg_dict, rdict, log, True, port))
-                p.start()
-                p.join()
-
-                if rdict.get('success', None):
-                    continue
-
-                # If not success, we need to do this the old way.
-                log.info("issueXMPPAlert: failover to lvalert_send") 
-            else:
-                # Not using LVAlert overseer, so just log the node and server
-                log.info("issueXMPPAlert: sending to node %s on %s" % (nodename, server))
-
-            # Set up environment for running lvalert_send script
-            env = os.environ.copy()
-
-            # Construct lvalert_send command
-            p = Popen(
-                ["lvalert_send",
-                 "--server=%s" % server,
-                 "--file=-",
-                 "--node=%s" % nodename,
-                ],
-                stdin=PIPE,
-                stdout=PIPE,
-                stderr=PIPE,
-                env=env)
-
-            # Send lvalert message to subprocess
-            out, err = p.communicate(msg)
-
-            log.debug("issueXMPPAlert: lvalert_send: return code %s" % p.returncode)
-            if p.returncode > 0:
-                # XXX This should probably raise an exception.
-                log.error("issueXMPPAlert: ERROR: %s" % err)
-
diff --git a/gracedb/alerts/main.py b/gracedb/alerts/main.py
index 5d7d04cdc..5aa68e42d 100644
--- a/gracedb/alerts/main.py
+++ b/gracedb/alerts/main.py
@@ -10,6 +10,7 @@ from django.conf import settings
 from django.contrib.auth.models import Group
 from django.core.mail import EmailMessage
 from django.db.models import QuerySet, Q
+from django.urls import reverse
 
 from core.time_utils import gpsToUtc
 from events.models import Event
@@ -18,6 +19,7 @@ from events.shortcuts import is_event
 from search.query.labels import filter_for_labels
 from superevents.shortcuts import is_superevent
 from userprofile.models import Contact
+from .email import issue_email_alerts
 from .phone import issue_phone_alerts
 from .xmpp import issue_xmpp_alerts
 
@@ -126,7 +128,10 @@ def issue_alerts(event_or_superevent, alert_type, serialized_object,
         if event.offline:
             return
 
-    # Compile phone and email recipients for alert
+    # Compile phone and email recipients for new or label alerts
+    if alert_type not in ["new", "label"]:
+        return
+
     if alert_type == "new":
         email_recips, phone_recips = get_alert_recips(event_or_superevent)
         # Force label = None for new alerts
@@ -136,7 +141,8 @@ def issue_alerts(event_or_superevent, alert_type, serialized_object,
             get_alert_recips_for_label(event_or_superevent, label)
 
     if settings.SEND_EMAIL_ALERTS:
-        issueEmailAlert(event_or_superevent, url)
+        url = reverse('view', args=[event_or_superevent.graceid])
+        issue_email_alerts(event_or_superevent, url)
 
     if settings.SEND_PHONE_ALERTS and phone_recips:
         issue_phone_alerts(event_or_superevent, phone_recips, label=label)
-- 
GitLab