Email admins about task failures

This commit is contained in:
Yingtong Li 2018-01-04 11:36:07 +08:00
parent e061ba7c3c
commit 3a44890803
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
9 changed files with 113 additions and 17 deletions

View File

@ -1,5 +1,5 @@
# Eos - Verifiable elections
# Copyright © 2017 RunasSudo (Yingtong Li)
# Copyright © 2017-18 RunasSudo (Yingtong Li)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@ -27,6 +27,8 @@ class Task(TopLevelObject):
FAILED = -10
TIMEOUT = -20
label = 'Unknown task'
_id = UUIDField()
run_strategy = EmbeddedObjectField()
@ -43,6 +45,12 @@ class Task(TopLevelObject):
def _run(self):
pass
def complete(self):
pass
def error(self):
pass
class DummyTask(Task):
_db_name = Task._db_name

View File

@ -1,5 +1,5 @@
# Eos - Verifiable elections
# Copyright © 2017 RunasSudo (Yingtong Li)
# Copyright © 2017-18 RunasSudo (Yingtong Li)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@ -28,6 +28,8 @@ class DirectRunStrategy(RunStrategy):
task.status = Task.Status.COMPLETE
task.completed_at = DateTimeField.now()
task.save()
task.complete()
except Exception as e:
task.status = Task.Status.FAILED
task.completed_at = DateTimeField.now()
@ -39,3 +41,5 @@ class DirectRunStrategy(RunStrategy):
else:
task.messages.append(repr(e))
task.save()
task.error()

View File

@ -1,5 +1,5 @@
# Eos - Verifiable elections
# Copyright © 2017 RunasSudo (Yingtong Li)
# Copyright © 2017-18 RunasSudo (Yingtong Li)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@ -28,6 +28,8 @@ from eos.psr.election import *
from eos.psr.mixnet import *
from eos.psr.workflow import *
from eosweb.core.tasks import *
import eos.core.hashing
import eosweb
@ -259,7 +261,7 @@ def election_admin_enter_task(election):
if workflow_task.status != WorkflowTask.Status.READY:
return flask.Response('Task is not yet ready or has already exited', 409)
task = WorkflowTaskEntryTask(
task = WorkflowTaskEntryWebTask(
election_id=election._id,
workflow_task=workflow_task._name,
status=Task.Status.READY,
@ -275,7 +277,7 @@ def election_admin_enter_task(election):
def election_admin_schedule_task(election):
workflow_task = election.workflow.get_task(flask.request.form['task_name'])
task = WorkflowTaskEntryTask(
task = WorkflowTaskEntryWebTask(
election_id=election._id,
workflow_task=workflow_task._name,
run_at=DateTimeField().deserialise(flask.request.form['datetime']),
@ -387,12 +389,6 @@ def email_authenticate():
return flask.redirect(flask.url_for('login_complete'))
@app.route('/email')
def tmp():
import sass
css = sass.compile(string=flask.render_template('email/base.scss'))
return flask.render_template('email/base.html', title='Hello World', text='<p>Dear voter,</p><p>You are registered to vote in the election Election Name.</p>', css=css)
# === Apps ===
for app_name in app.config['APPS']:

60
eosweb/core/tasks.py Normal file
View File

@ -0,0 +1,60 @@
# Eos - Verifiable elections
# Copyright © 2017-18 RunasSudo (Yingtong Li)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
import premailer
import sass
import flask
import flask_mail
from eos.core.tasks import *
from eos.base.election import *
class WebTask(Task):
def error(self):
import eosweb
# Prepare email
title = 'Task failed: {}'.format(self.label)
css = sass.compile(string=flask.render_template('email/base.scss'))
html = flask.render_template(
'email/base.html',
title=title,
css=css,
text='<p>The task <i>{}</i> failed execution. The output was:</p><pre>{}</pre>'.format(self.label, '\n'.join(self.messages))
)
html = premailer.Premailer(html).transform()
body = flask.render_template(
'email/base.txt',
title=title,
text='The task "{}" failed execution. The output was:\n\n{}'.format(self.label, '\n'.join(self.messages))
)
# Send email
mail = flask_mail.Mail(eosweb.app)
msg = flask_mail.Message(
title,
recipients=[admin.email for admin in eosweb.app.config['ADMINS'] if isinstance(admin, EmailUser)],
body=body,
html=html
)
mail.send(msg)
class WorkflowTaskEntryWebTask(WorkflowTaskEntryTask, WebTask):
pass

View File

@ -1,6 +1,6 @@
{#
Eos - Verifiable elections
Copyright © 2017 RunasSudo (Yingtong Li)
Copyright © 2017-18 RunasSudo (Yingtong Li)
This file adapted from https://github.com/leemunroe/responsive-html-email-template, licensed under the MIT licence.
@ -25,7 +25,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>{{ title }}</title>
<style>
{{ css }}
{{ css|safe }}
</style>
</head>
<body class="">

View File

@ -1,6 +1,6 @@
{#
Eos - Verifiable elections
Copyright © 2017 RunasSudo (Yingtong Li)
Copyright © 2017-18 RunasSudo (Yingtong Li)
This file adapted from https://github.com/leemunroe/responsive-html-email-template, licensed under the MIT licence.

View File

@ -0,0 +1,26 @@
{#
Eos - Verifiable elections
Copyright © 2017-18 RunasSudo (Yingtong Li)
This file adapted from https://github.com/leemunroe/responsive-html-email-template, licensed under the MIT licence.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
#}
{{ text|safe }}
---
Eos Voting for {{ eosweb.app.config['ORG_NAME'] }}
{{ eosweb.app.config['BASE_URI'] }}

View File

@ -32,9 +32,9 @@ DB_NAME = 'eos'
# Email
SMTP_HOST, SMTP_PORT = 'localhost', 25
SMTP_USER, SMTP_PASS = None, None
SMTP_FROM = 'eos@localhost'
MAIL_SERVER, MAIL_PORT = 'localhost', 25
MAIL_USERNAME, MAIL_PASSWORD = None, None
MAIL_DEFAULT_SENDER = 'eos@localhost'
# Reddit

View File

@ -1,8 +1,10 @@
coverage==4.4.1
Flask==0.12.2
Flask-Mail==0.9.1
Flask-OAuthlib==0.9.4
gunicorn==19.7.1
libsass==0.13.4
premailer==3.1.1
psycopg2==2.7.3.2
PyExecJS==1.4.1
pymongo==3.5.1