GoldyBot.modules

  1from __future__ import annotations
  2
  3import os
  4import sys
  5from typing import List
  6import importlib.util
  7
  8import GoldyBot
  9from GoldyBot.errors import ModuleFailedToLoad, ModuleNotFound
 10
 11MODULE_NAME = "MODULES"
 12
 13sys.path.insert(1, GoldyBot.paths.MODULES)
 14sys.path.append(GoldyBot.paths.INTERNAL_MODULES_V4)
 15
 16class Module(object):
 17    """Goldy Bot class to easily interface with modules."""
 18    def __init__(self, path_to_module:str=None, module_file_name:str=None):
 19        self.path_to_module = path_to_module
 20        self.module_file_name = module_file_name
 21
 22        self.version_ = None
 23        self.author_ = None
 24        self.author_github_ = None
 25        self.open_source_link_ = None
 26
 27        self.is_internal_module_ = False
 28        self.is_external_module_ = False
 29        self.is_package_module_ = False
 30
 31        self.ignored_modules_list = GoldyBot.config.Config(GoldyBot.files.File(GoldyBot.paths.GOLDY_CONFIG_JSON)).read("ignored_modules")
 32
 33        if self.path_to_module == None:
 34            if self.module_file_name == None:
 35                GoldyBot.logging.log("error", "Module() must have either arguments 'path_to_module' or 'module_file_name' passed in.")
 36            else:
 37                # Find where module is located.
 38                #----------------------------------
 39                if self.module_file_name in os.listdir(GoldyBot.paths.INTERNAL_COGS_V4):
 40                    self.path_to_module = f"{GoldyBot.paths.INTERNAL_COGS_V4}/{self.module_file_name}"
 41                    self.is_internal_module_ = True
 42
 43                if self.module_file_name in os.listdir(GoldyBot.paths.MODULES):
 44                    self.path_to_module = f"{GoldyBot.paths.MODULES}/{self.module_file_name}"
 45                    self.is_external_module_ = True
 46
 47                if not self.path_to_module == None:
 48                    GoldyBot.logging.log(f"[{MODULE_NAME}] The module '{self.module_file_name}' was found in '{self.path_to_module}'.")
 49                    
 50                    if os.path.isdir(self.path_to_module): # Checks if the module is a package module.
 51                        GoldyBot.logging.log("info", f"[{MODULE_NAME}] The module '{self.module_file_name}' was dectected as a package module.")
 52                        self.is_package_module_ = True
 53
 54                else:
 55                    #GoldyBot.logging.log("warn", f"[{MODULE_NAME}] The module '{self.module_file_name}' was not found!")
 56                    raise ModuleNotFound(f"[{MODULE_NAME}] The module '{self.module_file_name}' was not found!")
 57        else:
 58            # Assume 'path_to_module' was used.
 59            self.module_file_name = path_to_module.split("/")[-1]
 60
 61        # Cache module.
 62        #----------------
 63        if self.is_external_module_:
 64            if not self.name in GoldyBot.cache.main_cache_dict["modules"]:
 65                GoldyBot.cache.main_cache_dict["modules"][f"{self.name}"] = {}
 66                GoldyBot.cache.main_cache_dict["modules"][f"{self.name}"]["extensions"] = {}
 67                GoldyBot.cache.main_cache_dict["modules"][f"{self.name}"]["object"] = self
 68        else:
 69            if not self.name in GoldyBot.cache.main_cache_dict["internal_modules"]:
 70                GoldyBot.cache.main_cache_dict["internal_modules"][f"{self.name}"] = {}
 71                GoldyBot.cache.main_cache_dict["internal_modules"][f"{self.name}"]["extensions"] = {}
 72                GoldyBot.cache.main_cache_dict["internal_modules"][f"{self.name}"]["object"] = self
 73
 74
 75    def load(self):
 76        """Commands Goldy Bot to load this module."""
 77        
 78        if not self.module_file_name[:-3] in self.ignored_modules_list:
 79            if self.is_package_module_:
 80                # Specify Package Module
 81                sys.path.append(self.path_to_module)
 82
 83                spec_module = importlib.util.spec_from_file_location(self.module_file_name, self.path_to_module + "/__init__.py")
 84            else:
 85                # Specify Module
 86                spec_module = importlib.util.spec_from_file_location(self.module_file_name[:-3], self.path_to_module)
 87
 88            # Get Module
 89            module_py = importlib.util.module_from_spec(spec_module)
 90            
 91            # Run Module
 92            spec_module.loader.exec_module(module_py)
 93
 94            # Get load function from module.
 95            try:
 96                load_function = getattr(module_py, "load")
 97                load_function()
 98
 99                GoldyBot.logging.log("info_4", f"[{MODULE_NAME}] Loaded the internal module '{self.module_file_name}'!")
