Source code for discordSuperUtils.Paginator

import asyncio
from math import ceil

import discord

__all__ = ("generate_embeds", "EmojiError", "PageManager", "ButtonsPageManager")


[docs]def generate_embeds(list_to_generate, title, description, fields=25, color=0xff0000, string_format='{}'): num_of_embeds = ceil((len(list_to_generate) + 1) / fields) embeds = [ discord.Embed( title=f"{title} (Page 1/{num_of_embeds})", description=description, color=color ) ] for i in range(2, num_of_embeds + 1): embeds.append(discord.Embed( title=f"{title} (Page {i}/{num_of_embeds})", color=color ) ) embed_index = 0 for index, element in enumerate(list_to_generate): embeds[embed_index].add_field(name=f"**{index + 1}.**", value=string_format.format(element), inline=False) if (index + 1) % fields == 0: embed_index += 1 return embeds
class ButtonError(Exception): __slots__ = ()
[docs]class EmojiError(Exception): __slots__ = ()
[docs]class ButtonsPageManager: __slots__ = ("ctx", "messages", "timeout", "buttons", "public", "index", "button_color") def __init__(self, ctx, messages, timeout=60, buttons=None, public=False, index=0, button_color=None): self.ctx = ctx self.messages = messages self.timeout = timeout self.buttons = buttons if buttons is not None else ["⏪", "◀️", "▶️", "⏩"] self.public = public self.index = index self.button_color = button_color
[docs] async def run(self): if len(self.buttons) != 4: raise ButtonError(f"Passed {len(self.buttons)} buttons when 4 are needed.") self.index = 0 if not -1 < self.index < len(self.messages) else self.index from discord_components import ActionRow, Button, ButtonStyle, DiscordComponents DiscordComponents(self.ctx.bot) components = ActionRow( [ Button( style=self.button_color or ButtonStyle.red, label=button, custom_id=button ) for button in self.buttons ] ) message_to_send = self.messages[self.index] # message_to_send must be of type embed, sadly, discord_components breaks the Messageable.send method # And breaks the file parameter, too message = await self.ctx.send(embed=message_to_send, components=components) while True: try: interaction = await self.ctx.bot.wait_for('button_click', check=lambda i: i.message == message, timeout=30) if interaction.user.bot: continue if interaction.user != self.ctx.author and not self.public: continue except asyncio.TimeoutError: break if interaction.custom_id == self.buttons[0]: self.index = 0 elif interaction.custom_id == self.buttons[1]: if self.index > 0: self.index -= 1 elif interaction.custom_id == self.buttons[2]: if self.index < len(self.messages) - 1: self.index += 1 elif interaction.custom_id == self.buttons[3]: self.index = len(self.messages) - 1 message_to_send = self.messages[self.index] for button in components[0]: button.disabled = False if self.index == len(self.messages) - 1: components[0][2].disabled = True components[0][3].disabled = True if self.index == 0: components[0][0].disabled = True components[0][1].disabled = True await interaction.respond( type=7, # Cannot find a proper enum :) content="", embed=message_to_send, components=components )
[docs]class PageManager: __slots__ = ("ctx", "messages", "timeout", "emojis", "public", "index") def __init__(self, ctx, messages, timeout=60, emojis=None, public=False, index=0): self.ctx = ctx self.messages = messages self.timeout = timeout self.emojis = emojis if emojis is not None else ["⏪", "◀️", "▶️", "⏩"] self.public = public self.index = index
[docs] async def run(self): if len(self.emojis) != 4: raise EmojiError(f"Passed {len(self.emojis)} emojis when 4 are needed.") self.index = 0 if not -1 < self.index < len(self.messages) else self.index message_to_send = self.messages[self.index] if isinstance(message_to_send, discord.Embed): message = await self.ctx.send(embed=message_to_send) else: message = await self.ctx.send(message_to_send) for emoji in self.emojis: await message.add_reaction(emoji) while True: try: reaction, user = await self.ctx.bot.wait_for('reaction_add', check=lambda x, y: x.message == message, timeout=self.timeout) if user.bot: continue if user != self.ctx.author and not self.public: continue except asyncio.TimeoutError: break if reaction.emoji == self.emojis[0]: self.index = 0 elif reaction.emoji == self.emojis[1]: if self.index > 0: self.index -= 1 elif reaction.emoji == self.emojis[2]: if self.index < len(self.messages) - 1: self.index += 1 elif reaction.emoji == self.emojis[3]: self.index = len(self.messages) - 1 await message.remove_reaction(reaction.emoji, user) message_to_send = self.messages[self.index] if isinstance(message_to_send, discord.Embed): await message.edit(embed=message_to_send, content=None) else: await message.edit(content=message_to_send, embed=None)