예제 #1
0
    def post(self):
        logging.debug( 'SubmitEditSurvey.post() request.body=' + self.request.body )

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

        title = text.formTextToStored( inputData['title'] )
        introduction = text.formTextToStored( inputData['introduction'] )
        linkKeyString = inputData['linkKey']
        browserCrumb = inputData.get( 'crumb', '' )
        loginCrumb = inputData.get( 'crumbForLogin', '' )
        logging.debug( 'SubmitEditSurvey.post() introduction=' + str(introduction) + ' browserCrumb=' + str(browserCrumb) 
            + ' loginCrumb=' + str(loginCrumb) 
            + ' linkKeyString=' + str(linkKeyString) )

        responseData = { 'success':False, 'requestLogId':requestLogId }
        cookieData = httpServer.validate( self.request, inputData, responseData, self.response )
        if not cookieData.valid():  return
        userId = cookieData.id()

        # Retrieve link-key record
        if linkKeyString is None:  return httpServer.outputJson( cookieData, responseData, self.response, errorMessage='linkKeyString is null' )
        linkKeyRecord = linkKey.LinkKey.get_by_id( linkKeyString )
        logging.debug( 'SubmitEditSurvey.post() linkKeyRecord=' + str(linkKeyRecord) )

        if linkKeyRecord is None:  return httpServer.outputJson( cookieData, responseData, self.response, errorMessage='linkKey not found' )
        if linkKeyRecord.destinationType != conf.SURVEY_CLASS_NAME:  return httpServer.outputJson( cookieData, responseData, self.response, errorMessage='linkKey destinationType=' + str(linkKeyRecord.destinationType) )
        surveyId = linkKeyRecord.destinationId
        loginRequired = linkKeyRecord.loginRequired

        if linkKeyRecord.loginRequired  and  not cookieData.loginId:  return httpServer.outputJson( cookieData, responseData, self.response, errorMessage=conf.NO_LOGIN )

        # Check survey length
        if not httpServer.isLengthOk( title, introduction, conf.minLengthSurveyIntro ):
            return httpServer.outputJson( cookieData, responseData, self.response, errorMessage=conf.TOO_SHORT )

        # Retrieve survey record.
        surveyRec = survey.Survey.get_by_id( int(surveyId) )
        logging.debug( 'SubmitEditSurvey.post() surveyRec=' + str(surveyRec) )

        if surveyRec is None:  return httpServer.outputJson( cookieData, responseData, self.response, errorMessage='survey not found' )

        # Verify that survey is editable
        if userId != surveyRec.creator:  return httpServer.outputJson( cookieData, responseData, self.response, errorMessage=conf.NOT_OWNER )
        if not surveyRec.allowEdit:  return httpServer.outputJson( cookieData, responseData, self.response, errorMessage=conf.HAS_RESPONSES )

        # Update survey record
        surveyRec.title = title
        surveyRec.introduction = introduction
        surveyRec.put()
        
        # Display updated survey.
        surveyDisplay = httpServerAutocomplete.surveyToDisplay( surveyRec, userId )
        responseData.update(  { 'success':True, 'survey':surveyDisplay }  )
        httpServer.outputJson( cookieData, responseData, self.response )
예제 #2
0
    def post(self, linkKeyStr, proposalId):

        if conf.isDev:
            logging.debug('SuggestReasons.post() linkKeyStr=' +
                          str(linkKeyStr) + ' proposalId=' + str(proposalId))

        # Collect inputs
        inputData = json.loads(self.request.body)
        if conf.isDev:
            logging.debug('SuggestReasons.post() inputData=' + str(inputData))

        reasonStart = text.formTextToStored(inputData.get('content', ''))
        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()

        if not reasonStart:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage='Empty input')

        # Retrieve top-level records
        (linkKeyRecord, proposalRecord,
         requestRecord) = retrieveRequestAndProposal(linkKeyStr, proposalId)
        if not linkKeyRecord: return  # Bad link
        proposalId = str(proposalRecord.key.id())
        if proposalRecord.freezeUserInput or (requestRecord and
                                              requestRecord.freezeUserInput):
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.FROZEN)

        # Retrieve reasons and vote, in parallel
        voteRecordsFuture = reasonVote.ReasonVote.query(
            reasonVote.ReasonVote.proposalId == proposalId,
            reasonVote.ReasonVote.userId
            == userId).fetch_async() if userId else None
        reasonRecords = reason.retrieveTopReasonsForStart(
            proposalId,
            reasonStart)  # Retrieve reasons while vote-record is retrieving
        voteRecords = voteRecordsFuture.get_result(
        ) if voteRecordsFuture else None

        # Filter/transform fields for display
        reasonDisps = [
            httpServer.reasonToDisplay(r, userId) for r in reasonRecords
        ]
        mergeReasonVotes(voteRecords, reasonDisps)

        # Display proposal data
        responseData = {'success': True, 'reasons': reasonDisps}
        httpServer.outputJson(cookieData, responseData, self.response)
예제 #3
0
    def post(self):
        logging.debug('SubmitNewSurvey.post() request.body=' +
                      self.request.body)

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

        introduction = text.formTextToStored(inputData.get('introduction', ''))
        browserCrumb = inputData.get('crumb', '')
        loginCrumb = inputData.get('crumbForLogin', '')
        loginRequired = inputData.get('loginRequired', False)
        logging.debug('SubmitNewSurvey.post() introduction=' +
                      str(introduction) + ' browserCrumb=' +
                      str(browserCrumb) + ' loginCrumb=' + str(loginCrumb) +
                      ' loginRequired=' + str(loginRequired))

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

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

        # Check survey introduction length.
        if not httpServer.isLengthOk(introduction, '',
                                     conf.minLengthSurveyIntro):
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.TOO_SHORT)

        # Construct and store new survey record.
        surveyRecord = survey.Survey(creator=userId,
                                     introduction=introduction,
                                     allowEdit=True)
        surveyRecordKey = surveyRecord.put()
        logging.debug('surveyRecordKey.id={}'.format(surveyRecordKey.id()))

        # Construct and store link key.
        surveyId = str(surveyRecordKey.id())
        linkKeyRecord = httpServer.createAndStoreLinkKey(
            conf.SURVEY_CLASS_NAME, surveyId, loginRequired, cookieData)

        # Display survey.
        surveyDisplay = httpServerAutocomplete.surveyToDisplay(
            surveyRecord, userId)
        linkKeyDisplay = httpServer.linkKeyToDisplay(linkKeyRecord)
        responseData.update({
            'success': True,
            'linkKey': linkKeyDisplay,
            'survey': surveyDisplay
        })
        httpServer.outputJson(cookieData, responseData, self.response)
