Example #1
0
  def testDeleteAllForProgram(self):
    """Tests if all proposal duplicates for a program are deleted.
    """
    #Before deleting.
    q = GSoCProposalDuplicate.all()
    q.filter('program', self.program1)
    q_result = q.fetch(limit=10)
    actual = [entity.key() for entity in q_result]
    expected = [entity.key() for entity in self.proposal_duplicates]
    self.assertEqual(actual, expected)

    #Delete duplicate proposals for program.
    duplicate_logic.deleteAllForProgram(self.program1)
    q = GSoCProposalDuplicate.all()
    q.filter('program', self.program1)
    actual = q.fetch(limit=10)
    expected = []
    self.assertEqual(actual, expected)

    #Test that duplicate proposals for other program were not deleted.
    expected = [entity.key() for entity in self.other_proposal_duplicates]
    q = GSoCProposalDuplicate.all()
    q.filter('program', self.program2)
    q_result = q.fetch(limit=10)
    actual = [entity.key() for entity in q_result]
    self.assertEqual(actual, expected)
Example #2
0
  def testDeleteAllForProgram(self):
    """Tests if all proposal duplicates for a program are deleted.
    """
    #Before deleting.
    q = GSoCProposalDuplicate.all()
    q.filter('program', self.program1)
    q_result = q.fetch(limit=10)
    actual = [entity.key() for entity in q_result]
    expected = [entity.key() for entity in self.proposal_duplicates]
    self.assertEqual(actual, expected)

    #Delete duplicate proposals for program.
    duplicate_logic.deleteAllForProgram(self.program1)
    q = GSoCProposalDuplicate.all()
    q.filter('program', self.program1)
    actual = q.fetch(limit=10)
    expected = []
    self.assertEqual(actual, expected)

    #Test that duplicate proposals for other program were not deleted.
    expected = [entity.key() for entity in self.other_proposal_duplicates]
    q = GSoCProposalDuplicate.all()
    q.filter('program', self.program2)
    q_result = q.fetch(limit=10)
    actual = [entity.key() for entity in q_result]
    self.assertEqual(actual, expected)
    def testDeleteAllForProgramNonDupesOnlyIsTrue(self):
        """Tests if only those proposals are deleted which have is_duplicate set
    to false.
    """
        #is_duplicate is set to False by default for all the GSoCProposalDuplicate
        #entities. So, test if all the entities in program1 are deleted.
        duplicate_logic.deleteAllForProgram(self.program1, non_dupes_only=True)
        q = GSoCProposalDuplicate.all()
        q.filter('program', self.program1)
        q.filter('is_duplicate', False)
        q_result = q.fetch(limit=10)
        expected = []
        actual = [entity.key() for entity in q_result]
        self.assertEqual(actual, expected)

        #set is_duplicate = True for each of the first 3 students in
        #self.other_gsoc_students and test if these are not deleted for program2.
        for i in xrange(3):
            self.other_proposal_duplicates[i].is_duplicate = True
            self.other_proposal_duplicates[i].put()
        duplicate_logic.deleteAllForProgram(self.program2, non_dupes_only=True)
        q = GSoCProposalDuplicate.all()
        q.filter('program', self.program2)
        q.filter('is_duplicate', False)
        q_result = q.fetch(limit=10)
        expected = []
        actual = [entity.key() for entity in q_result]
        self.assertEqual(actual, expected)
        #check if entities with is_duplicate=True are not deleted
        q = GSoCProposalDuplicate.all()
        q.filter('program', self.program2)
        q.filter('is_duplicate', True)
        q_result = q.fetch(limit=10)
        expected = [
            entity.key() for entity in self.other_proposal_duplicates[:3]
        ]
        actual = [entity.key() for entity in q_result]
        self.assertEqual(actual, expected)
