discord.py 2.0 fun

Invites will not work because discord-ext-menus needs to be updated in Red
This commit is contained in:
aikaterna
2022-02-18 18:03:37 -08:00
parent 3d54796b69
commit 57ae7a52cd
7 changed files with 102 additions and 78 deletions

View File

@@ -1,7 +1,6 @@
import discord
from redbot.core import Config, commands, checks
from typing import Optional, Literal
import datetime
import re
IMAGE_LINKS = re.compile(r"(http[s]?:\/\/[^\"\']*\.(?:png|jpg|jpeg|gif|png))")
@@ -37,7 +36,7 @@ class Away(commands.Cog):
def _draw_play(self, song):
song_start_time = song.start
total_time = song.duration
current_time = datetime.datetime.utcnow()
current_time = discord.utils.utcnow()
elapsed_time = current_time - song_start_time
sections = 12
loc_time = round((elapsed_time / total_time) * sections) # 10 sections
@@ -60,7 +59,7 @@ class Away(commands.Cog):
"""
Makes the embed reply
"""
avatar = author.avatar_url_as() # This will return default avatar if no avatar is present
avatar = author.display_avatar # This will return default avatar if no avatar is present
color = author.color
if message:
link = IMAGE_LINKS.search(message)
@@ -226,7 +225,7 @@ class Away(commands.Cog):
return False
@commands.Cog.listener()
async def on_message(self, message: discord.Message):
async def on_message_without_command(self, message: discord.Message):
guild = message.guild
if not guild or not message.mentions or message.author.bot:
return
@@ -667,7 +666,7 @@ class Away(commands.Cog):
if ctx.channel.permissions_for(ctx.me).embed_links:
em = discord.Embed(description=msg[:2048], color=author.color)
em.set_author(name=f"{author.display_name}'s away settings", icon_url=author.avatar_url)
em.set_author(name=f"{author.display_name}'s away settings", icon_url=author.avatar.url)
await ctx.send(embed=em)
else:
await ctx.send(f"{author.display_name} away settings\n" + msg)

View File