예제 #4
0
def standardizeContent(content):
    content = text.formTextToStored(content) if content else None
    content = content.strip(
        ' \n\r\x0b\x0c'
    ) if content else None  # For now keep TAB to delimit answer from reason
    return content if content else None
예제 #5
0
    def post(self):
        logging.debug(('EditSlice.post()', 'request.body=', self.request.body))

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

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

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

        title = slice.standardizeContent(
            text.formTextToStored(inputData['title']))
        reason = slice.standardizeContent(
            text.formTextToStored(inputData['reason']))
        linkKeyString = inputData['linkKey']
        sliceId = inputData.get('sliceId', None)  # Null if slice is new
        logging.debug(
            ('EditSlice.post()', 'sliceId=', sliceId, 'title=', title,
             'reason=', reason, 'linkKeyString=', linkKeyString))

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

        # Retrieve budget record to check budget creator
        budgetRec = budget.Budget.get_by_id(int(budgetId))
        if budgetRec is None:
            return httpServer.outputJson(
                cookieData,
                responseData,
                self.response,
                errorMessage='budget record not found')
        if budgetRec.creator != userId:
            return httpServer.outputJson(
                cookieData,
                responseData,
                self.response,
                errorMessage='budgetRec.creator != userId')

        # Check slice length
        if (not title) or (len(title) < conf.minLengthSliceTitle):
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.TOO_SHORT)
        if budgetRec.hideReasons:
            if reason:
                return httpServer.outputJson(cookieData,
                                             responseData,
                                             self.response,
                                             errorMessage='reasons hidden')
        else:
            if (not reason) or (len(reason) < conf.minLengthSliceTitle):
                return httpServer.outputJson(
                    cookieData,
                    responseData,
                    self.response,
                    errorMessage=conf.REASON_TOO_SHORT)

        # Delete old slice if it has no votes
        if sliceId:
            oldSliceRec = slice.Slice.get_by_id(sliceId)
            if oldSliceRec is None:
                return httpServer.outputJson(
                    cookieData,
                    responseData,
                    self.response,
                    errorMessage='slice record not found')
            if oldSliceRec.budgetId != budgetId:
                return httpServer.outputJson(
                    cookieData,
                    responseData,
                    self.response,
                    errorMessage='oldSliceRec.budgetId != budgetId')
            if oldSliceRec.creator != userId:
                return httpServer.outputJson(cookieData,
                                             responseData,
                                             self.response,
                                             errorMessage=NOT_OWNER)
            if (oldSliceRec.voteCount <= 0):
                oldSliceRec.key.delete()

        # Create new slice only if there is existing record/vote
        sliceRec = slice.Slice.get(budgetId, title, reason)
        if sliceRec is None:
            sliceRec = slice.Slice.create(budgetId,
                                          title,
                                          reason,
                                          creator=userId)
        # Store slice record
        sliceRec.fromEditPage = True
        sliceRec.put()

        # Display updated slices
        sliceDisplay = httpServerBudget.sliceToDisplay(sliceRec, userId)
        responseData.update({'success': True, 'slice': sliceDisplay})
        httpServer.outputJson(cookieData, responseData, self.response)
예제 #6
0
    def post(self):
        logging.debug('SubmitNewBudget.post() request.body=' +
                      self.request.body)

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

        title = text.formTextToStored(inputData.get('title', ''))
        introduction = text.formTextToStored(inputData.get('introduction', ''))
        total = float(inputData.get('total', None))
        loginRequired = inputData.get('loginRequired', False)
        experimentalPassword = inputData.get('experimentalPassword', None)
        hideReasons = bool(inputData.get('hideReasons', False))
        logging.debug('SubmitNewBudget.post() title=' + str(title) +
                      ' total=' + str(total) + ' introduction=' +
                      str(introduction) + ' loginRequired=' +
                      str(loginRequired) + ' hideReasons=' + str(hideReasons))

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

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

        # Check budget introduction length
        if not httpServer.isLengthOk(title, introduction,
                                     conf.minLengthBudgetIntro):
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.TOO_SHORT)

        # Check budget-total
        if (total <= 0):
            return httpServer.outputJson(
                cookieData,
                responseData,
                self.response,
                errorMessage='Budget total must be a positive number')

        # Check experimental password (low-risk secret)
        if (hideReasons or loginRequired or experimentalPassword) and (
                experimentalPassword != secrets.experimentalPassword):
            return httpServer.outputJson(
                cookieData,
                responseData,
                self.response,
                errorMessage=conf.EXPERIMENT_NOT_AUTHORIZED)

        # Construct and store new budget record
        budgetRecord = budget.Budget(creator=userId,
                                     title=title,
                                     introduction=introduction,
                                     total=total,
                                     allowEdit=True,
                                     hideReasons=hideReasons)
        budgetRecordKey = budgetRecord.put()
        logging.debug('budgetRecordKey.id={}'.format(budgetRecordKey.id()))

        # Construct and store link key
        budgetId = str(budgetRecordKey.id())
        linkKeyRecord = httpServer.createAndStoreLinkKey(
            conf.BUDGET_CLASS_NAME, budgetId, loginRequired, cookieData)

        # Display budget
        budgetDisplay = httpServerBudget.budgetToDisplay(budgetRecord, userId)
        linkKeyDisplay = httpServer.linkKeyToDisplay(linkKeyRecord)
        responseData.update({
            'success': True,
            'linkKey': linkKeyDisplay,
            'budget': budgetDisplay
        })
        httpServer.outputJson(cookieData, responseData, self.response)
