Example #1
0
def accept_proposals(request, *args, **kwargs):
    """Accept proposals for an organization
  """

    params = request.POST

    # Setup an artifical request deadline
    timelimit = int(params["timelimit"])
    timekeeper = Timekeeper(timelimit)

    # Query proposals based on status
    org = org_logic.getFromKeyName(params["orgkey"])
    proposals = student_proposal_logic.getProposalsToBeAcceptedForOrg(org)

    # Accept proposals
    try:
        for remain, proposal in timekeeper.iterate(proposals):
            logging.info("accept %s %s %s", remain, org.key(), proposal.key())
            accept_proposal(proposal)
            accept_proposal_email(proposal)

    # Requeue this task for continuation
    except DeadlineExceededError:
        taskqueue.add(url=request.path, params=params)
        return responses.terminateTask()

    # Reject remaining proposals
    taskqueue.add(url=params["nextpath"], params=params)
    return responses.terminateTask()
Example #2
0
def accept_proposals(request, *args, **kwargs):
  """Accept proposals for an organization
  """

  params = request.POST

  # Setup an artifical request deadline
  timelimit = int(params["timelimit"])
  timekeeper = Timekeeper(timelimit)

  # Query proposals based on status
  org = org_logic.getFromKeyName(params["orgkey"])
  proposals = student_proposal_logic.getProposalsToBeAcceptedForOrg(org)

  # Accept proposals
  try:
    for remain, proposal in timekeeper.iterate(proposals):
      logging.info("accept %s %s %s", remain, org.key(), proposal.key())
      accept_proposal(proposal)
      accept_proposal_email(proposal)

  # Requeue this task for continuation
  except DeadlineExceededError:
    taskqueue.add(url=request.path, params=params)
    return responses.terminateTask()

  # Reject remaining proposals
  taskqueue.add(url=params["nextpath"], params=params)
  return responses.terminateTask()
Example #3
0
    def getListProposalsData(self, request, rp_params, mp_params, p_params,
                             org_entity):
        """Returns the list data for listProposals.
    """

        from soc.modules.gsoc.logic.models.ranker_root import logic \
            as ranker_root_logic
        from soc.modules.gsoc.logic.models.student_proposal import logic \
            as sp_logic
        from soc.modules.gsoc.models import student_proposal
        from soc.modules.gsoc.views.helper import list_info as list_info_helper
        from soc.modules.gsoc.views.models import student_proposal \
            as student_proposal_view

        idx = request.GET.get('idx', '')
        idx = int(idx) if idx.isdigit() else -1

        args = order = []

        if idx == 0:
            # retrieve the ranker
            fields = {
                'link_id': student_proposal.DEF_RANKER_NAME,
                'scope': org_entity
            }

            ranker_root = ranker_root_logic.getForFields(fields, unique=True)
            ranker = ranker_root_logic.getRootFromEntity(ranker_root)

            keys = []

            # only when the program allows allocations
            # to be seen we should color the list
            if org_entity.scope.allocations_visible:
                proposals = sp_logic.getProposalsToBeAcceptedForOrg(org_entity)
                keys = [i.key() for i in proposals]

                # show the amount of slots assigned on the webpage
                context['slots_visible'] = True

            # TODO(ljvderijk) once sorting with IN operator is fixed,
            # make this list show more
            filter = {'org': org_entity, 'status': 'pending'}
            params = rp_params
            # order by descending score
            order = ['-score']
            args = [ranker, keys]
        elif idx == 1:
            # check if the current user is a mentor
            user_entity = user_logic.getForCurrentAccount()

            fields = {
                'user': user_entity,
                'scope': org_entity,
            }
            mentor_entity = mentor_logic.getForFields(fields, unique=True)

            filter = {
                'org': org_entity,
                'mentor': mentor_entity,
                'status': 'pending'
            }
            params = mp_params
        elif idx == 2:
            filter = {'org': org_entity}
            params = p_params
        else:
            return responses.jsonErrorResponse(request, "idx not valid")

        contents = helper.lists.getListData(request,
                                            params,
                                            filter,
                                            'public',
                                            order=order,
                                            args=args)
        json = simplejson.dumps(contents)

        return responses.jsonResponse(request, json)
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()
Example #5
0
    def getListProposalsData(self, request, params_collection, org_entity):
        """Returns the list data for listProposals.

    Args:
      request: HTTPRequest object
      params_collection: List of list Params indexed with the idx of the list
      org_entity: GSoCOrganization entity for which the lists are generated
    """

        from soc.modules.gsoc.logic.models.proposal_duplicates import logic \
            as pd_logic
        from soc.modules.gsoc.logic.models.ranker_root import logic \
            as ranker_root_logic

        idx = lists.getListIndex(request)

        # default list settings
        args = []
        visibility = None

        if idx == 0:
            filter = {'org': org_entity, 'status': 'new'}
        elif idx == 1:
            # retrieve the ranker
            fields = {
                'link_id': student_proposal.DEF_RANKER_NAME,
                'scope': org_entity
            }

            ranker_root = ranker_root_logic.getForFields(fields, unique=True)
            ranker = ranker_root_logic.getRootFromEntity(ranker_root)

            status = {}

            program_entity = org_entity.scope

            # only when the program allows allocations
            # we show that proposals are likely to be
            # accepted or rejected
            if program_entity.allocations_visible:
                proposals = sp_logic.getProposalsToBeAcceptedForOrg(org_entity)

                duplicate_proposals = []

                # get all the duplicate entities if duplicates can be shown
                # to the organizations and make a list of all such proposals.
                if program_entity.duplicates_visible:
                    duplicate_properties = {
                        'orgs': org_entity,
                        'is_duplicate': True
                    }
                    duplicates = pd_logic.getForFields(duplicate_properties)

                    for duplicate in duplicates:
                        duplicate_proposals.extend(duplicate.duplicates)

                for proposal in proposals:
                    proposal_key = proposal.key()
                    if proposal.status == 'pending' and proposal_key in duplicate_proposals:
                        status[proposal_key] = """<strong><font color="red">
                Duplicate</font></strong>"""
                    else:
                        status[proposal_key] = """<strong><font color="green">
                Pending acceptance</font><strong>"""

            filter = {
                'org': org_entity,
                'status': ['accepted', 'pending', 'rejected']
            }

            # some extras for the list
            args = [ranker, status]
            visibility = 'review'
        elif idx == 2:
            # check if the current user is a mentor
            user_entity = user_logic.getCurrentUser()

            fields = {
                'user': user_entity,
                'scope': org_entity,
                'status': ['active', 'inactive']
            }
            mentor_entity = mentor_logic.getForFields(fields, unique=True)

            filter = {
                'org': org_entity,
                'mentor': mentor_entity,
                'status': ['pending', 'accepted', 'rejected']
            }
        elif idx == 3:
            filter = {'org': org_entity, 'status': 'invalid'}
        else:
            return lists.getErrorResponse(request, "idx not valid")

        params = params_collection[idx]
        contents = helper.lists.getListData(request,
                                            params,
                                            filter,
                                            visibility=visibility,
                                            args=args)

        return lists.getResponse(request, contents)
