implemented class loader for concrete instances of commands
This commit is contained in:
parent
70cbb2ca9a
commit
0e53eedfba
24
commands/command_base.py
Normal file
24
commands/command_base.py
Normal file
@ -0,0 +1,24 @@
|
||||
from abc import ABCMeta, abstractmethod
|
||||
|
||||
|
||||
class AbstractCommand(metaclass=ABCMeta):
|
||||
"""
|
||||
This is the base class for commands. In order to load a command a few conditions must be met:
|
||||
1) The class name MUST begin with 'Command' i.e. CommandTTS, CommandBan, etc...
|
||||
2) the class MUST extend AbstractCommand
|
||||
|
||||
Generally, it would be advisable to define the command (something like !so, !tts, !songrequest) as a variable of the
|
||||
class and to then call super().__init__(command)
|
||||
"""
|
||||
def __init__(self, command: str):
|
||||
self.command = command
|
||||
|
||||
def honk(self):
|
||||
print("Success! %s" % self.command)
|
||||
|
||||
def get_command(self) -> str:
|
||||
return self.command
|
||||
|
||||
@abstractmethod
|
||||
def do_command(self, fulltext):
|
||||
pass
|
||||
15
commands/implemented/command_tts.py
Normal file
15
commands/implemented/command_tts.py
Normal file
@ -0,0 +1,15 @@
|
||||
from abc import ABCMeta
|
||||
|
||||
from commands.command_base import AbstractCommand
|
||||
|
||||
|
||||
class CommandTTS(AbstractCommand, metaclass=ABCMeta):
|
||||
|
||||
command = "!tts"
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(CommandTTS.command)
|
||||
|
||||
def do_command(self, fulltext):
|
||||
print(fulltext)
|
||||
|
||||
88
commands/loader.py
Normal file
88
commands/loader.py
Normal file
@ -0,0 +1,88 @@
|
||||
import importlib
|
||||
import importlib.util
|
||||
import inspect
|
||||
import os
|
||||
import sys
|
||||
|
||||
from commands.command_base import AbstractCommand
|
||||
|
||||
|
||||
def load_commands() -> dict:
|
||||
clear_compiled()
|
||||
commands = compile_and_load()
|
||||
return commands
|
||||
|
||||
|
||||
def compile_and_load_file(path: str) -> (str, AbstractCommand):
|
||||
module_name = os.path.split(path)[1].replace(".py", "")
|
||||
spec = importlib.util.spec_from_file_location(module_name, path)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
sys.modules[module_name] = module
|
||||
spec.loader.load_module(module_name)
|
||||
|
||||
for name, obj in inspect.getmembers(module):
|
||||
if inspect.isclass(obj) and name.startswith("Command"):
|
||||
command_inst = obj()
|
||||
print("Successfully loaded %s: %s" % (name, command_inst.get_command()))
|
||||
return command_inst.get_command(), command_inst
|
||||
return "", None
|
||||
|
||||
|
||||
def compile_and_load() -> dict:
|
||||
dic = {}
|
||||
compiled_path = get_implementations_dir()
|
||||
for dirName, subdirList, fileList in os.walk(compiled_path):
|
||||
for file in fileList:
|
||||
name = os.path.join(dirName, file)
|
||||
print("compiling %s" % name)
|
||||
name, command = compile_and_load_file(name)
|
||||
dic[name] = command
|
||||
break
|
||||
return dic
|
||||
|
||||
|
||||
def clear_compiled():
|
||||
compiled_path = get_compiled_dir()
|
||||
for dirName, subdirList, fileList in os.walk(compiled_path):
|
||||
for file in fileList:
|
||||
name = os.path.join(dirName, file)
|
||||
os.remove(name)
|
||||
break
|
||||
|
||||
|
||||
def get_base_dir():
|
||||
cwd = os.getcwd()
|
||||
split = os.path.split(cwd)
|
||||
current = split[len(split) - 1]
|
||||
if current == 'commands':
|
||||
return check_dir(cwd)
|
||||
if current == 'Praxis_Bot':
|
||||
return check_dir(os.path.join(current, "commands"))
|
||||
else:
|
||||
print("could not find working directory for Praxis_Bot/commands")
|
||||
raise
|
||||
|
||||
|
||||
def script_to_pyc(path: str):
|
||||
split = os.path.split(path)
|
||||
current = split[len(split) - 1]
|
||||
full = os.path.join(get_compiled_dir(), current + 'c')
|
||||
return full
|
||||
|
||||
|
||||
def get_implementations_dir():
|
||||
return check_dir(os.path.join(get_base_dir(), "implemented"))
|
||||
|
||||
|
||||
def get_compiled_dir():
|
||||
return check_dir(os.path.join(get_base_dir(), "compiled"))
|
||||
|
||||
|
||||
def check_dir(path: str):
|
||||
if not os.path.exists(path):
|
||||
os.mkdir(path, 0x777)
|
||||
return path
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
load_commands()
|
||||
Loading…
Reference in New Issue
Block a user