예제 #7
0
    def post(self):
        logging.debug('SubmitEditBudget.post() request.body=' +
                      self.request.body)

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

        title = text.formTextToStored(inputData['title'])
        introduction = text.formTextToStored(inputData['introduction'])
        total = float(inputData.get('total', None))
        linkKeyString = inputData['linkKey']
        logging.debug('SubmitEditBudget.post() title=' + str(title) +
                      ' total=' + str(total) + ' introduction=' +
                      str(introduction))

        responseData = {'success': False, 'requestLogId': requestLogId}
        cookieData = httpServer.validate(self.request, inputData, responseData,
                                         self.response)
        if not cookieData.valid(): return
        userId = cookieData.id()

        # Retrieve link-key record
        if linkKeyString is None:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage='linkKeyString is null')
        linkKeyRecord = linkKey.LinkKey.get_by_id(linkKeyString)
        logging.debug('SubmitEditBudget.post() linkKeyRecord=' +
                      str(linkKeyRecord))

        if linkKeyRecord is None:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage='linkKey not found')
        if linkKeyRecord.destinationType != conf.BUDGET_CLASS_NAME:
            return httpServer.outputJson(
                cookieData,
                responseData,
                self.response,
                errorMessage='linkKey destinationType=' +
                str(linkKeyRecord.destinationType))
        budgetId = linkKeyRecord.destinationId
        loginRequired = linkKeyRecord.loginRequired

        if linkKeyRecord.loginRequired and not cookieData.loginId:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.NO_LOGIN)

        # Check budget introduction length
        if not httpServer.isLengthOk(title, introduction,
                                     conf.minLengthBudgetIntro):
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.TOO_SHORT)

        # Check budget-total
        if (total <= 0):
            return httpServer.outputJson(
                cookieData,
                responseData,
                self.response,
                errorMessage='Budget total must be a positive number')

        # Retrieve budget record
        budgetRec = budget.Budget.get_by_id(int(budgetId))
        logging.debug('SubmitEditBudget.post() budgetRec=' + str(budgetRec))

        if budgetRec is None:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage='budget not found')

        # Verify that budget is editable
        if userId != budgetRec.creator:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.NOT_OWNER)
        if not budgetRec.allowEdit:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.HAS_RESPONSES)

        # Update budget record
        budgetRec.title = title
        budgetRec.introduction = introduction
        budgetRec.total = total
        budgetRec.put()

        # Display updated budget.
        budgetDisplay = httpServerBudget.budgetToDisplay(budgetRec, userId)
        responseData.update({'success': True, 'budget': budgetDisplay})
        httpServer.outputJson(cookieData, responseData, self.response)
예제 #8
0
    def post(self):
        logging.debug('SubmitEditProposal.post() request.body=' +
                      self.request.body)

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

        title = text.formTextToStored(inputData['title'])
        detail = text.formTextToStored(inputData['detail'])
        linkKeyString = inputData['linkKey']
        proposalId = str(int(inputData['proposalId']))
        browserCrumb = inputData['crumb']
        loginCrumb = inputData.get('crumbForLogin', '')
        logging.debug('SubmitEditProposal.post() title=' + str(title) +
                      ' detail=' + str(detail) + ' browserCrumb=' +
                      str(browserCrumb) + ' loginCrumb=' + str(loginCrumb) +
                      ' linkKeyString=' + str(linkKeyString) + ' proposalId=' +
                      str(proposalId))

        # User id from cookie, crumb...
        responseData = {'success': False, 'requestLogId': requestLogId}
        cookieData = httpServer.validate(self.request, inputData, responseData,
                                         self.response)
        if not cookieData.valid(): return
        userId = cookieData.id()

        # Check proposal length
        if not httpServer.isLengthOk(title, detail, conf.minLengthProposal):
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.TOO_SHORT)

        # Require link-key.
        linkKeyRec = linkKey.LinkKey.get_by_id(linkKeyString)
        logging.debug('SubmitEditProposal.post() linkKeyRec=' +
                      str(linkKeyRec))

        if linkKeyRec is None:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage='linkKey not found')

        if linkKeyRec.loginRequired and not cookieData.loginId:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.NO_LOGIN)

        # Retrieve proposal record.
        proposalRec = proposal.Proposal.get_by_id(int(proposalId))
        logging.debug('SubmitEditProposal.post() proposalRec=' +
                      str(proposalRec))

        if proposalRec is None:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage='proposal not found')

        # Verify that proposal matches link-key.
        if linkKeyRec.destinationType == conf.REQUEST_CLASS_NAME:
            if proposalRec.requestId != linkKeyRec.destinationId:
                return httpServer.outputJson(
                    cookieData,
                    responseData,
                    self.response,
                    errorMessage=
                    'proposalRec.requestId != linkKeyRec.destinationId')

        elif linkKeyRec.destinationType == conf.PROPOSAL_CLASS_NAME:
            if proposalId != linkKeyRec.destinationId:
                return httpServer.outputJson(
                    cookieData,
                    responseData,
                    self.response,
                    errorMessage='proposalId != linkKeyRec.destinationId')

        else:
            return httpServer.outputJson(
                cookieData,
                responseData,
                self.response,
                errorMessage='linkKey destinationType=' +
                str(linkKeyRec.destinationType))

        # Verify that proposal is editable
        if userId != proposalRec.creator:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.NOT_OWNER)
        if not proposalRec.allowEdit:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.HAS_RESPONSES)

        # Update proposal record.
        proposalRec.title = title
        proposalRec.detail = detail
        proposalRec.put()

        # Display updated proposal.
        proposalDisplay = httpServer.proposalToDisplay(proposalRec, userId)
        responseData.update({'success': True, 'proposal': proposalDisplay})
        httpServer.outputJson(cookieData, responseData, self.response)
예제 #9
0
    def post(self, linkKeyStr):
        logging.debug('linkKeyStr=' + linkKeyStr)

        # Collect inputs
        inputData = json.loads(self.request.body)
        if conf.isDev:
            logging.debug('SuggestReasons.post() inputData=' + str(inputData))
        content = text.formTextToStored(inputData.get('content', ''))

        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()

        if not content:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage='Empty input')

        # Retrieve link-record
        linkKeyRecord = linkKey.LinkKey.get_by_id(linkKeyStr)
        if (linkKeyRecord == None) or (linkKeyRecord.destinationType !=
                                       conf.REQUEST_CLASS_NAME):
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.BAD_LINK)
        requestId = linkKeyRecord.destinationId

        # Retrieve RequestForProposal
        requestRecord = requestForProposals.RequestForProposals.get_by_id(
            int(requestId))
        if requestRecord and (requestRecord.freezeUserInput):
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.FROZEN)

        # Retrieve Proposals
        proposalRecords = proposal.retrieveTopProposalsForStart(
            requestRecord.key.id(), content)

        linkKeyDisp = httpServer.linkKeyToDisplay(linkKeyRecord)
        requestDisp = httpServer.requestToDisplay(requestRecord, userId)
        proposalDisps = [
            httpServer.proposalToDisplay(p,
                                         userId,
                                         requestRecord=requestRecord)
            for p in proposalRecords
        ]

        # Display
        responseData = {
            'success': True,
            'linkKey': linkKeyDisp,
            'request': requestDisp,
            'proposals': proposalDisps
        }
        httpServer.outputJson(cookieData, responseData, self.response)
