Case-insensitive dictionary check with lower() - python

I'm trying to use lower() so the role names are not case sensitive. So if a user types lol instead of LoL it won't go through the if statement if not role_id:
This is how I'm doing it:
#commands.command()
#commands.check(lambda ctx: ctx.channel.id in [555844758778544160])
async def add(self, ctx, *, rolename):
author = ctx.message.author
role_dict = {
"Members":557212810468392970,
"PS4":568761643916328960,
"LoL":559792606364565505}
role_id = role_dict.get(rolename.lower())
if not role_id:
await ctx.send("I cannot find the role {}.".format(rolename))
return
role = discord.utils.get(ctx.message.guild.roles, id = role_id)
message = '{} added the role **{}**'.format(author.display_name, role.name)
embed = discord.Embed(description=message.format(author.display_name, role.name), colour=0xff0000)
await author.add_roles(role)
await ctx.send("Role Added")
This line here role_id = role_dict.get(rolename.lower()) is the culprit when I add the role !add lol rather than LoL this is what I'm getting:
Help much appreciated.

The problem is that you're comparing a lowercase rolename with dictionary keys that are not in lowercase. For a case-insensitive check, both the rolename and dictionary keys should be lowercase.
Either manually change the dictionary keys to lowercase:
role_dict = {
"members":557212810468392970,
"ps4":568761643916328960,
"lol":559792606364565505}
Or create it programmatically with a dict comprehension, and check if rolename.lower() is in the lowercase dict:
role_dict = {
"Members":557212810468392970,
"PS4":568761643916328960,
"LoL":559792606364565505}
lowercase_dict = {k.lower():v for k,v in role_dict.items()}
role_id = lowercase_dict.get(rolename.lower())
if not role_id:
await ctx.send("I cannot find the role {}.".format(rolename))
return

Related

Discord py How to add role by name not id

How to add role by name not id. group is string
await message.author.add_roles(message.author, group)
You can use discord.utils.get function for this:
role_name = "role" # specify role name here
role = discord.utils.get(message.guild.roles, name=role_name)
if role is not None:
await message.author.add_roles(role)

How to set a collection name in MongoDB

I encountered such a problem, I do not know how to set the name of this collection through the code when creating a collection, that is, I write:
cluster = MongoClient("link")
db = cluster.BananiData
collection = db.ctx.guild.id
but the name is set as ctx.guild.id, I need to insert the server ID in the name, how can this be implemented?
P.S: I use python
code:
cluster = MongoClient("mongodb+srv://Bananchik:hdkkIFkk6VKywSDH#cluster0.olcto.mongodb.net/<BananiData>?retryWrites=true&w=majority")
db = cluster.BananiData
collection = db.ctx.guild.id
#collection = cluster.BananiData.LevelSystem
class DataBases(commands.Cog):
""" ФСБ? """
def __init__(self, bot):
self.bot = bot
#commands.command()
#commands.check(permissions.is_owner)
async def test_db(self, ctx):
await ctx.send(collection)
await ctx.send("DB id created")
for member in ctx.guild.members:
print(member)
post = {
"_id": member.id,
"xp": 0,
"lvl": 1,
"message_count": 0
}
if collection.count_documents({"_id": member.id}) == 0:
collection.insert_one(post)
print(f"Пользователь **{member.name}** добавлен в базу данных")
It is a good practice to enclose the name you want to assign to a collection inside a
square bracket if you are using python.
Example:
If you want to create a collection by the name "SampleCollection", you could use the below command, even though
. operator works.
collection = db["SampleCollection"]
Therefore,
You should change the collection initialization code like the following:
collection = db[ctx.guild.id]
Note: Make sure that ctx.guild.id variable is of type str else it won't work.

How do I get a list of all the roles my discord bot has?

