123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- from copy import deepcopy
- from rest_framework.response import Response
- from django.core.exceptions import ValidationError
- from django.utils import six
- from django.utils.translation import gettext as _
- from django.utils.translation import ungettext
- from misago.acl import add_acl
- from misago.threads.permissions import allow_vote_poll
- from misago.threads.serializers import PollSerializer
- def poll_vote_create(request, thread, poll):
- poll.make_choices_votes_aware(request.user)
- allow_vote_poll(request.user, poll)
- try:
- clean_votes = validate_votes(poll, request.data)
- except ValidationError as e:
- return Response({'detail': six.text_type(e)}, status=400)
- remove_user_votes(request.user, poll, clean_votes)
- set_new_votes(request, poll, clean_votes)
- add_acl(request.user, poll)
- serialized_poll = PollSerializer(poll).data
- poll.choices = list(map(presave_clean_choice, deepcopy(poll.choices)))
- poll.save()
- return Response(serialized_poll)
- def presave_clean_choice(choice):
- del choice['selected']
- return choice
- def validate_votes(poll, votes):
- try:
- votes_len = len(votes)
- if votes_len > poll.allowed_choices:
- message = ungettext(
- "This poll disallows voting for more than %(choices)s choice.",
- "This poll disallows voting for more than %(choices)s choices.",
- poll.allowed_choices,
- )
- raise ValidationError(message % {'choices': poll.allowed_choices})
- except TypeError:
- raise ValidationError(_("One or more of poll choices were invalid."))
- valid_choices = [c['hash'] for c in poll.choices]
- clean_votes = []
- for vote in votes:
- if vote in valid_choices:
- clean_votes.append(vote)
- if len(clean_votes) != len(votes):
- raise ValidationError(_("One or more of poll choices were invalid."))
- if not len(votes):
- raise ValidationError(_("You have to make a choice."))
- return clean_votes
- def remove_user_votes(user, poll, final_votes):
- removed_votes = []
- for choice in poll.choices:
- if choice['selected'] and choice['hash'] not in final_votes:
- poll.votes -= 1
- choice['votes'] -= 1
- choice['selected'] = False
- removed_votes.append(choice['hash'])
- if removed_votes:
- poll.pollvote_set.filter(voter=user, choice_hash__in=removed_votes).delete()
- def set_new_votes(request, poll, final_votes):
- for choice in poll.choices:
- if not choice['selected'] and choice['hash'] in final_votes:
- poll.votes += 1
- choice['votes'] += 1
- choice['selected'] = True
- poll.pollvote_set.create(
- category=poll.category,
- thread=poll.thread,
- voter=request.user,
- voter_name=request.user.username,
- voter_slug=request.user.slug,
- choice_hash=choice['hash'],
- voter_ip=request.user_ip,
- )
|