views.py 12.6 KB
Newer Older
1 2 3
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.core.exceptions import ObjectDoesNotExist
christophe siraut's avatar
christophe siraut committed
4 5
from django.core.urlresolvers import reverse
from django.forms.models import inlineformset_factory, BaseInlineFormSet
6
from django.http import HttpResponse, HttpResponseRedirect
7
from django.shortcuts import get_object_or_404, render_to_response
8
from django.template import RequestContext
9
from django.utils.translation import ugettext_lazy as _
10 11 12
from account.views import email_notify
from meetingpoll.forms import PollForm, ChoiceForm, VoteForm, BulletinForm
from meetingpoll.models import Poll, Choice, Vote, Bulletin
christophe siraut's avatar
christophe siraut committed
13

14

christophe siraut's avatar
christophe siraut committed
15
def new(request):
Christophe Siraut's avatar
Cleanup  
Christophe Siraut committed
16
    if request.method == 'POST':
17
        form = PollForm(request.POST)
Christophe Siraut's avatar
Cleanup  
Christophe Siraut committed
18
        if form.is_valid():
19 20 21 22 23
            poll = Poll(**form.cleaned_data)
            if request.user.is_authenticated():
                poll.user = request.user
            poll.save()
            key = 'is_' + poll.id + '_author'
24 25 26
            request.session[key] = True  # This writes cookie
            return HttpResponseRedirect(reverse('choices',
                                                args=(str(poll.id),)))
christophe siraut's avatar
christophe siraut committed
27
    else:
28
        form = PollForm()
29
        if request.user.is_anonymous():
30
            request.session.clear()
31 32 33 34 35 36
            messages.warning(request, _('You are not logged so you will not \
be able to modify your poll after creation or recieve notifications.'))
    return render_to_response('meetingpoll/poll_form.html',
                              {'form': form},
                              context_instance=RequestContext(request))

christophe siraut's avatar
christophe siraut committed
37 38 39 40

def get_ordereditem_formset(form, formset=BaseInlineFormSet, **kwargs):
    return inlineformset_factory(Poll, Choice, form, formset, **kwargs)

41

christophe siraut's avatar
christophe siraut committed
42 43
def editchoices(request, poll_id):

Christophe Siraut's avatar
Cleanup  
Christophe Siraut committed
44
    poll = get_object_or_404(Poll.objects.all(), id=poll_id)
christophe siraut's avatar
christophe siraut committed
45
    language_code = request.LANGUAGE_CODE
46 47 48
    key = 'is_' + poll_id + '_author'  # Anonymous wants to edit his new poll?
    if request.user != poll.user and not request.session.get(key, False):
        return HttpResponseRedirect(reverse('home'))
christophe siraut's avatar
christophe siraut committed
49

50 51
    OrderedItemFormset = get_ordereditem_formset(ChoiceForm,
                                                 extra=0, can_delete=True)
christophe siraut's avatar
christophe siraut committed
52 53

    if request.method == "POST":
54
        #Should we set a maximum of choices here?
christophe siraut's avatar
christophe siraut committed
55 56 57
        instances = OrderedItemFormset(request.POST, instance=poll)
        if instances.is_valid():
            for instance in instances.cleaned_data:
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
                this_choice = instance['choice']
                if not instance.get('DELETE'):
                    try:
                        choice = Choice.objects.get(poll=poll, choice=instance['choice'])
                        choice.details = instance['details']
                        choice.save()
                    except ObjectDoesNotExist:
                        choice = Choice(poll=poll, choice=instance['choice'], details=instance['details'])
                        choice.save()
                        # If bulletins for this poll existed before edition
                        # add an 'false' vote child to them for newly created choice.
                        # This makes template computation easier
                        for bulletin in Bulletin.objects.filter(poll=poll):
                            nvote = Vote(choice=choice, bulletin=bulletin, voice=False)
                            nvote.save()
                else:
                    try:
                        choice = Choice.objects.get(poll=poll, choice=this_choice)
                        choice.delete()  #Removing a Choice will remove all childeren Vote objects.
                    except :
                        pass
79
            return HttpResponseRedirect(poll.link)
christophe siraut's avatar
christophe siraut committed
80
        else:
81
            messages.error(request, _("There are some errors in the form you posted."))
Christophe Siraut's avatar
Cleanup  
Christophe Siraut committed
82
            vforms = instances
83

christophe siraut's avatar
christophe siraut committed
84
    else:
85 86
        if Choice.objects.filter(poll=poll_id).count() == 0:
            # Sall we replace next line with something like OrderedItemFormset(extra=2)
87 88
            OrderedItemFormset = get_ordereditem_formset(
                ChoiceForm, extra=1, can_delete=True)
89
            vforms = OrderedItemFormset(instance=poll)
90 91 92
        else:
            vforms = OrderedItemFormset(instance=poll)

93
    return render_to_response('meetingpoll/choice_form.html',
94 95 96 97
                              {'object': poll,
                               'vforms': vforms,
                               'language_code': language_code},
                              context_instance=RequestContext(request))
98

