示例#1
0
def getSubscribedEmails(conversation, exclude=None):
    """Gets the list of email addresses for all users subscribed to a
  conversation.

  Args:
    conversation: Key (ndb) of GCIConversation.
    exclude: Keys (ndb) of Users that, if given, will not be in the set of
             emails.

  Returns:
    Set of email addresses.
  """
    conversation_ent = conversation.get()
    conv_users = queryConversationUserForConversation(conversation)
    program_key = ndb.Key.to_old_key(conversation_ent.program)
    addresses = set()

    for conv_user in conv_users:
        if conv_user.enable_notifications and (not exclude or conv_user.user
                                               not in exclude):
            profile = profile_logic.getProfileForUsername(
                conv_user.user.id(), program_key)

            if not profile:
                raise Exception(
                    'Could not find GCIProfile for user %s and program. %s' %
                    (conv_user.name, program_key.name()))

            addresses.add(profile.contact.email)

    return addresses
示例#2
0
def getSubscribedEmails(conversation, exclude=None):
  """Gets the list of email addresses for all users subscribed to a
  conversation.

  Args:
    conversation: Key (ndb) of GCIConversation.
    exclude: Keys (ndb) of Users that, if given, will not be in the set of
             emails.

  Returns:
    Set of email addresses.
  """
  conversation_ent = conversation.get()
  conv_users = queryConversationUserForConversation(conversation)
  program_key = ndb.Key.to_old_key(conversation_ent.program)
  addresses = set()

  for conv_user in conv_users:
    if conv_user.enable_notifications and (
        not exclude or conv_user.user not in exclude):
      profile = profile_logic.getProfileForUsername(
          conv_user.user.id(), program_key)

      if not profile:
        raise Exception('Could not find GCIProfile for user %s and program. %s'
            % (conv_user.name, program_key.name()))

      addresses.add(profile.contact.email)

  return addresses
示例#3
0
def doesUserBelongInConversation(
    user, conversation, ignore_auto_update_users=True):
  """Decides whether the user in a conversation belongs in the conversation.

  If ignore_auto_update_users is False, True will be returned if the
  conversation's auto_update_users is False.

  Args:
    user: Key (ndb) of a User.
    conversation: Key (ndb) of a GCIConversation.
    ignore_auto_update_users: Whether this should ignore the conversation's
                              auto_update_users property.

  Returns:
    Whether the user belongs in the conversation. If the conversation's
    recipients_type is 'User', True is always returned. Also returns true if
    the user is the conversation's creator.
  """
  conversation_ent = conversation.get()

  if not conversation_ent.auto_update_users and not ignore_auto_update_users:
    return True

  if conversation_ent.creator == user:
    return True

  profile = profile_logic.getProfileForUsername(
      user.id(), conversation_ent.program.to_old_key())

  if not profile:
    raise Exception('Could not find GCIProfile for user and program.')

  if conversation_ent.recipients_type == conversation_model.PROGRAM:
    if conversation_ent.include_admins and profile.is_admin:
      return True
    elif conversation_ent.include_mentors and profile.is_mentor:
      return True
    elif conversation_ent.include_students and profile.is_student:
      return True
    elif (profile.is_student and conversation_ent.include_winners
        and profile.student_data.is_winner):
      return True
    else:
      return False
  elif conversation_ent.recipients_type == conversation_model.ORGANIZATION:
    if (conversation_ent.include_admins and
        conversation_ent.organization in profile.admin_for):
      return True
    elif (conversation_ent.include_mentors and
        conversation_ent.organization in profile.mentor_for):
      return True
    elif (profile.is_student and conversation_ent.include_winners
        and profile.student_data.is_winner and
        conversation_ent.organization == profile.student_data.winner_for):
      return True
    else:
      return False

  # This might be reached if conversation recipients_type is 'User'
  return True
