@gen.coroutine
  def Unshare(self, client, viewpoint, ep_dicts, followers):
    from viewfinder.backend.db.episode import Episode

    # Gather db keys for all episodes and photos.
    episode_keys = []
    photo_keys = []
    for episode_id, photo_ids in ep_dicts.iteritems():
      episode_keys.append(DBKey(episode_id, None))
      for photo_id in photo_ids:
        photo_keys.append(DBKey(photo_id, None))

    # Query for all episodes and photos in parallel and in batches.
    episodes, photos = yield [gen.Task(Episode.BatchQuery,
                                       client,
                                       episode_keys,
                                       None,
                                       must_exist=False),
                              gen.Task(Photo.BatchQuery,
                                       client,
                                       photo_keys,
                                       None,
                                       must_exist=False)]

    viewpoint_id = viewpoint.viewpoint_id
    user_id = viewpoint.user_id
    ep_iter = iter(episodes)
    ph_iter = iter(photos)
    for episode_id, photo_ids in ep_dicts.iteritems():
      unshare_episode = next(ep_iter)
      acc = Accounting()
      unshare_photos = []
      for photo_id in photo_ids:
        acc.IncrementFromPhoto(next(ph_iter))

      if viewpoint.IsDefault():
        # Decrement owned by stats on both the viewpoint and the user.
        self.GetViewpointOwnedBy(viewpoint_id, user_id).DecrementStatsFrom(acc)
        # Don't recompute owned-by stats, just copy them from the viewpoint accounting object.
        self.GetUserOwnedBy(user_id).CopyStatsFrom(self.GetViewpointOwnedBy(viewpoint_id, user_id))
      else:
        # Viewpoint shared_by for sharer.
        self.GetViewpointSharedBy(viewpoint_id, unshare_episode.user_id).DecrementStatsFrom(acc)
        # Viewpoint visible_to for viewpoint.
        self.GetViewpointVisibleTo(viewpoint_id).DecrementStatsFrom(acc)
        # User shared_by for sharer.
        self.GetUserSharedBy(unshare_episode.user_id).DecrementStatsFrom(acc)

        # Viewpoint visible_to for followers.
        for follower in followers:
          if not follower.IsRemoved():
            self.GetUserVisibleTo(follower.user_id).DecrementStatsFrom(acc)
Generate and update accounting entries for an Unshare event. Multiple episodes may be
dataset/ETHPy150Open viewfinderco/viewfinder/backend/db/accounting.py/AccountingAccumulator.Unshare