Exemple #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)
Exemple #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)
Exemple #3
0
  def getListData(self):
    idx = lists.getListIndex(self.data.request)
    if idx != 0:
      return None

    program = self.data.program

    # Hold all the accepted projects for orgs where this user is a member of
    accepted = []
    # Hold all duplicates for either the entire program or the orgs of the user.
    duplicates = []
    dupQ = GSoCProposalDuplicate.all()
    dupQ.filter('is_duplicate', True)
    dupQ.filter('org', self.data.url_ndb_org.key.to_old_key())
    dupQ.filter('program', program)

    accepted.extend(
        p.key() for p in getProposalsToBeAcceptedForOrg(self.data.url_ndb_org))

    duplicate_entities = dupQ.fetch(1000)
    for dup in duplicate_entities:
      duplicates.extend(dup.duplicates)

    q = GSoCProposal.all()
    q.filter('org', self.data.url_ndb_org.key.to_old_key())
    q.filter('program', program)

    starter = lists.keyStarter

    # TODO(daniel): enable prefetching from ndb models ('org', 'parent')
    # prefetcher = lists.ModelPrefetcher(GSoCProposal, [], parent=True)

    response_builder = lists.RawQueryContentResponseBuilder(
        self.data.request, self._list_config, q, starter, prefetcher=None)
    return response_builder.build(accepted, duplicates)
Exemple #4
0
  def getListData(self):
    idx = lists.getListIndex(self.request)
    if idx != 0:
      return None

    org = self.data.organization
    program = self.data.program

    # Hold all the accepted projects for orgs where this user is a member of
    accepted = []
    # Hold all duplicates for either the entire program or the orgs of the user.
    duplicates = []
    dupQ = GSoCProposalDuplicate.all()
    dupQ.filter('is_duplicate', True)
    dupQ.filter('org', org)
    dupQ.filter('program', program)

    accepted.extend([p.key() for p in getProposalsToBeAcceptedForOrg(org)])

    duplicate_entities = dupQ.fetch(1000)
    for dup in duplicate_entities:
      duplicates.extend(dup.duplicates)

    q = GSoCProposal.all()
    q.filter('org', org)
    q.filter('program', program)

    starter = lists.keyStarter
    prefetcher = lists.modelPrefetcher(GSoCProposal, ['org'], parent=True)

    response_builder = lists.RawQueryContentResponseBuilder(
        self.request, self._list_config, q, starter, prefetcher=prefetcher)
    return response_builder.build(accepted, duplicates)
  def testCalculateDuplicatesForSingleOrg(self):
    """Test that calculates properly creates GSoCProposalDuplicate entities for
    a single organization.
    """
    # skip the initialization step
    status = duplicates_logic.getOrCreateStatusForProgram(self.gsoc)
    status.status = 'processing'
    status.put()

    post_data = {'program_key': self.gsoc.key().id_or_name()}

    response = self.post(self.CALCULATE_URL, post_data)

    # must have enqueued itself again successfully
    self.assertEqual(response.status_code, httplib.OK)
    self.assertTasksInQueue(n=1)
    self.assertTasksInQueue(n=1, url=self.CALCULATE_URL)

    # the new task should have a query cursor present
    params = self.get_tasks()[0]['params']
    self.assertTrue(params.has_key('org_cursor'))
    self.assertEqual(params['program_key'],
                     urllib.quote_plus(self.gsoc.key().id_or_name()))

    # 2 duplicates should have been created since there are 2 students
    duplicates = GSoCProposalDuplicate.all().fetch(1000)
    self.assertLength(duplicates, 2)
    for dup in duplicates:
      if dup.student.key() == self.student1.key():
        self.assertTrue(dup.is_duplicate)
      else:
        self.assertFalse(dup.is_duplicate)

    status = duplicates_logic.getOrCreateStatusForProgram(self.gsoc)
    self.assertEqual(status.status, 'processing')
Exemple #6
0
    def testCalculateDuplicatesForSingleOrg(self):
        """Test that calculates properly creates GSoCProposalDuplicate entities for
    a single organization.
    """
        # skip the initialization step
        status = duplicates_logic.getOrCreateStatusForProgram(self.gsoc)
        status.status = 'processing'
        status.put()

        post_data = {'program_key': self.gsoc.key().id_or_name()}

        response = self.post(self.CALCULATE_URL, post_data)

        # must have enqueued itself again successfully
        self.assertEqual(response.status_code, httplib.OK)
        self.assertTasksInQueue(n=1)
        self.assertTasksInQueue(n=1, url=self.CALCULATE_URL)

        # the new task should have a query cursor present
        params = self.get_tasks()[0]['params']
        self.assertTrue(params.has_key('org_cursor'))
        self.assertEqual(params['program_key'],
                         urllib.quote_plus(self.gsoc.key().id_or_name()))

        # 2 duplicates should have been created since there are 2 students
        duplicates = GSoCProposalDuplicate.all().fetch(1000)
        self.assertLength(duplicates, 2)
        for dup in duplicates:
            if dup.student.key() == self.student1.key():
                self.assertTrue(dup.is_duplicate)
            else:
                self.assertFalse(dup.is_duplicate)

        status = duplicates_logic.getOrCreateStatusForProgram(self.gsoc)
        self.assertEqual(status.status, 'processing')
  def testCalculateFailsWhenMissingProgram(self):
    """Tests that calculates fails when a Program is not present in the POST
    data.
    """
    post_data = {}

    response = self.post(self.CALCULATE_URL, post_data)

    self.assertEqual(response.status_code, httplib.OK)
    self.assertTasksInQueue(n=0)
    self.assertEqual(GSoCProposalDuplicate.all().count(1), 0)
    def testCalculateFailsWhenMissingProgram(self):
        """Tests that calculates fails when a Program is not present in the POST
    data.
    """
        post_data = {}

        response = self.post(self.CALCULATE_URL, post_data)

        self.assertEqual(response.status_code, httplib.OK)
        self.assertTasksInQueue(n=0)
        self.assertEqual(GSoCProposalDuplicate.all().count(1), 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)
Exemple #10
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)
    def testCalculateDuplicatesTerminates(self):
        """Test that calculates terminates properly after going through all orgs.
    """
        # skip the initialization step
        status = duplicates_logic.getOrCreateStatusForProgram(self.gsoc)
        status.status = 'processing'
        status.put()

        post_data = {'program_key': self.gsoc.key().id_or_name()}

        response = self.post(self.CALCULATE_URL, post_data)

        # must have enqueued itself again successfully
        self.assertEqual(response.status_code, httplib.OK)
        self.assertTasksInQueue(n=1)
        self.assertTasksInQueue(n=1, url=self.CALCULATE_URL)

        # this data should be used for the second iteration
        params = self.get_tasks()[0]['params']
        for key, value in params.iteritems():
            params[key] = urllib.unquote_plus(value)

        # clean the queue
        self.clear_task_queue()

        response = self.post(self.CALCULATE_URL, params)

        # only 1 org in test data so task should terminate now
        self.assertEqual(response.status_code, httplib.OK)
        self.assertTasksInQueue(n=0)

        # 1 duplicate should be left after task termination
        duplicates = GSoCProposalDuplicate.all().fetch(1000)
        self.assertEqual(len(duplicates), 1)
        dup = duplicates[0]
        self.assertTrue(dup.is_duplicate)

        student_key = GSoCProposalDuplicate.student.get_value_for_datastore(
            dup)
        self.assertEqual(student_key, self.student1.key.to_old_key())
        self.assertEqual(len(dup.duplicates),
                         _FIRST_STUDENT_NUMBER_OF_DUPLICATES)

        status = duplicates_logic.getOrCreateStatusForProgram(self.program)
        self.assertEqual(status.status, 'idle')
Exemple #12
0
  def context(self, data, check, mutator):
    """Returns the context for this page."""
    program = data.program

    q = GSoCProposalDuplicate.all()
    q.filter('program', program)
    q.filter('is_duplicate', True)

    duplicates = [Duplicate(data, duplicate) for duplicate in q.fetch(1000)]
    duplicates_status = duplicates_logic.getOrCreateStatusForProgram(program)

    context = {
      'page_name': 'Duplicates for %s' %program.name,
      'duplicates_status': duplicates_status,
      'duplicates': duplicates,
    }

    return context
  def testCalculateDuplicatesTerminates(self):
    """Test that calculates terminates properly after going through all orgs.
    """
    # skip the initialization step
    status = duplicates_logic.getOrCreateStatusForProgram(self.gsoc)
    status.status = 'processing'
    status.put()

    post_data = {'program_key': self.gsoc.key().id_or_name()}

    response = self.post(self.CALCULATE_URL, post_data)

    # must have enqueued itself again successfully
    self.assertEqual(response.status_code, httplib.OK)
    self.assertTasksInQueue(n=1)
    self.assertTasksInQueue(n=1, url=self.CALCULATE_URL)

    # this data should be used for the second iteration
    params = self.get_tasks()[0]['params']
    for key, value in params.iteritems():
      params[key] = urllib.unquote_plus(value)

    # clean the queue
    self.clear_task_queue()

    response = self.post(self.CALCULATE_URL, params)

    # only 1 org in test data so task should terminate now
    self.assertEqual(response.status_code, httplib.OK)
    self.assertTasksInQueue(n=0)

    # 1 duplicate should be left after task termination
    duplicates = GSoCProposalDuplicate.all().fetch(1000)
    self.assertEqual(len(duplicates), 1)
    dup = duplicates[0]
    self.assertTrue(dup.is_duplicate)

    student_key = GSoCProposalDuplicate.student.get_value_for_datastore(dup)
    self.assertEqual(student_key, self.student1.key.to_old_key())
    self.assertEqual(len(dup.duplicates), _FIRST_STUDENT_NUMBER_OF_DUPLICATES)

    status = duplicates_logic.getOrCreateStatusForProgram(self.program)
    self.assertEqual(status.status, 'idle')
Exemple #14
0
def deleteAllForProgram(program_entity, non_dupes_only=False):
  """Deletes all ProposalDuplicates for a given program.

  Args:
    program_entity: Program to delete the ProposalDuplicatesFor
    non_dupes_only: Iff True removes only the ones which have is_duplicate
      set to False. False by default.
  """

  q = GSoCProposalDuplicate.all()
  q.filter('program', program_entity)

  if non_dupes_only:
    q.filter('is_duplicate', False)

  # can not delete more then 500 entities in one call
  proposal_duplicates = q.fetch(500)
  while proposal_duplicates:
    db.delete(proposal_duplicates)
    proposal_duplicates = q.fetch(500)
Exemple #15
0
def deleteAllForProgram(program_entity, non_dupes_only=False):
    """Deletes all ProposalDuplicates for a given program.

  Args:
    program_entity: Program to delete the ProposalDuplicatesFor
    non_dupes_only: Iff True removes only the ones which have is_duplicate
      set to False. False by default.
  """

    q = GSoCProposalDuplicate.all()
    q.filter("program", program_entity)

    if non_dupes_only:
        q.filter("is_duplicate", False)

    # can not delete more then 500 entities in one call
    proposal_duplicates = q.fetch(500)
    while proposal_duplicates:
        db.delete(proposal_duplicates)
        proposal_duplicates = q.fetch(500)
Exemple #16
0
    def context(self, data, check, mutator):
        """Returns the context for this page."""
        program = data.program

        q = GSoCProposalDuplicate.all()
        q.filter('program', program)
        q.filter('is_duplicate', True)

        duplicates = [
            Duplicate(data, duplicate) for duplicate in q.fetch(1000)
        ]
        duplicates_status = duplicates_logic.getOrCreateStatusForProgram(
            program)

        context = {
            'page_name': 'Duplicates for %s' % program.name,
            'duplicates_status': duplicates_status,
            'duplicates': duplicates,
        }

        return context
