예제 #1
0
파일: access.py 프로젝트: jamslevy/gsoc
  def checkIsAfterEvent(self, django_args, event_name, key_name_arg):
    """Checks if the given event has taken place for the given program.

    Args:
      django_args: a dictionary with django's arguments
      event_name: the name of the event which is checked
      key_name_arg: the entry in django_args that specifies the given program
        keyname. If none is given the key_name is constructed from django_args
        itself.

    Raises:
      AccessViolationResponse:
      * if no active Program is found
      * if the event has not taken place yet
    """

    if key_name_arg and key_name_arg in django_args:
      key_name = django_args[key_name_arg]
    else:
      key_name = program_logic.getKeyNameFromFields(django_args)

    program_entity = program_logic.getFromKeyName(key_name)

    if not program_entity or (
        program_entity.status in ['inactive', 'invalid']):
      raise out_of_band.AccessViolation(message_fmt=DEF_SCOPE_INACTIVE_MSG)

    if timeline_helper.isAfterEvent(program_entity.timeline, event_name):
      return

    raise out_of_band.AccessViolation(message_fmt=DEF_PAGE_INACTIVE_MSG)
예제 #2
0
파일: access.py 프로젝트: jamslevy/gsoc
  def checkIsHostForProgramInScope(self, django_args):
    """Checks if the user is a host for the specified program.
    
    Args:
      django_args: a dictionary with django's arguments
    """

    program = program_logic.getFromKeyName(django_args['scope_path'])

    if not program or program.status == 'invalid':
      raise out_of_band.AccessViolation(message_fmt=DEF_NO_ACTIVE_PROGRAM_MSG)

    django_args = {'scope_path': program.scope_path}
    self.checkHasActiveRoleForScope(django_args, host_logic)
예제 #3
0
def runTimelineConversionUpdate(request, entities, context, *args, **kwargs):
    """AppEngine Task that converts Timelines into GSoCTimelines.

  It also updates all GSoCPrograms with a reference to the new GSoCTimeline.

  Args:
    request: Django Request object
    entities: list of Timeline entities to convert
    context: the context of this task
  """

    from soc.modules.gsoc.models.timeline import GSoCTimeline
    from soc.modules.gsoc.logic.models.program import logic as program_logic

    # get all the properties that are part of each Timeline
    timeline_model = timeline_logic.getModel()
    timeline_properties = timeline_model.properties().keys()

    # use this to store all the new GSoCTimelines and GSoCPrograms
    gsoc_timelines = []
    gsoc_programs = []

    for entity in entities:
        gsoc_properties = {}

        for timeline_property in timeline_properties:
            # copy over all the information from the timeline entity
            gsoc_properties[timeline_property] = getattr(
                entity, timeline_property)

        gsoc_program = program_logic.getFromKeyName(entity.key().id_or_name())
        gsoc_properties['scope'] = gsoc_program.scope

        # create the new GSoCTimeline entity and prepare it to be stored
        gsoc_timeline_entity = GSoCTimeline(key_name=entity.key().name(),
                                            **gsoc_properties)
        gsoc_timelines.append(gsoc_timeline_entity)

        # set the timeline for the GSoCProgram entity and prepare it for storage
        gsoc_program.timeline = gsoc_timeline_entity
        gsoc_programs.append(gsoc_program)

    # store all the new GSoCTimelines and GSoCPrograms
    db.put(gsoc_timelines)
    db.put(gsoc_programs)

    # task completed, return
    return
예제 #4
0
def runTimelineConversionUpdate(request, entities, context, *args, **kwargs):
  """AppEngine Task that converts Timelines into GSoCTimelines.

  It also updates all GSoCPrograms with a reference to the new GSoCTimeline.

  Args:
    request: Django Request object
    entities: list of Timeline entities to convert
    context: the context of this task
  """

  from soc.modules.gsoc.models.timeline import GSoCTimeline
  from soc.modules.gsoc.logic.models.program import logic as program_logic

  # get all the properties that are part of each Timeline
  timeline_model = timeline_logic.getModel()
  timeline_properties = timeline_model.properties().keys()

  # use this to store all the new GSoCTimelines and GSoCPrograms
  gsoc_timelines = []
  gsoc_programs = []

  for entity in entities:
    gsoc_properties = {}

    for timeline_property in timeline_properties:
      # copy over all the information from the timeline entity
      gsoc_properties[timeline_property] = getattr(entity, timeline_property)

    gsoc_program = program_logic.getFromKeyName(entity.key().id_or_name())
    gsoc_properties['scope'] = gsoc_program.scope

    # create the new GSoCTimeline entity and prepare it to be stored
    gsoc_timeline_entity = GSoCTimeline(key_name=entity.key().name(),
                                        **gsoc_properties)
    gsoc_timelines.append(gsoc_timeline_entity)

    # set the timeline for the GSoCProgram entity and prepare it for storage
    gsoc_program.timeline = gsoc_timeline_entity
    gsoc_programs.append(gsoc_program)

  # store all the new GSoCTimelines and GSoCPrograms
  db.put(gsoc_timelines)
  db.put(gsoc_programs)

  # task completed, return
  return
