Пример #1
0
  def isStudentForSurvey(self):
    """Checks if the student can take survey for the project.
    """
    assert access_checker.isSet(self.data.profile)
    assert access_checker.isSet(self.data.project)

    self.isProjectInURLValid()

    project = self.data.project

    # check if the project belongs to the current user and if so he
    # can access the survey
    expected_profile_key = project.parent_key()
    if expected_profile_key != self.data.profile.key():
      raise AccessViolation(DEF_STUDENT_EVAL_DOES_NOT_BELONG_TO_YOU)

    # check if the project is still ongoing
    if project.status in ['invalid', 'withdrawn']:
      raise AccessViolation(DEF_EVAL_NOT_ACCESSIBLE_FOR_PROJECT)

    # check if the project has failed in a previous evaluation
    # TODO(Madhu): This still has a problem that when the project fails
    # in the final evaluation, the users will not be able to access the
    # midterm evaluation show page. Should be fixed.
    if project.status == 'failed' and project.failed_evaluations:
      failed_evals = db.get(project.failed_evaluations)
      fe_keynames = [f.grading_survey_group.grading_survey.key(
          ).id_or_name() for f in failed_evals]
      if self.data.student_evaluation.key().id_or_name() not in fe_keynames:
        raise AccessViolation(DEF_FAILED_PREVIOUS_EVAL % (
            self.data.student_evaluation.short_name.lower()))
Пример #2
0
    def isPossibleMentorForProposal(self):
        """Checks if the user is a possible mentor for the proposal in the data.
    """
        assert isSet(self.profile)
        assert isSet(self.proposal)

        return self.profile.key() in self.proposal.possible_mentors
Пример #3
0
def newCommentContext(data, comment, to_emails):
  """Sends out a notification to alert the user of a new comment.

  Args:
    data: a RequestData object
  """
  assert isSet(data.proposal)
  assert isSet(data.proposer)

  review_notification_url = data.redirect.comment(comment, full=True)
  edit_link = data.redirect.program().urlOf('edit_gsoc_profile', full=True)

  review_type = 'private' if comment.is_private else 'public'
  reviewed_name = data.proposal.title

  message_properties = {
      'review_notification_url': review_notification_url,
      'reviewer_name': comment.author.name(),
      'reviewed_name': reviewed_name,
      'review_content': comment.content,
      'review_visibility': review_type,
      'proposer_name': data.proposer.name(),
      'org': data.proposal.org.name,
      'profile_edit_link': edit_link,
      }

  # determine the subject
  subject = DEF_NEW_REVIEW_SUBJECT % message_properties

  template = DEF_NEW_REVIEW_NOTIFICATION_TEMPLATE

  if data.proposer.notify_public_comments and not comment.is_private:
    to_emails.append(data.proposer.email)

  return getContext(data, to_emails, message_properties, subject, template)
Пример #4
0
  def context(self):
    assert isSet(self.data.program)
    assert isSet(self.data.timeline)
    assert isSet(self.data.student_evaluation_record)

    record = self.data.student_evaluation_record
    student = self.data.url_profile

    context = {
        'page_name': 'Student evaluation - %s' % (student.name()),
        'student': student.name(),
        'organization': self.data.project.org.name,
        'project': self.data.project.title,
        'top_msg': LoggedInMsg(self.data, apply_link=False),
        'css_prefix': GSoCStudentEvaluationReadOnlyTemplate.Meta.css_prefix,
        }

    if record:
      context['record'] = GSoCStudentEvaluationReadOnlyTemplate(record)

    if self.data.timeline.surveyPeriod(self.data.student_evaluation):
      if self.data.role == 'student':
        context['update_link'] = self.data.redirect.survey_record(
            self.data.student_evaluation.link_id).urlOf(
            'gsoc_take_student_evaluation')
      else:
        context['submission_msg'] = ugettext(
            'Bug your student to submit the evaluation.')

    return context
Пример #5
0
  def canStudentUpdateProject(self):
    """Checks if the student can edit the project details."""
    assert access_checker.isSet(self.data.program)
    assert access_checker.isSet(self.data.timeline)

    self.isProjectInURLValid()

    # check if the timeline allows updating project
    self.isProgramVisible()
    self.acceptedStudentsAnnounced()

    # check if the current used is an active student
    self.isActiveStudent()

    # check if the project belongs to the current user
    expected_profile_key = self.data.url_project.parent_key()
    if expected_profile_key != self.data.ndb_profile.key.to_old_key():
      error_msg = access_checker.DEF_ENTITY_DOES_NOT_BELONG_TO_YOU % {
          'name': 'project'
          }
      raise exception.Forbidden(message=error_msg)

    # check if the status allows the project to be updated
    if self.data.url_project.status in ['invalid', 'withdrawn', 'failed']:
      raise exception.Forbidden(
          message=access_checker.DEF_CANNOT_UPDATE_ENTITY % {
              'name': 'project'
              })
Пример #6
0
def handledInviteContext(data):
  """Sends a message that the invite to obtain a role has been handled.

  Args:
    data: a RequestData object
  """

  assert isSet(data.invite)
  assert isSet(data.invited_profile)

  # do not send notifications if the user has opted out
  if not data.invited_profile.notify_invite_handled:
    return {}

  status = data.invite.status
  action = 'resubmitted' if status == 'pending' else status
  edit_link = data.redirect.program().urlOf('edit_gsoc_profile', full=True)

  message_properties = {
      'role_verbose' : data.invite.roleName(),
      'org': data.invite.org.name,
      'action': action,
      'profile_edit_link': edit_link,
      }

  subject = DEF_HANDLED_INVITE_SUBJECT % message_properties

  template = DEF_HANDLED_INVITE_NOTIFICATION_TEMPLATE

  to_email = data.invited_profile.email

  # from user set to None to not leak who rejected it.
  return getContext(data, [to_email], message_properties, subject, template)
