Exemple #1
0
  def _constructFilterForProjectSelection(self, survey, params):
    """Returns the filter needed for the Project selection view.

    Constructs a filter that returns all valid projects for which the current
    user is the mentor. Only for the projects in the program given by the
    survey's scope of course.

    For args see project_survey.View._constructFilterForProjectSelection().
    """

    from soc.modules.gsoc.logic.models.mentor import logic as mentor_logic

    survey_logic = params['logic']

    user_entity = user_logic.getCurrentUser()

    # get the mentor entities for the current user and program
    fields = {'user': user_entity,
              'program': survey_logic.getScope(survey),
              'status': 'active'}

    mentor_entities = mentor_logic.getForFields(fields)

    # TODO: Ensure that this doesn't break when someone is a mentor for
    # a lot of organizations.

    fields = {'mentor': mentor_entities,
              'status': 'accepted'}

    return fields
  def _editPost(self, request, entity, fields):
    """See base.View._editPost().
    """

    if not entity:
      fields['link_id'] = 't%i' % (int(time.time()*100))
    else:
      fields['link_id'] = entity.link_id

    # fill in the scope via call to super
    super(View, self)._editPost(request, entity, fields)

    # editing a project so set the program, student and mentor field
    if entity:
      organization = entity.scope
    else:
      organization = fields['scope']

    fields['program'] = organization.scope

    filter = {'scope': fields['program'],
              'link_id': fields['student_id']}
    fields['student'] = student_logic.logic.getForFields(filter, unique=True)

    filter = {'scope': organization,
              'link_id': fields['mentor_id'],
              'status': 'active'}
    fields['mentor'] = mentor_logic.getForFields(filter, unique=True)
  def _editPost(self, request, entity, fields):
    """See base.View._editPost().
    """

    if not entity:
      fields['link_id'] = 't%i' % (int(time.time()*100))
    else:
      fields['link_id'] = entity.link_id

    # fill in the scope via call to super
    super(View, self)._editPost(request, entity, fields)

    # editing a project so set the program, student and mentor field
    if entity:
      organization = entity.scope
    else:
      organization = fields['scope']

    fields['program'] = organization.scope

    filter = {'scope': fields['program'],
              'link_id': fields['student_id']}
    fields['student'] = student_logic.logic.getForFields(filter, unique=True)

    filter = {'scope': organization,
              'link_id': fields['mentor_id'],
              'status': 'active'}
    fields['mentor'] = mentor_logic.getForFields(filter, unique=True)
Exemple #4
0
  def _getResultsViewRecordFields(self, survey, allowed_to_read):
    """Get the Results View filter for ProjectSurveyRecords.

    For args see survey.View()._getResultsViewRecordFields()

    Returns:
      Returns the dictionary containing the fields to filter on
    """

    from soc.modules.gsoc.logic.models.mentor import logic as mentor_logic
    from soc.modules.gsoc.logic.models.org_admin import logic as \
        org_admin_logic

    if allowed_to_read:
      return super(View, self)._getResultsViewRecordFields(survey,
                                                           allowed_to_read)

    fields = {'survey': survey}

    user_entity = user_logic.getCurrentUser()
    program_entity = survey.scope

    role_fields = {'user': user_entity,
                   'program': program_entity,
                   'status': ['active', 'inactive']}

    org_admins = org_admin_logic.getForFields(role_fields)
    mentors = mentor_logic.getForFields(role_fields)

    organizations = {}

    if org_admins:
      for org_admin in org_admins:
        # for each org admin store the organization
        org_scope = org_admin.scope
        org_key_name = org_scope.key().id_or_name()
        organizations[org_key_name] = org_scope

    if mentors:
      for mentor in mentors:
        # for each mentor store the organization
        # This will allow the user to view the GradingProjectSurvey Records
        # listing for projects which he might have no further access to.
        org_scope = mentor.scope
        org_key_name = org_scope.key().id_or_name()
        organizations[org_key_name] = org_scope

    if organizations:
      # filter on all the found organizations
      fields['org'] = organizations.values()
    else:
      # This user is no org admin or mentor and should only see
      # his/her own records.
      fields['user'] = user_entity

    return fields
