Browse Source

More clean up, and linting.

main
Nichole Mattera 2 months ago
parent
commit
8215463dc1
7 changed files with 135 additions and 111 deletions
  1. +71
    -64
      Robocop.py
  2. +29
    -19
      cogs/admin.py
  3. +8
    -9
      cogs/basic.py
  4. +11
    -10
      cogs/common.py
  5. +2
    -0
      cogs/links.py
  6. +13
    -9
      cogs/meme.py
  7. +1
    -0
      helpers/checks.py

+ 71
- 64
Robocop.py View File

@@ -1,21 +1,19 @@
import os
import asyncio
import sys
import logging
import logging.handlers
import traceback
import config

import discord
from discord.ext import commands

stdout_handler = logging.StreamHandler(sys.stdout)

log_format = logging.Formatter(
'[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s')
"[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s"
)
stdout_handler.setFormatter(log_format)

log = logging.getLogger('discord')
log = logging.getLogger("discord")
log.setLevel(logging.INFO)
log.addHandler(stdout_handler)

@@ -25,25 +23,27 @@ def get_prefix(bot, message):

return commands.when_mentioned_or(*prefixes)(bot, message)

initial_extensions = ['cogs.common',
'cogs.admin',
'cogs.basic',
'cogs.links',
'cogs.meme']

bot = commands.Bot(command_prefix=get_prefix,
description=config.bot_description, pm_help=True)
initial_extensions = [
"cogs.common",
"cogs.admin",
"cogs.basic",
"cogs.links",
"cogs.meme",
]

bot = commands.Bot(
command_prefix=get_prefix, description=config.bot_description, pm_help=True
)

bot.log = log
bot.loop = asyncio.get_event_loop()
bot.config = config

if __name__ == '__main__':
if __name__ == "__main__":
for extension in initial_extensions:
try:
bot.load_extension(extension)
except Exception as e:
log.error(f'Failed to load extension {extension}.')
log.error(f"Failed to load extension {extension}.")
log.error(traceback.print_exc())


@@ -51,15 +51,16 @@ if __name__ == '__main__':
async def on_ready():
bot.botlog_channel = bot.get_channel(config.botlog_channel)

log.info(f'\nLogged in as: {bot.user.name} - '
f'{bot.user.id}\ndpy version: {discord.__version__}\n')
log.info(
f"\nLogged in as: {bot.user.name} - "
f"{bot.user.id}\ndpy version: {discord.__version__}\n"
)
game_name = f"{config.prefixes[0]}help"

msg = f"{bot.user.name} has started!"
await bot.botlog_channel.send(msg)

activity = discord.Activity(name=game_name,
type=discord.ActivityType.listening)
activity = discord.Activity(name=game_name, type=discord.ActivityType.listening)

await bot.change_presence(activity=activity)

@@ -73,9 +74,11 @@ async def on_error(event_method, *args, **kwargs):
async def on_command_error(ctx, error):
error_text = str(error)

err_msg = f"Error with \"{ctx.message.content}\" from "\
f"\"{ctx.message.author} ({ctx.message.author.id}) "\
f"of type {type(error)}: {error_text}"
err_msg = (
f'Error with "{ctx.message.content}" from '
f'"{ctx.message.author} ({ctx.message.author.id}) '
f"of type {type(error)}: {error_text}"
)

log.error(err_msg)

