This commit is contained in:
2024-10-29 15:20:28 +01:00
parent eb2960aa10
commit e955ef4e28
34 changed files with 201 additions and 476 deletions

9
gwendolyn/exceptions.py Normal file
View File

@ -0,0 +1,9 @@
class NoToken(Exception):
def __init__(self) -> None:
self.message = "No discord bot token has been set in the .env file"
super().__init__(self.message)
class MongoCannotConnect(Exception):
def __init__(self) -> None:
self.message = "Cannot connect to the mongo client"
super().__init__(self.message)

21
gwendolyn/ext/events.py Normal file
View File

@ -0,0 +1,21 @@
from interactions import Extension, listen, Status, Activity, ActivityType
from interactions.api.events import Startup, Error
class EventExtension(Extension):
"""Listens to miscellaneous events."""
@listen(Startup)
async def startup(self, _):
"""Log and sets status when it logs in."""
name = self.bot.user.username
userid = str(self.bot.user.id)
logged_in_message = f"Logged in as {name}, {userid}"
self.bot.log(logged_in_message, level=25)
command_list = ",".join([str(i.name) for i in self.bot.application_commands])
self.bot.log(f"Commands: {command_list}")
activity = Activity("custom", ActivityType.CUSTOM, state="Type `/help` for commands")
await self.bot.change_presence(activity=activity, status=Status.ONLINE)
@listen(Error)
async def error(self, err: Error):
self.bot.log(f"Error at {err.source}", level=25)

View File

@ -1,9 +1,41 @@
from interactions import Extension, slash_command, SlashContext
from interactions import Extension, slash_command, SlashContext, Status
from gwendolyn.utils import PARAMS as params
class MiscExtension(Extension):
"""Contains the miscellaneous commands."""
@slash_command()
@slash_command(**params["misc"]["hello"])
async def hello(self, ctx: SlashContext):
"""Greet the bot."""
await ctx.send(f"Hello, I'm {self.bot.user.mention}!")
await self.other.hello_func(ctx)
@slash_command(**params["misc"]["help"])
async def help(self, ctx: SlashContext, command=""):
"""Get help for commands."""
await self.bot.other.help_func(ctx, command)
@slash_command(**params["misc"]["ping"])
async def ping(self, ctx: SlashContext):
"""Send the bot's latency."""
await ctx.send(f"Pong!\nLatency is {round(self.bot.latency * 1000)}ms")
@slash_command(**params["misc"]["thank"])
async def thank(self, ctx: SlashContext):
"""Thank the bot."""
await ctx.send("You're welcome :blush:")
@slash_command(**params["misc"]["stop"])
async def stop(self, ctx: SlashContext):
if f"{ctx.author.id}" in self.bot.admins:
await ctx.send("Goodnight...")
await self.bot.change_presence(status=Status.INVISIBLE)
# self.bot.database_funcs.wipe_games()
self.bot.log("Logging out", level=25)
await self.bot.stop()
else:
log_message = f"{ctx.author.display_name} tried to stop me!"
self.bot.log(log_message, str(ctx.channel_id))
await ctx.send(f"I don't think I will, {ctx.author.display_name}")

View File

@ -0,0 +1,5 @@
"""A collection of all Gwendolyn functions."""
__all__ = ["Other"]
from .other import Other

View File

@ -0,0 +1,5 @@
"""Misc. functions for Gwendolyn."""
__all__ = ["Other"]
from .other import Other

View File

