Source code for pyggui.helpers.file_handling

"""
Module for anything related to files
"""

from __future__ import annotations
from typing import Callable, List, Tuple, Dict, Union
import os
import time
import json

import pygame


[docs]class ImageLoader:
[docs] @staticmethod def load_image(image_path: str) -> pygame.surface.Surface: """ Method loads given path into image. Args: image_path (str): Path to image to load Returns: pygame.surface.Surface: Image loaded as a Pygame surface """ return pygame.image.load(image_path).convert() # .convert() optimizes speed by 5x
[docs] @staticmethod def load_transparent_image(image_path: str) -> pygame.surface.Surface: """ Method loads given path into transparent image. Args: image_path (str): Path to image to load Returns: pygame.surface.Surface: Image loaded as a Pygame surface """ return pygame.image.load(image_path).convert_alpha() # .convert() optimizes speed by 5x
[docs] @staticmethod def load_folder(folder_path: str) -> List[pygame.surface.Surface]: """ Method loads all ImageLoader from the folder intro a sprite list. Args: folder_path (str): Path to folder to load images from Returns: list[pygame.surface.Surface]: List containing Pygame images loaded as surfaces """ image_list = [] for image_path in os.listdir(folder_path): path = os.path.join(folder_path, image_path) image_list.append(ImageLoader.load_image(path)) return image_list
[docs] @staticmethod def load_transparent_folder(folder_path: str) -> List[pygame.surface.Surface]: """ Method loads all ImageLoader from the folder intro a sprite list. Args: folder_path (str): Path to folder to load images from Returns: list[pygame.surface.Surface]: List containing Pygame images loaded as surfaces """ image_list = [] for image_path in os.listdir(folder_path): path = os.path.join(folder_path, image_path) image_list.append(ImageLoader.load_transparent_image(path)) return image_list
[docs]class DirectoryReader: """ Class consisting of static methods for reading directories. Used for fetching sub-directories, all files, the directories structure, etc. """
[docs] @staticmethod def get_all_directories(dir_path: str) -> List[Tuple[str, str]]: """ Method finds all sub-directories in the given directory. Args: dir_path (str): Path to directory to search from Returns: List[Tuple[str, str]]: List of tuples (directory name, directory path). """ folder_list = [] for item in os.scandir(dir_path): if item.is_dir(): folder_list.append((item.name, os.path.abspath(item.path))) return folder_list
[docs] @staticmethod def get_all_files(dir_path: str) -> List[Tuple[str, str]]: """ Method finds all file names and its paths in the given directory. Args: dir_path (str): Path to directory to search from Returns: List[Tuple[str, str]]: List of tuples (file name, file path). """ file_list = [] for item in os.scandir(dir_path): if item.is_file(): file_list.append((item.name, os.path.abspath(item.path))) # Append tuple return file_list
[docs] @staticmethod def get_structure(dir_path: str) -> Dict[str, Union[str, List, Dict]]: """ Method goes over the passed directory and creates a special structured dictionary. Created dictionary follows this rules: * For each directory create a sub-dictionary under the directories name as the key, * Each file in giver directory is added in a list under 'files' key, file gets added as a tuple where first value is the files name, second value its relative path based on dir_path. The above is then run recursively across the directories tree structure. Example: Passing bottom directory with its relative or absolute path Directory: button/ - normal.png on_click/ - 01.png - 02.png on_hover/ - 01.png Will return dictionary: { 'path': 'button/' 'files': [('normal.png', 'button/normal.png')], 'on_click': { 'path': 'button/on_click' 'files': [ ('01.png', 'button/on_click/01.png'), ('02.png', 'button/on_click/02.png') ] }, 'on_hover': { 'path': 'button/on_hover', 'files': [ ('01.png', 'button/on_hover/01.png') ] } } Args: dir_path (str): Directory path to traverse and create structure from. Returns: Dict[str, Union[str, List, Dict]]: Structured dictionary. """ norm_dir_path = os.path.normpath(dir_path) # Normalize path main_structure = {"path": norm_dir_path} # Main mutable dictionary that will get returned def traverse(structure: Dict, directory: str) -> None: """ Recursive function goes over directory, adding its files in the structure key = 'files' list, recursive call for each directory found. """ for name, full_path in [(path, os.path.join(directory, path)) for path in os.listdir(directory)]: # If file if os.path.isfile(full_path): # Add each file to files key in structure if "files" not in structure: structure["files"] = [] structure["files"].append((name, full_path)) # If directory if os.path.isdir(full_path): # Add new structure under basename, recursive call basename = os.path.basename(full_path) structure[basename] = {"path": full_path} traverse(structure[basename], full_path) # Call function traverse(main_structure, norm_dir_path) return main_structure
[docs]class Json: """ Class for loading, writing and updating data in json files. All json files must contain dictionaries as the main scope object. """
[docs] @staticmethod def load(path: str) -> Union[Dict, List]: """ Method loads a single json file, returning its contents. Args: path (str): Path to Json file. Returns: Union[Dict, List]: Content of the Json file """ try: with open(path, "r") as f: data = json.load(f) return data except FileNotFoundError: print(f"Json.load: Unable to find Json file on path:\n {path}")
[docs] @staticmethod def update(path: str, data: Dict) -> Dict: """ Method will update the dictionary with data and return the updated dict. Args: path (str): Path to Json file. data (Dict): Dictionary of key-value pairs to update in the json file Returns: Dict: Updated dictionary. """ # Read data try: with open(path, "r") as f: read_data = json.load(f) except FileNotFoundError: print(f"Json.update: Unable to find Json file on path:\n {path}") return # Update read_data.update(data) # Save, at this point we know the path exists with open(path, "w") as f: json.dump(read_data, f, indent=4) return read_data
[docs] @staticmethod def save(path: str, data: Dict) -> None: """ Method saves data into a json file specified by passed path. Args: path (str): Path to Json file to save data to. data (Dict): Dictionary to save in the json file. """ # Check if path contains .json if not (".json" in path): path += ".json" # Write data try: with open(path, "w") as f: json.dump(data, f, indent=4) except FileNotFoundError: print(f"Json.save: Unable to find Json file on path:\n {path}") return