Example #1
0
    def testPostIdConstruction(self):
        """Verify round-trip of various post-ids."""
        def _RoundTripPostId(original_episode_id, original_photo_id):
            post_id = Post.ConstructPostId(original_episode_id,
                                           original_photo_id)
            new_episode_id, new_photo_id = Post.DeconstructPostId(post_id)
            self.assertEqual(original_episode_id, new_episode_id)
            self.assertEqual(original_photo_id, new_photo_id)

        _RoundTripPostId(Episode.ConstructEpisodeId(time.time(), 0, 0),
                         Photo.ConstructPhotoId(time.time(), 0, 0))

        _RoundTripPostId(
            Episode.ConstructEpisodeId(time.time(), 1, (127, 'extra')),
            Photo.ConstructPhotoId(time.time(), 1, (127, 'extra')))

        _RoundTripPostId(
            Episode.ConstructEpisodeId(time.time(), 1, (128, None)),
            Photo.ConstructPhotoId(time.time(), 1, (128, None)))

        _RoundTripPostId(
            Episode.ConstructEpisodeId(time.time(), 4000000000,
                                       (5000000000, 'v123')),
            Photo.ConstructPhotoId(time.time(), 6000000000,
                                   (7000000000, 'v123')))
Example #2
0
def _SetWelcomeIds(user, upload_request):
    """Assigns activity, episode, and photo ids for all welcome conversation requests. Assets
  are assigned unique ids starting at 1.
  """
    # Construct the activity id.
    unique_id = 1
    act_dict = upload_request['activity']
    act_dict['activity_id'] = Activity.ConstructActivityId(
        act_dict['timestamp'], user.webapp_dev_id, unique_id)
    unique_id += 1

    # Construct the episode id.
    ep_dict = upload_request['episode']
    ep_dict['episode_id'] = Episode.ConstructEpisodeId(ep_dict['timestamp'],
                                                       user.webapp_dev_id,
                                                       unique_id)
    unique_id += 1

    # Construct the photo ids.
    for ph_dict in upload_request['photos']:
        # Create metadata for each photo.
        ph_dict['photo_id'] = Photo.ConstructPhotoId(ph_dict['timestamp'],
                                                     user.webapp_dev_id,
                                                     unique_id)
        unique_id += 1
Example #3
0
    def testBatchQuery(self):
        """Test DBObject.BatchQuery."""
        # Create some data to query.
        keys = []
        for i in xrange(3):
            photo_id = Photo.ConstructPhotoId(time.time(),
                                              self._mobile_dev.device_id, 1)
            episode_id = Episode.ConstructEpisodeId(time.time(),
                                                    self._mobile_dev.device_id,
                                                    1)
            ph_dict = {
                'photo_id': photo_id,
                'user_id': self._user.user_id,
                'episode_id': episode_id
            }
            self._RunAsync(Photo.CreateNew, self._client, **ph_dict)
            keys.append(DBKey(photo_id, None))

        # Add a key that will not be found.
        keys.append(DBKey('unk-photo', None))

        photos = self._RunAsync(Photo.BatchQuery,
                                self._client,
                                keys,
                                None,
                                must_exist=False)
        self.assertEqual(len(photos), 4)
        for i in xrange(3):
            self.assertEqual(photos[i].GetKey(), keys[i])
        self.assertIsNone(photos[3])
 def _CreatePhotoDict(self, user_cookie, **update_ph_dict):
   """Create dict() for a test photo, overriding default values with
   whatever is passed in "update_ph_dict"."""
   user_id, device_id = self._tester.GetIdsFromCookie(user_cookie)
   timestamp = update_ph_dict.get('timestamp', time.time() - self._test_id)
   ph_dict = {'photo_id': Photo.ConstructPhotoId(timestamp, device_id, self._test_id),
              'aspect_ratio': .75 + self._test_id,
              'content_type': 'image/jpeg',
              'tn_md5': util.ComputeMD5Hex('thumbnail image data'),
              'med_md5': util.ComputeMD5Hex('medium image data'),
              'full_md5': util.ComputeMD5Hex('full image data'),
              'orig_md5': util.ComputeMD5Hex('original image data'),
              'location': {'latitude': 47.5675, 'longitude':-121.962, 'accuracy': 0.0},
              'placemark': {'iso_country_code': u'US',
                            'thoroughfare': u'SE 43rd St',
                            'locality': u'Fall City',
                            'country': u'United States',
                            'subthoroughfare': u'28408',
                            'state': u'Washington',
                            'sublocality': u'Issaquah Plateau'},
              'tn_size': 5 * 1024,
              'med_size': 40 * 1024,
              'full_size': 150 * 1024,
              'orig_size': 1200 * 1024,
              'timestamp': timestamp,
              'caption': 'Photo caption #%d' % self._test_id}
   self._test_id += 1
   ph_dict.update(**update_ph_dict)
   return ph_dict
  def _UploadEpisodeWithPhoto(self):
    """Create episode with photo and upload.
    Returns: photo_id of created photo.
    """
    timestamp = time.time()

    episode_id = Episode.ConstructEpisodeId(timestamp, self._device_ids[0], 100)
    ep_dict = {'episode_id': episode_id,
               'timestamp': timestamp,
               'title': 'Episode Title'}

    photo_id = Photo.ConstructPhotoId(timestamp, self._device_ids[0], 100)
    ph_dict = {'aspect_ratio': 1.3333,
               'timestamp': timestamp,
               'tn_md5': util.ComputeMD5Hex('thumbnail image data'),
               'med_md5': util.ComputeMD5Hex('medium image data'),
               'full_md5': util.ComputeMD5Hex('full image data'),
               'orig_md5': util.ComputeMD5Hex('original image data'),
               'tn_size': 5*1024,
               'med_size': 10*1024,
               'full_size': 150*1024,
               'orig_size': 1200*1024,
               'caption': 'a photo',
               'photo_id': photo_id}

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

    return photo_id
