Esempio n. 1
0
    def getListData(self):
        """Returns the list data as requested by the current request.

    If the lists as requested is not supported by this component None is
    returned.
    """
        if lists.getListIndex(self.data.request) != 1:
            return None

        q = GCITask.all()
        q.filter('program', self.data.program)
        q.filter(
            'org IN',
            map(lambda org_key: org_key.to_old_key(),
                self.data.ndb_profile.mentor_for))

        starter = lists.keyStarter
        # TODO(daniel): enable prefetching
        #prefetcher = lists.ListModelPrefetcher(
        #    GCITask, ['org', 'student', 'created_by', 'modified_by'], ['mentors'])

        response_builder = lists.RawQueryContentResponseBuilder(
            self.data.request, self._list_config, q, starter, prefetcher=None)

        return response_builder.build()
Esempio n. 2
0
  def _processStudentEntity(self, entity, properties):
    query = GCITask.all()
    query.filter('student', entity)
    query.filter('status', 'Closed')
    no_of_tasks = query.count()

    properties['number_of_tasks_completed'] = no_of_tasks
Esempio n. 3
0
  def testPostButtonExtendDeadline(self):
    """Tests the extend deadline button.
    """
    self.data.createMentor(self.org)

    profile_helper = GCIProfileHelper(self.gci, self.dev_test)
    profile_helper.createOtherUser('*****@*****.**').createStudent()
    student = profile_helper.profile

    # set it in the future so that the auto state transfer doesn't trigger
    deadline = datetime.datetime.utcnow() + datetime.timedelta(hours=24)

    self.task.status = 'Claimed'
    self.task.student = student
    self.task.deadline = deadline
    self.task.put()

    url = self._taskPageUrl(self.task)
    response = self.buttonPost(
        url, 'button_extend_deadline', {'hours': 1})

    task = GCITask.get(self.task.key())
    self.assertResponseRedirect(response)

    delta = task.deadline - deadline
    self.assertTrue(delta.seconds == 3600)

    # check if a comment has been created
    comments = self.task.comments()
    self.assertLength(comments, 1)
    self.assertMailSentToSubscribers(comments[0])
Esempio n. 4
0
    def testPostButtonNeedsWork(self):
        """Tests the needs more work for task button.
    """
        self.data.createMentor(self.org)

        profile_helper = GCIProfileHelper(self.gci, self.dev_test)
        profile_helper.createOtherUser("*****@*****.**").createStudent()
        student = profile_helper.profile

        self.task.status = "NeedsReview"
        self.task.student = student
        self.task.put()

        url = self._taskPageUrl(self.task)
        response = self.buttonPost(url, "button_needs_work")

        # check if the task is properly closed
        task = GCITask.get(self.task.key())
        self.assertResponseRedirect(response)
        self.assertEqual(task.status, "NeedsWork")
        self.assertEqual(task.student.key(), student.key())
        self.assertEqual(task.deadline, None)

        # check if a comment has been created
        comments = self.task.comments()
        self.assertLength(comments, 1)
        self.assertMailSentToSubscribers(comments[0])
Esempio n. 5
0
    def testPostButtonUnassign(self):
        """Tests the unassign button.
    """
        self.data.createMentor(self.org)

        profile_helper = GCIProfileHelper(self.gci, self.dev_test)
        profile_helper.createOtherUser("*****@*****.**").createStudent()
        student = profile_helper.profile

        self.task.status = "Claimed"
        self.task.student = student
        self.task.put()

        url = self._taskPageUrl(self.task)
        response = self.buttonPost(url, "button_unassign")

        # check if the task is properly unassigned
        task = GCITask.get(self.task.key())
        self.assertResponseRedirect(response)
        self.assertEqual(task.status, "Reopened")
        self.assertEqual(task.student, None)
        self.assertEqual(task.deadline, None)

        # check if a comment has been created
        comments = self.task.comments()
        self.assertLength(comments, 1)
        self.assertMailSentToSubscribers(comments[0])
Esempio n. 6
0
    def testPostButtonExtendDeadline(self):
        """Tests the extend deadline button.
    """
        self.data.createMentor(self.org)

        profile_helper = GCIProfileHelper(self.gci, self.dev_test)
        profile_helper.createOtherUser("*****@*****.**").createStudent()
        student = profile_helper.profile

        # set it in the future so that the auto state transfer doesn't trigger
        deadline = datetime.datetime.utcnow() + datetime.timedelta(hours=24)

        self.task.status = "Claimed"
        self.task.student = student
        self.task.deadline = deadline
        self.task.put()

        url = self._taskPageUrl(self.task)
        response = self.buttonPost(url, "button_extend_deadline", {"hours": 1})

        task = GCITask.get(self.task.key())
        self.assertResponseRedirect(response)

        delta = task.deadline - deadline
        self.assertTrue(delta.seconds == 3600)

        # check if a comment has been created
        comments = self.task.comments()
        self.assertLength(comments, 1)
        self.assertMailSentToSubscribers(comments[0])
Esempio n. 7
0
    def testPostButtonAssign(self):
        """Tests the assign button.
    """
        self.data.createMentor(self.org)

        profile_helper = GCIProfileHelper(self.gci, self.dev_test)
        profile_helper.createOtherUser("*****@*****.**").createStudent()
        student = profile_helper.profile

        self.task.status = "ClaimRequested"
        self.task.student = student
        self.task.put()

        url = self._taskPageUrl(self.task)
        response = self.buttonPost(url, "button_assign")

        # check if the task is properly assigned and a deadline has been set
        task = GCITask.get(self.task.key())
        self.assertResponseRedirect(response)
        self.assertEqual(task.status, "Claimed")
        self.assertEqual(task.student.key(), student.key())
        self.assertTrue(task.deadline)

        # check if a comment has been created
        comments = self.task.comments()
        self.assertLength(comments, 1)
        self.assertMailSentToSubscribers(comments[0])

        # check if the update task has been enqueued
        self.assertTasksInQueue(n=1, url=self._taskUpdateUrl(task))
Esempio n. 8
0
  def testPostButtonAssign(self):
    """Tests the assign button.
    """
    self.data.createMentor(self.org)

    profile_helper = GCIProfileHelper(self.gci, self.dev_test)
    profile_helper.createOtherUser('*****@*****.**').createStudent()
    student = profile_helper.profile

    self.task.status = 'ClaimRequested'
    self.task.student = student
    self.task.put()

    url = self._taskPageUrl(self.task)
    response = self.buttonPost(url, 'button_assign')

    # check if the task is properly assigned and a deadline has been set
    task = GCITask.get(self.task.key())
    self.assertResponseRedirect(response)
    self.assertEqual(task.status, 'Claimed')
    self.assertEqual(task.student.key(), student.key())
    self.assertTrue(task.deadline)

    # check if a comment has been created
    comments = self.task.comments()
    self.assertLength(comments, 1)
    self.assertMailSentToSubscribers(comments[0])

    # check if the update task has been enqueued
    self.assertTasksInQueue(n=1, url=self._taskUpdateUrl(task))
