Ejemplo n.º 1
0
  def context(self):
    """Returns the context for this view.
    """
    task = self.data.task

    context = {
      'page_name': '%s - %s' %(task.title, task.org.name),
      'task': task,
      'is_mentor': self.data.mentorFor(task.org),
      'task_info': TaskInformation(self.data),
    }

    if task.deadline:
      context['complete_percentage'] = timeline_helper.completePercentage(
          end=task.deadline, duration=(task.time_to_complete*3600))

    if self.data.is_visible:
      context['work_submissions'] = WorkSubmissions(self.data)
      context['comment_ids'] = [i.key().id() for i in self.data.comments]
      context['comments'] = CommentsTemplate(self.data)

    if not context['is_mentor']:
      # Programmatically change css for non-mentors, to for instance show
      # the open cog when a task can be claimed.
      if task.status == 'Closed':
        block_type = 'completed'
      elif task_logic.isOwnerOfTask(task, self.data.profile):
        block_type = 'owned'
      elif task.status in ACTIVE_CLAIMED_TASK:
        block_type = 'claimed'
      else:
        block_type = 'open'
      context['block_task_type'] = block_type

    return context
Ejemplo n.º 2
0
  def context(self):
    """Returns the context for the current template.
    """
    task = self.data.task
    mentors = [m.public_name for m in db.get(task.mentors)]
    profile = self.data.profile

    # We count everyone from the org as a mentor, the mentors property
    # is just who best to contact about this task
    context = {
        'task': task,
        'mentors': mentors,
        'is_mentor': self.data.mentorFor(task.org),
        'is_task_mentor': profile.key() in task.mentors if profile else None,
        'is_owner': task_logic.isOwnerOfTask(task, self.data.profile),
        'is_claimed': task.status in ACTIVE_CLAIMED_TASK,
        'profile': self.data.profile,
    }

    if task.deadline:
      rdays, rhrs, rmins = timeline_helper.remainingTimeSplit(task.deadline)
      context['remaining_days'] = rdays
      context['remaining_hours'] = rhrs
      context['remaining_minutes'] = rmins

    self.setButtonControls(context)

    return context
Ejemplo n.º 3
0
  def checkAccess(self):
    """Checks whether this task is visible to the public and any other checks
    if it is a POST request.
    """
    self.mutator.taskFromKwargs(comments=True, work_submissions=True)
    self.data.is_visible = self.check.isTaskVisible()

    if task_logic.updateTaskStatus(self.data.task):
      # The task logic updated the status of the task since the deadline passed
      # and the GAE task was late to run. Reload the page.
      raise RedirectRequest('')

    if self.request.method == 'POST':
      # Access checks for the different forms on this page. Note that there
      # are no elif clauses because one could add multiple GET params :).
      self.check.isProfileActive()

      if 'reply' in self.data.GET:
        # checks for posting comments
        # valid tasks and profile are already checked.
        self.check.isBeforeAllWorkStopped()
        self.check.isCommentingAllowed()

      if 'submit_work' in self.data.GET:
        self.check.isBeforeAllWorkStopped()
        if not task_logic.canSubmitWork(self.data.task, self.data.profile):
          self.check.fail(DEF_NOT_ALLOWED_TO_UPLOAD_WORK)

      if 'button' in self.data.GET:
        # check for any of the buttons
        button_name = self._buttonName()

        buttons = {}
        TaskInformation(self.data).setButtonControls(buttons)
        if not buttons.get(button_name):
          self.check.fail(DEF_NOT_ALLOWED_TO_OPERATE_BUTTON % button_name)

      if 'send_for_review' in self.data.GET:
        self.check.isBeforeAllWorkStopped()
        if not task_logic.isOwnerOfTask(self.data.task, self.data.profile) or \
            not self.data.work_submissions:
          self.check.fail(DEF_CANT_SEND_FOR_REVIEW)

      if 'delete_submission' in self.data.GET:
        self.check.isBeforeAllWorkStopped()
        id = self._submissionId()
        work = GCIWorkSubmission.get_by_id(id, parent=self.data.task)

        if not work:
          self.check.fail(DEF_NO_WORK_FOUND %id)

        time_expired = work.submitted_on - datetime.datetime.now()
        if work.user.key() != self.data.user.key() or \
            time_expired > task_logic.DELETE_EXPIRATION:
          self.check.fail(DEF_NOT_ALLOWED_TO_DELETE)
