Run black on all examples and require it for CI

This commit is contained in:
Rapptz 2022-03-24 23:39:50 -04:00
parent 968a1f366f
commit 8591cfc5e7
21 changed files with 91 additions and 44 deletions

View File

@ -48,4 +48,4 @@ jobs:
- name: Run black - name: Run black
if: ${{ always() && steps.install-deps.outcome == 'success' }} if: ${{ always() && steps.install-deps.outcome == 'success' }}
run: | run: |
black --check --verbose discord black --check --verbose discord examples

View File

@ -2,6 +2,7 @@ from discord.ext import tasks
import discord import discord
class MyClient(discord.Client): class MyClient(discord.Client):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
@ -27,5 +28,6 @@ class MyClient(discord.Client):
async def before_my_task(self): async def before_my_task(self):
await self.wait_until_ready() # wait until the bot logs in await self.wait_until_ready() # wait until the bot logs in
client = MyClient() client = MyClient()
client.run('token') client.run('token')

View File

@ -1,6 +1,7 @@
import discord import discord
import asyncio import asyncio
class MyClient(discord.Client): class MyClient(discord.Client):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)

View File

@ -15,16 +15,19 @@ intents.message_content = True
bot = commands.Bot(command_prefix='?', description=description, intents=intents) bot = commands.Bot(command_prefix='?', description=description, intents=intents)
@bot.event @bot.event
async def on_ready(): async def on_ready():
print(f'Logged in as {bot.user} (ID: {bot.user.id})') print(f'Logged in as {bot.user} (ID: {bot.user.id})')
print('------') print('------')
@bot.command() @bot.command()
async def add(ctx, left: int, right: int): async def add(ctx, left: int, right: int):
"""Adds two numbers together.""" """Adds two numbers together."""
await ctx.send(left + right) await ctx.send(left + right)
@bot.command() @bot.command()
async def roll(ctx, dice: str): async def roll(ctx, dice: str):
"""Rolls a dice in NdN format.""" """Rolls a dice in NdN format."""
@ -37,22 +40,26 @@ async def roll(ctx, dice: str):
result = ', '.join(str(random.randint(1, limit)) for r in range(rolls)) result = ', '.join(str(random.randint(1, limit)) for r in range(rolls))
await ctx.send(result) await ctx.send(result)
@bot.command(description='For when you wanna settle the score some other way') @bot.command(description='For when you wanna settle the score some other way')
async def choose(ctx, *choices: str): async def choose(ctx, *choices: str):
"""Chooses between multiple choices.""" """Chooses between multiple choices."""
await ctx.send(random.choice(choices)) await ctx.send(random.choice(choices))
@bot.command() @bot.command()
async def repeat(ctx, times: int, content='repeating...'): async def repeat(ctx, times: int, content='repeating...'):
"""Repeats a message multiple times.""" """Repeats a message multiple times."""
for i in range(times): for i in range(times):
await ctx.send(content) await ctx.send(content)
@bot.command() @bot.command()
async def joined(ctx, member: discord.Member): async def joined(ctx, member: discord.Member):
"""Says when a member joined.""" """Says when a member joined."""
await ctx.send(f'{member.name} joined in {member.joined_at}') await ctx.send(f'{member.name} joined in {member.joined_at}')
@bot.group() @bot.group()
async def cool(ctx): async def cool(ctx):
"""Says if a user is cool. """Says if a user is cool.
@ -62,9 +69,11 @@ async def cool(ctx):
if ctx.invoked_subcommand is None: if ctx.invoked_subcommand is None:
await ctx.send(f'No, {ctx.subcommand_passed} is not cool') await ctx.send(f'No, {ctx.subcommand_passed} is not cool')
@cool.command(name='bot') @cool.command(name='bot')
async def _bot(ctx): async def _bot(ctx):
"""Is the bot cool?""" """Is the bot cool?"""
await ctx.send('Yes, the bot is cool.') await ctx.send('Yes, the bot is cool.')
bot.run('token') bot.run('token')

View File