예제 #5
0
파일: stats.py 프로젝트: jamslevy/gsoc
def startSpam():
  """Creates the job that is responsible for sending mails.
  """

  from soc.logic.models.job import logic as job_logic
  from soc.logic.models.priority_group import logic as priority_logic
  from soc.logic.models.program import logic as program_logic

  program_entity = program_logic.getFromKeyName('google/gsoc2009')

  priority_group = priority_logic.getGroup(priority_logic.EMAIL)
  job_fields = {
      'priority_group': priority_group,
      'task_name': 'setupStudentProposalMailing',
      'key_data': [program_entity.key()]}

  job_logic.updateOrCreateFromFields(job_fields)
예제 #6
0
def _runSurveyUpdate(entities, logic):
    """AppEngine Task that updates Survey entities.

  Args:
    entities: list of Survey entities to update
    logic: concrete logic instance which the surveys are to be updated for

  Returns:
    A list of pairs that maps the old surveys with the corresponding new ones.
  """

    from soc.modules.gsoc.logic.models.program import logic as program_logic

    # get all the properties that are part of each Document
    survey_model = logic.getModel()
    survey_properties = survey_model.properties().keys()

    new_surveys = []

    for entity in entities:
        new_survey_properties = {}

        for survey_property in survey_properties:
            # copy over all the information from the Survey entity
            new_survey_properties[survey_property] = getattr(
                entity, survey_property)

        new_survey_properties['prefix'] = 'gsoc_program'
        new_survey_properties['scope'] = program_logic.getFromKeyName(
            entity.scope.key().id_or_name())

        new_survey_key = logic.getKeyNameFromFields(new_survey_properties)
        new_survey = survey_model(key_name=new_survey_key,
                                  **new_survey_properties)

        # force the prefix to gsoc_program before saving it for storage
        new_survey.prefix = 'gsoc_program'

        new_surveys.append(new_survey)

    # batch put the new Surveys
    db.put(new_surveys)

    # task completed, return
    return
예제 #7
0
def startSpam():
    """Creates the job that is responsible for sending mails.
  """

    from soc.logic.models.job import logic as job_logic
    from soc.logic.models.priority_group import logic as priority_logic
    from soc.logic.models.program import logic as program_logic

    program_entity = program_logic.getFromKeyName('google/gsoc2009')

    priority_group = priority_logic.getGroup(priority_logic.EMAIL)
    job_fields = {
        'priority_group': priority_group,
        'task_name': 'setupStudentProposalMailing',
        'key_data': [program_entity.key()]
    }

    job_logic.updateOrCreateFromFields(job_fields)
예제 #8
0
def _runSurveyUpdate(entities, logic):
  """AppEngine Task that updates Survey entities.

  Args:
    entities: list of Survey entities to update
    logic: concrete logic instance which the surveys are to be updated for

  Returns:
    A list of pairs that maps the old surveys with the corresponding new ones.
  """

  from soc.modules.gsoc.logic.models.program import logic as program_logic

  # get all the properties that are part of each Document
  survey_model = logic.getModel()
  survey_properties = survey_model.properties().keys()

  new_surveys = []

  for entity in entities:
    new_survey_properties = {}

    for survey_property in survey_properties:
      # copy over all the information from the Survey entity
      new_survey_properties[survey_property] = getattr(entity,
                                                       survey_property)

    new_survey_properties['prefix'] = 'gsoc_program'
    new_survey_properties['scope'] = program_logic.getFromKeyName(
        entity.scope.key().id_or_name())

    new_survey_key = logic.getKeyNameFromFields(new_survey_properties)
    new_survey = survey_model(key_name=new_survey_key, **new_survey_properties)

    # force the prefix to gsoc_program before saving it for storage
    new_survey.prefix = 'gsoc_program'

    new_surveys.append(new_survey)

  # batch put the new Surveys
  db.put(new_surveys)

  # task completed, return
  return
