Display all emotes in server but with spaces - python-3.x

Seems quite easy but I just can't figure it out. I basically have a script that makes the bot list all the emotes of the server, but the problem is it doesn't make spaces which means it won't preview the emotes and it will all be just text and boring as i have alot of emotes, lets use actual emojis as an example ":laughing:" shows 😂. ":laughing::laughing:" should show 😂😂 but just shows ':laughing::laughing:' as it is instead. This is because there isn't space, how can i fix that in my script? In this image you can see what i mean Now And then this
#client.command(pass_context=True)
async def emotes(ctx, msg: str = None):
"""List all emotes in this server."""
if msg:
server, found = client.find_server(msg)
if not found:
return await client.send(server)
else:
server = ctx.message.server
emojis = [str(x) for x in server.emojis]
await client.say("".join(emojis))

I suppose the problem is in absence of a space in the separator string "", which you're using for joining emojis.
Replace this
await client.say("".join(emojis))
By this
await client.say(" ".join(emojis))

#client.command(pass_context=True)
async def emotes(ctx, msg: str = None):
"""List all emotes in this server."""
if msg:
server, found = client.find_server(msg)
if not found:
return await client.send(server)
else:
server = ctx.message.server
emojis = [str(x) for x in server.emojis]
await client.say(" ".join(emojis))

different account, turns out it wasn't the spaces as it still didn't work with them, it's because I was using Async, rewrite works well and shows the emotes without having to put spaces

Related

Send Images with Hikari Python

I made a function to send an image on invocation but instead it ends
up sending 'attachment://img.jpg'
here's the function :
#bot.command
#lightbulb.command('img', 'Test command')
#lightbulb.implements(lightbulb.SlashCommand)
async def imgsnd(ctx):
filename = 'img.jpg'
with open(filename, "rb") as fh:
f = hikari.File('/Users/admin/Desktop/Bot/'+filename)
await ctx.respond(f)
Sending attachments as a slash command initial response wasnt supported until 2.0.0.dev106. Consider upgrading and the issue will be solved.
Additionally, even tho this wasn't part of the question, just a pointer. That open is not necessary and, on top of that, blocking. Instead, you can reduce your code to this:
#bot.command
#lightbulb.command('img', 'Test command')
#lightbulb.implements(lightbulb.SlashCommand)
async def imgsnd(ctx):
f = hikari.File('/Users/admin/Desktop/Bot/img.jpg')
await ctx.respond(f)

Why doesn't isalpha() work for sanitizing user input?