100            except AttributeError:
101                raise ModuleFailedToLoad(f"[{MODULE_NAME}] The internal module '{self.name}' failed to load because it did not contain the 'load()' function.")
102
103            # Find information variables in module.
104            try: self.version_ = getattr(module_py, "VERSION")
105            except AttributeError: self.version_ = None
106
107            try: self.author_ = getattr(module_py, "AUTHOR")
108            except AttributeError: self.author_ = None
109
110            try: self.author_github_ = getattr(module_py, "AUTHOR_GITHUB")
111            except AttributeError: self.author_github_ = None
112
113            try: self.open_source_link_ = getattr(module_py, "OPEN_SOURCE_LINK")
114            except AttributeError: self.open_source_link_ = None
115
116        else:
117            GoldyBot.logging.log("info", f"[{MODULE_NAME}] The internal module '{self.name}' is not being loaded as it was ignored.")
118
119    def reload(self) -> List[GoldyBot.objects.command.Command]:
120        """Commands Goldy Bot to reload this module."""
121
122        # Unload the module.
123        #--------------------------
124        self.unload()
125
126        # Load the module again.
127        #--------------------------
128        GoldyBot.logging.log(f"[{MODULE_NAME}] Reloading module...")
129        self.load()
130
131        return self.commands
132
133    def unload(self):
134        """Commands Goldy Bot to unload this module with it's commands."""
135
136        # Remove all commands in module.
137        #---------------------------------
138        GoldyBot.logging.log(f"[{MODULE_NAME}] Getting all module's commands...")
139        commands_list = self.commands
140
141        for command in commands_list:
142            command.remove()
143        
144        GoldyBot.logging.log(f"[{MODULE_NAME}] Removed all commands!")
145
146        GoldyBot.logging.log("info_5", f"[{MODULE_NAME}] Unloaded the module '{self.module_file_name}'!")
147
148    @property
149    def name(self):
150        """Returns the name of the module."""
151        if self.is_package_module_:
152            return self.module_file_name
153        else:
154            return self.module_file_name[:-3]
155
156    @property
157    def version(self) -> float|None:
158        """Returns the current version of the module if stated."""
159        return self.version_
160
161    @property
162    def author(self) -> str|None:
163        """Returns the name of the developer who created this module if stated. """
164        return self.author_
165
166    @property
167    def author_github(self) -> str|None:
168        """Returns a link to the authors github page if stated."""
169        return self.author_github_
170
171    @property
172    def open_source_link(self) -> str|None:
173        """Returns link to github repository for this module."""
174        return self.open_source_link_
175
176    github_repo = open_source_link
177    """Alias of ``open_source_link``"""
178
179    @property
180    def commands(self):
181        """List of commands in the module."""
182        if self.is_internal_module: modules_list_name = "internal_modules"
183        else: modules_list_name = "modules"
184
185        commands:List[GoldyBot.objects.command.Command] = []
186
187        # Finding all commands in this.
188        #-----------------------
189        GoldyBot.logging.log(f"[{MODULE_NAME}] Finding all commands in the module '{self.name}'...")
190        for extension in GoldyBot.cache.main_cache_dict[modules_list_name][self.name]["extensions"]:
191            for command in GoldyBot.cache.main_cache_dict[modules_list_name][self.name]["extensions"][extension]["commands"]:
192                command:GoldyBot.objects.command.Command
193
194                commands.append(command)
195
196        return commands
197
198    @property
199    def is_internal_module(self):
200        """Commands Goldy Bot to check whether this module is an internal module or an external one."""
201        if self.is_internal_module_:
202            return True
203        else:
204            return False
class Module:
 17class Module(object):
 18    """Goldy Bot class to easily interface with modules."""
 19    def __init__(self, path_to_module:str=None, module_file_name:str=None):
 20        self.path_to_module = path_to_module
 21        self.module_file_name = module_file_name
 22
 23        self.version_ = None
 24        self.author_ = None
 25        self.author_github_ = None
 26        self.open_source_link_ = None
 27
 28        self.is_internal_module_ = False
 29        self.is_external_module_ = False
 30        self.is_package_module_ = False
 31
 32        self.ignored_modules_list = GoldyBot.config.Config(GoldyBot.files.File(GoldyBot.paths.GOLDY_CONFIG_JSON)).read("ignored_modules")
 33
 34        if self.path_to_module == None:
 35            if self.module_file_name == None:
 36                GoldyBot.logging.log("error", "Module() must have either arguments 'path_to_module' or 'module_file_name' passed in.")
 37            else:
 38                # Find where module is located.
 39                #----------------------------------
 40                if self.module_file_name in os.listdir(GoldyBot.paths.INTERNAL_COGS_V4):
 41                    self.path_to_module = f"{GoldyBot.paths.INTERNAL_COGS_V4}/{self.module_file_name}"
 42                    self.is_internal_module_ = True
 43
 44                if self.module_file_name in os.listdir(GoldyBot.paths.MODULES):
 45                    self.path_to_module = f"{GoldyBot.paths.MODULES}/{self.module_file_name}"
 46                    self.is_external_module_ = True
 47
 48                if not self.path_to_module == None:
 49                    GoldyBot.logging.log(f"[{MODULE_NAME}] The module '{self.module_file_name}' was found in '{self.path_to_module}'.")
 50                    
 51                    if os.path.isdir(self.path_to_module): # Checks if the module is a package module.
 52                        GoldyBot.logging.log("info", f"[{MODULE_NAME}] The module '{self.module_file_name}' was dectected as a package module.")
 53                        self.is_package_module_ = True
 54
 55                else:
 56                    #GoldyBot.logging.log("warn", f"[{MODULE_NAME}] The module '{self.module_file_name}' was not found!")
 57                    raise ModuleNotFound(f"[{MODULE_NAME}] The module '{self.module_file_name}' was not found!")
 58        else:
 59            # Assume 'path_to_module' was used.
 60            self.module_file_name = path_to_module.split("/")[-1]
 61
 62        # Cache module.
 63        #----------------
 64        if self.is_external_module_:
 65            if not self.name in GoldyBot.cache.main_cache_dict["modules"]:
 66                GoldyBot.cache.main_cache_dict["modules"][f"{self.name}"] = {}
 67                GoldyBot.cache.main_cache_dict["modules"][f"{self.name}"]["extensions"] = {}
 68                GoldyBot.cache.main_cache_dict["modules"][f"{self.name}"]["object"] = self
 69        else:
 70            if not self.name in GoldyBot.cache.main_cache_dict["internal_modules"]:
 71                GoldyBot.cache.main_cache_dict["internal_modules"][f"{self.name}"] = {}
 72                GoldyBot.cache.main_cache_dict["internal_modules"][f"{self.name}"]["extensions"] = {}
 73                GoldyBot.cache.main_cache_dict["internal_modules"][f"{self.name}"]["object"] = self
 74
 75
 76    def load(self):
 77        """Commands Goldy Bot to load this module."""
 78        
 79        if not self.module_file_name[:-3] in self.ignored_modules_list:
 80            if self.is_package_module_:
 81                # Specify Package Module
 82                sys.path.append(self.path_to_module)
 83
 84                spec_module = importlib.util.spec_from_file_location(self.module_file_name, self.path_to_module + "/__init__.py")
 85            else:
 86                # Specify Module
 87                spec_module = importlib.util.spec_from_file_location(self.module_file_name[:-3], self.path_to_module)
 88
 89            # Get Module
 90            module_py = importlib.util.module_from_spec(spec_module)
 91            
 92            # Run Module
 93            spec_module.loader.exec_module(module_py)
 94
 95            # Get load function from module.
 96            try:
 97                load_function = getattr(module_py, "load")
 98                load_function()
 99