I am trying to get a list of all the roles my bot has from top to bottom so I can get the highest role's color.
Not sure what you mean by the "highest role's color", also your post is missing your code.
One way to get the roles the bot has in the guild (via a command) is to get the guild member object and then loop the role objects for that member.
Try this:
#bot.command()
async def list_roles(ctx):
bot_member = ctx.guild.get_member(bot.user.id)
for bot_role in bot_member.roles:
print(f'guild role {bot_role} color {bot_role.color}')
Console output:
guild role #everyone color #000000
guild role masterbot color #2ecc71
guild role winnerPicker color #e67e22
guild role gabAdmin color #ad1457
you can do a loop in all roles like this using Guild.roles
#bot.command()
async def get_roles(ctx):
all_roles = []
for role in ctx.guild.roles:
all_roles.append(role.name)
all_roles.reverse()# to make it higher first
print(all_roles)
you can do with .me in a guild
getting the list:
Guild = THE GUILD YOU WANT TO GET THE ROLES
BotMember = GUILD.members.me
for role in BotMember.roles:
print(f'Role: {role.name} Color: {role.color}')
console log:
Role: #everyone Color: #000000
Role: BaldeGuy Color: #2ecc71
Role: Lorrita Color: #e67e22
Role: Moderator Color: #ad1457
getting the highest role:
Guild = THE GUILD YOU WANT TO GET THE ROLES
BotMember = GUILD.members.me
HighestRole = BotMember.roles.highest.name
print(f'Highest role: {HighestRole}')
console.log:
Highest role: {Moderator}

Getting the keys, and not the values

So I want to get the json keys and compare them with the variable q
Json file
{
"api_key": "YOUR AUTOBUY API KEY",
"prefix": "PREFIX FOR BOT COMMANDS (for e.x !redeem, ?claim, etc",
"redeem_message": "Thanks for redeeming your order for {0}, I have added the ROLE_NAME_HERE role.",
"role_id": "REPLACE THIS WITH THE ID OF THE ROLE YOU WANT TO GIVE UPON REDEEMING",
"redeem_channel_id": "REPLACE THIS WITH THE CHANNEL ID WHERE PEOPLE CAN USE THE REDEEM COMMAND",
"bot_token": "PUT YOUR DISCORD BOT TOKEN HERE"
}
Code
import json
def search(q):
with open("config.json") as f:
data = json.load(f)
for obj in data:
print(data[obj])
search(q="role_id")
Expected output: REPLACE THIS WITH THE ID OF THE ROLE YOU WANT TO GIVE UPON REDEEMING (cause q = role_id and I want it to return the value of the key)
Actual output:
YOUR AUTOBUY API KEY
PREFIX FOR BOT COMMANDS (for e.x !redeem, ?claim, etc
Thanks for redeeming your order for {0}, I have added the ROLE_NAME_HERE role.
REPLACE THIS WITH THE ID OF THE ROLE YOU WANT TO GIVE UPON REDEEMING
REPLACE THIS WITH THE CHANNEL ID WHERE PEOPLE CAN USE THE REDEEM COMMAND
PUT YOUR DISCORD BOT TOKEN HERE
Super simple, no need for a for loop if you just need one value:
import json
def search(q):
with open("config.json") as f:
data = json.load(f)
print(data[q])
search(q="role_id")
below
data = {'A':12,'B':13}
q = 'A2'
value = data.get(q)
if value is not None:
print(value)
else:
print('{} not found'.format(q))

Format of Discord.Role

I'm making a Discord bot, but on the part where the bot determines the Permission of the Author, it does not recognise roles, valuables like "owner" and "admin" are the ID of the role, What is the format for discord.Role?
I've tried making classes with an id and name
perms = 0
if moderator in message.author.roles:
perms = 1
if admin in message.author.roles:
perms = 2
if owner in message.author.roles:
perms = 3
if muted in message.author.roles:
perms = -1
Right now it outputs perms as 0 even though it should be 3 as my role is "owner".
According to the discord.py documentation member.roles (or message.author.roles in your case) returns a list of Role class instances, not role IDs (documentation entry).
You can read about the Role class in the documentation as well.
If you want to check if a member has a role with the specified ID, you can get a list of his role IDs first:
perms = 0
ids = [role.id for role in message.author.roles]
if moderator in ids:
perms = 1
if admin in ids:
perms = 2
if owner in ids:
perms = 3
if muted in ids:
perms = -1

Categories

Resources