Example #4
0
  def testDeleteAllForProgramNonDupesOnlyIsTrue(self):
    """Tests if only those proposals are deleted which have is_duplicate set
    to false.
    """
    #is_duplicate is set to False by default for all the GSoCProposalDuplicate
    #entities. So, test if all the entities in program1 are deleted.
    duplicate_logic.deleteAllForProgram(self.program1, non_dupes_only=True)
    q = GSoCProposalDuplicate.all()
    q.filter('program', self.program1)
    q.filter('is_duplicate', False)
    q_result = q.fetch(limit=10)
    expected = []
    actual = [entity.key() for entity in q_result]
    self.assertEqual(actual, expected)

    #set is_duplicate = True for each of the first 3 students in
    #self.other_gsoc_students and test if these are not deleted for program2.
    for i in xrange(3):
      self.other_proposal_duplicates[i].is_duplicate = True
      self.other_proposal_duplicates[i].put()
    duplicate_logic.deleteAllForProgram(self.program2, non_dupes_only=True)
    q = GSoCProposalDuplicate.all()
    q.filter('program', self.program2)
    q.filter('is_duplicate', False)
    q_result = q.fetch(limit=10)
    expected = []
    actual = [entity.key() for entity in q_result]
    self.assertEqual(actual, expected)
    #check if entities with is_duplicate=True are not deleted
    q = GSoCProposalDuplicate.all()
    q.filter('program', self.program2)
    q.filter('is_duplicate', True)
    q_result = q.fetch(limit=10)
    expected = [entity.key() for entity in self.other_proposal_duplicates[:3]]
    actual = [entity.key() for entity in q_result]
    self.assertEqual(actual, expected)
Example #5
0
  def start(self, request, *args, **kwargs):
    """Starts the task to find all duplicate proposals which are about to be
    accepted for a single GSoCProgram.

    Expects the following to be present in the POST dict:
      program_key: Specifies the program key name for which to find the
                   duplicate proposals
      repeat: Specifies if a new task that must be performed again an hour
              later, with the same POST data

    Args:
      request: Django Request object
    """

    from soc.logic.helper import timeline as timeline_helper

    post_dict = request.POST

    # retrieve the program_key and repeat option from POST data
    program_key = post_dict.get('program_key')
    repeat = post_dict.get('repeat')

    if not (program_key and repeat):
      # invalid task data, log and return OK
      return error_handler.logErrorAndReturnOK(
          'Invalid task data: %s' % post_dict)

    # get the program for the given keyname
    program_entity = GSoCProgram.get_by_key_name(program_key)

    if not program_entity:
      # invalid program specified, log and return OK
      return error_handler.logErrorAndReturnOK(
          'Invalid program specified: %s' % program_key)

    # obtain the proposal duplicate status
    pds_entity = duplicates_logic.getOrCreateStatusForProgram(program_entity)

    if pds_entity.status == 'idle':
      # delete all old duplicates
      duplicates_logic.deleteAllForProgram(program_entity)

      # pass these data along params as POST to the new task
      task_params = {'program_key': program_key}
      task_url = '/tasks/gsoc/proposal_duplicates/calculate'

      new_task = taskqueue.Task(params=task_params, url=task_url)

      def txn():
        # add a new task that performs duplicate calculation per
        # organization
        new_task.add(transactional=True)

        # update the status of the PDS entity to processing
        pds_entity.status = 'processing'
        pds_entity.put()

      db.RunInTransaction(txn)

    # Add a new clone of this task that must be performed an hour later because
    # the current task is part of the task that repeatedly runs but repeat
    # it before accepted students are announced only.
    if repeat == 'yes' and timeline_helper.isBeforeEvent(
        program_entity.timeline, 'accepted_students_announced_deadline'):
      # pass along these params as POST to the new task
      task_params = {'program_key': program_key,
                     'repeat': 'yes'}
      task_url = '/tasks/gsoc/proposal_duplicates/start'

      new_task = taskqueue.Task(params=task_params, url=task_url,
                                countdown=3600)
      new_task.add()

    # return OK
    return http.HttpResponse()