christophe siraut's avatar
christophe siraut committed
99

100 101 102
@login_required
def delete(request, poll_id):

Christophe Siraut's avatar
Cleanup  
Christophe Siraut committed
103
    poll = get_object_or_404(Poll.objects.all(), id=poll_id)
104

105
    if poll.user == request.user:
106 107 108 109 110
        poll.delete()

    return HttpResponseRedirect('/')


christophe siraut's avatar
christophe siraut committed
111
def make_buletin_form(poll, **kwargs):
112
    return [[VoteForm(prefix=choice)] for choice in Choice.objects.filter(poll=poll.id)]
christophe siraut's avatar
christophe siraut committed
113 114 115


def vote(request, poll_id):
Christophe Siraut's avatar
Cleanup  
Christophe Siraut committed
116
    poll = get_object_or_404(Poll.objects.all(), id=poll_id)
117
    has_voted, is_updated = False, False
christophe siraut's avatar
christophe siraut committed
118 119

    if request.method == 'POST':
120 121
        form = BulletinForm(request.POST, initial={'poll': poll.id})
        vforms = [[VoteForm(request.POST, prefix=choice, instance=choice) ] for choice in Choice.objects.filter(poll=poll.id)]
christophe siraut's avatar
christophe siraut committed
122

123
        if form.is_valid():
christophe siraut's avatar
christophe siraut committed
124 125 126 127 128 129 130 131
            if request.user.is_authenticated():
                voter = str(request.user)
            else:
                voter = form.cleaned_data['voter']
                if request.session.get('name'):
                    voter = request.session.get('name')

            if voter != 'your name':
Christophe Siraut's avatar
Cleanup  
Christophe Siraut committed
132 133
                if not Bulletin.objects.filter(poll=poll.id, voter=voter):
                    bulletin = Bulletin(poll=poll, voter=voter)
christophe siraut's avatar
christophe siraut committed
134 135
                    bulletin.save()
                else:
Christophe Siraut's avatar
Cleanup  
Christophe Siraut committed
136
                    bulletin = Bulletin.objects.get(poll=poll.id, voter=voter)
christophe siraut's avatar
christophe siraut committed
137 138 139 140 141

                for forms in vforms:
                    for vorm in forms:
                        if vorm.is_valid():
                            try:
Christophe Siraut's avatar
Cleanup  
Christophe Siraut committed
142
                                choice = Choice.objects.get(choice=vorm.cleaned_data['choice'], poll=poll)
christophe siraut's avatar
christophe siraut committed
143
                            except:
144
                                return HttpResponse(vorm.cleaned_data['choice'])
christophe siraut's avatar
christophe siraut committed
145

Christophe Siraut's avatar
Cleanup  
Christophe Siraut committed
146 147
                            if not Vote.objects.filter(choice=choice, bulletin=bulletin):
                                new = Vote(choice=choice, bulletin=bulletin, comment=vorm.cleaned_data['comment'])
Christophe Siraut's avatar
Christophe Siraut committed
148 149
                                if vorm.cleaned_data['voice']:
                                    new.voice = vorm.cleaned_data['voice']
christophe siraut's avatar
christophe siraut committed
150 151 152 153
                                new.save()
                                if new.voice:
                                    choice.votecount += 1
                                    choice.save()
154
                                if request.user.is_anonymous():  # Anonymous has voted...
christophe siraut's avatar
christophe siraut committed
155
                                    key = 'has_voted-' + poll.id
156 157
                                    request.session[key] = True  # This writes cookie
                                    request.session['name'] = voter  # This writes cookie
158
                                    has_voted = True  # Used to show "Forget me"
christophe siraut's avatar
christophe siraut committed
159
                            else:
Christophe Siraut's avatar
Cleanup  
Christophe Siraut committed
160
                                old = Vote.objects.get(choice=choice, bulletin=bulletin)
christophe siraut's avatar
christophe siraut committed
161 162 163 164 165 166 167 168 169 170 171 172 173

                                if old.voice:
                                    if not vorm.cleaned_data['voice']:
                                        choice.votecount -= 1
                                        choice.save()
                                else:
                                    if vorm.cleaned_data['voice']:
                                        choice.votecount += 1
                                        choice.save()

                                old.voice = vorm.cleaned_data['voice']
                                old.comment = vorm.cleaned_data['comment']
                                old.save()
174 175
                                is_updated = True
                if has_voted:
176
                    messages.success(request, _("Your vote has been counted, thank you."))
177
                if is_updated:
178
                    messages.success(request, _("Your vote has been updated, thank you."))
179 180 181 182 183 184
                if has_voted and poll.user:
                    try:
                        if poll.user.userprofile.email_notifications:
                            email_notify(poll, voter)
                    except:
                        pass
christophe siraut's avatar
christophe siraut committed
185
            else:
186
                messages.error(request, _('Did you forget to provide your name?'))
christophe siraut's avatar
christophe siraut committed
187
        else:
188
            messages.error(request, _('Did you forget to provide your name?'))
189
            voter = _('your name')
