📝 Cogs and utils

Improved code style and added comments and docstrings to cogs and utils.
This commit is contained in:
NikolajDanger
2021-04-15 15:16:56 +02:00
parent 35b2446a10
commit 43f26ec383
11 changed files with 725 additions and 255 deletions

View File

@ -1,6 +1,44 @@
import re, git, os, json, time
"""
Contains classes used for utilities.
def sanitize(data : str, options : bool = False):
*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:
@ -8,7 +46,7 @@ def sanitize(data : str, options : bool = False):
lineValues = line.split(":")
lineValues[0] = lineValues[0].lower()
lineValues[1] = lineValues[1].replace(" ", "")
if options:
if lowerCaseValue:
lineValues[1] = lineValues[1].lower()
if lineValues[0] in ["testing guild ids", "admins"]:
@ -23,18 +61,26 @@ def sanitize(data : str, options : bool = False):
return dct
class Options():
"""Contains the options for the bot."""
def __init__(self):
with open("options.txt","r") as f:
"""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):
with open("credentials.txt","r") as f:
"""Initialize the credentials."""
with open("credentials.txt", "r") as f:
data = sanitize(f.read())
self.token = data["bot token"]
@ -46,34 +92,99 @@ class Credentials():
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()
connectFourReactionTest(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):
user = self.bot.database["users"].find_one({"_id":userID})
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 != None:
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):
user = self.bot.database["users"].find_one({"user name":re.compile(userName, re.IGNORECASE)})
def getID(self, userName: str):
"""
Get the id of a user you have the username of.
if user != None:
*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, channel):
self.bot.database[gameType].delete_one({"_id":channel})
def deleteGame(self, gameType: str, channel: str):
"""
Remove a game from the database.
def stopServer(self):
*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({})
@ -84,35 +195,80 @@ class databaseFuncs():
g = git.cmd.Git("")
g.pull()
def connectFourReactionTest(self,channel,message,user):
game = self.bot.database["connect 4 games"].find_one({"_id":str(channel.id)})
def connectFourReactionTest(self, message: discord.Message,
user: discord.User):
"""
Test if the given message is the current connect four game.
with open("resources/games/oldImages/connectFour"+str(channel.id), "r") as f:
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/oldImages/connectFour{channel.id}"
with open(filePath, "r") as f:
oldImage = int(f.read())
if message.id == oldImage:
self.bot.log("They reacted to the connectFour game")
turn = game["turn"]
if user == game["players"][turn]:
return True, turn+1
return True
else:
self.bot.log("It wasn't their turn")
return False, 0
return False
else:
return False, 0
return False
def hangmanReactionTest(self, channel, message, user):
try:
with open("resources/games/oldImages/hangman"+str(channel.id), "r") as f:
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/oldImages/hangman{channel.id}"
if os.path.isfile(filePath):
with open(filePath, "r") as f:
oldMessages = f.read().splitlines()
except:
else:
return False
gameMessage = False
for oldMessage in oldMessages:
oldMessageID = int(oldMessage)
if message.id == oldMessageID:
game = self.bot.database["hangman games"].find_one({"_id":str(channel.id)})
database = self.bot.database["hangman games"]
channelSearch = {"_id": str(channel.id)}
game = database.find_one(channelSearch)
if user == game["player"]:
gameMessage = True
@ -120,9 +276,30 @@ class databaseFuncs():
return gameMessage
def bedreNetflixReactionTest(self, channel, message):
if os.path.isfile(f"resources/bedreNetflix/oldMessage{str(channel.id)}"):
with open("resources/bedreNetflix/oldMessage"+str(channel.id),"r") as f:
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
@ -136,6 +313,7 @@ class databaseFuncs():
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()
@ -144,6 +322,6 @@ class databaseFuncs():
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}}
queryFilter = {"_id": idNumber}
update = {"$set": {"last synced": now}}
collection.update_one(queryFilter, update)