Ejemplo n.º 4
0
    def context(self):
        """Returns the context for the current template.
    """
        context = {
            'submissions': self._buildWorkSubmissionContext(),
            'download_url': self.data.redirect.id().urlOf('gci_download_work')
        }

        task = self.data.task
        is_owner = task_logic.isOwnerOfTask(task, self.data.ndb_profile)

        if is_owner:
            context['send_for_review'] = self.data.work_submissions and \
                task.status in SEND_FOR_REVIEW_ALLOWED

        deleteable = []
        if self.data.ndb_user:
            for work in self.data.work_submissions:
                work_key = ndb.Key.from_old_key(
                    task_model.GCIWorkSubmission.user.get_value_for_datastore(
                        work))
                if work_key == self.data.ndb_user.key:
                    # Ensure that it is the work from the current user in case the task
                    # got re-assigned.
                    time_expired = work.submitted_on - datetime.datetime.now()
                    if time_expired < task_logic.DELETE_EXPIRATION:
                        deleteable.append(work)
        context['deleteable'] = deleteable

        if task_logic.canSubmitWork(task, self.data.ndb_profile):
            if self.data.POST and 'submit_work' in self.data.GET:
                # File form doesn't have any POST parameters so it should not be
                # passed while reconstructing the form. So only URL form is
                # constructed from POST data
                context['work_url_form'] = WorkSubmissionURLForm(
                    data=self.data.POST)
            else:
                context['work_url_form'] = WorkSubmissionURLForm()

            # As mentioned in the comment above since there is no POST data to
            # be passed to the file form, it is constructed in the same way
            # in either cases.
            context['work_file_form'] = WorkSubmissionFileForm()
            if self.data.GET.get('file', None) == '0':
                context['work_file_form'].addFileRequiredError()

            if self.data.GET.get('ws_error', None) == '1':
                context['ws_error'] = True

            url = '%s?submit_work' % (self.data.redirect.id().urlOf(
                url_names.GCI_VIEW_TASK))
            context['direct_post_url'] = url

        return context
Ejemplo n.º 5
0
  def context(self):
    """Returns the context for the current template.
    """
    context = {
        'submissions': self._buildWorkSubmissionContext(),
        'download_url': self.data.redirect.id().urlOf('gci_download_work')
        }

    task = self.data.task
    is_owner = task_logic.isOwnerOfTask(task, self.data.ndb_profile)

    if is_owner:
      context['send_for_review'] = self.data.work_submissions and \
          task.status in SEND_FOR_REVIEW_ALLOWED

    deleteable = []
    if self.data.ndb_user:
      for work in self.data.work_submissions:
        work_key = ndb.Key.from_old_key(
            task_model.GCIWorkSubmission.user.get_value_for_datastore(work))
        if work_key == self.data.ndb_user.key:
          # Ensure that it is the work from the current user in case the task
          # got re-assigned.
          time_expired = work.submitted_on - datetime.datetime.now()
          if time_expired < task_logic.DELETE_EXPIRATION:
            deleteable.append(work)
    context['deleteable'] = deleteable

    if task_logic.canSubmitWork(task, self.data.ndb_profile):
      if self.data.POST and 'submit_work' in self.data.GET:
        # File form doesn't have any POST parameters so it should not be
        # passed while reconstructing the form. So only URL form is
        # constructed from POST data
        context['work_url_form'] = WorkSubmissionURLForm(data=self.data.POST)
      else:
        context['work_url_form'] = WorkSubmissionURLForm()

      # As mentioned in the comment above since there is no POST data to
      # be passed to the file form, it is constructed in the same way
      # in either cases.
      context['work_file_form'] = WorkSubmissionFileForm()
      if self.data.GET.get('file', None) == '0':
        context['work_file_form'].addFileRequiredError()

      if self.data.GET.get('ws_error', None) == '1':
        context['ws_error'] = True

      url = '%s?submit_work' % (
          self.data.redirect.id().urlOf(url_names.GCI_VIEW_TASK))
      context['direct_post_url'] = url

    return context