Пример #7
0
    def context(self):
        """Handler to for GSoC Show Request Page HTTP get request.
    """

        assert isSet(self.data.request_entity)
        assert isSet(self.data.can_respond)
        assert isSet(self.data.organization)
        assert isSet(self.data.requester)

        show_actions = self.data.request_entity.status in [
            'pending', 'withdrawn'
        ]
        if self.data.can_respond and self.data.request_entity.status == 'rejected':
            show_actions = True

        return {
            'page_name':
            "Request to become a mentor",
            'request':
            self.data.request_entity,
            'org':
            self.data.organization,
            'actions':
            self.ACTIONS,
            'user_name':
            self.data.requester.name,
            'user_email':
            accounts.denormalizeAccount(self.data.requester.account).email(),
            'show_actions':
            show_actions,
            'can_respond':
            self.data.can_respond,
        }
Пример #8
0
  def getScores(self):
    """Gets all the scores for the proposal.
    """
    assert isSet(self.data.private_comments_visible)
    assert isSet(self.data.proposal)

    if not self.data.private_comments_visible:
      return None

    total = 0
    number = 0
    user_score = 0

    query = db.Query(GSoCScore).ancestor(self.data.proposal)
    for score in query:
      total += score.value
      number += 1

      author_key = GSoCScore.author.get_value_for_datastore(score)
      if author_key == self.data.profile.key():
        user_score = score.value

    return {
        'average': total / number if number else 0,
        'number': number,
        'total': total,
        'user_score': user_score,
        }
Пример #9
0
  def context(self):
    assert isSet(self.data.url_user)
    assert isSet(self.data.url_profile)

    # TODO(nathaniel): Eliminate this state-setting call.
    self.data.redirect.profile()

    is_banned = self.data.url_profile.status == 'invalid'

    profile_banned = ToggleButtonTemplate(
        self.data, 'on_off', 'Banned', 'user-banned',
        self.data.redirect.urlOf(self._getActionURLName()),
        checked=is_banned,
        help_text=self._getHelpText(),
        labels={
            'checked': 'Yes',
            'unchecked': 'No'})
    self.toggle_buttons.append(profile_banned)

    context = {
        'title': 'Host Actions',
        'toggle_buttons': self.toggle_buttons,
        }

    return context
Пример #10
0
    def context(self):
        assert isSet(self.data.url_user)
        assert isSet(self.data.url_profile)

        # TODO(nathaniel): Eliminate this state-setting call.
        self.data.redirect.profile()

        is_banned = self.data.url_profile.status == 'invalid'

        profile_banned = ToggleButtonTemplate(self.data,
                                              'on_off',
                                              'Banned',
                                              'user-banned',
                                              self.data.redirect.urlOf(
                                                  self._getActionURLName()),
                                              checked=is_banned,
                                              help_text=self._getHelpText(),
                                              labels={
                                                  'checked': 'Yes',
                                                  'unchecked': 'No'
                                              })
        self.toggle_buttons.append(profile_banned)

        context = {
            'title': 'Host Actions',
            'toggle_buttons': self.toggle_buttons,
        }

        return context
Пример #11
0
def handledRequestContext(data, status):
  """Sends a message that the request to get a role has been handled.

  Args:
    data: a RequestData object
  """

  assert isSet(data.request_entity)
  assert isSet(data.requester_profile)

  # do not send notifications if the user has opted out
  if not data.requester_profile.notify_request_handled:
    return {}

  edit_link = data.redirect.program().urlOf('edit_gsoc_profile', full=True)

  message_properties = {
      'role_verbose' : data.request_entity.roleName(),
      'org': data.request_entity.org.name,
      'action': status,
      'profile_edit_link': edit_link,
      }

  subject = DEF_HANDLED_REQUEST_SUBJECT % message_properties

  template = DEF_HANDLED_REQUEST_NOTIFICATION_TEMPLATE

  to_email = data.requester_profile.email

  # from user set to None to not leak who rejected it.
  return getContext(data, [to_email], message_properties, subject, template)
Пример #12
0
  def context(self, data, check, mutator):
    assert isSet(data.program)
    assert isSet(data.timeline)
    assert isSet(data.student_evaluation_record)

    record = data.student_evaluation_record
    student = data.url_ndb_profile

    org_key = project_model.GSoCProject.org.get_value_for_datastore(
        data.url_project)
    org = ndb.Key.from_old_key(org_key).get()

    context = {
        'page_name': 'Student evaluation - %s' % (student.public_name),
        'student': student.public_name,
        'organization': org.name,
        'project': data.url_project.title,
        'css_prefix': GSoCStudentEvaluationReadOnlyTemplate.Meta.css_prefix,
        }

    if record:
      context['record'] = GSoCStudentEvaluationReadOnlyTemplate(record)

    if data.timeline.surveyPeriod(data.student_evaluation):
      if data.role == 'student':
        context['update_link'] = data.redirect.survey_record(
            data.student_evaluation.link_id).urlOf(
            'gsoc_take_student_evaluation')
      else:
        context['submission_msg'] = ugettext(
            'Bug your student to submit the evaluation.')

    return context
