@gen.engine
  def _CheckMultipleShareNew(self, viewpoint, activities, callback):
    # Gather any duplicate share_new activities.
    earliest_activity = None
    dup_activities = []
    for activity in activities:
      if activity.name == 'share_new':
        if earliest_activity is None:
          earliest_activity = activity
        elif activity.timestamp < earliest_activity.timestamp and activity.user_id == viewpoint.user_id:
          dup_activities.append(earliest_activity)
          earliest_activity = activity
        else:
          dup_activities.append(activity)

    # Report corruption for each duplicate.
    if len(dup_activities) > 0:
      for activity in dup_activities:
        # Only support empty or matching or redundant follower_ids.
        follower_ids = json.loads(activity.json)['follower_ids']
        assert len(follower_ids) == 0 or follower_ids == json.loads(earliest_activity.json)['follower_ids'] or \
               (len(follower_ids) == 1 and follower_ids[0] == viewpoint.user_id), \
               (activity, earliest_activity)
        yield gen.Task(self._ReportCorruption, viewpoint.viewpoint_id,
                       'multiple share_new activities', (earliest_activity.activity_id, activity.activity_id),
                       partial(self._RepairMultipleShareNew, activity))
    callback()
Checks that a viewpoint has at most one share_new activity.
dataset/ETHPy150Open viewfinderco/viewfinder/backend/db/tools/dbchk.py/DatabaseChecker._CheckMultipleShareNew