christophe siraut's avatar
christophe siraut committed
190 191 192 193 194 195 196 197 198

    else: # request.method = 'GET'

        key = 'is_' + poll.id + '_author'
        if request.session.get(key, False):
            # Assume author is positive for all choices, when he votes for the first time.
            vforms = [ [ VoteForm(initial={'choice': choice,'voice': True,}, prefix=choice) ] for choice in Choice.objects.filter(poll=poll_id) ]
        else:
            # Default formset for unknown user
199
            vforms = [ [ VoteForm(initial={'choice': choice,}, prefix=choice) ] for choice in Choice.objects.filter(poll=poll_id) ]
christophe siraut's avatar
christophe siraut committed
200 201 202 203
        if request.user.is_authenticated():
            voter = str(request.user)
            try:
                bulletin = Bulletin.objects.get(poll=poll,voter=voter)
204
                messages.info(request, _("You have voted."))
christophe siraut's avatar
christophe siraut committed
205 206 207 208 209 210 211
                diff = len(vforms) - len(Vote.objects.filter(bulletin=bulletin))
                if diff == 0:
                    """
                    Hum, previously bulletin has not the same amount of vote objects,
                    we should concatenate the existing votes with empty remaing ones...
                    Give an empty bulletin for now.
                    """
Christophe Siraut's avatar
Cleanup  
Christophe Siraut committed
212
                    vforms = [ [ VoteForm(initial={'choice': vote.choice,'voice': vote.voice, 'comment': vote.comment}, prefix=vote.choice) ] for vote in Vote.objects.filter(bulletin=bulletin).order_by('choice__choice') ]
christophe siraut's avatar
christophe siraut committed
213 214 215 216

            except:
                pass
        else:
217 218 219 220 221
            voter = request.session.get('name')
            if voter:
                has_voted = True  # Used to show "Forget me"
            else:
                messages.info(request, _("Login let you modify your vote anytime."))
christophe siraut's avatar
christophe siraut committed
222 223 224 225
            key = 'has_voted-' + poll.id
            if request.session.get(key, False):
                #error_message = 'Modify your vote? (clear cookie if you are not ' + voter + ')'
                try:
Christophe Siraut's avatar
Cleanup  
Christophe Siraut committed
226
                    bulletin = Bulletin.objects.get(poll=poll, voter=voter)
227 228
                    messages.success(request, _('%s has voted and can still modify its vote.') % voter)
                    messages.info(request, _('Not %s? Click Forget me.') % voter)
christophe siraut's avatar
christophe siraut committed
229 230 231 232 233 234 235
                    diff = len(vforms) - len(Vote.objects.filter(bulletin=bulletin))
                    if diff == 0:
                        """
                        Hum, previously bulletin has not the same amount of vote objects,
                        we should concatenate the existing votes with empty remaing ones...
                        Give an empty bulletin for now.
                        """
236
                        vforms = [ [ VoteForm(initial={'choice': vote.choice,'voice': vote.voice, 'comment': vote.comment,}, prefix=vote.choice) ] for vote in Vote.objects.filter(bulletin=bulletin).order_by('choice__choice') ]
christophe siraut's avatar
christophe siraut committed
237 238 239

                except:
                    pass
240 241 242
            else:
                if voter:
                    messages.info(request, _('Not %s? Click Forget me.') % voter)
christophe siraut's avatar
christophe siraut committed
243

244 245 246 247 248
    form = BulletinForm(instance=poll, initial={'voter': voter})
    return render_to_response('meetingpoll/poll_detail.html',
                              {'object': poll, 'form': form, 'vforms':vforms, 'has_voted': has_voted},
                              context_instance=RequestContext(request))

christophe siraut's avatar
christophe siraut committed
249

chris's avatar
chris committed
250
def exp_csv(request, poll_id):
Christophe Siraut's avatar
Christophe Siraut committed
251 252 253 254 255 256
    import csv

    # Create the HttpResponse object with the appropriate CSV header.
    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename=nuages.csv'

Christophe Siraut's avatar
Cleanup  
Christophe Siraut committed
257
    poll = get_object_or_404(Poll.objects.all(), id=poll_id)
chris's avatar
chris committed
258 259
    choices = Choice.objects.filter(poll=poll)
    bulletins = Bulletin.objects.filter(poll=poll)
Christophe Siraut's avatar
Christophe Siraut committed
260 261 262
    writer = csv.writer(response, quotechar='"', quoting=csv.QUOTE_ALL)
    fr = ["",]
    for c in choices:
Christophe Siraut's avatar
Cleanup  
Christophe Siraut committed
263
        fr.append(c)
Christophe Siraut's avatar
Christophe Siraut committed
264 265 266 267 268 269 270
    writer.writerow(fr)
    for b in bulletins:
        r = [b.voter.encode("utf-8"),]
        for v in Vote.objects.filter(bulletin=b):
            r.append(v)
        writer.writerow(r)
    return response
271 272 273 274

def clear_cookie(request, poll_id):
    request.session.clear()
    return HttpResponseRedirect(reverse('vote', args=(poll_id,)))