defxult / discordlevelingsystem Goto Github PK
View Code? Open in Web Editor NEWA library to implement a leveling system into a discord bot. Contains features such as XP, level, ranks, and role awards.
License: MIT License
A library to implement a leveling system into a discord bot. Contains features such as XP, level, ranks, and role awards.
License: MIT License
Is the repository open for contribution?
If it is open I would love to work on some leveling cards for more user customization...
using PIL i made this and would live to implement here, if possible
also i have some ideas for leaderboard
I would love to work on a fork if i am allowed to make something like this!
Hello !
I just wanted to know how do I set a maximum xp for each level?
for example 100 XP for 1 Level
Hi @Defxult,
First of thank you for sharing this awesome set of levelling tools.
I would like to ask if it would it be possible to add level promotion, what I mean by this at each level cap the experience accumulations stops until a faction to 'promote' a user is called.
Example:
In my mind it would be an setting that skips automated advancement of the user and lets that behaviour be decided outside the library.
I hope it is something that can be added as it would save me allot of time having to start a level system from scratch.
I don't know if this is possible or not but this method would return an int
based on the amount of xp
needed for a level
It's similar to next_level_up()
but instead of returning the remaining
amount it returns the total
amount
Example:
xp_needed_for_level_2 = await DiscordLevelingSystem.get_xp_for_level(2)
print(xp_needed_for_level_2)
# >>> 200 (Example int)
Describe the bug
When I try to install discordLevelingSystem, a error message appear, and I don't know what cause this, I laready tried to change python version, and nothing changed, tried --upgrade (still nothing), so I don't know what to do. (yes discord is installed on my computer ( I used pip install discord --upgrade), but it still say ModuleNotFoundError: No module named 'discord' ).
To Reproduce
pip install discordLevelingSystem
Traceback if any
Collecting discordLevelingSystem (from -r .\requirements.txt (line 7))
Using cached discordLevelingSystem-1.2.0.tar.gz (58 kB)
Installing build dependencies ... done
Getting requirements to build wheel ... error
error: subprocess-exited-with-error
× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─> [21 lines of output]
Traceback (most recent call last):
File "C:\Users\ender\AppData\Local\Programs\Python\Python310\lib\site-packages\pip\_vendor\pyproject_hooks\_in_process\_in_process.py", line 353, in <module>
main()
File "C:\Users\ender\AppData\Local\Programs\Python\Python310\lib\site-packages\pip\_vendor\pyproject_hooks\_in_process\_in_process.py", line 335, in main
json_out['return_val'] = hook(**hook_input['kwargs'])
File "C:\Users\ender\AppData\Local\Programs\Python\Python310\lib\site-packages\pip\_vendor\pyproject_hooks\_in_process\_in_process.py", line 118, in get_requires_for_build_wheel
return hook(config_settings)
File "C:\Users\ender\AppData\Local\Temp\pip-build-env-_ab12cde\overlay\Lib\site-packages\setuptools\build_meta.py", line 341, in get_requires_for_build_wheel
return self._get_build_requires(config_settings, requirements=['wheel'])
File "C:\Users\ender\AppData\Local\Temp\pip-build-env-_ab12cde\overlay\Lib\site-packages\setuptools\build_meta.py", line 323, in _get_build_requires
self.run_setup()
File "C:\Users\ender\AppData\Local\Temp\pip-build-env-_ab12cde\overlay\Lib\site-packages\setuptools\build_meta.py", line 487, in run_setup
super(_BuildMetaLegacyBackend,
File "C:\Users\ender\AppData\Local\Temp\pip-build-env-_ab12cde\overlay\Lib\site-packages\setuptools\build_meta.py", line 338, in run_setup
exec(code, locals())
File "<string>", line 2, in <module>
File "C:\Users\ender\AppData\Local\Temp\pip-install-fghi23jk\discordlevelingsystem_8e83c0b019e441568f860ceb21d4a8fd\discordLevelingSystem\__init__.py", line 12, in <module>
from .announcement import LevelUpAnnouncement
File "C:\Users\ender\AppData\Local\Temp\pip-install-fghi23jk\discordlevelingsystem_8e83c0b019e441568f860ceb21d4a8fd\discordLevelingSystem\announcement.py", line 28, in <module>
from discord import AllowedMentions, Embed, Member as DMember
ModuleNotFoundError: No module named 'discord'
[end of output]
note: This error originates from a subprocess, and is likely not a problem with pip.
error: subprocess-exited-with-error
× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─> See above for output.
note: This error originates from a subprocess, and is likely not a problem with pip.
Required Checklist
Version Info
What's the exact version of discordLevelingSystem/discord.py are you using?
pip show discord.py Name: discord.py Version: 2.2.3 Summary: A Python wrapper for the Discord API Home-page: https://github.com/Rapptz/discord.py
Hi, i would like to request mongodb integration. as i want to host my py-cord bot on heroku and since heroku has ephemeral storage system, the .db files would be cleared out periodically.
Hence i request support for mongodb
Hello @Defxult !
I would like to suggest some features which can be added to the PyPI / GitHub
lib version in the next update.
1. LevelUpAnnouncement Class Attributes: (for embeds)
LevelUpAnnouncement.AUTHOR_AVATAR
LevelUpAnnouncement.AUTHOR_NAME (instead of mention)
LevelUpAnnouncement.GUILD_ICON
(url)
2. XP / LEVEL Methods
DiscordLevelingSystem.add_xp(member: Member)
DiscordLevelingSystem.remove_xp(member: Member)
DiscordLevelingSystem.set_level(member: Member)
DiscordLevelingSystem.set_booster_role(role: Role, *, boost_amount)
(eg. boost_amount : 2x, 3x, 0.5x)
3. EASY LEADERBOARD Methods
DiscordLevelingSystem.leaderboard(guild: Guild, message : str)
(normal message)3. ADVANCED LEADERBOARD Methods
DiscordLevelingSystem.leaderboard(guild: Guild, message : Embed)
(embedded message)4. NEW CLASS For Leaderboard
Class Attributes for Leaderboard
: (discord.Embed)
Leaderboard.MEMBER_NAME
Leaderboard.MEMBER_MENTION
Leaderboard.GUILD_ICON
(url)
Thanks.
(Discord : INFINIX#7276)
Describe the bug
When doing add_xp() the xp is added only to the user's total xp and the current xp is not updated. When I consult the database I can see that lxp is added but only to the total xp.
To Reproduce
Minimal code to reproduce the bug/error
import discord
from discordLevelingSystem import DiscordLevelingSystem, RoleAward, LevelUpAnnouncement
lvl = DiscordLevelingSystem(level_up_announcement=announcement, no_xp_channels=[1022441601420759100])
announcement = LevelUpAnnouncement(f'{LevelUpAnnouncement.Member.mention} just leveled up to level {LevelUpAnnouncement.LEVEL} 😎')
lvl.connect_to_database_file(r'database path')
bot = discord.Bot(intents=discord.Intents(messages=True, guilds=True, members=True))
@bot.event
async def on_voice_state_update(member, before, after):
print("Voice state updated")
if before.channel is None and after.channel is not None:
print("User joined a voice channel")
await lvl.add_xp(member, 20)
print("20 xp added to user")
print(member)
Traceback if any
N/A
Required Checklist
Version Info
What's the exact version of discordLevelingSystem/discord.py are you using?
Users or Guilds without icons/avatars break the bot
If something doesn't have an avatar, it'll give an error
To Reproduce
Use the bare minimum code in the README
Traceback if any
Traceback (most recent call last):
File "C:\Users\censor\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\client.py", line 382, in _run_event
await coro(*args, **kwargs)
File "c:\Users\censor\Documents\Github\file-storage\Robot Maxx\cogs\levels.py", line 41, in on_message
await self.lvl.award_xp(amount=25, message=message)
File "C:\Users\censor\AppData\Local\Programs\Python\Python310\lib\site-packages\discordLevelingSystem\decorators.py", line 62, in wrapper
return await func(*args, **kwargs)
File "C:\Users\censor\AppData\Local\Programs\Python\Python310\lib\site-packages\discordLevelingSystem\decorators.py", line 80, in wrapper
return await func(*args, **kwargs)
File "C:\Users\censor\AppData\Local\Programs\Python\Python310\lib\site-packages\discordLevelingSystem\decorators.py", line 104, in wrapper
return await func(*args, **kwargs)
File "C:\Users\censor\AppData\Local\Programs\Python\Python310\lib\site-packages\discordLevelingSystem\leveling_system.py", line 1899, in award_xp
await self._handle_level_up(message, md, leveled_up=member_level_up)
File "C:\Users\censor\AppData\Local\Programs\Python\Python310\lib\site-packages\discordLevelingSystem\leveling_system.py", line 1713, in _handle_level_up
announcement_message = lua._parse_message(lua.message, self._message_author)
File "C:\Users\censor\AppData\Local\Programs\Python\Python310\lib\site-packages\discordLevelingSystem\announcement.py", line 212, in _parse_message
full = self._convert_member_markdown(partial, message_author)
File "C:\Users\censor\AppData\Local\Programs\Python\Python310\lib\site-packages\discordLevelingSystem\announcement.py", line 180, in _convert_member_markdown
AnnouncementMember.avatar_url : message_author.avatar.url,
AttributeError: 'NoneType' object has no attribute 'url'
Required Checklist
py_cord-2.0.0.dist-info
discordLevelingSystem-1.1.0-py3.10.egg-info
Describe the bug
leaderboard doesn't sort users correctly
You're on the level 3 (#2) and you have 608 XP!
Top 1: someone №1
Top 2: someone №2
Top 3: someone else
while should be:
Top 1: someone №1
Top 2: TheRjavisDev
Top 3: someone else
To Reproduce
Minimal code to reproduce the bug/error
data = await lvl.each_member_data(ctx.guild,sort_by='rank')
if data[1].name and data[2].name and data[3].name:
await ctx.respond(f"Top 1: {data[1].name} ({data[1].level})\nTop 2: {data[2].name} ({data[2].level})\nTop 3: {data[3].name} ({data[3].level})")
else:
await ctx.respond("Not enough members to display leaderboard!")
Traceback if any
N/A
Required Checklist
Version Info
What's the exact version of discordLevelingSystem/pycord are you using?
I'm not sure is it a pycord or discordlevelingsystem issue, so you can close it if it's invalid
one more thing: total_xp is not being accepted by sort_by
python version 3.8.10
pycord 2.0
Traceback (most recent call last):
File "/mnt/sharessd/code/python/utachi-refractor/ablelevel.py", line 3, in
from discordLevelingSystem import DiscordLevelingSystem
File "/home/pooh/.local/share/virtualenvs/utachi-refractor-hCTN_qea/lib/python3.8/site-packages/discordLevelingSystem/init.py", line 12, in
from .announcement import LevelUpAnnouncement
File "/home/pooh/.local/share/virtualenvs/utachi-refractor-hCTN_qea/lib/python3.8/site-packages/discordLevelingSystem/announcement.py", line 70, in
class LevelUpAnnouncement:
File "/home/pooh/.local/share/virtualenvs/utachi-refractor-hCTN_qea/lib/python3.8/site-packages/discordLevelingSystem/announcement.py", line 141, in LevelUpAnnouncement
def init(self, message: Union[str, Embed]=default_message, level_up_channel_ids: Optional[Sequence[int]]=None, allowed_mentions: AllowedMentions=default_mentions, tts: bool=False, delete_after: Optional[float]=None):
TypeError: 'ABCMeta' object is not subscriptable
Hi @Defxult !
I just found a new bug while I was testing my code.
ISSUE:
DiscordLevelingSystem.create_database_file(file_path: str)
method only registers the member id
as the primary key in leaderboard table
, while the guild id doesn't get registered.DiscordLevelingSystem
(leveling_system.py), I couldn't find any code which registers the guild in the leaderboard table. This means the bot would only update the leaderboard table when the member/author
sends a message, regardless of being in the same guild or a different one.1
in a server and my next level in another server was level 2
(while testing the code).member's
level and XP shouldn't remain the same in all the servers.Probably not a bug:
await DiscordLevelingSystem.get_data_for(member: Member)
method.MemberData
in the readme.md file.Requesting you to please resolve this issue as soon as possible.
Thank you
Describe the bug
I'm trying to create a rank command in commands.Cog but when I try to start the discord bot it says me about "the event loop is already running" how can I fix it
To Reproduce
Minimal code to reproduce the bug/error
import discord, random
from discord.ext import commands
from discord import app_commands, File
from easy_pil import Editor, load_image_async, Font
from discordLevelingSystem import DiscordLevelingSystem, LevelUpAnnouncement
announcement = LevelUpAnnouncement(f"¡GG {LevelUpAnnouncement.Member.mention}, you just advanced to level {LevelUpAnnouncement.LEVEL} <a:gigachad:1043899515754782740>!")
lvl = DiscordLevelingSystem(rate=6,per=20.0,level_up_announcement=announcement)
lvl.connect_to_database_file(r'C:\Users\Personal\Desktop\Mimi-Bot\DiscordLevelingSystem.db')
class ranks(commands.Cog):
def init(self, client):
self.client = client
@commands.Cog.listener()
async def on_ready(self):
print("Loaded ranks")
@commands.Cog.listener()
async def on_message(self, message):
await lvl.award_xp(amount=25, message=message)
@app_commands.command(name="rank", description="¡Get your actual rank!")
@app_commands.checks.cooldown(1, 5.0, key=lambda i: (i.guild_id, i.user.id))
async def rank(self, interaction: discord.Interaction, member: discord.Member=None):
if member == None:
member = interaction.user
data = await lvl.get_data_for(member)
xp_total_lvl_up = DiscordLevelingSystem.get_xp_for_level(data.level+1)
xp_actual = await lvl.get_xp_for(member)
data = await lvl.get_data_for(member)
xp_total_lvl_up = DiscordLevelingSystem.get_xp_for_level(data.level+1)
xp_actual = await lvl.get_xp_for(member)
percentage = int(((xp_actual * 100)/ xp_total_lvl_up))
if percentage < 1:
percentage = 0
## Rank card
background = Editor(f"{0}.png")
profile = await load_image_async(str(member.avatar.url))
profile = Editor(profile).resize((150, 150)).circle_image()
poppins = Font.poppins(size=40)
poppins_small = Font.poppins(size=30)
background.paste(profile.image, (30, 30))
background.rectangle((30, 220), width=650, height=40, fill="#fff", radius=20)
background.bar(
(30, 220),
max_width=650,
height=40,
percentage=percentage,
fill="#ff9933",
radius=20,
)
background.text((200, 40), str(member.name), font=poppins, color="#ff9933")
background.rectangle((200, 100), width=350, height=2, fill="#ff9933")
background.text(
(200, 130),
f"Level : {data.level} "
+ f" XP : {xp_actual} / {xp_total_lvl_up} " + f"Rank: {data.rank}",
font=poppins_small,
color="#ff9933",
)
card = File(fp=background.image_bytes, filename="zCARD.png")
await interaction.response.send_message(file=card)
@rank.error
async def on_rank_error(self, interaction: discord.Interaction, error: app_commands.AppCommandError):
messages = ["¡Bro, calm down!", "¡Bro, slow!", "¡Just be patient!", "¡You have to wait!"]
if isinstance(error, app_commands.CommandOnCooldown):
await interaction.response.send_message(content=random.choice(messages), ephemeral=True)
elif isinstance(error, app_commands.AppCommandError):
await interaction.response.send_message(f"Error: {error}", ephemeral=True)
async def setup(client):
await client.add_cog(ranks(client))
Traceback if any
2022-11-27 19:07:55 ERROR discord.client Ignoring exception in on_ready
Traceback (most recent call last):
File "C:\Users\Personal\AppData\Local\Programs\Python\Python310\lib\site-packages\discordLevelingSystem\leveling_system.py", line 359, in connect_to_database_file
self._connection = self._loop.run_until_complete(aiosqlite.connect(path))
File "C:\Users\Personal\AppData\Local\Programs\Python\Python310\lib\asyncio\base_events.py", line 622, in run_until_complete
self._check_running()
File "C:\Users\Personal\AppData\Local\Programs\Python\Python310\lib\asyncio\base_events.py", line 582, in _check_running
raise RuntimeError('This event loop is already running')
RuntimeError: This event loop is already running
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\Personal\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\bot.py", line 934, in _load_from_module_spec
spec.loader.exec_module(lib) # type: ignore
File "", line 883, in exec_module
File "", line 241, in _call_with_frames_removed
File "c:\Users\Personal\Desktop\Mimi-Bot\cogs\rank.py", line 9, in
lvl.connect_to_database_file(r'C:\Users\Personal\Desktop\Mimi-Bot\DiscordLevelingSystem.db')
File "C:\Users\Personal\AppData\Local\Programs\Python\Python310\lib\site-packages\discordLevelingSystem\leveling_system.py", line 363, in connect_to_database_file
raise ConnectionFailure
discordLevelingSystem.errors.ConnectionFailure: Cannot connect to database file because the event loop is already running
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\Personal\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\client.py", line 409, in _run_event
await coro(*args, **kwargs)
File "c:\Users\Personal\Desktop\Mimi-Bot\main.py", line 15, in on_ready
await client.load_extension(f"cogs.{file[:-3]}")
File "C:\Users\Personal\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\bot.py", line 1012, in load_extension
await self._load_from_module_spec(spec, name)
File "C:\Users\Personal\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\bot.py", line 937, in _load_from_module_spec
raise errors.ExtensionFailed(key, e) from e
discord.ext.commands.errors.ExtensionFailed: Extension 'cogs.rank' raised an error: ConnectionFailure: Cannot connect to database file because the event loop is already running
Required Checklist
Version Info
What's the exact version of discordLevelingSystem/discord.py are you using?
Hello,
con you fix that as fast as possible please.
This is my top command:
@commands.command(name="top", description="Guarda la classifica del tuo server.")
async def top(inter: commands.Context, self):
data = await self.lvl.each_member_data(inter.guild, sort_by='rank')
top_10 = data[:10]
leaderboard_message = "Top 10 Leaderboard:\n"
for member_data in top_10:
member = inter.guild.get_member(member_data['user_id'])
leaderboard_message += f"{member.display_name}: Rank {member_data['rank']}\n"
await inter.send(leaderboard_message)
This is the traceback
Traceback (most recent call last):
File "/home/container/.local/lib/python3.11/site-packages/discord/ext/commands/core.py", line 235, in wrapped
ret = await coro(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/container/cogs/leveling.py", line 47, in top
data = await self.lvl.each_member_data(inter.guild, sort_by='rank')
^^^^^^^^
AttributeError: 'Context' object has no attribute 'lvl'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/container/.local/lib/python3.11/site-packages/discord/ext/commands/bot.py", line 1350, in invoke
await ctx.command.invoke(ctx)
File "/home/container/.local/lib/python3.11/site-packages/discord/ext/commands/core.py", line 1029, in invoke
await injected(*ctx.args, **ctx.kwargs) # type: ignore
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/container/.local/lib/python3.11/site-packages/discord/ext/commands/core.py", line 244, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'Context' object has no attribute 'lvl'
Required Checklist
Hey @Defxult !
I would like to suggest a method by which we can send embeds for LevelUpAnnounecment
message.
And can you please provide the link for your Discord Server if you have so that we can get help from others using this Library too :)
Thank you.
(Discord : INFINIX#7276)
Describe the bug
For some reason, award_xp isn't putting the user into the database or giving experience even if I use add_record to put them in.
To Reproduce
Minimal code to reproduce the bug/error
I have written the bare minimum to get a bot running with this code, as this is how I have my bot written.
import discord
import asyncio
from discordLevelingSystem import DiscordLevelingSystem
from discordLevelingSystem.errors import DatabaseFileNotFound, LeaderboardNotFound, ImproperLeaderboard, NotConnected,\
ConnectionFailure, DiscordLevelingSystemError
from discord.ext import commands
from discord.ext.commands import AutoShardedBot
from pathlib import Path
from config import donator_role, prefixes, token
intents = discord.Intents.default()
intents.message_content = True
intents.members = True
intents.presences = True
if not Path(r'database/DiscordLevelingSystem.db').is_file():
try:
DiscordLevelingSystem.create_database_file(r'./database/')
except (ConnectionFailure, DatabaseFileNotFound) as error:
raise error
class DiscordBot(AutoShardedBot):
def __init__(self):
super().__init__(
command_prefix=commands.when_mentioned_or(*prefixes),
intents=intents
)
lvl = DiscordLevelingSystem(rate=1, per=60.0, awards=None, announce_level_up=True, stack_awards=True)
async def on_message(self, message: discord.Message) -> None:
if message.author == self.user or message.author.bot:
return
await self.process_commands(message)
try:
await self.lvl.add_record(
guild_id=message.guild.id,
member_id=message.author.id,
member_name=message.author.name,
level=0
)
except DiscordLevelingSystemError:
raise DiscordLevelingSystemError
try:
await self.lvl.award_xp(
amount=[15, 25],
message=message,
refresh_name=True,
bonus=DiscordLevelingSystem(
donator_role,
20,
multiply=False
)
)
except (DatabaseFileNotFound, LeaderboardNotFound, ImproperLeaderboard, NotConnected) as e:
raise e
if __name__ == "__main__":
try:
DiscordBot.lvl.connect_to_database_file(r'database/DiscordLevelingSystem.db')
except (ConnectionFailure, DatabaseFileNotFound) as error:
raise error
asyncio.run(DiscordBot().start(token=token))
Traceback if any
N/A
Required Checklist
Version Info
What's the exact version of discordLevelingSystem/discord.py are you using?
Hi @Defxult!
First of all, I would appreciate your contribution to this library.
I did check out version 0.0.2 of the library. It is very nice. Thanks a lot for adding those features.
But, I am facing some issues with it.
ISSUE
level_up_channel_id
(an optional parameter for the LevelUpAnnouncement class), if not in an async loop.cur = conn.cursor()
predicate = cur.execute('SELECT * FROM config WHERE guild_id=?', (object.guild.id,))
predicate = predicate.fetchone()
if predicate[1]:
level_up_channel = predicate[7] #predicate[7] here, is the level_up_channel_id stored in the db
announcement = LevelUpAnnouncement(message = discord.Embed(title=f"<a:pepeclap:850247977943040001> CONGRATULATIONS!", description=f"{LevelUpAnnouncement.Member.mention} JUST LEVELED UP TO **LEVEL {LevelUpAnnouncement.LEVEL}**!", color = discord.Color.gold()) .set_thumbnail(url = LevelUpAnnouncement.Member.avatar_url) .set_footer(icon_url = LevelUpAnnouncement.Member.Guild.icon_url, text="MADE BY INFINIX#7276"), level_up_channel_id = level_up_channel)
DiscordLevelingSystem.connect_to_database_file
in an async func like on_message_event
, we can easily fetch the guild's id by message.guild.id
.Thanks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.