Example #6
0
  def getListProposalsData(self, request, params_collection, org_entity):
    """Returns the list data for listProposals.

    Args:
      request: HTTPRequest object
      params_collection: List of list Params indexed with the idx of the list
      org_entity: GSoCOrganization entity for which the lists are generated
    """

    from soc.modules.gsoc.logic.models.proposal_duplicates import logic \
        as pd_logic
    from soc.modules.gsoc.logic.models.ranker_root import logic \
        as ranker_root_logic

    idx = lists.getListIndex(request)

    # default list settings
    args = []
    visibility = None

    if idx == 0:
      filter = {'org': org_entity,
                'status': 'new'}
    elif idx == 1:
      # retrieve the ranker
      fields = {'link_id': student_proposal.DEF_RANKER_NAME,
                'scope': org_entity}

      ranker_root = ranker_root_logic.getForFields(fields, unique=True)
      ranker = ranker_root_logic.getRootFromEntity(ranker_root)

      status = {}

      program_entity = org_entity.scope

      # only when the program allows allocations
      # we show that proposals are likely to be
      # accepted or rejected
      if program_entity.allocations_visible:
        proposals = sp_logic.getProposalsToBeAcceptedForOrg(org_entity)

        duplicate_proposals = []

        # get all the duplicate entities if duplicates can be shown
        # to the organizations and make a list of all such proposals.
        if program_entity.duplicates_visible:
          duplicate_properties = {
              'orgs': org_entity,
              'is_duplicate': True
              }
          duplicates = pd_logic.getForFields(duplicate_properties)

          for duplicate in duplicates:
            duplicate_proposals.extend(duplicate.duplicates)

        for proposal in proposals:
          proposal_key =  proposal.key()
          if proposal.status == 'pending' and proposal_key in duplicate_proposals:
            status[proposal_key] = """<strong><font color="red">
                Duplicate</font></strong>"""
          else:
            status[proposal_key] = """<strong><font color="green">
                Pending acceptance</font><strong>"""

      filter = {'org': org_entity,
                'status': ['accepted','pending','rejected']}

      # some extras for the list
      args = [ranker, status]
      visibility = 'review'
    elif idx == 2:
      # check if the current user is a mentor
      user_entity = user_logic.getCurrentUser()

      fields = {'user': user_entity,
                'scope': org_entity,
                'status': ['active', 'inactive']}
      mentor_entity = mentor_logic.getForFields(fields, unique=True)

      filter = {'org': org_entity,
                'mentor': mentor_entity,
                'status': ['pending', 'accepted', 'rejected']}
    elif idx == 3:
      filter = {'org': org_entity,
                'status': 'invalid'}
    else:
      return lists.getErrorResponse(request, "idx not valid")

    params = params_collection[idx]
    contents = helper.lists.getListData(request, params, filter,
                                        visibility=visibility, args=args)

    return lists.getResponse(request, contents)
