Example #1
0
  def _setSurveyTakeContext(self, request, params, context, survey,
                            survey_record):
    """Sets the context for the ProjectSurvey take page.

    This includes setting the help_text, status and project_entity.

    Args:
        request: HTTP request object
        params: the params for the current View
        context: the context for the view to update
        survey: a Survey entity
        survey_record: a SurveyRecordEntity
    """

    from soc.modules.gsoc.logic.models.student_project import logic as \
        student_project_logic

    # call super first to set the other context items
    super(View, self)._setSurveyTakeContext(request, params, context, survey,
                                            survey_record)

    # retrieve the project using the key name in the GET param
    get_dict = request.GET
    context['project_entity'] = student_project_logic.getFromKeyName(
        get_dict['project'])
Example #2
0
  def _takePost(self, request, params, entity, record, properties):
    """Hook into the view for the take's page POST request.

    This is used to ensure the right StudentProject gets stored

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

    from soc.modules.gsoc.logic.models.student_project import logic as \
        student_project_logic

    # retrieve the project using the key name in the GET param
    get_dict = request.GET
    project_entity = student_project_logic.getFromKeyName(get_dict['project'])

    # update the properties that will be stored with the referenced project
    properties.update(project=project_entity, org=project_entity.scope)
Example #3
0
  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()
Example #4
0
    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()
Example #5
0
    def _getSurveyRecordFor(self, survey, request, params):
        """Returns the SurveyRecord for the given Survey and request.

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

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

        from soc.modules.gsoc.logic.models.student_project import logic as \
            student_project_logic

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

        # get the StudentProject specified in the GET params
        project_key_name = request.GET['project']
        project_entity = student_project_logic.getFromKeyName(project_key_name)

        filter = {'survey': survey, 'project': project_entity}

        return record_logic.getForFields(filter, unique=True)
