Get started on a basic web UI
This commit is contained in:
parent
5fd8716b38
commit
6ebf83ed96
@ -308,5 +308,13 @@ class TopLevelObject(DocumentObject):
|
|||||||
#res = db[self._name].replace_one({'_id': self.serialise()['_id']}, self.serialise(), upsert=True)
|
#res = db[self._name].replace_one({'_id': self.serialise()['_id']}, self.serialise(), upsert=True)
|
||||||
res = db[self._db_name].replace_one({'_id': self._fields['_id'].serialise(self._id)}, EosObject.serialise_and_wrap(self), upsert=True)
|
res = db[self._db_name].replace_one({'_id': self._fields['_id'].serialise(self._id)}, EosObject.serialise_and_wrap(self), upsert=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_all(cls):
|
||||||
|
return [EosObject.deserialise_and_unwrap(x) for x in db[cls._db_name].find()]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_by_id(cls, _id):
|
||||||
|
return EosObject.deserialise_and_unwrap(db[cls._db_name].find_one(_id))
|
||||||
|
|
||||||
class EmbeddedObject(DocumentObject):
|
class EmbeddedObject(DocumentObject):
|
||||||
pass
|
pass
|
||||||
|
@ -14,5 +14,5 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# 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/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
# Allow FLASK_APP=eosweb instead of eosweb.eosweb
|
# Allow FLASK_APP=eosweb instead of eosweb.core.main
|
||||||
from .eosweb import app
|
from .core.main import app
|
||||||
|
@ -13,19 +13,3 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# 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/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import click
|
|
||||||
import flask
|
|
||||||
|
|
||||||
app = flask.Flask(__name__)
|
|
||||||
|
|
||||||
@app.cli.command('test')
|
|
||||||
@click.option('--prefix', default=None)
|
|
||||||
@click.option('--lang', default=None)
|
|
||||||
def run_tests(prefix, lang):
|
|
||||||
import eos.tests
|
|
||||||
eos.tests.run_tests(prefix, lang)
|
|
||||||
|
|
||||||
@app.route('/')
|
|
||||||
def index():
|
|
||||||
return flask.render_template('index.html')
|
|
92
eosweb/core/main.py
Normal file
92
eosweb/core/main.py
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
# Eos - Verifiable elections
|
||||||
|
# Copyright © 2017 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 click
|
||||||
|
import flask
|
||||||
|
|
||||||
|
from eos.base.election import *
|
||||||
|
from eos.psr.crypto import *
|
||||||
|
from eos.psr.election import *
|
||||||
|
from eos.psr.mixnet import *
|
||||||
|
from eos.psr.workflow import *
|
||||||
|
|
||||||
|
import eos.core.hashing
|
||||||
|
|
||||||
|
app = flask.Flask(__name__)
|
||||||
|
|
||||||
|
@app.cli.command('test')
|
||||||
|
@click.option('--prefix', default=None)
|
||||||
|
@click.option('--lang', default=None)
|
||||||
|
def run_tests(prefix, lang):
|
||||||
|
import eos.tests
|
||||||
|
eos.tests.run_tests(prefix, lang)
|
||||||
|
|
||||||
|
# TODO: Will remove this once we have a web UI
|
||||||
|
@app.cli.command('drop_db_and_setup')
|
||||||
|
def setup_test_election():
|
||||||
|
# DANGER!
|
||||||
|
client.drop_database('test')
|
||||||
|
|
||||||
|
# Set up election
|
||||||
|
election = PSRElection()
|
||||||
|
election.workflow = PSRWorkflow()
|
||||||
|
|
||||||
|
# Set election details
|
||||||
|
election.name = 'Test Election'
|
||||||
|
|
||||||
|
for i in range(3):
|
||||||
|
voter = Voter()
|
||||||
|
election.voters.append(voter)
|
||||||
|
|
||||||
|
election.mixing_trustees.append(MixingTrustee())
|
||||||
|
|
||||||
|
election.sk = EGPrivateKey.generate()
|
||||||
|
election.public_key = election.sk.public_key
|
||||||
|
|
||||||
|
question = ApprovalQuestion(prompt='President', choices=['John Smith', 'Joe Bloggs', 'John Q. Public'])
|
||||||
|
election.questions.append(question)
|
||||||
|
|
||||||
|
question = ApprovalQuestion(prompt='Chairman', choices=['John Doe', 'Andrew Citizen'])
|
||||||
|
election.questions.append(question)
|
||||||
|
|
||||||
|
election.save()
|
||||||
|
|
||||||
|
# Freeze election
|
||||||
|
election.workflow.get_task('eos.base.workflow.TaskConfigureElection').enter()
|
||||||
|
|
||||||
|
# Open voting
|
||||||
|
election.workflow.get_task('eos.base.workflow.TaskOpenVoting').enter()
|
||||||
|
|
||||||
|
election.save()
|
||||||
|
|
||||||
|
@app.context_processor
|
||||||
|
def inject_globals():
|
||||||
|
return {'eos': eos, 'SHA256': eos.core.hashing.SHA256}
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def index():
|
||||||
|
return flask.render_template('index.html')
|
||||||
|
|
||||||
|
def using_election(func):
|
||||||
|
def wrapped(election_id):
|
||||||
|
election = Election.get_by_id(election_id)
|
||||||
|
return func(election)
|
||||||
|
return wrapped
|
||||||
|
|
||||||
|
@app.route('/election/<election_id>/view')
|
||||||
|
@using_election
|
||||||
|
def election_view(election):
|
||||||
|
return flask.render_template('election/view.html', election=election)
|
22
eosweb/core/static/css/main.css
Normal file
22
eosweb/core/static/css/main.css
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
Eos - Verifiable elections
|
||||||
|
Copyright © 2017 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.hash {
|
||||||
|
font-family: monospace;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
56
eosweb/core/templates/election/base.html
Normal file
56
eosweb/core/templates/election/base.html
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{#
|
||||||
|
Eos - Verifiable elections
|
||||||
|
Copyright © 2017 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/>.
|
||||||
|
#}
|
||||||
|
|
||||||
|
{% block title %}{{ election.name }}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>{{ election.name }}</h1>
|
||||||
|
|
||||||
|
<p><small><b>Election fingerprint:</b> <span class="hash">{{ SHA256().update_obj(election).hash_as_b64() }}</span></small></p>
|
||||||
|
|
||||||
|
<div class="ui secondary pointing menu" id="election-tab-menu">
|
||||||
|
<a href="#" class="election-tab-ajax item active">Overview</a>
|
||||||
|
</div>
|
||||||
|
<div class="ui container" id="election-tab-content">
|
||||||
|
{% block electioncontent %}
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block basecontent %}
|
||||||
|
{{ super() }}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(".election-tab-ajax").click(function() {
|
||||||
|
var linkEl = $(this);
|
||||||
|
history.pushState({}, "", linkEl.attr("href"));
|
||||||
|
|
||||||
|
$("#election-tab-menu .item").removeClass("active");
|
||||||
|
linkEl.addClass("active");
|
||||||
|
|
||||||
|
$("#election-tab-content").html('<div class="ui active text loader">Loading. Please wait.</div>');
|
||||||
|
|
||||||
|
$("#election-tab-content").load(linkEl.attr("href") + " #election-tab-content", function() {
|
||||||
|
linkEl.find(".loader").removeClass("active");
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
51
eosweb/core/templates/election/view.html
Normal file
51
eosweb/core/templates/election/view.html
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
{% extends 'election/base.html' %}
|
||||||
|
|
||||||
|
{#
|
||||||
|
Eos - Verifiable elections
|
||||||
|
Copyright © 2017 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/>.
|
||||||
|
#}
|
||||||
|
|
||||||
|
{% set Status = eos.base.workflow.WorkflowTask.Status %}
|
||||||
|
|
||||||
|
{% block electioncontent %}
|
||||||
|
{% if election.workflow.get_task('eos.base.workflow.TaskConfigureElection').status == Status.EXITED %}
|
||||||
|
{% if election.workflow.get_task('eos.base.workflow.TaskOpenVoting').status == Status.EXITED %}
|
||||||
|
<p><a href="#" class="ui huge primary button">Click here to vote in this election</a></p>
|
||||||
|
{% else %}
|
||||||
|
<p><button class="ui huge button">Voting in this election has not yet opened</button></p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Voting in this election
|
||||||
|
{% if election.workflow.get_task('eos.base.workflow.TaskOpenVoting').status == Status.EXITED %}
|
||||||
|
opened
|
||||||
|
{% else %}
|
||||||
|
is scheduled to open
|
||||||
|
{% endif %}
|
||||||
|
at the administrators' discretion, and
|
||||||
|
{% if election.workflow.get_task('eos.base.workflow.TaskCloseVoting').status == Status.EXITED %}
|
||||||
|
closed
|
||||||
|
{% else %}
|
||||||
|
is scheduled to close
|
||||||
|
{% endif %}
|
||||||
|
at the administrators' discretion.
|
||||||
|
</p>
|
||||||
|
{% else %}
|
||||||
|
<p><button class="ui huge button">This election is not yet ready for voting</button></p>
|
||||||
|
|
||||||
|
<p>The administrator of this election has not yet finished setting the election parameters. The details of the election may change at any time.</p>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
@ -21,5 +21,10 @@
|
|||||||
{% block title %}Home{% endblock %}
|
{% block title %}Home{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
Hello World!
|
<p>Please choose an election from the list below:</p>
|
||||||
|
<ul>
|
||||||
|
{% for election in eos.base.election.Election.get_all() %}
|
||||||
|
<li><a href="{{ url_for('election_view', election_id=election._id) }}">{{ election.name }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
{% endblock %}
|
{% endblock %}
|
Loading…
Reference in New Issue
Block a user