Exemplo n.º 1
0
    def QueryFollowerIds(cls,
                         client,
                         viewpoint_id,
                         callback,
                         excl_start_key=None,
                         limit=None):
        """Query followers belonging to the viewpoint (up to 'limit' total) for
    the specified 'viewpoint_id'. The query is for followers starting with
    (but excluding) 'excl_start_key'. The callback is invoked with an array
    of follower user ids and the last queried key.
    """
        def _OnQueryFollowerKeys(follower_keys):
            follower_ids = [key.hash_key for key in follower_keys]
            last_key = follower_ids[-1] if len(follower_ids) > 0 else None

            callback((follower_ids, last_key))

        # Query the viewpoint_id secondary index with excl_start_key & limit.
        query_expr = ('follower.viewpoint_id={id}', {'id': viewpoint_id})
        start_index_key = db_client.DBKey(
            excl_start_key,
            viewpoint_id) if excl_start_key is not None else None
        Follower.IndexQueryKeys(client,
                                query_expr,
                                callback=_OnQueryFollowerKeys,
                                start_index_key=start_index_key,
                                limit=limit)
Exemplo n.º 2
0
    def _FormatAllAttributes(self, item):
        """Build list of (column, key, value, pretty_value). We need a list to keep the columns ordered.
    The interpretation of the 'key' column depends on the beginning of the 'term' column."""
        attrs = []
        term = item.get('t', None)
        key = item.get('k', None)
        data = item.get('d', None)
        split = term.split(':')
        table = split[0]
        key_pretty = key
        if table == 'co':
            db_key = Contact._ParseIndexKey(key)
            key_pretty = self._SortQueryLink('Contact', db_key.hash_key,
                                             db_key.range_key)
        elif table == 'ev':
            key_pretty = self._EpisodeLink(key)
        elif table == 'fo':
            db_key = Follower._ParseIndexKey(key)
            key_pretty = self._SortQueryLink('Follower', db_key.hash_key,
                                             db_key.range_key)
        elif table == 'id':
            key_pretty = self._HashQueryLink('Identity', key)
        elif table == 'vp':
            key_pretty = self._ViewpointLink(key)

        attrs.append(('term', 't', term, term))
        attrs.append(('key', 'k', key, key_pretty))
        attrs.append(('data', 't', data, data))
        attrs.append(('_version', '_ve', data, data))
        return attrs
Exemplo n.º 3
0
  def _FormatAllAttributes(self, item):
    """Build list of (column, key, value, pretty_value). We need a list to keep the columns ordered.
    The interpretation of the 'key' column depends on the beginning of the 'term' column."""
    attrs = []
    term = item.get('t', None)
    key = item.get('k', None)
    data = item.get('d', None)
    split = term.split(':')
    table = split[0]
    key_pretty = key
    if table == 'co':
      db_key = Contact._ParseIndexKey(key)
      key_pretty = self._SortQueryLink('Contact', db_key.hash_key, db_key.range_key)
    elif table == 'ev':
      key_pretty = self._EpisodeLink(key)
    elif table == 'fo':
      db_key = Follower._ParseIndexKey(key)
      key_pretty = self._SortQueryLink('Follower', db_key.hash_key, db_key.range_key)
    elif table == 'id':
      key_pretty = self._HashQueryLink('Identity', key)
    elif table == 'vp':
      key_pretty = self._ViewpointLink(key)

    attrs.append(('term', 't', term, term))
    attrs.append(('key', 'k', key, key_pretty))
    attrs.append(('data', 't', data, data))
    attrs.append(('_version', '_ve', data, data))
    return attrs
