diff --git a/README.md b/README.md index 7f6fffd..0d57401 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,6 @@ Gwendolyn is a discord bot that I made. It does a bunch of stuff. * Roll Star Wars RPG dice! * Keep track of Star Wars RPG character sheets! * Query Wolfram Alpha -* Invest fake money in the stock market * Play trivia, connect 4, blackjack, hangman and hex And much more!!! (not really. That's pretty much all it can do. See help files in resources directory for list of commands) diff --git a/gwendolyn/__init__.py b/gwendolyn/__init__.py index 17b7d0d..95165ca 100644 --- a/gwendolyn/__init__.py +++ b/gwendolyn/__init__.py @@ -1,6 +1,5 @@ """The main module for Gwendolyn.""" -# pylint: disable=invalid-name -__all__ = ["funcs", "utils", "Gwendolyn"] +__all__ = ["Gwendolyn"] from .gwendolyn_client import Gwendolyn diff --git a/gwendolyn/ext/misc.py b/gwendolyn/ext/misc.py new file mode 100644 index 0000000..3464a74 --- /dev/null +++ b/gwendolyn/ext/misc.py @@ -0,0 +1,9 @@ +from interactions import Extension, slash_command, SlashContext + +class MiscExtension(Extension): + """Contains the miscellaneous commands.""" + + @slash_command() + async def hello(self, ctx: SlashContext): + """Greet the bot.""" + await ctx.send(f"Hello, I'm {self.bot.user.mention}!") \ No newline at end of file diff --git a/gwendolyn/funcs/games/invest.py b/gwendolyn/funcs/games/invest.py deleted file mode 100644 index eaac8f0..0000000 --- a/gwendolyn/funcs/games/invest.py +++ /dev/null @@ -1,286 +0,0 @@ -""" -Contains functions relating to invest commands. - -*Classes* ---------- - Invest - Contains all the code for the invest commands. -""" -import discord # Used for embeds -from discord_slash.context import SlashContext # Used for type hints - - -class Invest(): - """ - Contains all the invest functions. - - *Methods* - --------- - getPrice(symbol: str) -> int - getPortfolio(user: str) -> str - buyStock(user: str, stock: str: buyAmount: int) -> str - sellStock(user: str, stock: str, buyAmount: int) -> str - parseInvest(ctx: discord_slash.context.SlashContext, - parameters: str) - """ - - def __init__(self, bot): - """Initialize the class.""" - self.bot = bot - - def getPrice(self, symbol: str): - """ - Get the price of a stock. - - *Parameters* - ------------ - symbol: str - The symbol of the stock to get the price of. - - *Returns* - --------- - price: int - The price of the stock. - """ - res = self.bot.finnhub_client.quote(symbol.upper()) - if res == {}: - return 0 - else: - return int(res["c"] * 100) - - def getPortfolio(self, user: str): - """ - Get the stock portfolio of a user. - - *Parameters* - ------------ - user: str - The id of the user to get the portfolio of. - - *Returns* - --------- - portfolio: str - The portfolio. - """ - investments_database = self.bot.database["investments"] - userInvestments = investments_database.find_one({"_id": user}) - - user_name = self.bot.database_funcs.get_name(user) - - if userInvestments in [None, {}]: - return f"{user_name} does not have a stock portfolio." - else: - portfolio = f"**Stock portfolio for {user_name}**" - - for key, value in list(userInvestments["investments"].items()): - purchaseValue = value["purchased for"] - stockPrice = self.getPrice(key) - valueAtPurchase = value["value at purchase"] - purchasedStock = value["purchased"] - valueChange = (stockPrice / valueAtPurchase) - currentValue = int(valueChange * purchasedStock) - portfolio += f"\n**{key}**: ___{currentValue} GwendoBucks___" - - if purchaseValue != "?": - portfolio += f" (purchased for {purchaseValue})" - - return portfolio - - def buyStock(self, user: str, stock: str, buyAmount: int): - """ - Buy an amount of a specific stock. - - *Paramaters* - ------------ - user: str - The id of the user buying. - stock: str - The symbol of the stock to buy. - buyAmount: int - The amount of GwendoBucks to use to buy the stock. - - *Returns* - --------- - send_message: str - The message to return to the user. - """ - if buyAmount < 100: - return "You cannot buy stocks for less than 100 GwendoBucks" - elif self.bot.money.checkBalance(user) < buyAmount: - return "You don't have enough money for that" - elif self.getPrice(stock) <= 0: - return f"{stock} is not traded on the american market." - else: - investments_database = self.bot.database["investments"] - stockPrice = self.getPrice(stock) - userInvestments = investments_database.find_one({"_id": user}) - - self.bot.money.addMoney(user, -1*buyAmount) - stock = stock.upper() - - if userInvestments is not None: - userInvestments = userInvestments["investments"] - if stock in userInvestments: - value = userInvestments[stock] - valueChange = (stockPrice / value["value at purchase"]) - currentValue = int(valueChange * value["purchased"]) - newAmount = currentValue + buyAmount - - value_path = f"investments.{stock}.value at purchase" - updater = {"$set": {value_path: stockPrice}} - investments_database.update_one({"_id": user}, updater) - - purchased_path = f"investments.{stock}.purchased" - updater = {"$set": {purchased_path: newAmount}} - investments_database.update_one({"_id": user}, updater) - - if value["purchased for"] != "?": - purchasedFor_path = f"investments.{stock}.purchased for" - updater = {"$set": {purchasedFor_path: buyAmount}} - investments_database.update_one({"_id": user}, updater) - else: - updater = { - "$set": { - "investments.{stock}": { - "purchased": buyAmount, - "value at purchase": stockPrice, - "purchased for": buyAmount - } - } - } - investments_database.update_one({"_id": user}, updater) - else: - new_user = { - "_id": user, - "investments": { - stock: { - "purchased": buyAmount, - "value at purchase": stockPrice, - "purchased for": buyAmount - } - } - } - investments_database.insert_one(new_user) - - user_name = self.bot.database_funcs.get_name(user) - send_message = "{} bought {} GwendoBucks worth of {} stock" - send_message = send_message.format(user_name, buyAmount, stock) - return send_message - - def sellStock(self, user: str, stock: str, sellAmount: int): - """ - Sell an amount of a specific stock. - - *Paramaters* - ------------ - user: str - The id of the user selling. - stock: str - The symbol of the stock to sell. - buyAmount: int - The amount of GwendoBucks to sell for. - - *Returns* - --------- - send_message: str - The message to return to the user. - """ - if sellAmount <= 0: - return "no" - else: - investments_database = self.bot.database["investments"] - user_data = investments_database.find_one({"_id": user}) - userInvestments = user_data["investments"] - - stock = stock.upper() - - if userInvestments is not None and stock in userInvestments: - value = userInvestments[stock] - stockPrice = self.getPrice(stock) - priceChange = (stockPrice / value["value at purchase"]) - purchasedAmount = int(priceChange * value["purchased"]) - purchased_path = f"investments.{stock}.purchased" - updater = {"$set": {purchased_path: purchasedAmount}} - investments_database.update_one({"_id": user}, updater) - valueAtPurchase_path = f"investments.{stock}.value at purchase" - updater = {"$set": {valueAtPurchase_path: stockPrice}} - investments_database.update_one({"_id": user}, updater) - if value["purchased"] >= sellAmount: - self.bot.money.addMoney(user, sellAmount) - if sellAmount < value["purchased"]: - purchased_path = f"investments.{stock}.purchased" - updater = {"$inc": {purchased_path: -sellAmount}} - investments_database.update_one({"_id": user}, updater) - - purchasedFor_path = f"investments.{stock}.purchased for" - updater = {"$set": {purchasedFor_path: "?"}} - investments_database.update_one({"_id": user}, updater) - else: - updater = {"$unset": {f"investments.{stock}": ""}} - investments_database.update_one({"_id": user}, updater) - - user_name = self.bot.database_funcs.get_name(user) - send_message = "{} sold {} GwendoBucks worth of {} stock" - return send_message.format(user_name, sellAmount, stock) - else: - return f"You don't have enough {stock} stocks to do that" - else: - return f"You don't have any {stock} stock" - - async def parseInvest(self, ctx: SlashContext, parameters: str): - """ - Parse an invest command. TO BE DELETED. - - *Parameters* - ------------ - ctx: discord_slash.context.SlashContext - The context of the slash command. - parameters: str - The parameters of the command. - """ - await self.bot.defer(ctx) - user = f"#{ctx.author.id}" - - if parameters.startswith("check"): - commands = parameters.split(" ") - if len(commands) == 1: - response = self.getPortfolio(user) - else: - price = self.getPrice(commands[1]) - if price == 0: - response = "{} is not traded on the american market." - response = response.format(commands[0].upper()) - else: - price = f"{price:,}".replace(",", ".") - response = self.bot.long_strings["Stock value"] - response = response.format(commands[1].upper(), price) - - elif parameters.startswith("buy"): - commands = parameters.split(" ") - if len(commands) == 3: - response = self.buyStock(user, commands[1], int(commands[2])) - else: - response = self.bot.long_strings["Stock parameters"] - - elif parameters.startswith("sell"): - commands = parameters.split(" ") - if len(commands) == 3: - response = self.sellStock(user, commands[1], int(commands[2])) - else: - response = self.bot.long_strings["Stock parameters"] - - else: - response = "Incorrect parameters" - - if response.startswith("**"): - responses = response.split("\n") - text = "\n".join(responses[1:]) - embedParams = { - "title": responses[0], - "description": text, - "colour": 0x00FF00 - } - em = discord.Embed(**embedParams) - await ctx.send(embed=em) - else: - await ctx.send(response) diff --git a/gwendolyn/gwendolyn_client.py b/gwendolyn/gwendolyn_client.py index d77fd82..d25d5b2 100644 --- a/gwendolyn/gwendolyn_client.py +++ b/gwendolyn/gwendolyn_client.py @@ -1,135 +1,40 @@ -""" -Contains the Gwendolyn class, a subclass of the discord command bot. - -*Classes* ---------- - Gwendolyn(discord.ext.commands.Bot) -""" -import os # Used for loading cogs in Gwendolyn.addCogs -import finnhub # Used to add a finhub client to the bot -import discord # Used for discord.Intents and discord.Status -import discord_slash # Used to initialized SlashCommands object -import git # Used to pull when stopping - -from discord.ext import commands # Used to inherit from commands.bot -from pymongo import MongoClient # Used for database management -from gwendolyn.funcs import Money, StarWars, Games, Other, LookupFuncs -from gwendolyn.utils import (get_options, get_credentials, log_this, - DatabaseFuncs, EventHandler, ErrorHandler, - long_strings) - - -class Gwendolyn(commands.Bot): - """ - A multifunctional Discord bot. - - *Methods* - --------- - log(messages: Union[str, list], channel: str = "", - level: int = 20) - stop(ctx: discord_slash.context.SlashContext) - defer(ctx: discord_slash.context.SlashContext) - """ - # pylint: disable=too-many-instance-attributes - - def __init__(self): - """Initialize the bot.""" - intents = discord.Intents.default() - intents.members = True - initiation_parameters = { - "command_prefix": " ", - "case_insensitive": True, - "intents": intents, - "status": discord.Status.dnd - } - super().__init__(**initiation_parameters) - - self._add_clients_and_options() - self._add_util_classes() - self._add_function_containers() - self._add_cogs() - - def _add_clients_and_options(self): - """Add all the client, option and credentials objects.""" - self.long_strings = long_strings() - self.options = get_options() - self.credentials = get_credentials() - finnhub_key = self.credentials["finnhub_key"] - self.finnhub_client = finnhub.Client(api_key=finnhub_key) - mongo_user = self.credentials["mongo_db_user"] - mongo_password = self.credentials["mongo_db_password"] - mongo_url = f"mongodb+srv://{mongo_user}:{mongo_password}@gwendolyn" - mongo_url += ".qkwfy.mongodb.net/Gwendolyn?retryWrites=true&w=majority" - database_clint = MongoClient(mongo_url) - - if self.options["testing"]: - self.log("Testing mode") - self.database = database_clint["Gwendolyn-Test"] - else: - self.database = database_clint["Gwendolyn"] - - def _add_util_classes(self): - """Add all the classes used as utility.""" - self.database_funcs = DatabaseFuncs(self) - self.event_handler = EventHandler(self) - self.error_handler = ErrorHandler(self) - slash_parameters = { - "sync_commands": True, - "sync_on_cog_reload": True, - "override_type": True - } - self.slash = discord_slash.SlashCommand(self, **slash_parameters) - - def _add_function_containers(self): - """Add all the function containers used for commands.""" - self.star_wars = StarWars(self) - self.other = Other(self) - self.lookup_funcs = LookupFuncs(self) - self.games = Games(self) - self.money = Money(self) - - def _add_cogs(self): - """Load cogs.""" - for filename in os.listdir("./gwendolyn/cogs"): - if filename.endswith(".py"): - self.load_extension(f"gwendolyn.cogs.{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_this(messages, channel, level) - - async def stop(self, ctx: discord_slash.context.SlashContext): - """ - Stop the bot, and stop running games. - - Only stops the bot if the user in ctx.author is one of the - admins given in options.txt. - - *parameters* - ------------ - ctx: discord_slash.context.SlashContext - The context of the "/stop" slash command. - """ - if f"#{ctx.author.id}" in self.options["admins"]: - await ctx.send("Pulling git repo and restarting...") - - await self.change_presence(status=discord.Status.offline) - - self.database_funcs.wipe_games() - if not self.options["testing"]: - git_client = git.cmd.Git("") - git_client.pull() - - self.log("Logging out", level=25) - await self.close() - else: - log_message = f"{ctx.author.display_name} tried to stop me!" - self.log(log_message, str(ctx.channel_id)) - await ctx.send(f"I don't think I will, {ctx.author.display_name}") - - async def defer(self, ctx: discord_slash.context.SlashContext): - """Send a "Gwendolyn is thinking" message to the user.""" - try: - await ctx.defer() - except discord_slash.error.AlreadyResponded: - self.log("defer failed") +from interactions import Client, Status +from gwendolyn.utils import get_options, get_credentials, long_strings, log + +from pymongo import MongoClient # Used for database management + +class Gwendolyn(Client): + + def __init__(self): + """Initialize the bot.""" + initiation_parameters = { + "status": Status.DND, + "delete_unused_application_cmds": True + } + super().__init__(**initiation_parameters) + + self._add_clients_and_options() + # self._add_util_classes() + # self._add_function_containers() + # self._add_cogs() + + def _add_clients_and_options(self): + """Add all the client, option and credentials objects.""" + self.long_strings = long_strings() + self.options = get_options() + self.credentials = get_credentials() + mongo_user = self.credentials["mongo_db_user"] + mongo_password = self.credentials["mongo_db_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) + + if self.options["testing"]: + self.log("Testing mode") + self.database = database_client["Gwendolyn-Test"] + else: + self.database = database_client["Gwendolyn"] + + 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) \ No newline at end of file diff --git a/gwendolyn/resources/help/help-invest.txt b/gwendolyn/resources/help/help-invest.txt deleted file mode 100644 index 4228ab0..0000000 --- a/gwendolyn/resources/help/help-invest.txt +++ /dev/null @@ -1,3 +0,0 @@ -`/invest` vil vise dig hvilke aktier du har. `/invest check [symbol]` viser dig en akties nuværende pris, hvor [symbol] er forkortelsen for firmaet. GwendoBucks er lig med 1 amerikans cent. -`/invest buy [symbol] [pris]` lader dig købe aktier. [pris] er mængden af GwendoBucks du bruger på at købe. Du kan købe for færre GwendoBucks end en enkelt akties pris, men ikke for mindre end 100 GwendoBucks. -`/invest buy [symbol] [pris]` lader dig sælge dine aktier. Du kan godt sælge for mindre end 100 GwendoBucks. \ No newline at end of file diff --git a/gwendolyn/resources/help/help.txt b/gwendolyn/resources/help/help.txt index 74da75f..1cfdeac 100644 --- a/gwendolyn/resources/help/help.txt +++ b/gwendolyn/resources/help/help.txt @@ -10,7 +10,6 @@ `/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. -`/invest` - Lader dig investere dine GwendoBucks i aktiemarkedet. `/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. diff --git a/gwendolyn/resources/slash_parameters.json b/gwendolyn/resources/slash_parameters.json index cd5a4d1..9011ff5 100644 --- a/gwendolyn/resources/slash_parameters.json +++ b/gwendolyn/resources/slash_parameters.json @@ -206,18 +206,6 @@ "name" : "undo", "description" : "Undo your last hex move" }, - "invest" : { - "name" : "invest", - "description" : "Invest GwendoBucks in the stock market", - "options" : [ - { - "name" : "parameters", - "description" : "The parameters for the command", - "type" : 3, - "required" : "false" - } - ] - }, "image" : { "name" : "image", "description" : "Get a random image from Bing" diff --git a/gwendolyn/resources/starting_files.json b/gwendolyn/resources/starting_files.json index 1495f31..d370a78 100644 --- a/gwendolyn/resources/starting_files.json +++ b/gwendolyn/resources/starting_files.json @@ -59,7 +59,7 @@ "gwendolyn/resources/star_wars/destinyPoints.txt": "", "gwendolyn/resources/movies.txt": "The Room", "gwendolyn/resources/names.txt": "Gandalf\n", - "credentials.txt" : "Bot token: TOKEN\nFinnhub API key: KEY\nWordnik API Key: KEY\nMongoDB user: USERNAME\nMongoDB password: PASSWORD\nWolframAlpha AppID: APPID\nRadarr API key: KEY\nSonarr API key: KEY\nqBittorrent username: USER\nqBittorrent password: PASSWORD", + "credentials.txt" : "Bot token: TOKEN\nWordnik API Key: KEY\nMongoDB user: USERNAME\nMongoDB password: PASSWORD\nWolframAlpha AppID: APPID\nRadarr API key: KEY\nSonarr API key: KEY\nqBittorrent username: USER\nqBittorrent password: PASSWORD", "options.txt" : "Testing: True\nTesting guild ids:\nAdmins:" }, "folder" : [ diff --git a/gwendolyn/utils/__init__.py b/gwendolyn/utils/__init__.py index c8353c0..4acd975 100644 --- a/gwendolyn/utils/__init__.py +++ b/gwendolyn/utils/__init__.py @@ -1,12 +1,5 @@ """A collections of utilities used by Gwendolyn and her functions.""" -__all__ = ["get_options", "get_credentials", "DatabaseFuncs", "EventHandler", - "ErrorHandler", "get_params", "log_this", "cap", "make_files", - "replace_multiple", "emoji_to_command"] +__all__ = ["make_files","get_options", "get_credentials", "long_strings", "log"] -from .helper_classes import DatabaseFuncs -from .event_handlers import EventHandler, ErrorHandler -from .util_functions import (get_params, log_this, cap, make_files, - replace_multiple, emoji_to_command, long_strings, - sanitize, get_options, get_credentials, encode_id, - decode_id) +from .util_functions import make_files, get_options, get_credentials, long_strings, log diff --git a/gwendolyn/utils/util_functions.py b/gwendolyn/utils/util_functions.py index 9689533..b5736e2 100644 --- a/gwendolyn/utils/util_functions.py +++ b/gwendolyn/utils/util_functions.py @@ -1,37 +1,7 @@ -""" -Contains utility functions used by parts of the bot. - -*Functions* ------------ - sanitize(data: str, lower_case_value: bool = false) -> dict - get_options() -> dict - get_credentials() -> dict - long_strings() -> dict - get_params() -> dict - log_this(messages: Union[str, list], channel: str = "", - level: int = 20) - cap(s: str) -> str - make_files() - replace_multiple(main_string: str, to_be_replaced: list, - new_string: str) -> str - emoji_to_command(emoji: str) -> str -""" -import string import json # Used by long_strings(), get_params() and make_files() import logging # Used for logging import os # Used by make_files() to check if files exist import sys # Used to specify printing for logging -import imdb # Used to disable logging for the module - - -BASE_37 = ":" + string.digits + string.ascii_uppercase -BASE_128 = list( - string.digits + - string.ascii_letters + - "!#$€£¢¥¤&%()*+,-./;:<=>?@[]_{|}~ `¦§©®«»±µ·¿əʒ" + - "ÆØÅÐÉÈÊÇÑÖ" + - "æøåðéèêçñö" -) # All of this is logging configuration FORMAT = " %(asctime)s | %(name)-16s | %(levelname)-8s | %(message)s" @@ -53,10 +23,6 @@ handler.setFormatter(logging.Formatter(fmt=PRINTFORMAT, datefmt=DATEFORMAT)) printer.addHandler(handler) printer.propagate = False -imdb._logging.setLevel("CRITICAL") # pylint: disable=protected-access -# Basically disables imdbpy logging, since it's being printed to the -# terminal. - def sanitize(data: str, lower_case_value: bool = False): """ Sanitize and create a dictionary from a string. @@ -134,7 +100,6 @@ def get_credentials(): credentials = {} credentials["token"] = data["bot token"] - credentials["finnhub_key"] = data["finnhub api key"] credentials["wordnik_key"] = data["wordnik api key"] credentials["mongo_db_user"] = data["mongodb user"] credentials["mongo_db_password"] = data["mongodb password"] @@ -161,30 +126,7 @@ def long_strings(): return data - -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) - - options = get_options() - - if options["testing"]: - for parameter in slash_parameters: - slash_parameters[parameter]["guild_ids"] = options["guild_ids"] - - return slash_parameters - - -def log_this(messages, channel: str = "", level: int = 20): +def log(messages, channel: str = "", level: int = 20): """ Log something in Gwendolyn's logs. @@ -222,49 +164,19 @@ def log_this(messages, channel: str = "", level: int = 20): for log_message in messages: logger.log(level, log_message) - -def cap(input_string: str): - """ - Capitalize a string like a movie title. - - That means "of" and "the" are not capitalized. - - *Parameters* - ------------ - input_string: str - The string to capitalized. - - *Returns* - --------- - return_string: str - The capitalized string. - """ - no_caps_list = ["of", "the"] - word_number = 0 - string_list = input_string.split() - return_string = '' - for word in string_list: - word_number += 1 - if word not in no_caps_list or word_number == 1: - word = word.capitalize() - return_string += word+" " - return_string = return_string[:-1] - return return_string - - def make_files(): """Create all the files and directories needed by Gwendolyn.""" def make_json_file(path, content): """Create json file if it doesn't exist.""" if not os.path.isfile(path): - log_this(path.split("/")[-1]+" didn't exist. Making it now.") + log(path.split("/")[-1]+" didn't exist. Making it now.") with open(path, "w", encoding="utf-8") as file_pointer: json.dump(content, file_pointer, indent=4) def make_txt_file(path, content): """Create txt file if it doesn't exist.""" if not os.path.isfile(path): - log_this(path.split("/")[-1]+" didn't exist. Making it now.") + log(path.split("/")[-1]+" didn't exist. Making it now.") with open(path, "w", encoding="utf-8") as file_pointer: file_pointer.write(content) @@ -272,121 +184,18 @@ def make_files(): """Create directory if it doesn't exist.""" if not os.path.isdir(path): os.makedirs(path) - log_this("The "+path.split("/")[-1]+" directory didn't exist") + log("The "+path.split("/")[-1]+" directory didn't exist") file_path = "gwendolyn/resources/starting_files.json" with open(file_path, "r", encoding="utf-8") as file_pointer: data = json.load(file_pointer) + for path in data["folder"]: + directory(path) + for path, content in data["json"].items(): make_json_file(path, content) for path, content in data["txt"].items(): make_txt_file(path, content) - for path in data["folder"]: - directory(path) - - -def replace_multiple(main_string: str, to_be_replaced: list, new_string: str): - """ - Replace multiple substrings in a string with the same substring. - - *Parameters* - ------------ - main_string: str - The string to replace substrings in. - to_be_replaced: list - The substrings to replace. - new_string: str - The string to replace the substrings with. - - *Returns* - --------- - main_string: str - The string with the substrings replaced. - """ - # Iterate over the strings to be replaced - for elem in to_be_replaced: - # Check if string is in the main string - if elem in main_string: - # Replace the string - main_string = main_string.replace(elem, new_string) - - return main_string - - -def emoji_to_command(emoji: str): - """ - Convert emoji to text. - - *Parameters* - ------------ - emoji: str - The emoji to decipher. - - *Returns* - --------- - : str - The deciphered string. - """ - if emoji == "1️⃣": - return_value = 1 - elif emoji == "2️⃣": - return_value = 2 - elif emoji == "3️⃣": - return_value = 3 - elif emoji == "4️⃣": - return_value = 4 - elif emoji == "5️⃣": - return_value = 5 - elif emoji == "6️⃣": - return_value = 6 - elif emoji == "7️⃣": - return_value = 7 - elif emoji == "🎲": - return_value = "roll" - elif emoji == "❌": - return_value = "none" - elif emoji == "✔️": - return_value = 1 - else: - return_value = "" - - return return_value - -def encode_id(info: list): - letters = list(":".join(info)) - dec = 0 - for i, letter in enumerate(letters): - try: - dec += (37**i) * BASE_37.index(letter.upper()) - except ValueError: - log_this(f"Could not encode letter {letter}", level=30) - - custom_id = [] - - while dec: - custom_id.append(BASE_128[dec % 128]) - dec = dec // 128 - - custom_id = ''.join(custom_id) - log_this(f"Encoded {info} to {custom_id}") - return custom_id - - -def decode_id(custom_id: str): - letters = list(custom_id) - dec = 0 - for i, letter in enumerate(letters): - dec += (128**i) * BASE_128.index(letter) - - info_string = [] - - while dec: - info_string.append(BASE_37[dec % 37]) - dec = dec // 37 - - info = ''.join(info_string).split(':') - log_this(f"Decoded {custom_id} to be {info}") - return ''.join(info_string).split(':') diff --git a/gwendolyn_old/__init__.py b/gwendolyn_old/__init__.py new file mode 100644 index 0000000..17b7d0d --- /dev/null +++ b/gwendolyn_old/__init__.py @@ -0,0 +1,6 @@ +"""The main module for Gwendolyn.""" +# pylint: disable=invalid-name + +__all__ = ["funcs", "utils", "Gwendolyn"] + +from .gwendolyn_client import Gwendolyn diff --git a/gwendolyn/cogs/event_cog.py b/gwendolyn_old/cogs/event_cog.py similarity index 100% rename from gwendolyn/cogs/event_cog.py rename to gwendolyn_old/cogs/event_cog.py diff --git a/gwendolyn/cogs/game_cog.py b/gwendolyn_old/cogs/game_cog.py similarity index 93% rename from gwendolyn/cogs/game_cog.py rename to gwendolyn_old/cogs/game_cog.py index 5d2370b..e9060e0 100644 --- a/gwendolyn/cogs/game_cog.py +++ b/gwendolyn_old/cogs/game_cog.py @@ -1,8 +1,8 @@ """Contains all the cogs that deal with game commands.""" from discord.ext import commands # Has the cog class -from discord_slash import cog_ext # Used for slash commands +from interactions import cog_ext # Used for slash commands -from gwendolyn.utils import get_params # pylint: disable=import-error +from gwendolyn_old.utils import get_params # pylint: disable=import-error params = get_params() @@ -24,11 +24,6 @@ class GamesCog(commands.Cog): """Give another user an amount of GwendoBucks.""" await self.bot.money.giveMoney(ctx, user, amount) - @cog_ext.cog_slash(**params["invest"]) - async def invest(self, ctx, parameters="check"): - """Invest GwendoBucks in the stock market.""" - await self.bot.games.invest.parseInvest(ctx, parameters) - @cog_ext.cog_slash(**params["trivia"]) async def trivia(self, ctx, answer=""): """Run a game of trivia.""" diff --git a/gwendolyn/cogs/lookup_cog.py b/gwendolyn_old/cogs/lookup_cog.py similarity index 85% rename from gwendolyn/cogs/lookup_cog.py rename to gwendolyn_old/cogs/lookup_cog.py index fa5de7f..79a0857 100644 --- a/gwendolyn/cogs/lookup_cog.py +++ b/gwendolyn_old/cogs/lookup_cog.py @@ -1,8 +1,8 @@ """Contains the LookupCog, which deals with the lookup commands.""" from discord.ext import commands # Has the cog class -from discord_slash import cog_ext # Used for slash commands +from interactions import cog_ext # Used for slash commands -from gwendolyn.utils import get_params # pylint: disable=import-error +from gwendolyn_old.utils import get_params # pylint: disable=import-error params = get_params() diff --git a/gwendolyn/cogs/misc_cog.py b/gwendolyn_old/cogs/misc_cog.py similarity index 94% rename from gwendolyn/cogs/misc_cog.py rename to gwendolyn_old/cogs/misc_cog.py index 8215aa5..a770867 100644 --- a/gwendolyn/cogs/misc_cog.py +++ b/gwendolyn_old/cogs/misc_cog.py @@ -1,9 +1,9 @@ """Contains the MiscCog, which deals with miscellaneous commands.""" from discord.ext import commands # Has the cog class -from discord_slash import cog_ext # Used for slash commands -from discord_slash.context import SlashContext +from interactions import cog_ext # Used for slash commands +from interactions import SlashContext -from gwendolyn.utils import get_params # pylint: disable=import-error +from gwendolyn_old.utils import get_params # pylint: disable=import-error params = get_params() diff --git a/gwendolyn/cogs/star_wars_cog.py b/gwendolyn_old/cogs/star_wars_cog.py similarity index 92% rename from gwendolyn/cogs/star_wars_cog.py rename to gwendolyn_old/cogs/star_wars_cog.py index 10101f0..1440f65 100644 --- a/gwendolyn/cogs/star_wars_cog.py +++ b/gwendolyn_old/cogs/star_wars_cog.py @@ -1,8 +1,8 @@ """Contains the StarWarsCog, which deals with Star Wars commands.""" from discord.ext import commands -from discord_slash import cog_ext +from interactions import cog_ext -from gwendolyn.utils import get_params # pylint: disable=import-error +from gwendolyn_old.utils import get_params # pylint: disable=import-error params = get_params() diff --git a/gwendolyn/exceptions.py b/gwendolyn_old/exceptions.py similarity index 100% rename from gwendolyn/exceptions.py rename to gwendolyn_old/exceptions.py diff --git a/gwendolyn/funcs/__init__.py b/gwendolyn_old/funcs/__init__.py similarity index 100% rename from gwendolyn/funcs/__init__.py rename to gwendolyn_old/funcs/__init__.py diff --git a/gwendolyn/funcs/games/__init__.py b/gwendolyn_old/funcs/games/__init__.py similarity index 100% rename from gwendolyn/funcs/games/__init__.py rename to gwendolyn_old/funcs/games/__init__.py diff --git a/gwendolyn/funcs/games/blackjack.py b/gwendolyn_old/funcs/games/blackjack.py similarity index 99% rename from gwendolyn/funcs/games/blackjack.py rename to gwendolyn_old/funcs/games/blackjack.py index 8b9a448..6b2bd4e 100644 --- a/gwendolyn/funcs/games/blackjack.py +++ b/gwendolyn_old/funcs/games/blackjack.py @@ -12,13 +12,13 @@ import math # Used for flooring decimal numbers import datetime # Used to generate the game id import asyncio # Used for sleeping -from discord_slash.context import InteractionContext as IntCont # Used for +from interactions import InteractionContext as IntCont # Used for # typehints -from discord_slash.context import ComponentContext +from interactions import ComponentContext from discord.abc import Messageable from PIL import Image -from gwendolyn.utils import replace_multiple +from gwendolyn_old.utils import replace_multiple from .game_base import CardGame, CardDrawer diff --git a/gwendolyn/funcs/games/connect_four.py b/gwendolyn_old/funcs/games/connect_four.py similarity index 99% rename from gwendolyn/funcs/games/connect_four.py rename to gwendolyn_old/funcs/games/connect_four.py index 3dbbe05..e891f5c 100644 --- a/gwendolyn/funcs/games/connect_four.py +++ b/gwendolyn_old/funcs/games/connect_four.py @@ -15,13 +15,13 @@ import discord # Used for typehints, discord.file and to check whether # the opponent in ConnectFour.start is a discord.User from PIL import Image, ImageDraw, ImageFont # Used by DrawConnectFour() -from discord_slash.context import SlashContext, ComponentContext # Used for +from interactions import SlashContext, ComponentContext # Used for # typehints -from discord_slash.utils.manage_components import (create_button, +from interactions.utils.manage_components import (create_button, create_actionrow) -from discord_slash.model import ButtonStyle +from interactions.model import ButtonStyle -from gwendolyn.utils import encode_id +from gwendolyn_old.utils import encode_id from .game_base import BoardGame ROWCOUNT = 6 diff --git a/gwendolyn/funcs/games/game_base.py b/gwendolyn_old/funcs/games/game_base.py similarity index 96% rename from gwendolyn/funcs/games/game_base.py rename to gwendolyn_old/funcs/games/game_base.py index 64c4576..857a0c0 100644 --- a/gwendolyn/funcs/games/game_base.py +++ b/gwendolyn_old/funcs/games/game_base.py @@ -4,14 +4,13 @@ from typing import Union from discord import File, User from discord.abc import Messageable -from discord_slash.utils.manage_components import (create_button, - create_actionrow) -from discord_slash.context import InteractionContext as IntCont +from interactions import Button, ActionRow +from interactions import InteractionContext as IntCont from PIL import ImageFont, Image, ImageDraw -from gwendolyn.exceptions import GameNotInDatabase -from gwendolyn.utils import encode_id +from gwendolyn_old.exceptions import GameNotInDatabase +from gwendolyn_old.utils import encode_id class GameBase(): """The base class for the games.""" @@ -29,7 +28,7 @@ class GameBase(): button_objects = [] for label, data, style in buttons: custom_id = encode_id([self.game_name] + data) - button_objects.append(create_button( + button_objects.append(Button( style=style, label=label, custom_id=custom_id @@ -37,7 +36,7 @@ class GameBase(): action_rows = [] for i in range(((len(button_objects)-1)//5)+1): - action_rows.append(create_actionrow(*button_objects[i*5:i*5+5])) + action_rows.append(ActionRow(*button_objects[i*5:i*5+5])) return action_rows diff --git a/gwendolyn/funcs/games/games_container.py b/gwendolyn_old/funcs/games/games_container.py similarity index 89% rename from gwendolyn/funcs/games/games_container.py rename to gwendolyn_old/funcs/games/games_container.py index e653046..794a150 100644 --- a/gwendolyn/funcs/games/games_container.py +++ b/gwendolyn_old/funcs/games/games_container.py @@ -8,7 +8,6 @@ Has a container for game functions. """ -from .invest import Invest from .trivia import Trivia from .blackjack import Blackjack from .connect_four import ConnectFour @@ -25,8 +24,6 @@ class Games(): ------------ bot: Gwendolyn The instance of Gwendolyn. - invest - Contains investment functions. blackjack Contains blackjack functions. connect_four @@ -41,7 +38,6 @@ class Games(): """Initialize the container.""" self.bot = bot - self.invest = Invest(bot) self.trivia = Trivia(bot) self.blackjack = Blackjack(bot) self.connect_four = ConnectFour(bot) diff --git a/gwendolyn/funcs/games/hangman.py b/gwendolyn_old/funcs/games/hangman.py similarity index 99% rename from gwendolyn/funcs/games/hangman.py rename to gwendolyn_old/funcs/games/hangman.py index cbc1abf..debf293 100644 --- a/gwendolyn/funcs/games/hangman.py +++ b/gwendolyn_old/funcs/games/hangman.py @@ -16,14 +16,14 @@ import random # Used to draw poorly import requests # Used for getting the word in Hangman.start() import discord # Used for discord.file and type hints -from discord_slash.utils.manage_components import (create_button, +from interactions.utils.manage_components import (create_button, create_actionrow) -from discord_slash.model import ButtonStyle -from discord_slash.context import SlashContext, ComponentContext +from interactions.model import ButtonStyle +from interactions import SlashContext, ComponentContext # Used for typehints from PIL import ImageDraw, Image, ImageFont # Used to draw the image -from gwendolyn.utils import encode_id +from gwendolyn_old.utils import encode_id class Hangman(): """ diff --git a/gwendolyn/funcs/games/hex.py b/gwendolyn_old/funcs/games/hex.py similarity index 100% rename from gwendolyn/funcs/games/hex.py rename to gwendolyn_old/funcs/games/hex.py diff --git a/gwendolyn/funcs/games/money.py b/gwendolyn_old/funcs/games/money.py similarity index 91% rename from gwendolyn/funcs/games/money.py rename to gwendolyn_old/funcs/games/money.py index e46583d..73c3e06 100644 --- a/gwendolyn/funcs/games/money.py +++ b/gwendolyn_old/funcs/games/money.py @@ -6,7 +6,7 @@ Contains the code that deals with money. Money Deals with money. """ -import discord_slash # Used for typehints +import interactions # Used for typehints import discord # Used for typehints @@ -17,9 +17,9 @@ class Money(): *Methods* --------- checkBalance(user: str) - sendBalance(ctx: discord_slash.context.SlashContext) + sendBalance(ctx: interactions.SlashContext) addMoney(user: str, amount: int) - giveMoney(ctx: discord_slash.context.SlashContext, user: discord.User, + giveMoney(ctx: interactions.SlashContext, user: discord.User, amount: int) *Attributes* @@ -58,13 +58,13 @@ class Money(): else: return 0 - async def sendBalance(self, ctx: discord_slash.context.SlashContext): + async def sendBalance(self, ctx: interactions.SlashContext): """ Get your own account balance. *Parameters* ------------ - ctx: discord_slash.context.SlashContext + ctx: interactions.SlashContext The context of the command. """ await self.bot.defer(ctx) @@ -104,14 +104,14 @@ class Money(): self.database["users"].insert_one(new_user) # Transfers money from one user to another - async def giveMoney(self, ctx: discord_slash.context.SlashContext, + async def giveMoney(self, ctx: interactions.SlashContext, user: discord.User, amount: int): """ Give someone else money from your account. *Parameters* ------------ - ctx: discord_slash.context.SlashContext + ctx: interactions.SlashContext The context of the command. user: discord.User The user to give money. diff --git a/gwendolyn/funcs/games/trivia.py b/gwendolyn_old/funcs/games/trivia.py similarity index 99% rename from gwendolyn/funcs/games/trivia.py rename to gwendolyn_old/funcs/games/trivia.py index e0d2284..9dad561 100644 --- a/gwendolyn/funcs/games/trivia.py +++ b/gwendolyn_old/funcs/games/trivia.py @@ -11,7 +11,7 @@ import json # Used to read data from api import random # Used to shuffle answers import asyncio # Used to sleep -from discord_slash.context import SlashContext # Used for type hints +from interactions import SlashContext # Used for type hints class Trivia(): diff --git a/gwendolyn/funcs/games/wordle.py b/gwendolyn_old/funcs/games/wordle.py similarity index 99% rename from gwendolyn/funcs/games/wordle.py rename to gwendolyn_old/funcs/games/wordle.py index 7fa9ffd..371bc35 100644 --- a/gwendolyn/funcs/games/wordle.py +++ b/gwendolyn_old/funcs/games/wordle.py @@ -5,7 +5,7 @@ from PIL import Image, ImageDraw from .game_base import DatabaseGame, BaseDrawer -from gwendolyn.exceptions import GameNotInDatabase +from gwendolyn_old.exceptions import GameNotInDatabase IMAGE_MARGIN = 90 SQUARE_SIZE = 150 diff --git a/gwendolyn/funcs/lookup/__init__.py b/gwendolyn_old/funcs/lookup/__init__.py similarity index 100% rename from gwendolyn/funcs/lookup/__init__.py rename to gwendolyn_old/funcs/lookup/__init__.py diff --git a/gwendolyn/funcs/lookup/lookup_funcs.py b/gwendolyn_old/funcs/lookup/lookup_funcs.py similarity index 99% rename from gwendolyn/funcs/lookup/lookup_funcs.py rename to gwendolyn_old/funcs/lookup/lookup_funcs.py index d2a54f7..83d4602 100644 --- a/gwendolyn/funcs/lookup/lookup_funcs.py +++ b/gwendolyn_old/funcs/lookup/lookup_funcs.py @@ -2,7 +2,7 @@ import math import json import discord -from gwendolyn.utils import cap +from gwendolyn_old.utils import cap STATS = [ "strength", diff --git a/gwendolyn/funcs/other/__init__.py b/gwendolyn_old/funcs/other/__init__.py similarity index 100% rename from gwendolyn/funcs/other/__init__.py rename to gwendolyn_old/funcs/other/__init__.py diff --git a/gwendolyn/funcs/other/generators.py b/gwendolyn_old/funcs/other/generators.py similarity index 100% rename from gwendolyn/funcs/other/generators.py rename to gwendolyn_old/funcs/other/generators.py diff --git a/gwendolyn/funcs/other/nerd_shit.py b/gwendolyn_old/funcs/other/nerd_shit.py similarity index 100% rename from gwendolyn/funcs/other/nerd_shit.py rename to gwendolyn_old/funcs/other/nerd_shit.py diff --git a/gwendolyn/funcs/other/other.py b/gwendolyn_old/funcs/other/other.py similarity index 100% rename from gwendolyn/funcs/other/other.py rename to gwendolyn_old/funcs/other/other.py diff --git a/gwendolyn/funcs/other/plex.py b/gwendolyn_old/funcs/other/plex.py similarity index 99% rename from gwendolyn/funcs/other/plex.py rename to gwendolyn_old/funcs/other/plex.py index c86eb9c..5a156c2 100644 --- a/gwendolyn/funcs/other/plex.py +++ b/gwendolyn_old/funcs/other/plex.py @@ -7,11 +7,11 @@ import imdb import discord import xmltodict -from discord_slash.utils.manage_components import (create_button, +from interactions.utils.manage_components import (create_button, create_actionrow) -from discord_slash.model import ButtonStyle +from interactions.model import ButtonStyle -from gwendolyn.utils import encode_id +from gwendolyn_old.utils import encode_id class Plex(): """Container for Plex functions and commands.""" diff --git a/gwendolyn/funcs/star_wars_funcs/__init__.py b/gwendolyn_old/funcs/star_wars_funcs/__init__.py similarity index 100% rename from gwendolyn/funcs/star_wars_funcs/__init__.py rename to gwendolyn_old/funcs/star_wars_funcs/__init__.py diff --git a/gwendolyn/funcs/star_wars_funcs/star_wars.py b/gwendolyn_old/funcs/star_wars_funcs/star_wars.py similarity index 100% rename from gwendolyn/funcs/star_wars_funcs/star_wars.py rename to gwendolyn_old/funcs/star_wars_funcs/star_wars.py diff --git a/gwendolyn/funcs/star_wars_funcs/star_wars_char.py b/gwendolyn_old/funcs/star_wars_funcs/star_wars_char.py similarity index 100% rename from gwendolyn/funcs/star_wars_funcs/star_wars_char.py rename to gwendolyn_old/funcs/star_wars_funcs/star_wars_char.py diff --git a/gwendolyn/funcs/star_wars_funcs/star_wars_destiny.py b/gwendolyn_old/funcs/star_wars_funcs/star_wars_destiny.py similarity index 100% rename from gwendolyn/funcs/star_wars_funcs/star_wars_destiny.py rename to gwendolyn_old/funcs/star_wars_funcs/star_wars_destiny.py diff --git a/gwendolyn/funcs/star_wars_funcs/star_wars_roll.py b/gwendolyn_old/funcs/star_wars_funcs/star_wars_roll.py similarity index 100% rename from gwendolyn/funcs/star_wars_funcs/star_wars_roll.py rename to gwendolyn_old/funcs/star_wars_funcs/star_wars_roll.py diff --git a/gwendolyn_old/gwendolyn_client.py b/gwendolyn_old/gwendolyn_client.py new file mode 100644 index 0000000..7a6792b --- /dev/null +++ b/gwendolyn_old/gwendolyn_client.py @@ -0,0 +1,132 @@ +""" +Contains the Gwendolyn class, a subclass of the discord command bot. + +*Classes* +--------- + Gwendolyn(discord.ext.commands.Bot) +""" +import os # Used for loading cogs in Gwendolyn.addCogs +import discord # Used for discord.Intents and discord.Status +import interactions # Used to initialized SlashCommands object +import git # Used to pull when stopping + +from discord.ext import commands # Used to inherit from commands.bot +from pymongo import MongoClient # Used for database management +from gwendolyn_old.funcs import Money, StarWars, Games, Other, LookupFuncs +from gwendolyn_old.utils import (get_options, get_credentials, log_this, + DatabaseFuncs, EventHandler, ErrorHandler, + long_strings) + + +class Gwendolyn(commands.Bot): + """ + A multifunctional Discord bot. + + *Methods* + --------- + log(messages: Union[str, list], channel: str = "", + level: int = 20) + stop(ctx: interactions.SlashContext) + defer(ctx: interactions.SlashContext) + """ + # pylint: disable=too-many-instance-attributes + + def __init__(self): + """Initialize the bot.""" + intents = discord.Intents.default() + intents.members = True + initiation_parameters = { + "command_prefix": " ", + "case_insensitive": True, + "intents": intents, + "status": discord.Status.dnd + } + super().__init__(**initiation_parameters) + + self._add_clients_and_options() + self._add_util_classes() + self._add_function_containers() + self._add_cogs() + + def _add_clients_and_options(self): + """Add all the client, option and credentials objects.""" + self.long_strings = long_strings() + self.options = get_options() + self.credentials = get_credentials() + mongo_user = self.credentials["mongo_db_user"] + mongo_password = self.credentials["mongo_db_password"] + mongo_url = f"mongodb+srv://{mongo_user}:{mongo_password}@gwendolyn" + mongo_url += ".qkwfy.mongodb.net/Gwendolyn?retryWrites=true&w=majority" + database_clint = MongoClient(mongo_url) + + if self.options["testing"]: + self.log("Testing mode") + self.database = database_clint["Gwendolyn-Test"] + else: + self.database = database_clint["Gwendolyn"] + + def _add_util_classes(self): + """Add all the classes used as utility.""" + self.database_funcs = DatabaseFuncs(self) + self.event_handler = EventHandler(self) + self.error_handler = ErrorHandler(self) + slash_parameters = { + "sync_commands": True, + "sync_on_cog_reload": True, + "override_type": True + } + self.slash = interactions.SlashCommand(self, **slash_parameters) + + def _add_function_containers(self): + """Add all the function containers used for commands.""" + self.star_wars = StarWars(self) + self.other = Other(self) + self.lookup_funcs = LookupFuncs(self) + self.games = Games(self) + self.money = Money(self) + + def _add_cogs(self): + """Load cogs.""" + for filename in os.listdir("./gwendolyn/cogs"): + if filename.endswith(".py"): + self.load_extension(f"gwendolyn.cogs.{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_this(messages, channel, level) + + async def stop(self, ctx: interactions.SlashContext): + """ + Stop the bot, and stop running games. + + Only stops the bot if the user in ctx.author is one of the + admins given in options.txt. + + *parameters* + ------------ + ctx: interactions.SlashContext + The context of the "/stop" slash command. + """ + if f"#{ctx.author.id}" in self.options["admins"]: + await ctx.send("Pulling git repo and restarting...") + + await self.change_presence(status=discord.Status.offline) + + self.database_funcs.wipe_games() + if not self.options["testing"]: + git_client = git.cmd.Git("") + git_client.pull() + + self.log("Logging out", level=25) + await self.close() + else: + log_message = f"{ctx.author.display_name} tried to stop me!" + self.log(log_message, str(ctx.channel_id)) + await ctx.send(f"I don't think I will, {ctx.author.display_name}") + + async def defer(self, ctx: interactions.SlashContext): + """Send a "Gwendolyn is thinking" message to the user.""" + try: + await ctx.defer() + except interactions.error.AlreadyResponded: + self.log("defer failed") diff --git a/gwendolyn_old/resources/fonts/comic-sans-bold.ttf b/gwendolyn_old/resources/fonts/comic-sans-bold.ttf new file mode 100644 index 0000000..a9227f1 Binary files /dev/null and b/gwendolyn_old/resources/fonts/comic-sans-bold.ttf differ diff --git a/gwendolyn_old/resources/fonts/futura-bold.ttf b/gwendolyn_old/resources/fonts/futura-bold.ttf new file mode 100644 index 0000000..5d8ce10 Binary files /dev/null and b/gwendolyn_old/resources/fonts/futura-bold.ttf differ diff --git a/gwendolyn_old/resources/fonts/times-new-roman.ttf b/gwendolyn_old/resources/fonts/times-new-roman.ttf new file mode 100644 index 0000000..f71d84a Binary files /dev/null and b/gwendolyn_old/resources/fonts/times-new-roman.ttf differ diff --git a/gwendolyn_old/resources/games/cards/0C.png b/gwendolyn_old/resources/games/cards/0C.png new file mode 100644 index 0000000..f9ade6d Binary files /dev/null and b/gwendolyn_old/resources/games/cards/0C.png differ diff --git a/gwendolyn_old/resources/games/cards/0D.png b/gwendolyn_old/resources/games/cards/0D.png new file mode 100644 index 0000000..a9de67e Binary files /dev/null and b/gwendolyn_old/resources/games/cards/0D.png differ diff --git a/gwendolyn_old/resources/games/cards/0H.png b/gwendolyn_old/resources/games/cards/0H.png new file mode 100644 index 0000000..df551b0 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/0H.png differ diff --git a/gwendolyn_old/resources/games/cards/0S.png b/gwendolyn_old/resources/games/cards/0S.png new file mode 100644 index 0000000..22141df Binary files /dev/null and b/gwendolyn_old/resources/games/cards/0S.png differ diff --git a/gwendolyn_old/resources/games/cards/2C.png b/gwendolyn_old/resources/games/cards/2C.png new file mode 100644 index 0000000..413b0da Binary files /dev/null and b/gwendolyn_old/resources/games/cards/2C.png differ diff --git a/gwendolyn_old/resources/games/cards/2D.png b/gwendolyn_old/resources/games/cards/2D.png new file mode 100644 index 0000000..f966e48 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/2D.png differ diff --git a/gwendolyn_old/resources/games/cards/2H.png b/gwendolyn_old/resources/games/cards/2H.png new file mode 100644 index 0000000..345744e Binary files /dev/null and b/gwendolyn_old/resources/games/cards/2H.png differ diff --git a/gwendolyn_old/resources/games/cards/2S.png b/gwendolyn_old/resources/games/cards/2S.png new file mode 100644 index 0000000..a0de145 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/2S.png differ diff --git a/gwendolyn_old/resources/games/cards/3C.png b/gwendolyn_old/resources/games/cards/3C.png new file mode 100644 index 0000000..f8b8183 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/3C.png differ diff --git a/gwendolyn_old/resources/games/cards/3D.png b/gwendolyn_old/resources/games/cards/3D.png new file mode 100644 index 0000000..cee21f3 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/3D.png differ diff --git a/gwendolyn_old/resources/games/cards/3H.png b/gwendolyn_old/resources/games/cards/3H.png new file mode 100644 index 0000000..8494e1c Binary files /dev/null and b/gwendolyn_old/resources/games/cards/3H.png differ diff --git a/gwendolyn_old/resources/games/cards/3S.png b/gwendolyn_old/resources/games/cards/3S.png new file mode 100644 index 0000000..78e3b20 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/3S.png differ diff --git a/gwendolyn_old/resources/games/cards/4C.png b/gwendolyn_old/resources/games/cards/4C.png new file mode 100644 index 0000000..8938459 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/4C.png differ diff --git a/gwendolyn_old/resources/games/cards/4D.png b/gwendolyn_old/resources/games/cards/4D.png new file mode 100644 index 0000000..d9ae5be Binary files /dev/null and b/gwendolyn_old/resources/games/cards/4D.png differ diff --git a/gwendolyn_old/resources/games/cards/4H.png b/gwendolyn_old/resources/games/cards/4H.png new file mode 100644 index 0000000..41a4488 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/4H.png differ diff --git a/gwendolyn_old/resources/games/cards/4S.png b/gwendolyn_old/resources/games/cards/4S.png new file mode 100644 index 0000000..70bc9cc Binary files /dev/null and b/gwendolyn_old/resources/games/cards/4S.png differ diff --git a/gwendolyn_old/resources/games/cards/5C.png b/gwendolyn_old/resources/games/cards/5C.png new file mode 100644 index 0000000..a7f49be Binary files /dev/null and b/gwendolyn_old/resources/games/cards/5C.png differ diff --git a/gwendolyn_old/resources/games/cards/5D.png b/gwendolyn_old/resources/games/cards/5D.png new file mode 100644 index 0000000..cff0617 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/5D.png differ diff --git a/gwendolyn_old/resources/games/cards/5H.png b/gwendolyn_old/resources/games/cards/5H.png new file mode 100644 index 0000000..1efcbf3 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/5H.png differ diff --git a/gwendolyn_old/resources/games/cards/5S.png b/gwendolyn_old/resources/games/cards/5S.png new file mode 100644 index 0000000..e708806 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/5S.png differ diff --git a/gwendolyn_old/resources/games/cards/6C.png b/gwendolyn_old/resources/games/cards/6C.png new file mode 100644 index 0000000..d8382d3 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/6C.png differ diff --git a/gwendolyn_old/resources/games/cards/6D.png b/gwendolyn_old/resources/games/cards/6D.png new file mode 100644 index 0000000..7ba40e9 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/6D.png differ diff --git a/gwendolyn_old/resources/games/cards/6H.png b/gwendolyn_old/resources/games/cards/6H.png new file mode 100644 index 0000000..93a84f8 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/6H.png differ diff --git a/gwendolyn_old/resources/games/cards/6S.png b/gwendolyn_old/resources/games/cards/6S.png new file mode 100644 index 0000000..874162b Binary files /dev/null and b/gwendolyn_old/resources/games/cards/6S.png differ diff --git a/gwendolyn_old/resources/games/cards/7C.png b/gwendolyn_old/resources/games/cards/7C.png new file mode 100644 index 0000000..f6a9653 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/7C.png differ diff --git a/gwendolyn_old/resources/games/cards/7D.png b/gwendolyn_old/resources/games/cards/7D.png new file mode 100644 index 0000000..6c4393d Binary files /dev/null and b/gwendolyn_old/resources/games/cards/7D.png differ diff --git a/gwendolyn_old/resources/games/cards/7H.png b/gwendolyn_old/resources/games/cards/7H.png new file mode 100644 index 0000000..d4a59ff Binary files /dev/null and b/gwendolyn_old/resources/games/cards/7H.png differ diff --git a/gwendolyn_old/resources/games/cards/7S.png b/gwendolyn_old/resources/games/cards/7S.png new file mode 100644 index 0000000..895f85c Binary files /dev/null and b/gwendolyn_old/resources/games/cards/7S.png differ diff --git a/gwendolyn_old/resources/games/cards/8C.png b/gwendolyn_old/resources/games/cards/8C.png new file mode 100644 index 0000000..bc87bf0 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/8C.png differ diff --git a/gwendolyn_old/resources/games/cards/8D.png b/gwendolyn_old/resources/games/cards/8D.png new file mode 100644 index 0000000..38c5695 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/8D.png differ diff --git a/gwendolyn_old/resources/games/cards/8H.png b/gwendolyn_old/resources/games/cards/8H.png new file mode 100644 index 0000000..c2812aa Binary files /dev/null and b/gwendolyn_old/resources/games/cards/8H.png differ diff --git a/gwendolyn_old/resources/games/cards/8S.png b/gwendolyn_old/resources/games/cards/8S.png new file mode 100644 index 0000000..0277cc6 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/8S.png differ diff --git a/gwendolyn_old/resources/games/cards/9C.png b/gwendolyn_old/resources/games/cards/9C.png new file mode 100644 index 0000000..d81b2f2 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/9C.png differ diff --git a/gwendolyn_old/resources/games/cards/9D.png b/gwendolyn_old/resources/games/cards/9D.png new file mode 100644 index 0000000..e0d3d05 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/9D.png differ diff --git a/gwendolyn_old/resources/games/cards/9H.png b/gwendolyn_old/resources/games/cards/9H.png new file mode 100644 index 0000000..7b679e1 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/9H.png differ diff --git a/gwendolyn_old/resources/games/cards/9S.png b/gwendolyn_old/resources/games/cards/9S.png new file mode 100644 index 0000000..f58493e Binary files /dev/null and b/gwendolyn_old/resources/games/cards/9S.png differ diff --git a/gwendolyn_old/resources/games/cards/AC.png b/gwendolyn_old/resources/games/cards/AC.png new file mode 100644 index 0000000..396c158 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/AC.png differ diff --git a/gwendolyn_old/resources/games/cards/AD.png b/gwendolyn_old/resources/games/cards/AD.png new file mode 100644 index 0000000..d702a39 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/AD.png differ diff --git a/gwendolyn_old/resources/games/cards/AH.png b/gwendolyn_old/resources/games/cards/AH.png new file mode 100644 index 0000000..435fc14 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/AH.png differ diff --git a/gwendolyn_old/resources/games/cards/AS.png b/gwendolyn_old/resources/games/cards/AS.png new file mode 100644 index 0000000..f07f67d Binary files /dev/null and b/gwendolyn_old/resources/games/cards/AS.png differ diff --git a/gwendolyn_old/resources/games/cards/JC.png b/gwendolyn_old/resources/games/cards/JC.png new file mode 100644 index 0000000..16418e4 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/JC.png differ diff --git a/gwendolyn_old/resources/games/cards/JD.png b/gwendolyn_old/resources/games/cards/JD.png new file mode 100644 index 0000000..05b0389 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/JD.png differ diff --git a/gwendolyn_old/resources/games/cards/JH.png b/gwendolyn_old/resources/games/cards/JH.png new file mode 100644 index 0000000..259421c Binary files /dev/null and b/gwendolyn_old/resources/games/cards/JH.png differ diff --git a/gwendolyn_old/resources/games/cards/JS.png b/gwendolyn_old/resources/games/cards/JS.png new file mode 100644 index 0000000..6e0554d Binary files /dev/null and b/gwendolyn_old/resources/games/cards/JS.png differ diff --git a/gwendolyn_old/resources/games/cards/KC.png b/gwendolyn_old/resources/games/cards/KC.png new file mode 100644 index 0000000..70c4ee5 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/KC.png differ diff --git a/gwendolyn_old/resources/games/cards/KD.png b/gwendolyn_old/resources/games/cards/KD.png new file mode 100644 index 0000000..95a3b8f Binary files /dev/null and b/gwendolyn_old/resources/games/cards/KD.png differ diff --git a/gwendolyn_old/resources/games/cards/KH.png b/gwendolyn_old/resources/games/cards/KH.png new file mode 100644 index 0000000..0defcbb Binary files /dev/null and b/gwendolyn_old/resources/games/cards/KH.png differ diff --git a/gwendolyn_old/resources/games/cards/KS.png b/gwendolyn_old/resources/games/cards/KS.png new file mode 100644 index 0000000..43b8e19 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/KS.png differ diff --git a/gwendolyn_old/resources/games/cards/QC.png b/gwendolyn_old/resources/games/cards/QC.png new file mode 100644 index 0000000..6f74177 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/QC.png differ diff --git a/gwendolyn_old/resources/games/cards/QD.png b/gwendolyn_old/resources/games/cards/QD.png new file mode 100644 index 0000000..85c443f Binary files /dev/null and b/gwendolyn_old/resources/games/cards/QD.png differ diff --git a/gwendolyn_old/resources/games/cards/QH.png b/gwendolyn_old/resources/games/cards/QH.png new file mode 100644 index 0000000..ba8e1e4 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/QH.png differ diff --git a/gwendolyn_old/resources/games/cards/QS.png b/gwendolyn_old/resources/games/cards/QS.png new file mode 100644 index 0000000..a6ef69f Binary files /dev/null and b/gwendolyn_old/resources/games/cards/QS.png differ diff --git a/gwendolyn_old/resources/games/cards/blue_back.png b/gwendolyn_old/resources/games/cards/blue_back.png new file mode 100644 index 0000000..24fcfb7 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/blue_back.png differ diff --git a/gwendolyn_old/resources/games/cards/gray_back.png b/gwendolyn_old/resources/games/cards/gray_back.png new file mode 100644 index 0000000..0b40ae3 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/gray_back.png differ diff --git a/gwendolyn_old/resources/games/cards/green_back.png b/gwendolyn_old/resources/games/cards/green_back.png new file mode 100644 index 0000000..79b7d8c Binary files /dev/null and b/gwendolyn_old/resources/games/cards/green_back.png differ diff --git a/gwendolyn_old/resources/games/cards/purple_back.png b/gwendolyn_old/resources/games/cards/purple_back.png new file mode 100644 index 0000000..ac96728 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/purple_back.png differ diff --git a/gwendolyn_old/resources/games/cards/red_back.png b/gwendolyn_old/resources/games/cards/red_back.png new file mode 100644 index 0000000..759383d Binary files /dev/null and b/gwendolyn_old/resources/games/cards/red_back.png differ diff --git a/gwendolyn_old/resources/games/cards/yellow_back.png b/gwendolyn_old/resources/games/cards/yellow_back.png new file mode 100644 index 0000000..11d29c9 Binary files /dev/null and b/gwendolyn_old/resources/games/cards/yellow_back.png differ diff --git a/gwendolyn_old/resources/games/deck_of_cards.txt b/gwendolyn_old/resources/games/deck_of_cards.txt new file mode 100644 index 0000000..a3beeb4 --- /dev/null +++ b/gwendolyn_old/resources/games/deck_of_cards.txt @@ -0,0 +1,52 @@ +ad +2d +3d +4d +5d +6d +7d +8d +9d +0d +jd +qd +kd +ac +2c +3c +4c +5c +6c +7c +8c +9c +0c +jc +qc +kc +ah +2h +3h +4h +5h +6h +7h +8h +9h +0h +jh +qh +kh +as +2s +3s +4s +5s +6s +7s +8s +9s +0s +js +qs +ks \ No newline at end of file diff --git a/gwendolyn_old/resources/games/default_images/blackjack.png b/gwendolyn_old/resources/games/default_images/blackjack.png new file mode 100644 index 0000000..7275c76 Binary files /dev/null and b/gwendolyn_old/resources/games/default_images/blackjack.png differ diff --git a/gwendolyn_old/resources/games/default_images/hangman.png b/gwendolyn_old/resources/games/default_images/hangman.png new file mode 100644 index 0000000..3370360 Binary files /dev/null and b/gwendolyn_old/resources/games/default_images/hangman.png differ diff --git a/gwendolyn/resources/games/images/blackjack740652054388932682.png b/gwendolyn_old/resources/games/images/blackjack740652054388932682.png similarity index 100% rename from gwendolyn/resources/games/images/blackjack740652054388932682.png rename to gwendolyn_old/resources/games/images/blackjack740652054388932682.png diff --git a/gwendolyn_old/resources/help/help-add_movie.txt b/gwendolyn_old/resources/help/help-add_movie.txt new file mode 100644 index 0000000..fae39ff --- /dev/null +++ b/gwendolyn_old/resources/help/help-add_movie.txt @@ -0,0 +1 @@ +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. \ No newline at end of file diff --git a/gwendolyn_old/resources/help/help-add_show.txt b/gwendolyn_old/resources/help/help-add_show.txt new file mode 100644 index 0000000..4868941 --- /dev/null +++ b/gwendolyn_old/resources/help/help-add_show.txt @@ -0,0 +1 @@ +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. \ No newline at end of file diff --git a/gwendolyn_old/resources/help/help-balance.txt b/gwendolyn_old/resources/help/help-balance.txt new file mode 100644 index 0000000..3bda209 --- /dev/null +++ b/gwendolyn_old/resources/help/help-balance.txt @@ -0,0 +1 @@ +Viser dig hvor mange GwendoBucks du har. \ No newline at end of file diff --git a/gwendolyn_old/resources/help/help-blackjack.txt b/gwendolyn_old/resources/help/help-blackjack.txt new file mode 100644 index 0000000..b3bc998 --- /dev/null +++ b/gwendolyn_old/resources/help/help-blackjack.txt @@ -0,0 +1 @@ +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. \ No newline at end of file diff --git a/gwendolyn_old/resources/help/help-connect_four.txt b/gwendolyn_old/resources/help/help-connect_four.txt new file mode 100644 index 0000000..622dc19 --- /dev/null +++ b/gwendolyn_old/resources/help/help-connect_four.txt @@ -0,0 +1 @@ +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. \ No newline at end of file diff --git a/gwendolyn_old/resources/help/help-downloading.txt b/gwendolyn_old/resources/help/help-downloading.txt new file mode 100644 index 0000000..b62f3dd --- /dev/null +++ b/gwendolyn_old/resources/help/help-downloading.txt @@ -0,0 +1,9 @@ +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. \ No newline at end of file diff --git a/gwendolyn_old/resources/help/help-give.txt b/gwendolyn_old/resources/help/help-give.txt new file mode 100644 index 0000000..8c2803c --- /dev/null +++ b/gwendolyn_old/resources/help/help-give.txt @@ -0,0 +1 @@ +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. \ No newline at end of file diff --git a/gwendolyn_old/resources/help/help-hangman.txt b/gwendolyn_old/resources/help/help-hangman.txt new file mode 100644 index 0000000..1d3741e --- /dev/null +++ b/gwendolyn_old/resources/help/help-hangman.txt @@ -0,0 +1 @@ +Brug `/hangman` til at starte et spil hangman. Brug derefter reaktionerne til at gætte bogstaver. Du har 6 gæt. \ No newline at end of file diff --git a/gwendolyn_old/resources/help/help-hello.txt b/gwendolyn_old/resources/help/help-hello.txt new file mode 100644 index 0000000..6aa55c9 --- /dev/null +++ b/gwendolyn_old/resources/help/help-hello.txt @@ -0,0 +1 @@ +Hvis du bruger kommandoen `/hello`, sender Gwendolyn en venlig hilsen. \ No newline at end of file diff --git a/gwendolyn_old/resources/help/help-hex.txt b/gwendolyn_old/resources/help/help-hex.txt new file mode 100644 index 0000000..9d1e14b --- /dev/null +++ b/gwendolyn_old/resources/help/help-hex.txt @@ -0,0 +1 @@ +Brug `/hex start` til at starte et spil imod Gwendolyn. Brug "/hex start [modstander]" for at spille imod en anden person. \ No newline at end of file diff --git a/gwendolyn_old/resources/help/help-image.txt b/gwendolyn_old/resources/help/help-image.txt new file mode 100644 index 0000000..b56c755 --- /dev/null +++ b/gwendolyn_old/resources/help/help-image.txt @@ -0,0 +1 @@ +Finder et tilfældigt billede fra internettet. \ No newline at end of file diff --git a/gwendolyn_old/resources/help/help-monster.txt b/gwendolyn_old/resources/help/help-monster.txt new file mode 100644 index 0000000..957043d --- /dev/null +++ b/gwendolyn_old/resources/help/help-monster.txt @@ -0,0 +1,2 @@ +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. \ No newline at end of file diff --git a/gwendolyn_old/resources/help/help-movie.txt b/gwendolyn_old/resources/help/help-movie.txt new file mode 100644 index 0000000..6c072de --- /dev/null +++ b/gwendolyn_old/resources/help/help-movie.txt @@ -0,0 +1 @@ +Giver titlen på en tilfældig film fra Plex. \ No newline at end of file diff --git a/gwendolyn_old/resources/help/help-name.txt b/gwendolyn_old/resources/help/help-name.txt new file mode 100644 index 0000000..85504a4 --- /dev/null +++ b/gwendolyn_old/resources/help/help-name.txt @@ -0,0 +1 @@ +Genererer et tilfældigt navn. \ No newline at end of file diff --git a/gwendolyn_old/resources/help/help-roll.txt b/gwendolyn_old/resources/help/help-roll.txt new file mode 100644 index 0000000..6cef66e --- /dev/null +++ b/gwendolyn_old/resources/help/help-roll.txt @@ -0,0 +1,8 @@ +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. \ No newline at end of file diff --git a/gwendolyn_old/resources/help/help-spell.txt b/gwendolyn_old/resources/help/help-spell.txt new file mode 100644 index 0000000..606b9ea --- /dev/null +++ b/gwendolyn_old/resources/help/help-spell.txt @@ -0,0 +1,2 @@ +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. \ No newline at end of file diff --git a/gwendolyn_old/resources/help/help-star_wars_character.txt b/gwendolyn_old/resources/help/help-star_wars_character.txt new file mode 100644 index 0000000..a3a271b --- /dev/null +++ b/gwendolyn_old/resources/help/help-star_wars_character.txt @@ -0,0 +1 @@ + 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. \ No newline at end of file diff --git a/gwendolyn_old/resources/help/help-star_wars_roll.txt b/gwendolyn_old/resources/help/help-star_wars_roll.txt new file mode 100644 index 0000000..f94e0e3 --- /dev/null +++ b/gwendolyn_old/resources/help/help-star_wars_roll.txt @@ -0,0 +1 @@ +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. \ No newline at end of file diff --git a/gwendolyn_old/resources/help/help-tavern.txt b/gwendolyn_old/resources/help/help-tavern.txt new file mode 100644 index 0000000..dc18077 --- /dev/null +++ b/gwendolyn_old/resources/help/help-tavern.txt @@ -0,0 +1 @@ +Genererer en tilfældig tavern. \ No newline at end of file diff --git a/gwendolyn_old/resources/help/help-thank.txt b/gwendolyn_old/resources/help/help-thank.txt new file mode 100644 index 0000000..d103b4d --- /dev/null +++ b/gwendolyn_old/resources/help/help-thank.txt @@ -0,0 +1 @@ +Lader dig takke Gwendolyn. \ No newline at end of file diff --git a/gwendolyn_old/resources/help/help-trivia.txt b/gwendolyn_old/resources/help/help-trivia.txt new file mode 100644 index 0000000..a5da454 --- /dev/null +++ b/gwendolyn_old/resources/help/help-trivia.txt @@ -0,0 +1,4 @@ +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. \ No newline at end of file diff --git a/gwendolyn_old/resources/help/help-wolf.txt b/gwendolyn_old/resources/help/help-wolf.txt new file mode 100644 index 0000000..a3dc722 --- /dev/null +++ b/gwendolyn_old/resources/help/help-wolf.txt @@ -0,0 +1 @@ +Lader dig slå ting op på Wolfram Alpha. \ No newline at end of file diff --git a/gwendolyn_old/resources/help/help.txt b/gwendolyn_old/resources/help/help.txt new file mode 100644 index 0000000..1cfdeac --- /dev/null +++ b/gwendolyn_old/resources/help/help.txt @@ -0,0 +1,23 @@ +`/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]". diff --git a/gwendolyn_old/resources/long_strings.json b/gwendolyn_old/resources/long_strings.json new file mode 100644 index 0000000..c9c5e42 --- /dev/null +++ b/gwendolyn_old/resources/long_strings.json @@ -0,0 +1,27 @@ +{ + "missing parameters" : "Missing command parameters. Try using `!help [command]` to find out how to use the command.", + "Can't log in": "Could not log in. Remember to write your bot token in the credentials.txt file", + "Blackjack all players standing": "All players are standing. The dealer now shows his cards and draws.", + "Blackjack first round": ". You can also double down with \"/blackjack double\" or split with \"/blackjack split\"", + "Blackjack commands": "You have 2 minutes to either hit or stand with \"/blackjack hit\" or \"/blackjack stand\"{}. It's assumed you're standing if you don't make a choice.", + "Blackjack double": "Adding another {} GwendoBucks to {}'s bet and drawing another card.", + "Blackjack different cards": "You can only split if your cards have the same value", + "Blackjack split": "Splitting {}'s hand into 2. Adding their original bet to the second hand. You can use \"/blackjack hit/stand/double 1\" and \"/blackjack hit/stand/double 2\" to play the different hands.", + "Blackjack started": "Blackjack game started. Use the buttons or \"/blackjack bet [amount]\" to enter the game within the next 30 seconds.", + "Blackjack going on": "There's already a blackjack game going on. Try again in a few minutes.", + "Stock value": "The current {} stock is valued at **{}** GwendoBucks", + "Stock parameters": "You must give both a stock name and an amount of GwendoBucks you wish to spend.", + "Trivia going on": "There's already a trivia question going on. Try again in like, a minute", + "Trivia time up": "Time's up! The answer was \"*{}) {}*\". Anyone who answered that has gotten 1 GwendoBuck", + "Connect 4 going on": "There's already a connect 4 game going on in this channel", + "Connect 4 placed": "{} placed a piece in column {}. It's now {}'s turn", + "Hangman going on": "There's already a Hangman game going on in the channel", + "Hangman lost game": " You've guessed wrong six times and have lost the game.", + "Hangman guessed word": " You've guessed the word! Congratulations! Adding 15 GwendoBucks to your account", + "Already on Plex": "{} is either already on Plex, downloading, or not available", + "No torrent": "{}No torrent exists. Likely because the movie is not yet released on DVD", + "No torrents downloading": "There are no torrents downloading right. If the torrent you're looking for was added more than 24 hours ago, it might already be on Plex.", + "Update": "{}\nThis message will update every 10 seconds for {} more minutes\n```", + "No updates": "{}\nThis message will not update anymore\n```", + "Invalid parameters": "Invalid or repeated parameters. Use '/help downloading' to see valid parameters." +} \ No newline at end of file diff --git a/gwendolyn_old/resources/slash_parameters.json b/gwendolyn_old/resources/slash_parameters.json new file mode 100644 index 0000000..9011ff5 --- /dev/null +++ b/gwendolyn_old/resources/slash_parameters.json @@ -0,0 +1,401 @@ +{ + "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" + } + ] + } +} \ No newline at end of file diff --git a/gwendolyn_old/resources/star_wars/starwarsskills.json b/gwendolyn_old/resources/star_wars/starwarsskills.json new file mode 100644 index 0000000..698cafe --- /dev/null +++ b/gwendolyn_old/resources/star_wars/starwarsskills.json @@ -0,0 +1,36 @@ +{ + "Astrogation" : "Intellect", + "Computers" : "Intellect", + "Cool" : "Presence", + "Vigilance" : "Willpower", + "Mechanics" : "Intellect", + "Melee" : "Brawn", + "Perception" : "Cunning", + "Piloting-space" : "Agility", + "Ranged-heavy" : "Agility", + "Ranged-light" : "Agility", + "Athletics" : "Brawn", + "Coercion" : "Willpower", + "Coordination" : "Agility", + "Charm" : "Presence", + "Medicine" : "Intellect", + "Negotiation" : "Presence", + "Piloting-planetary" : "Agility", + "Stealth" : "Agility", + "skulduggery" : "Cunning", + "Brawl" : "Brawn", + "Discipline" : "Willpower", + "Gunnery" : "Agility", + "Core-worlds" : "Intellect", + "Outer-rim" : "Intellect", + "Underworld" : "Intellect", + "Leadership" : "Presence", + "Lore" : "Intellect", + "Resilience" : "Brawn", + "Streetwise" : "Cunning", + "Survival" : "Cunning", + "Xenology" : "Intellect", + "Lightsaber" : "Brawn", + "Education" : "Intellect", + "Deception" : "Cunning" +} \ No newline at end of file diff --git a/gwendolyn_old/resources/star_wars/starwarstemplates.json b/gwendolyn_old/resources/star_wars/starwarstemplates.json new file mode 100644 index 0000000..00773a9 --- /dev/null +++ b/gwendolyn_old/resources/star_wars/starwarstemplates.json @@ -0,0 +1,82 @@ +{ + "Character": { + "Name": "New Character", + "Species": "", + "Career": "", + "Specialization-trees": [], + "Soak": 0, + "Wound-threshold": 0, + "Wounds": 0, + "Strain-threshold": 0, + "Strain": 0, + "Defense-ranged": 0, + "Defense-melee": 0, + "Force-rating": 0, + "Characteristics": { + "Brawn": 2, + "Agility": 2, + "Intellect": 2, + "Cunning": 2, + "Willpower": 2, + "Presence": 2 + }, + "Skills": { + "Astrogation": 0, + "Athletics": 0, + "Brawl": 0, + "Charm": 0, + "Coercion": 0, + "Computers": 0, + "Cool": 0, + "Coordination": 0, + "Core-worlds": 0, + "Discipline": 0, + "Deception": 0, + "Education": 0, + "Gunnery": 0, + "Leadership": 0, + "Lightsaber": 0, + "Lore": 0, + "Mechanics": 0, + "Medicine": 0, + "Melee": 0, + "Negotiation": 0, + "Outer-rim": 0, + "Perception": 0, + "Piloting-planetary": 0, + "Piloting-space": 0, + "Ranged-heavy": 0, + "Ranged-light": 0, + "Resilience": 0, + "skulduggery": 0, + "Stealth": 0, + "Streetwise": 0, + "Survival": 0, + "Underworld": 0, + "Vigilance": 0, + "Xenology": 0 + }, + "Lightsaber-characteristic": "Brawn", + "Obligations": {}, + "Morality": { + "Weakness": "", + "Strength": "", + "Conflict": "", + "Morality": "" + }, + "Credits": 0, + "Equipment": [], + "Armor": "", + "Critical-injuries": {}, + "Weapons": {}, + "Talents": {}, + "Force-powers": {} + }, + "Weapon": { + "Skill" : "", + "Damage" : 0, + "Range" : "", + "Crit" : 0, + "Special" : [] + } +} \ No newline at end of file diff --git a/gwendolyn_old/resources/starting_files.json b/gwendolyn_old/resources/starting_files.json new file mode 100644 index 0000000..d370a78 --- /dev/null +++ b/gwendolyn_old/resources/starting_files.json @@ -0,0 +1,74 @@ +{ + "json":{ + "gwendolyn/resources/lookup/spells.json" : { + "Fireball" : { + "casting_time" : "1 action", + "components" : "V, S, M (a tiny ball of bat guano and sulfur)", + "description" : "A bright streak flashes from your pointing finger to a point you choose within range and then blossoms with a low roar into an explosion of flame. Each creature in a 20-foot-radius sphere centered on that point must make a Dexterity saving throw. A target takes 8d6 fire damage on a failed save, or half as much damage on a successful one. The fire spreads around corners. It ignites flammable objects in the area that aren’t being worn or carried. At Higher Levels. When you cast this spell using a spell slot of 4th level or higher, the damage increases by 1d6 for each slot level above 3rd.", + "duration" : "Instantaneous", + "level" : "3rd", + "range" : "150 feet", + "school" : "Evocation", + "ritual" : false + } + }, + "gwendolyn/resources/lookup/monsters.json" : [ + { + "name": "Bandit", + "size": "Medium", + "type": "humanoid", + "subtype": "any race", + "alignment": "any non-lawful alignment", + "armor_class": 12, + "hit_points": 11, + "hit_dice": "2d8", + "speed": "30 ft.", + "strength": 11, + "dexterity": 12, + "constitution": 12, + "intelligence": 10, + "wisdom": 10, + "charisma": 10, + "damage_vulnerabilities": "", + "damage_resistances": "", + "damage_immunities": "", + "condition_immunities": "", + "senses": "passive Perception 10", + "languages": "any one language (usually Common)", + "challenge_rating": "1/8", + "actions": [ + { + "name": "Scimitar", + "desc": "Melee Weapon Attack: +3 to hit, reach 5 ft., one target. Hit: 4 (1d6 + 1) slashing damage.", + "attack_bonus": 3, + "damage_dice": "1d6", + "damage_bonus": 1 + }, + { + "name": "Light Crossbow", + "desc": "Ranged Weapon Attack: +3 to hit, range 80 ft./320 ft., one target. Hit: 5 (1d8 + 1) piercing damage.", + "attack_bonus": 3, + "damage_dice": "1d8", + "damage_bonus": 1 + } + ] + } + ] + }, + "txt": { + "gwendolyn/resources/star_wars/destinyPoints.txt": "", + "gwendolyn/resources/movies.txt": "The Room", + "gwendolyn/resources/names.txt": "Gandalf\n", + "credentials.txt" : "Bot token: TOKEN\nWordnik API Key: KEY\nMongoDB user: USERNAME\nMongoDB password: PASSWORD\nWolframAlpha AppID: APPID\nRadarr API key: KEY\nSonarr API key: KEY\nqBittorrent username: USER\nqBittorrent password: PASSWORD", + "options.txt" : "Testing: True\nTesting guild ids:\nAdmins:" + }, + "folder" : [ + "gwendolyn/resources/lookup", + "gwendolyn/resources/games/blackjack_tables", + "gwendolyn/resources/games/connect_four_boards", + "gwendolyn/resources/games/hex_boards", + "gwendolyn/resources/games/hangman_boards", + "gwendolyn/resources/plex", + "gwendolyn/resources/games/old_images" + ] +} \ No newline at end of file diff --git a/gwendolyn_old/utils/__init__.py b/gwendolyn_old/utils/__init__.py new file mode 100644 index 0000000..c8353c0 --- /dev/null +++ b/gwendolyn_old/utils/__init__.py @@ -0,0 +1,12 @@ +"""A collections of utilities used by Gwendolyn and her functions.""" + +__all__ = ["get_options", "get_credentials", "DatabaseFuncs", "EventHandler", + "ErrorHandler", "get_params", "log_this", "cap", "make_files", + "replace_multiple", "emoji_to_command"] + +from .helper_classes import DatabaseFuncs +from .event_handlers import EventHandler, ErrorHandler +from .util_functions import (get_params, log_this, cap, make_files, + replace_multiple, emoji_to_command, long_strings, + sanitize, get_options, get_credentials, encode_id, + decode_id) diff --git a/gwendolyn/utils/event_handlers.py b/gwendolyn_old/utils/event_handlers.py similarity index 93% rename from gwendolyn/utils/event_handlers.py rename to gwendolyn_old/utils/event_handlers.py index 695005a..5884faf 100644 --- a/gwendolyn/utils/event_handlers.py +++ b/gwendolyn_old/utils/event_handlers.py @@ -13,9 +13,9 @@ import discord # Used to init discord.Game and discord.Status, as well from discord.ext import commands # Used to compare errors with command # errors -from discord_slash.context import SlashContext, ComponentContext -from gwendolyn.utils.util_functions import decode_id -from gwendolyn.exceptions import InvalidInteraction +from interactions import SlashContext, ComponentContext +from gwendolyn_old.utils.util_functions import decode_id +from gwendolyn_old.exceptions import InvalidInteraction class EventHandler(): @@ -25,8 +25,8 @@ class EventHandler(): *Methods* --------- on_ready() - on_slash_command(ctx: discord_slash.context.SlashContext) - on_reaction_add(ctx: discord_slash.context.SlashContext) + on_slash_command(ctx: interactions.SlashContext) + on_reaction_add(ctx: interactions.SlashContext) """ def __init__(self, bot): @@ -125,7 +125,7 @@ class ErrorHandler(): *Methods* --------- - on_slash_command_error(ctx: discord_slash.context.SlashContext, + on_slash_command_error(ctx: interactions.SlashContext, error: Exception) on_error(method: str) """ diff --git a/gwendolyn/utils/helper_classes.py b/gwendolyn_old/utils/helper_classes.py similarity index 100% rename from gwendolyn/utils/helper_classes.py rename to gwendolyn_old/utils/helper_classes.py diff --git a/gwendolyn_old/utils/util_functions.py b/gwendolyn_old/utils/util_functions.py new file mode 100644 index 0000000..8075425 --- /dev/null +++ b/gwendolyn_old/utils/util_functions.py @@ -0,0 +1,391 @@ +""" +Contains utility functions used by parts of the bot. + +*Functions* +----------- + sanitize(data: str, lower_case_value: bool = false) -> dict + get_options() -> dict + get_credentials() -> dict + long_strings() -> dict + get_params() -> dict + log_this(messages: Union[str, list], channel: str = "", + level: int = 20) + cap(s: str) -> str + make_files() + replace_multiple(main_string: str, to_be_replaced: list, + new_string: str) -> str + emoji_to_command(emoji: str) -> str +""" +import string +import json # Used by long_strings(), get_params() and make_files() +import logging # Used for logging +import os # Used by make_files() to check if files exist +import sys # Used to specify printing for logging +import imdb # Used to disable logging for the module + + +BASE_37 = ":" + string.digits + string.ascii_uppercase +BASE_128 = list( + string.digits + + string.ascii_letters + + "!#$€£¢¥¤&%()*+,-./;:<=>?@[]_{|}~ `¦§©®«»±µ·¿əʒ" + + "ÆØÅÐÉÈÊÇÑÖ" + + "æøåðéèêçñö" +) + +# All of this is logging configuration +FORMAT = " %(asctime)s | %(name)-16s | %(levelname)-8s | %(message)s" +PRINTFORMAT = "%(asctime)s - %(message)s" +DATEFORMAT = "%Y-%m-%d %H:%M:%S" + +logging.addLevelName(25, "PRINT") +loggingConfigParams = { + "format": FORMAT, + "datefmt": DATEFORMAT, + "level": logging.INFO, + "filename": "gwendolyn.log" +} +logging.basicConfig(**loggingConfigParams) +logger = logging.getLogger("Gwendolyn") +printer = logging.getLogger("printer") +handler = logging.StreamHandler(sys.stdout) +handler.setFormatter(logging.Formatter(fmt=PRINTFORMAT, datefmt=DATEFORMAT)) +printer.addHandler(handler) +printer.propagate = False + +imdb._logging.setLevel("CRITICAL") # pylint: disable=protected-access +# Basically disables imdbpy logging, since it's being printed to the +# terminal. + +def sanitize(data: str, lower_case_value: bool = False): + """ + Sanitize and create a dictionary from a string. + + Each element is created from a line with a : in it. The key is left + of the :, the value is right of it. + + *Parameters* + ------------ + data: str + The string to create a dict from. + lower_case_value: bool = False + Whether the value of each element should be lowercase. + + *Returns* + --------- + dct: dict + The sanitized dictionary of elements. + + """ + data = data.splitlines() + dct = {} + for line in data: + if line[0] != "#" and ":" in line: + line_values = line.split(":") + line_values[0] = line_values[0].lower() + line_values[1] = line_values[1].replace(" ", "") + if lower_case_value: + line_values[1] = line_values[1].lower() + + if line_values[0] in ["testing guild ids", "admins"]: + line_values[1] = line_values[1].split(",") + if all(i.isnumeric() for i in line_values[1]): + line_values[1] = [int(i) for i in line_values[1]] + + if any(i == line_values[1] for i in ["true", "false"]): + line_values[1] = (line_values[1] == "true") + + dct[line_values[0]] = line_values[1] + + return dct + + +def get_options(): + """ + Get the bot options as dict. + + *Returns* + --------- + options: dict + The options of the bot. + """ + with open("options.txt", "r", encoding="utf-8") as file_pointer: + data = sanitize(file_pointer.read(), True) + + options = {} + + options["testing"] = data["testing"] + options["guild_ids"] = data["testing guild ids"] + options["admins"] = data["admins"] + return options + +def get_credentials(): + """ + Returns the credentials used by the bot as a dict. + + *Returns* + --------- + credentials: dict + The credentials used by the bot. + """ + with open("credentials.txt", "r", encoding="utf-8") as file_pointer: + data = sanitize(file_pointer.read()) + + credentials = {} + + credentials["token"] = data["bot token"] + credentials["wordnik_key"] = data["wordnik api key"] + credentials["mongo_db_user"] = data["mongodb user"] + credentials["mongo_db_password"] = data["mongodb password"] + credentials["wolfram_alpha_key"] = data["wolframalpha appid"] + credentials["radarr_key"] = data["radarr api key"] + credentials["sonarr_key"] = data["sonarr api key"] + credentials["qbittorrent_username"] = data["qbittorrent username"] + credentials["qbittorrent_password"] = data["qbittorrent password"] + + return credentials + +def long_strings(): + """ + Get the data from gwendolyn/resources/long_strings.json. + + *Returns* + --------- + data: dict + The long strings and their keys. + """ + long_strings_path = "gwendolyn/resources/long_strings.json" + with open(long_strings_path, "r", encoding="utf-8") as file_pointer: + data = json.load(file_pointer) + + return data + + +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) + + options = get_options() + + if options["testing"]: + for parameter in slash_parameters: + slash_parameters[parameter]["guild_ids"] = options["guild_ids"] + + return slash_parameters + + +def log_this(messages, channel: str = "", level: int = 20): + """ + Log something in Gwendolyn's logs. + + *Parameters* + ------------ + messages: Union[str, list] + A string or list of strings to be logged. If there are + multiple strings and the level is PRINT (25) or higher, + only the first string will be printed. + channel: str = "" + The channel the event to be logged occurred in. Will be + logged along with the message(s). + level: int = 20 + The level to log the message(s) at. If PRINT (25) or + higher, the first message will be printed to the console. + """ + channel = channel.replace("Direct Message with ", "") + if isinstance(messages, str): + messages = [messages] + + print_message = messages[0] + + for i, message in enumerate(messages): + if channel != "": + messages[i] = f"{message} - ({channel})" # Adds channel ID + # to log messages + + if len(messages) > 1: # Tells user to check the log if there are + # more messages there + print_message += " (details in log)" + + if level >= 25: + printer.log(level, print_message) + + for log_message in messages: + logger.log(level, log_message) + + +def cap(input_string: str): + """ + Capitalize a string like a movie title. + + That means "of" and "the" are not capitalized. + + *Parameters* + ------------ + input_string: str + The string to capitalized. + + *Returns* + --------- + return_string: str + The capitalized string. + """ + no_caps_list = ["of", "the"] + word_number = 0 + string_list = input_string.split() + return_string = '' + for word in string_list: + word_number += 1 + if word not in no_caps_list or word_number == 1: + word = word.capitalize() + return_string += word+" " + return_string = return_string[:-1] + return return_string + + +def make_files(): + """Create all the files and directories needed by Gwendolyn.""" + def make_json_file(path, content): + """Create json file if it doesn't exist.""" + if not os.path.isfile(path): + log_this(path.split("/")[-1]+" didn't exist. Making it now.") + with open(path, "w", encoding="utf-8") as file_pointer: + json.dump(content, file_pointer, indent=4) + + def make_txt_file(path, content): + """Create txt file if it doesn't exist.""" + if not os.path.isfile(path): + log_this(path.split("/")[-1]+" didn't exist. Making it now.") + with open(path, "w", encoding="utf-8") as file_pointer: + file_pointer.write(content) + + def directory(path): + """Create directory if it doesn't exist.""" + if not os.path.isdir(path): + os.makedirs(path) + log_this("The "+path.split("/")[-1]+" directory didn't exist") + + file_path = "gwendolyn/resources/starting_files.json" + with open(file_path, "r", encoding="utf-8") as file_pointer: + data = json.load(file_pointer) + + for path, content in data["json"].items(): + make_json_file(path, content) + + for path, content in data["txt"].items(): + make_txt_file(path, content) + + for path in data["folder"]: + directory(path) + + +def replace_multiple(main_string: str, to_be_replaced: list, new_string: str): + """ + Replace multiple substrings in a string with the same substring. + + *Parameters* + ------------ + main_string: str + The string to replace substrings in. + to_be_replaced: list + The substrings to replace. + new_string: str + The string to replace the substrings with. + + *Returns* + --------- + main_string: str + The string with the substrings replaced. + """ + # Iterate over the strings to be replaced + for elem in to_be_replaced: + # Check if string is in the main string + if elem in main_string: + # Replace the string + main_string = main_string.replace(elem, new_string) + + return main_string + + +def emoji_to_command(emoji: str): + """ + Convert emoji to text. + + *Parameters* + ------------ + emoji: str + The emoji to decipher. + + *Returns* + --------- + : str + The deciphered string. + """ + if emoji == "1️⃣": + return_value = 1 + elif emoji == "2️⃣": + return_value = 2 + elif emoji == "3️⃣": + return_value = 3 + elif emoji == "4️⃣": + return_value = 4 + elif emoji == "5️⃣": + return_value = 5 + elif emoji == "6️⃣": + return_value = 6 + elif emoji == "7️⃣": + return_value = 7 + elif emoji == "🎲": + return_value = "roll" + elif emoji == "❌": + return_value = "none" + elif emoji == "✔️": + return_value = 1 + else: + return_value = "" + + return return_value + +def encode_id(info: list): + letters = list(":".join(info)) + dec = 0 + for i, letter in enumerate(letters): + try: + dec += (37**i) * BASE_37.index(letter.upper()) + except ValueError: + log_this(f"Could not encode letter {letter}", level=30) + + custom_id = [] + + while dec: + custom_id.append(BASE_128[dec % 128]) + dec = dec // 128 + + custom_id = ''.join(custom_id) + log_this(f"Encoded {info} to {custom_id}") + return custom_id + + +def decode_id(custom_id: str): + letters = list(custom_id) + dec = 0 + for i, letter in enumerate(letters): + dec += (128**i) * BASE_128.index(letter) + + info_string = [] + + while dec: + info_string.append(BASE_37[dec % 37]) + dec = dec // 37 + + info = ''.join(info_string).split(':') + log_this(f"Decoded {custom_id} to be {info}") + return ''.join(info_string).split(':') diff --git a/main.py b/main.py index ba3dee2..2525734 100644 --- a/main.py +++ b/main.py @@ -1,30 +1,17 @@ """Runs the Gwendolyn bot.""" -import platform # Used to test if the bot is running on windows, in - # order to fix a bug with asyncio -import asyncio # used to set change the loop policy if the bot is - # running on windows - from gwendolyn import Gwendolyn from gwendolyn.utils import make_files - def main(): """Starts the bot""" - if platform.system() == "Windows": - asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) - # Creates the required files make_files() # Creates the Bot bot = Gwendolyn() - - try: - # Runs the whole shabang - bot.run(bot.credentials["token"]) - except Exception as exception: # pylint: disable=broad-except - bot.log(bot.long_strings[f"Can't log in: {repr(exception)}"]) + bot.load_extension("gwendolyn.ext.misc") + bot.start("NzM4NzYwODkyNjczNTU2NTYy.GPjy55.xbYtH20UtCjOl87C-2DEPx2BwFWh2-xn1-9YnE") if __name__ == "__main__": main() diff --git a/project-guidelines.md b/project-guidelines.md deleted file mode 100644 index 583932d..0000000 --- a/project-guidelines.md +++ /dev/null @@ -1,113 +0,0 @@ -# Git - -## Workflow rules -1. Coding on Gwendolyn is performed in [feature branch workflow](https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow). This means all code should be added in a separate feature branch before it's added to the `master` branch. -1. Feature branches must be created from current `master` branch when -1. Never push to the `master` branch. All code from feature branches should be added with pull requests. [NikolajDanger](https://github.com/NikolajDanger) is the only developer who can accept pull requests to `master`. -1. ***All code*** pushed to `master` must: - + Work - + Be reachable when the bot is running - + Follow the code style guidelines laid out later in this doc. -1. Code pushed to feature branches require none of those. - -## Commit messages -Commit subject lines should not be longer than 72 characters. Each line in the body must not be longer than 80 characters. - -Whether a commit requires more than a subject line is up to the developer's discretion. Another developer should be able to know _exactly_ what has changed by reading the commit. - -### Emoji -Commit messages must start with an emoji relating to the nature of the commit, because emojis are fun. Emojis are put in commit messages with github shortcodes (e.g. :heart: is `:heart:`). [Emojipedia](https://emojipedia.org/) has the github shortcodes for all emoji. - -There are no rules for which emoji to use where, but here's some inspiration: - -:bug: (`:bug:`) - Fixing a bug. - -:pencil: (`:pencil:`) - Adding to or changing `README.md`, documentation, logging code or other text. - -:stop_sign: (`:stop_sign:`) - Adding or changing code that deals with exceptions and errors. - -:sparkles: (`:sparkles:`) - Adding new feature. - -# Terminology -Comments, strings, variable names, class names, docstrings, as well as all other text in your code, filenames and directory names should use this terminology correctly. - -**bot** - The current discord client and instance of the Gwendolyn class. - -**cog** - A class that contains an amount of bot commands. - -**ctx** - The [context](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#context) of a command. All command and error functions should use `ctx` as the context variable. - -**utils** - Functions, classes and methods that are only used by the bot and don't use the Discord API. - -# Code - -## Code Style -All the Python code should follow the [PEP 8 guidelines](https://www.python.org/dev/peps/pep-0008/), with the following additions: -+ Variable and function names must fully consist of either full words or common/understandable abbreviations. -+ Use f-strings when applicable. - -### Documentation -+ Comment lines should not exede 72 characters. -+ There should be a comment for each import, explaining where the module is used. -+ Comments should explain things that are not obvious and not described in a docstring. - -### Docstrings -+ There should be a docstring defining every module, function, class and method for all Python code in Gwendolyn. -+ Obvious cases can be described in a single-line docstring, `"""Like this"""`. -+ Single-line docstrings should have the start- and end-quotations be on the same line. Multi-line docstrings should have the end-quotation on its own line: - ``` - """Like this - - Some docstring - """ - ``` -+ Class docstrings should define and describe all class attributes, and provide a list of class methods, showing input and output types. This information should be provided like this: - ``` - """Class docstring - - *Attributes* - ------------ - color : string - The color of the class. - dead : bool - Whether the class is dead or not. - - *Methods* - --------- - changeColor(newColor : str) -> bool - kill() -> bool - """ - ``` -+ Method and function docstrings should define and describe all parameters and what it returns, in the same format as the docstring above. -+ Module docstrings should define classes and functions in the module, in the same format as the docstring above. - -## Error Handling -Code called by a command should not have `try` and `except` statements. All errors should be raised to the `on_command_error()` or `Command.error()` functions, where they can be dealt with. - -## Cogs -The `Command` methods in cogs should only exist to perform small tasks or call code from elsewhere in the Gwendolyn code. Therefore, a single `Command` method should not contain more than 3 lines of code and should not use any modules other than `Discord.py` and the Gwendolyn modules. If a cog method calls a function in Gwendolyn, ctx must be passed, and the function should handle sending messages. - -## Codebase Management -### Folders -+ `cogs/` contains the command cogs. -+ `funcs/` contains all functions and classes called on to perform commands. All functions must be accessible through a class, of which the `Gwendolyn` class has an instance as an attribute. -+ `gwendolyn/resources/` contains the images, lookup databases, fonts etc. that the rest of the code uses. - -### Important files -+ `Gwendolyn.py` contains the Gwendolyn class and running it starts the bot. It should be lightweight and not more than 100 lines. - -## Logging -Things you should know about the logging: -+ `log()` is a method of the `Gwendolyn` class. -+ It is used to log to the log-file (`gwendolyn.log`) and print to the command line. -+ The function can take either a list of strings or a string as its first parameter. If the parameter is a string, it is converted to a list of 1 string. -+ The first string in the list is printed. All strings in the list are logged to the log-file. -+ If the list is longer than 1 string, `(details in log)` is added to the printed string. -+ The level parameter is 20 by default, which means the level is `INFO`. 40 corresponds to a level of `ERROR`, and 25 corresponds to `print`. -+ Logs of level `INFO` are not printed. -+ Logs of level `ERROR` should only be created in the `on_command_error()`, `on_error()` or `Command.error()` functions. - -### Logging rules -1. Never call the `log_this()` function from `/utils/utilFuncs/`. Always call `bot.log`. -1. The `on_slash_command()` and `on_ready()` events are the only times log should be called at level 25. `INFO` level logs should be used for all other logging. -1. Always provide the channel id if available. Although you shouldn't pass the channel id to a function purely to use it in logs. diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 8032025..0000000 --- a/requirements.txt +++ /dev/null @@ -1,14 +0,0 @@ -d20==1.1.2 -discord.py==1.7.3 -discord_py_slash_command==3.0.3 -fandom_py==0.2.1 -finnhub_python==2.4.13 -GitPython==3.1.27 -IMDbPY==2021.4.18 -lxml==4.8.0 -Pillow==9.1.0 -pymongo==4.1.1 -pymongo[srv] -requests==2.27.1 -wolframalpha==5.0.0 -xmltodict==0.13.0 \ No newline at end of file