Exemple #1
0
def startTasks(request):
  """Presents a view that allows the user to start update tasks.
  """

  template = 'soc/tasks/start_update.html'

  context = responses.getUniversalContext(request)

  options = task_runner.getOptions()

  sorted_keys = []
  for key, option in options.iteritems():
    option['name'] = key
    sorted_keys.append(
        (option['from_version'], option['in_version_order'], key))

  # sort the keys
  sorted_keys.sort()

  # store only the true option
  sorted_options = []

  for key_tuple in sorted_keys:
    option_key = key_tuple[2]
    sorted_options.append(options[option_key])

  context.update(
      page_name='Update Tasks starter',
      options=sorted_options,
      )

  content = loader.render_to_string(template, dictionary=context)
  return http.HttpResponse(content)
Exemple #2
0
    def acceptInvite(self,
                     request,
                     access_type,
                     page_name=None,
                     params=None,
                     **kwargs):
        """Creates the page process an invite into a Role.

    Args:
      request: the standard Django HTTP request object
      access_type : the name of the access type which should be checked
      page_name: the page name displayed in templates as page and header title
      params: a dict with params for this View
      kwargs: contains the ID for the Request entity
    """

        request_entity = request_logic.getFromIDOr404(int(kwargs['id']))

        # get the context for this webpage
        context = responses.getUniversalContext(request)
        responses.useJavaScript(context, params['js_uses_all'])
        context['page_name'] = page_name

        if request.method == 'POST':
            return self.acceptInvitePost(request, context, params,
                                         request_entity, **kwargs)
        else:
            # request.method == 'GET'
            return self.acceptInviteGet(request, context, params,
                                        request_entity, **kwargs)
  def applicant(self, request, access_type,
                page_name=None, params=None, **kwargs):
    """Handles the creation of an Organization via an approved application.

    Args:
      request: the standard Django HTTP request object
      access_type : the name of the access type which should be checked
      page_name: the page name displayed in templates as page and header title
      params: a dict with params for this View
      kwargs: the Key Fields for the specified entity
    """

    # get the context for this webpage
    context = responses.getUniversalContext(request)
    responses.useJavaScript(context, params['js_uses_all'])
    context['page_name'] = page_name

    get_dict = request.GET
    record_id = get_dict.get('id', None)

    org_app_logic = params['org_app_logic']
    record_logic = org_app_logic.getRecordLogic()

    if not record_id or not record_id.isdigit():
      raise out_of_band.Error('No valid OrgAppRecord ID specified.')
    else:
      record_entity =  record_logic.getFromIDOr404(int(record_id))

    if request.method == 'POST':
      return self.applicantPost(request, context, params,
                                record_entity, **kwargs)
    else:
      # request.method == 'GET'
      return self.applicantGet(request, context, params,
                               record_entity, **kwargs)
Exemple #4
0
    def invite(self,
               request,
               access_type,
               page_name=None,
               params=None,
               **kwargs):
        """Creates the page on which an invite can be send out.

    Args:
      request: the standard Django HTTP request object
      access_type : the name of the access type which should be checked
      context: dictionary containing the context for this view
      params: a dict with params for this View
      kwargs: the Key Fields for the specified entity
    """

        # get the context for this webpage
        context = responses.getUniversalContext(request)
        responses.useJavaScript(context, params['js_uses_all'])
        context['page_name'] = page_name

        group_entity = params['group_logic'].getFromKeyName(
            kwargs['scope_path'])

        context['instruction_message'] = (self.DEF_INVITE_INSTRUCTION_MSG_FMT %
                                          (params['name'], group_entity.name))

        if request.method == 'POST':
            return self.invitePost(request, context, params, group_entity,
                                   **kwargs)
        else:
            # request.method == 'GET'
            return self.inviteGet(request, context, params, **kwargs)
Exemple #5
0
    def process_exception(self, request, exception):
        """Called when an uncaught exception is raised.

    See the Django middleware documentation for an explanation of
    the method signature.
    """

        template = None
        context = responses.getUniversalContext(request)

        if isinstance(exception, DeadlineExceededError):
            template = 'soc/deadline_exceeded.html'
        if isinstance(exception, MemoryError):
            template = 'soc/memory_error.html'
        if isinstance(exception, AssertionError):
            template = 'soc/assertion_error.html'
        if isinstance(exception, out_of_band.Error):
            return responses.errorResponse(exception, request)

        if template:
            logging.exception(exception)
            return responses.respond(request, template, context=context)

        # let Django handle it
        return None
Exemple #6
0
  def wrapper(self, request, access_type, *args, **kwargs):
    """Decorator wrapper method.
    """
    params = kwargs.get('params', {})

    # Try to extract rights
    if 'rights' in params:
      rights = params['rights']
    else:
      rights = self._params['rights']

    check_kwargs = kwargs.copy()
    context = responses.getUniversalContext(request)
    responses.useJavaScript(context, self._params['js_uses_all'])

    id = context['account']
    user = context['user']

    check_kwargs['GET'] = request.GET
    check_kwargs['POST'] = request.POST
    check_kwargs['context'] = context

    # reset and pre-fill the Checker's cache
    rights.setCurrentUser(id, user)

    # Do the access check dance
    try:
      rights.checkAccess(access_type, check_kwargs)
    except out_of_band.Error, error:
      return helper.responses.errorResponse(error, request)
Exemple #7
0
    def processRequest(self,
                       request,
                       access_type,
                       page_name=None,
                       params=None,
                       **kwargs):
        """Creates the page upon which a request can be processed.

    Args:
      request: the standard Django HTTP request object
      access_type : the name of the access type which should be checked
      page_name: the page name displayed in templates as page and header title
      params: a dict with params for this View
      kwargs: the Key Fields for the specified entity
    """

        # get the request entity using the information from kwargs
        request_entity = request_logic.getFromIDOr404(int(kwargs['id']))

        # get the context for this webpage
        context = responses.getUniversalContext(request)
        responses.useJavaScript(context, params['js_uses_all'])

        context['page_name'] = '%s from %s to become a %s' % (
            page_name, request_entity.user.name, params['name'])

        # TODO(ljvderijk): Should be a POST request
        get_dict = request.GET

        if 'status' in get_dict.keys():
            if get_dict['status'] in [
                    'group_accepted', 'rejected', 'withdrawn', 'ignored'
            ]:
                # update the request_entity and redirect away from this page
                request_status = get_dict['status']

                # only update when the status is changing
                if request_status != request_entity.status:
                    request_logic.updateEntityProperties(
                        request_entity, {'status': get_dict['status']})

                group_view = params.get('group_view')
                if not group_view:
                    return http.HttpResponseRedirect('/')
                else:
                    # redirect to the requests list
                    return http.HttpResponseRedirect(
                        redirects.getListRequestsRedirect(
                            request_entity.group, group_view.getParams()))

        # put the entity in the context
        context['entity'] = request_entity
        context['request_status'] = request_entity.status
        context['role_verbose'] = params['name']
        context['url_name'] = params['url_name']

        #display the request processing page using the appropriate template
        template = request_view.view.getParams()['request_processing_template']

        return responses.respond(request, template, context=context)
Exemple #8
0
    def request(self,
                request,
                access_type,
                page_name=None,
                params=None,
                **kwargs):
        """Handles the request concerning the view that creates a request
    for attaining a certain Role.

    Args:
      request: the standard Django HTTP request object
      page_name: the page name displayed in templates as page and header title
      params: a dict with params for this View
      kwargs: the Key Fields for the specified entity
    """

        # get the context for this webpage
        context = responses.getUniversalContext(request)
        responses.useJavaScript(context, params['js_uses_all'])
        context['page_name'] = page_name

        group_entity = params['group_logic'].getFromKeyName(
            kwargs['scope_path'])

        context['instruction_message'] = (
            self.DEF_REQUEST_INSTRUCTION_MSG_FMT %
            (params['name'], group_entity.name))

        if request.method == 'POST':
            return self.requestPost(request, context, params, group_entity,
                                    **kwargs)
        else:
            # request.method == 'GET'
            return self.requestGet(request, context, params, **kwargs)
Exemple #9
0
  def acceptInvite(self, request, access_type,
                   page_name=None, params=None, **kwargs):
    """Creates the page process an invite into a Role.

    Args:
      request: the standard Django HTTP request object
      access_type : the name of the access type which should be checked
      page_name: the page name displayed in templates as page and header title
      params: a dict with params for this View
      kwargs: contains the ID for the Request entity
    """

    request_entity = request_logic.getFromIDOr404(int(kwargs['id']))

     # get the context for this webpage
    context = responses.getUniversalContext(request)
    responses.useJavaScript(context, params['js_uses_all'])
    context['page_name'] = page_name

    if request.method == 'POST':
      return self.acceptInvitePost(request, context, params, request_entity,
                                   **kwargs)
    else:
      # request.method == 'GET'
      return self.acceptInviteGet(request, context, params, request_entity,
                                  **kwargs)
Exemple #10
0
    def visualize(self,
                  request,
                  access_type,
                  page_name=None,
                  params=None,
                  **kwargs):
        """Visualization view for a statistic specified in request params.
    """

        link_id = kwargs['link_id']
        scope_path = kwargs['scope_path']
        logic = params['logic']

        statistic = self._getStatisticEntity(link_id, scope_path, logic)

        context = responses.getUniversalContext(request)

        if not logic.checkIfStatisticReady(statistic):
            template = 'soc/error.html'
            context['message'] = self.DEF_NO_VISUALIZATION_MSG_FMT % (
                statistic.name)
        else:
            responses.useJavaScript(context, params['js_uses_all'])
            context['entity'] = statistic
            context['page_name'] = "Statistic visualization"
            context['link_id'] = statistic.link_id
            context['scope_path'] = statistic.scope_path
            context['visualization_types'] = logic.getVisualizationTypesJson(
                statistic)

            template = 'soc/statistic/show.html'

        return responses.respond(request, template, context)
Exemple #11
0
  def invite(self, request, access_type,
             page_name=None, params=None, **kwargs):
    """Creates the page on which an invite can be send out.

    Args:
      request: the standard Django HTTP request object
      access_type : the name of the access type which should be checked
      context: dictionary containing the context for this view
      params: a dict with params for this View
      kwargs: the Key Fields for the specified entity
    """

    # get the context for this webpage
    context = responses.getUniversalContext(request)
    responses.useJavaScript(context, params['js_uses_all'])
    context['page_name'] = page_name

    group_entity = params['group_logic'].getFromKeyName(kwargs['scope_path'])

    context['instruction_message'] = (self.DEF_INVITE_INSTRUCTION_MSG_FMT %
        (params['name'], group_entity.name))

    if request.method == 'POST':
      return self.invitePost(request, context, params, group_entity, **kwargs)
    else:
      # request.method == 'GET'
      return self.inviteGet(request, context, params, **kwargs)
  def process_exception(self, request, exception):
    """Called when an uncaught exception is raised.

    See the Django middleware documentation for an explanation of
    the method signature.
    """

    template = None
    context = responses.getUniversalContext(request)

    if isinstance(exception, DeadlineExceededError):
      template = 'soc/deadline_exceeded.html'
    if isinstance(exception, MemoryError):
      template = 'soc/memory_error.html'
    if isinstance(exception, AssertionError):
      template = 'soc/assertion_error.html'
    if isinstance(exception, out_of_band.Error):
      return responses.errorResponse(exception, request)

    if template:
      logging.exception(exception)
      return responses.respond(request, template, context=context)

    # let Django handle it
    return None
Exemple #13
0
    def wrapper(self, request, access_type, *args, **kwargs):
        """Decorator wrapper method.
    """
        params = kwargs.get('params', {})

        # Try to extract rights
        if 'rights' in params:
            rights = params['rights']
        else:
            rights = self._params['rights']

        check_kwargs = kwargs.copy()
        context = responses.getUniversalContext(request)
        responses.useJavaScript(context, self._params['js_uses_all'])

        id = context['account']
        user = context['user']

        check_kwargs['GET'] = request.GET
        check_kwargs['POST'] = request.POST
        check_kwargs['context'] = context

        # reset and pre-fill the Checker's cache
        rights.setCurrentUser(id, user)

        # Do the access check dance
        try:
            rights.checkAccess(access_type, check_kwargs)
        except out_of_band.Error, error:
            return helper.responses.errorResponse(error, request)
