def as_proposal_duplicates(context, proposal_duplicate):
  """Returns a HTML representation of a proposal duplicates.
  """

  context['student'] =  proposal_duplicate.student
  orgs = db.get(proposal_duplicate.orgs)
  proposals = db.get(proposal_duplicate.duplicates)

  orgs_details = {}
  for org in orgs:
    orgs_details[org.key().id_or_name()] = {
        'name': org.name
        }
    fields = {'scope': org,
              'status': 'active'}
    org_admins = org_admin_logic.getForFields(fields)

    orgs_details[org.key().id_or_name()]['admins'] = []
    for org_admin in org_admins:
      orgs_details[org.key().id_or_name()]['admins'].append({
          'name': org_admin.name(),
          'email': org_admin.email
          })

    orgs_details[org.key().id_or_name()]['proposals'] = []
    for proposal in proposals:
      if proposal.org.key() == org.key():
        orgs_details[org.key().id_or_name()]['proposals'].append({
            'key': proposal.key().id_or_name(),
            'title': proposal.title,
            })

  context['orgs'] = orgs_details
  return context
예제 #2
0
def as_proposal_duplicates(context, proposal_duplicate):
    """Returns a HTML representation of a proposal duplicates.
  """

    context['student'] = proposal_duplicate.student
    orgs = db.get(proposal_duplicate.orgs)
    proposals = db.get(proposal_duplicate.duplicates)

    orgs_details = {}
    for org in orgs:
        orgs_details[org.key().id_or_name()] = {'name': org.name}
        fields = {'scope': org, 'status': 'active'}
        org_admins = org_admin_logic.getForFields(fields)

        orgs_details[org.key().id_or_name()]['admins'] = []
        for org_admin in org_admins:
            orgs_details[org.key().id_or_name()]['admins'].append({
                'name':
                org_admin.name(),
                'email':
                org_admin.email
            })

        orgs_details[org.key().id_or_name()]['proposals'] = []
        for proposal in proposals:
            if proposal.org.key() == org.key():
                orgs_details[org.key().id_or_name()]['proposals'].append({
                    'key':
                    proposal.key().id_or_name(),
                    'title':
                    proposal.title,
                })

    context['orgs'] = orgs_details
    return context
예제 #3
0
def _orgStatusRetriever(entity):
  """Determines a new status for a given organization based on its current
  status.

  Args:
    entity: organization entity
  """

  if entity.status in ['new', 'active']:
    return 'inactive'

  if entity.status == 'inactive':
    # check if there is an org admin for this organization
    fields = {
        'scope': entity,
        'status': ['active', 'inactive']
        }
    if org_admin_logic.getForFields(fields, unique=True):
      return 'active'
    else:
      return 'new'

  # this part of code should not be reached; it means that the status of
  # the entity should not be changed
  return entity.status
예제 #4
0
    def _getResultsViewRecordFields(self, survey, allowed_to_read):
        """Get the Results View filter for ProjectSurveyRecords.

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

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

        from soc.modules.gsoc.logic.models.org_admin import logic as \
            org_admin_logic
        from soc.modules.gsoc.logic.models.student import logic as \
            student_logic

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

        fields = {'survey': survey}

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

        student_fields = {
            'scope': program_entity,
            'user': user_entity,
            'status': ['active', 'inactive']
        }
        student_entity = student_logic.getForFields(student_fields,
                                                    unique=True)

        if student_entity:
            # just get all records for the current user
            fields['user'] = user_entity
            return fields

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

        org_admins = org_admin_logic.getForFields(org_admin_fields)

        if org_admins:
            # filter on all the organizations this user is org admin for
            organizations = []

            for org_admin in org_admins:
                organizations.append(org_admin.scope)

            # TODO: this might blow up if the user is org admin for too many orgs
            fields['org'] = organizations

        if not student_entity and not org_admins:
            # return only the surveys for the current user
            fields['user'] = user_entity

        return fields
예제 #5
0
  def _getResultsViewRecordFields(self, survey, allowed_to_read):
    """Get the Results View filter for ProjectSurveyRecords.

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

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

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

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

    fields = {'survey': survey}

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

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

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

    organizations = {}

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

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

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

    return fields
