From 1802dc26196486f450b34edf9bef8df448bcaeac Mon Sep 17 00:00:00 2001 From: aikaterna <20862007+aikaterna@users.noreply.github.com> Date: Fri, 27 Oct 2023 15:37:28 -0700 Subject: [PATCH] Update for Red 3.5 and some fixes --- emote/__init__.py | 7 ++- emote/emote.py | 99 ++++++++++++++----------------- geico/info.json | 1 + horoscope/__init__.py | 6 +- horoscope/horoscope.py | 132 +++++++++++++++++------------------------ horoscope/info.json | 9 +-- longcat/__init__.py | 6 +- longcat/info.json | 2 +- longcat/longcat.py | 24 ++++---- loot/__init__.py | 6 +- loot/info.json | 2 +- loot/loot.py | 27 +++++---- lootbox/__init__.py | 6 +- lootbox/info.json | 2 +- lootbox/lootbox.py | 53 +++++++++-------- points/__init__.py | 6 +- points/info.json | 10 +--- points/points.py | 74 ++++++++++++----------- strawpoll/info.json | 1 + the100/info.json | 18 +++--- trove/info.json | 1 + 21 files changed, 238 insertions(+), 254 deletions(-) diff --git a/emote/__init__.py b/emote/__init__.py index fc8c6ac..a045878 100644 --- a/emote/__init__.py +++ b/emote/__init__.py @@ -1,8 +1,9 @@ from redbot.core import commands from .emote import Emote +__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users." -def setup(bot: commands.Bot): + +async def setup(bot: commands.Bot): n = Emote(bot) - bot.add_listener(n.check_emotes, "on_message") - bot.add_cog(n) + await bot.add_cog(n) diff --git a/emote/emote.py b/emote/emote.py index dc4d941..3614dc5 100644 --- a/emote/emote.py +++ b/emote/emote.py @@ -11,20 +11,23 @@ from redbot.core.data_manager import cog_data_path # if this seem hard to read/understand, remove the comments. Might make it easier -BaseCog = getattr(commands, "Cog", object) - -class Emote(BaseCog): +class Emote(commands.Cog): """Emote was made using irdumb's sadface cog's code. Owner is responsible for it's handling.""" + async def red_delete_data_for_user(self, **kwargs): + """Nothing to delete.""" + return + default_guild_settings = {"status": False, "emotes": {}} def __init__(self, bot: Red): self.bot = bot self._emote = Config.get_conf(self, 1824791591) - self._emote_path = cog_data_path(self) / "images" + # self._emote_path = os.sep.join([str(cog_data_path(self)), "images"]) + self._emote_path = cog_data_path(self) self._emote.register_guild(**self.default_guild_settings) @@ -33,8 +36,8 @@ def __init__(self, bot: Red): # doesn't make sense to use this command in a pm, because pms aren't in servers # mod_or_permissions needs something in it otherwise it's mod or True which is always True - def __unload(self): - self.session.close() + def cog_unload(self): + self.bot.loop.create_task(self.session.close()) @commands.group() @commands.guild_only() @@ -84,25 +87,19 @@ async def add(self, ctx, name, url): return if url.endswith(".gifv"): url = url.replace(".gifv", ".gif") - try: - await ctx.send("Downloading {}.".format(name)) - async with self.session.get(url, headers=option) as r: - emote = await r.read() - print(self._emote_path) - with open(self._emote_path + "{}.{}".format(name, url[-3:]), "wb") as f: - f.write(emote) - - await ctx.send("Adding {} to the list.".format(name)) - emotes[name] = "{}.{}".format(name, url[-3:]) - await self._emote.guild(guild).emote.set(emotes) - await ctx.send("{} has been added to the list".format(name)) - except Exception as e: - print(e) - await ctx.send( - "It seems your url is not valid," - " please make sure you are not typing names with spaces as they are and then the url." - " If so, do [p]emotes add name_with_spaces url" - ) + + await ctx.send("Downloading {}.".format(name)) + async with self.session.get(url, headers=option) as r: + emote = await r.read() + filename = f"{name}.{url[-3:]}" + patha = os.path.join(str(self._emote_path), filename) + with open(patha, "wb") as f: + f.write(emote) + + await ctx.send("Adding {} to the list.".format(name)) + emotes[name] = "{}.{}".format(name, url[-3:]) + await self._emote.guild(guild).emotes.set(emotes) + await ctx.send("{} has been added to the list".format(name)) @checks.is_owner() @emotes.command() @@ -144,26 +141,26 @@ async def edit(self, ctx, name, newname): if newname in emotes: await ctx.send("This keyword already exists, please use another keyword.") return - try: - if name in emotes: - emotes[newname] = "{}.{}".format(newname, emotes[name][-3:]) - os.rename(self._emote + emotes[name], self._emote + emotes[newname]) - del emotes[name] - else: - await ctx.send( - "{} is not a valid name, please make sure the name of the" - " emote that you want to edit exists" - " Use [p]emotes list to verify it's there.".format(name) - ) - return - await self._emote.guild(guild).emote.set(emotes) - await ctx.send("{} in the emotes list has been renamed to {}".format(name, newname)) - except FileNotFoundError: + # try: + if name in emotes: + emotes[newname] = "{}.{}".format(newname, emotes[name][-3:]) + os.rename(str(self._emote_path) + os.sep + emotes[name], str(self._emote_path) + os.sep + emotes[newname]) + del emotes[name] + else: await ctx.send( - "For some unknown reason, your emote is not available in the default directory," - " that is, data/emote/images. This means that it can't be edited." - " But it has been successfully edited in the emotes list." + "{} is not a valid name, please make sure the name of the" + " emote that you want to edit exists" + " Use [p]emotes list to verify it's there.".format(name) ) + return + await self._emote.guild(guild).emote.set(emotes) + await ctx.send("{} in the emotes list has been renamed to {}".format(name, newname)) + # except FileNotFoundError: + # await ctx.send( + # "For some unknown reason, your emote is not available in the default directory," + # " that is, data/emote/images. This means that it can't be edited." + # " But it has been successfully edited in the emotes list." + # ) @emotes.command() @commands.guild_only() @@ -313,6 +310,7 @@ def check(m): continue break else: + missing = [] emotes = await self._emote.guild(guild).emotes() istyles = sorted(emotes) for n in istyles: @@ -426,25 +424,20 @@ def check(m): str(count) + " Keywords have been successfully added to the image list" ) - async def check_emotes(self, message): + @commands.Cog.listener() + async def on_message_without_command(self, message): # check if setting is on in this server # Let emotes happen in PMs always guild = message.guild if guild is None: return - emotes = await self._emote.guild(guild).emotes() # Filter unauthorized users, bots and empty messages if not message.content: return - # Don't respond to commands - for m in await self.bot.db.prefix(): - if message.content.startswith(m): - return - - if guild is not None: - if not (await self._emote.guild(guild).status()): - return + if not (await self._emote.guild(guild).status()): + return + emotes = await self._emote.guild(guild).emotes() msg = message.content.lower().split() listed = [] diff --git a/geico/info.json b/geico/info.json index f60d36f..ff1c5b0 100644 --- a/geico/info.json +++ b/geico/info.json @@ -1,5 +1,6 @@ { "author": ["Aioxas"], + "hidden": true, "install_msg": "Thanks for installing my cog. \n[p]bash and [p]quotes will be your guides.\nA 15-minute call could save you 15 percent (or more) on car insurance.", "name": "Geico", "short": "Online quote retrieval", diff --git a/horoscope/__init__.py b/horoscope/__init__.py index cc1f676..ab5961a 100644 --- a/horoscope/__init__.py +++ b/horoscope/__init__.py @@ -1,5 +1,7 @@ from .horoscope import Horoscope +__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users." -def setup(bot): - bot.add_cog(Horoscope(bot)) + +async def setup(bot): + await bot.add_cog(Horoscope(bot)) diff --git a/horoscope/horoscope.py b/horoscope/horoscope.py index 454d216..8eeba56 100644 --- a/horoscope/horoscope.py +++ b/horoscope/horoscope.py @@ -1,31 +1,40 @@ -from redbot.core import commands -from redbot.core.data_manager import bundled_data_path -from redbot.core.utils.chat_formatting import box import aiohttp +import asyncio +import discord import html import os -import asyncio import re -import discord -from redbot.core.bot import Red + +from io import BytesIO from PIL import Image, ImageDraw, ImageFont -BaseCog = getattr(commands, "Cog", object) +from redbot.core import commands +from redbot.core.bot import Red +from redbot.core.data_manager import bundled_data_path +from redbot.core.utils.chat_formatting import box + +class Horoscope(commands.Cog): + """View a horoscope, or get a fortune cookie with lucky numbers.""" + + async def red_delete_data_for_user(self, **kwargs): + """Nothing to delete.""" + return -class Horoscope(BaseCog): def __init__(self, bot: Red): self.bot = bot self.session = aiohttp.ClientSession(loop=self.bot.loop) + self.headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0"} def cog_unload(self): - asyncio.get_event_loop().create_task(self.session.close()) + self.bot.loop.create_task(self.session.close()) @commands.guild_only() - @commands.command(name="horo") + @commands.command(name="horo", aliases=["horoscope"]) @commands.cooldown(10, 60, commands.BucketType.user) async def _horoscope(self, ctx, *, sign: str): - """Retrieves today's horoscope for a zodiac sign. + """ + Retrieves today's horoscope for a zodiac sign. Works with both signs and birthdays. Make sure to do Month/Day. Western Zodiac: @@ -43,12 +52,8 @@ async def _horoscope(self, ctx, *, sign: str): [p]horo daily, virgo [p]horo whatever, virgo [p]horo chinese, 1901 - [p]horo love, 02/10""" - option = { - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " - "AppleWebKit/537.36 (KHTML, lnamee Gecko) " - "Chrome/67.0.3396.99 Safari/537.36" - } + [p]horo love, 02/10 + """ signs = [ "aries", "taurus", @@ -83,7 +88,8 @@ async def _horoscope(self, ctx, *, sign: str): "chinese": "http://www.horoscope.com/us/horoscopes/chinese/horoscope-chinese-daily-today.aspx?sign=", } regex = [ - r"([^`]*?)<\/strong> - ([^`]*?)\n", + r"<\/strong> - ([^`]*?)\n", + r"\w+\s\d+,\s\d+", ] try: horos = sign.split(", ") @@ -103,11 +109,12 @@ async def _horoscope(self, ctx, *, sign: str): uri = horo_styles[style] sign_num = str(chinese_signs.index(sign) + 1) uir = uri + sign_num - async with self.session.get(uir, headers=option) as resp: + async with self.session.get(uir, headers=self.headers) as resp: test = str(await resp.text('ISO-8859-1')) msg = re.findall(regex[0], test)[0] - msg_content = msg[2].replace("
", "") - msg = msg_content + " - " + msg[1] + date = re.findall(regex[1], test)[0] + msg_content = msg.replace("", "") + msg = msg_content + " - " + date await ctx.send( "Today's chinese horoscope for the one" " born in the year of the {} is:\n".format(sign) + box(msg) @@ -125,11 +132,12 @@ async def _horoscope(self, ctx, *, sign: str): sign_num = str(signs.index(sign) + 1) sign = sign.title() uir = uri + sign_num - async with self.session.get(uir, headers=option) as resp: + async with self.session.get(uir, headers=self.headers) as resp: test = str(await resp.text('ISO-8859-1')) msg = re.findall(regex[0], test)[0] - msg_content = msg[2].replace("", "") - msg = msg_content + " - " + msg[1] + date = re.findall(regex[1], test)[0] + msg_content = msg.replace("", "") + msg = msg_content + " - " + date if style == "love": await ctx.send( "Today's love horoscope for **{}** is:\n".format(sign) + box(msg) @@ -201,7 +209,6 @@ async def _cookie(self, ctx): r"3\)<\/strong><\/a>([^`]*?)<\/div>", ] url = "http://www.fortunecookiemessage.com" - await self.file_check() async with self.session.get(url, headers={"encoding": "utf-8"}) as resp: test = str(await resp.text('ISO-8859-1')) fortune = re.findall(regex[0], test) @@ -212,59 +219,23 @@ async def _cookie(self, ctx): info = re.findall(regex[4], test) info[0] = html.unescape(info[0]) dailynum = re.findall(regex[5], test) - self.fortune_process(fortune[0]) - await ctx.send("Your fortune is:", file=discord.File(str(bundled_data_path(self) / "cookie-edit.png"))) + img_png = self.fortune_process(fortune[0]) + await ctx.send("Your fortune is:", file=discord.File(img_png, f"cookie_{ctx.author.id}.png")) await ctx.send("\n" + title[1] + info[1] + "\n" + title[2] + dailynum[0]) - os.remove(str(bundled_data_path(self) / "cookie-edit.png")) - - async def file_check(self): - urls = [ - "https://images-2.discordapp.net/.eJwNwcENwyAMAMBdGABDCWCyDSKIoCYxwuZVdff27qPWvNSuTpHBO8DRudA8NAvN3Kp" - "uRO2qeXTWhW7IIrmcd32EwQbjMCRMaJNxPmwILxcRg_9Da_yWYoQ3dV5z6fE09f0BC6EjAw.B0sII_QLbL9kJo6Zbb4GuO4MQNw", - "https://cdn.discordapp.com/attachments/218222973557932032/240223136447070208/FortuneCookieNF.ttf", - ] - option = { - "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0)" - " Gecko/20100101 Firefox/40.1" - } - if os.path.exists(str(bundled_data_path(self) / "cookie.png")): - async with self.session.get(urls[0], headers=option) as resp: - test = await resp.read() - meow = False - with open(str(bundled_data_path(self) / "cookie.png"), "rb") as e: - if len(test) != len(e.read()): - meow = True - if meow: - with open(str(bundled_data_path(self) / "cookie.png"), "wb") as f: - f.write(test) - elif not os.path.exists(str(bundled_data_path(self) / "cookie.png")): - async with self.session.get(urls[0], headers=option) as resp: - test = await resp.read() - with open(str(bundled_data_path(self) / "cookie.png"), "wb") as f: - f.write(test) - if not os.path.exists(str(bundled_data_path(self) / "FortuneCookieNF.ttf")): - async with self.session.get(urls[1], headers=option) as resp: - test = await resp.read() - with open(str(bundled_data_path(self) / "FortuneCookieNF.ttf"), "wb") as f: - f.write(test) + @commands.is_owner() @commands.guild_only() - @commands.command(name="font") + @commands.command(name="tsujiurafont") @commands.cooldown(10, 60, commands.BucketType.user) async def _font(self, ctx, url: str = None): """Allows you to set the font that the fortune cookies are shown in. Only accepts ttf.""" - option = { - "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0)" - " Gecko/20100101 Firefox/40.1" - } - if url is None: - url = "https://cdn.discordapp.com/attachments/218222973557932032/240223136447070208/FortuneCookieNF.ttf" + url = "https://github.com/Aioxas/ax-cogs/blob/V3.5/horoscope/data/FortuneCookieNF.ttf" if os.path.isfile(str(bundled_data_path(self) / "FortuneCookieNF.ttf")): return else: - async with self.session.get(url, headers=option) as resp: + async with self.session.get(url, headers=self.headers) as resp: test = await resp.read() with open(str(bundled_data_path(self) / "FortuneCookieNF.ttf"), "wb") as f: f.write(test) @@ -274,15 +245,18 @@ async def _font(self, ctx, url: str = None): await ctx.send("Font has been saved") def fortune_process(self, fortune): - img = Image.open(str(bundled_data_path(self) / "cookie.png")) - draw = ImageDraw.Draw(img) - font = ImageFont.truetype(str(bundled_data_path(self) / "FortuneCookieNF.ttf"), 15) - line = fortune.split() - sep = " " - line1 = sep.join(line[:5]) - line2 = sep.join(line[5:10]) - line3 = sep.join(line[10:]) - draw.text((134, 165), line1, (0, 0, 0), font=font, align="center") - draw.text((134, 180), line2, (0, 0, 0), font=font, align="center") - draw.text((134, 195), line3, (0, 0, 0), font=font, align="center") - img.save(str(bundled_data_path(self) / "cookie-edit.png")) + with Image.open(str(bundled_data_path(self) / "cookie.png")) as img: + draw = ImageDraw.Draw(img) + font = ImageFont.truetype(str(bundled_data_path(self) / "FortuneCookieNF.ttf"), 15) + line = fortune.split() + sep = " " + line1 = sep.join(line[:5]) + line2 = sep.join(line[5:10]) + line3 = sep.join(line[10:]) + draw.text((134, 165), line1, (0, 0, 0), font=font, align="center") + draw.text((134, 180), line2, (0, 0, 0), font=font, align="center") + draw.text((134, 195), line3, (0, 0, 0), font=font, align="center") + img_buffer = BytesIO() + img.save(img_buffer, format='PNG') + img_buffer.seek(0) + return img_buffer diff --git a/horoscope/info.json b/horoscope/info.json index 0dbc943..845ca0b 100644 --- a/horoscope/info.json +++ b/horoscope/info.json @@ -3,13 +3,8 @@ "install_msg": "Thanks for installing my cog. \n[p]help Horoscope should be enough. If not [p]help horo, [p]help tsujiura should.", "name": "horoscope", "short": "Zodiac and Chinese Horoscope and Fortune Cookie cog", - "requirements": [ - "Pillow" - ], - "tags": [ - "Utilites", - "Fun" - ], + "requirements": ["Pillow"], + "tags": ["horoscope", "fortune"], "description": "You can check your love and daily horoscope, as well as chinese horoscope. Random fortune cookie included.", "type": "COG" } diff --git a/longcat/__init__.py b/longcat/__init__.py index 108bcf5..f895ab8 100644 --- a/longcat/__init__.py +++ b/longcat/__init__.py @@ -1,7 +1,9 @@ from redbot.core import commands from .longcat import Longcat +__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users." -def setup(bot: commands.Bot): + +async def setup(bot: commands.Bot): cog = Longcat(bot) - bot.add_cog(cog) + await bot.add_cog(cog) diff --git a/longcat/info.json b/longcat/info.json index feace75..3e0eead 100644 --- a/longcat/info.json +++ b/longcat/info.json @@ -4,6 +4,6 @@ "NAME" : "longcat", "SHORT" : "All hail Longcat. Based on canapin's longcat js command.", "REQUIREMENTS" : ["Pillow"], - "TAGS" : ["Fun"], + "TAGS" : ["longcat", "fun"], "DESCRIPTION" : "Longcats man. Looooongcats" } diff --git a/longcat/longcat.py b/longcat/longcat.py index 9da63f7..392dddd 100644 --- a/longcat/longcat.py +++ b/longcat/longcat.py @@ -1,16 +1,19 @@ -import os -import time import discord +import io from PIL import Image +import random from redbot.core import commands from redbot.core.data_manager import bundled_data_path - from redbot.core.bot import Red -BaseCog = getattr(commands, "Cog", object) +class Longcat(commands.Cog): + """Longcat is long.""" + + async def red_delete_data_for_user(self, **kwargs): + """Nothing to delete.""" + return -class Longcat(BaseCog): def __init__(self, bot: Red): self.bot = bot @@ -21,6 +24,7 @@ def __init__(self, bot: Red): @commands.command(aliases=nreow) async def cat(self, ctx): + """Longcat is long. Use more "a" characters in the command to make a longer cat.""" # we grab the length of the used prefix and add one letter c if str(ctx.message.content.split(ctx.prefix)[1]).startswith("ny"): len_prefix = len(ctx.prefix) + 2 @@ -45,8 +49,8 @@ async def cat(self, ctx): for im in the_cat: cat.paste(im, (x_offset, 0)) x_offset += im.size[0] - # I'm giving it a name based on a timestamp, this prevents future problems - litter_box = str(time.time()).split(".")[0] + ".png" - cat.save(bundled_data_path(self) / litter_box) - await ctx.send(file=discord.File(fp=str((bundled_data_path(self) / litter_box)))) - os.remove(bundled_data_path(self) / litter_box) + cat_image_file_object = io.BytesIO() + cat.save(cat_image_file_object, format="png") + cat_image_file_object.seek(0) + cat_image_final = discord.File(fp=cat_image_file_object, filename=f"{random.randint(25000,99999)}_longcat.png") + await ctx.send(file=cat_image_final) diff --git a/loot/__init__.py b/loot/__init__.py index 4f56ef2..4c1d3aa 100644 --- a/loot/__init__.py +++ b/loot/__init__.py @@ -1,6 +1,8 @@ from redbot.core import commands from .loot import Loot +__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users." -def setup(bot: commands.Bot): - bot.add_cog(Loot(bot)) + +async def setup(bot: commands.Bot): + await bot.add_cog(Loot(bot)) diff --git a/loot/info.json b/loot/info.json index 87f98a5..0d893b9 100644 --- a/loot/info.json +++ b/loot/info.json @@ -4,6 +4,6 @@ "NAME" : "Loot", "SHORT" : "Keeping tabs on who paid for loot", "REQUIREMENTS" : [], - "TAGS" : ["Utilities"], + "TAGS" : ["utility", "loot", "tracking"], "DESCRIPTION" : "Keeping tabs on who paid for loot" } diff --git a/loot/loot.py b/loot/loot.py index 2569d8f..1fe7510 100644 --- a/loot/loot.py +++ b/loot/loot.py @@ -3,10 +3,13 @@ from redbot.core import Config, commands from redbot.core.bot import Red -BaseCog = getattr(commands, "Cog", object) +class Loot(commands.Cog): + """Keep track of text-based items.""" -class Loot(BaseCog): + async def red_delete_data_for_user(self, **kwargs): + """Nothing to delete.""" + return default_guild_settings = {} @@ -15,26 +18,26 @@ def __init__(self, bot: Red): self._loot = Config.get_conf(self, 9741981201) self._loot.register_guild(**self.default_guild_settings) - @commands.group(pass_context=True) + @commands.group() async def loot(self, ctx): """Loot related commands""" if ctx.invoked_subcommand is None: await ctx.send_help() - @loot.command(pass_context=True) + @loot.command() async def add(self, ctx, name: str, char: str, price: int): """Adds players and amounts paid to an item""" name = name.lower() guild = ctx.guild loot = await self._loot.guild(guild).all() if name not in loot: - await ctx.send("item doesn't exist, please use [p]loot create first") + await ctx.send(f"Item doesn't exist, please use `{ctx.prefix}loot create` first") return loot[name][char] = price await ctx.send("{} paid {} for {}".format(char, price, name)) await self._loot.guild(guild).set(loot) - @loot.command(pass_context=True) + @loot.command() async def create(self, ctx, name: str): """Creates an item in the current guild.""" name = name.lower() @@ -47,7 +50,7 @@ async def create(self, ctx, name: str): await ctx.send("{} has been added.".format(name)) await self._loot.guild(guild).set(loot) - @loot.command(pass_context=True) + @loot.command() async def info(self, ctx, name: str): """Shows who has invested in the item""" name = name.lower() @@ -67,21 +70,21 @@ async def info(self, ctx, name: str): embed.add_field(name="__Price Paid__", value=gold) await ctx.send(embed=embed) - @loot.command(pass_context=True) + @loot.command() async def list(self, ctx): """Shows existing loot in the current guild""" guild = ctx.guild loot = await self._loot.guild(guild).all() if len(loot) < 1: await ctx.send( - "No items have been created for this guild yet, please create some using [p]item create" + f"No items have been created for this guild yet, please create some using `{ctx.prefix}item create" " first, thanks" ) return items = loot.keys() await ctx.send("Here are this guild's items:\n{}".format("\n".join(items))) - @loot.command(pass_context=True, hidden=True) + @loot.command(hidden=True) async def remove(self, ctx, name: str, char: str = None): """Deletes existing characters in an item or items""" name = name.lower() @@ -89,8 +92,8 @@ async def remove(self, ctx, name: str, char: str = None): loot = await self._loot.guild(guild).all() if name not in loot.keys(): await ctx.send( - "Please make sure that the name is spelled correctly and " - "that you can find it in [p]loot list" + f"Please make sure that the name is spelled correctly and " + "that you can find it in `{ctx.prefix}loot list`" ) return if char is None: diff --git a/lootbox/__init__.py b/lootbox/__init__.py index b8c68fc..f07dac0 100644 --- a/lootbox/__init__.py +++ b/lootbox/__init__.py @@ -1,6 +1,8 @@ from redbot.core import commands from .lootbox import Lootbox +__red_end_user_data_statement__ = "This cog does not persistently store data or metadata about users." -def setup(bot: commands.Bot): - bot.add_cog(Lootbox(bot)) + +async def setup(bot: commands.Bot): + await bot.add_cog(Lootbox(bot)) diff --git a/lootbox/info.json b/lootbox/info.json index c69be32..6e82488 100644 --- a/lootbox/info.json +++ b/lootbox/info.json @@ -4,6 +4,6 @@ "NAME" : "Lootbox", "SHORT" : "Simulate lootboxes", "REQUIREMENTS" : ["numpy"], - "TAGS" : ["fun"], + "TAGS" : ["lootbox", "simulate", "simulation"], "DESCRIPTION" : "Create and simulate lootboxes. The more you add to it, the more precise the simulations will be. (Not accurate to the tiniest details)" } diff --git a/lootbox/lootbox.py b/lootbox/lootbox.py index 5383621..75eefac 100644 --- a/lootbox/lootbox.py +++ b/lootbox/lootbox.py @@ -4,10 +4,13 @@ from redbot.core import Config, checks, commands from redbot.core.bot import Red -BaseCog = getattr(commands, "Cog", object) +class Lootbox(commands.Cog): + """Create and simulate lootboxes.""" -class Lootbox(BaseCog): + async def red_delete_data_for_user(self, **kwargs): + """Nothing to delete.""" + return default_guild_settings = {"boxes": {}} @@ -17,13 +20,13 @@ def __init__(self, bot: Red): self._lootbox.register_guild(**self.default_guild_settings) - @commands.group(pass_context=True) + @commands.group() async def box(self, ctx): """Box related commands""" if ctx.invoked_subcommand is None: await ctx.send_help() - @box.command(pass_context=True) + @box.command() async def add(self, ctx, name: str, content: str, multi: int = None): """Adds items to a box Usage: @@ -35,7 +38,7 @@ async def add(self, ctx, name: str, content: str, multi: int = None): boxes = await self._lootbox.guild(guild).boxes() counter = 0 if name not in boxes: - await ctx.send("Box doesn't exist, please use [p]box create first") + await ctx.send(f"Box doesn't exist, please use `{ctx.prefix}box create` first") return if ", " in content: content = content.split(", ") @@ -58,7 +61,7 @@ async def add(self, ctx, name: str, content: str, multi: int = None): ) await self._lootbox.guild(guild).boxes.set(boxes) - @box.command(pass_context=True) + @box.command() async def create(self, ctx, name: str, output: int, *, content: str): """Creates a box in the current server [p]box create winter 6 Key, Unsealing Charm, Black Padded Coat, Infernal Horn""" @@ -85,13 +88,13 @@ async def create(self, ctx, name: str, output: int, *, content: str): await self._lootbox.guild(guild).boxes.set(boxes) @checks.mod_or_permissions() - @box.group(pass_context=True) + @box.group() async def edit(self, ctx): """Allows editing of box names or output""" if ctx.invoked_subcommand is None: await ctx.send_help() - @edit.command(pass_context=True) + @edit.command() async def name(self, ctx, name: str, newname: str): """Allows editing of the boxes' name winter = current name @@ -102,8 +105,8 @@ async def name(self, ctx, name: str, newname: str): boxes = await self._lootbox.guild(guild).boxes() if name not in boxes: await ctx.send( - "Box doesn't exist, please make sure the spelling is correct and" - " that it's found in [p]box list" + f"Box doesn't exist, please make sure the spelling is correct and" + f" that it's found in `{ctx.prefix}box list`" ) return newname = newname.lower() @@ -114,7 +117,7 @@ async def name(self, ctx, name: str, newname: str): await ctx.send("{} has been renamed to {}".format(name, newname)) await self._lootbox.guild(guild).boxes.set(boxes) - @edit.command(pass_context=True) + @edit.command() async def output(self, ctx, name: str, output: int): """Allows adjusting how many items come out of the simulated lootbox @@ -124,15 +127,15 @@ async def output(self, ctx, name: str, output: int): boxes = await self._lootbox.guild(guild).boxes() if name not in boxes: await ctx.send( - "Box doesn't exist, please make sure the spelling is correct and" - " that it's found in [p]box list" + f"Box doesn't exist, please make sure the spelling is correct and" + f" that it's found in `{ctx.prefix}box list`" ) return boxes[name]["output"] = output await ctx.send("{} box's output has changed to {}".format(name, output)) await self._lootbox.guild(guild).boxes.set(boxes) - @box.command(pass_context=True) + @box.command() async def info(self, ctx, name: str): """Shows info on the box, it's contents and the probability of getting an item""" @@ -141,8 +144,8 @@ async def info(self, ctx, name: str): boxes = await self._lootbox.guild(guild).boxes() if name not in boxes: await ctx.send( - "Please make sure that the name is spelled correctly and " - "that you can find it in [p]box list" + f"Box doesn't exist, please make sure the spelling is correct and" + f" that it's found in `{ctx.prefix}box list`" ) return outputs = {} @@ -176,14 +179,14 @@ async def info(self, ctx, name: str): await ctx.send(embed=embed) - @box.command(pass_context=True) + @box.command() async def list(self, ctx): """Shows existing boxes in the current server""" guild = ctx.guild boxes = await self._lootbox.guild(guild).boxes() if len(boxes) < 1: await ctx.send( - "No boxes have been created for this server yet, please create some using [p]box create" + f"No boxes have been created for this server yet, please create some using `{ctx.prefix}box create`" " first, thanks" ) return @@ -191,7 +194,7 @@ async def list(self, ctx): await ctx.send("Here are this server's boxes:\n{}".format("\n".join(boxes))) @checks.is_owner() - @box.command(pass_context=True) + @box.command() async def remove(self, ctx, name: str): """Deletes existing boxes""" name = name.lower() @@ -199,15 +202,15 @@ async def remove(self, ctx, name: str): boxes = await self._lootbox.guild(guild).boxes() if name not in boxes: await ctx.send( - "Please make sure that the name is spelled correctly and " - "that you can find it in [p]box list" + f"Please make sure that the name is spelled correctly and " + f"that you can find it in `{ctx.prefix}box list`" ) return boxes.pop(name, None) await self._lootbox.guild(guild).boxes.set(boxes) await ctx.send("Box has been removed") - @box.command(pass_context=True) + @box.command() async def sim(self, ctx, name: str, item: str = None): """Simulates the opening of a box (It won't be as accurate as an actual lootbox) If an item is always in a box, put the item name spelled correctly, @@ -219,8 +222,8 @@ async def sim(self, ctx, name: str, item: str = None): boxes = await self._lootbox.guild(guild).boxes() if name not in boxes: await ctx.send( - "Please make sure that the name is spelled correctly and " - "that you can find it in [p]box list" + f"Please make sure that the name is spelled correctly and " + f"that you can find it in `{ctx.prefix}box list`" ) return box = list(boxes[name]["content"].keys()) @@ -228,7 +231,7 @@ async def sim(self, ctx, name: str, item: str = None): values = list(boxes[name]["content"].values()) value = sum(values) if sum(values) == 0: - ctx.send("add some items to your box first using [p]box add