Graph API post comment with photo attachment - python

I am trying to get my script to post a comment on all comments of a parent post that meet a certain requirement. I am able to get the text to post reliably but I can't seem to get the photo attachment to show up. I'm programming in Python3 and using the Facebook-sdk library to assist.
When reading the Graph API documentation I found the following fields described on the comments edge:
attachment_id
An optional ID of a unpublished photo (see no_story field in /{user-id}/photos) uploaded to Facebook to include as a photo comment. One of attachment_url, attachment_id, message or source must be provided when publishing.
(string)
attachment_url
The URL of an image to include as a photo comment. One of attachment_url, attachment_id, message or source must be provided when publishing.
(string)
source
A photo, encoded as form data, to use as a photo comment. One of attachment_url, attachment_id, message or source must be provided when publishing.
(multipart/form-data)
My code is currently formatted as such (I've provided partial code relevant to this issue):
my_dict = {
0: ('file_1.JPG', "Some text for file 1"),
1: ('file_2.jpg', "Different text for file 2"),
2: ('file_3.JPG', "More different text for file 3"),
3: ('file_4.JPG', "A fourth bit of text for file 4.")
}
comments = api.get_object('PAGE.NUMBER.HERE?fields=posts{comments}')
com_index = comments['posts']['data'][0]['comments']['data']
photo_id = my_dict[x][0]
my_image = 'file:///Users/filepath/{}'.format(photo_id)
text = my_dict[x][1]
api.put_object(com_index[com_index]['id'], "comments/comments", source=(my_image, 'image/jpg'), message=text)
I have tried both with and without the 'image/jpg' argument in the source tuple.
Instead of using 'source' I've also tried:
attachment_url=card_image
attachment=card_image
When using attachment_url I get an invalid url error; when using the other parameters the text always is posted but the photo is not posted.
Lastly, I've tried changing the edge to be a /photos edge of the comment instead of the /comments edge of another comment, but still no luck (as below):
api.put_object(com_index[comment]['id'], "comments/photo", source=(my_image, 'image/jpg'), message=text)
What is the proper method to post a reply that has a photo attachment?

I think {objet-id}/comments is depreciated since version 2.10. Check this.

I'm not a Python guy, but perhaps this is working anyway ;)
my_dict = {
0: ('file_1.JPG', "Some text for file 1"),
1: ('file_2.jpg', "Different text for file 2"),
2: ('file_3.JPG', "More different text for file 3"),
3: ('file_4.JPG', "A fourth bit of text for file 4.")
}
comments = api.get_object('PAGE.NUMBER.HERE?fields=posts{comments}')
com_index = comments['posts']['data'][0]['comments']['data']
photo_id = my_dict[x][0]
my_image = 'file:///Users/filepath/{}'.format(photo_id)
photo = open(my_image)
text = my_dict[x][1]
api.put_object(com_index[com_index]['id'], "comments/comments", source=photo.read(), message=text)
photo.close()

Related

Check whether a website provides photo or video based on a pattern in its URL

I am wondering how I can figure out if a website provide photo or video by checking its URL. I investigated the website that I am interested in and found that most of the links I have are in this form: (I am not sure if I can actually name the website, so for now I just wrote it in a form of an example):
http://www.example.com/abcdef
where example is the main domain and abcdef is a number like 69964. The interesting pattern I found is that after entering this URL, if it actually has video the URL will change automatically to https://www.example.com/abcdef#mode=tour while if it's just a photo, it will change to https://www.example.com/abcdef#mode=0
Now I have a list of URLs from this website and I just want to check if it has photo or video, or it's not working (invalid URL). Is there anyway to do that?
So I have a rather simple solution for this.
Inspecting the URLs provided by the OP (e.g., https://www.pixilink.com/93313) indicates that the #mode= default value is provided by the variable initial_mode = in an embedded javascript. So to establish whether a URL will default to "picture" (#mode=0) or video (#mode=tour) can be accomplished by investigating the value assigned to this variable.
#Function to get the value of initial_mode from the URL
urlmode <- function(x){
mycontent <- readLines(x)
mypos <- grep("initial_mode = ", mycontent)
if(grepl("0", mycontent[mypos])){
cat("\n", x, "has default initial_mode picture: #mode=0 \n")
return("picture")
} else if(grepl("tour", mycontent[mypos])){
cat("\n", x, "has default initial_mode video: #mode=tour \n")
return("video")
} else{
cat("\n", x, "is an invalid URL. \n")
return("invalid")
}
}
#Example URLs to demonstrate functionality
myurl1 <- "https://www.pixilink.com/93313"
myurl2 <- "https://www.pixilink.com/69964"
urlmode(myurl1)
#
# https://www.pixilink.com/93313 has default initial_mode picture: #mode=0
#[1] "picture"
#Warning message:
#In readLines(x) :
# incomplete final line found on 'https://www.pixilink.com/93313'
#
urlmode(myurl2)
#
# https://www.pixilink.com/69964 has default initial_mode video: #mode=tour
#[1] "video"
#Warning message:
#In readLines(x) :
# incomplete final line found on 'https://www.pixilink.com/69964'
Needless to say this is an extremely simplistic function that will (most likely) fail all but the ideal (sub)set of cases. But it's a start.

dropbox.exceptions.ApiError: ... CreateFileRequestError('validation_error', None)

I want to get and save the URL of an image to a variable via dropbox API in python. I'm following this guide but I get the error shown in the title.
I searched for the function dbx.file_requests_create and probably doing something wrong with title or destination. Should the title be some existing source? Because I just set it by myself.
import dropbox
dbx = dropbox.Dropbox('Y2_M...aVP')
req = dbx.file_requests_create(title='Images', destination='/C:/Users/Dropbox/Apps/myProject/image.jpg')
print req.url
print req.id
EDIT: I found this link FileRequestError. It says:
There was an error validating the request. For example, the title was invalid, or there were disallowed characters in the destination path.
EDIT-2 [SOLVED]: Thanks to Aran-Fey and Greg for their comments, I solved the problem by replacing req = dbx.file_requests_create(title='Images', destination='/C:/Users/Dropbox/Apps/myProject/image.jpg') with
req = dbx.sharing_create_shared_link_with_settings('/image.jpg', settings=None)
Also, for people who have problem with getting the image when sharing it, just change the last character of the link from 0 to 1 as mentioned on this and this.
You can add this line to the end newURL = req.url[:-1] + "1" to solve the matter.

Username and Password login

I'd like to create a Login in which will open a text/csv file read the "Valid" usernames and passwords from the file and then if whatever the user has added has matched what was in the file then it will allow access to the rest of the program
How would i integrate the code below into one of which opens a file reads valid usernames and passwords and checks it against the users input
Currently i have something which works but there is only one password which i have set in the code.
Password = StringVar()
Username = StringVar()
def EnterPassword():
file = open('Logins.txt', 'w') #Text file i am using
with open('Logins.txt') as file:
data = file.read() #data=current text in text file
UsernameAttempt = Username.get()#how to get value from entry box
PasswordAttempt = Password.get()#how to get value from entry box
if PasswordAttempt == '' and UsernameAttempt == '':
self.delete()
Landlord = LandlordMenu()
else:
PasswordError = messagebox.showerror('Password/Username Entry','Incorrect Username or Password entered.\n Please try again.')
PasswordButton = Button(self.GenericGui,text = 'Landlord Section',height = 3, width = 15, command = EnterPassword, font = ('TkDefaultFont',14),relief=RAISED).place(x=60,y=175)
Some assistance would be appreciated
Please have a look at some documentation. Your question in "Coding Comments" -> #how to get value from entry box is easy to be solved using official documentation.
For reading files there is also official documentation on strings and file operations (reading file line by line into string, using string.split(';') to get arrays instead of row-strings).
Please do read documentation before writing applications. You do not need to know the complete API of all python modules but where to look. It is very exhausting to be dependent on other users / developers when there is no actual need for it (as there is very detailed documentation and tons of howtows for that kind of stuff).
This is not meant to be offensive but to show you how easy you can get documentation. Both results where first-results from a search engine. (ddg)
Please keep in mind that SO is neither a code writing service nor a let-me-google-that-for-you forum.

How to check / uncheck checkboxes in a PDF with Python (preferably PyPDF2)?

I have the code below
from PyPDF2 import PdfFileReader, PdfFileWriter
d = {
"Name": "James",
" Date": "1/1/2016",
"City": "Wilmo",
"County": "United States"
}
reader = PdfFileReader("medicareRRF.pdf")
inFields = reader.getFields()
watermark = PdfFileReader("justSign.pdf")
writer = PdfFileWriter()
page = reader.getPage(0)
page.mergePage(watermark.getPage(0))
writer.addPage(page)
written_page = writer.getPage(0)
writer.updatePageFormFieldValues(written_page, d)
Which correctly fills in the PDF with the dictionary (d), but how can I check and uncheck boxes on the PDF? Here is the getField() info for one of the boxes:
u'Are you ok': {'/FT': '/Btn','/Kids': [IndirectObject(36, 0),
IndirectObject(38, 0)],'/T': u'Are you ok','/V': '/No'}
I tried adding {'Are you ok' : '/Yes'} and several other similar ways, but nothing worked.
I came across the same issue, looked in several places, and was disappointed that I couldn't find the answer. After a few frustrating hours looking at my code, the pyPDF2 code, and the Adobe PDF 1.7 spec, I finally figured it out. If you debug into updatePageFormFieldValues, you'll see that it uses only TextStringObjects. Checkboxes are not text fields -- even the /V values are not text fields, which seemed counterintuitive at least to me. Debugging into that function showed me that checkboxes are instead NameObjects so I created my own function to handle them. I create two dicts: one with only text values that I pass to the built-in updatePageFormFieldValues function and a second with only checkbox values. I also set the /AS to ensure visibility (see PDF spec). My function looks like this:
def updateCheckboxValues(page, fields):
for j in range(0, len(page['/Annots'])):
writer_annot = page['/Annots'][j].getObject()
for field in fields:
if writer_annot.get('/T') == field:
writer_annot.update({
NameObject("/V"): NameObject(fields[field]),
NameObject("/AS"): NameObject(fields[field])
})
However, as far as I can tell, whether you use /1, /On, or /Yes depends on how the form was defined or perhaps what the PDF reader is looking for. For me, /1 worked.
I will like to add on to the answer #rpsip.
from PyPDF2 import PdfReader, PdfWriter
from PyPDF2.generic import NameObject
reader = PdfReader(r"form2.pdf") #where you read the pdf in the same directory
writer = PdfWriter()
page = reader.pages[0] #read page 1 of your pdf
fields = reader.get_fields()
print (fields) # this is to identify if you can see the form fills in that page
writer.add_page(page) #this line is necessary otherwise the pdf will be corrupted
for i in range(len(page["/Annots"])): #in order to access the "Annots" key
print ((page["/Annots"][i].get_object())) #to find out which of the form fills are checkbox or text fill
if (page["/Annots"][i].get_object())['/FT']=="/Btn" and (page["/Annots"][i].get_object())['/T']=='Check Box3': #this is my filter so that I can filter checkboxes and the checkbox I want i.e. "Check Box 3"
print (page["/Annots"][i].get_object()) #further check if I got what I wanted as per the filter
writer_annot = page["/Annots"][i].get_object()
writer_annot.update(
{
NameObject("/V"): NameObject(
"/Yes"), #NameObject being only for checkbox, and please try "/Yes" or "/1" or "/On" to see which works
NameObject("/AS"): NameObject(
"/Yes" #NameObject being only for checkbox, and please try "/Yes" or "/1" or "/On" to see which works
)
}
)
with open("filled-out.pdf", "wb") as output_stream:
writer.write(output_stream) #save the ticked pdf file as another file named "filled-out.pdf"
hoped I helped.

Provide tab title with reportlab generated pdf

This question is really simple, but I can't find any data on it.
When I generate a pdf with reportlab, passing the httpresponse as a file, browsers that are configured to show files display the pdf correctly. However, the title of the tab remains "(Anonymous) 127.0.0.1/whatnot", which is kinda ugly for the user.
Since most sites are able to somehow display an appropiate title, I think it's doable... Is there some sort of title parameter that I can pass to the pdf? Or some header for the response? This is my code:
def render_pdf_report(self, context, file_name):
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'filename="{}"'.format(file_name)
document = BaseDocTemplate(response, **self.get_create_document_kwargs())
# pdf generation code
document.build(story)
return response
Seems that Google Chrome doesn't display the PDF titles at all.
I tested the link in your comment (biblioteca.org.ar) and it displays in Firefox as " - 211756.pdf", seems there's an empty title and Firefox then just displays the filename instead of the full URL path.
I reproduced the same behaviour using this piece of code:
from reportlab.pdfgen import canvas
c = canvas.Canvas("hello.pdf")
c.setTitle("hello stackoverflow")
c.drawString(100, 750, "Welcome to Reportlab!")
c.save()
Opening it in Firefox yields the needed result:
I found out about setTitle in ReportLab's User Guide. It has it listed on page 16. :)
I was also looking for this and I found this in the source code.
reportlab/src/reportlab/platypus/doctemplate.py
# line - 467
We can set the document's title by
document.title = 'Sample Title'
I realise this is an old question but dropping in an answer for anyone using SimpleDocTemplate. The title property can be set in constructor of SimpleDocTemplate as a kwarg. e.g.
doc = SimpleDocTemplate(pdf_bytes, title="my_pdf_title")
If you are using trml2pdf, you will need to add the "title" attribute in the template tag, ie., <template title="Invoices" ...
In addition to what others have said, you can use
Canvas.setTitle("yourtitle")
which shows up fine in chrome.

Categories