예제 #6
0
  def _getResultsViewRecordFields(self, survey, allowed_to_read):
    """Get the Results View filter for ProjectSurveyRecords.

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

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

    from soc.modules.gsoc.logic.models.org_admin import logic as \
        org_admin_logic
    from soc.modules.gsoc.logic.models.student import logic as \
        student_logic

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

    fields = {'survey': survey}

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

    student_fields = {'scope': program_entity,
                      'user': user_entity,
                      'status': ['active', 'inactive']}
    student_entity = student_logic.getForFields(student_fields, unique=True)

    if student_entity:
      # just get all records for the current user
      fields['user'] = user_entity
      return fields

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

    org_admins = org_admin_logic.getForFields(org_admin_fields)

    if org_admins:
      # filter on all the organizations this user is org admin for
      organizations = []

      for org_admin in org_admins:
        organizations.append(org_admin.scope)

      # TODO: this might blow up if the user is org admin for too many orgs
      fields['org'] = organizations

    if not student_entity and not org_admins:
      # return only the surveys for the current user
      fields['user'] = user_entity

    return fields
def as_student_proposal_review_duplicate(context, proposal):
  """Returns a HTML representation of a proposal duplicates for the Proposal
  Review page.
  """

  org_entity = proposal.org

  fields = {'scope': org_entity,
                'status': 'active'}
  org_admin_entities = org_admin_logic.getForFields(fields)

  org_admins = [(org_admin.name(), org_admin.email) 
                        for org_admin in org_admin_entities]

  context.update({'title': proposal.title,
                           'org_name': org_entity.name,
                           'org_admins': org_admins })

  return context
예제 #8
0
def as_student_proposal_review_duplicate(context, proposal):
    """Returns a HTML representation of a proposal duplicates for the Proposal
  Review page.
  """

    org_entity = proposal.org

    fields = {'scope': org_entity, 'status': 'active'}
    org_admin_entities = org_admin_logic.getForFields(fields)

    org_admins = [(org_admin.name(), org_admin.email)
                  for org_admin in org_admin_entities]

    context.update({
        'title': proposal.title,
        'org_name': org_entity.name,
        'org_admins': org_admins
    })

    return context
예제 #9
0
  def _getTimeDependentEntries(self, program_entity, params, id, user):
    """Returns a list with time dependent menu items.
    """

    items = []

    timeline_entity = program_entity.timeline

    org_app_survey = org_app_logic.getForProgram(program_entity)

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

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

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

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

      org_app_record_logic = org_app_logic.getRecordLogic()

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

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

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

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

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

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

    deadline = 'accepted_organization_announced_deadline'

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

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

    deadline = 'accepted_students_announced_deadline'

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

    return items
예제 #10
0
def sendSurveyReminderForProject(request, *args, **kwargs):
  """Sends a reminder mail for a given StudentProject and Survey.

  A reminder is only send if no record is on file for the given Survey and 
  StudentProject.

  Expects the following to be present in the POST dict:
    survey_key: specifies the key name for the ProjectSurvey to send reminders
                for
    survey_type: either project or grading depending on the type of Survey
    project_key: key which specifies the project to send a reminder for

  Args:
    request: Django Request object
  """

  from soc.logic import mail_dispatcher
  from soc.logic.models.site import logic as site_logic
  from soc.views.helper import redirects

  from soc.modules.gsoc.logic.models.org_admin import logic as org_admin_logic
  from soc.modules.gsoc.logic.models.student_project import logic as \
      student_project_logic
  from soc.modules.gsoc.logic.models.survey import grading_logic
  from soc.modules.gsoc.logic.models.survey import project_logic

  post_dict = request.POST

  project_key = post_dict.get('project_key')
  survey_key = post_dict.get('survey_key')
  survey_type = post_dict.get('survey_type')

  if not (project_key and survey_key and survey_type):
    # invalid task data, log and return OK
    return error_handler.logErrorAndReturnOK(
        'Invalid sendSurveyReminderForProject data: %s' % post_dict)

  # set logic depending on survey type specified in POST
  if survey_type == 'project':
    survey_logic = project_logic
  elif survey_type == 'grading':
    survey_logic = grading_logic

  # retrieve the project and survey
  student_project = student_project_logic.getFromKeyName(project_key)

  if not student_project:
    # no existing project found, log and return OK
    return error_handler.logErrorAndReturnOK(
        'Invalid project specified %s:' % project_key)

  survey = survey_logic.getFromKeyName(survey_key)

  if not survey:
    # no existing survey found, log and return OK
    return error_handler.logErrorAndReturnOK(
        'Invalid survey specified %s:' % survey_key)

  # try to retrieve an existing record
  record_logic = survey_logic.getRecordLogic()

  fields = {'project': student_project,
            'survey': survey}
  record_entity = record_logic.getForFields(fields, unique=True)

  if not record_entity:
    # send reminder email because we found no record

    student_entity = student_project.student
    site_entity = site_logic.getSingleton()

    if survey_type == 'project':
      survey_redirect = redirects.getTakeSurveyRedirect(
          survey,{'url_name': 'gsoc/project_survey'})
      to_role = student_entity
      mail_template = 'soc/project_survey/mail/reminder_gsoc.html'
    elif survey_type == 'grading':
      survey_redirect = redirects.getTakeSurveyRedirect(
          survey,{'url_name': 'gsoc/grading_project_survey'})
      to_role = student_project.mentor
      mail_template = 'soc/grading_project_survey/mail/reminder_gsoc.html'

    survey_url = "http://%(host)s%(redirect)s" % {
      'redirect': survey_redirect,
      'host': system.getHostname(),
      }

    # set the context for the mail template
    mail_context = {
        'student_name': student_entity.name(),
        'project_title': student_project.title,
        'survey_url': survey_url,
        'survey_end': survey.survey_end,
        'to_name': to_role.name(),
        'site_name': site_entity.site_name,
    }

    # set the sender
    (_, sender_address) = mail_dispatcher.getDefaultMailSender()
    mail_context['sender'] = sender_address
    # set the receiver and subject
    mail_context['to'] = to_role.email
    mail_context['subject'] = 'Evaluation Survey "%s" Reminder' %(survey.title)

    # find all org admins for the project's organization
    org_entity = student_project.scope

    fields = {'scope': org_entity,
              'status': 'active'}
    org_admin_entities = org_admin_logic.getForFields(fields)

    # collect email addresses for all found org admins
    org_admin_addresses = []

    for org_admin_entity in org_admin_entities:
      org_admin_addresses.append(org_admin_entity.email)

    if org_admin_addresses:
      mail_context['cc'] = org_admin_addresses

    # send out the email
    mail_dispatcher.sendMailFromTemplate(mail_template, mail_context)

  # return OK
  return http.HttpResponse()
예제 #11
0
    def checkIsAllowedToViewProjectSurveyRecordAs(self, django_args,
                                                  survey_logic, role_name,
                                                  record_key_location):
        """Checks whether the current user is allowed to view the record given in
    the GET data by the record_key_location.

    Args:
      django_args: a dictionary with django's arguments
      survey_logic: Survey Logic instance that belongs to the SurveyRecord
        type in question
      role_name: string containing either "student" or "mentor". Determines
        which of the roles the within the project the current user should have
        to view the evaluation results.
      record_key_location: string containing the name of the GET param which
        contains the id for the SurveyRecord to retrieve

    Raises:
      AccessViolation if:
        - No valid numeric Record ID is given in the POST data.
        - No Record could be retrieved for the given Record ID.
        - The current user has not taken the survey, is not the Student/Mentor
          (depending on the role_name) and is not an Org Admin for the project
          to which the SurveyRecord belongs.
    """

        if not role_name in ['mentor', 'student']:
            raise InvalidArgumentError('role_name is not mentor or student')

        self.checkIsUser(django_args)
        user_entity = self.user

        get_dict = django_args['GET']
        record_id = get_dict.get(record_key_location)

        if not record_id or not record_id.isdigit():
            raise out_of_band.AccessViolation(
                message_fmt=access.DEF_NO_VALID_RECORD_ID)
        else:
            record_id = int(record_id)

        record_logic = survey_logic.getRecordLogic()
        record_entity = record_logic.getFromIDOr404(record_id)

        if record_entity.user.key() == user_entity.key():
            # this record belongs to the current user
            return

        if role_name == 'student':
            role_entity = record_entity.project.student
        elif role_name == 'mentor':
            role_entity = record_entity.project.mentor

        if role_entity.user.key() == user_entity.key() and (
                role_entity.status in ['active', 'inactive']):
            # this user has the role required
            return

        fields = {
            'user': user_entity,
            'scope': record_entity.org,
            'status': ['active', 'inactive']
        }
        admin_entity = org_admin_logic.getForFields(fields, unique=True)

        if admin_entity:
            # this user is org admin for the retrieved record's project
            return

        # The current user is no Org Admin, has not taken the Survey and is not
        # the one responsible for taking this survey.
        raise out_of_band.AccessViolation(
            message_fmt=access.DEF_NOT_YOUR_RECORD)
예제 #12
0
    def checkRoleAndStatusForStudentProposal(self, django_args, allowed_roles,
                                             role_status, proposal_status):
        """Checks if the current user has access to the given proposal.

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

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

        self.checkIsUser(django_args)

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

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

        user_entity = self.user

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

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

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

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

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

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

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

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

        # no roles found, access denied
        raise out_of_band.AccessViolation(message_fmt=access.DEF_NEED_ROLE_MSG)
