Browse Source

moved log to util, and all of the core cog parts into the core.py file. All to be loaded up as one core into the bot.

tags/v2.0.0
Roxie Gibson 5 years ago
parent
commit
115149f0d7
9 changed files with 239 additions and 299 deletions
  1. +0
    -7
      readthedocs.yml
  2. +1
    -7
      roxbot.py
  3. +9
    -10
      roxbot/__init__.py
  4. +2
    -1
      roxbot/cogs/ags.py
  5. +197
    -4
      roxbot/core.py
  6. +0
    -139
      roxbot/err_handle.py
  7. +0
    -128
      roxbot/logging.py
  8. +3
    -3
      roxbot/settings/preferences_example.ini
  9. +27
    -0
      roxbot/utils.py

+ 0
- 7
readthedocs.yml View File

@@ -1,7 +0,0 @@
build:
image: latest

python:
version: 3.6

requirements_file: requirements.txt

+ 1
- 7
roxbot.py View File

@@ -40,7 +40,7 @@ from roxbot import guild_settings as gs
# Sets up Logging
logger = logging.getLogger('discord')
logger.setLevel(logging.INFO)
handler = logging.FileHandler(filename='roxbot.log', encoding='utf-8', mode='w')
handler = logging.FileHandler(filename='roxbot.log', encoding='utf-8', mode='a')
handler.setFormatter(logging.Formatter('%(asctime)s:%(levelname)s:%(name)s: %(message)s'))
logger.addHandler(handler)

@@ -61,12 +61,6 @@ async def on_ready():
bot.load_extension("roxbot.core")
print("core.py Loaded")

bot.load_extension("roxbot.err_handle")
print("err_handle.py Loaded")

bot.load_extension("roxbot.logging")
print("logging.py Loaded")

print("")
print("Discord.py version: " + discord.__version__)
print("Client logged in\n")

+ 9
- 10
roxbot/__init__.py View File

@@ -24,24 +24,23 @@


from roxbot import checks, http, guild_settings, converters, utils, roxbotfacts

from roxbot.exceptions import *
from roxbot.enums import EmbedColours
from roxbot.logging import log
from roxbot.utils import blacklisted
from roxbot.utils import blacklisted, log

import configparser

dev_mode = False

settings = configparser.ConfigParser()
settings.read("roxbot/settings/preferences.ini")
config = configparser.ConfigParser()
config.read("roxbot/settings/preferences.ini")

command_prefix = settings["Roxbot"]["Command_Prefix"]
owner = int(settings["Roxbot"]["OwnerID"])
command_prefix = config["Roxbot"]["Command_Prefix"]
owner = int(config["Roxbot"]["OwnerID"])

token = settings["Tokens"]["Discord"]
tat_token = settings["Tokens"]["Tatsumaki"]
imgur_token = settings["Tokens"]["Imgur"]
token = config["Tokens"]["Discord"]
imgur_token = config["Tokens"]["Imgur"]