@ -0,0 +1,50 @@
import datetime # Used in hello_func
from interactions import SlashContext, Embed, SlashCommand
def gen_help_text(commands: list[SlashCommand]):
return '\n'.join([f"`/{i.name}`\t{i.description}" for i in commands])
class Other():
def __init__(self, bot):
self.bot = bot
# Responds with a greeting of a time-appropriate maner
async def hello_func(self, ctx: SlashContext):
def time_in_range(start, end, i):
# Return true if i is in the range [start, end]
if start <= end:
return start <= i <= end
else:
return start <= i or i <= end
author = ctx.author.display_name
now = datetime.datetime.now()
if time_in_range(now.replace(hour=5, minute=0, second=0, microsecond=0),now.replace(hour=10, minute=0, second=0, microsecond=0), now):
send_message = "Good morning, "+str(author)
elif time_in_range(now.replace(hour=13, minute=0, second=0, microsecond=0),now.replace(hour=18, minute=0, second=0, microsecond=0), now):
send_message = "Good afternoon, "+str(author)
elif time_in_range(now.replace(hour=18, minute=0, second=0, microsecond=0),now.replace(hour=22, minute=0, second=0, microsecond=0), now):
send_message = "Good evening, "+str(author)
elif time_in_range(now.replace(hour=22, minute=0, second=0, microsecond=0),now.replace(hour=23, minute=59, second=59, microsecond=0), now):
send_message = "Good night, "+str(author)
else:
send_message = "Hello, "+str(author)
await ctx.send(send_message)
async def help_func(self, ctx: SlashContext, command: str):
if command == "":
text = gen_help_text([i for i in self.bot.application_commands if isinstance(i,SlashCommand)])
embed = Embed(title = "Help", description = text,color = 0x59f442)
await ctx.send(embed = embed)
else:
self.bot.log(f"Looking for help-{command}.txt",str(ctx.channel_id))
try:
with open(f"gwendolyn/resources/help/help-{command}.txt",encoding="utf-8") as file_pointer:
text = file_pointer.read()
embed = Embed(title = command.capitalize(), description = text,color = 0x59f442)
await ctx.send(embed = embed)
except:
await ctx.send(f"Could not find a help file for the command '/{command}'")

View File

@ -1,10 +1,13 @@
from interactions import Client, Status
from gwendolyn.utils import log
from dotenv import load_dotenv
from os import getenv
from os import getenv, listdir
from interactions import Client, Status
from pymongo import MongoClient # Used for database management
from gwendolyn.utils import log
from gwendolyn.exceptions import NoToken, MongoCannotConnect
from gwendolyn.funcs import Other
class Gwendolyn(Client):
def __init__(self, testing: bool = True):
"""Initialize the bot."""
@ -17,27 +20,45 @@ class Gwendolyn(Client):
self.testing = testing
self._add_clients_and_options()
# self._add_util_classes()
# self._add_function_containers()
# self._add_cogs()
self._add_functions()
self._add_extensions()
def _add_clients_and_options(self):
"""Add all the client, option and credentials objects."""
load_dotenv()
self.bot_token = getenv("DISCORD_TOKEN")
if self.bot_token == "TOKEN":
raise NoToken()
self.admins = getenv("ADMINS").split(",")
mongo_user = getenv("MONGODB_USER")
mongo_password = getenv("MONGODB_PASSWORD")
mongo_url = f"mongodb+srv://{mongo_user}:{mongo_password}@gwendolyn"
mongo_url += ".qkwfy.mongodb.net/Gwendolyn?retryWrites=true&w=majority"
database_client = MongoClient(mongo_url)
try:
database_client.admin.command("ping")
except:
raise MongoCannotConnect()
if self.testing:
self.log("Testing mode")
self.database = database_client["Gwendolyn-Test"]
else:
self.database = database_client["Gwendolyn"]
def _add_functions(self):
self.other = Other(self)
def _add_extensions(self):
"""Load cogs."""
for filename in listdir("./gwendolyn/ext"):
if filename.endswith(".py"):
self.load_extension(f"gwendolyn.ext.{filename[:-3]}")
def log(self, messages, channel: str = "", level: int = 20): # pylint:disable=no-self-use
"""Log a message. Described in utils/util_functions.py."""
log(messages, channel, level)

View File

@ -1 +0,0 @@
Du kan søge efter en film ved at skrive `/add_movie [søgning]`. Gwendolyn vil derefter vise dig resultater baseret på din søgning. Du kan derfra reagere på Gwendolyns besked for at downloade en specifik film.

View File