Пример #13
0
  def isPossibleMentorForProposal(self):
    """Checks if the user is a possible mentor for the proposal in the data.
    """
    assert isSet(self.profile)
    assert isSet(self.proposal)

    return self.profile.key() in self.proposal.possible_mentors
Пример #14
0
    def canStudentUpdateProject(self):
        """Checks if the student can edit the project details."""
        assert access_checker.isSet(self.data.program)
        assert access_checker.isSet(self.data.timeline)

        self.isProjectInURLValid()

        # check if the timeline allows updating project
        self.isProgramVisible()
        self.acceptedStudentsAnnounced()

        # check if the current used is an active student
        self.isActiveStudent()

        # check if the project belongs to the current user
        expected_profile_key = self.data.url_project.parent_key()
        if expected_profile_key != self.data.ndb_profile.key.to_old_key():
            error_msg = access_checker.DEF_ENTITY_DOES_NOT_BELONG_TO_YOU % {
                'name': 'project'
            }
            raise exception.Forbidden(message=error_msg)

        # check if the status allows the project to be updated
        if self.data.url_project.status in ['invalid', 'withdrawn', 'failed']:
            raise exception.Forbidden(
                message=access_checker.DEF_CANNOT_UPDATE_ENTITY %
                {'name': 'project'})
Пример #15
0
    def _acceptRequest(self):
        """Accepts a request.
    """
        assert isSet(self.data.organization)
        assert isSet(self.data.requester_profile)

        request_key = self.data.request_entity.key()
        profile_key = self.data.requester_profile.key()
        organization_key = self.data.organization.key()

        def accept_request_txn():
            request = db.get(request_key)
            profile = db.get(profile_key)

            request.status = "accepted"
            profile.is_mentor = True
            profile.mentor_for.append(organization_key)
            profile.mentor_for = list(set(profile.mentor_for))

            profile.put()
            request.put()

            context = notifications.handledRequestContext(self.data, request.status)
            sub_txn = mailer.getSpawnMailTaskTxn(context, parent=request)
            # TODO(SRabbelier): just call as soon as we make User Request's parent
            db.run_in_transaction(sub_txn)

        accept_request_txn()
Пример #16
0
    def context(self, data, check, mutator):
        assert access_checker.isSet(data.conversation)
        assert access_checker.isSet(data.user)

        # Marks the conversation as "read" for the user
        gciconversation_logic.markAllReadForConversationAndUser(
            data.conversation.key, ndb.Key.from_old_key(data.user.key())
        )

        num_users = gciconversation_logic.queryConversationUserForConversation(data.conversation.key).count()

        messages = gcimessage_logic.queryForConversation(data.conversation.key).order(
            gcimessage_model.GCIMessage.sent_on
        )

        for message in messages:
            message.author_name = db.get(ndb.Key.to_old_key(message.author)).name
            message.sent_on_relative = timeformat_helper.relativeTime(message.sent_on)
            message.sent_on_ctime = message.sent_on.ctime()

        return {
            "page_name": data.conversation.subject,
            "conversation": data.conversation,
            "num_users": num_users,
            "messages": messages,
            "user_list": UserList(data),
            "user_actions": UserActions(data),
            "reply_action": urlresolvers.reverse(url_names.GCI_CONVERSATION_REPLY, kwargs=data.kwargs),
        }
Пример #17
0
    def getScores(self):
        """Gets all the scores for the proposal.
    """
        assert isSet(self.data.private_comments_visible)
        assert isSet(self.data.proposal)

        if not self.data.private_comments_visible:
            return None

        total = 0
        number = 0
        user_score = 0

        query = db.Query(GSoCScore).ancestor(self.data.proposal)
        for score in query:
            total += score.value
            number += 1

            author_key = GSoCScore.author.get_value_for_datastore(score)
            if author_key == self.data.profile.key():
                user_score = score.value

        return {
            'average': total / number if number else 0,
            'number': number,
            'total': total,
            'user_score': user_score,
        }
Пример #18
0
    def context(self):
        """See soc.views.template.Template.context for full specification."""
        assert access_checker.isSet(self.data.conversation)
        assert access_checker.isSet(self.data.user)

        query = gciconversation_logic.queryConversationUserForConversationAndUser(
            self.data.conversation.key, ndb.Key.from_old_key(self.data.user.key())
        )
        conv_user_results = query.fetch(1)
        assert conv_user_results

        conv_user = conv_user_results[0]

        self.data.redirect.id()

        url = self.data.redirect.urlOf(url_names.GCI_CONVERSATION_NOTIFICATION_TOGGLE)

        enable_notifications = toggle_button_view.ToggleButtonTemplate(
            self.data,
            "on_off",
            translation.ugettext("Enable Notifications"),
            "notifications-enabled",
            url,
            checked=conv_user.enable_notifications,
            help_text=self.DEF_ENABLE_NOTIFICATIONS_HELP,
            labels={"checked": "Yes", "unchecked": "No"},
        )
        self.toggle_buttons.append(enable_notifications)

        return {"title": translation.ugettext("Conversation Actions"), "toggle_buttons": self.toggle_buttons}
Пример #19
0
  def context(self):
    assert isSet(self.data.program)
    assert isSet(self.data.url_profile)
    assert isSet(self.data.url_user)

    user = self.data.url_user
    profile = self.data.url_profile
    program = self.data.program
    r = self.redirect.profile()

    links = []

    for project in GSoCProject.all().ancestor(profile):
      r.project(project.key().id())
      links.append(r.urlOf('gsoc_project_details', full=True))

    r = self.redirect.profile()

    return {
        'page_name': '%s Profile - %s' % (program.short_name, profile.name()),
        'program_name': program.name,
        'form_top_msg': LoggedInMsg(self.data, apply_link=False),
        'user': profile_show.UserReadOnlyTemplate(user),
        'profile': GSoCProfileReadOnlyTemplate(profile),
        'links': links,
        'css_prefix': GSoCProfileReadOnlyTemplate.Meta.css_prefix,
        'submit_tax_link': r.urlOf('gsoc_tax_form_admin'),
        'submit_enrollment_link': r.urlOf('gsoc_enrollment_form_admin'),
        }