Esempio n. 9
0
  def testPostButtonUnassign(self):
    """Tests the unassign button.
    """
    self.data.createMentor(self.org)

    profile_helper = GCIProfileHelper(self.gci, self.dev_test)
    profile_helper.createOtherUser('*****@*****.**').createStudent()
    student = profile_helper.profile

    self.task.status = 'Claimed'
    self.task.student = student
    self.task.put()

    url = self._taskPageUrl(self.task)
    response = self.buttonPost(url, 'button_unassign')

    # check if the task is properly unassigned
    task = GCITask.get(self.task.key())
    self.assertResponseRedirect(response)
    self.assertEqual(task.status, 'Reopened')
    self.assertEqual(task.student, None)
    self.assertEqual(task.deadline, None)

    # check if a comment has been created
    comments = self.task.comments()
    self.assertLength(comments, 1)
    self.assertMailSentToSubscribers(comments[0])
Esempio n. 10
0
  def testPostButtonNeedsWork(self):
    """Tests the needs more work for task button.
    """
    self.data.createMentor(self.org)

    profile_helper = GCIProfileHelper(self.gci, self.dev_test)
    profile_helper.createOtherUser('*****@*****.**').createStudent()
    student = profile_helper.profile

    self.task.status = 'NeedsReview'
    self.task.student = student
    self.task.put()

    url = self._taskPageUrl(self.task)
    response = self.buttonPost(url, 'button_needs_work')

    # check if the task is properly closed
    task = GCITask.get(self.task.key())
    self.assertResponseRedirect(response)
    self.assertEqual(task.status, 'NeedsWork')
    self.assertEqual(task.student.key(), student.key())
    self.assertEqual(task.deadline, None)

    # check if a comment has been created
    comments = self.task.comments()
    self.assertLength(comments, 1)
    self.assertMailSentToSubscribers(comments[0])
Esempio n. 11
0
  def taskFromKwargs(self, comments=False, work_submissions=True):
    """Sets the GCITask entity in RequestData object.

    The entity that is set will always be in a valid state and for the program
    that is set in the RequestData.

    Args:
      comments: If true the comments on this task are added to RequestData
      work_submissions: If true the work submissions on this task are added to
                        RequestData
    """
    id = long(self.data.kwargs['id'])
    task = GCITask.get_by_id(id)

    if not task or (task.program.key() != self.data.program.key()) or \
        task.status == 'invalid':
      error_msg = access_checker.DEF_ID_BASED_ENTITY_NOT_EXISTS % {
          'model': 'GCITask',
          'id': id,
          }
      raise NotFound(error_msg)

    self.data.task = task

    if comments:
      self.data.comments = task.comments()

    if work_submissions:
      self.data.work_submissions = task.workSubmissions()
Esempio n. 12
0
      def publish_task_txn(profile_key):
        """Publishes or unpublishes a task in a transaction.

        profile_key: profile key of the user who takes this action.
        """
        task = GCITask.get_by_id(int(task_key))
        profile = profile_key.get()

        if not task:
          logging.warning("Task with task_id '%s' does not exist", task_key)
          return

        org_key = ndb.Key.from_old_key(
            GCITask.org.get_value_for_datastore(task))
        if not org_key in profile.admin_for:
          logging.warning('Not an org admin')
          return

        if publish:
          if task.status in task_model.UNAVAILABLE:
            task.status = task_model.OPEN
            task.put()
          else:
            logging.warning(
                'Trying to publish task with %s status.', task.status)
        else:
          if task.status == task_model.OPEN:
            task.status = task_model.UNPUBLISHED
            task.put()
          else:
            logging.warning(
                'Trying to unpublish task with %s status.', task.status)
Esempio n. 13
0
            def publish_task_txn(profile_key):
                """Publishes or unpublishes a task in a transaction.

        profile_key: profile key of the user who takes this action.
        """
                task = GCITask.get_by_id(int(task_key))
                profile = profile_key.get()

                if not task:
                    logging.warning("Task with task_id '%s' does not exist",
                                    task_key)
                    return

                org_key = ndb.Key.from_old_key(
                    GCITask.org.get_value_for_datastore(task))
                if not org_key in profile.admin_for:
                    logging.warning('Not an org admin')
                    return

                if publish:
                    if task.status in task_model.UNAVAILABLE:
                        task.status = task_model.OPEN
                        task.put()
                    else:
                        logging.warning(
                            'Trying to publish task with %s status.',
                            task.status)
                else:
                    if task.status == task_model.OPEN:
                        task.status = task_model.UNPUBLISHED
                        task.put()
                    else:
                        logging.warning(
                            'Trying to unpublish task with %s status.',
                            task.status)
Esempio n. 14
0
    def context(self):
        context = {
            'user_email':
            accounts.denormalizeAccount(self.data.user.account).email(),
            'link_id':
            self.data.user.link_id,
            'logout_link':
            links.LINKER.logout(self.data.request),
            'dashboard_link':
            links.LINKER.program(self.data.program, 'gci_dashboard')
        }

        # TODO(daniel): simplify this if statement
        if self.data.ndb_profile:
            if (self.data.ndb_profile.is_student
                    and self.data.ndb_profile.status
                    == profile_model.Status.ACTIVE):
                q = GCITask.all()
                q.filter('student', self.data.ndb_profile.key.to_old_key())
                q.filter('status IN', ACTIVE_CLAIMED_TASK)
                task = q.get()
                if task:
                    context['task'] = task
                    context['time_left'] = self.getTimeLeftForTask(task)
                    task_url = self.data.redirect.id(
                        task.key().id()).urlOf('gci_view_task')
                    context['task_url'] = task_url
        return context
Esempio n. 15
0
  def getListData(self):
    """Returns the list data as requested by the current request.

    If the lists as requested is not supported by this component None is
    returned.
    """
    if lists.getListIndex(self.data.request) != 1:
      return None

    q = GCITask.all()
    q.filter('program', self.data.program)
    q.filter(
        'org IN',
        map(lambda org_key: org_key.to_old_key(),
            self.data.ndb_profile.mentor_for))

    starter = lists.keyStarter
    # TODO(daniel): enable prefetching
    #prefetcher = lists.ListModelPrefetcher(
    #    GCITask, ['org', 'student', 'created_by', 'modified_by'], ['mentors'])

    response_builder = lists.RawQueryContentResponseBuilder(
        self.data.request, self._list_config, q, starter,
        prefetcher=None)

    return response_builder.build()
Esempio n. 16
0
  def recalculateForStudent(self, request, *args, **kwargs):
    """Recalculates GCI Student Ranking for the specified student.

    Args in POST:
      key: The string version of the key for the GCIProfile entity
           representing the student.
    """
    post_dict = request.POST
    key = db.Key(post_dict['key'])
    student = GCIProfile.get(key)

    if not student:
      logging.warning('Enqueued task to recalculate ranking for '
                      'non-existent student %s' %(key))
      return responses.terminateTask()

    # get all the tasks that the student has completed
    q = GCITask.all()
    q.filter('student', student)
    q.filter('status', 'Closed')
    tasks = q.fetch(1000)

    ranking_logic.calculateRankingForStudent(student, tasks)

    return responses.terminateTask()
