Skip to content

Instantly share code, notes, and snippets.

@velocityzen
Created September 26, 2011 16:30
Show Gist options
  • Star 24 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save velocityzen/1242662 to your computer and use it in GitHub Desktop.
Save velocityzen/1242662 to your computer and use it in GitHub Desktop.
This script take pictures from directory and post it to tumblr blog and then delete it. Tumblr API v2! This example for oath file upload.
import urlparse
import oauth2 as oauth
consumer_key = ''
consumer_secret = ''
request_token_url = 'http://www.tumblr.com/oauth/request_token'
access_token_url = 'http://www.tumblr.com/oauth/access_token'
authorize_url = 'http://www.tumblr.com/oauth/authorize'
consumer = oauth.Consumer(consumer_key, consumer_secret)
client = oauth.Client(consumer)
# Step 1: Get a request token. This is a temporary token that is used for
# having the user authorize an access token and to sign the request to obtain
# said access token.
resp, content = client.request(request_token_url, "GET")
if resp['status'] != '200':
raise Exception("Invalid response %s." % resp['status'])
request_token = dict(urlparse.parse_qsl(content))
print "Request Token:"
print " - oauth_token = %s" % request_token['oauth_token']
print " - oauth_token_secret = %s" % request_token['oauth_token_secret']
print
# Step 2: Redirect to the provider. Since this is a CLI script we do not
# redirect. In a web application you would redirect the user to the URL
# below.
print "Go to the following link in your browser:"
print "%s?oauth_token=%s" % (authorize_url, request_token['oauth_token'])
print
# After the user has granted access to you, the consumer, the provider will
# redirect you to whatever URL you have told them to redirect to. You can
# usually define this in the oauth_callback argument as well.
accepted = 'n'
while accepted.lower() == 'n':
accepted = raw_input('Have you authorized me? (y/n) ')
oauth_verifier = raw_input('What is the PIN? ')
# Step 3: Once the consumer has redirected the user back to the oauth_callback
# URL you can request the access token the user has approved. You use the
# request token to sign this request. After this is done you throw away the
# request token and use the access token returned. You should store this
# access token somewhere safe, like a database, for future use.
token = oauth.Token(request_token['oauth_token'],
request_token['oauth_token_secret'])
token.set_verifier(oauth_verifier)
client = oauth.Client(consumer, token)
resp, content = client.request(access_token_url, "POST")
access_token = dict(urlparse.parse_qsl(content))
print "Access Token:"
print " - oauth_token = %s" % access_token['oauth_token']
print " - oauth_token_secret = %s" % access_token['oauth_token_secret']
print
print "You may now access protected resources using the access tokens above."
print
import glob
import json
import os
import time
import urllib2
import urlparse
import oauth2
from poster.encode import multipart_encode
from poster.streaminghttp import register_openers
class APIError(StandardError):
def __init__(self, msg, response=None):
StandardError.__init__(self, msg)
class TumblrAPIv2:
def __init__(self, consumer_key, consumer_secret, oauth_token, oauth_token_secret):
self.consumer = oauth2.Consumer(consumer_key, consumer_secret)
self.token = oauth2.Token(oauth_token, oauth_token_secret)
self.url = "http://api.tumblr.com"
def parse_response(self, result):
content = json.loads(result)
if 400 <= int(content["meta"]["status"]) <= 600:
raise APIError(content["meta"]["msg"], result)
return content["response"]
def createPhotoPost(self, id, post):
url = self.url + "/v2/blog/%s/post" %id
img_file = post['data']
del(post['data'])
req = oauth2.Request.from_consumer_and_token(self.consumer,
token=self.token,
http_method="POST",
http_url=url,
parameters=post)
req.sign_request(oauth2.SignatureMethod_HMAC_SHA1(), self.consumer, self.token)
compiled_postdata = req.to_postdata()
all_upload_params = urlparse.parse_qs(compiled_postdata, keep_blank_values=True)
for key, val in all_upload_params.iteritems():
all_upload_params[key] = val[0]
all_upload_params['data'] = open(img_file, 'rb')
datagen, headers = multipart_encode(all_upload_params)
request = urllib2.Request(url, datagen, headers)
try:
respdata = urllib2.urlopen(request).read()
except urllib2.HTTPError, ex:
return 'Received error code: ', ex.code
return self.parse_response(respdata)
register_openers()
CONSUMER_KEY = ''
CONSUMER_SECRET = ''
OAUTH_TOKEN = ''
OAUTH_TOKEN_SECRET = ''
DIR = 'dir/with/pictures'
FILE_MASK = '*.jpg'
BLOG = 'blog here'
api = TumblrAPIv2(CONSUMER_KEY, CONSUMER_SECRET, OAUTH_TOKEN, OAUTH_TOKEN_SECRET)
for img in glob.glob( os.path.join(DIR, FILE_MASK) ):
date = time.gmtime(os.path.getmtime(img))
post = {
'type' : 'photo',
'date' : time.strftime ("%Y-%m-%d %H:%M:%S", date),
'data' : img,
'tags' : time.strftime ("%Y", date) + ", photo",
'caption' : time.strftime ("%B %d / %Y", date)
}
try:
response = api.createPhotoPost(BLOG,post)
if 'id' in response:
print response['id']
os.remove(img)
else:
print response
break
except APIError:
print "Error"
break
print "Done!"
@westondeboer
Copy link

