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)
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 get(self, linkKeyStr, proposalId): logging.debug('getProposalData.GetProposalData() linkKeyStr=' + linkKeyStr + ' proposalId=' + str(proposalId)) # Collect inputs. onlyTopReasons = (self.request.get('onlyTop', None) == 'true') logging.debug('onlyTopReasons=' + str(onlyTopReasons)) httpRequestId = os.environ.get(conf.REQUEST_LOG_ID) responseData = {'success': False, 'httpRequestId': httpRequestId} cookieData = httpServer.validate(self.request, self.request.GET, responseData, self.response, idRequired=False) userId = cookieData.id() # Retrieve and check linkKey. linkKeyRecord = linkKey.LinkKey.get_by_id(linkKeyStr) requestId = None if linkKeyRecord is None: logging.debug('linkKeyRecord is None') return httpServer.outputJson(cookieData, responseData, self.response, errorMessage=conf.BAD_LINK) elif linkKeyRecord.destinationType == conf.PROPOSAL_CLASS_NAME: proposalId = linkKeyRecord.destinationId elif linkKeyRecord.destinationType == conf.REQUEST_CLASS_NAME: requestId = linkKeyRecord.destinationId else: logging.debug('linkKeyRecord has unhandled destinationType=' + str(linkKeyRecord.destinationType)) return httpServer.outputJson(cookieData, responseData, self.response, errorMessage=conf.BAD_LINK) # Retrieve Proposal by id, filter/transform fields for display. proposalRecord = proposal.Proposal.get_by_id(int(proposalId)) logging.debug('GetProposalData() proposalRecord=' + str(proposalRecord)) if proposalRecord.requestId != requestId: logging.debug('proposalRecord.requestId=' + str(proposalRecord.requestId) + ' != requestId=' + str(requestId)) return httpServer.outputJson(cookieData, responseData, self.response, errorMessage=conf.BAD_LINK) proposalDisp = httpServer.proposalToDisplay(proposalRecord, userId) logging.debug('GetProposalData() proposalDisp=' + str(proposalDisp)) # Prepare parallel retrieve reasons, with votes. if onlyTopReasons: reasonRecordsFutures = reason.retrieveTopReasonsAsync( proposalId, conf.MAX_TOP_REASONS) else: reasonRecordsFutures = [ reason.Reason.query( reason.Reason.proposalId == proposalId).fetch_async() ] # If userId exists... retrieve user's ReasonVotes by KeyProperty proposalId x userId. voteRecordsFuture = reasonVote.ReasonVote.query( reasonVote.ReasonVote.proposalId == proposalId, reasonVote.ReasonVote.userId == userId).fetch_async() if userId else None # Run parallel retrieval. Filter/transform fields for display. linkKeyDisplay = httpServer.linkKeyToDisplay(linkKeyRecord) logging.debug('GetProposalData() linkKeyDisplay=' + str(linkKeyDisplay)) reasonRecords = reason.fetchReasonRecordsFutures(reasonRecordsFutures) logging.debug('GetProposalData() reasonRecords=' + str(reasonRecords)) reasonDisps = [ httpServer.reasonToDisplay(r, userId) for r in reasonRecords ] logging.debug('GetProposalData() reasonDisps=' + str(reasonDisps)) voteRecords = voteRecordsFuture.get_result( ) if voteRecordsFuture else None logging.debug('GetProposalData() voteRecords=' + str(voteRecords)) # For each reason... lookup user vote ... set reason.myVote reasonToVoteRec = {v.reasonId: v for v in voteRecords} if voteRecords else {} logging.debug('GetProposalData() reasonToVoteRec=' + str(reasonToVoteRec)) for r in reasonDisps: voteRec = reasonToVoteRec.get(r['id']) r['myVote'] = voteRec.voteUp if voteRec else False # Store proposal to user's recent (cookie). user.storeRecentLinkKey(linkKeyStr, cookieData) # Display proposal data. responseData = { 'success': True, 'linkKey': linkKeyDisplay, 'proposal': proposalDisp, 'reasons': reasonDisps, } logging.debug( 'GetProposalData() responseData=' + json.dumps(responseData, indent=4, separators=(', ', ':'))) httpServer.outputJson(cookieData, responseData, self.response)
def get(self, linkKeyStr): logging.debug('linkKeyStr=' + linkKeyStr) # Collect inputs cursor = self.request.get('cursor', None) cursor = Cursor(urlsafe=cursor) if cursor else None getReasons = (self.request.get('getReasons', 'true') == 'true') logging.debug('getReasons=' + str(getReasons)) httpRequestId = os.environ.get(conf.REQUEST_LOG_ID) responseData = {'success': False, 'httpRequestId': httpRequestId} cookieData = httpServer.validate(self.request, self.request.GET, responseData, self.response, idRequired=False) userId = cookieData.id() # Retrieve requestId from linkKey. destinationType must be RequestForProposals. linkKeyRecord = linkKey.LinkKey.get_by_id(linkKeyStr) logging.debug('GetRequestData.get() linkKeyRecord=' + str(linkKeyRecord)) if (linkKeyRecord == None) or (linkKeyRecord.destinationType != conf.REQUEST_CLASS_NAME): return httpServer.outputJson(cookieData, responseData, self.response, errorMessage=conf.BAD_LINK) # Retrieve RequestForProposal by id, filter/transform fields for display. requestId = linkKeyRecord.destinationId requestRecordFuture = requestForProposals.RequestForProposals.get_by_id_async( int(requestId)) requestRecord = requestRecordFuture.get_result( ) if requestRecordFuture else None logging.debug('GetRequestData.get() userId=' + str(userId) + ' requestRecord.creator=' + str(requestRecord.creator)) # If userId exists... async-retrieve user's ReasonVotes by KeyProperty requestId x userId. voteRecordsFuture = None if getReasons and userId: voteRecordsFuture = reasonVote.ReasonVote.query( reasonVote.ReasonVote.requestId == requestId, reasonVote.ReasonVote.userId == userId).fetch_async() # Retrieve Proposals by KeyProperty requestId # Get all data up to current page maximum length. + Refreshes earlier proposal data. maxProposals = const.INITIAL_MAX_PROPOSALS proposalRecords, cursor, hasMore = proposal.retrieveTopProposals( requestId, maxProposals, cursor=cursor) cursor = cursor.urlsafe() if cursor else None # Async-retrieve top N reasons per proposal, equal number of pro/con reasons reasonRecordsFutures = [] if getReasons: for proposalRec in proposalRecords: maxReasonsPerType = conf.MAX_TOP_REASONS / 2 proRecordsFuture, conRecordsFuture = reason.retrieveTopReasonsAsync( proposalRec.key.id(), maxReasonsPerType) reasonRecordsFutures.append(proRecordsFuture) reasonRecordsFutures.append(conRecordsFuture) # Wait for parallel retrievals logging.debug('GetRequestData.get() requestRecord=' + str(requestRecord)) reasonRecords = [] for reasonRecordsFuture in reasonRecordsFutures: reasonRecordsForProp, cursor, hasMore = reasonRecordsFuture.get_result( ) logging.debug('GetRequestData.get() reasonRecordsForProp=' + str(reasonRecordsForProp)) reasonRecords.extend(reasonRecordsForProp) reasonRecords = sorted(reasonRecords, key=lambda r: -r.score) logging.debug('GetRequestData.get() reasonRecords=' + str(reasonRecords)) voteRecords = voteRecordsFuture.get_result( ) if voteRecordsFuture else [] logging.debug('GetRequestData.get() voteRecords=' + str(voteRecords)) # Transform records for display. linkKeyDisp = httpServer.linkKeyToDisplay(linkKeyRecord) logging.debug('GetRequestData.get() linkKeyDisp=' + str(linkKeyDisp)) requestDisp = httpServer.requestToDisplay(requestRecord, userId) logging.debug('GetRequestData.get() requestDisp=' + str(requestDisp)) proposalDisps = [ httpServer.proposalToDisplay(p, userId, requestRecord=requestRecord) for p in proposalRecords ] logging.debug('GetRequestData.get() proposalDisps=' + str(proposalDisps)) reasonDisps = [ httpServer.reasonToDisplay(r, userId) for r in reasonRecords ] logging.debug('GetRequestData.get() reasonDisps=' + str(reasonDisps)) # For each reason... collect user vote in reason.myVote reasonToVoteRec = {v.reasonId: v for v in voteRecords} if voteRecords else {} logging.debug('GetRequestData.get() reasonToVoteRec=' + str(reasonToVoteRec)) for r in reasonDisps: voteRec = reasonToVoteRec.get(r['id']) r['myVote'] = voteRec.voteUp if voteRec else False # Store request to user's recent requests (cookie). user.storeRecentLinkKey(linkKeyStr, cookieData) # Display request data. responseData = { 'success': True, 'linkKey': linkKeyDisp, 'request': requestDisp, 'proposals': proposalDisps, 'reasons': reasonDisps, 'maxProposals': maxProposals, 'cursor': cursor, } logging.debug( 'GetRequestData.get() responseData=' + json.dumps(responseData, indent=4, separators=(', ', ':'))) httpServer.outputJson(cookieData, responseData, self.response)
def get(self, linkKeyStr, proposalId): if conf.isDev: logging.debug('TopReasons.get() linkKeyStr=' + str(linkKeyStr) + ' proposalId=' + str(proposalId)) # Collect inputs preview = self.request.get('preview', None) is not None cursorPro = self.request.get('cursorPro', None) cursorPro = Cursor(urlsafe=cursorPro) if cursorPro else None cursorCon = self.request.get('cursorCon', None) cursorCon = Cursor(urlsafe=cursorCon) if cursorCon else None httpRequestId = os.environ.get(conf.REQUEST_LOG_ID) responseData = {'success': False, 'httpRequestId': httpRequestId} cookieData = httpServer.validate(self.request, self.request.GET, responseData, self.response, idRequired=False) userId = cookieData.id() # Retrieve top-level records (linkKeyRecord, proposalRecord, requestRecord) = retrieveRequestAndProposal(linkKeyStr, proposalId) if not linkKeyRecord: return # Bad link proposalId = str(proposalRecord.key.id()) # Retrieve reasons and vote, in parallel voteRecordsFuture = reasonVote.ReasonVote.query( reasonVote.ReasonVote.proposalId == proposalId, reasonVote.ReasonVote.userId == userId).fetch_async() if userId else None maxReasonsPerType = (conf.MAX_TOP_REASONS / 2) if preview else 10 proRecordsFuture, conRecordsFuture = reason.retrieveTopReasonsAsync( proposalId, maxReasonsPerType, cursorPro=cursorPro, cursorCon=cursorCon) proRecords, cursorPro, morePros = proRecordsFuture.get_result() conRecords, cursorCon, moreCons = conRecordsFuture.get_result() cursorPro = cursorPro.urlsafe() if cursorPro else None cursorCon = cursorCon.urlsafe() if cursorCon else None voteRecords = voteRecordsFuture.get_result( ) if voteRecordsFuture else None # Filter/transform fields for display linkKeyDisplay = httpServer.linkKeyToDisplay(linkKeyRecord) proposalDisp = httpServer.proposalToDisplay( proposalRecord, userId, requestRecord=requestRecord) reasonDisps = [ httpServer.reasonToDisplay(r, userId) for r in (proRecords + conRecords) ] mergeReasonVotes(voteRecords, reasonDisps) # Store request/proposal to user's recent (cookie) user.storeRecentLinkKey(linkKeyStr, cookieData) # Display proposal data responseData = { 'success': True, 'linkKey': linkKeyDisplay, 'proposal': proposalDisp, 'reasons': reasonDisps, 'cursorPro': cursorPro, 'cursorCon': cursorCon } httpServer.outputJson(cookieData, responseData, self.response)
def post(self): logging.debug('SubmitVote.post() request.body=' + self.request.body) # Collect inputs requestLogId = os.environ.get(conf.REQUEST_LOG_ID) inputData = json.loads(self.request.body) logging.debug('SubmitVote.post() inputData=' + str(inputData)) linkKeyStr = inputData['linkKey'] reasonId = str(int(inputData['reasonId'])) voteUp = inputData['vote'] browserCrumb = inputData['crumb'] loginCrumb = inputData.get('crumbForLogin', '') logging.debug('SubmitVote.post() linkKeyStr=' + str(linkKeyStr) + ' reasonId=' + str(reasonId) + ' voteUp=' + str(voteUp) + ' 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() # Verify that linkKey matches request/proposal. linkKeyRec = linkKey.LinkKey.get_by_id(linkKeyStr) if linkKeyRec is None: return httpServer.outputJson(cookieData, responseData, self.response, errorMessage='linkKey not found') if linkKeyRec.destinationId is None: return httpServer.outputJson( cookieData, responseData, self.response, errorMessage='linkKey.destinationId=null') logging.debug('SubmitVote.post() linkKeyRec=' + str(linkKeyRec)) if linkKeyRec.loginRequired and not cookieData.loginId: return httpServer.outputJson(cookieData, responseData, self.response, errorMessage=conf.NO_LOGIN) reasonRecord = reason.Reason.get_by_id(int(reasonId)) if reasonRecord is None: return httpServer.outputJson(cookieData, responseData, self.response, errorMessage='reasonId not found') logging.debug('reasonRecord=' + str(reasonRecord)) isRequestForProposals = False if linkKeyRec.destinationType == conf.PROPOSAL_CLASS_NAME: # Verify that reason belongs to linkKey's proposal. if reasonRecord.proposalId != linkKeyRec.destinationId: return httpServer.outputJson( cookieData, responseData, self.response, errorMessage= 'reasonRecord.proposalId != linkKeyRec.destinationId') elif linkKeyRec.destinationType == conf.REQUEST_CLASS_NAME: # Verify that reason belongs to linkKey's request. if reasonRecord.requestId != linkKeyRec.destinationId: return httpServer.outputJson( cookieData, responseData, self.response, errorMessage= 'reasonRecord.requestId != linkKeyRec.destinationId') isRequestForProposals = True else: return httpServer.outputJson( cookieData, responseData, self.response, errorMessage='linkKey destinationType=' + linkKeyRec.destinationType) # Set vote, update vote count -- using transactions and retry. success, reasonRecordUpdated, voteRecord = reason.vote( reasonRecord.requestId, reasonRecord.proposalId, reasonId, userId, voteUp, isRequestForProposals=isRequestForProposals) logging.debug('success=' + str(success) + ' reasonRecordUpdated=' + str(reasonRecordUpdated) + ' voteRecord=' + str(voteRecord)) if not success: return httpServer.outputJson( cookieData, responseData, self.response, errorMessage='reason.vote() success=false') if reasonRecordUpdated is not None: reasonRecord = reasonRecordUpdated # Display reason and votes. reasonDisplay = httpServer.reasonToDisplay(reasonRecord, userId) reasonDisplay['myVote'] = voteRecord.voteUp and (str( voteRecord.reasonId) == str(reasonRecord.key.id())) responseData.update({'success': success, 'reason': reasonDisplay}) logging.debug('responseData=' + str(responseData)) httpServer.outputJson(cookieData, responseData, self.response) logging.debug('SubmitVote.post() done') # Mark reason as not editable. if reasonRecord.allowEdit: reason.setEditable(reasonId, False)
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('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)