예제 #10
0
    def post(self):
        logging.debug(
            LogMessage('SubmitEditRequest', 'request.body=',
                       self.request.body))

        # Collect inputs
        requestLogId = os.environ.get(conf.REQUEST_LOG_ID)
        inputData = json.loads(self.request.body)
        logging.debug(LogMessage('SubmitEditRequest', 'inputData=', inputData))

        title = text.formTextToStored(inputData.get('inputTitle', ''))
        detail = text.formTextToStored(inputData.get('inputDetail', ''))
        linkKeyString = inputData.get('linkKey', None)
        browserCrumb = inputData.get('crumb', '')
        loginCrumb = inputData.get('crumbForLogin', '')
        logging.debug(
            LogMessage('SubmitEditRequest', 'title=', title, 'detail=', detail,
                       'browserCrumb=', browserCrumb, 'loginCrumb=',
                       loginCrumb, 'linkKeyString=', linkKeyString))

        # User id from cookie, crumb...
        responseData = {'success': False, 'requestLogId': requestLogId}
        cookieData = httpServer.validate(self.request, inputData, responseData,
                                         self.response)
        if not cookieData.valid(): return
        userId = cookieData.id()

        # Require link-key, and convert it to requestId.
        linkKeyRec = linkKey.LinkKey.get_by_id(linkKeyString)
        logging.debug(
            LogMessage('SubmitEditRequest', 'linkKeyRec=', linkKeyRec))

        if linkKeyRec is None:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage='linkKey not found')
        if linkKeyRec.destinationType != conf.REQUEST_CLASS_NAME:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage='linkKey not a request')
        requestId = int(linkKeyRec.destinationId)
        logging.debug(LogMessage('SubmitEditRequest', 'requestId=', requestId))

        if linkKeyRec.loginRequired and not cookieData.loginId:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.NO_LOGIN)

        # Check request length.
        if not httpServer.isLengthOk(title, detail, conf.minLengthRequest):
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.TOO_SHORT)

        # Retrieve request record.
        requestForProposalsRec = requestForProposals.RequestForProposals.get_by_id(
            requestId)
        logging.debug(
            LogMessage('SubmitEditRequest', 'requestForProposalsRec=',
                       requestForProposalsRec))
        if requestForProposalsRec is None:
            return httpServer.outputJson(
                cookieData,
                responseData,
                self.response,
                errorMessage='requestForProposalsRec not found')

        # Verify that request is editable.
        if userId != requestForProposalsRec.creator:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.NOT_OWNER)
        if not requestForProposalsRec.allowEdit:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.HAS_RESPONSES)
        if requestForProposalsRec.freezeUserInput:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.FROZEN)

        # Update request record.
        requestForProposalsRec.title = title
        requestForProposalsRec.detail = detail
        requestForProposalsRec.put()

        linkKeyDisplay = httpServer.linkKeyToDisplay(linkKeyRec)
        requestDisplay = httpServer.requestToDisplay(requestForProposalsRec,
                                                     userId)
        responseData.update({
            'success': True,
            'linkKey': linkKeyDisplay,
            'request': requestDisplay
        })
        httpServer.outputJson(cookieData, responseData, self.response)
예제 #11
0
    def post(
        self
    ):  # Not a transaction, because it is ok to fail link creation, and orphan the request.

        logging.debug(
            LogMessage('SubmitNewRequest', 'request.body=', self.request.body))

        # Collect inputs
        requestLogId = os.environ.get(conf.REQUEST_LOG_ID)
        inputData = json.loads(self.request.body)
        logging.debug(LogMessage('SubmitNewRequest', 'inputData=', inputData))

        title = text.formTextToStored(inputData.get('title', ''))
        detail = text.formTextToStored(inputData.get('detail', ''))
        loginRequired = bool(inputData.get('loginRequired', False))
        experimentalPassword = inputData.get('experimentalPassword', None)
        hideReasons = bool(inputData.get('hideReasons', False))
        browserCrumb = inputData.get('crumb', '')
        loginCrumb = inputData.get('crumbForLogin', '')
        logging.debug(
            LogMessage('SubmitNewRequest', 'title=', title, 'detail=', detail,
                       'browserCrumb=', browserCrumb, 'loginCrumb=',
                       loginCrumb, 'loginRequired=', loginRequired,
                       'hideReasons=', hideReasons))

        # User id from cookie, crumb...
        responseData = {'success': False, 'requestLogId': requestLogId}
        cookieData = httpServer.validate(self.request,
                                         inputData,
                                         responseData,
                                         self.response,
                                         loginRequired=loginRequired)
        if not cookieData.valid(): return
        userId = cookieData.id()

        # Check request length
        if not httpServer.isLengthOk(title, detail, conf.minLengthRequest):
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.TOO_SHORT)

        # Check experimental password (low-risk secret)
        if (hideReasons or loginRequired or experimentalPassword) and (
                experimentalPassword != secrets.experimentalPassword):
            return httpServer.outputJson(
                cookieData,
                responseData,
                self.response,
                errorMessage=conf.EXPERIMENT_NOT_AUTHORIZED)

        # Construct new request record
        requestRecord = requestForProposals.RequestForProposals(
            creator=userId,
            title=title,
            detail=detail,
            allowEdit=True,
            hideReasons=hideReasons)
        # Store request record
        requestRecordKey = requestRecord.put()
        logging.debug(
            LogMessage('SubmitNewRequest', 'requestRecordKey.id=',
                       requestRecordKey.id()))

        # Construct and store link key.
        requestId = str(requestRecordKey.id())
        linkKeyRecord = httpServer.createAndStoreLinkKey(
            conf.REQUEST_CLASS_NAME, requestId, loginRequired, cookieData)

        # Send response data.
        linkKeyDisplay = httpServer.linkKeyToDisplay(linkKeyRecord)
        requestDisplay = httpServer.requestToDisplay(requestRecord, userId)
        responseData.update({
            'success': True,
            'linkKey': linkKeyDisplay,
            'request': requestDisplay
        })
        httpServer.outputJson(cookieData, responseData, self.response)