@@ -86,56 +89,60 @@ async def on_command_error(ctx, error):
if isinstance(error, commands.NoPrivateMessage):
return await ctx.send("This command doesn't work on DMs.")
elif isinstance(error, commands.MissingPermissions):
roles_needed = '\n- '.join(error.missing_perms)
return await ctx.send(f"{ctx.author.mention}: You don't have the right"
" permissions to run this command. You need: "
f"```- {roles_needed}```")
roles_needed = "\n- ".join(error.missing_perms)
return await ctx.send(
f"{ctx.author.mention}: You don't have the right"
" permissions to run this command. You need: "
f"```- {roles_needed}```"
)
elif isinstance(error, commands.BotMissingPermissions):
roles_needed = '\n-'.join(error.missing_perms)
return await ctx.send(f"{ctx.author.mention}: Bot doesn't have "
"the right permissions to run this command. "
"Please add the following roles: "
f"```- {roles_needed}```")
roles_needed = "\n-".join(error.missing_perms)
return await ctx.send(
f"{ctx.author.mention}: Bot doesn't have "
"the right permissions to run this command. "
"Please add the following roles: "
f"```- {roles_needed}```"
)
elif isinstance(error, commands.CommandOnCooldown):
return await ctx.send(f"{ctx.author.mention}: You're being "
"ratelimited. Try in "
f"{error.retry_after:.1f} seconds.")
return await ctx.send(
f"{ctx.author.mention}: You're being "
"ratelimited. Try in "
f"{error.retry_after:.1f} seconds."
)
elif isinstance(error, commands.CheckFailure):
return await ctx.send(f"{ctx.author.mention}: Check failed. "
"You might not have the right permissions "
"to run this command, or you may not be able "
"to run this command in the current channel.")
elif isinstance(error, commands.CommandInvokeError) and\
("Cannot send messages to this user" in error_text):
return await ctx.send(f"{ctx.author.mention}: I can't DM you.\n"
"You might have me blocked or have DMs "
f"blocked globally or for {ctx.guild.name}.\n"
"Please resolve that, then "
"run the command again.")
return await ctx.send(
f"{ctx.author.mention}: Check failed. "
"You might not have the right permissions "
"to run this command, or you may not be able "
"to run this command in the current channel."
)
elif isinstance(error, commands.CommandInvokeError) and (
"Cannot send messages to this user" in error_text
):
return await ctx.send(
f"{ctx.author.mention}: I can't DM you.\n"
"You might have me blocked or have DMs "
f"blocked globally or for {ctx.guild.name}.\n"
"Please resolve that, then "
"run the command again."
)
elif isinstance(error, commands.CommandNotFound):
# Nothing to do when command is not found.
return

help_text = f"Usage of this command is: ```{ctx.prefix}"\
f"{ctx.command.signature}```\nPlease see `{ctx.prefix}help "\
f"{ctx.command.name}` for more info about this command."
help_text = (
f"Usage of this command is: ```{ctx.prefix}"
f"{ctx.command.signature}```\nPlease see `{ctx.prefix}help "
f"{ctx.command.name}` for more info about this command."
)
if isinstance(error, commands.BadArgument):
return await ctx.send(f"{ctx.author.mention}: You gave incorrect "
f"arguments. {help_text}")
return await ctx.send(
f"{ctx.author.mention}: You gave incorrect " f"arguments. {help_text}"
)
elif isinstance(error, commands.MissingRequiredArgument):
return await ctx.send(f"{ctx.author.mention}: You gave incomplete "
f"arguments. {help_text}")


@bot.event
async def on_message(message):
if message.author.bot:
return

if (message.guild) and (message.guild.id not in config.guild_whitelist):
return
return await ctx.send(
f"{ctx.author.mention}: You gave incomplete " f"arguments. {help_text}"
)

ctx = await bot.get_context(message)
await bot.invoke(ctx)

bot.run(config.token, bot=True, reconnect=True)

+ 29
- 19
cogs/admin.py View File

@@ -11,7 +11,7 @@ class Admin(Cog):
self.bot = bot
self.last_eval_result = None
self.previous_eval_code = None
async def cog_load_actions(self, cog_name):
if cog_name == "verification":
verif_channel = self.bot.get_channel(config.welcome_channel)
@@ -19,7 +19,9 @@ class Admin(Cog):

@commands.guild_only()
@commands.check(check_if_bot_manager)
@commands.command(name='exit', aliases=["quit", "bye", "stop", "kill", "restart", "die"])
@commands.command(
name="exit", aliases=["quit", "bye", "stop", "kill", "restart", "die"]
)
async def _exit(self, ctx):
"""Shuts down the bot, bot manager only."""
await ctx.send(":wave: Goodbye!")
@@ -30,22 +32,25 @@ class Admin(Cog):
@commands.command()
async def pull(self, ctx, auto=False):
"""Does a git pull, bot manager only."""
tmp = await ctx.send('Pulling...')
tmp = await ctx.send("Pulling...")
git_output = await self.bot.async_call_shell("git pull")
await tmp.edit(content=f"Pull complete. Output: ```{git_output}```")
if auto:
cogs_to_reload = re.findall(r'cogs/([a-z_]*).py[ ]*\|', git_output)
cogs_to_reload = re.findall(r"cogs/([a-z_]*).py[ ]*\|", git_output)
for cog in cogs_to_reload:
try:
self.bot.unload_extension("cogs." + cog)
self.bot.load_extension("cogs." + cog)
self.bot.log.info(f'Reloaded ext {cog}')
await ctx.send(f':white_check_mark: `{cog}` '
'successfully reloaded.')
self.bot.log.info(f"Reloaded ext {cog}")
await ctx.send(
f":white_check_mark: `{cog}` " "successfully reloaded."
)
await self.cog_load_actions(cog)
except:
await ctx.send(f':x: Cog reloading failed, traceback: '
f'```\n{traceback.format_exc()}\n```')
await ctx.send(
f":x: Cog reloading failed, traceback: "
f"```\n{traceback.format_exc()}\n```"
)
return