Exemple #5
0
    def _manageSetMentor(self, request, template, context, params, entity,
                         form):
        """Handles the POST request for changing a Projects's mentor.

    Args:
        template: the template used for this view
        entity: the student project entity
        form: instance of the form used to set the mentor
        rest: see base.View.public()
    """

        if not form.is_valid():
            context['mentor_edit_form'] = form

            # add an a fresh additional mentors form
            context['additional_mentor_form'] = params[
                'additional_mentor_form']()

            return responses.respond(request, template, context)

        _, fields = forms_helper.collectCleanedFields(form)

        # get the mentor from the form
        fields = {
            'link_id': fields['mentor_id'],
            'scope': entity.scope,
            'status': 'active'
        }
        mentor = mentor_logic.getForFields(fields, unique=True)

        # update the project with the assigned mentor
        fields = {'mentor': mentor}

        additional_mentors = entity.additional_mentors

        # pylint: disable=E1103
        if additional_mentors and mentor.key() in additional_mentors:
            # remove the mentor that is now becoming the primary mentor
            additional_mentors.remove(mentor.key())
            fields['additional_mentors'] = additional_mentors

        # update the project with the new mentor and possible
        # new set of additional mentors
        project_logic.updateEntityProperties(entity, fields)

        # redirect to the same page
        redirect = request.path
        return http.HttpResponseRedirect(redirect)
  def _manageSetMentor(self, request, template, context, params, entity, form):
    """Handles the POST request for changing a Projects's mentor.

    Args:
        template: the template used for this view
        entity: the student project entity
        form: instance of the form used to set the mentor
        rest: see base.View.public()
    """

    if not form.is_valid():
      context['mentor_edit_form'] = form

      # add an a fresh additional mentors form
      context['additional_mentor_form'] = params['additional_mentor_form']()

      return responses.respond(request, template, context)

    _, fields = forms_helper.collectCleanedFields(form)

    # get the mentor from the form
    fields = {'link_id': fields['mentor_id'],
              'scope': entity.scope,
              'status': 'active'}
    mentor = mentor_logic.getForFields(fields, unique=True)

    # update the project with the assigned mentor
    fields = {'mentor': mentor}

    additional_mentors = entity.additional_mentors

    # pylint: disable=E1103
    if additional_mentors and mentor.key() in additional_mentors:
      # remove the mentor that is now becoming the primary mentor
      additional_mentors.remove(mentor.key())
      fields['additional_mentors'] = additional_mentors

    # update the project with the new mentor and possible 
    # new set of additional mentors
    project_logic.updateEntityProperties(entity, fields)

    # redirect to the same page
    redirect = request.path
    return http.HttpResponseRedirect(redirect)
Exemple #7
0
    def _manageAddAdditionalMentor(self, request, template, context, params,
                                   entity, form):
        """Handles the POST request for changing a Projects's additional mentors.

    Args:
        template: the template used for this view
        entity: the student project entity
        form: instance of the form used to add an additional mentor
        rest: see base.View.public()
    """

        if not form.is_valid():
            context['additional_mentor_form'] = form

            # add a fresh edit mentor form
            initial = {'mentor_id': entity.mentor.link_id}
            context['mentor_edit_form'] = params['mentor_edit_form'](
                initial=initial)

            return responses.respond(request, template, context)

        _, fields = forms_helper.collectCleanedFields(form)

        # get the mentor from the form
        fields = {
            'link_id': fields['mentor_id'],
            'scope': entity.scope,
            'status': 'active'
        }
        mentor = mentor_logic.getForFields(fields, unique=True)

        # add this mentor to the additional mentors
        if not entity.additional_mentors:
            additional_mentors = [mentor.key()]
        else:
            additional_mentors = entity.additional_mentors
            additional_mentors.append(mentor.key())

        fields = {'additional_mentors': additional_mentors}
        project_logic.updateEntityProperties(entity, fields)

        # redirect to the same page
        redirect = request.path
        return http.HttpResponseRedirect(redirect)
  def _manageAddAdditionalMentor(self, request, template, 
                                 context, params, entity, form):
    """Handles the POST request for changing a Projects's additional mentors.

    Args:
        template: the template used for this view
        entity: the student project entity
        form: instance of the form used to add an additional mentor
        rest: see base.View.public()
    """

    if not form.is_valid():
      context['additional_mentor_form'] = form

      # add a fresh edit mentor form
      initial = {'mentor_id': entity.mentor.link_id}
      context['mentor_edit_form'] = params['mentor_edit_form'](initial=initial)

      return responses.respond(request, template, context)

    _, fields = forms_helper.collectCleanedFields(form)

    # get the mentor from the form
    fields = {'link_id': fields['mentor_id'],
              'scope': entity.scope,
              'status': 'active'}
    mentor = mentor_logic.getForFields(fields, unique=True)

    # add this mentor to the additional mentors
    if not entity.additional_mentors:
      additional_mentors = [mentor.key()]
    else:
      additional_mentors = entity.additional_mentors
      additional_mentors.append(mentor.key())

    fields = {'additional_mentors': additional_mentors}
    project_logic.updateEntityProperties(entity, fields)

    # redirect to the same page
    redirect = request.path
    return http.HttpResponseRedirect(redirect)
Exemple #9
0
    def manageGet(self, request, template, context, params, entity, **kwargs):
        """Handles the GET request for the project's manage page.

    Args:
        template: the template used for this view
        entity: the student project entity
        rest: see base.View.public()
    """

        get_dict = request.GET

        if 'remove' in get_dict and entity.status == 'accepted':
            # get the mentor to remove
            fields = {'link_id': get_dict['remove'], 'scope': entity.scope}
            mentor = mentor_logic.getForFields(fields, unique=True)

            additional_mentors = entity.additional_mentors
            # pylint: disable=E1103
            if additional_mentors and mentor.key() in additional_mentors:
                # remove the mentor from the additional mentors list
                additional_mentors.remove(mentor.key())
                fields = {'additional_mentors': additional_mentors}
                project_logic.updateEntityProperties(entity, fields)

            # redirect to the same page without GET arguments
            redirect = request.path
            return http.HttpResponseRedirect(redirect)

        if project_logic.canChangeMentors(entity):
            # populate forms with the current mentors set
            initial = {'mentor_id': entity.mentor.link_id}
            context['mentor_edit_form'] = params['mentor_edit_form'](
                initial=initial)
            context['additional_mentor_form'] = params[
                'additional_mentor_form']()

        return responses.respond(request, template, context)
