How do I only get a picture from PRAW - python

I am trying to use PRAW for a discord.py command. However I do not want videos to play when I execute the command, so is there a way I can only get pictures when I get the post?
Here is what I have:
#commands.command()
async def aww(self, ctx):
subreddit = reddit.subreddit("aww")
allsubs = []
top = subreddit.top(limit = 50)
for submission in top:
allsubs.append(submission)
randomsub = random.choice(allsubs)
name = randomsub.title
url = randomsub.url
em = discord.Embed(
title = name,
color = discord.Color.blurple()
)
em.set_image(url = url)
await ctx.send(embed = em)
Any help will be appreciated, thanks!

Because the PRAW api only provides you a url (str) without any information on the URL, I'd suggest adding some conditionals to ensure that the url is a photo and not a video.
e.g.
randomsub = random.choice(allsubs)
extension = randomsub.url[len(randomsub.url) - 3 :].lower()
while "jpg" not in extension or "png" not in extension:
randomsub = random.choice(allsubs)
extension = randomsub.url[len(randomsub.url) - 3 :].lower()
And proceed from there. Obviously there are more graceful ways of solving this but the underlying point is the same.

Related

How to show the url of an image with python discord bot?

I am creating a small bot in Python, but I have a small problem and I want it to show me the image as a link and I don't know how to do it.
This is the code I am currently using:
with io.BytesIO() as image_binary:
img1.save(image_binary, 'PNG')
image_binary.seek(0)
embed=discord.Embed(title="Skin Minecraft", url="https://twitter.com/", description=f"", color=discord.Colour.random())
embed.set_image(url=f"attachment://Skin-{usuariominecraft}.png")
await ctx.send(embed=embed, file=discord.File(fp=image_binary, filename=f"Skin-{usuariominecraft}.png"))
What I want is for it to show me the link directly, like this:
https://cdn.discordapp.com/attachments/1050554950377295932/1051229055581700216/Skin-TCGBayQ.png
I can't get how to do it.
Is it possible to do this?
I leave you what I could do...
import import base64
import requests
Code:
nombre_local_imagen = f"Skin-Minecraft.png"
imagen = requests.get(f"{SkinMc}").content
with open(f"{nombre_local_imagen}", "wb") as handler:
handler.write(imagen)
embed=discord.Embed(title="Skin Minecraft", url="https://twitter.com/", description=f"", color=discord.Colour.random())
file = discord.File(f"Skin-Minecraft.png", filename=f"Skin-Minecraft.png")
embed.set_image(url=f"attachment://Skin-Minecraft.png")
embed.set_footer(text=f"TEXTO")
await ctx.send(file=file, embed=embed)
headers = {'Authorization': 'Client-ID XxXx',} #get client_ID => https://api.imgur.com/oauth2/addclient
params = {'image': base64.b64encode(open(f'Skin-Minecraft.png', 'rb').read())}
r = requests.post(f'https://api.imgur.com/3/image', headers=headers, data=params)
data = r.json()["data"]["link"]
await ctx.channel.send(f"```{data}```")
Hope this can help you

Telegram Bot receive video from user

i want my bot to receive videos thats been sent by users. Previously, i did this coding to receive images from users but i still cant use my bot to receive videos from them. Can any of you help me solve this problem?
coding:
file = update.message.photo[-1].file_id
At first place telegram can recieve two types of videos: simple videofile, that was sent by user as attachment and "video_note" - video that was created directly in the telegram.
Recieving both these types are pretty similar:
At first we need to obtain file_id:
def GetVideoNoteId(update):
if update['message'].get('video_note') != None:
return update['message']['video_note']['file_id']
else:
return 'not videonote'
second step - getting filepath of that file on telegram servers - from where we should download that file:
def GetVideoNoteFileSource(FileId):
url = 'https://api.telegram.org/bot' + TOKEN + '/' + 'getFile'
jsn = {'file_id': FileId}
r = requests.get(url,json=jsn).json()
fileSource = r['result']['file_path']
return fileSource
And third - finally - getting this file:
def GetFile(fileSource):
url = 'https://api.telegram.org/file/bot' + TOKEN + '/' + fileSource
r = requests.get(url)
filename = 'Video.mp4'
try:
with open(filename, 'wb') as file:
file.write(r.content)
return 'file dowloaded'
except:
return 'there are something wrong'
With videofile as attachments similar, but
return update['message']['video_note']['file_id'] - would be looks different (i do not remmember)

Any idea why images don't display sometimes ? (bot discord scraping python)

In resume, I'm trying to create a bot discord that could send a message each time there is a sell on an NFT marketplace. To do that, I'm scrapping the page of the collection I want and recup all the information on the NFT sold, such as the image, the price, the mint token, ...
There is no problem in the scraping part, I can recup all the information but sometimes, the image doesn't display in the embed message in discord and I don't understand why (I use the url image to display it with set_thumbnail(url = image)).
Here is the code for the display :
#To recup the image, need to go the arweave url
arweave_image = requests.get(meta.json()['data']['metadata']['data']['uri'])
image = arweave_image.json()["image"]
print(name)
print(image)
#Display an embed message on Discord
embed = discord.Embed(title = "**" + name + " vendu !**", color=0xfa8072)
embed.set_author(name="Magic Eden", icon_url="https://imagedelivery.net/E-VnZk4fwouzlzwX_qz4fg/532afb9b-8805-424d-8f85-da5c3e0f8600/public")
embed.set_thumbnail(url = image)
embed.add_field(name = "Price", value = str(price) + ' SOL', inline = False)
embed.add_field(name = "Mint token", value = mint_token, inline = False)
await channel.send(embed = embed)
Any idea ?
I check if sometimes there was a problem with the url, but each time the image didn't appear in discord, the url was retrieved in the variable and I could google it.
EDIT : exemple of an image that didn't display : https://arweave.net/_MLyaflmmE1ciSnLeIT4aCnz_XbA9o7oTFzEmPq3eyU?ext=png