Example #6
0
 def testPhotoIdSortOrder(self):
     """Create a series of photo ids and verify sort order. Sort order
 is by time first (from newest to oldest), then from oldest to newest
 device id, then from oldest to newest device photo id.
 """
     # attributes are a tuple of time, device id, and device photo id.
     photo_attributes = [(100, 1, 1), (100, 1, 2), (100, 1, 3), (100, 2, 1),
                         (100, 2, 2), (100, 2, 3), (99, 1, 3), (99, 2, 2),
                         (99, 3, 1), (98, 3, 1), (97, 2, 1), (96, 1, 1)]
     photo_ids = [
         Photo.ConstructPhotoId(p[0], p[1], p[2]) for p in photo_attributes
     ]
     self.assertEqual(photo_ids, sorted(photo_ids))
Example #7
0
 def _UploadPhotoOperation(self,
                           user_id,
                           device_id,
                           seed,
                           callback,
                           photo_id=None):
     """Creates an upload photos operation using seed to create unique ids."""
     request = {
         'user_id':
         user_id,
         'activity': {
             'activity_id':
             Activity.ConstructActivityId(time.time(), device_id, seed),
             'timestamp':
             time.time()
         },
         'episode': {
             'user_id':
             user_id,
             'episode_id':
             Episode.ConstructEpisodeId(time.time(), device_id, seed),
             'timestamp':
             time.time()
         },
         'photos': [{
             'photo_id':
             Photo.ConstructPhotoId(time.time(), device_id, seed)
             if photo_id is None else photo_id,
             'aspect_ratio':
             1.3333,
             'timestamp':
             time.time(),
             'tn_size':
             5 * 1024,
             'med_size':
             50 * 1024,
             'full_size':
             150 * 1024,
             'orig_size':
             1200 * 1024
         }]
     }
     Operation.CreateAndExecute(self._client, user_id, device_id,
                                'UploadEpisodeOperation.Execute', request,
                                callback)
Example #8
0
    def testRealTimeIndexing(self):
        """Tests index updates in real-time."""
        def _QueryAndVerify(p, barrier_cb, query, is_in):
            def _Verify(keys):
                ids = [key.hash_key for key in keys]
                if is_in:
                    self.assertTrue(p.photo_id in ids)
                else:
                    self.assertFalse(p.photo_id in ids)
                barrier_cb()

            Photo.IndexQueryKeys(self._client, query, callback=_Verify)

        def _OnUpdate(p):
            with util.Barrier(self.stop) as b:
                _QueryAndVerify(p, b.Callback(), ('photo.caption={c}', {
                    'c': 'Class'
                }), False)
                _QueryAndVerify(p, b.Callback(), ('photo.caption={c}', {
                    'c': 'reunion'
                }), False)
                _QueryAndVerify(p, b.Callback(), ('photo.caption={c}', {
                    'c': '1992'
                }), True)
                _QueryAndVerify(p, b.Callback(), ('photo.caption={c}', {
                    'c': 'culumbia'
                }), True)

        def _Update(p):
            p.caption = 'Columbia High School c.o. 1992'
            p.Update(self._client, callback=partial(_OnUpdate, p))

        photo_id = Photo.ConstructPhotoId(time.time(), 1, 1)
        p = self.UpdateDBObject(Photo,
                                user_id=self._user.user_id,
                                photo_id=photo_id,
                                caption='Class of 1992 reunion')

        with util.Barrier(partial(_Update, p)) as b:
            _QueryAndVerify(p, b.Callback(), ('photo.caption={c}', {
                'c': 'reunion'
            }), True)
            _QueryAndVerify(p, b.Callback(), ('photo.caption={c}', {
                'c': '1992'
            }), True)