예제 #12
0
    def post(
        self
    ):  # Not a transaction, because it is ok to fail link creation, and orphan the request.

        logging.debug('SubmitNewRequest.post() request.body=' +
                      self.request.body)

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

        title = text.formTextToStored(inputData.get('title', ''))
        detail = text.formTextToStored(inputData.get('detail', ''))
        loginRequired = inputData.get('loginRequired', False)
        browserCrumb = inputData.get('crumb', '')
        loginCrumb = inputData.get('crumbForLogin', '')
        logging.debug('SubmitNewRequest.post() title=' + str(title) +
                      ' detail=' + str(detail) + ' browserCrumb=' +
                      str(browserCrumb) + ' loginCrumb=' + str(loginCrumb) +
                      ' loginRequired=' + str(loginRequired))

        # User id from cookie, crumb...
        responseData = {'success': False, 'requestLogId': requestLogId}
        cookieData = httpServer.validate(self.request,
                                         inputData,
                                         responseData,
                                         self.response,
                                         loginRequired=loginRequired)
        if not cookieData.valid(): return
        userId = cookieData.id()

        # Check request length
        if not httpServer.isLengthOk(title, detail, conf.minLengthRequest):
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.TOO_SHORT)

        # Construct new request record
        requestRecord = requestForProposals.RequestForProposals(
            creator=userId,
            title=title,
            detail=detail,
            allowEdit=True,
        )
        # Store request record
        requestRecordKey = requestRecord.put()
        logging.debug('requestRecordKey.id={}'.format(requestRecordKey.id()))

        # Construct and store link key.
        requestId = str(requestRecordKey.id())
        linkKeyRecord = httpServer.createAndStoreLinkKey(
            conf.REQUEST_CLASS_NAME, requestId, loginRequired, cookieData)

        # Send response data.
        linkKeyDisplay = httpServer.linkKeyToDisplay(linkKeyRecord)
        requestDisplay = httpServer.requestToDisplay(requestRecord, userId)
        responseData.update({
            'success': True,
            'linkKey': linkKeyDisplay,
            'request': requestDisplay
        })
        httpServer.outputJson(cookieData, responseData, self.response)
예제 #13
0
    def post(self):
        logging.debug(
            ('SubmitEditQuestion.post()', 'request.body=', self.request.body))

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

        content = text.formTextToStored(inputData['content'])
        linkKeyString = inputData['linkKey']
        questionId = inputData.get(
            'questionId',
            None)  # Allow questionId=null, which creates new question
        questionId = str(int(questionId)) if questionId else None
        browserCrumb = inputData.get('crumb', None)
        loginCrumb = inputData.get('crumbForLogin', None)
        logging.debug(
            ('SubmitEditQuestion.post()', 'content=', content, 'browserCrumb=',
             browserCrumb, 'loginCrumb=', loginCrumb, 'linkKeyString=',
             linkKeyString, 'questionId=', questionId))

        responseData = {'success': False, 'requestLogId': requestLogId}
        cookieData = httpServer.validate(self.request, inputData, responseData,
                                         self.response)
        if not cookieData.valid(): return
        userId = cookieData.id()

        # Retrieve link-key record
        if linkKeyString is None:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage='linkKeyString is null')
        linkKeyRecord = linkKey.LinkKey.get_by_id(linkKeyString)
        logging.debug(
            ('SubmitEditQuestion.post()', 'linkKeyRecord=', linkKeyRecord))

        if linkKeyRecord is None:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage='linkKey not found')
        if linkKeyRecord.destinationType != conf.SURVEY_CLASS_NAME:
            return httpServer.outputJson(
                cookieData,
                responseData,
                self.response,
                errorMessage='linkKey destinationType=' +
                str(linkKeyRecord.destinationType))
        surveyId = linkKeyRecord.destinationId
        loginRequired = linkKeyRecord.loginRequired

        if linkKeyRecord.loginRequired and not cookieData.loginId:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.NO_LOGIN)

        # Check question length
        if not httpServer.isLengthOk(content, '', conf.minLengthQuestion):
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.TOO_SHORT)

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

        # Retrieve question record
        # If question record exists...
        if questionId:
            questionRec = question.Question.get_by_id(int(questionId))
            logging.debug(
                ('SubmitEditQuestion.post()', 'questionRec=', questionRec))

            if questionRec is None:
                return httpServer.outputJson(cookieData,
                                             responseData,
                                             self.response,
                                             errorMessage='question not found')
            if questionRec.surveyId != linkKeyRecord.destinationId:
                return httpServer.outputJson(
                    cookieData,
                    responseData,
                    self.response,
                    errorMessage=
                    'questionRec.surveyId != linkKeyRecord.destinationId')

            # Verify that question is editable
            if userId != questionRec.creator:
                return httpServer.outputJson(cookieData,
                                             responseData,
                                             self.response,
                                             errorMessage=conf.NOT_OWNER)
            if not questionRec.allowEdit:
                return httpServer.outputJson(cookieData,
                                             responseData,
                                             self.response,
                                             errorMessage=conf.HAS_RESPONSES)

            # Update question record.
            questionRec.content = content
            questionRec.put()

        # If question record does not exist...
        else:
            # Create question record
            questionRec = question.Question(surveyId=surveyId,
                                            creator=userId,
                                            content=content,
                                            allowEdit=True)
            questionKey = questionRec.put()
            questionId = str(questionKey.id())

            # Add question id to survey
            # If question is created but survey fails, then question will be orphaned.  Alternatively, use a transaction.
            questionIds = list(surveyRec.questionIds)
            questionIds.append(questionId)
            surveyRec.questionIds = questionIds  # Use property assignment for immediate value checking
            surveyRec.put()

        # Display updated question.
        questionDisplay = httpServerAutocomplete.questionToDisplay(
            questionRec, userId)
        responseData.update({'success': True, 'question': questionDisplay})
        httpServer.outputJson(cookieData, responseData, self.response)