@ -1 +0,0 @@
Du kan søge efter et show ved at skrive `/add_show [søgning]`. Gwendolyn vil derefter vise dig resultater baseret på din søgning. Du kan derfra reagere på Gwendolyns besked for at downloade et specifikt show.

View File

@ -1 +0,0 @@
Viser dig hvor mange GwendoBucks du har.

View File

@ -1 +0,0 @@
Kommandoen `/blackjack start` starter et spil blackjack. `/blackjack bet [beløb]` lader dig vædde en mængde af dine GwendoBucks. Du bruger `/blackjack hit`, `/blackjack stand`, `/blackjack split` og `/blackjack double` i løbet af spillet.

View File

@ -1 +0,0 @@
Brug `/connect_four start` til at starte et spil imod Gwendolyn. Brug `/connect_four start [modstander]` for at spille imod en anden person. Du kan også bruge `/connect_four start [1-5]`, hvor tallet er sværhedsgraden af Gwendolyn du gerne vil spille imod.

View File

@ -1,9 +0,0 @@
Viser dig de film og serier der er "requested" men ikke endnu på Plex. Kommandoen kan tage imod op til 4 parametre:
`-d`, `--downloading`, `--dm`, `--downloadManager` - Viser de torrents der er _ved_ at downloade. Hvis ingen parametre er givet, bliver det her parameter givet automatisk som det eneste.
`-m`, `--movies` - Viser de film der mangler.
`-s`, `--shows`, `--series` - Viser serier hvor alle afsnit mangler.
`-e`, `--episodes` - Viser de serier der mangler mindst 1 episode. Kan kun bruges hvis `-s` også bruges.

View File

@ -1 +0,0 @@
Du kan give GwendoBucks til andre med `/give [modtager] [antal]`, hvor [modtager] er den der skal modtage GwendoBucks og [antal] er hvor mange GwendoBucks du giver dem.

View File

@ -1 +0,0 @@
Brug `/hangman` til at starte et spil hangman. Brug derefter reaktionerne til at gætte bogstaver. Du har 6 gæt.

View File

@ -1 +0,0 @@
Hvis du bruger kommandoen `/hello`, sender Gwendolyn en venlig hilsen.

View File

@ -1 +0,0 @@
Brug `/hex start` til at starte et spil imod Gwendolyn. Brug "/hex start [modstander]" for at spille imod en anden person.

View File

@ -1 +0,0 @@
Finder et tilfældigt billede fra internettet.

View File

@ -1,2 +0,0 @@
Søg efter et monster i D&D med `/monster [monster]`, hvor [monster] er navnet på det monster du søger efter.
Hvis Gwendolyn ikke kan finde det, er det ofte fordi du har skrevet navnet forkert.

View File

@ -1 +0,0 @@
Giver titlen på en tilfældig film fra Plex.

View File

@ -1 +0,0 @@
Genererer et tilfældigt navn.

View File

@ -1,8 +0,0 @@
Rul terninger i xdy format. Kan udføre matematik udover rullende. Kan også gøre følgende:
`kx` - Beholder kun rul med værdien x.
`rox` - Genrul rul med værdien x første gang.
`rrx` - Genrul alle rul med værdien x
`mix` - Gør alle rul under x til x.
`max` - Gør alle rul over x til x.
`rax` - Genruller og tilføjer rul med værdien x.
`l/h` før x - For de laveste/højeste x rul.

View File

@ -1,2 +0,0 @@
Søg efter en spell i D&D med `/spell [spell]`, hvor [spell] er navnet på den spell du søger efter.
Hvis Gwendolyn ikke kan finde den, er det ofte fordi du har skrevet navnet forkert.

View File

@ -1 +0,0 @@
Du kan bruge kommandoer som `/star_wars_character name Jared` eller `/star_wars_character skills astrogation 3` til at ændre din karakters info. Kommandoen `/star_wars_character` vil give dig et character sheet for din karakter.

View File

@ -1 +0,0 @@
Lader dig rulle Star Wars terninger. Du kan skrive tal der repræsenterer antallet af hver terning i rækkefølgen: ability, proficiency, difficulty, challenge, boost, setback og force. Du behøver ikke skrive et tal til alle terningerne. Du kan også skrive forbogstavet for terningen du vil rulle før antallet, såsom "/star_wars_roll f2", der ruller 2 force terninger.