예제 #13
0
  def checkRoleAndStatusForStudentProposal(self, django_args, allowed_roles,
                                           role_status, proposal_status):
    """Checks if the current user has access to the given proposal.

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

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

    self.checkIsUser(django_args)

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

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

    user_entity = self.user

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

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

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

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

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

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

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

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

    # no roles found, access denied
    raise out_of_band.AccessViolation(
        message_fmt=access.DEF_NEED_ROLE_MSG)
예제 #14
0
    def checkIsAllowedToTakeProjectSurveyAs(self, django_args, survey_logic,
                                            role_name, project_key_location):
        """Checks whether a ProjectSurvey can be taken by the current User.

    role_name argument determines wether the current user is taking the survey
    as a student or mentor specified by the project in GET dict.

    If the survey is taken as a mentor, org admins for the Organization in
    which the project resides will also have access.

    However if the project entry is not present in the dictionary this access
    check passes.

    Args:
      django_args: a dictionary with django's arguments
      survey_logic: instance of ProjectSurveyLogic (or subclass)
      role_name: String containing either "student" or "mentor"
      project_key_location: String containing the key entry in the GET dict
        where the key for the project can be located.
    """

        if not role_name in ['mentor', 'student']:
            raise InvalidArgumentError('role_name is not mentor or student')

        # check if the current user is signed up
        self.checkIsUser(django_args)
        user_entity = self.user

        # get the project keyname from the GET dictionary
        get_dict = django_args['GET']
        key_name = get_dict.get(project_key_location)

        if not key_name:
            # no key name present so no need to deny access
            return

        # retrieve the Student Project for the key
        project_entity = student_project_logic.getFromKeyNameOr404(key_name)

        # check if a survey can be conducted about this project
        if project_entity.status != 'accepted':
            raise out_of_band.AccessViolation(
                message_fmt=DEF_NOT_ALLOWED_PROJECT_FOR_SURVEY_MSG)

        # get the correct role depending on the role_name
        if role_name == 'student':
            role_entity = project_entity.student
        elif role_name == 'mentor':
            role_entity = project_entity.mentor

        # check if the role matches the current user
        if role_entity.user.key() != user_entity.key() and (role_entity.status
                                                            == 'active'):
            if role_name == 'student':
                raise out_of_band.AccessViolation(
                    message_fmt=DEF_NOT_ALLOWED_PROJECT_FOR_SURVEY_MSG)
            elif role_name == 'mentor':
                # check if the current user is an Org Admin for this Student Project
                fields = {
                    'user': user_entity,
                    'scope': project_entity.scope,
                    'status': 'active'
                }
                admin_entity = org_admin_logic.getForFields(fields,
                                                            unique=True)
                if not admin_entity:
                    # this user is no Org Admin or Mentor for this project
                    raise out_of_band.AccessViolation(
                        message_fmt=DEF_NOT_ALLOWED_PROJECT_FOR_SURVEY_MSG)
        elif role_entity.status != 'active':
            # this role is not active
            raise out_of_band.AccessViolation(
                message_fmt=access.DEF_NEED_ROLE_MSG)

        return
예제 #15
0
  def checkIsAllowedToTakeProjectSurveyAs(self, django_args, survey_logic,
                                          role_name, project_key_location):
    """Checks whether a ProjectSurvey can be taken by the current User.

    role_name argument determines wether the current user is taking the survey
    as a student or mentor specified by the project in GET dict.

    If the survey is taken as a mentor, org admins for the Organization in
    which the project resides will also have access.

    However if the project entry is not present in the dictionary this access
    check passes.

    Args:
      django_args: a dictionary with django's arguments
      survey_logic: instance of ProjectSurveyLogic (or subclass)
      role_name: String containing either "student" or "mentor"
      project_key_location: String containing the key entry in the GET dict
        where the key for the project can be located.
    """

    if not role_name in ['mentor', 'student']:
      raise InvalidArgumentError('role_name is not mentor or student')

    # check if the current user is signed up
    self.checkIsUser(django_args)
    user_entity = self.user

    # get the project keyname from the GET dictionary
    get_dict = django_args['GET']
    key_name = get_dict.get(project_key_location)

    if not key_name:
      # no key name present so no need to deny access
      return

    # retrieve the Student Project for the key
    project_entity = student_project_logic.getFromKeyNameOr404(key_name)

    # check if a survey can be conducted about this project
    if project_entity.status != 'accepted':
      raise out_of_band.AccessViolation(
          message_fmt=DEF_NOT_ALLOWED_PROJECT_FOR_SURVEY_MSG)

    # get the correct role depending on the role_name
    if role_name == 'student':
      role_entity = project_entity.student
    elif role_name == 'mentor':
      role_entity = project_entity.mentor

    # check if the role matches the current user
    if role_entity.user.key() != user_entity.key() and (
        role_entity.status == 'active'):
      if role_name == 'student':
        raise out_of_band.AccessViolation(
            message_fmt=DEF_NOT_ALLOWED_PROJECT_FOR_SURVEY_MSG)
      elif role_name == 'mentor':
        # check if the current user is an Org Admin for this Student Project
        fields = {'user': user_entity,
                  'scope': project_entity.scope,
                  'status': 'active'}
        admin_entity = org_admin_logic.getForFields(fields, unique=True)
        if not admin_entity:
          # this user is no Org Admin or Mentor for this project
          raise out_of_band.AccessViolation(
              message_fmt=DEF_NOT_ALLOWED_PROJECT_FOR_SURVEY_MSG)
    elif role_entity.status != 'active':
      # this role is not active
      raise out_of_band.AccessViolation(message_fmt=access.DEF_NEED_ROLE_MSG)

    return
예제 #16
0
  def checkIsAllowedToViewProjectSurveyRecordAs(
      self, django_args, survey_logic, role_name, record_key_location):
    """Checks whether the current user is allowed to view the record given in
    the GET data by the record_key_location.

    Args:
      django_args: a dictionary with django's arguments
      survey_logic: Survey Logic instance that belongs to the SurveyRecord
        type in question
      role_name: string containing either "student" or "mentor". Determines
        which of the roles the within the project the current user should have
        to view the evaluation results.
      record_key_location: string containing the name of the GET param which
        contains the id for the SurveyRecord to retrieve

    Raises:
      AccessViolation if:
        - No valid numeric Record ID is given in the POST data.
        - No Record could be retrieved for the given Record ID.
        - The current user has not taken the survey, is not the Student/Mentor
          (depending on the role_name) and is not an Org Admin for the project
          to which the SurveyRecord belongs.
    """

    if not role_name in ['mentor', 'student']:
      raise InvalidArgumentError('role_name is not mentor or student')

    self.checkIsUser(django_args)
    user_entity = self.user

    get_dict = django_args['GET']
    record_id = get_dict.get(record_key_location)

    if not record_id or not record_id.isdigit():
      raise out_of_band.AccessViolation(
          message_fmt=access.DEF_NO_VALID_RECORD_ID)
    else:
      record_id = int(record_id)

    record_logic = survey_logic.getRecordLogic()
    record_entity = record_logic.getFromIDOr404(record_id)

    if record_entity.user.key() == user_entity.key():
      # this record belongs to the current user
      return

    if role_name == 'student':
      role_entity = record_entity.project.student
    elif role_name == 'mentor':
      role_entity = record_entity.project.mentor

    if role_entity.user.key() == user_entity.key() and (
        role_entity.status in ['active', 'inactive']):
      # this user has the role required
      return

    fields = {'user': user_entity,
              'scope': record_entity.org,
              'status': ['active','inactive']}
    admin_entity = org_admin_logic.getForFields(fields, unique=True)

    if admin_entity:
      # this user is org admin for the retrieved record's project
      return

    # The current user is no Org Admin, has not taken the Survey and is not
    # the one responsible for taking this survey.
    raise out_of_band.AccessViolation(message_fmt=access.DEF_NOT_YOUR_RECORD)
예제 #17
0
    def _getTimeDependentEntries(self, program_entity, params, id, user):
        """Returns a list with time dependent menu items.
    """

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

        items = []

        timeline_entity = program_entity.timeline

        org_app_survey = org_app_logic.getForProgram(program_entity)

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

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

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

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

            org_app_record_logic = org_app_logic.getRecordLogic()

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

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

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

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

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

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

        deadline = 'accepted_organization_announced_deadline'

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

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

        deadline = 'accepted_students_announced_deadline'

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

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

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

    For params see base.View.public().

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

    get_dict = request.GET

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

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

    program_entity = program_logic.getFromKeyFieldsOr404(kwargs)

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

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

    orgs_data = {}
    proposals_data = []

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

      org_data = {'name': org.name}

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

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

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

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

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

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

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

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

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

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

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

    For params see base.View.public().

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

        get_dict = request.GET

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

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

        program_entity = program_logic.getFromKeyFieldsOr404(kwargs)

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

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

        orgs_data = {}
        proposals_data = []

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

            org_data = {'name': org.name}

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

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

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

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

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

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

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

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

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

        return self.json(request, data)
예제 #20
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()
    """

        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)
