package com.megagoodsoftware.smugmug;
import java.io.*;
import java.net.*;
import java.util.*;
import org.apache.http.*;
import org.apache.http.client.*;
import org.apache.http.client.methods.*;
import org.apache.http.entity.*;
import org.apache.http.impl.client.*;
import org.apache.http.message.*;
import org.json.*;
import android.util.*;
import com.megagoodsoftware.smugmug.CountingHttpEntity.*;
import com.megagoodsoftware.smugmug.exceptions.*;
public class SmugMugClient {
private final static String API_KEY = "ggmky75M7OFLskaXu6S6wu1SD6degX1Q";
public final static String API_VERSION = "1.2.2";
public static final String METHOD_CATEGORIES_GET = "smugmug.categories.get";
public static final String METHOD_LOGOUT = "smugmug.logout";
public static final String METHOD_IMAGES_GET = "smugmug.images.get";
public static final String METHOD_IMAGES_UPLOAD = "smugmug.images.upload";
public static final String METHOD_ALBUMS_GET = "smugmug.albums.get";
public static final String METHOD_LOGIN_WITH_HASH = "smugmug.login.withHash";
public static final String METHOD_LOGIN_WITH_PASSWORD = "smugmug.login.withPassword";
private final static String SMUGMUG_URL = "https://secure.smugmug.com/services/api/json/" + API_VERSION;
private HttpClient client;
private HttpPut uploadHttpPut;
public SmugMugClient() {
client = new DefaultHttpClient();
}
public void setClient(HttpClient client) {
this.client = client;
}
protected HttpClient getClient() {
return this.client;
}
private static String buildMethodUrl(String method) {
return SMUGMUG_URL + "/?method=" + method + "&APIKey=" + API_KEY;
}
private static String buildMethodUrl(String method, String session) {
return buildMethodUrl(method) + "&SessionId=" + session;
}
protected static void setUserAgent(AbstractHttpMessage message) {
message.setHeader("User-Agent", Constants.USER_AGENT);
}
public static String convertStreamToString(InputStream is) {
/*
* To convert the InputStream to String we use the BufferedReader.readLine()
* method. We iterate until the BufferedReader return null which means
* there's no more data to read. Each line will appended to a StringBuilder
* and returned as String.
*/
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
Log.e(Constants.TAG, "IOException while parsing stream", e);
} finally {
try {
is.close();
} catch (IOException e) {
Log.e(Constants.TAG, "IOException while closing stream", e);
}
}
return sb.toString();
}
private static void checkStatusOk(JSONObject json) throws JSONException, SmugMugFailedResponse {
if ("ok".equals(json.getString("stat")))
return;
throw SmugMugFailedResponseFactory.createSmugMugFailedResponse(json
.getInt("code"), json.getString("message"));
}
private void setAccountFromJSON(JSONObject json, SmugMugAccount acct) throws JSONException {
JSONObject jsonLogin = json.getJSONObject("Login");
acct.setSession(jsonLogin.getJSONObject("Session").getString("id"));
acct.setType(jsonLogin.getString("AccountType"));
acct.setFilesizeLimit(jsonLogin.getInt("FileSizeLimit"));
acct.setNickName(jsonLogin.getJSONObject("User").getString("NickName"));
acct.setDisplayName(jsonLogin.getJSONObject("User").getString(
"DisplayName"));
}
public SmugMugAccount login(int userId, String hashPassword) throws SmugMugInternalError, SmugMugBadAuthentication
{
JSONObject json;
try {
json = connect(buildMethodUrl(METHOD_LOGIN_WITH_HASH) + "&PasswordHash=" + hashPassword + "&UserID=" + userId);
SmugMugAccount acct = new SmugMugAccount();
acct.setUserId(userId);
acct.setPassword(hashPassword);
setAccountFromJSON(json, acct);
return acct;
} catch (JSONException e) {
throw new SmugMugInternalError("Unable to parse JSON string");
} catch (SmugMugBadAuthentication e) {
Log.w(Constants.TAG, "Invalid Login", e);
throw e;
} catch (SmugMugInternalError e) {
Log.w(Constants.TAG, "Couldn't Connect", e);
throw e;
} catch (Exception e) {
Log.e(Constants.TAG, "uncaught exception: " + e.getLocalizedMessage(), e);
throw new SmugMugInternalError("uncaught exception");
}
}
public HashMap<String, SmugMugAlbum> getAllAlbums(String session) throws SmugMugInternalError, SmugMugFailedResponse {
HashMap<String, SmugMugAlbum> albums = new HashMap<String, SmugMugAlbum>();
JSONObject json = connect(buildMethodUrl(METHOD_ALBUMS_GET, session));
JSONArray jsonArray;
try {
jsonArray = json.getJSONArray("Albums");
for (int index = 0; index < jsonArray.length(); index++)
{
JSONObject jsonAlbum = jsonArray.getJSONObject(index);
int albumId = jsonAlbum.getInt("id");
String albumKey = jsonAlbum.getString("Key");
String albumName = jsonAlbum.getString("Title");
JSONObject jsonCategory= jsonAlbum.getJSONObject("Category");
SmugMugAlbum album = new SmugMugAlbum(albumId, albumKey, albumName);
album.setCategory(jsonCategory.getString("Name"));
albums.put(Integer.toString(albumId), album);
}
} catch (JSONException e) {
Log.e(Constants.TAG, "unable to parse JSON object", e);
throw new SmugMugInternalError("unable to parse JSON");
}
return albums;
}
private String connectString(String url) throws ClientProtocolException, IOException
{
String result = null;
Log.d(Constants.TAG, url);
// Prepare a request object
HttpGet get = new HttpGet(url);
setUserAgent(get);
// Execute the request
HttpResponse response = client.execute(get);
// Examine the response status
Log.d(Constants.TAG, response.getStatusLine().toString());
// Get hold of the response entity
HttpEntity entity = response.getEntity();
// If the response does not enclose an entity, there is no need
// to worry about connection release
if (entity != null) {
InputStream instream = null;
try {
instream = entity.getContent();
result = convertStreamToString(instream);
Log.d(Constants.TAG, result);
} finally {
// Closing the input stream will trigger connection release
try {
instream.close();
} catch (Exception e) {
Log.e(Constants.TAG, "unable to close stream", e);
}
}
}
return result;
}
protected JSONObject connect(String url) throws SmugMugInternalError, SmugMugFailedResponse
{
try {
JSONObject json = new JSONObject(connectString(url));
checkStatusOk(json);
return json;
} catch (JSONException e) {
Log.e(Constants.TAG, "Error while parsing JSON", e);
throw new SmugMugInternalError(e.getLocalizedMessage());
} catch (ClientProtocolException e) {
Log.e(Constants.TAG, "Invalid protocol", e);
throw new SmugMugInternalError(e.getLocalizedMessage());
} catch (IOException e) {
Log.e(Constants.TAG, "IOException occured", e);
throw new SmugMugInternalError(e.getLocalizedMessage());
}
}
public SmugMugImage upload(ProgressListener listener, InputStream istream, String md5, String sessionId, SmugMugAlbum album, String name) throws SmugMugConnectionError, SmugMugFailedResponse, SmugMugInternalError {
try {
uploadHttpPut = new HttpPut("http://upload.smugmug.com/" + URLEncoder.encode(name) + "?method=smugmug.images.upload");
setUserAgent(uploadHttpPut);
uploadHttpPut.setHeader("Content-MD5", md5);
uploadHttpPut.setHeader("X-Smug-SessionID", sessionId);
uploadHttpPut.setHeader("X-Smug-Version", API_VERSION);
uploadHttpPut.setHeader("X-Smug-ResponseType", "JSON");
uploadHttpPut.setHeader("X-Smug-AlbumID", Integer.toString(album.getId()));
uploadHttpPut.setHeader("X-Smug-FileName", name);
AbstractHttpEntity entity = new InputStreamEntity(istream, istream.available());
if (listener == null)
uploadHttpPut.setEntity(entity);
else
uploadHttpPut.setEntity(new CountingHttpEntity(entity, listener));
HttpResponse response = client.execute(uploadHttpPut);
Log.i(Constants.TAG, "Upload response status: " + response.getStatusLine().getReasonPhrase());
String result = convertStreamToString(response.getEntity().getContent());
Log.d(Constants.TAG, result);
JSONObject j = new JSONObject(result);
checkStatusOk(j);
return new SmugMugImage(j.getJSONObject("Image").getInt("id"), j.getJSONObject("Image").getString("Key"), name);
} catch (IOException e) {
Log.e(Constants.TAG, "IOException occured", e);
throw new SmugMugConnectionError();
} catch (JSONException e) {
Log.e(Constants.TAG, "error while parsing JSON object", e);
throw new SmugMugInternalError("error while parsing JSON object");
}
}
protected HttpPut getHttpPut() {
return uploadHttpPut;
}
public boolean logout(String sessionId) {
try {
connect(buildMethodUrl(METHOD_LOGOUT, sessionId));
return true;
} catch (SmugMugInternalError e) {
Log.e(Constants.TAG, "Error occured while logging out", e);
} catch (SmugMugInvalidSession e) {
Log.i(Constants.TAG, "invalid session during logout (session expired?)");
} catch (SmugMugFailedResponse e) {
Log.e(Constants.TAG, "Bad response while logging out: " + e.getLocalizedMessage(), e);
}
return false;
}
public HashMap<String, SmugMugCategory> getAllCategories(String sessionId) throws SmugMugFailedResponse, SmugMugInternalError {
try {
JSONObject json = connect(buildMethodUrl(METHOD_CATEGORIES_GET,
sessionId));
JSONArray jsonArray = json.getJSONArray("Categories");
HashMap<String, SmugMugCategory> categories = new HashMap<String, SmugMugCategory>();
for (int index = 0; index < jsonArray.length(); index++) {
JSONObject jsonCat = jsonArray.getJSONObject(index);
int catId = jsonCat.getInt("id");
String catName = jsonCat.getString("Name");
SmugMugCategory category = new SmugMugCategory(catId, catName);
categories.put(Integer.toString(catId), category);
}
return categories;
} catch (SmugMugFailedResponse e) {
Log.w(Constants.TAG, "failed response received: "
+ e.getLocalizedMessage());
throw e;
} catch (JSONException e) {
Log.e(Constants.TAG, "unable to parse JSON object", e);
throw new SmugMugInternalError("unable to parse JSON");
} catch (Exception e) {
Log.e(Constants.TAG, "uncaught exception: "
+ e.getLocalizedMessage(), e);
throw new SmugMugInternalError("uncaught exception");
}
}
public SmugMugAccount login(String email, String password) throws SmugMugInternalError, SmugMugBadAuthentication {
JSONObject json;
try {
json = connect(buildMethodUrl(METHOD_LOGIN_WITH_PASSWORD) + "&EmailAddress=" + email + "&Password=" + password);
SmugMugAccount acct = new SmugMugAccount();
JSONObject jsonLogin = json.getJSONObject("Login");
acct.setUserId(jsonLogin.getJSONObject("User").getInt("id"));
acct.setPassword(jsonLogin.getString("PasswordHash"));
setAccountFromJSON(json, acct);
return acct;
} catch (JSONException e) {
throw new SmugMugInternalError("Unable to parse JSON string");
} catch (SmugMugBadAuthentication e) {
Log.w(Constants.TAG, "Invalid Login", e);
throw e;
} catch (SmugMugFailedResponse e) {
String msg = "Failed Response, code: " + e.getCode() + " message: " + e.getMessage();
Log.e(Constants.TAG, msg);
throw new SmugMugInternalError(msg);
} catch (Exception e) {
Log.e(Constants.TAG, "uncaught exception", e);
throw new SmugMugInternalError("uncaught exception");
}
}
public void updateImages(String sessionId, SmugMugAlbum album) throws SmugMugFailedResponse, SmugMugInternalError {
updateImages_new(sessionId, album);
}
public void updateImages_new(String sessionId, SmugMugAlbum album) throws SmugMugFailedResponse, SmugMugInternalError {
try {
JSONObject json = connect(buildMethodUrl(METHOD_IMAGES_GET,
sessionId) + "&AlbumID=" + album.getId() + "&AlbumKey=" + album.getKey() + "&Heavy=true");
JSONObject jsonAlbum = json.getJSONObject("Album");
JSONArray jsonArray = jsonAlbum.getJSONArray("Images");
album.clearImages();
for (int index = 0; index < jsonArray.length(); index++) {
JSONObject jsonImage = jsonArray.getJSONObject(index);
int id = jsonImage.getInt("id");
String key = jsonImage.getString("Key");
String name = jsonImage.getString("FileName");
SmugMugImage image = new SmugMugImage(id, key, name);
image.setCaption(jsonImage.getString("Caption"));
image.setTinyUrl(jsonImage.getString("TinyURL"));
image.setThumbUrl(jsonImage.getString("ThumbURL"));
image.setSmallUrl(jsonImage.getString("SmallURL"));
image.setMediumUrl(jsonImage.getString("MediumURL"));
album.addImage(image);
}
} catch (SmugMugFailedResponse e) {
Log.w(Constants.TAG, "failed response received: "
+ e.getLocalizedMessage());
throw e;
} catch (JSONException e) {
Log.e(Constants.TAG, "unable to parse JSON object", e);
throw new SmugMugInternalError("unable to parse JSON");
} catch (Exception e) {
Log.e(Constants.TAG, "uncaught exception: "
+ e.getLocalizedMessage(), e);
throw new SmugMugInternalError("uncaught exception");
}
}
public void updateImages_old(String sessionId, SmugMugAlbum album) throws SmugMugFailedResponse, SmugMugInternalError {
try {
JSONObject json = connect(buildMethodUrl(METHOD_IMAGES_GET,
sessionId) + "&AlbumID=" + album.getId() + "&AlbumKey=" + album.getKey() + "&Heavy=true");
JSONArray jsonArray = json.getJSONArray("Images");
album.clearImages();
for (int index = 0; index < jsonArray.length(); index++) {
JSONObject jsonImage = jsonArray.getJSONObject(index);
int id = jsonImage.getInt("id");
String key = jsonImage.getString("Key");
String name = jsonImage.getString("FileName");
SmugMugImage image = new SmugMugImage(id, key, name);
image.setCaption(jsonImage.getString("Caption"));
image.setTinyUrl(jsonImage.getString("TinyURL"));
image.setThumbUrl(jsonImage.getString("ThumbURL"));
image.setSmallUrl(jsonImage.getString("SmallURL"));
image.setMediumUrl(jsonImage.getString("MediumURL"));
album.addImage(image);
}
} catch (SmugMugFailedResponse e) {
Log.w(Constants.TAG, "failed response received: "
+ e.getLocalizedMessage());
throw e;
} catch (JSONException e) {
Log.e(Constants.TAG, "unable to parse JSON object", e);
throw new SmugMugInternalError("unable to parse JSON");
} catch (Exception e) {
Log.e(Constants.TAG, "uncaught exception: "
+ e.getLocalizedMessage(), e);
throw new SmugMugInternalError("uncaught exception");
}
}
}
|