150 lines
5.9 KiB
Python
150 lines
5.9 KiB
Python
from anonsurvey.models import Survey, Question, QuestionGroup,\
|
|
OfferedAnswer, Answer
|
|
from django.views import generic
|
|
from django.conf import settings
|
|
from django.shortcuts import get_object_or_404, render_to_response
|
|
from django.core.urlresolvers import reverse
|
|
from django.http import HttpResponseRedirect, HttpResponse
|
|
from django.template import RequestContext
|
|
import re
|
|
from django.utils.translation import ugettext_lazy as _
|
|
import time
|
|
from django.views.decorators.http import require_POST
|
|
from anonsurvey import utils
|
|
|
|
|
|
class SurveysView(generic.ListView):
|
|
template_name = 'anonsurvey/surveys.html'
|
|
context_object_name = 'surveys'
|
|
paginate_by = settings.SURVEYS_PAGE_SIZE
|
|
|
|
def get_queryset(self):
|
|
return Survey.objects.filter(active=True).order_by(
|
|
'mod_datetime')
|
|
|
|
|
|
class SurveyView(generic.DetailView):
|
|
model = Survey
|
|
slug_field = 'name'
|
|
template_name = 'anonsurvey/survey.html'
|
|
|
|
def get_queryset(self):
|
|
survey = super(SurveyView, self).get_queryset()
|
|
return survey.filter(active=True)
|
|
|
|
|
|
def value_matches(pattern, value):
|
|
if not pattern:
|
|
return True
|
|
pattern = '^{}$'.format(pattern)
|
|
return re.match(pattern, value)
|
|
|
|
|
|
@require_POST
|
|
def complete_survey(request, pk):
|
|
survey = get_object_or_404(Survey, pk=pk)
|
|
error_messages = []
|
|
last_post = {}
|
|
if not survey.active:
|
|
error_messages.append(_('Survey is no longer active'))
|
|
questions = []
|
|
else:
|
|
questions = survey.question_set.all()
|
|
# build last_post data dict
|
|
for key in request.POST:
|
|
if key.startswith('q'):
|
|
value = request.POST.getlist(key)
|
|
key = key[1:]
|
|
last_post[key] = value
|
|
# generate unique client_id
|
|
while True:
|
|
client_id = str(time.time())
|
|
existing_answers = Answer.objects.filter(client_id=client_id)
|
|
if not existing_answers:
|
|
break
|
|
time.sleep(0.001)
|
|
# remove ip address from client_id - PRIVACY
|
|
# client_id = '{}@{}'.format(client_id, utils.get_client_ip(request))
|
|
client_answers = []
|
|
# parse, validate and collect answers
|
|
# if survey is inactive questions is empty list (see above)
|
|
for question in questions:
|
|
post_name = 'q{}'.format(question.id)
|
|
if post_name in request.POST:
|
|
post_value = request.POST.getlist(post_name)
|
|
# remove empty strings (can get for inputs)
|
|
for x in post_value:
|
|
if not x:
|
|
post_value.remove(x)
|
|
else:
|
|
post_value = None
|
|
if question.requires_answer and not post_value:
|
|
error_messages.append(_('Question "{}" requires answer').format(
|
|
question.text))
|
|
else:
|
|
if question.question_type in ('R', 'C', 'RI', 'CI'):
|
|
for a_id in post_value:
|
|
spam = get_object_or_404(OfferedAnswer, pk=int(a_id))
|
|
# collect choice answers that are not input for RI and CI
|
|
if ((question.question_type in ('RI', 'CI') and
|
|
spam.answer_type != 'I') or
|
|
(question.question_type in ('R', 'C'))):
|
|
clanswer = Answer()
|
|
clanswer.client_id = client_id
|
|
clanswer.answer = spam
|
|
client_answers.append(clanswer)
|
|
if (question.question_type == 'RI' or
|
|
question.question_type == 'CI'):
|
|
answers = question.offeredanswer_set.filter(answer_type='I')
|
|
alen = len(answers)
|
|
if alen > 1:
|
|
error_messages.append(_('Invalid form'))
|
|
elif alen < 1:
|
|
oanswer = None
|
|
else:
|
|
oanswer = answers[0]
|
|
if oanswer and str(oanswer.id) in post_value:
|
|
# get input value for choice input
|
|
input_name = 'q{}_value'.format(question.id)
|
|
if input_name in request.POST:
|
|
post_value = request.POST[input_name]
|
|
if not post_value:
|
|
oanswer = None
|
|
validate_input_value = False
|
|
else:
|
|
validate_input_value = True
|
|
clanswer = Answer()
|
|
clanswer.client_id = client_id
|
|
clanswer.answer = oanswer
|
|
clanswer.text = post_value
|
|
client_answers.append(clanswer)
|
|
else:
|
|
validate_input_value = False
|
|
elif question.question_type == 'I':
|
|
validate_input_value = True
|
|
oanswer = question.offeredanswer_set.all()[0]
|
|
post_value = post_value[0]
|
|
clanswer = Answer()
|
|
clanswer.client_id = client_id
|
|
clanswer.answer = oanswer
|
|
clanswer.text = post_value
|
|
client_answers.append(clanswer)
|
|
else:
|
|
validate_input_value = False
|
|
if validate_input_value and oanswer:
|
|
pattern = oanswer.validation_format
|
|
if not value_matches(pattern, post_value):
|
|
error_messages.append(
|
|
_('Answer for question "{}" must be in '
|
|
'format "{}"').format(question.text, pattern))
|
|
if error_messages:
|
|
resp_dict = {
|
|
'survey': survey,
|
|
'error_messages': error_messages,
|
|
'last_post': last_post,
|
|
}
|
|
return render_to_response(SurveyView.template_name, resp_dict,
|
|
context_instance=RequestContext(request))
|
|
for clanswer in client_answers:
|
|
clanswer.save()
|
|
return HttpResponseRedirect(reverse('survey_thanks'))
|