Compare commits

...

21 Commits

Author SHA1 Message Date
ee47862d7c Merge pull request 'added threading' (#10) from threading-idea into Discord-Script
Reviewed-on: #10
2020-11-17 10:34:25 +00:00
Alex Orid
c04322ccd7 Threading Fix 2020-11-17 05:30:43 -05:00
Alex Orid
b2b1d87949 Fixed Command Typo 2020-11-16 16:59:55 -05:00
Alex Orid
a167a7eba4 Updated Command Loader 2020-10-20 15:47:27 -04:00
Alex Orid
0e0456ca9e Prep for Bug Fix
Currently there is a bug where if discord and twitch have the same named commands,
the command will fail.
2020-10-20 06:26:41 -04:00
Alex Orid
83dad6764a Got rid of junk 2020-10-20 06:16:49 -04:00
Alex Orid
ce702b8b01 Working TTS on Discord
I also cleaned up tts usage in a few other places.
2020-10-20 06:12:26 -04:00
Alex Orid
5f3b3bb775 Cleaned up Main 2020-10-20 05:07:41 -04:00
Alex Orid
b0169ec68d Setup Cooldowns & Msg Clean Up 2020-10-20 04:44:52 -04:00
Alex Orid
323a5b1e9e Clean Up 2020-10-20 04:27:04 -04:00
Alex Orid
6c7df8674d Working Discord Roll Command 2020-10-20 04:18:45 -04:00
Alex Orid
7258bc0baf Update README.md 2020-10-20 03:44:08 -04:00
Alex Orid
14894e9aed Fixed Inconsistency 2020-10-20 03:41:56 -04:00
Alex Orid
07a48e0aa7 Updated ReadMe & Templates 2020-10-20 03:35:14 -04:00
Alex Orid
bab4a31d95 Cleaned up Main 2020-10-20 03:24:53 -04:00
Alex Orid
c4b409fd00 Modified more Lines 2020-10-20 03:12:42 -04:00
Alex Orid
81c458ddd1 Removed Line 2020-10-20 03:10:41 -04:00
Alex Orid
c55e708928 Added Test 2020-10-20 03:08:29 -04:00
Alex Orid
b29787d5c3 This Works? 2020-10-20 03:07:26 -04:00
Alex Orid
df3aa80a65 Progress Maybe?
This is the current error I run into:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:\Users\ADO\AppData\Local\Programs\Python\Python37\lib\threading.py", line
926, in _bootstrap_inner
    self.run()
  File "C:\Users\ADO\AppData\Local\Programs\Python\Python37\lib\threading.py", line
870, in run
    self._target(*self._args, **self._kwargs)
TypeError: discord_module_init() argument after * must be an iterable, not Discord_Module
2020-10-20 03:00:33 -04:00
Alex Orid
4f55c84ba8 idea 2020-10-20 00:10:42 -04:00
11 changed files with 221 additions and 39 deletions

View File

@ -19,8 +19,15 @@ Oauth = `https://twitchapps.com/tmi/`
V5 Client ID = `https://twitchtokengenerator.com/` V5 Client ID = `https://twitchtokengenerator.com/`
### For Database Credentials ### For Database Credentials
Nickname = `Anything You Want`
Engine = `"mysql+mysqlconnector://root:password@localhost:3306/DatabaseName"` Engine = `"mysql+mysqlconnector://root:password@localhost:3306/DatabaseName"`
### For Discord Credentials
Nickname = `Anything You Want`
Token = `https://discord.com/developers/`
## Credential Usage: ## Credential Usage:
Place json credentials in the `/credentials/` folder. Place json credentials in the `/credentials/` folder.

View File

@ -19,12 +19,13 @@ class CommandRoll(AbstractCommand, metaclass=ABCMeta):
def __init__(self): def __init__(self):
super().__init__(CommandRoll.command, n_args=1, command_type=AbstractCommand.CommandType.DISCORD) super().__init__(CommandRoll.command, n_args=1, command_type=AbstractCommand.CommandType.DISCORD)
def do_command(self, bot, discord_message: discord.Message): async def do_command(self, bot, discord_message: discord.Message):
print("!roll Detected") print("!roll Detected")
#twitch_message.chat.send("test acknowledged") #twitch_message.chat.send("test acknowledged")
diceRoll: str = "" diceRoll: str = ""
discord_message.channel.send("Rolling Dice...") await bot.send_message(discord_message, "Rolling Dice...")
#await discord_message.channel.send("Rolling Dice...")
print("Rolling Dice...") print("Rolling Dice...")
temp_preParsedMessage = discord_message.content.split("+") temp_preParsedMessage = discord_message.content.split("+")
@ -67,6 +68,8 @@ class CommandRoll(AbstractCommand, metaclass=ABCMeta):
else: else:
diceRoll = str(roll) diceRoll = str(roll)
diceRoll = "@" + message.author.display_name + " rolled: " + diceRoll
diceRoll = discord_message.author.mention + " rolled: " + diceRoll
print(diceRoll) print(diceRoll)
discord_message.channel.send(diceRoll) await bot.send_message(discord_message, diceRoll)
#await discord_message.channel.send(diceRoll)

View File

@ -18,5 +18,5 @@ class CommandTTS(AbstractCommand, metaclass=ABCMeta):
bot.tts_enabled = True bot.tts_enabled = True
elif args[1] == "stop": elif args[1] == "stop":
if twitch_message.sender.lower() == twitch_message.channel: if twitch_message.sender.lower() == twitch_message.channel:
bot.send_message("tts activated on #%s" % twitch_message.channel) bot.send_message("tts deactivated on #%s" % twitch_message.channel)
bot.tts_enabled = False bot.tts_enabled = False

View File

@ -0,0 +1,30 @@
from abc import ABCMeta
from commands.command_base import AbstractCommand
import discord
import discord.message
class CommandTTS(AbstractCommand, metaclass=ABCMeta):
command = "!tts"
def __init__(self):
super().__init__(CommandTTS.command, n_args=1, command_type=AbstractCommand.CommandType.DISCORD)
async def do_command(self, bot, discord_message: discord.message):
args = self.get_args(discord_message.content)
if args[1] == "start":
print(discord_message.author.top_role)
print("start detected")
if str(discord_message.author.top_role) == "Admin":
print("Admin Check")
response = str("tts activated on %s" % discord_message.guild.name)
await bot.send_message(discord_message, response)
bot.tts_enabled = True
elif args[1] == "stop":
print("stop detected")
if str(discord_message.author.top_role) == "Admin":
print("Admin Check")
response = str("tts deactivated on %s" % discord_message.guild.name)
await bot.send_message(discord_message, response)
bot.tts_enabled = False

View File

@ -12,6 +12,9 @@ def load_commands() -> Dict[str, AbstractCommand]:
commands = compile_and_load() commands = compile_and_load()
return commands return commands
def load_commands_new(commandType: AbstractCommand.CommandType) -> Dict[str, AbstractCommand]:
commands = compile_and_load_new(commandType)
return commands
def compile_and_load_file(path: str) -> (str, AbstractCommand): def compile_and_load_file(path: str) -> (str, AbstractCommand):
module_name = os.path.split(path)[1].replace(".py", "") module_name = os.path.split(path)[1].replace(".py", "")
@ -41,6 +44,18 @@ def compile_and_load() -> Dict[str, AbstractCommand]:
break break
return dic return dic
def compile_and_load_new(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)
if command is not None and command.command_type is commandType:
dic[name] = command
break
return dic
def get_base_dir() -> str: def get_base_dir() -> str:
cwd = os.getcwd() cwd = os.getcwd()
@ -52,7 +67,7 @@ def get_base_dir() -> str:
return check_dir(os.path.join(cwd, "commands")) return check_dir(os.path.join(cwd, "commands"))
else: else:
print("could not find working directory for Praxis_Bot/commands") print("could not find working directory for Praxis_Bot/commands")
raise raise Exception
def get_implementations_dir() -> str: def get_implementations_dir() -> str:

View File

@ -74,7 +74,7 @@ class PollyVoices(Enum):
Zhiyu = "Zhiyu" Zhiyu = "Zhiyu"
botList = ("Nightbot", "StreamElements", "Moobot", "praxis_bot") botList = ("Nightbot", "StreamElements", "Moobot", "Praxis Bot", "praxis_bot", "MEE6 +", "Nerdy", "Rythm", "Groovy")
slurList = ("fag", "faggot", "niga", "nigga", "nigger", "retard", "tard", "rtard", "coon") slurList = ("fag", "faggot", "niga", "nigga", "nigger", "retard", "tard", "rtard", "coon")

View File

@ -1,4 +1,4 @@
{ {
"username": "AnythingYouWant", "nickname": "AnythingYouWant",
"token": "" "token": ""
} }

View File

@ -3,28 +3,44 @@ import re
from discord import message from discord import message
from discord.client import Client from discord.client import Client
import asyncio
import config as config import config as config
import db import db
import tts import tts
import commands.loader as command_loader
from commands.command_base import AbstractCommand
import credentials import credentials
import discord import discord
import discord.message import discord.message
import discord.channel import discord.channel
from cooldowns import Cooldown_Module
class Discord_Module(discord.Client): class Discord_Module(discord.Client):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.loop = asyncio.get_event_loop()
self.dbCredential: credentials.DB_Credential self.dbCredential: credentials.DB_Credential
self.discordCredential: credentials.Discord_Credential self.discordCredential: credentials.Discord_Credential
self.cooldownModule:Cooldown_Module = Cooldown_Module()
self.cooldownModule.setupCooldown("discordRateLimit", 10, 1)
self.commands = command_loader.load_commands_new(AbstractCommand.CommandType.DISCORD)
self.tts_enabled: bool = False self.tts_enabled: bool = False
async def startup(self):
await self.start(self.discordCredential.token)
def main(self): def main(self):
self.run(self.discordCredential.token) print("starting loop")
self.loop.create_task(self.startup())
self.loop.run_forever()
async def on_ready(self): async def on_ready(self):
print('Logged on as', self.user) print('Logged on as', self.user)
@ -39,8 +55,85 @@ class Discord_Module(discord.Client):
if message.content == "//test": if message.content == "//test":
await message.channel.send('test response') await message.channel.send('test response')
def do_command(self): if not await self.isSenderBot(message):
pass if self.cooldownModule.isCooldownActive("discordRateLimit") == False:
await self.eval_commands(message)
await self.tts_message(message)
async def eval_commands(self, message: discord.Message):
# containsURL: bool = self.contains_url(message)
try:
#first_space_idx = message.text.index(' ')
# This fixes a error where if you send a command without arguments it fails because
# it cant find the substring.
if message.content.find(" ") != -1:
first_space_idx = message.content.index(' ')
else:
first_space_idx = -1
command_text = ' '
if first_space_idx > -1:
command_text = message.content[0:first_space_idx]
else:
command_text = message.content
command = self.commands[command_text]
if command is not None and command.command_type is AbstractCommand.CommandType.DISCORD:
await command.do_command(self, message)
except Exception as e:
# Undo the following for debug stuff
#print(e)
pass # we don't care
async def send_message(self, message, response):
if self.cooldownModule.isCooldownActive("discordRateLimit") == False:
await message.channel.send(response)
self.cooldownModule.actionTrigger("discordRateLimit")
async def tts_message(self, message: discord.Message):
if not await self.contains_slur(message):
if self.tts_enabled:
if not message.content.startswith('!'):
text_to_say: str = "%s says, %s" % (message.author.display_name, message.content)
channel_text = "%s user msg" % message.channel
tts.tts(text_to_say)
# Checks for basic slurs.
async def contains_slur(self, message: discord.Message):
containsSlur: bool = False
if await self.slur_check(message.content) or await self.slur_check(message.author.display_name):
containsSlur = True
return containsSlur
async def slur_check(self, text):
containsSlur: bool = False
parsedMessage = text.split(" ")
for word in parsedMessage:
for slur in config.slurList:
if word.lower() == slur:
containsSlur = True
break # we want to immediately escape if we found a slur
if containsSlur:
break
if containsSlur:
print("<{ slur detected! }>")
#print("<{ slur detected! }> " + " [#" + message.channel + "](" + message.author.display_name + ") used a slur in chat")
return containsSlur
# Checks if Sender is bot.
async def isSenderBot(self, message: discord.Message):
isBot = False
for bot in config.botList:
if message.author.display_name.lower() == bot.lower():
isBot = True
print("<{ bot detected! }> ")
return isBot
@ -54,4 +147,6 @@ if __name__ == "__main__":
testModule.discordCredential = credentials_manager.find_Discord_Credential("praxis_bot") testModule.discordCredential = credentials_manager.find_Discord_Credential("praxis_bot")
testModule.main() testModule.main()
testModule.main()

57
main.py
View File

@ -11,35 +11,66 @@ import utilities_script as utility
import credentials import credentials
import threading
twitch_chat: twitch_script.Twitch_Module twitch_chat: twitch_script.Twitch_Module
credentials_manager: credentials.Credentials_Module credentials_manager: credentials.Credentials_Module
discord_connection: discord_script.Discord_Module
def main(): def main():
global twitch_chat pass
global credentials_manager
credentials_manager = credentials.Credentials_Module()
credentials_manager.load_credentials()
dbCert: credentials.DB_Credential = credentials_manager.find_Credential(credentials.DB_Credential, "praxis_bot") def new_main(inputArg):
twitchCert: credentials.Twitch_Credential = credentials_manager.find_Twitch_Credential("praxis_bot") args = utility.get_args(inputArg)
discordCert: credentials.Discord_Credential = credentials_manager.find_Discord_Credential("praxis_bot")
twitch_chat = twitch_script.Twitch_Module() def twitch_module_init(dbCert, twitchCert):
twitch_chat.db_manager.setup_engine(dbCert) twitch_chat.db_manager.setup_engine(dbCert)
twitch_chat.twitchCredential = twitchCert twitch_chat.twitchCredential = twitchCert
twitch_chat.join_channel(None, "thecuriousnerd") twitch_chat.join_channel(None, "thecuriousnerd")
discord_connection = discord_script.Discord_Module()
def discord_module_init(dbCert, discordCert):
discord_connection.dbCredential = dbCert discord_connection.dbCredential = dbCert
discord_connection.discordCredential = discordCert discord_connection.discordCredential = discordCert
discord_connection.main() discord_connection.main()
#Doesn't do stuff past this point
twitch_chat.send_message("activated")
def thread_main():
global twitch_chat
global discord_connection
global credentials_manager
twitch_chat = twitch_script.Twitch_Module()
discord_connection = discord_script.Discord_Module()
credentials_manager = credentials.Credentials_Module()
credentials_manager.load_credentials()
dbCert: credentials.DB_Credential = credentials_manager.find_Credential(credentials.DB_Credential, "praxis_bot")
twitchCert: credentials.Twitch_Credential = credentials_manager.find_Twitch_Credential("praxis_bot")
discordCert: credentials.Discord_Credential = credentials_manager.find_Discord_Credential("praxis_bot")
threads = []
twitch = threading.Thread(target=twitch_module_init, args=(dbCert, twitchCert))
threads.append(twitch)
twitch.start()
discord = threading.Thread(target=discord_module_init, args=(dbCert, discordCert))
threads.append(discord)
discord.start()
print("---Post Thread Creation Test---")
for t in threads:
t.join()
print("---Point of no return---")
if __name__ == "__main__": if __name__ == "__main__":
main() thread_main()

View File

@ -23,7 +23,7 @@ class Twitch_Module():
self.db_manager: db.db_module = db.db_module() self.db_manager: db.db_module = db.db_module()
self.chat: twitch.Chat self.chat: twitch.Chat
self.commands = command_loader.load_commands() self.commands = command_loader.load_commands_new(AbstractCommand.CommandType.TWITCH)
self.tts_enabled: bool = False self.tts_enabled: bool = False
self.tts_whitelist_enabled: bool = False self.tts_whitelist_enabled: bool = False
self.links_allowed: bool = True self.links_allowed: bool = True
@ -34,8 +34,8 @@ class Twitch_Module():
# Default Twitch Chat limit is 20 per 30 seconds # Default Twitch Chat limit is 20 per 30 seconds
# If Mod or Op, Twitch Chat limit is 100 per 30 seconds # If Mod or Op, Twitch Chat limit is 100 per 30 seconds
self.twitchChat_cooldown:Cooldown_Module = Cooldown_Module() self.cooldownModule:Cooldown_Module = Cooldown_Module()
self.twitchChat_cooldown.setupCooldown("twitchChat", 20, 32) self.cooldownModule.setupCooldown("twitchChat", 20, 32)
def join_channel(self, credential: credentials.Twitch_Credential, channel_name:str): def join_channel(self, credential: credentials.Twitch_Credential, channel_name:str):
channel_name = "#" + channel_name channel_name = "#" + channel_name
@ -60,9 +60,9 @@ class Twitch_Module():
self.chat.irc.socket.close() self.chat.irc.socket.close()
def send_message(self, message): def send_message(self, message):
if self.twitchChat_cooldown.isCooldownActive("twitchChat") == False: if self.cooldownModule.isCooldownActive("twitchChat") == False:
self.chat.send(message) self.chat.send(message)
self.twitchChat_cooldown.actionTrigger("twitchChat") self.cooldownModule.actionTrigger("twitchChat")
def send_whisper(self, user, message): def send_whisper(self, user, message):
pass pass
@ -73,13 +73,12 @@ class Twitch_Module():
if message.channel == "thecuriousnerd": if message.channel == "thecuriousnerd":
if not self.isSenderBot(message): if not self.isSenderBot(message):
if self.twitchChat_cooldown.isCooldownActive("twitchChat") == False: if self.cooldownModule.isCooldownActive("twitchChat") == False:
self.eval_commands(message) self.eval_commands(message)
#elif message.channel == message.sender:
#self.eval_commands(message)
self.tts_message(message) self.tts_message(message)
def eval_commands(self, message: twitch.chat.Message): def eval_commands(self, message: twitch.chat.Message):
print("evaling command")
# containsURL: bool = self.contains_url(message) # containsURL: bool = self.contains_url(message)
try: try:
#first_space_idx = message.text.index(' ') #first_space_idx = message.text.index(' ')
@ -99,9 +98,12 @@ class Twitch_Module():
command = self.commands[command_text] command = self.commands[command_text]
if command is not None and command.command_type is AbstractCommand.CommandType.TWITCH: if command is not None and command.command_type is AbstractCommand.CommandType.TWITCH:
print("evaling command")
command.do_command(self, message) command.do_command(self, message)
except Exception as e: except Exception as e:
print(e) # Undo the following for debug stuff
#print(e)
print("failed command")
pass # we don't care pass # we don't care
@ -112,11 +114,7 @@ class Twitch_Module():
text_to_say: str = "%s says, %s" % (message.sender, message.text) text_to_say: str = "%s says, %s" % (message.sender, message.text)
channel_text = "%s user msg" % message.channel channel_text = "%s user msg" % message.channel
if message.sender.lower() == message.channel: tts.tts(text_to_say)
tts.tts(text_to_say)
else:
# tts.tts(message.sender + " says, " + message.text)
tts.tts(text_to_say, channel_text)
def contains_url(self, message: twitch.chat.Message): def contains_url(self, message: twitch.chat.Message):
containsURL = re.search(self._urlMatcher, message.text.lower()) is not None containsURL = re.search(self._urlMatcher, message.text.lower()) is not None

View File

@ -1,3 +1,6 @@
import os import os
clearScreen = lambda: os.system('cls' if os.name == 'nt' else 'clear') clearScreen = lambda: os.system('cls' if os.name == 'nt' else 'clear')
def get_args(text: str) -> list:
return text.split(" ")