Skip to content

Commit

Permalink
Merge pull request #971 from DDMAL/jacky/enable-email-notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
jackyyzhang03 authored Jul 7, 2023
2 parents eb9365d + e39afb1 commit c49325f
Show file tree
Hide file tree
Showing 15 changed files with 183 additions and 38 deletions.
2 changes: 2 additions & 0 deletions rodan-main/code/rodan/celery.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
redo_runjob_tree,
retry_workflowrun,
send_email,
send_templated_email,
)
from rodan.jobs.master_task import master_task # noqa

Expand All @@ -33,4 +34,5 @@
app.tasks.register(redo_runjob_tree)
app.tasks.register(retry_workflowrun)
app.tasks.register(send_email)
app.tasks.register(send_templated_email)
app.tasks.register(master_task)
4 changes: 4 additions & 0 deletions rodan-main/code/rodan/email.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from djoser import email

class PasswordChangedConfirmationEmail(email.PasswordChangedConfirmationEmail):
template_name = "emails/password_changed_confirmation.html"
26 changes: 8 additions & 18 deletions rodan-main/code/rodan/jobs/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -808,26 +808,18 @@ def run(self, runjob_id):
wfrun_id = RunJob.objects.filter(pk=runjob_id).values_list(
"workflow_run__uuid", flat=True
)[0]
workflowrun = WorkflowRun.objects.get(uuid=wfrun_id)
workflow_run = WorkflowRun.objects.get(uuid=wfrun_id)
user = WorkflowRun.objects.get(uuid=wfrun_id).creator
if not rodan_settings.TEST:
if (
user.email
and rodan_settings.EMAIL_USE
and user.user_preference.send_email
):
subject = "Workflow Run '{0}' is waiting for user input".format(
workflowrun.name
)
body = (
"A workflow run you started is waiting for user input.\n\n"
)
body = body + "Name: {0}\n".format(workflowrun.name)
body = body + "Description: {0}".format(workflowrun.description)
to = [user.email]
registry.tasks["rodan.core.send_email"].apply_async(
(subject, body, to)
)
email_template = "emails/workflow_run_waiting_for_user_input.html"
context = {"name": workflow_run.name, "description": workflow_run.description}
registry.tasks["rodan.core.send_templated_email"].apply_async((to, email_template, context))

return "WAITING FOR INPUT"
else:
Expand Down Expand Up @@ -1014,20 +1006,18 @@ def on_failure(self, exc, task_id, args, kwargs, einfo):
WorkflowRun.objects.filter(uuid=wfrun_id).update(status=task_status.FAILED)

# Send an email to owner of WorkflowRun
workflowrun = WorkflowRun.objects.get(uuid=wfrun_id)
workflow_run = WorkflowRun.objects.get(uuid=wfrun_id)
user = WorkflowRun.objects.get(uuid=wfrun_id).creator
if not rodan_settings.TEST:
if (
user.email
and rodan_settings.EMAIL_USE
and user.user_preference.sned_email
):
subject = "Workflow Run '{0}' failed".format(workflowrun.name)
body = "A workflow run you started has failed.\n\n"
body = body + "Name: {0}\n".format(workflowrun.name)
body = body + "Description: {0}".format(workflowrun.description)
to = [user.email]
registry.tasks["rodan.core.send_email"].apply_async((subject, body, to))
email_template = "rodan/email/workflow_run_failed.html"
context = { "name": workflow_run.name, "description": workflow_run.description}
registry.tasks["rodan.core.send_templated_email"].apply_async((to, email_template, context))

def _add_error_information_to_runjob(self, exc, einfo):
# Any job using the default_on_failure method can define an error_information
Expand Down
7 changes: 6 additions & 1 deletion rodan-main/code/rodan/jobs/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
from rodan.jobs.base import TemporaryDirectory
from rodan.jobs.diva_generate_json import GenerateJson
from rodan.jobs.resource_identification import fileparse
from templated_mail.mail import BaseEmailMessage

# from rodan.celery import app

Expand Down Expand Up @@ -934,9 +935,13 @@ def inner_redo(rj):

@task(name="rodan.core.send_email")
def send_email(subject, body, to):
email = EmailMessage(subject, body, settings.EMAIL_HOST_USER, to)
email = EmailMessage(subject, body, settings.DEFAULT_FROM_EMAIL, to)
email.send()

@task(name="rodan.core.send_templated_email")
def send_templated_email(to, email_template, context):
BaseEmailMessage(context=context, template_name=email_template).send(to)


@task(name="rodan.core.create_archive")
def create_archive(resource_uuids):
Expand Down
13 changes: 5 additions & 8 deletions rodan-main/code/rodan/jobs/master_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,22 +80,19 @@ def master_task(workflow_run_id):
)

