diff --git a/app/forms/poll.py b/app/forms/poll.py index 4a003ff..58db791 100644 --- a/app/forms/poll.py +++ b/app/forms/poll.py @@ -1,5 +1,5 @@ from flask_wtf import FlaskForm -from wtforms import StringField, SubmitField, TextAreaField +from wtforms import StringField, SubmitField, TextAreaField, SelectField from wtforms.fields.html5 import DateTimeField from wtforms.validators import InputRequired, Optional @@ -19,6 +19,13 @@ class PollForm(FlaskForm): # TODO: add a validator to check if there is at least one choice ] ) + type = SelectField( + 'Type', + choices=[ + ('simplepoll', 'Réponse unique'), + ('multiplepoll', 'Réponses multiples') + ] + ) start = DateTimeField( 'Début', default=datetime.now(), diff --git a/app/models/polls/multiple.py b/app/models/polls/multiple.py new file mode 100644 index 0000000..fe83acd --- /dev/null +++ b/app/models/polls/multiple.py @@ -0,0 +1,49 @@ +from app import db +from app.models.poll import Poll, PollAnswer +from collections import Counter +from itertools import chain + + +class MultiplePoll(Poll): + """Poll with many answers allowed""" + + __tablename__ = 'multiplepoll' + + # Names of templates + template = 'multiplepoll.html' + + __mapper_args__ = { + 'polymorphic_identity': __tablename__, + } + + def __init__(self, author, title, choices, **kwargs): + choices = [Choice(i, t) for i, t in enumerate(choices)] + super().__init__(author, title, choices, **kwargs) + + # Mandatory methods + def vote(self, user, request): + answers_id = [] + for c in self.choices: + if f"pollanswers-{c.id}" in request.form: + answers_id.append(c.id) + return PollAnswer(self, user, answers_id) + + @property + def results(self): + values = {c: 0 for c in self.choices} + counter = Counter(values) + for a in self.answers: + counter.update([self.choice_from_id(id) for id in a.answer]) + 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): + self.id = id + self.title = title diff --git a/app/routes/account/polls.py b/app/routes/account/polls.py index 665566f..4b58b62 100644 --- a/app/routes/account/polls.py +++ b/app/routes/account/polls.py @@ -3,6 +3,7 @@ from flask import abort, flash, redirect, request, url_for from flask_login import current_user from app.models.polls.simple import SimplePoll +from app.models.polls.multiple import MultiplePoll from app.forms.poll import PollForm from app.utils.render import render @@ -10,10 +11,14 @@ from app.utils.render import render def account_polls(): form = PollForm() polls = current_user.polls + polls_types = { + 'simplepoll': SimplePoll, + 'multiplepoll': MultiplePoll, + } if form.validate_on_submit(): choices = list(filter(None, form.choices.data.split('\n'))) - p = SimplePoll(current_user, form.title.data, choices, + p = polls_types[form.type.data](current_user, form.title.data, choices, start=form.start.data, end=form.end.data) db.session.add(p) db.session.commit() diff --git a/app/templates/account/polls.html b/app/templates/account/polls.html index bac4c4a..d562421 100644 --- a/app/templates/account/polls.html +++ b/app/templates/account/polls.html @@ -9,7 +9,6 @@

Créer un sondage

- {{ form.hidden_tag() }}
{{ form.title.label }}
{{ form.title(size=32) }}
@@ -24,6 +23,13 @@ {{ error }} {% endfor %}
+
+ {{ form.type.label }}
+ {{ form.type }}
+ {% for error in form.type.errors %} + {{ error }} + {% endfor %} +
{{ form.start.label }} {{ form.start() }} @@ -38,6 +44,7 @@ {{ error }} {% endfor %}
+ {{ form.hidden_tag() }}
{{ form.submit(class_="bg-ok") }}
diff --git a/app/templates/widgets/polls/multiplepoll.html b/app/templates/widgets/polls/multiplepoll.html new file mode 100644 index 0000000..502b5dd --- /dev/null +++ b/app/templates/widgets/polls/multiplepoll.html @@ -0,0 +1,25 @@ +{% macro choices(poll) %} +
+{% for choice in poll.choices %} + +
+{% endfor %} +
+{% endmacro %} + +{% macro results(poll) %} + + {% for choice, votes in poll.results.most_common() %} + + + + + + {% endfor %} + + + +
+ + {{ votes }}
Participations{{ len(poll.answers) }}
+{% endmacro %}