Exemple #10
0
  def manageGet(self, request, template, context, params, entity, **kwargs):
    """Handles the GET request for the project's manage page.

    Args:
        template: the template used for this view
        entity: the student project entity
        rest: see base.View.public()
    """

    get_dict = request.GET

    if 'remove' in get_dict and entity.status == 'accepted':
      # get the mentor to remove
      fields = {'link_id': get_dict['remove'],
                'scope': entity.scope}
      mentor = mentor_logic.getForFields(fields, unique=True)

      additional_mentors = entity.additional_mentors
      # pylint: disable=E1103
      if additional_mentors and mentor.key() in additional_mentors:
        # remove the mentor from the additional mentors list
        additional_mentors.remove(mentor.key())
        fields = {'additional_mentors': additional_mentors}
        project_logic.updateEntityProperties(entity, fields)

      # redirect to the same page without GET arguments
      redirect = request.path
      return http.HttpResponseRedirect(redirect)

    if project_logic.canChangeMentors(entity):
      # populate forms with the current mentors set
      initial = {'mentor_id': entity.mentor.link_id}
      context['mentor_edit_form'] = params['mentor_edit_form'](initial=initial)
      context['additional_mentor_form'] = params['additional_mentor_form']()

    return responses.respond(request, template, context)
Exemple #11
0
    def checkRoleAndStatusForStudentProposal(self, django_args, allowed_roles,
                                             role_status, proposal_status):
        """Checks if the current user has access to the given proposal.

    Args:
      django_args: a dictionary with django's arguments
      allowed_roles: list with names for the roles allowed to pass access check
      role_status: list with states allowed for the role
      proposal_status: a list with states allowed for the proposal

     Raises:
       AccessViolationResponse:
         - If there is no proposal found
         - If the proposal is not in one of the required states.
         - If the user does not have any ofe the required roles
    """

        self.checkIsUser(django_args)

        # bail out with 404 if no proposal is found
        proposal_entity = student_proposal_logic.getFromKeyFieldsOr404(
            django_args)

        if not proposal_entity.status in proposal_status:
            # this proposal can not be accessed at the moment
            raise out_of_band.AccessViolation(
                message_fmt=access.DEF_NO_ACTIVE_ENTITY_MSG)

        user_entity = self.user

        if 'proposer' in allowed_roles:
            # check if this proposal belongs to the current user
            student_entity = proposal_entity.scope
            if (user_entity.key()
                    == student_entity.user.key()) and (student_entity.status
                                                       in role_status):
                return

        filter = {'user': user_entity, 'status': role_status}

        if 'host' in allowed_roles:
            # check if the current user is a host for this proposal's program
            filter['scope'] = proposal_entity.program.scope

            if host_logic.getForFields(filter, unique=True):
                return

        if 'org_admin' in allowed_roles:
            # check if the current user is an admin for this proposal's org
            filter['scope'] = proposal_entity.org

            if org_admin_logic.getForFields(filter, unique=True):
                return

        if 'mentor' in allowed_roles:
            # check if the current user is a mentor for this proposal's org
            filter['scope'] = proposal_entity.org

            if mentor_logic.getForFields(filter, unique=True):
                return

        # no roles found, access denied
        raise out_of_band.AccessViolation(message_fmt=access.DEF_NEED_ROLE_MSG)