View File

@ -1 +0,0 @@
Genererer en tilfældig tavern.

View File

@ -1 +0,0 @@
Lader dig takke Gwendolyn.

View File

@ -1,4 +0,0 @@
Lader dig spille et spil trivia. `/trivia` starter spillet.
Hvert spil trivia varer i 1 minut, og der kan kun være et enkelt spil i hver kanal ad gangen.
`/trivia [svar]` lader dig svare på det nuværende spørgsmål, hvor [svar] er a, b, c eller d.
Hvis du svarer rigtigt får du 1 GwendoBuck.

View File

@ -1 +0,0 @@
Lader dig slå ting op på Wolfram Alpha.

View File

@ -1,23 +0,0 @@
`/hello` - En venlig hilsen.
`/roll` - Rul terninger i xdy format.
`/spell` - Slå en besværgelse op.
`/monster` - Slå et monster op.
`/image` - Finder et tilfældigt billede fra internettet.
`/movie` - Giver titlen på en tilfældig film fra Plex
`/name` - Genererer et tilfældigt navn.
`/tavern` - Genererer en tilfældig tavern.
`/give` - Lader dig give GwendoBucks til andre.
`/star_wars_character` - Lader dig lave en Star Wars karakter.
`/star_wars_roll` - Lader dig rulle Star Wars terninger.
`/balance` - Viser dig hvor mange GwendoBucks du har.
`/blackjack` - Lader dig spille et spil blackjack.
`/trivia` - Lader dig spille et spil trivia, hvor du kan tjene GwendoBucks.
`/connect_four` - Lader dig spille et spil fire på stribe.
`/hex` - Lader dig spille et spil Hex.
`/hangman` - Lader dig spille et spil hangman.
`/wolf` - Lader dig slå ting op på Wolfram Alpha.
`/add_movie` - Lader dig tilføje film til Plex.
`/add_show` - Lader dig tilføje tv shows til Plex.
`/downloading` - Viser dig hvor langt de torrents der er ved at downloade er kommet.
`/thank` - Lader dig takke Gwendolyn.
Du kan få ekstra information om kommandoerne med "/help [kommando]".

View File