@ -22,11 +22,11 @@ ytdl_format_options = {
'quiet': True, 'quiet': True,
'no_warnings': True, 'no_warnings': True,
'default_search': 'auto', 'default_search': 'auto',
'source_address': '0.0.0.0' # bind to ipv4 since ipv6 addresses cause issues sometimes 'source_address': '0.0.0.0', # bind to ipv4 since ipv6 addresses cause issues sometimes
} }
ffmpeg_options = { ffmpeg_options = {
'options': '-vn' 'options': '-vn',
} }
ytdl = youtube_dl.YoutubeDL(ytdl_format_options) ytdl = youtube_dl.YoutubeDL(ytdl_format_options)
@ -125,21 +125,27 @@ class Music(commands.Cog):
elif ctx.voice_client.is_playing(): elif ctx.voice_client.is_playing():
ctx.voice_client.stop() ctx.voice_client.stop()
intents = discord.Intents.default() intents = discord.Intents.default()
intents.message_content = True intents.message_content = True
bot = commands.Bot(command_prefix=commands.when_mentioned_or("!"), bot = commands.Bot(
command_prefix=commands.when_mentioned_or("!"),
description='Relatively simple music bot example', description='Relatively simple music bot example',
intents=intents) intents=intents,
)
@bot.event @bot.event
async def on_ready(): async def on_ready():
print(f'Logged in as {bot.user} (ID: {bot.user.id})') print(f'Logged in as {bot.user} (ID: {bot.user.id})')
print('------') print('------')
async def main(): async def main():
async with bot: async with bot:
await bot.add_cog(Music(bot)) await bot.add_cog(Music(bot))
await bot.start('token') await bot.start('token')
asyncio.run(main()) asyncio.run(main())

View File