Пример #20
0
    def context(self):
        """Handler to for GSoC Show Request Page HTTP get request.
    """
        assert isSet(self.data.request_entity)
        assert isSet(self.data.can_respond)
        assert isSet(self.data.organization)
        assert isSet(self.data.requester)

        # This code is dupcliated between request and invite
        status = self.data.request_entity.status

        can_accept = can_reject = can_withdraw = can_resubmit = False

        if self.data.can_respond:
            # admin speaking
            if status == "pending":
                can_accept = True
                can_reject = True
            if status == "rejected":
                can_accept = True
        else:
            # requester speaking
            if status == "withdrawn":
                can_resubmit = True
            if status == "pending":
                can_withdraw = True

        show_actions = can_accept or can_reject or can_withdraw or can_resubmit

        org_key = self.data.organization.key()
        status_msg = None

        if self.data.requester_profile.key() == self.data.profile.key():
            if org_key in self.data.requester_profile.org_admin_for:
                status_msg = "You are now an organization administrator for this organization."
            elif org_key in self.data.requester_profile.mentor_for:
                status_msg = "You are now a mentor for this organization."
        else:
            if org_key in self.data.requester_profile.org_admin_for:
                status_msg = "This user is now an organization administrator with your organization."
            elif org_key in self.data.requester_profile.mentor_for:
                status_msg = "This user is now a mentor with your organization."

        return {
            "page_name": "Request to become a mentor",
            "request": self.data.request_entity,
            "org": self.data.organization,
            "actions": self.ACTIONS,
            "status_msg": status_msg,
            "user_name": self.data.requester_profile.name(),
            "user_link_id": self.data.requester.link_id,
            "user_email": accounts.denormalizeAccount(self.data.requester.account).email(),
            "show_actions": show_actions,
            "can_accept": can_accept,
            "can_reject": can_reject,
            "can_withdraw": can_withdraw,
            "can_resubmit": can_resubmit,
        }
Пример #21
0
  def isPossibleMentorForProposal(self, mentor_profile=None):
    """Checks if the user is a possible mentor for the proposal in the data.
    """
    assert isSet(self.profile)
    assert isSet(self.proposal)

    profile = mentor_profile if mentor_profile else self.profile

    return profile.key() in self.proposal.possible_mentors
Пример #22
0
  def isUserInConversation(self):
    """Checks if the user is part of a conversation."""
    assert access_checker.isSet(self.data.conversation)
    assert access_checker.isSet(self.data.user)

    query = gciconversation_logic.queryConversationUserForConversationAndUser(
        self.data.conversation.key, ndb.Key.from_old_key(self.data.user.key()))

    if query.count() == 0:
      raise exception.Forbidden(message=DEF_NOT_IN_CONVERSATION)
Пример #23
0
  def checkAccess(self):
    self.mutator.projectFromKwargs()
    self.mutator.mentorEvaluationFromKwargs()
    self.mutator.mentorEvaluationRecordFromKwargs()

    assert isSet(self.data.project)
    assert isSet(self.data.mentor_evaluation)

    self.check.isProfileActive()
    self.check.isMentorForSurvey()
Пример #24
0
  def mentorEvaluationRecordFromKwargs(self):
    """Sets the mentor evaluation record in RequestData object.
    """
    assert access_checker.isSet(self.data.mentor_evaluation)
    assert access_checker.isSet(self.data.project)

    self.data.organization = self.data.project.org

    q = GSoCGradingProjectSurveyRecord.all()
    q.filter('project', self.data.project)
    q.filter('survey', self.data.mentor_evaluation)
    self.data.mentor_evaluation_record = q.get()
Пример #25
0
    def post(self):
        assert isSet(self.data.proposer)
        assert isSet(self.data.proposal)

        comment = self.createCommentFromForm()
        if comment:
            self.redirect.review(self.data.proposal.key().id(),
                                 self.data.proposer.link_id)
            self.redirect.to('review_gsoc_proposal')
        else:
            # TODO: probably we want to handle an error somehow
            pass
Пример #26
0
  def _acceptRequest(self):
    """Accepts a request.
    """

    assert isSet(self.data.organization)
    assert isSet(self.data.requester_profile)

    self.data.request_entity.status = 'accepted'
    self.data.requester_profile.mentor_for.append(self.data.organization.key())

    self.data.requester_profile.put()
    self.data.request_entity.put()
Пример #27
0
    def createOrUpdateScore(self, value):
        """Creates a new score or updates a score if there is already one
    posted by the current user.

    If the value passed in is 0 then the Score of the user will be removed and
    None will be returned.

    Args:
      value: The value of the score the user gave as an integer.

    Returns:
      The score entity that was created/updated or None if value is 0.
    """
        assert isSet(self.data.proposal)
        assert isSet(self.data.proposal_org)

        max_score = self.data.proposal_org.max_score

        if value < 0 or value > max_score:
            raise BadRequest("Score must not be higher than %d" % max_score)

        query = db.Query(GSoCScore)
        query.filter("author = ", self.data.profile)
        query.ancestor(self.data.proposal)

        def update_score_trx():
            delta = 0

            # update score entity
            score = query.get()
            if not score:
                if not value:
                    return
                old_value = 0
                score = GSoCScore(parent=self.data.proposal, author=self.data.profile, value=value)
                score.put()
                delta = 1
            else:
                old_value = score.value
                if not value:
                    delta = -1
                    score.delete()
                else:
                    score.value = value
                    score.put()

            # update total score for the proposal
            proposal = db.get(self.data.proposal.key())
            proposal.score += value - old_value
            proposal.nr_scores += delta
            proposal.put()

        db.run_in_transaction(update_score_trx)
