Now loads config from JSON

This commit is contained in:
2025-12-04 00:51:29 -05:00
parent d798608688
commit 640479569a
2 changed files with 304 additions and 78 deletions

246
bot.py
View File

@@ -3,6 +3,8 @@ import dotenv
import os import os
import asyncio import asyncio
import random import random
import json
from collections.abc import Callable
class MessageCondition: class MessageCondition:
def check_condition(self, message:discord.Message) -> bool: return True def check_condition(self, message:discord.Message) -> bool: return True
@@ -87,9 +89,10 @@ class EmojiResponse(MessageResponse):
return return
class MessageHandler: class MessageHandler:
def __init__(self, conditions:list[MessageCondition], responses:list[MessageResponse]): def __init__(self, conditions:list[MessageCondition], responses:list[MessageResponse], blocking:bool = True):
self.conditions = conditions self.conditions = conditions
self.responses = responses self.responses = responses
self.blocking = blocking
def handle_message(self, message:discord.Message) -> bool: def handle_message(self, message:discord.Message) -> bool:
handled = False handled = False
@@ -112,82 +115,169 @@ less_than_conditions = [
TextCondition("violence") TextCondition("violence")
] ]
handlers:list[MessageHandler] = [ class ConfigLoader():
MessageHandler( def load_and_condition(self, data) -> AndCondition:
[ conditions:list[TextCondition] = []
AndCondition( for condition_data in data["conditions"]:
[ conditions.append(self.load_condition(condition_data))
RandomCondition(0.7),
OrCondition(less_than_conditions) return AndCondition(conditions)
]
) def load_or_condition(self, data) -> OrCondition:
], conditions:list[TextCondition] = []
[ for condition_data in data["conditions"]:
TextResponse("WHAT ARE YOU WAITING FOR?") conditions.append(self.load_condition(condition_data))
]
), return OrCondition(conditions)
MessageHandler(
less_than_conditions, def load_text_condition(self, data) -> TextCondition:
[ text = data["text"]
EmojiResponse("lessthan")
] filter_whitespace = True
), if "filter_whitespace" in data:
MessageHandler( filter_whitespace = data["filter_whitespace"]
[
TextCondition("shutup"), filter_case = True
TextCondition("shutthehellup"), if "filter_case" in data:
TextCondition("shutthefuckup") filter_case = data["filter_case"]
],
[ filter_punctuation = True
TextResponse("SILENCE"), if "filter_punctuation" in data:
EmojiResponse("lessthan") filter_punctuation = data["filter_punctuation"]
]
), return TextCondition(text, filter_whitespace, filter_case, filter_punctuation)
MessageHandler(
[ def load_random_condition(self, data) -> RandomCondition:
TextCondition("pieces"), chance = data["chance"]
TextCondition("peices") return RandomCondition(chance)
],
[ def load_match_word_condition(self, data) -> MatchWordCondition:
TextResponse("Put. It. Together.") text = data["text"]
] filter_case = True
), if "filter_case" in data:
MessageHandler( filter_case = data["filter_case"]
[
AndCondition( filter_punctuation = True
[ if "filter_punctuation" in data:
TextCondition("annoy"), filter_punctuation = data["filter_punctuation"]
RandomCondition(0.5)
] return MatchWordCondition(text, filter_case, filter_punctuation)
)
], conditions:dict[str, Callable] = {
[ "text": load_text_condition,
TextResponse("Stop annoying yourself.") "match_word": load_match_word_condition,
] "random": load_random_condition,
), "and": load_and_condition,
MessageHandler( "or": load_or_condition
[ }
AndCondition(
[ def load_condition(self, data) -> MessageCondition:
TextCondition("bot"), return self.conditions[data["type"]](self, data)
RandomCondition(0.35)
] def load_text_response(self, data) -> TextResponse:
) return TextResponse(data["text"])
],
[ def load_emoji_response(self, data) -> EmojiResponse:
TextResponse("I'm not a bot.") return EmojiResponse(data["emoji"])
]
), responses:dict[str, Callable] = {
MessageHandler( "text": load_text_response,
[ "emoji": load_emoji_response
MatchWordCondition("late") }
],
[ def load_response(self, data) -> MessageResponse:
TextResponse("https://tenor.com/view/warframe-whispers-in-the-wall-tenno-entrati-1999-gif-16943765476869672917"), return self.responses[data["type"]](self, data)
EmojiResponse("albrecht_entrati")
] def load_handler(self, data) -> MessageHandler:
) conditions:list[MessageCondition] = []
] for condition_data in data["conditions"]:
conditions.append(self.load_condition(condition_data))
responses:list[MessageResponse] = []
for response_data in data["responses"]:
responses.append(self.load_response(response_data))
blocking = True
if "blocking" in data:
blocking = data["blocking"]
return MessageHandler(conditions, responses, blocking)
def load_config_from_file(self, path:str) -> list[MessageHandler]:
with open(path) as file:
config_dict = json.load(file)
handlers:list[MessageHandler] = []
for data in config_dict["message_handlers"]:
handlers.append(self.load_handler(data))
return handlers
loader = ConfigLoader()
handlers:list[MessageHandler] = loader.load_config_from_file("./config.json")
# [
# MessageHandler(
# less_than_conditions,
# [
# EmojiResponse("lessthan"),
# TextResponse("WHAT ARE YOU WAITING FOR?")
# ]
# ),
# MessageHandler(
# [
# TextCondition("shutup"),
# TextCondition("shutthehellup"),
# TextCondition("shutthefuckup")
# ],
# [
# TextResponse("SILENCE"),
# EmojiResponse("lessthan")
# ]
# ),
# MessageHandler(
# [
# TextCondition("pieces"),
# TextCondition("peices")
# ],
# [
# TextResponse("Put. It. Together.")
# ]
# ),
# MessageHandler(
# [
# AndCondition(
# [
# TextCondition("annoy"),
# RandomCondition(0.5)
# ]
# )
# ],
# [
# TextResponse("Stop annoying yourself.")
# ]
# ),
# MessageHandler(
# [
# AndCondition(
# [
# TextCondition("bot"),
# RandomCondition(0.35)
# ]
# )
# ],
# [
# TextResponse("I'm not a bot.")
# ]
# ),
# MessageHandler(
# [
# MatchWordCondition("late")
# ],
# [
# TextResponse("https://tenor.com/view/warframe-whispers-in-the-wall-tenno-entrati-1999-gif-16943765476869672917"),
# EmojiResponse("albrecht_entrati")
# ]
# )
# ]
dotenv.load_dotenv(".env") dotenv.load_dotenv(".env")
@@ -209,7 +299,7 @@ async def on_message(message):
print(f"Message from {message.author}: {message.content}") print(f"Message from {message.author}: {message.content}")
for handler in handlers: for handler in handlers:
if handler.handle_message(message): if handler.handle_message(message) and handler.blocking:
return return
def process_string(string:str, filter_whitespace:bool = True, filter_case:bool = True, filter_punctuation:bool = True) -> str: def process_string(string:str, filter_whitespace:bool = True, filter_case:bool = True, filter_punctuation:bool = True) -> str:

136
example_config.json Normal file
View File

@@ -0,0 +1,136 @@
{
"message_handlers": [
{
"conditions": [
{
"type": "text",
"text": "lessthan"
},
{
"type": "text",
"text": "focus"
},
{
"type": "text",
"text": "hypnosis"
},
{
"type": "text",
"text": "didntnotice"
},
{
"type": "text",
"text": "evennotice"
},
{
"type": "text",
"text": "oblivion"
},
{
"type": "text",
"text": "barelyrecognize"
},
{
"type": "text",
"text": "violence"
}
],
"responses": [
{
"type": "emoji",
"emoji": "lessthan"
},
{
"type": "text",
"text": "WHAT ARE YOU WAITING FOR?"
}
]
},
{
"conditions": [
{
"type": "match_word",
"text": "late"
}
],
"responses": [
{
"type": "emoji",
"emoji": "albrecht_entrati"
},
{
"type": "text",
"text": "https://tenor.com/view/warframe-whispers-in-the-wall-tenno-entrati-1999-gif-16943765476869672917"
}
]
},
{
"conditions": [
{
"type": "and",
"conditions": [
{
"type": "random",
"chance": 0.35
},
{
"type": "match_word",
"text": "bot"
}
]
}
],
"responses": [
{
"type": "text",
"text": "I'm not a bot."
}
]
},
{
"conditions": [
{
"type": "text",
"text": "shutup"
},
{
"type": "text",
"text": "shutthehellup"
}
],
"responses": [
{
"type": "text",
"text": "SILENCE"
},
{
"type": "emoji",
"emoji": "lessthan"
}
]
},
{
"conditions": [
{
"type": "and",
"conditions": [
{
"type": "text",
"text": "annoy"
},
{
"type": "random",
"chance": 0.5
}
]
}
],
"responses": [
{
"type": "text",
"text": "Stop annoying yourself."
}
]
}
]
}