Example #7
0
    def assignedProposals(self,
                          request,
                          access_type,
                          page_name=None,
                          params=None,
                          filter=None,
                          **kwargs):
        """Returns a JSON dict containing all the proposals that would have
    a slot assigned for a specific set of orgs.

    The request.GET limit and offset determines how many and which
    organizations should be returned.

    For params see base.View.public().

    Returns: JSON object with a collection of orgs and proposals. Containing
             identification information and contact information.
    """

        get_dict = request.GET

        if not (get_dict.get('limit') and get_dict.get('offset')):
            return self.json(request, {})

        try:
            limit = max(0, int(get_dict['limit']))
            offset = max(0, int(get_dict['offset']))
        except ValueError:
            return self.json(request, {})

        program_entity = program_logic.getFromKeyFieldsOr404(kwargs)

        fields = {'scope': program_entity, 'slots >': 0, 'status': 'active'}

        org_entities = org_logic.logic.getForFields(fields,
                                                    limit=limit,
                                                    offset=offset)

        orgs_data = {}
        proposals_data = []

        # for each org get the proposals who will be assigned a slot
        for org in org_entities:

            org_data = {'name': org.name}

            fields = {'scope': org, 'status': 'active', 'user': org.founder}

            org_admin = org_admin_logic.getForFields(fields, unique=True)

            if org_admin:
                # pylint: disable-msg=E1103
                org_data['admin_name'] = org_admin.name()
                org_data['admin_email'] = org_admin.email

            proposals = student_proposal_logic.getProposalsToBeAcceptedForOrg(
                org, step_size=program_entity.max_slots)

            if not proposals:
                # nothing to accept, next organization
                continue

            # store information about the org
            orgs_data[org.key().id_or_name()] = org_data

            # store each proposal in the dictionary
            for proposal in proposals:
                student_entity = proposal.scope

                proposals_data.append({
                    'key_name':
                    proposal.key().id_or_name(),
                    'proposal_title':
                    proposal.title,
                    'student_key':
                    student_entity.key().id_or_name(),
                    'student_name':
                    student_entity.name(),
                    'student_contact':
                    student_entity.email,
                    'org_key':
                    org.key().id_or_name()
                })

        # return all the data in JSON format
        data = {'orgs': orgs_data, 'proposals': proposals_data}

        return self.json(request, data)
Example #8
0
  def assignedProposals(self, request, access_type, page_name=None,
                        params=None, filter=None, **kwargs):
    """Returns a JSON dict containing all the proposals that would have
    a slot assigned for a specific set of orgs.

    The request.GET limit and offset determines how many and which
    organizations should be returned.

    For params see base.View.public().

    Returns: JSON object with a collection of orgs and proposals. Containing
             identification information and contact information.
    """

    get_dict = request.GET

    if not (get_dict.get('limit') and get_dict.get('offset')):
      return self.json(request, {})

    try:
      limit = max(0, int(get_dict['limit']))
      offset = max(0, int(get_dict['offset']))
    except ValueError:
      return self.json(request, {})

    program_entity = program_logic.getFromKeyFieldsOr404(kwargs)

    fields = {'scope': program_entity,
              'slots >': 0,
              'status': 'active'}

    org_entities = org_logic.getForFields(fields,
        limit=limit, offset=offset)

    orgs_data = {}
    proposals_data = []

    # for each org get the proposals who will be assigned a slot
    for org in org_entities:

      org_data = {'name': org.name}

      fields = {'scope': org,
                'status': 'active',
                'user': org.founder}

      org_admin = org_admin_logic.getForFields(fields, unique=True)

      if org_admin:
        # pylint: disable=E1103
        org_data['admin_name'] = org_admin.name()
        org_data['admin_email'] = org_admin.email

      proposals = student_proposal_logic.getProposalsToBeAcceptedForOrg(
          org, step_size=program_entity.max_slots)

      if not proposals:
        # nothing to accept, next organization
        continue

      # store information about the org
      orgs_data[org.key().id_or_name()] = org_data

      # store each proposal in the dictionary
      for proposal in proposals:
        student_entity = proposal.scope

        proposals_data.append(
            {'key_name': proposal.key().id_or_name(),
            'proposal_title': proposal.title,
            'student_key': student_entity.key().id_or_name(),
            'student_name': student_entity.name(),
            'student_contact': student_entity.email,
            'org_key': org.key().id_or_name()
            })

    # return all the data in JSON format
    data = {'orgs': orgs_data,
            'proposals': proposals_data}

    return self.json(request, data)
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()