from app import db from enum import Enum from sqlalchemy.orm import backref from datetime import datetime, timedelta from collections import Counter class Poll(db.Model): """Default class for polls""" __tablename__ = 'poll' # Names of templates template = 'defaultpoll.html' # Unique ID id = db.Column(db.Integer, primary_key=True) # Type type = db.Column(db.String(20)) # Author author_id = db.Column(db.Integer, db.ForeignKey('member.id')) author = db.relationship('Member', backref=backref('polls'), foreign_keys=author_id) # Title/question title = db.Column(db.UnicodeText) # Start datetime start = db.Column(db.DateTime, default=datetime.now()) # 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: # The list of answers (of type PollAnswer) __mapper_args__ = { 'polymorphic_identity': __tablename__, 'polymorphic_on':type } def __init__(self, author, title, choices, start=datetime.now(), end=datetime.now()): self.author = author self.title = title self.choices = choices self.start = start self.end = end def delete(self): """Deletes a poll and its answers""" for a in self.answers: db.session.delete(a) db.session.commit() db.session.delete(self) # Common properties and methods @property def started(self): """Returns whether the poll is open""" return self.start <= datetime.now() @property def ended(self): """Returns whether the poll is closed""" return self.end < datetime.now() def has_voted(self, user): """Returns wheter the user has voted""" # TODO: use ORM for this dirty request return user in [a.author for a in self.answers] def can_vote(self, user): """Returns true if the current user can vote. More conditions may be added in the future""" return user.is_authenticated # Poll-specific methods. Must be overrided per-poll definition def vote(self, user, data): """Return a PollAnswer object from specified user and data""" return None @property def results(self): """Returns an easy-to-use object with answers of the poll.""" return None 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'), index=True) 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) answer = db.Column(db.PickleType) def __init__(self, poll, user, answer): self.poll = poll self.author = user self.answer = answer