Beispiel #1
0
    def get(self, linkKeyStr, questionId):

        logging.debug(LogMessage('UserAnswer', 'linkKeyStr=', linkKeyStr))

        # Collect inputs.
        httpRequestId = os.environ.get(conf.REQUEST_LOG_ID)
        responseData = {'success': False, 'httpRequestId': httpRequestId}

        cookieData = httpServer.validate(self.request,
                                         self.request.GET,
                                         responseData,
                                         self.response,
                                         crumbRequired=False,
                                         signatureRequired=False)
        if not cookieData.valid(): return
        userId = cookieData.id()

        # Retrieve and check linkKey.
        linkKeyRecord = linkKey.LinkKey.get_by_id(linkKeyStr)
        if (linkKeyRecord is None) or (linkKeyRecord.destinationType !=
                                       conf.SURVEY_CLASS_NAME):
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.BAD_LINK)
        surveyId = linkKeyRecord.destinationId

        # Retrieve all answers for this question and voter
        answerVoteRec = answerVote.get(questionId, userId)
        logging.debug(LogMessage('UserAnswer', 'answerVoteRec=',
                                 answerVoteRec))

        answerRecord = answer.Answer.get_by_id(answerVoteRec.answerId)
        logging.debug(LogMessage('UserAnswer', 'answerRecord=', answerRecord))

        if answerRecord.surveyId != surveyId:
            return httpServer.outputJson(
                cookieData,
                responseData,
                self.response,
                errorMessage='answerRecord.surveyId != surveyId')

        answerDisplay = httpServerAutocomplete.answerToDisplay(
            answerRecord, userId) if answerRecord else None

        # Display answers data.
        responseData.update({'success': True, 'answer': answerDisplay})
        httpServer.outputJson(cookieData, responseData, self.response)
Beispiel #2
0
    def get(self, linkKeyStr, questionId):

        logging.debug(
            LogMessage('QuestionAnswersFromCreator', 'linkKeyStr=', linkKeyStr,
                       'questionId=', questionId))

        # Collect inputs.
        httpRequestId = os.environ.get(conf.REQUEST_LOG_ID)
        responseData = {'success': False, 'httpRequestId': httpRequestId}

        cookieData = httpServer.validate(self.request,
                                         self.request.GET,
                                         responseData,
                                         self.response,
                                         crumbRequired=False,
                                         signatureRequired=False)
        if not cookieData.valid(): return
        userId = cookieData.id()

        # Retrieve and check linkKey.
        linkKeyRecord = linkKey.LinkKey.get_by_id(linkKeyStr)
        if (linkKeyRecord is None) or (linkKeyRecord.destinationType !=
                                       conf.SURVEY_CLASS_NAME):
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.BAD_LINK)
        surveyId = linkKeyRecord.destinationId

        # Retrieve all answers for this question and creator.
        answerRecords = answer.Answer.query(
            answer.Answer.questionId == questionId,
            answer.Answer.creator == userId,
            answer.Answer.fromEditPage == True).fetch()
        answersByContent = sorted(answerRecords, key=lambda a: a.content)
        answerDisplays = [
            httpServerAutocomplete.answerToDisplay(a, userId)
            for a in answersByContent
        ]

        # Display answers data.
        responseData = {'success': True, 'answers': answerDisplays}
        httpServer.outputJson(cookieData, responseData, self.response)
Beispiel #3
0
    def get(self, linkKeyStr, questionId):

        logging.debug(
            LogMessage('QuestionFrequentAnswers', 'linkKeyStr=', linkKeyStr,
                       'questionId=', questionId))

        # Collect inputs.
        answerStart = self.request.get('answerStart', None)
        logging.debug(
            LogMessage('QuestionFrequentAnswers', 'answerStart=', answerStart))
        all = (self.request.get('all', None) == 'true')

        httpRequestId = os.environ.get(conf.REQUEST_LOG_ID)
        responseData = {'success': False, 'httpRequestId': httpRequestId}

        cookieData = httpServer.validate(self.request,
                                         self.request.GET,
                                         responseData,
                                         self.response,
                                         idRequired=False)
        userId = cookieData.id()

        # Retrieve and check linkKey.
        linkKeyRecord = linkKey.LinkKey.get_by_id(linkKeyStr)
        if (linkKeyRecord is None) or (linkKeyRecord.destinationType !=
                                       conf.SURVEY_CLASS_NAME):
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.BAD_LINK)
        surveyId = linkKeyRecord.destinationId

        # Check that question is part of survey, because the answer query may be too expensive to allow unnecessary calls.
        questionRecord = question.Question.get_by_id(int(questionId))
        if questionRecord is None:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage='questionRecord is null')
        if questionRecord.surveyId != surveyId:
            return httpServer.outputJson(
                cookieData,
                responseData,
                self.response,
                errorMessage='questionRecord.surveyId != surveyId')

        # Retrieve most frequent answers for question
        if all:
            answerRecordsTrunc = answer.Answer.query(
                answer.Answer.surveyId == surveyId,
                answer.Answer.questionId == questionId, answer.Answer.voteCount
                > 0).order(-answer.Answer.voteCount).fetch()
            hasMoreAnswers = False

        else:
            maxAnswersPerQuestion = 10
            answerRecords = answer.Answer.query(
                answer.Answer.surveyId == surveyId,
                answer.Answer.questionId == questionId,
                answer.Answer.voteCount > 0).order(
                    -answer.Answer.voteCount).fetch(maxAnswersPerQuestion + 1)

            answerRecordsTrunc = answerRecords[0:maxAnswersPerQuestion]
            hasMoreAnswers = len(answerRecordsTrunc) < len(answerRecords)

        logging.debug(
            LogMessage('QuestionFrequentAnswers', 'answerRecordsTrunc=',
                       answerRecordsTrunc))

        answerDisplays = [
            httpServerAutocomplete.answerToDisplay(a, userId)
            for a in answerRecordsTrunc
        ]

        # Display answers data.
        responseData.update({
            'success': True,
            'answers': answerDisplays,
            'hasMoreAnswers': hasMoreAnswers
        })
        httpServer.outputJson(cookieData, responseData, self.response)