Example #9
0
  def testFileSizeExtraction(self):
    """Ensure that the EXTRACT_FILE_SIZES migration works correctly."""
    episode_id = Episode.ConstructEpisodeId(1, self._device_ids[0], 1)
    photo_id = Photo.ConstructPhotoId(1, self._device_ids[0], 1)
    # create request with size fields in client_data.
    request = {'activity': self._tester.CreateActivityDict(self._cookie),
               'episode': {'episode_id': episode_id,
                           'timestamp': 1},
               'photos': [self._CreatePhotoDict(self._cookie, photo_id=photo_id,
                                                client_data={'tn_size':'5', 'med_size':'40',
                                                             'full_size':'150', 'orig_size':'1200'})]}

    # remove size fields from the photo metadata, leaving only those in client_data.
    photo = request['photos'][0]
    del photo['tn_size']
    del photo['med_size']
    del photo['full_size']
    del photo['orig_size']

    self._SendRequest('upload_episode', self._cookie, request, version=Message.INLINE_INVALIDATIONS)
Example #10
0
    def testMetaphoneQueries(self):
        """Tests metaphone queries."""
        def _QueryAndVerify(p, barrier_cb, query_expr, match):
            def _Verify(keys):
                ids = [key.hash_key for key in keys]
                if match:
                    self.assertTrue(p.photo_id in ids)
                else:
                    self.assertFalse(ids)
                barrier_cb()

            Photo.IndexQueryKeys(self._client, query_expr, callback=_Verify)

        photo_id = Photo.ConstructPhotoId(time.time(), 1, 1)
        p = self.UpdateDBObject(Photo,
                                user_id=self._user.user_id,
                                photo_id=photo_id,
                                caption='Summer in East Hampton')

        with util.Barrier(self.stop) as b:
            _QueryAndVerify(p, b.Callback(), ('photo.caption={c}', {
                'c': 'summer'
            }), True)
            _QueryAndVerify(p, b.Callback(), ('photo.caption={c}', {
                'c': 'sumer'
            }), True)
            _QueryAndVerify(p, b.Callback(), ('photo.caption={c}', {
                'c': 'summa'
            }), False)
            _QueryAndVerify(p, b.Callback(), ('photo.caption={c}', {
                'c': 'sum'
            }), False)
            _QueryAndVerify(p, b.Callback(), ('photo.caption={c}', {
                'c': 'hamton'
            }), False)
            _QueryAndVerify(p, b.Callback(), ('photo.caption={c}', {
                'c': 'hamptons'
            }), True)
            _QueryAndVerify(p, b.Callback(), ('photo.caption={c}', {
                'c': 'hammpton'
            }), True)
Example #11
0
    def testQuery(self):
        """Verify photo creation and query by photo id."""
        def _OnQuery(p, p2):
            self.assertEqual(p2.caption, p.caption)
            self.assertEqual(p2.photo_id, p.photo_id)
            self.stop()

        def _OnCreatePhoto(p):
            Photo.Query(self._client, p.photo_id, None, partial(_OnQuery, p))

        photo_id = Photo.ConstructPhotoId(time.time(),
                                          self._mobile_dev.device_id, 1)
        episode_id = Episode.ConstructEpisodeId(time.time(),
                                                self._mobile_dev.device_id, 2)
        p_dict = {
            'photo_id': photo_id,
            'episode_id': episode_id,
            'user_id': self._user.user_id,
            'caption': 'a photo'
        }
        Photo.CreateNew(self._client, callback=_OnCreatePhoto, **p_dict)
