Created
December 5, 2011 12:59
-
-
Save heshiyou/1433526 to your computer and use it in GitHub Desktop.
Posting photo to wall using Facebook Graph API
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
import os | |
import itertools | |
import mimetypes | |
import mimetools | |
import urllib | |
import urllib2 | |
import cgi | |
try: | |
import json | |
except ImportError: | |
from django.utils import simplejson as json | |
# this class allows you to upload a file to a URL | |
# using pure urllib | |
class MultiPartForm(object): | |
"""Accumulate the data to be used when posting a form. | |
source: http://www.doughellmann.com/PyMOTW/urllib2/#uploading-files | |
""" | |
def __init__(self): | |
self.form_fields = [] | |
self.files = [] | |
self.boundary = mimetools.choose_boundary() | |
return | |
def get_content_type(self): | |
return 'multipart/form-data; boundary=%s' % self.boundary | |
def add_field(self, name, value): | |
"""Add a simple field to the form data.""" | |
self.form_fields.append((name, value)) | |
return | |
def add_file(self, fieldname, filename, fileHandle, mimetype=None): | |
"""Add a file to be uploaded.""" | |
body = fileHandle.read() | |
if mimetype is None: | |
mimetype = mimetypes.guess_type(filename)[0] or 'application/octet-stream' | |
self.files.append((fieldname, filename, mimetype, body)) | |
return | |
def __str__(self): | |
"""Return a string representing the form data, including attached files.""" | |
# Build a list of lists, each containing "lines" of the | |
# request. Each part is separated by a boundary string. | |
# Once the list is built, return a string where each | |
# line is separated by '\r\n'. | |
parts = [] | |
part_boundary = '--' + self.boundary | |
# Add the form fields | |
parts.extend( | |
[part_boundary, | |
'Content-Disposition: form-data; name="%s"' % name, | |
'', | |
value, | |
] | |
for name, value in self.form_fields | |
) | |
# Add the files to upload | |
parts.extend( | |
[part_boundary, | |
'Content-Disposition: file; name="%s"; filename="%s"' % \ | |
(field_name, filename), | |
'Content-Type: %s' % content_type, | |
'', | |
body, | |
] | |
for field_name, filename, content_type, body in self.files | |
) | |
# Flatten the list and add closing boundary marker, | |
# then return CR+LF separated data | |
flattened = list(itertools.chain(*parts)) | |
flattened.append('--' + self.boundary + '--') | |
flattened.append('') | |
flattened = map(str, flattened) | |
return '\r\n'.join(flattened) | |
def get_client_access_token(app_id, app_secret): | |
#create an access token acting as if we are a | |
#desktop client (we in fact are!). app_id and | |
#app_secrets are the parameters that you get | |
#get when you create a new app | |
params = { | |
'grant_type': 'client_credentials', | |
'client_id': app_id, | |
'client_secret': app_secret | |
} | |
response = cgi.parse_qs(urllib.urlopen( | |
"https://graph.facebook.com/oauth/access_token?" + | |
urllib.urlencode(params)).read()) | |
access_token = response["access_token"][-1] | |
return access_token | |
def create_user(app_id, access_token): | |
#create a test user using desktop-client | |
#access token. We need 'publish_stream' and | |
#'user_photos' extended permissions | |
params = { | |
'access_token': access_token, | |
'installed': 'true', | |
'permissions': 'publish_stream,user_photos' | |
} | |
params = urllib.urlencode(params) | |
url = 'https://graph.facebook.com/%s/accounts/test-users'%(app_id) | |
request = urllib2.Request(url, headers = {}, data = params) | |
response = urllib2.urlopen(request) | |
response = response.read() | |
response = json.loads(response) | |
return response | |
def upload_pic(uid, access_token, pic_caption, pic_file_name, pic_file): | |
#using access_token for the newly created test user upload | |
#an image file from disk (or any other file like source) to | |
#the user's account. | |
#pic_caption: the caption to the pic | |
#pic_file_name: name of the file (used only to guess mimetype) | |
#pic_file: a file like object representing the file (one can | |
#open a url and use the response here if the file to be uploaded | |
#is on the web (and not on the disk) | |
form = MultiPartForm() | |
form.add_field('access_token', access_token) | |
form.add_field('caption', pic_caption) | |
form.add_file('source', pic_file_name, pic_file) | |
request = urllib2.Request('https://graph.facebook.com/%s/photos'%(uid)) | |
body = str(form) | |
request.add_header('Content-type', form.get_content_type()) | |
request.add_header('Content-length', len(body)) | |
request.add_data(body) | |
return urllib2.urlopen(request).read() | |
def do(): | |
if not len(sys.argv) == 5: | |
print "usage: python %s <app_id> <app_secret> <caption> <file_path>"%(sys.argv[0]) | |
return | |
app_id = sys.argv[1] | |
app_secret = sys.argv[2] | |
p_caption = sys.argv[3] | |
file_path = sys.argv[4] | |
client_access_token = get_client_access_token(app_id, app_secret) | |
user_info = create_user(app_id, client_access_token) | |
u_id = user_info['id'] | |
print 'created test user account with id: %s'%(u_id) | |
u_access_token = user_info['access_token'] | |
user_login_url = user_info['login_url'] | |
p_file_name = os.path.basename(file_path) | |
p_file = open(file_path) | |
upload_pic(u_id, u_access_token, p_caption, p_file_name, p_file) | |
print 'login as the test user and view the uploaded pic: %s'%(user_login_url) | |
if __name__ == '__main__': | |
do() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment