Exemplo n.º 1
0
  def _PostComment(self, sharer_user, timestamp, message, asset_id=None):
    """Creates a new comment and a corresponding activity."""
    comment_id = Comment.ConstructCommentId(timestamp, self._new_user.webapp_dev_id, self._unique_id)
    self._unique_id += 1
    comment = yield Comment.CreateNew(self._client,
                                      viewpoint_id=self._viewpoint_id,
                                      comment_id=comment_id,
                                      user_id=sharer_user.user_id,
                                      asset_id=asset_id,
                                      timestamp=timestamp,
                                      message=message)

    # Create post_comment activity.
    yield self._CreateActivity(sharer_user, timestamp, Activity.CreatePostComment, cm_dict={'comment_id': comment_id})

    raise gen.Return(comment)
Exemplo n.º 2
0
    def NotifyPostComment(cls, client, followers, act_dict, cm_dict):
        """Notifies specified followers that a new comment has been posted to the viewpoint.
    Invalidates this comment and all comments posted in the future by setting the start_key.
    Doing this enables the client to efficiently "stack" comment invalidations by fetching
    all comments beyond the lowest start_key in a single call to query_viewpoints. Creates a
    post_comment activity in the viewpoint.
    """
        from viewfinder.backend.db.comment import Comment

        activity_func = NotificationManager._CreateActivityFunc(
            act_dict, Activity.CreatePostComment, cm_dict)

        # Construct comment id that will sort before the posted comment and all others with
        # greater timestamps. Only do this if comment will not be in-lined.
        if len(cm_dict['message']
               ) > NotificationManager.MAX_INLINE_COMMENT_LEN:
            start_key = Comment.ConstructCommentId(cm_dict['timestamp'], 0, 0)
            invalidate = {
                'viewpoints': [{
                    'viewpoint_id': cm_dict['viewpoint_id'],
                    'get_comments': True,
                    'comment_start_key': start_key
                }]
            }
        else:
            invalidate = None

        yield NotificationManager._NotifyFollowers(client,
                                                   cm_dict['viewpoint_id'],
                                                   followers,
                                                   invalidate,
                                                   activity_func,
                                                   inc_badge=True)
Exemplo n.º 3
0
  def testInlineCommentsMigration(self):
    """Ensure that the INLINE_COMMENTS migration works correctly."""
    comment_id = self._tester.PostComment(self._cookie, self._user.private_vp_id, 'hi')

    response_dict = self._SendRequest('query_notifications', self._cookie,
                                      {'scan_forward': False},
                                      version=Message.EXTRACT_FILE_SIZES)
    notify_dict = response_dict['notifications'][0]
    invalidate = notify_dict['invalidate']

    self.assertEqual(notify_dict['name'], 'post_comment')

    timestamp, device_id, uniquifier = Comment.DeconstructCommentId(comment_id)
    start_key = Comment.ConstructCommentId(timestamp, 0, 0)
    self.assertEqual(invalidate, {'viewpoints': [{'viewpoint_id': self._user.private_vp_id,
                                                  'get_comments': True,
                                                  'comment_start_key': start_key}]})
Exemplo n.º 4
0
def _TestPostComment(tester, user_cookie, request_dict):
    """Called by the ServiceTester in order to test post_comment
  service API call.
  """
    validator = tester.validator
    user_id, device_id = tester.GetIdsFromCookie(user_cookie)
    request_dict = deepcopy(request_dict)

    # Send post_comment request.
    actual_dict = tester.SendRequest('post_comment', user_cookie, request_dict)
    op_dict = tester._DeriveNotificationOpDict(user_id, device_id,
                                               request_dict)

    # post_comment is no-op if comment already exists.
    db_key = DBKey(request_dict['viewpoint_id'], request_dict['comment_id'])
    if validator.GetModelObject(Comment, db_key, must_exist=False) is None:
        # Validate Comment object.
        comment_dict = deepcopy(request_dict)
        comment_dict['user_id'] = user_id
        comment_dict.pop('headers', None)
        comment_dict.pop('activity', None)
        expected_comment = validator.ValidateCreateDBObject(
            Comment, **comment_dict)

        # Validate activity and notifications for the post.
        activity_dict = {
            'name': 'post_comment',
            'activity_id': request_dict['activity']['activity_id'],
            'timestamp': request_dict['activity']['timestamp'],
            'comment_id': expected_comment.comment_id
        }

        if len(expected_comment.message
               ) > NotificationManager.MAX_INLINE_COMMENT_LEN:
            start_key = Comment.ConstructCommentId(expected_comment.timestamp,
                                                   0, 0)
            invalidate = {
                'viewpoints': [{
                    'viewpoint_id': expected_comment.viewpoint_id,
                    'get_comments': True,
                    'comment_start_key': start_key
                }]
            }
        else:
            invalidate = None

        validator.ValidateFollowerNotifications(expected_comment.viewpoint_id,
                                                activity_dict,
                                                op_dict,
                                                invalidate,
                                                sends_alert=True)

    # Validate response dict.
    tester._CompareResponseDicts('post_comment', user_id, request_dict, {},
                                 actual_dict)
    return actual_dict
Exemplo n.º 5
0
  def _Update(self):
    """Updates the database:
       1. Revives any followers that have removed the viewpoint.
       2. Creates the new comment.
    """
    # Revive any REMOVED followers.
    yield gen.Task(Follower.ReviveRemovedFollowers, self._client, self._followers)

    # Create the comment.
    yield Comment.CreateNew(self._client, **self._cm_dict)
Exemplo n.º 6
0
 def testWrongDeviceId(self):
     """ERROR: Try to create a comment using a device id that is different
 than the one in the user cookie.
 """
     self.assertRaisesHttpError(403,
                                self._tester.PostComment,
                                self._cookie3,
                                self._vp_id,
                                message='message',
                                comment_id=Comment.ConstructCommentId(
                                    100, 1000, 1))
Exemplo n.º 7
0
  def MigrateBackward(self, client, message, callback):
    from viewfinder.backend.db.comment import Comment

    for notify_dict in message.dict['notifications']:
      if 'inline' in notify_dict and 'comment' in notify_dict['inline']:
        comment_dict = notify_dict['inline'].pop('comment')
        start_key = Comment.ConstructCommentId(comment_dict['timestamp'], 0, 0)
        notify_dict['invalidate'] = {'viewpoints': [{'viewpoint_id': comment_dict['viewpoint_id'],
                                                     'get_comments': True,
                                                     'comment_start_key': start_key}]}

    callback()
Exemplo n.º 8
0
    def QueryComments(cls,
                      client,
                      viewpoint_id,
                      callback,
                      excl_start_key=None,
                      limit=None):
        """Queries comments belonging to the viewpoint (up to 'limit' total) for
    the specified 'viewpoint_id'. Starts with comments having a key greater
    than 'excl_start_key'. Returns a tuple with the array of comments and
    the last queried key.
    """
        def _OnQueryComments(comments):
            callback((comments,
                      comments[-1].comment_id if len(comments) > 0 else None))

        Comment.RangeQuery(client,
                           viewpoint_id,
                           range_desc=None,
                           limit=limit,
                           col_names=None,
                           callback=_OnQueryComments,
                           excl_start_key=excl_start_key)
Exemplo n.º 9
0
 def _CreateTestComment(self, viewpoint_id, comment_id, user_id, message):
   """Create comment for testing purposes."""
   comment = Comment.CreateFromKeywords(viewpoint_id=viewpoint_id, comment_id=comment_id,
                                        user_id=user_id, message=message)
   self._RunAsync(comment.Update, self._client)
   return comment
Exemplo n.º 10
0
    def testAssetIdAltDevice(self):
        """Test construction of assets using a different device than the calling device."""
        # ------------------------------
        # Try to upload using a device not owned by the user at all.
        # ------------------------------
        ep_dict = self._CreateEpisodeDict(self._cookie)
        ep_dict['episode_id'] = Episode.ConstructEpisodeId(
            time.time(), self._device_ids[2], self._test_id)
        self._test_id += 1

        ph_dict = self._CreatePhotoDict(self._cookie)
        ph_dict['photo_id'] = Photo.ConstructPhotoId(time.time(),
                                                     self._device_ids[2],
                                                     self._test_id)
        self._test_id += 1

        self.assertRaisesHttpError(403, self._tester.UploadEpisode,
                                   self._cookie, ep_dict, [ph_dict])

        # ------------------------------
        # Upload using alternate devices owned by the user.
        # ------------------------------
        ep_dict = self._CreateEpisodeDict(self._cookie)
        ep_dict['episode_id'] = Episode.ConstructEpisodeId(
            time.time(), self._extra_device_id1, self._test_id)
        self._test_id += 1

        ph_dict = self._CreatePhotoDict(self._cookie)
        ph_dict['photo_id'] = Photo.ConstructPhotoId(time.time(),
                                                     self._extra_device_id2,
                                                     self._test_id)
        self._test_id += 1

        act_dict = self._tester.CreateActivityDict(self._cookie)
        act_dict['activity_id'] = Activity.ConstructActivityId(
            time.time(), self._extra_device_id1, self._test_id)
        self._test_id += 1

        self._tester.UploadEpisode(self._cookie, ep_dict, [ph_dict], act_dict)

        # ------------------------------
        # Share to a new viewpoint using alternate devices owned by the user.
        # ------------------------------
        viewpoint_id = Viewpoint.ConstructViewpointId(self._extra_device_id2,
                                                      self._test_id)
        self._test_id += 1

        self._tester.ShareNew(self._cookie,
                              [(ep_dict['episode_id'], [ph_dict['photo_id']])],
                              [self._user2.user_id],
                              viewpoint_id=viewpoint_id)

        # ------------------------------
        # Post to the new viewpoint using alternate devices owned by the user.
        # ------------------------------
        comment_id = Comment.ConstructCommentId(time.time(),
                                                self._extra_device_id1,
                                                self._test_id)
        self._test_id += 1

        self._tester.PostComment(self._cookie, viewpoint_id, 'hi')
Exemplo n.º 11
0
 def testRepr(self):
     comment = Comment.CreateFromKeywords(viewpoint_id='vp1',
                                          comment_id='c1',
                                          message='hello')
     self.assertIn('vp1', repr(comment))
     self.assertNotIn('hello', repr(comment))
Exemplo n.º 12
0
 def testSortOrder(self):
     """Verify that comments sort ascending by timestamp."""
     timestamp = time.time()
     comment_id1 = Comment.ConstructCommentId(timestamp, 0, 0)
     comment_id2 = Comment.ConstructCommentId(timestamp + 1, 0, 0)
     self.assertGreater(comment_id2, comment_id1)