Ejemplo n.º 6
0
  def setButtonControls(self, context):
    """Enables buttons on the TaskInformation block based on status and the
    user.

    Args:
      context: Context dictionary which to write to.
    """
    profile = self.data.profile
    if not profile:
      # no buttons for someone without a profile
      return

    if self.data.timeline.allReviewsStopped():
      # no buttons after all reviews has stopped
      return

    task = self.data.task

    is_org_admin = self.data.orgAdminFor(task.org)
    is_mentor = self.data.mentorFor(task.org)
    is_student = self.data.is_student
    is_owner = task_logic.isOwnerOfTask(task, profile)

    if is_org_admin:
      can_unpublish = (task.status in CLAIMABLE) and not task.student
      context['button_unpublish'] = can_unpublish
      context['button_delete'] = not task.student

    if is_mentor:
      context['button_edit'] = task.status in \
          UNPUBLISHED + CLAIMABLE + ACTIVE_CLAIMED_TASK
      context['button_assign'] = task.status == 'ClaimRequested'
      context['button_unassign'] = task.status in ACTIVE_CLAIMED_TASK
      context['button_close'] = task.status == 'NeedsReview'
      context['button_needs_work'] = task.status == 'NeedsReview'
      context['button_extend_deadline'] = task.status in TASK_IN_PROGRESS

    if is_student:
      if not self.data.timeline.tasksClaimEnded():
        context['button_claim'] = task_logic.canClaimRequestTask(
            task, profile)

    if is_owner:
      if not self.data.timeline.tasksClaimEnded():
        context['button_unclaim'] = task.status in ACTIVE_CLAIMED_TASK

    if task.status != 'Closed':
      context['button_subscribe'] = not profile.key() in task.subscribers
      context['button_unsubscribe'] = profile.key() in task.subscribers
Ejemplo n.º 7
0
    def context(self):
        """Returns the context for the current template.
    """
        task = self.data.task
        mentors = [
            mentor.public_name for mentor in ndb.get_multi(
                map(ndb.Key.from_old_key, task.mentors))
        ]
        profile = self.data.ndb_profile

        # We count everyone from the org as a mentor, the mentors property
        # is just who best to contact about this task
        context = {
            'task':
            task,
            'mentors':
            mentors,
            'is_mentor':
            self.data.mentorFor(
                task_model.GCITask.org.get_value_for_datastore(task)),
            'is_task_mentor':
            profile.key.to_old_key() in task.mentors if profile else None,
            'is_owner':
            task_logic.isOwnerOfTask(task, self.data.ndb_profile),
            'is_claimed':
            task.status in ACTIVE_CLAIMED_TASK,
            'profile':
            self.data.ndb_profile,
        }

        if task.deadline:
            rdays, rhrs, rmins = timeline_helper.remainingTimeSplit(
                task.deadline)
            context['remaining_days'] = rdays
            context['remaining_hours'] = rhrs
            context['remaining_minutes'] = rmins

        self.setButtonControls(context)

        return context
Ejemplo n.º 8
0
    def context(self, data, check, mutator):
        """Returns the context for this view."""
        task = data.task

        context = {
            'page_name': '%s - %s' % (task.title, task.org.name),
            'task': task,
            'is_mentor': data.mentorFor(task.org.key()),
            'task_info': TaskInformation(data),
        }

        if task.deadline:
            # TODO(nathaniel): This is math - move it to a helper function.
            context[
                'complete_percentage'] = timeline_helper.completePercentage(
                    end=task.deadline, duration=(task.time_to_complete * 3600))

        if data.is_visible:
            context['work_submissions'] = WorkSubmissions(data)
            context['comment_ids'] = [i.key().id() for i in data.comments]
            context['comments'] = CommentsTemplate(data)

        if not context['is_mentor']:
            # Programmatically change css for non-mentors, to for instance show
            # the open cog when a task can be claimed.
            if task.status == 'Closed':
                block_type = 'completed'
            elif task_logic.isOwnerOfTask(task, data.ndb_profile):
                block_type = 'owned'
            elif task.status in ACTIVE_CLAIMED_TASK:
                block_type = 'claimed'
            else:
                block_type = 'open'
            context['block_task_type'] = block_type

        return context