Exemple #12
0
  def _getTimeDependentEntries(self, program_entity, params, id, user):
    """Returns a list with time dependent menu items.
    """

    items = []

    timeline_entity = program_entity.timeline

    org_app_survey = org_app_logic.getForProgram(program_entity)

    if org_app_survey and \
        timeline_helper.isActivePeriod(org_app_survey, 'survey'):
      # add the organization signup link
      items += [
          (redirects.getTakeSurveyRedirect(
               org_app_survey, {'url_name': 'gsoc/org_app'}),
          "Apply to become an Organization", 'any_access')]

    if user and org_app_survey and timeline_helper.isAfterEvent(
        org_app_survey, 'survey_start'):

      main_admin_fields = {
          'main_admin': user,
          'survey': org_app_survey,
          }

      backup_admin_fields = {
          'backup_admin': user,
          'survey': org_app_survey
          }

      org_app_record_logic = org_app_logic.getRecordLogic()

      if org_app_record_logic.getForFields(main_admin_fields, unique=True) or \
          org_app_record_logic.getForFields(backup_admin_fields, unique=True):
        # add the 'List my Organization Applications' link
        items += [
            (redirects.getListSelfRedirect(org_app_survey,
                                           {'url_name' : 'gsoc/org_app'}),
             "List My Organization Applications", 'any_access')]

    # get the student entity for this user and program
    filter = {
        'user': user,
        'scope': program_entity,
        'status': ['active', 'inactive']
        }
    student_entity = student_logic.getForFields(filter, unique=True)

    if student_entity:
      items += self._getStudentEntries(program_entity, student_entity,
                                       params, id, user, 'gsoc')

    # get mentor and org_admin entity for this user and program
    filter = {
        'user': user,
        'program': program_entity,
        'status': ['active', 'inactive']
        }
    mentor_entity = mentor_logic.getForFields(filter, unique=True)
    org_admin_entity = org_admin_logic.getForFields(filter, unique=True)

    if mentor_entity or org_admin_entity:
      items += self._getOrganizationEntries(program_entity, org_admin_entity,
                                            mentor_entity, params, id, user)

    if not (student_entity or mentor_entity or org_admin_entity):
      if timeline_helper.isActivePeriod(timeline_entity, 'student_signup'):
        # this user does not have a role yet for this program
        items += [
            ('/gsoc/student/apply/%s' % (program_entity.key().id_or_name()),
            "Register as a Student", 'any_access')]

    deadline = 'accepted_organization_announced_deadline'

    if timeline_helper.isAfterEvent(timeline_entity, deadline):
      url = redirects.getAcceptedOrgsRedirect(program_entity, params)
      # add a link to list all the organizations
      items += [(url, "List participating Organizations", 'any_access')]

      if not student_entity and \
          timeline_helper.isBeforeEvent(timeline_entity, 'program_end'):
        # add apply to become a mentor link
        items += [
            ('/gsoc/org/apply_mentor/%s' % (program_entity.key().id_or_name()),
           "Apply to become a Mentor", 'any_access')]

    deadline = 'accepted_students_announced_deadline'

    if timeline_helper.isAfterEvent(timeline_entity, deadline):
      items += [(redirects.getListProjectsRedirect(program_entity,
          {'url_name':'gsoc/program'}),
          "List all Student Projects", 'any_access')]

    return items
  def _enableMentorManagement(self, entity, params, context):
    """Sets the data required to manage mentors for a StudentProject.

    Args:
      entity: StudentProject entity to manage
      params: params dict for the manage view
      context: context for the manage view
    """

    context['can_manage_mentors'] = True

    # get all mentors for this organization
    fields = {'scope': entity.scope,
              'status': 'active'}
    mentors = mentor_logic.getForFields(fields)

    choices = [(mentor.link_id,'%s (%s)' %(mentor.name(), mentor.link_id))
                  for mentor in mentors]

    # create the form that org admins will use to reassign a mentor
    dynafields = [
        {'name': 'mentor_id',
         'base': forms.ChoiceField,
         'label': 'Primary Mentor',
         'required': True,
         'passthrough': ['required', 'choices', 'label'],
         'choices': choices,
        },]

    dynaproperties = params_helper.getDynaFields(dynafields)

    mentor_edit_form = dynaform.newDynaForm(
        dynabase = params['dynabase'],
        dynaproperties = dynaproperties,
    )

    params['mentor_edit_form'] = mentor_edit_form

    additional_mentors = entity.additional_mentors

    # we want to show the names of the additional mentors in the context
    # therefore they need to be resolved to entities first
    additional_mentors_context = []

    for mentor_key in additional_mentors:
      mentor_entity = mentor_logic.getFromKeyName(
          mentor_key.id_or_name())
      additional_mentors_context.append(mentor_entity)

    context['additional_mentors'] = additional_mentors_context

    # all mentors who are not already an additional mentor or
    # the primary mentor are allowed to become an additional mentor
    possible_additional_mentors = [m for m in mentors if 
        (m.key() not in additional_mentors) 
        and (m.key() != entity.mentor.key())]

    # create the information to be shown on the additional mentor form
    additional_mentor_choices = [
        (mentor.link_id,'%s (%s)' %(mentor.name(), mentor.link_id))
        for mentor in possible_additional_mentors]

    dynafields = [
        {'name': 'mentor_id',
         'base': forms.ChoiceField,
         'label': 'Co-Mentor',
         'required': True,
         'passthrough': ['required', 'choices', 'label'],
         'choices': additional_mentor_choices,
        },]

    dynaproperties = params_helper.getDynaFields(dynafields)

    additional_mentor_form = dynaform.newDynaForm(
        dynabase = params['dynabase'],
        dynaproperties = dynaproperties,
    )

    params['additional_mentor_form'] = additional_mentor_form
Exemple #14
0
  def checkRoleAndStatusForStudentProposal(self, django_args, allowed_roles,
                                           role_status, proposal_status):
    """Checks if the current user has access to the given proposal.

    Args:
      django_args: a dictionary with django's arguments
      allowed_roles: list with names for the roles allowed to pass access check
      role_status: list with states allowed for the role
      proposal_status: a list with states allowed for the proposal

     Raises:
       AccessViolationResponse:
         - If there is no proposal found
         - If the proposal is not in one of the required states.
         - If the user does not have any ofe the required roles
    """

    self.checkIsUser(django_args)

    # bail out with 404 if no proposal is found
    proposal_entity = student_proposal_logic.getFromKeyFieldsOr404(django_args)

    if not proposal_entity.status in proposal_status:
      # this proposal can not be accessed at the moment
      raise out_of_band.AccessViolation(
          message_fmt=access.DEF_NO_ACTIVE_ENTITY_MSG)

    user_entity = self.user

    if 'proposer' in allowed_roles:
      # check if this proposal belongs to the current user
      student_entity = proposal_entity.scope
      if (user_entity.key() == student_entity.user.key()) and (
          student_entity.status in role_status):
        return

    filter = {'user': user_entity,
        'status': role_status}

    if 'host' in allowed_roles:
      # check if the current user is a host for this proposal's program
      filter['scope'] =  proposal_entity.program.scope

      if host_logic.getForFields(filter, unique=True):
        return

    if 'org_admin' in allowed_roles:
      # check if the current user is an admin for this proposal's org
      filter['scope'] = proposal_entity.org

      if org_admin_logic.getForFields(filter, unique=True):
        return

    if 'mentor' in allowed_roles:
      # check if the current user is a mentor for this proposal's org
      filter['scope'] = proposal_entity.org

      if mentor_logic.getForFields(filter, unique=True):
        return

    # no roles found, access denied
    raise out_of_band.AccessViolation(
        message_fmt=access.DEF_NEED_ROLE_MSG)
