diff --git a/eos/core/tasks/__init__.py b/eos/core/tasks/__init__.py index 96cb0ea..3e7d3a3 100644 --- a/eos/core/tasks/__init__.py +++ b/eos/core/tasks/__init__.py @@ -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 diff --git a/eos/core/tasks/direct.py b/eos/core/tasks/direct.py index d0e883a..086f0ae 100644 --- a/eos/core/tasks/direct.py +++ b/eos/core/tasks/direct.py @@ -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() diff --git a/eosweb/core/main.py b/eosweb/core/main.py index 5da1b46..dea2ce4 100644 --- a/eosweb/core/main.py +++ b/eosweb/core/main.py @@ -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='
Dear voter,
You are registered to vote in the election Election Name.
', css=css) - # === Apps === for app_name in app.config['APPS']: diff --git a/eosweb/core/tasks.py b/eosweb/core/tasks.py new file mode 100644 index 0000000..8cac44b --- /dev/null +++ b/eosweb/core/tasks.py @@ -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, seeThe task {} failed execution. The output was:
{}'.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 diff --git a/eosweb/core/templates/email/base.html b/eosweb/core/templates/email/base.html index a8dcf4b..fc944fb 100644 --- a/eosweb/core/templates/email/base.html +++ b/eosweb/core/templates/email/base.html @@ -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 @@