예제 #21
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()
    """

    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)
예제 #22
0
def sendSurveyReminderForProject(request, *args, **kwargs):
    """Sends a reminder mail for a given StudentProject and Survey.

  A reminder is only send if no record is on file for the given Survey and 
  StudentProject.

  Expects the following to be present in the POST dict:
    survey_key: specifies the key name for the ProjectSurvey to send reminders
                for
    survey_type: either project or grading depending on the type of Survey
    project_key: key which specifies the project to send a reminder for

  Args:
    request: Django Request object
  """

    from soc.logic import mail_dispatcher
    from soc.logic.models.site import logic as site_logic
    from soc.views.helper import redirects

    from soc.modules.gsoc.logic.models.org_admin import logic as org_admin_logic
    from soc.modules.gsoc.logic.models.student_project import logic as \
        student_project_logic
    from soc.modules.gsoc.logic.models.survey import grading_logic
    from soc.modules.gsoc.logic.models.survey import project_logic

    post_dict = request.POST

    project_key = post_dict.get('project_key')
    survey_key = post_dict.get('survey_key')
    survey_type = post_dict.get('survey_type')

    if not (project_key and survey_key and survey_type):
        # invalid task data, log and return OK
        return error_handler.logErrorAndReturnOK(
            'Invalid sendSurveyReminderForProject data: %s' % post_dict)

    # set logic depending on survey type specified in POST
    if survey_type == 'project':
        survey_logic = project_logic
    elif survey_type == 'grading':
        survey_logic = grading_logic

    # retrieve the project and survey
    student_project = student_project_logic.getFromKeyName(project_key)

    if not student_project:
        # no existing project found, log and return OK
        return error_handler.logErrorAndReturnOK(
            'Invalid project specified %s:' % project_key)

    survey = survey_logic.getFromKeyName(survey_key)

    if not survey:
        # no existing survey found, log and return OK
        return error_handler.logErrorAndReturnOK(
            'Invalid survey specified %s:' % survey_key)

    # try to retrieve an existing record
    record_logic = survey_logic.getRecordLogic()

    fields = {'project': student_project, 'survey': survey}
    record_entity = record_logic.getForFields(fields, unique=True)

    if not record_entity:
        # send reminder email because we found no record

        student_entity = student_project.student
        site_entity = site_logic.getSingleton()

        if survey_type == 'project':
            survey_redirect = redirects.getTakeSurveyRedirect(
                survey, {'url_name': 'gsoc/project_survey'})
            to_role = student_entity
            mail_template = 'soc/project_survey/mail/reminder_gsoc.html'
        elif survey_type == 'grading':
            survey_redirect = redirects.getTakeSurveyRedirect(
                survey, {'url_name': 'gsoc/grading_project_survey'})
            to_role = student_project.mentor
            mail_template = 'soc/grading_project_survey/mail/reminder_gsoc.html'

        survey_url = "http://%(host)s%(redirect)s" % {
            'redirect': survey_redirect,
            'host': system.getHostname(),
        }

        # set the context for the mail template
        mail_context = {
            'student_name': student_entity.name(),
            'project_title': student_project.title,
            'survey_url': survey_url,
            'survey_end': survey.survey_end,
            'to_name': to_role.name(),
            'site_name': site_entity.site_name,
        }

        # set the sender
        (_, sender_address) = mail_dispatcher.getDefaultMailSender()
        mail_context['sender'] = sender_address
        # set the receiver and subject
        mail_context['to'] = to_role.email
        mail_context['subject'] = 'Evaluation Survey "%s" Reminder' % (
            survey.title)

        # find all org admins for the project's organization
        org_entity = student_project.scope

        fields = {'scope': org_entity, 'status': 'active'}
        org_admin_entities = org_admin_logic.getForFields(fields)

        # collect email addresses for all found org admins
        org_admin_addresses = []

        for org_admin_entity in org_admin_entities:
            org_admin_addresses.append(org_admin_entity.email)

        if org_admin_addresses:
            mail_context['cc'] = org_admin_addresses

        # send out the email
        mail_dispatcher.sendMailFromTemplate(mail_template, mail_context)

    # return OK
    return http.HttpResponse()
예제 #23
0
def sendMailAboutGradingRecordResult(request, *args, **kwargs):
  """Sends out a mail about the result of one GradingRecord.

  Expects the following to be present in the POST dict:
    record_key: Specifies the key for the record to process.

  Args:
    request: Django Request object
  """

  from soc.logic import mail_dispatcher
  from soc.logic.models.site import logic as site_logic

  from soc.modules.gsoc.logic.models.grading_record import logic as \
      grading_record_logic
  from soc.modules.gsoc.logic.models.org_admin import logic as org_admin_logic

  post_dict = request.POST

  # check and retrieve the record_key that has been done last
  if 'record_key' in post_dict and post_dict['record_key'].isdigit():
    record_key = int(post_dict['record_key'])
  else:
    record_key = None

  if not record_key:
    # no GradingRecord key specified, log and return OK
    error_handler.logErrorAndReturnOK(
        'No valid record_key specified in POST data: %s' % request.POST)

  record_entity = grading_record_logic.getFromID(record_key)

  if not record_entity:
    # no valid GradingRecord key specified, log and return OK
    error_handler.logErrorAndReturnOK(
        'No valid GradingRecord key specified: %s' % record_key)

  survey_group_entity = record_entity.grading_survey_group
  project_entity = record_entity.project
  student_entity = project_entity.student
  mentor_entity = project_entity.mentor
  org_entity = project_entity.scope
  site_entity = site_logic.getSingleton()

  mail_context = {
    'survey_group': survey_group_entity,
    'grading_record': record_entity,
    'project': project_entity,
    'organization': org_entity,
    'site_name': site_entity.site_name,
    'to_name': student_entity.name()
  }

  # set the sender
  (sender, sender_address) = mail_dispatcher.getDefaultMailSender()
  mail_context['sender'] = sender_address

  # set the receiver and subject
  mail_context['to'] = student_entity.email
  mail_context['cc'] = [mentor_entity.email]
  mail_context['subject'] = '%s results processed for %s' %(
      survey_group_entity.name, project_entity.title)

  # find all org admins for the project's organization
  fields = {'scope': org_entity,
            'status': 'active'}
  org_admin_entities = org_admin_logic.getForFields(fields)

  # collect all helping mentors
  additional_mentors = db.get(project_entity.additional_mentors)

  # add them all to the cc list
  for org_member in org_admin_entities + additional_mentors:
    mail_context['cc'].extend(org_member.email)

  # send out the email using a template
  mail_template = 'soc/grading_record/mail/result.html'
  mail_dispatcher.sendMailFromTemplate(mail_template, mail_context)

  # return OK
  return http.HttpResponse()