Esempio n. 17
0
def getRemainingTaskQuota(org):
    """Returns the number of remaining tasks that the organization can publish.

  While calculating the remaining quota we consider all the tasks that
  were published including the closed tasks but not the deleted tasks.

  Args:
    org: The organization entity for which the quota must be calculated

  Returns:
    An integer which is the number of tasks the organization can publish yet
  """
    # TODO(Madhu): Refactor to create Open Tasks and Closed tasks variables
    # count all the tasks the organization has published till now.
    # This excludes tasks in Unapproved, Unpublished and Invalid states.
    valid_status = [
        "Open",
        "Reopened",
        "ClaimRequested",
        "Claimed",
        "ActionNeeded",
        "Closed",
        "AwaitingRegistration",
        "NeedsWork",
        "NeedsReview",
    ]

    q = GCITask.all()
    q.filter("org", org)
    q.filter("status IN", valid_status)

    return org.task_quota_limit - q.count()
Esempio n. 18
0
    def recalculateForStudent(self, request, *args, **kwargs):
        """Recalculates GCI Student Ranking for the specified student.

    Args in POST:
      key: The string version of the key for the GCIProfile entity
           representing the student.
    """
        post_dict = request.POST
        key = db.Key(post_dict['key'])
        student = GCIProfile.get(key)

        if not student:
            logging.warning(
                'Enqueued task to recalculate ranking for '
                'non-existent student %s', key)
            return responses.terminateTask()

        # get all the tasks that the student has completed
        q = GCITask.all()
        q.filter('student', student)
        q.filter('status', 'Closed')
        tasks = q.fetch(1000)

        score_logic.calculateRankingForStudent(student, tasks)

        return responses.terminateTask()
Esempio n. 19
0
def queryAllTasksClosedByStudent(profile, keys_only=False):
  """Returns a query for all the tasks that have been closed by the
  specified profile.
  """
  if not profile.student_info:
    raise ValueError('Only students can be queried for closed tasks.')

  return GCITask.all(keys_only=keys_only).filter(
      'student', profile).filter('status', 'Closed')
  
Esempio n. 20
0
def process_task(task):
  """Conversion to make GCI Tasks ID based and getting rid of unnecessary
  properties.
  """
  if task.key().name():
    # Get the values for all the properties in the GCITask model from the
    # old entity to create the new entity.
    new_task_properties = {}
    for prop in TASK_PROPERTIES:
      new_task_properties[prop] = getattr(task, prop)
      new_task_properties['org'] = task.scope

    new_task = GCITask(**new_task_properties)
    new_task_key = new_task.put()

    if new_task_key:
      # Update all the comments with the new task as the parent
      comments = GCIComment.all().ancestor(task).fetch(1000)
      for c in comments:
        new_comm_properties = {}
        for c_prop in COMMENT_PROPERTIES:
          new_comm_properties[c_prop] = getattr(c, c_prop)
        new_comment = GCIComment(parent=new_task_key, **new_comm_properties)

        # set these fields to behave like last_modified_on/by
        new_comment.modified_on = new_comment.created_on
        new_comment.modified_by = new_comment.created_by

        yield operation.db.Put(new_comment)
        yield operation.counters.Increment("comment_updated")

      # Update all the work submission entities with the new task as the parent
      work_submissions = GCIWorkSubmission.all().ancestor(task).fetch(1000)
      for ws in work_submissions:
        new_ws_properties = {}
        for ws_prop in WORK_SUBMISSION_PROPERTIES:
          new_ws_properties[ws_prop] = getattr(ws, ws_prop)
        new_ws = GCIWorkSubmission(parent=new_task_key, **new_ws_properties)
        yield operation.db.Put(new_ws)
        yield operation.counters.Increment("work_submission_updated")

      yield operation.counters.Increment("task_updated")
Esempio n. 21
0
    def testPostButtonDelete(self):
        """Tests the delete button.
    """
        self.data.createOrgAdmin(self.org)

        url = self._taskPageUrl(self.task)
        response = self.buttonPost(url, "button_delete")

        task = GCITask.get(self.task.key())
        self.assertResponseRedirect(response)
        self.assertEqual(task, None)
Esempio n. 22
0
  def testPostButtonUnpublish(self):
    """Tests the unpublish button.
    """
    self.data.createOrgAdmin(self.org)

    url = self._taskPageUrl(self.task)
    response = self.buttonPost(url, 'button_unpublish')

    task = GCITask.get(self.task.key())
    self.assertResponseRedirect(response)
    self.assertEqual(task.status, 'Unpublished')
Esempio n. 23
0
  def testPostButtonDelete(self):
    """Tests the delete button.
    """
    self.data.createOrgAdmin(self.org)

    url = self._taskPageUrl(self.task)
    response = self.buttonPost(url, 'button_delete')

    task = GCITask.get(self.task.key())
    self.assertResponseRedirect(response)
    self.assertEqual(task, None)
Esempio n. 24
0
    def testPostButtonUnpublish(self):
        """Tests the unpublish button.
    """
        self.data.createOrgAdmin(self.org)

        url = self._taskPageUrl(self.task)
        response = self.buttonPost(url, "button_unpublish")

        task = GCITask.get(self.task.key())
        self.assertResponseRedirect(response)
        self.assertEqual(task.status, "Unpublished")
Esempio n. 25
0
    def getListData(self):
        if lists.getListIndex(self.data.request) != 1:
            return None
        q = GCITask.all()
        q.filter('org', self.data.organization)
        q.filter('status', 'Closed')
        starter = lists.keyStarter

        response_builder = lists.RawQueryContentResponseBuilder(
            self.data.request, self.list_config, q, starter)
        return response_builder.build()
Esempio n. 26
0
  def getListData(self):
    if lists.getListIndex(self.request) != 0:
      return None
    q = GCITask.all()
    q.filter('org', self.data.organization)
    q.filter('status IN', CLAIMABLE)
    starter = lists.keyStarter

    response_builder = lists.RawQueryContentResponseBuilder(
        self.request, self.list_config, q, starter)
    return response_builder.build()
Esempio n. 27
0
    def getListData(self):
        idx = lists.getListIndex(self.data.request)
        if idx == 0:
            q = GCITask.all()
            q.filter('program', self.data.program)
            q.filter('status', 'Closed')

            response_builder = lists.RawQueryContentResponseBuilder(
                self.data.request, self._list_config, q, lists.keyStarter)

            return response_builder.build()
        else:
            return None
Esempio n. 28
0
  def getListData(self):
    idx = lists.getListIndex(self.data.request)
    if idx == 0:
      q = GCITask.all()
      q.filter('program', self.data.program)
      q.filter('status', 'Closed')

      response_builder = lists.RawQueryContentResponseBuilder(
          self.data.request, self._list_config, q, lists.keyStarter)

      return response_builder.build()
    else:
      return None
