def testCalculateFinishedThroughPostWithCorrectXsrfToken(self): """Tests the result after calculating duplicate proposals is finished. Through HTTP POST with correct XSRF token, when finished (there is no org to calculate), all pb records with no duplicate proposals are deleted and there is no taskqueue spawned. """ pd_fields = { 'program': self.program, 'student': self.student, 'orgs':[self.organization.key()], 'duplicates': [self.student_proposal.key()], 'is_duplicate': False } pd_logic.updateOrCreateFromFields(pd_fields) pds = pd_logic.getForFields({'program': self.program}) self.assertEqual(len(pds), 1) fields = {'scope': self.program, 'slots >': 0, 'status': 'active'} # Get all organizations and save the cursor q = gsoc_organization_logic.getQueryForFields(fields) q.fetch(3) org_cursor = q.cursor() url = '/tasks/gsoc/proposal_duplicates/calculate' postdata = {'program_key': self.program.key().name(), 'org_cursor': unicode(org_cursor)} xsrf_token = self.getXsrfToken(url, data=postdata) postdata.update(xsrf_token=xsrf_token) response = self.client.post(url, postdata) self.assertEqual(response.status_code, httplib.OK) pds = pd_logic.getForFields({'program': self.program}) self.assertEqual(len(pds), 0) task_url = '/tasks/gsoc/proposal_duplicates/calculate' self.assertTasksInQueue(n=0, url=task_url)
def testCalculateFinishedThroughPostWithCorrectXsrfToken(self): """Tests the result after calculating duplicate proposals is finished. Through HTTP POST with correct XSRF token, when finished (there is no org to calculate), all pb records with no duplicate proposals are deleted and there is no taskqueue spawned. """ pd_fields = { 'program': self.program, 'student': self.student, 'orgs': [self.organization.key()], 'duplicates': [self.student_proposal.key()], 'is_duplicate': False } pd_logic.updateOrCreateFromFields(pd_fields) pds = pd_logic.getForFields({'program': self.program}) self.assertEqual(len(pds), 1) fields = {'scope': self.program, 'slots >': 0, 'status': 'active'} # Get all organizations and save the cursor q = gsoc_organization_logic.getQueryForFields(fields) q.fetch(3) org_cursor = q.cursor() url = '/tasks/gsoc/proposal_duplicates/calculate' postdata = { 'program_key': self.program.key().name(), 'org_cursor': unicode(org_cursor) } xsrf_token = self.getXsrfToken(url, data=postdata) postdata.update(xsrf_token=xsrf_token) response = self.client.post(url, postdata) self.assertEqual(response.status_code, httplib.OK) pds = pd_logic.getForFields({'program': self.program}) self.assertEqual(len(pds), 0) task_url = '/tasks/gsoc/proposal_duplicates/calculate' self.assertTasksInQueue(n=0, url=task_url)
def calculate(request, *args, **kwargs): """Calculates the duplicate proposals in a given program for a student on a per Organization basis. Expects the following to be present in the POST dict: program_key: Specifies the program key name for which to find the duplicate proposals org_cursor: Specifies the organization datastore cursor from which to start the processing of finding the duplicate proposals Args: request: Django Request object """ from soc.modules.gsoc.logic.models.student_proposal import logic \ as sp_logic post_dict = request.POST program_key = post_dict.get('program_key') if not program_key: # invalid task data, log and return OK return error_handler.logErrorAndReturnOK('Invalid program key: %s' % post_dict) program_entity = program_logic.getFromKeyName(program_key) if not program_entity: # invalid program specified, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid program specified: %s' % program_key) fields = {'scope': program_entity, 'slots >': 0, 'status': 'active'} # get the organization and update the cursor if possible q = org_logic.getQueryForFields(fields) # retrieve the org_cursor from POST data org_cursor = post_dict.get('org_cursor') if org_cursor: org_cursor = str(org_cursor) q.with_cursor(org_cursor) result = q.fetch(1) # update the cursor org_cursor = q.cursor() if result: org_entity = result[0] # get all the proposals likely to be accepted in the program accepted_proposals = sp_logic.getProposalsToBeAcceptedForOrg( org_entity) for ap in accepted_proposals: student_entity = ap.scope proposal_duplicate = pd_logic.getForFields( {'student': student_entity}, unique=True) if proposal_duplicate and ap.key( ) not in proposal_duplicate.duplicates: # non-counted (to-be) accepted proposal found pd_fields = { 'duplicates': proposal_duplicate.duplicates + [ap.key()], } pd_fields['is_duplicate'] = len(pd_fields['duplicates']) >= 2 if org_entity.key() not in proposal_duplicate.orgs: pd_fields['orgs'] = proposal_duplicate.orgs + [ org_entity.key() ] proposal_duplicate = pd_logic.updateEntityProperties( proposal_duplicate, pd_fields) else: pd_fields = { 'program': program_entity, 'student': student_entity, 'orgs': [org_entity.key()], 'duplicates': [ap.key()], 'is_duplicate': False } proposal_duplicate = pd_logic.updateOrCreateFromFields( pd_fields) # Adds a new task that performs duplicate calculation for # the next organization. task_params = { 'program_key': program_key, 'org_cursor': unicode(org_cursor) } task_url = '/tasks/gsoc/proposal_duplicates/calculate' new_task = taskqueue.Task(params=task_params, url=task_url) new_task.add() else: # There aren't any more organizations to process. So delete # all the proposals for which there are not more than one # proposal for duplicates property. pd_logic.deleteAllForProgram(program_entity, non_dupes_only=True) # update the proposal duplicate status and its timestamp pds_entity = pds_logic.getOrCreateForProgram(program_entity) new_fields = { 'status': 'idle', 'calculated_on': datetime.datetime.now() } pds_logic.updateEntityProperties(pds_entity, new_fields) # return OK return http.HttpResponse()
def calculate(request, *args, **kwargs): """Calculates the duplicate proposals in a given program for a student on a per Organization basis. Expects the following to be present in the POST dict: program_key: Specifies the program key name for which to find the duplicate proposals org_cursor: Specifies the organization datastore cursor from which to start the processing of finding the duplicate proposals Args: request: Django Request object """ from soc.modules.gsoc.logic.models.student_proposal import logic \ as sp_logic post_dict = request.POST program_key = post_dict.get('program_key') if not program_key: # invalid task data, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid program key: %s' % post_dict) program_entity = program_logic.getFromKeyName(program_key) if not program_entity: # invalid program specified, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid program specified: %s' % program_key) fields = {'scope': program_entity, 'slots >': 0, 'status': 'active'} # get the organization and update the cursor if possible q = org_logic.getQueryForFields(fields) # retrieve the org_cursor from POST data org_cursor = post_dict.get('org_cursor') if org_cursor: org_cursor = str(org_cursor) q.with_cursor(org_cursor) result = q.fetch(1) # update the cursor org_cursor = q.cursor() if result: org_entity = result[0] # get all the proposals likely to be accepted in the program accepted_proposals = sp_logic.getProposalsToBeAcceptedForOrg(org_entity) for ap in accepted_proposals: student_entity = ap.scope proposal_duplicate = pd_logic.getForFields({'student': student_entity}, unique=True) if proposal_duplicate and ap.key() not in proposal_duplicate.duplicates: # non-counted (to-be) accepted proposal found pd_fields = { 'duplicates': proposal_duplicate.duplicates + [ap.key()], } pd_fields['is_duplicate'] = len(pd_fields['duplicates']) >= 2 if org_entity.key() not in proposal_duplicate.orgs: pd_fields['orgs'] = proposal_duplicate.orgs + [org_entity.key()] proposal_duplicate = pd_logic.updateEntityProperties( proposal_duplicate, pd_fields) else: pd_fields = { 'program': program_entity, 'student': student_entity, 'orgs':[org_entity.key()], 'duplicates': [ap.key()], 'is_duplicate': False } proposal_duplicate = pd_logic.updateOrCreateFromFields(pd_fields) # Adds a new task that performs duplicate calculation for # the next organization. task_params = {'program_key': program_key, 'org_cursor': unicode(org_cursor)} task_url = '/tasks/gsoc/proposal_duplicates/calculate' new_task = taskqueue.Task(params=task_params, url=task_url) new_task.add() else: # There aren't any more organizations to process. So delete # all the proposals for which there are not more than one # proposal for duplicates property. pd_logic.deleteAllForProgram(program_entity, non_dupes_only=True) # update the proposal duplicate status and its timestamp pds_entity = pds_logic.getOrCreateForProgram(program_entity) new_fields = {'status': 'idle', 'calculated_on': datetime.datetime.now()} pds_logic.updateEntityProperties(pds_entity, new_fields) # return OK return http.HttpResponse()