@classmethod
  def QueryPosts(cls, client, episode_id, user_id, callback,
                 limit=None, excl_start_key=None, base_results=None):
    def _OnQueryMetadata(posts, results):
      """Constructs the photo metadata to return. The "check_label" argument
      is used to determine whether to use the old permissions model or the
      new one. If "check_label" is true, then only return a photo if a label
      is present. Otherwise, the photo is part of an episode created by
      the new sharing functionality, and the user automatically has access
      to all photos in that episode.
      """
      ph_dicts = base_results or []
      for post, (photo, user_post) in zip(posts, results):
        ph_dict = photo._asdict()
        labels = post.labels.combine()
        if user_post is not None:
          labels = labels.union(user_post.labels.combine())
        if len(labels) > 0:
          ph_dict['labels'] = list(labels)
        ph_dicts.append(ph_dict)

      last_key = posts[-1].photo_id if len(posts) > 0 else None
      if last_key is not None and len(ph_dicts) < limit:
        Episode.QueryPosts(client, episode_id, user_id, callback, limit=limit,
                           excl_start_key=last_key, base_results=ph_dicts)
      else:
        callback((ph_dicts, last_key))

    def _OnQueryPosts(posts):
      with util.ArrayBarrier(partial(_OnQueryMetadata, posts)) as b:
        for post in posts:
          with util.ArrayBarrier(b.Callback()) as metadata_b:
            post_id = Post.ConstructPostId(post.episode_id, post.photo_id)
            Photo.Query(client, hash_key=post.photo_id, col_names=None,
                        callback=metadata_b.Callback())
            UserPost.Query(client, hash_key=user_id, range_key=post_id,
                           col_names=None, callback=metadata_b.Callback(), must_exist=False)

    # Query the posts with limit & excl_start_key.
    Post.RangeQuery(client, hash_key=episode_id, range_desc=None, limit=limit,
                    col_names=None, callback=_OnQueryPosts, excl_start_key=excl_start_key)
Queries posts (up to 'limit' total) for the specified
dataset/ETHPy150Open viewfinderco/viewfinder/backend/db/episode.py/Episode.QueryPosts