From ded62cefacfa5726b9a0877b8f85152ae1487e1b Mon Sep 17 00:00:00 2001 From: Alex Orid Date: Sun, 25 Apr 2021 00:57:22 -0400 Subject: [PATCH 01/13] initial commit --- channel_points/command_base.py | 57 +++++++++ .../implemented/Command_lights_v2.py | 75 ++++++++++++ channel_points/implemented/Command_roll_v2.py | 114 ++++++++++++++++++ channel_points/implemented/Command_test_v2.py | 25 ++++ channel_points/loader.py | 79 ++++++++++++ standalone_channelpoints.py | 78 ++++++++++++ 6 files changed, 428 insertions(+) create mode 100644 channel_points/command_base.py create mode 100644 channel_points/implemented/Command_lights_v2.py create mode 100644 channel_points/implemented/Command_roll_v2.py create mode 100644 channel_points/implemented/Command_test_v2.py create mode 100644 channel_points/loader.py create mode 100644 standalone_channelpoints.py diff --git a/channel_points/command_base.py b/channel_points/command_base.py new file mode 100644 index 0000000..b3afc97 --- /dev/null +++ b/channel_points/command_base.py @@ -0,0 +1,57 @@ +from abc import ABCMeta, abstractmethod +from enum import Enum, auto + + +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) + """ + + class CommandType(Enum): + NONE = auto() + Praxis = auto() + TWITCH = auto() + DISCORD = auto() + Ver2 = auto() + + class CommandSource(Enum): + default = 0 + Praxis = 1 + Twitch = 2 + Discord = 3 + + def __init__(self, command: str, n_args: int = 0, command_type=CommandType.NONE, helpText:list=["No Help"], CommandEnabled = True): + self.command = command + self.n_args = n_args + self.command_type = command_type + self.help = helpText + self.isCommandEnabled = CommandEnabled + + # 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 + + # no touch! + def get_commandType(self): + return self.command_type + + # no touch! + def get_help(self): + return self.help + + # no touch! + def is_command_enabled(self): + return self.isCommandEnabled + + @abstractmethod + def do_command(self, bot, user, command, rest, bonusData): + pass \ No newline at end of file diff --git a/channel_points/implemented/Command_lights_v2.py b/channel_points/implemented/Command_lights_v2.py new file mode 100644 index 0000000..ccde22b --- /dev/null +++ b/channel_points/implemented/Command_lights_v2.py @@ -0,0 +1,75 @@ +from abc import ABCMeta + +import lights_module +from commands.command_base import AbstractCommand + +import utilities_script as utility + +class Command_lights_v2(AbstractCommand, metaclass=ABCMeta): + """ + this is the test command. + """ + command = "!lights" + + def __init__(self): + super().__init__(Command_lights_v2.command, n_args=1, command_type=AbstractCommand.CommandType.Ver2) + self.help = ["This command allows you to modify the lights via the Lights_Module.", + "\nExample:","lights \"SCENE\"","lights \"COLOR\"","lights \"R\" \"G\" \"B\"","lights \"1\" \"0.5\" \"0\""] + self.isCommandEnabled = True + + def do_command(self, source = AbstractCommand.CommandSource.default, user = "User", command = "", rest = "", bonusData = None): + returnString = "" + + tempBool = True + if tempBool == True: + LightModule = lights_module.Lights_Module() + LightModule.main() + #bot.return_message("\nRGB Command Detected!") + tempFix = command + " " + rest + + tempParsedMessage = tempFix.split(" ") + sceneCommand = False + if (len(tempParsedMessage)) > 2: + #bot.return_message("RGB Command!") + rgb_r = float(tempParsedMessage[1]) + rgb_g = float(tempParsedMessage[2]) + rgb_b = float(tempParsedMessage[3]) + xy_result = LightModule.rgb_to_xy(rgb_r, rgb_g, rgb_b) + #bot.return_message("got XY") + LightModule.bridge_.set_group(16, "xy", xy_result) + #bot.return_message("sent color to [Lights_Module]") + else: + if "stream" in tempParsedMessage: + sceneCommand = True + LightModule.bridge_.run_scene("Downstairs", "Stream") + elif "normal" in tempParsedMessage: + sceneCommand = True + LightModule.bridge_.run_scene("Downstairs", "Bright") + elif "haxor" in tempParsedMessage: + sceneCommand = True + LightModule.bridge_.run_scene("Downstairs", "hacker vibes") + elif "off" in tempParsedMessage: + sceneCommand = True + LightModule.bridge_.set_group("Downstairs", "on", False) + elif "on" in tempParsedMessage: + sceneCommand = True + LightModule.bridge_.set_group("Downstairs", "on", True) + elif "ravemode" in tempParsedMessage: + sceneCommand = True + LightModule.raveMode() + else: + #bot.return_message("Color Command!") + xy_result = LightModule.color_string_parser(tempParsedMessage) + #bot.return_message("got XY") + LightModule.bridge_.set_group(16, "xy", xy_result) + #bot.return_message("sent color to [Lights_Module]") + + #if sceneCommand == True: + #bot.return_message("Scene Command!") + + returnString = user + " changed the light's color!" + + return returnString + + def get_help(self): + return self.help \ No newline at end of file diff --git a/channel_points/implemented/Command_roll_v2.py b/channel_points/implemented/Command_roll_v2.py new file mode 100644 index 0000000..a174567 --- /dev/null +++ b/channel_points/implemented/Command_roll_v2.py @@ -0,0 +1,114 @@ +from abc import ABCMeta + +from commands.command_base import AbstractCommand + +import random +import utilities_script as utility + +class Command_roll_v2(AbstractCommand, metaclass=ABCMeta): + """ + this is the test command. + """ + command = "!roll" + + def __init__(self): + super().__init__(Command_roll_v2.command, n_args=1, command_type=AbstractCommand.CommandType.Ver2) + self.help = ["This will roll dice, based on your inputs.", + "\nExample:","roll \"d20\"", "roll \"1D20+5\"", "roll \"10df\"", "roll \"10Df+3\""] + self.isCommandEnabled = True + + def do_command(self, source = AbstractCommand.CommandSource.default, user = "User", command = "", rest = "", bonusData = None): + returnString = user + " sent: [ " + command + " ] with: " + rest + + if ("f") in rest.lower(): + returnString = self.roll(2, user, command + " " +rest) + else: + returnString = self.roll(1, user, command + " " +rest) + + return returnString + + def roll(self, roll_type, user, user_message): + diceRoll = "" + switch = { + 1: "Standard", + 2: "Fate Dice" + } + temp_preParsedMessage = user_message.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_type == 1: + print("-rolling...") + # 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]))) # This is the roller + + 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])) # This is the roller + + if len(temp_preParsedMessage) == 2: + diceRoll = str(roll) + " + " + temp_preParsedMessage[1] + " = " + str( + roll + int(temp_preParsedMessage[1])) + else: + diceRoll = str(roll) + diceRoll = user + " rolled: " + diceRoll + + if roll_type == 2: + + print("-fate Rolling....") + # !roll 4df + # If roll is in xdx+x format + if loopBool == True: + rolls: list = [] + for x in range(int(parsedMessage[0])): + rolls.append(random.randint(-1, 1)) # This is the roller + + 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, 1) # This is the roller + + if len(temp_preParsedMessage) == 2: + diceRoll = str(roll) + " + " + temp_preParsedMessage[1] + " = " + str( + roll + int(temp_preParsedMessage[1])) + else: + diceRoll = str(roll) + diceRoll = user + " fate rolled: " + diceRoll + + return diceRoll + + def get_help(self): + return self.help \ No newline at end of file diff --git a/channel_points/implemented/Command_test_v2.py b/channel_points/implemented/Command_test_v2.py new file mode 100644 index 0000000..18995d3 --- /dev/null +++ b/channel_points/implemented/Command_test_v2.py @@ -0,0 +1,25 @@ +from abc import ABCMeta + +from commands.command_base import AbstractCommand + +import utilities_script as utility + +class Command_test_v2(AbstractCommand, metaclass=ABCMeta): + """ + this is the test command. + """ + command = "testerino" + + def __init__(self): + super().__init__(Command_test_v2.command, n_args=1, command_type=AbstractCommand.CommandType.Ver2) + self.help = ["This is a test command.", + "\nExample:","testerino"] + self.isCommandEnabled = True + + def do_command(self, source = AbstractCommand.CommandSource.default, user = "User", command = "", rest = "", bonusData = None): + returnString = user + " sent: [ " + command + " ] with: " + rest + #print(returnString) + return returnString + + def get_help(self): + return self.help \ No newline at end of file diff --git a/channel_points/loader.py b/channel_points/loader.py new file mode 100644 index 0000000..a92b544 --- /dev/null +++ b/channel_points/loader.py @@ -0,0 +1,79 @@ +import importlib +import importlib.util +import inspect +import os +import sys +from typing import Dict + +from commands.command_base import AbstractCommand + + +#New +def load_commands(commandType: AbstractCommand.CommandType) -> Dict[str, AbstractCommand]: + print(" -Loading ", commandType ," Commands...\n") + commands = compile_and_load(commandType) + return commands + +#New +def compile_and_load_file(path: str, commandType: AbstractCommand.CommandType): + 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() + if commandType == command_inst.get_commandType(): + print(" ---Successfully loaded %s: %s" % (commandType, command_inst.get_command())) + return command_inst.get_command(), command_inst + elif commandType != command_inst.get_commandType(): + print(" -%s CommandType did not match: %s for: %s" % (command_inst.get_commandType(), commandType, command_inst.get_command())) + return "", None + + +#New +def compile_and_load(commandType: AbstractCommand.CommandType) -> Dict[str, AbstractCommand]: + dic = {} + 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, commandType) + if command is not None and command.command_type is commandType: + dic[name] = command + break + return dic + +def get_base_dir() -> str: + cwd = os.getcwd() + split = os.path.split(cwd) + current = split[len(split) - 1] + if current == 'commands': + return check_dir(cwd) + elif current == 'Praxis_Bot' or current == 'Praxis': + return check_dir(os.path.join(cwd, "commands")) + else: + print("could not find working directory for Praxis_Bot/commands") + raise Exception + + +def get_implementations_dir() -> str: + return check_dir(os.path.join(get_base_dir(), "implemented")) + + +def get_compiled_dir() -> str: + return check_dir(os.path.join(get_base_dir(), "compiled")) + + +def check_dir(path: str) -> str: + if not os.path.exists(path): + os.mkdir(path, 0x777) + return path + + +if __name__ == "__main__": + cmds = load_commands() + diff --git a/standalone_channelpoints.py b/standalone_channelpoints.py new file mode 100644 index 0000000..53a6e28 --- /dev/null +++ b/standalone_channelpoints.py @@ -0,0 +1,78 @@ +import flask +from flask import request + +import commands.loader as command_loader +from commands.command_base import AbstractCommand + +api = flask.Flask(__name__) +# enable/disable this to get web pages of crashes returned +api.config["DEBUG"] = True + +loadedCommands = {} + +def init(): + # todo load entire command library and cache it here + load_commands() + + +def load_commands(): + global loadedCommands + loadedCommands = command_loader.load_commands(AbstractCommand.CommandType.Ver2) + + +def is_command(command: str) -> bool: + #print(command) + for cmd in loadedCommands: + #print(cmd) + if command == cmd: + return True + + if command == "!echo": + return True + else: + return False + +def handle_command(source, username, command, rest, bonusData): + if command == "!echo": + message = "Got payload [%s]" % rest + #print(message) + return flask.make_response("{\"message\":\"%s\"}" % message, 200, {"Content-Type": "application/json"}) + + cmd:AbstractCommand = loadedCommands[command] + if cmd is not None: + cmd_response = cmd.do_command(source, username, command, rest, bonusData) + return flask.make_response("{\"message\":\"%s\"}" % cmd_response, 200, {"Content-Type": "application/json"}) + + #print("Doing a command") + + +@api.route('/api/v1/command', methods=['GET']) +def command_check(): + if 'name' in request.args: + if is_command(request.args['name']): + return flask.make_response('', 200) + else: + return flask.make_response('', 404) + + +@api.route('/api/v1/exec', methods=['GET']) +def exec_command(): + if 'command_name' not in request.args: + return flask.make_response('{\"text\":"Argument \'command_name\' not in request"}', 400) + if 'rest' not in request.args: + return flask.make_response('{\"text\":"Argument \'rest\' not in request"}', 400) + + if 'command_source' not in request.args: + return flask.make_response('{\"text\":"Argument \'command_source\' not in request"}', 400) + + if 'user_name' not in request.args: + username = "User" + else: + username = request.args['user_name'] + + return handle_command(request.args['command_source'], username, request.args['command_name'], request.args['rest'], request.args['bonus_data']) + + +if __name__ == '__main__': + init() + api.run(host='0.0.0.0') -- 2.45.2 From a9641a44abbc392fe7278fb29a71eb72b8b6f85b Mon Sep 17 00:00:00 2001 From: Alex Orid Date: Sun, 25 Apr 2021 01:48:37 -0400 Subject: [PATCH 02/13] port changes --- Dockerfile_standalone_channelPoints | 11 +++++++++++ docker-compose.yaml | 8 +++++++- makedockerimages.bat | 1 + standalone_channelpoints.py | 2 +- standalone_command.py | 2 +- standalone_twitch_script.py | 4 ++-- 6 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 Dockerfile_standalone_channelPoints diff --git a/Dockerfile_standalone_channelPoints b/Dockerfile_standalone_channelPoints new file mode 100644 index 0000000..fae84ac --- /dev/null +++ b/Dockerfile_standalone_channelPoints @@ -0,0 +1,11 @@ +FROM python:3.10.0a7-alpine3.13 + +WORKDIR /Praxis + +COPY requirements_sa_command.txt requirements_sa_command.txt +RUN apk add --update gcc libc-dev linux-headers && rm -rf /var/cache/apk/* +RUN pip3 install -r requirements_sa_command.txt + +COPY . . + +CMD [ "python3", "standalone_channelPoints.py"] \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index 603da78..6481868 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -3,7 +3,13 @@ services: standalone_command: image: standalone_command ports: - - 5000:5000 + - 6009:6009 + environment: + - ISDOCKER=cat + standalone_channelPoints: + image: standalone_channelPoints + ports: + - 6969:6969 environment: - ISDOCKER=cat standalone_twitchscript: diff --git a/makedockerimages.bat b/makedockerimages.bat index 876b9a0..a3fbca1 100644 --- a/makedockerimages.bat +++ b/makedockerimages.bat @@ -1,4 +1,5 @@ docker build --file Dockerfile_standalone_command --tag standalone_command . +docker build --file Dockerfile_standalone_channelPoints --tag standalone_channelPoints . docker build --file Dockerfile_standalone_DiscordScript --tag standalone_discordscript . docker build --file Dockerfile_standalone_TwitchScript --tag standalone_twitchscript . docker build --file Dockerfile_standalone_Twitch_Pubsub --tag standalone_twitch_pubsub . \ No newline at end of file diff --git a/standalone_channelpoints.py b/standalone_channelpoints.py index 53a6e28..8dc8a5b 100644 --- a/standalone_channelpoints.py +++ b/standalone_channelpoints.py @@ -75,4 +75,4 @@ def exec_command(): if __name__ == '__main__': init() - api.run(host='0.0.0.0') + api.run(host='0.0.0.0', port=6969) diff --git a/standalone_command.py b/standalone_command.py index 53a6e28..3c77bcc 100644 --- a/standalone_command.py +++ b/standalone_command.py @@ -75,4 +75,4 @@ def exec_command(): if __name__ == '__main__': init() - api.run(host='0.0.0.0') + api.run(host='0.0.0.0', port=6009) diff --git a/standalone_twitch_script.py b/standalone_twitch_script.py index aba70f0..a9b8552 100644 --- a/standalone_twitch_script.py +++ b/standalone_twitch_script.py @@ -69,14 +69,14 @@ class Twitch_Module(): def is_command(self, word: str) -> bool: # todo need to url-escape word clean_param = urlencode({'name': word}) - url = "http://standalone_command:5000/api/v1/command?%s" % clean_param + url = "http://standalone_command:6009/api/v1/command?%s" % clean_param resp = requests.get(url) return resp.status_code == 200 def exec_command(self, realMessage: twitch.chat.Message, command: str, rest: str): # todo need to url-escape command and rest params = urlencode({'command_source': commands.command_base.AbstractCommand.CommandSource.Twitch,'user_name': realMessage.sender, 'command_name': command, 'rest': rest, 'bonus_data': realMessage}) - url = "http://standalone_command:5000/api/v1/exec?%s" % params + url = "http://standalone_command:6009/api/v1/exec?%s" % params resp = requests.get(url) if resp.status_code == 200: print("Got the following message: %s" % resp.text) -- 2.45.2 From ca48b67a01acfb34352c916e257270d30fe6e7a9 Mon Sep 17 00:00:00 2001 From: Alex Orid Date: Sun, 25 Apr 2021 11:46:35 -0400 Subject: [PATCH 03/13] typos --- Dockerfile_standalone_channelPoints | 2 +- docker-compose.yaml | 4 ++-- makedockerimages.bat | 2 +- standalone_discord_script.py | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Dockerfile_standalone_channelPoints b/Dockerfile_standalone_channelPoints index fae84ac..5c4e21d 100644 --- a/Dockerfile_standalone_channelPoints +++ b/Dockerfile_standalone_channelPoints @@ -8,4 +8,4 @@ RUN pip3 install -r requirements_sa_command.txt COPY . . -CMD [ "python3", "standalone_channelPoints.py"] \ No newline at end of file +CMD [ "python3", "standalone_channelpoints.py"] \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index 6481868..d378b8b 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -6,8 +6,8 @@ services: - 6009:6009 environment: - ISDOCKER=cat - standalone_channelPoints: - image: standalone_channelPoints + standalone_channelpoints: + image: standalone_channelpoints ports: - 6969:6969 environment: diff --git a/makedockerimages.bat b/makedockerimages.bat index a3fbca1..8e66509 100644 --- a/makedockerimages.bat +++ b/makedockerimages.bat @@ -1,5 +1,5 @@ docker build --file Dockerfile_standalone_command --tag standalone_command . -docker build --file Dockerfile_standalone_channelPoints --tag standalone_channelPoints . +docker build --file Dockerfile_standalone_channelpoints --tag standalone_channelpoints . docker build --file Dockerfile_standalone_DiscordScript --tag standalone_discordscript . docker build --file Dockerfile_standalone_TwitchScript --tag standalone_twitchscript . docker build --file Dockerfile_standalone_Twitch_Pubsub --tag standalone_twitch_pubsub . \ No newline at end of file diff --git a/standalone_discord_script.py b/standalone_discord_script.py index 291a9b8..8ece8a7 100644 --- a/standalone_discord_script.py +++ b/standalone_discord_script.py @@ -87,14 +87,14 @@ class Discord_Module(discord.Client): async def is_command(self, word: str) -> bool: # todo need to url-escape word clean_param = urlencode({'name': word}) - url = "http://standalone_command:5000/api/v1/command?%s" % clean_param + url = "http://standalone_command:6009/api/v1/command?%s" % clean_param resp = requests.get(url) return resp.status_code == 200 async def exec_command(self, realMessage: discord.Message, command: str, rest: str): # todo need to url-escape command and rest params = urlencode({'command_source': commands.command_base.AbstractCommand.CommandSource.Discord, 'user_name': realMessage.author.mention, 'command_name': command, 'rest': rest, 'bonus_data': realMessage}) - url = "http://standalone_command:5000/api/v1/exec?%s" % params + url = "http://standalone_command:6009/api/v1/exec?%s" % params resp = requests.get(url) if resp.status_code == 200: print("Got the following message: %s" % resp.text) -- 2.45.2 From e3a9c0bccdef30a99614a63c7155f98df3127449 Mon Sep 17 00:00:00 2001 From: Alex Orid Date: Sun, 25 Apr 2021 20:59:28 -0400 Subject: [PATCH 04/13] Channel Point Rewards --- channel_points/channelPoints_base.py | 54 +++++++++ channel_points/channelPoints_loader.py | 79 ++++++++++++ channel_points/command_base.py | 57 --------- .../ChannelPointReward_Hydration_v2.py | 24 ++++ .../implemented/Command_lights_v2.py | 75 ------------ channel_points/implemented/Command_roll_v2.py | 114 ------------------ channel_points/loader.py | 79 ------------ 7 files changed, 157 insertions(+), 325 deletions(-) create mode 100644 channel_points/channelPoints_base.py create mode 100644 channel_points/channelPoints_loader.py delete mode 100644 channel_points/command_base.py create mode 100644 channel_points/implemented/ChannelPointReward_Hydration_v2.py delete mode 100644 channel_points/implemented/Command_lights_v2.py delete mode 100644 channel_points/implemented/Command_roll_v2.py delete mode 100644 channel_points/loader.py diff --git a/channel_points/channelPoints_base.py b/channel_points/channelPoints_base.py new file mode 100644 index 0000000..71ecba6 --- /dev/null +++ b/channel_points/channelPoints_base.py @@ -0,0 +1,54 @@ +from abc import ABCMeta, abstractmethod +from enum import Enum, auto + + +class AbstractChannelPoints(metaclass=ABCMeta): + """ + This is the base class for channel points. In order to load a channel point redemption a few conditions must be met: + 1) The class name MUST begin with 'ChannelPoint' i.e. CommandTTS, CommandBan, etc... + 2) the class MUST extend AbstractCommand + + Generally, it would be advisable to define the ChannelPointPrize redemption name as a variable of the + class and to then call super().__init__(command) + """ + + class ChannelPointsType(Enum): + NONE = auto() + Ver2 = auto() + + class ChannelPointsSource(Enum): + default = 0 + Praxis = 1 + Twitch = 2 + Discord = 3 + + def __init__(self, ChannelPointRewardName: str, n_args: int = 0, channelPointReward_type=ChannelPointsType.NONE, helpText:list=["No Help"], isChannelPointRewardEnabled = True): + self.ChannelPointRewardName = ChannelPointRewardName + self.n_args = n_args + self.ChannelPointRewardType = channelPointReward_type + self.help = helpText + self.isChannelPointRewardEnabled = isChannelPointRewardEnabled + + # no touch! + def get_args(self, text: str) -> list: + return text.split(" ")[0:self.n_args + 1] + + # no touch! + def get_ChannelPointRewardName(self) -> str: + return self.ChannelPointRewardName + + # no touch! + def get_ChannelPointRewardType(self): + return self.ChannelPointRewardType + + # no touch! + def get_help(self): + return self.help + + # no touch! + def is_ChannelPointReward_enabled(self): + return self.isChannelPointRewardEnabled + + @abstractmethod + def do_ChannelPointReward(self, bot, user, command, rest, bonusData): + pass \ No newline at end of file diff --git a/channel_points/channelPoints_loader.py b/channel_points/channelPoints_loader.py new file mode 100644 index 0000000..9bd4ef9 --- /dev/null +++ b/channel_points/channelPoints_loader.py @@ -0,0 +1,79 @@ +import importlib +import importlib.util +import inspect +import os +import sys +from typing import Dict + +from channel_points.channelPoints_base import AbstractChannelPoints + + +#New +def load_rewards(channelPointsType: AbstractChannelPoints.ChannelPointsType) -> Dict[str, AbstractChannelPoints]: + print(" -Loading ", channelPointsType ," ChannelPointRewards...\n") + channelPointRewards = compile_and_load(channelPointsType) + return channelPointRewards + +#New +def compile_and_load_file(path: str, channelPointsType: AbstractChannelPoints.ChannelPointsType): + 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("ChannelPointReward"): + channelPointReward_inst = obj() + if channelPointsType == channelPointReward_inst.get_ChannelPointRewardType(): + print(" ---Successfully loaded %s: %s" % (channelPointsType, channelPointReward_inst.get_ChannelPointRewardType())) + return channelPointReward_inst.get_ChannelPointRewardType(), channelPointReward_inst + elif channelPointsType != channelPointReward_inst.get_ChannelPointRewardType(): + print(" -%s ChannelPointsType did not match: %s for: %s" % (channelPointReward_inst.get_ChannelPointRewardType(), channelPointsType, channelPointReward_inst.get_ChannelPointRewardName())) + return "", None + + +#New +def compile_and_load(ChannelPointsRewardType: AbstractChannelPoints.ChannelPointsType) -> Dict[str, AbstractChannelPoints]: + dic = {} + 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, reward = compile_and_load_file(name, ChannelPointsRewardType) + if reward is not None and reward.ChannelPointRewardType is ChannelPointsRewardType: + dic[name] = reward + break + return dic + +def get_base_dir() -> str: + cwd = os.getcwd() + split = os.path.split(cwd) + current = split[len(split) - 1] + if current == 'channel_points': + return check_dir(cwd) + elif current == 'Praxis_Bot' or current == 'Praxis': + return check_dir(os.path.join(cwd, "channel_points")) + else: + print("could not find working directory for Praxis_Bot/channel_points") + raise Exception + + +def get_implementations_dir() -> str: + return check_dir(os.path.join(get_base_dir(), "implemented")) + + +def get_compiled_dir() -> str: + return check_dir(os.path.join(get_base_dir(), "compiled")) + + +def check_dir(path: str) -> str: + if not os.path.exists(path): + os.mkdir(path, 0x777) + return path + + +if __name__ == "__main__": + rewards = load_rewards() + diff --git a/channel_points/command_base.py b/channel_points/command_base.py deleted file mode 100644 index b3afc97..0000000 --- a/channel_points/command_base.py +++ /dev/null @@ -1,57 +0,0 @@ -from abc import ABCMeta, abstractmethod -from enum import Enum, auto - - -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) - """ - - class CommandType(Enum): - NONE = auto() - Praxis = auto() - TWITCH = auto() - DISCORD = auto() - Ver2 = auto() - - class CommandSource(Enum): - default = 0 - Praxis = 1 - Twitch = 2 - Discord = 3 - - def __init__(self, command: str, n_args: int = 0, command_type=CommandType.NONE, helpText:list=["No Help"], CommandEnabled = True): - self.command = command - self.n_args = n_args - self.command_type = command_type - self.help = helpText - self.isCommandEnabled = CommandEnabled - - # 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 - - # no touch! - def get_commandType(self): - return self.command_type - - # no touch! - def get_help(self): - return self.help - - # no touch! - def is_command_enabled(self): - return self.isCommandEnabled - - @abstractmethod - def do_command(self, bot, user, command, rest, bonusData): - pass \ No newline at end of file diff --git a/channel_points/implemented/ChannelPointReward_Hydration_v2.py b/channel_points/implemented/ChannelPointReward_Hydration_v2.py new file mode 100644 index 0000000..a63520f --- /dev/null +++ b/channel_points/implemented/ChannelPointReward_Hydration_v2.py @@ -0,0 +1,24 @@ +from abc import ABCMeta + +from channel_points.channelPoints_base import AbstractChannelPoints + +import utilities_script as utility + +class ChannelPointReward_Hydration_v2(AbstractChannelPoints, metaclass=ABCMeta): + """ + this is the hydration reward. + """ + ChannelPointRewardName = "hydration" + + def __init__(self): + super().__init__(ChannelPointReward_Hydration_v2.ChannelPointRewardName, n_args=1, command_type=AbstractChannelPoints.ChannelPointsType.Ver2) + self.help = ["This is a hydration channel point reward."] + self.isChannelPointRewardEnabled = True + + def do_ChannelPointReward(self, source = AbstractChannelPoints.ChannelPointsSource.default, user = "User", command = "", rest = "", bonusData = None): + returnString = user + " sent: [ " + command + " ] with: " + rest + #print(returnString) + return returnString + + def get_help(self): + return self.help \ No newline at end of file diff --git a/channel_points/implemented/Command_lights_v2.py b/channel_points/implemented/Command_lights_v2.py deleted file mode 100644 index ccde22b..0000000 --- a/channel_points/implemented/Command_lights_v2.py +++ /dev/null @@ -1,75 +0,0 @@ -from abc import ABCMeta - -import lights_module -from commands.command_base import AbstractCommand - -import utilities_script as utility - -class Command_lights_v2(AbstractCommand, metaclass=ABCMeta): - """ - this is the test command. - """ - command = "!lights" - - def __init__(self): - super().__init__(Command_lights_v2.command, n_args=1, command_type=AbstractCommand.CommandType.Ver2) - self.help = ["This command allows you to modify the lights via the Lights_Module.", - "\nExample:","lights \"SCENE\"","lights \"COLOR\"","lights \"R\" \"G\" \"B\"","lights \"1\" \"0.5\" \"0\""] - self.isCommandEnabled = True - - def do_command(self, source = AbstractCommand.CommandSource.default, user = "User", command = "", rest = "", bonusData = None): - returnString = "" - - tempBool = True - if tempBool == True: - LightModule = lights_module.Lights_Module() - LightModule.main() - #bot.return_message("\nRGB Command Detected!") - tempFix = command + " " + rest - - tempParsedMessage = tempFix.split(" ") - sceneCommand = False - if (len(tempParsedMessage)) > 2: - #bot.return_message("RGB Command!") - rgb_r = float(tempParsedMessage[1]) - rgb_g = float(tempParsedMessage[2]) - rgb_b = float(tempParsedMessage[3]) - xy_result = LightModule.rgb_to_xy(rgb_r, rgb_g, rgb_b) - #bot.return_message("got XY") - LightModule.bridge_.set_group(16, "xy", xy_result) - #bot.return_message("sent color to [Lights_Module]") - else: - if "stream" in tempParsedMessage: - sceneCommand = True - LightModule.bridge_.run_scene("Downstairs", "Stream") - elif "normal" in tempParsedMessage: - sceneCommand = True - LightModule.bridge_.run_scene("Downstairs", "Bright") - elif "haxor" in tempParsedMessage: - sceneCommand = True - LightModule.bridge_.run_scene("Downstairs", "hacker vibes") - elif "off" in tempParsedMessage: - sceneCommand = True - LightModule.bridge_.set_group("Downstairs", "on", False) - elif "on" in tempParsedMessage: - sceneCommand = True - LightModule.bridge_.set_group("Downstairs", "on", True) - elif "ravemode" in tempParsedMessage: - sceneCommand = True - LightModule.raveMode() - else: - #bot.return_message("Color Command!") - xy_result = LightModule.color_string_parser(tempParsedMessage) - #bot.return_message("got XY") - LightModule.bridge_.set_group(16, "xy", xy_result) - #bot.return_message("sent color to [Lights_Module]") - - #if sceneCommand == True: - #bot.return_message("Scene Command!") - - returnString = user + " changed the light's color!" - - return returnString - - def get_help(self): - return self.help \ No newline at end of file diff --git a/channel_points/implemented/Command_roll_v2.py b/channel_points/implemented/Command_roll_v2.py deleted file mode 100644 index a174567..0000000 --- a/channel_points/implemented/Command_roll_v2.py +++ /dev/null @@ -1,114 +0,0 @@ -from abc import ABCMeta - -from commands.command_base import AbstractCommand - -import random -import utilities_script as utility - -class Command_roll_v2(AbstractCommand, metaclass=ABCMeta): - """ - this is the test command. - """ - command = "!roll" - - def __init__(self): - super().__init__(Command_roll_v2.command, n_args=1, command_type=AbstractCommand.CommandType.Ver2) - self.help = ["This will roll dice, based on your inputs.", - "\nExample:","roll \"d20\"", "roll \"1D20+5\"", "roll \"10df\"", "roll \"10Df+3\""] - self.isCommandEnabled = True - - def do_command(self, source = AbstractCommand.CommandSource.default, user = "User", command = "", rest = "", bonusData = None): - returnString = user + " sent: [ " + command + " ] with: " + rest - - if ("f") in rest.lower(): - returnString = self.roll(2, user, command + " " +rest) - else: - returnString = self.roll(1, user, command + " " +rest) - - return returnString - - def roll(self, roll_type, user, user_message): - diceRoll = "" - switch = { - 1: "Standard", - 2: "Fate Dice" - } - temp_preParsedMessage = user_message.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_type == 1: - print("-rolling...") - # 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]))) # This is the roller - - 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])) # This is the roller - - if len(temp_preParsedMessage) == 2: - diceRoll = str(roll) + " + " + temp_preParsedMessage[1] + " = " + str( - roll + int(temp_preParsedMessage[1])) - else: - diceRoll = str(roll) - diceRoll = user + " rolled: " + diceRoll - - if roll_type == 2: - - print("-fate Rolling....") - # !roll 4df - # If roll is in xdx+x format - if loopBool == True: - rolls: list = [] - for x in range(int(parsedMessage[0])): - rolls.append(random.randint(-1, 1)) # This is the roller - - 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, 1) # This is the roller - - if len(temp_preParsedMessage) == 2: - diceRoll = str(roll) + " + " + temp_preParsedMessage[1] + " = " + str( - roll + int(temp_preParsedMessage[1])) - else: - diceRoll = str(roll) - diceRoll = user + " fate rolled: " + diceRoll - - return diceRoll - - def get_help(self): - return self.help \ No newline at end of file diff --git a/channel_points/loader.py b/channel_points/loader.py deleted file mode 100644 index a92b544..0000000 --- a/channel_points/loader.py +++ /dev/null @@ -1,79 +0,0 @@ -import importlib -import importlib.util -import inspect -import os -import sys -from typing import Dict - -from commands.command_base import AbstractCommand - - -#New -def load_commands(commandType: AbstractCommand.CommandType) -> Dict[str, AbstractCommand]: - print(" -Loading ", commandType ," Commands...\n") - commands = compile_and_load(commandType) - return commands - -#New -def compile_and_load_file(path: str, commandType: AbstractCommand.CommandType): - 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() - if commandType == command_inst.get_commandType(): - print(" ---Successfully loaded %s: %s" % (commandType, command_inst.get_command())) - return command_inst.get_command(), command_inst - elif commandType != command_inst.get_commandType(): - print(" -%s CommandType did not match: %s for: %s" % (command_inst.get_commandType(), commandType, command_inst.get_command())) - return "", None - - -#New -def compile_and_load(commandType: AbstractCommand.CommandType) -> Dict[str, AbstractCommand]: - dic = {} - 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, commandType) - if command is not None and command.command_type is commandType: - dic[name] = command - break - return dic - -def get_base_dir() -> str: - cwd = os.getcwd() - split = os.path.split(cwd) - current = split[len(split) - 1] - if current == 'commands': - return check_dir(cwd) - elif current == 'Praxis_Bot' or current == 'Praxis': - return check_dir(os.path.join(cwd, "commands")) - else: - print("could not find working directory for Praxis_Bot/commands") - raise Exception - - -def get_implementations_dir() -> str: - return check_dir(os.path.join(get_base_dir(), "implemented")) - - -def get_compiled_dir() -> str: - return check_dir(os.path.join(get_base_dir(), "compiled")) - - -def check_dir(path: str) -> str: - if not os.path.exists(path): - os.mkdir(path, 0x777) - return path - - -if __name__ == "__main__": - cmds = load_commands() - -- 2.45.2 From 2c7a2b3ef0027c5adc46d0fadfa8f09d2b8e5a5a Mon Sep 17 00:00:00 2001 From: Alex Orid Date: Mon, 26 Apr 2021 13:03:27 -0400 Subject: [PATCH 05/13] Update standalone_twitch_pubsub.py --- standalone_twitch_pubsub.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/standalone_twitch_pubsub.py b/standalone_twitch_pubsub.py index 0b18474..1497fab 100644 --- a/standalone_twitch_pubsub.py +++ b/standalone_twitch_pubsub.py @@ -69,6 +69,16 @@ class Twitch_Pubsub(): print('got callback for UUID ' + str(uuid)) pprint(data) + def callback_bits(self, uuid: UUID, data: dict) -> None: + print("Bits Redemption") + print('got callback for UUID ' + str(uuid)) + pprint(data) + + def callback_subs(self, uuid: UUID, data: dict) -> None: + print("Subs Redemption") + print('got callback for UUID ' + str(uuid)) + pprint(data) + if __name__ == "__main__": testModule = Twitch_Pubsub() -- 2.45.2 From 65a723b5dfa8783e7551f9190961f95c96f5b54a Mon Sep 17 00:00:00 2001 From: Alex Orid Date: Mon, 26 Apr 2021 14:47:15 -0400 Subject: [PATCH 06/13] renaming and fixing parameters --- ...ts => Dockerfile_standalone_channelRewards | 2 +- .../ChannelPointReward_Hydration_v2.py | 24 ------ channel_points/implemented/Command_test_v2.py | 25 ------ .../channelRewards_base.py | 32 ++++---- .../channelRewards_loader.py | 32 ++++---- .../implemented/ChannelReward_Hydration.py | 22 ++++++ commands/command_base.py | 2 +- docker-compose.yaml | 4 +- makedockerimages.bat | 2 +- standalone_channelpoints.py | 78 ------------------- standalone_channelrewards.py | 78 +++++++++++++++++++ 11 files changed, 138 insertions(+), 163 deletions(-) rename Dockerfile_standalone_channelPoints => Dockerfile_standalone_channelRewards (83%) delete mode 100644 channel_points/implemented/ChannelPointReward_Hydration_v2.py delete mode 100644 channel_points/implemented/Command_test_v2.py rename channel_points/channelPoints_base.py => channel_rewards/channelRewards_base.py (51%) rename channel_points/channelPoints_loader.py => channel_rewards/channelRewards_loader.py (53%) create mode 100644 channel_rewards/implemented/ChannelReward_Hydration.py delete mode 100644 standalone_channelpoints.py create mode 100644 standalone_channelrewards.py diff --git a/Dockerfile_standalone_channelPoints b/Dockerfile_standalone_channelRewards similarity index 83% rename from Dockerfile_standalone_channelPoints rename to Dockerfile_standalone_channelRewards index 5c4e21d..b5d541e 100644 --- a/Dockerfile_standalone_channelPoints +++ b/Dockerfile_standalone_channelRewards @@ -8,4 +8,4 @@ RUN pip3 install -r requirements_sa_command.txt COPY . . -CMD [ "python3", "standalone_channelpoints.py"] \ No newline at end of file +CMD [ "python3", "standalone_channelrewards.py"] \ No newline at end of file diff --git a/channel_points/implemented/ChannelPointReward_Hydration_v2.py b/channel_points/implemented/ChannelPointReward_Hydration_v2.py deleted file mode 100644 index a63520f..0000000 --- a/channel_points/implemented/ChannelPointReward_Hydration_v2.py +++ /dev/null @@ -1,24 +0,0 @@ -from abc import ABCMeta - -from channel_points.channelPoints_base import AbstractChannelPoints - -import utilities_script as utility - -class ChannelPointReward_Hydration_v2(AbstractChannelPoints, metaclass=ABCMeta): - """ - this is the hydration reward. - """ - ChannelPointRewardName = "hydration" - - def __init__(self): - super().__init__(ChannelPointReward_Hydration_v2.ChannelPointRewardName, n_args=1, command_type=AbstractChannelPoints.ChannelPointsType.Ver2) - self.help = ["This is a hydration channel point reward."] - self.isChannelPointRewardEnabled = True - - def do_ChannelPointReward(self, source = AbstractChannelPoints.ChannelPointsSource.default, user = "User", command = "", rest = "", bonusData = None): - returnString = user + " sent: [ " + command + " ] with: " + rest - #print(returnString) - return returnString - - def get_help(self): - return self.help \ No newline at end of file diff --git a/channel_points/implemented/Command_test_v2.py b/channel_points/implemented/Command_test_v2.py deleted file mode 100644 index 18995d3..0000000 --- a/channel_points/implemented/Command_test_v2.py +++ /dev/null @@ -1,25 +0,0 @@ -from abc import ABCMeta - -from commands.command_base import AbstractCommand - -import utilities_script as utility - -class Command_test_v2(AbstractCommand, metaclass=ABCMeta): - """ - this is the test command. - """ - command = "testerino" - - def __init__(self): - super().__init__(Command_test_v2.command, n_args=1, command_type=AbstractCommand.CommandType.Ver2) - self.help = ["This is a test command.", - "\nExample:","testerino"] - self.isCommandEnabled = True - - def do_command(self, source = AbstractCommand.CommandSource.default, user = "User", command = "", rest = "", bonusData = None): - returnString = user + " sent: [ " + command + " ] with: " + rest - #print(returnString) - return returnString - - def get_help(self): - return self.help \ No newline at end of file diff --git a/channel_points/channelPoints_base.py b/channel_rewards/channelRewards_base.py similarity index 51% rename from channel_points/channelPoints_base.py rename to channel_rewards/channelRewards_base.py index 71ecba6..98c9504 100644 --- a/channel_points/channelPoints_base.py +++ b/channel_rewards/channelRewards_base.py @@ -2,7 +2,7 @@ from abc import ABCMeta, abstractmethod from enum import Enum, auto -class AbstractChannelPoints(metaclass=ABCMeta): +class AbstractChannelRewards(metaclass=ABCMeta): """ This is the base class for channel points. In order to load a channel point redemption a few conditions must be met: 1) The class name MUST begin with 'ChannelPoint' i.e. CommandTTS, CommandBan, etc... @@ -12,43 +12,45 @@ class AbstractChannelPoints(metaclass=ABCMeta): class and to then call super().__init__(command) """ - class ChannelPointsType(Enum): + class ChannelRewardsType(Enum): NONE = auto() - Ver2 = auto() + channelPoints = auto() + twitch_bits = auto() + twitch_subs = auto() - class ChannelPointsSource(Enum): + class ChannelRewardsSource(Enum): default = 0 Praxis = 1 Twitch = 2 Discord = 3 - def __init__(self, ChannelPointRewardName: str, n_args: int = 0, channelPointReward_type=ChannelPointsType.NONE, helpText:list=["No Help"], isChannelPointRewardEnabled = True): - self.ChannelPointRewardName = ChannelPointRewardName + def __init__(self, ChannelRewardName: str, n_args: int = 0, ChannelReward_type=ChannelRewardsType.NONE, helpText:list=["No Help"], isChannelRewardEnabled = True): + self.ChannelRewardName = ChannelRewardName self.n_args = n_args - self.ChannelPointRewardType = channelPointReward_type + self.ChannelRewardType = ChannelReward_type self.help = helpText - self.isChannelPointRewardEnabled = isChannelPointRewardEnabled + self.isChannelRewardEnabled = isChannelRewardEnabled # no touch! def get_args(self, text: str) -> list: return text.split(" ")[0:self.n_args + 1] # no touch! - def get_ChannelPointRewardName(self) -> str: - return self.ChannelPointRewardName + def get_ChannelRewardName(self) -> str: + return self.ChannelRewardName # no touch! - def get_ChannelPointRewardType(self): - return self.ChannelPointRewardType + def get_ChannelRewardType(self): + return self.ChannelRewardType # no touch! def get_help(self): return self.help # no touch! - def is_ChannelPointReward_enabled(self): - return self.isChannelPointRewardEnabled + def is_ChannelReward_enabled(self): + return self.isChannelRewardEnabled @abstractmethod - def do_ChannelPointReward(self, bot, user, command, rest, bonusData): + def do_ChannelReward(self, source, user, command, rest, bonusData): pass \ No newline at end of file diff --git a/channel_points/channelPoints_loader.py b/channel_rewards/channelRewards_loader.py similarity index 53% rename from channel_points/channelPoints_loader.py rename to channel_rewards/channelRewards_loader.py index 9bd4ef9..3b8b79d 100644 --- a/channel_points/channelPoints_loader.py +++ b/channel_rewards/channelRewards_loader.py @@ -5,17 +5,17 @@ import os import sys from typing import Dict -from channel_points.channelPoints_base import AbstractChannelPoints +from channel_rewards.channelRewards_base import AbstractChannelRewards #New -def load_rewards(channelPointsType: AbstractChannelPoints.ChannelPointsType) -> Dict[str, AbstractChannelPoints]: - print(" -Loading ", channelPointsType ," ChannelPointRewards...\n") - channelPointRewards = compile_and_load(channelPointsType) - return channelPointRewards +def load_rewards(channelRewardsType: AbstractChannelRewards.ChannelRewardsType) -> Dict[str, AbstractChannelRewards]: + print(" -Loading ", channelRewardsType ," ChannelRewards...\n") + ChannelRewards = compile_and_load(channelRewardsType) + return ChannelRewards #New -def compile_and_load_file(path: str, channelPointsType: AbstractChannelPoints.ChannelPointsType): +def compile_and_load_file(path: str, channelRewardsType: AbstractChannelRewards.ChannelRewardsType): 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) @@ -23,26 +23,26 @@ def compile_and_load_file(path: str, channelPointsType: AbstractChannelPoints.Ch spec.loader.load_module(module_name) for name, obj in inspect.getmembers(module): - if inspect.isclass(obj) and name.startswith("ChannelPointReward"): - channelPointReward_inst = obj() - if channelPointsType == channelPointReward_inst.get_ChannelPointRewardType(): - print(" ---Successfully loaded %s: %s" % (channelPointsType, channelPointReward_inst.get_ChannelPointRewardType())) - return channelPointReward_inst.get_ChannelPointRewardType(), channelPointReward_inst - elif channelPointsType != channelPointReward_inst.get_ChannelPointRewardType(): - print(" -%s ChannelPointsType did not match: %s for: %s" % (channelPointReward_inst.get_ChannelPointRewardType(), channelPointsType, channelPointReward_inst.get_ChannelPointRewardName())) + if inspect.isclass(obj) and name.startswith("ChannelReward"): + ChannelReward_inst = obj() + if channelRewardsType == ChannelReward_inst.get_ChannelRewardType(): + print(" ---Successfully loaded %s: %s" % (channelRewardsType, ChannelReward_inst.get_ChannelRewardType())) + return ChannelReward_inst.get_ChannelRewardType(), ChannelReward_inst + elif channelRewardsType != ChannelReward_inst.get_ChannelRewardType(): + print(" -%s ChannelRewardsType did not match: %s for: %s" % (ChannelReward_inst.get_ChannelRewardType(), channelRewardsType, ChannelReward_inst.get_ChannelRewardName())) return "", None #New -def compile_and_load(ChannelPointsRewardType: AbstractChannelPoints.ChannelPointsType) -> Dict[str, AbstractChannelPoints]: +def compile_and_load(ChannelRewardType: AbstractChannelRewards.ChannelRewardsType) -> Dict[str, AbstractChannelRewards]: dic = {} 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, reward = compile_and_load_file(name, ChannelPointsRewardType) - if reward is not None and reward.ChannelPointRewardType is ChannelPointsRewardType: + name, reward = compile_and_load_file(name, ChannelRewardType) + if reward is not None and reward.ChannelRewardType is ChannelRewardType: dic[name] = reward break return dic diff --git a/channel_rewards/implemented/ChannelReward_Hydration.py b/channel_rewards/implemented/ChannelReward_Hydration.py new file mode 100644 index 0000000..64c9ae9 --- /dev/null +++ b/channel_rewards/implemented/ChannelReward_Hydration.py @@ -0,0 +1,22 @@ +from abc import ABCMeta + +from channel_rewards.channelRewards_base import AbstractChannelRewards + +class ChannelReward_Hydration_v2(AbstractChannelRewards, metaclass=ABCMeta): + """ + this is the hydration reward. + """ + ChannelRewardName = "hydration" + + def __init__(self): + super().__init__(ChannelReward_Hydration_v2.ChannelRewardName, n_args=1, command_type=AbstractChannelRewards.ChannelRewardsType.channelPoints) + self.help = ["This is a hydration channel point reward."] + self.isChannelRewardEnabled = True + + def do_ChannelReward(self, source = AbstractChannelRewards.ChannelRewardsSource.default, user = "User", command = "", rest = "", bonusData = None): + returnString = user + " sent: [ " + command + " ] with: " + rest + #print(returnString) + return returnString + + def get_help(self): + return self.help \ No newline at end of file diff --git a/commands/command_base.py b/commands/command_base.py index b3afc97..f73a801 100644 --- a/commands/command_base.py +++ b/commands/command_base.py @@ -53,5 +53,5 @@ class AbstractCommand(metaclass=ABCMeta): return self.isCommandEnabled @abstractmethod - def do_command(self, bot, user, command, rest, bonusData): + def do_command(self, source, user, command, rest, bonusData): pass \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index d378b8b..fbf0e1b 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -6,8 +6,8 @@ services: - 6009:6009 environment: - ISDOCKER=cat - standalone_channelpoints: - image: standalone_channelpoints + standalone_channelrewards: + image: standalone_channelrewards ports: - 6969:6969 environment: diff --git a/makedockerimages.bat b/makedockerimages.bat index 8e66509..f008b0e 100644 --- a/makedockerimages.bat +++ b/makedockerimages.bat @@ -1,5 +1,5 @@ docker build --file Dockerfile_standalone_command --tag standalone_command . -docker build --file Dockerfile_standalone_channelpoints --tag standalone_channelpoints . +docker build --file Dockerfile_standalone_channelRewards --tag standalone_channelrewards . docker build --file Dockerfile_standalone_DiscordScript --tag standalone_discordscript . docker build --file Dockerfile_standalone_TwitchScript --tag standalone_twitchscript . docker build --file Dockerfile_standalone_Twitch_Pubsub --tag standalone_twitch_pubsub . \ No newline at end of file diff --git a/standalone_channelpoints.py b/standalone_channelpoints.py deleted file mode 100644 index 8dc8a5b..0000000 --- a/standalone_channelpoints.py +++ /dev/null @@ -1,78 +0,0 @@ -import flask -from flask import request - -import commands.loader as command_loader -from commands.command_base import AbstractCommand - -api = flask.Flask(__name__) -# enable/disable this to get web pages of crashes returned -api.config["DEBUG"] = True - -loadedCommands = {} - -def init(): - # todo load entire command library and cache it here - load_commands() - - -def load_commands(): - global loadedCommands - loadedCommands = command_loader.load_commands(AbstractCommand.CommandType.Ver2) - - -def is_command(command: str) -> bool: - #print(command) - for cmd in loadedCommands: - #print(cmd) - if command == cmd: - return True - - if command == "!echo": - return True - else: - return False - -def handle_command(source, username, command, rest, bonusData): - if command == "!echo": - message = "Got payload [%s]" % rest - #print(message) - return flask.make_response("{\"message\":\"%s\"}" % message, 200, {"Content-Type": "application/json"}) - - cmd:AbstractCommand = loadedCommands[command] - if cmd is not None: - cmd_response = cmd.do_command(source, username, command, rest, bonusData) - return flask.make_response("{\"message\":\"%s\"}" % cmd_response, 200, {"Content-Type": "application/json"}) - - #print("Doing a command") - - -@api.route('/api/v1/command', methods=['GET']) -def command_check(): - if 'name' in request.args: - if is_command(request.args['name']): - return flask.make_response('', 200) - else: - return flask.make_response('', 404) - - -@api.route('/api/v1/exec', methods=['GET']) -def exec_command(): - if 'command_name' not in request.args: - return flask.make_response('{\"text\":"Argument \'command_name\' not in request"}', 400) - if 'rest' not in request.args: - return flask.make_response('{\"text\":"Argument \'rest\' not in request"}', 400) - - if 'command_source' not in request.args: - return flask.make_response('{\"text\":"Argument \'command_source\' not in request"}', 400) - - if 'user_name' not in request.args: - username = "User" - else: - username = request.args['user_name'] - - return handle_command(request.args['command_source'], username, request.args['command_name'], request.args['rest'], request.args['bonus_data']) - - -if __name__ == '__main__': - init() - api.run(host='0.0.0.0', port=6969) diff --git a/standalone_channelrewards.py b/standalone_channelrewards.py new file mode 100644 index 0000000..a883178 --- /dev/null +++ b/standalone_channelrewards.py @@ -0,0 +1,78 @@ +import flask +from flask import request + +import channel_rewards.channelRewards_loader as rewards_loader +from channel_rewards.channelRewards_base import AbstractChannelRewards + +api = flask.Flask(__name__) +# enable/disable this to get web pages of crashes returned +api.config["DEBUG"] = True + +loadedRewards = {} + +def init(): + # todo load entire reward library and cache it here + load_rewards() + + +def load_rewards(): + global loadedRewards + loadedRewards[AbstractChannelRewards.ChannelRewardsType.channelPoints] = rewards_loader.load_rewards(AbstractChannelRewards.ChannelRewardsType.channelPoints) + loadedRewards[AbstractChannelRewards.ChannelRewardsType.twitch_bits] = rewards_loader.load_rewards(AbstractChannelRewards.ChannelRewardsType.twitch_bits) + loadedRewards[AbstractChannelRewards.ChannelRewardsType.twitch_subs] = rewards_loader.load_rewards(AbstractChannelRewards.ChannelRewardsType.twitch_subs) + + +def is_reward(reward_name: str, reward_type: str) -> bool: + #print(reward) + for reward in loadedRewards[reward_type]: + #print(reward) + if reward_name == reward: + return True + + if reward_name == "!echo": + return True + else: + return False + +def handle_reward(source, username, reward_name, reward_type, rest, bonusData): + #reward:AbstractChannelRewards = loadedRewards[reward_name] + reward:AbstractChannelRewards = loadedRewards[reward_type][reward_name] + if reward is not None: + reward_response = reward.do_ChannelReward(source, username, reward_name, rest, bonusData) + return flask.make_response("{\"message\":\"%s\"}" % reward_response, 200, {"Content-Type": "application/json"}) + + #print("Doing a reward") + + +@api.route('/api/v1/reward', methods=['GET']) +def reward_check(): + if 'reward_name' in request.args and 'reward_type' in request.args: + if is_reward(request.args['reward_name'], request.args['reward_type']): + return flask.make_response('', 200) + else: + return flask.make_response('', 404) + + +@api.route('/api/v1/exec', methods=['GET']) +def exec_reward(): + if 'reward_name' not in request.args: + return flask.make_response('{\"text\":"Argument \'reward_name\' not in request"}', 400) + if 'reward_type' not in request.args: + return flask.make_response('{\"text\":"Argument \'reward_name\' not in request"}', 400) + if 'rest' not in request.args: + return flask.make_response('{\"text\":"Argument \'rest\' not in request"}', 400) + + if 'reward_source' not in request.args: + return flask.make_response('{\"text\":"Argument \'reward_source\' not in request"}', 400) + + if 'user_name' not in request.args: + username = "User" + else: + username = request.args['user_name'] + + return handle_reward(request.args['reward_source'], username, request.args['reward_name'], request.args['reward_type'], request.args['rest'], request.args['bonus_data']) + + +if __name__ == '__main__': + init() + api.run(host='0.0.0.0', port=6969) -- 2.45.2 From d682baa8645c341698b7aca675eeea85502705c6 Mon Sep 17 00:00:00 2001 From: Alex Orid Date: Mon, 26 Apr 2021 14:49:28 -0400 Subject: [PATCH 07/13] changed api --- standalone_command.py | 2 +- standalone_twitch_script.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/standalone_command.py b/standalone_command.py index 3c77bcc..def50cb 100644 --- a/standalone_command.py +++ b/standalone_command.py @@ -55,7 +55,7 @@ def command_check(): return flask.make_response('', 404) -@api.route('/api/v1/exec', methods=['GET']) +@api.route('/api/v1/exec_command', methods=['GET']) def exec_command(): if 'command_name' not in request.args: return flask.make_response('{\"text\":"Argument \'command_name\' not in request"}', 400) diff --git a/standalone_twitch_script.py b/standalone_twitch_script.py index a9b8552..bb0f82d 100644 --- a/standalone_twitch_script.py +++ b/standalone_twitch_script.py @@ -76,7 +76,7 @@ class Twitch_Module(): def exec_command(self, realMessage: twitch.chat.Message, command: str, rest: str): # todo need to url-escape command and rest params = urlencode({'command_source': commands.command_base.AbstractCommand.CommandSource.Twitch,'user_name': realMessage.sender, 'command_name': command, 'rest': rest, 'bonus_data': realMessage}) - url = "http://standalone_command:6009/api/v1/exec?%s" % params + url = "http://standalone_command:6009/api/v1/exec_command?%s" % params resp = requests.get(url) if resp.status_code == 200: print("Got the following message: %s" % resp.text) -- 2.45.2 From e857ea390afbfeb482546c449b69b9aea8ef86c7 Mon Sep 17 00:00:00 2001 From: Alex Orid Date: Mon, 26 Apr 2021 14:49:56 -0400 Subject: [PATCH 08/13] api typo --- standalone_channelrewards.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standalone_channelrewards.py b/standalone_channelrewards.py index a883178..29ef68c 100644 --- a/standalone_channelrewards.py +++ b/standalone_channelrewards.py @@ -53,7 +53,7 @@ def reward_check(): return flask.make_response('', 404) -@api.route('/api/v1/exec', methods=['GET']) +@api.route('/api/v1/exec_reward', methods=['GET']) def exec_reward(): if 'reward_name' not in request.args: return flask.make_response('{\"text\":"Argument \'reward_name\' not in request"}', 400) -- 2.45.2 From df8805e5eeca37b68543587c9c56a5f4c45fed6b Mon Sep 17 00:00:00 2001 From: Alex Orid Date: Mon, 26 Apr 2021 15:31:22 -0400 Subject: [PATCH 09/13] api stuff --- standalone_twitch_pubsub.py | 57 ++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/standalone_twitch_pubsub.py b/standalone_twitch_pubsub.py index 1497fab..a3ff5bb 100644 --- a/standalone_twitch_pubsub.py +++ b/standalone_twitch_pubsub.py @@ -1,7 +1,14 @@ -import credentials +import re +from json import loads +from urllib.parse import urlencode +import requests + +import credentials import config +import channel_rewards.channelRewards_base + import twitchAPI from twitchAPI.pubsub import PubSub from twitchAPI.twitch import Twitch @@ -10,6 +17,7 @@ from twitchAPI.oauth import UserAuthenticator from pprint import pprint from uuid import UUID +from cooldowns import Cooldown_Module class Twitch_Pubsub(): def __init__(self): @@ -22,6 +30,9 @@ class Twitch_Pubsub(): self.uuid_1 = None self.uuid_2 = None + self.cooldownModule: Cooldown_Module = Cooldown_Module() + self.cooldownModule.setupCooldown("twitchChat", 20, 32) + def setup(self): self.twitch.authenticate_app(self.target_scope) @@ -68,6 +79,11 @@ class Twitch_Pubsub(): print("Channel Point Redemption") print('got callback for UUID ' + str(uuid)) pprint(data) + #self.callback_EXEC( + # "sender", + # "rewardName", + # channel_rewards.channelRewards_base.AbstractChannelRewards.ChannelRewardsType.channelPoints, + # data) def callback_bits(self, uuid: UUID, data: dict) -> None: print("Bits Redemption") @@ -79,6 +95,45 @@ class Twitch_Pubsub(): print('got callback for UUID ' + str(uuid)) pprint(data) + + def callback_EXEC(self, sender, rewardName:str, rewardType, raw_data): + try: + is_actionable = self.is_reward(rewardName, rewardType) + if is_actionable: + if self.cooldownModule.isCooldownActive("twitchChat") == False: + self.exec_reward(sender, rewardName, rewardType, "", raw_data) + except: + print("something went wrong with a reward") + + def is_reward(self, rewardName:str, rewardType): + # todo need to url-escape word + clean_param = urlencode({'reward_name': rewardName, 'reward_type':rewardType}) + url = "http://channelrewards:6969/api/v1/reward?%s" % clean_param + resp = requests.get(url) + return resp.status_code == 200 + + def exec_reward(self, sender, reward, rewardType, rest, realMessage): + params = urlencode( + {'command_source': channel_rewards.channelRewards_base.AbstractChannelRewards.ChannelRewardsSource.Twitch, + 'user_name': sender, + 'reward_name': reward, + 'reward_type': rewardType, + 'rest': rest, + 'bonus_data': realMessage}) + + url = "http://channelrewards:6969/api/v1/exec_reward?%s" % params + resp = requests.get(url) + if resp.status_code == 200: + print("Got the following message: %s" % resp.text) + data = loads(resp.text) + msg = data['message'] + if msg is not None: + #self.send_message(msg) #Cant Send messages with this pubsub library afaik + pass + else: + # todo handle failed requests + pass + if __name__ == "__main__": testModule = Twitch_Pubsub() -- 2.45.2 From a29f71e268ee668c0e3c17ea378513ef7cbf041e Mon Sep 17 00:00:00 2001 From: Alex Orid Date: Mon, 26 Apr 2021 17:23:47 -0400 Subject: [PATCH 10/13] fixed type error --- .../implemented/ChannelReward_Hydration.py | 12 ++--- standalone_channelrewards.py | 16 ++++--- standalone_twitch_pubsub.py | 45 ++++++++++++------- 3 files changed, 47 insertions(+), 26 deletions(-) diff --git a/channel_rewards/implemented/ChannelReward_Hydration.py b/channel_rewards/implemented/ChannelReward_Hydration.py index 64c9ae9..9b06e84 100644 --- a/channel_rewards/implemented/ChannelReward_Hydration.py +++ b/channel_rewards/implemented/ChannelReward_Hydration.py @@ -6,16 +6,18 @@ class ChannelReward_Hydration_v2(AbstractChannelRewards, metaclass=ABCMeta): """ this is the hydration reward. """ - ChannelRewardName = "hydration" + ChannelRewardName = "Hydrate" def __init__(self): - super().__init__(ChannelReward_Hydration_v2.ChannelRewardName, n_args=1, command_type=AbstractChannelRewards.ChannelRewardsType.channelPoints) + super().__init__(ChannelReward_Hydration_v2.ChannelRewardName, n_args=1, ChannelRewardType=AbstractChannelRewards.ChannelRewardsType.channelPoints) self.help = ["This is a hydration channel point reward."] self.isChannelRewardEnabled = True - def do_ChannelReward(self, source = AbstractChannelRewards.ChannelRewardsSource.default, user = "User", command = "", rest = "", bonusData = None): - returnString = user + " sent: [ " + command + " ] with: " + rest - #print(returnString) + def do_ChannelReward(self, source = AbstractChannelRewards.ChannelRewardsSource.default, user = "User", rewardName = "", rest = "", bonusData = None): + returnString = user + " sent: [ " + rewardName + " ] with: " + rest + print(returnString) + for x in range(10): + print("This is wet") return returnString def get_help(self): diff --git a/standalone_channelrewards.py b/standalone_channelrewards.py index 29ef68c..5f142f5 100644 --- a/standalone_channelrewards.py +++ b/standalone_channelrewards.py @@ -22,18 +22,22 @@ def load_rewards(): loadedRewards[AbstractChannelRewards.ChannelRewardsType.twitch_subs] = rewards_loader.load_rewards(AbstractChannelRewards.ChannelRewardsType.twitch_subs) -def is_reward(reward_name: str, reward_type: str) -> bool: - #print(reward) - for reward in loadedRewards[reward_type]: - #print(reward) - if reward_name == reward: - return True +def is_reward(reward_name, reward_type) -> bool: + tempType = reward_type.replace('ChannelRewardsType.', '') + realTempType = AbstractChannelRewards.ChannelRewardsType.__dict__[tempType] + + rewardList = loadedRewards[realTempType] + print("testing mcgoo") + for reward in rewardList: + print(reward) + print("testing oogcm") if reward_name == "!echo": return True else: return False + def handle_reward(source, username, reward_name, reward_type, rest, bonusData): #reward:AbstractChannelRewards = loadedRewards[reward_name] reward:AbstractChannelRewards = loadedRewards[reward_type][reward_name] diff --git a/standalone_twitch_pubsub.py b/standalone_twitch_pubsub.py index a3ff5bb..8535e74 100644 --- a/standalone_twitch_pubsub.py +++ b/standalone_twitch_pubsub.py @@ -7,6 +7,7 @@ import requests import credentials import config +from channel_rewards.channelRewards_base import AbstractChannelRewards import channel_rewards.channelRewards_base import twitchAPI @@ -79,11 +80,22 @@ class Twitch_Pubsub(): print("Channel Point Redemption") print('got callback for UUID ' + str(uuid)) pprint(data) - #self.callback_EXEC( - # "sender", - # "rewardName", - # channel_rewards.channelRewards_base.AbstractChannelRewards.ChannelRewardsType.channelPoints, - # data) + #print("attempting to get data: ") + #print(data['data']['redemption']['user']['display_name']) + #print(data['data']['redemption']['reward']['title']) + #print(data['data']['redemption']['reward']['prompt']) + try: + userinput = data['data']['redemption']['user_input'] + except: + userinput = "" + #print(userinput) + self.callback_EXEC( + data['data']['redemption']['user']['display_name'], + data['data']['redemption']['reward']['title'], + AbstractChannelRewards.ChannelRewardsType.channelPoints, + data['data']['redemption']['reward']['prompt'], + userinput, + data) def callback_bits(self, uuid: UUID, data: dict) -> None: print("Bits Redemption") @@ -95,33 +107,36 @@ class Twitch_Pubsub(): print('got callback for UUID ' + str(uuid)) pprint(data) - - def callback_EXEC(self, sender, rewardName:str, rewardType, raw_data): + def callback_EXEC(self, sender, rewardName:str, rewardType, rewardPrompt, userInput, raw_data): try: is_actionable = self.is_reward(rewardName, rewardType) if is_actionable: if self.cooldownModule.isCooldownActive("twitchChat") == False: - self.exec_reward(sender, rewardName, rewardType, "", raw_data) + self.exec_reward(sender, rewardName, rewardType, rewardPrompt, userInput, raw_data) except: print("something went wrong with a reward") - def is_reward(self, rewardName:str, rewardType): + def is_reward(self, rewardName, rewardType): # todo need to url-escape word clean_param = urlencode({'reward_name': rewardName, 'reward_type':rewardType}) - url = "http://channelrewards:6969/api/v1/reward?%s" % clean_param + print(rewardName, rewardType) + #standalone_channelrewards + url = "http://localhost:6969/api/v1/reward?%s" % clean_param resp = requests.get(url) return resp.status_code == 200 - def exec_reward(self, sender, reward, rewardType, rest, realMessage): + def exec_reward(self, sender, rewardName, rewardType, rewardPrompt, userInput, realMessage): params = urlencode( - {'command_source': channel_rewards.channelRewards_base.AbstractChannelRewards.ChannelRewardsSource.Twitch, + {'reward_source': channel_rewards.channelRewards_base.AbstractChannelRewards.ChannelRewardsSource.Twitch, 'user_name': sender, - 'reward_name': reward, + 'reward_name': rewardName, 'reward_type': rewardType, - 'rest': rest, + 'reward_prompt': rewardPrompt, + 'user_input' : userInput, 'bonus_data': realMessage}) - url = "http://channelrewards:6969/api/v1/exec_reward?%s" % params + #standalone_channelrewards + url = "http://localhost:6969/api/v1/exec_reward?%s" % params resp = requests.get(url) if resp.status_code == 200: print("Got the following message: %s" % resp.text) -- 2.45.2 From 7e591e3791f955f3350fe5ecc459fca370b0fafa Mon Sep 17 00:00:00 2001 From: Alex Orid Date: Mon, 26 Apr 2021 18:43:54 -0400 Subject: [PATCH 11/13] is reward real --- channel_rewards/channelRewards_base.py | 4 ++-- channel_rewards/channelRewards_loader.py | 10 +++++----- standalone_channelrewards.py | 20 ++++++++++---------- standalone_twitch_pubsub.py | 1 + 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/channel_rewards/channelRewards_base.py b/channel_rewards/channelRewards_base.py index 98c9504..8eceeae 100644 --- a/channel_rewards/channelRewards_base.py +++ b/channel_rewards/channelRewards_base.py @@ -24,10 +24,10 @@ class AbstractChannelRewards(metaclass=ABCMeta): Twitch = 2 Discord = 3 - def __init__(self, ChannelRewardName: str, n_args: int = 0, ChannelReward_type=ChannelRewardsType.NONE, helpText:list=["No Help"], isChannelRewardEnabled = True): + def __init__(self, ChannelRewardName: str, n_args: int = 0, ChannelRewardType=ChannelRewardsType.NONE, helpText:list=["No Help"], isChannelRewardEnabled = True): self.ChannelRewardName = ChannelRewardName self.n_args = n_args - self.ChannelRewardType = ChannelReward_type + self.ChannelRewardType = ChannelRewardType self.help = helpText self.isChannelRewardEnabled = isChannelRewardEnabled diff --git a/channel_rewards/channelRewards_loader.py b/channel_rewards/channelRewards_loader.py index 3b8b79d..8a2db6e 100644 --- a/channel_rewards/channelRewards_loader.py +++ b/channel_rewards/channelRewards_loader.py @@ -26,8 +26,8 @@ def compile_and_load_file(path: str, channelRewardsType: AbstractChannelRewards. if inspect.isclass(obj) and name.startswith("ChannelReward"): ChannelReward_inst = obj() if channelRewardsType == ChannelReward_inst.get_ChannelRewardType(): - print(" ---Successfully loaded %s: %s" % (channelRewardsType, ChannelReward_inst.get_ChannelRewardType())) - return ChannelReward_inst.get_ChannelRewardType(), ChannelReward_inst + print(" ---Successfully loaded %s: %s" % (channelRewardsType, ChannelReward_inst.get_ChannelRewardName())) + return ChannelReward_inst.get_ChannelRewardName(), ChannelReward_inst elif channelRewardsType != ChannelReward_inst.get_ChannelRewardType(): print(" -%s ChannelRewardsType did not match: %s for: %s" % (ChannelReward_inst.get_ChannelRewardType(), channelRewardsType, ChannelReward_inst.get_ChannelRewardName())) return "", None @@ -51,12 +51,12 @@ def get_base_dir() -> str: cwd = os.getcwd() split = os.path.split(cwd) current = split[len(split) - 1] - if current == 'channel_points': + if current == 'channel_rewards': return check_dir(cwd) elif current == 'Praxis_Bot' or current == 'Praxis': - return check_dir(os.path.join(cwd, "channel_points")) + return check_dir(os.path.join(cwd, "channel_rewards")) else: - print("could not find working directory for Praxis_Bot/channel_points") + print("could not find working directory for Praxis_Bot/channel_rewards") raise Exception diff --git a/standalone_channelrewards.py b/standalone_channelrewards.py index 5f142f5..9dea20a 100644 --- a/standalone_channelrewards.py +++ b/standalone_channelrewards.py @@ -12,25 +12,23 @@ loadedRewards = {} def init(): # todo load entire reward library and cache it here - load_rewards() - - -def load_rewards(): - global loadedRewards + print("init stuff") loadedRewards[AbstractChannelRewards.ChannelRewardsType.channelPoints] = rewards_loader.load_rewards(AbstractChannelRewards.ChannelRewardsType.channelPoints) loadedRewards[AbstractChannelRewards.ChannelRewardsType.twitch_bits] = rewards_loader.load_rewards(AbstractChannelRewards.ChannelRewardsType.twitch_bits) loadedRewards[AbstractChannelRewards.ChannelRewardsType.twitch_subs] = rewards_loader.load_rewards(AbstractChannelRewards.ChannelRewardsType.twitch_subs) def is_reward(reward_name, reward_type) -> bool: + #global loadedRewards tempType = reward_type.replace('ChannelRewardsType.', '') realTempType = AbstractChannelRewards.ChannelRewardsType.__dict__[tempType] - rewardList = loadedRewards[realTempType] - print("testing mcgoo") - for reward in rewardList: - print(reward) - print("testing oogcm") + for reward in loadedRewards[realTempType]: + print("found: ",reward,"type: ",type(reward)) + if reward_name == reward: + print("Equal") + return True + if reward_name == "!echo": return True @@ -51,7 +49,9 @@ def handle_reward(source, username, reward_name, reward_type, rest, bonusData): @api.route('/api/v1/reward', methods=['GET']) def reward_check(): if 'reward_name' in request.args and 'reward_type' in request.args: + print("reward_name:", request.args['reward_name'],"reward_type:", request.args['reward_type']) if is_reward(request.args['reward_name'], request.args['reward_type']): + print("about to send") return flask.make_response('', 200) else: return flask.make_response('', 404) diff --git a/standalone_twitch_pubsub.py b/standalone_twitch_pubsub.py index 8535e74..5132622 100644 --- a/standalone_twitch_pubsub.py +++ b/standalone_twitch_pubsub.py @@ -111,6 +111,7 @@ class Twitch_Pubsub(): try: is_actionable = self.is_reward(rewardName, rewardType) if is_actionable: + print("Trying to do the thing") if self.cooldownModule.isCooldownActive("twitchChat") == False: self.exec_reward(sender, rewardName, rewardType, rewardPrompt, userInput, raw_data) except: -- 2.45.2 From 41a3362b643bb2ebcde7ae025cc4e62d6d3fbbd3 Mon Sep 17 00:00:00 2001 From: Alex Orid Date: Mon, 26 Apr 2021 18:55:11 -0400 Subject: [PATCH 12/13] working channel point rewards --- channel_rewards/channelRewards_base.py | 2 +- .../implemented/ChannelReward_Hydration.py | 9 +++---- standalone_channelrewards.py | 24 ++++++++++++++----- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/channel_rewards/channelRewards_base.py b/channel_rewards/channelRewards_base.py index 8eceeae..10d6966 100644 --- a/channel_rewards/channelRewards_base.py +++ b/channel_rewards/channelRewards_base.py @@ -52,5 +52,5 @@ class AbstractChannelRewards(metaclass=ABCMeta): return self.isChannelRewardEnabled @abstractmethod - def do_ChannelReward(self, source, user, command, rest, bonusData): + def do_ChannelReward(self, source, user, command, rewardPrompt, userInput, bonusData): pass \ No newline at end of file diff --git a/channel_rewards/implemented/ChannelReward_Hydration.py b/channel_rewards/implemented/ChannelReward_Hydration.py index 9b06e84..e3d94cb 100644 --- a/channel_rewards/implemented/ChannelReward_Hydration.py +++ b/channel_rewards/implemented/ChannelReward_Hydration.py @@ -13,12 +13,9 @@ class ChannelReward_Hydration_v2(AbstractChannelRewards, metaclass=ABCMeta): self.help = ["This is a hydration channel point reward."] self.isChannelRewardEnabled = True - def do_ChannelReward(self, source = AbstractChannelRewards.ChannelRewardsSource.default, user = "User", rewardName = "", rest = "", bonusData = None): - returnString = user + " sent: [ " + rewardName + " ] with: " + rest - print(returnString) - for x in range(10): - print("This is wet") - return returnString + def do_ChannelReward(self, source = AbstractChannelRewards.ChannelRewardsSource.default, user = "User", rewardName = "", rewardPrompt = "", userInput = "", bonusData = None): + + return None def get_help(self): return self.help \ No newline at end of file diff --git a/standalone_channelrewards.py b/standalone_channelrewards.py index 9dea20a..d7f5632 100644 --- a/standalone_channelrewards.py +++ b/standalone_channelrewards.py @@ -36,11 +36,13 @@ def is_reward(reward_name, reward_type) -> bool: return False -def handle_reward(source, username, reward_name, reward_type, rest, bonusData): +def handle_reward(source, username, reward_name, reward_type, rewardPrompt, userInput, bonusData): #reward:AbstractChannelRewards = loadedRewards[reward_name] - reward:AbstractChannelRewards = loadedRewards[reward_type][reward_name] + tempType = reward_type.replace('ChannelRewardsType.', '') + realTempType = AbstractChannelRewards.ChannelRewardsType.__dict__[tempType] + reward:AbstractChannelRewards = loadedRewards[realTempType][reward_name] if reward is not None: - reward_response = reward.do_ChannelReward(source, username, reward_name, rest, bonusData) + reward_response = reward.do_ChannelReward(source, username, reward_name, rewardPrompt, userInput, bonusData) return flask.make_response("{\"message\":\"%s\"}" % reward_response, 200, {"Content-Type": "application/json"}) #print("Doing a reward") @@ -63,8 +65,11 @@ def exec_reward(): return flask.make_response('{\"text\":"Argument \'reward_name\' not in request"}', 400) if 'reward_type' not in request.args: return flask.make_response('{\"text\":"Argument \'reward_name\' not in request"}', 400) - if 'rest' not in request.args: - return flask.make_response('{\"text\":"Argument \'rest\' not in request"}', 400) + if 'reward_prompt' not in request.args: + return flask.make_response('{\"text\":"Argument \'reward_prompt\' not in request"}', 400) + if 'user_input' not in request.args: + return flask.make_response('{\"text\":"Argument \'user_input\' not in request"}', 400) + if 'reward_source' not in request.args: return flask.make_response('{\"text\":"Argument \'reward_source\' not in request"}', 400) @@ -74,7 +79,14 @@ def exec_reward(): else: username = request.args['user_name'] - return handle_reward(request.args['reward_source'], username, request.args['reward_name'], request.args['reward_type'], request.args['rest'], request.args['bonus_data']) + return handle_reward( + request.args['reward_source'], + username, + request.args['reward_name'], + request.args['reward_type'], + request.args['reward_prompt'], + request.args['user_input'], + request.args['bonus_data']) if __name__ == '__main__': -- 2.45.2 From 9c0172b02180f89a748aad548f9c935b3e15f34f Mon Sep 17 00:00:00 2001 From: Alex Orid Date: Mon, 26 Apr 2021 19:49:11 -0400 Subject: [PATCH 13/13] address/api fix --- lights_module.py | 2 +- rebuild_docker_and_run.bat | 8 ++++++++ standalone_discord_script.py | 2 +- standalone_twitch_pubsub.py | 4 ++-- 4 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 rebuild_docker_and_run.bat diff --git a/lights_module.py b/lights_module.py index 9e5fa9d..a3f0308 100644 --- a/lights_module.py +++ b/lights_module.py @@ -197,4 +197,4 @@ if __name__ == "__main__": #testModule.discordCredential = credentials_manager.find_Discord_Credential(config.credentialsNickname) testModule.main() - testModule.raveMode() \ No newline at end of file + #testModule.raveMode() \ No newline at end of file diff --git a/rebuild_docker_and_run.bat b/rebuild_docker_and_run.bat new file mode 100644 index 0000000..e3f449b --- /dev/null +++ b/rebuild_docker_and_run.bat @@ -0,0 +1,8 @@ +cd "c:\praxis" +docker-compose down +docker build --file Dockerfile_standalone_command --tag standalone_command . +docker build --file Dockerfile_standalone_channelRewards --tag standalone_channelrewards . +docker build --file Dockerfile_standalone_DiscordScript --tag standalone_discordscript . +docker build --file Dockerfile_standalone_TwitchScript --tag standalone_twitchscript . +docker build --file Dockerfile_standalone_Twitch_Pubsub --tag standalone_twitch_pubsub . +docker-compose up -d \ No newline at end of file diff --git a/standalone_discord_script.py b/standalone_discord_script.py index 8ece8a7..9f9c59c 100644 --- a/standalone_discord_script.py +++ b/standalone_discord_script.py @@ -94,7 +94,7 @@ class Discord_Module(discord.Client): async def exec_command(self, realMessage: discord.Message, command: str, rest: str): # todo need to url-escape command and rest params = urlencode({'command_source': commands.command_base.AbstractCommand.CommandSource.Discord, 'user_name': realMessage.author.mention, 'command_name': command, 'rest': rest, 'bonus_data': realMessage}) - url = "http://standalone_command:6009/api/v1/exec?%s" % params + url = "http://standalone_command:6009/api/v1/exec_command?%s" % params resp = requests.get(url) if resp.status_code == 200: print("Got the following message: %s" % resp.text) diff --git a/standalone_twitch_pubsub.py b/standalone_twitch_pubsub.py index 5132622..aec0c4c 100644 --- a/standalone_twitch_pubsub.py +++ b/standalone_twitch_pubsub.py @@ -122,7 +122,7 @@ class Twitch_Pubsub(): clean_param = urlencode({'reward_name': rewardName, 'reward_type':rewardType}) print(rewardName, rewardType) #standalone_channelrewards - url = "http://localhost:6969/api/v1/reward?%s" % clean_param + url = "http://standalone_channelrewards:6969/api/v1/reward?%s" % clean_param resp = requests.get(url) return resp.status_code == 200 @@ -137,7 +137,7 @@ class Twitch_Pubsub(): 'bonus_data': realMessage}) #standalone_channelrewards - url = "http://localhost:6969/api/v1/exec_reward?%s" % params + url = "http://standalone_channelrewards:6969/api/v1/exec_reward?%s" % params resp = requests.get(url) if resp.status_code == 200: print("Got the following message: %s" % resp.text) -- 2.45.2