Skip to content

Commit 14ce71b

Browse files
committed
email notification when extraction is done
1 parent 44876af commit 14ce71b

File tree

4 files changed

+75
-2
lines changed

4 files changed

+75
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
99
- files.upload_preview and collections.upload_preview does not require section_id for metadata [CATS-935](https://opensource.ncsa.illinois.edu/jira/browse/CATS-935)
1010

1111
### Added
12+
- Email notification when extraction is done [CATSPYC-17] (https://opensource.ncsa.illinois.edu/jira/browse/CATSPYC-17)
1213
- Docker compose file for starting up the Clowder stack [BD-2226](https://opensource.ncsa.illinois.edu/jira/browse/BD-2226)
1314

1415
## 2.1.1 - 2018-07-12
@@ -40,4 +41,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
4041
- Now has onbuild version of pyclowder
4142
- release.sh will now tag images (e.g. this will be tagged 2.0.3 2.0 and 2)
4243
- RABBITMQ_URI is now set to amqp://guest:guest@rabbitmq/%2F to allow easy deployment
43-
using docker-compose of clowder
44+
using docker-compose of clowder

Dockerfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ ENV RABBITMQ_URI="amqp://guest:guest@rabbitmq:5672/%2F" \
55
RABBITMQ_EXCHANGE="clowder" \
66
RABBITMQ_QUEUE="" \
77
REGISTRATION_ENDPOINTS="" \
8+
EMAIL_SERVER="" \
9+
EMAIL_SENDER="extractor" \
810
MAIN_SCRIPT=""
911

1012
# install python
@@ -23,6 +25,7 @@ RUN pip install --upgrade /tmp/pyclowder \
2325

2426
# folder for pyclowder code
2527
WORKDIR /home/clowder
28+
COPY notifications.json /home/clowder
2629

2730
# command to run when starting container
2831
CMD python "./${MAIN_SCRIPT}"

notifications.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"extractor_name": "ExtractorName",
3+
"sender": "[email protected]",
4+
"notifications": {
5+
"email": {
6+
"from": "${sender}",
7+
"subject": "${extractor_name} is done",
8+
"body": "This is email notification on extraction completion."
9+
}
10+
}
11+
}

pyclowder/connectors.py

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@
4848
import pyclowder.files
4949
import pyclowder.utils
5050

51+
import smtplib
52+
from email.mime.text import MIMEText
53+
from email.mime.multipart import MIMEMultipart
54+
from string import Template
55+
5156

5257
class Connector(object):
5358
""" Class that will listen for messages.
@@ -70,6 +75,49 @@ def __init__(self, extractor_name, extractor_info, check_message=None, process_m
7075
else:
7176
self.mounted_paths = mounted_paths
7277

78+
filename = 'notifications.json'
79+
self.smtp_server = None
80+
if os.path.isfile(filename):
81+
try:
82+
with open(filename) as notifications_file:
83+
notifications_content = notifications_file.read()
84+
notifications_template = Template(notifications_content)
85+
notifications_json = json.loads(notifications_content)
86+
notifications_json['extractor_name'] = extractor_name
87+
notifications = notifications_template.safe_substitute(notifications_json)
88+
89+
notifications_interpolate = json.loads(notifications)
90+
self.smtp_server = os.getenv('EMAIL_SERVER', None)
91+
self.emailmsg = MIMEMultipart('alternative')
92+
93+
self.emailmsg['From'] = os.getenv('EMAIL_SENDER', notifications_json.get('sender'))
94+
self.emailmsg['Subject'] = notifications_interpolate.get('notifications').get('email').get(
95+
'subject')
96+
self.emailmsg['Body'] = notifications_interpolate.get('notifications').get('email').get('body')
97+
except Exception: # pylint: disable=broad-except
98+
print("Error loading notifications.json")
99+
100+
def email(self, emaillist, clowderurl):
101+
""" Send extraction completion as the email notification """
102+
logger = logging.getLogger(__name__)
103+
if emaillist and self.smtp_server:
104+
server = smtplib.SMTP(self.smtp_server)
105+
msg = MIMEMultipart('alternative')
106+
msg['Subject'] = self.emailmsg['Subject']
107+
msg['From'] = self.emailmsg['From']
108+
109+
content = "%s \n%s" % (self.emailmsg['Body'], clowderurl)
110+
content = MIMEText(content.encode('utf-8'), _charset='utf-8')
111+
msg.attach(content)
112+
113+
try:
114+
logger.debug("send email notification to %s, %s " % (emaillist, msg.as_string()))
115+
server.sendmail(msg['From'], emaillist, msg.as_string())
116+
except:
117+
logger.warning("failed to send email notification to %s" % emaillist)
118+
pass
119+
server.quit()
120+
73121
def listen(self):
74122
"""Listen for incoming messages.
75123
@@ -309,7 +357,10 @@ def _process_message(self, body):
309357
"""
310358

311359
logger = logging.getLogger(__name__)
312-
360+
emailaddrlist = None
361+
if body.get('notifies'):
362+
emailaddrlist = body.get('notifies')
363+
logger.debug(emailaddrlist)
313364
host = body.get('host', '')
314365
if host == '':
315366
return
@@ -356,6 +407,10 @@ def _process_message(self, body):
356407
resource['local_paths'] = [file_path]
357408

358409
self.process_message(self, host, secret_key, resource, body)
410+
411+
clowderurl = "%sfiles/%s" % (host, body.get('id', ''))
412+
# notificatino of extraction job is done by email.
413+
self.email(emailaddrlist, clowderurl)
359414
finally:
360415
if file_path is not None and not found_local:
361416
try:
@@ -372,6 +427,9 @@ def _process_message(self, body):
372427
resource['local_paths'] = file_paths
373428

374429
self.process_message(self, host, secret_key, resource, body)
430+
clowderurl = "%sdatasets/%s" % (host, body.get('datasetId', ''))
431+
# notificatino of extraction job is done by email.
432+
self.email(emailaddrlist, clowderurl)
375433
finally:
376434
for tmp_f in tmp_files:
377435
try:

0 commit comments

Comments
 (0)