Exemple #14
0
    def maintenance(self, request):
        """Returns a 'down for maintenance' view.
    """

        context = responses.getUniversalContext(request)
        context['page_name'] = ugettext('Maintenance')

        notice = context.pop('site_notice')

        if not notice:
            context['body_content'] = DEF_IN_UNEXPECTED_MAINTENANCE_MSG
        else:
            context['body_content'] = notice

        context['header_title'] = DEF_DOWN_FOR_MAINTENANCE_MSG
        context['sidebar_menu_items'] = [
            {
                'heading': DEF_DOWN_FOR_MAINTENANCE_MSG,
                'group': ''
            },
        ]

        template = 'soc/base.html'

        return responses.respond(request, template, context=context)
Exemple #15
0
  def visualize(self, request, access_type, page_name=None, params=None,
                **kwargs):
    """Visualization view for a statistic specified in request params.
    """

    link_id = kwargs['link_id']
    scope_path = kwargs['scope_path']
    logic = params['logic']

    statistic = self._getStatisticEntity(link_id, scope_path, logic)

    context = responses.getUniversalContext(request)

    if not logic.checkIfStatisticReady(statistic):
      template = 'soc/error.html'
      context['message'] = self.DEF_NO_VISUALIZATION_MSG_FMT % (statistic.name)
    else:
      responses.useJavaScript(context, params['js_uses_all'])
      context['entity'] = statistic
      context['page_name'] = "Statistic visualization"
      context['link_id'] = statistic.link_id
      context['scope_path'] = statistic.scope_path
      context['visualization_types'] = logic.getVisualizationTypesJson(statistic)

      template = 'soc/statistic/show.html'

    return responses.respond(request, template, context)
Exemple #16
0
  def request(self, request, access_type,
              page_name=None, params=None, **kwargs):
    """Handles the request concerning the view that creates a request
    for attaining a certain Role.

    Args:
      request: the standard Django HTTP request object
      page_name: the page name displayed in templates as page and header title
      params: a dict with params for this View
      kwargs: the Key Fields for the specified entity
    """

    # get the context for this webpage
    context = responses.getUniversalContext(request)
    responses.useJavaScript(context, params['js_uses_all'])
    context['page_name'] = page_name

    group_entity = params['group_logic'].getFromKeyName(kwargs['scope_path'])

    context['instruction_message'] = (self.DEF_REQUEST_INSTRUCTION_MSG_FMT %
        (params['name'], group_entity.name))

    if request.method == 'POST':
      return self.requestPost(request, context, params, group_entity, **kwargs)
    else:
      # request.method == 'GET'
      return self.requestGet(request, context, params, **kwargs)
Exemple #17
0
  def viewResults(self, request, access_type, page_name=None,
                  params=None, **kwargs):
    """View for SurveyRecord and SurveyRecordGroup.
    """

    results_logic = params['logic'].getRecordLogic()

    user = user_logic.getForCurrentAccount()

    # TODO(ajaksu): use the named parameter link_id from the re
    if request.path == '/survey/show/user/' + user.link_id:
      records = tuple(user.surveys_taken.run())
      context = responses.getUniversalContext(request)
      context['content'] = records[0].survey.survey_content
      responses.useJavaScript(context, params['js_uses_all'])
      context['page_name'] = u'Your survey records.'
    else:
      entity, context = self.getContextEntity(request, page_name,
                                              params, kwargs)

      if context is None:
        # user cannot see this page, return error response
        return entity
      context['content'] = entity.survey_content
      can_write = False
      rights = self._params['rights']
      try:
        rights.checkIsSurveyWritable({'key_name': entity.key().name(),
                                      'prefix': entity.prefix,
                                      'scope_path': entity.scope_path,
                                      'link_id': entity.link_id,},
                                     'key_name')
        can_write = True
      except out_of_band.AccessViolation:
        pass

      filter = self._params.get('filter') or {}

      # if user can edit the survey, show everyone's results
      if can_write:
        filter['survey'] = entity
      else:
        filter.update({'user': user, 'survey': entity})

      limit = self._params.get('limit') or 1000
      offset = self._params.get('offset') or 0
      order = self._params.get('order') or []
      idx = self._params.get('idx') or 0

      records = results_logic.getForFields(filter=filter, limit=limit,
                                        offset=offset, order=order)

    updates = dicts.rename(params, params['list_params'])
    context.update(updates)

    context['results'] = records, records

    template = 'soc/survey/results_page.html'
    return responses.respond(request, template, context=context)
Exemple #18
0
  def processRequest(self, request, access_type,
                     page_name=None, params=None, **kwargs):
    """Creates the page upon which a request can be processed.

    Args:
      request: the standard Django HTTP request object
      access_type : the name of the access type which should be checked
      page_name: the page name displayed in templates as page and header title
      params: a dict with params for this View
      kwargs: the Key Fields for the specified entity
    """

    # get the context for this webpage
    context = responses.getUniversalContext(request)
    responses.useJavaScript(context, params['js_uses_all'])
    context['page_name'] = page_name

    # get the request entity using the information from kwargs
    fields = {'link_id': kwargs['link_id'],
        'scope_path': kwargs['scope_path'],
        'role': params['logic'].role_name}
    request_entity = request_logic.logic.getForFields(fields, unique=True)

    # pylint: disable-msg=E1103
    user_entity = user_logic.logic.getFromKeyNameOr404(request_entity.link_id)

    get_dict = request.GET

    if 'status' in get_dict.keys():
      if get_dict['status'] in ['group_accepted', 'rejected', 'ignored']:
        # update the request_entity and redirect away from this page
        request_status = get_dict['status']

        # only update when the status is changing
        if request_status != request_entity.status:
          request_logic.logic.updateEntityProperties(request_entity, {
              'status': get_dict['status']})

        group_view = params.get('group_view')
        if not group_view:
          return http.HttpResponseRedirect('/')
        else:
          # redirect to the requests list
          return http.HttpResponseRedirect(
              redirects.getListRequestsRedirect(request_entity.scope, 
                  group_view.getParams()))

    # put the entity in the context
    context['entity'] = request_entity
    context['user_in_request'] = user_entity
    context['request_status'] = request_entity.status 
    context['role_name'] = params['logic'].role_name

    #display the request processing page using the appropriate template
    template = request_view.view.getParams()['request_processing_template']

    return responses.respond(request, template, context=context)
Exemple #19
0
  def manage(self, request, access_type,
             page_name=None, params=None, **kwargs):
    """Handles the request concerning the view that let's 
       you manage a role's status.

    Args:
      request: the standard Django HTTP request object
      page_name: the page name displayed in templates as page and header title
      params: a dict with params for this View
      kwargs: the Key Fields for the specified entity
    """

    # get the context for this webpage
    context = responses.getUniversalContext(request)
    responses.useJavaScript(context, params['js_uses_all'])
    context['page_name'] = page_name

    logic = params['logic']

    # get the entity for the given fields in kwargs
    fields = {'scope_path': kwargs['scope_path'],
        'link_id': kwargs['link_id']}
    role_entity = logic.getForFields(kwargs, unique=True)

    # get the redirect for the cancel button or when the resignation is done
    redirect = params['manage_redirect'](role_entity.scope,
        params['group_view'].getParams())

    # check to see if resign is true
    get_dict = request.GET
    resign = get_dict.get('resign')

    if resign == 'true':

      resign_error = params['logic'].canResign(role_entity)

      if not resign_error:
        # change the status of this role_entity to invalid
        fields = {'status': 'invalid'}
        logic.updateEntityProperties(role_entity, fields)

        # redirect to the roles listing
        return http.HttpResponseRedirect(redirect)
      else:
        # show error to the user
        context['resign_error'] = ugettext(resign_error %params)

    # set the appropriate context
    context['entity'] = role_entity
    context['url_name'] = params['url_name']
    context['cancel_redirect'] = redirect

    # get the manage template
    template = params['manage_template']

    # return a proper response
    return responses.respond(request, template, context=context)
Exemple #20
0
  def processInvite(self, request, access_type,
                   page_name=None, params=None, **kwargs):
    """Creates the page upon which an invite can be processed.

    Args:
      request: the standard Django HTTP request object
      access_type : the name of the access type which should be checked
      page_name: the page name displayed in templates as page and header title
      params: a dict with params for this View
      kwargs: the Key Fields for the specified entity
    """

    from soc.views.models.role import ROLE_VIEWS

    # get the context for this webpage
    context = responses.getUniversalContext(request)
    helper.responses.useJavaScript(context, params['js_uses_all'])

    # get the request entity using the information from kwargs
    request_entity = request_logic.getFromIDOr404(int(kwargs['id']))

    invite_accepted_redirect = redirects.getInviteAcceptedRedirect(
        request_entity, self._params)

    role_params = ROLE_VIEWS[request_entity.role].getParams()

    role_logic = role_params['logic']
    if not role_logic.canRejectInvite(request_entity.group):
      return http.HttpResponseRedirect(invite_accepted_redirect)

    # set the page name using the request_entity
    context['page_name'] = '%s %s for %s' % (page_name, 
        role_params['name'], request_entity.group.name)

    get_dict = request.GET

    # TODO(ljvderijk): Should be made a POST request.
    if 'status' in get_dict.keys():
      if get_dict['status'] == 'canceled':
        # this invite has been canceled mark as such
        request_logic.updateEntityProperties(request_entity, {
            'status': 'canceled'})

        # redirect to user request overview
        return http.HttpResponseRedirect('/user/requests')

    # put the entity in the context
    context['entity'] = request_entity
    context['module_name'] = params['module_name']
    context['role_name'] = role_params['name']
    context['invite_accepted_redirect'] = (invite_accepted_redirect)

    #display the invite processing page using the appropriate template
    template = params['invite_processing_template']

    return responses.respond(request, template, context=context)
Exemple #21
0
  def processRequest(self, request, access_type,
                     page_name=None, params=None, **kwargs):
    """Creates the page upon which a request can be processed.

    Args:
      request: the standard Django HTTP request object
      access_type : the name of the access type which should be checked
      page_name: the page name displayed in templates as page and header title
      params: a dict with params for this View
      kwargs: the Key Fields for the specified entity
    """

    # get the request entity using the information from kwargs
    request_entity = request_logic.getFromIDOr404(int(kwargs['id']))

    # get the context for this webpage
    context = responses.getUniversalContext(request)
    responses.useJavaScript(context, params['js_uses_all'])

    context['page_name'] = '%s from %s to become a %s' % (
        page_name, request_entity.user.name, params['name'])

    # TODO(ljvderijk): Should be a POST request
    get_dict = request.GET

    if 'status' in get_dict.keys():
      if get_dict['status'] in ['group_accepted', 'rejected', 'withdrawn',
                                'ignored']:
        # update the request_entity and redirect away from this page
        request_status = get_dict['status']

        # only update when the status is changing
        if request_status != request_entity.status:
          request_logic.updateEntityProperties(request_entity, {
              'status': get_dict['status']})

        group_view = params.get('group_view')
        if not group_view:
          return http.HttpResponseRedirect('/')
        else:
          # redirect to the requests list
          return http.HttpResponseRedirect(
              redirects.getListRequestsRedirect(request_entity.group,
                  group_view.getParams()))

    # put the entity in the context
    context['entity'] = request_entity
    context['request_status'] = request_entity.status 
    context['role_verbose'] = params['name']
    context['url_name'] = params['url_name']

    #display the request processing page using the appropriate template
    template = request_view.view.getParams()['request_processing_template']

    return responses.respond(request, template, context=context)
