mirror of https://github.com/stijndcl/didier
Leaderboard cleanup
parent
ca687956f6
commit
81a0d90a12
|
@ -1,5 +1,5 @@
|
|||
from data.embeds.xkcd import XKCDEmbed
|
||||
from data.menus import paginated_leaderboard
|
||||
from data.menus import leaderboards
|
||||
from decorators import help
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
|
|
|
@ -1,18 +1,12 @@
|
|||
from typing import Callable, Optional
|
||||
|
||||
from data.menus import paginated_leaderboard
|
||||
from decorators import help
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
|
||||
from data.menus import leaderboards
|
||||
from decorators import help
|
||||
from enums.help_categories import Category
|
||||
from enums.numbers import Numbers
|
||||
from functions import checks, xp
|
||||
from functions.database import currency, stats, poke, muttn
|
||||
import math
|
||||
import requests
|
||||
from functions import checks
|
||||
|
||||
|
||||
# TODO some sort of general leaderboard generation because all of them are the same
|
||||
class Leaderboards(commands.Cog):
|
||||
|
||||
def __init__(self, client):
|
||||
|
@ -20,29 +14,9 @@ class Leaderboards(commands.Cog):
|
|||
self.utilsCog = self.client.get_cog("Utils")
|
||||
|
||||
# Don't allow any commands to work when locked
|
||||
def cog_check(self, ctx):
|
||||
def cog_check(self, _):
|
||||
return not self.client.locked
|
||||
|
||||
def _generate_embed_data(self, entries: list,
|
||||
key_f: Callable = lambda x: x[0],
|
||||
data_f: Callable = lambda x: x[1],
|
||||
ignore_non_pos: bool = True) -> Optional[list[tuple]]:
|
||||
data = []
|
||||
for i, v in enumerate(sorted(entries, key=data_f, reverse=True)):
|
||||
entry_data = data_f(v)
|
||||
|
||||
# Leaderboard is empty
|
||||
if i == 0 and entry_data == 0 and ignore_non_pos:
|
||||
return None
|
||||
|
||||
# Ignore entries with no data
|
||||
if ignore_non_pos and entry_data <= 0:
|
||||
continue
|
||||
|
||||
data.append((key_f(v), f"{entry_data:,}", entry_data,))
|
||||
|
||||
return data
|
||||
|
||||
@commands.group(name="Leaderboard", aliases=["Lb", "Leaderboards"], case_insensitive=True, usage="[Categorie]*",
|
||||
invoke_without_command=True)
|
||||
@commands.check(checks.allowedChannels)
|
||||
|
@ -56,154 +30,48 @@ class Leaderboards(commands.Cog):
|
|||
|
||||
@leaderboard.command(name="Dinks", aliases=["Cash"], hidden=True)
|
||||
async def dinks(self, ctx):
|
||||
entries = currency.getAllRows()
|
||||
platDinks = currency.getAllPlatDinks()
|
||||
|
||||
# Take platinum dinks into account
|
||||
for i, user in enumerate(entries):
|
||||
if str(user[0]) in platDinks:
|
||||
# Tuples don't support assignment, cast to list
|
||||
user = list(user)
|
||||
user[1] += platDinks[str(user[0])] * Numbers.q.value
|
||||
entries[i] = user
|
||||
|
||||
data = self._generate_embed_data(entries, key_f=lambda x: x[0], data_f=lambda x: (float(x[1]) + float(x[3])))
|
||||
|
||||
if data is None:
|
||||
return await self.empty_leaderboard(ctx, "Dinks Leaderboard",
|
||||
"Er zijn nog geen personen met Didier Dinks.")
|
||||
|
||||
lb = paginated_leaderboard.Leaderboard(
|
||||
ctx=ctx, title="Dinks Leaderboard", data=data, fetch_names=True
|
||||
)
|
||||
|
||||
await lb.send(ctx)
|
||||
lb = leaderboards.DinksLeaderboard(ctx=ctx)
|
||||
await lb.send()
|
||||
|
||||
@leaderboard.command(name="Corona", hidden=True)
|
||||
async def corona(self, ctx):
|
||||
result = requests.get("https://disease.sh/v3/covid-19/countries").json()
|
||||
result.sort(key=lambda x: int(x["cases"]), reverse=True)
|
||||
|
||||
data = []
|
||||
for country in result:
|
||||
data.append((country["country"], f"{country['cases']:,}",))
|
||||
|
||||
lb = paginated_leaderboard.Leaderboard(
|
||||
ctx=ctx, title="Corona Leaderboard", data=data, highlight="Belgium",
|
||||
colour=discord.Colour.red()
|
||||
)
|
||||
|
||||
await lb.send(ctx)
|
||||
lb = leaderboards.CoronaLeaderboard(ctx=ctx)
|
||||
await lb.send()
|
||||
|
||||
@leaderboard.command(name="Bitcoin", aliases=["Bc"], hidden=True)
|
||||
async def bitcoin(self, ctx):
|
||||
users = currency.getAllRows()
|
||||
data = self._generate_embed_data(users, data_f=lambda x: round(float(x[8]), 8))
|
||||
|
||||
if data is None:
|
||||
return await self.empty_leaderboard(ctx, "Bitcoin Leaderboard",
|
||||
"Er zijn nog geen personen met Bitcoins.")
|
||||
|
||||
lb = paginated_leaderboard.Leaderboard(
|
||||
ctx=ctx, title="Bitcoin Leaderboard", data=data, fetch_names=True
|
||||
)
|
||||
|
||||
await lb.send(ctx)
|
||||
lb = leaderboards.BitcoinLeaderboard(ctx=ctx)
|
||||
await lb.send()
|
||||
|
||||
@leaderboard.command(name="Rob", hidden=True)
|
||||
async def rob(self, ctx):
|
||||
users = list(stats.getAllRows())
|
||||
data = self._generate_embed_data(users, data_f=lambda x: math.floor(float(x[4])))
|
||||
|
||||
if data is None:
|
||||
return await self.empty_leaderboard(ctx, "Rob Leaderboard",
|
||||
"Er heeft nog niemand Didier Dinks gestolen.")
|
||||
|
||||
lb = paginated_leaderboard.Leaderboard(
|
||||
ctx=ctx, title="Rob Leaderboard", data=data, fetch_names=True
|
||||
)
|
||||
|
||||
await lb.send(ctx)
|
||||
lb = leaderboards.RobLeaderboard(ctx=ctx)
|
||||
await lb.send()
|
||||
|
||||
@leaderboard.command(name="Poke", hidden=True)
|
||||
async def poke(self, ctx):
|
||||
entries = stats.getAllRows()
|
||||
blacklist = poke.getAllBlacklistedUsers()
|
||||
# Remove blacklisted users
|
||||
entries = list(filter(lambda x: x[0] not in blacklist, entries))
|
||||
|
||||
data = self._generate_embed_data(entries, data_f=lambda x: round(int(x[1])))
|
||||
if data is None:
|
||||
return await self.empty_leaderboard(ctx, "Poke Leaderboard", "Er is nog niemand getikt.")
|
||||
|
||||
lb = paginated_leaderboard.Leaderboard(
|
||||
ctx=ctx, title="Poke Leaderboard", data=data, fetch_names=True
|
||||
)
|
||||
|
||||
await lb.send(ctx)
|
||||
lb = leaderboards.PokeLeaderboard(ctx=ctx)
|
||||
await lb.send()
|
||||
|
||||
@leaderboard.command(name="Xp", aliases=["Level"], hidden=True)
|
||||
async def xp(self, ctx):
|
||||
entries = stats.getAllRows()
|
||||
data = self._generate_embed_data(entries, data_f=lambda x: round(int(x[12])))
|
||||
|
||||
def _format_entry(entry: int) -> str:
|
||||
return f"Level {xp.calculate_level(entry):,} | {entry:,} XP"
|
||||
|
||||
lb = paginated_leaderboard.Leaderboard(
|
||||
ctx=ctx, title="XP Leaderboard", data=data, fetch_names=True, format_f=_format_entry
|
||||
)
|
||||
|
||||
await lb.send(ctx)
|
||||
lb = leaderboards.XPLeaderboard(ctx=ctx)
|
||||
await lb.send()
|
||||
|
||||
@leaderboard.command(name="Messages", aliases=["Mc", "Mess"], hidden=True)
|
||||
async def messages(self, ctx):
|
||||
entries = stats.getAllRows()
|
||||
message_count = stats.getTotalMessageCount()
|
||||
|
||||
data = self._generate_embed_data(entries, data_f=lambda x: round(int(x[11])))
|
||||
|
||||
def _format_entry(entry: int) -> str:
|
||||
perc = round(entry * 100 / message_count, 2)
|
||||
return f"{entry:,} | {perc}%"
|
||||
|
||||
lb = paginated_leaderboard.Leaderboard(
|
||||
ctx=ctx, title="Messages Leaderboard", data=data, fetch_names=True, format_f=_format_entry
|
||||
)
|
||||
|
||||
await lb.send(ctx)
|
||||
lb = leaderboards.MessageLeaderboard(ctx=ctx)
|
||||
await lb.send()
|
||||
|
||||
@leaderboard.command(name="Muttn", aliases=["M", "Mutn", "Mutten"], hidden=True)
|
||||
async def muttn(self, ctx):
|
||||
entries = muttn.getAllRows()
|
||||
data = self._generate_embed_data(entries, data_f=lambda x: round(float(x[1]), 2))
|
||||
if data is None:
|
||||
return await self.empty_leaderboard(ctx, "Muttn Leaderboard", "Der zittn nog geen muttns in de server.")
|
||||
|
||||
def _format_entry(entry: float) -> str:
|
||||
return f"{entry}%"
|
||||
|
||||
lb = paginated_leaderboard.Leaderboard(
|
||||
ctx=ctx, title="Muttn Leaderboard", data=data, fetch_names=True, format_f=_format_entry
|
||||
)
|
||||
|
||||
await lb.send(ctx)
|
||||
lb = leaderboards.MuttnLeaderboard(ctx=ctx)
|
||||
await lb.send()
|
||||
|
||||
async def callLeaderboard(self, name, ctx):
|
||||
command = [command for command in self.leaderboard.commands if command.name.lower() == name.lower()][0]
|
||||
await command(ctx)
|
||||
|
||||
async def startPaginated(self, ctx, source, name, colour=discord.Colour.blue()):
|
||||
pages = paginated_leaderboard.Pages(source=paginated_leaderboard.Source(source, name, colour),
|
||||
clear_reactions_after=True)
|
||||
await pages.start(ctx)
|
||||
|
||||
async def empty_leaderboard(self, ctx, name, message, colour=discord.Colour.blue()):
|
||||
embed = discord.Embed(colour=colour)
|
||||
embed.set_author(name=name)
|
||||
embed.description = message
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
|
||||
def setup(client):
|
||||
client.add_cog(Leaderboards(client))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from data.menus import paginated_leaderboard
|
||||
from data.menus import leaderboards
|
||||
from decorators import help
|
||||
import discord
|
||||
from discord.ext import commands, menus
|
||||
|
|
|
@ -0,0 +1,275 @@
|
|||
import math
|
||||
from abc import ABC, abstractmethod
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Union, Optional
|
||||
|
||||
import discord
|
||||
import requests
|
||||
from discord import ApplicationContext
|
||||
from discord.ext import menus
|
||||
from discord.ext.commands import Context
|
||||
|
||||
from data.menus.paginated import Paginated
|
||||
from enums.numbers import Numbers
|
||||
from functions import xp
|
||||
from functions.database import currency, stats, poke, muttn
|
||||
from functions.utils import get_display_name
|
||||
|
||||
|
||||
@dataclass
|
||||
class Leaderboard(Paginated, ABC):
|
||||
highlight: str = None
|
||||
colour: discord.Colour = discord.Colour.blue()
|
||||
fetch_names: bool = True
|
||||
ignore_non_pos: bool = True
|
||||
|
||||
def __post_init__(self):
|
||||
self.data = self.process_data(self.get_data())
|
||||
|
||||
@abstractmethod
|
||||
def get_data(self) -> list[tuple]:
|
||||
pass
|
||||
|
||||
def process_data(self, entries: list[tuple]) -> Optional[list[tuple]]:
|
||||
data = []
|
||||
for i, v in enumerate(sorted(entries, key=self.get_value, reverse=True)):
|
||||
entry_data = self.get_value(v)
|
||||
|
||||
# Leaderboard is empty
|
||||
if i == 0 and entry_data == 0 and self.ignore_non_pos:
|
||||
return None
|
||||
|
||||
# Ignore entries with no data
|
||||
if self.ignore_non_pos and entry_data <= 0:
|
||||
continue
|
||||
|
||||
data.append((self.get_key(v), f"{entry_data:,}", entry_data,))
|
||||
|
||||
return data
|
||||
|
||||
def get_key(self, data: tuple):
|
||||
return data[0]
|
||||
|
||||
def get_value(self, data: tuple):
|
||||
return data[1]
|
||||
|
||||
def _should_highlight(self, data) -> bool:
|
||||
"""Check if an entry should be highlighted"""
|
||||
if self.fetch_names:
|
||||
return data == self.ctx.author.id
|
||||
|
||||
return data == self.highlight
|
||||
|
||||
def format_entry_data(self, data: tuple) -> str:
|
||||
return str(data[1])
|
||||
|
||||
def format_entry(self, index: int, data: tuple) -> str:
|
||||
name = data[0]
|
||||
|
||||
if self.fetch_names:
|
||||
name = get_display_name(self.ctx, int(data[0]))
|
||||
|
||||
s = f"{index + 1}: {name} ({self.format_entry_data(data)})"
|
||||
|
||||
if self._should_highlight(data[0]):
|
||||
return f"**{s}**"
|
||||
|
||||
return s
|
||||
|
||||
@property
|
||||
def empty_description(self) -> str:
|
||||
return ""
|
||||
|
||||
async def empty_leaderboard(self, ctx: Union[ApplicationContext, Context]):
|
||||
embed = discord.Embed(colour=self.colour)
|
||||
embed.set_author(name=self.title)
|
||||
embed.description = self.empty_description
|
||||
|
||||
if isinstance(ctx, ApplicationContext):
|
||||
return await ctx.respond(embed=embed)
|
||||
|
||||
return await ctx.reply(embed=embed, mention_author=False)
|
||||
|
||||
async def respond(self, **kwargs) -> discord.Message:
|
||||
if self.data is None:
|
||||
return await self.empty_leaderboard(self.ctx)
|
||||
|
||||
return await super().respond(**kwargs)
|
||||
|
||||
async def send(self, **kwargs) -> discord.Message:
|
||||
if self.data is None:
|
||||
return await self.empty_leaderboard(self.ctx)
|
||||
|
||||
return await super().send(**kwargs)
|
||||
|
||||
|
||||
@dataclass
|
||||
class BitcoinLeaderboard(Leaderboard):
|
||||
title: str = field(default="Bitcoin Leaderboard")
|
||||
|
||||
def get_data(self) -> list[tuple]:
|
||||
return currency.getAllRows()
|
||||
|
||||
def get_value(self, data: tuple):
|
||||
return round(float(data[8]), 8)
|
||||
|
||||
@property
|
||||
def empty_description(self) -> str:
|
||||
return "Er zijn nog geen personen met Bitcoins."
|
||||
|
||||
|
||||
@dataclass
|
||||
class CoronaLeaderboard(Leaderboard):
|
||||
colour: discord.Colour = field(default=discord.Colour.red())
|
||||
fetch_names: bool = field(default=False)
|
||||
highlight: str = field(default="Belgium")
|
||||
title: str = field(default="Corona Leaderboard")
|
||||
|
||||
def get_data(self) -> list[tuple]:
|
||||
result = requests.get("https://disease.sh/v3/covid-19/countries").json()
|
||||
result.sort(key=lambda x: int(x["cases"]), reverse=True)
|
||||
|
||||
data = []
|
||||
for country in result:
|
||||
data.append((country["country"], f"{country['cases']:,}", country["cases"]))
|
||||
|
||||
return data
|
||||
|
||||
def get_value(self, data: tuple):
|
||||
return data[2]
|
||||
|
||||
|
||||
@dataclass
|
||||
class DinksLeaderboard(Leaderboard):
|
||||
title: str = field(default="Dinks Leaderboard")
|
||||
|
||||
def get_data(self) -> list[tuple]:
|
||||
entries = currency.getAllRows()
|
||||
platDinks = currency.getAllPlatDinks()
|
||||
|
||||
# Take platinum dinks into account
|
||||
for i, user in enumerate(entries):
|
||||
if str(user[0]) in platDinks:
|
||||
# Tuples don't support assignment, cast to list
|
||||
user = list(user)
|
||||
user[1] += platDinks[str(user[0])] * Numbers.q.value
|
||||
entries[i] = user
|
||||
|
||||
return entries
|
||||
|
||||
def get_value(self, data: tuple):
|
||||
return float(data[1]) + float(data[3])
|
||||
|
||||
@property
|
||||
def empty_description(self) -> str:
|
||||
return "Er zijn nog geen personen met Didier Dinks."
|
||||
|
||||
|
||||
@dataclass
|
||||
class MessageLeaderboard(Leaderboard):
|
||||
title: str = field(default="Message Leaderboard")
|
||||
message_count: int = field(init=False)
|
||||
|
||||
def get_data(self) -> list[tuple]:
|
||||
entries = stats.getAllRows()
|
||||
self.message_count = stats.getTotalMessageCount()
|
||||
return entries
|
||||
|
||||
def get_value(self, data: tuple):
|
||||
return round(int(data[11]))
|
||||
|
||||
def format_entry_data(self, data: tuple) -> str:
|
||||
perc = round(data[2] * 100 / self.message_count, 2)
|
||||
return f"{data[2]:,} | {perc}%"
|
||||
|
||||
|
||||
@dataclass
|
||||
class MuttnLeaderboard(Leaderboard):
|
||||
title: str = field(default="Muttn Leaderboard")
|
||||
|
||||
def get_data(self) -> list[tuple]:
|
||||
return muttn.getAllRows()
|
||||
|
||||
def get_value(self, data: tuple):
|
||||
return round(float(data[1]), 2)
|
||||
|
||||
def format_entry_data(self, data: tuple) -> str:
|
||||
return f"{data[2]}%"
|
||||
|
||||
def empty_description(self) -> str:
|
||||
return "Der zittn nog geen muttns in de server."
|
||||
|
||||
|
||||
@dataclass
|
||||
class PokeLeaderboard(Leaderboard):
|
||||
title: str = field(default="Poke Leaderboard")
|
||||
|
||||
def get_data(self) -> list[tuple]:
|
||||
data = stats.getAllRows()
|
||||
blacklist = poke.getAllBlacklistedUsers()
|
||||
return list(filter(lambda x: x[0] not in blacklist, data))
|
||||
|
||||
def get_value(self, data: tuple):
|
||||
return round(int(data[1]))
|
||||
|
||||
@property
|
||||
def empty_description(self) -> str:
|
||||
return "Er is nog niemand getikt."
|
||||
|
||||
|
||||
@dataclass
|
||||
class RobLeaderboard(Leaderboard):
|
||||
title: str = field(default="Rob Leaderboard")
|
||||
|
||||
def get_data(self) -> list[tuple]:
|
||||
return list(stats.getAllRows())
|
||||
|
||||
def get_value(self, data: tuple):
|
||||
return math.floor(float(data[4]))
|
||||
|
||||
@property
|
||||
def empty_description(self) -> str:
|
||||
return "Er heeft nog niemand Didier Dinks gestolen."
|
||||
|
||||
|
||||
@dataclass
|
||||
class XPLeaderboard(Leaderboard):
|
||||
title: str = field(default="XP Leaderboard")
|
||||
|
||||
def get_data(self) -> list[tuple]:
|
||||
return stats.getAllRows()
|
||||
|
||||
def get_value(self, data: tuple):
|
||||
return round(int(data[12]))
|
||||
|
||||
def format_entry_data(self, data: tuple) -> str:
|
||||
entry = data[2]
|
||||
return f"Level {xp.calculate_level(entry):,} | {entry:,} XP"
|
||||
|
||||
|
||||
class Source(menus.ListPageSource):
|
||||
def __init__(self, data, name, colour=discord.Colour.blue()):
|
||||
super().__init__(data, per_page=10)
|
||||
self.name = name
|
||||
self.colour = colour
|
||||
|
||||
async def format_page(self, menu: menus.MenuPages, entries):
|
||||
offset = menu.current_page * self.per_page
|
||||
|
||||
description = ""
|
||||
for i, v in enumerate(entries, start=offset):
|
||||
# Check if the person's name has to be highlighted
|
||||
if v.startswith("**") and v.endswith("**"):
|
||||
description += "**"
|
||||
v = v[2:]
|
||||
description += "{}: {}\n".format(i + 1, v)
|
||||
embed = discord.Embed(colour=self.colour)
|
||||
embed.set_author(name=self.name)
|
||||
embed.description = description
|
||||
embed.set_footer(text="{}/{}".format(menu.current_page + 1, self.get_max_pages()))
|
||||
return embed
|
||||
|
||||
|
||||
class Pages(menus.MenuPages):
|
||||
def __init__(self, source, clear_reactions_after, timeout=30.0):
|
||||
super().__init__(source, timeout=timeout, delete_message_after=True, clear_reactions_after=clear_reactions_after)
|
|
@ -0,0 +1,67 @@
|
|||
from abc import ABC, abstractmethod
|
||||
from dataclasses import dataclass
|
||||
from typing import Union
|
||||
|
||||
import discord
|
||||
from discord import ApplicationContext
|
||||
from discord.ext import pages
|
||||
from discord.ext.commands import Context
|
||||
|
||||
|
||||
@dataclass
|
||||
class Paginated(ABC):
|
||||
"""Abstract class to support paginated menus easily"""
|
||||
ctx: Union[ApplicationContext, Context]
|
||||
title: str
|
||||
data: list[tuple] = None
|
||||
per_page: int = 10
|
||||
colour: discord.Colour = discord.Colour.blue()
|
||||
|
||||
def create_embed(self, description: str) -> discord.Embed:
|
||||
embed = discord.Embed(colour=self.colour)
|
||||
embed.set_author(name=self.title)
|
||||
embed.description = description
|
||||
|
||||
return embed
|
||||
|
||||
@abstractmethod
|
||||
def format_entry(self, index: int, value: tuple) -> str:
|
||||
pass
|
||||
|
||||
def create_pages(self, data: list[tuple]) -> list[discord.Embed]:
|
||||
# Amount of entries added to this page
|
||||
added = 0
|
||||
page_list = []
|
||||
|
||||
description = ""
|
||||
for i, v in enumerate(data):
|
||||
s = self.format_entry(i, v)
|
||||
|
||||
description += s + "\n"
|
||||
added += 1
|
||||
|
||||
# Page full, create an embed & change counters
|
||||
if added == self.per_page:
|
||||
embed = self.create_embed(description)
|
||||
|
||||
description = ""
|
||||
added = 0
|
||||
page_list.append(embed)
|
||||
|
||||
# Add final embed if necessary
|
||||
if added != 0:
|
||||
embed = self.create_embed(description)
|
||||
page_list.append(embed)
|
||||
|
||||
return page_list
|
||||
|
||||
def create_paginator(self) -> pages.Paginator:
|
||||
return pages.Paginator(pages=self.create_pages(self.data), show_disabled=False, disable_on_timeout=True, timeout=30)
|
||||
|
||||
async def respond(self, **kwargs) -> discord.Message:
|
||||
paginator = self.create_paginator()
|
||||
return await paginator.respond(self.ctx.interaction, **kwargs)
|
||||
|
||||
async def send(self, **kwargs) -> discord.Message:
|
||||
paginator = self.create_paginator()
|
||||
return await paginator.send(self.ctx, **kwargs)
|
|
@ -1,125 +0,0 @@
|
|||
from typing import Callable
|
||||
|
||||
import discord
|
||||
from discord import ApplicationContext
|
||||
from discord.ext import menus, pages
|
||||
from dataclasses import dataclass
|
||||
|
||||
from discord.ext.commands import Context
|
||||
|
||||
from functions.utils import get_display_name
|
||||
|
||||
|
||||
@dataclass
|
||||
class Leaderboard:
|
||||
ctx: Context
|
||||
title: str
|
||||
data: list
|
||||
highlight: str = None
|
||||
format_f: Callable = None
|
||||
per_page: int = 10
|
||||
colour: discord.Colour = discord.Colour.blue()
|
||||
fetch_names: bool = False
|
||||
|
||||
def _should_highlight(self, data) -> bool:
|
||||
"""Check if an entry should be highlighted"""
|
||||
if self.fetch_names:
|
||||
return data == self.ctx.author.id
|
||||
|
||||
return data == self.highlight
|
||||
|
||||
def _format(self, index: int, data: tuple) -> str:
|
||||
name = data[0]
|
||||
|
||||
if self.fetch_names:
|
||||
name = get_display_name(self.ctx, int(data[0]))
|
||||
|
||||
formatted_data = self.format_f(data[2]) if self.format_f is not None else data[1]
|
||||
|
||||
s = f"{index + 1}: {name} ({formatted_data})"
|
||||
|
||||
return s
|
||||
|
||||
def _get_page_count(self) -> int:
|
||||
"""Get the amount of pages required to represent this data"""
|
||||
count = len(self.data) // self.per_page
|
||||
if len(self.data) % self.per_page != 0:
|
||||
count += 1
|
||||
|
||||
return count
|
||||
|
||||
def _create_embed(self, description: str) -> discord.Embed:
|
||||
embed = discord.Embed(colour=self.colour)
|
||||
embed.set_author(name=self.title)
|
||||
embed.description = description
|
||||
|
||||
return embed
|
||||
|
||||
def create_pages(self) -> list[discord.Embed]:
|
||||
# Amount of entries added to this page
|
||||
added = 0
|
||||
page_list = []
|
||||
|
||||
description = ""
|
||||
for i, v in enumerate(self.data):
|
||||
s = self._format(i, v)
|
||||
|
||||
if self._should_highlight(v[0]):
|
||||
s = f"**{s}**"
|
||||
|
||||
description += s + "\n"
|
||||
added += 1
|
||||
|
||||
# Page full, create an embed & change counters
|
||||
if added == self.per_page:
|
||||
embed = self._create_embed(description)
|
||||
|
||||
description = ""
|
||||
added = 0
|
||||
page_list.append(embed)
|
||||
|
||||
# Add final embed
|
||||
if added != 0:
|
||||
embed = self._create_embed(description)
|
||||
page_list.append(embed)
|
||||
|
||||
return page_list
|
||||
|
||||
def create_paginator(self) -> pages.Paginator:
|
||||
return pages.Paginator(pages=self.create_pages(), show_disabled=False, disable_on_timeout=True, timeout=30)
|
||||
|
||||
async def respond(self, ctx: ApplicationContext, **kwargs) -> discord.Message:
|
||||
paginator = self.create_paginator()
|
||||
return await paginator.respond(ctx.interaction, **kwargs)
|
||||
|
||||
async def send(self, ctx: Context, **kwargs) -> discord.Message:
|
||||
paginator = self.create_paginator()
|
||||
return await paginator.send(ctx, **kwargs)
|
||||
|
||||
|
||||
class Source(menus.ListPageSource):
|
||||
def __init__(self, data, name, colour=discord.Colour.blue()):
|
||||
super().__init__(data, per_page=10)
|
||||
self.name = name
|
||||
self.colour = colour
|
||||
|
||||
async def format_page(self, menu: menus.MenuPages, entries):
|
||||
offset = menu.current_page * self.per_page
|
||||
|
||||
description = ""
|
||||
for i, v in enumerate(entries, start=offset):
|
||||
# Check if the person's name has to be highlighted
|
||||
if v.startswith("**") and v.endswith("**"):
|
||||
description += "**"
|
||||
v = v[2:]
|
||||
description += "{}: {}\n".format(i + 1, v)
|
||||
embed = discord.Embed(colour=self.colour)
|
||||
embed.set_author(name=self.name)
|
||||
embed.description = description
|
||||
embed.set_footer(text="{}/{}".format(menu.current_page + 1, self.get_max_pages()))
|
||||
return embed
|
||||
|
||||
|
||||
class Pages(menus.MenuPages):
|
||||
def __init__(self, source, clear_reactions_after, timeout=30.0):
|
||||
super().__init__(source, timeout=timeout, delete_message_after=True, clear_reactions_after=clear_reactions_after)
|
Loading…
Reference in New Issue