Files
Gwendolyn/Gwendolyn.py
NikolajDanger 06b5d881ea 🔀 Merging with master
2021-06-14 21:06:51 +02:00

151 lines
5.1 KiB
Python

"""
Contains the Gwendolyn class, and runs it when run as script.
*Classes*
---------
Gwendolyn(discord.ext.commands.Bot)
"""
import os # Used for loading cogs in Gwendolyn.addCogs
import finnhub # Used to add a finhub client to the bot
import 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 discord # Used for discord.Intents and discord.Status
import discord_slash # Used to initialized SlashCommands object
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, longStrings)
class Gwendolyn(commands.Bot):
"""
A multifunctional Discord bot.
*Methods*
---------
log(messages: Union[str, list], channel: str = "",
level: int = 20)
stop(ctx: discord_slash.context.SlashContext)
defer(ctx: discord_slash.context.SlashContext)
"""
def __init__(self):
"""Initialize the bot."""
intents = discord.Intents.default()
intents.members = True
initParams = {
"command_prefix": " ",
"case_insensitive": True,
"intents": intents,
"status": discord.Status.dnd
}
super().__init__(**initParams)
self._addClientsAndOptions()
self._addUtilClasses()
self._addFunctionContainers()
self._addCogs()
def _addClientsAndOptions(self):
"""Add all the client, option and credentials objects."""
self.longStrings = longStrings()
self.options = Options()
self.credentials = Credentials()
finnhubKey = self.credentials.finnhubKey
self.finnhubClient = finnhub.Client(api_key=finnhubKey)
mongoUser = self.credentials.mongoDBUser
mongoPassword = self.credentials.mongoDBPassword
mongoLink = f"mongodb+srv://{mongoUser}:{mongoPassword}@gwendolyn"
mongoLink += ".qkwfy.mongodb.net/Gwendolyn?retryWrites=true&w=majority"
dataBaseClient = MongoClient(mongoLink)
if self.options.testing:
self.log("Testing mode")
self.database = dataBaseClient["Gwendolyn-Test"]
else:
self.database = dataBaseClient["Gwendolyn"]
def _addUtilClasses(self):
"""Add all the classes used as utility."""
self.databaseFuncs = databaseFuncs(self)
self.eventHandler = EventHandler(self)
self.errorHandler = ErrorHandler(self)
slashParams = {
"sync_commands": True,
"sync_on_cog_reload": True,
"override_type": True
}
self.slash = discord_slash.SlashCommand(self, **slashParams)
def _addFunctionContainers(self):
"""Add all the function containers used for commands."""
self.starWars = StarWars(self)
self.other = Other(self)
self.lookupFuncs = LookupFuncs(self)
self.games = Games(self)
self.money = Money(self)
def _addCogs(self):
"""Load cogs."""
for filename in os.listdir("./cogs"):
if filename.endswith(".py"):
self.load_extension(f"cogs.{filename[:-3]}")
def log(self, messages, channel: str = "", level: int = 20):
"""Log a message. Described in utils/utilFunctions.py."""
logThis(messages, channel, level)
async def stop(self, ctx: discord_slash.context.SlashContext):
"""
Stop the bot, and stop running games.
Only stops the bot if the user in ctx.author is one of the
admins given in options.txt.
*parameters*
------------
ctx: discord_slash.context.SlashContext
The context of the "/stop" slash command.
"""
if f"#{ctx.author.id}" in self.options.admins:
await ctx.send("Pulling git repo and restarting...")
await self.change_presence(status=discord.Status.offline)
self.databaseFuncs.wipeGames()
self.log("Logging out", level=25)
await self.close()
else:
logMessage = f"{ctx.author.display_name} tried to stop me!"
self.log(logMessage, str(ctx.channel_id))
await ctx.send(f"I don't think I will, {ctx.author.display_name}")
async def defer(self, ctx: discord_slash.context.SlashContext):
"""Send a "Gwendolyn is thinking" message to the user."""
try:
await ctx.defer()
except discord_slash.error.AlreadyResponded:
self.log("defer failed")
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:
bot.log(bot.longStrings["Can't log in"])