/* Copyright (c) 2011 Niall Sheridan
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.asplode.tumblr;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import oauth.signpost.OAuthConsumer;
import oauth.signpost.OAuthProvider;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import oauth.signpost.commonshttp.CommonsHttpOAuthProvider;
import oauth.signpost.exception.OAuthCommunicationException;
import oauth.signpost.exception.OAuthExpectationFailedException;
import oauth.signpost.exception.OAuthMessageSignerException;
import oauth.signpost.exception.OAuthNotAuthorizedException;
import oauth.signpost.signature.HmacSha1MessageSigner;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.json.JSONException;
import org.json.JSONObject;
/**
* @author nsheridan
*
*/
public class Tumblr {
private final String BASE_URL = "http://api.tumblr.com/v2";
private final String REQUEST_URL = "http://www.tumblr.com/oauth/request_token";
private final String ACCESS_URL = "http://www.tumblr.com/oauth/access_token";
private final String AUTH_URL = "http://www.tumblr.com/oauth/authorize";
private String oauth_callback;
private String email;
private String password;
private String blog;
private ArrayList<BasicNameValuePair> params;
private String oauth_key;
private OAuthConsumer consumer;
private OAuthProvider provider;
HttpClient client;
/**
* @param oauth_key
* OAuth key.
* @param oauth_secret
* OAuth secret key.
*/
public Tumblr(String oauth_key, String oauth_secret, String callback_url) {
this.params = new ArrayList<BasicNameValuePair>();
this.oauth_key = oauth_key;
consumer = new CommonsHttpOAuthConsumer(oauth_key, oauth_secret);
consumer.setMessageSigner(new HmacSha1MessageSigner());
provider = new CommonsHttpOAuthProvider(REQUEST_URL, ACCESS_URL, AUTH_URL);
client = new DefaultHttpClient();
oauth_callback = callback_url;
}
private static String convertToString(InputStream in) throws IOException {
StringBuffer out = new StringBuffer();
byte[] b = new byte[4096];
for (int n; (n = in.read(b)) != -1;) {
out.append(new String(b, 0, n));
}
return out.toString();
}
public String getAuthURL() throws OAuthMessageSignerException,
OAuthNotAuthorizedException, OAuthExpectationFailedException,
OAuthCommunicationException {
return provider.retrieveRequestToken(consumer, oauth_callback);
}
public void setOAuthTokens(String token, String secret) {
consumer.setTokenWithSecret(token, secret);
}
private String[] getOAuthTokens() throws OAuthMessageSignerException,
OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException,
IOException {
/* basically, if we're getting here and these things are set we should have already set this information.
if not, well then kaboom!!! don't mess up sammy! */
if(oauth_callback != null && !oauth_callback.isEmpty()) {
String[] result = new String[2];
result[0] = consumer.getToken();
result[1] = consumer.getTokenSecret();
return result;
}
ArrayList<BasicNameValuePair> xauth_params = new ArrayList<BasicNameValuePair>();
xauth_params.add(new BasicNameValuePair("x_auth_mode", "client_auth"));
xauth_params.add(new BasicNameValuePair("x_auth_username", email));
xauth_params.add(new BasicNameValuePair("x_auth_password", password));
HttpPost post = new HttpPost("https://www.tumblr.com/oauth/access_token");
try {
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(xauth_params);
post.setEntity(entity);
consumer.sign(post);
HttpResponse response = client.execute(post);
String s = convertToString(response.getEntity().getContent());
String[] tokens = s.split("&");
String[] result = new String[2];
result[0] = tokens[0].split("=")[1];
result[1] = tokens[1].split("=")[1];
return result;
} catch (UnsupportedEncodingException e) {
}
return null;
}
private JSONObject APIKeyGet(String url) throws ClientProtocolException, IOException,
IllegalStateException, JSONException {
HttpGet req = new HttpGet(url);
HttpResponse response = client.execute(req);
JSONObject result = new JSONObject(convertToString(response.getEntity().getContent()));
return result;
}
private JSONObject OAuthGet(String url) throws OAuthMessageSignerException,
OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException,
IOException, IllegalStateException, JSONException {
String[] oauth_tokens = getOAuthTokens();
consumer.setTokenWithSecret(oauth_tokens[0], oauth_tokens[1]);
HttpGet req = new HttpGet(url);
consumer.sign(req);
HttpResponse response = client.execute(req);
JSONObject result = new JSONObject(convertToString(response.getEntity().getContent()));
return result;
}
private JSONObject OAuthPost(String url) throws OAuthMessageSignerException,
OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException,
IOException, IllegalStateException, JSONException {
String[] oauth_tokens = getOAuthTokens();
consumer.setTokenWithSecret(oauth_tokens[0], oauth_tokens[1]);
HttpPost req = new HttpPost(url);
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "UTF-8");
req.setEntity(entity);
consumer.sign(req);
HttpResponse response = client.execute(req);
JSONObject result = new JSONObject(convertToString(response.getEntity().getContent()));
params.clear();
return result;
}
private JSONObject Get(String url) throws ClientProtocolException, IOException,
IllegalStateException, JSONException {
HttpGet req = new HttpGet(url);
HttpParams params = new BasicHttpParams();
params.setParameter("http.protocol.handle-redirects", false);
req.setParams(params);
HttpResponse response = client.execute(req);
JSONObject result = new JSONObject(convertToString(response.getEntity().getContent()));
return result;
}
@SuppressWarnings("unused")
private JSONObject Post(String url) throws ClientProtocolException, IOException,
IllegalStateException, JSONException {
HttpPost req = new HttpPost(url);
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "UTF-8");
req.setEntity(entity);
HttpResponse response = client.execute(req);
JSONObject result = new JSONObject(convertToString(response.getEntity().getContent()));
params.clear();
return result;
}
/**
* @param email
* Email address
* @param password
* Password
*/
public void setCredentials(String email, String password) {
this.email = email;
this.password = password;
}
/**
* @param blog
* Blog url e.g. "myblog.tumblr.com", "tumblr.mydomain.com"
*/
public void setBlog(String blog) {
this.blog = blog;
}
/**
* @return Blog info
* @throws NoBlogException
* @throws ClientProtocolException
* @throws IOException
* @throws IllegalStateException
* @throws JSONException
*/
public JSONObject getBlogInfo() throws NoBlogException, ClientProtocolException, IOException,
IllegalStateException, JSONException {
if (blog == null) {
throw new NoBlogException();
}
String url = BASE_URL + "/blog/" + blog + "/info" + "?api_key=" + oauth_key;
JSONObject result = APIKeyGet(url);
return result;
}
/**
* @return Blog avatar, 64x64
* @throws NoBlogException
* @throws ClientProtocolException
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
public JSONObject getAvatar() throws NoBlogException, ClientProtocolException,
IllegalStateException, IOException, JSONException {
if (blog == null) {
throw new NoBlogException();
}
String url = BASE_URL + "/blog/" + blog + "/avatar";
JSONObject result = Get(url);
return result;
}
/**
* @param size
* Size of avatar. 16, 24, 30, 40, 48, 64, 96, 128, 512.
* @return Avatar of requested size.
* @throws NoBlogException
* @throws ClientProtocolException
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
public JSONObject getAvatar(int size) throws NoBlogException, ClientProtocolException,
IllegalStateException, IOException, JSONException {
if (blog == null) {
throw new NoBlogException();
}
String url = BASE_URL + "/blog/" + blog + "/avatar/" + size;
JSONObject result = Get(url);
return result;
}
/**
* @return Followers
* @throws NoBlogException
* @throws OAuthMessageSignerException
* @throws OAuthExpectationFailedException
* @throws OAuthCommunicationException
* @throws ClientProtocolException
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
public JSONObject getFollowers() throws NoBlogException, OAuthMessageSignerException,
OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException,
IllegalStateException, IOException, JSONException {
if (blog == null) {
throw new NoBlogException();
}
String url = BASE_URL + "/blog/" + blog + "/followers";
JSONObject result = OAuthGet(url);
return result;
}
/**
* @param notes
* Include note count and note metadata
* @return Posts
* @throws NoBlogException
* @throws ClientProtocolException
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
public JSONObject getPosts(boolean notes) throws NoBlogException, ClientProtocolException,
IllegalStateException, IOException, JSONException {
if (blog == null) {
throw new NoBlogException();
}
String url = BASE_URL + "/blog/" + blog + "/posts?api_key=" + oauth_key;
if (notes) {
url += "¬es_info";
}
JSONObject result = APIKeyGet(url);
return result;
}
/**
* @param notes
* Include note count and note metadata
* @param offset
* Post number to start at
* @return Posts
* @throws NoBlogException
* @throws ClientProtocolException
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
public JSONObject getPosts(boolean notes, int offset) throws NoBlogException,
ClientProtocolException, IllegalStateException, IOException, JSONException {
if (blog == null) {
throw new NoBlogException();
}
String url = BASE_URL + "/blog/" + blog + "/posts?api_key=" + oauth_key + "&offset="
+ offset;
if (notes) {
url += "¬es_info";
}
JSONObject result = APIKeyGet(url);
return result;
}
/**
* @param postid
* Post ID
* @param notes
* Include note count and note metadata
* @return Specific post
* @throws NoBlogException
* @throws ClientProtocolException
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
public JSONObject getPost(String postid, boolean notes) throws NoBlogException,
ClientProtocolException, IllegalStateException, IOException, JSONException {
if (blog == null) {
throw new NoBlogException();
}
String url = BASE_URL + "/blog/" + blog + "/posts?api_key=" + oauth_key + "&id=" + postid;
if (notes) {
url += "¬es_info";
}
JSONObject result = APIKeyGet(url);
return result;
}
/**
* @return Posts in the queue
* @throws NoBlogException
* @throws OAuthMessageSignerException
* @throws OAuthExpectationFailedException
* @throws OAuthCommunicationException
* @throws ClientProtocolException
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
public JSONObject getQueue() throws NoBlogException, OAuthMessageSignerException,
OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException,
IllegalStateException, IOException, JSONException {
if (blog == null) {
throw new NoBlogException();
}
String url = BASE_URL + "/blog/" + blog + "/posts/queue";
JSONObject result = OAuthGet(url);
return result;
}
/**
* @return Draft posts
* @throws NoBlogException
* @throws OAuthMessageSignerException
* @throws OAuthExpectationFailedException
* @throws OAuthCommunicationException
* @throws ClientProtocolException
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
public JSONObject getDrafts() throws NoBlogException, OAuthMessageSignerException,
OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException,
IllegalStateException, IOException, JSONException {
if (blog == null) {
throw new NoBlogException();
}
String url = BASE_URL + "/blog/" + blog + "/posts/draft";
JSONObject result = OAuthGet(url);
return result;
}
/**
* @param id
* Post ID to reblog
* @param key
* Reblog key of the post to be reblogged
* @param comment
* Comment to include with the reblog
* @return Status of the request
* @throws NoBlogException
* @throws OAuthMessageSignerException
* @throws OAuthExpectationFailedException
* @throws OAuthCommunicationException
* @throws ClientProtocolException
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
public JSONObject reblogPost(String id, String key, String comment) throws NoBlogException,
OAuthMessageSignerException, OAuthExpectationFailedException,
OAuthCommunicationException, ClientProtocolException, IllegalStateException,
IOException, JSONException {
if (blog == null) {
throw new NoBlogException();
}
params.add(new BasicNameValuePair("id", id));
params.add(new BasicNameValuePair("reblog_key", key));
params.add(new BasicNameValuePair("comment", comment));
String url = BASE_URL + "/blog/" + blog + "/post/reblog";
JSONObject result = OAuthPost(url);
return result;
}
/**
* @param id
* Post ID to delete.
* @return Status of the request
* @throws NoBlogException
* @throws OAuthMessageSignerException
* @throws OAuthExpectationFailedException
* @throws OAuthCommunicationException
* @throws ClientProtocolException
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
public JSONObject deletePost(String id) throws NoBlogException, OAuthMessageSignerException,
OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException,
IllegalStateException, IOException, JSONException {
if (blog == null) {
throw new NoBlogException();
}
params.add(new BasicNameValuePair("id", id));
String url = BASE_URL + "/blog/" + blog + "/post/delete";
JSONObject result = OAuthPost(url);
return result;
}
/**
* @return User info
* @throws OAuthMessageSignerException
* @throws OAuthExpectationFailedException
* @throws OAuthCommunicationException
* @throws ClientProtocolException
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
public JSONObject getUserInfo() throws OAuthMessageSignerException,
OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException,
IllegalStateException, IOException, JSONException {
String url = BASE_URL + "/user/info";
JSONObject result = OAuthPost(url);
return result;
}
/**
* @param notes
* Include note count and note metadata
* @return Dashboard
* @throws OAuthMessageSignerException
* @throws OAuthExpectationFailedException
* @throws OAuthCommunicationException
* @throws ClientProtocolException
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
public JSONObject getDashboard(boolean notes) throws OAuthMessageSignerException,
OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException,
IllegalStateException, IOException, JSONException {
String url = BASE_URL + "/user/dashboard";
if (notes) {
url += "?notes_info";
}
JSONObject result = OAuthGet(url);
return result;
}
/**
* @param notes
* Include note count and note metadata
* @param offset
* Post number to start at.
* @return Dashboard
* @throws OAuthMessageSignerException
* @throws OAuthExpectationFailedException
* @throws OAuthCommunicationException
* @throws ClientProtocolException
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
public JSONObject getDashboard(boolean notes, int offset) throws OAuthMessageSignerException,
OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException,
IllegalStateException, IOException, JSONException {
String url = BASE_URL + "/user/dashboard?offset=" + offset;
if (notes) {
url += "¬es_info";
}
JSONObject result = OAuthGet(url);
return result;
}
/**
* @return Liked posts
* @throws OAuthMessageSignerException
* @throws OAuthExpectationFailedException
* @throws OAuthCommunicationException
* @throws ClientProtocolException
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
public JSONObject getLikes() throws OAuthMessageSignerException,
OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException,
IllegalStateException, IOException, JSONException {
String url = BASE_URL + "/user/likes";
JSONObject result = OAuthGet(url);
return result;
}
/**
* @param offset
* Post number to start at
* @return Liked posts
* @throws OAuthMessageSignerException
* @throws OAuthExpectationFailedException
* @throws OAuthCommunicationException
* @throws ClientProtocolException
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
public JSONObject getLikes(int offset) throws OAuthMessageSignerException,
OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException,
IllegalStateException, IOException, JSONException {
String url = BASE_URL + "/user/likes?offset=" + offset;
JSONObject result = OAuthGet(url);
return result;
}
/**
* @return Blogs the user is following
* @throws OAuthMessageSignerException
* @throws OAuthExpectationFailedException
* @throws OAuthCommunicationException
* @throws ClientProtocolException
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
public JSONObject getFollowing() throws OAuthMessageSignerException,
OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException,
IllegalStateException, IOException, JSONException {
String url = BASE_URL + "/user/following";
JSONObject result = OAuthGet(url);
return result;
}
/**
* @param offset
* Post number to start at
* @return Blogs the user is following
* @throws OAuthMessageSignerException
* @throws OAuthExpectationFailedException
* @throws OAuthCommunicationException
* @throws ClientProtocolException
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
public JSONObject getFollowing(int offset) throws OAuthMessageSignerException,
OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException,
IllegalStateException, IOException, JSONException {
String url = BASE_URL + "/user/following?offset=" + offset;
JSONObject result = OAuthGet(url);
return result;
}
/**
* @param blogURL
* URL of the blog to follow
* @return Status of the request
* @throws OAuthMessageSignerException
* @throws OAuthExpectationFailedException
* @throws OAuthCommunicationException
* @throws ClientProtocolException
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
public JSONObject follow(String blogURL) throws OAuthMessageSignerException,
OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException,
IllegalStateException, IOException, JSONException {
String url = BASE_URL + "/user/follow";
params.add(new BasicNameValuePair("url", blogURL));
JSONObject result = OAuthPost(url);
return result;
}
/**
* @param blogURL
* URL of the blog to unfollow
* @return Status of the request
* @throws OAuthMessageSignerException
* @throws OAuthExpectationFailedException
* @throws OAuthCommunicationException
* @throws ClientProtocolException
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
public JSONObject unfollow(String blogURL) throws OAuthMessageSignerException,
OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException,
IllegalStateException, IOException, JSONException {
String url = BASE_URL + "/user/unfollow";
params.add(new BasicNameValuePair("url", blogURL));
JSONObject result = OAuthPost(url);
return result;
}
/**
* @param id
* Post ID
* @param reblog_key
* Post reblog key
* @return Status of the request
* @throws OAuthMessageSignerException
* @throws OAuthExpectationFailedException
* @throws OAuthCommunicationException
* @throws ClientProtocolException
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
public JSONObject likePost(String id, String reblog_key) throws OAuthMessageSignerException,
OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException,
IllegalStateException, IOException, JSONException {
String url = BASE_URL + "/user/like";
params.add(new BasicNameValuePair("id", id));
params.add(new BasicNameValuePair("reblog_key", reblog_key));
JSONObject result = OAuthPost(url);
return result;
}
/**
* @param id
* Post ID
* @param reblog_key
* Post reblog key
* @return Status of the request
* @throws OAuthMessageSignerException
* @throws OAuthExpectationFailedException
* @throws OAuthCommunicationException
* @throws ClientProtocolException
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
public JSONObject unlikePost(String id, String reblog_key) throws OAuthMessageSignerException,
OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException,
IllegalStateException, IOException, JSONException {
String url = BASE_URL + "/user/unlike";
params.add(new BasicNameValuePair("id", id));
params.add(new BasicNameValuePair("reblog_key", reblog_key));
JSONObject result = OAuthPost(url);
return result;
}
}