summaryrefslogtreecommitdiff
path: root/polls
diff options
context:
space:
mode:
Diffstat (limited to 'polls')
-rw-r--r--polls/__init__.py0
-rw-r--r--polls/admin.py34
-rw-r--r--polls/feeds.py55
-rw-r--r--polls/forms.py132
-rw-r--r--polls/models.py227
-rw-r--r--polls/templatetags/__init__.py0
-rw-r--r--polls/templatetags/get_range.py25
-rw-r--r--polls/views.py491
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)