Esempio n. 29
0
    def recalculateGCIRanking(self, request, *args, **kwargs):
        """Recalculates student ranking for the entire program.

    Args in POST dict:
      cursor: Query cursor to figure out where we need to start processing
    """

        key_name = '%s/%s' % (kwargs['sponsor'], kwargs['program'])
        cursor = request.POST.get('cursor')

        program = GCIProgram.get_by_key_name(key_name)
        if not program:
            logging.warning(
                'Enqueued recalculate ranking task for non-existing program: %s',
                key_name)
            return responses.terminateTask()

        # Retrieve the students for the program
        q = GCIProfile.all()
        q.filter('program', program)
        q.filter('is_student', True)

        if cursor:
            q.with_cursor(cursor)

        students = q.fetch(25)

        for student in students:
            # get all the tasks that the student has completed
            task_q = GCITask.all()
            task_q.filter('student', student)
            task_q.filter('status', 'Closed')

            tasks = task_q.fetch(1000)

            # calculate score with all the tasks
            score_logic.calculateScore(student, tasks, program)

            # calculate org score with all the tasks
            db.run_in_transaction(org_score_logic.updateOrgScoresTxn(tasks))

        if students:
            # schedule task to do the rest of the students
            params = {
                'cursor': q.cursor(),
            }
            taskqueue.add(queue_name='gci-update',
                          url=request.path,
                          params=params)

        return responses.terminateTask()
Esempio n. 30
0
def convertGCITask(task_key):
  """Converts the specified task by changing values of its profile related
  properties to the new NDB based profile entities.

  Args:
    task_key: Task key.
  """
  task = GCITask.get(task_key)
  task.created_by = _convertReferenceProperty(GCITask.created_by, task)
  task.modified_by = _convertReferenceProperty(GCITask.modified_by, task)
  task.student = _convertReferenceProperty(GCITask.student, task)
  task.mentors = _convertListProperty(GCITask.mentors, task)
  task.subscribers = _convertListProperty(GCITask.subscribers, task)
  task.put()
Esempio n. 31
0
def convertGCITask(task_key):
    """Converts the specified task by changing values of its profile related
  properties to the new NDB based profile entities.

  Args:
    task_key: Task key.
  """
    task = GCITask.get(task_key)
    task.created_by = _convertReferenceProperty(GCITask.created_by, task)
    task.modified_by = _convertReferenceProperty(GCITask.modified_by, task)
    task.student = _convertReferenceProperty(GCITask.student, task)
    task.mentors = _convertListProperty(GCITask.mentors, task)
    task.subscribers = _convertListProperty(GCITask.subscribers, task)
    task.put()
Esempio n. 32
0
    def testPostButtonSubscribe(self):
        """Tests the subscribe button.
    """
        self.data.createMentor(self.org)

        profile = self.data.profile
        self.assertFalse(profile.key() in self.task.subscribers)

        url = self._taskPageUrl(self.task)
        response = self.buttonPost(url, "button_subscribe")

        task = GCITask.get(self.task.key())
        self.assertResponseRedirect(response)
        self.assertTrue(profile.key() in task.subscribers)
Esempio n. 33
0
  def testPostButtonSubscribe(self):
    """Tests the subscribe button.
    """
    self.data.createMentor(self.org)

    profile = self.data.profile
    self.assertFalse(profile.key() in self.task.subscribers)

    url = self._taskPageUrl(self.task)
    response = self.buttonPost(url, 'button_subscribe')

    task = GCITask.get(self.task.key())
    self.assertResponseRedirect(response)
    self.assertTrue(profile.key() in task.subscribers)
Esempio n. 34
0
  def testPostButtonUnsubscribe(self):
    """Tests the unsubscribe button.
    """
    self.data.createMentor(self.org)

    # subscribe to the task manually
    profile = self.data.profile
    self.task.subscribers.append(profile.key())
    self.task.put()

    url = self._taskPageUrl(self.task)
    response = self.buttonPost(url, 'button_unsubscribe')

    task = GCITask.get(self.task.key())
    self.assertResponseRedirect(response)
    self.assertFalse(profile.key() in task.subscribers)
Esempio n. 35
0
    def testPostButtonUnsubscribe(self):
        """Tests the unsubscribe button.
    """
        self.data.createMentor(self.org)

        # subscribe to the task manually
        profile = self.data.profile
        self.task.subscribers.append(profile.key())
        self.task.put()

        url = self._taskPageUrl(self.task)
        response = self.buttonPost(url, "button_unsubscribe")

        task = GCITask.get(self.task.key())
        self.assertResponseRedirect(response)
        self.assertFalse(profile.key() in task.subscribers)
Esempio n. 36
0
  def recalculateGCIRanking(self, request, *args, **kwargs):
    """Recalculates student ranking for the entire program.

    Args in POST dict:
      cursor: Query cursor to figure out where we need to start processing
    """

    key_name = '%s/%s' % (kwargs['sponsor'], kwargs['program'])
    cursor = request.POST.get('cursor')

    program = GCIProgram.get_by_key_name(key_name)
    if not program:
      logging.warning(
          'Enqueued recalculate ranking task for non-existing '
          'program: %s' %key_name)
      return responses.terminateTask()

    # Retrieve the students for the program
    q = GCIProfile.all()
    q.filter('scope', program)
    q.filter('is_student', True)

    if cursor:
      q.with_cursor(cursor)

    students = q.fetch(25)

    for student in students:
      # get all the tasks that the student has completed
      task_q = GCITask.all()
      task_q.filter('student', student)
      task_q.filter('status', 'Closed')

      tasks = task_q.fetch(1000)

      # calculate ranking with all the tasks
     # ranking_logic.calculateRankingForStudent(student, tasks)
      ranking_logic.calculateScore(student, tasks, program)

    if students:
      # schedule task to do the rest of the students
      params = {
          'cursor': q.cursor(),
          }
      taskqueue.add(queue_name='gci-update', url=request.path, params=params)

    return responses.terminateTask()
Esempio n. 37
0
def clear(*args, **kwargs):
  """Removes all entities from the datastore.
  """

  # TODO(dbentley): If there are more than 1000 instances of any model,
  # this method will not clear all instances.  Instead, it should continually
  # call .all(), delete all those, and loop until .all() is empty.
  entities = itertools.chain(*[
      Survey.all(),
      SurveyRecord.all(),
      GCIOrganization.all(),
      GSoCTimeline.all(),
      GCITimeline.all(),
      GSoCProgram.all(),
      GSoCProject.all(),
      GSoCProposal.all(),
      GCIProgram.all(),
      GCIScore.all(),
      GSoCStudentInfo.all(),
      GCIStudentInfo.all(),
      GCITask.all(),
      Sponsor.all(),
      Site.all(),
      Document.all(),
      # The below models are all subclasses of ndb.Model and therefore must
      # use .query() to return all instances instead of .all().
      soc_org_model.SOCOrganization.query(),
      profile_model.Profile.query(),
      soc_profile.SOCStudentData.query(),
      user.User.query(),
      address.Address.query(),
      contact.Contact.query()
      ])

  try:
    for entity in entities:
      if isinstance(entity, ndb.Model):
        entity.key.delete()
      else:
        entity.delete()
  except db.Timeout:
    return http.HttpResponseRedirect('#')
  memcache.flush_all()

  return http.HttpResponse('Done')
Esempio n. 38
0
    def recalculateGCIRanking(self, request, *args, **kwargs):
        """Recalculates student ranking for the entire program.

    Args in POST dict:
      cursor: Query cursor to figure out where we need to start processing
    """

        key_name = "%s/%s" % (kwargs["sponsor"], kwargs["program"])
        cursor = request.POST.get("cursor")

        program = GCIProgram.get_by_key_name(key_name)
        if not program:
            logging.warning("Enqueued recalculate ranking task for non-existing program: %s", key_name)
            return responses.terminateTask()

        # Retrieve the students for the program
        q = GCIProfile.all()
        q.filter("program", program)
        q.filter("is_student", True)

        if cursor:
            q.with_cursor(cursor)

        students = q.fetch(25)

        for student in students:
            # get all the tasks that the student has completed
            task_q = GCITask.all()
            task_q.filter("student", student)
            task_q.filter("status", "Closed")

            tasks = task_q.fetch(1000)

            # calculate score with all the tasks
            score_logic.calculateScore(student, tasks, program)

            # calculate org score with all the tasks
            db.run_in_transaction(org_score_logic.updateOrgScoresTxn(tasks))

        if students:
            # schedule task to do the rest of the students
            params = {"cursor": q.cursor()}
            taskqueue.add(queue_name="gci-update", url=request.path, params=params)

        return responses.terminateTask()
Esempio n. 39
0
def clear(*args, **kwargs):
    """Removes all entities from the datastore.
  """

    # TODO(dbentley): If there are more than 1000 instances of any model,
    # this method will not clear all instances.  Instead, it should continually
    # call .all(), delete all those, and loop until .all() is empty.
    entities = itertools.chain(*[
        Survey.all(),
        SurveyRecord.all(),
        GCIOrganization.all(),
        GSoCTimeline.all(),
        GCITimeline.all(),
        GSoCProgram.all(),
        GSoCProject.all(),
        GSoCProposal.all(),
        GCIProgram.all(),
        GCIScore.all(),
        GSoCStudentInfo.all(),
        GCIStudentInfo.all(),
        GCITask.all(),
        Sponsor.all(),
        Site.all(),
        Document.all(),
        # The below models are all subclasses of ndb.Model and therefore must
        # use .query() to return all instances instead of .all().
        soc_org_model.SOCOrganization.query(),
        profile_model.Profile.query(),
        soc_profile.SOCStudentData.query(),
        user.User.query(),
        address.Address.query(),
        contact.Contact.query()
    ])

    try:
        for entity in entities:
            if isinstance(entity, ndb.Model):
                entity.key.delete()
            else:
                entity.delete()
    except db.Timeout:
        return http.HttpResponseRedirect('#')
    memcache.flush_all()

    return http.HttpResponse('Done')
Esempio n. 40
0
  def testPostButtonClaim(self):
    """Tests the claim task button.
    """
    self.data.createStudent()

    url = self._taskPageUrl(self.task)
    response = self.buttonPost(url, 'button_claim')

    # check if the task is properly claimed
    task = GCITask.get(self.task.key())
    self.assertResponseRedirect(response)
    self.assertEqual(task.status, 'ClaimRequested')
    self.assertEqual(task.student.key(), self.data.profile.key())

    # check if a comment has been created
    comments = self.task.comments()
    self.assertLength(comments, 1)
    self.assertMailSentToSubscribers(comments[0])
Esempio n. 41
0
    def updateGCITask(self, request, id, *args, **kwargs):
        """Method executed by Task Queue API to update a GCI Task to
    relevant state.

    Args:
      request: the standard Django HTTP request object
    """
        id = int(id)

        task = GCITask.get_by_id(id)

        if not task:
            # invalid task data, log and return OK
            return error_handler.logErrorAndReturnOK("No GCITask found for id: %s" % id)

        task_logic.updateTaskStatus(task)

        return http.HttpResponse()
Esempio n. 42
0
def process_tag(tag):
  """Replace all the references to the list of old tasks to the new tasks.
  """
  new_tagged_keys = []
  for t in tag.tagged:
    try:
      task = GCITask.get(t)
      new_tagged = new_task_for_old(task) if task else None
    except db.KindError:
      new_tagged = t

    if new_tagged:
      new_tagged_keys.append(new_tagged)

  tag.tagged = new_tagged_keys

  yield operation.db.Put(tag)
  yield operation.counters.Increment("tag_updated")
Esempio n. 43
0
    def testPostButtonClaim(self):
        """Tests the claim task button.
    """
        self.data.createStudent()

        url = self._taskPageUrl(self.task)
        response = self.buttonPost(url, "button_claim")

        # check if the task is properly claimed
        task = GCITask.get(self.task.key())
        self.assertResponseRedirect(response)
        self.assertEqual(task.status, "ClaimRequested")
        self.assertEqual(task.student.key(), self.data.profile.key())

        # check if a comment has been created
        comments = self.task.comments()
        self.assertLength(comments, 1)
        self.assertMailSentToSubscribers(comments[0])
Esempio n. 44
0
  def updateRankingWithTask(self, request, *args, **kwargs):
    """Updates student ranking based on the task passed as post argument.

    Args in POST dict:
      id: The (numeric) id of the task to update the ranking for
    """
    post_dict = request.POST

    id = int(post_dict.get('id'))
    task = GCITask.get_by_id(id)

    if not task:
      logging.warning('Ranking update queued for non-existing task: %s' %id)
      responses.terminateTask()

    ranking_logic.updateScore(task)

    logging.info("ranking_update updateRankingWithTask ends")
    return responses.terminateTask()
Esempio n. 45
0
    def updateGCITask(self, request, id, *args, **kwargs):
        """Method executed by Task Queue API to update a GCI Task to
    relevant state.

    Args:
      request: the standard Django HTTP request object
    """
        id = int(id)

        task = GCITask.get_by_id(id)

        if not task:
            # invalid task data, log and return OK
            return error_handler.logErrorAndReturnOK(
                'No GCITask found for id: %s' % id)

        task_logic.updateTaskStatus(task)

        return http.HttpResponse()
Esempio n. 46
0
    def testPostSendForReview(self):
        """Tests for submitting work.
    """
        self.data.createStudent()

        self.task.status = "Claimed"
        self.task.student = self.data.profile
        # set deadline to far future
        self.task.deadline = datetime.datetime.utcnow() + datetime.timedelta(days=1)
        self.task.put()

        GCITaskHelper(self.program).createWorkSubmission(self.task, self.data.profile)

        url = "%s?send_for_review" % self._taskPageUrl(self.task)
        response = self.post(url)

        task = GCITask.get(self.task.key())
        self.assertResponseRedirect(response)
        self.assertEqual(task.status, "NeedsReview")
