Created
November 23, 2011 21:22
-
-
Save codingjester/1389963 to your computer and use it in GitHub Desktop.
Working version of Photo Uploads for Tumblr API V2
This file contains 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 urllib,hmac,time,hashlib,base64,httplib,sys,json,urlparse | |
## This is just a simple example that is self contained. | |
## You will need to modified it to make it work | |
## | |
## creds - need to be filled out | |
## blognmae - needs to be defined | |
## | |
## reads in image files from the command line and posts to your blog | |
## | |
## Your example body will contain something like: | |
## | |
## data%5B0%5D= => data[0]=<start binary> | |
## | |
## So from here you can gather that it's data[0], data[1] and so on. | |
## | |
## This code works for single photos as well as multiple photos | |
## | |
## Code was tested usings Python 2.7, no guarantees it'll work for others. | |
## Usage: | |
## python gistfilename.py example1.jpg [example2.jpg example3.jpg ...] | |
## | |
## | |
class TumblrAPI: | |
def __init__(self, cred): | |
self.consumer_key = cred['consumer_key'] | |
self.secret_key = cred['secret_key'] | |
self.oauth_token_secret= cred['oauth_token_secret'] | |
self.oauth_token = cred['oauth_token'] | |
def parse(self,url): | |
p = urlparse.urlparse(url) | |
return (p.netloc,p.netloc,p.path) | |
def oauth_sig(self,method,uri,params): | |
""" | |
Creates the valid OAuth signature. | |
""" | |
#eg: POST&http%3A%2F%2Fapi.tumblr.com%2Fv2%2Fblog%2Fexample.tumblr.com%2Fpost | |
s = method + '&'+ urllib.quote(uri).replace('/','%2F')+ '&' + '%26'.join( | |
#escapes all the key parameters, we then strip and url encode these guys | |
[urllib.quote(k) +'%3D'+ urllib.quote(params[k]).replace('/','%2F') for k in sorted(params.keys())] | |
) | |
s = s.replace('%257E','~') | |
return urllib.quote(base64.encodestring(hmac.new(self.secret_key + "&"+self.oauth_token_secret,s,hashlib.sha1).digest()).strip()) | |
def oauth_gen(self,method,url,iparams,headers): | |
""" | |
Creates the oauth parameters we're going to need to sign the body | |
""" | |
params = dict([(x[0], urllib.quote(str(x[1])).replace('/','%2F')) for x in iparams.iteritems()]) | |
params['oauth_consumer_key'] = self.consumer_key | |
params['oauth_nonce'] = str(time.time())[::-1] | |
params['oauth_signature_method'] = 'HMAC-SHA1' | |
params['oauth_timestamp'] = str(int(time.time())) | |
params['oauth_version'] = '1.0' | |
params['oauth_token']= self.oauth_token | |
params['oauth_signature'] = self.oauth_sig(method,'http://'+headers['Host'] + url, params) | |
headers['Authorization' ] = 'OAuth ' + ', '.join(['%s="%s"' %(k,v) for k,v in params.iteritems() if 'oauth' in k ]) | |
def _postOAuth(self,url,params={}): | |
""" | |
Does the actual posting. Content-type is set as x-www-form-urlencoded | |
Everything url-encoded and data is sent through the body of the request. | |
""" | |
(machine,host,uri) = self.parse(url) | |
headers= {'Host': host,"Content-type": 'application/x-www-form-urlencoded'} | |
self.oauth_gen('POST',uri,params,headers) | |
conn = httplib.HTTPConnection(machine) | |
#URL Encode the paramers and make sure and kill any trailing slashes. | |
conn.request('POST',uri,urllib.urlencode(params).replace('/','%2F'),headers); | |
return conn.getresponse() | |
def createPost(self,id,params={}): | |
url = 'http://api.tumblr.com/v2/blog/%s/post' %id | |
return self._resp(self._postOAuth(url,params),201); | |
def _resp(self,resp,code=200): | |
if resp.status != code: | |
raise Exception('response code is %d - %s' % (resp.status,resp.read())); | |
return json.loads(resp.read())['response'] | |
cred = { "consumer_key" : 'your-consumer-key', | |
'secret_key' : 'your-consumer-secret', | |
'oauth_token' : 'access-token', | |
'oauth_token_secret' : 'access-token-secret'} | |
blogname = 'manurday.tumblr.com' | |
api = TumblrAPI(cred) | |
params = {} | |
params['type'] = 'photo' | |
for x in range(1,len(sys.argv)): | |
params['data[%d]' % (x-1) ] = file(sys.argv[x]).read() | |
print api.createPost(blogname,params); |
I got exactly the same error as @boppyer
exactly the same error here too :( python 2.7.2
I removed an extraneous & which was leftover by accident. Sorry. Gist works now.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I get this error popping up, any ideas what I might be doing wrong?
Traceback (most recent call last): File "tumblrv2api.py", line 97, in print api.createPost(blogname,params); File "tumblrv2api.py", line 77, in createPost return self._resp(self._postOAuth(url,params),201); File "tumblrv2api.py", line 81, in _resp raise Exception('response code is %d - %s' % (resp.status,resp.read())); Exception: response code is 401 - {"meta":{"status":401,"msg":"Not Authorized"},"response":[]}