@commands.guild_only()
@@ -57,11 +62,13 @@ class Admin(Cog):
self.bot.load_extension("cogs." + ext)
await self.cog_load_actions(ext)
except:
await ctx.send(f':x: Cog loading failed, traceback: '
f'```\n{traceback.format_exc()}\n```')
await ctx.send(
f":x: Cog loading failed, traceback: "
f"```\n{traceback.format_exc()}\n```"
)
return
self.bot.log.info(f'Loaded ext {ext}')
await ctx.send(f':white_check_mark: `{ext}` successfully loaded.')
self.bot.log.info(f"Loaded ext {ext}")
await ctx.send(f":white_check_mark: `{ext}` successfully loaded.")

@commands.guild_only()
@commands.check(check_if_bot_manager)
@@ -69,8 +76,8 @@ class Admin(Cog):
async def unload(self, ctx, ext: str):
"""Unloads a cog, bot manager only."""
self.bot.unload_extension("cogs." + ext)
self.bot.log.info(f'Unloaded ext {ext}')
await ctx.send(f':white_check_mark: `{ext}` successfully unloaded.')
self.bot.log.info(f"Unloaded ext {ext}")
await ctx.send(f":white_check_mark: `{ext}` successfully unloaded.")

@commands.check(check_if_bot_manager)
@commands.command()
@@ -86,11 +93,14 @@ class Admin(Cog):
self.bot.load_extension("cogs." + ext)
await self.cog_load_actions(ext)
except:
await ctx.send(f':x: Cog reloading failed, traceback: '
f'```\n{traceback.format_exc()}\n```')
await ctx.send(
f":x: Cog reloading failed, traceback: "
f"```\n{traceback.format_exc()}\n```"
)
return
self.bot.log.info(f'Reloaded ext {ext}')
await ctx.send(f':white_check_mark: `{ext}` successfully reloaded.')
self.bot.log.info(f"Reloaded ext {ext}")
await ctx.send(f":white_check_mark: `{ext}` successfully reloaded.")


def setup(bot):
bot.add_cog(Admin(bot))

+ 8
- 9
cogs/basic.py View File

@@ -1,35 +1,34 @@
import time
import config
import discord
from discord.ext import commands
from discord.ext.commands import Cog


class Basic(Cog):
def __init__(self, bot):
self.bot = bot
@commands.guild_only()
@commands.command()
async def membercount(self, ctx):
"""Prints the member count of the server."""
await ctx.send(f"{ctx.guild.name} has "
f"{ctx.guild.member_count} members!")
await ctx.send(f"{ctx.guild.name} has " f"{ctx.guild.member_count} members!")

@commands.command(aliases=['p'])
@commands.command(aliases=["p"])
async def ping(self, ctx):
"""Shows ping values to discord.

RTT = Round-trip time, time taken to send a message to discord
GW = Gateway Ping"""
before = time.monotonic()
tmp = await ctx.send('Calculating ping...')
tmp = await ctx.send("Calculating ping...")
after = time.monotonic()
rtt_ms = (after - before) * 1000
gw_ms = self.bot.latency * 1000

message_text = f":ping_pong:\n"\
f"rtt: `{rtt_ms:.1f}ms`\n"\
f"gw: `{gw_ms:.1f}ms`"
message_text = (
f":ping_pong:\n" f"rtt: `{rtt_ms:.1f}ms`\n" f"gw: `{gw_ms:.1f}ms`"
)
self.bot.log.info(message_text)
await tmp.edit(content=message_text)



+ 11
- 10
cogs/common.py View File