Ejemplo n.º 9
0
    def setButtonControls(self, context):
        """Enables buttons on the TaskInformation block based on status and the
    user.

    Args:
      context: Context dictionary which to write to.
    """
        if not self.data.ndb_profile:
            # no buttons for someone without a profile
            return

        if self.data.timeline.allReviewsStopped():
            # no buttons after all reviews has stopped
            return

        task = self.data.task

        is_org_admin = self.data.orgAdminFor(task.org.key())
        is_mentor = self.data.mentorFor(task.org.key())
        is_student = self.data.ndb_profile.is_student
        is_owner = task_logic.isOwnerOfTask(task, self.data.ndb_profile)

        if is_org_admin:
            can_unpublish = task.status == task_model.OPEN and not task.student
            context['button_unpublish'] = can_unpublish

            can_publish = task.status in task_model.UNAVAILABLE
            context['button_publish'] = can_publish

            context['button_delete'] = not task.student

        if is_mentor:
            context['button_edit'] = task.status in \
                task_model.UNAVAILABLE + CLAIMABLE + ACTIVE_CLAIMED_TASK
            context['button_assign'] = task.status == 'ClaimRequested'
            context['button_unassign'] = task.status in ACTIVE_CLAIMED_TASK
            context['button_close'] = task.status == 'NeedsReview'
            context['button_needs_work'] = task.status == 'NeedsReview'
            context['button_extend_deadline'] = task.status in TASK_IN_PROGRESS

        if is_student:
            if not self.data.timeline.tasksClaimEnded():
                if not profile_logic.hasStudentFormsUploaded(
                        self.data.ndb_profile):
                    # TODO(nathaniel): make this .program() call unnecessary.
                    self.data.redirect.program()

                    context['student_forms_link'] = self.data.redirect.urlOf(
                        url_names.GCI_STUDENT_FORM_UPLOAD)
                # TODO(lennie): Separate the access check out in to different
                # methods and add a context variable to show separate messages.'
                context['button_claim'] = task_logic.canClaimRequestTask(
                    task, self.data.ndb_profile)

        if is_owner:
            if not self.data.timeline.tasksClaimEnded():
                context['button_unclaim'] = task.status in ACTIVE_CLAIMED_TASK

        if task.status != 'Closed':
            task_subscribers_keys = map(ndb.Key.from_old_key, task.subscribers)
            context['button_subscribe'] = (not self.data.ndb_profile.key
                                           in task_subscribers_keys)
            context['button_unsubscribe'] = (not self.data.ndb_profile.key
                                             in task.subscribers)
Ejemplo n.º 10
0
    def checkAccess(self, data, check, mutator):
        """Checks whether this task is visible to the public and any other checks
    if it is a POST request.
    """
        mutator.taskFromKwargs(comments=True, work_submissions=True)
        data.is_visible = check.isTaskVisible()

        if task_logic.updateTaskStatus(data.task):
            # The task logic updated the status of the task since the deadline passed
            # and the GAE task was late to run. Reload the page.
            raise exception.Redirect('')

        if data.request.method == 'POST':
            # Access checks for the different forms on this page. Note that there
            # are no elif clauses because one could add multiple GET params :).
            check.isProfileActive()

            # Tasks for non-active organizations cannot be touched
            check.isOrganizationActive(data.task.org)

            if 'reply' in data.GET:
                # checks for posting comments
                # valid tasks and profile are already checked.
                check.isBeforeAllWorkStopped()
                check.isCommentingAllowed()

            if 'submit_work' in data.GET:
                check.isBeforeAllWorkStopped()
                if not task_logic.canSubmitWork(data.task, data.ndb_profile):
                    check.fail(DEF_NOT_ALLOWED_TO_UPLOAD_WORK)

            if 'button' in data.GET:
                # check for any of the buttons
                button_name = self._buttonName(data)

                buttons = {}
                TaskInformation(data).setButtonControls(buttons)
                if not buttons.get(button_name):
                    check.fail(DEF_NOT_ALLOWED_TO_OPERATE_BUTTON % button_name)

            if 'send_for_review' in data.GET:
                check.isBeforeAllWorkStopped()
                if not task_logic.isOwnerOfTask(data.task, data.ndb_profile) or \
                    not data.work_submissions or \
                    data.task.status not in TASK_IN_PROGRESS:
                    check.fail(DEF_CANT_SEND_FOR_REVIEW)

            if 'delete_submission' in data.GET:
                check.isBeforeAllWorkStopped()
                task_id = self._submissionId(data)
                work = work_submission_model.GCIWorkSubmission.get_by_id(
                    task_id, parent=data.task)

                if not work:
                    check.fail(DEF_NO_WORK_FOUND % id)

                user_key = ndb.Key.from_old_key(
                    task_model.GCIWorkSubmission.user.get_value_for_datastore(
                        work))
                time_expired = work.submitted_on - datetime.datetime.now()
                if (user_key != data.ndb_user.key
                        or time_expired > task_logic.DELETE_EXPIRATION):
                    check.fail(DEF_NOT_ALLOWED_TO_DELETE)
