Reputation: 27
This is my event that configures levels for each member and stores the information in a JSON file. I would like a leaderboard that lists the top 10 people with the highest level but I am unsure how to go about doing this. Thanks in advance.
class on_message(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.Cog.listener()
async def on_message(self, message):
channel = self.bot.get_channel(config.server_chat)
with open("users.json", "r") as f:
users = json.load(f)
await update_data(users, message.author)
await add_experience(users, message.author, 1)
await level_up(users, message.author, message, channel)
with open("users.json", "w") as f:
json.dump(users, f)
async def update_data(users, user):
if not str(user.id) in users:
users[str(user.id)] = {}
users[str(user.id)]["experience"] = 0
users[str(user.id)]["level"] = 1
users[str(user.id)]["messages"] = 0
async def add_experience(users, user, exp):
users[str(user.id)]["experience"] += exp
users[str(user.id)]["messages"] += exp
async def level_up(users, user, message, channel):
experience = users[str(user.id)]["experience"]
lvl_start = users[str(user.id)]["level"]
lvl_end = int(lvl_start * 5)
update = lvl_start + 1
if experience >= lvl_end:
users[str(user.id)]["experience"] = 0
users[str(user.id)]["level"] = lvl_start + 1
if not message.author.bot:
lvl = users[str(user.id)]["level"]
await channel.send(f"**{user.mention} reached level {update}**")
def setup(bot):
bot.add_cog(on_message(bot))
Upvotes: 0
Views: 332
Reputation: 2917
You can sort JSON data and get first 10 users:
@commands.command()
async def leaderboard(self, ctx):
with open("users.json", "w") as f:
data = json.load(f)
embed = discord.Embed(title="Leaderboard")
for user_id, user_data in sorted(data.items(), key=lambda x: x[1]['experience'], reverse=True)[:10]:
embed.add_field(name=self.bot.get_user(user_id), value=f"Experience: {user_data['experience']}\nLevel: {user_data['level']}", inline=False)
await ctx.send(embed=embed)
Upvotes: 1