Removing field value from embed issue - python-3.x

Hi I'm wanting to add a check to a embed field.
Currently when it's None it will just leave a name="Steam" value and a empty value="[{result2[0]}](http://steamcommunity.com/profiles/{result2[0]}).
I'm wanting to make a check to see if result2 is in the database - I put an if statement if result2: before the embed field - if it does not return None it will show the embed field.` If result returns a None Type then don't show the embed field.
Not sure if this is possible.
Here is an example and a mockup edited in paint
The one marked 1 is what results I'm getting if check returns None
The one marked 2 is what result I get if the check returns a not
None
The one marked 3 is mocked up in paint version of what result
I'd like to have if None is returned.
Here is the code I'm working with:
#commands.group(invoke_without_command=True)
async def profile(self, ctx, user: discord.Member=None):
user = user or ctx.author
db = sqlite3.connect('profiles.sqlite')
cursor = db.cursor()
cursor.execute(f"SELECT profile FROM profile WHERE username={user.id}")
result = cursor.fetchone()
cursor.execute(f"SELECT steam FROM profile WHERE username={user.id}")
result2 = cursor.fetchone()
if result is None:
await ctx.send(f"{user.display_name}'s bio has not been created yet.")
return
else:
desc = f"**Bio:**\n{(result[0])}"
embed = discord.Embed(title=f"{user.display_name}'s Profile", description=desc, color=user.colour)
if result2: #here I add the check before adding the embed field
embed.add_field(name="Steam", value=f"[{result2[0]}](http://steamcommunity.com/profiles/{result2[0]})")
await ctx.send(embed=embed)
Help would be appreciated.

It looks like result2 is a list containing None, or something similar. Let's directly check result2[0] as well as result2
if result2 and result2[0]:
embed.add_field(name="Steam", value=f"[{result2[0]}](http://steamcommunity.com/profiles/{result2[0]})")

Related

How can i customize Output of My Database for my discord bot?

This is My inventory command sorry, I cant send the image cuz I don't have 10 reputations to do that,
here is my code first see the image it will help you guys get a better understanding of what I am asking pardon if it sounds rude
#app_commands.command(name="inventory", description="check you inventory")
#app_commands.guild_only()
async def inventory(self, interaction: discord.Interaction) -> None:
await interaction.response.defer(ephemeral=False, thinking=True)
author = interaction.user.id
lol = await self.bot.db.fetch("SELECT item_info.item_name,user_inventory.count FROM user_inventory INNER JOIN item_info USING(item_id) WHERE user_inventory.user_id = $1",author)
await interaction.followup.send(embed=discord.Embed(title=f"{interaction.user.name}'s Inventory ", description=f"{lol}"))
SO I am making a bot like dank Memer For my discord Server, I am pretty sure you guys have seen the dank memer Inventory command, How beautiful their embed is and the use of emoting But as I have shown you guys an image, my inventory command is kinda messy and ugly and I am getting record but I want to value and count, how can I get them and how can I make embed like dank memer like the amount of space btw 1 item, emotes and everything I am new here so pardon if I asked something that I should not
https://magicstack.github.io/asyncpg/current/api/index.html?highlight=fetch#asyncpg.cursor.Cursor.fetch
fetch returns a list of Record instances.
You can iterate over the list to get a single Record instance.
lol = await self.bot.db.fetch("SELECT item_info.item_name,user_inventory.count FROM user_inventory INNER JOIN item_info USING(item_id) WHERE user_inventory.user_id = $1",author)
for element in lol:
...
From your image:
To the item_name you'd have to do:
element.get("item_name", "no name")
see: https://magicstack.github.io/asyncpg/current/api/index.html?highlight=record#asyncpg.Record
If it does not find item_name it will return the string "no name"
You created an Embed here:
embed=discord.Embed(title=f"{interaction.user.name}'s Inventory ", description=f"{lol}")
However that only has a title and description. If you want to put the item_name and count information into embed you do something like:
embed.add_field(name=element.get("item_name", "no name"), value=element.get("count", "NaN"))
see: https://discordpy.readthedocs.io/en/stable/api.html?highlight=embed#discord.Embed.add_field
so it looks something like:
async def inventory(self, interaction: discord.Interaction) -> None:
await interaction.response.defer(ephemeral=False, thinking=True)
author = interaction.user.id
lol = await self.bot.db.fetch("SELECT item_info.item_name,user_inventory.count FROM user_inventory INNER JOIN item_info USING(item_id) WHERE user_inventory.user_id = $1",author)
embed=discord.Embed(title=f"{interaction.user.name}'s Inventory ", description="")
for element in lol:
embed.add_field(name=element.get("item_name", "no name"), value=element.get("count", "NaN"))
await interaction.followup.send(embed=embed)
PS: Code looks really ugly but I'm just basing mine off yours. It is not recommended but I understand you are learning.