# Send an email to owner of WorkflowRun
workflowrun = WorkflowRun.objects.get(uuid=workflow_run_id)
workflow_run = WorkflowRun.objects.get(uuid=workflow_run_id)
user = WorkflowRun.objects.get(uuid=workflow_run_id).creator
if not settings.TEST:
if (
user.email
and getattr(settings, 'EMAIL_USE', False)
and user.user_preference.send_email
):
subject = "Workflow Run '{0}' FINISHED".format(workflowrun.name)
body = "A workflow run you started has finished.\n\n"
body = body + "Name: {0}\n".format(workflowrun.name)
body = body + "Description: {0}".format(workflowrun.description)
to = [user.email]
registry.tasks["rodan.core.send_email"].apply_async(
(subject, body, to)
)
email_template = "emails/workflow_run_finished.html"
context = {"name": workflow_run.name, "description": workflow_run.description}

registry.tasks["rodan.core.send_templated_email"].apply_async((to, email_template, context))

# return value is ignored, and provided as information in Celery stdout.
return "wfRun {0} FINISHED".format(workflow_run_id)
Expand Down
29 changes: 19 additions & 10 deletions rodan-main/code/rodan/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,19 +239,28 @@
###############################################################################
# A sample email configuration. These parameters are used to send emails to
# the owner of WorkflowRuns, etc.
# To enable emailing, fill out email parameters below and set EMAIL_USE to True.
# See https://docs.djangoproject.com/en/1.10/topics/email/ for
# more details on how to customize your email configuration.
# SMTP credentials should be set as environment variables. If they are not set,
# emails will be printed to the console instead.

# [TODO] - Setup proper email configuration.
EMAIL_USE = True
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend" if os.getenv("EMAIL_HOST") else "django.core.mail.backends.console.EmailBackend"
EMAIL_HOST = os.getenv("EMAIL_HOST")
EMAIL_PORT = os.getenv("EMAIL_PORT")
EMAIL_HOST_USER = os.getenv("EMAIL_HOST_USER")
EMAIL_HOST_PASSWORD = os.getenv("EMAIL_HOST_PASSWORD")
EMAIL_USE_TLS = True

EMAIL_USE = False
# EMAIL_USE_TLS = True
# EMAIL_HOST = 'smtp.gmail.com'
# EMAIL_HOST_USER = os.getenv('EMAIL_HOST_USER')
# EMAIL_HOST_PASSWORD = os.getenv('EMAIL_HOST_PASS')
# EMAIL_PORT = 587
DEFAULT_FROM_EMAIL = "Rodan <[email protected]>"

SITE_NAME = "Rodan"

DJOSER = {
"PASSWORD_CHANGED_EMAIL_CONFIRMATION": True,
"EMAIL": {
"password_changed_confirmation": "rodan.email.PasswordChangedConfirmationEmail",
}

}

###############################################################################
# 2.a Rodan Server Configuration
Expand Down
9 changes: 9 additions & 0 deletions rodan-main/code/rodan/templates/emails/added_to_project.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{% load i18n %}

{% block subject %}
{% blocktrans %}{{ site_name }} - You have been added to project '{{ project_name }}'!{% endblocktrans %}
{% endblock %}

