コード例 #1
0
ファイル: formatters.py プロジェクト: zorro0799/viewfinder
 def _FormatAttribute(self, name, value):
     """Returns the attribute value; If none, returns '-'. Formats by
 default the following fields: 'viewpoint_id', 'episode_id',
 'photo_id', 'timestamp', 'Location', 'Placemark'.
 """
     if name == 'viewpoint_id' or name == 'private_vp_id':
         did, (vid, sid) = Viewpoint.DeconstructViewpointId(value)
         pretty = '%s/%d/%d' % (value, did, vid)
         return FmtDefault._ViewpointLink(value, pretty)
     elif name == 'user_id' or name == 'sender_id':
         return self._UserLink(value)
     elif name == 'episode_id' or name == 'parent_ep_id':
         ts, did, (eid, sid) = Episode.DeconstructEpisodeId(value)
         pretty = '%s/%d/%d' % (value, did, eid)
         return self._EpisodeLink(value, pretty)
     elif name == 'photo_id' or name == 'parent_id':
         ts, did, (pid, sid) = Photo.DeconstructPhotoId(value)
         pretty = '%s/%d/%d' % (value, did, pid)
         return self._PhotoLink(value, pretty)
     elif name == 'timestamp' or name == 'last_updated' or name == 'expires' or name == 'last_fetch':
         return self._FormatTimestamp(value)
     elif name == 'location':
         return self._XEscape(', '.join([
             '%s: %s' % (k, v)
             for k, v in UnpackLocation(value)._asdict().items()
         ]))
     elif name == 'placemark':
         return self._XEscape(', '.join([
             '%s: %s' % (k, v)
             for k, v in UnpackPlacemark(value)._asdict().items()
         ]))
     else:
         return self._XEscape('%s' % value)
コード例 #2
0
    def _AllocateTargetEpisodeIds(self, client, user_id, device_id,
                                  target_viewpoint_id, source_ep_ids):
        """For each episode listed in "source_ep_ids", determines if a child episode already
    exists in the given viewpoint. If not, allocates a new episode id using the user's asset
    id allocator. The same timestamp used to create the source episode id is used to create
    the target episode id.

    Returns the list of target episodes ids, including both existing ids and allocated ids.
    """
        # First check whether each episode has already been shared/saved into the target viewpoint.
        tasks = []
        for source_ep_id in source_ep_ids:
            query_expr = ('episode.parent_ep_id={id}', {'id': source_ep_id})
            tasks.append(gen.Task(Episode.IndexQuery, client, query_expr,
                                  None))

        target_ep_ids = []
        allocate_ids_count = 0
        target_episodes_list = yield tasks
        for target_episodes in target_episodes_list:
            found_match = False
            for episode in target_episodes:
                if episode.viewpoint_id == target_viewpoint_id:
                    target_ep_ids.append(episode.episode_id)
                    found_match = True
                    break

            # If no matching child episode, then need to allocate an episode id.
            if not found_match:
                target_ep_ids.append(None)
                allocate_ids_count += 1

        if allocate_ids_count > 0:
            # Allocate ids for any episodes which do not yet exist, and merge them into target_ep_ids.
            id = yield gen.Task(User.AllocateAssetIds, client, user_id,
                                allocate_ids_count)
            for i, source_ep_id in enumerate(source_ep_ids):
                if target_ep_ids[i] is None:
                    timestamp, _, _ = source_ep_id = Episode.DeconstructEpisodeId(
                        source_ep_id)
                    target_ep_ids[i] = Episode.ConstructEpisodeId(
                        timestamp, device_id, id)
                    id += 1

        raise gen.Return(target_ep_ids)
コード例 #3
0
    def _GetShareInfo(cls, activity):
        """Returns a tuple with information about a "share_existing" or "share_new" operation:
         episode_dates: List of timestamps for each episode in the share.
         num_shares: Total count of photos shared.
    """
        episode_dates = []
        num_shares = 0

        args_dict = json.loads(activity.json)
        for ep_dict in args_dict['episodes']:
            # Extract timestamps from episode id so that we don't need to query for episode object.
            ts, dev_id, uniquifier = Episode.DeconstructEpisodeId(
                ep_dict['episode_id'])
            episode_dates.append(date.fromtimestamp(ts))

            num_shares += len(ep_dict['photo_ids'])

        return (episode_dates, num_shares)
コード例 #4
0
def _ValidateAutoSave(tester, user_id, device_id, request_dict):
    """Validates that the shared photos have been saved to the default viewpoint of any follower
  that has the target viewpoint marked as "auto-save".
  """
    from viewfinder.backend.www.test.save_photos_test import _ValidateSavePhotos
    validator = tester.validator

    # Validate auto-save.
    follower_matches = lambda f: f.viewpoint_id == request_dict['viewpoint_id']
    for follower in validator.QueryModelObjects(Follower,
                                                predicate=follower_matches):
        # Only validate current followers that have viewpoint marked as auto-save.
        if not follower.ShouldAutoSave() or follower.IsRemoved():
            continue

        follower_user = tester._RunAsync(User.Query, validator.client,
                                         follower.user_id, None)

        # Skip validation of follower that is sharing from default viewpoint.
        source_episodes = [
            validator.GetModelObject(Episode, ep_dict['existing_episode_id'])
            for ep_dict in request_dict['episodes']
        ]
        if all(ep.viewpoint_id == follower_user.private_vp_id
               for ep in source_episodes):
            continue

        # The share_existing op triggered a save_photos op, so wait for that to complete.
        tester._RunAsync(OpManager.Instance().WaitForUserOps, validator.client,
                         follower.user_id)

        # Get the ids of episodes that should have been created during the auto-save.
        expected_asset_id = follower_user.asset_id_seq

        save_request_dict = deepcopy(request_dict)

        # Iterate backwards, since last episode should have used last asset id.
        for ep_dict in reversed(save_request_dict['episodes']):
            # The share_existing "new_episode_id" becomes the "existing_episode_id" for save_photos.
            ep_dict['existing_episode_id'] = ep_dict['new_episode_id']

            # If target episode already existed, that should have been used.
            episode_matches = lambda e: e.user_id == follower.user_id and e.parent_ep_id == ep_dict[
                'existing_episode_id']
            episodes = validator.QueryModelObjects(Episode,
                                                   predicate=episode_matches)
            if episodes:
                ep_dict['new_episode_id'] = episodes[0].episode_id
            else:
                expected_asset_id -= 1
                timestamp, _, _ = Episode.DeconstructEpisodeId(
                    ep_dict['existing_episode_id'])
                ep_dict['new_episode_id'] = Episode.ConstructEpisodeId(
                    timestamp, follower_user.webapp_dev_id, expected_asset_id)

        # Create expected activity dict for the save_photos op.
        expected_asset_id -= 1
        save_activity_id = Activity.ConstructActivityId(
            request_dict['activity']['timestamp'], follower_user.webapp_dev_id,
            expected_asset_id)
        save_request_dict['activity']['activity_id'] = save_activity_id

        # Create expected operation id for the save_photos op.
        expected_asset_id -= 1
        save_op_id = Operation.ConstructOperationId(
            follower_user.webapp_dev_id, expected_asset_id)
        save_request_dict['headers']['op_id'] = save_op_id

        _ValidateSavePhotos(tester, follower.user_id,
                            follower_user.webapp_dev_id, save_request_dict)