PCv5/app/models/poll.py

121 lines
3.3 KiB
Python
Raw Normal View History

from app import db
from enum import Enum
from sqlalchemy.orm import backref
2021-02-19 22:07:31 +01:00
from datetime import datetime, timedelta
from collections import Counter
class Poll(db.Model):
2021-02-19 22:07:31 +01:00
"""Default class for polls"""
__tablename__ = 'poll'
2021-02-19 22:07:31 +01:00
# Names of templates
template = 'defaultpoll.html'
# Unique ID
id = db.Column(db.Integer, primary_key=True)
# Type
2021-02-19 22:07:31 +01:00
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)
2021-02-19 22:07:31 +01:00
# 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:
# <answers> The list of answers (of type PollAnswer)
2021-02-19 22:07:31 +01:00
__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)
2021-02-19 22:07:31 +01:00
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)
2021-02-19 22:07:31 +01:00
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)
2021-02-19 22:07:31 +01:00
answer = db.Column(db.PickleType)
def __init__(self, poll, user, answer):
self.poll = poll
2021-02-19 22:07:31 +01:00
self.author = user
self.answer = answer