예제 #14
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)
예제 #15
0
    def post(self):

        logging.debug('SubmitNewProposalForRequest.post() request.body=' +
                      self.request.body)

        # Collect inputs
        requestLogId = os.environ.get(conf.REQUEST_LOG_ID)
        responseData = {'success': False, 'requestLogId': requestLogId}
        inputData = json.loads(self.request.body)
        logging.debug('SubmitNewProposalForRequest.post() inputData=' +
                      str(inputData))

        requestLinkKeyStr = inputData['requestId']
        title = text.formTextToStored(inputData['title'])
        detail = text.formTextToStored(inputData['detail'])
        initialReason1 = text.formTextToStored(
            inputData.get('initialReason1', None))
        initialReason2 = text.formTextToStored(
            inputData.get('initialReason2', None))
        initialReason3 = text.formTextToStored(
            inputData.get('initialReason3', None))
        browserCrumb = inputData['crumb']
        loginCrumb = inputData.get('crumbForLogin', '')
        logging.debug('SubmitNewProposalForRequest.post() requestLinkKeyStr=' +
                      str(requestLinkKeyStr) + ' title=' + str(title) +
                      ' detail=' + str(detail) + ' browserCrumb=' +
                      str(browserCrumb) + ' loginCrumb=' + str(loginCrumb))

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

        # Check proposal length
        if not httpServer.isLengthOk(title, detail, conf.minLengthProposal):
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.TOO_SHORT)
        initialReasons = [
            r for r in [initialReason1, initialReason2, initialReason3]
            if r is not None
        ]
        for initialReason in initialReasons:
            if initialReason is not None and not httpServer.isLengthOk(
                    initialReason, None, conf.minLengthReason):
                httpServer.outputJsonError(conf.REASON_TOO_SHORT, responseData,
                                           self.response)
                return

        # Require link-key, and convert it to requestId.
        if requestLinkKeyStr is None:
            httpServer.outputJsonError('requestLinkKeyStr is null',
                                       responseData, self.response)
            return
        requestLinkKeyRec = linkKey.LinkKey.get_by_id(requestLinkKeyStr)
        logging.debug('SubmitNewProposalForRequest.post() requestLinkKeyRec=' +
                      str(requestLinkKeyRec))

        if requestLinkKeyRec is None:
            httpServer.outputJsonError('requestLinkKey not found',
                                       responseData, self.response)
            return
        if requestLinkKeyRec.destinationType != conf.REQUEST_CLASS_NAME:
            httpServer.outputJsonError('requestLinkKey not a request',
                                       responseData, self.response)
            return
        requestId = requestLinkKeyRec.destinationId

        if requestLinkKeyRec.loginRequired and not cookieData.loginId:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.NO_LOGIN)

        # Get user id from cookie
        requestRec = requestForProposals.RequestForProposals.get_by_id(
            int(requestId))
        if not requestRec: return

        # Construct new proposal record
        proposalRecord = proposal.Proposal(
            requestId=requestId,
            creator=userId,
            title=title,
            detail=detail,
            allowEdit=(len(initialReasons) == 0))
        # Store proposal record
        proposalRecordKey = proposalRecord.put()
        proposalId = str(proposalRecordKey.id())
        logging.debug('proposalRecordKey.id={}'.format(proposalRecordKey.id()))

        # For each initial reason...
        reasonDisplays = []
        for initialReason in initialReasons:
            # Construct new reason record.
            reasonRecord = reason.Reason(requestId=requestId,
                                         proposalId=proposalId,
                                         creator=userId,
                                         proOrCon=conf.PRO,
                                         content=initialReason,
                                         allowEdit=True)
            # Store reason record.
            reasonRecordKey = reasonRecord.put()
            logging.debug('reasonRecordKey={}'.format(reasonRecordKey))

            # Convert reason for display.
            reasonDisplays.append(
                httpServer.reasonToDisplay(reasonRecord, userId))

        # Display proposal.
        proposalDisplay = httpServer.proposalToDisplay(proposalRecord, userId)
        responseData.update({
            'success': True,
            'proposal': proposalDisplay,
            'reasons': reasonDisplays
        })
        httpServer.outputJson(cookieData, responseData, self.response)

        # Mark request-for-proposals as not editable.
        if (requestRec.allowEdit):
            requestForProposals.setEditable(requestId, False)
예제 #16
0
    def post(self):
        logging.debug('SubmitEditReason.post() request.body=' +
                      self.request.body)

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

        linkKeyStr = inputData.get('linkKey', None)
        reasonId = str(int(inputData.get('reasonId', None)))
        reasonContent = text.formTextToStored(inputData.get(
            'inputContent', ''))
        browserCrumb = inputData.get('crumb', '')
        loginCrumb = inputData.get('crumbForLogin', '')
        logging.debug('SubmitEditReason.post() linkKeyStr=' + str(linkKeyStr) +
                      ' reasonId=' + str(reasonId) + ' reasonContent=' +
                      str(reasonContent) + ' browserCrumb=' +
                      str(browserCrumb) + ' loginCrumb=' + str(loginCrumb))

        # User id from cookie, crumb...
        responseData = {'success': False, 'requestLogId': requestLogId}
        cookieData = httpServer.validate(self.request, inputData, responseData,
                                         self.response)
        if not cookieData.valid(): return
        userId = cookieData.id()

        # Check reason length.
        if not httpServer.isLengthOk(reasonContent, '', conf.minLengthReason):
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.TOO_SHORT)

        # Retrieve link-key record
        linkKeyRec = linkKey.LinkKey.get_by_id(linkKeyStr)
        if linkKeyRec is None:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage='linkKey not found')
        logging.debug('SubmitEditReason.post() linkKeyRec=' + str(linkKeyRec))

        if linkKeyRec.loginRequired and not cookieData.loginId:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.NO_LOGIN)

        # Verify that reason belongs to request.
        reasonRec = reason.Reason.get_by_id(int(reasonId))
        if reasonRec is None:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage='reason not found')
        logging.debug('SubmitEditReason.post() reasonRec=' + str(reasonRec))

        # Check link key
        if linkKeyRec.destinationType == conf.PROPOSAL_CLASS_NAME:
            # Verify that reason belongs to linkKey's proposal.
            if reasonRec.proposalId != linkKeyRec.destinationId:
                return httpServer.outputJson(
                    cookieData,
                    responseData,
                    self.response,
                    errorMessage=
                    'reasonRec.proposalId != linkKeyRec.destinationId')

        elif linkKeyRec.destinationType == conf.REQUEST_CLASS_NAME:
            # Verify that reason belongs to linkKey's request.
            if reasonRec.requestId != linkKeyRec.destinationId:
                return httpServer.outputJson(
                    cookieData,
                    responseData,
                    self.response,
                    errorMessage=
                    'reasonRec.requestId != linkKeyRec.destinationId')

        else:
            httpServer.outputJson(cookieData,
                                  responseData,
                                  self.response,
                                  errorMessage='linkKey destinationType=' +
                                  linkKeyRec.destinationType)

        # Verify that proposal is editable
        if userId != reasonRec.creator:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.NOT_OWNER)
        if not reasonRec.allowEdit:
            httpServer.outputJson(cookieData,
                                  responseData,
                                  self.response,
                                  errorMessage=conf.HAS_RESPONSES)

        # Update reason record.
        reasonRec.content = reasonContent
        reasonRec.put()

        # Display reason.
        reasonDisplay = httpServer.reasonToDisplay(reasonRec, userId)
        responseData.update({'success': True, 'reason': reasonDisplay})
        httpServer.outputJson(cookieData, responseData, self.response)