예제 #9
0
def runStudentProposalUpdate(request, entities, context, *args, **kwargs):
  """AppEngine Task that updates StudentProposal entities.

  Args:
    request: Django Request object
    entities: list of StudentProposal entities to update
    context: the context of this task
  """

  from soc.modules.gsoc.logic.models.mentor import logic as mentor_logic
  from soc.modules.gsoc.logic.models.organization import logic as org_logic
  from soc.modules.gsoc.logic.models.program import logic as program_logic
  from soc.modules.gsoc.logic.models.student import logic as student_logic

  for entity in entities:
    entity.scope = student_logic.getFromKeyName(
        entity.scope.key().id_or_name())
    entity.org = org_logic.getFromKeyName(entity.org.key().id_or_name())
    entity.program = program_logic.getFromKeyName(
        entity.program.key().id_or_name())

    if entity.mentor:
      entity.mentor = mentor_logic.getFromKeyName(
          entity.mentor.key().id_or_name())

    old_mentors = entity.possible_mentors
    new_mentors = []

    for old_mentor in old_mentors:
      new_mentor = mentor_logic.getFromKeyName(old_mentor.id_or_name())
      new_mentors.append(new_mentor.key())

    entity.possible_mentors = new_mentors

  # store all StudentProposal
  db.put(entities)

  # task completed, return
  return
예제 #10
0
def runStudentProposalUpdate(request, entities, context, *args, **kwargs):
  """AppEngine Task that updates StudentProposal entities.

  Args:
    request: Django Request object
    entities: list of StudentProposal entities to update
    context: the context of this task
  """

  from soc.modules.gsoc.logic.models.mentor import logic as mentor_logic
  from soc.modules.gsoc.logic.models.organization import logic as org_logic
  from soc.modules.gsoc.logic.models.program import logic as program_logic
  from soc.modules.gsoc.logic.models.student import logic as student_logic

  for entity in entities:
    entity.scope = student_logic.getFromKeyName(
        entity.scope.key().id_or_name())
    entity.org = org_logic.getFromKeyName(entity.org.key().id_or_name())
    entity.program = program_logic.getFromKeyName(
        entity.program.key().id_or_name())

    if entity.mentor:
      entity.mentor = mentor_logic.getFromKeyName(
          entity.mentor.key().id_or_name())

    old_mentors = entity.possible_mentors
    new_mentors = []

    for old_mentor in old_mentors:
      new_mentor = mentor_logic.getFromKeyName(old_mentor.id_or_name())
      new_mentors.append(new_mentor.key())

    entity.possible_mentors = new_mentors

  # store all StudentProposal
  db.put(entities)

  # task completed, return
  return
예제 #11
0
def runGradingSurveyGroupUpdate(request, entities, context, *args, **kwargs):
  """AppEngine Task that updates GradingSurveyGroup entities.

  Args:
    request: Django Request object
    entities: list of Document entities to update
    context: the context of this task
  """

  from soc.modules.gsoc.logic.models.program import logic as program_logic

  for entity in entities:
    entity.scope = program_logic.getFromKeyName(
        entity.scope.key().id_or_name())

    survey_attrs = ['grading_survey', 'student_survey']
    for survey_attr in survey_attrs:
      survey = getattr(entity, survey_attr)

      # update if the survey field is defined and its prefix is 'program'
      if not survey or not survey.prefix == 'program':
        continue

      survey_key_name = 'gsoc_' + survey.key().id_or_name()

      if survey_attr == 'student_survey':
        logic = project_survey_logic
      else:
        logic = grading_survey_logic

      new_survey = logic.getFromKeyName(survey_key_name)
      setattr(entity, survey_attr, new_survey)

  db.put(entities)

  # task completed, return
  return
