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 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)
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): logging.debug( LogMessage('SubmitFreezeRequest', 'request.body=', self.request.body)) # Collect inputs requestLogId = os.environ.get(conf.REQUEST_LOG_ID) inputData = json.loads(self.request.body) logging.debug( LogMessage('SubmitFreezeRequest', 'inputData=', inputData)) freeze = bool(inputData.get('freezeUserInput', False)) linkKeyString = inputData.get('linkKey', None) logging.debug( LogMessage('SubmitFreezeRequest', 'freeze=', freeze, '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() # Retrieve link-key record linkKeyRec = linkKey.LinkKey.get_by_id(linkKeyString) logging.debug( LogMessage('SubmitFreezeRequest', '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('SubmitFreezeRequest', 'requestId=', requestId)) if linkKeyRec.loginRequired and not cookieData.loginId: return httpServer.outputJson(cookieData, responseData, self.response, errorMessage=conf.NO_LOGIN) # Retrieve request record requestForProposalsRec = requestForProposals.RequestForProposals.get_by_id( int(requestId)) logging.debug( LogMessage('SubmitFreezeRequest', 'requestForProposalsRec=', requestForProposalsRec)) if requestForProposalsRec is None: return httpServer.outputJson( cookieData, responseData, self.response, errorMessage='requestForProposalsRec not found') # Verify that user is authorized if userId != requestForProposalsRec.creator: return httpServer.outputJson(cookieData, responseData, self.response, errorMessage=conf.NOT_OWNER) # Update request record requestForProposalsRec.freezeUserInput = freeze 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 ): # 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)