Пример #1
0
  def _AutoSave(self):
    """For each follower that has enabled auto-save for this viewpoint, trigger save_photos
    operation that will save the shared photos to their default viewpoint.
    """
    # Get ids of all the source episodes that will be provided to save_photos.
    source_ep_ids = [ep_dict['new_episode_id'] for ep_dict in self._ep_dicts]

    for follower in self._followers:
      # Skip follower if he did not mark this viewpoint for auto-saving.
      if not follower.ShouldAutoSave():
        continue

      # Skip follower if he is removed from the conversation.
      if follower.IsRemoved():
        continue

      follower_user = yield gen.Task(User.Query, self._client, follower.user_id, None)

      # Skip follower if he is the sharer, and is sharing only episodes from his default viewpoint.
      if follower_user.user_id == self._user_id:
        if all(source_episode.viewpoint_id == follower_user.private_vp_id
          for source_episode, posts in self._source_ep_posts_list):
            continue

      # Allocate ids for save_photos operation and activity.
      first_id = yield gen.Task(User.AllocateAssetIds, self._client, follower.user_id, 2)
      op_id = Operation.ConstructOperationId(follower_user.webapp_dev_id, first_id)
      activity_id = Activity.ConstructActivityId(self._act_dict['timestamp'],
                                                 follower_user.webapp_dev_id,
                                                 first_id + 1)

      # Generate ids for any target episodes that don't already exist.
      target_ep_ids = yield ViewfinderOperation._AllocateTargetEpisodeIds(self._client,
                                                                          follower.user_id,
                                                                          follower_user.webapp_dev_id,
                                                                          follower_user.private_vp_id,
                                                                          source_ep_ids)

      # Create target episode dicts expected by the SavePhotos op.
      target_eps_list = []
      for ep_dict, target_ep_id in zip(self._ep_dicts, target_ep_ids):
        target_eps_list.append({'existing_episode_id': ep_dict['new_episode_id'],
                                'new_episode_id': target_ep_id,
                                'photo_ids': ep_dict['photo_ids']})

      save_photos_dict = {'headers': {'op_id': op_id, 'op_timestamp': self._op.timestamp},
                          'user_id': follower.user_id,
                          'activity': {'activity_id': activity_id, 'timestamp': self._act_dict['timestamp']},
                          'episodes': target_eps_list}

      # Create the save_photos op for this user. Use the raw DBClient instance since self._client
      # is wrapped with OpMgrDBClient. 
      yield gen.Task(Operation.CreateAndExecute,
                     DBClient.Instance(),
                     follower.user_id,
                     follower_user.webapp_dev_id,
                     'SavePhotosOperation.Execute',
                     save_photos_dict)
Пример #2
0
    def _AutoSave(self):
        """For each follower that has enabled auto-save for this viewpoint, trigger save_photos
    operation that will save the shared photos to their default viewpoint.
    """
        # Get ids of all the source episodes that will be provided to save_photos.
        source_ep_ids = [
            ep_dict['new_episode_id'] for ep_dict in self._ep_dicts
        ]

        for follower in self._followers:
            # Skip follower if he did not mark this viewpoint for auto-saving.
            if not follower.ShouldAutoSave():
                continue

            # Skip follower if he is removed from the conversation.
            if follower.IsRemoved():
                continue

            follower_user = yield gen.Task(User.Query, self._client,
                                           follower.user_id, None)

            # Skip follower if he is the sharer, and is sharing only episodes from his default viewpoint.
            if follower_user.user_id == self._user_id:
                if all(source_episode.viewpoint_id ==
                       follower_user.private_vp_id for source_episode, posts in
                       self._source_ep_posts_list):
                    continue

            # Allocate ids for save_photos operation and activity.
            first_id = yield gen.Task(User.AllocateAssetIds, self._client,
                                      follower.user_id, 2)
            op_id = Operation.ConstructOperationId(follower_user.webapp_dev_id,
                                                   first_id)
            activity_id = Activity.ConstructActivityId(
                self._act_dict['timestamp'], follower_user.webapp_dev_id,
                first_id + 1)

            # Generate ids for any target episodes that don't already exist.
            target_ep_ids = yield ViewfinderOperation._AllocateTargetEpisodeIds(
                self._client, follower.user_id, follower_user.webapp_dev_id,
                follower_user.private_vp_id, source_ep_ids)

            # Create target episode dicts expected by the SavePhotos op.
            target_eps_list = []
            for ep_dict, target_ep_id in zip(self._ep_dicts, target_ep_ids):
                target_eps_list.append({
                    'existing_episode_id':
                    ep_dict['new_episode_id'],
                    'new_episode_id':
                    target_ep_id,
                    'photo_ids':
                    ep_dict['photo_ids']
                })

            save_photos_dict = {
                'headers': {
                    'op_id': op_id,
                    'op_timestamp': self._op.timestamp
                },
                'user_id': follower.user_id,
                'activity': {
                    'activity_id': activity_id,
                    'timestamp': self._act_dict['timestamp']
                },
                'episodes': target_eps_list
            }

            # Create the save_photos op for this user. Use the raw DBClient instance since self._client
            # is wrapped with OpMgrDBClient.
            yield gen.Task(Operation.CreateAndExecute, DBClient.Instance(),
                           follower.user_id, follower_user.webapp_dev_id,
                           'SavePhotosOperation.Execute', save_photos_dict)
