      def check_tkinter_available(command):
          """ Check whether TkInter is installed on user's machine """
          tkinter_vars = [tk, ttk, filedialog, messagebox, TclError]
          if any(var is None for var in tkinter_vars):
              if "gui" in command:
                  print(
                      "It looks like TkInter isn't installed for your OS, so "
                      "the GUI has been "
                      "disabled. To enable the GUI please install the TkInter "
                      "application.\n"
                      "You can try:\n"
                      "  Windows/macOS:      Install ActiveTcl Community "
                      "Edition from "
                      "www.activestate.com\n"
                      "  Ubuntu/Mint/Debian: sudo apt install python3-tk\n"
                      "  Arch:               sudo pacman -S tk\n"
                      "  CentOS/Redhat:      sudo yum install tkinter\n"
                      "  Fedora:             sudo dnf install python3-tkinter\n",
                      file=sys.stderr)
              return False
          return True
  
      def extract_options(self, subparsers):
          """ Extract the existing ArgParse Options """
 
</s> remove     def check_tkinter_available(command):
 </s> add     def check_tkinter_available(): </s> remove         filter_files = self.arguments.filter
        if not isinstance(self.arguments.filter, list):
            filter_files = [self.arguments.filter]
        filter_files = list(filter(lambda fn: Path(fn).exists(), filter_files))
        
        if filter_files:
            import_FaceFilter()
            print('Loading reference images for filtering: %s' % filter_files)
            return FaceFilter(filter_files, nfilter_files, self.arguments.ref_threshold)
 </s> add     @staticmethod
    def get_optional_arguments():
        """ Put the arguments in a list so that they are accessible from both argparse and gui """
        argument_list = []
        argument_list.append({"opts": ("-r", "--rotate-images"),
                              "type": str,
                              "dest": "rotate_images",
                              "default": None,
                              "help": "If a face isn't found, rotate the images to try to "
                                      "find a face. Can find more faces at the cost of extraction "
                                      "speed. Pass in a single number to use increments of that "
                                      "size up to 360, or pass in a list of numbers to enumerate "
                                      "exactly what angles to check"})
        argument_list.append({"opts": ("-bt", "--blur-threshold"),
                              "type": int,
                              "dest": "blur_thresh",
                              "default": None,
                              "help": "Automatically discard images blurrier than the specified "
                                      "threshold. Discarded images are moved into a \"blurry\" "
                                      "sub-folder. Lower values allow more blur"})
        argument_list.append({"opts": ("-j", "--processes"),
                              "type": int,
                              "default": 1,
                              "help": "Number of CPU processes to use. WARNING: ONLY USE THIS "
                                      " IF YOU ARE NOT EXTRACTING ON A GPU. Anything above 1 "
                                      " process on a GPU will run out of memory and will crash"})
        argument_list.append({"opts": ("-s", "--skip-existing"),
                              "action": "store_true",
                              "dest": "skip_existing",
                              "default": False,
                              "help": "Skips frames that have already been extracted"})
        argument_list.append({"opts": ("-dl", "--debug-landmarks"),
                              "action": "store_true",
                              "dest": "debug_landmarks",
                              "default": False,
                              "help": "Draw landmarks on the ouput faces for debug"})
        argument_list.append({"opts": ("-ae", "--align-eyes"),
                              "action": "store_true",
                              "dest": "align_eyes",
                              "default": False,
                              "help": "Perform extra alignment to ensure left/right eyes "
                                      "are  at the same height"})
        return argument_list </s> remove             if 'gui' in command:
                print('Could not detect a display. The GUI has been disabled.')
                if os.name == 'posix':
                    print('macOS users need to install XQuartz. '
                          'See https://support.apple.com/en-gb/HT201341')
 </s> add             if os.name == 'posix':
                print('macOS users need to install XQuartz. '
                      'See https://support.apple.com/en-gb/HT201341') </s> remove     def parse_arguments(self, description, subparser, command):
        for option in self.argument_list:
            args = option['opts']
            kwargs = {key: option[key] for key in option.keys() if key != 'opts'}
            self.parser.add_argument(*args, **kwargs)
        
        self.parser = self.add_optional_arguments(self.parser)
        self.parser.set_defaults(func=self.process_arguments)
 </s> add     @staticmethod
    def get_optional_arguments():
        """ Put the arguments in a list so that they are accessible from both argparse and gui """
        argument_list = []
        argument_list.append({"opts": ("-m", "--model-dir"),
                              "action": FullPaths,
                              "dest": "model_dir",
                              "default": "models",
                              "help": "Model directory. A directory containing the trained model "
                                      "you wish to process. Defaults to 'models'"})
        argument_list.append({"opts": ("-a", "--input-aligned-dir"),
                              "action": FullPaths,
                              "dest": "input_aligned_dir",
                              "default": None,
                              "help": "Input \"aligned directory\". A directory that should "
                                      "contain the aligned faces extracted from the input files. "
                                      "If you delete faces from this folder, they'll be skipped "
                                      "during conversion. If no aligned dir is specified, all "
                                      "faces will be converted"})
        argument_list.append({"opts": ("-t", "--trainer"),
                              "type": str,
                              # case sensitive because this is used to load a plug-in.
                              "choices": PluginLoader.get_available_models(),
                              "default": PluginLoader.get_default_model(),
                              "help": "Select the trainer that was used to create the model"})
        argument_list.append({"opts": ("-c", "--converter"),
                              "type": str,
                              # case sensitive because this is used to load a plugin.
                              "choices": ("Masked", "Adjust"),
                              "default": "Masked",
                              "help": "Converter to use"})
        argument_list.append({"opts": ("-b", "--blur-size"),
                              "type": int,
                              "default": 2,
                              "help": "Blur size. (Masked converter only)"})
        argument_list.append({"opts": ("-e", "--erosion-kernel-size"),
                              "dest": "erosion_kernel_size",
                              "type": int,
                              "default": None,
                              "help": "Erosion kernel size. Positive values apply erosion "
                                      "which reduces the edge of the swapped face. Negative "
                                      "values apply dilation which allows the swapped face "
                                      "to cover more space. (Masked converter only)"})
        argument_list.append({"opts": ("-M", "--mask-type"),
                              #lowercase this, because its just a string later on.
                              "type": str.lower,
                              "dest": "mask_type",
                              "choices": ["rect", "facehull", "facehullandrect"],
                              "default": "facehullandrect",
                              "help": "Mask to use to replace faces. (Masked converter only)"})
        argument_list.append({"opts": ("-sh", "--sharpen"),
                              "type": str.lower,
                              "dest": "sharpen_image",
                              "choices": ["bsharpen", "gsharpen"],
                              "default": None,
                              "help": "Use Sharpen Image.bsharpen for Box Blur, gsharpen for "
                                      "Gaussian Blur (Masked converter only)"})
        argument_list.append({"opts": ("-g", "--gpus"),
                              "type": int,
                              "default": 1,
                              "help": "Number of GPUs to use for conversion"})
        argument_list.append({"opts": ("-fr", "--frame-ranges"),
                              "nargs": "+",
                              "type": str,
                              "help": "frame ranges to apply transfer to e.g. For frames 10 to "
                                      "50 and 90 to 100 use --frame-ranges 10-50 90-100. Files "
                                      "must have the frame-number as the last number in the "
                                      "name!"})
        argument_list.append({"opts": ("-d", "--discard-frames"),
                              "action": "store_true",
                              "dest": "discard_frames",
                              "default": False,
                              "help": "When used with --frame-ranges discards frames that are "
                                      "not processed instead of writing them out unchanged"})
        argument_list.append({"opts": ("-s", "--swap-model"),
                              "action": "store_true",
                              "dest": "swap_model",
                              "default": False,
                              "help": "Swap the model. Instead of A -> B, swap B -> A"})
        argument_list.append({"opts": ("-S", "--seamless"),
                              "action": "store_true",
                              "dest": "seamless_clone",
                              "default": False,
                              "help": "Use cv2's seamless clone. (Masked converter only)"})
        argument_list.append({"opts": ("-mh", "--match-histgoram"),
                              "action": "store_true",
                              "dest": "match_histogram",
                              "default": False,
                              "help": "Use histogram matching. (Masked converter only)"})
        argument_list.append({"opts": ("-sm", "--smooth-mask"),
                              "action": "store_true",
                              "dest": "smooth_mask",
                              "default": True,
                              "help": "Smooth mask (Adjust converter only)"})
        argument_list.append({"opts": ("-aca", "--avg-color-adjust"),
                              "action": "store_true",
                              "dest": "avg_color_adjust",
                              "default": True,
                              "help": "Average color adjust. (Adjust converter only)"})
        return argument_list </s> remove         if faces_count > 1 and self.arguments.verbose:
            self.verify_output = True
 </s> add     @staticmethod
    def get_argument_list():
        """ Put the arguments in a list so that they are accessible from both argparse and gui """
        argument_list = []
        argument_list.append({"opts": ("-i", "--input-dir"),
                              "action": FullPaths,
                              "dest": "input_dir",
                              "default": "input",
                              "help": "Input directory. A directory containing the files "
                                      "you wish to process. Defaults to 'input'"})
        argument_list.append({"opts": ("-o", "--output-dir"),
                              "action": FullPaths,
                              "dest": "output_dir",
                              "default": "output",
                              "help": "Output directory. This is where the converted files will "
                                      "be stored. Defaults to 'output'"})
        argument_list.append({"opts": ("--alignments", ),
                              "type": str,
                              "dest": "alignments_path",
                              "help": "optional path to alignments file"})
        argument_list.append({"opts": ("--serializer", ),
                              "type": str.lower,
                              "dest": "serializer",
                              "choices": ("yaml", "json", "pickle"),
                              "help": "serializer for alignments file"})
        argument_list.append({"opts": ("-D", "--detector"),
                              "type": str,
                              # case sensitive because this is used to load a plugin.
                              "choices": ("hog", "cnn"),
                              "default": "hog",
                              "help": "Detector to use. 'cnn' detects many more angles but "
                                      "will be much more resource intensive and may fail "
                                      "on large files"})
        argument_list.append({"opts": ("-l", "--ref_threshold"),
                              "type": float,
                              "dest": "ref_threshold",
                              "default": 0.6,
                              "help": "Threshold for positive face recognition"})
        argument_list.append({"opts": ("-n", "--nfilter"),
                              "type": str,
                              "dest": "nfilter",
                              "nargs": "+",
                              "default": None,
                              "help": "Reference image for the persons you do not want to "
                                      "process. Should be a front portrait. Multiple images"
                                      "can be added space separated"})
        argument_list.append({"opts": ("-f", "--filter"),
                              "type": str,
                              "dest": "filter",
                              "nargs": "+",
                              "default": None,
                              "help": "Reference images for the person you want to process. "
                                      "Should be a front portrait. Multiple images"
                                      "can be added space separated"})
        argument_list.append({"opts": ("-v", "--verbose"),
                              "action": "store_true",
                              "dest": "verbose",
                              "default": False,
                              "help": "Show verbose output"})
        return argument_list
            print(
                "It looks like TkInter isn't installed for your OS, so "
                "the GUI has been "
                "disabled. To enable the GUI please install the TkInter "
                "application.\n"
                "You can try:\n"
                "  Windows/macOS:      Install ActiveTcl Community "
                "Edition from "
                "www.activestate.com\n"
                "  Ubuntu/Mint/Debian: sudo apt install python3-tk\n"
                "  Arch:               sudo pacman -S tk\n"
                "  CentOS/Redhat:      sudo yum install tkinter\n"
                "  Fedora:             sudo dnf install python3-tkinter\n",
                file=sys.stderr)
      def check_tkinter_available(command):
          """ Check whether TkInter is installed on user's machine """
          tkinter_vars = [tk, ttk, filedialog, messagebox, TclError]
          if any(var is None for var in tkinter_vars):
            print(
                "It looks like TkInter isn't installed for your OS, so "
                "the GUI has been "
                "disabled. To enable the GUI please install the TkInter "
                "application.\n"
                "You can try:\n"
                "  Windows/macOS:      Install ActiveTcl Community "
                "Edition from "
                "www.activestate.com\n"
                "  Ubuntu/Mint/Debian: sudo apt install python3-tk\n"
                "  Arch:               sudo pacman -S tk\n"
                "  CentOS/Redhat:      sudo yum install tkinter\n"
                "  Fedora:             sudo dnf install python3-tkinter\n",
                file=sys.stderr)
            print(
                "It looks like TkInter isn't installed for your OS, so "
                "the GUI has been "
                "disabled. To enable the GUI please install the TkInter "
                "application.\n"
                "You can try:\n"
                "  Windows/macOS:      Install ActiveTcl Community "
                "Edition from "
                "www.activestate.com\n"
                "  Ubuntu/Mint/Debian: sudo apt install python3-tk\n"
                "  Arch:               sudo pacman -S tk\n"
                "  CentOS/Redhat:      sudo yum install tkinter\n"
                "  Fedora:             sudo dnf install python3-tkinter\n",
                file=sys.stderr)
            print(
                "It looks like TkInter isn't installed for your OS, so "
                "the GUI has been "
                "disabled. To enable the GUI please install the TkInter "
                "application.\n"
                "You can try:\n"
                "  Windows/macOS:      Install ActiveTcl Community "
                "Edition from "
                "www.activestate.com\n"
                "  Ubuntu/Mint/Debian: sudo apt install python3-tk\n"
                "  Arch:               sudo pacman -S tk\n"
                "  CentOS/Redhat:      sudo yum install tkinter\n"
                "  Fedora:             sudo dnf install python3-tkinter\n",
                file=sys.stderr)
            print(
                "It looks like TkInter isn't installed for your OS, so "
                "the GUI has been "
                "disabled. To enable the GUI please install the TkInter "
                "application.\n"
                "You can try:\n"
                "  Windows/macOS:      Install ActiveTcl Community "
                "Edition from "
                "www.activestate.com\n"
                "  Ubuntu/Mint/Debian: sudo apt install python3-tk\n"
                "  Arch:               sudo pacman -S tk\n"
                "  CentOS/Redhat:      sudo yum install tkinter\n"
                "  Fedora:             sudo dnf install python3-tkinter\n",
                file=sys.stderr)
            print(
                "It looks like TkInter isn't installed for your OS, so "
                "the GUI has been "
                "disabled. To enable the GUI please install the TkInter "
                "application.\n"
                "You can try:\n"
                "  Windows/macOS:      Install ActiveTcl Community "
                "Edition from "
                "www.activestate.com\n"
                "  Ubuntu/Mint/Debian: sudo apt install python3-tk\n"
                "  Arch:               sudo pacman -S tk\n"
                "  CentOS/Redhat:      sudo yum install tkinter\n"
                "  Fedora:             sudo dnf install python3-tkinter\n",
                file=sys.stderr)
            print(
                "It looks like TkInter isn't installed for your OS, so "
                "the GUI has been "
                "disabled. To enable the GUI please install the TkInter "
                "application.\n"
                "You can try:\n"
                "  Windows/macOS:      Install ActiveTcl Community "
                "Edition from "
                "www.activestate.com\n"
                "  Ubuntu/Mint/Debian: sudo apt install python3-tk\n"
                "  Arch:               sudo pacman -S tk\n"
                "  CentOS/Redhat:      sudo yum install tkinter\n"
                "  Fedora:             sudo dnf install python3-tkinter\n",
                file=sys.stderr)
            print(
                "It looks like TkInter isn't installed for your OS, so "
                "the GUI has been "
                "disabled. To enable the GUI please install the TkInter "
                "application.\n"
                "You can try:\n"
                "  Windows/macOS:      Install ActiveTcl Community "
                "Edition from "
                "www.activestate.com\n"
                "  Ubuntu/Mint/Debian: sudo apt install python3-tk\n"
                "  Arch:               sudo pacman -S tk\n"
                "  CentOS/Redhat:      sudo yum install tkinter\n"
                "  Fedora:             sudo dnf install python3-tkinter\n",
                file=sys.stderr)
            print(
                "It looks like TkInter isn't installed for your OS, so "
                "the GUI has been "
                "disabled. To enable the GUI please install the TkInter "
                "application.\n"
                "You can try:\n"
                "  Windows/macOS:      Install ActiveTcl Community "
                "Edition from "
                "www.activestate.com\n"
                "  Ubuntu/Mint/Debian: sudo apt install python3-tk\n"
                "  Arch:               sudo pacman -S tk\n"
                "  CentOS/Redhat:      sudo yum install tkinter\n"
                "  Fedora:             sudo dnf install python3-tkinter\n",
                file=sys.stderr)
            print(
                "It looks like TkInter isn't installed for your OS, so "
                "the GUI has been "
                "disabled. To enable the GUI please install the TkInter "
                "application.\n"
                "You can try:\n"
                "  Windows/macOS:      Install ActiveTcl Community "
                "Edition from "
                "www.activestate.com\n"
                "  Ubuntu/Mint/Debian: sudo apt install python3-tk\n"
                "  Arch:               sudo pacman -S tk\n"
                "  CentOS/Redhat:      sudo yum install tkinter\n"
                "  Fedora:             sudo dnf install python3-tkinter\n",
                file=sys.stderr)
            print(
                "It looks like TkInter isn't installed for your OS, so "
                "the GUI has been "
                "disabled. To enable the GUI please install the TkInter "
                "application.\n"
                "You can try:\n"
                "  Windows/macOS:      Install ActiveTcl Community "
                "Edition from "
                "www.activestate.com\n"
                "  Ubuntu/Mint/Debian: sudo apt install python3-tk\n"
                "  Arch:               sudo pacman -S tk\n"
                "  CentOS/Redhat:      sudo yum install tkinter\n"
                "  Fedora:             sudo dnf install python3-tkinter\n",
                file=sys.stderr)
            print(
                "It looks like TkInter isn't installed for your OS, so "
                "the GUI has been "
                "disabled. To enable the GUI please install the TkInter "
                "application.\n"
                "You can try:\n"
                "  Windows/macOS:      Install ActiveTcl Community "
                "Edition from "
                "www.activestate.com\n"
                "  Ubuntu/Mint/Debian: sudo apt install python3-tk\n"
                "  Arch:               sudo pacman -S tk\n"
                "  CentOS/Redhat:      sudo yum install tkinter\n"
                "  Fedora:             sudo dnf install python3-tkinter\n",
                file=sys.stderr)
            print(
                "It looks like TkInter isn't installed for your OS, so "
                "the GUI has been "
                "disabled. To enable the GUI please install the TkInter "
                "application.\n"
                "You can try:\n"
                "  Windows/macOS:      Install ActiveTcl Community "
                "Edition from "
                "www.activestate.com\n"
                "  Ubuntu/Mint/Debian: sudo apt install python3-tk\n"
                "  Arch:               sudo pacman -S tk\n"
                "  CentOS/Redhat:      sudo yum install tkinter\n"
                "  Fedora:             sudo dnf install python3-tkinter\n",
                file=sys.stderr)
            print(
                "It looks like TkInter isn't installed for your OS, so "
                "the GUI has been "
                "disabled. To enable the GUI please install the TkInter "
                "application.\n"
                "You can try:\n"
                "  Windows/macOS:      Install ActiveTcl Community "
                "Edition from "
                "www.activestate.com\n"
                "  Ubuntu/Mint/Debian: sudo apt install python3-tk\n"
                "  Arch:               sudo pacman -S tk\n"
                "  CentOS/Redhat:      sudo yum install tkinter\n"
                "  Fedora:             sudo dnf install python3-tkinter\n",
                file=sys.stderr)
            print(
                "It looks like TkInter isn't installed for your OS, so "
                "the GUI has been "
                "disabled. To enable the GUI please install the TkInter "
                "application.\n"
                "You can try:\n"
                "  Windows/macOS:      Install ActiveTcl Community "
                "Edition from "
                "www.activestate.com\n"
                "  Ubuntu/Mint/Debian: sudo apt install python3-tk\n"
                "  Arch:               sudo pacman -S tk\n"
                "  CentOS/Redhat:      sudo yum install tkinter\n"
                "  Fedora:             sudo dnf install python3-tkinter\n",
                file=sys.stderr)
            print(
                "It looks like TkInter isn't installed for your OS, so "
                "the GUI has been "
                "disabled. To enable the GUI please install the TkInter "
                "application.\n"
                "You can try:\n"
                "  Windows/macOS:      Install ActiveTcl Community "
                "Edition from "
                "www.activestate.com\n"
                "  Ubuntu/Mint/Debian: sudo apt install python3-tk\n"
                "  Arch:               sudo pacman -S tk\n"
                "  CentOS/Redhat:      sudo yum install tkinter\n"
                "  Fedora:             sudo dnf install python3-tkinter\n",
                file=sys.stderr)
              return False
          return True
  
      def extract_options(self, subparsers):
          """ Extract the existing ArgParse Options """
keep keep keep keep replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace keep keep keep keep keep
 cli/scripts Refactor (#367)

* Refactor for PEP 8 and split process function

* Remove backwards compatibility for skip frames

* Split optional functions into own class. Make functions more modular

* Conform scripts folder to PEP 8

* train.py - Fix write image bug. Make more modular

* extract.py - Make more modular, Put optional actions into own class

* cli.py - start PEP 8

* cli,py - Pep 8. Refactor and make modular. Bugfixes

* 1st round refactor. Completely untested and probably broken.

* convert.py: Extract alignments from frames if they don't exist

* BugFix: SkipExisting broken since face name refactor

* Extract.py tested

* Minor formatting

* convert.py + train.py amended not tested

* train.py - Semi-fix for hang on reaching target iteration. Now quits on preview mode
Make tensorflow / system warning less verbose

* 2nd pass refactor. Semi tested

bugfixes

* Remove obsolete code. imread/write to Utils

* rename inout.py to fsmedia.py

* Final bugfixes 
scripts/gui.py