Beispiel #1
0
    def wrapper(*args, **kwargs):
        question_slug = kwargs['question_slug']
        the_user = args[0].user

        try:
            the_question = MultipleChoiceQuestion.objects.get(
                slug=question_slug)
        except CustomAppError as e:
            return DefaultErrorPage(e,
                                    "Could not find the question specified.")

        # the current user can only access his questions, not other people's
        if (the_question.linked_survey.author.id != the_user.id):
            return DefaultErrorPage(
                mesg="You do not have permission to view this question.")

        return fn(*args, **kwargs)
Beispiel #2
0
    def wrapper(*args, **kwargs):
        question_slug = kwargs['question_slug']
        the_user = args[0].user

        the_question = MultipleChoiceQuestion.objects.get(slug=question_slug)

        if (Pub_Or_Not == 'Not_Published'):
            if (the_question.linked_survey.publishing_set.count() > 0):
                return DefaultErrorPage(
                    mesg=
                    "This question is already published and cannot be edited.")

        if (Pub_Or_Not == 'Published'):
            if (the_question.linked_survey.publishing_set.count() == 0):
                return DefaultErrorPage(
                    mesg="This question is not published yet.")

        return fn(*args, **kwargs)
Beispiel #3
0
def DeleteQuestion(request, question_slug=''):

    if request.method != "POST":
        return DefaultErrorPage(mesg="Delete does not work with GET.")

    theQuestion = GetQuestionFromSlug(question_slug)
    try:
        DeleteRelatedPublishings(theQuestion)
        linked_survey = theQuestion.linked_survey
        theQuestion.delete()
        linked_survey.delete()

    #need to add transcation/rollback here
    except (DatabaseError, IntegrityError) as e:
        return DefaultErrorPage(
            e, "Could not delete this question due to a database error.")

    return utils.custom_redirect('ShowQuestionsList',
                                 just_deleted_question=True)
Beispiel #4
0
def RespondToQuestion(request,
                      question_slug='',
                      answer_slug='',
                      redirect_url='',
                      **kwargs):

    #see if question is already answered by this IP address

    try:
        theQuestion = GetQuestionFromSlug(question_slug)

    except CustomAppError as e:
        return DefaultErrorPage(e,
                                "Could not find the question you specified.")
    try:
        theAnswer = GetAnswerFromSlug(answer_slug)

    except CustomAppError as e:
        return DefaultErrorPage(e, "Could not find the answer you specified.")

    # turns out blocking by IP is not effective, you could block an entire house
    # as it will use the IP assigned by the ISP
    # instead we will use cookies

    #source_ip_addr = GetIpAddress(request)

    #turn OFF while developing...turn on later

    if settings.COOKIE_BLOCKING == 'True':
        if ThisPersonAlreadyResponded(request, theQuestion):
            return PageForIPAddrAlreadyVoted(theQuestion)

    #if we made it here, the user hasn't already replied. Return success
    #although actually the AJAX call this page makes will actually cause the vote to register
    #had to do that, as Heroku or FB or some non-humans were sending GET to this page
    #and registering votes which distorting the vote

    return PageForUserResponseAccepted(theQuestion, theAnswer, request,
                                       redirect_url)
Beispiel #5
0
def ShowResults(request, question_slug, IsAjax=False):

    template = 'show_question_details.html' if IsAjax == False else 'answer_and_chart_sub_template.html'

    try:
        theQuestion = GetQuestionFromSlug(question_slug)

    except CustomAppError as e:
        return DefaultErrorPage(e,
                                mesg="Could not find the question specified.")

    #get the answer choices and get the vote counts

    theAnswers = theQuestion.multiplechoiceansweritem_set.all()
    vote_tally, total_votes = GetVoteTally(theAnswers)

    is_published = (theQuestion.linked_survey.publishing_set.count() > 0)


    return render_to_response(template, {'question' : theQuestion, 'answers' : theAnswers, 'is_published' : \
                                         is_published,  'is_results_page' : True, 'vote_tally' : json.dumps(vote_tally), 'total_votes': total_votes}, \
                              context_instance=RequestContext(request))
Beispiel #6
0
def AddQuestion(request, **kwargs):

    template = 'edit_question.html'

    theUser = request.user

    #inline formset is a good tool to use to get answers that have a foreign key to a question

    MultipleChoiceAnswerItemFormset = inlineformset_factory(
        MultipleChoiceQuestion,
        MultipleChoiceAnswerItem,
        form=MultipleChoiceAnswerItemModelForm,
        formset=MultipleChoiceAnswerItemModelFormset,
        extra=2,
        can_delete=True)

    #POST means user has submitted the form with new question and answer options

    if request.method == 'POST':

        #prefix helps distinguish forms from each other
        form = MultipleChoiceQuestionModelForm(request.POST, prefix='Question')
        formset = MultipleChoiceAnswerItemFormset(request.POST,
                                                  prefix='Answer')

        if form.is_valid() and formset.is_valid():

            try:
                #create new question but don't commit to DB yet as we have to
                #create the survey object first as the question has a foreign key to the survey object

                new_question = form.save(commit=False)

                #create new survey, for now each question has a survey object. no more than 1 question per survey for now

                new_survey = MultipleChoiceSurvey(
                    create_date=datetime.datetime.now(), author=theUser)
                new_survey.save()

                the_new_id = new_survey.id

                new_question.linked_survey = MultipleChoiceSurvey.objects.get(
                    id=the_new_id)

                new_question.save()

                new_question_in_db = MultipleChoiceQuestion.objects.get(
                    id=new_question.id)

                new_answers = formset.save(commit=False)

                for a in new_answers:
                    a.linked_question = new_question_in_db
                    a.save()

            #To-do: need to actually do a rollback of all changes here upon getting an unlikely DB error
            #should use Django's atomic.transaction probably
            except (DatabaseError, IntegrityError) as e:
                return DefaultErrorPage(
                    e,
                    "Your question could not be saved due to some problem with the database. Please try again later."
                )

            #redirect to ShowQuestionDetails when done adding a question
            return HttpResponseRedirect(
                reverse('ShowQuestionDetails',
                        kwargs={'question_slug': new_question_in_db.slug}))
        else:

            #if form is not valid, i.e. the new question has a problem, just rerender the form with errors
            return render_to_response(template, {
                'form': form,
                'formset': formset,
                'add_or_edit': 'add'
            },
                                      context_instance=RequestContext(request))

    # if method is GET show a blank form
    else:
        form = MultipleChoiceQuestionModelForm(prefix='Question')
        formset = MultipleChoiceAnswerItemFormset(prefix='Answer')
    return render_to_response(template, {
        'form': form,
        'formset': formset,
        'add_or_edit': 'add'
    },
                              context_instance=RequestContext(request))