@ -1,401 +1,32 @@
{
"add_movie" : {
"name" : "add_movie",
"description" : "Request a movie for Plex",
"options" : [
{
"name" : "movie",
"description" : "The movie to request",
"type" : 3,
"required" : "true"
}
]
},
"add_show" : {
"name" : "add_show",
"description" : "Request a show for Plex",
"options" : [
{
"name" : "show",
"description" : "The show to request",
"type" : 3,
"required" : "true"
}
]
},
"balance" : {
"name" : "balance",
"description" : "See your balance of GwendoBucks"
},
"blackjack_bet" : {
"base" : "blackjack",
"name" : "bet",
"description" : "Enter the current blackjack game with a bet",
"options" : [
{
"name" : "bet",
"description" : "Your bet",
"type" : 4,
"required" : "true"
}
]
},
"blackjack_cards" : {
"base" : "blackjack",
"name" : "cards",
"description" : "Get a count of the cards used in blackjack games"
},
"blackjack_hilo" : {
"base" : "blackjack",
"name" : "hilo",
"description" : "Get the current hi-lo value for the cards used in blackjack games"
},
"blackjack_shuffle" : {
"base" : "blackjack",
"name" : "shuffle",
"description" : "Shuffle the cards used in blackjack games"
},
"blackjack_start" : {
"base" : "blackjack",
"name" : "start",
"description" : "Start a game of blackjack"
},
"connect_four_start_gwendolyn" : {
"base" : "connect_four",
"subcommand_group" : "start",
"name" : "Gwendolyn",
"description" : "Start a game of connect four against Gwendolyn",
"options" : [
{
"name" : "difficulty",
"description" : "The difficulty of Gwendolyn's AI",
"type" : 4,
"required" : "false"
}
]
},
"connect_four_start_user" : {
"base" : "connect_four",
"subcommand_group" : "start",
"name" : "user",
"description" : "Start a game of connect four against another user",
"options" : [
{
"name" : "user",
"description" : "The user to start a game against",
"type" : 6,
"required" : "true"
}
]
},
"downloading" : {
"name" : "downloading",
"description" : "See current downloads for Plex",
"options" : [
{
"name" : "parameters",
"description" : "Parameters for the command",
"type" : 3,
"required" : "false"
}
]
},
"game" : {
"name" : "game",
"description" : "Set the 'playing' text for Gwendolyn",
"options" : [
{
"name" : "game_text",
"description" : "The game to set the 'playing' text to",
"type" : 3,
"required" : "true"
}
]
},
"give" : {
"name" : "give",
"description" : "Give GwendoBucks to another user",
"options" : [
{
"name" : "user",
"description" : "The user you're sending GwendoBucks to",
"type" : 6,
"required" : "true"
},
{
"name" : "amount",
"description" : "The number of GwendoBucks you're sending",
"type" : 4,
"required" : "true"
}
]
},
"hangman" : {
"name" : "hangman",
"description" : "Start a game of hangman"
},
"hello" : {
"name" : "hello",
"description" : "Greet Gwendolyn"
},
"help" : {
"name" : "help",
"description" : "Get help with a command",
"options" : [
{
"name" : "command",
"description" : "The command you want help with",
"type" : 3,
"required" : "false"
}
]
},
"hex_place" : {
"base" : "hex",
"name" : "place",
"description" : "Place a piece on the hex board",
"options" : [
{
"name" : "coordinates",
"description" : "The coordinates to place the piece at",
"type" : 3,
"required" : "true"
}
]
},
"hex_start_gwendolyn" : {
"base" : "hex",
"subcommand_group" : "start",
"name" : "Gwendolyn",
"description" : "Start a game of hex against Gwendolyn",
"options" : [
{
"name" : "difficulty",
"description" : "The difficulty of Gwendolyn's AI",
"type" : 4,
"required" : "false"
}
]
},
"hex_start_user" : {
"base" : "hex",
"subcommand_group" : "start",
"name" : "user",
"description" : "Start a game of hex against another user",
"options" : [
{
"name" : "user",
"description" : "The user to start a game against",
"type" : 6,
"required" : "true"
}
]
},
"hex_surrender" : {
"base" : "hex",
"name" : "surrender",
"description" : "Surrender the game of hex"
},
"hex_swap" : {
"base" : "hex",
"name" : "swap",
"description" : "Perform a hex swap"
},
"hex_undo" : {
"base" : "hex",
"name" : "undo",
"description" : "Undo your last hex move"
},
"image" : {
"name" : "image",
"description" : "Get a random image from Bing"
},
"monster" : {
"name" : "monster",
"description" : "Look up a monster",
"options" : [
{
"name" : "query",
"description" : "The monster to look up",
"type" : 3,
"required" : "true"
}
]
},
"movie" : {
"name" : "movie",
"description" : "Get the name and information of a random movie"
},
"name" : {
"name" : "name",
"description" : "Generate a random name"
},
"ping" : {
"name" : "ping",
"description" : "Get the Gwendolyn's latency to the server"
},
"roll" : {
"name" : "roll",
"description" : "Roll rpg dice",
"options" : [
{
"name" : "dice",
"description" : "The dice to roll",
"type" : 3,
"required" : "false"
}
]
},
"spell" : {
"name" : "spell",
"description" : "Look up a spell",
"options" : [
{
"name" : "query",
"description" : "The spell to look up",
"type" : 3,
"required" : "true"
}
]
},
"star_wars_character" : {
"name" : "star_wars_character",
"description" : "Manage your Star Wars character sheet",
"options" : [
{
"name" : "parameters",
"description" : "The parameters for the command",
"type" : 3,
"required" : "false"
}
]
},
"star_wars_crit" : {
"name" : "star_wars_crit",
"description" : "Roll a Star Wars critical injury",
"options" : [
{
"name" : "severity",
"description" : "The severity of the hit",
"type" : 4,
"required" : "true"
}
]
},
"star_wars_destiny" : {
"name" : "star_wars_destiny",
"description" : "Use and see Star Wars Destiny points",
"options" : [
{
"name" : "parameters",
"description" : "The parameters for the command",
"type" : 3,
"required" : "false"
}
]
},
"star_wars_roll" : {
"name" : "star_wars_roll",
"description" : "Roll Star Wars dice",
"options" : [
{
"name" : "dice",
"description" : "The dice, or ability, to roll",
"type" : 3,
"required" : "false"
}
]
},
"stop" : {
"name" : "stop",
"description" : "Restart Gwendolyn"
},
"tavern" : {
"name" : "tavern",
"description" : "Generate a random tavern"
},
"thank" : {
"name" : "thank",
"description" : "Thank Gwendolyn for her service"
},
"trivia" : {
"name" : "trivia",
"description" : "Play a game of trivia",
"options" : [
{
"name" : "answer",
"description" : "Your answer to the trivia question",
"type" : 3,
"required" : "false",
"choices" : [
{
"name" : "a",
"value" : "a"
},
{
"name" : "b",
"value" : "b"
},
{
"name" : "c",
"value" : "c"
},
{
"name" : "d",
"value" : "d"
}
]
}
]
},
"wiki" : {
"name" : "wiki",
"description" : "Searches for and gets the info for a wiki page",
"options" : [
{
"name" : "page",
"description" : "The page to find",
"type" : 3,
"required" : "false"
}
]
},
"wolf" : {
"name" : "wolf",
"description" : "Performs a search on Wolfram Alpha",
"options" : [
{
"name" : "query",
"description" : "What to search for on Wolfram Alpha",
"type" : 3,
"required" : "true"
}
]
},
"wordle_start": {
"base": "wordle",
"name" : "start",
"description": "Start a game of wordle",
"options": [
{
"name": "letters",
"description" : "How many letters the word should be",
"type": 4,
"required": "false"
}
]
},
"wordle_guess": {
"base": "wordle",
"name" : "guess",
"description": "Guess a word in wordle",
"options": [
{
"name": "guess",
"description" : "Your guess",
"type": 3,
"required": "true"
}
]
"misc": {
"hello" : {
"name" : "hello",
"description" : "Greet Gwendolyn"
},
"help" : {
"name" : "help",
"description" : "Get help with a command",
"options" : [
{
"name" : "command",
"description" : "The command you want help with",
"type" : 3,
"required" : "false"
}
]
},
"ping" : {
"name" : "ping",
"description" : "Get the Gwendolyn's latency to the server"
},
"stop" : {
"name" : "stop",
"description" : "Stop Gwendolyn"
},
"thank" : {
"name" : "thank",
"description" : "Thank Gwendolyn for her service"
}
}
}

View File

@ -1,5 +1,5 @@
"""A collections of utilities used by Gwendolyn and her functions."""
__all__ = ["make_files","log"]
__all__ = ["make_files","log","PARAMS"]
from .util_functions import make_files, log
from .util_functions import make_files, log, PARAMS

View File

@ -23,6 +23,23 @@ handler.setFormatter(logging.Formatter(fmt=PRINTFORMAT, datefmt=DATEFORMAT))
printer.addHandler(handler)
printer.propagate = False
def get_params():
"""
Get the slash command parameters.
*Returns*
---------
params: dict
The parameters for every slash command.
"""
path = "gwendolyn/resources/slash_parameters.json"
with open(path, "r", encoding="utf-8") as file_pointer:
slash_parameters = json.load(file_pointer)
return slash_parameters
PARAMS = get_params()
def log(messages, channel: str = "", level: int = 20):
"""
Log something in Gwendolyn's logs.

View File

@ -10,7 +10,6 @@ def main():
# Creates the Bot
bot = Gwendolyn()
bot.load_extension("gwendolyn.ext.misc")
bot.start()
if __name__ == "__main__":