Пример #28
0
  def post(self):
    assert isSet(self.data.proposer)
    assert isSet(self.data.proposal)

    comment = self.createCommentFromForm()
    if comment:
      self.redirect.review(self.data.proposal.key().id(),
                           self.data.proposer.link_id)
      self.redirect.to('review_gsoc_proposal')
    else:
      # TODO: probably we want to handle an error somehow
      pass
Пример #29
0
    def _acceptRequest(self):
        """Accepts a request.
    """

        assert isSet(self.data.organization)
        assert isSet(self.data.requester_profile)

        self.data.request_entity.status = 'accepted'
        self.data.requester_profile.mentor_for.append(
            self.data.organization.key())

        self.data.requester_profile.put()
        self.data.request_entity.put()
Пример #30
0
  def canUserEditTask(self):
    """Returns True/False depending on whether the currently logged in user
    can edit the task.
    """
    assert access_checker.isSet(self.data.task)
    assert access_checker.isSet(self.data.mentor_for)

    task = self.data.task

    valid_org_keys = [o.key() for o in self.data.mentor_for]
    if task.org.key() not in valid_org_keys:
      return False

    return True
Пример #31
0
  def canCreateTask(self):
    """Checks whether the currently logged in user can edit the task.
    """
    assert access_checker.isSet(self.data.organization)
    assert access_checker.isSet(self.data.mentor_for)

    valid_org_keys = [o.key() for o in self.data.mentor_for]
    if self.data.organization.key() not in valid_org_keys:
      raise AccessViolation(DEF_NO_TASK_CREATE_PRIV % (
          self.data.organization.name))

    if (request_data.isBefore(self.data.timeline.orgsAnnouncedOn()) \
        or self.data.timeline.tasksClaimEnded()):
      raise AccessViolation(access_checker.DEF_PAGE_INACTIVE)
Пример #32
0
    def checkAccess(self):
        self.check.isProgramVisible()
        self.check.isProfileActive()
        self.mutator.proposalFromKwargs()
        self.mutator.commentVisible()
        assert isSet(self.data.proposer)
        assert isSet(self.data.proposal_org)

        # check if the comment is given by the author of the proposal
        if self.data.proposer.key() == self.data.profile.key():
            self.data.public_only = True
            return

        self.data.public_only = False
        self.check.isMentorForOrganization(self.data.proposal_org)
Пример #33
0
def updatedProposalContext(data, proposal, to_emails):
    """Sends out a notification to alert the user of an updated proposal.

  Args:
    data: a RequestData object
  """
    assert isSet(data.organization)

    proposal_notification_url = links.ABSOLUTE_LINKER.userId(
        data.ndb_profile.key,
        proposal.key().id(), url_names.PROPOSAL_REVIEW)
    edit_profile_url = links.ABSOLUTE_LINKER.program(
        data.program, urls.UrlNames.PROFILE_EDIT, secure=True)

    message_properties = {
        'proposal_notification_url': proposal_notification_url,
        'proposer_name': data.ndb_profile.public_name,
        'proposal_name': proposal.title,
        'proposal_content': proposal.content,
        'org': data.organization.name,
        'profile_edit_link': edit_profile_url,
    }

    # determine the subject
    subject = DEF_UPDATED_PROPOSAL_SUBJECT % message_properties

    template = DEF_UPDATED_PROPOSAL_NOTIFICATION_TEMPLATE

    return getContext(data.site, data.program, to_emails, message_properties,
                      subject, template)
Пример #34
0
  def checkAccess(self, data, check, mutator):
    mutator.studentEvaluationFromKwargs()
    mutator.studentEvaluationRecordFromKwargs()

    assert isSet(data.student_evaluation)

    if user_logic.isHostForProgram(data.ndb_user, data.program.key()):
      return

    show_url = data.redirect.survey_record(
          data.student_evaluation.link_id).urlOf(
          'gsoc_show_student_evaluation')
    check.isStudentSurveyActive(
        data.student_evaluation, data.url_ndb_profile, show_url=show_url)

    check.isProfileActive()
    # TODO(dcrodman): When GSoCProject is converted to NDB, this Key
    # conversion will need to be removed.
    org_key = project_model.GSoCProject.org.get_value_for_datastore(
        data.url_project)
    org_key = ndb.Key.from_old_key(org_key)

    if data.orgAdminFor(org_key):
      raise exception.Redirect(show_url)

    check.canUserTakeSurvey(data.student_evaluation, 'student')
    check.isStudentForSurvey()
