views.py 4.09 KB
Newer Older
1 2 3 4 5
"""
View endpoints for Survey
"""

import json
6
import logging
7

8
from django.conf import settings
9 10
from django.contrib.auth.decorators import login_required
from django.core.urlresolvers import reverse
11
from django.http import HttpResponse, HttpResponseNotFound, HttpResponseRedirect
12
from django.utils.html import escape
13
from django.views.decorators.http import require_POST
14 15
from opaque_keys.edx.keys import CourseKey

16
from edxmako.shortcuts import render_to_response
17
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
18
from survey.models import SurveyForm
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

log = logging.getLogger("edx.survey")


@login_required
def view_survey(request, survey_name):
    """
    View to render the survey to the end user
    """
    redirect_url = request.GET.get('redirect_url')

    return view_student_survey(request.user, survey_name, redirect_url=redirect_url)


def view_student_survey(user, survey_name, course=None, redirect_url=None, is_required=False, skip_redirect_url=None):
    """
    Shared utility method to render a survey form
    NOTE: This method is shared between the Survey and Courseware Djangoapps
    """

    redirect_url = redirect_url if redirect_url else reverse('dashboard')
    dashboard_redirect_url = reverse('dashboard')
    skip_redirect_url = skip_redirect_url if skip_redirect_url else dashboard_redirect_url

    survey = SurveyForm.get(survey_name, throw_if_not_found=False)
    if not survey:
        return HttpResponseRedirect(redirect_url)

    # the result set from get_answers, has an outer key with the user_id
    # just remove that outer key to make the JSON payload simplier
    existing_answers = survey.get_answers(user=user).get(user.id, {})

51
    platform_name = configuration_helpers.get_value('platform_name', settings.PLATFORM_NAME)
52

53 54 55 56 57 58 59 60
    context = {
        'existing_data_json': json.dumps(existing_answers),
        'postback_url': reverse('submit_answers', args=[survey_name]),
        'redirect_url': redirect_url,
        'skip_redirect_url': skip_redirect_url,
        'dashboard_redirect_url': dashboard_redirect_url,
        'survey_form': survey.form,
        'is_required': is_required,
61
        'mail_to_link': configuration_helpers.get_value('email_from_address', settings.CONTACT_EMAIL),
62
        'platform_name': platform_name,
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
        'course': course,
    }

    return render_to_response("survey/survey.html", context)


@require_POST
@login_required
def submit_answers(request, survey_name):
    """
    Form submission post-back endpoint.

    NOTE: We do not have a formal definition of a Survey Form, it's just some authored HTML
    form fields (via Django Admin site). Therefore we do not do any validation of the submission server side. It is
    assumed that all validation is done via JavaScript in the survey.html file
    """
    survey = SurveyForm.get(survey_name, throw_if_not_found=False)

    if not survey:
        return HttpResponseNotFound()

    answers = {}
    for key in request.POST.keys():
        # support multi-SELECT form values, by string concatenating them with a comma separator
        array_val = request.POST.getlist(key)
        answers[key] = request.POST[key] if len(array_val) == 0 else ','.join(array_val)

    # the URL we are supposed to redirect to is
    # in a hidden form field
    redirect_url = answers['_redirect_url'] if '_redirect_url' in answers else reverse('dashboard')

94 95
    course_key = CourseKey.from_string(answers['course_id']) if 'course_id' in answers else None

96 97 98 99 100 101 102 103 104 105
    allowed_field_names = survey.get_field_names()

    # scrub the answers to make sure nothing malicious from the user gets stored in
    # our database, e.g. JavaScript
    filtered_answers = {}
    for answer_key in answers.keys():
        # only allow known input fields
        if answer_key in allowed_field_names:
            filtered_answers[answer_key] = escape(answers[answer_key])

106
    survey.save_user_answers(request.user, filtered_answers, course_key)
107 108 109 110 111 112 113

    response_params = json.dumps({
        # The HTTP end-point for the payment processor.
        "redirect_url": redirect_url,
    })

    return HttpResponse(response_params, content_type="text/json")