Esempio n. 1
0
    def post(self, linkKeyStr, proposalId):

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

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

        reasonStart = text.formTextToStored(inputData.get('content', ''))
        httpRequestId = os.environ.get(conf.REQUEST_LOG_ID)
        responseData = {'success': False, 'httpRequestId': httpRequestId}
        cookieData = httpServer.validate(self.request,
                                         self.request.GET,
                                         responseData,
                                         self.response,
                                         idRequired=False)
        userId = cookieData.id()

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

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

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

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

        # Display proposal data
        responseData = {'success': True, 'reasons': reasonDisps}
        httpServer.outputJson(cookieData, responseData, self.response)
Esempio n. 2
0
    def post(self):

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        # Mark proposal as not editable.
        if proposalRec.allowEdit:
            proposal.setEditable(proposalId, False)
Esempio n. 3
0
    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)
Esempio n. 4
0
    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)
Esempio n. 5
0
    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)
Esempio n. 6
0
    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)
Esempio n. 7
0
    def post(self):

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

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

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

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

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

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

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

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

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

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

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

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

        # Mark proposal as not editable.
        if proposalRec.allowEdit:
            proposal.setEditable(proposalId, False)
Esempio n. 8
0
    def post(self):
        logging.debug('SubmitEditReason.post() request.body=' +
                      self.request.body)

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

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

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

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

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

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

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

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

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

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

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

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

        # Display reason.
        reasonDisplay = httpServer.reasonToDisplay(reasonRec, userId)
        responseData.update({'success': True, 'reason': reasonDisplay})
        httpServer.outputJson(cookieData, responseData, self.response)
Esempio n. 9
0
    def post(self):

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

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

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

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

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

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

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

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

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

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

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

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

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

        # Mark request-for-proposals as not editable.
        if (requestRec.allowEdit):
            requestForProposals.setEditable(requestId, False)