Exemple #15
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)
Exemple #16
0
    def _getTimeDependentEntries(self, program_entity, params, id, user):
        """Returns a list with time dependent menu items.
    """

        from soc.modules.gsoc.logic.models.org_app_survey import logic as \
            org_app_logic

        items = []

        timeline_entity = program_entity.timeline

        org_app_survey = org_app_logic.getForProgram(program_entity)

        if org_app_survey and \
            timeline_helper.isActivePeriod(timeline_entity, 'org_signup'):
            # add the organization signup link
            items += [
                (redirects.getTakeSurveyRedirect(org_app_survey,
                                                 {'url_name': 'gsoc/org_app'}),
                 "Apply to become an Organization", 'any_access')
            ]

        if user and org_app_survey and timeline_helper.isAfterEvent(
                timeline_entity, 'org_signup_start'):

            main_admin_fields = {
                'main_admin': user,
                'survey': org_app_survey,
            }

            backup_admin_fields = {
                'backup_admin': user,
                'survey': org_app_survey
            }

            org_app_record_logic = org_app_logic.getRecordLogic()

            if org_app_record_logic.getForFields(main_admin_fields, unique=True) or \
                org_app_record_logic.getForFields(backup_admin_fields, unique=True):
                # add the 'List my Organization Applications' link
                items += [(redirects.getListSelfRedirect(
                    org_app_survey, {'url_name': 'gsoc/org_app'}),
                           "List My Organization Applications", 'any_access')]

        # get the student entity for this user and program
        filter = {
            'user': user,
            'scope': program_entity,
            'status': ['active', 'inactive']
        }
        student_entity = student_logic.getForFields(filter, unique=True)

        if student_entity:
            items += self._getStudentEntries(program_entity, student_entity,
                                             params, id, user, 'gsoc')

        # get mentor and org_admin entity for this user and program
        filter = {
            'user': user,
            'program': program_entity,
            'status': ['active', 'inactive']
        }
        mentor_entity = mentor_logic.getForFields(filter, unique=True)
        org_admin_entity = org_admin_logic.getForFields(filter, unique=True)

        if mentor_entity or org_admin_entity:
            items += self._getOrganizationEntries(program_entity,
                                                  org_admin_entity,
                                                  mentor_entity, params, id,
                                                  user)

        if user and not (student_entity or mentor_entity or org_admin_entity):
            if timeline_helper.isActivePeriod(timeline_entity,
                                              'student_signup'):
                # this user does not have a role yet for this program
                items += [('/gsoc/student/apply/%s' %
                           (program_entity.key().id_or_name()),
                           "Register as a Student", 'any_access')]

        deadline = 'accepted_organization_announced_deadline'

        if timeline_helper.isAfterEvent(timeline_entity, deadline):
            url = redirects.getAcceptedOrgsRedirect(program_entity, params)
            # add a link to list all the organizations
            items += [(url, "List participating Organizations", 'any_access')]

            if not student_entity and \
                timeline_helper.isBeforeEvent(timeline_entity, 'program_end'):
                # add apply to become a mentor link
                items += [('/gsoc/org/apply_mentor/%s' %
                           (program_entity.key().id_or_name()),
                           "Apply to become a Mentor", 'any_access')]

        deadline = 'accepted_students_announced_deadline'

        if timeline_helper.isAfterEvent(timeline_entity, deadline):
            items += [(redirects.getListProjectsRedirect(
                program_entity, {'url_name': 'gsoc/program'}),
                       "List all Student Projects", 'any_access')]

        return items