Exemplo n.º 4
0
def _RunService(callback):
    """Removes the follower by loading follower relation and deleting it.
  Removes all notifications related to the viewpoint.
  """
    assert options.options.user_id, 'must specify a user id (--user_id)'
    assert options.options.viewpoint_id, 'must specify a viewpoint id (--viewpoint_id)'

    client = DBClient.Instance()

    def _OnService(response_dict):
        logging.info('result: %s' %
                     util.ToCanonicalJSON(response_dict, indent=2))
        callback()

    def _OnNotification(n, cb):
        if n.viewpoint_id == options.options.viewpoint_id:
            n.name = 'clear_badges'
            n.sender_id = 494
            n.sender_device_id = 2260
            n.invalidate = None
            n.op_id = None
            n.viewpoint_id = None
            n.update_seq = None
            n.viewed_seq = None
            n.activity_id = None
            n.badge = 0
            print 'resetting notification to clear_badges: %s' % n
            n.Update(client, cb)
        else:
            cb()

    def _DoneQueryFollowed():
        Notification.VisitRange(client, options.options.user_id, None, None,
                                _OnNotification, callback)

    def _OnQueryFollowed(f, cb):
        if f.viewpoint_id == options.options.viewpoint_id:
            print 'deleting: %s' % f
            f.Delete(client, cb)
        else:
            cb()

    def _OnDeleteFollower():
        Followed.VisitRange(client, options.options.user_id, None, None,
                            _OnQueryFollowed, _DoneQueryFollowed)

    def _OnQueryFollower(f):
        if f:
            print 'deleting: %s' % f
            f.Delete(client, _OnDeleteFollower)
        else:
            _OnDeleteFollower()

    Follower.Query(client,
                   options.options.user_id,
                   options.options.viewpoint_id,
                   None,
                   _OnQueryFollower,
                   must_exist=False)
Exemplo n.º 5
0
        def _UpdateFollower(follower_id):
            """Create a new follower of this viewpoint in the database."""
            follower = Follower(user_id=follower_id, viewpoint_id=self.viewpoint_id)
            follower.timestamp = timestamp
            follower.adding_user_id = adding_user_id
            follower.viewed_seq = 0
            follower.labels = [Follower.CONTRIBUTE]

            # Create the follower and corresponding Followed record.
            yield [
                gen.Task(follower.Update, client),
                gen.Task(
                    Followed.UpdateDateUpdated,
                    client,
                    follower_id,
                    self.viewpoint_id,
                    old_timestamp=None,
                    new_timestamp=timestamp,
                ),
            ]

            raise gen.Return(follower)
Exemplo n.º 6
0
    def VisitFollowerIds(cls,
                         client,
                         viewpoint_id,
                         visitor,
                         callback,
                         consistent_read=False):
        """Visit all followers of the specified viewpoint and invoke the
    "visitor" function with each follower id. See VisitIndexKeys for
    additional detail.
    """
        def _OnVisit(follower_key, visit_callback):
            visitor(follower_key.hash_key, visit_callback)

        query_expr = ('follower.viewpoint_id={id}', {'id': viewpoint_id})
        Follower.VisitIndexKeys(client,
                                query_expr,
                                _OnVisit,
                                callback,
                                consistent_read=consistent_read)
Exemplo n.º 7
0
    def CreateNew(cls, client, **vp_dict):
        """Creates the viewpoint specified by 'vp_dict' and creates a follower relation between
    the requesting user and the viewpoint with the ADMIN label. The caller is responsible for
    checking permission to do this, as well as ensuring that the viewpoint does not yet exist
    (or is just being identically rewritten).

    Returns a tuple containing the newly created objects: (viewpoint, follower).
    """
        tasks = []

        # Create the viewpoint.
        assert 'viewpoint_id' in vp_dict and 'user_id' in vp_dict and 'timestamp' in vp_dict, vp_dict
        viewpoint = Viewpoint.CreateFromKeywords(**vp_dict)
        viewpoint.last_updated = viewpoint.timestamp
        viewpoint.update_seq = 0
        tasks.append(gen.Task(viewpoint.Update, client))

        # Create the follower and give all permissions, since it's the owner.
        foll_dict = {
            'user_id': viewpoint.user_id,
            'viewpoint_id': viewpoint.viewpoint_id,
            'timestamp': viewpoint.timestamp,
            'labels': list(Follower.PERMISSION_LABELS),
            'viewed_seq': 0
        }
        if viewpoint.IsDefault():
            foll_dict['labels'].append(Follower.PERSONAL)

        follower = Follower.CreateFromKeywords(**foll_dict)
        tasks.append(gen.Task(follower.Update, client))

        # Create the corresponding Followed record.
        tasks.append(
            gen.Task(Followed.UpdateDateUpdated,
                     client,
                     viewpoint.user_id,
                     viewpoint.viewpoint_id,
                     old_timestamp=None,
                     new_timestamp=viewpoint.last_updated))
        yield tasks

        raise gen.Return((viewpoint, follower))
