text: from eflow.utils.string_utils import convert_to_filename, \
      correct_directory_path
  import os
  import pickle
  import json
  
  __author__ = "Eric Cacciavillani"
  __copyright__ = "Copyright 2019, eFlow"
  __credits__ = ["Eric Cacciavillani"]
  __license__ = "MIT"
  __maintainer__ = "EricCacciavillani"
  __email__ = "eric.cacciavillani@gmail.com"
  
  def check_if_directory_exists(directory_path):
      """
  
          Checks if the given directory path exists. Raises an error if doesn't
  
      Args:
          directory_path: string
              Given path that already exists.
  
      Raises:
          Raise an error if the given directory does not exist on the users system.
      """
      if not os.path.exists(directory_path):
          raise SystemError("Main directory path doesn't exist.\n"
                            "To help ensure unwanted directories are created you "
                            "must have a pre-defined path.")
  
  def create_unique_directory(directory_path,
                              folder_name):
      """
  
          Creates a unique folder in the proper directory structure.
  
      Args:
          directory_path: string
              Given path that already exists.
  
          folder_name: string
              Folder name to generated.
      """
  
      os.makedirs(get_unique_directory_path(directory_path,
                                            folder_name))
  
  def get_unique_directory_path(directory_path,
                                folder_name):
      """
  
          Iterate through directory structure until a unique folder name can be
          found.
  
          Note:
              Keeps changing the folder name by appending 1 each iteration.
  
      Args:
          directory_path: string
              Given path that already exists.
  
          folder_name: string
               Folder name to compare against other directories that exist in the
               directory_path.
  
      Returns:
          Returns back a directory path with a unique folder name.
      """
  
      # -----
      directory_path = correct_directory_path(directory_path)
      check_if_directory_exists(directory_path)
  
      create_dir_structure(directory_path=directory_path,
                           create_sub_dir="")
  
      # Ensures the folder is unique in the directory
      iterable = 0
      while True:
          if iterable != 0:
              created_path = f'{directory_path}{folder_name} {iterable}'
          else:
              created_path = f'{directory_path}{folder_name}'
  
          if not os.path.exists(created_path):
              break
  
          iterable += 1
  
      return created_path
  
  
  def create_dir_structure(directory_path,
                           create_sub_dir):
      """
  
          Creates required directory structures inside the parent
          directory figures.
  
      Args:
          directory_path: string
              Given path that already exists.
  
          create_sub_dir: string
              Sub directory to create a given folder path.
  
      Returns:
          Returns back the created directory.
      """
      directory_path = correct_directory_path(directory_path)
      check_if_directory_exists(directory_path)
  
      for directory in create_sub_dir.split("/"):
          directory_path += "/" + directory
          if not os.path.exists(directory_path):
              os.makedirs(directory_path)
  
      return correct_directory_path(directory_path)
  
  
  def write_object_text_to_file(obj,
                                directory_path,
                                filename,
                                remove_file_extension=True):
      """
  
          Writes the object's string representation to a text file.
  
      Args:
          obj: any
              Any object that has a string 'repr'.
  
          directory_path: string
              Given path that already exists.
  
          filename: string
              Text file's name.
      """
      directory_path = correct_directory_path(directory_path)
      check_if_directory_exists(directory_path)
  
      filename = convert_to_filename(filename, remove_file_extension=remove_file_extension)
      file_dir = f'{directory_path}{filename}.txt'
  
      f = open(file_dir, 'w')
      f.write('obj = ' + repr(obj) + '\n')
      f.close()
  
  def pickle_object_to_file(obj,
                            directory_path,
                            filename,
                            remove_file_extension=True):
      """
  
          Writes the object to a pickle file.
  
      Args:
          obj: any object
              Any python object that can be pickled.
  
          directory_path: string
              Given path that already exists.
  
          filename: string
               Pickle file's name.
      """
      try:
          directory_path = correct_directory_path(directory_path)
          check_if_directory_exists(directory_path)
  
          # Ensures no file extensions in filename
          filename = convert_to_filename(filename,
                                         remove_file_extension=remove_file_extension)
          file_dir = f'{directory_path}{filename}.pkl'
          list_pickle = open(file_dir, 'wb')
          pickle.dump(obj,
                      list_pickle)
      finally:
          list_pickle.close()
  
      return file_dir
  
  def load_pickle_object(file_path):
      with open(file_path, 'rb') as handle:
          return pickle.load(handle)
  
  def dict_to_json_file(dict_obj,
                        directory_path,
                        filename,
                        remove_file_extension=True):
      """
  
          Writes a dict to a json file.
  
      Args:
          dict_obj: dict
              Dictionary object.
  
          directory_path: string
              Given path that already exists.
  
          filename: string
              Json file's name.
      """
      directory_path = correct_directory_path(directory_path)
      check_if_directory_exists(directory_path)
  
      filename = convert_to_filename(filename,remove_file_extension=remove_file_extension)
  
      with open(f'{directory_path}{filename}.json',
                'w',
                encoding='utf-8') as outfile:
          json.dump(dict_obj,
                    outfile,
                    ensure_ascii=False,
                    indent=2)
  
  def json_file_to_dict(filepath):
      """
  
          Returns back the dictionary from of a json file.
  
      Args:
          filepath: string
               Given path to the filename.
  
      Returns:
          Returns back the dictionary from of a json file.
      """
      json_file = open(filepath)
      json_str = json_file.read()
      json_data = json.loads(json_str)
      json_file.close()
  
      return json_data
  
  def get_all_directories_from_path(directory_path):
      """
  
         Gets directories names with the provided path.
  
      Args:
          directory_path: string
              Given path that already exists.
  
      Returns:
          Returns back a set a directories with the provided path.
      """
      directory_path = correct_directory_path(directory_path)
      check_if_directory_exists(directory_path)
  
      dirs_in_paths = []
      for (dirpath, dirnames, filenames) in os.walk(directory_path):
          dirs_in_paths.extend(dirnames)
          break
  
      return set(dirs_in_paths)
  
  
  def get_all_files_from_path(directory_path,
                              file_extension=None):
      """
  
          Gets all filenames with the provided path.
  
      Args:
          directory_path: string
              Given path that already exists.
  
          file_extension: string
              Only return files that have a given extension.
  
      Returns:
          Returns back a set a filenames with the provided path.
      """
      directory_path = correct_directory_path(directory_path)
      check_if_directory_exists(directory_path)
  
      files_in_paths = []
      for (dirpath, dirnames, filenames) in os.walk(directory_path):
  
          if file_extension:
              file_extension = file_extension.replace(".","")
              for file in filenames:
                  if file.endswith(f'.{file_extension}'):
                      files_in_paths.append(file)
          else:
              files_in_paths.extend(filenames)
          break
  
      return set(files_in_paths)
  