Example #1
0
    def managePost(self, request, template, context, params, entity, **kwargs):
        """Handles the POST 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()
    """

        post_dict = request.POST

        if 'set_mentor' in post_dict and project_logic.canChangeMentors(
                entity):
            form = params['mentor_edit_form'](post_dict)
            return self._manageSetMentor(request, template, context, params,
                                         entity, form)
        elif 'add_additional_mentor' in post_dict and \
            project_logic.canChangeMentors(entity):
            form = params['additional_mentor_form'](post_dict)
            return self._manageAddAdditionalMentor(request, template, context,
                                                   params, entity, form)
        else:
            # unexpected error return the normal page
            logging.warning('Unexpected POST data found')
            return self.manageGet(request, template, context, params, entity)
Example #2
0
  def managePost(self, request, template, context, params, entity, **kwargs):
    """Handles the POST 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()
    """

    post_dict = request.POST

    if 'set_mentor' in post_dict and project_logic.canChangeMentors(entity):
      form = params['mentor_edit_form'](post_dict)
      return self._manageSetMentor(request, template, context, params, entity,
                                   form)
    elif 'add_additional_mentor' in post_dict and \
        project_logic.canChangeMentors(entity):
      form = params['additional_mentor_form'](post_dict)
      return self._manageAddAdditionalMentor(request, template, context,
                                             params, entity, form)
    else:
      # unexpected error return the normal page
      logging.warning('Unexpected POST data found')
      return self.manageGet(request, template, context, params, entity)