Beispiel #7
0
def PublishQuestionToFacebook(request, graph, question_slug=''):

    #     debugprint('starting publish func: ' + str(datetime.datetime.now()))
    #     debugprint('method=' + request.method)
    #

    #should never happen, but if we don't get a graph object passed in from the facebook decorator,
    #we must go back to the question page with an error
    if not graph:
        return utils.custom_redirect('ShowQuestionDetails',
                                     question_slug,
                                     fb_post_error=True)

    # skip exception handling here, the decorator already checked
    theQuestion = GetQuestionFromSlug(question_slug)
    #
    #first create a publishing object to represent that this question is now in 'published' state
    # and no longer be changed
    try:

        IsAlreadyPublished = (theQuestion.linked_survey.publishing_set.count()
                              > 0)

        new_publishing = FacebookPublishing(
            linked_survey=theQuestion.linked_survey,
            publish_date=datetime.datetime.now(),
            dummy_field='dummy_data')

        new_publishing.save()

        #create bit.ly url's for the voting url's

        theAnswers = theQuestion.multiplechoiceansweritem_set.all().order_by(
            'pk')

        ViewHelpers.CreateURLsForAnswersIfNeeded(question_slug,
                                                 IsAlreadyPublished,
                                                 theAnswers)

    #need to add rollback/transaction here, actually the whole view should be in a transaction
    #and rolled back if any problems
    except (DatabaseError, IntegrityError) as e:
        return DefaultErrorPage(
            e,
            mesg=
            "There was a problem posting your question to facebook due to a database or other error. Please try again later."
        )

    fb_post_str = ConstructFBPostForQuestion(theQuestion, theAnswers)

    #     debugprint('before call to post to FB ' + str(datetime.datetime.now()) + ' ' + request.method)
    #     debugprint('method=' + request.method)
    #     #result = graph.set('me/feed', message=fb_post_str)

    #creates an asynchronous task using RQ to post to Facebook passing it the access token
    # and post text
    try:
        asynch_post_job = ViewHelpers.post_to_fb_async.delay(
            graph.access_token, fb_post_str)
    except Exception as e:
        return utils.custom_redirect('ShowQuestionDetails',
                                     question_slug,
                                     fb_post_error=True)
#     debugprint('after call to post to FB ' + str(datetime.datetime.now()) + ' ' + request.method)
#     debugprint('method=' + request.method)

    return utils.custom_redirect('ShowQuestionDetails',
                                 question_slug,
                                 just_published_on_FB=True)
Beispiel #8
0
def EditQuestion(request, question_slug='', **kwargs):

    #def inline_formset(request, form_class, template):
    template = 'edit_question.html'

    MultipleChoiceAnswerItemFormset = inlineformset_factory(
        MultipleChoiceQuestion,
        MultipleChoiceAnswerItem,
        form=MultipleChoiceAnswerItemModelForm,
        formset=MultipleChoiceAnswerItemModelFormset,
        extra=1,
        can_delete=True)
    theQuestion = MultipleChoiceQuestion.objects.get(slug=question_slug)

    # if POST the user submitted changes to the question. So validate and save to DB
    if request.method == 'POST':

        form = MultipleChoiceQuestionModelForm(request.POST,
                                               prefix="Question",
                                               instance=theQuestion)
        formset = MultipleChoiceAnswerItemFormset(request.POST,
                                                  prefix="Answer",
                                                  instance=theQuestion)

        is_question_form_valid = form.is_valid()
        is_answer_formset_valid = formset.is_valid()

        if is_question_form_valid and is_answer_formset_valid:

            try:
                form.save()
                formset.save()
            except (DatabaseError, IntegrityError) as e:
                return DefaultErrorPage(
                    e,
                    mesg=
                    "Could not save your changes to the question due to a database error. Try again later."
                )

            #redirect to the show the updated question

            return HttpResponseRedirect(
                reverse('ShowQuestionDetails',
                        kwargs={'question_slug': question_slug}))
        else:  #form is invalid, re-render form with errors

            return render_to_response(template, {
                'form': form,
                'formset': formset,
                'question': theQuestion,
                'add_or_edit': 'edit'
            },
                                      context_instance=RequestContext(request))
    #handle GET
    #render the form
    else:
        form = MultipleChoiceQuestionModelForm(prefix="Question",
                                               instance=theQuestion)
        formset = MultipleChoiceAnswerItemFormset(prefix="Answer",
                                                  instance=theQuestion)
    return render_to_response(template, {
        'form': form,
        'formset': formset,
        'question': theQuestion,
        'add_or_edit': 'edit'
    },
                              context_instance=RequestContext(request))