100                GoldyBot.logging.log("info_4", f"[{MODULE_NAME}] Loaded the internal module '{self.module_file_name}'!")
101            except AttributeError:
102                raise ModuleFailedToLoad(f"[{MODULE_NAME}] The internal module '{self.name}' failed to load because it did not contain the 'load()' function.")
103
104            # Find information variables in module.
105            try: self.version_ = getattr(module_py, "VERSION")
106            except AttributeError: self.version_ = None
107
108            try: self.author_ = getattr(module_py, "AUTHOR")
109            except AttributeError: self.author_ = None
110
111            try: self.author_github_ = getattr(module_py, "AUTHOR_GITHUB")
112            except AttributeError: self.author_github_ = None
113
114            try: self.open_source_link_ = getattr(module_py, "OPEN_SOURCE_LINK")
115            except AttributeError: self.open_source_link_ = None
116
117        else:
118            GoldyBot.logging.log("info", f"[{MODULE_NAME}] The internal module '{self.name}' is not being loaded as it was ignored.")
119
120    def reload(self) -> List[GoldyBot.objects.command.Command]:
121        """Commands Goldy Bot to reload this module."""
122
123        # Unload the module.
124        #--------------------------
125        self.unload()
126
127        # Load the module again.
128        #--------------------------
129        GoldyBot.logging.log(f"[{MODULE_NAME}] Reloading module...")
130        self.load()
131
132        return self.commands
133
134    def unload(self):
135        """Commands Goldy Bot to unload this module with it's commands."""
136
137        # Remove all commands in module.
138        #---------------------------------
139        GoldyBot.logging.log(f"[{MODULE_NAME}] Getting all module's commands...")
140        commands_list = self.commands
141
142        for command in commands_list:
143            command.remove()
144        
145        GoldyBot.logging.log(f"[{MODULE_NAME}] Removed all commands!")
146
147        GoldyBot.logging.log("info_5", f"[{MODULE_NAME}] Unloaded the module '{self.module_file_name}'!")
148
149    @property
150    def name(self):
151        """Returns the name of the module."""
152        if self.is_package_module_:
153            return self.module_file_name
154        else:
155            return self.module_file_name[:-3]
156
157    @property
158    def version(self) -> float|None:
159        """Returns the current version of the module if stated."""
160        return self.version_
161
162    @property
163    def author(self) -> str|None:
164        """Returns the name of the developer who created this module if stated. """
165        return self.author_
166
167    @property
168    def author_github(self) -> str|None:
169        """Returns a link to the authors github page if stated."""
170        return self.author_github_
171
172    @property
173    def open_source_link(self) -> str|None:
174        """Returns link to github repository for this module."""
175        return self.open_source_link_
176
177    github_repo = open_source_link
178    """Alias of ``open_source_link``"""
179
180    @property
181    def commands(self):
182        """List of commands in the module."""
183        if self.is_internal_module: modules_list_name = "internal_modules"
184        else: modules_list_name = "modules"
185
186        commands:List[GoldyBot.objects.command.Command] = []
187
188        # Finding all commands in this.
189        #-----------------------
190        GoldyBot.logging.log(f"[{MODULE_NAME}] Finding all commands in the module '{self.name}'...")
191        for extension in GoldyBot.cache.main_cache_dict[modules_list_name][self.name]["extensions"]:
192            for command in GoldyBot.cache.main_cache_dict[modules_list_name][self.name]["extensions"][extension]["commands"]:
193                command:GoldyBot.objects.command.Command
194
195                commands.append(command)
196
197        return commands
198
199    @property
200    def is_internal_module(self):
201        """Commands Goldy Bot to check whether this module is an internal module or an external one."""
202        if self.is_internal_module_:
203            return True
204        else:
205            return False

