diff --git a/crc/api/tools.py b/crc/api/tools.py
index e889f73b..64ad8a0b 100644
--- a/crc/api/tools.py
+++ b/crc/api/tools.py
@@ -96,11 +96,12 @@ def evaluate_python_expression(body):
except Exception as e:
return {"result": False, "expression": body['expression'], "key": body['key'], "error": str(e)}
+
def send_test_email(subject, address, message, data=None):
- rendered, wrapped = EmailService().get_rendered_content(message, data)
+ content, content_html = EmailService().get_rendered_content(message, data)
EmailService.add_email(
subject=subject,
sender=DEFAULT_SENDER,
recipients=[address],
- content=rendered,
- content_html=wrapped)
+ content=content,
+ content_html=content_html)
diff --git a/crc/models/email.py b/crc/models/email.py
index a549cfdb..cf2bb543 100644
--- a/crc/models/email.py
+++ b/crc/models/email.py
@@ -23,9 +23,8 @@ class EmailModel(db.Model):
class EmailModelSchema(ma.Schema):
- # TODO: clean this us. Do we need load_instance and unknown?
+
class Meta:
model = EmailModel
- load_instance = True
- additional = ["id", "subject", "sender", "recipients", "timestamp"]
- unknown = INCLUDE
+ fields = ["id", "subject", "sender", "recipients", "cc", "bcc", "content", "content_html",
+ "study_id", "timestamp", "workflow_spec_id"]
diff --git a/crc/scripts/email.py b/crc/scripts/email.py
index 307cbda3..2e5a7105 100644
--- a/crc/scripts/email.py
+++ b/crc/scripts/email.py
@@ -3,6 +3,7 @@ import traceback
from crc import app, session
from crc.api.common import ApiError
+from crc.models.email import EmailModelSchema
from crc.models.file import FileModel, CONTENT_TYPES
from crc.models.workflow import WorkflowModel
from crc.services.document_service import DocumentService
@@ -93,7 +94,7 @@ email(subject="My Subject", recipients="user@example.com", attachments=['Study_A
print(repr(traceback.format_exception(exc_type, exc_value,
exc_traceback)))
raise e
- return email_model.id
+ return EmailModelSchema().dump(email_model)
def get_email_addresses(self, users, study_id):
emails = []
diff --git a/crc/scripts/get_localtime.py b/crc/scripts/get_localtime.py
new file mode 100644
index 00000000..83fab223
--- /dev/null
+++ b/crc/scripts/get_localtime.py
@@ -0,0 +1,34 @@
+from crc.api.common import ApiError
+from crc.scripts.script import Script
+
+import dateparser
+import pytz
+
+
+class GetLocaltime(Script):
+
+ def get_description(self):
+ return """Converts a UTC Datetime object into a Datetime object with a different timezone.
+ Defaults to US/Eastern"""
+
+ def do_task_validate_only(self, task, study_id, workflow_id, *args, **kwargs):
+ if 'timestamp' in kwargs:
+ return True
+ raise ApiError(code='missing_timestamp',
+ message='You must include a timestamp to convert.')
+
+ def do_task(self, task, study_id, workflow_id, *args, **kwargs):
+ if 'timestamp' in kwargs:
+ timestamp = kwargs['timestamp']
+ if 'timezone' in kwargs:
+ timezone = kwargs['timezone']
+ else:
+ timezone = 'US/Eastern'
+ parsed_timestamp = dateparser.parse(timestamp)
+ localtime = parsed_timestamp.astimezone(pytz.timezone(timezone))
+ return str(localtime)
+
+ else:
+ raise ApiError(code='missing_timestamp',
+ message='You must include a timestamp to convert.')
+
diff --git a/crc/services/email_service.py b/crc/services/email_service.py
index 86810faa..20006827 100644
--- a/crc/services/email_service.py
+++ b/crc/services/email_service.py
@@ -47,9 +47,11 @@ class EmailService(object):
msg.attach(file['name'], file['type'], file_data.data)
mail.send(msg)
+
except Exception as e:
app.logger.error('An exception happened in EmailService', exc_info=True)
app.logger.error(str(e))
+ raise e
db.session.add(email_model)
db.session.commit()
diff --git a/migrations/versions/ba6df7e560a1_modify_email_timestamp.py b/migrations/versions/ba6df7e560a1_modify_email_timestamp.py
new file mode 100644
index 00000000..58f870de
--- /dev/null
+++ b/migrations/versions/ba6df7e560a1_modify_email_timestamp.py
@@ -0,0 +1,24 @@
+"""modify email timestamp
+
+Revision ID: ba6df7e560a1
+Revises: 6d8ceb1c18cb
+Create Date: 2021-10-13 10:54:23.894034
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+
+# revision identifiers, used by Alembic.
+revision = 'ba6df7e560a1'
+down_revision = '6d8ceb1c18cb'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+ op.execute("alter table email alter column timestamp type timestamp with time zone")
+
+
+def downgrade():
+ op.execute("alter table email alter column timestamp type timestamp without time zone")
diff --git a/tests/data/email/email.bpmn b/tests/data/email/email.bpmn
index 40489409..389ba06d 100644
--- a/tests/data/email/email.bpmn
+++ b/tests/data/email/email.bpmn
@@ -19,15 +19,12 @@ Email content to be delivered to {{ ApprvlApprvr1 }}
---
**Test Some Formatting**
- _UVA Tracking Number:_ {{ 321 }}
-
-
+ _UVA Tracking Number:_ {{ 321 }}
Hypertext Markup Language content for this email
' + + # Make sure we generate an error + with self.assertRaises(Exception) as e: + EmailService.add_email(subject=subject, sender=sender, recipients=recipients, + content=content, content_html=content_html, study_id=study.id) + # Make sure it's the error we want + self.assertEqual('This is my exception!', e.exception.args[0]) diff --git a/tests/scripts/test_get_localtime.py b/tests/scripts/test_get_localtime.py new file mode 100644 index 00000000..7e5b489b --- /dev/null +++ b/tests/scripts/test_get_localtime.py @@ -0,0 +1,17 @@ +from tests.base_test import BaseTest +from crc.scripts.get_localtime import GetLocaltime + + +class TestGetLocaltime(BaseTest): + + def test_get_localtime(self): + self.load_example_data() + + workflow = self.create_workflow('get_localtime') + workflow_api = self.get_workflow_api(workflow) + task = workflow_api.next_task + + timestamp = task.data['timestamp'] + localtime = task.data['localtime'] + + self.assertEqual(localtime, GetLocaltime().do_task(None, None, None, timestamp=timestamp))