Esempio n. 47
0
def clear(*args, **kwargs):
  """Removes all entities from the datastore.
  """

  # TODO(dbentley): If there are more than 1000 instances of any model,
  # this method will not clear all instances.  Instead, it should continually
  # call .all(), delete all those, and loop until .all() is empty.
  entities = itertools.chain(*[
      Notification.all(),
      GCIStudent.all(),
      Survey.all(),
      SurveyRecord.all(),
      StudentProposal.all(),
      GSoCOrganization.all(),
      GCIOrganization.all(),
      GSoCTimeline.all(),
      GCITimeline.all(),
      GSoCProgram.all(),
      GSoCProfile.all(),
      GCIProfile.all(),
      GSoCProposal.all(),
      GCIProgram.all(),
      GCIScore.all(),
      GSoCStudentInfo.all(),
      GCIStudentInfo.all(),
      GCITask.all(),
      Host.all(),
      Sponsor.all(),
      User.all(),
      Site.all(),
      Document.all(),
      ])

  try:
    for entity in entities:
      entity.delete()
  except db.Timeout:
    return http.HttpResponseRedirect('#')
  # pylint: disable=E1101
  memcache.flush_all()

  return http.HttpResponse('Done')
Esempio n. 48
0
  def testPostSendForReview(self):
    """Tests for submitting work.
    """
    self.data.createStudent()

    self.task.status = 'Claimed'
    self.task.student = self.data.profile
    # set deadline to far future
    self.task.deadline = datetime.datetime.utcnow() + datetime.timedelta(days=1)
    self.task.put()

    GCITaskHelper(self.program).createWorkSubmission(
        self.task, self.data.profile)

    url = '%s?send_for_review' %self._taskPageUrl(self.task)
    response = self.post(url)

    task = GCITask.get(self.task.key())
    self.assertResponseRedirect(response)
    self.assertEqual(task.status, 'NeedsReview')
Esempio n. 49
0
    def updateRankingWithTask(self, request, *args, **kwargs):
        """Updates student ranking based on the task passed as post argument.

    Args in POST dict:
      id: The (numeric) id of the task to update the ranking for
    """
        post_dict = request.POST

        id = int(post_dict.get('id'))
        task = GCITask.get_by_id(id)

        if not task:
            logging.warning('Ranking update queued for non-existing task: %s',
                            id)
            responses.terminateTask()

        score_logic.updateScore(task)

        logging.info("ranking_update updateRankingWithTask ends")
        return responses.terminateTask()
Esempio n. 50
0
  def context(self):
    context = {
        'user_email': accounts.denormalizeAccount(self.data.user.account).email(),
        'link_id': self.data.user.link_id,
        'logout_link': self.data.redirect.logout().url(),
        'dashboard_link': self.data.redirect.dashboard().url()
    }

    if self.data.profile:
      if self.data.is_student and self.data.profile.status == 'active':
        q = GCITask.all()
        q.filter('student', self.data.profile)
        q.filter('status IN', ACTIVE_CLAIMED_TASK)
        task = q.get()
        if task:
          context['task'] = task
          context['time_left'] = self.getTimeLeftForTask(task)
          task_url = self.data.redirect.id(
              task.key().id()).urlOf('gci_view_task')
          context['task_url'] = task_url
    return context
Esempio n. 51
0
    def getListData(self):
        """Returns the list data as requested by the current request.

    If the lists as requested is not supported by this component None is
    returned.
    """
        if lists.getListIndex(self.request) != 1:
            return None

        q = GCITask.all()
        q.filter("program", self.data.program)
        q.filter("org IN", self.data.mentor_for)

        starter = lists.keyStarter
        prefetcher = lists.listModelPrefetcher(GCITask, ["org", "student", "created_by", "modified_by"], ["mentors"])

        response_builder = lists.RawQueryContentResponseBuilder(
            self.request, self._list_config, q, starter, prefetcher=prefetcher
        )

        return response_builder.build()
 def subscribe_to_task_txn(task_key, subscribe):
     task = GCITask.get(task_key)
     task.subscribers = list(set(task.subscribers + subscribe))
     task.put()
     return task
Esempio n. 53
0
    def bulkCreateTasks(self, request, *args, **kwargs):
        """Task that creates GCI Tasks from bulk data specified in the POST dict.

    The POST dict should have the following information present:
        bulk_create_key: the key of the bulk_create entity
    """
        import settings

        # keep track of our own timelimit (20 seconds)
        timelimit = 20000
        timekeeper = Timekeeper(timelimit)

        post_dict = request.POST

        bulk_create_key = post_dict.get('bulk_create_key')
        if not bulk_create_key:
            return error_handler.logErrorAndReturnOK(
                'Not all POST data specified in: %s' % post_dict)

        bulk_data = GCIBulkCreateData.get(bulk_create_key)
        if not bulk_data:
            return error_handler.logErrorAndReturnOK(
                'No valid data found for key: %s' % bulk_create_key)

        # note that we only query for the quota once
        org_admin = ndb.Key.from_old_key(
            GCIBulkCreateData.created_by.get_value_for_datastore(
                bulk_data)).get()
        org = bulk_data.org
        task_quota = getRemainingTaskQuota(org)

        # TODO(ljvderijk): Add transactions

        tasks = bulk_data.tasks
        while len(tasks) > 0:
            try:
                # check if we have time
                timekeeper.ping()

                if settings.GCI_TASK_QUOTA_LIMIT_ENABLED and task_quota <= 0:
                    return error_handler.logErrorAndReturnOK(
                        'Task quota reached for %s' % (org.name))

                # remove the first task
                task_as_string = tasks.pop(0)

                loaded_task = json.loads(task_as_string)
                task = {}
                for key, value in loaded_task.iteritems():
                    # If we don't do this python will complain about kwargs not being
                    # strings when we try to save the new task.
                    task[key.encode('UTF-8')] = value

                logging.info('Uncleaned task: %s', task)
                # clean the data
                errors = self._cleanTask(task, org)

                if errors:
                    logging.warning(
                        'Invalid task data uploaded, the following errors occurred: %s',
                        errors)
                    bulk_data.errors.append(db.Text(
                        'The task in row %i contains the following errors.\n %s' \
                        %(bulk_data.tasksRemoved(), '\n'.join(errors))))

                # at-most-once semantics for creating tasks
                bulk_data.put()

                if errors:
                    # do the next task
                    continue

                # set other properties
                task['org'] = org

                # TODO(daniel): access program in more efficient way
                task['program'] = org_admin.program.to_old_key()
                task['status'] = task_model.UNPUBLISHED
                task['created_by'] = org_admin.to_old_key()
                task['modified_by'] = org_admin.to_old_key()
                # TODO(ljv): Remove difficulty level completely if needed.
                # Difficulty is hardcoded to easy since GCI2012 has no difficulty.
                task['difficulty_level'] = DifficultyLevel.EASY

                subscribers_entities = task['mentor_entities'] + [org_admin]
                task['subscribers'] = list(
                    set([
                        ent.key() for ent in subscribers_entities
                        if ent.automatic_task_subscription
                    ]))

                # create the new task
                logging.info('Creating new task with fields: %s', task)
                task_entity = GCITask(**task)
                task_entity.put()
                task_quota = task_quota - 1
            except DeadlineExceededError:
                # time to bail out
                break

        if len(tasks) == 0:
            # send out a message
            notifications.sendBulkCreationCompleted(bulk_data)
            bulk_data.delete()
        else:
            # there is still work to be done, do a non 500 response and requeue
            task_params = {'bulk_create_key': bulk_data.key()}
            new_task = taskqueue.Task(params=task_params, url=BULK_CREATE_URL)
            # add to the gci queue
            new_task.add(queue_name='gci-update')

        # we're done here
        return http.HttpResponse('OK')