Beispiel #4
0
    def post(self, linkKeyStr, questionId):

        logging.debug(
            LogMessage('QuestionAnswersForPrefix', 'linkKeyStr=', linkKeyStr,
                       'questionId=', questionId))

        # Collect inputs
        inputData = json.loads(self.request.body)
        logging.debug(
            LogMessage('QuestionAnswersForPrefix', 'inputData=', inputData))
        answerStart = answer.standardizeContent(
            inputData.get('answerStart', None))
        logging.debug(
            LogMessage('QuestionAnswersForPrefix', 'answerStart=',
                       answerStart))

        httpRequestId = os.environ.get(conf.REQUEST_LOG_ID)
        responseData = {'success': False, 'httpRequestId': httpRequestId}

        # No user-id required, works for any user with the link-key
        cookieData = httpServer.validate(self.request,
                                         self.request.GET,
                                         responseData,
                                         self.response,
                                         idRequired=False)
        userId = cookieData.id()

        # Retrieve and check linkKey.
        linkKeyRecord = linkKey.LinkKey.get_by_id(linkKeyStr)
        if (linkKeyRecord is None) or (linkKeyRecord.destinationType !=
                                       conf.SURVEY_CLASS_NAME):
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.BAD_LINK)
        surveyId = linkKeyRecord.destinationId

        # No need to enforce login-required in GET calls, only on write operations that create/use link-key
        # But enforcing here because the search is expensive, and part of a write flow
        if linkKeyRecord.loginRequired and not cookieData.loginId:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.NO_LOGIN)

        # Check that question is part of survey, because the answer query may be too expensive to allow unnecessary calls.
        questionRecord = question.Question.get_by_id(int(questionId))
        if questionRecord is None:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage='questionRecord is null')
        if questionRecord.surveyId != surveyId:
            return httpServer.outputJson(
                cookieData,
                responseData,
                self.response,
                errorMessage='questionRecord.surveyId != surveyId')

        # Retrieve survey record
        surveyRecord = survey.Survey.get_by_id(int(surveyId))
        if surveyRecord is None:
            return httpServer.outputJson(
                cookieData,
                responseData,
                self.response,
                errorMessage='survey record not found')
        # Check that survey is not frozen, to reduce the cost of abuse via search queries
        if surveyRecord.freezeUserInput:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.FROZEN)

        # Retrieve best suggested answers for this question and creator.
        answersOrdered = answer.retrieveTopAnswers(
            surveyId,
            questionId,
            answerStart=answerStart,
            hideReasons=surveyRecord.hideReasons)
        logging.debug(
            LogMessage('QuestionAnswersForPrefix', 'answersOrdered=',
                       answersOrdered))

        answerDisplays = [
            httpServerAutocomplete.answerToDisplay(a, userId)
            for a in answersOrdered
        ]

        # Display answers data.
        responseData.update({'success': True, 'answers': answerDisplays})
        httpServer.outputJson(cookieData, responseData, self.response)