Exemple #22
0
    def processInvite(self,
                      request,
                      access_type,
                      page_name=None,
                      params=None,
                      **kwargs):
        """Creates the page upon which an invite can be processed.

    Args:
      request: the standard Django HTTP request object
      access_type : the name of the access type which should be checked
      page_name: the page name displayed in templates as page and header title
      params: a dict with params for this View
      kwargs: the Key Fields for the specified entity
    """

        from soc.views.models.role import ROLE_VIEWS

        # get the context for this webpage
        context = responses.getUniversalContext(request)
        helper.responses.useJavaScript(context, params['js_uses_all'])

        # get the request entity using the information from kwargs
        request_entity = request_logic.getFromIDOr404(int(kwargs['id']))

        role_params = ROLE_VIEWS[request_entity.role].getParams()

        # set the page name using the request_entity
        context['page_name'] = '%s %s for %s' % (
            page_name, role_params['name'], request_entity.group.name)

        get_dict = request.GET

        if 'status' in get_dict.keys():
            if get_dict['status'] == 'rejected':
                # this invite has been rejected mark as rejected
                request_logic.updateEntityProperties(request_entity,
                                                     {'status': 'rejected'})

                # redirect to user request overview
                return http.HttpResponseRedirect('/user/requests')

        # put the entity in the context
        context['entity'] = request_entity
        context['module_name'] = params['module_name']
        context['role_name'] = role_params['name']
        context['invite_accepted_redirect'] = (
            redirects.getInviteAcceptedRedirect(request_entity, self._params))

        #display the invite processing page using the appropriate template
        template = params['invite_processing_template']

        return responses.respond(request, template, context=context)
Exemple #23
0
  def acceptOrgAdminIntivation(self, request, access_type, page_name=None,
                               params=None, **kwargs):
    """Creates the page process an invite into an OrgAdmin role.
    """

    request_entity = request_logic.getFromIDOr404(int(kwargs['id']))

    # get the context for this webpage
    context = responses.getUniversalContext(request)
    responses.useJavaScript(context, params['js_uses_all'])
    context['page_name'] = page_name

    return acceptInvitation(request, context, params, request_entity, 'org_admin', **kwargs)
Exemple #24
0
  def process_request(self, request):
    """Called when a request is made.

    See the Django middleware documentation for an explanation of
    the method signature.
    """

    context = responses.getUniversalContext(request)
    allowed = (context['is_admin']
        or ('HTTP_X_APPENGINE_CRON' in os.environ)
        or ('HTTP_X_APPENGINE_QUEUENAME' in os.environ))

    if not allowed and context['in_maintenance']:
      return self.maintenance(request)
Exemple #25
0
  def processInvite(self, request, access_type,
                   page_name=None, params=None, **kwargs):
    """Creates the page upon which an invite can be processed.

    Args:
      request: the standard Django HTTP request object
      access_type : the name of the access type which should be checked
      page_name: the page name displayed in templates as page and header title
      params: a dict with params for this View
      kwargs: the Key Fields for the specified entity
    """

    # get the context for this webpage
    context = responses.getUniversalContext(request)
    helper.responses.useJavaScript(context, params['js_uses_all'])

    request_logic = params['logic']

    # get the request entity using the information from kwargs
    fields = {'link_id': kwargs['link_id'],
        'scope_path': kwargs['scope_path'],
        'role': kwargs['role'],
        'status': 'group_accepted'}
    request_entity = request_logic.getForFields(fields, unique=True)

    # set the page name using the request_entity
    context['page_name'] = '%s %s' % (page_name, 
        request_entity.role_verbose)

    get_dict = request.GET

    if 'status' in get_dict.keys():
      if get_dict['status'] == 'rejected':
        # this invite has been rejected mark as rejected
        request_logic.updateEntityProperties(request_entity, {
            'status': 'rejected'})

        # redirect to user request overview
        return http.HttpResponseRedirect('/user/requests')

    # put the entity in the context
    context['entity'] = request_entity
    context['module_name'] = params['module_name']
    context['invite_accepted_redirect'] = (
        redirects.getInviteAcceptedRedirect(request_entity, self._params))

    #display the invite processing page using the appropriate template
    template = params['invite_processing_template']

    return responses.respond(request, template, context=context)
Exemple #26
0
  def view_wrapper(request, *args, **kwds):
    """View decorator wrapper method.
    """

    context = responses.getUniversalContext(request)

    try:
      if not context['is_admin'] and context['in_maintenance']:
        return maintenance(request)

      return func(request, *args, **kwds)
    except CapabilityDisabledError, exception:
      logging.exception(exception)
      # assume the site is in maintenance if we get CDE
      return maintenance(request)
Exemple #27
0
    def manage(self,
               request,
               access_type,
               page_name=None,
               params=None,
               **kwargs):
        """Handles the request concerning the view that let's 
       you manage a role's status.

    Args:
      request: the standard Django HTTP request object
      page_name: the page name displayed in templates as page and header title
      params: a dict with params for this View
      kwargs: the Key Fields for the specified entity
    """

        # get the context for this webpage
        context = responses.getUniversalContext(request)
        responses.useJavaScript(context, params['js_uses_all'])
        context['page_name'] = page_name

        logic = params['logic']

        # get the entity for the given fields in kwargs
        role_entity = logic.getFromKeyFieldsOr404(kwargs)

        # get the redirect for the cancel button or when the resignation is done
        redirect = params['manage_redirect'](role_entity.scope,
                                             params['group_view'].getParams())

        if request.method == 'POST':
            resign_error = logic.canResign(role_entity)
            if not resign_error:
                return self.managePost(request, params, role_entity, redirect)

            # show error to the user
            context['resign_error'] = resign_error % params

        # set the appropriate context
        context['entity'] = role_entity
        context['url_name'] = params['url_name']
        context['cancel_redirect'] = redirect

        # get the manage template
        template = params['manage_template']

        # return a proper response
        return responses.respond(request, template, context=context)
Exemple #28
0
  def home(self, request, page_name=None, params=None, **kwargs):
    """Renders the home page for seeding operations.
    """
    template = 'modules/seeder/home.html'
    configuration_sheet = request.FILES.get('configuration_sheet', None);
    if configuration_sheet:
      configuration_sheet = configuration_sheet.read()
    else:
      configuration_sheet = ''

    context = responses.getUniversalContext(request)
    context['configuration_sheet'] = simplejson.dumps(configuration_sheet)

    # FIXME : temporarily comment due to errors 
    #responses.useJavaScript(context, params['js_uses_all'])

    return responses.respond(request, template, context)
Exemple #29
0
    def home(self, request, page_name=None, params=None, **kwargs):
        """Renders the home page for seeding operations.
    """
        template = 'modules/seeder/home.html'
        configuration_sheet = request.FILES.get('configuration_sheet', None)
        if configuration_sheet:
            configuration_sheet = configuration_sheet.read()
        else:
            configuration_sheet = ''

        context = responses.getUniversalContext(request)
        context['configuration_sheet'] = simplejson.dumps(configuration_sheet)

        # FIXME : temporarily comment due to errors
        #responses.useJavaScript(context, params['js_uses_all'])

        return responses.respond(request, template, context)
Exemple #30
0
    def acceptOrgAdminIntivation(self,
                                 request,
                                 access_type,
                                 page_name=None,
                                 params=None,
                                 **kwargs):
        """Creates the page process an invite into an OrgAdmin role.
    """

        request_entity = request_logic.getFromIDOr404(int(kwargs['id']))

        # get the context for this webpage
        context = responses.getUniversalContext(request)
        responses.useJavaScript(context, params['js_uses_all'])
        context['page_name'] = page_name

        return acceptInvitation(request, context, params, request_entity,
                                'org_admin', **kwargs)
Exemple #31
0
    def submitForms(self, request, access_type, page_name=None, params=None, **kwargs):
        """Form upload page for a given student.

    See base.View.public() for more details.
    """

        template = "modules/gci/student/submit_forms.html"
        context = responses.getUniversalContext(request)
        context["page_name"] = page_name

        logic = params["logic"]

        entity = logic.getFromKeyFieldsOr404(kwargs)

        if request.method == "POST":
            return self.submitFormsPost(request, params, context, entity)
        else:
            return self.submitFormsGet(request, params, template, context, entity)
Exemple #32
0
  def manage(self, request, access_type,
             page_name=None, params=None, **kwargs):
    """Handles the request concerning the view that let's 
       you manage a role's status.

    Args:
      request: the standard Django HTTP request object
      page_name: the page name displayed in templates as page and header title
      params: a dict with params for this View
      kwargs: the Key Fields for the specified entity
    """

    # get the context for this webpage
    context = responses.getUniversalContext(request)
    responses.useJavaScript(context, params['js_uses_all'])
    context['page_name'] = page_name

    logic = params['logic']

    # get the entity for the given fields in kwargs
    role_entity = logic.getFromKeyFieldsOr404(kwargs)

    # get the redirect for the cancel button or when the resignation is done
    redirect = params['manage_redirect'](role_entity.scope,
        params['group_view'].getParams())

    if request.method == 'POST':
      resign_error = logic.canResign(role_entity)
      if not resign_error:
        return self.managePost(request, params, role_entity, redirect)

      # show error to the user
      context['resign_error'] = resign_error % params

    # set the appropriate context
    context['entity'] = role_entity
    context['url_name'] = params['url_name']
    context['cancel_redirect'] = redirect

    # get the manage template
    template = params['manage_template']

    # return a proper response
    return responses.respond(request, template, context=context)
Exemple #33
0
    def maintenance(self, request, page_name):
        """Returns a 'down for maintenance' view.
    """

        context = responses.getUniversalContext(request)
        context["page_name"] = page_name

        notice = context.pop("site_notice")

        if not notice:
            context["body_content"] = self.DEF_NOT_IN_MAINTENANCE_MSG
        else:
            context["body_content"] = notice
            context["header_title"] = self.DEF_DOWN_FOR_MAINTENANCE_MSG
            context["sidebar_menu_items"] = [{"heading": self.DEF_DOWN_FOR_MAINTENANCE_MSG, "group": ""}]

        template = "soc/base.html"

        return responses.respond(request, template, context=context)
Exemple #34
0
  def startTask(self, request, option_name):
    """Starts the specified Task for the given option.
    """

    context = responses.getUniversalContext(request)
    context['page_name'] = 'Start Update Task'

    option = self.options.get(option_name)
    if not option:
      template = 'soc/error.html'
      context['message'] = 'Uknown option "%s".' % option_name
    else:
      template = 'soc/tasks/run_update.html'
      context['option'] = option
      context['success'] = option['starter'](request,
                                             self._getRunUpdateURL(option_name))

    content = loader.render_to_string(template, dictionary=context)
    return http.HttpResponse(content)
Exemple #35
0
  def getContextEntity(self, request, page_name, params, kwargs):
    context = responses.getUniversalContext(request)
    responses.useJavaScript(context, params['js_uses_all'])
    context['page_name'] = page_name
    entity = None

    # TODO(ajaksu): there has to be a better way in this universe to get these
    kwargs['prefix'] = 'program'
    kwargs['link_id'] = request.path.split('/')[-1]
    kwargs['scope_path'] = '/'.join(request.path.split('/')[4:-1])

    entity = survey_logic.getFromKeyFieldsOr404(kwargs)

    if not self._public(request, entity, context):
      error = out_of_band.Error('')
      error = responses.errorResponse(
          error, request, template=params['error_public'], context=context)
      return error, None

    return entity, context
Exemple #36
0
  def applicant(self, request, access_type,
                page_name=None, params=None, **kwargs):
    """Handles the creation of a group via an approved group application.

    Args:
      request: the standard Django HTTP request object
      access_type : the name of the access type which should be checked
      page_name: the page name displayed in templates as page and header title
      params: a dict with params for this View
      kwargs: the Key Fields for the specified entity
    """

    # get the context for this webpage
    context = responses.getUniversalContext(request)
    responses.useJavaScript(context, params['js_uses_all'])
    context['page_name'] = page_name

    if request.method == 'POST':
      return self.applicantPost(request, context, params, **kwargs)
    else:
      # request.method == 'GET'
      return self.applicantGet(request, context, params, **kwargs)
Exemple #37
0
  def applicant(self, request, access_type,
                page_name=None, params=None, **kwargs):
    """Handles the creation of a group via an approved group application.

    Args:
      request: the standard Django HTTP request object
      access_type : the name of the access type which should be checked
      page_name: the page name displayed in templates as page and header title
      params: a dict with params for this View
      kwargs: the Key Fields for the specified entity
    """

    # get the context for this webpage
    context = responses.getUniversalContext(request)
    responses.useJavaScript(context, params['js_uses_all'])
    context['page_name'] = page_name

    if request.method == 'POST':
      return self.applicantPost(request, context, params, **kwargs)
    else:
      # request.method == 'GET'
      return self.applicantGet(request, context, params, **kwargs)
