diff options
| author | etienne <etienne@07715635-78ed-41b0-aaf1-0afda6c37f35> | 2010-03-27 17:06:03 +0000 |
|---|---|---|
| committer | etienne <etienne@07715635-78ed-41b0-aaf1-0afda6c37f35> | 2010-03-27 17:06:03 +0000 |
| commit | 95729368a48257b110ea33dfb005785f8ed6734f (patch) | |
| tree | 8b99b375a4b4a2e121a9192910af15485ea2b7c3 /polls | |
| parent | 8ded76ae513b38d14773449e46543b54cf48ef49 (diff) | |
| download | Papillon-95729368a48257b110ea33dfb005785f8ed6734f.tar.bz2 Papillon-95729368a48257b110ea33dfb005785f8ed6734f.zip | |
Rearrange directories - include documentation
Diffstat (limited to 'polls')
| -rw-r--r-- | polls/__init__.py | 0 | ||||
| -rw-r--r-- | polls/admin.py | 34 | ||||
| -rw-r--r-- | polls/feeds.py | 55 | ||||
| -rw-r--r-- | polls/forms.py | 132 | ||||
| -rw-r--r-- | polls/models.py | 227 | ||||
| -rw-r--r-- | polls/templatetags/__init__.py | 0 | ||||
| -rw-r--r-- | polls/templatetags/get_range.py | 25 | ||||
| -rw-r--r-- | polls/views.py | 491 |
8 files changed, 0 insertions, 964 deletions
diff --git a/polls/__init__.py b/polls/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/polls/__init__.py +++ /dev/null diff --git a/polls/admin.py b/polls/admin.py deleted file mode 100644 index 2207c60..0000000 --- a/polls/admin.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/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. - -""" -Settings for administration pages -""" - -from papillon.polls.models import Poll, Category -from django.contrib import admin - -class PollAdmin(admin.ModelAdmin): - search_fields = ("name",) - list_display = ('name', 'category', 'modification_date', 'public', 'open') - list_filter = ('public', 'open', 'category') - -# register of differents database fields -admin.site.register(Category) -admin.site.register(Poll, PollAdmin) diff --git a/polls/feeds.py b/polls/feeds.py deleted file mode 100644 index 2d52dc7..0000000 --- a/polls/feeds.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/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. - -import time - -from django.core.exceptions import ObjectDoesNotExist -from django.contrib.syndication.feeds import Feed -from django.utils.translation import gettext_lazy as _ - -from papillon.settings import BASE_SITE -from papillon.polls.models import Poll, Vote, Voter - - -class PollLatestEntries(Feed): - def get_object(self, poll_url): - if len(poll_url) < 1: - raise ObjectDoesNotExist - return Poll.objects.get(base_url=poll_url[0]) - - def title(self, obj): - return _("Papillon - poll : ") + obj.name - - def link(self, obj): - if not obj: - raise FeedDoesNotExist - return BASE_SITE + "/poll/" + obj.base_url - - def description(self, obj): - return obj.description - - def item_link(self, voter): - url = "%s/poll/%s_%d" % (BASE_SITE, voter.poll.base_url, - time.mktime(voter.modification_date.timetuple())) - return url - - def items(self, obj): - voters = Voter.objects.filter(poll__id=obj.id).\ -order_by('-modification_date')[:10] - return voters
\ No newline at end of file diff --git a/polls/forms.py b/polls/forms.py deleted file mode 100644 index 3a151aa..0000000 --- a/polls/forms.py +++ /dev/null @@ -1,132 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright (C) 2009 É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. - -''' -Forms management -''' - -from datetime import datetime - -from django import forms -from django.contrib.admin import widgets as adminwidgets -from django.utils.translation import gettext_lazy as _ - -from papillon.polls.models import Poll, Category, Choice, Comment -from papillon import settings - -class TextareaWidget(forms.Textarea): - """ - Manage the edition of a text using TinyMCE - """ - class Media: - js = ["%stiny_mce.js" % settings.TINYMCE_URL, - "%stextareas.js" % settings.MEDIA_URL,] - -class PollForm(forms.ModelForm): - def __init__(self, *args, **kwargs): - super(PollForm, self).__init__(*args, **kwargs) - self.fields['description'].widget = TextareaWidget() - -class CreatePollForm(PollForm): - class Meta: - model = Poll - exclude = ['base_url', 'admin_url', 'open', 'author', 'enddate', - 'public', 'opened_admin', 'hide_choices'] - if not Category.objects.all(): - exclude.append('category') - -class CommentForm(forms.ModelForm): - class Meta: - model = Comment - exclude = ['date',] - def __init__(self, *args, **kwargs): - super(CommentForm, self).__init__(*args, **kwargs) - self.fields['text'].widget = TextareaWidget() - -# workaround for SplitDateTime with required=False -class SplitDateTimeJSField(forms.SplitDateTimeField): - def __init__(self, *args, **kwargs): - super(SplitDateTimeJSField, self).__init__(*args, **kwargs) - self.widget.widgets[0].attrs = {'class': 'vDateField'} - self.widget.widgets[1].attrs = {'class': 'vTimeField'} - -class AdminPollForm(PollForm): - class Meta: - model = Poll - exclude = ['author', 'author_name', 'base_url', 'admin_url', - 'dated_choices', 'type'] - if not Category.objects.all(): - exclude.append('category') - enddate = SplitDateTimeJSField(widget=adminwidgets.AdminSplitDateTime(), - required=False, label=Poll._meta.get_field('enddate').verbose_name, - help_text=Poll._meta.get_field('enddate').help_text) - -class ChoiceForm(forms.ModelForm): - class Meta: - model = Choice - fields = ('name', 'limit', 'poll', 'order',) - def __init__(self, *args, **kwargs): - super(ChoiceForm, self).__init__(*args, **kwargs) - self.fields['poll'].widget = forms.HiddenInput() - self.fields['order'].widget = forms.HiddenInput() - -class DatedChoiceForm(ChoiceForm): - def __init__(self, *args, **kwargs): - super(DatedChoiceForm, self).__init__(*args, **kwargs) - self.fields['name'].widget = adminwidgets.AdminSplitDateTime() - - def clean_name(self): - try: - poll_id = self.data['poll'] - poll = Poll.objects.get(id=int(poll_id)) - except (ValueError, Poll.DoesNotExist): - raise forms.ValidationError(_('Invalid poll')) - data = self.cleaned_data['name'] - if poll.dated_choices: - # management of dates fields - if data.startswith('[') and data.endswith(']') and "'" in data: - datas = data.split("'") - try: - assert len(datas) == 5 - time = datas[3] - if not time: - time = '00:00:00' - date = "%s %s" % (datas[1], time) - datetime.strptime(date, '%Y-%m-%d %H:%M:%S') - data = date - except (ValueError, AssertionError): - raise forms.ValidationError(_('Invalid date format: \ -YYYY-MM-DD HH:MM:SS')) - return data - - def clean_limit(self): - """ - data = eval(self.cleaned_data['name']) - - new_limit = int(request.POST[key]) - sum = choice.getSum() - if new_limit < sum: - response_dct['error'] = _("You cannot lower \ -%(name)s's limit to this number : there is currently %(sum)d votes for this \ -choice.") % {'name':choice.name, 'sum':sum} - else: - choice.limit = new_limit - choice.save() -""" - pass diff --git a/polls/models.py b/polls/models.py deleted file mode 100644 index f8b3b22..0000000 --- a/polls/models.py +++ /dev/null @@ -1,227 +0,0 @@ -#!/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) diff --git a/polls/templatetags/__init__.py b/polls/templatetags/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/polls/templatetags/__init__.py +++ /dev/null diff --git a/polls/templatetags/get_range.py b/polls/templatetags/get_range.py deleted file mode 100644 index b9d8328..0000000 --- a/polls/templatetags/get_range.py +++ /dev/null @@ -1,25 +0,0 @@ -from django.template import Library - -register = Library() - -@register.filter -def get_range( value ): - """ - Filter - returns a list containing range made from given value - Usage (in template): - - <ul>{% for i in 3|get_range %} - <li>{{ i }}. Do something</li> -{% endfor %}</ul> - -Results with the HTML: -<ul> -<li>0. Do something</li> -<li>1. Do something</li> -<li>2. Do something</li> -</ul> - -Instead of 3 one may use the variable set in the views - """ - return range(value) - diff --git a/polls/views.py b/polls/views.py deleted file mode 100644 index e9ef572..0000000 --- a/polls/views.py +++ /dev/null @@ -1,491 +0,0 @@ -#!/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. - -''' -Views management -''' - -from random import choice as random_choice -import string -import time -from datetime import datetime - -from django.utils.translation import gettext_lazy as _ -from django.shortcuts import render_to_response -from django.http import HttpResponseRedirect - -from papillon.settings import LANGUAGES, BASE_SITE -from papillon.polls.models import Poll, PollUser, Choice, Voter, Vote, \ - Category, Comment -from papillon.polls.forms import CreatePollForm, AdminPollForm, ChoiceForm, \ - DatedChoiceForm, CommentForm - -def getBaseResponse(request): - """Manage basic fields for the template - If not null the second argument returned is a redirection. - """ - url = BASE_SITE - # setting the current language and available languages - if 'language' in request.GET: - if request.GET['language'] in [language[0] for language in LANGUAGES]: - request.session['django_language'] = request.GET['language'] - return None, HttpResponseRedirect(request.path) - languages = [] - for language_code, language_label in LANGUAGES: - languages.append((language_code, language_label)) - return {'root_url':url, 'languages':languages}, None - -def index(request): - "Main page" - response_dct, redirect = getBaseResponse(request) - if redirect: - return redirect - response_dct['polls'] = Poll.objects.filter(public=True, category=None) - response_dct['categories'] = Category.objects.all() - error = '' - if 'bad_poll' in request.GET: - response_dct['error'] = _("The poll requested don't exist (anymore?)") - return render_to_response('main.html', response_dct) - -def category(request, category_id): - "Page for a category" - response_dct, redirect = getBaseResponse(request) - if redirect: - return redirect - category = Category.objects.get(id=int(category_id)) - response_dct['category'] = category - response_dct['polls'] = Poll.objects.filter(public=True, category=category) - return render_to_response('category.html', response_dct) - -def create(request): - '''Creation of a poll. - ''' - def genRandomURL(): - "Generation of a random url" - url = '' - while not url or Poll.objects.filter(base_url=url).count() or\ - Poll.objects.filter(admin_url=url).count(): - url = '' - chars = string.letters + string.digits - for i in xrange(6): - url += random_choice(chars) - url += str(int(time.time())) - return url - - response_dct, redirect = getBaseResponse(request) - if redirect: - return redirect - - if request.method == 'POST': - form = CreatePollForm(request.POST) - if form.is_valid(): - poll = form.save() - poll.admin_url = genRandomURL() - poll.base_url = genRandomURL() - poll.save() - return HttpResponseRedirect('%seditChoicesAdmin/%s/' % ( - response_dct['root_url'], poll.admin_url)) - else: - form = CreatePollForm() - response_dct['form'] = form - return render_to_response('create.html', response_dct) - -def edit(request, admin_url): - '''Edition of a poll. - ''' - response_dct, redirect = getBaseResponse(request) - if redirect: - return redirect - try: - poll = Poll.objects.filter(admin_url=admin_url)[0] - except IndexError: - # if the poll don't exist redirect to the creation page - url = response_dct['root_url'] - return HttpResponseRedirect('%screate' % ( - response_dct['root_url'])) - Form = AdminPollForm - - if request.method == 'POST': - form = Form(request.POST, instance=poll) - if form.is_valid(): - poll = form.save() - return HttpResponseRedirect('%sedit/%s/' % ( - response_dct['root_url'], poll.admin_url)) - else: - form = Form(instance=poll) - response_dct['form'] = form - response_dct['poll'] = poll - return render_to_response('edit.html', response_dct) - -def editChoicesAdmin(request, admin_url): - response_dct, redirect = getBaseResponse(request) - if redirect: - return redirect - try: - poll = Poll.objects.filter(admin_url=admin_url)[0] - except IndexError: - # if the poll don't exist redirect to the main page - url = "/".join(request.path.split('/')[:-2]) - return response_dct, HttpResponseRedirect(url) - response_dct['poll'] = poll - return editChoices(request, response_dct, admin=True) - -def editChoicesUser(request, poll_url): - response_dct, redirect = getBaseResponse(request) - if redirect: - return redirect - try: - poll = Poll.objects.filter(base_url=poll_url)[0] - except IndexError: - poll = None - if not poll or not poll.opened_admin: - # if the poll don't exist redirect to the main page - url = "/".join(request.path.split('/')[:-2]) - return HttpResponseRedirect(url) - response_dct['poll'] = poll - return editChoices(request, response_dct) - -def editChoices(request, response_dct, admin=False): - '''Edition of choices. - ''' - poll = response_dct['poll'] - tpl = 'editChoicesAdmin.html' - if not admin: - tpl = 'editChoicesUser.html' - Form = ChoiceForm - if poll.dated_choices: - Form = DatedChoiceForm - try: - order = Choice.objects.order_by('-order')[0].order - order += 1 - except IndexError: - order = 0 - form = Form(initial={'poll':poll.id, 'order':str(order)}) - - if request.method == 'POST': - # if a new choice is submitted - if 'add' in request.POST and request.POST['poll'] == str(poll.id): - f = Form(request.POST) - if f.is_valid(): - choice = f.save() - poll.reorder() - else: - form = f - if admin and 'edit' in request.POST \ - and request.POST['poll'] == str(poll.id): - try: - choice = Choice.objects.get(id=int(request.POST['edit'])) - if choice.poll != poll: - raise ValueError - f = Form(request.POST, instance=choice) - if f.is_valid(): - choice = f.save() - poll.reorder() - except (Choice.DoesNotExist, ValueError): - pass - if admin: - # check if a choice has been choosen for deletion - for key in request.POST: - if key.startswith('delete_') and request.POST[key]: - try: - choice = Choice.objects.get(id=int(key[len('delete_'):])) - if choice.poll != poll: - raise ValueError - Vote.objects.filter(choice=choice).delete() - choice.delete() - except (Choice.DoesNotExist, ValueError): - pass - # check if the order of a choice has to be changed - if admin and request.method == 'GET': - for key in request.GET: - try: - current_url = request.path.split('?')[0] - if 'up_choice' in key: - choice = Choice.objects.get(id=int(request.GET[key])) - if choice.poll != poll: - raise ValueError - choice.changeOrder(-1) - poll.reorder() - # redirect in order to avoid a change with a refresh - return HttpResponseRedirect(current_url) - if 'down_choice' in key: - choice = Choice.objects.get(id=int(request.GET[key])) - if choice.poll != poll: - raise ValueError - choice.changeOrder(1) - poll.reorder() - # redirect in order to avoid a change with a refresh - return HttpResponseRedirect(current_url) - except (ValueError, Choice.DoesNotExist): - pass - choices = Choice.objects.filter(poll=poll).order_by('order') - for choice in choices: - if admin and poll.dated_choices: - choice.name = choice.date - choice.form = Form(instance=choice) - response_dct['choices'] = choices - response_dct['form_new_choice'] = form - return render_to_response(tpl, response_dct) - -def poll(request, poll_url): - """Display a poll - poll_url is given to identify the poll. If '_' is in the poll_url the second - part of the url is the unix time given to highlight a particular vote - modification - """ - - def modifyVote(request, choices): - "Modify user's votes" - try: - voter = Voter.objects.filter( - id=int(request.POST['voter']))[0] - except (ValueError, IndexError): - return - # if no author_name is given deletion of associated votes and - # author - if not request.POST['author_name']: - # verify if the author can be deleted - delete_user = None - if not voter.user.password: - v = Voter.objects.filter(user=voter.user) - if len(v) == 1 and v[0] == voter: - delete_user = voter.user - for choice in choices: - v = Vote.objects.filter(voter=voter, choice=choice) - v.delete() - voter.delete() - if delete_user: - delete_user.delete() - return - # update the name - voter.user.name = request.POST['author_name'] - voter.user.save() - # update the modification date - voter.save() - selected_choices = [] - # set the selected choices - for key in request.POST: - # modify a one choice poll - if key == 'vote' and request.POST[key]: - try: - id = int(request.POST[key]) - vote = Vote.objects.filter(id=id)[0] - if vote.choice not in choices: - # bad vote id : the associated choice has - # probably been deleted - vote.delete() - else: - vote.value = 1 - vote.save() - selected_choices.append(vote.choice) - except (ValueError, IndexError): - # the vote don't exist anymore - pass - # modify an existing vote - if key.startswith('vote_') and request.POST[key]: - try: - id = int(key.split('_')[1]) - vote = Vote.objects.filter(id=id)[0] - if vote.choice not in choices: - # bad vote id : the associated choice has - # probably been deleted - vote.delete() - else: - # try if a specific value is specified in the form - # like in balanced poll - try: - value = int(request.POST[key]) - except ValueError: - value = 1 - vote.value = value - vote.save() - selected_choices.append(vote.choice) - except (ValueError, IndexError): - # the vote don't exist anymore - pass - # update non selected choices - for choice in choices: - if choice not in selected_choices: - try: - v = Vote.objects.filter(voter=voter, choice=choice)[0] - v.value = 0 - except IndexError: - # the vote don't exist with this choice : probably - # a new choice - v = Vote(voter=voter, choice=choice, value=0) - v.save() - def newComment(request, poll): - "Comment the poll" - if 'comment_author' not in request.POST \ - or not request.POST['comment_author'] \ - or not request.POST['comment']: - return - c = Comment(poll=poll, author_name=request.POST['comment_author'], - text=request.POST['comment']) - c.save() - - def newVote(request, choices): - "Create new votes" - if not request.POST['author_name']: - return - author = PollUser(name=request.POST['author_name']) - author.save() - voter = Voter(user=author, poll=poll) - voter.save() - selected_choices = [] - - # set the selected choices - for key in request.POST: - # standard vote - if key.startswith('choice_') and request.POST[key]: - try: - id = int(key.split('_')[1]) - choice = Choice.objects.filter(id=id)[0] - if choice not in choices: - raise ValueError - # try if a specific value is specified in the form - # like in balanced poll - try: - value = int(request.POST[key]) - except ValueError: - value = 1 - v = Vote(voter=voter, choice=choice, value=value) - v.save() - selected_choices.append(choice) - except (ValueError, IndexError): - # bad choice id : the choice has probably been deleted - pass - # one choice vote - if key == 'choice' and request.POST[key]: - try: - id = int(request.POST[key]) - choice = Choice.objects.filter(id=id)[0] - if choice not in choices: - raise ValueError - v = Vote(voter=voter, choice=choice, value=1) - v.save() - selected_choices.append(choice) - except (ValueError, IndexError): - # bad choice id : the choice has probably been deleted - pass - # set non selected choices - for choice in choices: - if choice not in selected_choices: - v = Vote(voter=voter, choice=choice, value=0) - v.save() - # results can now be displayed - request.session['knowned_vote_' + poll.base_url] = 1 - response_dct, redirect = getBaseResponse(request) - if redirect: - return redirect - highlight_vote_date = None - if '_' in poll_url: - url_spl = poll_url.split('_') - if len(url_spl) == 2: - poll_url, highlight_vote_date = url_spl - try: - highlight_vote_date = int(highlight_vote_date) - except ValueError: - highlight_vote_date = None - try: - poll = Poll.objects.filter(base_url=poll_url)[0] - except IndexError: - poll = None - choices = list(Choice.objects.filter(poll=poll)) - # if the poll don't exist or if it has no choices the user is - # redirected to the main page - if not choices or not poll: - url = "/".join(request.path.split('/')[:-3]) - url += "/?bad_poll=1" - return HttpResponseRedirect(url) - - # a vote is submitted - if 'author_name' in request.POST and poll.open: - if 'voter' in request.POST: - # modification of an old vote - modifyVote(request, choices) - else: - newVote(request, choices) - # update the modification date of the poll - poll.save() - if 'comment' in request.POST and poll.open: - # comment posted - newComment(request, poll) - - # 'voter' is in request.GET when the edit button is pushed - if 'voter' in request.GET and poll.open: - try: - response_dct['current_voter_id'] = int(request.GET['voter']) - except ValueError: - pass - - response_dct.update({'poll':poll, - 'VOTE':Vote.VOTE,}) - response_dct['base_url'] = "/".join(request.path.split('/')[:-2]) \ - + '/%s/' % poll.base_url - - # get voters and sum for each choice for this poll - voters = Voter.objects.filter(poll=poll) - choice_ids = [choice.id for choice in choices] - for voter in voters: - # highlight a voter - if time.mktime(voter.modification_date.timetuple()) \ - == highlight_vote_date: - voter.highlight = True - voter.votes = voter.getVotes(choice_ids) - # initialize undefined vote - choice_vote_ids = [vote.choice.id for vote in voter.votes] - for choice in choices: - if choice.id not in choice_vote_ids: - vote = Vote(voter=voter, choice=choice, value=None) - vote.save() - idx = choices.index(choice) - voter.votes.insert(idx, vote) - sums = [choice.getSum(poll.type == 'B') for choice in choices] - vote_max = max(sums) - c_idx = 0 - while c_idx < len(choices): - try: - c_idx = sums.index(vote_max, c_idx) - choices[c_idx].highlight = True - c_idx += 1 - except ValueError: - c_idx = len(choices) - # set non-available choices if the limit is reached for a choice - response_dct['limit_set'] = None - for choice in choices: - if choice.limit: - response_dct['limit_set'] = True - if choice.limit and sums[choices.index(choice)] >= choice.limit: - choice.available = False - else: - choice.available = True - choice.save() - response_dct['voters'] = voters - response_dct['choices'] = choices - response_dct['comments'] = Comment.objects.filter(poll=poll) - # verify if vote's result has to be displayed - response_dct['hide_vote'] = poll.hide_choices - if poll.hide_choices: - if u'display_result' in request.GET: - request.session['knowned_vote_' + poll.base_url] = 1 - if 'knowned_vote_' + poll.base_url in request.session: - response_dct['hide_vote'] = False - response_dct['form_comment'] = CommentForm() - return render_to_response('vote.html', response_dct) |