예제 #17
0
def standardizeContent( content ):
    content = text.formTextToStored( content ) if content  else None
    content = content.strip(' \n\r\x0b\x0c') if content  else None    # Keep TAB to delimit slice-title from reason
    return content if content  else None
예제 #18
0
    def post(self):

        logging.debug('SubmitNewReason.post() request.body=' +
                      self.request.body)

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

        linkKeyStr = inputData.get('linkKey', None)
        proposalId = str(int(inputData.get('proposalId', None)))
        proOrCon = inputData.get('proOrCon', None)
        reasonContent = text.formTextToStored(
            inputData.get('reasonContent', ''))
        browserCrumb = inputData.get('crumb', '')
        loginCrumb = inputData.get('crumbForLogin', '')
        logging.debug('SubmitNewReason.post() linkKeyStr=' + str(linkKeyStr) +
                      ' proposalId=' + str(proposalId) + ' proOrCon=' +
                      str(proOrCon) + ' reasonContent=' + str(reasonContent) +
                      ' browserCrumb=' + str(browserCrumb) + loginCrumb +
                      str(loginCrumb))

        # User id from cookie, crumb...
        responseData = {'success': False, 'requestLogId': requestLogId}
        cookieData = httpServer.validate(self.request, inputData, responseData,
                                         self.response)
        if not cookieData.valid(): return
        userId = cookieData.id()

        # Check reason length.
        if not httpServer.isLengthOk(reasonContent, '', conf.minLengthReason):
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.TOO_SHORT)

        # Retrieve link-key record
        linkKeyRec = linkKey.LinkKey.get_by_id(linkKeyStr)
        if linkKeyRec is None:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage='linkKey not found')
        logging.debug('SubmitNewReason.post() linkKeyRec=' + str(linkKeyRec))

        if linkKeyRec.loginRequired and not cookieData.loginId:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.NO_LOGIN)

        # Retrieve proposal record
        proposalRec = proposal.Proposal.get_by_id(int(proposalId))
        if proposalRec is None:
            return httpServer.outputJson(cookieDataresponseData,
                                         self.response,
                                         errorMessage='proposal not found')
        logging.debug('SubmitNewReason.post() proposalRec=' + str(proposalRec))

        # Check link key
        requestId = None
        if linkKeyRec.destinationType == conf.PROPOSAL_CLASS_NAME:
            # Verify that reason belongs to linkKey's proposal.
            if proposalId != linkKeyRec.destinationId:
                return httpServer.outputJson(
                    cookieData,
                    responseData,
                    self.response,
                    errorMessage='proposalId != linkKeyRec.destinationId')

        elif linkKeyRec.destinationType == conf.REQUEST_CLASS_NAME:
            # Verify that reason belongs to linkKey's request, via proposal record.
            requestId = proposalRec.requestId
            if requestId != linkKeyRec.destinationId:
                return httpServer.outputJson(
                    cookieData,
                    responseData,
                    self.response,
                    errorMessage='requestId != linkKeyRec.destinationId')
        else:
            return httpServer.outputJson(
                cookieData,
                responseData,
                self.response,
                errorMessage='linkKey destinationType=' +
                linkKeyRec.destinationType)

        # Construct new reason record
        reasonRecord = reason.Reason(requestId=requestId,
                                     proposalId=proposalId,
                                     creator=userId,
                                     proOrCon=proOrCon,
                                     content=reasonContent,
                                     allowEdit=True)
        # Store reason record
        reasonRecordKey = reasonRecord.put()
        logging.debug('reasonRecordKey={}'.format(reasonRecordKey))

        # Display reason
        reasonDisplay = httpServer.reasonToDisplay(reasonRecord, userId)
        responseData.update({'success': True, 'reason': reasonDisplay})
        httpServer.outputJson(cookieData, responseData, self.response)

        # Mark proposal as not editable.
        if proposalRec.allowEdit:
            proposal.setEditable(proposalId, False)
