Source code for discord.ext.forms.reactions

from discord.ext import commands
import discord
from typing import List, Union
import typing
import asyncio
import re
[docs]class ReactionForm(object): # I don't like subclassing shut up """ The Reaction input object. ... Parameters ---------- message : discord.Message The message of the reaction form object. bot : typing.Union[discord.CLient, discord.ext.commands.Bot] The bot being used for the form. user : typing.Union[discord.Member, discord.User] The member or user who should be able to use the form. If none, the form will be open to anyone. """ def __init__(self, message:discord.Message, bot: Union[discord.Client, commands.Bot],user:Union[discord.Member, discord.User]=None): self._msg = message self._bot = bot self._reactions = {} self.timeout = 120 self.persist = False self._user = user
[docs] def set_timeout(self,timeout:int) -> None: self.timeout = timeout
[docs] def add_reaction(self,reaction:discord.Emoji,result) -> dict: """Adds a question to the form. Returns the full list of questions the form has, including the newly added one. The questions are held in dictionaries containing the `question` and optionally `type` keys. The `question` key contains the question as a string, and the `type` key contains the input validation (if any is specified) """ self._reactions[reaction] = result return self._reactions
[docs] async def set_color(self,color:str) -> None: """Sets the color of the form embeds.""" match = re.search(r'0x(\d|f){6}', str) if not match: raise InvalidColor(f"{color} is invalid. Be sure to use colors such as '0xffffff'") self._color = color
[docs] async def start(self) -> dict: """Starts the form in the specified channel. If none is specified, the channel will be fetched from the `context` parameter of the form's initialization.""" message = self._msg rl = [] for i in self._reactions.keys(): await message.add_reaction(str(i)) rl.append(str(i)) await asyncio.sleep(0.5) for i in message.reactions: rl.append(str(i.emoji)) def check(r): if self._user is not None: return r.message_id == message.id and str(r.emoji) in rl and r.user_id == self._user.id else: return r.message_id == message.id and str(r.emoji) in rl try: r = await self._bot.wait_for('raw_reaction_add',check=check,timeout=self.timeout) except: return await message.edit("Timeout!") return self._reactions[str(r.emoji)]
[docs]class ReactionMenu(object): def __init__(self, ctx:discord.ext.commands.Context, embeds:List[discord.Embed]): self._ctx = ctx self._embeds = embeds self.timeout = 120 self._mappings = {} self.removereaction = True
[docs] def addemoji(self, emoji:str, page:int) -> bool: """Adds an emoji/page mapping to your menu. Parameters ---------- emoji : str The emoji to be used as a string. Custom emoji are supported. page : int The page to be mapped. Uses normal indexing (e.g. 1 is the first page) Returns ------- bool : The result of the emoji being added. False means an error occurred (most likely you tried to add an emoji that was already set) and True means that everything was successful. """ int(page) if emoji in ["◀","⏹","▶"]: return False self._mappings[emoji] = page return True
[docs] async def start(self, channel=None): current = 0 ctx = self._ctx embeds = self._embeds cemojis = self._mappings if not channel: if not ctx: raise TypeError("start() missing 1 required positional argument: 'channel' or class 'ctx'") channel = ctx.channel msg = await ctx.send(embed=embeds[0]) await msg.add_reaction("◀") await msg.add_reaction("⏹") await msg.add_reaction("▶") emojis = ["◀","⏹","▶"] for e in cemojis.keys(): await msg.add_reaction() while True: def check(r): return str(r.emoji) in emojis and r.user_id == ctx.author.id try: r = await ctx.bot.wait_for('raw_reaction_add',check=check,timeout=self.timeout) except asyncio.TimeoutError: return await msg.edit("Timeout!") if str(r.emoji) in emojis: if str(r.emoji) == emojis[0]: if current != 0: await msg.edit(embed=embeds[current-1]) current = current-1 if str(r.emoji) == emojis[1]: await msg.clear_reactions() break if str(r.emoji) == emojis[2]: if current != len(embeds)-1: await msg.edit(embed=embeds[current+1]) current += 1 if str(r.emoji) in cemojis.keys(): await msg.edit(embed=embeds[cemojis[str(r.emoji)]]-1) current = cemojis[str(r.emoji)] if self.removereaction: await msg.remove_reaction(r.emoji,ctx.author)
""" # Soon... class NeoPaginator(object): def __init__(self, limit_per_page:int, entries:List): self._limit = limit_per_page self._entries = entries self.pages = [] page = [] for i in entries: if (entries.index(i)+1) % limit_per_page == 0: self.pages.append(page) page = [] else: page.append(i) """
[docs]class InvalidColor(Exception): pass