This repository has been archived by the owner on Jul 17, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathTheNewTTS_StreamlabsSystem.py
312 lines (280 loc) · 10.9 KB
/
TheNewTTS_StreamlabsSystem.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
# TheNewTTS script for Streamlabs Chatbot
# Copyright (C) 2020 Luis Sanchez
#
# Versions:
# - 2.1.0 10/05/2020 -
# Added a clean repeated words/emotes option
# Added a clean repeated letters option
# Added a clean and replace links option
# Added a ignore messages starting with a character option
# - 2.0.0 08/29/2020 -
# Added a say username before message option
# Added a skip command
# Fixed sometimes skipping messages
# Fixed script stopped working suddenly
# - 1.2.1 12/09/2019 - Fixed Youtube/Mixer blacklist comparison against user ID instead of username
# - 1.2.0 12/08/2019 - Added blacklist
# - 1.1.0 12/03/2019 - Added max length in seconds
# - 1.0.1 11/27/2019 - Fixed sound not playing
# - 1.0.0 11/12/2019 - Initial release
# [Required] Import Libraries #
import re
import os
import sys
import clr
import time
import json
import codecs
# Add script's folder to path to be able to find the other modules
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from tts_media import Media_Manager, run_cmd
# [Required] Script Information #
Description = "Text to speech with Google translate voice"
ScriptName = "TheNewTTS"
Creator = "LuisSanchezDev"
Version = "1.2.1"
Website = "https://www.fiverr.com/luissanchezdev"
# Define Global Variables
global PATH,CONFIG_FILE, BLACKLIST_FILE
PATH = os.path.dirname(os.path.realpath(__file__))
CONFIG_FILE = os.path.join(PATH,"config.json")
BLACKLIST_FILE = os.path.join(PATH,"blacklist.db")
MAX_CHARACTERS_ALLOWED = 200
global SETTINGS, MEDIA_MGR, BLACKLIST
SETTINGS = {}
MEDIA_MGR = None
BLACKLIST = None
# [Required] Initialize Data (Only called on load) #
def Init():
global SETTINGS, PATH, CONFIG_FILE, BLACKLIST_FILE, BLACKLIST, MEDIA_MGR
cache_folder = os.path.join(PATH, "cache")
def ensure_cache_dir():
if os.path.isdir(cache_folder):
Parent.Log("TTS", "Deleting folder!")
# os.system('RMDIR /Q/S "{0}"'.format(cache_folder))
run_cmd('RMDIR /Q/S "{0}"'.format(cache_folder))
os.mkdir(cache_folder)
Parent.Log("TTS", "Deleting folder")
while True:
try:
ensure_cache_dir()
break
except:
continue
try:
with codecs.open(CONFIG_FILE, encoding="utf-8-sig", mode='r') as file:
SETTINGS = json.load(file, encoding="utf-8-sig")
except:
SETTINGS = {
"read_all_text": False,
"clean_repeated_words": True,
"clean_repeated_letters": True,
"clean_urls": True,
"url_replacement": "link removed",
"say_username": True,
"say_after_username": "says",
"ignore_starting_with": "!",
"command": "!tts",
"permission": "Everyone",
"cooldown": 0,
"user_cooldown": 0,
"cost": 0,
"msg_permission": "You don't have enough permissions to use this command.",
"msg_cooldown": "This command is still on cooldown!",
"msg_user_cooldown": "You need to wait before using this command again.",
"msg_cost": "You don't have enough money!",
"lang": "English (US) [en-US]",
"pitch": 100,
"speed": 100,
"volume": 90,
"length": 5,
"cmd_ban": "!ttsban",
"cmd_unban": "!ttsunban",
"moderator_permission": "Caster",
"cmd_skip": "!ttskip"
}
SETTINGS["lang"] = re.match(r"^.*\[(.+)\]", SETTINGS["lang"]).groups()[0]
SETTINGS["pitch"] /= 100.0
SETTINGS["speed"] /= 100.0
SETTINGS["volume"] /= 100.0
SETTINGS["_path"] = PATH
SETTINGS["_cache"] = cache_folder
# config.json backwards compatibility
# Max tts length added
if "length" not in SETTINGS: SETTINGS["length"] = 5
# Blacklisting added
if "cmd_ban" not in SETTINGS: SETTINGS["cmd_ban"] = "!ttsban"
if "cmd_unban" not in SETTINGS: SETTINGS["cmd_unban"] = "!ttsunban"
# Moderator commands added
if "moderator_permission" not in SETTINGS: SETTINGS["moderator_permission"] = "Caster"
if "cmd_skip" not in SETTINGS: SETTINGS["cmd_skip"] = "!ttskip"
# Say username added
if "say_username" not in SETTINGS: SETTINGS["say_username"] = True
if "say_after_username" not in SETTINGS: SETTINGS["say_after_username"] = "says"
# Ignore starting with added
if "ignore_starting_with" not in SETTINGS: SETTINGS["ignore_starting_with"] = "!"
# Clean words/letters/urls added
if "clean_repeated_words" not in SETTINGS: SETTINGS["clean_repeated_words"] = True
if "clean_repeated_letters" not in SETTINGS: SETTINGS["clean_repeated_letters"] = True
if "clean_urls" not in SETTINGS: SETTINGS["clean_urls"] = True
if "url_replacement" not in SETTINGS: SETTINGS["url_replacement"] = "link removed"
BLACKLIST = Blacklist(BLACKLIST_FILE)
MEDIA_MGR = Media_Manager(SETTINGS)
# [Required] Execute Data / Process messages #
def Execute(data):
global SETTINGS, MEDIA_MGR
if data.IsChatMessage():
command = data.GetParam(0)
if Parent.HasPermission(data.User, SETTINGS["moderator_permission"], ""):
target = data.GetParam(1)
if command == SETTINGS["cmd_skip"]:
MEDIA_MGR.skip()
return
elif command == SETTINGS["cmd_ban"]:
if data.GetParamCount() != 2:
Parent.SendStreamMessage("Usage: {0} <username>".format(SETTINGS["cmd_ban"]))
return
if BLACKLIST.add_user(target):
Parent.SendStreamMessage(target + " successfully blacklisted!")
else:
Parent.SendStreamMessage(target + " already blacklisted!")
return
elif command == SETTINGS["cmd_unban"]:
if data.GetParamCount() != 2:
Parent.SendStreamMessage("Usage: {0} <username>".format(SETTINGS["cmd_unban"]))
return
if BLACKLIST.remove_user(target):
Parent.SendStreamMessage(target + " removed from blacklist!")
else:
Parent.SendStreamMessage(target + " was not blacklisted!")
return
text = data.Message
if SETTINGS["clean_repeated_words"]:
text = clean_repeated_words(text)
if SETTINGS["clean_repeated_letters"]:
text = clean_repeated_letters(text)
if SETTINGS["clean_urls"]:
text = clean_urls(text)
if SETTINGS["read_all_text"]:
if BLACKLIST.is_user_blacklisted(data.UserName):
return
if text[0] == SETTINGS["ignore_starting_with"]:
return
if len(text) > MAX_CHARACTERS_ALLOWED:
MEDIA_MGR.append(data.UserName + "'s message was too long")
else:
if SETTINGS["say_username"]:
MEDIA_MGR.append(data.UserName + " " + SETTINGS["say_after_username"])
MEDIA_MGR.append(text)
return
elif command == SETTINGS["command"]:
if not Parent.HasPermission(data.User, SETTINGS["permission"], ""):
Parent.SendStreamMessage(SETTINGS["msg_permission"])
return
if BLACKLIST.is_user_blacklisted(data.UserName):
Parent.SendStreamMessage(data.User + " is blacklisted!")
return
if SETTINGS["user_cooldown"] and Parent.GetUserCooldownDuration(ScriptName, SETTINGS["command"], data.User):
Parent.SendStreamMessage(SETTINGS["msg_user_cooldown"])
return
if SETTINGS["cooldown"] and Parent.GetCooldownDuration(ScriptName, SETTINGS["command"]):
Parent.SendStreamMessage(SETTINGS["msg_cooldown"])
return
if not Parent.RemovePoints(data.User, data.UserName, SETTINGS["cost"]) and not SETTINGS["cost"] <= 0:
Parent.SendStreamMessage(SETTINGS["msg_cost"])
return
if not data.GetParam(1):
Parent.SendStreamMessage("You need to specify a message")
return
text = " ".join(text.split(' ')[1:])
if len(text) > MAX_CHARACTERS_ALLOWED:
Parent.AddPoints(data.User, data.UserName, SETTINGS["cost"])
Parent.SendStreamMessage("Can't read message because the text istoo long!")
return
else:
if SETTINGS["say_username"]:
MEDIA_MGR.append(data.UserName + " " + SETTINGS["say_after_username"])
MEDIA_MGR.append(text)
Parent.AddCooldown(ScriptName, SETTINGS["command"], SETTINGS["cooldown"])
Parent.AddUserCooldown(ScriptName, SETTINGS["command"], data.User, SETTINGS["user_cooldown"])
return
# [Required] Tick method (Gets called during every iteration even when there is no incoming data) #
def Tick():
pass
# [Optional] Reload Settings (Called when a user clicks the Save Settings button in the Chatbot UI) #
def ReloadSettings(jsonData):
global MEDIA_MGR
Unload()
Init()
MEDIA_MGR.append("Configuration updated successfully")
# Unload (Called when a user reloads their scripts or closes the bot / cleanup stuff)
def Unload():
global MEDIA_MGR
if MEDIA_MGR:
# Parent.Log("TTS", "Closing media manager")
MEDIA_MGR.close()
del MEDIA_MGR
# Parent.Log("TTS", "Media manager closed!")
# MEDIA_MGR = None
class Blacklist:
def __init__(self, file_path):
self._path = file_path
def add_user(self, user_name):
user_name = Blacklist._strip_username(user_name)
if self.is_user_blacklisted(user_name): return False
db = self._load()
db.append(user_name)
self._save(db)
return True
def remove_user(self, user_name):
user_name = Blacklist._strip_username(user_name)
if not self.is_user_blacklisted(user_name): return False
db = self._load()
db.remove(user_name)
self._save(db)
return True
def is_user_blacklisted(self, user_name):
user_name = Blacklist._strip_username(user_name)
if user_name in self._load(): return True
return False
def _load(self):
if not os.path.isfile(self._path): return []
with codecs.open(self._path, encoding="utf-8-sig", mode='r') as file:
return json.load(file, encoding="utf-8-sig")
def _save(self, modified_db):
with codecs.open(self._path, encoding="utf-8-sig", mode='w') as file:
file.write(json.dumps(modified_db, encoding="utf-8-sig"))
@staticmethod
def _strip_username(user_name):
user_name = user_name.lower()
if "@" in user_name:
user_name = user_name.replace("@","")
return user_name
def clean_repeated_words(text):
text = text.replace(":", " ")
text = re.sub(r'\s+', " ", text).strip()
words = text.split(" ")
output_text = []
last_word = ""
for word in words:
if word.lower() != last_word.lower():
output_text.append(word)
last_word = word
return " ".join(output_text)
def clean_repeated_letters(text):
return re.sub(r'(.)\1{2,}', r'\1', text)
def clean_urls(text):
global SETTINGS
PATTERN = r'[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)'
text = re.sub(PATTERN, SETTINGS["url_replacement"], text)
text = re.sub('https?', "", text)
return text
# [TheNewTTS] UI Link buttons #
def donate():
os.startfile("https://streamlabs.com/luissanchezdev/tip")
def open_contact_me():
os.startfile("www.fiverr.com/luissanchezdev/makea-custom-streamlabs-chatbot-script")
def open_contact_td():
os.startfile("https://www.fiverr.com/tecno_diana/make-cute-twich-emote-for-your-stream")
def open_readme():
os.startfile("https://github.com/LuisSanchez-Dev/TheNewTTS")