I am a very new to Python and Facebook Graph API and hope you can help me out with this:
I have writted (in Python) a peace of code that uploads images tu a page on facebook (in a post, so it contains some text too) and this works as expected. Now I am trying to write a peace of code capable of downloading thhe image inside a post (given post_id). Unfortunately I always get "file corrupted " error.
Here is the code I use to download the image:
# this function uploads an image from a web url
ret = upload_img_to_fb(url)
# decode JSON from the request
post_id = json.loads(ret)
ret = get_json_from_fb_postID(post_id['post_id'])
perm_url = json.loads(ret)
print('Perm url = ' + perm_url['permalink_url'] + '\n')
img_response = requests.get(perm_url['permalink_url'])
image = open("foto4.jpg","wb")
image.write(img_response.content)
image.close()
Now, the print will print the following:
Perm url = https://www.facebook.com/102956292308044/photos/a.103716555565351/107173241886349/?type=3
which, acording to what I understood makes everything wrong because it is not a picture, even if a picture is displayed on the screen. So I right clicked the pic and opened it's link and I got:
https://scontent.fbzo1-2.fna.fbcdn.net/v/t39.30808-6/273008252_107171558553184_3697853178128736286_n.jpg?_nc_cat=103&ccb=1-5&_nc_sid=9267fe&_nc_ohc=d0ZvWSTzIogAX-PsuzN&_nc_ht=scontent.fbzo1-2.fna&oh=00_AT8GWh0wDHgB6tGCzHuPE2VZFus9EgWhllaJfVkZ-Nqtow&oe=620465E4
and if I pass this last link as parameter to img_response = requests.get() it works.
How do I get around this?
So say from a random api, lets say api.example.com as an example. It sends a random image once you go on it and sends the json for it. So like {"url": "api.example.com/img1.png"}. After de-jsonifying it how can i download the image and save it in some folder, but if its already downloaded so say the image name is taken it will not download it.
Edit: here is my code i done so far.
`
url = f"https://nekos.life/api/v2/img/neko"
response = requests.get(url)
response.raise_for_status()
jsonResponse = response.`json()
urll = (jsonResponse["url"])
urllib.request.urlretrieve(urll, "neko.png")`
as said in this article, i think [os.path][1] can do the job pretty well.
just try to use
os.path.exists(phot_path)
that should be it.
[1]: https://linuxize.com/post/python-check-if-file-exists/
I am trying to reload an image in a loop from the blob's URL into a text area.
So, I am following the given IronPython examples to be able to download a blob and set to a document property called Img1 and eventually I'm setting that property to a label inside the text area. And my plan is to run this in a wait-loop cycle.
The code looks like this:
#from System.Drawing import Image
from System import Uri
from System.Net import HttpWebRequest
from Spotfire.Dxp.Data import BinaryLargeObject
uri = Uri("http://100.206.214.99/remote/display.bmp")
request = HttpWebRequest.Create(uri)
response = request.GetResponse()
stream = response.GetResponseStream()
blob = BinaryLargeObject.Create(stream)
Document.Properties["Img1"] = blob
It's all working fine, but I'm not able to adjust the height or width of the image/blob. Can anyone help me with this?
complete Python newbie, sorry!
I'm using the Telebot starter kit (https://github.com/yukuku/telebot) which handles replies as:
elif 'who are you' in text:
reply('telebot starter kit, created by yukuku: https://github.com/yukuku/telebot')
I was able to get it to reply with an image with:
elif 'Test1' in text:
reply(img=urllib2.urlopen('https://i.ytimg.com/vi/VC8H5B2YVCY/maxresdefault.jpg').read())
But cannot send animated gifs. Sending as an img per above uses sendPhoto which is static
I'm sure it has to be a case of adding the InlineQueryResultGif class and calling it inside a reply() but I've tried lots and lots of ways of doing that but I'm not making any progress
Help!
EDIT to show some attempts:
Firstly I tried editing the elif argument that was already in place for sending the img:
elif gif:
gif = multipart.post_multipart(BASE_URL + 'InlineQueryResultGif', [
('chat_id', str(chat_id)),
('reply_to_message_id', str(message_id)),
], [
('gif', 'image.gif', gif),
])
and then simply changing the reply to be:
elif 'Test4' in text:
reply(gif=urllib2.urlopen('http://www.reactiongifs.us/wp-content/uploads/2014/08/popcorn_indiana_jones.gif').read())
Then I've tried adding the InlineQueryResultGif class itself:
class InlineQueryResult:
pass
class InlineQueryResultGif(InlineQueryResult):
""" Represents a link to an animated GIF file. By default, this animated GIF file will be sent by the user with
optional caption. Alternatively, you can provide message_text to send it instead of the animation.
Attributes:
id (str) :Unique identifier of this result
gif_url (str) :A valid URL for the GIF file. File size must not exceed 1MB
gif_width (int) :*Optional.* Width of the GIF
gif_height (int) :*Optional.* Height of the GIF
thumb_url (str) :*Optional.* URL of a static thumbnail for the result (jpeg or gif)
title (str) :*Optional.* Title for the result
caption (str) :*Optional.* Caption of the GIF file to be sent
message_text (str) :*Optional.* Text of a message to be sent instead of the animation
parse_mode (str) :*Optional.* Send “Markdown”, if you want Telegram apps to show bold,
italic and inline URLs in your bot's message.
disable_web_page_preview (bool) :*Optional.* Disables link previews for links in the sent message
"""
def __init__(self, id, gif_url,
gif_width=None, gif_height=None, thumb_url=None, title=None,
caption=None, message_text=None, parse_mode=None, disable_web_page_preview=None):
self.type = 'gif'
self.id = id
self.gif_url = gif_url
self.gif_width = gif_width
self.gif_height = gif_height
self.thumb_url = thumb_url
self.title = title
self.caption = caption
self.message_text = message_text
self.parse_mode = parse_mode
self.disable_web_page_preview = disable_web_page_preview
And tried to call it inside the reply:
elif 'Test2' in text:
reply(InlineQueryResultGif('http://www.reactiongifs.us/wp-content/uploads/2014/08/popcorn_indiana_jones.gif'))
And lots of different versions of the above. Not getting anything to work
I'm using python-telegram-bot and this is how I approached this.
def sendImage(bot, update, dataval): # Funtion to send images or gifs the proper way
val = dataval.rsplit('.', 1)[1]
if val == 'gif':
# Send a gif
bot.sendDocument(chat_id=update.message.chat_id, document = dataval)
elif val == 'webm':
bot.sendMessage(chat_id=update.message.chat_id, text = "The item attempted to be sent is unsupported at the moment.")
else:
# Send a Picture
bot.sendPhoto(chat_id=update.message.chat_id, photo=dataval)
In my example above, I pass a url to the function in the dataval variable. I haven't re-visited this in many months, so, its possible that webm's are supported now. Also, there is a way to send images by their id as stored on telegram's servers, however, I do not know how to use that method.
You almost had it right the first time before implementing the inline stuff, except you need to use sendDocument:
elif gif:
resp = multipart.post_multipart(BASE_URL + 'sendDocument', [
('chat_id', str(chat_id)),
('reply_to_message_id', str(message_id)),
], [
('gif', 'image.gif', gif),
])
...and then use urllib2 to read the gif like so:
elif 'Test2' in text:
reply(gif=urllib2.urlopen('http://www.reactiongifs.us/wp-content/uploads/2014/08/popcorn_indiana_jones.gif').read())
You can also do this with local files, but I found the file:// functionality in urllib2 to be quite frustrating when dealing with relative paths (such as with Google AppEngine). For local files, I just use urllib instead, like so:
elif 'Test2' in text:
reply(gif=urllib.urlopen('images/animated.gif').read())
If you can, try using this Python library for telegram
https://github.com/python-telegram-bot/python-telegram-bot
With this you can easily send animated gifs with sendDocument:
bot.sendChatAction(chat_id=chat_id, action=telegram.ChatAction.UPLOAD_PHOTO)
bot.sendDocument(chat_id=chat_id, document=image_url)
My approach (using python-telegram-bot) and this is how I got this work.
def get_gif_data():
""" Generates binary data to post animation """
files = []
for file in os.listdir("."):
if file.endswith(".gif"):
files.append(file)
new_gif = files[randrange(len(files))]
logger.info(f"-== Used gif file: {new_gif}")
animation = open(new_gif, 'rb').read()
return animation
def echo_gif(update: Update, context: CallbackContext) -> None:
"""Echo to /gif with gif"""
context.bot.sendAnimation(chat_id=update.message.chat_id,
animation=get_gif_data(), ## that's just data from local gif file
caption='That is your gif!',
)
print("GIF!")
return
I'd like to send a Image (via URL or Path), on request.
I use the source code here.
The code has already a sample to send an image (via URL or Path), but I don't get it since I'm new to Python.
Here's the sample code snippet:
elif text == '/image': #request
img = Image.new('RGB', (512, 512))
base = random.randint(0, 16777216)
pixels = [base+i*j for i in range(512) for j in range(512)] # generate sample image
img.putdata(pixels)
output = StringIO.StringIO()
img.save(output, 'JPEG')
reply(img=output.getvalue())
Some API infos can be found here.
Thanks for your patience.
To send a photo from URL:
bot.send_photo(chat_id=chat_id, photo='https://telegram.org/img/t_logo.png')
To send a photo from local Drive:
bot.send_photo(chat_id=chat_id, photo=open('tests/test.png', 'rb'))
Here is the reference documentation.
I was struggling to connect the python-telegram-bot examples with the above advice. Especially, while having context and update, I couldnt find chatid and bot. Now, my two cents:
pic=os.path.expanduser("~/a.png")
context.bot.send_photo(chat_id=update.effective_chat.id, photo=open(pic,'rb'))