diff --git a/.gitignore b/.gitignore index e10cdc3..59cd0e4 100644 --- a/.gitignore +++ b/.gitignore @@ -153,16 +153,16 @@ static token.txt credentials.txt options.txt -resources/star_wars/destinyPoints.txt -resources/bedreNetflix/ -resources/games/hilo/ -resources/games/blackjackTables/ -resources/games/old_images/ -resources/games/connect4Boards/ -resources/games/hexBoards/ -resources/games/hangmanBoards/ -resources/lookup/monsters.json -resources/lookup/spells.json -resources/movies.txt -resources/names.txt +gwendolyn/resources/star_wars/destinyPoints.txt +gwendolyn/resources/bedre_netflix/ +gwendolyn/resources/games/hilo/ +gwendolyn/resources/games/blackjack_tables/ +gwendolyn/resources/games/old_images/ +gwendolyn/resources/games/connect4Boards/ +gwendolyn/resources/games/hex_boards/ +gwendolyn/resources/games/hangman_boards/ +gwendolyn/resources/lookup/monsters.json +gwendolyn/resources/lookup/spells.json +gwendolyn/resources/movies.txt +gwendolyn/resources/names.txt gwendolynTest.py diff --git a/gwendolyn/__init__.py b/gwendolyn/__init__.py new file mode 100644 index 0000000..17b7d0d --- /dev/null +++ b/gwendolyn/__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/cogs/event_cog.py b/gwendolyn/cogs/event_cog.py similarity index 93% rename from cogs/event_cog.py rename to gwendolyn/cogs/event_cog.py index 6216ae7..4737f8c 100644 --- a/cogs/event_cog.py +++ b/gwendolyn/cogs/event_cog.py @@ -25,7 +25,7 @@ class EventCog(commands.Cog): """Log when a slash error occurs.""" await self.bot.error_handler.on_slash_command_error(ctx, error) - async def on_error(self, method): + async def on_error(self, method, *args, **kwargs): # pylint: disable=unused-argument """Log when an error occurs.""" await self.bot.error_handler.on_error(method) diff --git a/cogs/game_cog.py b/gwendolyn/cogs/game_cog.py similarity index 65% rename from cogs/game_cog.py rename to gwendolyn/cogs/game_cog.py index d6bb92f..0caad15 100644 --- a/cogs/game_cog.py +++ b/gwendolyn/cogs/game_cog.py @@ -2,9 +2,9 @@ from discord.ext import commands # Has the cog class from discord_slash import cog_ext # Used for slash commands -from utils import getParams # pylint: disable=import-error +from gwendolyn.utils import get_params # pylint: disable=import-error -params = getParams() +params = get_params() class GamesCog(commands.Cog): @@ -42,48 +42,48 @@ class BlackjackCog(commands.Cog): """Initialize the cog.""" self.bot = bot - @cog_ext.cog_subcommand(**params["blackjackStart"]) - async def blackjackStart(self, ctx): + @cog_ext.cog_subcommand(**params["blackjack_start"]) + async def blackjack_start(self, ctx): """Start a game of blackjack.""" await self.bot.games.blackjack.start(ctx) - @cog_ext.cog_subcommand(**params["blackjackBet"]) - async def blackjackBet(self, ctx, bet): + @cog_ext.cog_subcommand(**params["blackjack_bet"]) + async def blackjack_bet(self, ctx, bet): """Enter the game of blackjack with a bet.""" await self.bot.games.blackjack.enterGame(ctx, bet) - @cog_ext.cog_subcommand(**params["blackjackStand"]) - async def blackjackStand(self, ctx, hand=""): + @cog_ext.cog_subcommand(**params["blackjack_stand"]) + async def blackjack_stand(self, ctx, hand=""): """Stand on your hand in blackjack.""" await self.bot.games.blackjack.stand(ctx, hand) - @cog_ext.cog_subcommand(**params["blackjackHit"]) - async def blackjackHit(self, ctx, hand=0): + @cog_ext.cog_subcommand(**params["blackjack_hit"]) + async def blackjack_hit(self, ctx, hand=0): """Hit on your hand in blackjack.""" await self.bot.games.blackjack.hit(ctx, hand) - @cog_ext.cog_subcommand(**params["blackjackDouble"]) - async def blackjackDouble(self, ctx, hand=0): + @cog_ext.cog_subcommand(**params["blackjack_double"]) + async def blackjack_double(self, ctx, hand=0): """Double in blackjack.""" await self.bot.games.blackjack.double(ctx, hand) - @cog_ext.cog_subcommand(**params["blackjackSplit"]) - async def blackjackSplit(self, ctx, hand=0): + @cog_ext.cog_subcommand(**params["blackjack_split"]) + async def blackjack_split(self, ctx, hand=0): """Split your hand in blackjack.""" await self.bot.games.blackjack.split(ctx, hand) - @cog_ext.cog_subcommand(**params["blackjackHilo"]) - async def blackjackHilo(self, ctx): + @cog_ext.cog_subcommand(**params["blackjack_hilo"]) + async def blackjack_hilo(self, ctx): """Get the hilo value for the deck in blackjack.""" await self.bot.games.blackjack.hilo(ctx) - @cog_ext.cog_subcommand(**params["blackjackShuffle"]) - async def blackjackShuffle(self, ctx): + @cog_ext.cog_subcommand(**params["blackjack_shuffle"]) + async def blackjack_shuffle(self, ctx): """Shuffle the blackjack game.""" await self.bot.games.blackjack.shuffle(ctx) - @cog_ext.cog_subcommand(**params["blackjackCards"]) - async def blackjackCards(self, ctx): + @cog_ext.cog_subcommand(**params["blackjack_cards"]) + async def blackjack_cards(self, ctx): """Get the amount of cards left in the blackjack deck.""" await self.bot.games.blackjack.cards(ctx) @@ -95,18 +95,18 @@ class ConnectFourCog(commands.Cog): """Initialize the cog.""" self.bot = bot - @cog_ext.cog_subcommand(**params["connect_fourStartUser"]) - async def connect_fourStartUser(self, ctx, user): + @cog_ext.cog_subcommand(**params["connect_four_start_user"]) + async def connect_four_start_user(self, ctx, user): """Start a game of connect four against another user.""" await self.bot.games.connect_four.start(ctx, user) - @cog_ext.cog_subcommand(**params["connect_fourStartGwendolyn"]) - async def connect_fourStartGwendolyn(self, ctx, difficulty=3): + @cog_ext.cog_subcommand(**params["connect_four_start_gwendolyn"]) + async def connect_four_start_gwendolyn(self, ctx, difficulty=3): """Start a game of connect four against Gwendolyn.""" await self.bot.games.connect_four.start(ctx, difficulty) - @cog_ext.cog_subcommand(**params["connect_fourSurrender"]) - async def connect_fourSurrender(self, ctx): + @cog_ext.cog_subcommand(**params["connect_four_surrender"]) + async def connect_four_surrender(self, ctx): """Surrender the game of connect four.""" await self.bot.games.connect_four.surrender(ctx) @@ -118,13 +118,13 @@ class HangmanCog(commands.Cog): """Initialize the cog.""" self.bot = bot - @cog_ext.cog_subcommand(**params["hangmanStart"]) - async def hangmanStart(self, ctx): + @cog_ext.cog_subcommand(**params["hangman_start"]) + async def hangman_start(self, ctx): """Start a game of hangman.""" await self.bot.games.hangman.start(ctx) - @cog_ext.cog_subcommand(**params["hangmanStop"]) - async def hangmanStop(self, ctx): + @cog_ext.cog_subcommand(**params["hangman_stop"]) + async def hangman_stop(self, ctx): """Stop the current game of hangman.""" await self.bot.games.hangman.stop(ctx) @@ -137,33 +137,33 @@ class HexCog(commands.Cog): self.bot = bot self.hex = self.bot.games.hex - @cog_ext.cog_subcommand(**params["hexStartUser"]) - async def hexStartUser(self, ctx, user): + @cog_ext.cog_subcommand(**params["hex_start_user"]) + async def hex_start_user(self, ctx, user): """Start a game of hex against another player.""" await self.hex.start(ctx, user) - @cog_ext.cog_subcommand(**params["hexStartGwendolyn"]) - async def hexStartGwendolyn(self, ctx, difficulty=2): + @cog_ext.cog_subcommand(**params["hex_start_gwendolyn"]) + async def hex_start_gwendolyn(self, ctx, difficulty=2): """Start a game of hex against Gwendolyn.""" await self.hex.start(ctx, difficulty) - @cog_ext.cog_subcommand(**params["hexPlace"]) - async def hexPlace(self, ctx, coordinates): + @cog_ext.cog_subcommand(**params["hex_place"]) + async def hex_place(self, ctx, coordinates): """Place a piece in the hex game.""" await self.hex.placeHex(ctx, coordinates, f"#{ctx.author.id}") - @cog_ext.cog_subcommand(**params["hexUndo"]) - async def hexUndo(self, ctx): + @cog_ext.cog_subcommand(**params["hex_undo"]) + async def hex_undo(self, ctx): """Undo your last hex move.""" await self.hex.undo(ctx) - @cog_ext.cog_subcommand(**params["hexSwap"]) - async def hexSwap(self, ctx): + @cog_ext.cog_subcommand(**params["hex_swap"]) + async def hex_swap(self, ctx): """Perform a hex swap.""" await self.hex.swap(ctx) - @cog_ext.cog_subcommand(**params["hexSurrender"]) - async def hexSurrender(self, ctx): + @cog_ext.cog_subcommand(**params["hex_surrender"]) + async def hex_surrender(self, ctx): """Surrender the hex game.""" await self.hex.surrender(ctx) diff --git a/cogs/lookup_cog.py b/gwendolyn/cogs/lookup_cog.py similarity index 89% rename from cogs/lookup_cog.py rename to gwendolyn/cogs/lookup_cog.py index 91167da..77c1114 100644 --- a/cogs/lookup_cog.py +++ b/gwendolyn/cogs/lookup_cog.py @@ -2,9 +2,9 @@ from discord.ext import commands # Has the cog class from discord_slash import cog_ext # Used for slash commands -from utils import getParams # pylint: disable=import-error +from gwendolyn.utils import get_params # pylint: disable=import-error -params = getParams() +params = get_params() class LookupCog(commands.Cog): diff --git a/cogs/misc_cog.py b/gwendolyn/cogs/misc_cog.py similarity index 77% rename from cogs/misc_cog.py rename to gwendolyn/cogs/misc_cog.py index ab6e146..cd2bffe 100644 --- a/cogs/misc_cog.py +++ b/gwendolyn/cogs/misc_cog.py @@ -2,9 +2,9 @@ from discord.ext import commands # Has the cog class from discord_slash import cog_ext # Used for slash commands -from utils import getParams # pylint: disable=import-error +from gwendolyn.utils import get_params # pylint: disable=import-error -params = getParams() +params = get_params() class MiscCog(commands.Cog): @@ -15,8 +15,8 @@ class MiscCog(commands.Cog): self.bot = bot self.bot.remove_command("help") self.generators = bot.other.generators - self.bedreNetflix = bot.other.bedreNetflix - self.nerdShit = bot.other.nerdShit + self.bedre_netflix = bot.other.bedre_netflix + self.nerd_shit = bot.other.nerd_shit @cog_ext.cog_slash(**params["ping"]) async def ping(self, ctx): @@ -29,7 +29,7 @@ class MiscCog(commands.Cog): await self.bot.stop(ctx) @cog_ext.cog_slash(**params["help"]) - async def helpCommand(self, ctx, command=""): + async def help_command(self, ctx, command=""): """Get help for commands.""" await self.bot.other.helpFunc(ctx, command) @@ -69,29 +69,29 @@ class MiscCog(commands.Cog): await self.generators.tavernGen(ctx) @cog_ext.cog_slash(**params["wiki"]) - async def wiki(self, ctx, wikiPage=""): + async def wiki(self, ctx, wiki_page=""): """Get a page on a fandom wiki.""" - await self.bot.other.findWikiPage(ctx, wikiPage) + await self.bot.other.findWikiPage(ctx, wiki_page) - @cog_ext.cog_slash(**params["addMovie"]) - async def addMovie(self, ctx, movie): + @cog_ext.cog_slash(**params["add_movie"]) + async def add_movie(self, ctx, movie): """Search for a movie and add it to the Plex server.""" - await self.bedreNetflix.requestMovie(ctx, movie) + await self.bedre_netflix.requestMovie(ctx, movie) - @cog_ext.cog_slash(**params["addShow"]) - async def addShow(self, ctx, show): + @cog_ext.cog_slash(**params["add_show"]) + async def add_show(self, ctx, show): """Search for a show and add it to the Plex server.""" - await self.bedreNetflix.requestShow(ctx, show) + await self.bedre_netflix.requestShow(ctx, show) @cog_ext.cog_slash(**params["downloading"]) async def downloading(self, ctx, parameters="-d"): """Get the current downloading torrents.""" - await self.bedreNetflix.downloading(ctx, parameters) + await self.bedre_netflix.downloading(ctx, parameters) @cog_ext.cog_slash(**params["wolf"]) async def wolf(self, ctx, query): """Perform a search on Wolfram Alpha.""" - await self.nerdShit.wolfSearch(ctx, query) + await self.nerd_shit.wolfSearch(ctx, query) def setup(bot): diff --git a/cogs/star_wars_cog.py b/gwendolyn/cogs/star_wars_cog.py similarity index 93% rename from cogs/star_wars_cog.py rename to gwendolyn/cogs/star_wars_cog.py index b029f9f..10101f0 100644 --- a/cogs/star_wars_cog.py +++ b/gwendolyn/cogs/star_wars_cog.py @@ -2,9 +2,9 @@ from discord.ext import commands from discord_slash import cog_ext -from utils import getParams # pylint: disable=import-error +from gwendolyn.utils import get_params # pylint: disable=import-error -params = getParams() +params = get_params() class StarWarsCog(commands.Cog): diff --git a/funcs/__init__.py b/gwendolyn/funcs/__init__.py similarity index 100% rename from funcs/__init__.py rename to gwendolyn/funcs/__init__.py diff --git a/funcs/games/__init__.py b/gwendolyn/funcs/games/__init__.py similarity index 100% rename from funcs/games/__init__.py rename to gwendolyn/funcs/games/__init__.py diff --git a/funcs/games/blackjack.py b/gwendolyn/funcs/games/blackjack.py similarity index 85% rename from funcs/games/blackjack.py rename to gwendolyn/funcs/games/blackjack.py index d02e087..4b5b1be 100644 --- a/funcs/games/blackjack.py +++ b/gwendolyn/funcs/games/blackjack.py @@ -18,7 +18,7 @@ from PIL import Image, ImageDraw, ImageFont from shutil import copyfile -from utils import replaceMultiple +from gwendolyn.utils import replace_multiple class Blackjack(): @@ -48,7 +48,7 @@ class Blackjack(): self.draw = DrawBlackjack(bot) self.decks = 4 - def _blackjackShuffle(self, channel: str): + def _blackjack_shuffle(self, channel: str): """ Shuffle an amount of decks equal to self.decks. @@ -62,23 +62,23 @@ class Blackjack(): """ self.bot.log("Shuffling the blackjack deck") - with open("resources/games/deckOfCards.txt", "r") as f: + with open("gwendolyn/resources/games/deck_of_cards.txt", "r") as f: deck = f.read() allDecks = deck.split("\n") * self.decks random.shuffle(allDecks) - blackjackCards = self.bot.database["blackjack cards"] + blackjack_cards = self.bot.database["blackjack cards"] cards = {"_id": channel} cardUpdater = {"$set": {"_id": channel, "cards": allDecks}} - blackjackCards.update_one(cards, cardUpdater, upsert=True) + blackjack_cards.update_one(cards, cardUpdater, upsert=True) # Creates hilo file self.bot.log(f"creating hilo doc for {channel}") data = 0 - blackjackHilo = self.bot.database["hilo"] + blackjack_hilo = self.bot.database["hilo"] hiloUpdater = {"$set": {"_id": channel, "hilo": data}} - blackjackHilo.update_one({"_id": channel}, hiloUpdater, upsert=True) + blackjack_hilo.update_one({"_id": channel}, hiloUpdater, upsert=True) def _calcHandValue(self, hand: list): """ @@ -103,7 +103,7 @@ class Blackjack(): for card in hand: cardValue = card[0] - cardValue = replaceMultiple(cardValue, ["0", "k", "q", "j"], "10") + cardValue = replace_multiple(cardValue, ["0", "k", "q", "j"], "10") if cardValue == "a": length = len(values) for x in range(length): @@ -135,17 +135,17 @@ class Blackjack(): """ self.bot.log("drawing a card") - blackjackCards = self.bot.database["blackjack cards"] - drawnCard = blackjackCards.find_one({"_id": channel})["cards"][0] - blackjackCards.update_one({"_id": channel}, {"$pop": {"cards": -1}}) + blackjack_cards = self.bot.database["blackjack cards"] + drawnCard = blackjack_cards.find_one({"_id": channel})["cards"][0] + blackjack_cards.update_one({"_id": channel}, {"$pop": {"cards": -1}}) value = self._calcHandValue([drawnCard]) - blackjackHilo = self.bot.database["hilo"] + blackjack_hilo = self.bot.database["hilo"] if value <= 6: - blackjackHilo.update_one({"_id": channel}, {"$inc": {"hilo": 1}}) + blackjack_hilo.update_one({"_id": channel}, {"$inc": {"hilo": 1}}) elif value >= 10: - blackjackHilo.update_one({"_id": channel}, {"$inc": {"hilo": -1}}) + blackjack_hilo.update_one({"_id": channel}, {"$inc": {"hilo": -1}}) return drawnCard @@ -168,22 +168,22 @@ class Blackjack(): done = False dealerHand = game["dealer hand"] - blackjackGames = self.bot.database["blackjack games"] + blackjack_games = self.bot.database["blackjack games"] if self._calcHandValue(dealerHand) < 17: dealerHand.append(self._drawCard(channel)) dealerUpdater = {"$set": {"dealer hand": dealerHand}} - blackjackGames.update_one({"_id": channel}, dealerUpdater) + blackjack_games.update_one({"_id": channel}, dealerUpdater) else: done = True if self._calcHandValue(dealerHand) > 21: dealerUpdater = {"$set": {"dealer busted": True}} - blackjackGames.update_one({"_id": channel}, dealerUpdater) + blackjack_games.update_one({"_id": channel}, dealerUpdater) return done - def _blackjackContinue(self, channel: str): + def _blackjack_continue(self, channel: str): """ Continues the blackjack game to the next round. @@ -206,8 +206,8 @@ class Blackjack(): done = False - blackjackGames = self.bot.database["blackjack games"] - blackjackGames.update_one({"_id": channel}, {"$inc": {"round": 1}}) + blackjack_games = self.bot.database["blackjack games"] + blackjack_games.update_one({"_id": channel}, {"$inc": {"round": 1}}) allStanding = True preAllStanding = True @@ -219,20 +219,20 @@ class Blackjack(): done = self._dealerDraw(channel) message = "The dealer draws a card." - blackjackGames.find_one({"_id": channel}) + blackjack_games.find_one({"_id": channel}) self.bot.log("Testing if all are standing") for user in game["user hands"]: userHand = game["user hands"][user] - testParams = [userHand, allStanding, preAllStanding, True] - standingTest = (self._testIfStanding(*testParams)) + test_parameters = [userHand, allStanding, preAllStanding, True] + standingTest = (self._testIfStanding(*test_parameters)) newUser, allStanding, preAllStanding = standingTest handUpdater = {"$set": {"user hands."+user: newUser}} - blackjackGames.update_one({"_id": channel}, handUpdater) + blackjack_games.update_one({"_id": channel}, handUpdater) if allStanding: gameUpdater = {"$set": {"all standing": True}} - blackjackGames.update_one({"_id": channel}, gameUpdater) + blackjack_games.update_one({"_id": channel}, gameUpdater) self.draw.drawImage(channel) @@ -303,23 +303,23 @@ class Blackjack(): if topLevel: if hand["split"] >= 1: testHand = hand["other hand"] - testParams = [testHand, allStanding, preAllStanding, False] - standingTest = (self._testIfStanding(*testParams)) + test_parameters = [testHand, allStanding, preAllStanding, False] + standingTest = (self._testIfStanding(*test_parameters)) hand["other hand"], allStanding, preAllStanding = standingTest if hand["split"] >= 2: testHand = hand["third hand"] - testParams = [testHand, allStanding, preAllStanding, False] - standingTest = (self._testIfStanding(*testParams)) + test_parameters = [testHand, allStanding, preAllStanding, False] + standingTest = (self._testIfStanding(*test_parameters)) hand["third hand"], allStanding, preAllStanding = standingTest if hand["split"] >= 3: testHand = hand["fourth hand"] - testParams = [testHand, allStanding, preAllStanding, False] - standingTest = (self._testIfStanding(*testParams)) + test_parameters = [testHand, allStanding, preAllStanding, False] + standingTest = (self._testIfStanding(*test_parameters)) hand["fourth hand"], allStanding, preAllStanding = standingTest return hand, allStanding, preAllStanding - def _blackjackFinish(self, channel: str): + def _blackjack_finish(self, channel: str): """ Generate the winnings message after the blackjack game ends. @@ -352,21 +352,21 @@ class Blackjack(): winningCalc = (self._calcWinnings(*_calcWinningsParams)) winnings, netWinnings, reason = winningCalc - userName = self.bot.database_funcs.getName(user) + user_name = self.bot.database_funcs.get_name(user) if winnings < 0: if winnings == -1: - finalWinnings += f"{userName} lost 1 GwendoBuck {reason}\n" + finalWinnings += f"{user_name} lost 1 GwendoBuck {reason}\n" else: moneyLost = -1 * winnings - winningText = f"{userName} lost {moneyLost} GwendoBucks" + winningText = f"{user_name} lost {moneyLost} GwendoBucks" winningText += f" {reason}\n" finalWinnings += winningText else: if winnings == 1: - finalWinnings += f"{userName} won 1 GwendoBuck {reason}\n" + finalWinnings += f"{user_name} won 1 GwendoBuck {reason}\n" else: - winningText = f"{userName} won {winnings} GwendoBucks" + winningText = f"{user_name} won {winnings} GwendoBucks" winningText += f" {reason}\n" finalWinnings += winningText @@ -554,7 +554,7 @@ class Blackjack(): return roundDone - async def _blackjackLoop(self, channel, gameRound: int, gameID: str): + async def _blackjack_loop(self, channel, gameRound: int, gameID: str): """ Run blackjack logic and continue if enough time passes. @@ -569,31 +569,31 @@ class Blackjack(): """ self.bot.log("Loop "+str(gameRound), str(channel.id)) - oldImagePath = f"resources/games/old_images/blackjack{channel.id}" - with open(oldImagePath, "r") as f: - oldImage = await channel.fetch_message(int(f.read())) + old_imagePath = f"gwendolyn/resources/games/old_images/blackjack{channel.id}" + with open(old_imagePath, "r") as f: + old_image = await channel.fetch_message(int(f.read())) - continueData = (self._blackjackContinue(str(channel.id))) + continueData = (self._blackjack_continue(str(channel.id))) new_message, allStanding, gamedone = continueData if new_message != "": self.bot.log(new_message, str(channel.id)) await channel.send(new_message) if not gamedone: - await oldImage.delete() - tablesPath = "resources/games/blackjackTables/" - filePath = f"{tablesPath}blackjackTable{channel.id}.png" - oldImage = await channel.send(file=discord.File(filePath)) - with open(oldImagePath, "w") as f: - f.write(str(oldImage.id)) + await old_image.delete() + tablesPath = "gwendolyn/resources/games/blackjack_tables/" + file_path = f"{tablesPath}blackjack_table{channel.id}.png" + old_image = await channel.send(file=discord.File(file_path)) + with open(old_imagePath, "w") as f: + f.write(str(old_image.id)) if allStanding: await asyncio.sleep(5) else: await asyncio.sleep(120) - blackjackGames = self.bot.database["blackjack games"] - game = blackjackGames.find_one({"_id": str(channel.id)}) + blackjack_games = self.bot.database["blackjack games"] + game = blackjack_games.find_one({"_id": str(channel.id)}) if game is None: rightRound = False @@ -604,11 +604,11 @@ class Blackjack(): if rightRound: if not gamedone: - log_message = f"Loop {gameRound} calling self._blackjackLoop()" + log_message = f"Loop {gameRound} calling self._blackjack_loop()" self.bot.log(log_message, str(channel.id)) - await self._blackjackLoop(channel, gameRound+1, gameID) + await self._blackjack_loop(channel, gameRound+1, gameID) else: - new_message = self._blackjackFinish(str(channel.id)) + new_message = self._blackjack_finish(str(channel.id)) await channel.send(new_message) else: log_message = f"Ending loop on round {gameRound}" @@ -631,8 +631,8 @@ class Blackjack(): user = f"#{ctx.author.id}" roundDone = False - blackjackGames = self.bot.database["blackjack games"] - game = blackjackGames.find_one({"_id": channel}) + blackjack_games = self.bot.database["blackjack games"] + game = blackjack_games.find_one({"_id": channel}) if user in game["user hands"]: @@ -670,8 +670,8 @@ class Blackjack(): handPath = f"user hands.{user}" gameUpdater = {"$set": {handPath: hand}} - blackjackGames.update_one({"_id": channel}, gameUpdater) - game = blackjackGames.find_one({"_id": channel}) + blackjack_games.update_one({"_id": channel}, gameUpdater) + game = blackjack_games.find_one({"_id": channel}) roundDone = self._isRoundDone(game) sendMessage = f"{ctx.author.display_name} hit" @@ -685,8 +685,8 @@ class Blackjack(): if roundDone: gameID = game["gameID"] - self.bot.log("Hit calling self._blackjackLoop()", channel) - await self._blackjackLoop(ctx.channel, game["round"]+1, gameID) + self.bot.log("Hit calling self._blackjack_loop()", channel) + await self._blackjack_loop(ctx.channel, game["round"]+1, gameID) async def double(self, ctx: discord_slash.context.SlashContext, handNumber: int = 0): @@ -704,9 +704,9 @@ class Blackjack(): channel = str(ctx.channel_id) user = f"#{ctx.author.id}" roundDone = False - blackjackGames = self.bot.database["blackjack games"] + blackjack_games = self.bot.database["blackjack games"] - game = blackjackGames.find_one({"_id": channel}) + game = blackjack_games.find_one({"_id": channel}) if user in game["user hands"]: handParams = [game["user hands"][user], handNumber] @@ -754,14 +754,14 @@ class Blackjack(): handPath = f"user hands.{user}" gameUpdater = {"$set": {handPath: hand}} - blackjackGames.update_one({"_id": channel}, gameUpdater) + blackjack_games.update_one({"_id": channel}, gameUpdater) - game = blackjackGames.find_one({"_id": channel}) + game = blackjack_games.find_one({"_id": channel}) roundDone = self._isRoundDone(game) sendMessage = self.bot.long_strings["Blackjack double"] - userName = self.bot.database_funcs.getName(user) - sendMessage = sendMessage.format(bet, userName) + user_name = self.bot.database_funcs.get_name(user) + sendMessage = sendMessage.format(bet, user_name) log_message = "They succeeded" else: log_message = "They tried to double without being in the game" @@ -772,8 +772,8 @@ class Blackjack(): if roundDone: gameID = game["gameID"] - self.bot.log("Double calling self._blackjackLoop()", channel) - await self._blackjackLoop(ctx.channel, game["round"]+1, gameID) + self.bot.log("Double calling self._blackjack_loop()", channel) + await self._blackjack_loop(ctx.channel, game["round"]+1, gameID) async def stand(self, ctx: discord_slash.context.SlashContext, handNumber: int = 0): @@ -792,8 +792,8 @@ class Blackjack(): user = f"#{ctx.author.id}" roundDone = False - blackjackGames = self.bot.database["blackjack games"] - game = blackjackGames.find_one({"_id": channel}) + blackjack_games = self.bot.database["blackjack games"] + game = blackjack_games.find_one({"_id": channel}) if game is not None and user in game["user hands"]: handParams = [game["user hands"][user], handNumber] @@ -824,8 +824,8 @@ class Blackjack(): handPath = f"user hands.{user}" gameUpdater = {"$set": {handPath: hand}} - blackjackGames.update_one({"_id": channel}, gameUpdater) - game = blackjackGames.find_one({"_id": channel}) + blackjack_games.update_one({"_id": channel}, gameUpdater) + game = blackjack_games.find_one({"_id": channel}) roundDone = self._isRoundDone(game) sendMessage = f"{ctx.author.display_name} is standing" @@ -840,8 +840,8 @@ class Blackjack(): if roundDone: gameID = game["gameID"] - self.bot.log("Stand calling self._blackjackLoop()", channel) - await self._blackjackLoop(ctx.channel, game["round"]+1, gameID) + self.bot.log("Stand calling self._blackjack_loop()", channel) + await self._blackjack_loop(ctx.channel, game["round"]+1, gameID) async def split(self, ctx: discord_slash.context.SlashContext, handNumber: int = 0): @@ -861,8 +861,8 @@ class Blackjack(): roundDone = False handNumberError = False - blackjackGames = self.bot.database["blackjack games"] - game = blackjackGames.find_one({"_id": channel}) + blackjack_games = self.bot.database["blackjack games"] + game = blackjack_games.find_one({"_id": channel}) if game["user hands"][user]["split"] == 0: hand = game["user hands"][user] @@ -954,7 +954,7 @@ class Blackjack(): handPath = f"user hands.{user}" gameUpdater = {"$set": {handPath: hand}} - blackjackGames.update_one({"_id": channel}, gameUpdater) + blackjack_games.update_one({"_id": channel}, gameUpdater) if otherHand == 3: otherHandPath = f"user hands.{user}.third hand" @@ -964,17 +964,17 @@ class Blackjack(): otherHandPath = f"user hands.{user}.other hand" gameUpdater = {"$set": {otherHandPath: newHand}} - blackjackGames.update_one({"_id": channel}, gameUpdater) + blackjack_games.update_one({"_id": channel}, gameUpdater) splitUpdater = {"$inc": {"user hands."+user+".split": 1}} - blackjackGames.update_one({"_id": channel}, splitUpdater) + blackjack_games.update_one({"_id": channel}, splitUpdater) - game = blackjackGames.find_one({"_id": channel}) + game = blackjack_games.find_one({"_id": channel}) roundDone = self._isRoundDone(game) sendMessage = self.bot.long_strings["Blackjack split"] - userName = self.bot.database_funcs.getName(user) - sendMessage = sendMessage.format(userName) + user_name = self.bot.database_funcs.get_name(user) + sendMessage = sendMessage.format(user_name) log_message = "They succeeded" await ctx.send(sendMessage) @@ -982,8 +982,8 @@ class Blackjack(): if roundDone: gameID = game["gameID"] - self.bot.log("Stand calling self._blackjackLoop()", channel) - await self._blackjackLoop(ctx.channel, game["round"]+1, gameID) + self.bot.log("Stand calling self._blackjack_loop()", channel) + await self._blackjack_loop(ctx.channel, game["round"]+1, gameID) async def enterGame(self, ctx: discord_slash.context.SlashContext, bet: int): @@ -1002,9 +1002,9 @@ class Blackjack(): user = f"#{ctx.author.id}" collection = self.bot.database["blackjack games"] game = collection.find_one({"_id": channel}) - userName = self.bot.database_funcs.getName(user) + user_name = self.bot.database_funcs.get_name(user) - self.bot.log(f"{userName} is trying to join the Blackjack game") + self.bot.log(f"{user_name} is trying to join the Blackjack game") if game is None: sendMessage = "There is no game going on in this channel" @@ -1031,13 +1031,13 @@ class Blackjack(): handValue = self._calcHandValue(playerHand) if handValue == 21: - blackjackHand = True + blackjack_hand = True else: - blackjackHand = False + blackjack_hand = False newHand = { "hand": playerHand, "bet": bet, "standing": False, - "busted": False, "blackjack": blackjackHand, + "busted": False, "blackjack": blackjack_hand, "hit": True, "doubled": False, "split": 0, "other hand": {}, "third hand": {}, "fourth hand": {} } @@ -1047,7 +1047,7 @@ class Blackjack(): enterGameText = "entered the game with a bet of" betText = f"{bet} GwendoBucks" - sendMessage = f"{userName} {enterGameText} {betText}" + sendMessage = f"{user_name} {enterGameText} {betText}" log_message = sendMessage self.bot.log(log_message) @@ -1064,7 +1064,7 @@ class Blackjack(): """ await self.bot.defer(ctx) channel = str(ctx.channel_id) - blackjackMinCards = 50 + blackjack_minCards = 50 self.bot.log("Starting blackjack game") await ctx.send("Starting a new game of blackjack") @@ -1074,8 +1074,8 @@ class Blackjack(): cardsLeft = len(cards["cards"]) # Shuffles if not enough cards - if cardsLeft < blackjackMinCards: - self._blackjackShuffle(channel) + if cardsLeft < blackjack_minCards: + self._blackjack_shuffle(channel) self.bot.log("Shuffling the blackjack deck...", channel) await ctx.channel.send("Shuffling the deck...") @@ -1101,9 +1101,9 @@ class Blackjack(): self.bot.database["blackjack games"].insert_one(newGame) - tableImagesPath = "resources/games/blackjackTables/" - emptyTableImagePath = f"resources/games/blackjackTable.png" - newTableImagePath = f"{tableImagesPath}blackjackTable{channel}.png" + tableImagesPath = "gwendolyn/resources/games/blackjack_tables/" + emptyTableImagePath = f"gwendolyn/resources/games/blackjack_table.png" + newTableImagePath = f"{tableImagesPath}blackjack_table{channel}.png" copyfile(emptyTableImagePath, newTableImagePath) gameStarted = True @@ -1112,20 +1112,20 @@ class Blackjack(): sendMessage = self.bot.long_strings["Blackjack started"] await ctx.channel.send(sendMessage) - tableImagesPath = "resources/games/blackjackTables/" - filePath = f"{tableImagesPath}blackjackTable{channel}.png" + tableImagesPath = "gwendolyn/resources/games/blackjack_tables/" + file_path = f"{tableImagesPath}blackjack_table{channel}.png" - oldImage = await ctx.channel.send(file=discord.File(filePath)) + old_image = await ctx.channel.send(file=discord.File(file_path)) - with open("resources/games/old_images/blackjack"+channel, "w") as f: - f.write(str(oldImage.id)) + with open("gwendolyn/resources/games/old_images/blackjack"+channel, "w") as f: + f.write(str(old_image.id)) await asyncio.sleep(30) gamedone = False - blackjackGames = self.bot.database["blackjack games"] - game = blackjackGames.find_one({"_id": channel}) + blackjack_games = self.bot.database["blackjack games"] + game = blackjack_games.find_one({"_id": channel}) if len(game["user hands"]) == 0: gamedone = True @@ -1136,10 +1136,10 @@ class Blackjack(): # Loop of game rounds if not gamedone: - self.bot.log("start() calling _blackjackLoop()", channel) - await self._blackjackLoop(ctx.channel, 1, gameID) + self.bot.log("start() calling _blackjack_loop()", channel) + await self._blackjack_loop(ctx.channel, 1, gameID) else: - new_message = self._blackjackFinish(channel) + new_message = self._blackjack_finish(channel) await ctx.channel.send(new_message) else: sendMessage = self.bot.long_strings["Blackjack going on"] @@ -1173,7 +1173,7 @@ class Blackjack(): The context of the command. """ channel = ctx.channel_id - self._blackjackShuffle(str(channel)) + self._blackjack_shuffle(str(channel)) self.bot.log("Shuffling the blackjack deck...", str(channel)) await ctx.send("Shuffling the deck...") @@ -1188,8 +1188,8 @@ class Blackjack(): """ channel = ctx.channel_id cardsLeft = 0 - blackjackGames = self.bot.database["blackjack cards"] - cards = blackjackGames.find_one({"_id": str(channel)}) + blackjack_games = self.bot.database["blackjack cards"] + cards = blackjack_games.find_one({"_id": str(channel)}) if cards is not None: cardsLeft = len(cards["cards"]) @@ -1234,11 +1234,11 @@ class DrawBlackjack(): self.bot.log("Drawing blackjack table", channel) game = self.bot.database["blackjack games"].find_one({"_id": channel}) - font = ImageFont.truetype('resources/fonts/futura-bold.ttf', 50) - smallFont = ImageFont.truetype('resources/fonts/futura-bold.ttf', 40) + font = ImageFont.truetype('gwendolyn/resources/fonts/futura-bold.ttf', 50) + smallFont = ImageFont.truetype('gwendolyn/resources/fonts/futura-bold.ttf', 40) self.SMALLBORDER = int(self.BORDER/3.5) - table = Image.open("resources/games/blackjackTable.png") + table = Image.open("gwendolyn/resources/games/blackjack_table.png") textImage = ImageDraw.Draw(table) hands = game["user hands"] @@ -1267,7 +1267,7 @@ class DrawBlackjack(): for x in range(len(hands)): key, value = list(hands.items())[x] - key = self.bot.database_funcs.getName(key) + key = self.bot.database_funcs.get_name(key) handParams = [ value["hand"], False, @@ -1359,8 +1359,8 @@ class DrawBlackjack(): textImage.text((textX, 1015), key, fill=white, font=smallFont) self.bot.log("Saving table image") - tableImagesPath = "resources/games/blackjackTables/" - tableImagePath = f"{tableImagesPath}blackjackTable{channel}.png" + tableImagesPath = "gwendolyn/resources/games/blackjack_tables/" + tableImagePath = f"{tableImagesPath}blackjack_table{channel}.png" table.save(tableImagePath) return @@ -1388,8 +1388,8 @@ class DrawBlackjack(): The image of the hand. """ self.bot.log("Drawing hand {hand}, {busted}, {blackjack}") - font = ImageFont.truetype('resources/fonts/futura-bold.ttf', 200) - font2 = ImageFont.truetype('resources/fonts/futura-bold.ttf', 120) + font = ImageFont.truetype('gwendolyn/resources/fonts/futura-bold.ttf', 200) + font2 = ImageFont.truetype('gwendolyn/resources/fonts/futura-bold.ttf', 120) length = len(hand) backgroundWidth = (self.BORDER*2)+691+(125*(length-1)) backgroundSize = (backgroundWidth, (self.BORDER*2)+1065) @@ -1398,15 +1398,15 @@ class DrawBlackjack(): cardY = self.BORDER+self.PLACEMENT[1] if dealer: - img = Image.open("resources/games/cards/"+hand[0].upper()+".png") + img = Image.open("gwendolyn/resources/games/cards/"+hand[0].upper()+".png") cardPosition = (self.BORDER+self.PLACEMENT[0], cardY) background.paste(img, cardPosition, img) - img = Image.open("resources/games/cards/red_back.png") + img = Image.open("gwendolyn/resources/games/cards/red_back.png") cardPosition = (125+self.BORDER+self.PLACEMENT[0], cardY) background.paste(img, cardPosition, img) else: for x in range(length): - cardPath = f"resources/games/cards/{hand[x].upper()}.png" + cardPath = f"gwendolyn/resources/games/cards/{hand[x].upper()}.png" img = Image.open(cardPath) cardPosition = (self.BORDER+(x*125)+self.PLACEMENT[0], cardY) background.paste(img, cardPosition, img) diff --git a/funcs/games/connect_four.py b/gwendolyn/funcs/games/connect_four.py similarity index 93% rename from funcs/games/connect_four.py rename to gwendolyn/funcs/games/connect_four.py index 4667882..430b38c 100644 --- a/funcs/games/connect_four.py +++ b/gwendolyn/funcs/games/connect_four.py @@ -133,8 +133,8 @@ class ConnectFour(): gwendoTurn = (players[0] == f"#{self.bot.user.id}") startedGame = True - opponentName = self.bot.database_funcs.getName(opponent) - turnName = self.bot.database_funcs.getName(players[0]) + opponentName = self.bot.database_funcs.get_name(opponent) + turnName = self.bot.database_funcs.get_name(players[0]) startedText = f"Started game against {opponentName}{diffText}." turnText = f"It's {turnName}'s turn" @@ -146,20 +146,20 @@ class ConnectFour(): # Sets the whole game in motion if startedGame: - boardsPath = "resources/games/connect4Boards/" - filePath = f"{boardsPath}board{ctx.channel_id}.png" - oldImage = await ctx.channel.send(file=discord.File(filePath)) + boardsPath = "gwendolyn/resources/games/connect4Boards/" + file_path = f"{boardsPath}board{ctx.channel_id}.png" + old_image = await ctx.channel.send(file=discord.File(file_path)) - old_imagesPath = "resources/games/old_images/" - oldImagePath = f"{old_imagesPath}connect_four{ctx.channel_id}" - with open(oldImagePath, "w") as f: - f.write(str(oldImage.id)) + old_imagesPath = "gwendolyn/resources/games/old_images/" + old_imagePath = f"{old_imagesPath}connect_four{ctx.channel_id}" + with open(old_imagePath, "w") as f: + f.write(str(old_image.id)) if gwendoTurn: await self._connect_fourAI(ctx) else: for reaction in self.REACTIONS: - await oldImage.add_reaction(reaction) + await old_image.add_reaction(reaction) async def placePiece(self, ctx: Union[SlashContext, discord.Message], user: int, column: int): @@ -183,7 +183,7 @@ class ConnectFour(): connect4Games = self.bot.database["connect 4 games"] game = connect4Games.find_one({"_id": channel}) playerNumber = game["players"].index(user)+1 - userName = self.bot.database_funcs.getName(user) + user_name = self.bot.database_funcs.get_name(user) placedPiece = False if game is None: @@ -216,8 +216,8 @@ class ConnectFour(): connect4Games.update_one({"_id": channel}, updater) sendMessage = "{} placed a piece in column {} and won. " - sendMessage = sendMessage.format(userName, column+1) - log_message = f"{userName} won" + sendMessage = sendMessage.format(user_name, column+1) + log_message = f"{user_name} won" winAmount = int(game["difficulty"])**2+5 if game["players"][won-1] != f"#{self.bot.user.id}": sendMessage += "Adding {} GwendoBucks to their account" @@ -229,9 +229,9 @@ class ConnectFour(): else: gameWon = False otherUserId = game["players"][turn] - otherUserName = self.bot.database_funcs.getName(otherUserId) + otherUserName = self.bot.database_funcs.get_name(otherUserId) sendMessage = self.bot.long_strings["Connect 4 placed"] - formatParams = [userName, column+1, otherUserName] + formatParams = [user_name, column+1, otherUserName] sendMessage = sendMessage.format(*formatParams) log_message = "They placed the piece" @@ -245,28 +245,28 @@ class ConnectFour(): if placedPiece: self.draw.drawImage(channel) - oldImagePath = f"resources/games/old_images/connect_four{channel}" - with open(oldImagePath, "r") as f: - oldImage = await ctx.channel.fetch_message(int(f.read())) + old_imagePath = f"gwendolyn/resources/games/old_images/connect_four{channel}" + with open(old_imagePath, "r") as f: + old_image = await ctx.channel.fetch_message(int(f.read())) - if oldImage is not None: - await oldImage.delete() + if old_image is not None: + await old_image.delete() else: self.bot.log("The old image was already deleted") - filePath = f"resources/games/connect4Boards/board{channel}.png" - oldImage = await ctx.channel.send(file=discord.File(filePath)) + file_path = f"gwendolyn/resources/games/connect4Boards/board{channel}.png" + old_image = await ctx.channel.send(file=discord.File(file_path)) if gameWon: self._endGame(channel) else: - with open(oldImagePath, "w") as f: - f.write(str(oldImage.id)) + with open(old_imagePath, "w") as f: + f.write(str(old_image.id)) if gwendoTurn: await self._connect_fourAI(ctx) else: for reaction in self.REACTIONS: - await oldImage.add_reaction(reaction) + await old_image.add_reaction(reaction) async def surrender(self, ctx: SlashContext): """ @@ -285,7 +285,7 @@ class ConnectFour(): loserIndex = game["players"].index(f"#{ctx.author.id}") winnerIndex = (loserIndex+1) % 2 winnerID = game["players"][winnerIndex] - winnerName = self.bot.database_funcs.getName(winnerID) + winnerName = self.bot.database_funcs.get_name(winnerID) sendMessage = f"{ctx.author.display_name} surrenders." sendMessage += f" This means {winnerName} is the winner." @@ -295,12 +295,12 @@ class ConnectFour(): sendMessage += f" Adding {reward} to their account" await ctx.send(sendMessage) - oldImagePath = f"resources/games/old_images/connect_four{channel}" - with open(oldImagePath, "r") as f: - oldImage = await ctx.channel.fetch_message(int(f.read())) + old_imagePath = f"gwendolyn/resources/games/old_images/connect_four{channel}" + with open(old_imagePath, "r") as f: + old_image = await ctx.channel.fetch_message(int(f.read())) - if oldImage is not None: - await oldImage.delete() + if old_image is not None: + await old_image.delete() else: self.bot.log("The old image was already deleted") @@ -331,7 +331,7 @@ class ConnectFour(): """ placementX, placementY = -1, column - for x, line in enumerate(board): + for x, line in list(enumerate(board))[::-1]: if line[column] == 0: placementX = x break @@ -353,7 +353,7 @@ class ConnectFour(): reward = difficulty**2 + 5 self.bot.money.addMoney(game["players"][winner-1], reward) - self.bot.database_funcs.deleteGame("connect 4 games", channel) + self.bot.database_funcs.delete_game("connect 4 games", channel) def _isWon(self, board: dict): won = 0 @@ -444,7 +444,7 @@ class ConnectFour(): player = game["players"].index(f"#{self.bot.user.id}")+1 difficulty = game["difficulty"] - scores = [int(-math.inf) for _ in range(COLUMNCOUNT)] + scores = [-math.inf for _ in range(COLUMNCOUNT)] for column in range(COLUMNCOUNT): testBoard = copy.deepcopy(board) testBoard = self._placeOnBoard(testBoard, player, column) @@ -454,8 +454,8 @@ class ConnectFour(): difficulty, player % 2+1, player, - int(-math.inf), - int(math.inf), + -math.inf, + math.inf, False ] scores[column] = await self._minimax(*_minimaxParams) @@ -564,7 +564,7 @@ class ConnectFour(): if depth == 0 or terminal or (points > 5000 or points < -6000): return points if maximizingPlayer: - value = int(-math.inf) + value = -math.inf for column in range(0, COLUMNCOUNT): testBoard = copy.deepcopy(board) testBoard = self._placeOnBoard(testBoard, player, column) @@ -587,7 +587,7 @@ class ConnectFour(): break return value else: - value = int(math.inf) + value = math.inf for column in range(0, COLUMNCOUNT): testBoard = copy.deepcopy(board) testBoard = self._placeOnBoard(testBoard, player, column) @@ -694,7 +694,7 @@ class DrawConnectFour(): winbarAlpha = 160 self.WINBARCOLOR = (250, 250, 250, 255) self.PIECESIZE = 300 - fontPath = "resources/fonts/futura-bold.ttf" + fontPath = "gwendolyn/resources/fonts/futura-bold.ttf" self.FONT = ImageFont.truetype(fontPath, self.TEXTSIZE) @@ -740,7 +740,7 @@ class DrawConnectFour(): self._drawFooter(d, game) - background.save(f"resources/games/connect4Boards/board{channel}.png") + background.save(f"gwendolyn/resources/games/connect4Boards/board{channel}.png") def _drawBoard(self, d: ImageDraw): # This whole part was the easiest way to make a rectangle with @@ -1023,12 +1023,12 @@ class DrawConnectFour(): if game["players"][0] == "Gwendolyn": player1 = "Gwendolyn" else: - player1 = self.bot.database_funcs.getName(game["players"][0]) + player1 = self.bot.database_funcs.get_name(game["players"][0]) if game["players"][1] == "Gwendolyn": player2 = "Gwendolyn" else: - player2 = self.bot.database_funcs.getName(game["players"][1]) + player2 = self.bot.database_funcs.get_name(game["players"][1]) exampleHeight = self.HEIGHT - self.BORDER exampleHeight += (self.BOTTOMBORDER+self.BORDER)//2 - self.TEXTSIZE//2 diff --git a/funcs/games/games_container.py b/gwendolyn/funcs/games/games_container.py similarity index 100% rename from funcs/games/games_container.py rename to gwendolyn/funcs/games/games_container.py diff --git a/funcs/games/hangman.py b/gwendolyn/funcs/games/hangman.py similarity index 90% rename from funcs/games/hangman.py rename to gwendolyn/funcs/games/hangman.py index 4b65d70..46e01da 100644 --- a/funcs/games/hangman.py +++ b/gwendolyn/funcs/games/hangman.py @@ -46,7 +46,7 @@ class Hangman(): self.__bot = bot self.__draw = DrawHangman(bot) self.__APIURL = "https://api.wordnik.com/v4/words.json/randomWords?" - apiKey = self.__bot.credentials.wordnikKey + apiKey = self.__bot.credentials["wordnik_key"] self.__APIPARAMS = { "hasDictionaryDef": True, "minCorpusCount": 5000, @@ -72,7 +72,7 @@ class Hangman(): channel = str(ctx.channel_id) user = f"#{ctx.author.id}" game = self.__bot.database["hangman games"].find_one({"_id": channel}) - userName = self.__bot.database_funcs.getName(user) + user_name = self.__bot.database_funcs.get_name(user) startedGame = False if game is None: @@ -100,7 +100,7 @@ class Hangman(): self.__draw.drawImage(channel) log_message = "Game started" - sendMessage = f"{userName} started game of hangman." + sendMessage = f"{user_name} started game of hangman." startedGame = True else: log_message = "There was already a game going on" @@ -110,9 +110,9 @@ class Hangman(): await ctx.send(sendMessage) if startedGame: - boardsPath = "resources/games/hangmanBoards/" - filePath = f"{boardsPath}hangmanBoard{channel}.png" - newImage = await ctx.channel.send(file=discord.File(filePath)) + boardsPath = "gwendolyn/resources/games/hangman_boards/" + file_path = f"{boardsPath}hangman_board{channel}.png" + newImage = await ctx.channel.send(file=discord.File(file_path)) blankMessage = await ctx.channel.send("_ _") reactionMessages = { @@ -120,10 +120,10 @@ class Hangman(): blankMessage: remainingLetters[15:] } - oldMessages = f"{newImage.id}\n{blankMessage.id}" + old_messages = f"{newImage.id}\n{blankMessage.id}" - with open(f"resources/games/old_images/hangman{channel}", "w") as f: - f.write(oldMessages) + with open(f"gwendolyn/resources/games/old_images/hangman{channel}", "w") as f: + f.write(old_messages) for message, letters in reactionMessages.items(): for letter in letters: @@ -149,13 +149,13 @@ class Hangman(): else: self.__bot.database["hangman games"].delete_one({"_id": channel}) - with open(f"resources/games/old_images/hangman{channel}", "r") as f: + with open(f"gwendolyn/resources/games/old_images/hangman{channel}", "r") as f: messages = f.read().splitlines() for message in messages: - oldMessage = await ctx.channel.fetch_message(int(message)) + old_message = await ctx.channel.fetch_message(int(message)) self.__bot.log("Deleting old message") - await oldMessage.delete() + await old_message.delete() await ctx.send("Game stopped") @@ -173,8 +173,8 @@ class Hangman(): The guess. """ channel = str(message.channel.id) - hangmanGames = self.__bot.database["hangman games"] - game = hangmanGames.find_one({"_id": channel}) + hangman_games = self.__bot.database["hangman games"] + game = hangman_games.find_one({"_id": channel}) gameExists = (game is not None) singleLetter = (len(guess) == 1 and guess.isalpha()) @@ -189,18 +189,18 @@ class Hangman(): if guess == letter: correctGuess += 1 updater = {"$set": {f"guessed.{x}": True}} - hangmanGames.update_one({"_id": channel}, updater) + hangman_games.update_one({"_id": channel}, updater) if correctGuess == 0: updater = {"$inc": {"misses": 1}} - hangmanGames.update_one({"_id": channel}, updater) + hangman_games.update_one({"_id": channel}, updater) updater = {"$push": {"guessed letters": guess}} - hangmanGames.update_one({"_id": channel}, updater) + hangman_games.update_one({"_id": channel}, updater) remainingLetters = list(string.ascii_uppercase) - game = hangmanGames.find_one({"_id": channel}) + game = hangman_games.find_one({"_id": channel}) for letter in game["guessed letters"]: remainingLetters.remove(letter) @@ -215,28 +215,28 @@ class Hangman(): self.__draw.drawImage(channel) if game["misses"] == 6: - hangmanGames.delete_one({"_id": channel}) + hangman_games.delete_one({"_id": channel}) sendMessage += self.__bot.long_strings["Hangman lost game"] remainingLetters = [] elif all(game["guessed"]): - hangmanGames.delete_one({"_id": channel}) + hangman_games.delete_one({"_id": channel}) self.__bot.money.addMoney(user, 15) sendMessage += self.__bot.long_strings["Hangman guessed word"] remainingLetters = [] await message.channel.send(sendMessage) - with open(f"resources/games/old_images/hangman{channel}", "r") as f: - oldMessageIDs = f.read().splitlines() + with open(f"gwendolyn/resources/games/old_images/hangman{channel}", "r") as f: + old_message_ids = f.read().splitlines() - for oldID in oldMessageIDs: - oldMessage = await message.channel.fetch_message(int(oldID)) + for oldID in old_message_ids: + old_message = await message.channel.fetch_message(int(oldID)) self.__bot.log("Deleting old message") - await oldMessage.delete() + await old_message.delete() - boardsPath = "resources/games/hangmanBoards/" - filePath = f"{boardsPath}hangmanBoard{channel}.png" - newImage = await message.channel.send(file=discord.File(filePath)) + boardsPath = "gwendolyn/resources/games/hangman_boards/" + file_path = f"{boardsPath}hangman_board{channel}.png" + newImage = await message.channel.send(file=discord.File(file_path)) if len(remainingLetters) > 0: if len(remainingLetters) > 15: @@ -250,13 +250,13 @@ class Hangman(): reactionMessages = {newImage: remainingLetters} if blankMessage != "": - oldMessages = f"{newImage.id}\n{blankMessage.id}" + old_messages = f"{newImage.id}\n{blankMessage.id}" else: - oldMessages = str(newImage.id) + old_messages = str(newImage.id) - oldImagePath = f"resources/games/old_images/hangman{channel}" - with open(oldImagePath, "w") as f: - f.write(oldMessages) + old_imagePath = f"gwendolyn/resources/games/old_images/hangman{channel}" + with open(old_imagePath, "w") as f: + f.write(old_messages) for message, letters in reactionMessages.items(): for letter in letters: @@ -315,7 +315,7 @@ class DrawHangman(): LETTERSIZE = 75 # Wrong guesses letter size WORDSIZE = 70 # Correct guesses letter size - FONTPATH = "resources/fonts/comic-sans-bold.ttf" + FONTPATH = "gwendolyn/resources/fonts/comic-sans-bold.ttf" self.__FONT = ImageFont.truetype(FONTPATH, LETTERSIZE) self.__SMALLFONT = ImageFont.truetype(FONTPATH, WORDSIZE) @@ -588,7 +588,7 @@ class DrawHangman(): random.seed(game["game ID"]) - background = Image.open("resources/paper.jpg") + background = Image.open("gwendolyn/resources/paper.jpg") gallow = self.__drawGallows() man = self.__drawMan(game["misses"], game["game ID"]) @@ -608,5 +608,5 @@ class DrawHangman(): missesTextWidth = missesText.size[0] background.paste(missesText, (850-missesTextWidth//2, 50), missesText) - boardPath = f"resources/games/hangmanBoards/hangmanBoard{channel}.png" + boardPath = f"gwendolyn/resources/games/hangman_boards/hangman_board{channel}.png" background.save(boardPath) diff --git a/funcs/games/hex.py b/gwendolyn/funcs/games/hex.py similarity index 88% rename from funcs/games/hex.py rename to gwendolyn/funcs/games/hex.py index 4f5279b..5700bd8 100644 --- a/funcs/games/hex.py +++ b/gwendolyn/funcs/games/hex.py @@ -28,24 +28,24 @@ class HexGame(): await ctx.send("You can't surrender when you're not a player.") else: opponent = (players.index(user) + 1) % 2 - opponentName = self.bot.database_funcs.getName(players[opponent]) + opponentName = self.bot.database_funcs.get_name(players[opponent]) self.bot.database["hex games"].update_one({"_id":channel},{"$set":{"winner":opponent + 1}}) await ctx.send(f"{ctx.author.display_name} surrendered") - with open(f"resources/games/old_images/hex{channel}", "r") as f: - oldImage = await ctx.channel.fetch_message(int(f.read())) + with open(f"gwendolyn/resources/games/old_images/hex{channel}", "r") as f: + old_image = await ctx.channel.fetch_message(int(f.read())) - if oldImage is not None: - await oldImage.delete() + if old_image is not None: + await old_image.delete() else: self.bot.log("The old image was already deleted") self.bot.log("Sending the image") - filePath = f"resources/games/hexBoards/board{channel}.png" - oldImage = await ctx.channel.send(file = discord.File(filePath)) + file_path = f"gwendolyn/resources/games/hex_boards/board{channel}.png" + old_image = await ctx.channel.send(file = discord.File(file_path)) - with open(f"resources/games/old_images/hex{channel}", "w") as f: - f.write(str(oldImage.id)) + with open(f"gwendolyn/resources/games/old_images/hex{channel}", "w") as f: + f.write(str(old_image.id)) self.bot.database["hex games"].delete_one({"_id":channel}) @@ -72,23 +72,23 @@ class HexGame(): opponent = game["players"][::-1][game["turn"]-1] gwendoTurn = (opponent == f"#{self.bot.user.id}") - opponentName = self.bot.database_funcs.getName(opponent) + opponentName = self.bot.database_funcs.get_name(opponent) await ctx.send(f"The color of the players were swapped. It is now {opponentName}'s turn") - with open(f"resources/games/old_images/hex{channel}", "r") as f: - oldImage = await ctx.channel.fetch_message(int(f.read())) + with open(f"gwendolyn/resources/games/old_images/hex{channel}", "r") as f: + old_image = await ctx.channel.fetch_message(int(f.read())) - if oldImage is not None: - await oldImage.delete() + if old_image is not None: + await old_image.delete() else: self.bot.log("The old image was already deleted") self.bot.log("Sending the image") - filePath = f"resources/games/hexBoards/board{channel}.png" - oldImage = await ctx.channel.send(file = discord.File(filePath)) + file_path = f"gwendolyn/resources/games/hex_boards/board{channel}.png" + old_image = await ctx.channel.send(file = discord.File(file_path)) - with open(f"resources/games/old_images/hex{channel}", "w") as f: - f.write(str(oldImage.id)) + with open(f"gwendolyn/resources/games/old_images/hex{channel}", "w") as f: + f.write(str(old_image.id)) if gwendoTurn: await self.hexAI(ctx) @@ -167,7 +167,7 @@ class HexGame(): gwendoTurn = (players[0] == f"#{self.bot.user.id}") startedGame = True - turnName = self.bot.database_funcs.getName(players[0]) + turnName = self.bot.database_funcs.get_name(players[0]) sendMessage = f"Started Hex game against {opponentName}{diffText}. It's {turnName}'s turn" log_message = "Game started" @@ -175,10 +175,10 @@ class HexGame(): self.bot.log(log_message) if startedGame: - filePath = f"resources/games/hexBoards/board{ctx.channel_id}.png" - newImage = await ctx.channel.send(file = discord.File(filePath)) + file_path = f"gwendolyn/resources/games/hex_boards/board{ctx.channel_id}.png" + newImage = await ctx.channel.send(file = discord.File(file_path)) - with open(f"resources/games/old_images/hex{ctx.channel_id}", "w") as f: + with open(f"gwendolyn/resources/games/old_images/hex{ctx.channel_id}", "w") as f: f.write(str(newImage.id)) if gwendoTurn: @@ -199,7 +199,7 @@ class HexGame(): else: players = game["players"] if user not in players: - sendMessage = f"You can't place when you're not in the game. The game's players are: {self.bot.database_funcs.getName(game['players'][0])} and {self.bot.database_funcs.getName(game['players'][1])}." + sendMessage = f"You can't place when you're not in the game. The game's players are: {self.bot.database_funcs.get_name(game['players'][0])} and {self.bot.database_funcs.get_name(game['players'][1])}." self.bot.log("They aren't in the game") elif players[game["turn"]-1] != user: sendMessage = "It's not your turn" @@ -228,12 +228,12 @@ class HexGame(): if winner == 0: # Continue with the game. gameWon = False - sendMessage = self.bot.database_funcs.getName(game["players"][player-1])+" placed at "+position.upper()+". It's now "+self.bot.database_funcs.getName(game["players"][turn-1])+"'s turn."# The score is "+str(score) + sendMessage = self.bot.database_funcs.get_name(game["players"][player-1])+" placed at "+position.upper()+". It's now "+self.bot.database_funcs.get_name(game["players"][turn-1])+"'s turn."# The score is "+str(score) else: # Congratulations! gameWon = True self.bot.database["hex games"].update_one({"_id":channel},{"$set":{"winner":winner}}) - sendMessage = self.bot.database_funcs.getName(game["players"][player-1])+" placed at "+position.upper()+" and won!" + sendMessage = self.bot.database_funcs.get_name(game["players"][player-1])+" placed at "+position.upper()+" and won!" if game["players"][winner-1] != f"#{self.bot.user.id}": winAmount = game["difficulty"]*10 sendMessage += " Adding "+str(winAmount)+" GwendoBucks to their account." @@ -258,17 +258,17 @@ class HexGame(): # Update the board self.draw.drawHexPlacement(channel,player, position) - with open(f"resources/games/old_images/hex{channel}", "r") as f: - oldImage = await ctx.channel.fetch_message(int(f.read())) + with open(f"gwendolyn/resources/games/old_images/hex{channel}", "r") as f: + old_image = await ctx.channel.fetch_message(int(f.read())) - if oldImage is not None: - await oldImage.delete() + if old_image is not None: + await old_image.delete() else: self.bot.log("The old image was already deleted") self.bot.log("Sending the image") - filePath = f"resources/games/hexBoards/board{channel}.png" - oldImage = await ctx.channel.send(file = discord.File(filePath)) + file_path = f"gwendolyn/resources/games/hex_boards/board{channel}.png" + old_image = await ctx.channel.send(file = discord.File(file_path)) if gameWon: self.bot.log("Dealing with the winning player") @@ -281,8 +281,8 @@ class HexGame(): self.bot.database["hex games"].delete_one({"_id":channel}) else: - with open(f"resources/games/old_images/hex{channel}", "w") as f: - f.write(str(oldImage.id)) + with open(f"gwendolyn/resources/games/old_images/hex{channel}", "w") as f: + f.write(str(old_image.id)) if gwendoTurn: await self.hexAI(ctx) @@ -321,7 +321,7 @@ class HexGame(): sendMessage = "It's not your turn" else: turn = game["turn"] - self.bot.log("Undoing {}'s last move".format(self.bot.database_funcs.getName(user))) + self.bot.log("Undoing {}'s last move".format(self.bot.database_funcs.get_name(user))) lastMove = game["gameHistory"].pop() game["board"][lastMove[0]][lastMove[1]] = 0 @@ -337,20 +337,20 @@ class HexGame(): await ctx.send(sendMessage) if undid: - with open(f"resources/games/old_images/hex{channel}", "r") as f: - oldImage = await ctx.channel.fetch_message(int(f.read())) + with open(f"gwendolyn/resources/games/old_images/hex{channel}", "r") as f: + old_image = await ctx.channel.fetch_message(int(f.read())) - if oldImage is not None: - await oldImage.delete() + if old_image is not None: + await old_image.delete() else: self.bot.log("The old image was already deleted") self.bot.log("Sending the image") - filePath = f"resources/games/hexBoards/board{channel}.png" - oldImage = await ctx.channel.send(file = discord.File(filePath)) + file_path = f"gwendolyn/resources/games/hex_boards/board{channel}.png" + old_image = await ctx.channel.send(file = discord.File(file_path)) - with open(f"resources/games/old_images/hex{channel}", "w") as f: - f.write(str(oldImage.id)) + with open(f"gwendolyn/resources/games/old_images/hex{channel}", "w") as f: + f.write(str(old_image.id)) # Plays as the AI @@ -474,7 +474,7 @@ class DrawHex(): self.HEXAGONHEIGHT = 1.5 * self.SIDELENGTH self.FONTSIZE = 45 self.TEXTCOLOR = (0,0,0) - self.FONT = ImageFont.truetype('resources/fonts/futura-bold.ttf', self.FONTSIZE) + self.FONT = ImageFont.truetype('gwendolyn/resources/fonts/futura-bold.ttf', self.FONTSIZE) self.LINETHICKNESS = 15 self.HEXTHICKNESS = 6 # This is half the width of the background lining between every hex @@ -490,7 +490,7 @@ class DrawHex(): self.COLYTHICKNESS = self.COLHEXTHICKNESS * math.sin(math.pi/6) # The Name display things: self.NAMESIZE = 60 - self.NAMEFONT = ImageFont.truetype('resources/fonts/futura-bold.ttf', self.NAMESIZE) + self.NAMEFONT = ImageFont.truetype('gwendolyn/resources/fonts/futura-bold.ttf', self.NAMESIZE) self.XNAME = {1:175, 2:self.CANVASWIDTH-100} self.YNAME = {1:self.CANVASHEIGHT-150, 2:150} self.NAMEHEXPADDING = 90 @@ -556,7 +556,7 @@ class DrawHex(): game = self.bot.database["hex games"].find_one({"_id":channel}) for p in [1,2]: - playername = self.bot.database_funcs.getName(game["players"][p-1]) + playername = self.bot.database_funcs.get_name(game["players"][p-1]) # Draw name x = self.XNAME[p] x -= self.NAMEFONT.getsize(playername)[0] if p==2 else 0 # player2's name is right-aligned @@ -573,13 +573,13 @@ class DrawHex(): (x, y+self.SMALLSIDELENGTH), ],fill = self.PIECECOLOR[p]) - im.save("resources/games/hexBoards/board"+channel+".png") + im.save("gwendolyn/resources/games/hex_boards/board"+channel+".png") def drawHexPlacement(self, channel,player,position): - FILEPATH = "resources/games/hexBoards/board"+channel+".png" + FILEPATH = "gwendolyn/resources/games/hex_boards/board"+channel+".png" self.bot.log(f"Drawing a newly placed hex. Filename: board{channel}.png") # Translates position @@ -589,7 +589,7 @@ class DrawHex(): row = int(position[1:])-1 # Find the coordinates for the filled hex drawing - hexCoords = [ + hex_coords = [ (self.BOARDCOORDINATES[row][column][0]+self.COLXTHICKNESS, self.BOARDCOORDINATES[row][column][1] + self.COLYTHICKNESS), (self.BOARDCOORDINATES[row][column][0]+self.HEXAGONWIDTH/2, self.BOARDCOORDINATES[row][column][1]-0.5*self.SIDELENGTH + self.COLHEXTHICKNESS), (self.BOARDCOORDINATES[row][column][0]+self.HEXAGONWIDTH-self.COLXTHICKNESS, self.BOARDCOORDINATES[row][column][1] + self.COLYTHICKNESS), @@ -603,7 +603,7 @@ class DrawHex(): with Image.open(FILEPATH) as im: d = ImageDraw.Draw(im,"RGBA") # Draws the hex piece - d.polygon(hexCoords,fill = self.PIECECOLOR[player], outline = self.BETWEENCOLOR) + d.polygon(hex_coords,fill = self.PIECECOLOR[player], outline = self.BETWEENCOLOR) # Save im.save(FILEPATH) @@ -611,7 +611,7 @@ class DrawHex(): self.bot.log("Error drawing new hex on board (error code 1541") def drawSwap(self, channel): - FILEPATH = "resources/games/hexBoards/board"+channel+".png" + FILEPATH = "gwendolyn/resources/games/hex_boards/board"+channel+".png" game = self.bot.database["hex games"].find_one({"_id":channel}) # Opens the image try: @@ -620,7 +620,7 @@ class DrawHex(): # Write player names and color for p in [1,2]: - playername = self.bot.database_funcs.getName(game["players"][p%2]) + playername = self.bot.database_funcs.get_name(game["players"][p%2]) x = self.XNAME[p] x -= self.NAMEFONT.getsize(playername)[0] if p==2 else 0 # player2's name is right-aligned diff --git a/funcs/games/invest.py b/gwendolyn/funcs/games/invest.py similarity index 95% rename from funcs/games/invest.py rename to gwendolyn/funcs/games/invest.py index 5e65c90..8977503 100644 --- a/funcs/games/invest.py +++ b/gwendolyn/funcs/games/invest.py @@ -65,12 +65,12 @@ class Invest(): investmentsDatabase = self.bot.database["investments"] userInvestments = investmentsDatabase.find_one({"_id": user}) - userName = self.bot.database_funcs.getName(user) + user_name = self.bot.database_funcs.get_name(user) if userInvestments in [None, {}]: - return f"{userName} does not have a stock portfolio." + return f"{user_name} does not have a stock portfolio." else: - portfolio = f"**Stock portfolio for {userName}**" + portfolio = f"**Stock portfolio for {user_name}**" for key, value in list(userInvestments["investments"].items()): purchaseValue = value["purchased for"] @@ -162,9 +162,9 @@ class Invest(): } investmentsDatabase.insert_one(newUser) - userName = self.bot.database_funcs.getName(user) + user_name = self.bot.database_funcs.get_name(user) sendMessage = "{} bought {} GwendoBucks worth of {} stock" - sendMessage = sendMessage.format(userName, buyAmount, stock) + sendMessage = sendMessage.format(user_name, buyAmount, stock) return sendMessage def sellStock(self, user: str, stock: str, sellAmount: int): @@ -219,9 +219,9 @@ class Invest(): updater = {"$unset": {f"investments.{stock}": ""}} investmentsDatabase.update_one({"_id": user}, updater) - userName = self.bot.database_funcs.getName(user) + user_name = self.bot.database_funcs.get_name(user) sendMessage = "{} sold {} GwendoBucks worth of {} stock" - return sendMessage.format(userName, sellAmount, stock) + return sendMessage.format(user_name, sellAmount, stock) else: return f"You don't have enough {stock} stocks to do that" else: diff --git a/funcs/games/money.py b/gwendolyn/funcs/games/money.py similarity index 90% rename from funcs/games/money.py rename to gwendolyn/funcs/games/money.py index 1113fbe..51d179a 100644 --- a/funcs/games/money.py +++ b/gwendolyn/funcs/games/money.py @@ -69,11 +69,11 @@ class Money(): """ await self.bot.defer(ctx) response = self.checkBalance("#"+str(ctx.author.id)) - userName = ctx.author.display_name + user_name = ctx.author.display_name if response == 1: - new_message = f"{userName} has {response} GwendoBuck" + new_message = f"{user_name} has {response} GwendoBuck" else: - new_message = f"{userName} has {response} GwendoBucks" + new_message = f"{user_name} has {response} GwendoBucks" await ctx.send(new_message) # Adds money to the account of a user @@ -98,7 +98,7 @@ class Money(): else: newUser = { "_id": user, - "user name": self.bot.database_funcs.getName(user), + "user name": self.bot.database_funcs.get_name(user), "money": amount } self.database["users"].insert_one(newUser) @@ -120,13 +120,13 @@ class Money(): """ await self.bot.defer(ctx) username = user.display_name - if self.bot.database_funcs.getID(username) is None: + if self.bot.database_funcs.get_id(username) is None: async for member in ctx.guild.fetch_members(limit=None): if member.display_name.lower() == username.lower(): username = member.display_name - userID = f"#{member.id}" + user_id = f"#{member.id}" newUser = { - "_id": userID, + "_id": user_id, "user name": username, "money": 0 } @@ -134,7 +134,7 @@ class Money(): userid = f"#{ctx.author.id}" userData = self.database["users"].find_one({"_id": userid}) - targetUser = self.bot.database_funcs.getID(username) + targetUser = self.bot.database_funcs.get_id(username) if amount <= 0: self.bot.log("They tried to steal") diff --git a/funcs/games/trivia.py b/gwendolyn/funcs/games/trivia.py similarity index 96% rename from funcs/games/trivia.py rename to gwendolyn/funcs/games/trivia.py index 8068e65..d03c2be 100644 --- a/funcs/games/trivia.py +++ b/gwendolyn/funcs/games/trivia.py @@ -181,8 +181,8 @@ class Trivia(): self.triviaCountPoints(channelId) - deleteGameParams = ["trivia questions", channelId] - self.bot.database_funcs.deleteGame(*deleteGameParams) + delete_gameParams = ["trivia questions", channelId] + self.bot.database_funcs.delete_game(*delete_gameParams) self.bot.log("Time's up for the trivia question", channelId) sendMessage = self.bot.long_strings["Trivia time up"] @@ -196,8 +196,8 @@ class Trivia(): userId = f"#{ctx.author.id}" response = self.triviaAnswer(userId, channelId, answer) if response is None: - userName = ctx.author.display_name - await ctx.send(f"{userName} answered **{answer}**") + user_name = ctx.author.display_name + await ctx.send(f"{user_name} answered **{answer}**") else: await ctx.send(response) else: diff --git a/funcs/lookup/__init__.py b/gwendolyn/funcs/lookup/__init__.py similarity index 100% rename from funcs/lookup/__init__.py rename to gwendolyn/funcs/lookup/__init__.py diff --git a/funcs/lookup/lookup_funcs.py b/gwendolyn/funcs/lookup/lookup_funcs.py similarity index 97% rename from funcs/lookup/lookup_funcs.py rename to gwendolyn/funcs/lookup/lookup_funcs.py index 7d0654c..efe24ca 100644 --- a/funcs/lookup/lookup_funcs.py +++ b/gwendolyn/funcs/lookup/lookup_funcs.py @@ -2,7 +2,7 @@ import math import json import discord -from utils import cap +from gwendolyn.utils import cap class LookupFuncs(): @@ -29,7 +29,7 @@ class LookupFuncs(): await ctx.send("I don't know that monster...") else: # Opens "monsters.json" - data = json.load(open('resources/lookup/monsters.json', encoding = "utf8")) + data = json.load(open('gwendolyn/resources/lookup/monsters.json', encoding = "utf8")) for monster in data: if "name" in monster and str(query) == monster["name"]: self.bot.log("Found it!") @@ -149,7 +149,7 @@ class LookupFuncs(): self.bot.log("Looking up "+query) # Opens "spells.json" - data = json.load(open('resources/lookup/spells.json', encoding = "utf8")) + data = json.load(open('gwendolyn/resources/lookup/spells.json', encoding = "utf8")) if query in data: self.bot.log("Returning spell information") sendMessage = (f"***{query}***\n*{data[query]['level']} level {data[query]['school']}\nCasting Time: {data[query]['casting_time']}\nRange:{data[query]['range']}\nComponents:{data[query]['components']}\nDuration:{data[query]['duration']}*\n \n{data[query]['description']}") diff --git a/funcs/other/__init__.py b/gwendolyn/funcs/other/__init__.py similarity index 100% rename from funcs/other/__init__.py rename to gwendolyn/funcs/other/__init__.py diff --git a/funcs/other/bedreNetflix.py b/gwendolyn/funcs/other/bedre_netflix.py similarity index 92% rename from funcs/other/bedreNetflix.py rename to gwendolyn/funcs/other/bedre_netflix.py index 5fb6c4a..f8226ec 100644 --- a/funcs/other/bedreNetflix.py +++ b/gwendolyn/funcs/other/bedre_netflix.py @@ -3,7 +3,7 @@ import requests, imdb, discord, json, math, time, asyncio class BedreNetflix(): def __init__(self,bot): self.bot = bot - ip = ["localhost", "192.168.0.40"][self.bot.options.testing] + ip = ["localhost", "192.168.0.40"][self.bot.options["testing"]] self.radarrURL = "http://"+ip+":7878/api/v3/" self.sonarrURL = "http://"+ip+":8989/api/" @@ -30,7 +30,7 @@ class BedreNetflix(): messageTitle = "**Is it any of these movies?**" messageText = "" - imdbIds = [] + imdb_ids = [] for x, movie in enumerate(movies): try: @@ -40,17 +40,17 @@ class BedreNetflix(): messageText += "\n"+str(x+1)+") "+movie["title"] except: messageText += "Error" - imdbIds.append(movie.movieID) + imdb_ids.append(movie.movieID) - self.bot.log("Returning a list of "+str(len(movies))+" possible movies: "+str(imdbIds)) + self.bot.log("Returning a list of "+str(len(movies))+" possible movies: "+str(imdb_ids)) em = discord.Embed(title=messageTitle,description=messageText,colour=0x00FF00) message = await ctx.send(embed=em) - messageData = {"messageID":message.id,"imdbIds":imdbIds} + messageData = {"message_id":message.id,"imdb_ids":imdb_ids} - with open("resources/bedreNetflix/oldMessage"+str(ctx.channel.id),"w") as f: + with open("gwendolyn/resources/bedre_netflix/old_message"+str(ctx.channel.id),"w") as f: json.dump(messageData,f) if len(movies) == 1: @@ -66,7 +66,7 @@ class BedreNetflix(): await message.clear_reactions() #Adds the requested movie to Bedre Netflix - async def addMovie(self, message, imdbId, editMessage = True): + async def add_movie(self, message, imdbId, editMessage = True): if imdbId == None: self.bot.log("Did not find what the user was searching for") if editMessage: @@ -75,7 +75,7 @@ class BedreNetflix(): await message.channel.send("Try searching for the IMDB id") else: self.bot.log("Trying to add movie "+str(imdbId)) - apiKey = self.bot.credentials.radarrKey + apiKey = self.bot.credentials["radarr_key"] response = requests.get(self.radarrURL+"movie/lookup/imdb?imdbId=tt"+imdbId+"&apiKey="+apiKey) lookupData = response.json() postData = {"qualityProfileId": 1, @@ -126,7 +126,7 @@ class BedreNetflix(): messageTitle = "**Is it any of these shows?**" messageText = "" - imdbNames = [] + imdb_names = [] for x, show in enumerate(shows): try: @@ -136,17 +136,17 @@ class BedreNetflix(): messageText += "\n"+str(x+1)+") "+show["title"] except: messageText += "Error" - imdbNames.append(show["title"]) + imdb_names.append(show["title"]) - self.bot.log("Returning a list of "+str(len(shows))+" possible shows: "+str(imdbNames)) + self.bot.log("Returning a list of "+str(len(shows))+" possible shows: "+str(imdb_names)) em = discord.Embed(title=messageTitle,description=messageText,colour=0x00FF00) message = await ctx.send(embed=em) - messageData = {"messageID":message.id,"imdbNames":imdbNames} + messageData = {"message_id":message.id,"imdb_names":imdb_names} - with open("resources/bedreNetflix/oldMessage"+str(ctx.channel.id),"w") as f: + with open("gwendolyn/resources/bedre_netflix/old_message"+str(ctx.channel.id),"w") as f: json.dump(messageData,f) if len(shows) == 1: @@ -162,14 +162,14 @@ class BedreNetflix(): await message.clear_reactions() #Adds the requested show to Bedre Netflix - async def addShow(self, message, imdbName): - if imdbName == None: + async def add_show(self, message, imdb_name): + if imdb_name == None: self.bot.log("Did not find what the user was searching for") await message.edit(embed = None, content = "Try searching for the IMDB id") else: - self.bot.log("Trying to add show "+str(imdbName)) - apiKey = self.bot.credentials.sonarrKey - response = requests.get(self.sonarrURL+"series/lookup?term="+imdbName.replace(" ","%20")+"&apiKey="+apiKey) + self.bot.log("Trying to add show "+str(imdb_name)) + apiKey = self.bot.credentials["sonarr_key"] + response = requests.get(self.sonarrURL+"series/lookup?term="+imdb_name.replace(" ","%20")+"&apiKey="+apiKey) lookupData = response.json()[0] postData = {"ProfileId" : 1, "rootFolderPath" : self.showPath, @@ -264,8 +264,8 @@ class BedreNetflix(): movieSectionTitle = "*Missing movies not downloading*" movieSectionTitleLine = "-"*((titleWidth-len(movieSectionTitle))//2) message.append(movieSectionTitleLine+movieSectionTitle+movieSectionTitleLine) - movieList = requests.get(self.radarrURL+"movie?apiKey="+self.bot.credentials.radarrKey).json() - movieQueue = requests.get(self.radarrURL+"queue?apiKey="+self.bot.credentials.radarrKey).json() + movieList = requests.get(self.radarrURL+"movie?apiKey="+self.bot.credentials["radarr_key"]).json() + movieQueue = requests.get(self.radarrURL+"queue?apiKey="+self.bot.credentials["radarr_key"]).json() movieQueueIDs = [] for queueItem in movieQueue["records"]: @@ -297,7 +297,7 @@ class BedreNetflix(): showSectionTitleLine = "-"*((titleWidth-len(showSectionTitle))//2) message.append(showSectionTitleLine+showSectionTitle+showSectionTitleLine) - showList = requests.get(self.sonarrURL+"series?apiKey="+self.bot.credentials.sonarrKey).json() + showList = requests.get(self.sonarrURL+"series?apiKey="+self.bot.credentials["sonarr_key"]).json() for show in showList: if show["seasons"][0]["seasonNumber"] == 0: @@ -381,14 +381,14 @@ class BedreNetflix(): if not allDownloaded: updatesLeft = 60 messageText = messageText[:-3]+"\nThis message will update every 10 seconds for "+str(math.ceil(updatesLeft/6))+" more minutes\n```" - oldMessage = await ctx.send(messageText) + old_message = await ctx.send(messageText) while ((not allDownloaded) and updatesLeft > 0): await asyncio.sleep(10) updatesLeft -= 1 messageText, allDownloaded = await self.genDownloadList(*params) messageText = messageText[:-3]+"\nThis message will update every 10 seconds for "+str(math.ceil(updatesLeft/6))+" more minutes\n```" - await oldMessage.edit(content = messageText) + await old_message.edit(content = messageText) messageText, allDownloaded = await self.genDownloadList(*params) @@ -399,7 +399,7 @@ class BedreNetflix(): messageText = messageText[:-3]+"\nThis message will not update anymore\n```" self.bot.log("The message updated 20 times") - await oldMessage.edit(content = messageText) + await old_message.edit(content = messageText) else: await ctx.send(messageText) diff --git a/funcs/other/generators.py b/gwendolyn/funcs/other/generators.py similarity index 98% rename from funcs/other/generators.py rename to gwendolyn/funcs/other/generators.py index a1621b3..8b8b5d9 100644 --- a/funcs/other/generators.py +++ b/gwendolyn/funcs/other/generators.py @@ -17,7 +17,7 @@ class Generators(): # Generates a random name async def nameGen(self, ctx): # Makes a list of all names from "names.txt" - names = open('resources/names.txt', encoding='utf8').read() + names = open('gwendolyn/resources/names.txt', encoding='utf8').read() corpus = list(names) # Makes a list of pairs diff --git a/funcs/other/nerdShit.py b/gwendolyn/funcs/other/nerd_shit.py similarity index 76% rename from funcs/other/nerdShit.py rename to gwendolyn/funcs/other/nerd_shit.py index 53f5306..1e8274a 100644 --- a/funcs/other/nerdShit.py +++ b/gwendolyn/funcs/other/nerd_shit.py @@ -8,9 +8,9 @@ class NerdShit(): async def wolfSearch(self,ctx,content): await self.bot.defer(ctx) - fnt = ImageFont.truetype('resources/fonts/times-new-roman.ttf', 20) + fnt = ImageFont.truetype('gwendolyn/resources/fonts/times-new-roman.ttf', 20) self.bot.log("Requesting data") - bot = wolframalpha.Client(self.bot.credentials.wolfKey) + bot = wolframalpha.Client(self.bot.credentials["wolfram_alpha_key"]) res = bot.query(content) self.bot.log("Processing data") @@ -49,33 +49,33 @@ class NerdShit(): for count, pod in enumerate(chunk): response = requests.get(pod.img["@src"]) - file = open("resources/wolfTemp.png", "wb") + file = open("gwendolyn/resources/wolfTemp.png", "wb") file.write(response.content) file.close() - oldImage = Image.open("resources/wolfTemp.png") - oldSize = oldImage.size + old_image = Image.open("gwendolyn/resources/wolfTemp.png") + oldSize = old_image.size if titleChucks[x][count] == "": placeForText = 0 else: placeForText = 30 newSize = (width,int(oldSize[1]+10+placeForText)) newImage = Image.new("RGB",newSize,color=(255,255,255)) - newImage.paste(oldImage, (int((int(oldSize[0]+10)-oldSize[0])/2),int(((newSize[1]-placeForText)-oldSize[1])/2)+placeForText)) + newImage.paste(old_image, (int((int(oldSize[0]+10)-oldSize[0])/2),int(((newSize[1]-placeForText)-oldSize[1])/2)+placeForText)) if titleChucks[x][count] != "": d = ImageDraw.Draw(newImage,"RGB") d.text((5,7),titleChucks[x][count],font=fnt,fill=(150,150,150)) wolfImage.paste(newImage,(0,heights[count])) newImage.close() - oldImage.close() + old_image.close() count += 1 - wolfImage.save("resources/wolf.png") + wolfImage.save("gwendolyn/resources/wolf.png") wolfImage.close() - await ctx.channel.send(file = discord.File("resources/wolf.png")) + await ctx.channel.send(file = discord.File("gwendolyn/resources/wolf.png")) - os.remove("resources/wolf.png") - os.remove("resources/wolfTemp.png") + os.remove("gwendolyn/resources/wolf.png") + os.remove("gwendolyn/resources/wolfTemp.png") else: self.bot.log("No returned data") await ctx.send("Could not find anything relating to your search") \ No newline at end of file diff --git a/funcs/other/other.py b/gwendolyn/funcs/other/other.py similarity index 94% rename from funcs/other/other.py rename to gwendolyn/funcs/other/other.py index 2955641..f901e1d 100644 --- a/funcs/other/other.py +++ b/gwendolyn/funcs/other/other.py @@ -7,11 +7,11 @@ import lxml # Used in imageFunc import fandom # Used in findWikiPage import d20 # Used in rollDice import ast -from .bedreNetflix import BedreNetflix -from .nerdShit import NerdShit +from .bedre_netflix import BedreNetflix +from .nerd_shit import NerdShit from .generators import Generators -from utils import cap +from gwendolyn.utils import cap fandom.set_lang("da") fandom.set_wiki("senkulpa") @@ -28,8 +28,8 @@ class MyStringifier(d20.MarkdownStringifier): class Other(): def __init__(self, bot): self.bot = bot - self.bedreNetflix = BedreNetflix(self.bot) - self.nerdShit = NerdShit(self.bot) + self.bedre_netflix = BedreNetflix(self.bot) + self.nerd_shit = NerdShit(self.bot) self.generators = Generators(self.bot) # Picks a random movie and returns information about it @@ -40,7 +40,7 @@ class Other(): imdbClient = imdb.IMDb() self.bot.log("Picking a movie") - with open("resources/movies.txt", "r") as f: + with open("gwendolyn/resources/movies.txt", "r") as f: movieList = f.read().split("\n") movieName = random.choice(movieList) @@ -183,13 +183,13 @@ class Other(): async def helpFunc(self, ctx, command): if command == "": - with open("resources/help/help.txt",encoding="utf-8") as f: + with open("gwendolyn/resources/help/help.txt",encoding="utf-8") as f: text = f.read() em = discord.Embed(title = "Help", description = text,colour = 0x59f442) await ctx.send(embed = em) else: self.bot.log(f"Looking for help-{command}.txt",str(ctx.channel_id)) - with open(f"resources/help/help-{command}.txt",encoding="utf-8") as f: + with open(f"gwendolyn/resources/help/help-{command}.txt",encoding="utf-8") as f: text = f.read() em = discord.Embed(title = command.capitalize(), description = text,colour = 0x59f442) await ctx.send(embed = em) diff --git a/funcs/star_wars_funcs/__init__.py b/gwendolyn/funcs/star_wars_funcs/__init__.py similarity index 100% rename from funcs/star_wars_funcs/__init__.py rename to gwendolyn/funcs/star_wars_funcs/__init__.py diff --git a/funcs/star_wars_funcs/star_wars.py b/gwendolyn/funcs/star_wars_funcs/star_wars.py similarity index 100% rename from funcs/star_wars_funcs/star_wars.py rename to gwendolyn/funcs/star_wars_funcs/star_wars.py diff --git a/funcs/star_wars_funcs/star_wars_char.py b/gwendolyn/funcs/star_wars_funcs/star_wars_char.py similarity index 97% rename from funcs/star_wars_funcs/star_wars_char.py rename to gwendolyn/funcs/star_wars_funcs/star_wars_char.py index b90e8d3..fd749f8 100644 --- a/funcs/star_wars_funcs/star_wars_char.py +++ b/gwendolyn/funcs/star_wars_funcs/star_wars_char.py @@ -7,15 +7,15 @@ class StarWarsChar(): self.bot = bot def getCharName(self, user : str): - self.bot.log("Getting name for "+self.bot.database_funcs.getName(user)+"'s character") + self.bot.log("Getting name for "+self.bot.database_funcs.get_name(user)+"'s character") userCharacter = self.bot.database["starwars characters"].find_one({"_id":user}) if userCharacter != None: self.bot.log("Name is "+userCharacter["Name"]) return userCharacter["Name"] else: - self.bot.log("Just using "+self.bot.database_funcs.getName(user)) - return self.bot.database_funcs.getName(user) + self.bot.log("Just using "+self.bot.database_funcs.get_name(user)) + return self.bot.database_funcs.get_name(user) def setUpDict(self, cmd : dict): self.bot.log("Setting up a dictionary in a nice way") @@ -252,7 +252,7 @@ class StarWarsChar(): if cmd == "": break - self.bot.log("Looking for "+self.bot.database_funcs.getName(user)+"'s character") + self.bot.log("Looking for "+self.bot.database_funcs.get_name(user)+"'s character") if userCharacter != None: self.bot.log("Found it! Looking for "+key+" in the data") if key in userCharacter: @@ -303,7 +303,7 @@ class StarWarsChar(): return cmd[0]+" added to "+key+" for " + userCharacter["Name"] elif key == "Weapons": - with open("resources/star_wars/starwarstemplates.json", "r") as f: + with open("gwendolyn/resources/star_wars/starwarstemplates.json", "r") as f: templates = json.load(f) newWeapon = templates["Weapon"] self.bot.log("Adding "+cmd+" to "+key) @@ -495,18 +495,18 @@ class StarWarsChar(): text = self.replaceWithSpaces(text) returnEmbed = True else: - self.bot.log("Makin' a character for "+self.bot.database_funcs.getName(user)) - with open("resources/star_wars/starwarstemplates.json", "r") as f: + self.bot.log("Makin' a character for "+self.bot.database_funcs.get_name(user)) + with open("gwendolyn/resources/star_wars/starwarstemplates.json", "r") as f: templates = json.load(f) newChar = templates["Character"] newChar["_id"] = user self.bot.database["starwars characters"].insert_one(newChar) - await ctx.send("Character for " + self.bot.database_funcs.getName(user) + " created") + await ctx.send("Character for " + self.bot.database_funcs.get_name(user) + " created") else: if cmd == "Purge": - self.bot.log("Deleting "+self.bot.database_funcs.getName(user)+"'s character") + self.bot.log("Deleting "+self.bot.database_funcs.get_name(user)+"'s character") self.bot.database["starwars characters"].delete_one({"_id":user}) - await ctx.send("Character for " + self.bot.database_funcs.getName(user) + " deleted") + await ctx.send("Character for " + self.bot.database_funcs.get_name(user) + " deleted") else: await ctx.send(self.replaceWithSpaces(str(self.charData(user,cmd)))) diff --git a/funcs/star_wars_funcs/star_wars_destiny.py b/gwendolyn/funcs/star_wars_funcs/star_wars_destiny.py similarity index 86% rename from funcs/star_wars_funcs/star_wars_destiny.py rename to gwendolyn/funcs/star_wars_funcs/star_wars_destiny.py index b1fac7f..acb2cc6 100644 --- a/funcs/star_wars_funcs/star_wars_destiny.py +++ b/gwendolyn/funcs/star_wars_funcs/star_wars_destiny.py @@ -7,13 +7,13 @@ class StarWarsDestiny(): roll, diceResults = self.bot.star_wars.roll.roll(0,0,0,0,0,0,num) roll = "".join(sorted(roll)) - with open("resources/star_wars/destinyPoints.txt","wt") as f: + with open("gwendolyn/resources/star_wars/destinyPoints.txt","wt") as f: f.write(roll) return "Rolled for Destiny Points and got:\n"+self.bot.star_wars.roll.diceResultToEmoji(diceResults)+"\n"+self.bot.star_wars.roll.resultToEmoji(roll) def destinyUse(self, user : str): - with open("resources/star_wars/destinyPoints.txt","rt") as f: + with open("gwendolyn/resources/star_wars/destinyPoints.txt","rt") as f: points = f.read() if user == "Nikolaj": @@ -21,7 +21,7 @@ class StarWarsDestiny(): if 'B' in points: points = points.replace("B","L",1) points = "".join(sorted(points)) - with open("resources/star_wars/destinyPoints.txt","wt") as f: + with open("gwendolyn/resources/star_wars/destinyPoints.txt","wt") as f: f.write(points) self.bot.log("Did it") return "Used a dark side destiny point. Destiny pool is now:\n"+self.bot.star_wars.roll.resultToEmoji(points) @@ -33,7 +33,7 @@ class StarWarsDestiny(): if 'L' in points: points = points.replace("L","B",1) points = "".join(sorted(points)) - with open("resources/star_wars/destinyPoints.txt","wt") as f: + with open("gwendolyn/resources/star_wars/destinyPoints.txt","wt") as f: f.write(points) self.bot.log("Did it") return "Used a light side destiny point. Destiny pool is now:\n"+self.bot.star_wars.roll.resultToEmoji(points) @@ -51,7 +51,7 @@ class StarWarsDestiny(): if cmd == "": self.bot.log("Retrieving destiny pool info") - with open("resources/star_wars/destinyPoints.txt","rt") as f: + with open("gwendolyn/resources/star_wars/destinyPoints.txt","rt") as f: sendMessage = self.bot.star_wars.roll.resultToEmoji(f.read()) else: commands = cmd.upper().split(" ") diff --git a/funcs/star_wars_funcs/star_wars_roll.py b/gwendolyn/funcs/star_wars_funcs/star_wars_roll.py similarity index 99% rename from funcs/star_wars_funcs/star_wars_roll.py rename to gwendolyn/funcs/star_wars_funcs/star_wars_roll.py index 07ad6e7..bd17710 100644 --- a/funcs/star_wars_funcs/star_wars_roll.py +++ b/gwendolyn/funcs/star_wars_funcs/star_wars_roll.py @@ -3,7 +3,7 @@ import re import string import json -with open("resources/star_wars/starwarsskills.json", "r") as f: +with open("gwendolyn/resources/star_wars/starwarsskills.json", "r") as f: skillData = json.load(f) class StarWarsRoll(): diff --git a/gwendolyn.py b/gwendolyn/gwendolyn_client.py similarity index 72% rename from gwendolyn.py rename to gwendolyn/gwendolyn_client.py index fe71638..ff4c683 100644 --- a/gwendolyn.py +++ b/gwendolyn/gwendolyn_client.py @@ -1,25 +1,22 @@ """ -Contains the Gwendolyn class, and runs it when run as script. +Contains the Gwendolyn class, a subclass of the discord command bot. *Classes* --------- Gwendolyn(discord.ext.commands.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 - 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 funcs import Money, StarWars, Games, Other, LookupFuncs -from utils import (Options, Credentials, logThis, makeFiles, DatabaseFuncs, - EventHandler, ErrorHandler, long_strings) +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): @@ -33,6 +30,7 @@ class Gwendolyn(commands.Bot): stop(ctx: discord_slash.context.SlashContext) defer(ctx: discord_slash.context.SlashContext) """ + # pylint: disable=too-many-instance-attributes def __init__(self): """Initialize the bot.""" @@ -54,17 +52,17 @@ class Gwendolyn(commands.Bot): def _add_clients_and_options(self): """Add all the client, option and credentials objects.""" self.long_strings = long_strings() - self.options = Options() - self.credentials = Credentials() - finnhub_key = self.credentials.finnhub_key + 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.mongoDBUser - mongo_password = self.credentials.mongoDBPassword + 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: + if self.options["testing"]: self.log("Testing mode") self.database = database_clint["Gwendolyn-Test"] else: @@ -92,13 +90,13 @@ class Gwendolyn(commands.Bot): def _add_cogs(self): """Load cogs.""" - for filename in os.listdir("./cogs"): + for filename in os.listdir("./gwendolyn/cogs"): if filename.endswith(".py"): - self.load_extension(f"cogs.{filename[:-3]}") + self.load_extension(f"gwendolyn.cogs.{filename[:-3]}") def log(self, messages, channel: str = "", level: int = 20): """Log a message. Described in utils/util_functions.py.""" - logThis(messages, channel, level) + log_this(messages, channel, level) async def stop(self, ctx: discord_slash.context.SlashContext): """ @@ -112,12 +110,15 @@ class Gwendolyn(commands.Bot): ctx: discord_slash.context.SlashContext The context of the "/stop" slash command. """ - if f"#{ctx.author.id}" in self.options.admins: + 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.wipeGames() + 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() @@ -132,20 +133,3 @@ class Gwendolyn(commands.Bot): await ctx.defer() except discord_slash.error.AlreadyResponded: self.log("defer failed") - - -if __name__ == "__main__": - if platform.system() == "Windows": - asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) - - # Creates the required files - makeFiles() - - # 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)}"]) diff --git a/resources/fonts/comic-sans-bold.ttf b/gwendolyn/resources/fonts/comic-sans-bold.ttf similarity index 100% rename from resources/fonts/comic-sans-bold.ttf rename to gwendolyn/resources/fonts/comic-sans-bold.ttf diff --git a/resources/fonts/futura-bold.ttf b/gwendolyn/resources/fonts/futura-bold.ttf similarity index 100% rename from resources/fonts/futura-bold.ttf rename to gwendolyn/resources/fonts/futura-bold.ttf diff --git a/resources/fonts/times-new-roman.ttf b/gwendolyn/resources/fonts/times-new-roman.ttf similarity index 100% rename from resources/fonts/times-new-roman.ttf rename to gwendolyn/resources/fonts/times-new-roman.ttf diff --git a/resources/games/blackjackTable.png b/gwendolyn/resources/games/blackjack_table.png similarity index 100% rename from resources/games/blackjackTable.png rename to gwendolyn/resources/games/blackjack_table.png diff --git a/resources/games/cards/0C.png b/gwendolyn/resources/games/cards/0C.png similarity index 100% rename from resources/games/cards/0C.png rename to gwendolyn/resources/games/cards/0C.png diff --git a/resources/games/cards/0D.png b/gwendolyn/resources/games/cards/0D.png similarity index 100% rename from resources/games/cards/0D.png rename to gwendolyn/resources/games/cards/0D.png diff --git a/resources/games/cards/0H.png b/gwendolyn/resources/games/cards/0H.png similarity index 100% rename from resources/games/cards/0H.png rename to gwendolyn/resources/games/cards/0H.png diff --git a/resources/games/cards/0S.png b/gwendolyn/resources/games/cards/0S.png similarity index 100% rename from resources/games/cards/0S.png rename to gwendolyn/resources/games/cards/0S.png diff --git a/resources/games/cards/2C.png b/gwendolyn/resources/games/cards/2C.png similarity index 100% rename from resources/games/cards/2C.png rename to gwendolyn/resources/games/cards/2C.png diff --git a/resources/games/cards/2D.png b/gwendolyn/resources/games/cards/2D.png similarity index 100% rename from resources/games/cards/2D.png rename to gwendolyn/resources/games/cards/2D.png diff --git a/resources/games/cards/2H.png b/gwendolyn/resources/games/cards/2H.png similarity index 100% rename from resources/games/cards/2H.png rename to gwendolyn/resources/games/cards/2H.png diff --git a/resources/games/cards/2S.png b/gwendolyn/resources/games/cards/2S.png similarity index 100% rename from resources/games/cards/2S.png rename to gwendolyn/resources/games/cards/2S.png diff --git a/resources/games/cards/3C.png b/gwendolyn/resources/games/cards/3C.png similarity index 100% rename from resources/games/cards/3C.png rename to gwendolyn/resources/games/cards/3C.png diff --git a/resources/games/cards/3D.png b/gwendolyn/resources/games/cards/3D.png similarity index 100% rename from resources/games/cards/3D.png rename to gwendolyn/resources/games/cards/3D.png diff --git a/resources/games/cards/3H.png b/gwendolyn/resources/games/cards/3H.png similarity index 100% rename from resources/games/cards/3H.png rename to gwendolyn/resources/games/cards/3H.png diff --git a/resources/games/cards/3S.png b/gwendolyn/resources/games/cards/3S.png similarity index 100% rename from resources/games/cards/3S.png rename to gwendolyn/resources/games/cards/3S.png diff --git a/resources/games/cards/4C.png b/gwendolyn/resources/games/cards/4C.png similarity index 100% rename from resources/games/cards/4C.png rename to gwendolyn/resources/games/cards/4C.png diff --git a/resources/games/cards/4D.png b/gwendolyn/resources/games/cards/4D.png similarity index 100% rename from resources/games/cards/4D.png rename to gwendolyn/resources/games/cards/4D.png diff --git a/resources/games/cards/4H.png b/gwendolyn/resources/games/cards/4H.png similarity index 100% rename from resources/games/cards/4H.png rename to gwendolyn/resources/games/cards/4H.png diff --git a/resources/games/cards/4S.png b/gwendolyn/resources/games/cards/4S.png similarity index 100% rename from resources/games/cards/4S.png rename to gwendolyn/resources/games/cards/4S.png diff --git a/resources/games/cards/5C.png b/gwendolyn/resources/games/cards/5C.png similarity index 100% rename from resources/games/cards/5C.png rename to gwendolyn/resources/games/cards/5C.png diff --git a/resources/games/cards/5D.png b/gwendolyn/resources/games/cards/5D.png similarity index 100% rename from resources/games/cards/5D.png rename to gwendolyn/resources/games/cards/5D.png diff --git a/resources/games/cards/5H.png b/gwendolyn/resources/games/cards/5H.png similarity index 100% rename from resources/games/cards/5H.png rename to gwendolyn/resources/games/cards/5H.png diff --git a/resources/games/cards/5S.png b/gwendolyn/resources/games/cards/5S.png similarity index 100% rename from resources/games/cards/5S.png rename to gwendolyn/resources/games/cards/5S.png diff --git a/resources/games/cards/6C.png b/gwendolyn/resources/games/cards/6C.png similarity index 100% rename from resources/games/cards/6C.png rename to gwendolyn/resources/games/cards/6C.png diff --git a/resources/games/cards/6D.png b/gwendolyn/resources/games/cards/6D.png similarity index 100% rename from resources/games/cards/6D.png rename to gwendolyn/resources/games/cards/6D.png diff --git a/resources/games/cards/6H.png b/gwendolyn/resources/games/cards/6H.png similarity index 100% rename from resources/games/cards/6H.png rename to gwendolyn/resources/games/cards/6H.png diff --git a/resources/games/cards/6S.png b/gwendolyn/resources/games/cards/6S.png similarity index 100% rename from resources/games/cards/6S.png rename to gwendolyn/resources/games/cards/6S.png diff --git a/resources/games/cards/7C.png b/gwendolyn/resources/games/cards/7C.png similarity index 100% rename from resources/games/cards/7C.png rename to gwendolyn/resources/games/cards/7C.png diff --git a/resources/games/cards/7D.png b/gwendolyn/resources/games/cards/7D.png similarity index 100% rename from resources/games/cards/7D.png rename to gwendolyn/resources/games/cards/7D.png diff --git a/resources/games/cards/7H.png b/gwendolyn/resources/games/cards/7H.png similarity index 100% rename from resources/games/cards/7H.png rename to gwendolyn/resources/games/cards/7H.png diff --git a/resources/games/cards/7S.png b/gwendolyn/resources/games/cards/7S.png similarity index 100% rename from resources/games/cards/7S.png rename to gwendolyn/resources/games/cards/7S.png diff --git a/resources/games/cards/8C.png b/gwendolyn/resources/games/cards/8C.png similarity index 100% rename from resources/games/cards/8C.png rename to gwendolyn/resources/games/cards/8C.png diff --git a/resources/games/cards/8D.png b/gwendolyn/resources/games/cards/8D.png similarity index 100% rename from resources/games/cards/8D.png rename to gwendolyn/resources/games/cards/8D.png diff --git a/resources/games/cards/8H.png b/gwendolyn/resources/games/cards/8H.png similarity index 100% rename from resources/games/cards/8H.png rename to gwendolyn/resources/games/cards/8H.png diff --git a/resources/games/cards/8S.png b/gwendolyn/resources/games/cards/8S.png similarity index 100% rename from resources/games/cards/8S.png rename to gwendolyn/resources/games/cards/8S.png diff --git a/resources/games/cards/9C.png b/gwendolyn/resources/games/cards/9C.png similarity index 100% rename from resources/games/cards/9C.png rename to gwendolyn/resources/games/cards/9C.png diff --git a/resources/games/cards/9D.png b/gwendolyn/resources/games/cards/9D.png similarity index 100% rename from resources/games/cards/9D.png rename to gwendolyn/resources/games/cards/9D.png diff --git a/resources/games/cards/9H.png b/gwendolyn/resources/games/cards/9H.png similarity index 100% rename from resources/games/cards/9H.png rename to gwendolyn/resources/games/cards/9H.png diff --git a/resources/games/cards/9S.png b/gwendolyn/resources/games/cards/9S.png similarity index 100% rename from resources/games/cards/9S.png rename to gwendolyn/resources/games/cards/9S.png diff --git a/resources/games/cards/AC.png b/gwendolyn/resources/games/cards/AC.png similarity index 100% rename from resources/games/cards/AC.png rename to gwendolyn/resources/games/cards/AC.png diff --git a/resources/games/cards/AD.png b/gwendolyn/resources/games/cards/AD.png similarity index 100% rename from resources/games/cards/AD.png rename to gwendolyn/resources/games/cards/AD.png diff --git a/resources/games/cards/AH.png b/gwendolyn/resources/games/cards/AH.png similarity index 100% rename from resources/games/cards/AH.png rename to gwendolyn/resources/games/cards/AH.png diff --git a/resources/games/cards/AS.png b/gwendolyn/resources/games/cards/AS.png similarity index 100% rename from resources/games/cards/AS.png rename to gwendolyn/resources/games/cards/AS.png diff --git a/resources/games/cards/JC.png b/gwendolyn/resources/games/cards/JC.png similarity index 100% rename from resources/games/cards/JC.png rename to gwendolyn/resources/games/cards/JC.png diff --git a/resources/games/cards/JD.png b/gwendolyn/resources/games/cards/JD.png similarity index 100% rename from resources/games/cards/JD.png rename to gwendolyn/resources/games/cards/JD.png diff --git a/resources/games/cards/JH.png b/gwendolyn/resources/games/cards/JH.png similarity index 100% rename from resources/games/cards/JH.png rename to gwendolyn/resources/games/cards/JH.png diff --git a/resources/games/cards/JS.png b/gwendolyn/resources/games/cards/JS.png similarity index 100% rename from resources/games/cards/JS.png rename to gwendolyn/resources/games/cards/JS.png diff --git a/resources/games/cards/KC.png b/gwendolyn/resources/games/cards/KC.png similarity index 100% rename from resources/games/cards/KC.png rename to gwendolyn/resources/games/cards/KC.png diff --git a/resources/games/cards/KD.png b/gwendolyn/resources/games/cards/KD.png similarity index 100% rename from resources/games/cards/KD.png rename to gwendolyn/resources/games/cards/KD.png diff --git a/resources/games/cards/KH.png b/gwendolyn/resources/games/cards/KH.png similarity index 100% rename from resources/games/cards/KH.png rename to gwendolyn/resources/games/cards/KH.png diff --git a/resources/games/cards/KS.png b/gwendolyn/resources/games/cards/KS.png similarity index 100% rename from resources/games/cards/KS.png rename to gwendolyn/resources/games/cards/KS.png diff --git a/resources/games/cards/QC.png b/gwendolyn/resources/games/cards/QC.png similarity index 100% rename from resources/games/cards/QC.png rename to gwendolyn/resources/games/cards/QC.png diff --git a/resources/games/cards/QD.png b/gwendolyn/resources/games/cards/QD.png similarity index 100% rename from resources/games/cards/QD.png rename to gwendolyn/resources/games/cards/QD.png diff --git a/resources/games/cards/QH.png b/gwendolyn/resources/games/cards/QH.png similarity index 100% rename from resources/games/cards/QH.png rename to gwendolyn/resources/games/cards/QH.png diff --git a/resources/games/cards/QS.png b/gwendolyn/resources/games/cards/QS.png similarity index 100% rename from resources/games/cards/QS.png rename to gwendolyn/resources/games/cards/QS.png diff --git a/resources/games/cards/blue_back.png b/gwendolyn/resources/games/cards/blue_back.png similarity index 100% rename from resources/games/cards/blue_back.png rename to gwendolyn/resources/games/cards/blue_back.png diff --git a/resources/games/cards/gray_back.png b/gwendolyn/resources/games/cards/gray_back.png similarity index 100% rename from resources/games/cards/gray_back.png rename to gwendolyn/resources/games/cards/gray_back.png diff --git a/resources/games/cards/green_back.png b/gwendolyn/resources/games/cards/green_back.png similarity index 100% rename from resources/games/cards/green_back.png rename to gwendolyn/resources/games/cards/green_back.png diff --git a/resources/games/cards/purple_back.png b/gwendolyn/resources/games/cards/purple_back.png similarity index 100% rename from resources/games/cards/purple_back.png rename to gwendolyn/resources/games/cards/purple_back.png diff --git a/resources/games/cards/red_back.png b/gwendolyn/resources/games/cards/red_back.png similarity index 100% rename from resources/games/cards/red_back.png rename to gwendolyn/resources/games/cards/red_back.png diff --git a/resources/games/cards/yellow_back.png b/gwendolyn/resources/games/cards/yellow_back.png similarity index 100% rename from resources/games/cards/yellow_back.png rename to gwendolyn/resources/games/cards/yellow_back.png diff --git a/resources/games/deckofCards.txt b/gwendolyn/resources/games/deck_of_cards.txt similarity index 100% rename from resources/games/deckofCards.txt rename to gwendolyn/resources/games/deck_of_cards.txt diff --git a/gwendolyn/resources/help/help-add_movie.txt b/gwendolyn/resources/help/help-add_movie.txt new file mode 100644 index 0000000..fae39ff --- /dev/null +++ b/gwendolyn/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/resources/help/help-addmovie.txt b/gwendolyn/resources/help/help-add_show.txt similarity index 60% rename from resources/help/help-addmovie.txt rename to gwendolyn/resources/help/help-add_show.txt index daa1ac6..4868941 100644 --- a/resources/help/help-addmovie.txt +++ b/gwendolyn/resources/help/help-add_show.txt @@ -1 +1 @@ -Du kan søge efter en film ved at skrive `/addmovie [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 +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/resources/help/help-balance.txt b/gwendolyn/resources/help/help-balance.txt similarity index 100% rename from resources/help/help-balance.txt rename to gwendolyn/resources/help/help-balance.txt diff --git a/resources/help/help-blackjack.txt b/gwendolyn/resources/help/help-blackjack.txt similarity index 100% rename from resources/help/help-blackjack.txt rename to gwendolyn/resources/help/help-blackjack.txt diff --git a/resources/help/help-connectfour.txt b/gwendolyn/resources/help/help-connect_four.txt similarity index 100% rename from resources/help/help-connectfour.txt rename to gwendolyn/resources/help/help-connect_four.txt diff --git a/resources/help/help-downloading.txt b/gwendolyn/resources/help/help-downloading.txt similarity index 100% rename from resources/help/help-downloading.txt rename to gwendolyn/resources/help/help-downloading.txt diff --git a/resources/help/help-give.txt b/gwendolyn/resources/help/help-give.txt similarity index 100% rename from resources/help/help-give.txt rename to gwendolyn/resources/help/help-give.txt diff --git a/resources/help/help-hangman.txt b/gwendolyn/resources/help/help-hangman.txt similarity index 100% rename from resources/help/help-hangman.txt rename to gwendolyn/resources/help/help-hangman.txt diff --git a/resources/help/help-hello.txt b/gwendolyn/resources/help/help-hello.txt similarity index 100% rename from resources/help/help-hello.txt rename to gwendolyn/resources/help/help-hello.txt diff --git a/resources/help/help-hex.txt b/gwendolyn/resources/help/help-hex.txt similarity index 100% rename from resources/help/help-hex.txt rename to gwendolyn/resources/help/help-hex.txt diff --git a/resources/help/help-image.txt b/gwendolyn/resources/help/help-image.txt similarity index 100% rename from resources/help/help-image.txt rename to gwendolyn/resources/help/help-image.txt diff --git a/resources/help/help-invest.txt b/gwendolyn/resources/help/help-invest.txt similarity index 100% rename from resources/help/help-invest.txt rename to gwendolyn/resources/help/help-invest.txt diff --git a/resources/help/help-monster.txt b/gwendolyn/resources/help/help-monster.txt similarity index 100% rename from resources/help/help-monster.txt rename to gwendolyn/resources/help/help-monster.txt diff --git a/resources/help/help-movie.txt b/gwendolyn/resources/help/help-movie.txt similarity index 100% rename from resources/help/help-movie.txt rename to gwendolyn/resources/help/help-movie.txt diff --git a/resources/help/help-name.txt b/gwendolyn/resources/help/help-name.txt similarity index 100% rename from resources/help/help-name.txt rename to gwendolyn/resources/help/help-name.txt diff --git a/resources/help/help-roll.txt b/gwendolyn/resources/help/help-roll.txt similarity index 100% rename from resources/help/help-roll.txt rename to gwendolyn/resources/help/help-roll.txt diff --git a/resources/help/help-spell.txt b/gwendolyn/resources/help/help-spell.txt similarity index 100% rename from resources/help/help-spell.txt rename to gwendolyn/resources/help/help-spell.txt diff --git a/resources/help/help-star_wars_character.txt b/gwendolyn/resources/help/help-star_wars_character.txt similarity index 100% rename from resources/help/help-star_wars_character.txt rename to gwendolyn/resources/help/help-star_wars_character.txt diff --git a/resources/help/help-star_wars_roll.txt b/gwendolyn/resources/help/help-star_wars_roll.txt similarity index 100% rename from resources/help/help-star_wars_roll.txt rename to gwendolyn/resources/help/help-star_wars_roll.txt diff --git a/resources/help/help-tavern.txt b/gwendolyn/resources/help/help-tavern.txt similarity index 100% rename from resources/help/help-tavern.txt rename to gwendolyn/resources/help/help-tavern.txt diff --git a/resources/help/help-thank.txt b/gwendolyn/resources/help/help-thank.txt similarity index 100% rename from resources/help/help-thank.txt rename to gwendolyn/resources/help/help-thank.txt diff --git a/resources/help/help-trivia.txt b/gwendolyn/resources/help/help-trivia.txt similarity index 100% rename from resources/help/help-trivia.txt rename to gwendolyn/resources/help/help-trivia.txt diff --git a/resources/help/help-wolf.txt b/gwendolyn/resources/help/help-wolf.txt similarity index 100% rename from resources/help/help-wolf.txt rename to gwendolyn/resources/help/help-wolf.txt diff --git a/resources/help/help.txt b/gwendolyn/resources/help/help.txt similarity index 90% rename from resources/help/help.txt rename to gwendolyn/resources/help/help.txt index e653eba..8db0a65 100644 --- a/resources/help/help.txt +++ b/gwendolyn/resources/help/help.txt @@ -17,8 +17,8 @@ `/hex` - Lader dig spille et spil Hex. `/hangman` - Lader dig spille et spil hangman. `/wolf` - Lader dig slå ting op på Wolfram Alpha. -`/addmovie` - Lader dig tilføje film til Bedre Netflix. -`/addshow` - Lader dig tilføje tv shows til Bedre Netflix. +`/add_movie` - Lader dig tilføje film til Bedre Netflix. +`/add_show` - Lader dig tilføje tv shows til Bedre Netflix. `/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/resources/long_strings.json b/gwendolyn/resources/long_strings.json similarity index 100% rename from resources/long_strings.json rename to gwendolyn/resources/long_strings.json diff --git a/resources/paper.jpg b/gwendolyn/resources/paper.jpg similarity index 100% rename from resources/paper.jpg rename to gwendolyn/resources/paper.jpg diff --git a/resources/slashParameters.json b/gwendolyn/resources/slash_parameters.json similarity index 95% rename from resources/slashParameters.json rename to gwendolyn/resources/slash_parameters.json index e4bd1ca..119dd88 100644 --- a/resources/slashParameters.json +++ b/gwendolyn/resources/slash_parameters.json @@ -1,6 +1,6 @@ { - "addMovie" : { - "name" : "addMovie", + "add_movie" : { + "name" : "add_movie", "description" : "Request a movie for Bedre Netflix", "options" : [ { @@ -11,8 +11,8 @@ } ] }, - "addShow" : { - "name" : "addShow", + "add_show" : { + "name" : "add_show", "description" : "Request a show for Bedre Netflix", "options" : [ { @@ -27,7 +27,7 @@ "name" : "balance", "description" : "See your balance of GwendoBucks" }, - "blackjackBet" : { + "blackjack_bet" : { "base" : "blackjack", "name" : "bet", "description" : "Enter the current blackjack game with a bet", @@ -40,12 +40,12 @@ } ] }, - "blackjackCards" : { + "blackjack_cards" : { "base" : "blackjack", "name" : "cards", "description" : "Get a count of the cards used in blackjack games" }, - "blackjackDouble" : { + "blackjack_double" : { "base" : "blackjack", "name" : "double", "description" : "Double your bet in blackjack", @@ -58,12 +58,12 @@ } ] }, - "blackjackHilo" : { + "blackjack_hilo" : { "base" : "blackjack", "name" : "hilo", "description" : "Get the current hi-lo value for the cards used in blackjack games" }, - "blackjackHit" : { + "blackjack_hit" : { "base" : "blackjack", "name" : "hit", "description" : "Hit on your hand in blackjack", @@ -76,12 +76,12 @@ } ] }, - "blackjackShuffle" : { + "blackjack_shuffle" : { "base" : "blackjack", "name" : "shuffle", "description" : "Shuffle the cards used in blackjack games" }, - "blackjackSplit" : { + "blackjack_split" : { "base" : "blackjack", "name" : "split", "description" : "Split your hand in blackjack", @@ -94,7 +94,7 @@ } ] }, - "blackjackStand" : { + "blackjack_stand" : { "base" : "blackjack", "name" : "stand", "description" : "Stand on your hand in blackjack", @@ -107,12 +107,12 @@ } ] }, - "blackjackStart" : { + "blackjack_start" : { "base" : "blackjack", "name" : "start", "description" : "Start a game of blackjack" }, - "connect_fourStartGwendolyn" : { + "connect_four_start_gwendolyn" : { "base" : "connect_four", "subcommand_group" : "start", "name" : "Gwendolyn", @@ -126,7 +126,7 @@ } ] }, - "connect_fourStartUser" : { + "connect_four_start_user" : { "base" : "connect_four", "subcommand_group" : "start", "name" : "user", @@ -140,7 +140,7 @@ } ] }, - "connect_fourSurrender" : { + "connect_four_surrender" : { "base" : "connect_four", "name" : "surrender", "description" : "Surrender the game of connect four" @@ -187,12 +187,12 @@ } ] }, - "hangmanStart" : { + "hangman_start" : { "base" : "hangman", "name" : "start", "description" : "Start a game of hangman" }, - "hangmanStop" : { + "hangman_stop" : { "base" : "hangman", "name" : "stop", "description" : "Stop the current game of hangman" @@ -213,7 +213,7 @@ } ] }, - "hexPlace" : { + "hex_place" : { "base" : "hex", "name" : "place", "description" : "Place a piece on the hex board", @@ -226,7 +226,7 @@ } ] }, - "hexStartGwendolyn" : { + "hex_start_gwendolyn" : { "base" : "hex", "subcommand_group" : "start", "name" : "Gwendolyn", @@ -240,7 +240,7 @@ } ] }, - "hexStartUser" : { + "hex_start_user" : { "base" : "hex", "subcommand_group" : "start", "name" : "user", @@ -254,17 +254,17 @@ } ] }, - "hexSurrender" : { + "hex_surrender" : { "base" : "hex", "name" : "surrender", "description" : "Surrender the game of hex" }, - "hexSwap" : { + "hex_swap" : { "base" : "hex", "name" : "swap", "description" : "Perform a hex swap" }, - "hexUndo" : { + "hex_undo" : { "base" : "hex", "name" : "undo", "description" : "Undo your last hex move" diff --git a/resources/star_wars/starwarsskills.json b/gwendolyn/resources/star_wars/starwarsskills.json similarity index 100% rename from resources/star_wars/starwarsskills.json rename to gwendolyn/resources/star_wars/starwarsskills.json diff --git a/resources/star_wars/starwarstemplates.json b/gwendolyn/resources/star_wars/starwarstemplates.json similarity index 100% rename from resources/star_wars/starwarstemplates.json rename to gwendolyn/resources/star_wars/starwarstemplates.json diff --git a/resources/startingFiles.json b/gwendolyn/resources/starting_files.json similarity index 82% rename from resources/startingFiles.json rename to gwendolyn/resources/starting_files.json index 1ad09a0..b22855e 100644 --- a/resources/startingFiles.json +++ b/gwendolyn/resources/starting_files.json @@ -1,6 +1,6 @@ { "json":{ - "resources/lookup/spells.json" : { + "gwendolyn/resources/lookup/spells.json" : { "Fireball" : { "casting_time" : "1 action", "components" : "V, S, M (a tiny ball of bat guano and sulfur)", @@ -12,7 +12,7 @@ "ritual" : false } }, - "resources/lookup/monsters.json" : [ + "gwendolyn/resources/lookup/monsters.json" : [ { "name": "Bandit", "size": "Medium", @@ -56,19 +56,19 @@ ] }, "txt": { - "resources/star_wars/destinyPoints.txt": "", - "resources/movies.txt": "The Room", - "resources/names.txt": "Gandalf\n", + "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", "options.txt" : "Testing: True\nTesting guild ids:\nAdmins:" }, "folder" : [ - "resources/lookup", - "resources/games/blackjackTables", - "resources/games/connect4Boards", - "resources/games/hexBoards", - "resources/games/hangmanBoards", - "resources/bedreNetflix", - "resources/games/old_images" + "gwendolyn/resources/lookup", + "gwendolyn/resources/games/blackjack_tables", + "gwendolyn/resources/games/connect4Boards", + "gwendolyn/resources/games/hex_boards", + "gwendolyn/resources/games/hangman_boards", + "gwendolyn/resources/bedre_netflix", + "gwendolyn/resources/games/old_images" ] } \ No newline at end of file diff --git a/gwendolyn/utils/__init__.py b/gwendolyn/utils/__init__.py new file mode 100644 index 0000000..863b018 --- /dev/null +++ b/gwendolyn/utils/__init__.py @@ -0,0 +1,11 @@ +"""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) diff --git a/utils/event_handlers.py b/gwendolyn/utils/event_handlers.py similarity index 67% rename from utils/event_handlers.py rename to gwendolyn/utils/event_handlers.py index 6b87b39..80e73bb 100644 --- a/utils/event_handlers.py +++ b/gwendolyn/utils/event_handlers.py @@ -6,16 +6,17 @@ Classes used to handle bot events and errors. EventHandler ErrorHandler """ -import discord # Used to init discord.Game and discord.Status, as well -# as compare errors to discord errors and as typehints import traceback # Used to get the traceback of errors import sys # Used to get traceback when the specific error is not -# available + # available + +import discord # Used to init discord.Game and discord.Status, as well + # as compare errors to discord errors and as typehints from discord.ext import commands # Used to compare errors with command -# errors + # errors from discord_slash.context import SlashContext -from utils.util_functions import emojiToCommand +from gwendolyn.utils.util_functions import emoji_to_command class EventHandler(): @@ -35,17 +36,15 @@ class EventHandler(): async def on_ready(self): """Log and sets status when it logs in.""" - slashCommandList = await self.bot.slash.to_dict() - print(slashCommandList['guild'][740652054388932679][13]) - await self.bot.database_funcs.syncCommands() + await self.bot.database_funcs.imdb_commands() name = self.bot.user.name userid = str(self.bot.user.id) - loggedInMessage = f"Logged in as {name}, {userid}" - self.bot.log(loggedInMessage, level=25) + logged_in_message = f"Logged in as {name}, {userid}" + self.bot.log(logged_in_message, level=25) game = discord.Game("Use /help for commands") - onlineStatus = discord.Status.online - await self.bot.change_presence(activity=game, status=onlineStatus) + online_status = discord.Status.online + await self.bot.change_presence(activity=game, status=online_status) async def on_slash_command(self, ctx: SlashContext): """Log when a slash command is given.""" @@ -55,13 +54,13 @@ class EventHandler(): subcommand = " " if ctx.subcommand_group is not None: - subcommandGroup = f"{ctx.subcommand_group} " + sub_command_group = f"{ctx.subcommand_group} " else: - subcommandGroup = "" + sub_command_group = "" args = " ".join([str(i) for i in ctx.args]) - fullCommand = f"/{ctx.command}{subcommand}{subcommandGroup}{args}" - log_message = f"{ctx.author.display_name} ran {fullCommand}" + full_command = f"/{ctx.command}{subcommand}{sub_command_group}{args}" + log_message = f"{ctx.author.display_name} ran {full_command}" self.bot.log(log_message, str(ctx.channel_id), level=25) async def on_reaction_add(self, reaction: discord.Reaction, @@ -71,52 +70,52 @@ class EventHandler(): tests = self.bot.database_funcs message = reaction.message channel = message.channel - reactedMessage = f"{user.display_name} reacted to a message" - self.bot.log(reactedMessage, str(channel.id)) - plexData = tests.bedreNetflixReactionTest(message) - # plexData is a list containing 3 elements: whether it was - # the addshow/addmovie command message the reaction was to + reacted_message = f"{user.display_name} reacted to a message" + self.bot.log(reacted_message, str(channel.id)) + plex_data = tests.bedre_netflix_reaction_test(message) + # plex_data is a list containing 3 elements: whether it was + # the add_show/add_movie command message the reaction was to # (bool), whether it's a movie (bool) (if false, it's a # show), and the imdb ids/names for the for the movies or # shows listed in the message (list). - reactionTestParams = [message, f"#{str(user.id)}"] + reaction_test_parameters = [message, f"#{str(user.id)}"] - if tests.connect_fourReactionTest(*reactionTestParams): - column = emojiToCommand(reaction.emoji) + if tests.connect_four_reaction_test(*reaction_test_parameters): + column = emoji_to_command(reaction.emoji) params = [message, f"#{user.id}", column-1] await self.bot.games.connect_four.placePiece(*params) - if plexData[0]: - plexFuncs = self.bot.other.bedreNetflix - if plexData[1]: - moviePick = emojiToCommand(reaction.emoji) - if moviePick == "none": - imdbID = None + if plex_data[0]: + plex_functions = self.bot.other.bedre_netflix + if plex_data[1]: + movie_pick = emoji_to_command(reaction.emoji) + if movie_pick == "none": + imdb_id = None else: - imdbID = plexData[2][moviePick-1] + imdb_id = plex_data[2][movie_pick-1] if isinstance(channel, discord.DMChannel): await message.delete() - await plexFuncs.addMovie(message, imdbID, False) + await plex_functions.add_movie(message, imdb_id, False) else: await message.clear_reactions() - await plexFuncs.addMovie(message, imdbID) + await plex_functions.add_movie(message, imdb_id) else: - showPick = emojiToCommand(reaction.emoji) - if showPick == "none": - imdbName = None + show_pick = emoji_to_command(reaction.emoji) + if show_pick == "none": + imdb_name = None else: - imdbName = plexData[2][showPick-1] + imdb_name = plex_data[2][show_pick-1] if isinstance(channel, discord.DMChannel): await message.delete() - await plexFuncs.addShow(message, imdbName, False) + await plex_functions.add_show(message, imdb_name, False) else: await message.clear_reactions() - await plexFuncs.addShow(message, imdbName) + await plex_functions.add_show(message, imdb_name) - elif tests.hangmanReactionTest(*reactionTestParams): + elif tests.hangman_reaction_test(*reaction_test_parameters): self.bot.log("They reacted to the hangman message") if ord(reaction.emoji) in range(127462, 127488): # The range is letter-emojis @@ -157,8 +156,8 @@ class ErrorHandler(): params = [type(error), error, error.__traceback__] exception = traceback.format_exception(*params) - exceptionString = "".join(exception) - log_messages = [f"exception in /{ctx.name}", f"{exceptionString}"] + exception_string = "".join(exception) + log_messages = [f"exception in /{ctx.name}", f"{exception_string}"] self.bot.log(log_messages, str(ctx.channel_id), 40) if isinstance(error, discord.errors.NotFound): self.bot.log("Context is non-existant", level=40) @@ -167,12 +166,12 @@ class ErrorHandler(): async def on_error(self, method: str): """Log when there's an error.""" - errorType = sys.exc_info()[0] - if errorType == discord.errors.NotFound: + error_type = sys.exc_info()[0] + if error_type == discord.errors.NotFound: self.bot.log("Deleted message before I could add all reactions") else: exception = traceback.format_exc() - exceptionString = "".join(exception) - log_messages = [f"exception in {method}", f"{exceptionString}"] + exception_string = "".join(exception) + log_messages = [f"exception in {method}", f"{exception_string}"] self.bot.log(log_messages, level=40) diff --git a/gwendolyn/utils/helper_classes.py b/gwendolyn/utils/helper_classes.py new file mode 100644 index 0000000..cf950ed --- /dev/null +++ b/gwendolyn/utils/helper_classes.py @@ -0,0 +1,260 @@ +""" +Contains classes used for utilities. + +*Classes* +--------- + DatabaseFuncs() +""" +import os # Used to test if files exist +import json # Used to read the data about add_movie/add_show +import time # Used to test how long it's been since commands were synced + +import re # Used in get_id +import discord # Used for type hints + + +class DatabaseFuncs(): + """ + Manages database functions. + + *Methods* + --------- + get_name(user_id: str) -> str + get_id(user_name: str) -> str + delete_game(game_type: str, channel: str) + wipe_games() + connect_four_reaction_test(message: discord.Message, + user: discord.User) -> bool + hangman_reaction_test(message: discord.Message, + user: discord.User) -> bool + bedre_netflix_reaction_test(message: discord.Message, + user: discord.User) -> bool, bool, + list + imdb_commands() + """ + + def __init__(self, bot): + """Initialize the class.""" + self.bot = bot + + def get_name(self, user_id: str): + """ + Get the name of a user you have the # id of. + + *Parameters: + ------------ + user_id: str + The id of the user you want the name of. The format is + "#" + str(discord.User.id) + + *Returns* + --------- + user_name: str + The name of the user. If the user couldn't be found, + returns the user_id. + """ + user = self.bot.database["users"].find_one({"_id": user_id}) + + if user_id == f"#{self.bot.user.id}": + return_name = "Gwendolyn" + elif user is not None: + return_name = user["user name"] + else: + self.bot.log(f"Couldn't find user {user_id}") + return_name = user_id + + return return_name + + def get_id(self, user_name: str): + """ + Get the id of a user you have the username of. + + *Parameters: + ------------ + user_name: str + The name of the user you want the id of. + + *Returns* + --------- + user_id: str + The id of the user in the format "#" + + str(discord.User.id). If the user couldn't be found, + returns the user_name. + """ + user_search = {"user name": re.compile(user_name, re.IGNORECASE)} + user = self.bot.database["users"].find_one(user_search) + + if user is not None: + return_id = user["_id"] + else: + self.bot.log("Couldn't find user "+user_name) + return_id = None + + return return_id + + def delete_game(self, game_type: str, channel: str): + """ + Remove a game from the database. + + *Parameters* + ------------ + game_type: str + The name of the collection the game is in, like + "hangman games", "blackjack games" etc. + channel: str + The channel id of the channel the game is on as a + string. + """ + self.bot.database[game_type].delete_one({"_id": channel}) + + def wipe_games(self): + """Delete all running games and pull from git.""" + game_types = [ + "trivia questions", + "blackjack games", + "connect 4 games", + "hangman games", + "hex games" + ] + for game_type in game_types: + self.bot.database[game_type].delete_many({}) + + def connect_four_reaction_test(self, message: discord.Message, + user: discord.User): + """ + Test if the given message is the current connect four game. + + Also tests if the given user is the one who's turn it is. + + *Parameters* + ------------ + message: discord.Message + The message to test. + user: discord.User + The user to test. + *Returns* + --------- + : bool + Whether the given message is the current connect four + game and if the user who reacted is the user who's turn + it is. + """ + channel = message.channel + channel_search = {"_id": str(channel.id)} + game = self.bot.database["connect 4 games"].find_one(channel_search) + + old_images_path = "gwendolyn/resources/games/old_images/" + file_path = old_images_path + f"connect_four{channel.id}" + if os.path.isfile(file_path): + with open(file_path, "r") as file_pointer: + old_image = int(file_pointer.read()) + else: + old_image = 0 + + if message.id == old_image: + self.bot.log("They reacted to the connect_four game") + turn = game["turn"] + if user == game["players"][turn]: + valid_reaction = True + else: + self.bot.log("It wasn't their turn") + valid_reaction = False + else: + valid_reaction = False + + return valid_reaction + + def hangman_reaction_test(self, message: discord.Message, + user: discord.User): + """ + Test if the given message is the current hangman game. + + Also tests if the given user is the one who's playing hangman. + + *Parameters* + ------------ + message: discord.Message + The message to test. + user: discord.User + The user to test. + *Returns* + --------- + : bool + Whether the given message is the current hangman game + and if the user who reacted is the user who's playing + hangman. + """ + channel = message.channel + file_path = f"gwendolyn/resources/games/old_images/hangman{channel.id}" + if os.path.isfile(file_path): + with open(file_path, "r") as file_pointer: + old_messages = file_pointer.read().splitlines() + else: + return False + game_message = False + + for old_message in old_messages: + old_message_id = int(old_message) + if message.id == old_message_id: + database = self.bot.database["hangman games"] + channel_search = {"_id": str(channel.id)} + game = database.find_one(channel_search) + if user == game["player"]: + game_message = True + + break + + return game_message + + def bedre_netflix_reaction_test(self, message: discord.Message): + """ + Test if the given message is the response to a plex request. + + *Parameters* + ------------ + message: discord.Message + The message to test. + + *Returns* + --------- + : bool + Whether the message is the response to a plex request. + : bool + Whether it was a movie request (false for a show + request) + : list + A list of ids or names of the shows or movies that + Gwendolyn presented after the request. + """ + channel = message.channel + old_messages_path = "gwendolyn/resources/bedre_netflix/" + file_path = old_messages_path + f"old_message{str(channel.id)}" + if os.path.isfile(file_path): + with open(file_path, "r") as file_pointer: + data = json.load(file_pointer) + else: + return (False, None, None) + + if data["message_id"] != message.id: + return (False, None, None) + + if "imdb_ids" in data: + return_data = (True, True, data["imdb_ids"]) + else: + return_data = (True, False, data["imdb_names"]) + + return return_data + + async def imdb_commands(self): + """Sync the slash commands with the discord API.""" + collection = self.bot.database["last synced"] + last_synced = collection.find_one() + now = time.time() + if last_synced["last synced"] < now - 86400: + slash_command_list = await self.bot.slash.to_dict() + self.bot.log(f"Updating commands: {slash_command_list}") + await self.bot.slash.sync_all_commands() + id_number = last_synced["_id"] + query_filter = {"_id": id_number} + update = {"$set": {"last synced": now}} + collection.update_one(query_filter, update) diff --git a/gwendolyn/utils/util_functions.py b/gwendolyn/utils/util_functions.py new file mode 100644 index 0000000..cd1d185 --- /dev/null +++ b/gwendolyn/utils/util_functions.py @@ -0,0 +1,340 @@ +""" +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 json # Used by longString(), 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 + +# 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") 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") as file_pointer: + data = sanitize(file_pointer.read()) + + 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"] + credentials["wolfram_alpha_key"] = data["wolframalpha appid"] + credentials["radarr_key"] = data["radarr api key"] + credentials["sonarr_key"] = data["sonarr api key"] + + return credentials + +def long_strings(): + """ + Get the data from gwendolyn/resources/long_strings.json. + + *Returns* + --------- + data: dict + The long strings and their keys. + """ + with open("gwendolyn/resources/long_strings.json", "r") 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. + """ + with open("gwendolyn/resources/slash_parameters.json", "r") 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") 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") 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") + + with open("gwendolyn/resources/starting_files.json") 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 diff --git a/main.py b/main.py new file mode 100644 index 0000000..ba3dee2 --- /dev/null +++ b/main.py @@ -0,0 +1,30 @@ +"""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)}"]) + +if __name__ == "__main__": + main() diff --git a/project-guidelines.md b/project-guidelines.md index 33ef2b4..583932d 100644 --- a/project-guidelines.md +++ b/project-guidelines.md @@ -91,7 +91,7 @@ The `Command` methods in cogs should only exist to perform small tasks or call c ### 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. -+ `resources/` contains the images, lookup databases, fonts etc. that the rest of the code uses. ++ `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. @@ -108,6 +108,6 @@ Things you should know about the logging: + 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 `logThis()` function from `/utils/utilFuncs/`. Always call `bot.log`. +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/resources/errorCodes.txt b/resources/errorCodes.txt deleted file mode 100644 index 9234601..0000000 --- a/resources/errorCodes.txt +++ /dev/null @@ -1,128 +0,0 @@ -000 - Unspecified error -001 - Not a command - -1 - Help -100 - Unspecified error -101 - Couldn't find help.txt -102 - Couldn't find help file for specified command - -2 - Stop -200 - Unspecified error -201 - Unauthorized user - -3 - Simple Commands -310 - Hello error -320 - Map error -330 - Name error -340 - Tavern error -350 - Game error - -4 - Roll -400 - Unspecified error - -5 - Spell -500 - Unspecified error -501 - Spell not in database - -6 - Monster -600 - Unspecified error -601 - Monster name too short -602 - Monster not in database - -7 - Image -700 - Unspecified error -701 - Can't connect to Bing -702 - Error picking camera type/image name - -8 - Movie -800 - Unspecified error -801 - Error in function -802 - Can't find movie on imdb -803 - Can't extract data -804 - Can't pick movie -805 - Embed error - -9 - Star Wars -910 - Unspecified swroll error -911 - Obligation roll fucked up -912 - No character swroll -913 - Didn't include heavy/light in ranged or planetary/space in piloting -914 - Swroll invalid input -920 - Unspecified swd error -921 - Didn't specify amount of players -922 - Invalid input -930 - Unspecified swcrit -931 - Swcrit didn't include a number -940 - Unspecified swchar error -941 - No weapons -942 - Can't add to character sheet -943 - No character swchar -944 - Not on character sheet -945 - Problem overwriting data -946 - Problem removing data -947 - Problem adding data -948 - Problem removing spaces -949 - Wrong data type - -10 - Wiki -1000 - Unspecified error -1001 - Something fucked up -1002 - Can't find page - -11 - Trivia -1100 - Unspecified error -1101 - Incorrect input -1102 - Can't find question -1103 - Not an answer -1104 - No question going on -1105 - User has already answered -1106 - There's already a question goin on in the channel - -12 - Money -1210 - Unspecified balance error -1220 - Unspecified give error -1221 - Conversion error -1222 - Incorrect input -1223a - User has no money -1223b - Not enough money - -13 - Blackjack -1300 - Unspecified error -1310 - Unspecified finishing error -1311 - Error calculating winnings -1312 - Error in calcWinnings function -1320 - Unspecified loop error -1321 - Loop interrupted while waiting -1322 - Error with getHandNumber() -1330 - Unspecified continue error -1331 - Error in testIfStanding() -1340 - Error in drawing blackjack table -1341 - Error in drawHand() - -14 - connect four -1400 - Unspecified error -1401 - Error deleting old image -1410 - Unspecified parsing error -1420 - Unspecified AI error - -15 - Hex -1500 - Unspecified -1501 - Error deleting old image -1510 - Unspecified parsing error -1520 - Unspecified AI error -1531 - Invalid position -1532 - Cannot place on existing piece -1533 - Position out of bounds -1541 - Error loading board-image -1542 - Error swapping - -17 - Hangman -1700 - Unspecified error -1701 - Error parsing command -1710 - Error in drawImage() -1711 - Error in drawGallows() -1712 - Error in drawMan() -1713 - Error in drawLetterLines() -1714 - Error in drawMisses() -1720 - Unspecified hangmanGuess() error -1730 - Unspecified hangmanStart() error diff --git a/resources/games/oldImages/blackjack740652054388932682 b/resources/games/oldImages/blackjack740652054388932682 deleted file mode 100644 index a5f44f7..0000000 --- a/resources/games/oldImages/blackjack740652054388932682 +++ /dev/null @@ -1 +0,0 @@ -854063181868695593 \ No newline at end of file diff --git a/resources/games/oldImages/hangman740652054388932682 b/resources/games/oldImages/hangman740652054388932682 deleted file mode 100644 index 5372483..0000000 --- a/resources/games/oldImages/hangman740652054388932682 +++ /dev/null @@ -1,2 +0,0 @@ -854064833909489734 -854064835040641044 \ No newline at end of file diff --git a/resources/games/oldImages/hex740652054388932682 b/resources/games/oldImages/hex740652054388932682 deleted file mode 100644 index 4147771..0000000 --- a/resources/games/oldImages/hex740652054388932682 +++ /dev/null @@ -1 +0,0 @@ -854064794356023346 \ No newline at end of file diff --git a/resources/help/help-addshow.txt b/resources/help/help-addshow.txt deleted file mode 100644 index 9d35d5c..0000000 --- a/resources/help/help-addshow.txt +++ /dev/null @@ -1 +0,0 @@ -Du kan søge efter et show ved at skrive `/addshow [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/utils/__init__.py b/utils/__init__.py deleted file mode 100644 index b6ad44b..0000000 --- a/utils/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -"""A collections of utilities used by Gwendolyn and her functions.""" - -__all__ = ["Options", "Credentials", "DatabaseFuncs", "EventHandler", - "ErrorHandler", "getParams", "logThis", "cap", "makeFiles", - "replaceMultiple", "emojiToCommand"] - -from .helper_classes import Options, Credentials, DatabaseFuncs -from .event_handlers import EventHandler, ErrorHandler -from .util_functions import (getParams, logThis, cap, makeFiles, - replaceMultiple, emojiToCommand, long_strings) diff --git a/utils/helper_classes.py b/utils/helper_classes.py deleted file mode 100644 index ce86b1f..0000000 --- a/utils/helper_classes.py +++ /dev/null @@ -1,330 +0,0 @@ -""" -Contains classes used for utilities. - -*Functions* ------------ - Sanitize(data: str, lowerCaseValue: bool = false) -> dict - -*Classes* ---------- - Options() - Credentials() - DatabaseFuncs() -""" -import re # Used in getID -import git # Used to pull when stopping -import os # Used to test if files exist -import json # Used to read the data about addmovie/addshow -import time # Used to test how long it's been since commands were synced -import discord # Used for type hints - - -def sanitize(data: str, lowerCaseValue: 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. - lowerCaseValue: 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: - lineValues = line.split(":") - lineValues[0] = lineValues[0].lower() - lineValues[1] = lineValues[1].replace(" ", "") - if lowerCaseValue: - lineValues[1] = lineValues[1].lower() - - if lineValues[0] in ["testing guild ids", "admins"]: - lineValues[1] = lineValues[1].split(",") - if all(i.isnumeric() for i in lineValues[1]): - lineValues[1] = [int(i) for i in lineValues[1]] - - if any(i == lineValues[1] for i in ["true", "false"]): - lineValues[1] = (lineValues[1] == "true") - - dct[lineValues[0]] = lineValues[1] - - return dct - - -class Options(): - """Contains the options for the bot.""" - - def __init__(self): - """Initialize the options.""" - with open("options.txt", "r") as f: - data = sanitize(f.read(), True) - - self.testing = data["testing"] - self.guildIds = data["testing guild ids"] - self.admins = data["admins"] - - -class Credentials(): - """Contains the credentials for the bot and apis.""" - - def __init__(self): - """Initialize the credentials.""" - with open("credentials.txt", "r") as f: - data = sanitize(f.read()) - - self.token = data["bot token"] - self.finnhub_key = data["finnhub api key"] - self.wordnikKey = data["wordnik api key"] - self.mongoDBUser = data["mongodb user"] - self.mongoDBPassword = data["mongodb password"] - self.wolfKey = data["wolframalpha appid"] - self.radarrKey = data["radarr api key"] - self.sonarrKey = data["sonarr api key"] - - -class DatabaseFuncs(): - """ - Manages database functions. - - *Methods* - --------- - getName(userID: str) -> str - getID(userName: str) -> str - deleteGame(gameType: str, channel: str) - wipeGames() - connect_fourReactionTest(message: discord.Message, - user: discord.User) -> bool - hangmanReactionTest(message: discord.Message, - user: discord.User) -> bool - BedreNetflixReactionTest(message: discord.Message, - user: discord.User) -> bool, bool, - list - syncCommands() - """ - - def __init__(self, bot): - """Initialize the class.""" - self.bot = bot - - def getName(self, userID: str): - """ - Get the name of a user you have the # id of. - - *Parameters: - ------------ - userID: str - The id of the user you want the name of. The format is - "#" + str(discord.User.id) - - *Returns* - --------- - userName: str - The name of the user. If the user couldn't be found, - returns the userID. - """ - user = self.bot.database["users"].find_one({"_id": userID}) - - if userID == f"#{self.bot.user.id}": - return "Gwendolyn" - elif user is not None: - return user["user name"] - else: - self.bot.log(f"Couldn't find user {userID}") - return userID - - def getID(self, userName: str): - """ - Get the id of a user you have the username of. - - *Parameters: - ------------ - userName: str - The name of the user you want the id of. - - *Returns* - --------- - userID: str - The id of the user in the format "#" + - str(discord.User.id). If the user couldn't be found, - returns the userName. - """ - userSearch = {"user name": re.compile(userName, re.IGNORECASE)} - user = self.bot.database["users"].find_one(userSearch) - - if user is not None: - return user["_id"] - else: - self.bot.log("Couldn't find user "+userName) - return None - - def deleteGame(self, gameType: str, channel: str): - """ - Remove a game from the database. - - *Parameters* - ------------ - gameType: str - The name of the collection the game is in, like - "hangman games", "blackjack games" etc. - channel: str - The channel id of the channel the game is on as a - string. - """ - self.bot.database[gameType].delete_one({"_id": channel}) - - def wipeGames(self): - """Delete all running games and pull from git.""" - self.bot.database["trivia questions"].delete_many({}) - self.bot.database["blackjack games"].delete_many({}) - self.bot.database["connect 4 games"].delete_many({}) - self.bot.database["hangman games"].delete_many({}) - self.bot.database["hex games"].delete_many({}) - - if not self.bot.options.testing: - g = git.cmd.Git("") - g.pull() - - def connect_fourReactionTest(self, message: discord.Message, - user: discord.User): - """ - Test if the given message is the current connect four game. - - Also tests if the given user is the one who's turn it is. - - *Parameters* - ------------ - message: discord.Message - The message to test. - user: discord.User - The user to test. - *Returns* - --------- - : bool - Whether the given message is the current connect four - game and if the user who reacted is the user who's turn - it is. - """ - channel = message.channel - channelSearch = {"_id": str(channel.id)} - game = self.bot.database["connect 4 games"].find_one(channelSearch) - - filePath = f"resources/games/old_images/connect_four{channel.id}" - if os.path.isfile(filePath): - with open(filePath, "r") as f: - oldImage = int(f.read()) - else: - oldImage = 0 - - if message.id == oldImage: - self.bot.log("They reacted to the connect_four game") - turn = game["turn"] - if user == game["players"][turn]: - return True - else: - self.bot.log("It wasn't their turn") - return False - else: - return False - - def hangmanReactionTest(self, message: discord.Message, - user: discord.User): - """ - Test if the given message is the current hangman game. - - Also tests if the given user is the one who's playing hangman. - - *Parameters* - ------------ - message: discord.Message - The message to test. - user: discord.User - The user to test. - *Returns* - --------- - : bool - Whether the given message is the current hangman game - and if the user who reacted is the user who's playing - hangman. - """ - channel = message.channel - filePath = f"resources/games/old_images/hangman{channel.id}" - if os.path.isfile(filePath): - with open(filePath, "r") as f: - oldMessages = f.read().splitlines() - else: - return False - gameMessage = False - - for oldMessage in oldMessages: - oldMessageID = int(oldMessage) - if message.id == oldMessageID: - database = self.bot.database["hangman games"] - channelSearch = {"_id": str(channel.id)} - game = database.find_one(channelSearch) - if user == game["player"]: - gameMessage = True - - break - - return gameMessage - - def bedreNetflixReactionTest(self, message: discord.Message): - """ - Test if the given message is the response to a plex request. - - *Parameters* - ------------ - message: discord.Message - The message to test. - - *Returns* - --------- - : bool - Whether the message is the response to a plex request. - : bool - Whether it was a movie request (false for a show - request) - : list - A list of ids or names of the shows or movies that - Gwendolyn presented after the request. - """ - channel = message.channel - filePath = f"resources/bedreNetflix/oldMessage{str(channel.id)}" - if os.path.isfile(filePath): - with open(filePath, "r") as f: - data = json.load(f) - else: - return False, None, None - - if data["messageID"] == message.id: - if "imdbIds" in data: - return True, True, data["imdbIds"] - else: - return True, False, data["imdbNames"] - else: - return False, None, None - - async def syncCommands(self): - """Sync the slash commands with the discord API.""" - collection = self.bot.database["last synced"] - lastSynced = collection.find_one() - now = time.time() - if lastSynced["last synced"] < now - 86400: - slashCommandList = await self.bot.slash.to_dict() - self.bot.log(f"Updating commands: {slashCommandList}") - await self.bot.slash.sync_all_commands() - idNumber = lastSynced["_id"] - queryFilter = {"_id": idNumber} - update = {"$set": {"last synced": now}} - collection.update_one(queryFilter, update) diff --git a/utils/util_functions.py b/utils/util_functions.py deleted file mode 100644 index af27573..0000000 --- a/utils/util_functions.py +++ /dev/null @@ -1,250 +0,0 @@ -""" -Contains utility functions used by parts of the bot. - -*Functions* ------------ - long_strings() -> dict - getParams() -> dict - logThis(messages: Union[str, list], channel: str = "", - level: int = 20) - cap(s: str) -> str - makeFiles() - replaceMultiple(mainString: str, toBeReplaced: list, - newString: str) -> str - emojiToCommand(emoji: str) -> str -""" -import json # Used by longString(), getParams() and makeFiles() -import logging # Used for logging -import os # Used by makeFiles() to check if files exist -import sys # Used to specify printing for logging -import imdb # Used to disable logging for the module -from .helper_classes import Options # Used by getParams() - - -# 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") # Basically disables imdbpy -# logging, since it's printed to the terminal. - - -def long_strings(): - """ - Get the data from resources/long_strings.json. - - *Returns* - --------- - data: dict - The long strings and their keys. - """ - with open("resources/long_strings.json", "r") as f: - data = json.load(f) - - return data - - -def getParams(): - """ - Get the slash command parameters. - - *Returns* - --------- - params: dict - The parameters for every slash command. - """ - with open("resources/slashParameters.json", "r") as f: - params = json.load(f) - - options = Options() - - if options.testing: - for p in params: - params[p]["guild_ids"] = options.guildIds - - return params - - -def logThis(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 type(messages) is str: - messages = [messages] - - printMessage = messages[0] - - for x, msg in enumerate(messages): - if channel != "": - messages[x] = f"{msg} - ({channel})" # Adds channel to log - # messages - - if len(messages) > 1: # Tells user to check the log if there are - # more messages there - printMessage += " (details in log)" - - if level >= 25: - printer.log(level, printMessage) - - for log_message in messages: - logger.log(level, log_message) - - -def cap(s: str): - """ - Capitalize a string like a movie title. - - That means "of" and "the" are not capitalized. - - *Parameters* - ------------ - s: str - The string to capitalized. - - *Returns* - --------- - res: str - The capitalized string. - """ - no_caps_list = ["of", "the"] - word_number = 0 - lst = s.split() - res = '' - for word in lst: - word_number += 1 - if word not in no_caps_list or word_number == 1: - word = word.capitalize() - res += word+" " - res = res[:-1] - return res - - -def makeFiles(): - """Create all the files and directories needed by Gwendolyn.""" - def makeJsonFile(path, content): - """Create json file if it doesn't exist.""" - if not os.path.isfile(path): - logThis(path.split("/")[-1]+" didn't exist. Making it now.") - with open(path, "w") as f: - json.dump(content, f, indent=4) - - def makeTxtFile(path, content): - """Create txt file if it doesn't exist.""" - if not os.path.isfile(path): - logThis(path.split("/")[-1]+" didn't exist. Making it now.") - with open(path, "w") as f: - f.write(content) - - def directory(path): - """Create directory if it doesn't exist.""" - if not os.path.isdir(path): - os.makedirs(path) - logThis("The "+path.split("/")[-1]+" directory didn't exist") - - with open("resources/startingFiles.json") as f: - data = json.load(f) - - for path, content in data["json"].items(): - makeJsonFile(path, content) - - for path, content in data["txt"].items(): - makeTxtFile(path, content) - - for path in data["folder"]: - directory(path) - - -def replaceMultiple(mainString: str, toBeReplaced: list, newString: str): - """ - Replace multiple substrings in a string with the same substring. - - *Parameters* - ------------ - mainString: str - The string to replace substrings in. - toBeReplaced: list - The substrings to replace. - newString: str - The string to replace the substrings with. - - *Returns* - --------- - mainString: str - The string with the substrings replaced. - """ - # Iterate over the strings to be replaced - for elem in toBeReplaced: - # Check if string is in the main string - if elem in mainString: - # Replace the string - mainString = mainString.replace(elem, newString) - - return mainString - - -def emojiToCommand(emoji: str): - """ - Convert emoji to text. - - *Parameters* - ------------ - emoji: str - The emoji to decipher. - - *Returns* - --------- - : str - The deciphered string. - """ - if emoji == "1️⃣": - return 1 - elif emoji == "2️⃣": - return 2 - elif emoji == "3️⃣": - return 3 - elif emoji == "4️⃣": - return 4 - elif emoji == "5️⃣": - return 5 - elif emoji == "6️⃣": - return 6 - elif emoji == "7️⃣": - return 7 - elif emoji == "🎲": - return "roll" - elif emoji == "❌": - return "none" - elif emoji == "✔️": - return 1 - else: - return ""