diff options
Diffstat (limited to 'papillon/polls/models.py')
| -rw-r--r-- | papillon/polls/models.py | 227 | 
1 files changed, 227 insertions, 0 deletions
diff --git a/papillon/polls/models.py b/papillon/polls/models.py new file mode 100644 index 0000000..f8b3b22 --- /dev/null +++ b/papillon/polls/models.py @@ -0,0 +1,227 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (C) 2008  Étienne Loks  <etienne.loks_AT_peacefrogsDOTnet> + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program.  If not, see <http://www.gnu.org/licenses/>. + +# See the file COPYING for details. + +''' +Models management +''' + +import datetime + +from django.db import models +from django.utils.translation import gettext_lazy as _ + +from papillon.settings import DAYS_TO_LIVE + +class Category(models.Model): +    name = models.CharField(max_length=100) +    description = models.TextField() +    def __unicode__(self): +        return self.name + +class PollUser(models.Model): +    name = models.CharField(max_length=100) +    email = models.CharField(max_length=100) +    password = models.CharField(max_length=100) +    modification_date = models.DateTimeField(auto_now=True) + +class Poll(models.Model): +    base_url = models.CharField(max_length=100, help_text=_('Copy this \ +address and send it to voters who want to participate to this poll')) +    admin_url = models.CharField(max_length=100,  help_text=_("Address to \ +modify the current poll")) +    author_name = models.CharField(verbose_name=_("Author name"),  +       max_length=100, help_text=_("Name, firstname or nickname of the author")) +    author = models.ForeignKey(PollUser, null=True, blank=True) +    name = models.CharField(max_length=200, verbose_name=_("Poll name"), +                            help_text=_("Global name to present the poll")) +    description = models.CharField(max_length=1000, +                            verbose_name=_("Poll description"),  +                            help_text=_("Precise description of the poll")) +    category = models.ForeignKey(Category, null=True, blank=True) +    TYPE = (('P', _('Yes/No poll')), +            ('B', _('Yes/No/Maybe poll')), +            ('O', _('One choice poll')), +            ('V', _('Valuable choice poll')),) +    type = models.CharField(max_length=1, choices=TYPE, +                      verbose_name=_("Type of the poll"), +                      help_text=_("""Type of the poll: + + - "Yes/No poll" is the appropriate type for a simple multi-choice poll + - "Yes/No/Maybe poll" allows voters to stay undecided + - "One choice poll" gives only one option to choose from + - "Valuable choice poll" permit users to give a note between 0 to 9 to \ +different choices +""")) +    dated_choices = models.BooleanField(verbose_name=_("Choices are dates"), +        default=False, help_text=_("Check this option to choose between dates")) +    enddate = models.DateTimeField(null=True, blank=True, +verbose_name=_("Closing date"), help_text=_("Closing date for participating to \ +the poll")) +    modification_date = models.DateTimeField(auto_now=True) +    public = models.BooleanField(default=False, +verbose_name=_("Display the poll on main page"), help_text=_("Check this \ +option to make the poll public")) +    opened_admin = models.BooleanField(default=False, +verbose_name=_("Allow users to add choices"), help_text=_("Check this option \ +to open the poll to new choices submitted by users")) +    hide_choices = models.BooleanField(default=False, +verbose_name=_("Hide votes to new voters"), help_text=_("Check this option to \ +hide poll results to new users")) +    open = models.BooleanField(default=True, +verbose_name=_("State of the poll"), help_text=_("Uncheck this option to close \ +the poll/check this option to reopen it")) + +    def getTypeLabel(self): +        idx = [type[0] for type in self.TYPE].index(self.type) +        return Poll.TYPE[idx][1] + +    def checkForErasement(self): +        '''Check if the poll has to be deleted''' +        if not DAYS_TO_LIVE: +            return +        now = datetime.datetime.now() +        dtl = datetime.timedelta(days=DAYS_TO_LIVE) +        if self.modification_date + dtl > now: +            return +        voters = Voter.objects.filter(poll=self) +        for voter in voters: +            if voter.modification_date + dtl > now: +                return +        for voter in voters: +            voter.user.delete() +            voter.delete() +        comments = Comment.objects.filter(poll=self) +        for comment in comments: +            comment.delete() +        self.delete() + +    def getChoices(self): +        """ +        Get choices associated to this vote""" +        return Choice.objects.filter(poll=self) + +    def reorder(self): +        """ +        Reorder choices of the poll""" +        if not self.dated_choices: +            return +        choices = self.getChoices() +        sort_fct = lambda x:datetime.datetime.strptime(x.name, +                                                       '%Y-%m-%d %H:%M:%S') +        choices = sorted(choices, key=sort_fct) +        for idx, choice in enumerate(choices): +            choice.order = idx +            choice.save() + +    class Admin: +        pass +    class Meta: +        ordering = ['-modification_date'] +    def __unicode__(self): +        return self.name + +class Comment(models.Model): +    '''Comment for a poll''' +    poll = models.ForeignKey(Poll) +    author_name = models.CharField(max_length=100) +    text = models.CharField(max_length=1000) +    date = models.DateTimeField(auto_now_add=True) +    class Meta: +        ordering = ['date'] + +class Voter(models.Model): +    user = models.ForeignKey(PollUser) +    poll = models.ForeignKey(Poll) +    creation_date = models.DateTimeField(auto_now_add=True) +    modification_date = models.DateTimeField(auto_now=True) +    class Meta: +        ordering = ['creation_date'] +    def __unicode__(self): +        return _("Vote from %(user)s") % {'user':self.user.name} +    def getVotes(self, choice_ids): +        '''Get votes for a subset of choices +        ''' +        query = Vote.objects.filter(voter=self) +        query = query.extra(where=['choice_id IN (%s)' \ +                     % ",".join([str(choice_id) for choice_id in choice_ids])]) +        return list(query.order_by('choice')) + +class Choice(models.Model): +    poll = models.ForeignKey(Poll) +    name = models.CharField(max_length=200) +    order = models.IntegerField() +    limit = models.IntegerField(null=True, blank=True) +    available = models.BooleanField(default=True) +    class Admin: +        pass +    class Meta: +        ordering = ['order'] + +    def get_date(self): +        if not self.poll.dated_choices: +            return self.name +        return datetime.datetime.strptime(self.name, '%Y-%m-%d %H:%M:%S') + +    def set_date(self, value): +        self._date = value +        #if not self.poll.dated_choices: +        #    self.name = value +        #self.name = datetime.strftime(value, '%Y-%m-%d %H:%M:%S') +    date = property(get_date, set_date) + +    def getSum(self, balanced_poll=None): +        '''Get the sum of votes for this choice''' +        sum = 0 +        for vote in Vote.objects.filter(choice=self, value__isnull=False): +            sum += vote.value +        if balanced_poll: +            return sum/2 +        return sum + +    def changeOrder(self, idx=1): +        ''' +        Change a choice in the list +        ''' +        if (self.order + idx) < 0: +            return +        choices = Choice.objects.filter(poll=self.poll) +        if self.order + idx > len(choices): +            return +        new_order = self.order + idx +        for choice in choices: +            if choice == self: +                continue +            if idx < 0 and choice.order < self.order \ +               and choice.order >= new_order: +               choice.order += 1 +               choice.save() +            if idx > 0 and choice.order > self.order \ +               and choice.order <= new_order: +               choice.order -= 1 +               choice.save() +        self.order = new_order +        self.save() + +class Vote(models.Model): +    voter = models.ForeignKey(Voter) +    choice = models.ForeignKey(Choice) +    VOTE = ((1, (_('Yes'),  _('Yes'))), +            (0, (_('No'), _('Maybe')), ), +            (-1, (_('No'), _('No'))),) +    value = models.IntegerField(choices=VOTE, blank=True, null=True)  | 
