66from collections import namedtuple
77import datetime as dt
88from io import BytesIO
9- from typing import Union , Optional , Tuple
9+ from typing import Union , Optional
1010
1111import disnake
1212from PIL import Image , ImageDraw , ImageFont , ImageFilter
1919from utils .bot import OGIROID
2020from utils .exceptions import LevelingSystemError , UserNotFound
2121from utils .models import User , RoleReward
22+ from utils .pagination import LeaderboardView
2223from utils .shortcuts import errorEmb , sucEmb
2324
2425FakeGuild = namedtuple ("FakeGuild" , "id" )
@@ -44,6 +45,10 @@ async def on_error(self, inter, error):
4445 else :
4546 raise error
4647
48+ async def get_count (self , guild : Guild ) -> int :
49+ record = await self .db .execute ("SELECT COUNT(*) FROM levels WHERE guild_id = ?" , (guild .id ,))
50+ return (await record .fetchone ())[0 ]
51+
4752 async def get_leaderboard (self , guild : Guild , limit : int = 10 , offset : Optional [int , int ] = None ) -> list [User ]:
4853 """get a list of users
4954 optionally you can specify a range of users to get from the leaderboard e.g. 200, 230
@@ -180,12 +185,12 @@ async def grant_xp(self, message):
180185
181186 async def handle_message (self , message : Message ):
182187 if any (
183- [
184- message .guild is None ,
185- message .author .bot ,
186- message .type not in [MessageType .default , MessageType .reply , MessageType .thread_starter_message ],
187- message .content .__len__ () < 5 ,
188- ]
188+ [
189+ message .guild is None ,
190+ message .author .bot ,
191+ message .type not in [MessageType .default , MessageType .reply , MessageType .thread_starter_message ],
192+ message .content .__len__ () < 5 ,
193+ ]
189194 ):
190195 return
191196 if not random .randint (1 , 3 ) == 1 :
@@ -280,10 +285,9 @@ async def send_levelup(message: Message, level: int):
280285 user = message .author
281286 if level in [0 , 1 , 2 , 3 ]:
282287 return
283- msg = f"""{ user .mention } , you have leveled up to level { level } !
288+ msg = f"""{ user .mention } , you have leveled up to level { level } ! 🥳
284289 """
285- addemoji = await message .channel .send (msg )
286- await addemoji .add_reaction ("🥳" )
290+ await message .channel .send (msg )
287291
288292 async def get_rank (self , guild_id , user_record ) -> int :
289293 """
@@ -400,43 +404,49 @@ async def leaderboard(self, inter: ApplicationCommandInteraction):
400404 Get the leaderboard of the server
401405 """
402406
403- # embed.add_field(name=f"{i + 1}. {user}", value=f"Level: {record.lvl}\nTotal XP: {record.total_exp:,}", inline=False)
404407 await inter .response .defer ()
405- records = await self .controller .get_leaderboard (inter .guild , limit = 10 )
408+ limit = 10
409+ set_user = False
410+ records = await self .controller .get_leaderboard (inter .guild , limit = limit )
411+ try :
412+ cmd_user = await self .controller .get_user (inter .author )
413+ except UserNotFound :
414+ cmd_user = None
415+
406416 if not records :
407417 return await errorEmb (inter , text = "No records found!" )
408418 embed = Embed (title = "Leaderboard" , color = 0x00FF00 )
409419
410420 for i , record in enumerate (records ):
411421 user = await self .bot .fetch_user (record .user_id )
412- embed . add_field ( name = f" { i + 1 } . { user } " , value = f"Level: { record . lvl } \n Total XP: { record . total_exp :, } " , inline = False )
413-
414- user = await self . controller . get_user ( inter . author )
415- if user :
416- try :
417- rank = await self . controller . get_rank ( inter . guild . id , user )
418- if rank > 10 :
419- embed . add_field (
420- name = f" { rank } . You" ,
421- value = f"Level: { user . lvl } \n Total XP: { user . xp :, } " ,
422- inline = False ,
423- )
424- except ValueError :
425- pass
422+ if record . user_id == inter . author . id :
423+ embed . add_field ( name = f" { i + 1 } . { user } ~ You " ,
424+ value = f"Level: { record . lvl } \n Total XP: { record . total_exp :, } " , inline = False )
425+ set_user = True
426+ else :
427+ embed . add_field ( name = f" { i + 1 } . { user } " , value = f"Level: { record . lvl } \n Total XP: { record . total_exp :, } " ,
428+ inline = False )
429+ if not set_user :
430+ rank = await self . controller . get_rank ( inter . guild . id , cmd_user )
431+ embed . add_field (
432+ name = f" { rank } . You" ,
433+ value = f"Level: { cmd_user . lvl } \n Total XP: { cmd_user . xp :, } " ,
434+ inline = False ,
435+ )
426436
427437 embed .set_footer (text = f"{ inter .author } " , icon_url = inter .author .avatar .url )
428438 embed .timestamp = dt .datetime .now ()
429439
430- await inter .send (embed = embed )
440+ await inter .send (embed = embed , view = LeaderboardView ( inter , self . controller , embed , inter . author . id ) )
431441
432442 @commands .slash_command ()
433443 @commands .guild_only ()
434444 @commands .has_any_role ("Staff" , "staff" )
435445 async def set_lvl (
436- self ,
437- inter : ApplicationCommandInteraction ,
438- user : Member ,
439- level : int = Param (description = "The level to set the user to" , le = 100 , ge = 0 ),
446+ self ,
447+ inter : ApplicationCommandInteraction ,
448+ user : Member ,
449+ level : int = Param (description = "The level to set the user to" , le = 100 , ge = 0 ),
440450 ):
441451 """
442452 Set a user's level
@@ -461,16 +471,17 @@ async def role_reward(self, inter: ApplicationCommandInteraction):
461471 @role_reward .sub_command ()
462472 @commands .has_permissions (manage_roles = True )
463473 async def add (
464- self ,
465- inter : ApplicationCommandInteraction ,
466- role : Role = Param (name = "role" , description = "what role to give" ),
467- level_needed : int = Param (name = "level_needed" , description = "The level needed to get the role" ),
474+ self ,
475+ inter : ApplicationCommandInteraction ,
476+ role : Role = Param (name = "role" , description = "what role to give" ),
477+ level_needed : int = Param (name = "level_needed" , description = "The level needed to get the role" ),
468478 ):
469479 """adds a role to the reward list"""
470480 if int (level_needed ) not in self .levels :
471481 return await errorEmb (inter , text = f"Level must be within 1-{ MAX_LEVEL } found" )
472482
473- if await self .bot .db .execute ("SELECT 1 FROM role_rewards WHERE guild_id = ? AND role_id = ?" , (inter .guild .id , role .id )):
483+ if await self .bot .db .execute ("SELECT 1 FROM role_rewards WHERE guild_id = ? AND role_id = ?" ,
484+ (inter .guild .id , role .id )):
474485 sql = "INSERT OR IGNORE INTO role_rewards (guild_id, role_id, required_lvl) VALUES (?, ?, ?)"
475486 await self .bot .db .execute (sql , (inter .guild .id , role .id , level_needed ))
476487 await self .bot .db .commit ()
@@ -480,12 +491,13 @@ async def add(
480491 @role_reward .sub_command ()
481492 @commands .has_permissions (manage_roles = True )
482493 async def remove (
483- self ,
484- inter : ApplicationCommandInteraction ,
485- role : Role = Param (name = "role" , description = "what role to remove" ),
494+ self ,
495+ inter : ApplicationCommandInteraction ,
496+ role : Role = Param (name = "role" , description = "what role to remove" ),
486497 ):
487498 """remove a role reward"""
488- if await self .bot .db .execute ("SELECT 1 FROM role_rewards WHERE guild_id = ? AND role_id = ?" , (inter .guild .id , role .id )):
499+ if await self .bot .db .execute ("SELECT 1 FROM role_rewards WHERE guild_id = ? AND role_id = ?" ,
500+ (inter .guild .id , role .id )):
489501 sql = "DELETE FROM role_rewards WHERE guild_id = ? AND role_id = ?"
490502 await self .bot .db .execute (sql , (inter .guild .id , role .id ))
491503 await self .bot .db .commit ()
@@ -505,9 +517,11 @@ async def list(self, inter: ApplicationCommandInteraction):
505517 for record in records :
506518 record = RoleReward (* record )
507519 embed .add_field (
508- name = f"Level { record .required_lvl } " , value = f"{ inter .guild .get_role (record .role_id ).mention } " , inline = False
520+ name = f"Level { record .required_lvl } " , value = f"{ inter .guild .get_role (record .role_id ).mention } " ,
521+ inline = False
509522 )
510- await inter .send (embed = embed , allowed_mentions = disnake .AllowedMentions (everyone = False , roles = False , users = False ))
523+ await inter .send (embed = embed ,
524+ allowed_mentions = disnake .AllowedMentions (everyone = False , roles = False , users = False ))
511525
512526
513527def setup (bot : OGIROID ):
0 commit comments