poll: add ability to vote

Fixed some bugs too
This commit is contained in:
Eldeberen 2021-02-20 00:33:34 +01:00
parent ec3f33ead0
commit 473448ab5b
Signed by: Darks
GPG Key ID: 7515644268BE1433
8 changed files with 65 additions and 31 deletions

View File

@ -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

View File

@ -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):

View File

@ -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:

View File

@ -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'))

View File

@ -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/<int:poll_id>", 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))

34
app/routes/polls/vote.py Normal file
View File

@ -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/<int:poll_id>/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'))

View File

@ -25,11 +25,11 @@
{# Current user has already voted #}
{% elif poll.has_voted(current_user) %}
<p><i>Vous avez déjà voté. Revenez le {{ poll.ended | date }} pour voir les résultats</i></p>
<p><i>Vous avez déjà voté. Revenez le {{ poll.end | date }} pour voir les résultats</i></p>
{# Current user can vote #}
{% else %}
<form class="poll" action="/poll/{{ poll.id }}" method="post" enctype="multipart/form-data">
<form class="poll" action="{{ url_for('poll_vote', poll_id=poll.id) }}" method="post" enctype="multipart/form-data">
{{ poll_template.choices(poll) }}
<input type="submit" value="Envoyer">
<input id="csrf_token" name="csrf_token" type="hidden" value="{{ csrf_token() }}">

View File

@ -1,7 +1,7 @@
{% macro choices(poll) %}
<fieldset>
{% for choice in poll.choices %}
<input type="radio" id="{{ poll.id }}-{{ choice.id }}" name="pollanwsers" value="{{ choice.title }}" />
<input type="radio" id="{{ poll.id }}-{{ choice.id }}" name="pollanwsers" value="{{ choice.id }}" />
<label for="{{ poll.id }}-{{ choice.id }}">{{ choice.title }}</label><br>
{% endfor %}
</fieldset>