Example #12
0
  def testInlineInvalidationsMigration(self):
    """Ensure that the INLINE_INVALIDATIONS migration works correctly."""
    episode_id = Episode.ConstructEpisodeId(1, self._device_ids[0], 1)
    photo_id = Photo.ConstructPhotoId(1, self._device_ids[0], 1)
    request = {'activity': self._tester.CreateActivityDict(self._cookie),
               'episode': {'episode_id': episode_id,
                           'timestamp': 1},
               'photos': [self._CreatePhotoDict(self._cookie, photo_id=photo_id)]}
    self._SendRequest('upload_episode', self._cookie, request,
                      version=Message.EXTRACT_MD5_HASHES)

    request = {'episodes': [{'episode_id': episode_id,
                             'photo_ids': [photo_id]}]}
    self._SendRequest('remove_photos', self._cookie, request,
                      version=Message.EXTRACT_MD5_HASHES)

    request = {'activity': self._tester.CreateActivityDict(self._cookie),
               'viewpoint_id': self._user.private_vp_id,
               'viewed_seq': 2}
    self._SendRequest('update_viewpoint', self._cookie, request,
                      version=Message.EXTRACT_MD5_HASHES)

    response = self._SendRequest('query_notifications', self._cookie, {},
                                 version=Message.EXTRACT_MD5_HASHES)

    # upload_episode notification.
    notify_dict = response['notifications'][1]
    self.assertFalse('inline' in notify_dict)
    self.assertTrue('activity' in notify_dict)
    self.assertEqual(notify_dict['activity']['update_seq'], 1)

    # remove_photos notification.
    notify_dict = response['notifications'][2]
    self.assertFalse('inline' in notify_dict)
    self.assertFalse('activity' in notify_dict)

    # update_viewpoint notification.
    notify_dict = response['notifications'][3]
    self.assertFalse('inline' in notify_dict)
    self.assertFalse('activity' in notify_dict)
Example #13
0
    def _CreateBlockedOperation(self, user_id, device_id, callback):
        """Creates a photo share after locking the viewpoint so that the operation will fail and get retried."""
        photo_id = Photo.ConstructPhotoId(time.time(), device_id, 123)
        self._RunAsync(self._UploadPhotoOperation,
                       user_id,
                       device_id,
                       1,
                       photo_id=photo_id)

        self._RunAsync(Lock.Acquire, self._client, LockResourceType.Viewpoint,
                       'vp123', Operation.ConstructOperationId(device_id, 123))

        request = {
            'user_id':
            user_id,
            'activity': {
                'activity_id': 'a123',
                'timestamp': time.time()
            },
            'viewpoint': {
                'viewpoint_id': 'vp123',
                'type': Viewpoint.EVENT
            },
            'episodes': [{
                'existing_episode_id': 'eg8QVrk3S',
                'new_episode_id': 'eg8QVrk3T',
                'timestamp': time.time(),
                'photo_ids': [photo_id]
            }],
            'contacts': [{
                'identity': 'Local:testing1',
                'name': 'Peter Mattis'
            }]
        }

        Operation.CreateAndExecute(self._client, user_id, device_id,
                                   'ShareNewOperation.Execute', request,
                                   callback)
Example #14
0
    def testUpdateAttribute(self):
        """Verify update of a photo attribute."""
        def _OnUpdate(p):
            p.aspect_ratio = None
            p.Update(self._client, self.stop)

        def _OnQuery(p):
            p.content_type = 'image/png'
            p.Update(self._client, partial(_OnUpdate, p))

        def _OnCreatePhoto(p):
            Photo.Query(self._client, p.photo_id, None, _OnQuery)

        photo_id = Photo.ConstructPhotoId(time.time(),
                                          self._mobile_dev.device_id, 1)
        episode_id = Episode.ConstructEpisodeId(time.time(),
                                                self._mobile_dev.device_id, 2)
        p_dict = {
            'photo_id': photo_id,
            'episode_id': episode_id,
            'user_id': self._user.user_id,
            'caption': 'A Photo'
        }
        Photo.CreateNew(self._client, callback=_OnCreatePhoto, **p_dict)
  def testUpdateEpisode(self):
    """Creates a new episode and photo and updates both."""
    timestamp = time.time()

    episode_id = Episode.ConstructEpisodeId(timestamp, self._device_ids[0], 100)
    ep_dict = {'episode_id': episode_id,
               'timestamp': timestamp,
               'title': 'Episode Title'}

    photo_id = Photo.ConstructPhotoId(timestamp, self._device_ids[0], 100)
    ph_dict = {'aspect_ratio': 1.3333,
               'timestamp': time.time(),
               'tn_md5': util.ComputeMD5Hex('thumbnail image data'),
               'med_md5': util.ComputeMD5Hex('medium image data'),
               'full_md5': util.ComputeMD5Hex('full image data'),
               'orig_md5': util.ComputeMD5Hex('original image data'),
               'tn_size': 5 * 1024,
               'med_size': 10 * 1024,
               'full_size': 150 * 1024,
               'orig_size': 1200 * 1024,
               'photo_id': photo_id}

    self._tester.UploadEpisode(self._cookie, ep_dict, [ph_dict])
    self._tester.UpdateEpisode(self._cookie, episode_id, description='A newly added description')
    def testWrongDeviceIds(self):
        """ERROR: Try to create an episode and photo using device ids that
    are different than the ones in the user cookies.
    """
        bad_episode_id = Episode.ConstructEpisodeId(100, 1000, 1)
        self.assertRaisesHttpError(403,
                                   self._tester.UploadEpisode,
                                   self._cookie,
                                   ep_dict={
                                       'episode_id': bad_episode_id,
                                       'timestamp': 100
                                   },
                                   ph_dict_list=[])

        episode_id = Episode.ConstructEpisodeId(100, self._device_ids[0], 100)
        bad_photo_id = Photo.ConstructPhotoId(100, 1000, 1)
        self.assertRaisesHttpError(403,
                                   self._tester.UploadEpisode,
                                   self._cookie,
                                   ep_dict={},
                                   ph_dict_list=[
                                       self._CreatePhotoDict(
                                           self._cookie, photo_id=bad_photo_id)
                                   ])