Пример #35
0
  def context(self):
    """Handler to for GSoC Organization Home page HTTP get request.
    """
    current_timeline = timeline_logic.getCurrentTimeline(
        self.data.program_timeline, self.data.org_app)

    assert isSet(self.data.organization)
    organization = self.data.organization

    context = {
        'page_name': '%s - Homepage' % organization.short_name,
        'organization': organization,
        'contact': Contact(self.data),
        'tags': organization.tags_string(organization.org_tag),
        'apply': Apply(self.data, current_timeline),
    }

    if self.data.orgAdminFor(organization):
      r = self.redirect
      r.organization(organization)
      context['edit_link'] =  r.urlOf('edit_gsoc_org_profile')
      context['invite_admin_link'] = r.invite('org_admin').urlOf('gsoc_invite')
      context['invite_mentor_link'] = r.invite('mentor').urlOf('gsoc_invite')

    if self.data.timeline.studentsAnnounced():
      context['project_list'] = ProjectList(self.request, self.data)

    return context
Пример #36
0
  def clean_link_id(self):
    """Accepts link_id of users which may be invited.
    """

    assert isSet(self.request_data.organization)

    invited_user = None

    link_id_cleaner = cleaning.clean_link_id('link_id')

    try:
      link_id = link_id_cleaner(self)
    except djangoforms.ValidationError, e:
      if e.code != 'invalid':
        raise

      email_cleaner = cleaning.clean_email('link_id')

      try:
        email_address = email_cleaner(self)
      except djangoforms.ValidationError, e:
        if e.code != 'invalid':
          raise
        msg = ugettext(u'Enter a valid link_id or email address.')
        raise djangoforms.ValidationError(msg, code='invalid')
Пример #37
0
  def post(self, data, check, mutator):
    """Get handler for the code sample delete file."""
    assert isSet(data.url_project)

    try:
      id_value = int(data.request.POST['id'])
      code_sample = GSoCCodeSample.get_by_id(id_value, data.url_project)

      if not code_sample:
        raise exception.BadRequest(message='Requested code sample not found')

      upload_of_work = code_sample.upload_of_work

      def txn():
        code_sample.delete()
        if upload_of_work:
          # this is executed outside of transaction
          upload_of_work.delete()

        if data.url_project.countCodeSamples() <= 1:
          project = GSoCProject.get(data.url_project.key())
          project.code_samples_submitted = False
          project.put()

      db.run_in_transaction(txn)

      url = links.LINKER.userId(
          data.url_profile.key(), data.url_project.key().id(),
          url_names.GSOC_PROJECT_UPDATE)
      return http.HttpResponseRedirect(url)
    except KeyError:
      raise exception.BadRequest(message='id argument missing in POST data')
    except ValueError:
      raise exception.BadRequest(
          message='id argument in POST data is not a number')
Пример #38
0
  def checkCanUserEditTask(self):
    """Checks whether the currently logged in user can edit the task.
    """
    assert access_checker.isSet(self.data.task)

    if not self.canUserEditTask():
      raise AccessViolation(DEF_NO_TASK_EDIT_PRIV % (self.data.task.org.name))
Пример #39
0
def updatedProposalContext(data, proposal, to_emails):
  """Sends out a notification to alert the user of an updated proposal.

  Args:
    data: a RequestData object
  """
  assert isSet(data.organization)

  proposal_notification_url = links.ABSOLUTE_LINKER.userId(
      data.ndb_profile.key, proposal.key().id(), url_names.PROPOSAL_REVIEW)
  edit_profile_url = links.ABSOLUTE_LINKER.program(
      data.program, urls.UrlNames.PROFILE_EDIT, secure=True)

  message_properties = {
      'proposal_notification_url': proposal_notification_url,
      'proposer_name': data.ndb_profile.public_name,
      'proposal_name': proposal.title,
      'proposal_content': proposal.content,
      'org': data.organization.name,
      'profile_edit_link': edit_profile_url,
  }

  # determine the subject
  subject = DEF_UPDATED_PROPOSAL_SUBJECT % message_properties

  template = DEF_UPDATED_PROPOSAL_NOTIFICATION_TEMPLATE

  return getContext(
      data.site, data.program, to_emails, message_properties, subject, template)
Пример #40
0
    def context(self, data, check, mutator):
        context = super(GCIProfileShowAdminPage,
                        self).context(data, check, mutator)
        assert access_checker.isSet(data.url_profile.student_info)

        profile = data.url_profile
        student_info = profile.student_info
        if student_info:
            if student_info.consent_form_verified:
                context['verify_consent_form_init'] = 'unchecked'
            else:
                context['verify_consent_form_init'] = 'checked'

            if student_info.student_id_form_verified:
                context['verify_student_id_form_init'] = 'unchecked'
            else:
                context['verify_student_id_form_init'] = 'checked'

            # TODO(nathaniel): Eliminate this state-setting call.
            data.redirect.profile(profile.link_id)
            context['student_task_link'] = data.redirect.urlOf(
                url_names.GCI_STUDENT_TASKS)

            context['user'] = self._getUserReadOnlyTemplate(data.url_user)

        return context
Пример #41
0
 def organization(self, organization=None):
   """Sets the kwargs for an url_patterns.ORG redirect."""
   if not organization:
     assert access_checker.isSet(self._data.organization)
     organization = self._data.organization
   self.program()
   self.kwargs['organization'] = organization.link_id
Пример #42
0
  def isTaskVisible(self):
    """Checks if the task is visible to the public.

    Returns: True if the task is visible, if the task is not visible
        but the user can edit the task, False.
    """
    assert access_checker.isSet(self.data.task)

    # TODO(nathaniel): Yep, this is weird.
    can_edit = False
    try:
      self.checkCanUserEditTask()
      self.checkHasTaskEditableStatus()
      self.checkTimelineAllowsTaskEditing()
      can_edit = True
    except exception.UserError:
      pass

    if not self.data.timeline.tasksPubliclyVisible():
      if can_edit:
        return False
      period = self.data.timeline.tasksPubliclyVisibleOn()
      raise exception.Forbidden(
          message=access_checker.DEF_PAGE_INACTIVE_BEFORE % period)

    if not self.data.task.isAvailable():
      if can_edit:
        return False
      raise exception.Forbidden(message=access_checker.DEF_PAGE_INACTIVE)

    return True