Exemple #38
0
  def maintenance(self, request):
    """Returns a 'down for maintenance' view.
    """

    context = responses.getUniversalContext(request)
    context['page_name'] = ugettext('Maintenance')

    notice = context.pop('site_notice')

    if not notice:
      context['body_content'] = DEF_IN_UNEXPECTED_MAINTENANCE_MSG
    else:
      context['body_content'] = notice

    context['header_title'] = DEF_DOWN_FOR_MAINTENANCE_MSG
    context['sidebar_menu_items'] = [
        {'heading': DEF_DOWN_FOR_MAINTENANCE_MSG,
         'group': ''},
        ]

    template = 'soc/base.html'

    return responses.respond(request, template, context=context)
Exemple #39
0
    def submitForms(self,
                    request,
                    access_type,
                    page_name=None,
                    params=None,
                    **kwargs):
        """Form upload page for a given student.

    See base.View.public() for more details.
    """

        template = 'modules/gci/student/submit_forms.html'
        context = responses.getUniversalContext(request)
        context['page_name'] = page_name

        logic = params['logic']

        entity = logic.getFromKeyFieldsOr404(kwargs)

        if request.method == 'POST':
            return self.submitFormsPost(request, params, context, entity)
        else:
            return self.submitFormsGet(request, params, template, context,
                                       entity)
  @decorators.check_access
  def review(self, request, access_type,
             page_name=None, params=None, **kwargs):
    """View that allows Organization Admins and Mentors to review the proposal.

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

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

    # 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.scope.name())
    context['entity'] = entity
    context['entity_type'] = params['name']
    context['entity_type_url'] = params['url_name']
    if self._show_review_not_appeared_msg:
      context['header_msg'] = self.DEF_REVIEW_NOT_APPEARED_MSG
      self._show_review_not_appeared_msg = False

    # get the roles important for reviewing an application
    filter = {
        'user': user_logic.logic.getCurrentUser(),
        'scope': entity.org,
        'status': 'active'
Exemple #41
0
class View(base.View):
    """View methods for the Student Project model.
  """

    DEF_NO_RECORD_AVAILABLE_MSG = ugettext('No Record Available')
    DEF_VIEW_RECORD_MSG = ugettext('View Record')
    DEF_TAKE_SURVEY_MSG = ugettext('Take Survey')

    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'] = [('checkHasAny', [[
            ('checkHasRoleForScope', [org_admin_logic, ['active',
                                                        'inactive']]),
            ('checkHasRoleForScope', [mentor_logic, ['active', 'inactive']])
        ]])]
        # TODO: lack of better name here!
        rights['st_edit'] = [
            'checkCanEditStudentProjectAsStudent',
            ('checkStudentProjectHasStatus', [['accepted', 'completed']])
        ]
        rights['overview'] = [('checkIsHostForProgram', [program_logic])]

        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('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>overview)/(?P<scope_path>%(ulnp)s)/%(lnp)s$',
             'soc.modules.gsoc.views.models.%(module_name)s.overview',
             'Overview of all %(name_plural)s for'),
        ]

        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['public_field_prefetch'] = ['mentor', 'student', 'scope']
        new_params['public_field_extra'] = lambda entity: {
            'student': entity.student.name(),
            'mentor': entity.mentor.name(),
            'org': entity.scope.name,
        }
        new_params['public_field_keys'] = [
            'student', 'title', 'mentor', 'org', 'status'
        ]
        new_params['public_field_names'] = [
            'Student', 'Title', 'Mentor', 'Organization', 'Status'
        ]

        new_params['org_home_field_prefetch'] = ['mentor', 'student']
        new_params['org_home_field_extra'] = lambda entity: {
            'student':
            entity.student.name(),
            'mentor':
            ', '.join(mentor.name() for mentor in [entity.mentor] + db.get(
                entity.additional_mentors))
        }
        new_params['org_home_field_keys'] = [
            'student', 'title', 'mentor', 'status'
        ]
        new_params['org_home_field_names'] = [
            'Student', 'Title', 'Mentor', 'Status'
        ]

        # define the list redirect action to show the notification
        new_params['public_row_extra'] = new_params[
            'org_home_row_extra'] = lambda entity: {
                'link': redirects.getPublicRedirect(entity, new_params)
            }
        new_params['org_home_row_action'] = {
            'type': 'redirect_custom',
            'parameters': dict(new_window=False),
        }

        new_params['admin_field_prefetch'] = ['mentor', 'student', 'scope']
        new_params['admin_field_extra'] = lambda entity: {
            'student': entity.student.name(),
            'mentor': entity.mentor.name(),
            'student_id': entity.student.link_id
        }
        new_params['admin_field_keys'] = [
            'student', 'title', 'mentor', 'status', 'student_id'
        ]
        new_params['admin_field_names'] = [
            'Student', 'Title', 'Mentor', 'Status', 'Student Link ID'
        ]
        new_params['admin_field_hidden'] = ['student_id']

        new_params['admin_conf_extra'] = {
            'multiselect': True,
        }
        new_params['admin_button_global'] = [{
            'bounds': [1, 'all'],
            'id': 'withdraw',
            'caption': 'Withdraw Project',
            'type': 'post',
            'parameters': {
                'url': '',
                'keys': ['key'],
                'refresh': 'current',
            }
        }, {
            'bounds': [1, 'all'],
            'id': 'accept',
            'caption': 'Accept Project',
            'type': 'post',
            'parameters': {
                'url': '',
                'keys': ['key'],
                'refresh': 'current',
            }
        }]

        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('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 getOverviewData(self, request, params, program):
        """Return data for withdraw.
    """

        fields = {
            'program': program,
        }

        idx = lists.getListIndex(request)

        if idx != 0:
            return lists.getErrorResponse(request, "idx not valid")

        contents = lists.getListData(request,
                                     params,
                                     fields,
                                     visibility='admin')

        return lists.getResponse(request, contents)

    @decorators.merge_params
    @decorators.check_access
    def overview(self,
                 request,
                 access_type,
                 page_name=None,
                 params=None,
                 **kwargs):
        """View that allows Program Admins to see/control all StudentProjects.

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

        program_entity = program_logic.getFromKeyFieldsOr404(kwargs)

        if request.POST:
            return self.overviewPost(request, params, program_entity)
        else:  #request.GET
            return self.overviewGet(request, page_name, params, program_entity,
                                    **kwargs)

    def overviewPost(self, request, params, program):
        """Handles the POST request for the Program Admins overview page.

    Args:
      request: Django HTTPRequest object
      params: Params for this view
      program: GSoCProgram entity
    """

        project_logic = params['logic']

        post_dict = request.POST

        data = simplejson.loads(post_dict.get('data', '[]'))
        button_id = post_dict.get('button_id', '')

        if button_id not in ['withdraw', 'accept']:
            logging.warning('Invalid button ID found %s' % (button_id))
            return http.HttpResponse()

        project_keys = []

        for selected in data:
            project_keys.append(selected['key'])

        # get all projects and prefetch the program field
        projects = project_logic.getFromKeyName(project_keys)
        project_logic.prefetchField('program', projects)

        # filter out all projects not belonging to the current program
        projects = [p for p in projects if p.program.key() == program.key()]

        for p in projects:
            fields = {}
            if button_id == 'withdraw':
                fields['status'] = 'withdrawn'
            elif button_id == 'accept':
                fields['status'] = 'accepted'

            # update the project with the new status
            project_logic.updateEntityProperties(p, fields)

        # return a 200 response
        return http.HttpResponse()

    def overviewGet(self, request, page_name, params, program_entity,
                    **kwargs):
        """Handles the GET request for the Program Admins overview page.

    Args:
      request: Django HTTPRequest object
      page_name: Name for this page
      params: Params for this view
      program_entity: GSocProgram entity
    """

        page_name = '%s %s' % (page_name, program_entity.name)

        list_params = params.copy()
        list_params['admin_row_extra'] = lambda entity: {
            'link': redirects.getPublicRedirect(entity, list_params)
        }

        list_params['list_description'] = ugettext(
            'An overview of all StudentProjects for %s. Click on an item to view '
            'the project, use the buttons on the list for withdrawing a project.'
            % (program_entity.name))

        if lists.isDataRequest(request):
            return self.getOverviewData(request, list_params, program_entity)

        project_list = lists.getListGenerator(request,
                                              list_params,
                                              idx=0,
                                              visibility='admin')

        # fill contents with the list
        contents = [project_list]

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

    def _getManageData(self, request, gps_params, ps_params, entity):
        """Returns the JSONResponse for the Manage page.

    Args:
      request: HTTPRequest object
      gps_params: GradingProjectSurvey list params
      ps_params: ProjectSurvey list params
      entity: StudentProject entity
    """

        idx = lists.getListIndex(request)

        if idx == 0:
            params = gps_params
        elif idx == 1:
            params = ps_params
        else:
            return lists.getErrorResponse(request, "idx not valid")

        fields = {'project': entity}
        record_logic = params['logic'].getRecordLogic()
        record_entities = record_logic.getForFields(fields)
        record_dict = dict(
            (i.survey.key(), i) for i in record_entities if i.survey)
        record_getter = lambda entity: record_dict.get(entity.key())
        args = [record_getter]

        fields = {'scope': entity.program, 'prefix': 'gsoc_program'}
        contents = lists.getListData(request, params, fields, args=args)

        return lists.getResponse(request, contents)

    @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()
    """

        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)

    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

    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)

    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)

    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 _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 getManageOverviewData(self, request, mo_params, org_entity):
        """Returns the manageOverview data.
    """

        args = []
        fields = {}

        idx = lists.getListIndex(request)

        if idx == 0:
            from soc.modules.gsoc.logic.models.survey import grading_logic as \
                grading_survey_logic
            from soc.modules.gsoc.logic.models.survey import project_logic as \
                project_survey_logic
            from soc.modules.gsoc.logic.models.survey_record import grading_logic
            from soc.modules.gsoc.logic.models.survey_record import project_logic

            program_entity = org_entity.scope

            fields = {'scope_path': program_entity.key().id_or_name()}

            # count the number of have been active ProjectSurveys
            project_surveys = project_survey_logic.getForFields(fields)
            project_survey_count = len(project_surveys)

            for project_survey in project_surveys:
                if not project_survey_logic.hasRecord(project_survey):
                    project_survey_count = project_survey_count - 1

            # count the number of have been active GradingProjectSurveys
            grading_surveys = grading_survey_logic.getForFields(fields)
            grading_survey_count = len(grading_surveys)

            for grading_survey in grading_surveys:
                if not grading_survey_logic.hasRecord(grading_survey):
                    grading_survey_count = grading_survey_count - 1

            fields = {'scope': org_entity}
            params = mo_params
            args = [
                project_surveys, project_survey_count, grading_surveys,
                grading_survey_count
            ]
        else:
            return lists.getErrorResponse(request, 'idx not valid')

        contents = lists.getListData(request, params, fields, args=args)

        return lists.getResponse(request, contents)

    @decorators.merge_params
    @decorators.check_access
    def manageOverview(self,
                       request,
                       access_type,
                       page_name=None,
                       params=None,
                       **kwargs):
        """View that allows Organization Admins to see an overview of 
       their Organization's Student Projects.

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

        from soc.modules.gsoc.logic.models.survey import grading_logic as \
            grading_survey_logic
        from soc.modules.gsoc.logic.models.survey import project_logic as \
            project_survey_logic
        from soc.modules.gsoc.logic.models.survey_record import grading_logic
        from soc.modules.gsoc.logic.models.survey_record import project_logic

        # make sure the organization exists
        org_entity = org_logic.getFromKeyNameOr404(kwargs['scope_path'])
        page_name = '%s %s' % (page_name, org_entity.name)

        mo_params = params.copy()

        #list all active projects
        mo_params['list_description'] = ugettext(
            'List of all %s for %s, if you are an Org Admin you can click '
            'a project for more actions. Such as reassigning mentors or viewing '
            'results of the evaluations.' %
            (params['name_plural'], org_entity.name))
        mo_params['public_field_names'] = params['public_field_names'] + [
            'Mentor evaluation', 'Student Evaluation'
        ]
        mo_params['public_field_keys'] = params['public_field_keys'] + [
            'mentor_evaluation', 'student_evaluation'
        ]

        fields = {'scope': org_entity, 'status': ['active', 'inactive']}
        org_admin = org_admin_logic.getForFields(fields, unique=True)

        # Org Admins get a link to manage the project, others go to public page
        if org_admin:
            mo_params['public_row_extra'] = lambda entity, *args: {
                'link': redirects.getManageRedirect(entity, mo_params)
            }
        else:
            mo_params['public_row_extra'] = lambda entity, *args: {
                'link': redirects.getPublicRedirect(entity, mo_params)
            }

        mo_params['public_field_prefetch'] = ['student', 'mentor', 'scope']
        mo_params['public_field_extra'] = lambda entity, ps, psc, gs, gsc: {
            'org':
            entity.scope.name,
            'student':
            '%s (%s)' % (entity.student.name(), entity.student.email),
            'mentor':
            entity.mentor.name(),
            'mentor_evaluation':
            '%d/%d' % (grading_logic.getQueryForFields({
                'project': entity
            }).count(), gsc),
            'student_evaluation':
            '%d/%d' % (project_logic.getQueryForFields({
                'project': entity
            }).count(), psc),
        }

        if lists.isDataRequest(request):
            return self.getManageOverviewData(request, mo_params, org_entity)

        mo_list = lists.getListGenerator(request, mo_params, idx=0)
        contents = [mo_list]

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

    @decorators.merge_params
    @decorators.check_access
    def stEdit(self,
               request,
               access_type,
               page_name=None,
               params=None,
               **kwargs):
        """View that allows students to edit information about their project.

    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'])

        # get the context for this webpage
        context = responses.getUniversalContext(request)
        responses.useJavaScript(context, params['js_uses_all'])
        context['page_name'] = page_name
        # cancel should go to the public view
        params['cancel_redirect'] = redirects.getPublicRedirect(entity, params)

        if request.POST:
            return self.stEditPost(request, context, params, entity, **kwargs)
        else:  #request.GET
            return self.stEditGet(request, context, params, entity, **kwargs)
Exemple #42
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)
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)
Exemple #44
0
class View(base.View):
    """View methods for the GradingSurveyGroup 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['create'] = [('checkIsHostForProgramInScope', program_logic)]
        rights['edit'] = [('checkIsHostForProgramInScope', program_logic)]
        rights['delete'] = ['checkIsDeveloper']
        rights['show'] = [('checkIsHostForProgramInScope', program_logic)]
        rights['list'] = ['checkIsDeveloper']
        rights['records'] = [('checkIsHostForProgramInScope', program_logic)]
        rights['edit_record'] = [('checkIsHostForProgramInScope',
                                  program_logic)]

        new_params = {}
        new_params['logic'] = survey_group_logic
        new_params['rights'] = rights
        new_params['name'] = "Grading Survey Group"
        new_params['url_name'] = 'gsoc/grading_survey_group'
        new_params['module_package'] = 'soc.modules.gsoc.views.models'
        new_params['sidebar_grouping'] = "Surveys"

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

        new_params['no_admin'] = True
        new_params['no_create_with_key_fields'] = True

        new_params['create_extra_dynaproperties'] = {
            'grading_survey':
            djangoforms.ModelChoiceField(GradingProjectSurvey, required=True),
            'student_survey':
            djangoforms.ModelChoiceField(ProjectSurvey, required=False),
        }

        new_params['extra_dynaexclude'] = [
            'link_id', 'scope', 'scope_path', 'last_update_started',
            'last_update_complete'
        ]

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

        patterns = [
            (r'^%(url_name)s/(?P<access_type>records)/%(key_fields)s$',
             '%(module_package)s.%(module_name)s.view_records',
             'Overview of GradingRecords'),
            (r'^%(url_name)s/(?P<access_type>edit_record)/%(key_fields)s$',
             '%(module_package)s.%(module_name)s.edit_record',
             'Edit a GradingRecord'),
        ]

        new_params['extra_django_patterns'] = patterns

        new_params[
            'view_records_template'] = 'soc/grading_survey_group/records.html'
        new_params[
            'records_heading_template'] = 'soc/grading_record/list/heading.html'
        new_params['records_row_template'] = 'soc/grading_record/list/row.html'
        new_params['record_edit_template'] = 'soc/grading_record/edit.html'

        # create the form that will be used to edit a GradingRecord
        record_logic = survey_group_logic.getRecordLogic()

        record_edit_form = dynaform.newDynaForm(
            dynabase=soc.views.helper.forms.BaseForm,
            dynamodel=record_logic.getModel(),
            dynaexclude=[
                'grading_survey_group', 'mentor_record', 'student_record',
                'project'
            ],
        )

        new_params['record_edit_form'] = record_edit_form

        new_params['public_field_keys'] = [
            "name", "last_update_started", "last_update_completed"
        ]
        new_params['public_field_names'] = [
            "Name", "Last update started", "Last update completed"
        ]

        new_params['records_field_extra'] = lambda entity: {
            "project_title":
            entity.project.title,
            "student_name":
            "%s (%s)" %
            (entity.project.student.name, entity.project.student.link_id),
            "organization":
            entity.project.name,
            "mentor_name":
            "%s (%s)" %
            (entity.project.mentor.name, entity.project.mentor.link_id),
            "final_grade":
            entity.grade_decision.capitalize(),
            "mentor_grade": ("Pass" if entity.mentor_record.grade else "Fail")
            if entity.mentor_record else "Not Available",
            "student_eval":
            "Yes" if entity.student_record else "Not Available",
        }
        new_params['records_field_keys'] = [
            "project_title", "student_name", "organization", "mentor_name",
            "final_grade", "mentor_grade", "student_eval", "locked"
        ]
        new_params['records_field_names'] = [
            "Project Name", "Student (link id)", "Organization",
            "Mentor (link id)", "Final Grade", "Mentor Grade", "Student Eval",
            "Locked"
        ]

        params = dicts.merge(params, new_params)

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

    @decorators.merge_params
    @decorators.check_access
    def create(self,
               request,
               access_type,
               page_name=None,
               params=None,
               **kwargs):
        """Pass the correct survey queries to GroupForm.

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

        if kwargs.get('scope_path'):
            self.setQueries(kwargs['scope_path'], params['create_form'])

        return super(View, self).create(request,
                                        access_type,
                                        page_name=page_name,
                                        params=params,
                                        **kwargs)

    @decorators.merge_params
    @decorators.check_access
    def edit(self,
             request,
             access_type,
             page_name=None,
             params=None,
             seed=None,
             **kwargs):
        """Pass the correct survey queries to GroupForm.

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

        self.setQueries(kwargs['scope_path'], params['edit_form'])

        return super(View, self).edit(request,
                                      access_type,
                                      page_name=page_name,
                                      params=params,
                                      seed=seed,
                                      **kwargs)

    def _editGet(self, request, entity, form):
        """Performs any required processing on the form to get its edit page.

    Args:
      request: the django request object
      entity: the entity to get
      form: the django form that will be used for the page
    """

        form.fields['link_id'].initial = entity.link_id

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

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

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

            # TODO: seriously redesign _editPost to pass along kwargs
            fields['scope_path'] = fields['grading_survey'].scope_path
        else:
            fields['link_id'] = entity.link_id

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

    def setQueries(self, program_keyname, group_form):
        """Add program filtering queries to the GroupForm.

    Args:
      program_keyname: keyname of the program to filter on
      group_form: DynaForm instance to set the queries for
    """

        # fetch the program
        program = program_logic.getFromKeyNameOr404(program_keyname)

        # filter grading surveys by program and use title for display
        grading_query = grading_logic.getQueryForFields(
            filter={'scope_path': program_keyname})

        # filter project surveys by program and use title for display
        student_query = project_logic.getQueryForFields(
            filter={'scope_path': program_keyname})

        group_form.base_fields['grading_survey'].query = grading_query
        group_form.base_fields['student_survey'].query = student_query

        # use survey titles in drop-downs
        self.choiceTitles(group_form, 'grading_survey', grading_logic)
        self.choiceTitles(group_form, 'student_survey', project_logic)

    def choiceTitles(self, group_form, field, logic):
        """Fetch entity titles for choice field entries.

    Args:
      group_form: The form to set the choice field entries for
      field: the field_name to set the choice entries for
      logic: the logic for the model to set the choice entries for
    """

        # TODO(ajaksu): subclass ModelChoiceField so we don't need this method
        choice_list = []

        model = logic.getModel()

        for value, text in tuple(group_form.base_fields[field].choices):
            if value:
                entity = model.get(value)
                text = '%s (%s)' % (entity.title, entity.link_id)
            choice_list.append((value, text))

        choices = tuple(choice_list)

        group_form.base_fields[field].choices = choices

    @decorators.merge_params
    @decorators.check_access
    def viewRecords(self,
                    request,
                    access_type,
                    page_name=None,
                    params=None,
                    **kwargs):
        """View which shows all collected records for a given GradingSurveyGroup.

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

        from google.appengine.api.labs import taskqueue

        from soc.logic import lists as lists_logic

        survey_group_logic = params['logic']
        record_logic = survey_group_logic.getRecordLogic()

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

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

        # get the POST request dictionary and check if we should take action
        post_dict = request.POST

        if post_dict.get('update_records'):
            # start the task to update all GradingRecords for the given group
            task_params = {'group_key': entity.key().id_or_name()}
            task_url = '/tasks/grading_survey_group/update_records'

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

            # update the GradingSurveyGroup with the new timestamp
            fields = {'last_update_started': datetime.datetime.now()}
            survey_group_logic.updateEntityProperties(entity, fields)

            context['message'] = 'Grading Records update successfully started.'

        if post_dict.get('update_projects'):
            # start the task to update all StudentProjects for the given group
            task_params = {'group_key': entity.key().id_or_name()}
            task_url = '/tasks/grading_survey_group/update_projects'

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

            context[
                'message'] = 'Student Projects update successfully started.'

        if post_dict.get('update_projects_and_mail'):
            # Start the task to update all StudentProjects for the given group and
            # send out emails.
            task_params = {
                'group_key': entity.key().id_or_name(),
                'send_mail': 'true'
            }
            task_url = '/tasks/grading_survey_group/update_projects'

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

            context['message'] = (
                'Student Projects update successfully started. '
                'And sending out e-mail with the results.')

        list_params = params.copy()
        list_params['logic'] = record_logic
        list_params['list_heading'] = params['records_heading_template']
        list_params['list_row'] = params['records_row_template']
        list_params['public_row_extra'] = lambda entity: {
            'link': redirects.getEditGradingRecordRedirect(
                entity, list_params)
        }
        # TODO(LIST)
        fields = {'grading_survey_group': entity}

        # list all records with grading_decision set to pass
        fields['grade_decision'] = 'pass'

        # get the list content for passing records
        pr_params = list_params.copy()
        pr_params['list_description'] = \
            'List of all Records which have their grading outcome set to pass.'
        pr_list = lists.getListContent(request, pr_params, fields, idx=0)

        # list all records with grading_decision set to fail
        fields['grade_decision'] = 'fail'

        # get the list content for all failing records
        fr_params = list_params.copy()
        fr_params['list_description'] = \
            'List of all Records which have their grading outcome set to fail.'
        fr_list = lists.getListContent(request, fr_params, fields, idx=1)

        # list all records with grading decision set to undecided
        fields['grade_decision'] = 'undecided'

        # get the list content for all undecided records
        ur_params = list_params.copy()
        ur_params['list_description'] = \
            'List of all Records which have their grading outcome set to undecided.'
        ur_list = lists.getListContent(request, ur_params, fields, idx=2)

        # specify the contents and create a Lists object for use in the context
        contents = [pr_list, fr_list, ur_list]
        context['list'] = lists_logic.Lists(contents)

        return responses.respond(request, template, context)
Exemple #45
0
    def manage(self,
               request,
               access_type,
               page_name=None,
               params=None,
               **kwargs):
        """Handles the request concerning the view that let's 
       you manage a role's status.

    Args:
      request: the standard Django HTTP request object
      page_name: the page name displayed in templates as page and header title
      params: a dict with params for this View
      kwargs: the Key Fields for the specified entity
    """

        # get the context for this webpage
        context = responses.getUniversalContext(request)
        responses.useJavaScript(context, params['js_uses_all'])
        context['page_name'] = page_name

        logic = params['logic']

        # get the entity for the given fields in kwargs
        fields = {
            'scope_path': kwargs['scope_path'],
            'link_id': kwargs['link_id']
        }
        role_entity = logic.getForFields(kwargs, unique=True)

        # get the redirect for the cancel button or when the resignation is done
        redirect = params['manage_redirect'](role_entity.scope,
                                             params['group_view'].getParams())

        # check to see if resign is true
        get_dict = request.GET
        resign = get_dict.get('resign')

        if resign == 'true':

            resign_error = params['logic'].canResign(role_entity)

            if not resign_error:
                # change the status of this role_entity to invalid
                fields = {'status': 'invalid'}
                logic.updateEntityProperties(role_entity, fields)

                # redirect to the roles listing
                return http.HttpResponseRedirect(redirect)
            else:
                # show error to the user
                context['resign_error'] = ugettext(resign_error % params)

        # set the appropriate context
        context['entity'] = role_entity
        context['url_name'] = params['url_name']
        context['cancel_redirect'] = redirect

        # get the manage template
        template = params['manage_template']

        # return a proper response
        return responses.respond(request, template, context=context)
Exemple #46
0
class View(survey_view.View):
    """View methods for the ProjectSurvey 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
    """

        new_params = {}
        new_params['logic'] = org_app_logic

        new_params['name'] = "Org Application Survey"
        new_params['url_name'] = 'org_app'

        new_params['extra_dynaexclude'] = ['taking_access']

        new_params['survey_take_form'] = OrgAppSurveyForm
        new_params['survey_record_form'] = OrgAppRecordForm

        new_params['extra_django_patterns'] = [
            (r'^%(url_name)s/(?P<access_type>list_self)/%(key_fields)s$',
             '%(module_package)s.%(module_name)s.list_self',
             'Overview of %(name_plural)s Taken by You'),
            (r'^%(url_name)s/(?P<access_type>review)/%(key_fields)s$',
             '%(module_package)s.%(module_name)s.review',
             'Review %(name)s from '),
            (r'^%(url_name)s/(?P<access_type>review_overview)/%(key_fields)s$',
             '%(module_package)s.%(module_name)s.review_overview',
             'Overview of %(name_plural)s for Review')
        ]

        new_params['review_template'] = 'soc/org_app_survey/review.html'

        new_params['successful_take_message'] = ugettext(
            'Organization Application submitted.')

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

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

        # create the form to review an Organization Application
        dynaproperties = {
            'status':
            forms.fields.ChoiceField(required=True,
                                     label='New Status',
                                     choices=[
                                         ('accepted', 'Accept'),
                                         ('pre-accepted', 'Pre-Accept'),
                                         ('rejected', 'Reject'),
                                         ('pre-rejected', 'Pre-Reject'),
                                         ('ignored', 'Ignore'),
                                     ])
        }

        review_form = dynaform.newDynaForm(
            dynabase=self._params['dynabase'],
            dynaproperties=dynaproperties,
        )

        self._params['review_form'] = review_form

        # define the params for the OrgAppSurveyRecord listing
        record_list_params = {}
        record_list_params['logic'] = self._params['logic'].getRecordLogic()
        record_list_params['js_uses_all'] = self._params['js_uses_all']
        record_list_params['list_template'] = self._params['list_template']

        # define the fields for the public list
        record_list_params['public_field_keys'] = ['name', 'home_page']
        record_list_params['public_field_names'] = ['Name', 'Home Page']
        record_list_params['public_field_extra'] = lambda entity: {
            'home_page': lists.urlize(entity.home_page, 'Click Here'),
        }

        # define the fields for the self list
        record_list_params['self_field_keys'] = [
            'name', 'main_admin', 'backup_admin'
        ]
        record_list_params['self_field_names'] = [
            'Organization Name', 'Main Admin', 'Backup Admin'
        ]
        record_list_params['self_field_prefetch'] = [
            'main_admin', 'backup_admin'
        ]
        record_list_params['self_field_extra'] = lambda entity: {
            'main_admin': entity.main_admin.name,
            'backup_admin': entity.backup_admin.name
        }
        record_list_params['self_row_action'] = {
            "type": "redirect_custom",
            "parameters": dict(new_window=False),
        }

        self._params['record_list_params'] = record_list_params

    @decorators.check_access
    def create(self,
               request,
               access_type,
               page_name=None,
               params=None,
               **kwargs):
        """Displays the create page for this entity type.

    If an OrgAppSurvey already exists it will redirect to the edit page.
    """

        params = dicts.merge(params, self._params)
        program_view = params['scope_view']
        program_logic = program_view.getParams()['logic']

        program_entity = program_logic.getFromKeyName(kwargs['scope_path'])
        org_app = org_app_logic.getForProgram(program_entity)

        if org_app:
            # redirect to edit page
            return http.HttpResponseRedirect(
                redirects.getEditRedirect(org_app, params))
        else:
            # show create page
            return super(View, self).create(request,
                                            access_type,
                                            page_name=page_name,
                                            params=params,
                                            **kwargs)

    def _getSurveyRecordFor(self, survey, request, params):
        """Returns the SurveyRecord for the given Survey and request.

    This method also take the ID specified as GET param into
    account when querying for the SurveyRecord.

    For params see survey.View._getSurveyRecordFor().
    """

        get_dict = request.GET
        record_id = get_dict.get('id', None)

        survey_logic = params['logic']
        record_logic = survey_logic.getRecordLogic()

        if not record_id or not record_id.isdigit():
            return None
        else:
            return record_logic.getFromIDOr404(int(record_id))

    def _takeGet(self, request, template, context, params, entity, record,
                 **kwargs):
        """Hooking into the view for the take's page GET request.

    For params see survey.View._takeGet().
    """

        # the form action should contain the requested record
        if record:
            context['form_action'] = "?id=%s" % (request.GET['id'])

    def _takePost(self, request, params, entity, record, properties):
        """Hook into the view for the take's page POST request.

    For params see survey.View._takePost().
    """

        from soc.logic.models.user import logic as user_logic

        if not record:
            # creating a new record
            user_entity = user_logic.getCurrentUser()
            properties['main_admin'] = user_entity

            if properties['agreed_to_tos']:
                properties['agreed_to_admin_agreement'] = True

        # remove fields we don't need to store in the SurveyRecord
        properties.pop('tos')
        properties.pop('agreed_to_tos')

    def _getRedirectOnSuccessfulTake(self, request, params, survey, record):
        """Returns a path to which the user should be redirected after successfully
    taking a OrgAppSurvey.
    """

        new_params = params['take_params']
        new_params['id'] = str(record.key().id_or_name())

        return requests.replaceSuffix(request.path, None, params=new_params)

    @decorators.merge_params
    @decorators.check_access
    def listSelf(self,
                 request,
                 access_type,
                 page_name=None,
                 params=None,
                 **kwargs):
        """View that lists all the OrgAppRecords you have access to.

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

        survey_logic = params['logic']

        entity = survey_logic.getFromKeyFieldsOr404(kwargs)

        list_params = params['record_list_params'].copy()

        if timeline_helper.isActivePeriod(entity, 'survey'):
            info = {'url_name': params['url_name'], 'survey': entity}
            list_params['self_row_extra'] = lambda entity: {
                'link': redirects.getRetakeOrgAppSurveyRedirect(entity, info)
            }
        else:
            list_params['self_row_extra'] = lambda entity: {
                'link': redirects.getViewSurveyRecordRedirect(entity, params)
            }

        ma_params = list_params.copy()
        ma_params['list_description'] = \
            'List of Applications for which you are Main Admin.'

        ba_params = list_params.copy()
        ba_params['list_description'] = \
            'List of Applications for which your are Backup Admin.'

        if lists.isDataRequest(request):
            return self._getListSelfData(request, entity, ma_params, ba_params)

        ma_list = lists.getListGenerator(request,
                                         ma_params,
                                         visibility='self',
                                         idx=0)
        ba_list = lists.getListGenerator(request,
                                         ba_params,
                                         visibility='self',
                                         idx=1)

        contents = [ma_list, ba_list]

        return self._list(request, list_params, contents, page_name)

    def _getListSelfData(self, request, entity, ma_params, ba_params):
        """Returns the listSelf data.
    """
        from soc.logic.models.user import logic as user_logic

        user_entity = user_logic.getCurrentUser()

        idx = lists.getListIndex(request)

        if idx == 0:
            fields = {'survey': entity, 'main_admin': user_entity}
            params = ma_params
        elif idx == 1:
            fields = {'survey': entity, 'backup_admin': user_entity}
            params = ba_params
        else:
            return lists.getErrorResponse(request, "idx not valid")

        contents = lists.getListData(request,
                                     params,
                                     fields,
                                     visibility='self')

        return lists.getResponse(request, contents)

    def processSaveReview(self, json):
        """Processes a save request from the reviewOverview page.
    """

        data = simplejson.loads(json)

        records = []

        for record_id, update in data.iteritems():
            if not record_id.isnumeric():
                logging.error("Non-numeric record_id %s in %s", record_id,
                              json)
                continue

            record = org_app_record.OrgAppRecord.get_by_id(int(record_id))
            if not record:
                logging.error("No record for id %s in %s", record_id, json)
                continue

            new_value = update.get('status', '').lower()
            if not new_value in org_app_record.OrgAppRecord.status.choices:
                logging.error("Invalid new value for id %s in %s", new_value,
                              json)
                continue

            record.status = new_value
            records.append(record)

        db.put(records)

    @decorators.merge_params
    @decorators.check_access
    def reviewOverview(self,
                       request,
                       access_type,
                       page_name=None,
                       params=None,
                       **kwargs):
        """Displays a list of applications that are in a different
    status of the application process.
    """
        survey_logic = params['logic']

        entity = survey_logic.getFromKeyFieldsOr404(kwargs)

        if request.POST:
            # POST request received, check and respond to button actions
            post_dict = request.POST

            if post_dict.get('button_id') == 'bulk_process':
                params['bulk_process_task'].start(entity.scope)

            if post_dict.get(
                    'button_id') == 'save_status' and 'data' in request.POST:
                self.processSaveReview(request.POST['data'])

            return http.HttpResponse()

        list_params = params['record_list_params'].copy()
        list_params['list_description'] = (
            'List of all the Organization Applications made to the %s program. '
            'Click an application to review it, or use the buttons on the top of '
            'the list for bulk actions.' % (entity.scope.name))

        info = {'url_name': params['url_name'], 'survey': entity}
        choices = org_app_record.OrgAppRecord.status.choices
        values = ";".join("%s:%s" % (i, i.capitalize()) for i in choices)

        list_params['overview_field_props'] = {
            'status': {
                'editable': True,
                'edittype': "select",
                'editoptions': {
                    'value': values
                }
            }
        }

        # define the basic fields for the overview list
        list_params['overview_field_keys'] = [
            'name',
            'home_page',
            'details',
            'status',
        ]
        list_params['overview_field_names'] = [
            'Organization Name',
            'Home Page',
            'Details',
            'Application Status',
        ]
        list_params['overview_field_extra'] = lambda entity: {
            'home_page':
            lists.urlize(entity.home_page),
            'status':
            entity.status.capitalize(),
            'details':
            lists.urlize(redirects.getReviewOrgAppSurvey(entity, info),
                         name="[details]"),
        }
        list_params['overview_button_global'] = [
            {
                'bounds': [0, 'all'],
                'id': 'bulk_process',
                'caption': 'Bulk Accept/Reject Organizations',
                'type': 'post',
                'parameters': {
                    'url': ''
                },
            },
            {
                'id': 'save_status',
                'caption': 'Save status',
                'type': 'post_edit',
                'parameters': {
                    'url': '',
                    'keys': ['key'],
                    'refresh': 'current',
                },
            },
        ]

        list_params['overview_row_action'] = {
            "type": "redirect_custom",
            "parameters": dict(new_window=False),
        }

        self._extendListWithSurveyAnswers(list_params, entity, 'overview')

        if lists.isDataRequest(request):
            # get all records for the entity specified in the URL
            fields = {'survey': entity}
            # use the overview visibility to show the correct columns to the Host
            contents = lists.getListData(request,
                                         list_params,
                                         fields,
                                         visibility='overview')

            return lists.getResponse(request, contents)

        overview_list = lists.getListGenerator(request,
                                               list_params,
                                               visibility='overview',
                                               idx=0)
        contents = [overview_list]

        return self._list(request, list_params, contents, page_name)

    @decorators.merge_params
    @decorators.check_access
    def review(self,
               request,
               access_type,
               page_name=None,
               params=None,
               **kwargs):
        """View that lists a OrgAppSurveyRecord to be reviewed.

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

        survey_logic = params['logic']
        record_logic = survey_logic.getRecordLogic()

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

        get_dict = request.GET
        record_id = get_dict.get('id')

        if record_id and record_id.isdigit():
            record_id = int(record_id)
            record_entity = record_logic.getFromIDOr404(record_id)
        else:
            raise out_of_band.Error('No valid Record ID given')

        if record_entity.survey.key() != survey_entity.key():
            # record does not match the retrieved survey
            raise out_of_band.Error(
                'Record ID does not match the given survey')

        # get the context for this webpage
        context = responses.getUniversalContext(request)
        responses.useJavaScript(context, params['js_uses_all'])
        context['page_name'] = '%s %s' % (page_name, record_entity.name)
        context['entity'] = survey_entity
        context['record'] = record_entity

        # store the read only survey form in the context
        survey_form = params['survey_record_form'](
            survey=survey_entity,
            survey_record=record_entity,
            survey_logic=self._params['logic'],
            read_only=True)
        survey_form.getFields()
        context['survey_form'] = survey_form

        if request.POST:
            return self.reviewPost(request, params, context, survey_entity,
                                   record_entity)
        else:
            return self.reviewGet(request, params, context, survey_entity,
                                  record_entity)
class View(survey_view.View):
    """View methods for the ProjectSurvey 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
    """

        new_params = {}
        new_params['logic'] = org_app_logic

        new_params['name'] = "Org Application Survey"
        new_params['url_name'] = 'org_app'

        new_params['extra_dynaexclude'] = ['taking_access']

        new_params['survey_take_form'] = OrgAppSurveyForm
        new_params['survey_record_form'] = OrgAppRecordForm

        new_params['extra_django_patterns'] = [
            (r'^%(url_name)s/(?P<access_type>list_self)/%(key_fields)s$',
             '%(module_package)s.%(module_name)s.list_self',
             'Overview of %(name_plural)s Taken by You'),
        ]

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

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

    @decorators.check_access
    def create(self,
               request,
               access_type,
               page_name=None,
               params=None,
               **kwargs):
        """Displays the create page for this entity type.

    If an OrgAppSurvey already exists it will redirect to the edit page.
    """

        params = dicts.merge(params, self._params)
        program_view = params['scope_view']
        program_logic = program_view.getParams()['logic']

        program_entity = program_logic.getFromKeyName(kwargs['scope_path'])
        org_app = org_app_logic.getForProgram(program_entity)

        if org_app:
            # redirect to edit page
            return http.HttpResponseRedirect(
                redirects.getEditRedirect(org_app, params))
        else:
            # show create page
            return super(View, self).create(request,
                                            access_type,
                                            page_name=page_name,
                                            params=params,
                                            **kwargs)

    def _getSurveyRecordFor(self, survey, request, params):
        """Returns the SurveyRecord for the given Survey and request.

    This method also take the ID specified as GET param into
    account when querying for the SurveyRecord.

    For params see survey.View._getSurveyRecordFor().
    """

        get_dict = request.GET
        record_id = get_dict.get('id', None)

        survey_logic = params['logic']
        record_logic = survey_logic.getRecordLogic()

        if not record_id or not record_id.isdigit():
            return None
        else:
            return record_logic.getFromIDOr404(int(record_id))

    def _takeGet(self, request, template, context, params, entity, record,
                 **kwargs):
        """Hooking into the view for the take's page GET request.

    For params see survey.View._takeGet().
    """

        # the form action should contain the requested record
        if record:
            context['form_action'] = "?id=%s" % (request.GET['id'])

    def _takePost(self, request, params, entity, record, properties):
        """Hook into the view for the take's page POST request.

    For params see survey.View._takePost().
    """

        from soc.logic.models.user import logic as user_logic

        if not record:
            # creating a new record
            user_entity = user_logic.getForCurrentAccount()
            properties['main_admin'] = user_entity

            if properties['agreed_to_tos']:
                properties['agreed_to_admin_agreement'] = True

        # remove fields we don't need to store in the SurveyRecord
        properties.pop('tos')
        properties.pop('agreed_to_tos')

    def _getRedirectOnSuccessfulTake(self, request, params, survey, record):
        """Returns a path to which the user should be redirected after successfully
    taking a OrgAppSurvey.
    """
        return request.path + '?id=' + str(record.key().id_or_name())

    @decorators.merge_params
    @decorators.check_access
    def list_self(self,
                  request,
                  access_type,
                  page_name=None,
                  params=None,
                  **kwargs):
        """View that lists all the OrgRecords you have access to.

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

        from soc.logic.models.user import logic as user_logic

        survey_logic = params['logic']
        record_logic = survey_logic.getRecordLogic()

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

        # get the context for this webpage
        context = responses.getUniversalContext(request)
        responses.useJavaScript(context, params['js_uses_all'])
        context['entity'] = entity

        list_contents = []
        user_entity = user_logic.getForCurrentAccount()

        list_params = params.copy()
        list_params['logic'] = record_logic
        list_params[
            'list_heading'] = 'soc/org_app_survey/list/records_heading.html'
        list_params['list_row'] = 'soc/org_app_survey/list/records_row.html'

        if timeline_helper.isActivePeriod(entity, 'survey'):
            info = {'url_name': list_params['url_name'], 'survey': entity}
            list_params['public_row_extra'] = lambda entity: {
                'link': redirects.getRetakeOrgAppSurveyRedirect(entity, info)
            }
        else:
            list_params['public_row_extra'] = lambda entity: {
                'link': redirects.getViewSurveyRecordRedirect(
                    entity, list_params)
            }

        fields = {'survey': entity, 'main_admin': user_entity}
        list_params['list_description'] = \
            'List of Applications for which you are Main Admin.'
        main_list = lists.getListContent(request,
                                         list_params,
                                         fields,
                                         need_content=True,
                                         idx=0)
        # TODO(LIST)
        if main_list:
            list_contents.append(main_list)

        fields = {'survey': entity, 'backup_admin': user_entity}
        list_params['list_description'] = \
            'List of Applications for which your are Backup Admin.'
        backup_list = lists.getListContent(request,
                                           list_params,
                                           fields,
                                           need_content=True,
                                           idx=1)

        if backup_list:
            list_contents.append(backup_list)

        return self._list(request, list_params, list_contents, page_name,
                          context)