@ -33,6 +33,7 @@ async def userinfo(ctx: commands.Context, user: discord.User):
avatar = user.display_avatar.url avatar = user.display_avatar.url
await ctx.send(f'User found: {user_id} -- {username}\n{avatar}') await ctx.send(f'User found: {user_id} -- {username}\n{avatar}')
@userinfo.error @userinfo.error
async def userinfo_error(ctx: commands.Context, error: commands.CommandError): async def userinfo_error(ctx: commands.Context, error: commands.CommandError):
# if the conversion above fails for any reason, it will raise `commands.BadArgument` # if the conversion above fails for any reason, it will raise `commands.BadArgument`
@ -40,6 +41,7 @@ async def userinfo_error(ctx: commands.Context, error: commands.CommandError):
if isinstance(error, commands.BadArgument): if isinstance(error, commands.BadArgument):
return await ctx.send('Couldn\'t find that user.') return await ctx.send('Couldn\'t find that user.')
# Custom Converter here # Custom Converter here
class ChannelOrMemberConverter(commands.Converter): class ChannelOrMemberConverter(commands.Converter):
async def convert(self, ctx: commands.Context, argument: str): async def convert(self, ctx: commands.Context, argument: str):
@ -75,7 +77,6 @@ class ChannelOrMemberConverter(commands.Converter):
raise commands.BadArgument(f'No Member or TextChannel could be converted from "{argument}"') raise commands.BadArgument(f'No Member or TextChannel could be converted from "{argument}"')
@bot.command() @bot.command()
async def notify(ctx: commands.Context, target: ChannelOrMemberConverter): async def notify(ctx: commands.Context, target: ChannelOrMemberConverter):
# This command signature utilises the custom converter written above # This command signature utilises the custom converter written above
@ -85,6 +86,7 @@ async def notify(ctx: commands.Context, target: ChannelOrMemberConverter):
await target.send(f'Hello, {target.name}!') await target.send(f'Hello, {target.name}!')
@bot.command() @bot.command()
async def ignore(ctx: commands.Context, target: typing.Union[discord.Member, discord.TextChannel]): async def ignore(ctx: commands.Context, target: typing.Union[discord.Member, discord.TextChannel]):
# This command signature utilises the `typing.Union` typehint. # This command signature utilises the `typing.Union` typehint.
@ -101,6 +103,7 @@ async def ignore(ctx: commands.Context, target: typing.Union[discord.Member, dis
elif isinstance(target, discord.TextChannel): # this could be an `else` but for completeness' sake. elif isinstance(target, discord.TextChannel): # this could be an `else` but for completeness' sake.
await ctx.send(f'Channel found: {target.mention}, adding it to the ignore list.') await ctx.send(f'Channel found: {target.mention}, adding it to the ignore list.')
# Built-in type converters. # Built-in type converters.
@bot.command() @bot.command()
async def multiply(ctx: commands.Context, number: int, maybe: bool): async def multiply(ctx: commands.Context, number: int, maybe: bool):
@ -112,4 +115,5 @@ async def multiply(ctx: commands.Context, number: int, maybe: bool):
return await ctx.send(number * 2) return await ctx.send(number * 2)
await ctx.send(number * 5) await ctx.send(number * 5)
bot.run('token') bot.run('token')

View File

@ -31,14 +31,16 @@ class MyBot(commands.Bot):
# use the new MyContext class # use the new MyContext class
return await super().get_context(message, cls=cls) return await super().get_context(message, cls=cls)
intents = discord.Intents.default() intents = discord.Intents.default()
intents.message_content = True intents.message_content = True
bot = MyBot(command_prefix='!', intents=intents) bot = MyBot(command_prefix='!', intents=intents)
@bot.command() @bot.command()
async def guess(ctx, number: int): async def guess(ctx, number: int):
""" Guess a random number from 1 to 6. """ """Guess a random number from 1 to 6."""
# explained in a previous example, this gives you # explained in a previous example, this gives you
# a random number from 1-6 # a random number from 1-6
value = random.randint(1, 6) value = random.randint(1, 6)
@ -47,6 +49,7 @@ async def guess(ctx, number: int):
# or a red cross mark if it wasn't # or a red cross mark if it wasn't
await ctx.tick(number == value) await ctx.tick(number == value)
# IMPORTANT: You shouldn't hard code your token # IMPORTANT: You shouldn't hard code your token
# these are very important, and leaking them can # these are very important, and leaking them can
# let people do very malicious things with your # let people do very malicious things with your

View File

@ -2,6 +2,7 @@
import discord import discord
class MyClient(discord.Client): class MyClient(discord.Client):
async def on_ready(self): async def on_ready(self):
print(f'Logged in as {self.user} (ID: {self.user.id})') print(f'Logged in as {self.user} (ID: {self.user.id})')
@ -19,6 +20,7 @@ class MyClient(discord.Client):
msg = f'{message.author} has deleted the message: {message.content}' msg = f'{message.author} has deleted the message: {message.content}'
await message.channel.send(msg) await message.channel.send(msg)
intents = discord.Intents.default() intents = discord.Intents.default()
intents.message_content = True intents.message_content = True

View File

@ -3,6 +3,7 @@
import discord import discord
import asyncio import asyncio
class MyClient(discord.Client): class MyClient(discord.Client):
async def on_ready(self): async def on_ready(self):
print(f'Logged in as {self.user} (ID: {self.user.id})') print(f'Logged in as {self.user} (ID: {self.user.id})')
@ -18,6 +19,7 @@ class MyClient(discord.Client):
msg = f'**{before.author}** edited their message:\n{before.content} -> {after.content}' msg = f'**{before.author}** edited their message:\n{before.content} -> {after.content}'
await before.channel.send(msg) await before.channel.send(msg)
intents = discord.Intents.default() intents = discord.Intents.default()
intents.message_content = True intents.message_content = True

View File

@ -4,6 +4,7 @@ import discord
import random import random
import asyncio import asyncio
class MyClient(discord.Client): class MyClient(discord.Client):
async def on_ready(self): async def on_ready(self):
print(f'Logged in as {self.user} (ID: {self.user.id})') print(f'Logged in as {self.user} (ID: {self.user.id})')
@ -32,6 +33,7 @@ class MyClient(discord.Client):
else: else:
await message.channel.send(f'Oops. It is actually {answer}.') await message.channel.send(f'Oops. It is actually {answer}.')
intents = discord.Intents.default() intents = discord.Intents.default()
intents.message_content = True intents.message_content = True

View File

@ -18,6 +18,7 @@ tree = app_commands.CommandTree(client)
# to test it in a guild. # to test it in a guild.
TEST_GUILD = discord.Object(ID) TEST_GUILD = discord.Object(ID)
@client.event @client.event
async def on_ready(): async def on_ready():
print(f'Logged in as {client.user} (ID: {client.user.id})') print(f'Logged in as {client.user} (ID: {client.user.id})')
@ -26,6 +27,7 @@ async def on_ready():
# Sync the application command with Discord. # Sync the application command with Discord.
await tree.sync(guild=TEST_GUILD) await tree.sync(guild=TEST_GUILD)
class Feedback(discord.ui.Modal, title='Feedback'): class Feedback(discord.ui.Modal, title='Feedback'):
# Our modal classes MUST subclass `discord.ui.Modal`, # Our modal classes MUST subclass `discord.ui.Modal`,
# but the title can be whatever you want. # but the title can be whatever you want.
@ -66,4 +68,5 @@ async def feedback(interaction: discord.Interaction):
# Send the modal with an instance of our `Feedback` class # Send the modal with an instance of our `Feedback` class
await interaction.response.send_modal(Feedback()) await interaction.response.send_modal(Feedback())
client.run('token') client.run('token')

View File

@ -2,6 +2,7 @@
import discord import discord
class MyClient(discord.Client): class MyClient(discord.Client):
async def on_ready(self): async def on_ready(self):
print(f'Logged in as {self.user} (ID: {self.user.id})') print(f'Logged in as {self.user} (ID: {self.user.id})')

View File

@ -2,6 +2,7 @@
import discord import discord
class MyClient(discord.Client): class MyClient(discord.Client):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
@ -78,6 +79,7 @@ class MyClient(discord.Client):
# If we want to do something in case of errors we'd do it here. # If we want to do something in case of errors we'd do it here.
pass pass
intents = discord.Intents.default() intents = discord.Intents.default()
intents.members = True intents.members = True

View File

@ -2,6 +2,7 @@
import discord import discord
class MyClient(discord.Client): class MyClient(discord.Client):
async def on_ready(self): async def on_ready(self):
print(f'Logged in as {self.user} (ID: {self.user.id})') print(f'Logged in as {self.user} (ID: {self.user.id})')
@ -15,6 +16,7 @@ class MyClient(discord.Client):
if message.content.startswith('!hello'): if message.content.startswith('!hello'):
await message.reply('Hello!', mention_author=True) await message.reply('Hello!', mention_author=True)
intents = discord.Intents.default() intents = discord.Intents.default()
intents.message_content = True intents.message_content = True

View File

@ -17,6 +17,7 @@ async def secret(ctx: commands.Context):
if ctx.invoked_subcommand is None: if ctx.invoked_subcommand is None:
await ctx.send('Shh!', delete_after=5) await ctx.send('Shh!', delete_after=5)
def create_overwrites(ctx, *objects): def create_overwrites(ctx, *objects):
"""This is just a helper function that creates the overwrites for the """This is just a helper function that creates the overwrites for the
voice/text channels. voice/text channels.
@ -31,10 +32,7 @@ def create_overwrites(ctx, *objects):
# a dict comprehension is being utilised here to set the same permission overwrites # a dict comprehension is being utilised here to set the same permission overwrites
# for each `discord.Role` or `discord.Member`. # for each `discord.Role` or `discord.Member`.
overwrites = { overwrites = {obj: discord.PermissionOverwrite(view_channel=True) for obj in objects}
obj: discord.PermissionOverwrite(view_channel=True)
for obj in objects
}
# prevents the default role (@everyone) from viewing the channel # prevents the default role (@everyone) from viewing the channel
# if it isn't already allowed to view the channel. # if it isn't already allowed to view the channel.
@ -45,6 +43,7 @@ def create_overwrites(ctx, *objects):
return overwrites return overwrites
# since these commands rely on guild related features, # since these commands rely on guild related features,
# it is best to lock it to be guild-only. # it is best to lock it to be guild-only.
@secret.command() @secret.command()
@ -63,6 +62,7 @@ async def text(ctx: commands.Context, name: str, *objects: typing.Union[discord.
reason='Very secret business.', reason='Very secret business.',
) )
@secret.command() @secret.command()
@commands.guild_only() @commands.guild_only()
async def voice(ctx: commands.Context, name: str, *objects: typing.Union[discord.Role, discord.Member]): async def voice(ctx: commands.Context, name: str, *objects: typing.Union[discord.Role, discord.Member]):
@ -75,9 +75,10 @@ async def voice(ctx: commands.Context, name: str, *objects: typing.Union[discord
await ctx.guild.create_voice_channel( await ctx.guild.create_voice_channel(
name, name,
overwrites=overwrites, overwrites=overwrites,
reason='Very secret business.' reason='Very secret business.',
) )
@secret.command() @secret.command()
@commands.guild_only() @commands.guild_only()
async def emoji(ctx: commands.Context, emoji: discord.PartialEmoji, *roles: discord.Role): async def emoji(ctx: commands.Context, emoji: discord.PartialEmoji, *roles: discord.Role):
@ -94,7 +95,7 @@ async def emoji(ctx: commands.Context, emoji: discord.PartialEmoji, *roles: disc
name=emoji.name, name=emoji.name,
image=emoji_bytes, image=emoji_bytes,
roles=roles, roles=roles,
reason='Very secret business.' reason='Very secret business.',
) )

View File

@ -15,7 +15,7 @@ class Dropdown(discord.ui.Select):
options = [ options = [
discord.SelectOption(label='Red', description='Your favourite colour is red', emoji='🟥'), discord.SelectOption(label='Red', description='Your favourite colour is red', emoji='🟥'),
discord.SelectOption(label='Green', description='Your favourite colour is green', emoji='🟩'), discord.SelectOption(label='Green', description='Your favourite colour is green', emoji='🟩'),
discord.SelectOption(label='Blue', description='Your favourite colour is blue', emoji='🟦') discord.SelectOption(label='Blue', description='Your favourite colour is blue', emoji='🟦'),
] ]
# The placeholder is what will be shown when no option is chosen # The placeholder is what will be shown when no option is chosen

View File

@ -4,6 +4,7 @@ from discord.ext import commands
import discord import discord
class EphemeralCounterBot(commands.Bot): class EphemeralCounterBot(commands.Bot):
def __init__(self): def __init__(self):
intents = discord.Intents.default() intents = discord.Intents.default()
@ -15,6 +16,7 @@ class EphemeralCounterBot(commands.Bot):
print(f'Logged in as {self.user} (ID: {self.user.id})') print(f'Logged in as {self.user} (ID: {self.user.id})')
print('------') print('------')
# Define a simple View that gives us a counter button # Define a simple View that gives us a counter button
class Counter(discord.ui.View): class Counter(discord.ui.View):
@ -33,6 +35,7 @@ class Counter(discord.ui.View):
# Make sure to update the message with our updated selves # Make sure to update the message with our updated selves
await interaction.response.edit_message(view=self) await interaction.response.edit_message(view=self)
# Define a View that will give us our own personal counter button # Define a View that will give us our own personal counter button
class EphemeralCounter(discord.ui.View): class EphemeralCounter(discord.ui.View):
# When this button is pressed, it will respond with a Counter view that will # When this button is pressed, it will respond with a Counter view that will
@ -42,11 +45,14 @@ class EphemeralCounter(discord.ui.View):
# ephemeral=True makes the message hidden from everyone except the button presser # ephemeral=True makes the message hidden from everyone except the button presser
await interaction.response.send_message('Enjoy!', view=Counter(), ephemeral=True) await interaction.response.send_message('Enjoy!', view=Counter(), ephemeral=True)
bot = EphemeralCounterBot() bot = EphemeralCounterBot()
@bot.command() @bot.command()
async def counter(ctx: commands.Context): async def counter(ctx: commands.Context):
"""Starts a counter for pressing.""" """Starts a counter for pressing."""
await ctx.send('Press!', view=EphemeralCounter()) await ctx.send('Press!', view=EphemeralCounter())
bot.run('token') bot.run('token')

View File

@ -5,6 +5,7 @@ from discord.ext import commands
import discord import discord
from urllib.parse import quote_plus from urllib.parse import quote_plus
class GoogleBot(commands.Bot): class GoogleBot(commands.Bot):
def __init__(self): def __init__(self):
intents = discord.Intents.default() intents = discord.Intents.default()