awesome! Thanks for this. Took my newb mind a couple of hours to figure it out.

  1. python auth.py
  2. go to url
  3. allow in tumblr
  4. y (yes authenticated)
  5. copy url you are returned to: ex google.com/?oauth_token=927839871293871928hikjb copy this long key
  6. PIN = number copied from step 5
  7. you get your oath token and secret

now fill it all up in photo2tumblr.py and your goodie good to go

@josenaves
Copy link

I've had the same problems as you (404). It's fully functional now !

The problems is with BLOG variable.

It's just the blog host name not the URL !

WRONG: http://josenaves.tumblr.com/
RIGHT: josenaves.tumblr.com

@gosharplite
Copy link

Here's my 2 cents. (Ubuntu)

  1. Register application with tumblr. Get Consumer Key and Secret Key. http://www.tumblr.com/oauth/apps
  2. Edit consumer_key and consumer_secret in auth.py
  3. Install python, python-oauth2, python-poster
  4. python auth.py
  5. go to url
  6. 'allow' in tumblr web page
  7. y (yes authenticated)
  8. copy url you are returned to: ex google.com/?oauth_token=927839871293871928hikjb copy this long key (as PIN)
  9. PIN = number copied from step 8
  10. Edit photo2tumblr.py
    CONSUMER_KEY = ''
    CONSUMER_SECRET = ''
    OAUTH_TOKEN = ''
    OAUTH_TOKEN_SECRET = ''
    DIR = 'dir/with/pictures'
    FILE_MASK = '*.jpg'
    BLOG = 'blog here'
  11. Careful about BLOG
    WRONG: http://josenaves.tumblr.com/
    RIGHT: josenaves.tumblr.com
  12. python photo2tumblr.py

@cosmicpudding
Copy link

Thanks for this great script! Following gosharplite's steps, I got it working for single images. But how do you extend it so it posts multiple images in a single post? I've tried a few things which haven't worked :p

@windmillium
Copy link

Step number 8 above should use the oauth_verifier param not the oauth_token, other than that it works.

@soenkesmiletzki
Copy link

I have some problem with this script.
i copied two pictures to a folder and starting script:

python photo2tumblr.py
106408893386
106408894521
Done!

So, both pictures are deleted at the picturefolder, but there is no posting at my tumblr blog.
Any idea?

@charlesbrandt
Copy link

Here's what I did to make this work for photosets (multiple photos for one post):
https://gist.github.com/charlesbrandt/11eadaec114288d621fa

@phrohdoh
Copy link

What is 'PIN' supposed to be?

$ python auth.py
Request Token:
    - oauth_token        = HNeepB644EtQcUTWGsSlhYZgQ0Z8Hg8kkI0XNqDR4x8Qyjl0Qa
    - oauth_token_secret = <secret key>

Go to the following link in your browser:
http://www.tumblr.com/oauth/authorize?oauth_token=HNeepB644EtQcUTWGsSlhYZgQ0Z8Hg8kkI0XNqDR4x8Qyjl0Qa

Have you authorized me? (y/n) y
What is the PIN?

My callback URL is just tumblr.com as I don't have a site for a test like this.

@j-gao
Copy link

j-gao commented Sep 27, 2016

Worked like a charm!! Thanks velocityzen!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment