Modified email script and email_service to accommodate new bcc, reply_to, and attachments arguments
Modified the email script description to add the new arguments Cleaned up some import statements
This commit is contained in:
parent
ef9fd9514d
commit
32c72c5a40
|
@ -1,29 +1,42 @@
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from crc import app
|
from crc import app, session
|
||||||
from crc.api.common import ApiError
|
from crc.api.common import ApiError
|
||||||
|
from crc.models.file import FileModel, CONTENT_TYPES
|
||||||
|
from crc.models.workflow import WorkflowModel
|
||||||
|
from crc.services.document_service import DocumentService
|
||||||
from crc.scripts.script import Script
|
from crc.scripts.script import Script
|
||||||
from crc.services.ldap_service import LdapService
|
|
||||||
from crc.services.email_service import EmailService
|
from crc.services.email_service import EmailService
|
||||||
|
from crc.services.ldap_service import LdapService
|
||||||
from crc.services.study_service import StudyService
|
from crc.services.study_service import StudyService
|
||||||
|
|
||||||
|
|
||||||
class Email(Script):
|
class Email(Script):
|
||||||
"""This Script allows to be introduced as part of a workflow and called from there, specifying
|
"""Send an email from a script task, as part of a workflow.
|
||||||
recipients and content """
|
You must specify recipients and content.
|
||||||
|
You can also specify cc, bcc, reply_to, and attachments"""
|
||||||
|
|
||||||
def get_description(self):
|
def get_description(self):
|
||||||
return """
|
return """
|
||||||
Creates an email, using the provided `subject`, `recipients`, and `cc` arguments.
|
Creates an email, using the provided `subject` and `recipients` arguments, which are required.
|
||||||
The recipients and cc arguments can contain an email address or list of email addresses.
|
The `Element Documentation` field in the script task must contain markdown that becomes the body of the email message.
|
||||||
|
|
||||||
|
You can also provide `cc`, `bcc`, `reply_to` and `attachments` arguments.
|
||||||
|
The cc, bcc, reply_to, and attachments arguments are not required.
|
||||||
|
|
||||||
|
The recipients, cc, and bcc arguments can contain an email address or list of email addresses.
|
||||||
In place of an email address, we accept the string 'associated', in which case we
|
In place of an email address, we accept the string 'associated', in which case we
|
||||||
look up the users associated with the study who have send_email set to True.
|
look up the users associated with the study who have send_email set to True.
|
||||||
The cc argument is not required.
|
The reply_to argument can contain an email address.
|
||||||
The "documentation" should contain markdown that will become the body of the email message.
|
The attachments arguments can contain a doc_code or list of doc_codes.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
email (subject="My Subject", recipients=["dhf8r@virginia.edu", pi.email, 'associated'])
|
email(subject="My Subject", recipients=["dhf8r@virginia.edu", pi.email, 'associated'])
|
||||||
email (subject="My Subject", recipients=["dhf8r@virginia.edu", pi.email], cc='associated')
|
email(subject="My Subject", recipients="user@example.com", cc='associated', bcc='test_user@example.com)
|
||||||
|
email(subject="My Subject", recipients="user@example.com", reply_to="reply_to@example.com")
|
||||||
|
email(subject="My Subject", recipients="user@example.com", attachments='Study_App_Doc')
|
||||||
|
email(subject="My Subject", recipients="user@example.com", attachments=['Study_App_Doc','Study_Protocol_Document'])
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def do_task_validate_only(self, task, study_id, workflow_id, *args, **kwargs):
|
def do_task_validate_only(self, task, study_id, workflow_id, *args, **kwargs):
|
||||||
|
@ -37,8 +50,17 @@ email (subject="My Subject", recipients=["dhf8r@virginia.edu", pi.email], cc='as
|
||||||
subject = self.get_subject(kwargs['subject'])
|
subject = self.get_subject(kwargs['subject'])
|
||||||
recipients = self.get_email_addresses(kwargs['recipients'], study_id)
|
recipients = self.get_email_addresses(kwargs['recipients'], study_id)
|
||||||
cc = []
|
cc = []
|
||||||
|
bcc = []
|
||||||
|
reply_to = None
|
||||||
|
files = None
|
||||||
if 'cc' in kwargs and kwargs['cc'] is not None:
|
if 'cc' in kwargs and kwargs['cc'] is not None:
|
||||||
cc = self.get_email_addresses(kwargs['cc'], study_id)
|
cc = self.get_email_addresses(kwargs['cc'], study_id)
|
||||||
|
if 'bcc' in kwargs and kwargs['bcc'] is not None:
|
||||||
|
bcc = self.get_email_addresses(kwargs['bcc'], study_id)
|
||||||
|
if 'reply_to' in kwargs:
|
||||||
|
reply_to = kwargs['reply_to']
|
||||||
|
if 'attachments' in kwargs:
|
||||||
|
files = self.get_files(kwargs['attachments'], study_id)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise ApiError(code="missing_argument",
|
raise ApiError(code="missing_argument",
|
||||||
|
@ -56,7 +78,10 @@ email (subject="My Subject", recipients=["dhf8r@virginia.edu", pi.email], cc='as
|
||||||
content=content,
|
content=content,
|
||||||
content_html=content_html,
|
content_html=content_html,
|
||||||
cc=cc,
|
cc=cc,
|
||||||
study_id=study_id
|
bcc=bcc,
|
||||||
|
study_id=study_id,
|
||||||
|
reply_to=reply_to,
|
||||||
|
attachment_files=files
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
exc_type, exc_value, exc_traceback = sys.exc_info()
|
exc_type, exc_value, exc_traceback = sys.exc_info()
|
||||||
|
@ -118,3 +143,31 @@ email (subject="My Subject", recipients=["dhf8r@virginia.edu", pi.email], cc='as
|
||||||
user_info = LdapService.user_info(associate.uid)
|
user_info = LdapService.user_info(associate.uid)
|
||||||
associated_emails.append(user_info.email_address)
|
associated_emails.append(user_info.email_address)
|
||||||
return associated_emails
|
return associated_emails
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_files(attachments, study_id):
|
||||||
|
files = []
|
||||||
|
codes = None
|
||||||
|
if isinstance(attachments, str):
|
||||||
|
codes = [attachments]
|
||||||
|
elif isinstance(attachments, list):
|
||||||
|
codes = attachments
|
||||||
|
|
||||||
|
if codes is not None:
|
||||||
|
for code in codes:
|
||||||
|
if DocumentService.is_allowed_document(code):
|
||||||
|
workflows = session.query(WorkflowModel).filter(WorkflowModel.study_id==study_id).all()
|
||||||
|
for workflow in workflows:
|
||||||
|
workflow_files = session.query(FileModel).\
|
||||||
|
filter(FileModel.workflow_id == workflow.id).\
|
||||||
|
filter(FileModel.irb_doc_code == code).all()
|
||||||
|
for file in workflow_files:
|
||||||
|
files.append({'id': file.id, 'name': file.name, 'type': CONTENT_TYPES[file.type.value]})
|
||||||
|
else:
|
||||||
|
raise ApiError(code='bad_doc_code',
|
||||||
|
message=f'The doc_code {code} is not valid.')
|
||||||
|
else:
|
||||||
|
raise ApiError(code='bad_argument_type',
|
||||||
|
message='The attachments argument must be a string or list of strings')
|
||||||
|
|
||||||
|
return files
|
||||||
|
|
|
@ -1,25 +1,23 @@
|
||||||
import markdown
|
import markdown
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from datetime import datetime
|
from flask import render_template
|
||||||
from flask import render_template, request
|
|
||||||
from flask_mail import Message
|
from flask_mail import Message
|
||||||
from jinja2 import Template
|
from jinja2 import Template
|
||||||
from sqlalchemy import desc
|
|
||||||
|
|
||||||
from crc import app, db, mail, session
|
from crc import app, db, mail, session
|
||||||
from crc.api.common import ApiError
|
|
||||||
|
|
||||||
from crc.models.study import StudyModel
|
|
||||||
from crc.models.email import EmailModel
|
from crc.models.email import EmailModel
|
||||||
|
from crc.models.file import FileDataModel
|
||||||
|
from crc.models.study import StudyModel
|
||||||
|
|
||||||
|
|
||||||
class EmailService(object):
|
class EmailService(object):
|
||||||
"""Provides common tools for working with an Email"""
|
"""Provides common tools for working with an Email"""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def add_email(subject, sender, recipients, content, content_html, cc=None, study_id=None):
|
def add_email(subject, sender, recipients, content, content_html,
|
||||||
|
cc=None, bcc=None, study_id=None, reply_to=None, attachment_files=None):
|
||||||
"""We will receive all data related to an email and store it"""
|
"""We will receive all data related to an email and store it"""
|
||||||
|
|
||||||
# Find corresponding study - if any
|
# Find corresponding study - if any
|
||||||
|
@ -35,11 +33,17 @@ class EmailService(object):
|
||||||
try:
|
try:
|
||||||
msg = Message(subject,
|
msg = Message(subject,
|
||||||
sender=sender,
|
sender=sender,
|
||||||
recipients=recipients)
|
recipients=recipients,
|
||||||
|
body=content,
|
||||||
|
html=content_html,
|
||||||
|
cc=cc,
|
||||||
|
bcc=bcc,
|
||||||
|
reply_to=reply_to)
|
||||||
|
|
||||||
msg.body = content
|
if attachment_files is not None:
|
||||||
msg.html = content_html
|
for file in attachment_files:
|
||||||
msg.cc = cc
|
file_data = session.query(FileDataModel).filter(FileDataModel.file_model_id==file['id']).first()
|
||||||
|
msg.attach(file['name'], file['type'], file_data.data)
|
||||||
|
|
||||||
mail.send(msg)
|
mail.send(msg)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
Loading…
Reference in New Issue