From 473448ab5b09e9d71c73a50ac43c7a9cffd9b726 Mon Sep 17 00:00:00 2001 From: Eldeberen Date: Sat, 20 Feb 2021 00:33:34 +0100 Subject: [PATCH] poll: add ability to vote Fixed some bugs too --- app/models/poll.py | 4 +-- app/models/polls/simple.py | 20 +++++++++--- app/routes/__init__.py | 3 +- app/routes/polls/create.py | 9 ++++++ app/routes/polls/submit.py | 20 ------------ app/routes/polls/vote.py | 34 +++++++++++++++++++++ app/templates/widgets/poll.html | 4 +-- app/templates/widgets/polls/simplepoll.html | 2 +- 8 files changed, 65 insertions(+), 31 deletions(-) create mode 100644 app/routes/polls/create.py delete mode 100644 app/routes/polls/submit.py create mode 100644 app/routes/polls/vote.py diff --git a/app/models/poll.py b/app/models/poll.py index e5bb0e9..9a6d0b2 100644 --- a/app/models/poll.py +++ b/app/models/poll.py @@ -69,7 +69,6 @@ class Poll(db.Model): @property def started(self): """Returns whether the poll is open""" - print(self.start, datetime.now()) return self.start <= datetime.now() @property @@ -118,6 +117,7 @@ class PollAnswer(db.Model): # Choice(s) answer = db.Column(db.PickleType) - def __init__(self, user, answer): + def __init__(self, poll, user, answer): + self.poll = poll self.author = user self.answer = answer diff --git a/app/models/polls/simple.py b/app/models/polls/simple.py index 87d0713..04c285c 100644 --- a/app/models/polls/simple.py +++ b/app/models/polls/simple.py @@ -19,19 +19,29 @@ class SimplePoll(Poll): super().__init__(author, title, choices, **kwargs) # Mandatory methods - def vote(self, user, data): - data = [data] # TODO - answer = PollAnswer(user, data) + def vote(self, user, request): + try: + choice_id = int(request.form['pollanwsers']) + except (KeyError, ValueError): + return None + + answer = PollAnswer(self, user, choice_id) return answer @property def results(self): values = {c: 0 for c in self.choices} counter = Counter(values) - for answer in self.answers: - counter.update([answer.answer]) + answers = [self.choice_from_id(a.answer) for a in self.answers] + counter.update(answers) return counter + # Custom method + def choice_from_id(self, id): + for c in self.choices: + if c.id == id: + return c + return None class Choice(): def __init__(self, id, title): diff --git a/app/routes/__init__.py b/app/routes/__init__.py index dd2283c..c8d40ae 100644 --- a/app/routes/__init__.py +++ b/app/routes/__init__.py @@ -5,8 +5,9 @@ from app.routes.account import login, account, notification from app.routes.admin import index, groups, account, trophies, forums, \ attachments, config, members from app.routes.forum import index, topic -from app.routes.programs import index +from app.routes.polls import create, vote from app.routes.posts import edit +from app.routes.programs import index from app.routes.api import markdown try: diff --git a/app/routes/polls/create.py b/app/routes/polls/create.py new file mode 100644 index 0000000..4bc7c22 --- /dev/null +++ b/app/routes/polls/create.py @@ -0,0 +1,9 @@ +from app import app, db +from flask import abort, redirect, request, url_for +from flask_login import current_user + +from app.models.poll import Poll + +@app.route("/poll/new", methods=['GET', 'POST']) +def poll_create(poll_id): + return redirect(url_for('index')) diff --git a/app/routes/polls/submit.py b/app/routes/polls/submit.py deleted file mode 100644 index 25aaeda..0000000 --- a/app/routes/polls/submit.py +++ /dev/null @@ -1,20 +0,0 @@ -from app import app, db -from flask import request -from flask_login import current_user - -from app.models.poll import Poll - -@app.route("/poll/", methods=['POST']) -def poll_submit(poll_id): - p = Poll.query.first_or_404() - - if not current_user.is_authenticated: - return 401 - if p.has_voted(current_user): - return 403 - - try: - resp = request.get_json()['text'] - except BadRequestKeyError: - abort(400) - return str(md(markdown)) diff --git a/app/routes/polls/vote.py b/app/routes/polls/vote.py new file mode 100644 index 0000000..08a7911 --- /dev/null +++ b/app/routes/polls/vote.py @@ -0,0 +1,34 @@ +from app import app, db +from flask import abort, flash, redirect, request, url_for +from flask_login import current_user + +from app.models.poll import Poll + +@app.route("/poll//vote", methods=['POST']) +def poll_vote(poll_id): + poll = Poll.query.first_or_404(poll_id) + + if not current_user.is_authenticated: + abort(401) + if not poll.can_vote(current_user): + abort(403) + if poll.has_voted(current_user): + abort(403) + if not poll.started: + abort(403) + if poll.ended: + abort(403) + + answer = poll.vote(current_user, request) + + if answer is None: + abort(400) + + db.session.add(answer) + db.session.commit() + + flash('Le vote a été pris en compte', 'info') + + if request.referrer: + return redirect(request.referrer) + return redirect(url_for('index')) diff --git a/app/templates/widgets/poll.html b/app/templates/widgets/poll.html index 4097b77..d63c595 100644 --- a/app/templates/widgets/poll.html +++ b/app/templates/widgets/poll.html @@ -25,11 +25,11 @@ {# Current user has already voted #} {% elif poll.has_voted(current_user) %} -

Vous avez déjà voté. Revenez le {{ poll.ended | date }} pour voir les résultats

+

Vous avez déjà voté. Revenez le {{ poll.end | date }} pour voir les résultats

{# Current user can vote #} {% else %} -
+ {{ poll_template.choices(poll) }} diff --git a/app/templates/widgets/polls/simplepoll.html b/app/templates/widgets/polls/simplepoll.html index 3225e44..2cbb3e1 100644 --- a/app/templates/widgets/polls/simplepoll.html +++ b/app/templates/widgets/polls/simplepoll.html @@ -1,7 +1,7 @@ {% macro choices(poll) %}
{% for choice in poll.choices %} - +
{% endfor %}