Пример #43
0
  def checkCanUserEditTask(self):
    """Checks whether the currently logged in user can edit the task."""
    assert access_checker.isSet(self.data.task)

    if not self.canUserEditTask():
      raise exception.Forbidden(
          message=DEF_NO_TASK_EDIT_PRIV % (self.data.task.org.name))
Пример #44
0
    def post(self, data, check, mutator):
        """Handles the POST request when editing a GradingRecord."""
        assert isSet(data.record)

        record_form = GradingRecordForm(data=data.POST)

        if not record_form.is_valid():
            return self.get(data, check, mutator)

        decision = record_form.cleaned_data['grade_decision']
        locked = record_form.cleaned_data['locked']

        record = data.record
        record.grade_decision = decision
        record.locked = locked
        record.put()

        grading_record.updateProjectsForGradingRecords([record])

        # pass along these params as POST to the new task
        task_params = {'record_key': str(record.key())}
        task_url = '/tasks/gsoc/grading_record/mail_result'

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

        data.redirect.id(record.grading_survey_group.key().id_or_name())
        return data.redirect.to('gsoc_grading_record_overview')
Пример #45
0
    def checkAccess(self, data, check, mutator):
        mutator.mentorEvaluationFromKwargs()
        mutator.mentorEvaluationRecordFromKwargs()

        assert isSet(data.mentor_evaluation)

        check.isProfileActive()
        check.isMentorForSurvey()
Пример #46
0
    def getComments(self):
        """Gets all the comments for the proposal visible by the current user.
    """
        assert isSet(self.data.private_comments_visible)
        assert isSet(self.data.proposal)

        public_comments = []
        private_comments = []

        query = db.Query(GSoCComment).ancestor(self.data.proposal)
        for comment in query:
            if not comment.is_private:
                public_comments.append(comment)
            elif self.data.private_comments_visible:
                private_comments.append(comment)

        return public_comments, private_comments
Пример #47
0
    def checkAccess(self, data, check, mutator):
        if not data.org_app:
            raise exception.NotFound(message=access_checker.DEF_NO_ORG_APP %
                                     data.program.name)
        mutator.orgAppRecordIfIdInKwargs()
        assert access_checker.isSet(data.org_app_record)

        check.canViewOrgApp()
Пример #48
0
    def post(self):
        """Handler to for GSoC Show Request Page HTTP post request.
    """

        assert isSet(self.data.action)
        assert isSet(self.data.request_entity)

        if self.data.action == self.ACTIONS['accept']:
            self._acceptRequest()
        elif self.data.action == self.ACTIONS['reject']:
            self._rejectRequest()
        elif self.data.action == self.ACTIONS['resubmit']:
            self._resubmitRequest()
        elif self.data.action == self.ACTIONS['withdraw']:
            self._withdrawRequest()

        self.redirect.program()
        self.redirect.to('gsoc_dashboard')
Пример #49
0
    def toggleNotificationsEnabled(self, data, value):
        """Makes email notifications enabled or disabled.

    Args:
      data: A RequestData describing the current request.
      value: can be either "checked" or "unchecked".
    """
        assert access_checker.isSet(data.conversation)
        assert access_checker.isSet(data.user)

        query = gciconversation_logic.queryConversationUserForConversationAndUser(
            data.conversation.key, ndb.Key.from_old_key(data.user.key()))
        conv_user_results = query.fetch(1)
        assert conv_user_results
        conv_user = conv_user_results[0]

        if value != 'checked' and value != 'unchecked':
            raise exception.BadRequest(
                message='Invalid post data. Value must be checked or unchecked.'
            )
        if value == 'checked' and not conv_user.enable_notifications:
            raise exception.BadRequest(
                message='Notifications were already disabled.')
        if value == 'unchecked' and conv_user.enable_notifications:
            raise exception.BadRequest(
                message='Notifications were already enabled.')

        conv_user_key = conv_user.key

        # TODO(nathaniel): Remove the suppression on the following line when
        # https://bitbucket.org/logilab/pylint.org/issue/6/false-positive-no
        # is fixed.
        @ndb.transactional(xg=True)  # pylint: disable=no-value-for-parameter
        def set_notifications_enabled_txn():
            # transactionally get latest GCIConversationUser
            conv_user = conv_user_key.get()
            if value == 'unchecked':
                conv_user.enable_notifications = True
            elif value == 'checked':
                conv_user.enable_notifications = False

            conv_user.put()

        set_notifications_enabled_txn()
Пример #50
0
  def jsonContext(self):
    """Handler for JSON requests.
    """
    assert isSet(self.data.organization)
    list_content = ProjectList(self.request, self.data).getListData()

    if not list_content:
      raise AccessViolation(
          'You do not have access to this data')
    return list_content.content()
Пример #51
0
  def program(self, program=None):
    """Sets kwargs for an url_patterns.PROGRAM redirect."""
    if not program:
      assert access_checker.isSet(self._data.program)
      program = self._data.program

    self._clear()

    self.kwargs['sponsor'] = program_logic.getSponsorKey(program).name()
    self.kwargs['program'] = program.link_id