Exemple #17
0
    def getListData(self):
        idx = lists.getListIndex(self.data.request)
        if idx != 0:
            return None

        program = self.data.program

        # Hold all the accepted projects for orgs where this user is a member of
        accepted = []
        # Hold all duplicates for either the entire program or the orgs of the user.
        duplicates = []
        dupQ = GSoCProposalDuplicate.all()
        dupQ.filter('is_duplicate', True)
        dupQ.filter('org', self.data.url_ndb_org.key.to_old_key())
        dupQ.filter('program', program)

        accepted.extend(
            p.key()
            for p in getProposalsToBeAcceptedForOrg(self.data.url_ndb_org))

        duplicate_entities = dupQ.fetch(1000)
        for dup in duplicate_entities:
            duplicates.extend(dup.duplicates)

        q = GSoCProposal.all()
        q.filter('org', self.data.url_ndb_org.key.to_old_key())
        q.filter('program', program)

        starter = lists.keyStarter

        # TODO(daniel): enable prefetching from ndb models ('org', 'parent')
        # prefetcher = lists.ModelPrefetcher(GSoCProposal, [], parent=True)

        response_builder = lists.RawQueryContentResponseBuilder(
            self.data.request, self._list_config, q, starter, prefetcher=None)
        return response_builder.build(accepted, duplicates)
  def context(self, data, check, mutator):
    context = {}

    user_role = None

    scores = self.getScores(data)

    # TODO: check if the scoring is not disabled
    score_action = reverse('score_gsoc_proposal', kwargs=data.kwargs)

    # get all the comments for the the proposal
    public_comments, private_comments = self.getComments(data)

    # TODO: check if it is possible to post a comment
    comment_action = reverse('comment_gsoc_proposal', kwargs=data.kwargs)

    if _getApplyingCommentType(data) == PRIVATE_COMMENTS:

      # only mentors and org admins can see that the proposal is ignored
      # TODO(daniel): replace status literals with constants
      context['proposal_ignored'] = data.url_proposal.status == 'ignored'

      form = PrivateCommentForm(data=data.POST or None)
      org_key = proposal_model.GSoCProposal.org.get_value_for_datastore(
          data.url_proposal)
      if data.orgAdminFor(org_key):
        user_role = 'org_admin'
      else:
        user_role = 'mentor'

    else:
      form = CommentForm(data=data.POST or None)

    comment_box = {
        'action': comment_action,
        'form': form,
    }

    # to keep the blocks as simple as possible, the if branches have
    # been broken down into several if blocks
    user_is_proposer = (
        data.user and (data.ndb_user.key == data.url_ndb_user.key()))
    if user_is_proposer:
      user_role = 'proposer'

      # we will check if the student is allowed to modify the proposal
      # after the student proposal deadline
      is_editable = data.timeline.afterStudentSignupEnd() and \
          data.url_proposal.is_editable_post_deadline
      if data.timeline.studentSignup() or is_editable:
        context['update_link'] = links.LINKER.userId(
            data.url_ndb_profile.key(), data.url_proposal.key().id(),
            'update_gsoc_proposal')

    possible_mentors = ndb.get_multi(
        map(ndb.Key.from_old_key, data.url_proposal.possible_mentors))
    possible_mentors = self.sanitizePossibleMentors(data, possible_mentors)
    possible_mentors_names = ', '.join([
        m.public_name for m in possible_mentors])

    org_key = proposal_model.GSoCProposal.org.get_value_for_datastore(
        data.url_proposal)
    org = ndb.Key.from_old_key(org_key).get()
    scoring_visible = _getApplyingCommentType(data) == PRIVATE_COMMENTS and (
        org.scoring_enabled)

    if data.orgAdminFor(org_key):
      scoring_visible = True

    duplicate = None
    if (data.program.duplicates_visible and
        data.orgAdminFor(org_key)):
      q = GSoCProposalDuplicate.all()
      q.filter('duplicates', data.url_proposal)
      q.filter('is_duplicate', True)
      dup_entity = q.get()
      duplicate = Duplicate(data, dup_entity) if dup_entity else None

    additional_info = data.url_proposal.additional_info

    if user_role:
      context['user_actions'] = UserActions(data, user_role)

    mentor_key = proposal_model.GSoCProposal.mentor.get_value_for_datastore(
        data.url_proposal)
    mentor = ndb.Key.from_old_key(mentor_key).get() if mentor_key else None
    context.update({
        'additional_info': url_helper.trim_url_to(additional_info, 50),
        'additional_info_link': additional_info,
        'comment_box': comment_box,
        'duplicate': duplicate,
        'max_score': org.max_score,
        'mentor': mentor,
        'page_name': data.url_proposal.title,
        'possible_mentors': possible_mentors_names,
        'private_comments': private_comments,
        'private_comments_visible':
             _getApplyingCommentType(data) == PRIVATE_COMMENTS,
        'proposal': data.url_proposal,
        'public_comments': public_comments,
        'public_comments_visible':
            _getApplyingCommentType(data) == PRIVATE_COMMENTS or
            _getApplyingCommentType(data) == PUBLIC_COMMENTS,
        'score_action': score_action,
        'scores': scores,
        'scoring_visible': scoring_visible,
        'student_email': data.url_ndb_profile.contact.email,
        'student_name': data.url_ndb_profile.public_name,
        'user_role': user_role,
        })

    return context
