mirror of https://github.com/stijndcl/didier
Compare commits
4 Commits
7ad2bf351e
...
a71232e292
| Author | SHA1 | Date |
|---|---|---|
|
|
a71232e292 | |
|
|
81a0d90a12 | |
|
|
ca687956f6 | |
|
|
062d54722b |
|
|
@ -85,7 +85,6 @@ class Events(commands.Cog):
|
||||||
Logs commands in your terminal.
|
Logs commands in your terminal.
|
||||||
:param ctx: Discord Context
|
:param ctx: Discord Context
|
||||||
"""
|
"""
|
||||||
print("a")
|
|
||||||
print(stringFormatters.format_command_usage(ctx))
|
print(stringFormatters.format_command_usage(ctx))
|
||||||
|
|
||||||
command_stats.invoked(command_stats.InvocationType.TextCommand)
|
command_stats.invoked(command_stats.InvocationType.TextCommand)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from data.embeds.xkcd import XKCDEmbed
|
from data.embeds.xkcd import XKCDEmbed
|
||||||
from data.menus import paginated_leaderboard
|
from data.menus import leaderboards
|
||||||
from decorators import help
|
from decorators import help
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,12 @@
|
||||||
from data.menus import paginated_leaderboard
|
|
||||||
from decorators import help
|
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
|
from data.menus import leaderboards
|
||||||
|
from decorators import help
|
||||||
from enums.help_categories import Category
|
from enums.help_categories import Category
|
||||||
from enums.numbers import Numbers
|
from functions import checks
|
||||||
from functions import checks, xp
|
|
||||||
from functions.database import currency, stats, poke, muttn
|
|
||||||
import math
|
|
||||||
import requests
|
|
||||||
|
|
||||||
|
|
||||||
# TODO some sort of general leaderboard because all of them are the same
|
|
||||||
class Leaderboards(commands.Cog):
|
class Leaderboards(commands.Cog):
|
||||||
|
|
||||||
def __init__(self, client):
|
def __init__(self, client):
|
||||||
|
|
@ -18,7 +14,7 @@ class Leaderboards(commands.Cog):
|
||||||
self.utilsCog = self.client.get_cog("Utils")
|
self.utilsCog = self.client.get_cog("Utils")
|
||||||
|
|
||||||
# Don't allow any commands to work when locked
|
# Don't allow any commands to work when locked
|
||||||
def cog_check(self, ctx):
|
def cog_check(self, _):
|
||||||
return not self.client.locked
|
return not self.client.locked
|
||||||
|
|
||||||
@commands.group(name="Leaderboard", aliases=["Lb", "Leaderboards"], case_insensitive=True, usage="[Categorie]*",
|
@commands.group(name="Leaderboard", aliases=["Lb", "Leaderboards"], case_insensitive=True, usage="[Categorie]*",
|
||||||
|
|
@ -34,179 +30,48 @@ class Leaderboards(commands.Cog):
|
||||||
|
|
||||||
@leaderboard.command(name="Dinks", aliases=["Cash"], hidden=True)
|
@leaderboard.command(name="Dinks", aliases=["Cash"], hidden=True)
|
||||||
async def dinks(self, ctx):
|
async def dinks(self, ctx):
|
||||||
entries = currency.getAllRows()
|
lb = leaderboards.DinksLeaderboard(ctx=ctx)
|
||||||
platDinks = currency.getAllPlatDinks()
|
await lb.send()
|
||||||
|
|
||||||
# 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 = []
|
|
||||||
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.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,))
|
|
||||||
|
|
||||||
lb = paginated_leaderboard.Leaderboard(
|
|
||||||
ctx=ctx, title="Dinks Leaderboard", data=data, fetch_names=True
|
|
||||||
)
|
|
||||||
|
|
||||||
await lb.send(ctx)
|
|
||||||
|
|
||||||
@leaderboard.command(name="Corona", hidden=True)
|
@leaderboard.command(name="Corona", hidden=True)
|
||||||
async def corona(self, ctx):
|
async def corona(self, ctx):
|
||||||
result = requests.get("https://disease.sh/v3/covid-19/countries").json()
|
lb = leaderboards.CoronaLeaderboard(ctx=ctx)
|
||||||
result.sort(key=lambda x: int(x["cases"]), reverse=True)
|
await lb.send()
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
@leaderboard.command(name="Bitcoin", aliases=["Bc"], hidden=True)
|
@leaderboard.command(name="Bitcoin", aliases=["Bc"], hidden=True)
|
||||||
async def bitcoin(self, ctx):
|
async def bitcoin(self, ctx):
|
||||||
users = currency.getAllRows()
|
lb = leaderboards.BitcoinLeaderboard(ctx=ctx)
|
||||||
boardTop = []
|
await lb.send()
|
||||||
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.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
|
|
||||||
name = self.utilsCog.getDisplayName(ctx, user[0])
|
|
||||||
if int(user[0]) == int(ctx.author.id):
|
|
||||||
boardTop.append("**{} ({:,})**".format(name, round(user[8], 8)))
|
|
||||||
else:
|
|
||||||
boardTop.append("{} ({:,})".format(name, round(user[8], 8)))
|
|
||||||
|
|
||||||
await self.startPaginated(ctx, boardTop, "Bitcoin Leaderboard")
|
|
||||||
|
|
||||||
@leaderboard.command(name="Rob", hidden=True)
|
@leaderboard.command(name="Rob", hidden=True)
|
||||||
async def rob(self, ctx):
|
async def rob(self, ctx):
|
||||||
users = list(stats.getAllRows())
|
lb = leaderboards.RobLeaderboard(ctx=ctx)
|
||||||
boardTop = []
|
await lb.send()
|
||||||
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.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
|
|
||||||
name = self.utilsCog.getDisplayName(ctx, user[0])
|
|
||||||
if int(user[0]) == int(ctx.author.id):
|
|
||||||
boardTop.append("**{} ({:,})**".format(name, math.floor(float(user[4]))))
|
|
||||||
else:
|
|
||||||
boardTop.append("{} ({:,})".format(name, math.floor(float(user[4]))))
|
|
||||||
await self.startPaginated(ctx, boardTop, "Rob Leaderboard")
|
|
||||||
|
|
||||||
@leaderboard.command(name="Poke", hidden=True)
|
@leaderboard.command(name="Poke", hidden=True)
|
||||||
async def poke(self, ctx):
|
async def poke(self, ctx):
|
||||||
s = stats.getAllRows()
|
lb = leaderboards.PokeLeaderboard(ctx=ctx)
|
||||||
blacklist = poke.getAllBlacklistedUsers()
|
await lb.send()
|
||||||
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.empty_leaderboard(ctx, "Poke Leaderboard", "Er is nog niemand getikt.")
|
|
||||||
|
|
||||||
elif int(user[1]) == 0:
|
|
||||||
break
|
|
||||||
# Don't include blacklisted users
|
|
||||||
elif str(user[0]) not in blacklist:
|
|
||||||
name = self.utilsCog.getDisplayName(ctx, user[0])
|
|
||||||
if int(user[0]) == int(ctx.author.id):
|
|
||||||
boardTop.append("**{} ({:,})**".format(name, round(int(user[1]))))
|
|
||||||
else:
|
|
||||||
boardTop.append("{} ({:,})".format(name, round(int(user[1]))))
|
|
||||||
await self.startPaginated(ctx, boardTop, "Poke Leaderboard")
|
|
||||||
|
|
||||||
@leaderboard.command(name="Xp", aliases=["Level"], hidden=True)
|
@leaderboard.command(name="Xp", aliases=["Level"], hidden=True)
|
||||||
async def xp(self, ctx):
|
async def xp(self, ctx):
|
||||||
s = stats.getAllRows()
|
lb = leaderboards.XPLeaderboard(ctx=ctx)
|
||||||
boardTop = []
|
await lb.send()
|
||||||
for i, user in enumerate(sorted(s, key=lambda x: x[12], reverse=True)):
|
|
||||||
if int(user[12]) == 0:
|
|
||||||
break
|
|
||||||
|
|
||||||
name = self.utilsCog.getDisplayName(ctx, user[0])
|
|
||||||
if int(user[0]) == int(ctx.author.id):
|
|
||||||
boardTop.append("**{} (Level {:,} | {:,} XP)**".format(name,
|
|
||||||
xp.calculate_level(round(int(user[12]))),
|
|
||||||
round(int(user[12]))))
|
|
||||||
else:
|
|
||||||
boardTop.append("{} (Level {:,} | {:,} XP)".format(name,
|
|
||||||
xp.calculate_level(round(int(user[12]))),
|
|
||||||
round(int(user[12]))))
|
|
||||||
await self.startPaginated(ctx, boardTop, "XP Leaderboard")
|
|
||||||
|
|
||||||
@leaderboard.command(name="Messages", aliases=["Mc", "Mess"], hidden=True)
|
@leaderboard.command(name="Messages", aliases=["Mc", "Mess"], hidden=True)
|
||||||
async def messages(self, ctx):
|
async def messages(self, ctx):
|
||||||
s = stats.getAllRows()
|
lb = leaderboards.MessageLeaderboard(ctx=ctx)
|
||||||
boardTop = []
|
await lb.send()
|
||||||
|
|
||||||
message_count = stats.getTotalMessageCount()
|
|
||||||
|
|
||||||
for i, user in enumerate(sorted(s, key=lambda x: x[11], reverse=True)):
|
|
||||||
if int(user[11]) == 0:
|
|
||||||
break
|
|
||||||
|
|
||||||
perc = round(int(user[11]) * 100 / message_count, 2)
|
|
||||||
|
|
||||||
name = self.utilsCog.getDisplayName(ctx, user[0])
|
|
||||||
if int(user[0]) == int(ctx.author.id):
|
|
||||||
boardTop.append("**{} ({:,} | {}%)**".format(name, round(int(user[11])), perc))
|
|
||||||
else:
|
|
||||||
boardTop.append("{} ({:,} | {}%)".format(name, round(int(user[11])), perc))
|
|
||||||
await self.startPaginated(ctx, boardTop, "Messages Leaderboard")
|
|
||||||
|
|
||||||
@leaderboard.command(name="Muttn", aliases=["M", "Mutn", "Mutten"], hidden=True)
|
@leaderboard.command(name="Muttn", aliases=["M", "Mutn", "Mutten"], hidden=True)
|
||||||
async def muttn(self, ctx):
|
async def muttn(self, ctx):
|
||||||
users = muttn.getAllRows()
|
lb = leaderboards.MuttnLeaderboard(ctx=ctx)
|
||||||
boardTop = []
|
await lb.send()
|
||||||
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.empty_leaderboard(ctx, "Muttn Leaderboard", "Der zittn nog geen muttns in de server.")
|
|
||||||
|
|
||||||
if float(user[1]) == 0:
|
|
||||||
break
|
|
||||||
|
|
||||||
name = self.utilsCog.getDisplayName(ctx, user[0])
|
|
||||||
if int(user[0]) == int(ctx.author.id):
|
|
||||||
boardTop.append("**{} ({})%**".format(name, round(float(user[1]), 2)))
|
|
||||||
else:
|
|
||||||
boardTop.append("{} ({}%)".format(name, round(float(user[1]), 2)))
|
|
||||||
await self.startPaginated(ctx, boardTop, "Muttn Leaderboard")
|
|
||||||
|
|
||||||
async def callLeaderboard(self, name, ctx):
|
async def callLeaderboard(self, name, ctx):
|
||||||
command = [command for command in self.leaderboard.commands if command.name.lower() == name.lower()][0]
|
command = [command for command in self.leaderboard.commands if command.name.lower() == name.lower()][0]
|
||||||
await command(ctx)
|
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):
|
def setup(client):
|
||||||
client.add_cog(Leaderboards(client))
|
client.add_cog(Leaderboards(client))
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,6 @@ from data.menus import custom_commands
|
||||||
from data.snipe import Action, Snipe
|
from data.snipe import Action, Snipe
|
||||||
from decorators import help
|
from decorators import help
|
||||||
from enums.help_categories import Category
|
from enums.help_categories import Category
|
||||||
from functions.database.custom_commands import get_all
|
|
||||||
from functions.stringFormatters import capitalize
|
|
||||||
from startup.didier import Didier
|
from startup.didier import Didier
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -14,10 +12,9 @@ class Other(commands.Cog):
|
||||||
def __init__(self, client: Didier):
|
def __init__(self, client: Didier):
|
||||||
self.client: Didier = client
|
self.client: Didier = client
|
||||||
|
|
||||||
# TODO add locked field to Didier instead of client
|
# Don't allow any commands to work when locked
|
||||||
# # Don't allow any commands to work when locked
|
def cog_check(self, _):
|
||||||
# def cog_check(self, ctx):
|
return not self.client.locked
|
||||||
# return not self.client.locked
|
|
||||||
|
|
||||||
@commands.command(name="Custom")
|
@commands.command(name="Custom")
|
||||||
@help.Category(category=Category.Didier)
|
@help.Category(category=Category.Didier)
|
||||||
|
|
@ -25,10 +22,7 @@ class Other(commands.Cog):
|
||||||
"""
|
"""
|
||||||
Get a list of all custom commands
|
Get a list of all custom commands
|
||||||
"""
|
"""
|
||||||
all_commands = get_all()
|
await custom_commands.CommandsList(ctx).send()
|
||||||
formatted = list(sorted(map(lambda x: capitalize(x["name"]), all_commands)))
|
|
||||||
src = custom_commands.CommandsList(formatted)
|
|
||||||
await custom_commands.Pages(source=src, clear_reactions_after=True).start(ctx)
|
|
||||||
|
|
||||||
@commands.command(name="Snipe")
|
@commands.command(name="Snipe")
|
||||||
@help.Category(category=Category.Other)
|
@help.Category(category=Category.Other)
|
||||||
|
|
|
||||||
127
cogs/train.py
127
cogs/train.py
|
|
@ -1,127 +0,0 @@
|
||||||
from data.menus import paginated_leaderboard
|
|
||||||
from decorators import help
|
|
||||||
import discord
|
|
||||||
from discord.ext import commands, menus
|
|
||||||
from enums.help_categories import Category
|
|
||||||
from functions import checks, timeFormatters
|
|
||||||
import requests
|
|
||||||
|
|
||||||
|
|
||||||
class Train(commands.Cog):
|
|
||||||
|
|
||||||
def __init__(self, client):
|
|
||||||
self.client = client
|
|
||||||
|
|
||||||
# Don't allow any commands to work when locked
|
|
||||||
def cog_check(self, ctx):
|
|
||||||
return not self.client.locked
|
|
||||||
|
|
||||||
@commands.command(name="Train", aliases=["Trein"], usage="[Vertrek]* [Bestemming]")
|
|
||||||
@help.Category(category=Category.School)
|
|
||||||
async def train(self, ctx, *args):
|
|
||||||
if not args or len(args) > 2:
|
|
||||||
await ctx.send("Controleer je argumenten.")
|
|
||||||
return
|
|
||||||
destination = args[-1]
|
|
||||||
departure = args[0] if len(args) > 1 else "Gent Sint-Pieters"
|
|
||||||
|
|
||||||
req = requests.get(
|
|
||||||
"http://api.irail.be/connections/?from={}&to={}&alerts=true&lang=nl&format=json".format(departure,
|
|
||||||
destination)).json()
|
|
||||||
if "error" in req:
|
|
||||||
embed = discord.Embed(colour=discord.Colour.red())
|
|
||||||
embed.set_author(name="Treinen van {} naar {}".format(
|
|
||||||
self.formatCity(departure), self.formatCity(destination)))
|
|
||||||
embed.add_field(name="Error", value="Er ging iets fout, probeer het later opnieuw.", inline=False)
|
|
||||||
await self.sendEmbed(ctx, embed)
|
|
||||||
return
|
|
||||||
|
|
||||||
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):
|
|
||||||
response = []
|
|
||||||
for connection in sorted(connections, key=lambda con: con["departure"]["time"]):
|
|
||||||
conn = {}
|
|
||||||
if connection["departure"]["canceled"] != "0" or connection["arrival"]["canceled"] != "0":
|
|
||||||
conn = {"Canceled": "Afgeschaft"}
|
|
||||||
dep = connection["departure"]
|
|
||||||
arr = connection["arrival"]
|
|
||||||
conn["depStation"] = self.formatCity(dep["station"])
|
|
||||||
conn["depTime"] = self.formatTime(dep["time"])
|
|
||||||
conn["delay"] = self.formatDelay(dep["delay"])
|
|
||||||
conn["track"] = dep["platform"]
|
|
||||||
conn["arrStation"] = self.formatCity(arr["station"])
|
|
||||||
conn["direction"] = self.formatCity(dep["direction"]["name"])
|
|
||||||
conn["arrTime"] = self.formatTime(arr["time"])
|
|
||||||
conn["duration"] = self.formatTime(connection["duration"])
|
|
||||||
response.append(conn)
|
|
||||||
return response
|
|
||||||
|
|
||||||
def formatTime(self, timestamp):
|
|
||||||
if int(timestamp) <= 86400:
|
|
||||||
minutes = int(timestamp) // 60
|
|
||||||
if minutes < 60:
|
|
||||||
return str(minutes) + "m"
|
|
||||||
return "{}h{:02}m".format(minutes // 60, minutes % 60)
|
|
||||||
else:
|
|
||||||
return timeFormatters.epochToDate(int(timestamp), "%H:%M")["date"]
|
|
||||||
|
|
||||||
def formatDelay(self, seconds):
|
|
||||||
seconds = int(seconds)
|
|
||||||
return self.sign(seconds) + self.formatTime(abs(seconds)) if seconds != 0 else ""
|
|
||||||
|
|
||||||
def sign(self, number):
|
|
||||||
return "-" if int(number) < 0 else "+"
|
|
||||||
|
|
||||||
def formatCity(self, city):
|
|
||||||
city = city[0].upper() + city[1:]
|
|
||||||
arr = []
|
|
||||||
for i, letter in enumerate(city):
|
|
||||||
if (i > 0 and (city[i - 1] == " " or city[i - 1] == "-")) or i == 0:
|
|
||||||
arr.append(letter.upper())
|
|
||||||
else:
|
|
||||||
arr.append(letter.lower())
|
|
||||||
return "".join(arr)
|
|
||||||
|
|
||||||
async def sendEmbed(self, ctx, embed):
|
|
||||||
if await checks.allowedChannels(ctx):
|
|
||||||
await ctx.send(embed=embed)
|
|
||||||
else:
|
|
||||||
await ctx.author.send(embed=embed)
|
|
||||||
|
|
||||||
|
|
||||||
class TrainPagination(menus.ListPageSource):
|
|
||||||
def __init__(self, data, departure, destination):
|
|
||||||
super().__init__(data, per_page=3)
|
|
||||||
self.departure = departure
|
|
||||||
self.destination = destination
|
|
||||||
|
|
||||||
async def format_page(self, menu: menus.MenuPages, entries):
|
|
||||||
offset = menu.current_page * self.per_page
|
|
||||||
embed = discord.Embed(colour=discord.Colour.blue())
|
|
||||||
embed.set_author(name="Treinen van {} naar {}".format(self.departure, self.destination))
|
|
||||||
embed.set_footer(text="{}/{}".format(menu.current_page + 1, self.get_max_pages()))
|
|
||||||
|
|
||||||
for i, connection in enumerate(entries, start=offset):
|
|
||||||
afgeschaft = "Canceled" in connection
|
|
||||||
embed.add_field(name="Van", value=str(connection["depStation"]), inline=True)
|
|
||||||
embed.add_field(name="Om", value=str(connection["depTime"]), inline=True)
|
|
||||||
embed.add_field(name="Spoor", value=str(connection["track"]), inline=True)
|
|
||||||
embed.add_field(name="Richting", value=str(connection["direction"]), inline=True)
|
|
||||||
embed.add_field(name="Aankomst", value=(str(connection["arrTime"])
|
|
||||||
if not afgeschaft else "**AFGESCHAFT**"), inline=True)
|
|
||||||
embed.add_field(name="Vertraging", value=str(connection["delay"]) if connection["delay"] != "" else "0",
|
|
||||||
inline=True)
|
|
||||||
|
|
||||||
# White space
|
|
||||||
if i - offset < 2:
|
|
||||||
embed.add_field(name="\u200b", value="\u200b", inline=False)
|
|
||||||
return embed
|
|
||||||
|
|
||||||
|
|
||||||
def setup(client):
|
|
||||||
client.add_cog(Train(client))
|
|
||||||
|
|
@ -1,21 +1,18 @@
|
||||||
import discord
|
from typing import Union
|
||||||
from discord.ext import menus
|
|
||||||
|
from discord import ApplicationContext
|
||||||
|
from discord.ext.commands import Context
|
||||||
|
|
||||||
|
from data.menus.paginated import Paginated
|
||||||
|
from functions.database.custom_commands import get_all
|
||||||
|
from functions.stringFormatters import capitalize
|
||||||
|
|
||||||
|
|
||||||
class CommandsList(menus.ListPageSource):
|
class CommandsList(Paginated):
|
||||||
def __init__(self, data, colour=discord.Colour.blue()):
|
def __init__(self, ctx: Union[ApplicationContext, Context]):
|
||||||
super().__init__(data, per_page=15)
|
all_commands = get_all()
|
||||||
self.colour = colour
|
commands_sorted = list(sorted(map(lambda x: (capitalize(x["name"]),), all_commands)))
|
||||||
|
super().__init__(ctx=ctx, title="Custom Commands", data=commands_sorted, per_page=15)
|
||||||
|
|
||||||
async def format_page(self, menu: menus.MenuPages, entries):
|
def format_entry(self, index: int, value: tuple) -> str:
|
||||||
embed = discord.Embed(colour=self.colour)
|
return value[0]
|
||||||
embed.set_author(name="Custom Commands")
|
|
||||||
embed.description = "\n".join(entries)
|
|
||||||
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,246 @@
|
||||||
|
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.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], **kwargs):
|
||||||
|
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, **kwargs)
|
||||||
|
|
||||||
|
async def respond(self, **kwargs) -> discord.Message:
|
||||||
|
if self.data is None:
|
||||||
|
return await self.empty_leaderboard(self.ctx, **kwargs)
|
||||||
|
|
||||||
|
return await super().respond(**kwargs)
|
||||||
|
|
||||||
|
async def send(self, **kwargs) -> discord.Message:
|
||||||
|
if self.data is None:
|
||||||
|
return await self.empty_leaderboard(self.ctx, mention_author=False, **kwargs)
|
||||||
|
|
||||||
|
return await super().send(mention_author=False, **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"
|
||||||
|
|
@ -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,127 +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 __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)
|
|
||||||
Loading…
Reference in New Issue