Exemple #17
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)
Exemple #18
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)
Exemple #19
0
class View(organization.View):
    """View methods for the Organization model.
  """
    def __init__(self, params=None):
        """Defines the fields and methods required for the base View class
    to provide the user with list, public, create, edit and delete views.

    Params:
      params: a dict with params for this View
    """

        rights = access.GSoCChecker(params)
        rights['any_access'] = ['allow']
        rights['show'] = ['allow']
        rights['create'] = ['checkIsDeveloper']
        rights['edit'] = [('checkHasRoleForKeyFieldsAsScope', org_admin_logic),
                          ('checkGroupIsActiveForLinkId', org_logic)]
        rights['delete'] = ['checkIsDeveloper']
        rights['home'] = ['allow']
        rights['public_list'] = ['allow']
        rights['applicant'] = [('checkIsOrgAppAccepted', org_app_logic)]
        rights['apply_mentor'] = ['checkIsUser']
        rights['list_requests'] = [('checkHasRoleForKeyFieldsAsScope',
                                    org_admin_logic)]
        rights['list_roles'] = [('checkHasRoleForKeyFieldsAsScope',
                                 org_admin_logic)]
        rights['list_proposals'] = [
            ('checkHasAny', [[('checkHasRoleForKeyFieldsAsScope',
                               [org_admin_logic, ['active', 'inactive']]),
                              ('checkHasRoleForKeyFieldsAsScope',
                               [mentor_logic, ['active', 'inactive']])]])
        ]

        new_params = {}
        new_params['logic'] = org_logic
        new_params['rights'] = rights

        new_params['scope_view'] = program_view

        new_params['name'] = "GSoC Organization"
        new_params['module_name'] = "organization"
        new_params['sidebar_grouping'] = 'Organizations'

        new_params['module_package'] = 'soc.modules.gsoc.views.models'
        new_params['url_name'] = 'gsoc/org'
        new_params['document_prefix'] = 'gsoc_org'

        new_params['mentor_role_name'] = 'gsoc_mentor'
        new_params['mentor_url_name'] = 'gsoc/mentor'
        new_params['org_admin_role_name'] = 'gsoc_org_admin'

        patterns = []

        patterns += [
            (r'^org_tags/(?P<access_type>pick)$',
             '%(module_package)s.%(module_name)s.pick_suggested_tags',
             "Pick a list of suggested tags."),
        ]

        new_params['extra_django_patterns'] = patterns

        new_params['extra_dynaexclude'] = [
            'slots', 'slots_calculated', 'nr_applications', 'nr_mentors'
        ]

        new_params['create_extra_dynaproperties'] = {
            'tags':
            widgets.ReferenceField(
                required=False,
                reference_url='org_tags',
                label=ugettext('Tags'),
                help_text=ugettext("A list of comma seperated tags"),
                example_text="e.g. python, django, appengine",
                filter=['scope_path'],
                group="1. Public Info"),
            'clean_tags':
            gsoc_cleaning.cleanTagsList('tags', gsoc_cleaning.COMMA_SEPARATOR),
            'contrib_template':
            forms.fields.CharField(widget=helper.widgets.FullTinyMCE(
                attrs={
                    'rows': 25,
                    'cols': 100
                })),
            'clean_contrib_template':
            cleaning.clean_html_content('contrib_template'),
            'clean_facebook':
            cleaning.clean_url('facebook'),
            'clean_twitter':
            cleaning.clean_url('twitter'),
            'clean_blog':
            cleaning.clean_url('blog'),
        }

        new_params['org_app_logic'] = org_app_logic

        params = dicts.merge(params, new_params, sub_merge=True)

        super(View, self).__init__(params)

        self._params['public_field_keys'].append('tags')
        self._params['public_field_names'].append("Tags")
        self._params['public_field_extra'] = lambda entity: {
            'ideas': lists.urlize(entity.ideas, 'Click Here'),
            'tags': entity.tags_string(entity.org_tag),
        }
        self._params['select_field_extra'] = self._params['public_field_extra']

    def _editGet(self, request, entity, form):
        """See base.View._editGet().
    """

        if entity.org_tag:
            form.fields['tags'].initial = entity.tags_string(entity.org_tag)

        return super(View, self)._editGet(request, entity, form)

    def _editPost(self, request, entity, fields):
        """See base.View._editPost().
    """

        super(View, self)._editPost(request, entity, fields)

        fields['org_tag'] = {
            'tags': fields['tags'],
            'scope': entity.scope if entity else fields['scope']
        }

    @decorators.check_access
    def pickSuggestedTags(self,
                          request,
                          access_type,
                          page_name=None,
                          params=None,
                          **kwargs):
        """Returns a JSON representation of a list of organization tags
     that are suggested for a given GSoCProgram in scope.
    """

        if 'scope_path' not in request.GET:
            data = []
        else:
            program = program_logic.getFromKeyName(
                request.GET.get('scope_path'))
            if not program:
                data = []
            else:
                fun = soc.cache.logic.cache(OrgTag.get_for_custom_query)
                suggested_tags = fun(OrgTag,
                                     filter={'scope': program},
                                     order=None)
                # TODO: this should be refactored after the issue with autocompletion
                #       is resolved
                data = simplejson.dumps({
                    'data':
                    [{
                        'link_id': item['tag']
                    } for item in
                     [dicts.toDict(tag, ['tag']) for tag in suggested_tags]],
                    'autocomplete_options': {
                        'multiple': True,
                        'selectFirst': False
                    }
                })

        return self.json(request, data, False)

    # TODO (dhans): merge common items with the GCI module in a single function
    def _getExtraMenuItems(self, role_description, params=None):
        """Used to create the specific Organization menu entries.

    For args see group.View._getExtraMenuItems().
    """
        submenus = []

        group_entity = role_description['group']
        program_entity = group_entity.scope
        roles = role_description['roles']

        mentor_entity = roles.get('gsoc_mentor')
        admin_entity = roles.get('gsoc_org_admin')

        is_active_mentor = mentor_entity and mentor_entity.status == 'active'
        is_active_admin = admin_entity and admin_entity.status == 'active'

        if admin_entity or mentor_entity:
            # add a link to view all the student proposals
            submenu = (redirects.getListProposalsRedirect(
                group_entity,
                params), "Manage Student Proposals", 'any_access')
            submenus.append(submenu)

            # add a link to manage student projects after they have been announced
            if timeline_helper.isAfterEvent(
                    program_entity.timeline,
                    'accepted_students_announced_deadline'):
                submenu = (redirects.getManageOverviewRedirect(
                    group_entity, {'url_name': 'gsoc/student_project'}),
                           "Manage Student Projects", 'any_access')
                submenus.append(submenu)

        if is_active_admin:
            # add a link to the management page
            submenu = (redirects.getListRolesRedirect(group_entity, params),
                       "Manage Admins and Mentors", 'any_access')
            submenus.append(submenu)

            # add a link to invite an org admin
            submenu = (redirects.getInviteRedirectForRole(
                group_entity,
                'gsoc/org_admin'), "Invite an Admin", 'any_access')
            submenus.append(submenu)

            # add a link to invite a member
            submenu = (redirects.getInviteRedirectForRole(
                group_entity, 'gsoc/mentor'), "Invite a Mentor", 'any_access')
            submenus.append(submenu)

            # add a link to the request page
            submenu = (redirects.getListRequestsRedirect(group_entity, params),
                       "List Requests and Invites", 'any_access')
            submenus.append(submenu)

            # add a link to the edit page
            submenu = (redirects.getEditRedirect(group_entity, params),
                       "Edit Organization Profile", 'any_access')
            submenus.append(submenu)

        if is_active_admin or is_active_mentor:
            submenu = (redirects.getCreateDocumentRedirect(
                group_entity, params['document_prefix']),
                       "Create a New Document", 'any_access')
            submenus.append(submenu)

            submenu = (redirects.getListDocumentsRedirect(
                group_entity,
                params['document_prefix']), "List Documents", 'any_access')
            submenus.append(submenu)

        if is_active_admin:
            # add a link to the resign page
            submenu = (redirects.getManageRedirect(
                roles['gsoc_org_admin'], {'url_name': 'gsoc/org_admin'}),
                       "Resign as Admin", 'any_access')
            submenus.append(submenu)

            # add a link to the edit page
            submenu = (redirects.getEditRedirect(
                roles['gsoc_org_admin'], {'url_name': 'gsoc/org_admin'}),
                       "Edit My Admin Profile", 'any_access')
            submenus.append(submenu)

        if is_active_mentor:
            # add a link to the resign page
            submenu = (redirects.getManageRedirect(
                roles['gsoc_mentor'],
                {'url_name': 'gsoc/mentor'}), "Resign as Mentor", 'any_access')
            submenus.append(submenu)

            # add a link to the edit page
            submenu = (redirects.getEditRedirect(roles['gsoc_mentor'],
                                                 {'url_name': 'gsoc/mentor'}),
                       "Edit My Mentor Profile", 'any_access')
            submenus.append(submenu)

        return submenus

    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)

    @decorators.merge_params
    @decorators.check_access
    def listProposals(self,
                      request,
                      access_type,
                      page_name=None,
                      params=None,
                      **kwargs):
        """Lists all proposals for the organization given in kwargs.

    For params see base.View.public().
    """

        from soc.modules.gsoc.logic.models.proposal_duplicates_status import \
            logic as ds_logic

        try:
            org_entity = self._logic.getFromKeyFieldsOr404(kwargs)
        except out_of_band.Error, error:
            return helper.responses.errorResponse(
                error, request, template=params['error_public'])

        program_entity = org_entity.scope
        is_after_deadline = timeline_helper.isAfterEvent(
            program_entity.timeline, 'accepted_students_announced_deadline')
        if is_after_deadline:
            redirect_fun = redirects.getProposalCommentRedirect
        else:
            redirect_fun = redirects.getReviewRedirect

        context = {}
        context['entity'] = org_entity
        # whether or not the amount of slots assigned should be shown
        context['slots_visible'] = org_entity.scope.allocations_visible

        # used to check the status of the duplicate process
        context['duplicate_status'] = ds_logic.getOrCreateForProgram(
            org_entity.scope)

        program_entity = org_entity.scope
        page_name = '%s %s (%s)' % (page_name, org_entity.name,
                                    program_entity.short_name)

        list_params = student_proposal_view.view.getParams().copy()
        list_params['list_template'] = 'soc/student_proposal/list_for_org.html'

        np_params = list_params.copy()  # new proposals
        description = ugettext('List of new %s sent to %s') % (
            np_params['name_plural'], org_entity.name)
        np_params['list_description'] = description
        np_params['public_row_extra'] = lambda entity: {
            'link': redirect_fun(entity, np_params),
        }

        rp_params = list_params.copy()  # ranked proposals
        rp_params['review_field_keys'] = [
            'rank', 'title', 'student', 'mentor', 'score', 'status',
            'last_modified_on', 'abstract', 'content', 'additional_info',
            'created_on'
        ]
        rp_params['review_field_hidden'] = [
            'abstract', 'content', 'additional_info', 'created_on'
        ]
        rp_params['review_field_names'] = [
            'Rank', 'Title', 'Student', 'Mentor', 'Score', 'Status',
            'Last Modified On', 'Abstract', 'Content', 'Additional Info',
            'Created On'
        ]
        rp_params['review_field_no_filter'] = ['status']
        rp_params['review_field_prefetch'] = ['scope', 'mentor', 'program']
        rp_params['review_field_extra'] = lambda entity, ranker, status: {
              'rank': ranker.FindRanks([[entity.score]])[0] + 1,
              'student': entity.scope.name(),
              'mentor': entity.mentor.name() if entity.mentor else
                  '%s Proposed' % len(entity.possible_mentors),
              'status': status.get(entity.key(),
                  '<font color="red">Pending rejection</font>') if (
                  entity.program.allocations_visible \
                  and entity.status == 'pending') else entity.status,
        }
        rp_params['review_row_action'] = {
            "type": "redirect_custom",
            "parameters": dict(new_window=True),
        }
        rp_params['review_row_extra'] = lambda entity, *args: {
            'link': redirect_fun(entity, rp_params)
        }
        rp_params['review_field_props'] = {
            "score": {
                "sorttype": "integer",
            },
            "rank": {
                "sorttype": "integer",
            },
        }
        rp_params['review_conf_min_num'] = 50

        description = ugettext('%s already under review sent to %s') % (
            rp_params['name_plural'], org_entity.name)
        rp_params['list_description'] = description

        mp_params = list_params.copy()  # proposals mentored by current user
        description = ugettext('List of %s sent to %s you are mentoring') % (
            mp_params['name_plural'], org_entity.name)
        mp_params['list_description'] = description
        mp_params['public_row_extra'] = lambda entity: {
            'link': redirect_fun(entity, mp_params)
        }

        ip_params = list_params.copy()  # invalid proposals
        ip_params['list_description'] = ugettext(
            'List of invalid %s sent to %s ') % (ip_params['name_plural'],
                                                 org_entity.name)
        ip_params['public_row_extra'] = lambda entity: {
            'link': redirect_fun(entity, ip_params)
        }

        if lists.isDataRequest(request):
            # retrieving data for a list
            return self.getListProposalsData(
                request, [np_params, rp_params, mp_params, ip_params],
                org_entity)

        # fill contents for all the needed lists
        contents = []

        # check if there are new proposals if so show them in a separate list
        fields = {'org': org_entity, 'status': 'new'}
        new_proposal = sp_logic.getForFields(fields, unique=True)

        if new_proposal:
            # we should add this list because there is a new proposal
            np_list = helper.lists.getListGenerator(request, np_params, idx=0)
            contents.append(np_list)

        order = ['-score']
        # the list of proposals that have been reviewed should always be shown
        rp_list = helper.lists.getListGenerator(request,
                                                rp_params,
                                                order=order,
                                                visibility='review',
                                                idx=1)
        contents.append(rp_list)

        # check whether the current user is a mentor for the organization
        user_entity = user_logic.getCurrentUser()

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

        if mentor_entity:
            # show the list of all proposals that this user is mentoring
            mp_list = helper.lists.getListGenerator(request, mp_params, idx=2)
            contents.append(mp_list)

        # check if there are invalid proposals if so show them in a separate list
        fields = {'org': org_entity, 'status': 'invalid'}
        invalid_proposal = sp_logic.getForFields(fields, unique=True)
        if invalid_proposal:
            ip_list = helper.lists.getListGenerator(request, ip_params, idx=3)
            contents.append(ip_list)

        return self._list(request, list_params, contents, page_name, context)
