yor-discord-bot / py_files / sketchy_sketch.py
sketchy_sketch.py
Raw
"""
This file contains the sketchySketch class.
"""
import json, os
from random import choice

class sketchySketch:
    """
    This class provides an interface to interact with images
    in a local directory to aid in sketching practice for artists.
    Intended to work with a Discord bot.
    """
    def __init__(self, dir_path):
        """
        Initializes the sketchySketch class.
        """
        self._dir_path = dir_path
        self._json_path = os.path.join(dir_path, 'files_dict.json')

        # === for mangaing bookmarked files === #
        self._bookmark_path = os.path.join(dir_path, 'bookmarked')
        if (not os.path.isdir(self._bookmark_path)):
            os.mkdir(self._bookmark_path)

        # === for managing deleted files === #
        self._delete_path = os.path.join(dir_path, 'deleted')
        if (not os.path.isdir(self._delete_path)):
            os.mkdir(self._delete_path)

        # === stores as data in dictionary === #
        self._files_dict = self._load_dir()


    def random_pic(self) -> str:
        """
        Returns the file path to a random image from the directory.
        """
        file_name = choice(list(self._files_dict.get('overall')))
        return os.path.join(self._dir_path, file_name)

    
    def add_pic(self, file_name) -> None:
        """
        Adds the given file name to the dictionary.        
        """
        self._files_dict.get('overall')[file_name] = {'url':None, 'rating':0, 'tags':[]}
        # update json
        self._save_json()


    def add_tag(self):
        """
        Adds the given tag to the file.
        """
        pass


    def pic_info(self, file_name) -> dict:
        """
        Returns a dictionary with information from the given file name.
        """
        # check if given file_name exists
        for info in self._files_dict.values():
            if (file_name in info):
                return info.get(file_name)
        # file_name does not exist
        return dict()


    def update_url(self, file_name, new_url) -> None:
        """
        Updates the image URL with the given file name and url.
        """
        for category in self._files_dict.values():
            if (file_name) in category:
                category[file_name]['url'] = new_url
                break
        # update json
        self._save_json()
    

    def bookmark_pic(self, file_name) -> bool:
        """ 
        Adds the given file name to bookmark folder.
        Returns True if successfully bookmarked file, otherwise False.
        """
        val = self._files_dict.get('overall').pop(file_name)
        self._files_dict.get('bookmarked')[file_name] = val
        result = self._move_pic(self._dir_path, self._bookmark_path, file_name)
        # update json
        self._save_json()
        return result

    
    def unbookmark_pic(self, file_name) -> None:
        """
        Unbookmarks the given file name, file will go back to the overall folder.
        """
        # check if file exists
        if (file_name not in self._files_dict.get('bookmarked')):
            return
        temp_file = self._files_dict.get('bookmarked').pop(file_name)
        self._files_dict.get('overall')[file_name] = temp_file
        self._move_pic(self._bookmark_path, self._dir_path, file_name)
        # update json
        self._save_json()


    def remove_pic(self, file_name) -> bool:
        """
        Removes the given file name from the directory to the deleted directory.
        Returns True if successfully removed file, otherwise False.
        """
        temp_file = self._files_dict.get('overall').pop(file_name)
        self._files_dict.get('deleted')[file_name] = temp_file
        result = self._move_pic(self._dir_path, self._delete_path, file_name)
        # update json
        self._save_json()
        return result


    def list_images(self) -> list:
        """
        Returns a list of paths to images in from the directory.
        """
        result = []
        for file_name in self._files_dict.get('overall'):
            result.append(os.path.join(self._dir_path, file_name))
        return result 


    def list_bookmarked(self) -> list:
        """
        Returns a list of bookmarked files.
        """
        result = [] 
        for file_name in self._files_dict.get('bookmarked'):
            result.append(os.path.join(self._bookmark_path, file_name))
        return result


    def list_deleted(self) -> list:
        """
        Returns a list of deleted files.
        """
        result = []
        for file_name in self._files_dict.get('deleted'):
            result.append(os.path.join(self._delete_path, file_name))
        return result


    def clear_bookmarked(self, file_name=None) -> None:
        """
        Default: Permanently deletes all bookmarked files.
        If file name is given, removes that file only.
        """
        if (file_name == None):
            for file in os.scandir(self._bookmark_path):
                os.remove(file.path)
        else:
            os.remove(os.path.join(self._bookmark_path, file_name))
        # update json
        self._save_json()


    def clear_deleted(self) -> None:
        """
        Permanently deletes all deleted files.
        """
        for file in os.scandir(self._delete_path):
            os.remove(file.path)
        # update json
        self._save_json()


    def curr_directory(self) -> str:
        """
        Returns the current directory as a str.
        """
        return self._dir_path


    def is_image(self, file_name):
        """
        Takes in a file name as a str, returns True if
        the file is an image.
        """
        pass


    def hashCode(self, file_name):
        """
        Takes in an image file name as a str, returns the
        hash code for the image.
        """
        pass


    ### PRIVATE HELPER METHODS ###        

    def _load_dir(self) -> dict:
        """
        Returns a dictionary for the all of the files.
        """
        # Structure of dictionary
        # {
        #   'overall':{
        #               file_name1 : { url: <str>, rating : <int>, tags : <list> },
        #               file_name2 : { url: <str>, rating : <int>, tags : <list> },
        #                                   ...
        #             },
        #   'bookmarked' : { *same as above },
        #   'deleted': { *same as above },
        # }
        #
        # empty dictionary format: {'url':None, 'rating':0, 'tags':[]}

        # check if dictionary contents already is stored
        if os.path.exists(self._json_path):
            with open(self._json_path) as f:
                return json.load(f)

        # build an empty dictionary structure
        overall_dict = dict()
        category = {str(self._dir_path):'overall',
                    str(self._bookmark_path):'bookmarked',
                    str(self._delete_path):'deleted'}
        avoid_files = {'bookmarked', 'deleted'}

        # create empty dictionary
        for path in [self._dir_path, self._bookmark_path, self._delete_path]:
            temp_dict = dict()
            for file in os.listdir(path):
                # initialize every file with empty content
                if (file not in avoid_files):
                    temp_dict.update({file:{'url':None, 'rating':0, 'tags':[]}})
            # insert into overall dictionary
            overall_dict.update({category.get(str(path)):temp_dict})

        return overall_dict


    def _save_json(self) -> None:
        """
        Saves the dictionary as a json file.
        """
        with open(self._json_path, 'w') as f:
            json.dump(self._files_dict, f)

    
    def _move_pic(self, curr_path, new_path, file_name) -> bool:
        """
        Moves the given file name from the given current 
        directory to the given new directory.
        """
        # check if file exists
        if (not os.path.exists(os.path.join(curr_path, file_name))):
            return False
        # move the file to given folder
        os.rename(os.path.join(curr_path, file_name), 
                  os.path.join(new_path, file_name))
        # update json
        self._save_json()
        return True


# if __name__ == '__main__':
#     dir_path = r'C:\Users\haose\OneDrive\Desktop\test_refs'
#     sketch = sketchySketch(dir_path)
#     sketch.update_url('0a23ed3b9c8dc177829b309607c4e992.jpg', 'test_url')