Package: disnakeSuperUtils
disnake-super-utilsDocumentationSecondary DocumentationA modern python module including many useful features that make discord bot programming extremely easy.The documentation is not done. if you have any questions, feel free to ask them in ourdiscord server.FeaturesVery easy to use and user-friendly.Object Oriented.Modern Leveling Manager.Modern Music/Audio playing manager. [Lavalink and FFmpeg support]Modern Async Database Manager (SQLite, MongoDB, PostgreSQL, MySQL, MariaDB).Modern Paginator.Modern Reaction Manager.Modern Economy Manager.Modern Image Manager (PIL).Modern Invite Tracker.Modern Command Hinter.Modern FiveM Server Parser.Modern Birthday Manager.Modern Prefix Manager.Includes easy to use convertors.Modern spotify client that is optimized for player fetching.Modern Punishment Manager (Kick, Ban, Infractions, Mutes)Modern Template Manager.Modern CogManager that supports usage of managers in discord cogs.Modern MessageFilter and AntiSpam.Customizable ModMail ManagerModern Youtube client that is optimized for player fetching.And many more!
(MORE COMING SOON!)InstallationInstalling disnakeSuperUtils is very easy.python-mpipinstalldisnakeSuperUtilsExamplesLeveling Example (With Role Manager)importdisnakefromdisnake.extimportcommandsimportdisnakeSuperUtilsbot=commands.Bot(command_prefix="-",intents=discord.Intents.all())LevelingManager=disnakeSuperUtils.LevelingManager(bot,award_role=True)ImageManager=(disnakeSuperUtils.ImageManager())# LevelingManager uses ImageManager to create the rank command.@bot.eventasyncdefon_ready():database=disnakeSuperUtils.DatabaseManager.connect(...)awaitLevelingManager.connect_to_database(database,["xp","roles","role_list"])print("Leveling manager is ready.",bot.user)@LevelingManager.event()asyncdefon_level_up(message,member_data,roles):awaitmessage.reply(f"You are now level{awaitmember_data.level()}"+(f", you have received the{roles[0]}"f" role."ifroleselse""))@bot.command()asyncdefrank(ctx):member_data=awaitLevelingManager.get_account(ctx.author)ifnotmember_data:awaitctx.send(f"I am still creating your account! please wait a few seconds.")returnguild_leaderboard=awaitLevelingManager.get_leaderboard(ctx.guild)member=[xforxinguild_leaderboardifx.member==ctx.author.id]image=awaitImageManager.create_leveling_profile(ctx.author,member_data,disnakeSuperUtils.Backgrounds.GALAXY,(127,255,0),guild_leaderboard.index(member[0])+1ifmemberelse-1,outline=5,)awaitctx.send(file=image)@bot.command()asyncdefset_roles(ctx,interval:int,*roles:discord.Role):awaitLevelingManager.set_interval(ctx.guild,interval)awaitLevelingManager.set_roles(ctx.guild,roles)awaitctx.send(f"Successfully set the interval to{interval}and role list to{', '.join(role.nameforroleinroles)}")@bot.command()asyncdefleaderboard(ctx):guild_leaderboard=awaitLevelingManager.get_leaderboard(ctx.guild)formatted_leaderboard=[f"Member:{x.member}, XP:{awaitx.xp()}"forxinguild_leaderboard]awaitdisnakeSuperUtils.PageManager(ctx,disnakeSuperUtils.generate_embeds(formatted_leaderboard,title="Leveling Leaderboard",fields=25,description=f"Leaderboard of{ctx.guild}",),).run()bot.run("token")Playing Examplefrommathimportfloorfromdisnake.extimportcommandsimportdisnakeSuperUtilsfromdisnakeSuperUtilsimportMusicManagerimportdisnakeclient_id=""client_secret=""bot=commands.Bot(command_prefix="-",intents=discord.Intents.all())# MusicManager = MusicManager(bot, spotify_support=False)MusicManager=MusicManager(bot,client_id=client_id,client_secret=client_secret,spotify_support=True)# if using spotify support use this instead ^^^@MusicManager.event()asyncdefon_music_error(ctx,error):raiseerror# add your error handling here! Errors are listed in the documentation.@MusicManager.event()asyncdefon_queue_end(ctx):print(f"The queue has ended in{ctx}")# You could wait and check activity, etc...@MusicManager.event()asyncdefon_inactivity_disconnect(ctx):print(f"I have left{ctx}due to inactivity..")@MusicManager.event()asyncdefon_play(ctx,player):awaitctx.send(f"Playing{player}")@bot.eventasyncdefon_ready():# database = disnakeSuperUtils.DatabaseManager.connect(...)# await MusicManager.connect_to_database(database, ["playlists"])print("Music manager is ready.",bot.user)@bot.command()asyncdefleave(ctx):ifawaitMusicManager.leave(ctx):awaitctx.send("Left Voice Channel")@bot.command()asyncdefnp(ctx):ifplayer:=awaitMusicManager.now_playing(ctx):duration_played=awaitMusicManager.get_player_played_duration(ctx,player)# You can format it, of course.awaitctx.send(f"Currently playing:{player},\n"f"Duration:{duration_played}/{player.duration}")@bot.command()asyncdefjoin(ctx):ifawaitMusicManager.join(ctx):awaitctx.send("Joined Voice Channel")@bot.group(invoke_without_command=True)asyncdefplaylists(ctx,user:discord.User):user_playlists=awaitMusicManager.get_user_playlists(user)formatted_playlists=[f"ID: '{user_playlist.id}'\nTitle: '{user_playlist.playlist.title}'\nTotal Songs:{len(user_playlist.playlist.songs)}"foruser_playlistinuser_playlists]embeds=disnakeSuperUtils.generate_embeds(formatted_playlists,f"Playlists of{user}",f"Shows{user.mention}'s playlists.",25,string_format="{}",)page_manager=disnakeSuperUtils.PageManager(ctx,embeds,public=True)awaitpage_manager.run()@playlists.command()asyncdefadd(ctx,url:str):added_playlist=awaitMusicManager.add_playlist(ctx.author,url)ifnotadded_playlist:awaitctx.send("Playlist URL not found!")returnawaitctx.send(f"Playlist added with ID{added_playlist.id}")@playlists.command()asyncdefplay(ctx,playlist_id:str):# This command is just an example, and not something you should do.# The saved playlist system is supposed to provide fast, easy and simple playing, and the user should not look for# the right playlist id before playing, as that defeats the whole point.# Instead of playing using a playlist id, I recommend playing using indexes.# Please, if you are playing using indexes, find the playlist id you need by getting all the user's playlists# and then finding the id from there.# Find the user's playlists using MusicManager.get_user_playlists(ctx.author, partial=True).# Make sure partial is True to speed up the fetching progress (incase you want to access the playlist data,# you can set it to False, of course).# Using these playlists, find the id the user wants, and play it (or whatever else you want to do with it).# Be creative!user_playlist=awaitMusicManager.get_playlist(ctx.author,playlist_id)ifnotuser_playlist:awaitctx.send("That playlist does not exist!")returnifnotctx.voice_clientornotctx.voice_client.is_connected():awaitMusicManager.join(ctx)asyncwithctx.typing():players=awaitMusicManager.create_playlist_players(user_playlist.playlist,ctx.author)ifplayers:ifawaitMusicManager.queue_add(players=players,ctx=ctx)andnotawaitMusicManager.play(ctx):awaitctx.send(f"Added playlist{user_playlist.playlist.title}")else:awaitctx.send("Query not found.")@playlists.command()asyncdefremove(ctx,playlist_id:str):user_playlist=awaitMusicManager.get_playlist(ctx.author,playlist_id)ifnotuser_playlist:awaitctx.send(f"Playlist with id{playlist_id}is not found.")returnawaituser_playlist.delete()awaitctx.send(f"Playlist{user_playlist.playlist.title}has been deleted")@bot.command()asyncdefplay(ctx,*,query:str):ifnotctx.voice_clientornotctx.voice_client.is_connected():awaitMusicManager.join(ctx)asyncwithctx.typing():players=awaitMusicManager.create_player(query,ctx.author)ifplayers:ifawaitMusicManager.queue_add(players=players,ctx=ctx)andnotawaitMusicManager.play(ctx):awaitctx.send("Added to queue")else:awaitctx.send("Query not found.")@bot.command()asyncdeflyrics(ctx,query:str=None):ifresponse:=awaitMusicManager.lyrics(ctx,query):title,author,query_lyrics=responsesplitted=query_lyrics.split("\n")res=[]current=""fori,splitinenumerate(splitted):iflen(splitted)<=i+1orlen(current)+len(splitted[i+1])>1024:res.append(current)current=""continuecurrent+=split+"\n"page_manager=disnakeSuperUtils.PageManager(ctx,[discord.Embed(title=f"Lyrics for '{title}' by '{author}', (Page{i+1}/{len(res)})",description=x,)fori,xinenumerate(res)],public=True,)awaitpage_manager.run()else:awaitctx.send("No lyrics found.")@bot.command()asyncdefpause(ctx):ifawaitMusicManager.pause(ctx):awaitctx.send("Player paused.")@bot.command()asyncdefresume(ctx):ifawaitMusicManager.resume(ctx):awaitctx.send("Player resumed.")@bot.command()asyncdefvolume(ctx,volume:int):awaitMusicManager.volume(ctx,volume)@bot.command()asyncdefloop(ctx):is_loop=awaitMusicManager.loop(ctx)ifis_loopisnotNone:awaitctx.send(f"Looping toggled to{is_loop}")@bot.command()asyncdefshuffle(ctx):is_shuffle=awaitMusicManager.shuffle(ctx)ifis_shuffleisnotNone:awaitctx.send(f"Shuffle toggled to{is_shuffle}")@bot.command()asyncdefautoplay(ctx):is_autoplay=awaitMusicManager.autoplay(ctx)ifis_autoplayisnotNone:awaitctx.send(f"Autoplay toggled to{is_autoplay}")@bot.command()asyncdefqueueloop(ctx):is_loop=awaitMusicManager.queueloop(ctx)ifis_loopisnotNone:awaitctx.send(f"Queue looping toggled to{is_loop}")@bot.command()asyncdefcomplete_queue(ctx):ifctx_queue:=awaitMusicManager.get_queue(ctx):formatted_queue=[f"Title: '{x.title}'\nRequester:{x.requesterandx.requester.mention}\n"f"Position:{i-ctx_queue.pos}"fori,xinenumerate(ctx_queue.queue)]num_of_fields=25embeds=disnakeSuperUtils.generate_embeds(formatted_queue,"Complete Song Queue","Shows the complete song queue.",num_of_fields,string_format="{}",)page_manager=disnakeSuperUtils.PageManager(ctx,embeds,public=True,index=floor(ctx_queue.pos/25))awaitpage_manager.run()@bot.command()asyncdefgoto(ctx,position:int):ifctx_queue:=awaitMusicManager.get_queue(ctx):new_pos=ctx_queue.pos+positionifnot0<=new_pos<len(ctx_queue.queue):awaitctx.send("Position is out of bounds.")returnawaitMusicManager.goto(ctx,new_pos)awaitctx.send(f"Moved to position{position}")@bot.command()asyncdefhistory(ctx):ifctx_queue:=awaitMusicManager.get_queue(ctx):formatted_history=[f"Title: '{x.title}'\nRequester:{x.requesterandx.requester.mention}"forxinctx_queue.history]embeds=disnakeSuperUtils.generate_embeds(formatted_history,"Song History","Shows all played songs",25,string_format="{}",)page_manager=disnakeSuperUtils.PageManager(ctx,embeds,public=True)awaitpage_manager.run()@bot.command()asyncdefskip(ctx,index:int=None):awaitMusicManager.skip(ctx,index)@bot.command()asyncdefqueue(ctx):ifctx_queue:=awaitMusicManager.get_queue(ctx):formatted_queue=[f"Title: '{x.title}\nRequester:{x.requesterandx.requester.mention}"forxinctx_queue.queue[ctx_queue.pos+1:]]embeds=disnakeSuperUtils.generate_embeds(formatted_queue,"Queue",f"Now Playing:{awaitMusicManager.now_playing(ctx)}",25,string_format="{}",)page_manager=disnakeSuperUtils.PageManager(ctx,embeds,public=True)awaitpage_manager.run()@bot.command()asyncdefrewind(ctx,index:int=None):awaitMusicManager.previous(ctx,index,no_autoplay=True)@bot.command()asyncdefls(ctx):ifqueue:=awaitMusicManager.get_queue(ctx):loop=queue.looploop_status=Noneifloop==disnakeSuperUtils.Loops.LOOP:loop_status="Looping enabled."elifloop==disnakeSuperUtils.Loops.QUEUE_LOOP:loop_status="Queue looping enabled."elifloop==disnakeSuperUtils.Loops.NO_LOOP:loop_status="No loop enabled."ifloop_status:awaitctx.send(loop_status)@bot.command()asyncdefmove(ctx,player_index:int,index:int):awaitMusicManager.move(ctx,player_index,index)bot.run("token")More examples are listed in the examples folder.Known IssuesRemoving an animated emoji wont be recognized as a reaction role, as it shows up as not animated for some reason, breaking the reaction matcher. (Discord API Related)Leveling might call the on_level_up event multiple times, resulting in duplicate messages, caused by duplicate records in the leveling table. (Fixed)SupportSupport ServerDocumentation