Exemple #20
0
  def _enableMentorManagement(self, entity, params, context):
    """Sets the data required to manage mentors for a StudentProject.

    Args:
      entity: StudentProject entity to manage
      params: params dict for the manage view
      context: context for the manage view
    """

    context['can_manage_mentors'] = True

    # get all mentors for this organization
    fields = {'scope': entity.scope,
              'status': 'active'}
    mentors = mentor_logic.getForFields(fields)

    choices = [(mentor.link_id,'%s (%s)' %(mentor.name(), mentor.link_id))
                  for mentor in mentors]

    # create the form that org admins will use to reassign a mentor
    dynafields = [
        {'name': 'mentor_id',
         'base': forms.ChoiceField,
         'label': 'Primary Mentor',
         'required': True,
         'passthrough': ['required', 'choices', 'label'],
         'choices': choices,
        },]

    dynaproperties = params_helper.getDynaFields(dynafields)

    mentor_edit_form = dynaform.newDynaForm(
        dynabase = params['dynabase'],
        dynaproperties = dynaproperties,
    )

    params['mentor_edit_form'] = mentor_edit_form

    additional_mentors = entity.additional_mentors

    # we want to show the names of the additional mentors in the context
    # therefore they need to be resolved to entities first
    additional_mentors_context = []

    for mentor_key in additional_mentors:
      mentor_entity = mentor_logic.getFromKeyName(
          mentor_key.id_or_name())
      additional_mentors_context.append(mentor_entity)

    context['additional_mentors'] = additional_mentors_context

    # all mentors who are not already an additional mentor or
    # the primary mentor are allowed to become an additional mentor
    possible_additional_mentors = [m for m in mentors if 
        (m.key() not in additional_mentors) 
        and (m.key() != entity.mentor.key())]

    # create the information to be shown on the additional mentor form
    additional_mentor_choices = [
        (mentor.link_id,'%s (%s)' %(mentor.name(), mentor.link_id))
        for mentor in possible_additional_mentors]

    dynafields = [
        {'name': 'mentor_id',
         'base': forms.ChoiceField,
         'label': 'Co-Mentor',
         'required': True,
         'passthrough': ['required', 'choices', 'label'],
         'choices': additional_mentor_choices,
        },]

    dynaproperties = params_helper.getDynaFields(dynafields)

    additional_mentor_form = dynaform.newDynaForm(
        dynabase = params['dynabase'],
        dynaproperties = dynaproperties,
    )

    params['additional_mentor_form'] = additional_mentor_form