[StealEmoji] Bug fixes and better handling (#42)

* StealEmoji properly handle Emojis not having the `__dict__` attribute

Start fix for emoiji vs animated max error

* Comment-out some prints

* First step to fixing stealemoji

Uses discord.Asset now

* Reformat

* Call __init__

* Fix duplicate emojis, formatting, caching
pull/109/head
bobloy 5 years ago committed by GitHub
parent e1256d26a5
commit 2a7a1b8b92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,17 +1,27 @@
import aiohttp
import discord import discord
from redbot.core import Config, checks, commands
from redbot.core import Config, commands
from redbot.core.bot import Red from redbot.core.bot import Red
from redbot.core.commands import Cog from redbot.core.commands import Cog
async def fetch_img(session, url): # Replaced with discord.Asset.read()
async with session.get(url) as response: # async def fetch_img(session: aiohttp.ClientSession, url: StrOrURL):
assert response.status == 200 # async with session.get(url) as response:
return await response.read() # assert response.status == 200
# return await response.read()
async def check_guild(guild, emoji):
if len(guild.emojis) >= 100:
return False
if len(guild.emojis) < 50:
return True
if emoji.animated:
return sum(e.animated for e in guild.emojis) < 50
else:
return sum(not e.animated for e in guild.emojis) < 50
class StealEmoji(Cog): class StealEmoji(Cog):
@ -22,20 +32,22 @@ class StealEmoji(Cog):
default_stolemoji = { default_stolemoji = {
"guildbank": None, "guildbank": None,
"name": None, "name": None,
"require_colons": False, "require_colons": None,
"managed": False, "managed": None,
"guild_id": None, "guild_id": None,
"url": None, "animated": None,
"animated": False,
} }
def __init__(self, red: Red): def __init__(self, red: Red):
super().__init__()
self.bot = red self.bot = red
self.config = Config.get_conf(self, identifier=11511610197108101109111106105) self.config = Config.get_conf(self, identifier=11511610197108101109111106105)
default_global = {"stolemoji": {}, "guildbanks": [], "on": False} default_global = {"stolemoji": {}, "guildbanks": [], "on": False, "notify": 0}
self.config.register_global(**default_global) self.config.register_global(**default_global)
self.is_on = await self.config.on()
@commands.group() @commands.group()
async def stealemoji(self, ctx: commands.Context): async def stealemoji(self, ctx: commands.Context):
""" """
@ -44,20 +56,44 @@ class StealEmoji(Cog):
if ctx.invoked_subcommand is None: if ctx.invoked_subcommand is None:
pass pass
@checks.is_owner()
@stealemoji.command(name="notify")
async def se_notify(self, ctx: commands.Context):
"""Cycles between notification settings for when an emoji is stolen
None (Default)
DM Owner
Msg in server channel
"""
curr_setting = await self.config.notify()
if not curr_setting:
await self.config.notify.set(1)
await ctx.send("Bot owner will now be notified when an emoji is stolen")
elif curr_setting == 1:
channel: discord.TextChannel = ctx.channel
await self.config.notify.set(channel.id)
await ctx.send("This channel will now be notified when an emoji is stolen")
else:
await self.config.notify.set(0)
await ctx.send("Notifications are now off")
@checks.is_owner()
@stealemoji.command(name="collect") @stealemoji.command(name="collect")
async def se_collect(self, ctx): async def se_collect(self, ctx):
"""Toggles whether emoji's are collected or not""" """Toggles whether emoji's are collected or not"""
curr_setting = await self.config.on() curr_setting = await self.config.on()
await self.config.on.set(not curr_setting) await self.config.on.set(not curr_setting)
self.is_on = await self.config.on()
await ctx.send("Collection is now " + str(not curr_setting)) await ctx.send("Collection is now " + str(not curr_setting))
@checks.is_owner()
@commands.guild_only()
@stealemoji.command(name="bank") @stealemoji.command(name="bank")
async def se_bank(self, ctx): async def se_bank(self, ctx):
"""Add current server as emoji bank""" """Add current server as emoji bank"""
await ctx.send(
"This will upload custom emojis to this server\n"
"Are you sure you want to make the current server an emoji bank? (y//n)"
)
def check(m): def check(m):
return ( return (
@ -66,31 +102,50 @@ class StealEmoji(Cog):
and m.author == ctx.author and m.author == ctx.author
) )
already_a_guildbank = ctx.guild.id in (await self.config.guildbanks())
if already_a_guildbank:
await ctx.send(
"This is already an emoji bank\n"
"Are you sure you want to remove the current server from the emoji bank list? (y/n)"
)
else:
await ctx.send(
"This will upload custom emojis to this server\n"
"Are you sure you want to make the current server an emoji bank? (y/n)"
)
msg = await self.bot.wait_for("message", check=check) msg = await self.bot.wait_for("message", check=check)
if msg.content in ["N", "NO"]: if msg.content.upper() in ["N", "NO"]:
await ctx.send("Cancelled") await ctx.send("Cancelled")
return return
async with self.config.guildbanks() as guildbanks: async with self.config.guildbanks() as guildbanks:
if already_a_guildbank:
guildbanks.remove(ctx.guild.id)
else:
guildbanks.append(ctx.guild.id) guildbanks.append(ctx.guild.id)
await ctx.send("This server has been added as an emoji bank") if already_a_guildbank:
await ctx.send("This server has been removed from being an emoji bank")
else:
await ctx.send("This server has been added to be an emoji bank")
@commands.Cog.listener() @commands.Cog.listener()
async def on_reaction_add(self, reaction: discord.Reaction, user: discord.User): async def on_reaction_add(self, reaction: discord.Reaction, user: discord.User):
"""Event handler for reaction watching""" """Event handler for reaction watching"""
if not reaction.custom_emoji: if not reaction.custom_emoji:
print("Not a custom emoji") # print("Not a custom emoji")
return return
if not (await self.config.on()): if not self.is_on:
print("Collecting is off") # print("Collecting is off")
return return
emoji = reaction.emoji emoji: discord.Emoji = reaction.emoji
if emoji in self.bot.emojis: if emoji in self.bot.emojis:
print("Emoji already in bot.emojis") # print("Emoji already in bot.emojis")
return return
# This is now a custom emoji that the bot doesn't have access to, time to steal it # This is now a custom emoji that the bot doesn't have access to, time to steal it
@ -99,30 +154,39 @@ class StealEmoji(Cog):
guildbank = None guildbank = None
banklist = await self.config.guildbanks() banklist = await self.config.guildbanks()
for guild_id in banklist: for guild_id in banklist:
guild = self.bot.get_guild(guild_id) guild: discord.Guild = self.bot.get_guild(guild_id)
if len(guild.emojis) < 50: # if len(guild.emojis) < 50:
if await check_guild(guild, emoji):
guildbank = guild guildbank = guild
break break
if guildbank is None: if guildbank is None:
print("No guildbank to store emoji") # print("No guildbank to store emoji")
# Eventually make a new banklist # Eventually make a new banklist
return return
# Next, have I saved this emoji before (because uploaded emoji != orignal emoji) # Next, have I saved this emoji before (because uploaded emoji != orignal emoji)
stolemojis = await self.config.stolemoji() if str(emoji.id) in await self.config.stolemoji():
# print("Emoji has already been stolen")
if emoji.id in stolemojis:
print("Emoji has already been stolen")
return return
# stolemojis = await self.config.stolemoji()
#
# print(stolemojis.keys())
#
# if emoji.id in stolemojis:
# print("Emoji has already been stolen")
# return
# Alright, time to steal it for real # Alright, time to steal it for real
# path = urlparse(emoji.url).path # path = urlparse(emoji.url).path
# ext = os.path.splitext(path)[1] # ext = os.path.splitext(path)[1]
async with aiohttp.ClientSession() as session: # async with aiohttp.ClientSession() as session:
img = await fetch_img(session, emoji.url) # img = await fetch_img(session, emoji.url)
img = await emoji.url.read()
# path = data_manager.cog_data_path(cog_instance=self) / (emoji.name+ext) # path = data_manager.cog_data_path(cog_instance=self) / (emoji.name+ext)
@ -135,20 +199,23 @@ class StealEmoji(Cog):
name=emoji.name, image=img, reason="Stole from " + str(user) name=emoji.name, image=img, reason="Stole from " + str(user)
) )
except discord.Forbidden as e: except discord.Forbidden as e:
print("PermissionError - no permission to add emojis") # print("PermissionError - no permission to add emojis")
raise PermissionError("No permission to add emojis") from e raise PermissionError("No permission to add emojis") from e
except discord.HTTPException as e: except discord.HTTPException as e:
print("HTTPException exception") # print("HTTPException exception")
raise e # Unhandled error raise e # Unhandled error
# If you get this far, YOU DID IT # If you get this far, YOU DID IT
save_dict = self.default_stolemoji.copy() save_dict = self.default_stolemoji.copy()
e_dict = vars(emoji) # e_attr_list = [a for a in dir(emoji) if not a.startswith("__")]
for k in save_dict.keys():
save_dict[k] = getattr(emoji, k, None)
for k in e_dict: # for k in e_attr_list:
if k in save_dict: # if k in save_dict:
save_dict[k] = e_dict[k] # save_dict[k] = getattr(emoji, k, None)
save_dict["guildbank"] = guildbank.id save_dict["guildbank"] = guildbank.id
@ -156,6 +223,12 @@ class StealEmoji(Cog):
stolemoji[emoji.id] = save_dict stolemoji[emoji.id] = save_dict
# Enable the below if you want to get notified when it works # Enable the below if you want to get notified when it works
# owner = await self.bot.application_info() notify_settings = await self.config.notify()
# owner = owner.owner if notify_settings:
# await owner.send("Just added emoji "+str(emoji)+" to server "+str(guildbank)) if notify_settings == 1:
owner = await self.bot.application_info()
target = owner.owner
else:
target = self.bot.get_channel(notify_settings)
await target.send(f"Just added emoji {emoji} to server {guildbank}")

Loading…
Cancel
Save