PCv5/app/models/poll.py

104 lines
2.7 KiB
Python

from app import db
from enum import Enum
from sqlalchemy.orm import backref
from datetime import datetime
from collections import Counter
class PollType(Enum):
"""Polls types: single/multiple answers. Easier than inheritance"""
SINGLE = 1
MULTIPLE = 2
class Poll(db.Model):
"""Some poll, with different options"""
__tablename__ = 'poll'
# Unique ID
id = db.Column(db.Integer, primary_key=True)
# Author
author_id = db.Column(db.Integer, db.ForeignKey('member.id'))
author = db.relationship('Member', backref=backref('polls'),
foreign_keys=author_id)
# Type
type = db.Column(db.Enum(PollType))
# Title/question
title = db.Column(db.UnicodeText)
# End datetime
end = db.Column(db.DateTime)
# Choices
# We want a size-variable list of strings, or a dictionnary with
# key/values, depending on the poll type.
# As the data is likely to be adapted to the poll type, the PickleType
# seems to be appropriate. Same applies for PollAnswer.
choices = db.Column(db.PickleType)
# Other fields populated automatically through relations:
# <answers> The list of answers (of type PollAnswer)
def __init__(self, title, choices, comment, type=PollType.SINGLE):
self.title = title
self.choices = choices
self.comment = comment
self.type = PollType.SINGLE
def delete(self):
"""Deletes a poll and its answers"""
for answer in SpecialPrivilege.query.filter_by(poll_id=self.id).all():
db.session.delete(answer)
db.session.commit()
db.session.delete(self)
db.session.commit()
# Some useful properties
@property
def ended(self):
return self.end > datetime.now()
@property
def results(self):
"""Returns a Counter populated with answers"""
r = Counter()
for answer in self.answers:
if self.type == SINGLE:
r.update([answer])
else:
r.update(answer)
return r
def has_voted(self, user):
# TODO: use ORM for this dirty request
return user in [a.author for a in self.answers]
def can_vote(self, user):
return user.is_authenticated
class PollAnswer(db.Model):
"""An answer to a poll"""
__tablename__ = 'pollanswer'
# Unique ID
id = db.Column(db.Integer, primary_key=True)
# Poll
poll_id = db.Column(db.Integer, db.ForeignKey('poll.id'))
poll = db.relationship('Poll', backref=backref('answers'),
foreign_keys=poll_id)
# Author. Must be Member
author_id = db.Column(db.Integer, db.ForeignKey('member.id'))
author = db.relationship('Member', foreign_keys=author_id)
# Choice(s)
choices = db.Column(db.PickleType)