How can I use something stored in a DataBase? SQLite / Python

So, I am new at DataBases and I have a question. I first made a re-search in the internet but could not find anything or actually I could not understand correctly what they were explaining. Before starting with my question I want to say that I am currently working in a Discord Bot in Python as Main Language and I am trying to create a per-server-prefix system. I have already made it once but in .JSON format. Then I heard that using .JSON to save this kind of Data is not actually good so I moved to DataBases. Now, my question is:
I have stored the guild_id and prefix in my DB, how could I use that for a per-server-prefix system? I have not tried anything yet except writing the Code to store both Texts. I would really love if anyone could explain to me not just tell me the Code! Any answer will be appreciated <3.
Main.py:
def get_prefix(client, message):
db = sqlite3.connect("main.sqlite")
cursor = db.cursor()
cursor.execute(f"SELECT prefix FROM prefixes WHERE guild_id = {message.guild.id}")
result = cursor.fetchone()
if result is None:
return "/"
else:
client = commands.Bot(command_prefix = get_prefix)
Prefixes.py (COGS):
#commands.command()
#commands.has_permissions(administrator=True)
async def prefix(self, ctx, prefix=None):
db = sqlite3.connect("main.sqlite")
cursor = db.cursor()
cursor.execute(f"SELECT prefix FROM prefixes WHERE guild_id = ?", ctx.guild.id)
result = cursor.fetchone()
if result is None:
sql = ("INSERT INTO prefixes(guild_id, prefix) VALUES(?,?)")
val = (ctx.guild.id, prefix)
await ctx.channel.send(f"{prefix}")
elif result is not None:
sql = ("UPDATE prefixes SET prefix = ? WHERE guild_id = ?")
val = (prefix, ctx.guild.id)
await ctx.channel.send(f"update `{prefix}`")
cursor.execute(sql, val)
db.commit()
cursor.close()
db.close()
That is pretty much the whole code. If you think anything should be changed or have any suggestions, answer in the comments!
All you need to do is, after the else, put return result. For example:
result = cursor.fetchone()
if result is None:
return "/"
else:
return result
cursor.fetchone() returns a tuple with each element requested in the row, as you only requested the prefix, it will contain just that (e.g: ("!",)) which is permitted as your command_prefix callable can return a string or tuple of strings.
Warning:
You may want to add a check to ensure that someone doesn't specify an empty string (A zero length string with nothing in it) as their prefix, otherwise your bot will attempt to run every message it sees as a command
References: discord.ext.commands.Bot.command_prefix

Python Compare lists

So I have this script,
good_users=[]
async def callposts(ctx):
g0=str(ctx.guild)
g=g0.replace(' ','_')
sqluse(g)
x="SELECT authorid, COUNT(*) FROM posts GROUP BY authorid"
mycursor.execute(x)
k=mycursor.fetchall()
for user in k:
if user[1] > 7:
good_users.append(user)
k.remove(user)
print(user)
return k
async def kick(ctx, uid):
await ctx.guild.kick(ctx.guild.get_member(int(uid)))
#client.command(pass_context = True)
async def post_check(ctx):
ausers=list(ctx.guild.members)
lowposters= await callposts(ctx)
for user in ausers:
if user == client.user:
print(user.name+" is a bot!")
ausers.remove(user)
elif user.id in exempt:
print(user.name+" is exempt!")
ausers.remove(user)
elif user.id in good_users:
print(user.name+" is a good user!")
ausers.remove(user)
else:
await kick(ctx,user.id)
print(ausers)
What I am trying to do here is remove inactive users. So I have 2 lists that I want to compare the memberlist to, exempt and good_users. I also am checking to make sure it isn't the bot. So this script removes the bot from the list but it doesn't remove the user that's in exempt or good users. So in turn it tries to kick everyone that's not a bot. They are trying to take over!
I'm looking this over but right now I'm sick so not 100%.
The prints are just for troubleshooting purposes however, all but the firt print in the callpost function print nothing and that one for some reason only prints the user, now it isn't printing the bot so the bot may not be in the list to get removed.
Any thoughts?
You're never appending anything to exempt_users and because of the scope of good_users it is only filled with users within callposts() because you're not returning it when calling it in post_check().
Changing the following should fix your problem:
Return good_users from callposts()
Add a new variable to where you call callposts() in post_check() like
lowposters, good_users = await callposts(ctx)
So I finally figured this out, the script was looking at user.id as an attribute of user object. To fix that I had to use
elif str(user.id) in exempt): and elif str(user.id) in good_users:

How to add check in embed definitions?

Hi there I'm trying to add checks to my embed definitions that return the users information from the sql database.
What I'd like to achieve is to check if the user has set a gametag and then if the data isn't there then don't show it on their profile.
However, I'm was able to pass a check to see if the user data is in the database if the result is None it will turn Steam None where as I rather not show it altogether.
Here is what I'm working with:
#commands.group(invoke_without_command=True)
async def profile(self, ctx, user: discord.Member=None):
user = user or ctx.author
db = sqlite3.connect('profiles.sqlite')
cursor = db.cursor()
cursor.execute(f"SELECT profile FROM profile WHERE username={user.id}")
result = cursor.fetchone()
cursor.execute(f"SELECT steam FROM profile WHERE username={user.id}")
result2 = cursor.fetchone()
if result is None:
await ctx.send(f"{user.display_name}'s bio has not been created yet.")
elif result4:
steam = f"**Steam** [{result2[0]}](http://steam.com/{result2[0]})" #return data from database.
else:
steam = "" # return nothing if nothing returned from database.
desc = f"{(result[0])} \n\n {steam}:" # define a embed description as f-string
embed = discord.Embed(title=f"{user.name}'s Profile", description=desc, color=user.colour)
await ctx.send(embed=embed)```
If I understand correctly, you do not want result2[0] to be None, whereas you are checking for result to be None. Make sure to check for both result2 and result2[0] to be not None and that should fix it.
Also, if that is supposed to stop the embed creation, you might want to return after the await ctx.send(...) (under "if result == None:").

How to get ID of a mentioned user (Discord.py)

#bot.command()
async def id(ctx, a:str): #a = #user
how would I get the ID of a user mentioned in the command, and output it as:
await ctx.send(id)
Use a converter to get the User object:
#bot.command(name="id")
async def id_(ctx, user: discord.User):
await ctx.send(user.id)
Or to get the id of the author:
#bot.command(name="id")
async def id_(ctx):
await ctx.send(ctx.author.id)
Just realized that when you #someone and store it to the variable "a", it contains the user ID in the form of '<#userid>'. So a bit of clean up can get me the user ID
Here's the code:
#bot.command()
async def id(ctx, a:str):
a = a.replace("<","")
a = a.replace(">","")
a = a.replace("#","")
await ctx.send(a)
Since my command consists of "rev id #someone", the #someone gets stored in 'a' as the string '<#userid>' instead of '#someone'.
If you want to handle a mention within your function, you can get the mention from the context instead of passing the mention as a string argument.
#bot.command()
async def id(ctx):
# Loop through the list of mentioned users and print the id of each.
print(*(user_mentioned.id for user_mentioned in ctx.message.mentions), sep='\n')
ctx.message.mentions will return:
A list of Member that were mentioned. If the message is in a private
message then the list will be of User instead.
When you loop through ctx.message.mentions, each item is a mentioned member with attributes such as id, name, discriminator. Here's another example of looping through the mentioned list to handle each member who was mentioned:
for user_mentioned in ctx.message.mentions:
# Now we can use the .id attribute.
print(f"{user_mentioned}'s ID is {user_mentioned.id}")
It's up to you whether you want to require the argument a as shown in the question above. If you do need this, note that the string will sometimes include an exclamation in the mention depending on whether it is:
for a User or command was posted from mobile app: <#1234567890>
for a Nickname or command was posted from desktop app: <#!1234567890>
Which is why I prefer to get the id from a member/user attribute.

Resources