@@ -85,14 +85,14 @@ class Blurplefy(commands.Cog):
await ctx.send("{}, starting blurple image analysis.".format(ctx.message.author.mention))
link = ctx.message.attachments
if user is None and not link:
picture = ctx.author.avatar_url
picture = ctx.author.avatar.url
else:
if not user:
if len(link) != 0:
for image in link:
picture = image.url
else:
picture = user.avatar_url
picture = user.avatar.url
try:
async with self.session.request("GET", str(picture)) as r:
response = await r.read()
@@ -109,7 +109,7 @@ class Blurplefy(commands.Cog):
await ctx.send("{}, starting blurple image analysis.".format(ctx.message.author.mention))
link = ctx.message.attachments
if user is None and not link:
picture = ctx.author.avatar_url
picture = ctx.author.avatar.url
role_check = True
elif not user:
if len(link) != 0:
@@ -117,7 +117,7 @@ class Blurplefy(commands.Cog):
picture = image.url
role_check = False
else:
picture = user.avatar_url
picture = user.avatar.url
role_check = False
try:
@@ -180,7 +180,7 @@ class Blurplefy(commands.Cog):
blurple_role_obj = discord.utils.get(ctx.guild.roles, id=blurple_role_id)
if (
blurplenesspercentage > 75
and picture == ctx.author.avatar_url
and picture == ctx.author.avatar.url
and blurple_role_obj not in ctx.author.roles
and percentblurple > 5
):
@@ -190,7 +190,7 @@ class Blurplefy(commands.Cog):
)
)
await ctx.author.add_roles(blurple_role_obj)
elif picture == ctx.author.avatar_url and blurple_role_obj not in ctx.author.roles:
elif picture == ctx.author.avatar.url and blurple_role_obj not in ctx.author.roles:
await ctx.send(
"{}, your profile pic does not have enough blurple (over 75% in total and over 5% blurple), therefore you are not eligible for the role {}.".format(
ctx.message.author.display_name, blurple_role_obj.name
@@ -206,14 +206,14 @@ class Blurplefy(commands.Cog):
await ctx.send("{}, starting blurple image analysis.".format(ctx.message.author.mention))
link = ctx.message.attachments
if user is None and not link:
picture = ctx.author.avatar_url
picture = ctx.author.avatar.url
else:
if not user:
if len(link) != 0:
for image in link:
picture = image.url
else:
picture = user.avatar_url
picture = user.avatar.url
try:
async with self.session.request("GET", str(picture)) as r:
response = await r.read()
@@ -380,12 +380,14 @@ class Blurplefy(commands.Cog):
@commands.command()
async def countdown(self, ctx):
"""Countdown to Discord's 7th Anniversary."""
embed = discord.Embed(name="", colour=0x7289DA)
timeleft = datetime.datetime(2021, 5, 13) + datetime.timedelta(hours=7) - datetime.datetime.utcnow()
embed.set_author(name="Time left until Discord's 6th Anniversary")
embed = discord.Embed()
embed.description="\N{ZERO WIDTH SPACE}"
embed.colour=0x7289DA
timeleft = datetime.datetime(2021, 5, 13, tzinfo=datetime.timezone.utc) + datetime.timedelta(hours=7) - discord.utils.utcnow()
embed.set_author(name="Time left until Discord's 7th Anniversary")
if int(timeleft.total_seconds()) < 0:
timeleft = datetime.datetime(2022, 5, 13) + datetime.timedelta(hours=7) - datetime.datetime.utcnow()
embed.set_author(name="Time left until Discord's 6th Anniversary")
timeleft = datetime.datetime(2022, 5, 13, tzinfo=datetime.timezone.utc) + datetime.timedelta(hours=7) - discord.utils.utcnow()
embed.set_author(name="Time left until Discord's 7th Anniversary")
embed.add_field(
name="Countdown to midnight, May 13, California time (UTC-7):",
value=("{}".format(self._dynamic_time(int(timeleft.total_seconds())))),

View File

@@ -374,7 +374,11 @@ class CardsAgainstHumanity(commands.Cog):
member["Task"] = None
# Set running to false
game["Running"] = False
self.games.remove(game)
try:
self.games.remove(game)
except ValueError:
# game was in progress but players left, leaving the open game with less than 3 people
pass
return False
async def typing(self, game, typeTime=5):
@@ -702,7 +706,7 @@ class CardsAgainstHumanity(commands.Cog):
await self.sendToUser(user, msg)
async def drawCard(self, game):
with open(str(bundled_data_path(self)) + "/deck.json", "r") as deck_file:
with open(str(bundled_data_path(self)) + "/deck.json", "r", encoding='utf-8') as deck_file:
deck = json.load(deck_file)
# Draws a random unused card and shuffles the deck if needed
totalDiscard = len(game["Discard"])
@@ -752,7 +756,7 @@ class CardsAgainstHumanity(commands.Cog):
i += 1
async def drawBCard(self, game):
with open(str(bundled_data_path(self)) + "/deck.json", "r") as deck_file:
with open(str(bundled_data_path(self)) + "/deck.json", "r", encoding='utf-8') as deck_file:
deck = json.load(deck_file)
# Draws a random black card
totalDiscard = len(game["BDiscard"])
@@ -890,7 +894,11 @@ class CardsAgainstHumanity(commands.Cog):
if message == None:
msg = "Ooookay, you say *nothing...*"
return await self.sendToUser(ctx.author, msg)
long_message = False
msg = f"*{ctx.author.name}* says: {message}"
if len(msg) > 1999:
msg = msg[:1990] + " [...]"
long_message = True
for member in userGame["Members"]:
if member["IsBot"]:
continue
@@ -901,7 +909,10 @@ class CardsAgainstHumanity(commands.Cog):
else:
# Update member's time
member["Time"] = int(time.time())
await self.sendToUser(ctx.author, "Message sent!")
msg = "Message sent!"
if long_message:
msg += " Your message was cut short to keep it under the 2000 character limit."
await self.sendToUser(ctx.author, msg)
@commands.command()
async def lay(self, ctx, *, card=None):
@@ -1069,7 +1080,7 @@ class CardsAgainstHumanity(commands.Cog):
"""Starts a new Cards Against Humanity game."""
try:
embed = discord.Embed(color=discord.Color.green())
embed.set_author(name="**Setting up the game...**")
embed.set_author(name="Setting up the game...")
await ctx.author.send(embed=embed)
except discord.errors.Forbidden:
return await ctx.send("You must allow Direct Messages from the bot for this game to work.")

View File

@@ -42,7 +42,7 @@ class Invites(commands.Cog):
@invites.command()
async def show(self, ctx: commands.Context, invite_code_or_url: str = None):
"""Show the stats for an invite, or show all invites."""
if not ctx.me.permissions_in(ctx.channel).administrator:
if not ctx.channel.permissions_for(ctx.guild.me).administrator:
return await self._send_embed(ctx, PERM_MSG)
if not invite_code_or_url:
@@ -57,7 +57,7 @@ class Invites(commands.Cog):
@invites.command()
async def leaderboard(self, ctx: commands.Context, list_all_invites: bool = False):
"""List pinned invites or all invites in a leaderboard style."""
if not ctx.me.permissions_in(ctx.channel).administrator:
if not ctx.channel.permissions_for(ctx.guild.me).administrator:
return await self._send_embed(ctx, PERM_MSG)
if not list_all_invites:
@@ -96,7 +96,7 @@ class Invites(commands.Cog):
@invites.command()
async def pin(self, ctx: commands.Context, invite_code_or_url: str):
"""Pin an invite to the leaderboard."""
if not ctx.me.permissions_in(ctx.channel).administrator:
if not ctx.channel.permissions_for(ctx.guild.me).administrator:
return await self._send_embed(ctx, PERM_MSG)
invite_code = await self._find_invite_code(invite_code_or_url)

View File

@@ -4,7 +4,6 @@ import discord
from redbot.core.bot import Red
from redbot.core import commands, checks, Config
from datetime import datetime
DEFAULT_OFFLINE_EMOJI = "\N{LARGE RED CIRCLE}"
DEFAULT_ONLINE_EMOJI = "\N{WHITE HEAVY CHECK MARK}"
@@ -12,7 +11,7 @@ DEFAULT_ONLINE_EMOJI = "\N{WHITE HEAVY CHECK MARK}"
class Otherbot(commands.Cog):
__author__ = ["aikaterna", "Predä 。#1001"]
__version__ = "0.10"
__version__ = "0.11"
async def red_delete_data_for_user(
self, *, requester: Literal["discord", "owner", "user", "user_strict"], user_id: int,
@@ -126,7 +125,8 @@ class Otherbot(commands.Cog):
else:
msg += f"**{name}**: {guild_data[attr]}\n"
em.description = msg
em.set_thumbnail(url=guild.icon_url)
if guild.icon:
em.set_thumbnail(url=guild.icon.url)
await ctx.send(embed=em)
else:
msg = "```\n"
@@ -346,7 +346,7 @@ class Otherbot(commands.Cog):
await self.generate_cache()
@commands.Cog.listener()
async def on_member_update(self, before: discord.Member, after: discord.Member):
async def on_presence_update(self, before: discord.Member, after: discord.Member):
if after.guild is None or not after.bot:
return
@@ -368,19 +368,16 @@ class Otherbot(commands.Cog):
em = discord.Embed(
color=0x8B0000,
description=f"{after.mention} is offline. {data['offline_emoji']}",
timestamp=datetime.utcnow(),
timestamp=discord.utils.utcnow(),
)
if not data["ping"]:
await channel.send(embed=em)
else:
if discord.version_info.minor < 4:
await channel.send(f"<@&{data['ping']}>", embed=em)
else:
await channel.send(
f"<@&{data['ping']}>",
embed=em,
allowed_mentions=discord.AllowedMentions(roles=True),
)
await channel.send(
f"<@&{data['ping']}>",
embed=em,
allowed_mentions=discord.AllowedMentions(roles=True),
)
else:
if not data["ping"]:
await channel.send(f"{after.mention} is offline. {data['offline_emoji']}")
@@ -401,19 +398,16 @@ class Otherbot(commands.Cog):
em = discord.Embed(
color=0x008800,
description=f"{after.mention} is back online. {data['online_emoji']}",
timestamp=datetime.utcnow(),
timestamp=discord.utils.utcnow(),
)
if not data["ping"]:
await channel.send(embed=em)
else:
if discord.version_info.minor < 4:
await channel.send(f"<@&{data['ping']}>", embed=em)
else:
await channel.send(
f"<@&{data['ping']}>",
embed=em,
allowed_mentions=discord.AllowedMentions(roles=True),
)
await channel.send(
f"<@&{data['ping']}>",
embed=em,
allowed_mentions=discord.AllowedMentions(roles=True),
)
else:
if not data["ping"]:
await channel.send(

View File

@@ -117,7 +117,7 @@ class Seen(commands.Cog):
elif output[2] > 1:
ts += "{} minutes ago".format(output[2])
em = discord.Embed(colour=discord.Color.green())
avatar = author.avatar_url or author.default_avatar_url
avatar = author.display_avatar
em.set_author(name="{} was seen {}".format(author.display_name, ts), icon_url=avatar)
await ctx.send(embed=em)

View File

@@ -213,6 +213,8 @@ class Tools(commands.Cog):
discord.TextChannel: "Text Channel",
discord.VoiceChannel: "Voice Channel",
discord.CategoryChannel: "Category",
discord.StageChannel: "Stage Channel",
discord.Thread: "Thread Channel",
}
load = "```\nLoading channel info...```"
@@ -223,41 +225,57 @@ class Tools(commands.Cog):
data = "```ini\n"
if caller == "invoke" or channel.guild != ctx.guild:
data += "[Server]: {}\n".format(channel.guild.name)
data += "[Name]: {}\n".format(cf.escape(str(channel)))
data += "[ID]: {}\n".format(channel.id)
data += "[Private]: {}\n".format(yesno[isinstance(channel, discord.abc.PrivateChannel)])
if isinstance(channel, discord.TextChannel) and channel.topic != "":
data += "[Topic]: {}\n".format(channel.topic)
data += "[Position]: {}\n".format(channel.position)
data += "[Created]: {}\n".format(self._dynamic_time(channel.created_at))
data += "[Type]: {}\n".format(typemap[type(channel)])
data += "[Server]: {}\n".format(channel.guild.name)
data += "[Name]: {}\n".format(cf.escape(str(channel)))
data += "[ID]: {}\n".format(channel.id)
data += "[Private]: {}\n".format(yesno[isinstance(channel, discord.abc.PrivateChannel)])
if isinstance(channel, discord.TextChannel) and channel.topic != None:
data += "[Topic]: {}\n".format(channel.topic)
try:
data += "[Position]: {}\n".format(channel.position)
except AttributeError:
# this is a thread
data += "[Parent Channel]: {} ({})\n".format(channel.parent.name, channel.parent.id)
data += "[Parent Position]: {}\n".format(channel.parent.position)
try:
data += "[Created]: {}\n".format(self._dynamic_time(channel.created_at))
except AttributeError:
# this is a thread
data += "[Updated]: {}\n".format(self._dynamic_time(channel.archive_timestamp))
data += "[Type]: {}\n".format(typemap[type(channel)])
if isinstance(channel, discord.TextChannel) and channel.is_news():
data += "[News Channel]: {}\n".format(channel.is_news())
if isinstance(channel, discord.VoiceChannel):
data += "[Users]: {}\n".format(len(channel.members))
data += "[User limit]: {}\n".format(channel.user_limit)
data += "[Bitrate]: {}kbps\n".format(int(channel.bitrate / 1000))
data += "[Users]: {}\n".format(len(channel.members))
data += "[User limit]: {}\n".format(channel.user_limit)
data += "[Bitrate]: {}kbps\n".format(int(channel.bitrate / 1000))
data += "```"
await asyncio.sleep(1)
await waiting.edit(content=data)
@commands.guild_only()
@commands.command()
async def eid(self, ctx, emoji: discord.Emoji):
async def eid(self, ctx, emoji: str = None):
"""Get an id for an emoji."""
if not isinstance(emoji, discord.Emoji):
return await ctx.send("I can't see that emoji in any of the servers I'm in.")
await ctx.send(f"**ID for {emoji}:** {emoji.id}")
@commands.guild_only()
@commands.command()
async def einfo(self, ctx, emoji: discord.Emoji):
async def einfo(self, ctx, emoji: str = None):
"""Emoji information."""
e = emoji
if not isinstance(emoji, discord.Emoji):
return await ctx.send("I can't see that emoji in any of the servers I'm in.")
m = (
f"{str(e)}\n"
f"{str(emoji)}\n"
f"```ini\n"
f"[NAME]: {e.name}\n"
f"[GUILD]: {e.guild}\n"
f"[URL]: {e.url}\n"
f"[ANIMATED]: {e.animated}"
f"[NAME]: {emoji.name}\n"
f"[GUILD]: {emoji.guild}\n"
f"[URL]: {emoji.url}\n"
f"[ANIMATED]: {emoji.animated}"
"```"
)
await ctx.send(m)
@@ -265,7 +283,7 @@ class Tools(commands.Cog):
@commands.guild_only()
@commands.command()
@checks.mod_or_permissions(manage_guild=True)
async def inrole(self, ctx, *, rolename):
async def inrole(self, ctx, *, rolename: str):
"""Check members in the role specified."""
guild = ctx.guild
await ctx.trigger_typing()
@@ -286,7 +304,7 @@ class Tools(commands.Cog):
if len(roles) == 1:
role = roles[0]
elif len(roles) < 1:
await ctx.send("No roles were found.")
await ctx.send(f"No roles containing `{rolename}` were found.")
return
else:
msg = (
@@ -555,7 +573,8 @@ class Tools(commands.Cog):
em.add_field(name="Position", value=role.position)
em.add_field(name="Valid Permissions", value="{}".format(perms_we_have))
em.add_field(name="Invalid Permissions", value="{}".format(perms_we_dont))
em.set_thumbnail(url=role.guild.icon_url)
if guild.icon:
em.set_thumbnail(url=role.guild.icon.url)
try:
await loadingmsg.edit(embed=em)
except discord.HTTPException:
@@ -654,12 +673,12 @@ class Tools(commands.Cog):
data = "```ini\n"
data += "[Name]: {}\n".format(guild.name)
data += "[ID]: {}\n".format(guild.id)
data += "[Region]: {}\n".format(guild.region)
data += "[Owner]: {}\n".format(guild.owner)
data += "[Users]: {}/{}\n".format(online, total_users)
data += "[Text]: {} channels\n".format(len(text_channels))
data += "[Voice]: {} channels\n".format(len(voice_channels))
data += "[Emojis]: {}\n".format(len(guild.emojis))
data += "[Stickers]: {}\n".format(len(guild.stickers))
data += "[Roles]: {} \n".format(len(guild.roles))
data += "[Created]: {}\n```".format(self._dynamic_time(guild.created_at))
await asyncio.sleep(1)
@@ -731,7 +750,7 @@ class Tools(commands.Cog):
data += "[Streaming]: [{}]({})\n".format(cf.escape(str(actstream.name)), cf.escape(actstream.url))
if actcustom := discord.utils.get(user.activities, type=discord.ActivityType.custom):
if actcustom.name is not None:
data += "[Custom status]: {}\n".format(cf.escape(str(actcustom.name)))
data += "[Custom Status]: {}\n".format(cf.escape(str(actcustom.name)))
passed = (ctx.message.created_at - user.created_at).days
data += "[Created]: {}\n".format(self._dynamic_time(user.created_at))
joined_at = self.fetch_joined_at(user, ctx.guild)
@@ -791,12 +810,11 @@ class Tools(commands.Cog):
@staticmethod
def _dynamic_time(time):
try:
date_join = datetime.datetime.strptime(str(time), "%Y-%m-%d %H:%M:%S.%f")
date_join = datetime.datetime.strptime(str(time), "%Y-%m-%d %H:%M:%S.%f%z")
except ValueError:
time = f"{str(time)}.0"
date_join = datetime.datetime.strptime(str(time), "%Y-%m-%d %H:%M:%S.%f")
date_now = datetime.datetime.now(datetime.timezone.utc)
date_now = date_now.replace(tzinfo=None)
date_join = datetime.datetime.strptime(str(time), "%Y-%m-%d %H:%M:%S.%f%z")
date_now = discord.utils.utcnow()
since_join = date_now - date_join
mins, secs = divmod(int(since_join.total_seconds()), 60)