@gen.coroutine
  def _AutoSave(self):
    # 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)
For each follower that has enabled auto-save for this viewpoint, trigger save_photos
dataset/ETHPy150Open viewfinderco/viewfinder/backend/op/share_existing_op.py/ShareExistingOperation._AutoSave