Goldy Bot class to easily interface with modules.

Module(path_to_module: str = None, module_file_name: str = None)
19    def __init__(self, path_to_module:str=None, module_file_name:str=None):
20        self.path_to_module = path_to_module
21        self.module_file_name = module_file_name
22
23        self.version_ = None
24        self.author_ = None
25        self.author_github_ = None
26        self.open_source_link_ = None
27
28        self.is_internal_module_ = False
29        self.is_external_module_ = False
30        self.is_package_module_ = False
31
32        self.ignored_modules_list = GoldyBot.config.Config(GoldyBot.files.File(GoldyBot.paths.GOLDY_CONFIG_JSON)).read("ignored_modules")
33
34        if self.path_to_module == None:
35            if self.module_file_name == None:
36                GoldyBot.logging.log("error", "Module() must have either arguments 'path_to_module' or 'module_file_name' passed in.")
37            else:
38                # Find where module is located.
39                #----------------------------------
40                if self.module_file_name in os.listdir(GoldyBot.paths.INTERNAL_COGS_V4):
41                    self.path_to_module = f"{GoldyBot.paths.INTERNAL_COGS_V4}/{self.module_file_name}"
42                    self.is_internal_module_ = True
43
44                if self.module_file_name in os.listdir(GoldyBot.paths.MODULES):
45                    self.path_to_module = f"{GoldyBot.paths.MODULES}/{self.module_file_name}"
46                    self.is_external_module_ = True
47
48                if not self.path_to_module == None:
49                    GoldyBot.logging.log(f"[{MODULE_NAME}] The module '{self.module_file_name}' was found in '{self.path_to_module}'.")
50                    
51                    if os.path.isdir(self.path_to_module): # Checks if the module is a package module.
52                        GoldyBot.logging.log("info", f"[{MODULE_NAME}] The module '{self.module_file_name}' was dectected as a package module.")
53                        self.is_package_module_ = True
54
55                else:
56                    #GoldyBot.logging.log("warn", f"[{MODULE_NAME}] The module '{self.module_file_name}' was not found!")
57                    raise ModuleNotFound(f"[{MODULE_NAME}] The module '{self.module_file_name}' was not found!")
58        else:
59            # Assume 'path_to_module' was used.
60            self.module_file_name = path_to_module.split("/")[-1]
61
62        # Cache module.
63        #----------------
64        if self.is_external_module_:
65            if not self.name in GoldyBot.cache.main_cache_dict["modules"]:
66                GoldyBot.cache.main_cache_dict["modules"][f"{self.name}"] = {}
67                GoldyBot.cache.main_cache_dict["modules"][f"{self.name}"]["extensions"] = {}
68                GoldyBot.cache.main_cache_dict["modules"][f"{self.name}"]["object"] = self
69        else:
70            if not self.name in GoldyBot.cache.main_cache_dict["internal_modules"]:
71                GoldyBot.cache.main_cache_dict["internal_modules"][f"{self.name}"] = {}
72                GoldyBot.cache.main_cache_dict["internal_modules"][f"{self.name}"]["extensions"] = {}
73                GoldyBot.cache.main_cache_dict["internal_modules"][f"{self.name}"]["object"] = self
def load(self):
 76    def load(self):
 77        """Commands Goldy Bot to load this module."""
 78        
 79        if not self.module_file_name[:-3] in self.ignored_modules_list:
 80            if self.is_package_module_:
 81                # Specify Package Module
 82                sys.path.append(self.path_to_module)
 83
 84                spec_module = importlib.util.spec_from_file_location(self.module_file_name, self.path_to_module + "/__init__.py")
 85            else:
 86                # Specify Module
 87                spec_module = importlib.util.spec_from_file_location(self.module_file_name[:-3], self.path_to_module)
 88
 89            # Get Module
 90            module_py = importlib.util.module_from_spec(spec_module)
 91            
 92            # Run Module
 93            spec_module.loader.exec_module(module_py)
 94
 95            # Get load function from module.
 96            try:
 97                load_function = getattr(module_py, "load")
 98                load_function()
 99