示例#4
0
def getProfileForUsername(username, program_key):
  """Returns profile entity for a user with the specified username and
  for the specified program.

  Args:
    username: a string containing username of the user.
    program_key: program key.

  Returns:
    profile entity for the specified user and program or None if the user
    does not have a profile for this program.
  """
  return profile_logic.getProfileForUsername(username, program_key,
      models=types.CI_MODELS)
示例#5
0
    def context(self):
        """Returns the context for the current template.
    """
        comments = []
        reply = self.data.GET.get('reply')

        for comment in self.data.comments:
            # generate Reply form, if needed
            form = None
            if self._commentingAllowed():
                comment_id = comment.key().id()
                if self.data.POST and reply == str(comment_id):
                    form = CommentForm(reply=comment_id, data=self.data.POST)
                else:
                    form = CommentForm(reply=comment_id)

            # generate author link, if comment sent by a student
            author_link = None

            if GCIComment.created_by.get_value_for_datastore(comment):
                author_key = ndb.Key.from_old_key(
                    GCIComment.created_by.get_value_for_datastore(comment))
            else:
                author_key = None
            if author_key:
                author = melange_profile_logic.getProfileForUsername(
                    author_key.id(), self.data.program.key())
                if author and author.is_student:
                    author_link = self.data.redirect.profile(
                        author.profile_id).urlOf(url_names.GCI_STUDENT_TASKS)
            else:
                author = None

            item = self.CommentItem(comment, form, author_link, author)
            comments.append(item)

        context = {
            'profile': self.data.ndb_profile,
            'comments': comments,
        }

        if self._commentingAllowed():
            if self.data.POST and reply == 'self':
                context['comment_form'] = CommentForm(data=self.data.POST)
            else:
                context['comment_form'] = CommentForm()

        return context
示例#6
0
  def context(self):
    """Returns the context for the current template.
    """
    comments = []
    reply = self.data.GET.get('reply')

    for comment in self.data.comments:
      # generate Reply form, if needed
      form = None
      if self._commentingAllowed():
        comment_id = comment.key().id()
        if self.data.POST and reply == str(comment_id):
          form = CommentForm(reply=comment_id, data=self.data.POST)
        else:
          form = CommentForm(reply=comment_id)

      # generate author link, if comment sent by a student
      author_link = None

      if GCIComment.created_by.get_value_for_datastore(comment):
        author_key = ndb.Key.from_old_key(
            GCIComment.created_by.get_value_for_datastore(comment))
      else:
        author_key = None
      if author_key:
        author = melange_profile_logic.getProfileForUsername(
            author_key.id(), self.data.program.key())
        if author and author.is_student:
          author_link = self.data.redirect.profile(author.profile_id).urlOf(
              url_names.GCI_STUDENT_TASKS)
      else:
        author = None

      item = self.CommentItem(comment, form, author_link, author)
      comments.append(item)

    context = {
        'profile': self.data.ndb_profile,
        'comments': comments,
    }

    if self._commentingAllowed():
      if self.data.POST and reply == 'self':
        context['comment_form'] = CommentForm(data=self.data.POST)
      else:
        context['comment_form'] = CommentForm()

    return context
示例#7
0
def cleanBackupAdmin(username, request_data):
    """Cleans backup_admin field.

  Args:
    username: Username of the user to assign as the backup administrator.
    request_data: request_data.RequestData for the current request.

  Raises:
    django_forms.ValidationError if no profile exists for at least one
    of the submitted usernames.
  """
    username = username.strip()
    profile = profile_logic.getProfileForUsername(username, request_data.program.key(), models=request_data.models)
    if not profile:
        raise django_forms.ValidationError(PROFILE_DOES_NOT_EXIST % username)
    elif profile.key == request_data.ndb_profile.key:
        raise django_forms.ValidationError(OTHER_PROFILE_IS_THE_CURRENT_PROFILE)
    else:
        return profile