{% block html_body %}
<p>{% blocktrans %}You have been added as '{{ role }}' to project '{{ project_name }}' by '{{ adder }}'!{% endblocktrans %}</p>
{% endblock html_body %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{% load i18n %}

{% block subject %}
{% blocktrans %}{{ site_name }} - Your password has been successfully changed!{% endblocktrans %}
{% endblock %}

{% block html_body %}
<p>{% trans "Your password has been changed!" %}</p>
{% endblock html_body %}
19 changes: 19 additions & 0 deletions rodan-main/code/rodan/templates/emails/workflow_run_failed.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{% load i18n %}

{% block subject %}
{% blocktrans %}{{ site_name }} - Workflow run '{{ name }}'' failed{% endblocktrans %}
{% endblock %}

{% block html_body %}
<p>{% trans "A workflow run you started has failed." %}</p>
<table>
<tr>
<th>{% trans "Name" %}</th>
<td>{{ name }}</td>
</tr>
<tr>
<th>{% trans "Description" %}</th>
<td>{{ description }}</td>
</tr>
</table>
{% endblock html_body %}
19 changes: 19 additions & 0 deletions rodan-main/code/rodan/templates/emails/workflow_run_finished.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{% load i18n %}

{% block subject %}
{% blocktrans %}{{ site_name }} - Workflow run '{{ name }}'' has finished!{% endblocktrans %}
{% endblock %}

{% block html_body %}
<p>{% trans "A workflow run you started has finished!" %}</p>
<table>
<tr>
<th>{% trans "Name" %}</th>
<td>{{ name }}</td>
</tr>
<tr>
<th>{% trans "Description" %}</th>
<td>{{ description }}</td>
</tr>
</table>
{% endblock html_body %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{% load i18n %}

{% block subject %}
{% blocktrans %}{{ site_name }} - Workflow run '{{ name }}'' is waiting for user input.{% endblocktrans %}
{% endblock %}

{% block html_body %}
<p>{% trans "A workflow run you started is waiting for user input." %}</p>
<table>
<tr>
<th>{% trans "Name" %}</th>
<td>{{ name }}</td>
</tr>
<tr>
<th>{% trans "Description" %}</th>
<td>{{ description }}</td>
</tr>
</table>
{% endblock html_body %}
36 changes: 35 additions & 1 deletion rodan-main/code/rodan/views/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
from rodan.models.project import Project, User
from rodan.serializers.project import ProjectListSerializer, ProjectDetailSerializer
from rodan.permissions import CustomObjectPermissions
from django.conf import settings
from django.db.models import Q

from celery import registry


class ProjectList(generics.ListCreateAPIView):
Expand Down Expand Up @@ -91,14 +92,31 @@ def put(self, request, *args, **kwargs):
detail={"detail": "User {0} does not exist.".format(u_info)}
)
users.append(user)

new_users = [user for user in users if user not in p.admin_group.user_set.all()]

p.admin_group.user_set.clear()
p.admin_group.user_set.add(*users)
if p.creator:
p.admin_group.user_set.add(p.creator)

if (getattr(settings, "EMAIL_USE", False)):
self.send_email(new_users)

return Response(p.admin_group.user_set.values_list("username", flat=True))

def patch(self, request, *args, **kwargs):
return self.put(request, *args, **kwargs)

def send_email(self, new_users):
project = self.get_object()
user = self.request.user

to = [user.email for user in new_users if user.email and user.user_preference.send_email]
email_template = "emails/added_to_project.html"
context = {"project_name": project.name, "role": "admin", "adder": user.username}

registry.tasks["rodan.core.send_templated_email"].apply_async((to, email_template, context))


class ProjectDetailWorkers(generics.GenericAPIView):
Expand Down Expand Up @@ -140,9 +158,25 @@ def put(self, request, *args, **kwargs):
detail={"detail": "User {0} does not exist.".format(u_info)}
)
users.append(user)

new_users = [user for user in users if user not in p.admin_group.user_set.all()]

p.worker_group.user_set.clear()
p.worker_group.user_set.add(*users)

self.send_email(new_users)

return Response(p.worker_group.user_set.values_list("username", flat=True))

def patch(self, request, *args, **kwargs):
return self.put(request, *args, **kwargs)

def send_email(self, new_users):
project = self.get_object()
user = self.request.user

to = [user.email for user in new_users if user.email and user.user_preference.send_email]
email_template = "emails/added_to_project.html"
context = {"project_name": project.name, "role": "worker", "adder": user.username}

registry.tasks["rodan.core.send_templated_email"].apply_async((to, email_template, context))
9 changes: 9 additions & 0 deletions scripts/local.env
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ DJANGO_ACCESS_LOG=/code/Rodan/rodan.log
DJANGO_DEBUG_LOG=/code/Rodan/database.log
SERVER_HOST=

###############################################################################
# SMTP Configuration
###############################################################################

EMAIL_HOST=
EMAIL_PORT=
EMAIL_HOST_USER=
EMAIL_HOST_PASSWORD=

###############################################################################
# Celery Configuration
###############################################################################
Expand Down
10 changes: 10 additions & 0 deletions scripts/production.sample
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ DJANGO_ADMIN_URL=^api/random_secret_admin/
IIPSRV_URL=https://rodan2.simssa.ca/fcgi-bin/iipsrv.fcgi/
DJANGO_ACCESS_LOG=/code/Rodan/rodan.log
DJANGO_DEBUG_LOG=/code/Rodan/database.log
SERVER_HOST=

###############################################################################
# SMTP Configuration
###############################################################################

EMAIL_HOST=
EMAIL_PORT=
EMAIL_HOST_USER=
EMAIL_HOST_PASSWORD=

###############################################################################
# Celery Configuration
Expand Down
10 changes: 10 additions & 0 deletions scripts/staging.sample
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ DJANGO_ADMIN_URL=^api/random_secret_admin/
IIPSRV_URL=http://rodan-staging.simssa.ca/fcgi-bin/iipsrv.fcgi/
DJANGO_ACCESS_LOG=/code/Rodan/rodan.log
DJANGO_DEBUG_LOG=/code/Rodan/database.log
SERVER_HOST=

###############################################################################
# SMTP Configuration
###############################################################################

EMAIL_HOST=
EMAIL_PORT=
EMAIL_HOST_USER=
EMAIL_HOST_PASSWORD=

###############################################################################
# Celery Configuration
Expand Down

0 comments on commit c49325f

Please sign in to comment.