from django.conf import settings from django.contrib import messages from django.contrib.auth.decorators import login_required from django.core.exceptions import ObjectDoesNotExist from django.core.urlresolvers import reverse from django.forms.models import inlineformset_factory, BaseInlineFormSet from django.shortcuts import get_object_or_404, render, HttpResponseRedirect, HttpResponse from django.template import RequestContext from django.utils.translation import ugettext_lazy as _ from .forms import UserProfileForm, PollForm, ChoiceForm, VoteForm, BulletinForm from .models import Poll, Choice, Vote, Bulletin from datetime import timedelta 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) def new(request): if request.method == 'POST': form = PollForm(request.POST) if form.is_valid(): poll = Poll(**form.cleaned_data) if request.user.is_authenticated(): poll.user = request.user poll.save() key = 'is_' + poll.id + '_author' request.session[key] = True # This writes cookie return HttpResponseRedirect(reverse('choices', args=(str(poll.id),))) else: form = PollForm() if request.user.is_anonymous(): request.session.clear() messages.warning(request, _('You are not logged so you will not \ be able to modify your poll after creation or recieve notifications.')) return render(request, 'meetingpoll/poll_form.html', {'form': form}) def get_formset(form, formset=BaseInlineFormSet, **kwargs): return inlineformset_factory(Poll, Choice, form, formset, **kwargs) def editchoices(request, poll_id): poll = get_object_or_404(Poll.objects.all(), id=poll_id) 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')) choiceFormset = get_formset(ChoiceForm, extra=1, can_delete=True) if request.method == "POST": formset = choiceFormset(request.POST, instance=poll) if formset.is_valid(): formset.save() if not '_addanother' in request.POST: voter = get_voter_name(request) if not voter: voter = 'Anonymous' if not Bulletin.objects.filter(poll=poll.id, voter=voter): bulletin = Bulletin(poll=poll, voter=voter) bulletin.save() votes = [Vote(bulletin=bulletin, choice=choice, voice=True) for choice in Choice.objects.filter(poll=poll.id)] for v in votes: v.save() if request.user.is_anonymous(): # Anonymous has voted... key = 'has_voted-' + poll.id request.session[key] = True # This writes cookie request.session['name'] = voter # This writes cookie poll.save() return HttpResponseRedirect(reverse('meetingpoll', args=(str(poll.id),))) else: messages.error(request, _("There are some errors in the form you posted.")) if Choice.objects.filter(poll=poll_id).count() == 0: choiceFormset = get_formset(ChoiceForm, extra=1, can_delete=True) formset = choiceFormset(instance=poll) else: last_choice = poll.choice_set.all().latest('choice').choice proposal = last_choice + timedelta(days=1) formset = choiceFormset(instance=poll, initial=[{'choice': proposal}]) return render(request, 'meetingpoll/choice_form.html', {'object': poll, 'formset': formset}) @login_required def delete(request, poll_id): poll = get_object_or_404(Poll.objects.all(), id=poll_id) if poll.user == request.user: poll.delete() return HttpResponseRedirect('/') def make_buletin_form(poll, **kwargs): return [[VoteForm(prefix=choice)] for choice in Choice.objects.filter(poll=poll.id)] def get_voter_name(request, form=None): if request.user.is_authenticated(): return str(request.user) else: if form: return form.cleaned_data['voter'] if request.session.get('name'): return request.session.get('name') def vote(request, poll_id): poll = get_object_or_404(Poll.objects.all(), id=poll_id) has_voted, is_updated = False, False if request.method == 'POST': 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)] if form.is_valid(): if request.POST.get('trap', False): return render( request, 'meetingpoll/poll_detail.html', {'object': poll, 'form': form, 'vforms': vforms, 'has_voted': has_voted}) voter = get_voter_name(request, form) for forms in vforms: for vorm in forms: if vorm.is_valid(): comment = vorm.cleaned_data['comment'] if 'http' in comment or 'href' in comment: messages.error(request, _('Sorry no link is allowed in comments.')) return render(request, 'meetingpoll/poll_detail.html', {'object': poll, 'form': form, 'vforms':vforms, 'has_voted': has_voted}) if len(Bulletin.objects.filter(poll=poll.id)) > 100: messages.error(request, _('Sorry this poll reached the maximum of participants')) return render(request, 'meetingpoll/poll_detail.html', {'object': poll, 'form': form, 'vforms':vforms, 'has_voted': has_voted}) if not voter or voter == 'your name': messages.error(request, _('Did you forget to provide your name?')) form = BulletinForm(instance=poll, initial={'voter': voter}) return render(request, 'meetingpoll/poll_detail.html', {'object': poll, 'form': form, 'vforms':vforms, 'has_voted': has_voted}) if not Bulletin.objects.filter(poll=poll.id, voter=voter): bulletin = Bulletin(poll=poll, voter=voter) bulletin.save() else: bulletin = Bulletin.objects.get(poll=poll.id, voter=voter) for forms in vforms: for vorm in forms: if vorm.is_valid(): try: choice = Choice.objects.get(choice=vorm.cleaned_data['choice'], poll=poll) except: continue if not Vote.objects.filter(choice=choice, bulletin=bulletin): new = Vote(choice=choice, bulletin=bulletin, comment=vorm.cleaned_data['comment']) if vorm.cleaned_data['voice']: new.voice = True else: new.voice = False new.save() if new.voice: choice.votecount += 1 choice.save() if request.user.is_anonymous(): # Anonymous has voted... key = 'has_voted-' + poll.id request.session[key] = True # This writes cookie request.session['name'] = voter # This writes cookie has_voted = True # Used to show "Forget me" else: old = Vote.objects.get(choice=choice, bulletin=bulletin) 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() is_updated = True if has_voted and poll.user: try: if poll.user.userprofile.email_notifications: email_notify(poll, voter) except: pass if has_voted or is_updated: messages.success(request, _("Your vote has been counted, thank you.")) poll.save() return HttpResponseRedirect(reverse('vote', args=(poll_id,))) else: messages.error(request, _('Did you forget to provide your name?')) voter = _('your name') 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 vforms = [ [ VoteForm(initial={'choice': choice,}, prefix=choice) ] for choice in Choice.objects.filter(poll=poll_id) ] if request.user.is_authenticated(): voter = str(request.user) try: bulletin = Bulletin.objects.get(poll=poll,voter=voter) messages.info(request, _("You have voted.")) 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. """ 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') ] except: pass else: 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.")) key = 'has_voted-' + poll.id if request.session.get(key, False): #error_message = 'Modify your vote? (clear cookie if you are not ' + voter + ')' try: bulletin = Bulletin.objects.get(poll=poll, voter=voter) messages.success(request, _('%s has voted and can still modify its vote.') % voter) messages.info(request, _('Not %s? Click Forget me.') % voter) 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. """ 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') ] except: pass else: if voter: messages.info(request, _('Not %s? Click Forget me.') % voter) form = BulletinForm(instance=poll, initial={'voter': voter}) return render(request, 'meetingpoll/poll_detail.html', {'object': poll, 'form': form, 'vforms':vforms, 'has_voted': has_voted}) def exp_csv(request, poll_id): import csv # Create the HttpResponse object with the appropriate CSV header. response = HttpResponse(mimetype='text/csv') response['Content-Disposition'] = 'attachment; filename=nuages.csv' poll = get_object_or_404(Poll.objects.all(), id=poll_id) choices = Choice.objects.filter(poll=poll) bulletins = Bulletin.objects.filter(poll=poll) writer = csv.writer(response, quotechar='"', quoting=csv.QUOTE_ALL) fr = ["",] for c in choices: fr.append(c) 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 @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}) def clear_cookie(request, poll_id): request.session.clear() return HttpResponseRedirect(reverse('vote', args=(poll_id,)))