Ejemplo n.º 11
0
  def setButtonControls(self, context):
    """Enables buttons on the TaskInformation block based on status and the
    user.

    Args:
      context: Context dictionary which to write to.
    """
    if not self.data.ndb_profile:
      # no buttons for someone without a profile
      return

    if self.data.timeline.allReviewsStopped():
      # no buttons after all reviews has stopped
      return

    task = self.data.task

    is_org_admin = self.data.orgAdminFor(task.org.key())
    is_mentor = self.data.mentorFor(task.org.key())
    is_student = self.data.ndb_profile.is_student
    is_owner = task_logic.isOwnerOfTask(task, self.data.ndb_profile)

    if is_org_admin:
      can_unpublish = task.status == task_model.OPEN and not task.student
      context['button_unpublish'] = can_unpublish

      can_publish = task.status in task_model.UNAVAILABLE
      context['button_publish'] = can_publish

      context['button_delete'] = not task.student

    if is_mentor:
      context['button_edit'] = task.status in \
          task_model.UNAVAILABLE + CLAIMABLE + ACTIVE_CLAIMED_TASK
      context['button_assign'] = task.status == 'ClaimRequested'
      context['button_unassign'] = task.status in ACTIVE_CLAIMED_TASK
      context['button_close'] = task.status == 'NeedsReview'
      context['button_needs_work'] = task.status == 'NeedsReview'
      context['button_extend_deadline'] = task.status in TASK_IN_PROGRESS

    if is_student:
      if not self.data.timeline.tasksClaimEnded():
        if not profile_logic.hasStudentFormsUploaded(self.data.ndb_profile):
          # TODO(nathaniel): make this .program() call unnecessary.
          self.data.redirect.program()

          context['student_forms_link'] = self.data.redirect.urlOf(
              url_names.GCI_STUDENT_FORM_UPLOAD)
        # TODO(lennie): Separate the access check out in to different
        # methods and add a context variable to show separate messages.'
        context['button_claim'] = task_logic.canClaimRequestTask(
            task, self.data.ndb_profile)

    if is_owner:
      if not self.data.timeline.tasksClaimEnded():
        context['button_unclaim'] = task.status in ACTIVE_CLAIMED_TASK

    if task.status != 'Closed':
      task_subscribers_keys = map(ndb.Key.from_old_key, task.subscribers)
      context['button_subscribe'] = (
          not self.data.ndb_profile.key in task_subscribers_keys)
      context['button_unsubscribe'] = (
          not self.data.ndb_profile.key in task.subscribers)
Ejemplo n.º 12
0
  def checkAccess(self, data, check, mutator):
    """Checks whether this task is visible to the public and any other checks
    if it is a POST request.
    """
    mutator.taskFromKwargs(comments=True, work_submissions=True)
    data.is_visible = check.isTaskVisible()

    if task_logic.updateTaskStatus(data.task):
      # The task logic updated the status of the task since the deadline passed
      # and the GAE task was late to run. Reload the page.
      raise exception.Redirect('')

    if data.request.method == 'POST':
      # Access checks for the different forms on this page. Note that there
      # are no elif clauses because one could add multiple GET params :).
      check.isProfileActive()

      # Tasks for non-active organizations cannot be touched
      check.isOrganizationActive(data.task.org)

      if 'reply' in data.GET:
        # checks for posting comments
        # valid tasks and profile are already checked.
        check.isBeforeAllWorkStopped()
        check.isCommentingAllowed()

      if 'submit_work' in data.GET:
        check.isBeforeAllWorkStopped()
        if not task_logic.canSubmitWork(data.task, data.ndb_profile):
          check.fail(DEF_NOT_ALLOWED_TO_UPLOAD_WORK)

      if 'button' in data.GET:
        # check for any of the buttons
        button_name = self._buttonName(data)

        buttons = {}
        TaskInformation(data).setButtonControls(buttons)
        if not buttons.get(button_name):
          check.fail(DEF_NOT_ALLOWED_TO_OPERATE_BUTTON % button_name)

      if 'send_for_review' in data.GET:
        check.isBeforeAllWorkStopped()
        if not task_logic.isOwnerOfTask(data.task, data.ndb_profile) or \
            not data.work_submissions or \
            data.task.status not in TASK_IN_PROGRESS:
          check.fail(DEF_CANT_SEND_FOR_REVIEW)

      if 'delete_submission' in data.GET:
        check.isBeforeAllWorkStopped()
        task_id = self._submissionId(data)
        work = work_submission_model.GCIWorkSubmission.get_by_id(
            task_id, parent=data.task)

        if not work:
          check.fail(DEF_NO_WORK_FOUND % id)

        user_key = ndb.Key.from_old_key(
            task_model.GCIWorkSubmission.user.get_value_for_datastore(work))
        time_expired = work.submitted_on - datetime.datetime.now()
        if (user_key != data.ndb_user.key or
            time_expired > task_logic.DELETE_EXPIRATION):
          check.fail(DEF_NOT_ALLOWED_TO_DELETE)