예제 #12
0
def runGradingSurveyGroupUpdate(request, entities, context, *args, **kwargs):
  """AppEngine Task that updates GradingSurveyGroup entities.

  Args:
    request: Django Request object
    entities: list of Document entities to update
    context: the context of this task
  """

  from soc.modules.gsoc.logic.models.program import logic as program_logic

  for entity in entities:
    entity.scope = program_logic.getFromKeyName(
        entity.scope.key().id_or_name())

    survey_attrs = ['grading_survey', 'student_survey']
    for survey_attr in survey_attrs:
      survey = getattr(entity, survey_attr)

      # update if the survey field is defined and its prefix is 'program'
      if not survey or not survey.prefix == 'program':
        continue

      survey_key_name = 'gsoc_' + survey.key().id_or_name()

      if survey_attr == 'student_survey':
        logic = project_survey_logic
      else:
        logic = grading_survey_logic

      new_survey = logic.getFromKeyName(survey_key_name)
      setattr(entity, survey_attr, new_survey)

  db.put(entities)

  # task completed, return
  return
예제 #13
0
def runDocumentUpdate(request, entities, context, *args, **kwargs):
  """AppEngine Task that updates Document entities.

  Args:
    request: Django Request object
    entities: list of Document entities to update
    context: the context of this task
  """

  from soc.modules.gsoc.logic.models.organization import logic as org_logic
  from soc.modules.gsoc.logic.models.program import logic as program_logic

  # get all the properties that are part of each Document
  document_model = document_logic.getModel()
  document_properties = document_model.properties().keys()

  # use this to store all the new Documents and Presences
  documents = []
  presences = []

  for entity in entities:

    if entity.prefix not in ['org', 'program']:
      # we do not want to convert this Document
      continue

    new_document_properties = {}

    for document_property in document_properties:
      # copy over all the information from the Document entity
      new_document_properties[document_property] = getattr(entity,
                                                           document_property)

    if entity.prefix == 'org':
      new_document_prefix = 'gsoc_org'
      presence_entity = org_logic.getFromKeyName(entity.scope_path)
    elif entity.prefix == 'program':
      new_document_prefix = 'gsoc_program'
      presence_entity = program_logic.getFromKeyName(entity.scope_path)

    new_document_properties['prefix'] = new_document_prefix
    new_document_properties['scope'] = presence_entity
    new_document_properties['home_for'] = presence_entity if entity.home_for else None

    # create the new Document entity and prepare it to be stored
    new_document_entity = document_model(
        key_name=document_logic.getKeyNameFromFields(new_document_properties),
        **new_document_properties)
    documents.append(new_document_entity)

    if entity.home_for:
      # update the presence for which this document was the home page
      presence_entity.home = new_document_entity
      presences.append(presence_entity)

  # store all the new Documents and updated Presences
  db.put(documents)
  db.put(presences)

  # task completed, return
  return
예제 #14
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 google.appengine.ext import db

  from soc.logic.models.program import logic as program_logic
  from soc.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()
예제 #15
0
def setupStudentProposalMailing(job_entity):
  """Job that setup jobs that will mail students if they have been accepted in
  a program with a GSoC-like workflow.

  Args:
    job_entity: a Job entity with key_data set to 
                [program, last_completed_student]
  """

  from soc.cron.job import FatalJobError


  # retrieve the data we need to continue our work
  key_data = job_entity.key_data
  program_key = key_data[0]
  program_keyname = program_key.name()

  program_entity = program_logic.getFromKeyName(program_keyname)

  if not program_entity:
    raise FatalJobError('The program with key %s could not be found' % (
        program_keyname))

  student_fields = {'scope': program_entity}

  if len(key_data) >= 2:
    # start where we left off
    student_fields['__key__ >'] = key_data[1]

  students = student_logic.getForFields(student_fields,
                                        limit=DEF_STUDENT_STEP_SIZE)

  # set the default fields for the jobs we are going to create
  priority_group = priority_logic.getGroup(priority_logic.EMAIL)
  job_fields = {
      'priority_group': priority_group,
      'task_name': 'sendStudentProposalMail'}

  job_query_fields = job_fields.copy()

  while students:
    # for each student create a mailing job
    for student in students:

      job_query_fields['key_data'] = student.key()
      mail_job = job_logic.getForFields(job_query_fields, unique=True)

      if not mail_job:
        # this student did not receive mail yet
        job_fields['key_data'] = [student.key()]
        job_logic.updateOrCreateFromFields(job_fields)

    # update our own job
    last_student_key = students[-1].key()

    if len(key_data) >= 2:
      key_data[1] = last_student_key
    else:
      key_data.append(last_student_key)

    updated_job_fields = {'key_data': key_data}
    job_logic.updateEntityProperties(job_entity, updated_job_fields)

    # rinse and repeat
    student_fields['__key__ >'] = last_student_key
    students = student_logic.getForFields(student_fields,
                                          limit=DEF_STUDENT_STEP_SIZE)

  # we are finished
  return