Example #3
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)
Example #4
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)
Example #5
0
class View(base.View):
  """View methods for the Student Project 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['create'] = ['checkIsDeveloper']
    rights['edit'] = ['checkIsDeveloper']
    rights['delete'] = ['checkIsDeveloper']
    rights['show'] = ['allow']
    rights['list'] = ['checkIsDeveloper']
    rights['manage'] = [('checkHasRoleForScope',
                         [org_admin_logic, ['active', 'inactive']]),
        ('checkStudentProjectHasStatus', [['accepted', 'failed', 'completed',
                                           'withdrawn']])]
    rights['manage_overview'] = [('checkHasRoleForScope', [
        org_admin_logic, ['active', 'inactive']])]
    # TODO: lack of better name here!
    rights['st_edit'] = [
        'checkCanEditStudentProjectAsStudent',
        ('checkStudentProjectHasStatus',
            [['accepted', 'completed']])
        ]
    rights['withdraw'] = ['checkIsHostForProgram']
    rights['withdraw_project'] = ['checkIsHostForStudentProject',
        ('checkStudentProjectHasStatus',
            [['accepted', 'completed']])
        ]
    rights['accept_project'] = ['checkIsHostForStudentProject',
        ('checkStudentProjectHasStatus',
            [['withdrawn']])
        ]

    new_params = {}
    new_params['logic'] = project_logic
    new_params['rights'] = rights
    new_params['name'] = "Student Project"
    new_params['url_name'] = "gsoc/student_project"
    new_params['module_package'] = 'soc.modules.gsoc.views.models'
    new_params['sidebar_grouping'] = 'Students'

    new_params['scope_view'] = org_view
    new_params['scope_redirect'] = redirects.getCreateRedirect

    new_params['no_create_with_key_fields'] = True

    new_params['extra_dynaexclude'] = ['program', 'status', 'link_id',
                                       'mentor', 'additional_mentors',
                                       'student', 'passed_evaluations',
                                       'failed_evaluations']

    new_params['create_extra_dynaproperties'] = {
        'scope_path': forms.CharField(widget=forms.HiddenInput,
            required=True),
        'public_info': forms.fields.CharField(required=True,
            widget=widgets.FullTinyMCE(attrs={'rows': 25, 'cols': 100})),
        'student_id': forms.CharField(label='Student Link ID',
            required=True),
        'mentor_id': forms.CharField(label='Mentor Link ID',
            required=True),
        'clean_abstract': cleaning.clean_content_length('abstract'),
        'clean_public_info': cleaning.clean_html_content('public_info'),
        'clean_student': cleaning.clean_link_id('student'),
        'clean_mentor': cleaning.clean_link_id('mentor'),
        'clean_additional_info': cleaning.clean_url('additional_info'),
        'clean_feed_url': cleaning.clean_feed_url,
        'clean': cleaning.validate_student_project('scope_path',
            'mentor_id', 'student_id')
        }

    new_params['edit_extra_dynaproperties'] = {
        'link_id': forms.CharField(widget=forms.HiddenInput),
        }

    patterns = [
        (r'^%(url_name)s/(?P<access_type>manage_overview)/%(scope)s$',
        'soc.modules.gsoc.views.models.%(module_name)s.manage_overview',
        'Overview of %(name_plural)s to Manage for'),
        (r'^%(url_name)s/(?P<access_type>manage)/%(key_fields)s$',
        'soc.modules.gsoc.views.models.%(module_name)s.manage',
        'Manage %(name)s'),
        (r'^%(url_name)s/(?P<access_type>st_edit)/%(key_fields)s$',
        'soc.modules.gsoc.views.models.%(module_name)s.st_edit',
        'Edit my %(name)s'),
        (r'^%(url_name)s/(?P<access_type>withdraw)/(?P<scope_path>%(ulnp)s)/%(lnp)s$',
        'soc.modules.gsoc.views.models.%(module_name)s.withdraw',
        'Withdraw %(name_plural)s'),
        (r'^%(url_name)s/(?P<access_type>withdraw_project)/%(key_fields)s$',
        'soc.modules.gsoc.views.models.%(module_name)s.withdraw_project',
        'Withdraw a %(name)s'),
        (r'^%(url_name)s/(?P<access_type>accept_project)/%(key_fields)s$',
        'soc.modules.gsoc.views.models.%(module_name)s.accept_project',
        'Accept a %(name)s'),
    ]

    new_params['extra_django_patterns'] = patterns

    new_params['edit_template'] = 'soc/student_project/edit.html'
    new_params['manage_template'] = 'soc/student_project/manage.html'
    new_params['manage_overview_heading'] = \
        'soc/student_project/list/heading_manage.html'
    new_params['manage_overview_row'] = \
        'soc/student_project/list/row_manage.html'

    new_params['public_field_extra'] = lambda entity: {
        "student": entity.student.name(),
        "mentor": entity.mentor.name(),
    }
    new_params['public_field_keys'] = ["student", "title", "mentor", "status"]
    new_params['public_field_names'] = ["Student", "Title", "Mentor", "Status"]

    params = dicts.merge(params, new_params)

    super(View, self).__init__(params=params)

    # create the form that students will use to edit their projects
    dynaproperties = {
        'public_info': forms.fields.CharField(required=True,
            widget=widgets.FullTinyMCE(attrs={'rows': 25, 'cols': 100})),
        'clean_abstract': cleaning.clean_content_length('abstract'),
        'clean_public_info': cleaning.clean_html_content('public_info'),
        'clean_additional_info': cleaning.clean_url('additional_info'),
        'clean_feed_url': cleaning.clean_feed_url,
        }

    student_edit_form = dynaform.newDynaForm(
        dynabase = self._params['dynabase'],
        dynamodel = self._params['logic'].getModel(),
        dynaexclude = self._params['create_dynaexclude'],
        dynaproperties = dynaproperties,
    )

    self._params['student_edit_form'] = student_edit_form

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

    form.fields['link_id'].initial = entity.link_id
    form.fields['student_id'].initial = entity.student.link_id
    form.fields['mentor_id'].initial = entity.mentor.link_id

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

  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 _public(self, request, entity, context):
    """Adds the names of all additional mentors to the context.

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

    additional_mentors = entity.additional_mentors

    if not additional_mentors:
      context['additional_mentors'] = []
    else:
      mentor_names = []

      for mentor_key in additional_mentors:
        additional_mentor = mentor_logic.getFromKeyName(
            mentor_key.id_or_name())
        mentor_names.append(additional_mentor.name())

      context['additional_mentors'] = ', '.join(mentor_names)

  def getWithdrawData(self, request, ap_params, wp_params, program_kwargs):
    """Return data for withdraw.
    """

    program = program_logic.getFromKeyFieldsOr404(program_kwargs)

    fields = {
        'program': program,
        }

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

    if idx == 0:
      fields['status'] = ['accepted', 'completed']
      params = ap_params
    elif idx == 1:
      fields['status'] = ['withdrawn']
      params = wp_params
    else:
      return responses.jsonErrorResponse(request, "idx not valid")

    contents = lists.getListData(request, params, fields, 'public')
    json = simplejson.dumps(contents)

    return responses.jsonResponse(request, json)

  @decorators.merge_params
  @decorators.check_access
  def withdraw(self, request, access_type,
               page_name=None, params=None, **kwargs):
    """View that allows Program Admins to accept or withdraw Student Projects.

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

    ap_params = params.copy() # accepted projects

    ap_params['public_row_extra'] = lambda entity: {
        'link': redirects.getWithdrawProjectRedirect(entity,ap_params)
    }

    ap_params['list_description'] = ugettext(
        "An overview of accepted and completed Projects. "
        "Click on a project to withdraw it.")

    wp_params = params.copy() # withdrawn projects

    wp_params['public_row_extra'] = lambda entity: {
        'link': redirects.getAcceptProjectRedirect(entity, wp_params)
    }
    wp_params['list_description'] = ugettext(
        "An overview of withdrawn Projects. "
        "Click on a project to undo the withdrawal.")

    if request.GET.get('fmt') == 'json':
      return self.getWithdrawData(request, ap_params, wp_params, kwargs)

    ap_list = lists.getListGenerator(request, ap_params, idx=0)
    wp_list = lists.getListGenerator(request, wp_params, idx=1)

    # fill contents with all the needed lists
    contents = [ap_list, wp_list]

    # call the _list method from base to display the list
    return self._list(request, params, contents, page_name)

  @decorators.merge_params
  @decorators.check_access
  def withdrawProject(self, request, access_type,
                      page_name=None, params=None, **kwargs):
    """View that allows Program Admins to withdraw Student Projects.

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

    """
# TODO(POST)
    logic = params['logic']
    entity = logic.getFromKeyFieldsOr404(kwargs)

    fields = {
        'status': 'withdrawn',
        }

    logic.updateEntityProperties(entity, fields)

    url = redirects.getWithdrawRedirect(entity.program, params)

    return http.HttpResponseRedirect(url)

  @decorators.merge_params
  @decorators.check_access
  def acceptProject(self, request, access_type,
                    page_name=None, params=None, **kwargs):
    """View that allows Program Admins to accept Student Projects.

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

    """
# TODO(POST)
    logic = params['logic']
    entity = logic.getFromKeyFieldsOr404(kwargs)

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

    logic.updateEntityProperties(entity, fields)

    url = redirects.getWithdrawRedirect(entity.program, params)

    return http.HttpResponseRedirect(url)

  @decorators.merge_params
  @decorators.check_access
  def manage(self, request, access_type,
             page_name=None, params=None, **kwargs):
    """View that allows Organization Admins to manage their Student Projects.

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

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

    template = params['manage_template']

    # get the context for this webpage
    context = responses.getUniversalContext(request)
    responses.useJavaScript(context, params['js_uses_all'])
    context['page_name'] = "%s '%s' from %s" % (page_name, entity.title,
                                                entity.student.name())
    context['entity'] = entity

    if project_logic.canChangeMentors(entity):
      # only accepted project can have their mentors managed
      self._enableMentorManagement(entity, params, context)

    context['evaluation_list'] = self._getEvaluationLists(request, params,
                                                          entity)

    if request.POST:
      return self.managePost(request, template, context, params, entity,
                             **kwargs)
    else: #request.GET
      return self.manageGet(request, template, context, params, entity,
                            **kwargs)