Example #6
0
  def calculate(self, 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
    """
    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 = GSoCProgram.get_by_key_name(program_key)
    if not program_entity:
      # invalid program specified, log and return OK
      return error_handler.logErrorAndReturnOK(
          'Invalid program specified: %s' % program_key)

    # get the organization and update the cursor if possible
    q = GSoCOrganization.all()
    q.filter('status', 'active')
    q.filter('scope', program_entity)
    q.filter('slots >', 0)

    # 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)

    org_entity = q.get()
    # update the cursor
    org_cursor = q.cursor()

    if org_entity:
      # get all the proposals likely to be accepted in the program
      accepted_proposals = proposal_logic.getProposalsToBeAcceptedForOrg(org_entity)

      for ap in accepted_proposals:
        student_entity = ap.parent()

        q = GSoCProposalDuplicate.all()
        q.filter('student', student_entity)
        proposal_duplicate = q.get()

        if proposal_duplicate and ap.key() not in proposal_duplicate.duplicates:
          # non-counted (to-be) accepted proposal found
          proposal_duplicate.duplicates = proposal_duplicate.duplicates + \
                                          [ap.key()]
          proposal_duplicate.is_duplicate = \
              len(proposal_duplicate.duplicates) >= 2
          if org_entity.key() not in proposal_duplicate.orgs:
            proposal_duplicate.orgs = proposal_duplicate.orgs + [org_entity.key()]
        else:
          pd_fields  = {
              'program': program_entity,
              'student': student_entity,
              'orgs':[org_entity.key()],
              'duplicates': [ap.key()],
              'is_duplicate': False
              }
          proposal_duplicate = GSoCProposalDuplicate(**pd_fields)

        proposal_duplicate.put()

      # 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.
      duplicates_logic.deleteAllForProgram(program_entity, non_dupes_only=True)

      # update the proposal duplicate status and its timestamp
      pds_entity = duplicates_logic.getOrCreateStatusForProgram(program_entity)
      pds_entity.status = 'idle'
      pds_entity.calculated_on = datetime.datetime.now()
      pds_entity.put()

    # return OK
    return http.HttpResponse()
  def calculate(self, 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
    """
    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 = GSoCProgram.get_by_key_name(program_key)
    if not program_entity:
      # invalid program specified, log and return OK
      return error_handler.logErrorAndReturnOK(
          'Invalid program specified: %s' % program_key)

    # get the organization and update the cursor if possible
    query = soc_org_model.SOCOrganization.query(
        soc_org_model.SOCOrganization.status == org_model.Status.ACCEPTED,
        soc_org_model.SOCOrganization.program ==
            ndb.Key.from_old_key(program_entity.key()),
        soc_org_model.SOCOrganization.slot_allocation > 0)

    # retrieve the org_cursor from POST data
    org_cursor = post_dict.get('org_cursor')
    start_cursor = (
        datastore_query.Cursor(urlsafe=org_cursor) if org_cursor else None)

    organizations, next_cursor, _ = query.fetch_page(
        1, start_cursor=start_cursor)

    if organizations:
      organization = organizations[0]
      # get all the proposals likely to be accepted in the program
      accepted_proposals = (
          proposal_logic.getProposalsToBeAcceptedForOrg(organization))

      for accepted_proposal in accepted_proposals:
        q = GSoCProposalDuplicate.all()
        q.filter('student', accepted_proposal.parent_key())
        proposal_duplicate = q.get()

        if (proposal_duplicate and
            accepted_proposal.key() not in proposal_duplicate.duplicates):
          # non-counted (to-be) accepted proposal found
          proposal_duplicate.duplicates = proposal_duplicate.duplicates + \
                                          [accepted_proposal.key()]
          proposal_duplicate.is_duplicate = \
              len(proposal_duplicate.duplicates) >= 2
          if organization.key.to_old_key() not in proposal_duplicate.orgs:
            proposal_duplicate.orgs = (
                proposal_duplicate.orgs + [organization.key.to_old_key()])
        else:
          pd_fields = {
              'program': program_entity,
              'student': accepted_proposal.parent_key(),
              'orgs':[organization.key.to_old_key()],
              'duplicates': [accepted_proposal.key()],
              'is_duplicate': False
              }
          proposal_duplicate = GSoCProposalDuplicate(**pd_fields)

        proposal_duplicate.put()

      # Adds a new task that performs duplicate calculation for
      # the next organization.
      task_params = {
          'program_key': program_key,
          'org_cursor': next_cursor.urlsafe()
          }
      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.
      duplicates_logic.deleteAllForProgram(program_entity, non_dupes_only=True)

      # update the proposal duplicate status and its timestamp
      pds_entity = duplicates_logic.getOrCreateStatusForProgram(program_entity)
      pds_entity.status = 'idle'
      pds_entity.calculated_on = datetime.datetime.now()
      pds_entity.put()

    # return OK
    return http.HttpResponse()
    def start(self, request, *args, **kwargs):
        """Starts the task to find all duplicate proposals which are about to be
    accepted for a single GSoCProgram.

    Expects the following to be present in the POST dict:
      program_key: Specifies the program key name for which to find the
                   duplicate proposals
      repeat: Specifies if a new task that must be performed again an hour
              later, with the same POST data

    Args:
      request: Django Request object
    """

        from soc.logic.helper import timeline as timeline_helper

        post_dict = request.POST

        # retrieve the program_key and repeat option from POST data
        program_key = post_dict.get('program_key')
        repeat = post_dict.get('repeat')

        if not (program_key and repeat):
            # invalid task data, log and return OK
            return error_handler.logErrorAndReturnOK('Invalid task data: %s' %
                                                     post_dict)

        # get the program for the given keyname
        program_entity = GSoCProgram.get_by_key_name(program_key)

        if not program_entity:
            # invalid program specified, log and return OK
            return error_handler.logErrorAndReturnOK(
                'Invalid program specified: %s' % program_key)

        # obtain the proposal duplicate status
        pds_entity = duplicates_logic.getOrCreateStatusForProgram(
            program_entity)

        if pds_entity.status == 'idle':
            # delete all old duplicates
            duplicates_logic.deleteAllForProgram(program_entity)

            # pass these data along params as POST to the new task
            task_params = {'program_key': program_key}
            task_url = '/tasks/gsoc/proposal_duplicates/calculate'

            new_task = taskqueue.Task(params=task_params, url=task_url)

            def txn():
                # add a new task that performs duplicate calculation per
                # organization
                new_task.add(transactional=True)

                # update the status of the PDS entity to processing
                pds_entity.status = 'processing'
                pds_entity.put()

            db.RunInTransaction(txn)

        # Add a new clone of this task that must be performed an hour later because
        # the current task is part of the task that repeatedly runs but repeat
        # it before accepted students are announced only.
        if repeat == 'yes' and timeline_helper.isBeforeEvent(
                program_entity.timeline,
                'accepted_students_announced_deadline'):
            # pass along these params as POST to the new task
            task_params = {'program_key': program_key, 'repeat': 'yes'}
            task_url = '/tasks/gsoc/proposal_duplicates/start'

            new_task = taskqueue.Task(params=task_params,
                                      url=task_url,
                                      countdown=3600)
            new_task.add()

        # return OK
        return http.HttpResponse()
    def calculate(self, 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
    """
        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 = GSoCProgram.get_by_key_name(program_key)
        if not program_entity:
            # invalid program specified, log and return OK
            return error_handler.logErrorAndReturnOK(
                'Invalid program specified: %s' % program_key)

        # get the organization and update the cursor if possible
        query = soc_org_model.SOCOrganization.query(
            soc_org_model.SOCOrganization.status == org_model.Status.ACCEPTED,
            soc_org_model.SOCOrganization.program == ndb.Key.from_old_key(
                program_entity.key()),
            soc_org_model.SOCOrganization.slot_allocation > 0)

        # retrieve the org_cursor from POST data
        org_cursor = post_dict.get('org_cursor')
        start_cursor = (datastore_query.Cursor(
            urlsafe=org_cursor) if org_cursor else None)

        organizations, next_cursor, _ = query.fetch_page(
            1, start_cursor=start_cursor)

        if organizations:
            organization = organizations[0]
            # get all the proposals likely to be accepted in the program
            accepted_proposals = (
                proposal_logic.getProposalsToBeAcceptedForOrg(organization))

            for accepted_proposal in accepted_proposals:
                q = GSoCProposalDuplicate.all()
                q.filter('student', accepted_proposal.parent_key())
                proposal_duplicate = q.get()

                if (proposal_duplicate and accepted_proposal.key()
                        not in proposal_duplicate.duplicates):
                    # non-counted (to-be) accepted proposal found
                    proposal_duplicate.duplicates = proposal_duplicate.duplicates + \
                                                    [accepted_proposal.key()]
                    proposal_duplicate.is_duplicate = \
                        len(proposal_duplicate.duplicates) >= 2
                    if organization.key.to_old_key(
                    ) not in proposal_duplicate.orgs:
                        proposal_duplicate.orgs = (
                            proposal_duplicate.orgs +
                            [organization.key.to_old_key()])
                else:
                    pd_fields = {
                        'program': program_entity,
                        'student': accepted_proposal.parent_key(),
                        'orgs': [organization.key.to_old_key()],
                        'duplicates': [accepted_proposal.key()],
                        'is_duplicate': False
                    }
                    proposal_duplicate = GSoCProposalDuplicate(**pd_fields)

                proposal_duplicate.put()

            # Adds a new task that performs duplicate calculation for
            # the next organization.
            task_params = {
                'program_key': program_key,
                'org_cursor': next_cursor.urlsafe()
            }
            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.
            duplicates_logic.deleteAllForProgram(program_entity,
                                                 non_dupes_only=True)

            # update the proposal duplicate status and its timestamp
            pds_entity = duplicates_logic.getOrCreateStatusForProgram(
                program_entity)
            pds_entity.status = 'idle'
            pds_entity.calculated_on = datetime.datetime.now()
            pds_entity.put()

        # return OK
        return http.HttpResponse()