示例#8
0
def cleanBackupAdmin(username, request_data):
  """Cleans backup_admin field.

  Args:
    username: Username of the user to assign as the backup administrator.
    request_data: request_data.RequestData for the current request.

  Raises:
    django_forms.ValidationError if no profile exists for at least one
    of the submitted usernames.
  """
  username = username.strip()
  profile = profile_logic.getProfileForUsername(
      username, request_data.program.key(), models=request_data.models)
  if not profile:
    raise django_forms.ValidationError(PROFILE_DOES_NOT_EXIST % username)
  elif profile.key == request_data.ndb_profile.key:
    raise django_forms.ValidationError(OTHER_PROFILE_IS_THE_CURRENT_PROFILE)
  else:
    return profile
示例#9
0
  def _continueShipmentSync(self, request, *args, **kwargs):
    """Continue syncing shipment data.

    POST Args:
      program_key: the key of the program which sync is being done for.
      shipment_info_id: id of the shipment info object that task is running
                        for.
      column_indexes: column indexes for specific columns in JSON format.
      sheet_rows: spreadsheets CSV chunk data in JSON format.
    """
    timekeeper = Timekeeper(20000)
    params = dicts.merge(request.POST, request.GET)

    if 'program_key' not in params:
      logging.error("missing program_key in params: '%s'", params)
      return responses.terminateTask()

    if 'shipment_info_id' not in params:
      logging.error("missing shipment_info_id in params: '%s'", params)
      return responses.terminateTask()

    self.setProgram(params['program_key'])
    self.setShipmentInfo(int(params['shipment_info_id']))

    if 'sheet_rows' not in params:
      logging.error("missing sheet_rows data in params: '%s'", params)
      return responses.terminateTask()

    if 'column_indexes' not in params:
      logging.error("missing column_indexes data in params: '%s'", params)
      return responses.terminateTask()

    column_indexes = json.loads(params['column_indexes'])
    sheet_rows = json.loads(params['sheet_rows'])

    try:
      for remain, row in timekeeper.iterate(sheet_rows):

        if len(row) < len(column_indexes):
          row.extend((len(column_indexes) - len(row)) * [''])
        data = self.getRowData(row, column_indexes)
        username = data['username']

        profile = profile_logic.getProfileForUsername(username, self.program_key)

        if not profile:
          logging.error("Profile with username '%s' for program '%s' is not found",
                        username, self.ndb_program_key.id())
          continue #continue to next row

        if not profile.is_student:
          logging.error("Profile with username '%s' is not a student", username)
          continue

        tracking = data['tracking']
        self.updateShipmentDataForStudent(profile, tracking)

    except DeadlineExceededError:
      if remain:
        remaining_rows = sheet_rows[(-1 * remain):]
        params = {
            'program_key': params.get('program_key'),
            'sheet_rows': json.dumps(remaining_rows),
            'column_indexes': params.get('column_indexes'),
            'shipment_info_id': params.get('shipment_info_id'),
        }
        task_continue_url = links.SOC_LINKER.site(url_names.GSOC_SHIPMENT_TASK_CONTINUE)
        taskqueue.add(url=task_continue_url, params=params)
        return responses.terminateTask()

    self.finishSync()
    return responses.terminateTask()