Exemple #19
0
    def context(self):
        assert isSet(self.data.public_comments_visible)
        assert isSet(self.data.private_comments_visible)
        assert isSet(self.data.url_profile)
        assert isSet(self.data.url_user)
        assert isSet(self.data.proposal)

        context = {}

        user_role = None

        scores = self.getScores()

        # TODO: check if the scoring is not disabled
        score_action = reverse("score_gsoc_proposal", kwargs=self.data.kwargs)

        # get all the comments for the the proposal
        public_comments, private_comments = self.getComments()

        # TODO: check if it is possible to post a comment
        comment_action = reverse("comment_gsoc_proposal", kwargs=self.data.kwargs)

        if self.data.private_comments_visible:
            form = PrivateCommentForm(self.data.POST or None)
            if self.data.orgAdminFor(self.data.proposal.org):
                user_role = "org_admin"
            else:
                user_role = "mentor"

        else:
            form = CommentForm(self.data.POST or None)

        comment_box = {"action": comment_action, "form": form}

        # to keep the blocks as simple as possible, the if branches have
        # been broken down into several if blocks
        user_is_proposer = self.data.user and (self.data.user.key() == self.data.url_user.key())
        if user_is_proposer:
            user_role = "proposer"

            # we will check if the student is allowed to modify the proposal
            # after the student proposal deadline
            is_editable = self.data.timeline.afterStudentSignupEnd() and self.data.proposal.is_editable_post_deadline
            if self.data.timeline.studentSignup() or is_editable:
                context["update_link"] = self.data.redirect.id().urlOf("update_gsoc_proposal")

        possible_mentors = db.get(self.data.proposal.possible_mentors)
        possible_mentors = self.sanitizePossibleMentors(possible_mentors)
        possible_mentors_names = ", ".join([m.name() for m in possible_mentors])

        scoring_visible = self.data.private_comments_visible and (not self.data.proposal_org.scoring_disabled)

        if self.data.orgAdminFor(self.data.proposal_org):
            scoring_visible = True

        duplicate = None
        if self.data.program.duplicates_visible and self.data.orgAdminFor(self.data.proposal_org):
            q = GSoCProposalDuplicate.all()
            q.filter("duplicates", self.data.proposal)
            q.filter("is_duplicate", True)
            dup_entity = q.get()
            duplicate = Duplicate(self.data, dup_entity) if dup_entity else None

        additional_info = self.data.proposal.additional_info

        if user_role:
            context["user_actions"] = UserActions(self.data, user_role)

        context.update(
            {
                "additional_info": url_helper.trim_url_to(additional_info, 50),
                "additional_info_link": additional_info,
                "comment_box": comment_box,
                "duplicate": duplicate,
                "max_score": self.data.proposal_org.max_score,
                "mentor": self.data.proposal.mentor,
                "page_name": self.data.proposal.title,
                "possible_mentors": possible_mentors_names,
                "private_comments": private_comments,
                "private_comments_visible": self.data.private_comments_visible,
                "proposal": self.data.proposal,
                "public_comments": public_comments,
                "public_comments_visible": self.data.public_comments_visible,
                "score_action": score_action,
                "scores": scores,
                "scoring_visible": scoring_visible,
                "student_email": self.data.url_profile.email,
                "student_name": self.data.url_profile.name(),
                "proposal_ignored": self.data.proposal.status == "ignored",
                "user_role": user_role,
            }
        )

        return context