__description__ = """RoxBot, A Discord Bot made by a filthy Mercy Main. Built with love (and discord.py) by Roxxers#7443.
@@ -51,7 +50,7 @@ __description__ = """RoxBot, A Discord Bot made by a filthy Mercy Main. Built wi
[Found a bug or need to report an issue? Report it here](https://gitlab.roxxers.xyz/roxxers/roxbot/issues/new?issue)
[Say Thanks](https://saythanks.io/to/Roxxers)"""
__author__ = "Roxanne Gibson"
__version__ = "2.0.0a"
__version__ = "2.0.0"

datetime_formatting = "{:%a %Y/%m/%d %H:%M:%S} UTC"


+ 2
- 1
roxbot/cogs/ags.py View File

@@ -36,6 +36,7 @@ ags_id = 393764974444675073
selfieperms = 394939389823811584
nsfwimageperms = 394941004043649036
newbie = 450042170112475136
tat_token = roxbot.config["Tokens"]["Tatsumaki"]


def is_ags():
@@ -45,7 +46,7 @@ def is_ags():
async def tatsumaki_api_call(member, guild):
base = "https://api.tatsumaki.xyz/"
url = base + "guilds/" + str(guild.id) + "/members/" + str(member.id) + "/stats"
return await roxbot.http.api_request(url, headers={"Authorization": roxbot.tat_token})
return await roxbot.http.api_request(url, headers={"Authorization": tat_token})


class AsortedGenderSounds:

+ 197
- 4
roxbot/core.py View File

@@ -24,8 +24,12 @@


import os
import string
import typing
import logging
import asyncio
import datetime
import youtube_dl

import roxbot

@@ -33,21 +37,206 @@ import discord
from discord.ext import commands


class Core:
"""Cog for commands that change the bot account and bot running."""
class ErrorHandling:

COMMANDNOTFOUND = "That Command doesn't exist."
COMMANDONCOOLDOWN = "This command is on cooldown, please wait {:.2f} seconds before trying again."
CHECKFAILURE = "You do not have permission to do this. Back off, thot!"
TOOMANYARGS = "Too many arguments given."
DISABLEDCOMMAND = "This command is disabled."
COGSETTINGDISABLED = "{} is disabled on this server."
NODMS = "This command cannot be used in private messages."

YTDLDOWNLOADERROR = "Video could not be downloaded: {}"

def __init__(self, bot_client):
self.bot = bot_client
self.dev = roxbot.dev_mode

async def on_command_error(self, ctx, error):
if self.dev:
raise error
else:
# UserError warning section
user_errors = (commands.MissingRequiredArgument, commands.BadArgument,
commands.TooManyArguments, roxbot.UserError)

if isinstance(error, user_errors):
embed = discord.Embed(colour=roxbot.EmbedColours.orange)
if isinstance(error, (commands.MissingRequiredArgument, commands.BadArgument, roxbot.UserError)):
embed.description = error.args[0]
elif isinstance(error, commands.TooManyArguments):
embed.description = self.TOOMANYARGS
return await ctx.send(embed=embed)

# ActualErrorHandling
embed = discord.Embed()
if isinstance(error, commands.NoPrivateMessage):
embed.description = self.NODMS
logging.INFO(embed.description)
elif isinstance(error, commands.DisabledCommand):
embed.description = self.DISABLEDCOMMAND
logging.INFO(embed.description)
elif isinstance(error, roxbot.CogSettingDisabled):
embed.description = self.COGSETTINGDISABLED.format(error.args[0])
logging.INFO(embed.description)
elif isinstance(error, commands.CommandNotFound):
try:
# Sadly this is the only part that makes a cog not modular. I have tried my best though to make it usable without the cog.
cc = roxbot.guild_settings.get(ctx.guild)["custom_commands"]
is_custom_command = bool(ctx.invoked_with in cc["1"] or ctx.invoked_with in cc["2"])
is_emoticon_face = bool(any(x in string.punctuation for x in ctx.message.content.strip(ctx.prefix)[0]))
is_too_short = bool(len(ctx.message.content) <= 2)
if is_custom_command or is_emoticon_face or is_too_short:
embed = None
else:
embed.description = self.COMMANDNOTFOUND
logging.INFO(embed.description)
except (KeyError, AttributeError):
# KeyError for cog missing, AttributeError if a command invoked via DM
embed.description = self.COMMANDNOTFOUND
logging.INFO(embed.description)
elif isinstance(error, commands.BotMissingPermissions):
embed.description = "{}".format(error.args[0].replace("Bot", "Roxbot"))
logging.INFO(embed.description)
elif isinstance(error, commands.MissingPermissions):
embed.description = "{}".format(error.args[0])
logging.INFO(embed.description)
elif isinstance(error, commands.CommandOnCooldown):
embed.description = self.COMMANDONCOOLDOWN.format(error.retry_after)
logging.INFO(embed.description)
elif isinstance(error, (commands.CheckFailure, commands.NotOwner)):
embed.description = self.CHECKFAILURE
logging.INFO(embed.description)

elif isinstance(error, commands.CommandInvokeError):
# YOUTUBE_DL ERROR HANDLING
if isinstance(error.original, youtube_dl.utils.GeoRestrictedError):
embed.description = self.YTDLDOWNLOADERROR.format("Video is GeoRestricted.")
logging.INFO(embed.description)
elif isinstance(error.original, youtube_dl.utils.DownloadError):
embed.description = self.YTDLDOWNLOADERROR.format(error.original.exc_info[1])
logging.INFO(embed.description)

# Final catches for errors undocumented.
else:
logging.ERROR(str(error))
embed = discord.Embed(title='Command Error', colour=roxbot.EmbedColours.dark_red)
embed.description = str(error)
embed.add_field(name='User', value=ctx.author)
embed.add_field(name='Message', value=ctx.message.content)
embed.timestamp = datetime.datetime.utcnow()
elif isinstance(error, commands.CommandError):
embed.description = "Error: {}".format(error.args[0])
logging.ERROR(embed.description)
else:
logging.ERROR(str(error))

if embed:
embed.colour = roxbot.EmbedColours.dark_red
await ctx.send(embed=embed)


class Logging:
"""Cog that deals with internal logging with Roxbot that is posted in Discord."""
def __init__(self, bot_client):
self.bot = bot_client

self.settings = {
"logging": {
"enabled": 0,
"convert": {"enabled": "bool", "channel": "channel"},
"channel": 0
}
}

self.bot.add_listener(self.cleanup_logging_settings, "on_guild_channel_delete")
self.bot.add_listener(self.log_member_join, "on_member_join")
self.bot.add_listener(self.log_member_remove, "on_member_remove")

@staticmethod
async def cleanup_logging_settings(channel):
"""Cleans up settings on removal of stored IDs."""
settings = roxbot.guild_settings.get(channel.guild)
r_logging = settings["logging"]
if channel.id == r_logging["channel"]:
r_logging["channel"] = 0
settings.update(r_logging, "logging")

async def log_member_join(self, member):
r_logging = roxbot.guild_settings.get(member.guild)["logging"]
if r_logging["enabled"]:
channel = self.bot.get_channel(r_logging["channel"])
embed = discord.Embed(title="{} joined the server".format(member), colour=roxbot.EmbedColours.pink)
embed.add_field(name="ID", value=member.id)
embed.add_field(name="Mention", value=member.mention)
embed.add_field(name="Date Account Created", value=roxbot.datetime_formatting.format(member.created_at))
embed.add_field(name="Date Joined", value=roxbot.datetime_formatting.format(member.joined_at))
embed.set_thumbnail(url=member.avatar_url)
return await channel.send(embed=embed)

async def log_member_remove(self, member):
# TODO: Add some way of detecting whether a user left/was kicked or was banned.
r_logging = roxbot.guild_settings.get(member.guild)["logging"]
if r_logging["enabled"]:
channel = self.bot.get_channel(r_logging["channel"])
embed = discord.Embed(description="{} left the server".format(member), colour=roxbot.EmbedColours.pink)
return await channel.send(embed=embed)

@commands.has_permissions(manage_channels=True)
@commands.guild_only()
@commands.command(aliases=["log"])
async def logging(self, ctx, setting, *, channel: typing.Optional[discord.TextChannel] = None):
"""Edits the logging settings.

Options:
enable/disable: Enable/disables logging.
channel: sets the channel.
"""

setting = setting.lower()
settings = roxbot.guild_settings.get(ctx.guild)

if setting == "enable":
settings["logging"]["enabled"] = 1
await ctx.send("'logging' was enabled!")
elif setting == "disable":
settings["logging"]["enabled"] = 0
await ctx.send("'logging' was disabled :cry:")
elif setting == "channel":
if not channel:
channel = ctx.channel
settings["logging"]["channel"] = channel.id
await ctx.send("{} has been set as the logging channel!".format(channel.mention))
else:
return await ctx.send("No valid option given.")
return settings.update(settings["logging"], "logging")


class Core(ErrorHandling, Logging):
"""Core bot cog. Includes management commands, logging, error handling, and backups."""
def __init__(self, bot_client):
self.bot = bot_client
super().__init__(self.bot)

# Backup setup
self.backup_task = self.bot.loop.create_task(self.auto_backups())

#############
# Backups #
#############

async def auto_backups(self):
await self.bot.wait_until_ready()
raw_settings = {}
for guild in self.bot.guilds:
raw_settings = {**raw_settings, **roxbot.guild_settings._open_config(guild, os.listdir('roxbot/settings/servers/{}'.format(guild.id)))}
directory = os.listdir('roxbot/settings/servers/{}'.format(guild.id))
raw_settings = {**raw_settings, **roxbot.guild_settings._open_config(guild, directory)}
while not self.bot.is_closed():
current_settings = {}
for guild in self.bot.guilds:
current_settings = {**current_settings, **roxbot.guild_settings._open_config(guild, os.listdir('roxbot/settings/servers/{}'.format(guild.id)))}
directory = os.listdir('roxbot/settings/servers/{}'.format(guild.id))
current_settings = {**current_settings, **roxbot.guild_settings._open_config(guild, directory)}
if raw_settings != current_settings:
raw_settings = current_settings
time = datetime.datetime.now()
@@ -62,6 +251,10 @@ class Core:
roxbot.guild_settings.backup(filename)
return await ctx.send("Settings file backed up as a folder named '{}".format(filename))

############################
# Bot Managment Commands #
############################

@commands.command()
@commands.is_owner()
async def blacklist(self, ctx, option):

+ 0
- 139
roxbot/err_handle.py View File

@@ -1,139 +0,0 @@
# -*- coding: utf-8 -*-

# MIT License
#
# Copyright (c) 2017-2018 Roxanne Gibson
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.


import string
import logging
import datetime
import youtube_dl

import discord
from discord.ext import commands

import roxbot
from roxbot import guild_settings


class ErrHandle:

COMMANDNOTFOUND = "That Command doesn't exist."
COMMANDONCOOLDOWN = "This command is on cooldown, please wait {:.2f} seconds before trying again."
CHECKFAILURE = "You do not have permission to do this. Back off, thot!"
TOOMANYARGS = "Too many arguments given."
DISABLEDCOMMAND = "This command is disabled."
COGSETTINGDISABLED = "{} is disabled on this server."
NODMS = "This command cannot be used in private messages."

YTDLDOWNLOADERROR = "Video could not be downloaded: {}"

def __init__(self, bot_client):
self.bot = bot_client
self.dev = roxbot.dev_mode

async def on_command_error(self, ctx, error):
if self.dev:
raise error
else:
# UserError warning section
user_errors = (commands.MissingRequiredArgument, commands.BadArgument,
commands.TooManyArguments, roxbot.UserError)

if isinstance(error, user_errors):
embed = discord.Embed(colour=roxbot.EmbedColours.orange)
if isinstance(error, (commands.MissingRequiredArgument, commands.BadArgument, roxbot.UserError)):
embed.description = error.args[0]
elif isinstance(error, commands.TooManyArguments):
embed.description = self.TOOMANYARGS
return await ctx.send(embed=embed)

# ActualErrorHandling
embed = discord.Embed()
if isinstance(error, commands.NoPrivateMessage):
embed.description = self.NODMS
logging.INFO(embed.description)
elif isinstance(error, commands.DisabledCommand):
embed.description = self.DISABLEDCOMMAND
logging.INFO(embed.description)
elif isinstance(error, roxbot.CogSettingDisabled):
embed.description = self.COGSETTINGDISABLED.format(error.args[0])
logging.INFO(embed.description)
elif isinstance(error, commands.CommandNotFound):
try:
# Sadly this is the only part that makes a cog not modular. I have tried my best though to make it usable without the cog.
cc = guild_settings.get(ctx.guild)["custom_commands"]
is_custom_command = bool(ctx.invoked_with in cc["1"] or ctx.invoked_with in cc["2"])
is_emoticon_face = bool(any(x in string.punctuation for x in ctx.message.content.strip(ctx.prefix)[0]))
is_too_short = bool(len(ctx.message.content) <= 2)
if is_custom_command or is_emoticon_face or is_too_short:
embed = None
else:
embed.description = self.COMMANDNOTFOUND
logging.INFO(embed.description)
except (KeyError, AttributeError):
# KeyError for cog missing, AttributeError if a command invoked via DM
embed.description = self.COMMANDNOTFOUND
logging.INFO(embed.description)
elif isinstance(error, commands.BotMissingPermissions):
embed.description = "{}".format(error.args[0].replace("Bot", "Roxbot"))
logging.INFO(embed.description)
elif isinstance(error, commands.MissingPermissions):
embed.description = "{}".format(error.args[0])
logging.INFO(embed.description)
elif isinstance(error, commands.CommandOnCooldown):
embed.description = self.COMMANDONCOOLDOWN.format(error.retry_after)
logging.INFO(embed.description)
elif isinstance(error, (commands.CheckFailure, commands.NotOwner)):
embed.description = self.CHECKFAILURE
logging.INFO(embed.description)

elif isinstance(error, commands.CommandInvokeError):
# YOUTUBE_DL ERROR HANDLING
if isinstance(error.original, youtube_dl.utils.GeoRestrictedError):
embed.description = self.YTDLDOWNLOADERROR.format("Video is GeoRestricted.")
logging.INFO(embed.description)
elif isinstance(error.original, youtube_dl.utils.DownloadError):
embed.description = self.YTDLDOWNLOADERROR.format(error.original.exc_info[1])
logging.INFO(embed.description)

# Final catches for errors undocumented.
else:
logging.ERROR(str(error))
embed = discord.Embed(title='Command Error', colour=roxbot.EmbedColours.dark_red)
embed.description = str(error)
embed.add_field(name='User', value=ctx.author)
embed.add_field(name='Message', value=ctx.message.content)
embed.timestamp = datetime.datetime.utcnow()
elif isinstance(error, commands.CommandError):
embed.description = "Error: {}".format(error.args[0])
logging.ERROR(embed.description)
else:
logging.ERROR(str(error))

if embed:
embed.colour = roxbot.EmbedColours.dark_red
await ctx.send(embed=embed)


def setup(bot_client):
bot_client.add_cog(ErrHandle(bot_client))

+ 0
- 128
roxbot/logging.py View File

@@ -1,128 +0,0 @@
# -*- coding: utf-8 -*-

# MIT License
#
# Copyright (c) 2017-2018 Roxanne Gibson
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.


import typing
import discord
from discord.ext import commands

import roxbot
from roxbot import guild_settings


async def log(guild, channel, command_name, **kwargs):
"""Logs activity internally for Roxbot. Will only do anything if the server enables internal logging.

This is mostly used for logging when certain commands are used that can be an issue for admins. Esp when Roxbot outputs
something that could break the rules, then deletes their message.

Params
=======
guild: discord.Guild
Used to check if the guild has logging enabled
channel: discord.TextChannel
command_name: str
kwargs: dict
All kwargs and two other params will be added to the logging embed as fields, allowing you to customise the output

"""
logging = guild_settings.get(guild)["logging"]
if logging["enabled"]:
embed = discord.Embed(title="{} command logging".format(command_name), colour=roxbot.EmbedColours.pink)
for key, value in kwargs.items():
embed.add_field(name=key, value=value)
return await channel.send(embed=embed)


class Logging:
def __init__(self, bot_client):
self.bot = bot_client
self.settings = {
"logging": {
"enabled": 0,
"convert": {"enabled": "bool", "channel": "channel"},
"channel": 0
}
}

async def on_guild_channel_delete(self, channel):
"""Cleans up settings on removal of stored IDs."""
settings = roxbot.guild_settings.get(channel.guild)
logging = settings["logging"]
if channel.id == logging["channel"]:
logging["channel"] = 0
settings.update(logging, "logging")

async def on_member_join(self, member):
logging = guild_settings.get(member.guild)["logging"]
if logging["enabled"]:
channel = self.bot.get_channel(logging["channel"])
embed = discord.Embed(title="{} joined the server".format(member), colour=roxbot.EmbedColours.pink)
embed.add_field(name="ID", value=member.id)
embed.add_field(name="Mention", value=member.mention)
embed.add_field(name="Date Account Created", value=roxbot.datetime_formatting.format(member.created_at))
embed.add_field(name="Date Joined", value=roxbot.datetime_formatting.format(member.joined_at))
embed.set_thumbnail(url=member.avatar_url)
return await channel.send(embed=embed)

async def on_member_remove(self, member):
# TODO: Add some way of detecting whether a user left/was kicked or was banned.
logging = guild_settings.get(member.guild)["logging"]
if logging["enabled"]:
channel = self.bot.get_channel(logging["channel"])
embed = discord.Embed(description="{} left the server".format(member), colour=roxbot.EmbedColours.pink)
return await channel.send(embed=embed)

@commands.has_permissions(manage_channels=True)
@commands.guild_only()
@commands.command(aliases=["log"])
async def logging(self, ctx, setting, *, channel: typing.Optional[discord.TextChannel] = None):
"""Edits the logging settings.

Options:
enable/disable: Enable/disables logging.
channel: sets the channel.
"""

setting = setting.lower()
settings = guild_settings.get(ctx.guild)

if setting == "enable":
settings["logging"]["enabled"] = 1
await ctx.send("'logging' was enabled!")
elif setting == "disable":
settings["logging"]["enabled"] = 0
await ctx.send("'logging' was disabled :cry:")
elif setting == "channel":
if not channel:
channel = ctx.channel
settings["logging"]["channel"] = channel.id
await ctx.send("{} has been set as the logging channel!".format(channel.mention))
else:
return await ctx.send("No valid option given.")
return settings.update(settings["logging"], "logging")


def setup(bot_client):
bot_client.add_cog(Logging(bot_client))

+ 3
- 3
roxbot/settings/preferences_example.ini View File

@@ -15,11 +15,11 @@ Imgur=TokenHere
Tatsumaki=TokenHere

[Backups]
; Settings for the servers.json backups.
; Settings for the server settings backups.
; This is the file that contains all settings for all servers the bot is in.

; Explaintion:
; enabled: Whether or not backups should be enabled. This is heavily recommened to be kept on.
; rate: The amount of time in seconds that the bot will check for changes in the settings file to backup. Default: 300 # 5 Minutes
; rate: The amount of time in minutes that the bot will check for changes in the settings file to backup. Default: 5 minutes
enabled=True
rate=300
rate=5

+ 27
- 0
roxbot/utils.py View File

@@ -27,6 +27,9 @@ import asyncio
import discord
import argparse

from roxbot import guild_settings
from roxbot.enums import EmbedColours


class ArgParser(argparse.ArgumentParser):
"""Create Roxbot's own version of ArgumentParser that doesn't exit the program on error."""
@@ -138,3 +141,27 @@ def blacklisted(user):
if str(user.id)+"\n" == line:
return True
return False


async def log(guild, channel, command_name, **kwargs):
"""Logs activity internally for Roxbot. Will only do anything if the server enables internal logging.

This is mostly used for logging when certain commands are used that can be an issue for admins. Esp when Roxbot outputs
something that could break the rules, then deletes their message.

Params
=======
guild: discord.Guild
Used to check if the guild has logging enabled
channel: discord.TextChannel
command_name: str
kwargs: dict
All kwargs and two other params will be added to the logging embed as fields, allowing you to customise the output

"""
logging = guild_settings.get(guild)["logging"]
if logging["enabled"]:
embed = discord.Embed(title="{} command logging".format(command_name), colour=EmbedColours.pink)
for key, value in kwargs.items():
embed.add_field(name=key, value=value)
return await channel.send(embed=embed)

Loading…
Cancel
Save