          elif not os.path.isdir(input_aligned_dir):
              logger.warning("Aligned directory not found. All faces listed in the "
                             "alignments file will be converted")
          else:
              faces_to_swap = [Path(path)
                               for path in get_image_paths(input_aligned_dir)]
              if not faces_to_swap:
                  logger.warning("Aligned directory is empty, no faces will be converted!")
              elif len(faces_to_swap) <= len(self.input_images) / 3:
                  logger.warning("Aligned directory contains an amount of images much less than "
                                 "the input, are you sure this is the right directory?")
          return faces_to_swap
  
      # SKIP FRAME RANGES #
      def get_frame_ranges(self):
          """ split out the frame ranges and parse out 'min' and 'max' values """
          if not self.args.frame_ranges:
 
</s> remove             logger.info("Aligned directory not specified. All faces listed in the "
                        "alignments file will be converted")
 </s> add             logger.verbose("Aligned directory not specified. All faces listed in the "
                           "alignments file will be converted") </s> remove             which faces in the target frames should be swapped """
        faces_to_swap = None
 </s> add             which faces in the target frames should be swapped.
            If it exists, obtain the hashes of the faces in the folder """
        face_hashes = list() </s> remove     def get_aligned_directory(self):
 </s> add     def remove_skipped_faces(self):
        """ Remove deleted faces from the loaded alignments """
        logger.debug("Filtering Faces")
        face_hashes = self.get_face_hashes()
        if not face_hashes:
            logger.debug("No face hashes. Not skipping any faces")
            return
        pre_face_count = self.alignments.faces_count
        self.alignments.filter_hashes(face_hashes, filter_out=False)
        logger.info("Faces filtered out: %s", pre_face_count - self.alignments.faces_count)

    def get_face_hashes(self): </s> remove             positions, so generate a warning and exit """
        if any(alignment.get("r", None)
               for val in self.alignments.data.values()
               for alignment in val):
            logger.error("There are rotated frames in the alignments "
                         "file. Position of faces will not be correctly "
                         "calculated for these frames. You should run rotation "
                         "tool to update the file prior to running sort: "
                         "'python tools.py alignments -j rotate -a "
                         "<alignments_file> -fr <frames_folder>'")
 </s> add             positions. Faces without hashes won't process.
            Check for these and generate a warning and exit """
        rotated = self.alignments.get_legacy_rotation()
        hashes = self.alignments.get_legacy_no_hashes()
        if rotated or hashes:
            logger.error("Legacy alignments found. Sort cannot continue. You should run legacy "
                         "tool to update the file prior to running sort: 'python tools.py "
                         "alignments -j legacy -a <alignments_file> -fr <frames_folder> -fc "
                         "<faces_folder>'") </s> remove         elif self.type == "faces" and self.job not in ("multi-faces",
                                                       "leftover-faces"):
 </s> add         elif self.type == "faces" and self.job not in ("multi-faces", "leftover-faces"):
            file_list = [path for path in get_image_paths(input_aligned_dir)]
            logger.info("Getting Face Hashes for selected Aligned Images")
            for face in tqdm(file_list, desc="Hashing Faces"):
                face_hashes.append(hash_image_file(face))
            logger.debug("Face Hashes: %s", (len(face_hashes)))
            if not face_hashes:
                logger.error("Aligned directory is empty, no faces will be converted!")
                exit(1)
            elif len(face_hashes) <= len(self.input_images) / 3:
                logger.warning("Aligned directory contains far fewer images than the input "
                               "directory, are you sure this is the right folder?")
        return face_hashes
          elif not os.path.isdir(input_aligned_dir):
              logger.warning("Aligned directory not found. All faces listed in the "
                             "alignments file will be converted")
          else:
            file_list = [path for path in get_image_paths(input_aligned_dir)]
            logger.info("Getting Face Hashes for selected Aligned Images")
            for face in tqdm(file_list, desc="Hashing Faces"):
                face_hashes.append(hash_image_file(face))
            logger.debug("Face Hashes: %s", (len(face_hashes)))
            if not face_hashes:
                logger.error("Aligned directory is empty, no faces will be converted!")
                exit(1)
            elif len(face_hashes) <= len(self.input_images) / 3:
                logger.warning("Aligned directory contains far fewer images than the input "
                               "directory, are you sure this is the right folder?")
        return face_hashes
            file_list = [path for path in get_image_paths(input_aligned_dir)]
            logger.info("Getting Face Hashes for selected Aligned Images")
            for face in tqdm(file_list, desc="Hashing Faces"):
                face_hashes.append(hash_image_file(face))
            logger.debug("Face Hashes: %s", (len(face_hashes)))
            if not face_hashes:
                logger.error("Aligned directory is empty, no faces will be converted!")
                exit(1)
            elif len(face_hashes) <= len(self.input_images) / 3:
                logger.warning("Aligned directory contains far fewer images than the input "
                               "directory, are you sure this is the right folder?")
        return face_hashes
            file_list = [path for path in get_image_paths(input_aligned_dir)]
            logger.info("Getting Face Hashes for selected Aligned Images")
            for face in tqdm(file_list, desc="Hashing Faces"):
                face_hashes.append(hash_image_file(face))
            logger.debug("Face Hashes: %s", (len(face_hashes)))
            if not face_hashes:
                logger.error("Aligned directory is empty, no faces will be converted!")
                exit(1)
            elif len(face_hashes) <= len(self.input_images) / 3:
                logger.warning("Aligned directory contains far fewer images than the input "
                               "directory, are you sure this is the right folder?")
        return face_hashes
            file_list = [path for path in get_image_paths(input_aligned_dir)]
            logger.info("Getting Face Hashes for selected Aligned Images")
            for face in tqdm(file_list, desc="Hashing Faces"):
                face_hashes.append(hash_image_file(face))
            logger.debug("Face Hashes: %s", (len(face_hashes)))
            if not face_hashes:
                logger.error("Aligned directory is empty, no faces will be converted!")
                exit(1)
            elif len(face_hashes) <= len(self.input_images) / 3:
                logger.warning("Aligned directory contains far fewer images than the input "
                               "directory, are you sure this is the right folder?")
        return face_hashes
            file_list = [path for path in get_image_paths(input_aligned_dir)]
            logger.info("Getting Face Hashes for selected Aligned Images")
            for face in tqdm(file_list, desc="Hashing Faces"):
                face_hashes.append(hash_image_file(face))
            logger.debug("Face Hashes: %s", (len(face_hashes)))
            if not face_hashes:
                logger.error("Aligned directory is empty, no faces will be converted!")
                exit(1)
            elif len(face_hashes) <= len(self.input_images) / 3:
                logger.warning("Aligned directory contains far fewer images than the input "
                               "directory, are you sure this is the right folder?")
        return face_hashes
            file_list = [path for path in get_image_paths(input_aligned_dir)]
            logger.info("Getting Face Hashes for selected Aligned Images")
            for face in tqdm(file_list, desc="Hashing Faces"):
                face_hashes.append(hash_image_file(face))
            logger.debug("Face Hashes: %s", (len(face_hashes)))
            if not face_hashes:
                logger.error("Aligned directory is empty, no faces will be converted!")
                exit(1)
            elif len(face_hashes) <= len(self.input_images) / 3:
                logger.warning("Aligned directory contains far fewer images than the input "
                               "directory, are you sure this is the right folder?")
        return face_hashes
            file_list = [path for path in get_image_paths(input_aligned_dir)]
            logger.info("Getting Face Hashes for selected Aligned Images")
            for face in tqdm(file_list, desc="Hashing Faces"):
                face_hashes.append(hash_image_file(face))
            logger.debug("Face Hashes: %s", (len(face_hashes)))
            if not face_hashes:
                logger.error("Aligned directory is empty, no faces will be converted!")
                exit(1)
            elif len(face_hashes) <= len(self.input_images) / 3:
                logger.warning("Aligned directory contains far fewer images than the input "
                               "directory, are you sure this is the right folder?")
        return face_hashes
            file_list = [path for path in get_image_paths(input_aligned_dir)]
            logger.info("Getting Face Hashes for selected Aligned Images")
            for face in tqdm(file_list, desc="Hashing Faces"):
                face_hashes.append(hash_image_file(face))
            logger.debug("Face Hashes: %s", (len(face_hashes)))
            if not face_hashes:
                logger.error("Aligned directory is empty, no faces will be converted!")
                exit(1)
            elif len(face_hashes) <= len(self.input_images) / 3:
                logger.warning("Aligned directory contains far fewer images than the input "
                               "directory, are you sure this is the right folder?")
        return face_hashes
  
      # SKIP FRAME RANGES #
      def get_frame_ranges(self):
          """ split out the frame ranges and parse out 'min' and 'max' values """
          if not self.args.frame_ranges:
keep keep keep keep replace replace replace replace replace replace replace replace keep keep keep keep keep
 Add Face Hashes to Alignments (#550)

* Convert main scripts to use face hashes

* Alignment tool: Use hashes, add logging, add face rename function

* More logging. Update Manual tool to work with hashing 
scripts/convert.py