Пример #3
0
  def _CreateSaveEpisodeDicts(self):
    """Creates a list of dicts describing the source and target episodes of the save. The
    episode dicts passed in the save_photos request are combined with episodes in any of the
    viewpoints passed in the save_photos request. Returns the list.
    """
    # Query episode ids from viewpoints given in the request, but skip those that are already in the request.
    vp_ep_ids = []
    skip_vp_ep_ids = set(ep_dict['existing_episode_id'] for ep_dict in self._ep_dicts)

    # Query photo_ids from viewpoint episodes.
    ep_ph_ids = {}

    @gen.coroutine
    def _VisitPosts(photo_ids, post):
      photo_ids.append(post.photo_id)

    @gen.coroutine
    def _VisitEpisodeKeys(episode_key):
      episode_id = episode_key.hash_key

      # Get list of episodes in the viewpoint that need a target episode id discovered/generated.
      if episode_id not in skip_vp_ep_ids:
        vp_ep_ids.append(episode_id)

      # For each episode in the viewpoint, get the complete list of photo ids in that episode.
      photo_ids = []
      yield gen.Task(Post.VisitRange, self._client, episode_id, None, None, partial(_VisitPosts, photo_ids))
      ep_ph_ids[episode_id] = photo_ids

    tasks = []
    for viewpoint_id in set(self._viewpoint_ids):
      query_expr = ('episode.viewpoint_id={id}', {'id': viewpoint_id})
      tasks.append(gen.Task(Episode.VisitIndexKeys, self._client, query_expr, _VisitEpisodeKeys))
    yield tasks

    # Allocate target ids for all episodes not given by the client.
    target_ep_ids = yield ViewfinderOperation._AllocateTargetEpisodeIds(self._client,
                                                                        self._user.user_id,
                                                                        self._user.webapp_dev_id,
                                                                        self._user.private_vp_id,
                                                                        vp_ep_ids)

    # Create save dicts for each of the viewpoint episodes to save.
    save_ep_dicts = {}
    for source_ep_id, target_ep_id in zip(vp_ep_ids, target_ep_ids):
      save_ep_dicts[target_ep_id] = {'existing_episode_id': source_ep_id,
                                     'new_episode_id': target_ep_id,
                                     'photo_ids': ep_ph_ids[source_ep_id]}

    # Now add the save dicts from the request, validating rules as we go.
    for ep_dict in self._ep_dicts:
      existing_ep_dict = save_ep_dicts.get(ep_dict['new_episode_id'], None)
      if existing_ep_dict is not None:
        if ep_dict['existing_episode_id'] != existing_ep_dict['existing_episode_id']:
          raise InvalidRequestError('Cannot save episodes "%s" and "%s" to same target episode "%s".' %
                                    (existing_ep_dict['existing_episode_id'],
                                     ep_dict['existing_episode_id'],
                                     ep_dict['new_episode_id']))

        existing_ep_dict['photo_ids'].extend(ep_dict['photo_ids'])
        existing_ep_dict['photo_ids'] = sorted(set(existing_ep_dict['photo_ids']))
      else:
        photo_ids = ep_dict['photo_ids']
        if ep_dict['existing_episode_id'] in ep_ph_ids:
          photo_ids.extend(ep_ph_ids[ep_dict['existing_episode_id']])

        save_ep_dicts[ep_dict['new_episode_id']] = {'existing_episode_id': ep_dict['existing_episode_id'],
                                                    'new_episode_id': ep_dict['new_episode_id'],
                                                    'photo_ids': sorted(set(photo_ids))}

    save_ep_dicts = [ep_dict for ep_dict in save_ep_dicts.itervalues()]
    save_ep_dicts.sort(key=itemgetter('new_episode_id'))
    raise gen.Return(save_ep_dicts)