async def getInput(self, ctx: commands.Context, turn): position = MessagePredicate.contained_in( self.options, channel=ctx.channel, user=turn) try: choice = await ctx.bot.wait_for("message", check=position, timeout=5.0) except asyncio.TimeoutError: return None return int(choice.content)
async def wait_for_author_choice(ctx: Context, valid_choices: List[str], timeout: int = 30): predicate = MessagePredicate.contained_in(ctx=ctx, user=ctx.author, collection=valid_choices) try: await ctx.bot.wait_for("message", check=predicate, timeout=timeout) except asyncio.TimeoutError: return predicate.result return predicate.result
async def wait_for_dm_choice(bot: Red, dm: discord.DMChannel, valid_choices: List[str], timeout: int = 30): predicate = MessagePredicate.contained_in(channel=dm, ctx=None, user=dm.recipient, collection=valid_choices) try: await bot.wait_for("message", check=predicate, timeout=timeout) except asyncio.TimeoutError: return predicate.result return predicate.result
async def get_style_data(self, ctx, style_type: Literal["drawers", "masks"]): mapper = { "drawers": { "message": DEFAULT_DRAWER_MESSAGE, "kwarg_key": "module_drawer", }, "masks": {"message": DEFAULT_MASK_MESSAGE, "kwarg_key": "color_mask"}, } pred = lambda x: MessagePredicate.contained_in(list(map(str, range(1, x + 1)))) await ctx.maybe_send_embed(mapper[style_type]["message"]) try: check = pred(len(self.styles[style_type])) message = await self.bot.wait_for("message", check=check, timeout=100) except asyncio.TimeoutError: await ctx.send("You took too long to respond, please start over.") return False else: return {mapper[style_type]["kwarg_key"]: self.styles[style_type][int(message.content)]}
async def memberships(self, ctx): """Displays a list of server/global memberships.""" data = await super().get_data(ctx) settings = await data.all() memberships = list(settings["Memberships"].keys()) if not memberships: return await ctx.send(_("There are no memberships to display.")) await ctx.send(_("Which of the following memberships would you like to know more " "about?\n`{}`.").format(utils.fmt_join(memberships))) pred = MessagePredicate.contained_in(memberships, ctx=ctx) try: membership = await ctx.bot.wait_for('message', timeout=25.0, check=pred) except asyncio.TimeoutError: return await ctx.send(_("No Response.")) games = settings["Games"] perks = settings["Memberships"][membership.content] playable = [x for x, y in games.items() if y['Access'] <= perks['Access']] reqs = _("Credits: {Credits}\nRole: {Role}\nDays on Server: {DOS}").format(**perks) color = utils.color_lookup(perks['Color']) desc = _("Access: {Access}\n" "Cooldown Reduction: {Reduction}\n" "Bonus Multiplier: {Bonus}x\n" "Color: {Color}").format(**perks) info = _("Memberships are automatically assigned to players when they meet it's " "requirements. If a player meets multiple membership requirements, they will be " "assigned the one with the highest access level. If a membership is assigned " "manually however, then the updater will skip that player until their membership " "has been revoked.") # Embed embed = discord.Embed(colour=color, description=desc) embed.title = membership.content embed.add_field(name=_("Playable Games"), value='\n'.join(playable)) embed.add_field(name=_("Requirements"), value=reqs) embed.set_footer(text=info) await ctx.send(embed=embed)
async def vset_cards_del(self, ctx): """ Delete a card """ async with self.config.guild(ctx.guild).cards() as cards: if not cards: await ctx.send(warning("No cards defined.")) return pages = self.format_list(cards) for page in pages: await ctx.send(box(page)) await ctx.send("Please choose the number of the message to delete.") pred = MessagePredicate.contained_in([str(i + 1) for i in range(len(cards))], ctx=ctx) try: await self.bot.wait_for("message", check=pred, timeout=60) except asyncio.TimeoutError: await ctx.send("Took too long, cancelled.") return del cards[pred.result] await ctx.tick()
async def economysetup(self, ctx: commands.Context): """ Go through the initial setup process. """ currency = await bank.get_currency_name(ctx.guild) pred = MessagePredicate.yes_or_no(ctx) await ctx.send( "Do you want the winner to have a specific role? (yes/no)") try: await self.bot.wait_for("message", timeout=30, check=pred) except asyncio.TimeoutError: return await ctx.send("You took too long. Try again, please.") if pred.result: await ctx.send("What role should it be?") role = MessagePredicate.valid_role(ctx) try: await self.bot.wait_for("message", timeout=30, check=role) except asyncio.TimeoutError: return await ctx.send("You took too long. Try again, please.") required = role.result await self.config.guild(ctx.guild).required.set(str(required)) await ctx.send( f"What amount of {currency} do you want me to give away? (whole number)" ) predi = MessagePredicate.valid_int(ctx) try: await self.bot.wait_for("message", timeout=30, check=predi) except asyncio.TimeoutError: return await ctx.send("You took too long. Try again, please.") amount = predi.result await self.config.guild(ctx.guild).amount.set(amount) await ctx.send( "I will send a few options of the raffle message. Please, choose number of the one you like the most." "```cs\nWrite '1' for this:```It's time for our {amount} giveaway!\nCongratulations {winner}! :tada: You just won {amount} {currency_name}!" "```cs\nWrite '2' for this:```Congratulations {winner}! :tada: You just won {amount} {currency_name}!" "```cs\nWrite '3' for this:```{winner} just won {amount} {currency_name}! :tada:" "```cs\nWrite '4' for a custom message.```") msg_list = ["1", "2", "3", "4"] predic = MessagePredicate.contained_in(msg_list, ctx) try: await self.bot.wait_for("message", timeout=30, check=predic) except asyncio.TimeoutError: return await ctx.send("You took too long. Try again, please.") msg = msg_list[predic.result] await self.config.guild(ctx.guild).msg.set(int(msg)) if int(msg) == 4: await ctx.send( "What's your message? Available parametres are: `{winner}`, `{amount}`, `{currency}`, `{server}`" ) def check(m): return m.author == ctx.author and m.channel == ctx.channel try: answer = await self.bot.wait_for("message", timeout=120, check=check) except asyncio.TimeoutError: return await ctx.send("You took too long. Try again, please.") custom = answer.content await self.config.guild(ctx.guild).custom.set(custom) await ctx.send( f"You have finished the setup! Command `{ctx.clean_prefix}economyraffle` is ready to be used. *Please note that scheduler isn't part of this cog.*" )
async def update_profile(bot, user_data: dict, author: discord.User): msg = await author.send( "What country are you from (Enter the number next to the country)?") country_data = WorldData.get("country", {}) validcountries = sorted( list(value.get("name") for _, value in country_data.items())) desc = "" valid_county_list = [] for index, value in enumerate(validcountries, start=1): desc += f"{index}. {value}\n" valid_county_list.append(str(index)) pages = [ box(page, lang="md") for page in list(pagify(desc, shorten_by=20)) ] ctx = namedtuple("Context", "author me bot send channel") new_ctx = ctx(author, bot.user, bot, author.send, msg.channel) menu_task = asyncio.create_task( menu(new_ctx, pages, DEFAULT_CONTROLS, timeout=180)) country = None pred_check = MessagePredicate.contained_in(valid_county_list, ctx=new_ctx) while not country: with contextlib.suppress(asyncio.TimeoutError): await bot.wait_for("message", timeout=30.0, check=pred_check) country = (valid_county_list[pred_check.result] if pred_check.result is not None else None) with contextlib.suppress(Exception): menu_task.cancel() user_data["country"] = validcountries[int(country) - 1] cached_country = user_data["country"].lower().strip() if cached_country: country_data = WorldData.get("country", {}) region = country_data.get(cached_country, {}).get("region") country_timezones = country_data.get(cached_country, {}).get("timezones") user_data["subzone"] = country_data.get(cached_country, {}).get("subregion") else: region = None country_timezones = None continent_data = sorted(CONTINENT_DATA.values()) if not region: await author.send("Which zone are you from?") embed = discord.Embed(title="Pick a number that matches your zone") desc = "" valid_continent_list = [] for index, value in enumerate(continent_data, start=1): desc += f"{index}. {value.title()}\n" valid_continent_list.append(str(index)) embed.description = box(desc, lang="md") await author.send(embed=embed) zone = None pred_check = MessagePredicate.contained_in(valid_continent_list, ctx=new_ctx) while not zone: with contextlib.suppress(asyncio.TimeoutError): await bot.wait_for("message", timeout=30.0, check=pred_check) zone = (valid_continent_list[pred_check.result] if pred_check.result is not None else None) user_data["zone"] = continent_data[int(zone) - 1] else: user_data["zone"] = country_data.get(cached_country, {}).get("region", None) user_data["language"] = None if country_timezones and len(country_timezones) > 1: country_timezones_dict = { str(i): key for i, key in enumerate(country_timezones, start=1) } country_timezones = sorted(country_timezones_dict.values()) await author.send( "There are multiple timezone for your country, please pick the one that match yours?" ) embed = discord.Embed(title="Pick a number that matches your timezone") desc = "" valid_timezone_list = [] for index, value in enumerate(country_timezones, start=1): desc += f"{index}. {value.upper()}\n" valid_timezone_list.append(str(index)) embed.description = box(desc, lang="md") await author.send(embed=embed) timezone = None pred_check = MessagePredicate.contained_in(valid_timezone_list, ctx=new_ctx) while not timezone: with contextlib.suppress(asyncio.TimeoutError): await bot.wait_for("message", timeout=30.0, check=pred_check) timezone = (valid_timezone_list[pred_check.result] if pred_check.result is not None else None) user_data["timezone"] = country_timezones[int(timezone) - 1] elif country_timezones and len(country_timezones) == 1: user_data["timezone"] = country_timezones[0] return user_data
async def qr(self, ctx: commands.Context, *, text: str): """Create a QR code from text. When you scan this QR code, it will take you to google with the text query, or the website if you provide a website. That's essentially how QR codes work. """ if len(text) > 250: await ctx.send("Please provide a sensible number of characters.") return qrc = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_L) qrc.add_data(text) pred = lambda x: MessagePredicate.contained_in(list(map(str, range(1, x + 1)))) await ctx.maybe_send_embed(DEFAULT_OPENING_MESSAGE.format(text)) try: result = await self.bot.wait_for("message", check=pred(3), timeout=100) except asyncio.TimeoutError: await ctx.send("You took too long to respond, please start over.") return else: result = int(result.content) qrc_kwargs = {} embed_kwargs = {"color": 16777215} if result == 1: for shade in ("background", "fill"): update = await self.get_colour_data(ctx, shade) if update is False: return if shade == "background": embed_kwargs["color"] = discord.Colour.from_rgb(*update["back_color"]) qrc_kwargs.update(update) if result == 2: qrc_kwargs["image_factory"] = styledpil.StyledPilImage for style_type in ("drawers", "masks"): update = await self.get_style_data(ctx, style_type) if update is False: return qrc_kwargs.update(update) confirmation_message = await ctx.maybe_send_embed("Generating QR code...") await ctx.trigger_typing() await asyncio.sleep(1) sender_kwargs = {} try: qrc = qrc.make_image(**qrc_kwargs) except DataOverflowError: sender_kwargs["content"] = "Failed to create a QR code for this text." else: buff = io.BytesIO() qrc.save(buff, "png") buff.seek(0) if await ctx.embed_requested(): embed = discord.Embed(**embed_kwargs) embed.set_image(url="attachment://qr.png") embed.set_author(name="Generated QR code") embed.add_field(name="Content", value=text) sender_kwargs["embed"] = embed sender_kwargs["file"] = discord.File(buff, filename="qr.png") finally: try: await confirmation_message.edit(**sender_kwargs) except (discord.HTTPException, TypeError): # TypeError raised because of nonjsonserializable discord.File object await ctx.send(**sender_kwargs)