Example #6
0
  def manage(self, request, access_type,
             page_name=None, params=None, **kwargs):
    """View that allows Organization Admins to manage their Student Projects.

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

    import soc.logic.lists

    from soc.modules.gsoc.views.models.grading_project_survey import view as \
        grading_survey_view
    from soc.modules.gsoc.views.models.project_survey import view as \
        project_survey_view

    entity = self._logic.getFromKeyFieldsOr404(kwargs)

    template = params['manage_template']

    # get the context for this webpage
    context = responses.getUniversalContext(request)
    responses.useJavaScript(context, params['js_uses_all'])
    context['page_name'] = "%s '%s' from %s" % (page_name, entity.title,
                                                entity.student.name())
    context['entity'] = entity

    if project_logic.canChangeMentors(entity):
      # only accepted project can have their mentors managed
      self._enableMentorManagement(entity, params, context)

    # list all surveys for this Project's Program
    gps_params = grading_survey_view.getParams().copy()
    gps_params['list_description'] = \
        'List of all Mentor Evaluations for this Project'
    gps_params['public_row_extra'] = lambda entity, *args: {}
    gps_params['public_row_action'] = {}
    gps_params['public_field_keys'] = [
        "title", "taken_by", "taken_on", "record_url", "take_url"
    ]
    gps_params['public_field_names'] = [
        "Title", "Taken by", "Taken on", "View", "(Re) Take",
    ]
    no_record = self.DEF_NO_RECORD_AVAILABLE_MSG

    # TODO(SRabbelier): use buttons instead
    project_entity = entity
    getExtra = lambda params: lambda entity, re: {
        "taken_by": no_record if not re(entity) else re(entity).user.name,
        "taken_on": no_record if not re(entity) else str(re(entity).modified),
        "record_url": no_record if not re(entity) else lists.urlize(
            redirects.getViewSurveyRecordRedirect(re(entity), params),
            name=self.DEF_VIEW_RECORD_MSG),
        "take_url": lists.urlize(redirects.getTakeProjectSurveyRedirect(
            project_entity, {'survey': entity, 'params': params}),
            name=self.DEF_TAKE_SURVEY_MSG),
    }

    gps_params['public_field_extra'] = getExtra(gps_params)

    # get the ProjectSurvey list
    ps_params = project_survey_view.getParams().copy()
    ps_params['list_description'] = \
        'List of all Student Evaluations for this Project'
    ps_params['public_row_extra'] = lambda entity, *args: {}
    ps_params['public_row_action'] = {}
    ps_params['public_field_keys'] = gps_params['public_field_keys']
    ps_params['public_field_names'] = gps_params['public_field_names']
    ps_params['public_field_ignore'] = ["take_url"]
    ps_params['public_field_extra'] = getExtra(ps_params)

    if lists.isDataRequest(request):
      return self._getManageData(request, gps_params, ps_params, entity)

    gps_list = lists.getListGenerator(request, gps_params, idx=0)
    ps_list = lists.getListGenerator(request, ps_params, idx=1)

    # store both lists in the content
    content = [gps_list, ps_list]

    context['evaluation_list'] = soc.logic.lists.Lists(content)

    if request.POST:
      return self.managePost(request, template, context, params, entity,
                             **kwargs)
    else: #request.GET
      return self.manageGet(request, template, context, params, entity,
                            **kwargs)
Example #7
0
    def manage(self,
               request,
               access_type,
               page_name=None,
               params=None,
               **kwargs):
        """View that allows Organization Admins to manage their Student Projects.

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

        import soc.logic.lists

        from soc.modules.gsoc.views.models.grading_project_survey import view as \
            grading_survey_view
        from soc.modules.gsoc.views.models.project_survey import view as \
            project_survey_view

        entity = self._logic.getFromKeyFieldsOr404(kwargs)

        template = params['manage_template']

        # get the context for this webpage
        context = responses.getUniversalContext(request)
        responses.useJavaScript(context, params['js_uses_all'])
        context['page_name'] = "%s '%s' from %s" % (page_name, entity.title,
                                                    entity.student.name())
        context['entity'] = entity

        if project_logic.canChangeMentors(entity):
            # only accepted project can have their mentors managed
            self._enableMentorManagement(entity, params, context)

        # list all surveys for this Project's Program
        gps_params = grading_survey_view.getParams().copy()
        gps_params['list_description'] = \
            'List of all Mentor Evaluations for this Project'
        gps_params['public_row_extra'] = lambda entity, *args: {}
        gps_params['public_row_action'] = {}
        gps_params['public_field_keys'] = [
            "title", "taken_by", "taken_on", "record_url", "take_url"
        ]
        gps_params['public_field_names'] = [
            "Title",
            "Taken by",
            "Taken on",
            "View",
            "(Re) Take",
        ]
        no_record = self.DEF_NO_RECORD_AVAILABLE_MSG

        # TODO(SRabbelier): use buttons instead
        project_entity = entity
        getExtra = lambda params: lambda entity, re: {
            "taken_by":
            no_record if not re(entity) else re(entity).user.name,
            "taken_on":
            no_record if not re(entity) else str(re(entity).modified),
            "record_url":
            no_record if not re(entity) else lists.urlize(
                redirects.getViewSurveyRecordRedirect(re(entity), params),
                name=self.DEF_VIEW_RECORD_MSG),
            "take_url":
            lists.urlize(redirects.getTakeProjectSurveyRedirect(
                project_entity, {
                    'survey': entity,
                    'params': params
                }),
                         name=self.DEF_TAKE_SURVEY_MSG),
        }

        gps_params['public_field_extra'] = getExtra(gps_params)

        # get the ProjectSurvey list
        ps_params = project_survey_view.getParams().copy()
        ps_params['list_description'] = \
            'List of all Student Evaluations for this Project'
        ps_params['public_row_extra'] = lambda entity, *args: {}
        ps_params['public_row_action'] = {}
        ps_params['public_field_keys'] = gps_params['public_field_keys']
        ps_params['public_field_names'] = gps_params['public_field_names']
        ps_params['public_field_ignore'] = ["take_url"]
        ps_params['public_field_extra'] = getExtra(ps_params)

        if lists.isDataRequest(request):
            return self._getManageData(request, gps_params, ps_params, entity)

        gps_list = lists.getListGenerator(request, gps_params, idx=0)
        ps_list = lists.getListGenerator(request, ps_params, idx=1)

        # store both lists in the content
        content = [gps_list, ps_list]

        context['evaluation_list'] = soc.logic.lists.Lists(content)

        if request.POST:
            return self.managePost(request, template, context, params, entity,
                                   **kwargs)
        else:  #request.GET
            return self.manageGet(request, template, context, params, entity,
                                  **kwargs)