lyricsgenius lyrics sometimes end with "EmbedShare URLCopyEmbedCopy"

I am making a Discord lyrics bot and to receive the lyrics. I am using genius API (lyricsgenius API wrapper). But when I receive the lyrics, it ends with this:
"away" is the last word in the song but it is accompanied with EmbedShare URLCopyEmbedCopy. Sometimes it is just the plain lyrics without the EmbedShare text.
With the same song:
Is there anyway to prevent that?
Source code for the lyrics command:
#commands.command(help="Gives the lyrics of the song XD! format //lyrics (author) (song name)")
async def lyrics(self, ctx, arg1, arg2):
song = genius.search_song(arg1, arg2)
print(song.lyrics)
name = ("Lyrics for " + arg2.capitalize() + " by " + arg1.capitalize())
gembed = discord.Embed(title=name.capitalize(), description=song.lyrics)
await ctx.send(embed=gembed)
This is a known bug with lyricsgenius and there's an open PR to address this issue: https://github.com/johnwmillr/LyricsGenius/pull/215.
This is because lyricsgenius web scrapes the lyrics from Genius' website, which means if their website updates, lyricsgenius would fail to fetch the lyrics. This library hasn't been updated in 6 months; itself being a web scraping library means that kind of inactivity would render the library severely unstable. Since the library is licensed under MIT, you can fork the library and maintain an up-to-date version for your project/bot. However, it would be much better to use a dedicated API to fetch songs lyrics to guarantee stability.
Also, lyricsgenius uses the synchronous requests library, which means it'll "block" your asynchronous bot while it fetches the lyrics. This is definitely undesirable for a Discord Bot since your bot would be completely unresponsive while it fetches the lyrics. Consider rewriting it using aiohttp or use run_in_executor when calling blocking functions.
Some Random API is something easy to deal with when you are creating a command that will send you the song lyrics.
This is how to do it with some random api,
# these imports are used for this particular lyrics command. the essential import here is aiohttp, which will be used to fetch the lyrics from the API
import textwrap
import urllib
import aiohttp
import datetime
#bot.command(aliases = ['l', 'lyrc', 'lyric']) # adding aliases to the command so they they can be triggered with other names
async def lyrics(ctx, *, search = None):
"""A command to find lyrics easily!"""
if not search: # if user hasnt given an argument, throw a error and come out of the command
embed = discord.Embed(
title = "No search argument!",
description = "You havent entered anything, so i couldnt find lyrics!"
)
return await ctx.reply(embed = embed)
# ctx.reply is available only on discord.py version 1.6.0, if you have a version lower than that use ctx.send
song = urllib.parse.quote(search) # url-encode the song provided so it can be passed on to the API
async with aiohttp.ClientSession() as lyricsSession:
async with lyricsSession.get(f'https://some-random-api.ml/lyrics?title={song}') as jsondata: # define jsondata and fetch from API
if not 300 > jsondata.status >= 200: # if an unexpected HTTP status code is recieved from the website, throw an error and come out of the command
return await ctx.send(f'Recieved poor status code of {jsondata.status}')
lyricsData = await jsondata.json() # load the json data into its json form
error = lyricsData.get('error')
if error: # checking if there is an error recieved by the API, and if there is then throwing an error message and returning out of the command
return await ctx.send(f'Recieved unexpected error: {error}')
songLyrics = lyricsData['lyrics'] # the lyrics
songArtist = lyricsData['author'] # the author's name
songTitle = lyricsData['title'] # the song's title
songThumbnail = lyricsData['thumbnail']['genius'] # the song's picture/thumbnail
# sometimes the song's lyrics can be above 4096 characters, and if it is then we will not be able to send it in one single message on Discord due to the character limit
# this is why we split the song into chunks of 4096 characters and send each part individually
for chunk in textwrap.wrap(songLyrics, 4096, replace_whitespace = False):
embed = discord.Embed(
title = songTitle,
description = chunk,
color = discord.Color.blurple(),
timestamp = datetime.datetime.utcnow()
)
embed.set_thumbnail(url = songThumbnail)
await ctx.send(embed = embed)

Unable to send file to Telegram Channel

Error below:
Failed to convert James Blake - Never Dreamed.mp4 to media. Not an existing file, an HTTP URL or a valid bot-API-like file ID
Function that I am running is here.
async def gramain():
# Getting information about yourself
me = await bott.get_me()
print(me.stringify())
filesww = os.listdir('media').pop()
now = os.getcwd()
mediadir = now + "/media/"
vid = open(mediadir+filesww, 'r')
# await bot.send_message(chat, 'Hello, friend!')
await bott.send_file(chat, filesww, video_note=True)
I trying to use this function from the library Telethon.
https://docs.telethon.dev/en/latest/modules/client.html#telethon.client.uploads.UploadMethods.send_file
I am unable to find out what the issue is. Please help!

Categories

Resources