Пример #52
0
    def context(self, data, check, mutator):
        """See soc.views.base.RequestHandler.context for specification."""
        assert isSet(data.program)
        assert isSet(data.user)

        profile = self._getProfile(data)
        program = data.program

        user_template = self._getUserReadOnlyTemplate(data.user)
        profile_template = self._getProfileReadOnlyTemplate(profile)
        css_prefix = profile_template.Meta.css_prefix

        return {
            'page_name':
            '%s Profile - %s' % (program.short_name, profile.name()),
            'program_name': program.name,
            'user': user_template,
            'profile': profile_template,
            'css_prefix': css_prefix,
            'tabs': self._getTabs(data)
        }
Пример #53
0
    def checkAccess(self, data, check, mutator):
        mutator.mentorEvaluationFromKwargs()
        mutator.mentorEvaluationRecordFromKwargs()

        assert isSet(data.mentor_evaluation)

        show_url = data.redirect.survey_record(
            data.mentor_evaluation.link_id).urlOf(
                'gsoc_show_mentor_evaluation')
        check.isSurveyActive(data.mentor_evaluation, show_url)
        check.canUserTakeSurvey(data.mentor_evaluation, 'org')
        check.isMentorForSurvey()
Пример #54
0
    def createReplyFromForm(self, data):
        """Creates a new message based on the data inserted into the form.

    Args:
      data: A RequestData object for the current request.

    Returns:
      A newly created message entity.
    """
        assert access_checker.isSet(data.conversation)
        assert access_checker.isSet(data.user)

        content = cleaning.sanitize_html_string(
            data.request.POST['content'].strip())

        if len(html.strip_tags(content).strip()) == 0:
            raise exception.Forbidden(message=DEF_BLANK_MESSAGE)

        author = ndb.Key.from_old_key(data.user.key())

        return gciconversation_logic.createMessage(data.conversation.key,
                                                   author, content)
Пример #55
0
    def context(self, data, check, mutator):
        assert access_checker.isSet(data.conversation)
        assert access_checker.isSet(data.user)

        # Marks the conversation as "read" for the user
        gciconversation_logic.markAllReadForConversationAndUser(
            data.conversation.key, ndb.Key.from_old_key(data.user.key()))

        num_users = (
            gciconversation_logic.queryConversationUserForConversation(
                data.conversation.key).count())

        messages = gcimessage_logic.queryForConversation(
            data.conversation.key).order(gcimessage_model.GCIMessage.sent_on)

        for message in messages:
            message.author_name = db.get(ndb.Key.to_old_key(
                message.author)).name
            message.sent_on_relative = timeformat_helper.relativeTime(
                message.sent_on)
            message.sent_on_ctime = message.sent_on.ctime()

        return {
            'page_name':
            data.conversation.subject,
            'conversation':
            data.conversation,
            'num_users':
            num_users,
            'messages':
            messages,
            'user_list':
            UserList(data),
            'user_actions':
            UserActions(data),
            'reply_action':
            urlresolvers.reverse(url_names.GCI_CONVERSATION_REPLY,
                                 kwargs=data.kwargs)
        }
Пример #56
0
    def createCommentFromForm(self):
        """Creates a new comment based on the data inserted in the form.

    Returns:
      a newly created comment entity or None
    """

        assert isSet(self.data.public_only)
        assert isSet(self.data.proposal)

        if self.data.public_only:
            comment_form = CommentForm(self.data.request.POST)
        else:
            # this form contains checkbox for indicating private/public comments
            comment_form = PrivateCommentForm(self.data.request.POST)

        if not comment_form.is_valid():
            return None

        comment_form.cleaned_data['author'] = self.data.profile

        return comment_form.create(commit=True, parent=self.data.proposal)
Пример #57
0
    def mentorEvaluationRecordFromKwargs(self):
        """Sets the mentor evaluation record in RequestData object.
    """
        assert access_checker.isSet(self.data.mentor_evaluation)

        # TODO(daniel): get rid of this ugly mutation!
        org_key = project_model.GSoCProject.org.get_value_for_datastore(
            self.data.url_project)
        self.data._url_ndb_org = ndb.Key.from_old_key(org_key).get()

        q = GSoCGradingProjectSurveyRecord.all()
        q.filter('project', self.data.url_project)
        q.filter('survey', self.data.mentor_evaluation)
        self.data.mentor_evaluation_record = q.get()
Пример #58
0
  def userOrg(self, user=None, organization=None):
    """Sets args for an url_patterns.USER_ORG redirect."""
    if not user:
      assert 'user' in self._data.kwargs
      user = self._data.kwargs['user']

    if not organization:
      assert access_checker.isSet(self._data.organization)
      organization = self._data.organization

    self.program()
    self.kwargs['user'] = user
    self.kwargs['organization'] = organization.link_id
    return self
Пример #59
0
    def canOrgAdminUpdateProject(self):
        """Checks if the organization admin can edit the project details."""
        assert access_checker.isSet(self.data.program)
        assert access_checker.isSet(self.data.timeline)

        self.isProjectInURLValid()

        # check if the timeline allows updating project
        self.isProgramVisible()
        self.acceptedStudentsAnnounced()

        # check if the person is an organization admin for the organization
        # to which the project was assigned
        org_key = ndb.Key.from_old_key(
            project_model.GSoCProject.org.get_value_for_datastore(
                self.data.url_project))
        self.isOrgAdminForOrganization(org_key)

        # check if the status allows the project to be updated
        if self.data.url_project.status in ['invalid', 'withdrawn', 'failed']:
            raise exception.Forbidden(
                message=access_checker.DEF_CANNOT_UPDATE_ENTITY %
                {'name': 'project'})