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)
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 )
def post(self): logging.debug('SetAnswer.post() request.body=' + self.request.body) # Collect inputs requestLogId = os.environ.get(conf.REQUEST_LOG_ID) inputData = json.loads(self.request.body) logging.debug('SetAnswer.post() inputData=' + str(inputData)) content = answer.standardizeContent(inputData.get('content', None)) linkKeyString = inputData['linkKey'] questionId = str(int(inputData['questionId'])) browserCrumb = inputData.get('crumb', None) logging.debug('SetAnswer.post() content=' + str(content) + ' browserCrumb=' + str(browserCrumb) + ' 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() surveyId, loginRequired = retrieveSurveyIdFromLinkKey( cookieData, linkKeyString, responseData, self.response) if surveyId is None: return # Check answer length if (content is not None) and not httpServer.isLengthOk( content, '', conf.minLengthAnswer): return httpServer.outputJson(cookieData, responseData, self.response, errorMessage=conf.TOO_SHORT) # Retrieve question record. questionRec = question.Question.get_by_id(int(questionId)) logging.debug('SetAnswer.post() questionRec=' + str(questionRec)) if questionRec is None: return httpServer.outputJson(cookieData, responseData, self.response, errorMessage='question not found') if questionRec.surveyId != surveyId: return httpServer.outputJson( cookieData, responseData, self.response, errorMessage='questionRec.surveyId != surveyId') # Update answer and vote. answerRec, voteRecord = answer.vote(questionId, surveyId, content, userId, questionRec.creator) # Display updated answer. responseData.update({'success': True, 'answerContent': content}) httpServer.outputJson(cookieData, responseData, self.response)
def post(self): logging.debug(('SetAnswer', 'request.body=', self.request.body)) # Collect inputs requestLogId = os.environ.get( conf.REQUEST_LOG_ID ) inputData = json.loads( self.request.body ) logging.debug(('SetAnswer', 'inputData=', inputData)) content = answer.standardizeContent( inputData.get( 'content', None ) ) linkKeyString = inputData['linkKey'] questionId = str( int( inputData['questionId'] ) ) browserCrumb = inputData.get( 'crumb', None ) logging.debug(('SetAnswer', 'content=', content, 'browserCrumb=', browserCrumb, 'linkKeyString=', 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 surveyId, loginRequired = retrieveSurveyIdFromLinkKey( cookieData, linkKeyString, responseData, self.response ) if surveyId is None: return # Check answer length if ( content is not None ) and not httpServer.isLengthOk( content, '', conf.minLengthAnswer ): return httpServer.outputJson( cookieData, responseData, self.response, errorMessage=conf.TOO_SHORT ) # Retrieve survey record to check whether survey is frozen 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.freezeUserInput: return httpServer.outputJson( cookieData, responseData, self.response, errorMessage=conf.FROZEN ) # Require that answer and reason both exist, or both can be empty answerStr, reason = answer.parseAnswerAndReason( content ) if surveyRec.hideReasons and reason: return httpServer.outputJson( cookieData, responseData, self.response, errorMessage='reasons hidden' ) if (not answerStr) and reason: return httpServer.outputJson( cookieData, responseData, self.response, errorMessage=conf.TOO_SHORT ) if answerStr and (not reason) and (not surveyRec.hideReasons): return httpServer.outputJson( cookieData, responseData, self.response, errorMessage=conf.REASON_TOO_SHORT ) # Retrieve question record. questionRec = question.Question.get_by_id( int(questionId) ) logging.debug(('SetAnswer', 'questionRec=', questionRec)) if questionRec is None: return httpServer.outputJson( cookieData, responseData, self.response, errorMessage='question not found' ) if questionRec.surveyId != surveyId: return httpServer.outputJson( cookieData, responseData, self.response, errorMessage='questionRec.surveyId != surveyId' ) # Update answer and vote. answerRec, voteRecord = answer.vote( questionId, surveyId, content, userId, questionRec.creator ) # Display updated answer. responseData.update( { 'success':True, 'answerContent':content } ) httpServer.outputJson( cookieData, responseData, self.response )
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)