views.py 11.7 KB
Newer Older
Christophe Siraut's avatar
Christophe Siraut committed
1
from django.conf import settings
2 3 4
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.core.exceptions import ObjectDoesNotExist
chris's avatar
chris committed
5 6
from django.core.urlresolvers import reverse
from django.forms.models import inlineformset_factory, BaseInlineFormSet
Christophe Siraut's avatar
Christophe Siraut committed
7
from django.shortcuts import get_object_or_404, render, HttpResponseRedirect
8
from django.template import RequestContext
9
from django.utils.translation import ugettext_lazy as _
Christophe Siraut's avatar
Christophe Siraut committed
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
from .forms import UserProfileForm, PollForm, ChoiceForm, VoteForm, BulletinForm
from .models import Poll, Choice, Vote, Bulletin


def email_notify(poll, voter):
    """Send email notification"""
    subject = _("Nuages email notification")
    message = _("User %s has voted.") % voter
    message += "\n\n"
    message += _("The link to your poll: %s") % poll.link
    message += "\n\n"
    message += _("Current results:")
    message += "\n\n"
    for choice in poll.choice_set.all():
        message += "%s: %i\n" % (choice.choice, choice.votecount)
    poll.user.email_user(subject, message, settings.DEFAULT_FROM_EMAIL)
chris's avatar
chris committed
26

27

chris's avatar
chris committed
28
def new(request):
Christophe Siraut's avatar
Christophe Siraut committed
29
    if request.method == 'POST':
30
        form = PollForm(request.POST)
Christophe Siraut's avatar
Christophe Siraut committed
31
        if form.is_valid():
32 33 34 35 36
            poll = Poll(**form.cleaned_data)
            if request.user.is_authenticated():
                poll.user = request.user
            poll.save()
            key = 'is_' + poll.id + '_author'
37 38 39
            request.session[key] = True  # This writes cookie
            return HttpResponseRedirect(reverse('choices',
                                                args=(str(poll.id),)))
chris's avatar
chris committed
40
    else:
41
        form = PollForm()
42
        if request.user.is_anonymous():
43
            request.session.clear()
44 45
            messages.warning(request, _('You are not logged so you will not \
be able to modify your poll after creation or recieve notifications.'))
Christophe Siraut's avatar
Christophe Siraut committed
46 47 48
    return render(request,
                  'meetingpoll/poll_form.html',
                  {'form': form})
49

chris's avatar
chris committed
50

Christophe Siraut's avatar
Christophe Siraut committed
51
def get_formset(form, formset=BaseInlineFormSet, **kwargs):
chris's avatar
chris committed
52 53
    return inlineformset_factory(Poll, Choice, form, formset, **kwargs)

54

chris's avatar
chris committed
55 56
def editchoices(request, poll_id):

Christophe Siraut's avatar
Christophe Siraut committed
57
    poll = get_object_or_404(Poll.objects.all(), id=poll_id)
58 59 60
    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'))
chris's avatar
chris committed
61

Christophe Siraut's avatar
Christophe Siraut committed
62
    choiceFormset = get_formset(ChoiceForm, extra=1, can_delete=True)
chris's avatar
chris committed
63 64

    if request.method == "POST":
Christophe Siraut's avatar
Christophe Siraut committed
65 66 67 68 69
        formset = choiceFormset(request.POST, instance=poll)
        if formset.is_valid():
            formset.save()
            if not '_addanother' in request.POST:
                return HttpResponseRedirect(poll.link)
chris's avatar
chris committed
70
        else:
Christophe Siraut's avatar
Christophe Siraut committed
71 72
            messages.error(request,
                           _("There are some errors in the form you posted."))
73

Christophe Siraut's avatar
Christophe Siraut committed
74 75 76
    if Choice.objects.filter(poll=poll_id).count() == 0:
        choiceFormset = get_formset(ChoiceForm, extra=2, can_delete=True)
    formset = choiceFormset(instance=poll)
77

Christophe Siraut's avatar
Christophe Siraut committed
78 79 80
    return render(request,
                  'meetingpoll/choice_form.html',
                  {'object': poll, 'formset': formset})
81

chris's avatar
chris committed
82

83 84 85
@login_required
def delete(request, poll_id):

Christophe Siraut's avatar
Christophe Siraut committed
86
    poll = get_object_or_404(Poll.objects.all(), id=poll_id)
87

88
    if poll.user == request.user:
89 90 91 92 93
        poll.delete()

    return HttpResponseRedirect('/')


chris's avatar
chris committed
94
def make_buletin_form(poll, **kwargs):
95
    return [[VoteForm(prefix=choice)] for choice in Choice.objects.filter(poll=poll.id)]
chris's avatar
chris committed
96 97 98


def vote(request, poll_id):
Christophe Siraut's avatar
Christophe Siraut committed
99
    poll = get_object_or_404(Poll.objects.all(), id=poll_id)
100
    has_voted, is_updated = False, False
chris's avatar
chris committed
101 102

    if request.method == 'POST':
103 104
        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)]
chris's avatar
chris committed
105

106
        if form.is_valid():
chris's avatar
chris committed
107 108 109 110 111 112 113 114
            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
Christophe Siraut committed
115 116
                if not Bulletin.objects.filter(poll=poll.id, voter=voter):
                    bulletin = Bulletin(poll=poll, voter=voter)
chris's avatar
chris committed
117 118
                    bulletin.save()
                else:
Christophe Siraut's avatar
Christophe Siraut committed
119
                    bulletin = Bulletin.objects.get(poll=poll.id, voter=voter)
chris's avatar
chris committed
120 121 122 123 124

                for forms in vforms:
                    for vorm in forms:
                        if vorm.is_valid():
                            try:
Christophe Siraut's avatar
Christophe Siraut committed
125
                                choice = Choice.objects.get(choice=vorm.cleaned_data['choice'], poll=poll)
chris's avatar
chris committed
126
                            except:
Christophe Siraut's avatar
Christophe Siraut committed
127
                                return render(request, vorm.cleaned_data['choice'])
chris's avatar
chris committed
128

Christophe Siraut's avatar
Christophe Siraut committed
129 130
                            if not Vote.objects.filter(choice=choice, bulletin=bulletin):
                                new = Vote(choice=choice, bulletin=bulletin, comment=vorm.cleaned_data['comment'])
chris's avatar
chris committed
131 132
                                if vorm.cleaned_data['voice']:
                                    new.voice = vorm.cleaned_data['voice']
chris's avatar
chris committed
133 134 135 136
                                new.save()
                                if new.voice:
                                    choice.votecount += 1
                                    choice.save()
137
                                if request.user.is_anonymous():  # Anonymous has voted...
chris's avatar
chris committed
138
                                    key = 'has_voted-' + poll.id
139 140
                                    request.session[key] = True  # This writes cookie
                                    request.session['name'] = voter  # This writes cookie
141
                                    has_voted = True  # Used to show "Forget me"
chris's avatar
chris committed
142
                            else:
Christophe Siraut's avatar
Christophe Siraut committed
143
                                old = Vote.objects.get(choice=choice, bulletin=bulletin)
chris's avatar
chris committed
144 145 146 147 148 149 150 151 152 153 154 155 156

                                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()
157 158
                                is_updated = True
                if has_voted:
159
                    messages.success(request, _("Your vote has been counted, thank you."))
160
                if is_updated:
161
                    messages.success(request, _("Your vote has been updated, thank you."))
162 163 164 165 166 167
                if has_voted and poll.user:
                    try:
                        if poll.user.userprofile.email_notifications:
                            email_notify(poll, voter)
                    except:
                        pass
chris's avatar
chris committed
168
            else:
169
                messages.error(request, _('Did you forget to provide your name?'))
chris's avatar
chris committed
170
        else:
171
            messages.error(request, _('Did you forget to provide your name?'))
172
            voter = _('your name')
chris's avatar
chris committed
173 174 175 176 177 178 179 180 181

    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
182
            vforms = [ [ VoteForm(initial={'choice': choice,}, prefix=choice) ] for choice in Choice.objects.filter(poll=poll_id) ]
chris's avatar
chris committed
183 184 185 186
        if request.user.is_authenticated():
            voter = str(request.user)
            try:
                bulletin = Bulletin.objects.get(poll=poll,voter=voter)
187
                messages.info(request, _("You have voted."))
chris's avatar
chris committed
188 189 190 191 192 193 194
                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
Christophe Siraut committed
195
                    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') ]
chris's avatar
chris committed
196 197 198 199

            except:
                pass
        else:
200 201 202 203 204
            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."))
chris's avatar
chris committed
205 206 207 208
            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
Christophe Siraut committed
209
                    bulletin = Bulletin.objects.get(poll=poll, voter=voter)
210 211
                    messages.success(request, _('%s has voted and can still modify its vote.') % voter)
                    messages.info(request, _('Not %s? Click Forget me.') % voter)
chris's avatar
chris committed
212 213 214 215 216 217 218
                    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.
                        """
219
                        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') ]
chris's avatar
chris committed
220 221 222

                except:
                    pass
223 224 225
            else:
                if voter:
                    messages.info(request, _('Not %s? Click Forget me.') % voter)
chris's avatar
chris committed
226

227
    form = BulletinForm(instance=poll, initial={'voter': voter})
Christophe Siraut's avatar
Christophe Siraut committed
228 229 230
    return render(request,
                  'meetingpoll/poll_detail.html',
                  {'object': poll, 'form': form, 'vforms':vforms, 'has_voted': has_voted})
231

chris's avatar
chris committed
232

233
def exp_csv(request, poll_id):
chris's avatar
chris committed
234 235 236 237 238 239
    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
Christophe Siraut committed
240
    poll = get_object_or_404(Poll.objects.all(), id=poll_id)
241 242
    choices = Choice.objects.filter(poll=poll)
    bulletins = Bulletin.objects.filter(poll=poll)
chris's avatar
chris committed
243 244 245
    writer = csv.writer(response, quotechar='"', quoting=csv.QUOTE_ALL)
    fr = ["",]
    for c in choices:
Christophe Siraut's avatar
Christophe Siraut committed
246
        fr.append(c)
chris's avatar
chris committed
247 248 249 250 251 252 253
    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
254

Christophe Siraut's avatar
Christophe Siraut committed
255 256 257 258 259 260 261 262 263 264 265 266 267 268
@login_required
def profile(request):
    """profile view"""
    if request.method == 'POST':
        form = UserProfileForm(request.POST)
        if form.is_valid():
            for k, v in form.cleaned_data.iteritems():
                setattr(request.user.userprofile, k, v)
            request.user.userprofile.save()
            return HttpResponseRedirect(reverse('home'))
    form = UserProfileForm(instance=request.user.userprofile)
    return render(request, "form.html", {'form': form})


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