Exemple #20
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 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 context(self, data, check, mutator):
        context = {}

        user_role = None

        scores = self.getScores(data)

        # TODO: check if the scoring is not disabled
        score_action = reverse('score_gsoc_proposal', kwargs=data.kwargs)

        # get all the comments for the the proposal
        public_comments, private_comments = self.getComments(data)

        # TODO: check if it is possible to post a comment
        comment_action = reverse('comment_gsoc_proposal', kwargs=data.kwargs)

        if _getApplyingCommentType(data) == PRIVATE_COMMENTS:

            # only mentors and org admins can see that the proposal is ignored
            # TODO(daniel): replace status literals with constants
            context['proposal_ignored'] = data.url_proposal.status == 'ignored'

            form = PrivateCommentForm(data=data.POST or None)
            org_key = proposal_model.GSoCProposal.org.get_value_for_datastore(
                data.url_proposal)
            if data.orgAdminFor(org_key):
                user_role = 'org_admin'
            else:
                user_role = 'mentor'

        else:
            form = CommentForm(data=data.POST or None)

        comment_box = {
            'action': comment_action,
            'form': form,
        }

        # to keep the blocks as simple as possible, the if branches have
        # been broken down into several if blocks
        user_is_proposer = (data.user
                            and (data.ndb_user.key == data.url_ndb_user.key()))
        if user_is_proposer:
            user_role = 'proposer'

            # we will check if the student is allowed to modify the proposal
            # after the student proposal deadline
            is_editable = data.timeline.afterStudentSignupEnd() and \
                data.url_proposal.is_editable_post_deadline
            if data.timeline.studentSignup() or is_editable:
                context['update_link'] = links.LINKER.userId(
                    data.url_ndb_profile.key(),
                    data.url_proposal.key().id(), 'update_gsoc_proposal')

        possible_mentors = ndb.get_multi(
            map(ndb.Key.from_old_key, data.url_proposal.possible_mentors))
        possible_mentors = self.sanitizePossibleMentors(data, possible_mentors)
        possible_mentors_names = ', '.join(
            [m.public_name for m in possible_mentors])

        org_key = proposal_model.GSoCProposal.org.get_value_for_datastore(
            data.url_proposal)
        org = ndb.Key.from_old_key(org_key).get()
        scoring_visible = _getApplyingCommentType(
            data) == PRIVATE_COMMENTS and (org.scoring_enabled)

        if data.orgAdminFor(org_key):
            scoring_visible = True

        duplicate = None
        if (data.program.duplicates_visible and data.orgAdminFor(org_key)):
            q = GSoCProposalDuplicate.all()
            q.filter('duplicates', data.url_proposal)
            q.filter('is_duplicate', True)
            dup_entity = q.get()
            duplicate = Duplicate(data, dup_entity) if dup_entity else None

        additional_info = data.url_proposal.additional_info

        if user_role:
            context['user_actions'] = UserActions(data, user_role)

        mentor_key = proposal_model.GSoCProposal.mentor.get_value_for_datastore(
            data.url_proposal)
        mentor = ndb.Key.from_old_key(mentor_key).get() if mentor_key else None
        context.update({
            'additional_info':
            url_helper.trim_url_to(additional_info, 50),
            'additional_info_link':
            additional_info,
            'comment_box':
            comment_box,
            'duplicate':
            duplicate,
            'max_score':
            org.max_score,
            'mentor':
            mentor,
            'page_name':
            data.url_proposal.title,
            'possible_mentors':
            possible_mentors_names,
            'private_comments':
            private_comments,
            'private_comments_visible':
            _getApplyingCommentType(data) == PRIVATE_COMMENTS,
            'proposal':
            data.url_proposal,
            'public_comments':
            public_comments,
            'public_comments_visible':
            _getApplyingCommentType(data) == PRIVATE_COMMENTS
            or _getApplyingCommentType(data) == PUBLIC_COMMENTS,
            'score_action':
            score_action,
            'scores':
            scores,
            'scoring_visible':
            scoring_visible,
            'student_email':
            data.url_ndb_profile.contact.email,
            'student_name':
            data.url_ndb_profile.public_name,
            'user_role':
            user_role,
        })

        return context