Example #17
0
    def testPostIdOrdering(self):
        """Verify that post_id sorts like (episode_id, photo_id) does."""
        def _Compare(episode_id1, photo_id1, episode_id2, photo_id2):
            result = cmp(episode_id1, episode_id2)
            if result == 0:
                result = cmp(photo_id1, photo_id2)

            post_id1 = Post.ConstructPostId(episode_id1, photo_id1)
            post_id2 = Post.ConstructPostId(episode_id2, photo_id2)
            self.assertEqual(cmp(post_id1, post_id2), result)

        timestamp = time.time()

        episode_id1 = Episode.ConstructEpisodeId(timestamp, 1, (127, None))
        episode_id2 = Episode.ConstructEpisodeId(timestamp, 1, (128, None))
        photo_id1 = Photo.ConstructPhotoId(timestamp, 1, 128)
        photo_id2 = Photo.ConstructPhotoId(timestamp, 1, 127)
        _Compare(episode_id1, photo_id1, episode_id2, photo_id2)

        episode_id1 = Episode.ConstructEpisodeId(timestamp, 127, 1)
        episode_id2 = Episode.ConstructEpisodeId(timestamp, 128, 1)
        photo_id1 = Photo.ConstructPhotoId(timestamp, 128, (1, None))
        photo_id2 = Photo.ConstructPhotoId(timestamp, 127, (1, None))
        _Compare(episode_id1, photo_id1, episode_id2, photo_id2)

        episode_id1 = Episode.ConstructEpisodeId(timestamp, 0, 0)
        episode_id2 = Episode.ConstructEpisodeId(timestamp, 0, 0)
        photo_id1 = Photo.ConstructPhotoId(timestamp, 0, 0)
        photo_id2 = Photo.ConstructPhotoId(timestamp, 0, 0)
        _Compare(episode_id1, photo_id1, episode_id2, photo_id2)

        episode_id1 = Episode.ConstructEpisodeId(timestamp, 1, 0)
        episode_id2 = Episode.ConstructEpisodeId(timestamp, 1, 1)
        photo_id1 = Photo.ConstructPhotoId(timestamp, 1, 1)
        photo_id2 = Photo.ConstructPhotoId(timestamp, 1, 0)
        _Compare(episode_id1, photo_id1, episode_id2, photo_id2)

        episode_id1 = Episode.ConstructEpisodeId(0, 0, 0)
        episode_id2 = Episode.ConstructEpisodeId(1, 0, 0)
        photo_id1 = Photo.ConstructPhotoId(1, 0, (0, None))
        photo_id2 = Photo.ConstructPhotoId(0, 0, (0, None))
        _Compare(episode_id1, photo_id1, episode_id2, photo_id2)

        episode_id1 = Episode.ConstructEpisodeId(timestamp, 0, (0, '1'))
        episode_id2 = Episode.ConstructEpisodeId(timestamp, 0, (0, '2'))
        photo_id1 = Photo.ConstructPhotoId(timestamp, 0, (0, None))
        photo_id2 = Photo.ConstructPhotoId(timestamp, 0, (0, None))
        _Compare(episode_id1, photo_id1, episode_id2, photo_id2)

        episode_id1 = Episode.ConstructEpisodeId(timestamp, 0, 0)
        episode_id2 = Episode.ConstructEpisodeId(timestamp, 0, 0)
        photo_id1 = Photo.ConstructPhotoId(timestamp, 0, (0, u'ab'))
        photo_id2 = Photo.ConstructPhotoId(timestamp, 0, (0, u'cd'))
        _Compare(episode_id1, photo_id1, episode_id2, photo_id2)
    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')