Exemplo n.º 8
0
        def _UpdateFollower(follower_id):
            """Create a new follower of this viewpoint in the database."""
            follower = Follower(user_id=follower_id,
                                viewpoint_id=self.viewpoint_id)
            follower.timestamp = timestamp
            follower.adding_user_id = adding_user_id
            follower.viewed_seq = 0
            follower.labels = [Follower.CONTRIBUTE]

            # Create the follower and corresponding Followed record.
            yield [
                gen.Task(follower.Update, client),
                gen.Task(Followed.UpdateDateUpdated,
                         client,
                         follower_id,
                         self.viewpoint_id,
                         old_timestamp=None,
                         new_timestamp=timestamp)
            ]

            raise gen.Return(follower)
Exemplo n.º 9
0
  def testMissingActivities(self):
    """Verifies detection of missing activities."""
    self._CreateTestViewpoint('vp1', self._user.user_id, [self._user2.user_id])
    self._CreateTestEpisode('vp1', 'ep1', self._user.user_id)
    self._CreateTestEpisode('vp1', 'ep2', self._user.user_id)
    self._CreateTestEpisode('vp1', 'ep3', self._user.user_id)
    self._CreateTestViewpoint('vp2', self._user.user_id, [self._user2.user_id])
    self._CreateTestEpisode('vp2', 'ep4', self._user.user_id)
    self._CreateTestComment('vp2', 'cm1', self._user.user_id, 'a comment')
    self._RunAsync(Activity.CreateShareNew, self._client, self._user.user_id, 'vp2', 'a1',
                   time.time(), 0, [{'new_episode_id': 'ep4', 'photo_ids': []}], [])
    self._CreateTestEpisode(self._user.private_vp_id, 'ep5', self._user.user_id)

    # Create an episode that would be created by save_photos.
    ep_dict = {'episode_id': 'ep6',
               'user_id': self._user.user_id,
               'viewpoint_id': self._user.private_vp_id,
               'parent_ep_id': 'ep4',
               'publish_timestamp': time.time(),
               'timestamp': time.time()}
    self._RunAsync(Episode.CreateNew, self._client, **ep_dict)

    # Create viewpoint that's missing a follower activity.
    self._CreateTestViewpoint('vp3', self._user.user_id, [])
    follower = Follower.CreateFromKeywords(user_id=self._user2.user_id, viewpoint_id='vp3')
    self._RunAsync(follower.Update, self._client)

    # Create viewpoint with a follower covered by merge_accounts (shouldn't be tagged as missing follower).
    self._CreateTestViewpoint('vp4', self._user.user_id, [self._user2.user_id])
    self._RunAsync(Activity.CreateMergeAccounts, self._client, self._user.user_id, 'vp2', 'a1',
                   time.time(), 0, self._user2.user_id, self._user.user_id)

    self._RunAsync(self._checker.CheckAllViewpoints)

    # Default viewpoints created by DBBaseTestCase are missing Followed records.
    corruption_text = \
      '  ---- viewpoint v-F- ----\n' \
      '  missing save_photos activity (1 instance)\n' \
      '  missing upload_episode activity (1 instance)\n' \
      '\n' \
      '  ---- viewpoint vp4 ----\n' \
      '  empty viewpoint (1 instance)\n' \
      '\n' \
      '  ---- viewpoint vp1 ----\n' \
      '  missing share_existing activity (2 instances)\n' \
      '  missing share_new activity (1 instance)\n' \
      '\n' \
      '  ---- viewpoint vp3 ----\n' \
      '  missing followed (1 instance)\n' \
      '  empty viewpoint (1 instance)\n' \
      '\n' \
      '  ---- viewpoint vp2 ----\n' \
      '  missing post_comment activity (1 instance)\n' \
      '  missing add_followers activity (1 instance)\n' \
      '\n' \
      'python dbchk.py --devbox --repair=True --viewpoints=v-F-,vp4,vp1,vp3,vp2'

    self.assertEqual(self._checker._email_args['text'],
                     'Found corruption(s) in database:\n\n%s' % corruption_text)

    self._RunDbChk({'viewpoints': ['vp1', 'vp2', 'vp3', 'vp4', 'v-F-'], 'repair': True})

    # Validate by checking again and finding no issues.
    self._RunAsync(self._checker.CheckAllViewpoints)
    self.assertIsNone(self._checker._email_args)