From 6ba9b1369a0c362b32a2b2c5d7cbe8eb16a62704 Mon Sep 17 00:00:00 2001 From: RunasSudo Date: Tue, 12 Dec 2017 20:49:02 +1030 Subject: [PATCH] Add task scheduling to election/admin UI --- eos/base/workflow.py | 9 +++++ eos/core/tasks/__init__.py | 5 +-- eosweb/core/main.py | 24 ++++++++++++- .../core/templates/election/admin/admin.html | 18 ++++++++++ eosweb/core/templates/election/view/view.html | 35 +++++++++++++++---- 5 files changed, 82 insertions(+), 9 deletions(-) diff --git a/eos/base/workflow.py b/eos/base/workflow.py index d0b5ada..d934bbf 100644 --- a/eos/base/workflow.py +++ b/eos/base/workflow.py @@ -92,6 +92,15 @@ class WorkflowTask(EmbeddedObject): self.status = WorkflowTask.Status.EXITED self.fire_event('exit') self.on_exit() + + def get_entry_task(self): + election = self.recurse_parents('eos.base.election.Election') + + for task in WorkflowTaskEntryTask.get_all(): + if task.election_id == election._id and task.workflow_task == self._name: + return task + + return None class Workflow(EmbeddedObject): tasks = EmbeddedObjectListField() diff --git a/eos/core/tasks/__init__.py b/eos/core/tasks/__init__.py index eadf612..91e9623 100644 --- a/eos/core/tasks/__init__.py +++ b/eos/core/tasks/__init__.py @@ -66,7 +66,7 @@ class TaskScheduler: tasks = Task.get_all() for task in tasks: - if task.status == Task.Status.READY and task.run_at and task.run_at < DateTimeField.now(): + if task.status == Task.Status.READY: pending_tasks.append(task) return pending_tasks @@ -100,4 +100,5 @@ class TaskScheduler: @staticmethod def tick(): for task in TaskScheduler.pending_tasks(): - task.run() + if task.run_at and task.run_at < DateTimeField.now(): + task.run() diff --git a/eosweb/core/main.py b/eosweb/core/main.py index 380f608..b0aa3fe 100644 --- a/eosweb/core/main.py +++ b/eosweb/core/main.py @@ -229,11 +229,33 @@ 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(election_id=election._id, workflow_task=workflow_task._name, status=Task.Status.READY, run_strategy=EosObject.lookup(app.config['TASK_RUN_STRATEGY'])()) + task = WorkflowTaskEntryTask( + election_id=election._id, + workflow_task=workflow_task._name, + status=Task.Status.READY, + run_strategy=EosObject.lookup(app.config['TASK_RUN_STRATEGY'])() + ) task.run() return flask.redirect(flask.url_for('election_admin_summary', election_id=election._id)) +@app.route('/election//admin/schedule_task', methods=['POST']) +@using_election +@election_admin +def election_admin_schedule_task(election): + workflow_task = election.workflow.get_task(flask.request.form['task_name']) + + task = WorkflowTaskEntryTask( + election_id=election._id, + workflow_task=workflow_task._name, + run_at=DateTimeField().deserialise(flask.request.form['datetime']), + status=Task.Status.READY, + run_strategy=EosObject.lookup(app.config['TASK_RUN_STRATEGY'])() + ) + task.save() + + return flask.redirect(flask.url_for('election_admin_summary', election_id=election._id)) + @app.route('/election//cast_ballot', methods=['POST']) @using_election def election_api_cast_vote(election): diff --git a/eosweb/core/templates/election/admin/admin.html b/eosweb/core/templates/election/admin/admin.html index 1c656a1..3644651 100644 --- a/eosweb/core/templates/election/admin/admin.html +++ b/eosweb/core/templates/election/admin/admin.html @@ -28,4 +28,22 @@ {% endif %} {% endfor %} + +

Schedule a task

+ +
+
+ + +
+
+ + +
+ +
{% endblock %} diff --git a/eosweb/core/templates/election/view/view.html b/eosweb/core/templates/election/view/view.html index 1d16fac..59e9008 100644 --- a/eosweb/core/templates/election/view/view.html +++ b/eosweb/core/templates/election/view/view.html @@ -37,17 +37,40 @@

Voting in this {{ election.kind }} {% if election.workflow.get_task('eos.base.workflow.TaskOpenVoting').status == Status.EXITED %} - opened at {{ election.workflow.get_task('eos.base.workflow.TaskOpenVoting').exited_at.strftime('%Y-%m-%d %H:%M:%S') }} UTC + opened at + {% if election.workflow.get_task('eos.base.workflow.TaskOpenVoting').get_entry_task().run_at %} + {{ election.workflow.get_task('eos.base.workflow.TaskOpenVoting').get_entry_task().run_at.strftime('%Y-%m-%d %H:%M:%S') }} UTC + according to schedule, + {% else %} + {{ election.workflow.get_task('eos.base.workflow.TaskOpenVoting').exited_at.strftime('%Y-%m-%d %H:%M:%S') }} UTC + at the administrator's discretion, + {% endif %} {% else %} - is scheduled to open + is scheduled to open at + {% if election.workflow.get_task('eos.base.workflow.TaskOpenVoting').get_entry_task().run_at %} + {{ election.workflow.get_task('eos.base.workflow.TaskOpenVoting').get_entry_task().run_at.strftime('%Y-%m-%d %H:%M:%S') }} UTC, + {% else %} + the administrator's discretion, + {% endif %} {% endif %} - at the administrators' discretion, and + and {% if election.workflow.get_task('eos.base.workflow.TaskCloseVoting').status == Status.EXITED %} - closed at {{ election.workflow.get_task('eos.base.workflow.TaskCloseVoting').exited_at.strftime('%Y-%m-%d %H:%M:%S') }} UTC + closed at + {% if election.workflow.get_task('eos.base.workflow.TaskCloseVoting').get_entry_task().run_at %} + {{ election.workflow.get_task('eos.base.workflow.TaskCloseVoting').get_entry_task().run_at.strftime('%Y-%m-%d %H:%M:%S') }} UTC + according to schedule + {% else %} + {{ election.workflow.get_task('eos.base.workflow.TaskCloseVoting').exited_at.strftime('%Y-%m-%d %H:%M:%S') }} UTC + at the administrator's discretion + {% endif %} {% else %} - is scheduled to close + is scheduled to close at + {% if election.workflow.get_task('eos.base.workflow.TaskCloseVoting').get_entry_task().run_at %} + {{ election.workflow.get_task('eos.base.workflow.TaskCloseVoting').get_entry_task().run_at.strftime('%Y-%m-%d %H:%M:%S') }} UTC. + {% else %} + the administrator's discretion. + {% endif %} {% endif %} - at the administrators' discretion.

{% else %}