Beispiel #5
0
    def post(self):
        logging.debug('EditAnswer.post() request.body=' + self.request.body)

        # Collect inputs
        requestLogId = os.environ.get(conf.REQUEST_LOG_ID)
        inputData = json.loads(self.request.body)
        logging.debug('EditAnswer.post() inputData=' + str(inputData))

        responseData = {'success': False, 'requestLogId': requestLogId}

        cookieData = httpServer.validate(self.request, inputData, responseData,
                                         self.response)
        if not cookieData.valid(): return
        userId = cookieData.id()

        content = answer.standardizeContent(
            text.formTextToStored(inputData['content']))
        linkKeyString = inputData['linkKey']
        answerId = inputData['answerId']
        questionId = str(int(inputData['questionId']))
        browserCrumb = inputData.get('crumb', None)
        logging.debug('EditAnswer.post() content=' + str(content) +
                      ' browserCrumb=' + str(browserCrumb) +
                      ' linkKeyString=' + str(linkKeyString) + ' answerId=' +
                      str(answerId))

        surveyId, loginRequired = retrieveSurveyIdFromLinkKey(
            cookieData, linkKeyString, responseData, self.response)
        if surveyId is None: return

        # Retrieve survey record to check survey creator
        surveyRec = survey.Survey.get_by_id(int(surveyId))
        if surveyRec is None:
            return httpServer.outputJson(
                cookieData,
                responseData,
                self.response,
                errorMessage='survey record not found')
        if surveyRec.creator != userId:
            return httpServer.outputJson(
                cookieData,
                responseData,
                self.response,
                errorMessage='surveyRec.creator != userId')

        # Split answers by newline
        contentLines = content.split('\n') if content else []
        # For each non-empty answer...
        answerDisplays = []
        for contentLine in contentLines:
            logging.debug('EditAnswer.post() contentLine=' + str(contentLine))
            if not contentLine: continue

            # Check answer length
            if not httpServer.isLengthOk(contentLine, '',
                                         conf.minLengthAnswer):
                return httpServer.outputJson(cookieData,
                                             responseData,
                                             self.response,
                                             errorMessage=conf.TOO_SHORT)

            # If new answer value already exists... error.  If new answer is same as old answer value... no problem?
            newAnswerId = answer.toKeyId(questionId, contentLine)
            answerRec = answer.Answer.get_by_id(newAnswerId)
            if answerRec: continue

            # Delete old answer
            if answerId:
                oldAnswerRec = answer.Answer.get_by_id(answerId)
                if oldAnswerRec is None:
                    return httpServer.outputJson(
                        cookieData,
                        responseData,
                        self.response,
                        errorMessage='answer record not found')
                if oldAnswerRec.surveyId != surveyId:
                    return httpServer.outputJson(
                        cookieData,
                        responseData,
                        self.response,
                        errorMessage='oldAnswerRec.surveyId != surveyId')
                oldAnswerRec.key.delete()
            # Create new answer
            answerRec = answer.newAnswer(questionId,
                                         surveyId,
                                         contentLine,
                                         userId,
                                         voteCount=0,
                                         fromEditPage=True)
            answerDisplay = httpServerAutocomplete.answerToDisplay(
                answerRec, userId)
            answerDisplays.append(answerDisplay)

        # Display updated answers
        responseData.update({'success': True, 'answers': answerDisplays})
        httpServer.outputJson(cookieData, responseData, self.response)
Beispiel #6
0
    def get(self, linkKeyStr, questionId):

        logging.debug('QuestionAnswersForPrefix.get() linkKeyStr=' +
                      str(linkKeyStr) + ' questionId=' + str(questionId))

        # Collect inputs.
        answerStart = self.request.get('answerStart', None)
        logging.debug('QuestionAnswersForPrefix.get() answerStart=' +
                      str(answerStart))

        httpRequestId = os.environ.get(conf.REQUEST_LOG_ID)
        responseData = {'success': False, 'httpRequestId': httpRequestId}

        # No user-id required, works for any user with the link-key
        cookieData = httpServer.validate(self.request,
                                         self.request.GET,
                                         responseData,
                                         self.response,
                                         idRequired=False)
        userId = cookieData.id()

        # Retrieve and check linkKey.
        linkKeyRecord = linkKey.LinkKey.get_by_id(linkKeyStr)
        if (linkKeyRecord is None) or (linkKeyRecord.destinationType !=
                                       conf.SURVEY_CLASS_NAME):
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.BAD_LINK)
        surveyId = linkKeyRecord.destinationId

        # No need to enforce login-required in GET calls, only on write operations that create/use link-key
        # But enforcing here because the search is expensive, and part of a write flow
        if linkKeyRecord.loginRequired and not cookieData.loginId:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.NO_LOGIN)

        # Check that question is part of survey, because the answer query may be too expensive to allow unnecessary calls.
        questionRecord = question.Question.get_by_id(int(questionId))
        if questionRecord is None:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage='questionRecord is null')
        if questionRecord.surveyId != surveyId:
            return httpServer.outputJson(
                cookieData,
                responseData,
                self.response,
                errorMessage='questionRecord.surveyId != surveyId')

        # Retrieve best suggested answers for this question and creator.
        answersOrdered = answer.retrieveTopAnswersAsync(
            surveyId, questionId, answerStart=answerStart)
        logging.debug('QuestionAnswersForPrefix.get() answersOrdered=' +
                      str(answersOrdered))

        answerDisplays = [
            httpServerAutocomplete.answerToDisplay(a, userId)
            for a in answersOrdered
        ]

        # Display answers data.
        responseData.update({'success': True, 'answers': answerDisplays})
        httpServer.outputJson(cookieData, responseData, self.response)