From 0e53eedfbaaeec477f43fd943aba14130989bb80 Mon Sep 17 00:00:00 2001 From: dtookey Date: Fri, 2 Oct 2020 12:30:47 -0400 Subject: [PATCH 01/14] implemented class loader for concrete instances of commands --- commands/command_base.py | 24 ++++++++ commands/implemented/command_tts.py | 15 +++++ commands/loader.py | 88 +++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 commands/command_base.py create mode 100644 commands/implemented/command_tts.py create mode 100644 commands/loader.py diff --git a/commands/command_base.py b/commands/command_base.py new file mode 100644 index 0000000..569f9a0 --- /dev/null +++ b/commands/command_base.py @@ -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 diff --git a/commands/implemented/command_tts.py b/commands/implemented/command_tts.py new file mode 100644 index 0000000..c172cea --- /dev/null +++ b/commands/implemented/command_tts.py @@ -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) + diff --git a/commands/loader.py b/commands/loader.py new file mode 100644 index 0000000..38c3685 --- /dev/null +++ b/commands/loader.py @@ -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() From 9038d244f24b942fe65a44fa0203a6eb14ce0d26 Mon Sep 17 00:00:00 2001 From: dtookey Date: Fri, 2 Oct 2020 12:38:10 -0400 Subject: [PATCH 02/14] cleaned up defunct bits of pyc implementation --- commands/loader.py | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/commands/loader.py b/commands/loader.py index 38c3685..265c3d0 100644 --- a/commands/loader.py +++ b/commands/loader.py @@ -8,7 +8,6 @@ from commands.command_base import AbstractCommand def load_commands() -> dict: - clear_compiled() commands = compile_and_load() return commands @@ -30,27 +29,19 @@ def compile_and_load_file(path: str) -> (str, AbstractCommand): def compile_and_load() -> dict: dic = {} - compiled_path = get_implementations_dir() - for dirName, subdirList, fileList in os.walk(compiled_path): + implementations = get_implementations_dir() + for dirName, subdirList, fileList in os.walk(implementations): for file in fileList: name = os.path.join(dirName, file) print("compiling %s" % name) name, command = compile_and_load_file(name) - dic[name] = command + if command is not None: + 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(): +def get_base_dir() -> str: cwd = os.getcwd() split = os.path.split(cwd) current = split[len(split) - 1] @@ -63,22 +54,15 @@ def get_base_dir(): 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(): +def get_implementations_dir() -> str: return check_dir(os.path.join(get_base_dir(), "implemented")) -def get_compiled_dir(): +def get_compiled_dir() -> str: return check_dir(os.path.join(get_base_dir(), "compiled")) -def check_dir(path: str): +def check_dir(path: str) -> str: if not os.path.exists(path): os.mkdir(path, 0x777) return path From 354a6da9ae64390f1459d5ee5cd4d9fc9409c96c Mon Sep 17 00:00:00 2001 From: dtookey Date: Fri, 2 Oct 2020 13:40:04 -0400 Subject: [PATCH 03/14] implemented a few doodads on the AbstractCommand class to make integration easier. Modified do_command to receive the Twitch_Module class from twitch_script.py and the twitch.chat.Message from the bot implemented the loader in the bot --- commands/command_base.py | 23 ++++++++++++++---- commands/implemented/command_test.py | 17 +++++++++++++ commands/implemented/command_tts.py | 17 +++++++++---- commands/loader.py | 8 ++++--- twitch_script.py | 36 +++++++++++++++++----------- 5 files changed, 75 insertions(+), 26 deletions(-) create mode 100644 commands/implemented/command_test.py diff --git a/commands/command_base.py b/commands/command_base.py index 569f9a0..5e50e85 100644 --- a/commands/command_base.py +++ b/commands/command_base.py @@ -1,4 +1,9 @@ from abc import ABCMeta, abstractmethod +from enum import Enum, auto + +import twitch.chat + +from twitch_script import Twitch_Module class AbstractCommand(metaclass=ABCMeta): @@ -10,15 +15,25 @@ class AbstractCommand(metaclass=ABCMeta): 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): + + class CommandType(Enum): + NONE = auto() + TWITCH = auto() + DISCORD = auto() + + def __init__(self, command: str, n_args: int = 0, command_type=CommandType.NONE): self.command = command + self.n_args = n_args + self.command_type = command_type - def honk(self): - print("Success! %s" % self.command) + # no touch! + def get_args(self, text: str) -> list: + return text.split(" ")[0:self.n_args + 1] + # no touch! def get_command(self) -> str: return self.command @abstractmethod - def do_command(self, fulltext): + def do_command(self, bot: Twitch_Module, twitch_message: twitch.chat.Message): pass diff --git a/commands/implemented/command_test.py b/commands/implemented/command_test.py new file mode 100644 index 0000000..7004c6b --- /dev/null +++ b/commands/implemented/command_test.py @@ -0,0 +1,17 @@ +from abc import ABCMeta + +import twitch.chat + +from commands.command_base import AbstractCommand +from twitch_script import Twitch_Module + + +class CommandTest(AbstractCommand, metaclass=ABCMeta): + command = "!test" + + def __init__(self): + super().__init__(CommandTest.command, command_type=AbstractCommand.CommandType.TWITCH) + + def do_command(self, bot: Twitch_Module, twitch_message: twitch.chat.Message): + print("!test Detected") + bot.chat.send("test acknowledged") diff --git a/commands/implemented/command_tts.py b/commands/implemented/command_tts.py index c172cea..91abc71 100644 --- a/commands/implemented/command_tts.py +++ b/commands/implemented/command_tts.py @@ -1,15 +1,22 @@ from abc import ABCMeta +import twitch.chat + from commands.command_base import AbstractCommand +from twitch_script import Twitch_Module class CommandTTS(AbstractCommand, metaclass=ABCMeta): - command = "!tts" def __init__(self): - super().__init__(CommandTTS.command) - - def do_command(self, fulltext): - print(fulltext) + super().__init__(CommandTTS.command, n_args=1, command_type=AbstractCommand.CommandType.TWITCH) + def do_command(self, bot: Twitch_Module, twitch_message: twitch.chat.Message): + args = self.get_args(twitch_message.text) + if args[1] == "start": + bot.send_message("tts activated on #%s" % twitch_message.channel) + bot.tts_enabled = True + elif args[1] == "stop": + bot.send_message("tts deactivated") + bot.tts_enabled = False diff --git a/commands/loader.py b/commands/loader.py index 265c3d0..a3b0d9f 100644 --- a/commands/loader.py +++ b/commands/loader.py @@ -3,11 +3,12 @@ import importlib.util import inspect import os import sys +from typing import Dict from commands.command_base import AbstractCommand -def load_commands() -> dict: +def load_commands() -> Dict[str, AbstractCommand]: commands = compile_and_load() return commands @@ -27,7 +28,7 @@ def compile_and_load_file(path: str) -> (str, AbstractCommand): return "", None -def compile_and_load() -> dict: +def compile_and_load() -> Dict[str, AbstractCommand]: dic = {} implementations = get_implementations_dir() for dirName, subdirList, fileList in os.walk(implementations): @@ -69,4 +70,5 @@ def check_dir(path: str) -> str: if __name__ == "__main__": - load_commands() + cmds = load_commands() + cmds["!tts"].do_command("!tts let's do some shit") diff --git a/twitch_script.py b/twitch_script.py index ccc5156..fab6bcf 100644 --- a/twitch_script.py +++ b/twitch_script.py @@ -7,8 +7,11 @@ import twitch.chat import config as config import db import tts +import commands.loader as command_loader import credentials +from commands.command_base import AbstractCommand + class Twitch_Module(): def __init__(self): @@ -18,7 +21,7 @@ class Twitch_Module(): self.db_manager: db.db_module = db.db_module() self.chat: twitch.Chat - + self.commands = command_loader.load_commands() self.tts_enabled: bool = False self.tts_whitelist_enabled: bool = False self.links_allowed: bool = True @@ -65,21 +68,26 @@ class Twitch_Module(): def eval_commands(self, message: twitch.chat.Message): containsURL: bool = self.contains_url(message) + command_text = message.text[0:message.text.index(' ')] - if message.text.startswith('!tts start'): - print("tts activated on #" + message.channel) - self.send_message("tts activated") - self.tts_enabled = True + command = self.commands[command_text] + if command is not None and command.command_type is not AbstractCommand.CommandType.NONE: + command.do_command(self, message) - if message.text.startswith('!tts stop'): - print("tts deactivated on #" + message.channel) - self.send_message("tts deactivated") - self.tts_enabled = True - - if message.text.startswith('!test'): - print("!test Detected") - message.chat.send("test acknowledged") - # message.chat.send(f'@{message.user().display_name}, you have {message.user().view_count} views.') + # if message.text.startswith('!tts start'): + # print("tts activated on #" + message.channel) + # self.send_message("tts activated") + # self.tts_enabled = True + # + # if message.text.startswith('!tts stop'): + # print("tts deactivated on #" + message.channel) + # self.send_message("tts deactivated") + # self.tts_enabled = False + # + # if message.text.startswith('!test'): + # print("!test Detected") + # message.chat.send("test acknowledged") + # # message.chat.send(f'@{message.user().display_name}, you have {message.user().view_count} views.') if message.text.startswith('!roll'): try: From 7c870caa9247deba39649b7841070856123e37a5 Mon Sep 17 00:00:00 2001 From: dtookey Date: Fri, 2 Oct 2020 13:40:04 -0400 Subject: [PATCH 04/14] implemented a few doodads on the AbstractCommand class to make integration easier. Modified do_command to receive the Twitch_Module class from twitch_script.py and the twitch.chat.Message from the bot implemented the loader in the bot --- commands/command_base.py | 23 ++++++++++++++--- commands/implemented/command_test.py | 17 +++++++++++++ commands/implemented/command_tts.py | 17 +++++++++---- commands/loader.py | 8 +++--- twitch_script.py | 38 +++++++++++++++++----------- 5 files changed, 76 insertions(+), 27 deletions(-) create mode 100644 commands/implemented/command_test.py diff --git a/commands/command_base.py b/commands/command_base.py index 569f9a0..5e50e85 100644 --- a/commands/command_base.py +++ b/commands/command_base.py @@ -1,4 +1,9 @@ from abc import ABCMeta, abstractmethod +from enum import Enum, auto + +import twitch.chat + +from twitch_script import Twitch_Module class AbstractCommand(metaclass=ABCMeta): @@ -10,15 +15,25 @@ class AbstractCommand(metaclass=ABCMeta): 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): + + class CommandType(Enum): + NONE = auto() + TWITCH = auto() + DISCORD = auto() + + def __init__(self, command: str, n_args: int = 0, command_type=CommandType.NONE): self.command = command + self.n_args = n_args + self.command_type = command_type - def honk(self): - print("Success! %s" % self.command) + # no touch! + def get_args(self, text: str) -> list: + return text.split(" ")[0:self.n_args + 1] + # no touch! def get_command(self) -> str: return self.command @abstractmethod - def do_command(self, fulltext): + def do_command(self, bot: Twitch_Module, twitch_message: twitch.chat.Message): pass diff --git a/commands/implemented/command_test.py b/commands/implemented/command_test.py new file mode 100644 index 0000000..7004c6b --- /dev/null +++ b/commands/implemented/command_test.py @@ -0,0 +1,17 @@ +from abc import ABCMeta + +import twitch.chat + +from commands.command_base import AbstractCommand +from twitch_script import Twitch_Module + + +class CommandTest(AbstractCommand, metaclass=ABCMeta): + command = "!test" + + def __init__(self): + super().__init__(CommandTest.command, command_type=AbstractCommand.CommandType.TWITCH) + + def do_command(self, bot: Twitch_Module, twitch_message: twitch.chat.Message): + print("!test Detected") + bot.chat.send("test acknowledged") diff --git a/commands/implemented/command_tts.py b/commands/implemented/command_tts.py index c172cea..91abc71 100644 --- a/commands/implemented/command_tts.py +++ b/commands/implemented/command_tts.py @@ -1,15 +1,22 @@ from abc import ABCMeta +import twitch.chat + from commands.command_base import AbstractCommand +from twitch_script import Twitch_Module class CommandTTS(AbstractCommand, metaclass=ABCMeta): - command = "!tts" def __init__(self): - super().__init__(CommandTTS.command) - - def do_command(self, fulltext): - print(fulltext) + super().__init__(CommandTTS.command, n_args=1, command_type=AbstractCommand.CommandType.TWITCH) + def do_command(self, bot: Twitch_Module, twitch_message: twitch.chat.Message): + args = self.get_args(twitch_message.text) + if args[1] == "start": + bot.send_message("tts activated on #%s" % twitch_message.channel) + bot.tts_enabled = True + elif args[1] == "stop": + bot.send_message("tts deactivated") + bot.tts_enabled = False diff --git a/commands/loader.py b/commands/loader.py index 265c3d0..a3b0d9f 100644 --- a/commands/loader.py +++ b/commands/loader.py @@ -3,11 +3,12 @@ import importlib.util import inspect import os import sys +from typing import Dict from commands.command_base import AbstractCommand -def load_commands() -> dict: +def load_commands() -> Dict[str, AbstractCommand]: commands = compile_and_load() return commands @@ -27,7 +28,7 @@ def compile_and_load_file(path: str) -> (str, AbstractCommand): return "", None -def compile_and_load() -> dict: +def compile_and_load() -> Dict[str, AbstractCommand]: dic = {} implementations = get_implementations_dir() for dirName, subdirList, fileList in os.walk(implementations): @@ -69,4 +70,5 @@ def check_dir(path: str) -> str: if __name__ == "__main__": - load_commands() + cmds = load_commands() + cmds["!tts"].do_command("!tts let's do some shit") diff --git a/twitch_script.py b/twitch_script.py index ccc5156..5ccaabd 100644 --- a/twitch_script.py +++ b/twitch_script.py @@ -7,8 +7,11 @@ import twitch.chat import config as config import db import tts +import commands.loader as command_loader import credentials +from commands.command_base import AbstractCommand + class Twitch_Module(): def __init__(self): @@ -18,7 +21,7 @@ class Twitch_Module(): self.db_manager: db.db_module = db.db_module() self.chat: twitch.Chat - + self.commands = command_loader.load_commands() self.tts_enabled: bool = False self.tts_whitelist_enabled: bool = False self.links_allowed: bool = True @@ -64,22 +67,27 @@ class Twitch_Module(): self.tts_message(message) def eval_commands(self, message: twitch.chat.Message): - containsURL: bool = self.contains_url(message) + # containsURL: bool = self.contains_url(message) + command_text = message.text[0:message.text.index(' ')] - if message.text.startswith('!tts start'): - print("tts activated on #" + message.channel) - self.send_message("tts activated") - self.tts_enabled = True + command = self.commands[command_text] + if command is not None and command.command_type is AbstractCommand.CommandType.TWITCH: + command.do_command(self, message) - if message.text.startswith('!tts stop'): - print("tts deactivated on #" + message.channel) - self.send_message("tts deactivated") - self.tts_enabled = True - - if message.text.startswith('!test'): - print("!test Detected") - message.chat.send("test acknowledged") - # message.chat.send(f'@{message.user().display_name}, you have {message.user().view_count} views.') + # if message.text.startswith('!tts start'): + # print("tts activated on #" + message.channel) + # self.send_message("tts activated") + # self.tts_enabled = True + # + # if message.text.startswith('!tts stop'): + # print("tts deactivated on #" + message.channel) + # self.send_message("tts deactivated") + # self.tts_enabled = False + # + # if message.text.startswith('!test'): + # print("!test Detected") + # message.chat.send("test acknowledged") + # # message.chat.send(f'@{message.user().display_name}, you have {message.user().view_count} views.') if message.text.startswith('!roll'): try: From 948877f0eeb8c23214a2665317a449f5b2f46448 Mon Sep 17 00:00:00 2001 From: dtookey Date: Fri, 2 Oct 2020 13:51:43 -0400 Subject: [PATCH 05/14] there are two lines in the test command. I botched one of them... --- commands/implemented/command_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/implemented/command_test.py b/commands/implemented/command_test.py index 7004c6b..45fd60f 100644 --- a/commands/implemented/command_test.py +++ b/commands/implemented/command_test.py @@ -14,4 +14,4 @@ class CommandTest(AbstractCommand, metaclass=ABCMeta): def do_command(self, bot: Twitch_Module, twitch_message: twitch.chat.Message): print("!test Detected") - bot.chat.send("test acknowledged") + twitch_message.chat.send("test acknowledged") From 98d8e969229fdd22829c5c0e5045afab4d35a0aa Mon Sep 17 00:00:00 2001 From: dtookey Date: Fri, 2 Oct 2020 14:35:55 -0400 Subject: [PATCH 06/14] removed class imports from command scripts --- commands/command_base.py | 4 ---- commands/implemented/command_test.py | 5 +---- commands/implemented/command_tts.py | 6 ++---- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/commands/command_base.py b/commands/command_base.py index 5e50e85..f3b479a 100644 --- a/commands/command_base.py +++ b/commands/command_base.py @@ -1,10 +1,6 @@ from abc import ABCMeta, abstractmethod from enum import Enum, auto -import twitch.chat - -from twitch_script import Twitch_Module - class AbstractCommand(metaclass=ABCMeta): """ diff --git a/commands/implemented/command_test.py b/commands/implemented/command_test.py index 45fd60f..c764dd8 100644 --- a/commands/implemented/command_test.py +++ b/commands/implemented/command_test.py @@ -1,9 +1,6 @@ from abc import ABCMeta -import twitch.chat - from commands.command_base import AbstractCommand -from twitch_script import Twitch_Module class CommandTest(AbstractCommand, metaclass=ABCMeta): @@ -12,6 +9,6 @@ class CommandTest(AbstractCommand, metaclass=ABCMeta): def __init__(self): super().__init__(CommandTest.command, command_type=AbstractCommand.CommandType.TWITCH) - def do_command(self, bot: Twitch_Module, twitch_message: twitch.chat.Message): + def do_command(self, bot, twitch_message): print("!test Detected") twitch_message.chat.send("test acknowledged") diff --git a/commands/implemented/command_tts.py b/commands/implemented/command_tts.py index 91abc71..4392cc5 100644 --- a/commands/implemented/command_tts.py +++ b/commands/implemented/command_tts.py @@ -1,9 +1,7 @@ from abc import ABCMeta -import twitch.chat - from commands.command_base import AbstractCommand -from twitch_script import Twitch_Module + class CommandTTS(AbstractCommand, metaclass=ABCMeta): @@ -12,7 +10,7 @@ class CommandTTS(AbstractCommand, metaclass=ABCMeta): def __init__(self): super().__init__(CommandTTS.command, n_args=1, command_type=AbstractCommand.CommandType.TWITCH) - def do_command(self, bot: Twitch_Module, twitch_message: twitch.chat.Message): + def do_command(self, bot, twitch_message): args = self.get_args(twitch_message.text) if args[1] == "start": bot.send_message("tts activated on #%s" % twitch_message.channel) From 143691c186871a11d00f674378e9402196cddb74 Mon Sep 17 00:00:00 2001 From: dtookey Date: Fri, 2 Oct 2020 14:35:55 -0400 Subject: [PATCH 07/14] removed class imports from command scripts --- commands/command_base.py | 4 ---- commands/implemented/command_test.py | 5 +---- commands/implemented/command_tts.py | 6 ++---- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/commands/command_base.py b/commands/command_base.py index 5e50e85..f3b479a 100644 --- a/commands/command_base.py +++ b/commands/command_base.py @@ -1,10 +1,6 @@ from abc import ABCMeta, abstractmethod from enum import Enum, auto -import twitch.chat - -from twitch_script import Twitch_Module - class AbstractCommand(metaclass=ABCMeta): """ diff --git a/commands/implemented/command_test.py b/commands/implemented/command_test.py index 45fd60f..c764dd8 100644 --- a/commands/implemented/command_test.py +++ b/commands/implemented/command_test.py @@ -1,9 +1,6 @@ from abc import ABCMeta -import twitch.chat - from commands.command_base import AbstractCommand -from twitch_script import Twitch_Module class CommandTest(AbstractCommand, metaclass=ABCMeta): @@ -12,6 +9,6 @@ class CommandTest(AbstractCommand, metaclass=ABCMeta): def __init__(self): super().__init__(CommandTest.command, command_type=AbstractCommand.CommandType.TWITCH) - def do_command(self, bot: Twitch_Module, twitch_message: twitch.chat.Message): + def do_command(self, bot, twitch_message): print("!test Detected") twitch_message.chat.send("test acknowledged") diff --git a/commands/implemented/command_tts.py b/commands/implemented/command_tts.py index 91abc71..4392cc5 100644 --- a/commands/implemented/command_tts.py +++ b/commands/implemented/command_tts.py @@ -1,9 +1,7 @@ from abc import ABCMeta -import twitch.chat - from commands.command_base import AbstractCommand -from twitch_script import Twitch_Module + class CommandTTS(AbstractCommand, metaclass=ABCMeta): @@ -12,7 +10,7 @@ class CommandTTS(AbstractCommand, metaclass=ABCMeta): def __init__(self): super().__init__(CommandTTS.command, n_args=1, command_type=AbstractCommand.CommandType.TWITCH) - def do_command(self, bot: Twitch_Module, twitch_message: twitch.chat.Message): + def do_command(self, bot, twitch_message): args = self.get_args(twitch_message.text) if args[1] == "start": bot.send_message("tts activated on #%s" % twitch_message.channel) From 1f86269bbbfe621a8ac73809fd56f72dbc29869d Mon Sep 17 00:00:00 2001 From: dtookey Date: Fri, 2 Oct 2020 14:47:04 -0400 Subject: [PATCH 08/14] updated documentation for command_test.py --- commands/command_base.py | 2 +- commands/implemented/command_test.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/commands/command_base.py b/commands/command_base.py index f3b479a..9bcbcb3 100644 --- a/commands/command_base.py +++ b/commands/command_base.py @@ -31,5 +31,5 @@ class AbstractCommand(metaclass=ABCMeta): return self.command @abstractmethod - def do_command(self, bot: Twitch_Module, twitch_message: twitch.chat.Message): + def do_command(self, bot, twitch_message): pass diff --git a/commands/implemented/command_test.py b/commands/implemented/command_test.py index c764dd8..d6fb5a5 100644 --- a/commands/implemented/command_test.py +++ b/commands/implemented/command_test.py @@ -4,6 +4,9 @@ from commands.command_base import AbstractCommand class CommandTest(AbstractCommand, metaclass=ABCMeta): + """ + this is a test command. and a poor excuse for a git commit. + """ command = "!test" def __init__(self): From bd675bdd32ac87f7ead6327554c95e04581b15c6 Mon Sep 17 00:00:00 2001 From: dtookey Date: Fri, 2 Oct 2020 14:58:49 -0400 Subject: [PATCH 09/14] updated script search logic --- commands/loader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/loader.py b/commands/loader.py index a3b0d9f..fafc4ec 100644 --- a/commands/loader.py +++ b/commands/loader.py @@ -48,7 +48,7 @@ def get_base_dir() -> str: current = split[len(split) - 1] if current == 'commands': return check_dir(cwd) - if current == 'Praxis_Bot': + elif current == 'Praxis_Bot' or current == 'Praxis': return check_dir(os.path.join(current, "commands")) else: print("could not find working directory for Praxis_Bot/commands") From ee6e5bd0a6febb9bd2afe0196e78466dd68960a3 Mon Sep 17 00:00:00 2001 From: dtookey Date: Fri, 2 Oct 2020 15:10:03 -0400 Subject: [PATCH 10/14] i'm an idiot --- commands/loader.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/commands/loader.py b/commands/loader.py index fafc4ec..cab69b1 100644 --- a/commands/loader.py +++ b/commands/loader.py @@ -49,7 +49,7 @@ def get_base_dir() -> str: if current == 'commands': return check_dir(cwd) elif current == 'Praxis_Bot' or current == 'Praxis': - return check_dir(os.path.join(current, "commands")) + return check_dir(os.path.join(cwd, "commands")) else: print("could not find working directory for Praxis_Bot/commands") raise @@ -71,4 +71,4 @@ def check_dir(path: str) -> str: if __name__ == "__main__": cmds = load_commands() - cmds["!tts"].do_command("!tts let's do some shit") + From 5b2c7c0ee92972b48af60398f19f745b4b9ac245 Mon Sep 17 00:00:00 2001 From: dtookey Date: Fri, 2 Oct 2020 15:20:15 -0400 Subject: [PATCH 11/14] handled KeyError on unfound commands better command_text finding --- twitch_script.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/twitch_script.py b/twitch_script.py index 5ccaabd..5bbc0e0 100644 --- a/twitch_script.py +++ b/twitch_script.py @@ -68,12 +68,19 @@ class Twitch_Module(): def eval_commands(self, message: twitch.chat.Message): # containsURL: bool = self.contains_url(message) - command_text = message.text[0:message.text.index(' ')] - - command = self.commands[command_text] - if command is not None and command.command_type is AbstractCommand.CommandType.TWITCH: - command.do_command(self, message) + first_space_idx = message.text.index(' ') + command_text = ' ' + if first_space_idx > -1: + command_text = message.text[0:first_space_idx] + else: + command_text = message.text + try: + command = self.commands[command_text] + if command is not None and command.command_type is AbstractCommand.CommandType.TWITCH: + command.do_command(self, message) + except Exception as e: + pass # we don't care # if message.text.startswith('!tts start'): # print("tts activated on #" + message.channel) # self.send_message("tts activated") From 59aba6ba20312cd5755d5ff3f3d22fb892fec81b Mon Sep 17 00:00:00 2001 From: dtookey Date: Fri, 2 Oct 2020 15:23:50 -0400 Subject: [PATCH 12/14] Okay, we'll just do the whole thing in a try block --- twitch_script.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/twitch_script.py b/twitch_script.py index 5bbc0e0..efe5a9f 100644 --- a/twitch_script.py +++ b/twitch_script.py @@ -68,19 +68,19 @@ class Twitch_Module(): def eval_commands(self, message: twitch.chat.Message): # containsURL: bool = self.contains_url(message) - first_space_idx = message.text.index(' ') - command_text = ' ' - if first_space_idx > -1: - command_text = message.text[0:first_space_idx] - else: - command_text = message.text - try: + first_space_idx = message.text.index(' ') + command_text = ' ' + if first_space_idx > -1: + command_text = message.text[0:first_space_idx] + else: + command_text = message.text + command = self.commands[command_text] if command is not None and command.command_type is AbstractCommand.CommandType.TWITCH: command.do_command(self, message) except Exception as e: - pass # we don't care + pass # we don't care # if message.text.startswith('!tts start'): # print("tts activated on #" + message.channel) # self.send_message("tts activated") From d00f01edc3d529170fddfdb68a826fa277905413 Mon Sep 17 00:00:00 2001 From: Alex Orid Date: Fri, 2 Oct 2020 20:18:51 -0400 Subject: [PATCH 13/14] Updated Roll Command --- commands/implemented/command_roll.py | 66 ++++++++++++++++++++++++++++ credentials.py | 15 +++---- twitch_script.py | 62 +++----------------------- 3 files changed, 79 insertions(+), 64 deletions(-) create mode 100644 commands/implemented/command_roll.py diff --git a/commands/implemented/command_roll.py b/commands/implemented/command_roll.py new file mode 100644 index 0000000..97bcfbb --- /dev/null +++ b/commands/implemented/command_roll.py @@ -0,0 +1,66 @@ +from abc import ABCMeta + +from commands.command_base import AbstractCommand + +import random + +class CommandRoll(AbstractCommand, metaclass=ABCMeta): + """ + this is the roll command. + """ + command = "!roll" + + def __init__(self): + super().__init__(CommandRoll.command, n_args=1, command_type=AbstractCommand.CommandType.TWITCH) + + def do_command(self, bot, twitch_message): + print("!roll Detected") + #twitch_message.chat.send("test acknowledged") + + diceRoll: str = "" + twitch_message.chat.send("Rolling Dice...") + print("Rolling Dice...") + + temp_preParsedMessage = twitch_message.text.split("+") + + tempParsedMessage = temp_preParsedMessage[0].split(" ") + temp_dice_stmt: str = tempParsedMessage[1] + parsedMessage = temp_dice_stmt.lower().split("d") + + loopBool: bool = False + if parsedMessage[0] != "": + loopBool = True + if loopBool == True: + if int(parsedMessage[0]) == 1: + loopBool = False + + # If roll is in xdx+x format + if loopBool == True: + rolls: list = [] + for x in range(int(parsedMessage[0])): + rolls.append(random.randint(1, int(parsedMessage[1]))) + + rollTotal = 0 + for roll in rolls: + rollTotal = rollTotal + roll + diceRoll = diceRoll + str(roll) + ", " + diceRoll = diceRoll[:-2] # This removes the last two characters in the string + + if len(temp_preParsedMessage) == 2: + diceRoll = diceRoll + " + " + temp_preParsedMessage[1] + " = " + str( + rollTotal + int(temp_preParsedMessage[1])) + else: + diceRoll = diceRoll + " = " + str(rollTotal) + # If roll is in dx+x format + if loopBool == False: + roll: int = random.randint(1, int(parsedMessage[1])) + + if len(temp_preParsedMessage) == 2: + diceRoll = str(roll) + " + " + temp_preParsedMessage[1] + " = " + str( + roll + int(temp_preParsedMessage[1])) + else: + diceRoll = str(roll) + + diceRoll = "@" + twitch_message.sender + " rolled: " + diceRoll + print(diceRoll) + twitch_message.chat.send(diceRoll) \ No newline at end of file diff --git a/credentials.py b/credentials.py index 1e5c551..6001812 100644 --- a/credentials.py +++ b/credentials.py @@ -24,13 +24,10 @@ class Twitch_Credential(): class Discord_Credential(): # Discord Credentials explanations here. - def __init__(self, username, helix, oauth, v5_client): + def __init__(self, nickname, token): # super().__init__() - # all of this is completely made up, i just wanted to make sure your file name switch worked right - self.username = username - self.helix = helix - self.oauth = oauth - self.v5_client = v5_client + self.nickname = nickname + self.token = token class DB_Credential(): # engine = "mysql+mysqlconnector://root:password@localhost:3306/DatabaseName" @@ -133,7 +130,7 @@ class Credentials_Module(): def find_Twitch_Credential(self, searchParam: str): print("Searching for Twitch Credential named: " + searchParam) foundSomething = False - tempCert: Twitch_Credential + tempCert: Twitch_Credential = None for cert in self.Twitch_Credentials_List: if cert.username == searchParam: print("Twitch Credential Found: {" + cert.username + "}") @@ -147,7 +144,7 @@ class Credentials_Module(): def find_Discord_Credential(self, searchParam: str): print("Searching for Discord Credential named: " + searchParam) foundSomething = False - tempCert: Discord_Credential + tempCert: Discord_Credential = None for cert in self.Discord_Credentials_List: if cert.username == searchParam: print("Discord Credential Found: {" + cert.username + "}") @@ -161,7 +158,7 @@ class Credentials_Module(): def find_DB_Credential(self, searchParam: str): print("Searching for DB Credential named: " + searchParam) foundSomething = False - tempCert: DB_Credential + tempCert: DB_Credential = None for cert in self.DB_Credentials_List: if cert.nickname == searchParam: print("DB Credential Found: {" + cert.nickname + "}") diff --git a/twitch_script.py b/twitch_script.py index a9f2ea8..9b66bbc 100644 --- a/twitch_script.py +++ b/twitch_script.py @@ -98,12 +98,13 @@ class Twitch_Module(): # message.chat.send("test acknowledged") # # message.chat.send(f'@{message.user().display_name}, you have {message.user().view_count} views.') - if message.text.startswith('!roll'): - try: - self.dice_roll(message) - except Exception: - self.send_message("{something went wrong}") - print("{something went wrong}") + # if message.text.startswith('!roll'): + # try: + # pass + # #self.dice_roll(message) + # except Exception: + # self.send_message("{something went wrong}") + # print("{something went wrong}") def tts_message(self, message: twitch.chat.Message): if not self.contains_slur(message): @@ -149,55 +150,6 @@ class Twitch_Module(): print("<{ slur detected! }> " + " [#" + message.channel + "](" + message.sender + ") used a slur in chat") return containsSlur - # Rolls Dice. - def dice_roll(self, message: twitch.chat.Message): - diceRoll: str = "" - self.send_message("Rolling Dice...") - print("Rolling Dice...") - - temp_preParsedMessage = message.text.split("+") - - tempParsedMessage = temp_preParsedMessage[0].split(" ") - temp_dice_stmt: str = tempParsedMessage[1] - parsedMessage = temp_dice_stmt.lower().split("d") - - loopBool: bool = False - if parsedMessage[0] != "": - loopBool = True - if loopBool == True: - if int(parsedMessage[0]) == 1: - loopBool = False - - # If roll is in xdx+x format - if loopBool == True: - rolls: list = [] - for x in range(int(parsedMessage[0])): - rolls.append(random.randint(1, int(parsedMessage[1]))) - - rollTotal = 0 - for roll in rolls: - rollTotal = rollTotal + roll - diceRoll = diceRoll + str(roll) + ", " - diceRoll = diceRoll[:-2] # This removes the last two characters in the string - - if len(temp_preParsedMessage) == 2: - diceRoll = diceRoll + " + " + temp_preParsedMessage[1] + " = " + str( - rollTotal + int(temp_preParsedMessage[1])) - else: - diceRoll = diceRoll + " = " + str(rollTotal) - # If roll is in dx+x format - if loopBool == False: - roll: int = random.randint(1, int(parsedMessage[1])) - - if len(temp_preParsedMessage) == 2: - diceRoll = str(roll) + " + " + temp_preParsedMessage[1] + " = " + str( - roll + int(temp_preParsedMessage[1])) - else: - diceRoll = str(roll) - - diceRoll = "@" + message.sender + " rolled: " + diceRoll - print(diceRoll) - self.send_message(diceRoll) # This is a old function used prior to the creation of the Twitch_Module class above. From 5d97066b8b4b4598aa7b0ac75280c5c3501576fa Mon Sep 17 00:00:00 2001 From: Alex Orid Date: Wed, 14 Oct 2020 04:11:37 -0400 Subject: [PATCH 14/14] Fixed No Substring/No Arguments Bug Fixed an error where if a command without arguments is sent it would fail. --- twitch_script.py | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/twitch_script.py b/twitch_script.py index 9b66bbc..50e1bce 100644 --- a/twitch_script.py +++ b/twitch_script.py @@ -71,7 +71,15 @@ class Twitch_Module(): def eval_commands(self, message: twitch.chat.Message): # containsURL: bool = self.contains_url(message) try: - first_space_idx = message.text.index(' ') + #first_space_idx = message.text.index(' ') + + # This fixes a error where if you send a command without arguments it fails because + # it cant find the substring. + if message.text.find(" ") != -1: + first_space_idx = message.text.index(' ') + else: + first_space_idx = -1 + command_text = ' ' if first_space_idx > -1: command_text = message.text[0:first_space_idx] @@ -82,29 +90,9 @@ class Twitch_Module(): if command is not None and command.command_type is AbstractCommand.CommandType.TWITCH: command.do_command(self, message) except Exception as e: + print(e) pass # we don't care - # if message.text.startswith('!tts start'): - # print("tts activated on #" + message.channel) - # self.send_message("tts activated") - # self.tts_enabled = True - # - # if message.text.startswith('!tts stop'): - # print("tts deactivated on #" + message.channel) - # self.send_message("tts deactivated") - # self.tts_enabled = False - # - # if message.text.startswith('!test'): - # print("!test Detected") - # message.chat.send("test acknowledged") - # # message.chat.send(f'@{message.user().display_name}, you have {message.user().view_count} views.') - - # if message.text.startswith('!roll'): - # try: - # pass - # #self.dice_roll(message) - # except Exception: - # self.send_message("{something went wrong}") - # print("{something went wrong}") + def tts_message(self, message: twitch.chat.Message): if not self.contains_slur(message):