예제 #19
0
    def post(self):

        logging.debug(
            LogMessage('SubmitNewReason', 'request.body=', self.request.body))

        # Collect inputs
        requestLogId = os.environ.get(conf.REQUEST_LOG_ID)
        inputData = json.loads(self.request.body)
        logging.debug(LogMessage('SubmitNewReason', 'inputData=', inputData))

        linkKeyStr = inputData.get('linkKey', None)
        proposalId = str(int(inputData.get('proposalId', None)))
        proOrCon = inputData.get('proOrCon', None)
        reasonContent = text.formTextToStored(
            inputData.get('reasonContent', ''))
        browserCrumb = inputData.get('crumb', '')
        loginCrumb = inputData.get('crumbForLogin', '')
        logging.debug(
            LogMessage('SubmitNewReason', 'linkKeyStr=', linkKeyStr,
                       'proposalId=', proposalId, 'proOrCon=', proOrCon,
                       'reasonContent=', reasonContent, 'browserCrumb=',
                       browserCrumb, 'loginCrumb=', loginCrumb))

        # User id from cookie, crumb...
        responseData = {'success': False, 'requestLogId': requestLogId}
        cookieData = httpServer.validate(self.request, inputData, responseData,
                                         self.response)
        if not cookieData.valid(): return
        userId = cookieData.id()

        # Check reason length.
        if not httpServer.isLengthOk(reasonContent, '', conf.minLengthReason):
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.TOO_SHORT)

        # Retrieve link-key record
        linkKeyRec = linkKey.LinkKey.get_by_id(linkKeyStr)
        if linkKeyRec is None:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage='linkKey not found')
        logging.debug(LogMessage('SubmitNewReason', 'linkKeyRec=', linkKeyRec))

        if linkKeyRec.loginRequired and not cookieData.loginId:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.NO_LOGIN)

        # Retrieve proposal record
        proposalRec = proposal.Proposal.get_by_id(int(proposalId))
        if proposalRec is None:
            return httpServer.outputJson(cookieDataresponseData,
                                         self.response,
                                         errorMessage='proposal not found')
        logging.debug(
            LogMessage('SubmitNewReason', 'proposalRec=', proposalRec))

        # Verify that reason belongs to linkKey's request/proposal, and check whether frozen
        requestId = None
        if linkKeyRec.destinationType == conf.PROPOSAL_CLASS_NAME:
            if proposalId != linkKeyRec.destinationId:
                return httpServer.outputJson(
                    cookieData,
                    responseData,
                    self.response,
                    errorMessage='proposalId != linkKeyRec.destinationId')
            if proposalRec.hideReasons:
                return httpServer.outputJson(cookieData,
                                             responseData,
                                             self.response,
                                             errorMessage='reasons hidden')
            if proposalRec.freezeUserInput:
                return httpServer.outputJson(cookieData,
                                             responseData,
                                             self.response,
                                             errorMessage=conf.FROZEN)

        elif linkKeyRec.destinationType == conf.REQUEST_CLASS_NAME:
            requestId = proposalRec.requestId
            if requestId != linkKeyRec.destinationId:
                return httpServer.outputJson(
                    cookieData,
                    responseData,
                    self.response,
                    errorMessage='requestId != linkKeyRec.destinationId')
            # Retrieve request-for-proposals, and check whether frozen
            requestRec = requestForProposals.RequestForProposals.get_by_id(
                int(requestId))
            if not requestRec:
                return httpServer.outputJson(cookieData,
                                             responseData,
                                             self.response,
                                             errorMessage='requestRec is null')
            if requestRec.hideReasons:
                return httpServer.outputJson(cookieData,
                                             responseData,
                                             self.response,
                                             errorMessage='reasons hidden')
            if requestRec.freezeUserInput:
                return httpServer.outputJson(cookieData,
                                             responseData,
                                             self.response,
                                             errorMessage=conf.FROZEN)

        else:
            return httpServer.outputJson(
                cookieData,
                responseData,
                self.response,
                errorMessage='linkKey destinationType=' +
                linkKeyRec.destinationType)

        # Retrieve any existing identical reason, to prevent duplicates
        existingReasons = reason.Reason.query(
            reason.Reason.requestId == requestId,
            reason.Reason.proposalId == proposalId,
            reason.Reason.proOrCon == proOrCon,
            reason.Reason.content == reasonContent).fetch(1)
        if existingReasons:
            return httpServer.outputJson(cookieData,
                                         responseData,
                                         self.response,
                                         errorMessage=conf.DUPLICATE)

        # Construct new reason record
        reasonRecord = reason.Reason(requestId=requestId,
                                     proposalId=proposalId,
                                     creator=userId,
                                     proOrCon=proOrCon,
                                     allowEdit=True)
        reasonRecord.setContent(reasonContent)
        # Store reason record
        reasonRecordKey = reasonRecord.put()
        logging.debug(
            LogMessage('SubmitNewReason', 'reasonRecordKey=', reasonRecordKey))

        # Display reason
        reasonDisplay = httpServer.reasonToDisplay(reasonRecord, userId)
        responseData.update({'success': True, 'reason': reasonDisplay})
        httpServer.outputJson(cookieData, responseData, self.response)

        # Mark proposal as not editable.
        if proposalRec.allowEdit:
            proposal.setEditable(proposalId, False)
예제 #20
0
    def post(self):

        logging.debug('SubmitNewProposal.post() request.body=' +
                      self.request.body)

        # Collect inputs
        requestLogId = os.environ.get(conf.REQUEST_LOG_ID)
        responseData = {'success': False, 'requestLogId': requestLogId}
        inputData = json.loads(self.request.body)
        logging.debug('SubmitNewProposal.post() inputData=' + str(inputData))

        title = text.formTextToStored(inputData.get('title', ''))
        detail = text.formTextToStored(inputData.get('detail', ''))
        loginRequired = inputData.get('loginRequired', False)
        browserCrumb = inputData.get('crumb', '')
        loginCrumb = inputData.get('crumbForLogin', '')
        logging.debug('SubmitNewProposal.post() title=' + str(title) +
                      ' detail=' + str(detail) + ' browserCrumb=' +
                      str(browserCrumb) + ' loginCrumb=' + str(loginCrumb) +
                      ' loginRequired=' + str(loginRequired))

        # Voter login not required to create initial proposal, though login may be required to use proposal
        cookieData = httpServer.validate(self.request,
                                         inputData,
                                         responseData,
                                         self.response,
                                         loginRequired=loginRequired)
        if not cookieData.valid(): return
        userId = cookieData.id()

        # Check proposal length.
        if not httpServer.isLengthOk(title, detail, conf.minLengthProposal):
            return httpServer.outputJson(responseData,
                                         self.response,
                                         errorMessage=conf.TOO_SHORT)

        # Construct new proposal record.
        proposalRecord = proposal.Proposal(
            creator=userId,
            title=title,
            detail=detail,
            allowEdit=True,
        )
        # Store proposal record.
        proposalRecordKey = proposalRecord.put()
        logging.debug('proposalRecordKey.id={}'.format(proposalRecordKey.id()))

        # Construct and store link key.
        proposalId = str(proposalRecordKey.id())
        proposalLinkKeyRecord = httpServer.createAndStoreLinkKey(
            conf.PROPOSAL_CLASS_NAME, proposalId, loginRequired, cookieData)

        # Display proposal
        linkKeyDisplay = httpServer.linkKeyToDisplay(proposalLinkKeyRecord)
        proposalDisplay = httpServer.proposalToDisplay(proposalRecord, userId)
        responseData.update({
            'success': True,
            'linkKey': linkKeyDisplay,
            'proposal': proposalDisplay
        })
        httpServer.outputJson(cookieData, responseData, self.response)