diff --git a/Dockerfile_standalone_command b/Dockerfile_standalone_command index 2d131c3..a35a33b 100644 --- a/Dockerfile_standalone_command +++ b/Dockerfile_standalone_command @@ -8,4 +8,4 @@ RUN pip3 install -r requirements_sa_command.txt COPY . . -CMD [ "python3", "standalone_command.py"] \ No newline at end of file +CMD [ "python3", "standalone_tts_core.py"] \ No newline at end of file diff --git a/Dockerfile_standalone_tts_core b/Dockerfile_standalone_tts_core new file mode 100644 index 0000000..2d131c3 --- /dev/null +++ b/Dockerfile_standalone_tts_core @@ -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_command.py"] \ No newline at end of file diff --git a/channel_rewards/implemented/ChannelReward_Hydration.py b/channel_rewards/implemented/ChannelReward_Hydration.py index 974a0e4..409620d 100644 --- a/channel_rewards/implemented/ChannelReward_Hydration.py +++ b/channel_rewards/implemented/ChannelReward_Hydration.py @@ -6,14 +6,14 @@ from json import loads from urllib.parse import urlencode import requests -class ChannelReward_Hydration_v2(AbstractChannelRewards, metaclass=ABCMeta): +class ChannelReward_Hydration(AbstractChannelRewards, metaclass=ABCMeta): """ this is the hydration reward. """ ChannelRewardName = "Hydrate" def __init__(self): - super().__init__(ChannelReward_Hydration_v2.ChannelRewardName, n_args=1, ChannelRewardType=AbstractChannelRewards.ChannelRewardsType.channelPoints) + super().__init__(ChannelReward_Hydration.ChannelRewardName, n_args=1, ChannelRewardType=AbstractChannelRewards.ChannelRewardsType.channelPoints) self.help = ["This is a hydration channel point reward."] self.isChannelRewardEnabled = True @@ -21,6 +21,7 @@ class ChannelReward_Hydration_v2(AbstractChannelRewards, metaclass=ABCMeta): #print("sending:",user, 16, "!lights hydration") self.dothething(user, 16, "!lights hydration", "") + self.send_TTS(user, rewardPrompt) return None def dothething(self, username, light_group, command, rest): @@ -40,5 +41,21 @@ class ChannelReward_Hydration_v2(AbstractChannelRewards, metaclass=ABCMeta): # todo handle failed requests pass + def send_TTS(self, username, message): + params = urlencode({'tts_sender': username, 'tts_text': message}) + #standalone_tts_core + url = "http://standalone_tts_core:60809/api/v1/tts/send_text?%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: + return msg + # todo send to logger and other relevent services + else: + # todo handle failed requests + pass + def get_help(self): return self.help \ No newline at end of file diff --git a/channel_rewards/implemented/ChannelReward_RubiksCube.py b/channel_rewards/implemented/ChannelReward_RubiksCube.py new file mode 100644 index 0000000..11b397e --- /dev/null +++ b/channel_rewards/implemented/ChannelReward_RubiksCube.py @@ -0,0 +1,44 @@ +from abc import ABCMeta + +from channel_rewards.channelRewards_base import AbstractChannelRewards + +from json import loads +from urllib.parse import urlencode +import requests + +class ChannelReward_RubiksCube(AbstractChannelRewards, metaclass=ABCMeta): + """ + this is the hydration reward. + """ + ChannelRewardName = "Solve a Rubiks Cube" + + def __init__(self): + super().__init__(ChannelReward_RubiksCube.ChannelRewardName, n_args=1, ChannelRewardType=AbstractChannelRewards.ChannelRewardsType.channelPoints) + self.help = ["This is a rubiks cube reward."] + self.isChannelRewardEnabled = True + + def do_ChannelReward(self, source = AbstractChannelRewards.ChannelRewardsSource.default, user = "User", rewardName = "", rewardPrompt = "", userInput = "", bonusData = None): + + #print("sending:",user, 16, "!lights hydration") + self.dothething(user, 16, "!lights rubikscube", "") + return None + + def dothething(self, username, light_group, command, rest): + # todo need to url-escape command and rest + params = urlencode({'user_name': username, 'light_group': light_group, 'command': command, 'rest':rest}) + #standalone_lights + url = "http://standalone_lights:42069/api/v1/exec_lights?%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: + return msg + # todo send to logger and other relevent services + else: + # todo handle failed requests + pass + + def get_help(self): + return self.help \ No newline at end of file diff --git a/chyron_module.py b/chyron_module.py index 1eed58a..d91e0a1 100644 --- a/chyron_module.py +++ b/chyron_module.py @@ -24,7 +24,7 @@ class Chyron_Module(): self.addItem( "Commands", "► Commands: ", - "!animal, !climateclock, !discord, !lights, !page, !roll") + "!animal, !climateclock, !discord, !page, !roll") self.addItem( "Website", "► Want to read about my various projects? visit: ", diff --git a/commands/implemented/Command_lights_v2.py b/commands/implemented/Command_lights_v2.py index d5173f4..1aff57a 100644 --- a/commands/implemented/Command_lights_v2.py +++ b/commands/implemented/Command_lights_v2.py @@ -6,6 +6,13 @@ from json import loads from urllib.parse import urlencode import requests +import config + +import os +import praxis_logging +praxis_logger_obj = praxis_logging.praxis_logger() +praxis_logger_obj.init(os.path.basename(__file__)) +praxis_logger_obj.log("\n -Starting Logs: " + os.path.basename(__file__)) class Command_lights_v2(AbstractCommand, metaclass=ABCMeta): """ @@ -21,9 +28,19 @@ class Command_lights_v2(AbstractCommand, metaclass=ABCMeta): def do_command(self, source = AbstractCommand.CommandSource.default, user = "User", command = "", rest = "", bonusData = None): returnString = "" - print("\n Command>: " + command + rest) + praxis_logger_obj.log("\n Command>: " + command + rest) + isTwitch = False - returnString = self.dothething(user, 16, command, rest) + if source is not None and source == AbstractCommand.CommandSource.Twitch: + for user_ in config.allowedCommandsList_TwitchPowerUsers: + if user_.lower() == user.lower(): + praxis_logger_obj.log(user_) + praxis_logger_obj.log(user) + returnString = self.dothething(user, 16, command, rest) + isTwitch = True + + if isTwitch == False: + returnString = self.dothething(user, 16, command, rest) return returnString diff --git a/config.py b/config.py index ac98bb8..e0562d9 100644 --- a/config.py +++ b/config.py @@ -80,6 +80,10 @@ dbStrategy = DBStrategy.SQLite #TTS Configs + +is_tts_Speaker_Enabled = False +is_tts_URL_Blocked = True + class Speaker(Enum): GOOGLE_TEXT_TO_SPEECH = 1 STREAMLABS_API = 2 diff --git a/docker-compose.yaml b/docker-compose.yaml index 73c3fe5..b99d496 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -24,6 +24,14 @@ services: - 42069:42069 environment: - ISDOCKER=cat + standalone_tts_core: + image: standalone_tts_core + volumes: + - "./:/Praxis/" + ports: + - 60809:60809 + environment: + - ISDOCKER=cat standalone_twitchscript: image: standalone_twitchscript volumes: diff --git a/makedockerimages.bat b/makedockerimages.bat index fc288bc..bc89705 100644 --- a/makedockerimages.bat +++ b/makedockerimages.bat @@ -1,6 +1,7 @@ docker build --file Dockerfile_standalone_command --tag standalone_command . docker build --file Dockerfile_standalone_channelRewards --tag standalone_channelrewards . docker build --file Dockerfile_standalone_lights --tag standalone_lights . +docker build --file Dockerfile_standalone_tts_core --tag standalone_tts_core . 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_lights.py b/standalone_lights.py index cca6f73..f237f8f 100644 --- a/standalone_lights.py +++ b/standalone_lights.py @@ -94,10 +94,20 @@ class Lights_Module(): def setGroups(): pass + def rubiksCube(self): + for rave in range(10): + rgb_r = random.random() + rgb_g = random.random() + rgb_b = random.random() + xy_result = self.rgb_to_xy(rgb_r, rgb_g, rgb_b) #This will take an rgb value and make it xy + self.bridge_.set_group(16, "xy", xy_result, transitiontime=0.2) + sleep(0.25) + self.bridge_.run_scene("Downstairs", "Stream") + def hydration(self): self.bridge_.run_scene("Downstairs", "hydration") - #sleep(20) - #self.bridge_.run_scene("Downstairs", "Stream") + sleep(20) + self.bridge_.run_scene("Downstairs", "Stream") def raveMode(self): for rave in range(30): @@ -250,6 +260,9 @@ def do_lights_command(user="", lightGroup="all", command = "", rest = ""): elif "on" in tempParsedMessage: sceneCommand = True RGB_Lights.bridge_.set_group("Downstairs", "on", True) + elif "rubikscube" in tempParsedMessage: + sceneCommand = True + RGB_Lights.rubiksCube() elif "hydration" in tempParsedMessage: sceneCommand = True RGB_Lights.hydration() diff --git a/standalone_tts_core.py b/standalone_tts_core.py new file mode 100644 index 0000000..19e0210 --- /dev/null +++ b/standalone_tts_core.py @@ -0,0 +1,52 @@ +import flask +from flask import request + +from json import loads +from urllib.parse import urlencode + +import requests + +import os +import praxis_logging +praxis_logger_obj = praxis_logging.praxis_logger() +praxis_logger_obj.init(os.path.basename(__file__)) +praxis_logger_obj.log("\n -Starting Logs: " + os.path.basename(__file__)) + +api = flask.Flask(__name__) +# enable/disable this to get web pages of crashes returned +api.config["DEBUG"] = True + +def init(): + praxis_logger_obj.log("init stuff") + +def send_text(tts_sender, tts_text): + + #Play Audio File + params = urlencode({'tts_sender': tts_sender, 'tts_text': tts_text}) + + url = "http://localhost:93986/api/v1/tts/speech?%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: + pass + else: + # todo handle failed requests + pass + + return flask.make_response('', 200) + +@api.route('/api/v1/tts/send_text', methods=['GET']) +def tts_send_text(): + if 'tts_sender' not in request.args: + tts_sender = "" + if 'tts_text' not in request.args: + return flask.make_response('{\"text\":"Argument \'tts_text\' not in request"}', 400) + + return send_text(request.args['tts_sender'], request.args['tts_text']) + +if __name__ == '__main__': + init() + api.run(host='0.0.0.0', port=60809) \ No newline at end of file diff --git a/standalone_tts_speaker.py b/standalone_tts_speaker.py new file mode 100644 index 0000000..9907f1c --- /dev/null +++ b/standalone_tts_speaker.py @@ -0,0 +1,64 @@ +import flask +from flask import request + +import tts + +import config +import utilities_script as utility + +import os +import praxis_logging +praxis_logger_obj = praxis_logging.praxis_logger() +praxis_logger_obj.init(os.path.basename(__file__)) +praxis_logger_obj.log("\n -Starting Logs: " + os.path.basename(__file__)) + +api = flask.Flask(__name__) +# enable/disable this to get web pages of crashes returned +api.config["DEBUG"] = True + +def init(): + praxis_logger_obj.log("init stuff") + +def isTTS_URL_Check(message): + isNotBlocked = True + is_ttsEnabled = config.is_tts_Speaker_Enabled + is_tts_URL_Allowed = not config.is_tts_URL_Blocked + has_URL = False + if utility.contains_url(message): + has_URL = True + + if is_tts_URL_Allowed: + if has_URL: + has_URL = False + if has_URL: + isNotBlocked = False + if not is_ttsEnabled: + isNotBlocked = False + + return isNotBlocked + +def try_TTS(tts_sender, tts_text): + text_to_say: str = "%s says, %s" % (tts_sender, tts_text) + + if tts_sender is None: + text_to_say = tts_text + + if isTTS_URL_Check(tts_text): + if not utility.contains_slur(tts_sender): + if not utility.contains_slur(text_to_say): + tts.tts(text_to_say) + + return flask.make_response('', 200) + +@api.route('/api/v1/tts/speech', methods=['GET']) +def tts_speech(): + if 'tts_sender' not in request.args: + tts_sender = "" + if 'tts_text' not in request.args: + return flask.make_response('{\"text\":"Argument \'tts_text\' not in request"}', 400) + + return try_TTS(request.args['tts_text']) + +if __name__ == '__main__': + init() + api.run(host='0.0.0.0', port=93986) \ No newline at end of file