예제 #16
0
def setupStudentProposalMailing(job_entity):
    """Job that setup jobs that will mail students if they have been accepted in
  a program with a GSoC-like workflow.

  Args:
    job_entity: a Job entity with key_data set to 
                [program, last_completed_student]
  """

    from soc.cron.job import FatalJobError

    # retrieve the data we need to continue our work
    key_data = job_entity.key_data
    program_key = key_data[0]
    program_keyname = program_key.name()

    program_entity = program_logic.getFromKeyName(program_keyname)

    if not program_entity:
        raise FatalJobError('The program with key %s could not be found' %
                            (program_keyname))

    student_fields = {'scope': program_entity}

    if len(key_data) >= 2:
        # start where we left off
        student_fields['__key__ >'] = key_data[1]

    students = student_logic.getForFields(student_fields,
                                          limit=DEF_STUDENT_STEP_SIZE)

    # set the default fields for the jobs we are going to create
    priority_group = priority_logic.getGroup(priority_logic.EMAIL)
    job_fields = {
        'priority_group': priority_group,
        'task_name': 'sendStudentProposalMail'
    }

    job_query_fields = job_fields.copy()

    while students:
        # for each student create a mailing job
        for student in students:

            job_query_fields['key_data'] = student.key()
            mail_job = job_logic.getForFields(job_query_fields, unique=True)

            if not mail_job:
                # this student did not receive mail yet
                job_fields['key_data'] = [student.key()]
                job_logic.updateOrCreateFromFields(job_fields)

        # update our own job
        last_student_key = students[-1].key()

        if len(key_data) >= 2:
            key_data[1] = last_student_key
        else:
            key_data.append(last_student_key)

        updated_job_fields = {'key_data': key_data}
        job_logic.updateEntityProperties(job_entity, updated_job_fields)

        # rinse and repeat
        student_fields['__key__ >'] = last_student_key
        students = student_logic.getForFields(student_fields,
                                              limit=DEF_STUDENT_STEP_SIZE)

    # we are finished
    return
예제 #17
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 google.appengine.ext import db

  from soc.logic.models.program import logic as program_logic
  from soc.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()
예제 #18
0
def runDocumentUpdate(request, entities, context, *args, **kwargs):
  """AppEngine Task that updates Document entities.

  Args:
    request: Django Request object
    entities: list of Document entities to update
    context: the context of this task
  """

  from soc.modules.gsoc.logic.models.organization import logic as org_logic
  from soc.modules.gsoc.logic.models.program import logic as program_logic

  # get all the properties that are part of each Document
  document_model = document_logic.getModel()
  document_properties = document_model.properties().keys()

  # use this to store all the new Documents and Presences
  documents = []
  presences = []

  for entity in entities:

    if entity.prefix not in ['org', 'program']:
      # we do not want to convert this Document
      continue

    new_document_properties = {}

    for document_property in document_properties:
      # copy over all the information from the Document entity
      new_document_properties[document_property] = getattr(entity,
                                                           document_property)

    if entity.prefix == 'org':
      new_document_prefix = 'gsoc_org'
      presence_entity = org_logic.getFromKeyName(entity.scope_path)
    elif entity.prefix == 'program':
      new_document_prefix = 'gsoc_program'
      presence_entity = program_logic.getFromKeyName(entity.scope_path)

    new_document_properties['prefix'] = new_document_prefix
    new_document_properties['scope'] = presence_entity
    new_document_properties['home_for'] = presence_entity if entity.home_for else None

    # create the new Document entity and prepare it to be stored
    new_document_entity = document_model(
        key_name=document_logic.getKeyNameFromFields(new_document_properties),
        **new_document_properties)
    documents.append(new_document_entity)

    if entity.home_for:
      # update the presence for which this document was the home page
      presence_entity.home = new_document_entity
      presences.append(presence_entity)

  # store all the new Documents and updated Presences
  db.put(documents)
  db.put(presences)

  # task completed, return
  return