示例#10
0
def refreshConversationsForUserAndProgram(user_key, program_key):
  """Adds/removes the user to/from conversations that they should be involved in
  based on the conversation's criteria.

  For example, if there is a conversation that should include all program
  mentors, and this user is a program mentor who is involved with the program
  but isn't part of the converation, this function will add the user to that
  conversation. Likewise, it will remove the user from converstions they have no
  business being in, unless they're the creator of the conversation or the
  conversation is for specific users.

  This will only look at conversations that have auto_update_users set as
  True, and whoose, recipients_type is not 'User'.

  This function will not add a user to a conversation if the user does not fit
  the conversation's criteria, even if the user is the creator. If the user is
  _only_ the creator of the conversation, the user's GCIConversationUser entity
  should have been created when the conversation was initially created.

  Args:
    user_key: Key (ndb) of the User.
    program_key: Key (ndb) of the GCIProgram.
  """
  profile = profile_logic.getProfileForUsername(
      user_key.id(), program_key.to_old_key())

  if not profile:
    raise Exception('Could not find Profile for user and program.')

  def deleteConvUserIfDoesntBelong(conv_user):
    if not doesConversationUserBelong(
        conversation_user=conv_user.key, ignore_auto_update_users=False):
      conv_user.key.delete()

  # Remove user from any conversations they're in that they don't belong in
  conv_user_query = queryForProgramAndUser(user=user_key, program=program_key)
  map(deleteConvUserIfDoesntBelong, conv_user_query)

  def addToConversation(conversation):
    addUserToConversation(conversation=conversation.key, user=user_key)

  mentor_org_keys = profile.mentor_for
  admin_org_keys = profile.admin_for

  # Make sure user is added to program conversations they belong in as a
  # student
  if profile.is_student:
    query = (queryConversationsForProgram(program_key)
        .filter(gciconversation_model.GCIConversation.recipients_type ==
            conversation_model.PROGRAM)
        .filter(gciconversation_model.GCIConversation.auto_update_users == True)
        .filter(gciconversation_model.GCIConversation.include_students == True))
    map(addToConversation, query)

  # Make sure user is added to program conversations they belong in as a
  # mentor
  if profile.is_mentor:
    query = (queryConversationsForProgram(program_key)
      .filter(gciconversation_model.GCIConversation.recipients_type ==
          conversation_model.PROGRAM)
      .filter(gciconversation_model.GCIConversation.auto_update_users == True)
      .filter(gciconversation_model.GCIConversation.include_mentors == True))
    map(addToConversation, query)

  # Make sure user is added to program conversations they belong in as an
  # admin
  if profile.is_admin:
    query = (queryConversationsForProgram(program_key)
        .filter(gciconversation_model.GCIConversation.recipients_type ==
            conversation_model.PROGRAM)
        .filter(gciconversation_model.GCIConversation.auto_update_users == True)
        .filter(gciconversation_model.GCIConversation.include_admins == True))
    map(addToConversation, query)

  # Make sure user is added to program conversations they belong in as a
  # winner
  if profile.student_data and profile.student_data.is_winner:
    query = (queryConversationsForProgram(program_key)
        .filter(gciconversation_model.GCIConversation.recipients_type ==
            conversation_model.PROGRAM)
        .filter(gciconversation_model.GCIConversation.auto_update_users == True)
        .filter(gciconversation_model.GCIConversation.include_winners == True))
    map(addToConversation, query)

  # Make sure user is added to org conversations they belong in as an org
  # mentor
  if profile.is_mentor and mentor_org_keys:
    query = (queryConversationsForProgram(program_key)
        .filter(gciconversation_model.GCIConversation.recipients_type ==
            conversation_model.ORGANIZATION)
        .filter(gciconversation_model.GCIConversation.auto_update_users == True)
        .filter(gciconversation_model.GCIConversation.include_mentors == True)
        .filter(gciconversation_model.GCIConversation.organization.IN(
            mentor_org_keys)))
    map(addToConversation, query)

  # Make sure user is added to org conversations they belong in as an org
  # admin
  if profile.is_admin and admin_org_keys:
    query = (queryConversationsForProgram(program_key)
        .filter(gciconversation_model.GCIConversation.recipients_type ==
            conversation_model.ORGANIZATION)
        .filter(gciconversation_model.GCIConversation.auto_update_users == True)
        .filter(gciconversation_model.GCIConversation.include_admins == True)
        .filter(gciconversation_model.GCIConversation.organization.IN(
            admin_org_keys)))
    map(addToConversation, query)

  # Make sure user is added to org conversations they belong in as an org
  # winner
  if profile.is_student and profile.student_data.is_winner:
    query = (queryConversationsForProgram(program_key)
        .filter(gciconversation_model.GCIConversation.recipients_type ==
            conversation_model.ORGANIZATION)
        .filter(gciconversation_model.GCIConversation.auto_update_users == True)
        .filter(gciconversation_model.GCIConversation.include_winners == True)
        .filter(gciconversation_model.GCIConversation.organization ==
            profile.student_data.winner_for))
    map(addToConversation, query)
