Skip to content

Instantly share code, notes, and snippets.

@charlesbrandt
Created July 19, 2015 12:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save charlesbrandt/11eadaec114288d621fa to your computer and use it in GitHub Desktop.
Save charlesbrandt/11eadaec114288d621fa to your computer and use it in GitHub Desktop.
Take pictures from directory and post them to a tumblr blog as a photoset (single post). This was adapted from: https://gist.github.com/velocityzen/1242662 Multiple photos in a photoset was adapted from: https://gist.github.com/derekg/1198576
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
"""
*2015.07.18 19:22:19
adapting from:
https://gist.github.com/velocityzen/1242662
and
https://gist.github.com/derekg/1198576
Instructions, courtesy of gosharplite:
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
"""
import glob
import json
import os
import time
import urllib2
import urlparse
import oauth2
from poster.encode import multipart_encode, MultipartParam
from poster.streaminghttp import register_openers
from datetime import datetime
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
imgs = 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]
for ct, img in enumerate(imgs):
print "CT:", ct
print "img:", img
#this is the trick to making all photos part of a photoset,
#rather than separate posts:
all_upload_params['data[%d]' % ct] = open(img, 'rb')
datagen, headers = multipart_encode(all_upload_params)
#print url
#print datagen
#print headers
request = urllib2.Request(url, datagen, headers)
try:
respdata = urllib2.urlopen(request).read()
except urllib2.HTTPError, ex:
print 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)
imgs = []
for img in glob.glob( os.path.join(DIR, FILE_MASK) ):
print img
imgs.append(img)
#this gives an array... use commented items in this case
#date = time.gmtime(os.path.getmtime(img))
date = datetime.now()
print date
print imgs
post = {
'type' : 'photo',
#'date' : time.strftime ("%Y-%m-%d %H:%M:%S", date),
'date' : date.strftime ("%Y-%m-%d %H:%M:%S"),
'data' : imgs,
#'tags' : time.strftime ("%Y", date) + ", photo",
'tags' : date.strftime ("%Y") + ", photo",
#'caption' : time.strftime ("%B %d / %Y", date)
'caption' : date.strftime ("%B %d / %Y")
}
try:
response = api.createPhotoPost(BLOG,post)
if 'id' in response:
print response['id']
#os.remove(img)
else:
print response
except APIError:
print "Error"
print "Done!"
@wlerin
Copy link

wlerin commented Jan 20, 2016

Thanks for this! I managed to adapt it to Requests (and Python 3):
https://gist.github.com/wlerin/70f55d0f62cdfedb0a74 and finally got it working.

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