Exemple #48
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)
Exemple #49
0
  def manageOverview(self, request, access_type,
             page_name=None, params=None, **kwargs):
    """View that allows Organization Admins to see an overview of 
       their Organization's Student Projects.

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

    # make sure the organization exists
    org_entity = org_logic.getFromKeyNameOr404(kwargs['scope_path'])
    fields = {'scope': org_entity}

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

    list_params = params.copy()

    #list all active projects
    fields['status'] = ['accepted', 'mid_term_passed']
    active_params = list_params.copy()
    active_params['list_description'] = \
        'List of all active %(name_plural)s' % list_params
    active_params['list_action'] = (redirects.getManageRedirect, list_params)

    active_list = lists.getListContent(
        request, active_params, fields, idx=0)

    # list all failed projects
    fields['status'] = ['mid_term_failed', 'final_failed']
    failed_params = list_params.copy()
    failed_params['list_description'] = ('List of all failed %(name_plural)s, '
        'these cannot be managed.') % list_params
    failed_params['list_action'] = (redirects.getPublicRedirect, list_params)

    failed_list = lists.getListContent(
        request, failed_params, fields, idx=1, need_content=True)

    #list all completed projects
    fields['status'] = ['passed']
    completed_params = list_params.copy()
    completed_params['list_description'] = ('List of %(name_plural)s that have '
        'successfully completed the program, '
        'these cannot be managed.' % list_params)
    completed_params['list_action'] = (redirects.getPublicRedirect, list_params)

    completed_list = lists.getListContent(
        request, completed_params, fields, idx=2, need_content=True)

    # always show the list with active projects
    content = [active_list]

    if failed_list != None:
      # do not show empty failed list
      content.append(failed_list)

    if completed_list != None:
      # do not show empty completed list
      content.append(completed_list)

    # call the _list method from base to display the list
    return self._list(request, list_params, content,
                      context['page_name'], context)
Exemple #50
0
  @decorators.check_access
  def stEdit(self, request, access_type,
             page_name=None, params=None, **kwargs):
    """View that allows students to edit information about their project.

    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'])

    # get the context for this webpage
    context = responses.getUniversalContext(request)
    responses.useJavaScript(context, params['js_uses_all'])
    context['page_name'] = page_name
    # cancel should go to the public view
    params['edit_cancel_redirect'] = redirects.getPublicRedirect(entity, params)

    if request.POST:
      return self.stEditPost(request, context, params, entity, **kwargs)
    else: #request.GET
      return self.stEditGet(request, context, params, entity, **kwargs)

  def stEditGet(self, request, context, params, entity, **kwargs):
    """Handles the GET request for the student's edit page.

    Args:
        entity: the student project entity
Exemple #51
0
class View(base.View):
    """View methods for the Survey 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.Checker(params)
        rights['any_access'] = ['allow']
        rights['show'] = [('checkIsSurveyWritable', survey_logic)]
        rights['create'] = ['checkIsUser']
        rights['edit'] = [('checkIsSurveyWritable', survey_logic)]
        rights['delete'] = ['checkIsDeveloper'
                            ]  # TODO: fix deletion of Surveys
        rights['list'] = ['checkDocumentList']
        rights['pick'] = ['checkDocumentPick']
        rights['record'] = [('checkHasAny', [[
            ('checkIsSurveyReadable', [survey_logic]),
            ('checkIsMySurveyRecord', [survey_logic, 'id'])
        ]])]
        rights['results'] = ['checkIsUser']
        rights['take'] = [('checkIsSurveyTakeable', survey_logic)]

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

        new_params['name'] = 'Survey'
        new_params['sidebar_grouping'] = "Surveys"

        new_params['extra_django_patterns'] = [
            (r'^%(url_name)s/(?P<access_type>take)/%(key_fields)s$',
             '%(module_package)s.%(module_name)s.take', 'Take %(name)s'),
            (r'^%(url_name)s/(?P<access_type>json)/%(scope)s$',
             '%(module_package)s.%(module_name)s.json',
             'Export %(name)s as JSON'),
            (r'^%(url_name)s/(?P<access_type>record)/%(key_fields)s$',
             '%(module_package)s.%(module_name)s.record',
             'View survey record for %(name)s'),
            (r'^%(url_name)s/(?P<access_type>results)/%(key_fields)s$',
             '%(module_package)s.%(module_name)s.results',
             'View survey results for %(name)s'),
            (r'^%(url_name)s/(?P<access_type>show)/user/(?P<link_id>)\w+$',
             '%(module_package)s.%(module_name)s.results',
             'View survey results for user'),
        ]

        new_params['export_content_type'] = 'text/text'
        new_params['export_extension'] = '.csv'
        new_params['export_function'] = surveys.toCSV(self)
        new_params['delete_redirect'] = '/'

        new_params['edit_template'] = 'soc/survey/edit.html'
        new_params['create_template'] = 'soc/survey/edit.html'
        new_params['public_template'] = 'soc/survey/public.html'
        new_params['record_template'] = 'soc/survey/view_record.html'
        new_params['take_template'] = 'soc/survey/take.html'

        new_params['no_create_raw'] = True
        new_params['no_create_with_scope'] = True
        new_params['no_create_with_key_fields'] = True
        new_params['no_list_raw'] = True
        new_params['sans_link_id_create'] = True
        new_params['sans_link_id_list'] = True

        new_params['create_dynafields'] = [
            {
                'name': 'link_id',
                'base': forms.fields.CharField,
                'label': 'Survey Link ID',
            },
        ]

        new_params['create_extra_dynaproperties'] = {
            'content':
            forms.fields.CharField(required=False,
                                   label='Description',
                                   widget=widgets.FullTinyMCE(attrs={
                                       'rows': 25,
                                       'cols': 100
                                   })),
            'survey_html':
            forms.fields.CharField(widget=forms.HiddenInput, required=False),
            'scope_path':
            forms.fields.CharField(widget=forms.HiddenInput, required=True),
            'prefix':
            forms.fields.CharField(widget=widgets.ReadOnlyInput(),
                                   required=True),
            'clean_content':
            cleaning.clean_html_content('content'),
            'clean_link_id':
            cleaning.clean_link_id('link_id'),
            'clean_scope_path':
            cleaning.clean_scope_path('scope_path'),
            'clean':
            cleaning.validate_document_acl(self, True),
        }

        new_params['extra_dynaexclude'] = [
            'author', 'created', 'home_for', 'modified_by', 'modified',
            'take_survey', 'survey_content'
        ]

        new_params['edit_extra_dynaproperties'] = {
            'doc_key_name':
            forms.fields.CharField(widget=forms.HiddenInput),
            'created_by':
            forms.fields.CharField(widget=widgets.ReadOnlyInput(),
                                   required=False),
            'last_modified_by':
            forms.fields.CharField(widget=widgets.ReadOnlyInput(),
                                   required=False),
            'clean':
            cleaning.validate_document_acl(self),
        }

        new_params['survey_take_form'] = surveys.SurveyTakeForm
        new_params['survey_record_form'] = surveys.SurveyRecordForm

        new_params['public_field_prefetch'] = ['author']
        new_params['public_field_extra'] = lambda entity: {
            "path": entity.scope_path + '/' + entity.link_id,
            "created_by": entity.author.link_id,
        }
        new_params['public_field_keys'] = [
            "path", "title", "link_id", "is_featured", "created_by", "created",
            "modified"
        ]
        new_params['public_field_names'] = [
            "Path",
            "Title",
            "Link ID",
            "Featured",
            "Created By",
            "Created On",
            "Modified",
        ]

        new_params['records_field_keys'] = ['taken_by', 'modified']
        new_params['records_field_names'] = [
            'Taken By',
            'Taken On',
        ]
        new_params['records_field_prefetch'] = ['user']
        new_params['records_field_extra'] = lambda entity: {
            'taken_by': '%s (%s)' % (entity.user.name, entity.user.link_id),
        }

        new_params['take_params'] = {'s': '0'}

        new_params['successful_take_message'] = ugettext(
            'Survey record submitted.')

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

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

    def list(self,
             request,
             access_type,
             page_name=None,
             params=None,
             filter=None,
             order=None,
             **kwargs):
        """See base.View.list.
    """

        if not filter:
            filter = kwargs

        return super(View, self).list(request,
                                      access_type,
                                      page_name=page_name,
                                      params=params,
                                      filter=filter,
                                      **kwargs)

    def _public(self, request, entity, context):
        """Add a preview version of the Survey to the page's context.

    Args:
      request: the django request object
      entity: the entity to make public
      context: the context object
    """

        # construct the form to be shown on the page
        # TODO(ljvderijk) Generate SurveyForm without passing along the logic
        survey_form = self._params['survey_take_form'](
            survey=entity, survey_logic=self._params['logic'])

        survey_form.getFields()

        context['survey_form'] = survey_form

        context['page_name'] = "%s titled '%s'" % (context['page_name'],
                                                   entity.title)

        # return True to signal that the page may be displayed
        return True

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

    Processes POST request items to add new dynamic field names,
    question types, and default prompt values to SurveyContent model.
    """

        user = user_logic.getCurrentUser()
        schema = {}
        survey_fields = {}

        if not entity:
            # new Survey
            if 'serialized' in request.POST:
                fields, schema, survey_fields = self.importSerialized(
                    request, fields, user)
            fields['author'] = user
        else:
            fields['author'] = entity.author
            schema = self.loadSurveyContent(schema, survey_fields, entity)

        # remove deleted properties from the model
        self.deleteQuestions(schema, survey_fields, request.POST)

        # add new text questions and re-build choice questions
        self.getRequestQuestions(schema, survey_fields, request.POST)

        # get schema options for choice questions
        self.getSchemaOptions(schema, survey_fields, request.POST)

        survey_content = getattr(entity, 'survey_content', None)
        # create or update a SurveyContent for this Survey
        survey_content = survey_logic.createSurvey(
            survey_fields, schema, survey_content=survey_content)

        # save survey_content for existent survey or pass for creating a new one
        if entity:
            entity.modified_by = user
            entity.survey_content = survey_content
            db.put(entity)
        else:
            fields['survey_content'] = survey_content

        fields['modified_by'] = user

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

    def loadSurveyContent(self, schema, survey_fields, entity):
        """Populate the schema dict and get text survey questions.
    """

        if hasattr(entity, 'survey_content'):

            # there is a SurveyContent already
            survey_content = entity.survey_content
            schema = eval(survey_content.schema)

            for question_name in survey_content.dynamic_properties():

                # get the current questions from the SurveyContent
                if question_name not in schema:
                    continue

                if schema[question_name]['type'] not in DEF_CHOICE_TYPES:
                    # Choice questions are always regenerated from request, see
                    # self.get_request_questions()
                    question = getattr(survey_content, question_name)
                    survey_fields[question_name] = question

        return schema

    def deleteQuestions(self, schema, survey_fields, POST):
        """Process the list of questions to delete, from a hidden input.
    """

        deleted = POST.get('__deleted__', '')

        if deleted:
            deleted = deleted.split(',')
            for field in deleted:

                if field in schema:
                    del schema[field]

                if field in survey_fields:
                    del survey_fields[field]

    def getRequestQuestions(self, schema, survey_fields, POST):
        """Get fields from request.

    We use two field/question naming and processing schemes:
      - Choice questions consist of <input/>s with a common name, being rebuilt
        anew on every edit POST so we can gather ordering, text changes,
        deletions and additions.
      - Text questions only have special survey__* names on creation, afterwards
        they are loaded from the SurveyContent dynamic properties.
    """

        for key, value in POST.items():

            if key.startswith('id_'):
                # Choice question fields, they are always generated from POST contents,
                # as their 'content' is editable and they're reorderable. Also get
                # its field index for handling reordering fields later.
                name, number = key[3:].replace('__field', '').rsplit('_', 1)

                if name not in schema:
                    if 'NEW_' + name in POST:
                        # new Choice question, set generic type and get its index
                        schema[name] = {'type': 'choice'}

                if name in schema and schema[name]['type'] in DEF_CHOICE_TYPES:
                    # build an index:content dictionary
                    if name in survey_fields:
                        if value not in survey_fields[name]:
                            survey_fields[name][int(number)] = value
                    else:
                        survey_fields[name] = {int(number): value}

            elif key.startswith('survey__'):  # Text question
                # this is super ugly but unless data is serialized the regex is needed
                prefix = re.compile('survey__([0-9]{1,3})__')
                prefix_match = re.match(prefix, key)

                index = prefix_match.group(0).replace('survey',
                                                      '').replace('__', '')
                index = int(index)

                field_name = prefix.sub('', key)
                field = 'id_' + key

                for ptype in DEF_PROPERTY_TYPES:
                    # should only match one
                    if ptype + "__" in field_name:
                        field_name = field_name.replace(ptype + "__", "")
                        if field_name not in schema:
                            schema[field_name] = {}
                        schema[field_name]["index"] = index
                        schema[field_name]["type"] = ptype

                # store text question tooltip from the input/textarea value
                schema[field_name]["tip"] = value

                # add the question as a dynamic property to survey_content
                survey_fields[field_name] = value

    def getSchemaOptions(self, schema, survey_fields, POST):
        """Get question, type, rendering and option order for choice questions.
    """

        RENDER = {
            'checkboxes': 'multi_checkbox',
            'select': 'single_select',
            'radio_buttons': 'quant_radio'
        }

        RENDER_TYPES = {
            'select': 'selection',
            'checkboxes': 'pick_multi',
            'radio_buttons': 'pick_quant'
        }

        for key in schema:
            if schema[key]['type'] in DEF_CHOICE_TYPES and key in survey_fields:
                render_for = 'render_for_' + key
                if render_for in POST:
                    schema[key]['render'] = RENDER[POST[render_for]]
                    schema[key]['type'] = RENDER_TYPES[POST[render_for]]

                # set the choice question's tooltip
                tip_for = 'tip_for_' + key
                schema[key]['tip'] = POST.get(tip_for)

                # handle reordering fields
                ordered = False
                order = 'order_for_' + key
                if order in POST and isinstance(survey_fields[key], dict):
                    order = POST[order]

                    # 'order_for_name' is jquery serialized from a sortable, so it's in
                    # a 'name[]=1&name[]=2&name[]=0' format ('id-li-' is set in our JS)
                    order = order.replace('id-li-%s[]=' % key, '')
                    order = order.split('&')

                    if len(order) == len(survey_fields[key]) and order[0]:
                        order = [int(number) for number in order]

                        if set(order) == set(survey_fields[key]):
                            survey_fields[key] = [
                                survey_fields[key][i] for i in order
                            ]
                            ordered = True

                    if not ordered:
                        # we don't have a good ordering to use
                        ordered = sorted(survey_fields[key].items())
                        survey_fields[key] = [
                            value for index, value in ordered
                        ]

            # set 'question' entry (free text label for question) in schema
            question_for = 'NEW_' + key
            if question_for in POST and POST[question_for]:
                schema[key]["question"] = POST[question_for]

            # set wheter the question is required
            required_for = 'required_for_' + key
            schema[key]['required'] = DEF_BOOL[POST[required_for]]

            # set wheter the question allows comments
            comment_for = 'comment_for_' + key
            schema[key]['has_comment'] = DEF_BOOL[POST[comment_for]]

            # set the question index from JS-calculated value
            index_for = 'index_for_' + key
            if index_for in POST:
                schema[key]['index'] = int(POST[index_for].replace('__', ''))

    def createGet(self, request, context, params, seed):
        """Pass the question types for the survey creation template.
    """

        context['question_types'] = DEF_QUESTION_TYPES

        # avoid spurious results from showing on creation
        context['new_survey'] = True
        return super(View, self).createGet(request, context, params, seed)

    def editGet(self, request, entity, context, params=None):
        """Process GET requests for the specified entity.

    Builds the SurveyForm that represents the Survey question contents.
    """

        self._entity = entity
        survey_content = entity.survey_content

        survey_form = surveys.SurveyEditForm(survey_content=survey_content,
                                             survey_logic=params['logic'])
        survey_form.getFields()

        local = dict(survey_form=survey_form,
                     question_types=DEF_QUESTION_TYPES,
                     survey_h=entity.survey_content)
        context.update(local)

        params['edit_form'] = surveys.HelperForm(params['edit_form'])
        if entity.survey_end and datetime.datetime.now() > entity.survey_end:
            # are we already passed the survey_end?
            context["passed_survey_end"] = True

        return super(View, self).editGet(request,
                                         entity,
                                         context,
                                         params=params)

    @decorators.merge_params
    @decorators.check_access
    def take(self,
             request,
             access_type,
             page_name=None,
             params=None,
             **kwargs):
        """View for taking a Survey.

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

        survey_logic = params['logic']

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

        template = params['take_template']

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

        # try to get an existing SurveyRecord for the current user
        survey_record = self._getSurveyRecordFor(entity, request, params)
        post_dict = request.POST

        # get an instance of SurveyTakeForm to use
        survey_form = params['survey_take_form'](survey=entity,
                                                 survey_record=survey_record,
                                                 survey_logic=params['logic'],
                                                 data=post_dict)

        # fill context with the survey_form and additional information
        context['survey_form'] = survey_form

        self._setSurveyTakeContext(request, params, context, entity,
                                   survey_record)

        if request.POST:
            return self.takePost(request, template, context, params,
                                 survey_form, entity, survey_record, **kwargs)
        else:  #request.GET
            return self.takeGet(request, template, context, params,
                                survey_form, entity, survey_record, **kwargs)