示例#11
0
 def testForExistingProfile(self):
   """Tests that profile is returned if exists."""
   profile = profile_logic.getProfileForUsername('test', self.program_key)
   self.assertEqual(profile.key, self.profile.key)
示例#12
0
 def testForOtherProgram(self):
   """Tests that no entity is returned for a different program."""
   other_program = seeder_logic.seed(program_model.Program)
   profile = profile_logic.getProfileForUsername('other', other_program.key())
   self.assertIsNone(profile)
示例#13
0
 def testForNoProfile(self):
   """Tests that no entity is returned when a user does not have a profile."""
   profile = profile_logic.getProfileForUsername('other', self.program_key)
   self.assertIsNone(profile)
示例#14
0
def refreshConversationsForUserAndProgram(user_key, program_key):
    """Adds/removes the user to/from conversations that they should be involved in
  based on the conversation's criteria.

  For example, if there is a conversation that should include all program
  mentors, and this user is a program mentor who is involved with the program
  but isn't part of the converation, this function will add the user to that
  conversation. Likewise, it will remove the user from converstions they have no
  business being in, unless they're the creator of the conversation or the
  conversation is for specific users.

  This will only look at conversations that have auto_update_users set as
  True, and whoose, recipients_type is not 'User'.

  This function will not add a user to a conversation if the user does not fit
  the conversation's criteria, even if the user is the creator. If the user is
  _only_ the creator of the conversation, the user's GCIConversationUser entity
  should have been created when the conversation was initially created.

  Args:
    user_key: Key (ndb) of the User.
    program_key: Key (ndb) of the GCIProgram.
  """
    profile = profile_logic.getProfileForUsername(user_key.id(),
                                                  program_key.to_old_key())

    if not profile:
        raise Exception('Could not find Profile for user and program.')

    def deleteConvUserIfDoesntBelong(conv_user):
        if not doesConversationUserBelong(conversation_user=conv_user.key,
                                          ignore_auto_update_users=False):
            conv_user.key.delete()

    # Remove user from any conversations they're in that they don't belong in
    conv_user_query = queryForProgramAndUser(user=user_key,
                                             program=program_key)
    map(deleteConvUserIfDoesntBelong, conv_user_query)

    def addToConversation(conversation):
        addUserToConversation(conversation=conversation.key, user=user_key)

    mentor_org_keys = profile.mentor_for
    admin_org_keys = profile.admin_for

    # Make sure user is added to program conversations they belong in as a
    # student
    if profile.is_student:
        query = (queryConversationsForProgram(program_key).filter(
            gciconversation_model.GCIConversation.recipients_type ==
            conversation_model.PROGRAM).filter(
                gciconversation_model.GCIConversation.auto_update_users == True
            ).filter(
                gciconversation_model.GCIConversation.include_students == True)
                 )
        map(addToConversation, query)

    # Make sure user is added to program conversations they belong in as a
    # mentor
    if profile.is_mentor:
        query = (queryConversationsForProgram(program_key).filter(
            gciconversation_model.GCIConversation.recipients_type ==
            conversation_model.PROGRAM).filter(
                gciconversation_model.GCIConversation.auto_update_users == True
            ).filter(
                gciconversation_model.GCIConversation.include_mentors == True))
        map(addToConversation, query)

    # Make sure user is added to program conversations they belong in as an
    # admin
    if profile.is_admin:
        query = (queryConversationsForProgram(program_key).filter(
            gciconversation_model.GCIConversation.recipients_type ==
            conversation_model.PROGRAM).filter(
                gciconversation_model.GCIConversation.auto_update_users == True
            ).filter(
                gciconversation_model.GCIConversation.include_admins == True))
        map(addToConversation, query)

    # Make sure user is added to program conversations they belong in as a
    # winner
    if profile.student_data and profile.student_data.is_winner:
        query = (queryConversationsForProgram(program_key).filter(
            gciconversation_model.GCIConversation.recipients_type ==
            conversation_model.PROGRAM).filter(
                gciconversation_model.GCIConversation.auto_update_users == True
            ).filter(
                gciconversation_model.GCIConversation.include_winners == True))
        map(addToConversation, query)

    # Make sure user is added to org conversations they belong in as an org
    # mentor
    if profile.is_mentor and mentor_org_keys:
        query = (queryConversationsForProgram(program_key).filter(
            gciconversation_model.GCIConversation.recipients_type ==
            conversation_model.ORGANIZATION).filter(
                gciconversation_model.GCIConversation.auto_update_users == True
            ).filter(gciconversation_model.GCIConversation.include_mentors ==
                     True).filter(
                         gciconversation_model.GCIConversation.organization.IN(
                             mentor_org_keys)))
        map(addToConversation, query)

    # Make sure user is added to org conversations they belong in as an org
    # admin
    if profile.is_admin and admin_org_keys:
        query = (queryConversationsForProgram(program_key).filter(
            gciconversation_model.GCIConversation.recipients_type ==
            conversation_model.ORGANIZATION).filter(
                gciconversation_model.GCIConversation.auto_update_users == True
            ).filter(gciconversation_model.GCIConversation.include_admins ==
                     True).filter(
                         gciconversation_model.GCIConversation.organization.IN(
                             admin_org_keys)))
        map(addToConversation, query)

    # Make sure user is added to org conversations they belong in as an org
    # winner
    if profile.is_student and profile.student_data.is_winner:
        query = (queryConversationsForProgram(program_key).filter(
            gciconversation_model.GCIConversation.recipients_type ==
            conversation_model.ORGANIZATION).filter(
                gciconversation_model.GCIConversation.auto_update_users == True
            ).filter(gciconversation_model.GCIConversation.include_winners ==
                     True).filter(
                         gciconversation_model.GCIConversation.organization ==
                         profile.student_data.winner_for))
        map(addToConversation, query)
