diff --git a/cogs/fun.py b/cogs/fun.py index f797803..affd2c9 100644 --- a/cogs/fun.py +++ b/cogs/fun.py @@ -1,5 +1,5 @@ from data.embeds.xkcd import XKCDEmbed -from data.menus import paginatedLeaderboard +from data.menus import paginated_leaderboard from decorators import help import discord from discord.ext import commands @@ -124,8 +124,9 @@ class Fun(commands.Cog): memeList = [": ".join([stringFormatters.title_case(meme[1]), str(meme[2])]) for meme in sorted(memeList, key=lambda x: x[1])] - pages = paginatedLeaderboard.Pages(source=paginatedLeaderboard.Source(memeList, "Memes", discord.Colour.blue()), - clear_reactions_after=True) + pages = paginated_leaderboard.Pages( + source=paginated_leaderboard.Source(memeList, "Memes", discord.Colour.blue()), + clear_reactions_after=True) await pages.start(ctx) @commands.command(name="Pjoke") diff --git a/cogs/leaderboards.py b/cogs/leaderboards.py index 724bf54..6eb9edf 100644 --- a/cogs/leaderboards.py +++ b/cogs/leaderboards.py @@ -1,4 +1,4 @@ -from data.menus import paginatedLeaderboard +from data.menus import paginated_leaderboard from decorators import help import discord from discord.ext import commands @@ -45,35 +45,36 @@ class Leaderboards(commands.Cog): user[1] += platDinks[str(user[0])] * Numbers.q.value entries[i] = user - boardTop = [] + data = [] for i, user in enumerate(sorted(entries, key=lambda x: (float(x[1]) + float(x[3])), reverse=True)): if i == 0 and float(user[1]) + float(user[3]) == 0.0: - return await self.emptyLeaderboard(ctx, "Dinks Leaderboard", "Er zijn nog geen personen met Didier Dinks.") + return await self.empty_leaderboard(ctx, "Dinks Leaderboard", + "Er zijn nog geen personen met Didier Dinks.") elif float(user[1]) + float(user[3]) > 0.0: + total_dinks = math.floor(float(user[1]) + float(user[3])) + data.append((user[0], total_dinks,)) - # Get the username in this guild - name = self.utilsCog.getDisplayName(ctx, user[0]) + lb = paginated_leaderboard.Leaderboard( + ctx=ctx, title="Dinks Leaderboard", data=data, fetch_names=True + ) - if int(user[0]) == int(ctx.author.id): - boardTop.append("**{} ({:,})**".format(name, math.floor(float(user[1]) + float(user[3])))) - else: - boardTop.append("{} ({:,})".format(name, math.floor(float(user[1]) + float(user[3])))) - - await self.startPaginated(ctx, boardTop, "Dinks Leaderboard") + await lb.send(ctx) @leaderboard.command(name="Corona", hidden=True) async def corona(self, ctx): - result = requests.get("http://corona.lmao.ninja/v2/countries").json() + result = requests.get("https://disease.sh/v3/covid-19/countries").json() result.sort(key=lambda x: int(x["cases"]), reverse=True) - board = [] - for land in result: - if land["country"] == "Belgium": - board.append("**{} ({:,})**".format(land["country"], land["cases"])) - else: - board.append("{} ({:,})".format(land["country"], land["cases"])) + data = [] + for country in result: + data.append((country["country"], f"{country['cases']:,}",)) - await self.startPaginated(ctx, board, "Corona Leaderboard", discord.Colour.red()) + lb = paginated_leaderboard.Leaderboard( + ctx=ctx, title="Corona Leaderboard", data=data, highlight="Belgium", + colour=discord.Colour.red() + ) + + await lb.send(ctx) @leaderboard.command(name="Bitcoin", aliases=["Bc"], hidden=True) async def bitcoin(self, ctx): @@ -82,7 +83,8 @@ class Leaderboards(commands.Cog): for i, user in enumerate(sorted(users, key=lambda x: x[8], reverse=True)): # Don't create an empty leaderboard if i == 0 and float(user[8]) == 0.0: - return await self.emptyLeaderboard(ctx, "Bitcoin Leaderboard", "Er zijn nog geen personen met Bitcoins.") + return await self.empty_leaderboard(ctx, "Bitcoin Leaderboard", + "Er zijn nog geen personen met Bitcoins.") elif float(user[8]) > 0.0: # Only add people with more than 0 # Get the username in this guild @@ -101,7 +103,8 @@ class Leaderboards(commands.Cog): for i, user in enumerate(sorted(users, key=lambda x: x[4], reverse=True)): # Don't create an empty leaderboard if i == 0 and float(user[4]) == 0.0: - return await self.emptyLeaderboard(ctx, "Rob Leaderboard", "Er heeft nog niemand Didier Dinks gestolen.") + return await self.empty_leaderboard(ctx, "Rob Leaderboard", + "Er heeft nog niemand Didier Dinks gestolen.") elif float(user[4]) > 0.0: # Only add people with more than 0 # Get the username in this guild @@ -119,7 +122,7 @@ class Leaderboards(commands.Cog): boardTop = [] for i, user in enumerate(sorted(s, key=lambda x: x[1], reverse=True)): if i == 0 and int(user[1]) == 0: - return await self.emptyLeaderboard(ctx, "Poke Leaderboard", "Er is nog niemand getikt.") + return await self.empty_leaderboard(ctx, "Poke Leaderboard", "Er is nog niemand getikt.") elif int(user[1]) == 0: break @@ -177,7 +180,7 @@ class Leaderboards(commands.Cog): boardTop = [] for i, user in enumerate(sorted(users, key=lambda x: x[1], reverse=True)): if i == 0 and int(user[1]) == 0: - return await self.emptyLeaderboard(ctx, "Muttn Leaderboard", "Der zittn nog geen muttns in de server.") + return await self.empty_leaderboard(ctx, "Muttn Leaderboard", "Der zittn nog geen muttns in de server.") if float(user[1]) == 0: break @@ -190,14 +193,15 @@ class Leaderboards(commands.Cog): await self.startPaginated(ctx, boardTop, "Muttn Leaderboard") async def callLeaderboard(self, name, ctx): - await [command for command in self.leaderboard.commands if command.name.lower() == name.lower()][0](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 = paginatedLeaderboard.Pages(source=paginatedLeaderboard.Source(source, name, colour), - clear_reactions_after=True) + pages = paginated_leaderboard.Pages(source=paginated_leaderboard.Source(source, name, colour), + clear_reactions_after=True) await pages.start(ctx) - async def emptyLeaderboard(self, ctx, name, message, colour=discord.Colour.blue()): + 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 diff --git a/cogs/store.py b/cogs/store.py index 25ee5c1..d24a500 100644 --- a/cogs/store.py +++ b/cogs/store.py @@ -1,5 +1,4 @@ from converters.numbers import Abbreviated -from data.menus import storePages from decorators import help import discord from discord.ext import commands @@ -22,11 +21,12 @@ class Store(commands.Cog): @commands.check(checks.allowedChannels) @help.Category(Category.Currency) async def store(self, ctx): - entries = store.getAllItems() - await storePages.Pages(source=storePages.Source(entries), clear_reactions_after=True).start(ctx) + pass + # entries = store.getAllItems() + # await storePages.Pages(source=storePages.Source(entries), clear_reactions_after=True).start(ctx) @store.command(name="Buy", aliases=["Get"], hidden=True) - async def storeBuy(self, ctx, item, amount: Abbreviated = 1): + async def store_buy(self, ctx, item, amount: Abbreviated = 1): if amount is None: return @@ -56,7 +56,7 @@ class Store(commands.Cog): )) @store.command(name="Sell", hidden=True) - async def storeSell(self, ctx, itemid, amount: Abbreviated = 1): + async def store_sell(self, ctx, itemid, amount: Abbreviated = 1): if amount is None: return await self.sell(ctx, itemid, amount) diff --git a/cogs/train.py b/cogs/train.py index 10dcbb0..5865bf8 100644 --- a/cogs/train.py +++ b/cogs/train.py @@ -1,4 +1,4 @@ -from data.menus import paginatedLeaderboard +from data.menus import paginated_leaderboard from decorators import help import discord from discord.ext import commands, menus @@ -36,10 +36,10 @@ class Train(commands.Cog): await self.sendEmbed(ctx, embed) return - pages = paginatedLeaderboard.Pages(source=TrainPagination(self.formatConnections(req["connection"]), - self.formatCity(departure), - self.formatCity(destination)), - clear_reactions_after=True) + pages = paginated_leaderboard.Pages(source=TrainPagination(self.formatConnections(req["connection"]), + self.formatCity(departure), + self.formatCity(destination)), + clear_reactions_after=True) await pages.start(ctx) def formatConnections(self, connections): diff --git a/data/menus/paginatedLeaderboard.py b/data/menus/paginatedLeaderboard.py deleted file mode 100644 index 45b5e35..0000000 --- a/data/menus/paginatedLeaderboard.py +++ /dev/null @@ -1,31 +0,0 @@ -import discord -from discord.ext import menus - - -# https://github.com/Rapptz/discord-ext-menus -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) diff --git a/data/menus/paginated_leaderboard.py b/data/menus/paginated_leaderboard.py new file mode 100644 index 0000000..dd9bec7 --- /dev/null +++ b/data/menus/paginated_leaderboard.py @@ -0,0 +1,127 @@ +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 __post_init__(self): + if self.format_f is None: + self.format_f = self._format + + 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])) + + s = f"{index + 1}: {name} ({data[1]})" + + 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_f(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) diff --git a/data/menus/storePages.py b/data/menus/storePages.py deleted file mode 100644 index f794554..0000000 --- a/data/menus/storePages.py +++ /dev/null @@ -1,28 +0,0 @@ -import discord -from discord.ext import menus - - -# https://github.com/Rapptz/discord-ext-menus -class Source(menus.ListPageSource): - def __init__(self, data): - super().__init__(data, per_page=10) - self.name = "Didier Store" - self.colour = discord.Colour.blue() - - async def format_page(self, menu: menus.MenuPages, entries): - offset = menu.current_page * self.per_page - - embed = discord.Embed(colour=self.colour) - embed.set_author(name=self.name) - embed.description = "Heb je een idee voor een item? DM DJ STIJN met je idee!" - embed.set_footer(text="{}/{}".format(menu.current_page + 1, self.get_max_pages())) - - for i, v in enumerate(entries, start=offset): - embed.add_field(name="#{} - {}".format(v[0], v[1]), value="{:,} Didier Dinks".format(v[2])) - - 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) diff --git a/functions/utils.py b/functions/utils.py new file mode 100644 index 0000000..b1a692a --- /dev/null +++ b/functions/utils.py @@ -0,0 +1,33 @@ +from typing import Union + +from discord import ApplicationContext +from discord.ext.commands import Context + +from data import constants + + +def get_display_name(ctx: Union[ApplicationContext, Context], user_id: int) -> str: + author = ctx.author if isinstance(ctx, Context) else ctx.user + + # Check if this is a DM, or the user is not in the guild + if ctx.guild is None or ctx.guild.get_member(user_id) is None: + # User is the author, no need to fetch their name + if user_id == author.id: + return author.display_name + + # Get member instance from CoC + COC = ctx.bot.get_guild(int(constants.DeZandbak)) + member = COC.get_member(user_id) + if member is not None: + return member.display_name + + # Try to fetch the user + user = ctx.bot.get_user(user_id) + if user is not None: + return user.name + + # User couldn't be found + return f"[? | {user_id}]" + + mem = ctx.guild.get_member(user_id) + return mem.display_name diff --git a/requirements.txt b/requirements.txt index e02e23c..a3d6c9c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,9 +3,6 @@ py-cord==2.0.0b1 python-dotenv==0.14.0 beautifulsoup4==4.9.1 -# discord.py==1.7.3 -git+https://github.com/Rapptz/discord-ext-menus@master -# discord-ext-ipc==2.0.0 psycopg2==2.8.5 psycopg2-binary==2.8.5 python-dateutil==2.6.1