@@ -1,6 +1,7 @@
import asyncio
from discord.ext.commands import Cog


class Common(Cog):
def __init__(self, bot):
self.bot = bot
@@ -10,22 +11,23 @@ class Common(Cog):

def escape_message(self, text: str):
"""Escapes unfun stuff from messages."""
return str(text).replace("@", "@ ").replace("<#", "# ")

async def async_call_shell(self, shell_command: str,
inc_stdout=True, inc_stderr=True):
async def async_call_shell(
self, shell_command: str, inc_stdout=True, inc_stderr=True
):
pipe = asyncio.subprocess.PIPE
proc = await asyncio.create_subprocess_shell(str(shell_command),
stdout=pipe,
stderr=pipe)
proc = await asyncio.create_subprocess_shell(
str(shell_command), stdout=pipe, stderr=pipe
)

if not (inc_stdout or inc_stderr):
return "??? you set both stdout and stderr to False????"

proc_result = await proc.communicate()
stdout_str = proc_result[0].decode('utf-8').strip()
stderr_str = proc_result[1].decode('utf-8').strip()
stdout_str = proc_result[0].decode("utf-8").strip()
stderr_str = proc_result[1].decode("utf-8").strip()

if inc_stdout and not inc_stderr:
return stdout_str
@@ -33,8 +35,7 @@ class Common(Cog):
return stderr_str

if stdout_str and stderr_str:
return f"stdout:\n\n{stdout_str}\n\n"\
f"======\n\nstderr:\n\n{stderr_str}"
return f"stdout:\n\n{stdout_str}\n\n" f"======\n\nstderr:\n\n{stderr_str}"
elif stdout_str:
return f"stdout:\n\n{stdout_str}"
elif stderr_str:


+ 2
- 0
cogs/links.py View File

@@ -3,6 +3,7 @@ import config
from discord.ext import commands
from discord.ext.commands import Cog


class Links(Cog):
"""
Commands for easily linking to stuff.
@@ -21,5 +22,6 @@ class Links(Cog):
"""Link to the Dominic Botoretto source code."""
await ctx.send(config.source_url)


def setup(bot):
bot.add_cog(Links(bot))

+ 13
- 9
cogs/meme.py View File

@@ -18,11 +18,13 @@ class Meme(Cog):
async def btwiuse(self, ctx):
"""BTW I use Arch."""
uname = platform.uname()
await ctx.send(f"BTW I use {platform.python_implementation()} "
f"{platform.python_version()} on {uname.system} "
f"{uname.release}")
@commands.command(aliases=['family'])
await ctx.send(
f"BTW I use {platform.python_implementation()} "
f"{platform.python_version()} on {uname.system} "
f"{uname.release}"
)

@commands.command(aliases=["family"])
async def quote(self, ctx):
"""Get a wise quote."""
quotes = [
@@ -51,7 +53,7 @@ class Meme(Cog):
"You make a deal, you got to live up to it.",
"Keep your car. Your respect is good enough for me.",
"The first time I saw my son he was behind bulletproof glass. I couldn't hold him. It was the worst pain I ever felt.",
"This is the cuban spirit."
"This is the cuban spirit.",
]
await ctx.send(random.choice(quotes))

@@ -80,10 +82,12 @@ class Meme(Cog):
async def clap(self, ctx, *, message: str):
"""Surrounds each word with clap emojis for emphasis."""

words = message.split(' ')
words = message.split(" ")

await ctx.message.delete()
await ctx.send(f"**{ctx.author.name}** {' '.join(map(lambda w: '๐Ÿ‘ ' + w, words))} ๐Ÿ‘")
await ctx.send(
f"**{ctx.author.name}** {' '.join(map(lambda w: '๐Ÿ‘ ' + w, words))} ๐Ÿ‘"
)

@commands.command(aliases=["owoify"])
async def uwuify(self, ctx, *, message: str):
@@ -117,7 +121,7 @@ class Meme(Cog):

await ctx.message.delete()
await ctx.send(f"**{ctx.author.name}** {message}")

def setup(bot):
bot.add_cog(Meme(bot))

+ 1
- 0
helpers/checks.py View File

@@ -1,5 +1,6 @@
import config


def check_if_bot_manager(ctx):
if not ctx.guild:
return False


Loadingโ€ฆ
Cancel
Save