示例#15
0
def doesUserBelongInConversation(user,
                                 conversation,
                                 ignore_auto_update_users=True):
    """Decides whether the user in a conversation belongs in the conversation.

  If ignore_auto_update_users is False, True will be returned if the
  conversation's auto_update_users is False.

  Args:
    user: Key (ndb) of a User.
    conversation: Key (ndb) of a GCIConversation.
    ignore_auto_update_users: Whether this should ignore the conversation's
                              auto_update_users property.

  Returns:
    Whether the user belongs in the conversation. If the conversation's
    recipients_type is 'User', True is always returned. Also returns true if
    the user is the conversation's creator.
  """
    conversation_ent = conversation.get()

    if not conversation_ent.auto_update_users and not ignore_auto_update_users:
        return True

    if conversation_ent.creator == user:
        return True

    profile = profile_logic.getProfileForUsername(
        user.id(), conversation_ent.program.to_old_key())

    if not profile:
        raise Exception('Could not find GCIProfile for user and program.')

    if conversation_ent.recipients_type == conversation_model.PROGRAM:
        if conversation_ent.include_admins and profile.is_admin:
            return True
        elif conversation_ent.include_mentors and profile.is_mentor:
            return True
        elif conversation_ent.include_students and profile.is_student:
            return True
        elif (profile.is_student and conversation_ent.include_winners
              and profile.student_data.is_winner):
            return True
        else:
            return False
    elif conversation_ent.recipients_type == conversation_model.ORGANIZATION:
        if (conversation_ent.include_admins
                and conversation_ent.organization in profile.admin_for):
            return True
        elif (conversation_ent.include_mentors
              and conversation_ent.organization in profile.mentor_for):
            return True
        elif (profile.is_student and conversation_ent.include_winners
              and profile.student_data.is_winner
              and conversation_ent.organization
              == profile.student_data.winner_for):
            return True
        else:
            return False

    # This might be reached if conversation recipients_type is 'User'
    return True