100                GoldyBot.logging.log("info_4", f"[{MODULE_NAME}] Loaded the internal module '{self.module_file_name}'!")
101            except AttributeError:
102                raise ModuleFailedToLoad(f"[{MODULE_NAME}] The internal module '{self.name}' failed to load because it did not contain the 'load()' function.")
103
104            # Find information variables in module.
105            try: self.version_ = getattr(module_py, "VERSION")
106            except AttributeError: self.version_ = None
107
108            try: self.author_ = getattr(module_py, "AUTHOR")
109            except AttributeError: self.author_ = None
110
111            try: self.author_github_ = getattr(module_py, "AUTHOR_GITHUB")
112            except AttributeError: self.author_github_ = None
113
114            try: self.open_source_link_ = getattr(module_py, "OPEN_SOURCE_LINK")
115            except AttributeError: self.open_source_link_ = None
116
117        else:
118            GoldyBot.logging.log("info", f"[{MODULE_NAME}] The internal module '{self.name}' is not being loaded as it was ignored.")

Commands Goldy Bot to load this module.

def reload(self) -> List[GoldyBot.objects.command.Command]:
120    def reload(self) -> List[GoldyBot.objects.command.Command]:
121        """Commands Goldy Bot to reload this module."""
122
123        # Unload the module.
124        #--------------------------
125        self.unload()
126
127        # Load the module again.
128        #--------------------------
129        GoldyBot.logging.log(f"[{MODULE_NAME}] Reloading module...")
130        self.load()
131
132        return self.commands

Commands Goldy Bot to reload this module.

def unload(self):
134    def unload(self):
135        """Commands Goldy Bot to unload this module with it's commands."""
136
137        # Remove all commands in module.
138        #---------------------------------
139        GoldyBot.logging.log(f"[{MODULE_NAME}] Getting all module's commands...")
140        commands_list = self.commands
141
142        for command in commands_list:
143            command.remove()
144        
145        GoldyBot.logging.log(f"[{MODULE_NAME}] Removed all commands!")
146
147        GoldyBot.logging.log("info_5", f"[{MODULE_NAME}] Unloaded the module '{self.module_file_name}'!")

Commands Goldy Bot to unload this module with it's commands.

name

Returns the name of the module.

version: float | None

Returns the current version of the module if stated.

author: str | None

Returns the name of the developer who created this module if stated.

author_github: str | None

Returns a link to the authors github page if stated.

github_repo: str | None
commands

List of commands in the module.

is_internal_module

Commands Goldy Bot to check whether this module is an internal module or an external one.