Example #6
0
  def _getSurveyRecordFor(self, survey, request, params):
    """Returns the SurveyRecord for the given Survey and request.

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

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

    from soc.modules.gsoc.logic.models.student_project import logic as \
        student_project_logic

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

    # get the StudentProject specified in the GET params
    project_key_name = request.GET['project']
    project_entity = student_project_logic.getFromKeyName(project_key_name)

    filter = {'survey': survey,
              'project': project_entity}

    return record_logic.getForFields(filter, unique=True)
def updateOrCreateRecordsForSurveyGroup(request, *args, **kwargs):
    """Updates or creates GradingRecords for the given GradingSurveyGroup.

  Expects the following to be present in the POST dict:
    group_key: Specifies the GradingSurveyGroup key name.
    project_key: optional to specify which project was the last for which this
                 task was run
  Args:
    request: Django Request object
  """

    from soc.modules.gsoc.logic.models.grading_record import logic as grading_record_logic
    from soc.modules.gsoc.logic.models.grading_survey_group import logic as survey_group_logic
    from soc.modules.gsoc.logic.models.student_project import logic as student_project_logic

    post_dict = request.POST

    group_key = post_dict.get('group_key')

    if not group_key:
        # invalid task data, log and return OK
        return error_handler.logErrorAndReturnOK(
            'Invalid updateRecordForSurveyGroup data: %s' % post_dict)

    # get the GradingSurveyGroup for the given keyname
    survey_group_entity = survey_group_logic.getFromKeyName(group_key)

    if not survey_group_entity:
        # invalid GradingSurveyGroup specified, log and return OK
        return error_handler.logErrorAndReturnOK(
            'Invalid GradingSurveyGroup specified: %s' % group_key)

    # check and retrieve the project_key that has been done last
    if 'project_key' in post_dict:
        project_start_key = post_dict['project_key']
    else:
        project_start_key = None

    # get all valid StudentProjects from starting key
    fields = {
        'program': survey_group_entity.scope,
        'status': ['accepted', 'failed', 'completed']
    }

    if project_start_key:
        # retrieve the last project that was done
        project_start = student_project_logic.getFromKeyName(project_start_key)

        if not project_start:
            # invalid starting project key specified, log and return OK
            return error_handler.logErrorAndReturnOK(
                'Invalid Student Project Key specified: %s' %
                (project_start_key))

        fields['__key__ >'] = project_start.key()

    # get the first batch_size number of StudentProjects
    project_entities = student_project_logic.getForFields(fields,
                                                          limit=DEF_BATCH_SIZE)

    # update/create and batch put the new GradingRecords
    grading_record_logic.updateOrCreateRecordsFor(survey_group_entity,
                                                  project_entities)

    if len(project_entities) == DEF_BATCH_SIZE:
        # spawn new task starting from the last
        new_project_start = project_entities[DEF_BATCH_SIZE -
                                             1].key().id_or_name()

        # pass along these params as POST to the new task
        task_params = {
            'group_key': group_key,
            'project_key': new_project_start
        }
        task_url = '/tasks/grading_survey_group/update_records'

        new_task = taskqueue.Task(params=task_params, url=task_url)
        new_task.add()
    else:
        # task completed, update timestamp for last update complete
        fields = {'last_update_complete': datetime.datetime.now()}
        survey_group_logic.updateEntityProperties(survey_group_entity, fields)

    # task completed, return OK
    return http.HttpResponse('OK')
def updateOrCreateRecordsForSurveyGroup(request, *args, **kwargs):
  """Updates or creates GradingRecords for the given GradingSurveyGroup.

  Expects the following to be present in the POST dict:
    group_key: Specifies the GradingSurveyGroup key name.
    project_key: optional to specify which project was the last for which this
                 task was run
  Args:
    request: Django Request object
  """

  from soc.modules.gsoc.logic.models.grading_record import logic as grading_record_logic
  from soc.modules.gsoc.logic.models.grading_survey_group import logic as survey_group_logic
  from soc.modules.gsoc.logic.models.student_project import logic as student_project_logic

  post_dict = request.POST

  group_key = post_dict.get('group_key')

  if not group_key:
    # invalid task data, log and return OK
    return error_handler.logErrorAndReturnOK(
        'Invalid updateRecordForSurveyGroup data: %s' % post_dict)

  # get the GradingSurveyGroup for the given keyname
  survey_group_entity = survey_group_logic.getFromKeyName(group_key)

  if not survey_group_entity:
    # invalid GradingSurveyGroup specified, log and return OK
    return error_handler.logErrorAndReturnOK(
        'Invalid GradingSurveyGroup specified: %s' % group_key)

  # check and retrieve the project_key that has been done last
  if 'project_key' in post_dict:
    project_start_key = post_dict['project_key']
  else:
    project_start_key = None

  # get all valid StudentProjects from starting key
  fields = {'program': survey_group_entity.scope,
            'status': ['accepted', 'failed', 'completed']}

  if project_start_key:
    # retrieve the last project that was done
    project_start = student_project_logic.getFromKeyName(project_start_key)

    if not project_start:
      # invalid starting project key specified, log and return OK
      return error_handler.logErrorAndReturnOK(
          'Invalid Student Project Key specified: %s' %(project_start_key))

    fields['__key__ >'] = project_start.key()

  # get the first batch_size number of StudentProjects
  project_entities = student_project_logic.getForFields(fields,
                                                        limit=DEF_BATCH_SIZE)

  # update/create and batch put the new GradingRecords
  grading_record_logic.updateOrCreateRecordsFor(survey_group_entity,
                                                project_entities)

  if len(project_entities) == DEF_BATCH_SIZE:
    # spawn new task starting from the last
    new_project_start = project_entities[DEF_BATCH_SIZE-1].key().id_or_name()

    # pass along these params as POST to the new task
    task_params = {'group_key': group_key,
                   'project_key': new_project_start}
    task_url = '/tasks/grading_survey_group/update_records'

    new_task = taskqueue.Task(params=task_params, url=task_url)
    new_task.add()
  else:
    # task completed, update timestamp for last update complete
    fields = {'last_update_complete': datetime.datetime.now()}
    survey_group_logic.updateEntityProperties(survey_group_entity, fields)

  # task completed, return OK
  return http.HttpResponse('OK')
Example #9
0
def spawnRemindersForProjectSurvey(request, *args, **kwargs):
    """Spawns tasks for each StudentProject in the given Program.

  Expects the following to be present in the POST dict:
    program_key: Specifies the program key name for which to loop over all the
                 StudentProjects for
    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: optional to specify which project was the last for which a
                 task was spawn

  Args:
    request: Django Request object
  """

    from soc.modules.gsoc.logic.models.program import logic as program_logic
    from soc.modules.gsoc.logic.models.student_project import logic as \
        student_project_logic

    # set default batch size
    batch_size = 10

    post_dict = request.POST

    # retrieve the program_key and survey_key from POST data
    program_key = post_dict.get('program_key')
    survey_key = post_dict.get('survey_key')
    survey_type = post_dict.get('survey_type')

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

    # get the program for the given keyname
    program_entity = program_logic.getFromKeyName(program_key)

    if not program_entity:
        # invalid program specified, log and return OK
        return error_handler.logErrorAndReturnOK(
            'Invalid program specified: %s' % program_key)

    # check and retrieve the project_key that has been done last
    if 'project_key' in post_dict:
        project_start_key = post_dict['project_key']
    else:
        project_start_key = None

    # get all valid StudentProjects from starting key
    fields = {'program': program_entity, 'status': 'accepted'}

    if project_start_key:
        # retrieve the last project that was done
        project_start = student_project_logic.getFromKeyName(project_start_key)

        if not project_start:
            # invalid starting project key specified, log and return OK
            return error_handler.logErrorAndReturnOK(
                'Invalid Student Project Key specified: %s' %
                (project_start_key))

        fields['__key__ >'] = project_start.key()

    project_entities = student_project_logic.getForFields(fields,
                                                          limit=batch_size)

    for project_entity in project_entities:
        # pass along these params as POST to the new task
        task_params = {
            'survey_key': survey_key,
            'survey_type': survey_type,
            'project_key': project_entity.key().id_or_name()
        }
        task_url = '/tasks/surveys/projects/send_reminder/send'

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

    if len(project_entities) == batch_size:
        # spawn new task starting from the last
        new_project_start = project_entities[batch_size - 1].key().id_or_name()

        # pass along these params as POST to the new task
        task_params = {
            'program_key': program_key,
            'survey_key': survey_key,
            'survey_type': survey_type,
            'project_key': new_project_start
        }
        task_url = '/tasks/surveys/projects/send_reminder/spawn'

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

    # return OK
    return http.HttpResponse()
Example #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()
Example #11
0
def spawnRemindersForProjectSurvey(request, *args, **kwargs):
  """Spawns tasks for each StudentProject in the given Program.

  Expects the following to be present in the POST dict:
    program_key: Specifies the program key name for which to loop over all the
                 StudentProjects for
    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: optional to specify which project was the last for which a
                 task was spawn

  Args:
    request: Django Request object
  """

  from soc.modules.gsoc.logic.models.program import logic as program_logic
  from soc.modules.gsoc.logic.models.student_project import logic as \
      student_project_logic

  # set default batch size
  batch_size = 10

  post_dict = request.POST

  # retrieve the program_key and survey_key from POST data
  program_key = post_dict.get('program_key')
  survey_key = post_dict.get('survey_key')
  survey_type = post_dict.get('survey_type')

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

  # get the program for the given keyname
  program_entity = program_logic.getFromKeyName(program_key)

  if not program_entity:
    # invalid program specified, log and return OK
    return error_handler.logErrorAndReturnOK(
        'Invalid program specified: %s' % program_key)

  # check and retrieve the project_key that has been done last
  if 'project_key' in post_dict:
    project_start_key = post_dict['project_key']
  else:
    project_start_key = None

  # get all valid StudentProjects from starting key
  fields = {'program': program_entity,
            'status': 'accepted'}

  if project_start_key:
    # retrieve the last project that was done
    project_start = student_project_logic.getFromKeyName(project_start_key)

    if not project_start:
      # invalid starting project key specified, log and return OK
      return error_handler.logErrorAndReturnOK(
          'Invalid Student Project Key specified: %s' %(project_start_key))

    fields['__key__ >'] = project_start.key()

  project_entities = student_project_logic.getForFields(fields,
                                                        limit=batch_size)

  for project_entity in project_entities:
    # pass along these params as POST to the new task
    task_params = {'survey_key': survey_key,
                   'survey_type': survey_type,
                   'project_key': project_entity.key().id_or_name()}
    task_url = '/tasks/surveys/projects/send_reminder/send'

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

  if len(project_entities) == batch_size:
    # spawn new task starting from the last
    new_project_start = project_entities[batch_size-1].key().id_or_name()

    # pass along these params as POST to the new task
    task_params = {'program_key': program_key,
                   'survey_key': survey_key,
                   'survey_type': survey_type,
                   'project_key': new_project_start}
    task_url = '/tasks/surveys/projects/send_reminder/spawn'

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

  # return OK
  return http.HttpResponse()
Example #12
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()