104 lines
2.7 KiB
Python
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)
|