Esempio n. 54
0
def seed(request, *args, **kwargs):
    """Seeds the datastore with some default values.
  """

    site_properties = {
        'key_name': 'site',
        'latest_gsoc': 'google/gsoc2014',
        'latest_gci': 'google/gci2013',
    }
    site = Site(**site_properties)
    site.put()

    account = accounts.getCurrentAccount()

    if not account:
        account = users.User(email='*****@*****.**')

    user_properties = {
        'id': 'test',
        'account_id': account.user_id(),
        'account': account,
    }
    current_user = user.User(**user_properties)
    current_user.put()

    group_properties = {
        'key_name': 'google',
        'link_id': 'google',
        'name': 'Google Inc.',
        'short_name': 'Google',
        'home_page': 'http://www.google.com',
        'email': '*****@*****.**',
        'description': 'This is the profile for Google.',
        'contact_street': 'Some Street',
        'contact_city': 'Some City',
        'contact_country': 'United States',
        'contact_postalcode': '12345',
        'phone': '15551110000',
        'status': 'active',
    }
    google = Sponsor(**group_properties)
    google.put()

    now = datetime.datetime.now()
    before = now - datetime.timedelta(365)
    after = now + datetime.timedelta(365)
    past_before = before - datetime.timedelta(2 * 365)
    past_after = after - datetime.timedelta(2 * 365)

    timeline_properties = {
        'key_name': 'google/gsoc2014',
        'link_id': 'gsoc2014',
        'scope': google,
        'program_start': before,
        'program_end': after,
        'accepted_organization_announced_deadline': before,
        'accepted_students_announced_deadline': after,
        'student_signup_start': before,
        'student_signup_end': after,
        'application_review_deadline': after,
        'student_application_matched_deadline': after,
        'accepted_students_announced_deadline': after,
        'form_submission_start': before,
    }
    gsoc2014_timeline = GSoCTimeline(**timeline_properties)
    gsoc2014_timeline.put()

    program_properties = {
        'key_name': 'google/gsoc2014',
        'link_id': 'gsoc2014',
        'program_id': 'gsoc2014',
        'sponsor': google,
        'scope': google,
        'name': 'Google Summer of Code 2014',
        'short_name': 'GSoC 2014',
        'description': 'This is the program for GSoC 2014.',
        'apps_tasks_limit': 42,
        'slots': 42,
        'timeline': gsoc2014_timeline,
        'status': program_model.STATUS_VISIBLE,
    }
    gsoc2014 = GSoCProgram(**program_properties)
    gsoc2014.put()

    timeline_properties.update({
        'key_name': 'google/gsoc2010',
        'link_id': 'gsoc2010',
        'program_start': past_before,
        'program_end': past_after,
        'accepted_organization_announced_deadline': past_before,
        'accepted_students_announced_deadline': past_after,
        'student_signup_start': past_before,
        'student_signup_end': past_after,
        'application_review_deadline': past_after,
        'student_application_matched_deadline': past_after,
        'accepted_students_announced_deadline': past_after,
        'form_submission_start': past_before,
    })
    gsoc2010_timeline = GSoCTimeline(**timeline_properties)
    gsoc2010_timeline.put()

    program_properties.update({
        'key_name': 'google/gsoc2010',
        'link_id': 'gsoc2010',
        'program_id': 'gsoc2010',
        'name': 'Google Summer of Code 2010',
        'description': 'This is the program for GSoC 2010.',
        'short_name': 'GSoC 2010',
        'timeline': gsoc2010_timeline,
    })
    gsoc2010 = GSoCProgram(**program_properties)
    gsoc2010.put()

    # TODO(drew): Replace gsoc2014.prefix with whatever its replacement becomes
    # once prefix is removed from program and no longer used in the query for
    # OrgAppSurvey in soc.views.helper.RequestData._getProgramWideFields().
    org_app_survey_properties = {
        'key_name': '%s/%s/orgapp' % (gsoc2014.prefix, gsoc2014.key().name()),
        'program': gsoc2014,
        'title': 'Org App Survey',
        'content': 'Here is some content.',
        'modified_by': current_user.key.to_old_key(),
        'survey_start': before,
        'survey_end': after
    }
    org_app_survey_model.OrgAppSurvey(**org_app_survey_properties).put()

    org_app_survey_properties['key_name'] = (
        '%s/%s/orgapp' % (gsoc2010.prefix, gsoc2010.key().name()))
    org_app_survey_properties['program'] = gsoc2010
    org_app_survey_properties['survey_start'] = past_before
    org_app_survey_properties['survey_end'] = past_after
    org_app_survey_model.OrgAppSurvey(**org_app_survey_properties).put()

    timeline_properties = {
        'key_name': 'google/gci2013',
        'link_id': 'gci2013',
        'scope': google,
        'program_start': before,
        'program_end': after,
        'accepted_organization_announced_deadline': before,
        'student_signup_start': before,
        'student_signup_end': after,
        'tasks_publicly_visible': before,
        'task_claim_deadline': after,
        'stop_all_work_deadline': after,
    }
    gci2013_timeline = GCITimeline(**timeline_properties)
    gci2013_timeline.put()

    program_properties.update({
        'key_name': 'google/gci2013',
        'link_id': 'gci2013',
        'program_id': 'gci2013',
        'name': 'Google Code In Contest 2013',
        'short_name': 'GCI 2009',
        'description': 'This is the program for GCI 2013.',
        'timeline': gci2013_timeline,
    })
    gci2013 = GCIProgram(**program_properties)
    gci2013.put()

    site.active_program = gci2013
    site.put()

    current_user.host_for = [
        ndb.Key.from_old_key(gsoc2010.key()),
        ndb.Key.from_old_key(gsoc2014.key()),
        ndb.Key.from_old_key(gci2013.key())
    ]
    current_user.put()

    group_properties.update({
        'key_name': 'google/gci2013/melange',
        'link_id': 'melange',
        'name': 'Melange Development Team',
        'short_name': 'Melange',
        'scope': gci2013,
        'program': gci2013,
        'sponsor': google,
        'home_page': 'http://code.google.com/p/soc',
        'description': 'Melange, share the love!',
        'license_name': 'Apache License',
        'ideas': 'http://code.google.com/p/soc/issues',
    })
    melange = GCIOrganization(**group_properties)
    melange.put()

    group_properties.update({
        'scope': gsoc2014,
        'program': gsoc2014,
    })

    address_properties = address.Address(street='1 Test St.',
                                         city='Some City',
                                         country='United States',
                                         postal_code='12345')
    address_properties.put()

    contact_info = contact.Contact(email='*****@*****.**')
    contact_info.put()

    gsoc_delta = datetime.timedelta(days=(365 * 18))

    profile_properties = {
        'id': gsoc2014.key().name() + '/' + current_user.key.id(),
        'parent': current_user.key,
        'public_name': 'test',
        'program': ndb.Key.from_old_key(gsoc2014.key()),
        'first_name': 'Test',
        'last_name': 'Example',
        'contact': contact_info,
        'residential_address': address_properties,
        'shipping_address': address_properties,
        'birth_date': datetime.date.today() - gsoc_delta,
        'program_knowledge': 'Friend referral',
    }
    profile = profile_model.Profile(**profile_properties)

    ndb_orgs = []
    for i in range(15):
        group_properties.update({
            'key_name': 'google/gsoc2014/org_%d' % i,
            'link_id': 'org_%d' % i,
            'name': 'Organization %d' % i,
            'short_name': 'Org %d' % i,
            'description': 'Organization %d!' % i,
        })

        org_properties = {
            'name': 'Organization %d' % i,
            'org_id': 'org_%d' % i,
            'program': ndb.Key.from_old_key(gsoc2014.key()),
            'description': 'Organization %d!' % i,
        }
        org = soc_org_model.SOCOrganization(id='google/gsoc2014/org_%d' % i,
                                            **org_properties)
        org.put()
        ndb_orgs.append(org)

        # Admin (and thus mentor) for the first org
        if i == 0:
            profile.admin_for.append(org.key)
            profile.mentor_for.append(org.key)
            profile.put()

        # Mentor for the second org
        if i == 1:
            profile.mentor_for.append(org.key)
            profile.put()

    profile_properties.update({
        'id':
        gci2013.key().name() + '/' + current_user.key.id(),
        'parent':
        current_user.key,
        'program':
        ndb.Key.from_old_key(gci2013.key()),
        'admin_for': [ndb.Key.from_old_key(melange.key())],
        'mentor_for': [ndb.Key.from_old_key(melange.key())],
    })
    melange_admin = profile_model.Profile(**profile_properties)
    # TODO: add GCI orgs
    melange_admin.put()

    task_properties = {
        'status': 'Open',
        'modified_by': melange_admin.key.to_old_key(),
        'subscribers': [melange_admin.key.to_old_key()],
        'title': 'Awesomeness',
        'created_by': melange_admin.key.to_old_key(),
        'created_on': now,
        'program': gci2013,
        'time_to_complete': 1337,
        'modified_on': now,
        'org': melange.key(),
        'description': '<p>AWESOME</p>',
        'difficulty_level': DifficultyLevel.MEDIUM,
        'types': ['Code']
    }
    gci_task = GCITask(**task_properties)
    gci_task.put()

    user_properties = {
        'id': 'student',
        'account_id': '12345',
        'account': users.User(email='*****@*****.**'),
    }
    student_user = user.User(**user_properties)
    student_user.put()

    gci_delta = datetime.timedelta(days=(365 * 14))

    contact_properties = contact.Contact(email='*****@*****.**',
                                         web_page='http://www.homepage.com/',
                                         blog='http://www.blog.com/',
                                         phone='1650253000')
    contact_properties.put()

    graduation_year = datetime.date.today() + datetime.timedelta(days=365)

    student_data = soc_profile.SOCStudentData(education=education.Education(
        school_id="123",
        school_country="United States",
        expected_graduation=int(graduation_year.strftime('%Y')),
        major='Some Major',
        degree=education.Degree.UNDERGRADUATE))
    student_data.put()

    student_id = 'student'
    student_properties = {
        'id': gsoc2014.key().name() + "/" + student_id,
        'parent': student_user.key,
        'program': ndb.Key.from_old_key(gsoc2014.key()),
        'public_name': 'Student',
        'first_name': 'Student',
        'last_name': 'Student',
        'contact': contact_properties,
        'residential_address': address_properties,
        'shipping_address': address_properties,
        'birth_date': datetime.date.today() - gci_delta,
        'tee_size': profile_model.TeeSize.L,
        'tee_style': profile_model.TeeStyle.MALE,
        'gender': profile_model.Gender.MALE,
        'program_knowledge': 'Friend referral.',
        'student_data': student_data,
    }
    melange_student = profile_model.Profile(**student_properties)
    melange_student.put()

    student_id = 'student2'
    user_properties = {
        'id': student_id,
        'account_id': 'student2',
        'account': users.User(email='*****@*****.**'),
    }
    student_user2 = user.User(**user_properties)
    student_user2.put()

    student_properties.update({
        'id': gsoc2014.key().name() + "/" + student_id,
        'parent': student_user2.key,
        'first_name': 'Student 2',
        'last_name': 'Example'
    })
    melange_student2 = profile_model.Profile(**student_properties)
    melange_student2.put()

    proposal_properties = {
        'parent': melange_student.key.to_old_key(),
        'program': gsoc2014,
        'title': 'test proposal',
        'abstract': 'test abstract',
        'content': 'test content',
        'mentor': profile.key.to_old_key(),
        'status': 'accepted',
        'has_mentor': True,
        'org': ndb_orgs[0].key.to_old_key(),
        'possible_mentors': [profile.key.to_old_key()]
    }
    melange_proposal = GSoCProposal(**proposal_properties)
    melange_proposal.put()

    project_properties = {
        'title': 'test project',
        'abstract': 'test abstract',
        'status': 'accepted',
        'parent': melange_student.key.to_old_key(),
        'mentors': [profile.key.to_old_key()],
        'program': gsoc2014,
        'org': ndb_orgs[0].key.to_old_key(),
        'proposal': melange_proposal.key(),
    }
    melange_project = GSoCProject(**project_properties)
    melange_project.put()
    ndb_orgs[1].slot_allocation = 1
    ndb_orgs[1].put()

    student_data.number_of_projects = 1
    student_data.number_of_proposals = 1
    student_data.project_for_orgs = [ndb_orgs[1].key]

    melange_student.put()
    melange_student2.put()

    project_properties.update({
        'student': melange_student2,
        'title': 'test project2'
    })
    melange_project2 = GSoCProject(**project_properties)
    melange_project2.put()
    ndb_orgs[1].slot_allocation += 1
    ndb_orgs[1].put()

    student_id = 'student'
    student_properties.update({
        'id': gci2013.key().name() + '/' + student_id,
        'parent': student_user.key,
        'program': ndb.Key.from_old_key(gci2013.key()),
    })
    gci_student = profile_model.Profile(**student_properties)
    gci_student.put()

    score_properties = {
        'parent': gci_student.key.to_old_key(),
        'program': gci2013,
        'points': 5,
        'tasks': [gci_task.key()]
    }
    score = GCIScore(**score_properties)
    score.put()

    document_properties = {
        'key_name': 'site/site/home',
        'link_id': 'home',
        'scope': site,
        'prefix': 'site',
        'author': current_user.key.to_old_key(),
        'title': 'Home Page',
        'content': 'This is the Home Page',
        'modified_by': current_user.key.to_old_key(),
    }
    home_document = Document(**document_properties)
    home_document.put()

    document_properties = {
        'key_name': 'user/test/notes',
        'link_id': 'notes',
        'scope': current_user.key.to_old_key(),
        'prefix': 'user',
        'author': current_user.key.to_old_key(),
        'title': 'My Notes',
        'content': 'These are my notes',
        'modified_by': current_user.key.to_old_key(),
    }
    notes_document = Document(**document_properties)
    notes_document.put()

    site.home = home_document
    site.put()

    memcache.flush_all()

    return http.HttpResponse('Done')