The trouble I'm having here is that the isalpha() function isn't doing what it's supposed to do, users are able to send messages that contain characters that are not alphabetical. I'm not sure why this occurs. I assumed that it was some kind of hosting issue (which from the looks of it wasn't) prior to assuming that there was a logical error in my code, but logically it makes sense to me which perhaps is wrong? I kinda also made the assumption that it had to do with the function not being asynchronous, I don't know I probably am reaching with that one.
import discord
from discord.ext import commands
import re
class Shiritori(commands.Cog):
""" Start a new word from the last letter of the one before. """
def __init__(self, client):
self.client = client
self.repeats = re.compile(r'(.)\1{2,}') # Matches spam like 'eeeeeee'
self.shiritori_channel = 578788555120312330 # Official
#commands.Cog.listener()
async def on_message(self, message):
try:
if message.channel.id == self.shiritori_channel:
previous_message = (await message.channel.history(limit=2).flatten())[1].content
repeats_mo = self.repeats.search(message.content)
if not repeats_mo and message.content.isalpha():
if previous_message[-1].lower() != message.content[0].lower():
await message.author.send(
f'Your message must start with the last letter of the latest message!')
await message.delete()
else:
await message.author.send("You can't do that here!")
await message.delete()
except discord.Forbidden:
await message.delete()
I guess you are expecting that any non-ascii English character is not alpha.
But
According to the doc,
str.isalpha() Return True if all characters in the string are
alphabetic and there is at least one character, False otherwise.
Alphabetic characters are those characters defined in the Unicode
character database as “Letter”, i.e., those with general category
property being one of “Lm”, “Lt”, “Lu”, “Ll”, or “Lo”. Note that this
is different from the “Alphabetic” property defined in the Unicode
Standard.
So for example à (french a) or любовь are also considered alpha
'à'.isalpha()
True
'любовь'.isalpha()
True
If you want the english letters, use isascii():
'à'.isascii()
False

Can not get client.command parameter to parse API response by key value in discord.py

I'm building a command onto an existing bot that will search an API and take a baseball player's name as a parameter to query a json response with. I've gotten everything to work correctly in test, only for the life of me I can't figure out how to restrict the results to only those that include the query parameter that is passed when the command is invoked within discord.
For example: a user will type !card Adam Dunn and only the value "Adam Dunn" for the key "name" will return. Currently, the entire first page of results is being sent no matter what is typed for the parameter, and with my embed logic running, each result gets a separate embed, which isn't ideal.
I've only included the pertinent lines of code and not included the massive embed of the results for readability's sake.
It's got to be something glaringly simple, but I think I've just been staring at it for too long to see it. Any help would be greatly appreciated, thank you!
Below is a console output when the command is run:
Here is the code I'm currently working with:
async def card(ctx, *, player_name: str):
async with ctx.channel.typing():
async with aiohttp.ClientSession() as cs:
async with cs.get("https://website.items.json") as r:
data = await r.json()
listings = data["items"]
for k in listings:
if player_name == k["name"]
print()```
I hope I understood you right. If the user did not give a player_name Then you will just keep searching for nothing, and you want to end if there is no player_name given. if that is the case then.
Set the default value of player_name: str=None to be None then check at the beginning of your code if it is there.
async def card(ctx, *, player_name: str=None):
if not player_name:
return await ctx.send('You must enter a player name')
# if there is a name do this
async with ctx.channel.typing():
async with aiohttp.ClientSession() as cs:
async with cs.get("https://theshownation.com/mlb20/apis/items.json") as r:
data = await r.json()
listings = data["items"]
for k in listings:
if player_name == k["name"]
print()```
Update:
I'm an idiot. Works as expected, but because the player_name I was searching for wasn't on the first page of results, it wasn't showing. When using a player_name that is on the first page of the API results, it works just fine.
This is a pagination issue, not a key value issue.

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:

Discord Python: How to mention a user along with sending a GIF

I've been looking for a way to code my Discord bot to mention a user that was tagged by a certain command as well as sending an image/gif to go with the message. So far, I am able to generate random images from one command and mention a user with a different command. I just need to figure out how to implement both for one command.
Here is the code that I used to generate random images from one command:
client = Bot(command_prefix=BOT_PREFIX)
#client.event
async def on_message(message):
if message.content.upper().startswith("?DOG"):
jessie1 = "https://cdn.discordapp.com/attachments/432563417887277060/484484259386621993/22B25E7A-3157-4C23-B889-47ECFE8A15A9.jpg"
snowy = "https://cdn.discordapp.com/attachments/487045791697862666/487390822485065749/824B6151-E818-49A4-A564-C2C752ED6384.jpg"
await client.send_message(message.channel, random.choice([snowy, jessie1]))
Here is the code that I used to mention another user:
elif message.content.upper().startswith('?GIVE BANANA'):
user = message.mentions[0]
responses = ["{} gave a banana to {} :banana:"]
choice = random.choice(responses)
choice = choice.format(message.author.mention, user.mention)
await client.send_message(message.channel, choice)
Within the second code, I can't figure out how to add an image with it. Preferably, I would like to generate random images with it, which is why I provided two code examples.
You format the message with the mention and then the link to the message.
elif message.content.upper().startswith('?SEND GIF'):
user = message.mentions[0]
jessie1 = "https://cdn.discordapp.com/attachments/432563417887277060/484484259386621993/22B25E7A-3157-4C23-B889-47ECFE8A15A9.jpg"
snowy = "https://cdn.discordapp.com/attachments/487045791697862666/487390822485065749/824B6151-E818-49A4-A564-C2C752ED6384.
gif_message = "{} here is the gif {}".format(user.mention, random.choice([snowy, jessie1]))
await client.send_message(message.channel, gif_message)

Resources