/* * Copyright (c) 2005 Aetrion LLC. */ package com.googlecode.flickrjandroid.photosets; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import com.googlecode.flickrjandroid.Flickr; import com.googlecode.flickrjandroid.FlickrException; import com.googlecode.flickrjandroid.Parameter; import com.googlecode.flickrjandroid.Response; import com.googlecode.flickrjandroid.Transport; import com.googlecode.flickrjandroid.oauth.OAuthInterface; import com.googlecode.flickrjandroid.oauth.OAuthUtils; import com.googlecode.flickrjandroid.people.User; import com.googlecode.flickrjandroid.photos.Extras; import com.googlecode.flickrjandroid.photos.Photo; import com.googlecode.flickrjandroid.photos.PhotoContext; import com.googlecode.flickrjandroid.photos.PhotoList; import com.googlecode.flickrjandroid.photos.PhotoUtils; import com.googlecode.flickrjandroid.util.JSONUtils; import com.googlecode.flickrjandroid.util.StringUtilities; /** * Interface for working with photosets. * * @author Anthony Eden * @version $Id: PhotosetsInterface.java,v 1.27 2009/11/08 21:58:00 x-mago Exp $ */ public class PhotosetsInterface { public static final String METHOD_ADD_PHOTO = "flickr.photosets.addPhoto"; public static final String METHOD_CREATE = "flickr.photosets.create"; public static final String METHOD_DELETE = "flickr.photosets.delete"; public static final String METHOD_EDIT_META = "flickr.photosets.editMeta"; public static final String METHOD_EDIT_PHOTOS = "flickr.photosets.editPhotos"; public static final String METHOD_GET_CONTEXT = "flickr.photosets.getContext"; public static final String METHOD_GET_INFO = "flickr.photosets.getInfo"; public static final String METHOD_GET_LIST = "flickr.photosets.getList"; public static final String METHOD_GET_PHOTOS = "flickr.photosets.getPhotos"; public static final String METHOD_ORDER_SETS = "flickr.photosets.orderSets"; public static final String METHOD_REMOVE_PHOTO = "flickr.photosets.removePhoto"; public static final String METHOD_REORDER_PHOTOS = "flickr.photosets.reorderPhotos"; public static final String METHOD_SET_PRIMARY_PHOTO = "flickr.photosets.setPrimaryPhoto"; private String apiKey; private String sharedSecret; private Transport transportAPI; public PhotosetsInterface(String apiKey, String sharedSecret, Transport transportAPI) { this.apiKey = apiKey; this.sharedSecret = sharedSecret; this.transportAPI = transportAPI; } /** * Add a photo to the end of the photoset. * <p/> * Note: requires authentication with the new authentication API with 'write' permission. * * @param photosetId * The photoset ID * @param photoId * The photo ID * @throws JSONException */ public void addPhoto(String photosetId, String photoId) throws IOException, FlickrException, JSONException { List<Parameter> parameters = new ArrayList<Parameter>(); parameters.add(new Parameter("method", METHOD_ADD_PHOTO)); parameters.add(new Parameter(OAuthInterface.PARAM_OAUTH_CONSUMER_KEY, apiKey)); parameters.add(new Parameter("photoset_id", photosetId)); parameters.add(new Parameter("photo_id", photoId)); OAuthUtils.addOAuthToken(parameters); Response response = transportAPI.postJSON(sharedSecret, parameters); if (response.isError()) { throw new FlickrException(response.getErrorCode(), response.getErrorMessage()); } } /** * Create a new photoset. * * @param title * The photoset title * @param description * The photoset description * @param primaryPhotoId * The primary photo id * @return The new Photset * @throws IOException * @throws FlickrException * @throws JSONException */ public Photoset create(String title, String description, String primaryPhotoId) throws IOException, FlickrException, JSONException { List<Parameter> parameters = new ArrayList<Parameter>(); parameters.add(new Parameter("method", METHOD_CREATE)); parameters.add(new Parameter(OAuthInterface.PARAM_OAUTH_CONSUMER_KEY, apiKey)); parameters.add(new Parameter("title", title)); parameters.add(new Parameter("description", description)); parameters.add(new Parameter("primary_photo_id", primaryPhotoId)); OAuthUtils.addOAuthToken(parameters); Response response = transportAPI.postJSON(sharedSecret, parameters); if (response.isError()) { throw new FlickrException(response.getErrorCode(), response.getErrorMessage()); } JSONObject photosetElement = response.getData().getJSONObject("photoset"); Photoset photoset = new Photoset(); photoset.setId(photosetElement.getString("id")); photoset.setUrl(photosetElement.getString("url")); return photoset; } /** * Delete the specified photoset. * * @param photosetId * The photoset ID * @throws IOException * @throws FlickrException * @throws JSONException */ public void delete(String photosetId) throws IOException, FlickrException, JSONException { List<Parameter> parameters = new ArrayList<Parameter>(); parameters.add(new Parameter("method", METHOD_DELETE)); parameters.add(new Parameter(OAuthInterface.PARAM_OAUTH_CONSUMER_KEY, apiKey)); parameters.add(new Parameter("photoset_id", photosetId)); OAuthUtils.addOAuthToken(parameters); Response response = transportAPI.postJSON(sharedSecret, parameters); if (response.isError()) { throw new FlickrException(response.getErrorCode(), response.getErrorMessage()); } } /** * Modify the meta-data for a photoset. * * @param photosetId * The photoset ID * @param title * A new title * @param description * A new description (can be null) * @throws IOException * @throws FlickrException * @throws JSONException */ public void editMeta(String photosetId, String title, String description) throws IOException, FlickrException, JSONException { List<Parameter> parameters = new ArrayList<Parameter>(); parameters.add(new Parameter("method", METHOD_EDIT_META)); parameters.add(new Parameter(OAuthInterface.PARAM_OAUTH_CONSUMER_KEY, apiKey)); parameters.add(new Parameter("photoset_id", photosetId)); parameters.add(new Parameter("title", title)); if (description != null) { parameters.add(new Parameter("description", description)); } OAuthUtils.addOAuthToken(parameters); Response response = transportAPI.postJSON(sharedSecret, parameters); if (response.isError()) { throw new FlickrException(response.getErrorCode(), response.getErrorMessage()); } } /** * Edit which photos are in the photoset. * * @param photosetId * The photoset ID * @param primaryPhotoId * The primary photo Id * @param photoIds * The photo IDs for the photos in the set * @throws IOException * @throws FlickrException * @throws JSONException */ public void editPhotos(String photosetId, String primaryPhotoId, String[] photoIds) throws IOException, FlickrException, JSONException { List<Parameter> parameters = new ArrayList<Parameter>(); parameters.add(new Parameter("method", METHOD_EDIT_PHOTOS)); parameters.add(new Parameter(OAuthInterface.PARAM_OAUTH_CONSUMER_KEY, apiKey)); parameters.add(new Parameter("photoset_id", photosetId)); parameters.add(new Parameter("primary_photo_id", primaryPhotoId)); parameters.add(new Parameter("photo_ids", StringUtilities.join(photoIds, ","))); OAuthUtils.addOAuthToken(parameters); Response response = transportAPI.postJSON(sharedSecret, parameters); if (response.isError()) { throw new FlickrException(response.getErrorCode(), response.getErrorMessage()); } } /** * Get a photo's context in the specified photo set. * * This method does not require authentication. * * @param photoId * The photo ID * @param photosetId * The photoset ID * @return The PhotoContext * @throws IOException * @throws FlickrException * @throws JSONException */ public PhotoContext getContext(String photoId, String photosetId) throws IOException, FlickrException, JSONException { List<Parameter> parameters = new ArrayList<Parameter>(); parameters.add(new Parameter("method", METHOD_GET_CONTEXT)); parameters.add(new Parameter("api_key", apiKey)); parameters.add(new Parameter("photo_id", photoId)); parameters.add(new Parameter("photoset_id", photosetId)); // the Flickr API page says this method does not require OAuth OAuthUtils.addOAuthToken(parameters); Response response = transportAPI.get(transportAPI.getPath(), parameters); if (response.isError()) { throw new FlickrException(response.getErrorCode(), response.getErrorMessage()); } JSONObject payload = response.getData(); Iterator<?> keys = payload.keys(); PhotoContext photoContext = new PhotoContext(); while (keys.hasNext()) { String key = String.valueOf(keys.next()); JSONObject element = payload.optJSONObject(key); if (key.equals("prevphoto")) { String id = element.getString("id"); if ("0".equals(id) == false) { // this is the first photo Photo photo = new Photo(); photo.setId(id); photo.setTitle(element.optString("title")); photo.setUrl(element.optString("url")); photoContext.setPreviousPhoto(photo); } } else if (key.equals("nextphoto")) { String id = element.getString("id"); if ("0".equals(id) == false) { // this is the last photo Photo photo = new Photo(); photo.setId(id); photo.setTitle(element.optString("title")); photo.setUrl(element.optString("url")); photoContext.setNextPhoto(photo); } } else if (key.equals("count")) { // TODO: process this information } else { System.err.println("unsupported element name: " + key); } } return photoContext; } /** * Get the information for a specified photoset. * * This method does not require authentication. * * @param photosetId * The photoset ID * @return The Photoset * @throws FlickrException * @throws IOException * @throws JSONException */ public Photoset getInfo(String photosetId) throws FlickrException, IOException, JSONException { List<Parameter> parameters = new ArrayList<Parameter>(); parameters.add(new Parameter("method", METHOD_GET_INFO)); parameters.add(new Parameter("api_key", apiKey)); parameters.add(new Parameter("photoset_id", photosetId)); Response response = transportAPI.get(transportAPI.getPath(), parameters); if (response.isError()) { throw new FlickrException(response.getErrorCode(), response.getErrorMessage()); } JSONObject photosetElement = response.getData().getJSONObject("photoset"); Photoset photoset = new Photoset(); photoset.setId(photosetElement.getString("id")); User owner = new User(); owner.setId(photosetElement.getString("owner")); photoset.setOwner(owner); Photo primaryPhoto = new Photo(); primaryPhoto.setId(photosetElement.getString("primary")); primaryPhoto.setSecret(photosetElement.getString("secret")); // TODO verify that this is the secret for the photo primaryPhoto.setServer(photosetElement.getString("server")); // TODO verify that this is the server for the photo primaryPhoto.setFarm(photosetElement.getString("farm")); photoset.setPrimaryPhoto(primaryPhoto); // TODO remove secret/server/farm from photoset? // It's rather related to the primaryPhoto, then to the photoset itself. photoset.setSecret(photosetElement.getString("secret")); photoset.setServer(photosetElement.getString("server")); photoset.setFarm(photosetElement.getString("farm")); photoset.setPhotoCount(photosetElement.getString("photos")); photoset.setTitle(JSONUtils.getChildValue(photosetElement, "title")); photoset.setDescription(JSONUtils.getChildValue(photosetElement, "description")); photoset.setPrimaryPhoto(primaryPhoto); return photoset; } /** * Get a list of all photosets for the specified user. * * This method does not require authentication. But to get a Photoset into the list, that contains just private photos, the call needs to be authenticated. * * @param userId * The User id * @return The Photosets collection * @throws IOException * @throws FlickrException * @throws JSONException */ public Photosets getList(String userId) throws IOException, FlickrException, JSONException { List<Parameter> parameters = new ArrayList<Parameter>(); parameters.add(new Parameter("method", METHOD_GET_LIST)); boolean signed = OAuthUtils.hasSigned(); if (signed) { parameters.add(new Parameter(OAuthInterface.PARAM_OAUTH_CONSUMER_KEY, apiKey)); } else { parameters.add(new Parameter("api_key", apiKey)); } if (userId != null) { parameters.add(new Parameter("user_id", userId)); } if (signed) { OAuthUtils.addOAuthToken(parameters); } Response response = signed ? transportAPI.postJSON(sharedSecret, parameters) : transportAPI.get(transportAPI.getPath(), parameters); if (response.isError()) { throw new FlickrException(response.getErrorCode(), response.getErrorMessage()); } Photosets photosetsObject = new Photosets(); JSONObject photosetsElement = response.getData().getJSONObject("photosets"); List<Photoset> photosets = new ArrayList<Photoset>(); JSONArray photosetElements = photosetsElement.optJSONArray("photoset"); for (int i = 0; photosetElements != null && i < photosetElements.length(); i++) { JSONObject photosetElement = photosetElements.getJSONObject(i); Photoset photoset = new Photoset(); photoset.setId(photosetElement.getString("id")); if (photosetElement.has("owner")) { User owner = new User(); owner.setId(photosetElement.getString("owner")); photoset.setOwner(owner); } Photo primaryPhoto = new Photo(); primaryPhoto.setId(photosetElement.getString("primary")); primaryPhoto.setSecret(photosetElement.getString("secret")); // TODO verify that this is the secret for the photo primaryPhoto.setServer(photosetElement.getString("server")); // TODO verify that this is the server for the photo primaryPhoto.setFarm(photosetElement.getString("farm")); photoset.setPrimaryPhoto(primaryPhoto); photoset.setSecret(photosetElement.getString("secret")); photoset.setServer(photosetElement.getString("server")); photoset.setFarm(photosetElement.getString("farm")); photoset.setPhotoCount(photosetElement.getString("photos")); photoset.setTitle(JSONUtils.getChildValue(photosetElement, "title")); photoset.setDescription(JSONUtils.getChildValue(photosetElement, "description")); photosets.add(photoset); } photosetsObject.setPhotosets(photosets); return photosetsObject; } /** * Get a collection of Photo objects for the specified Photoset. * * This method does not require authentication. * * @see com.gmail.yuyang226.flickr.photos.Extras * @see com.gmail.yuyang226.flickr.Flickr#PRIVACY_LEVEL_NO_FILTER * @see com.gmail.yuyang226.flickr.Flickr#PRIVACY_LEVEL_PUBLIC * @see com.gmail.yuyang226.flickr.Flickr#PRIVACY_LEVEL_FRIENDS * @see com.gmail.yuyang226.flickr.Flickr#PRIVACY_LEVEL_FRIENDS_FAMILY * @see com.gmail.yuyang226.flickr.Flickr#PRIVACY_LEVEL_FAMILY * @see com.gmail.yuyang226.flickr.Flickr#PRIVACY_LEVEL_FRIENDS * @param photosetId * The photoset ID * @param extras * Set of extra-fields * @param privacy_filter * filter value for authenticated calls * @param perPage * The number of photos per page * @param page * The page offset * @return PhotoList The Collection of Photo objects * @throws IOException * @throws FlickrException * @throws JSONException */ public PhotoList getPhotos(String photosetId, Set<String> extras, int privacy_filter, int perPage, int page) throws IOException, FlickrException, JSONException { PhotoList photos = new PhotoList(); List<Parameter> parameters = new ArrayList<Parameter>(); parameters.add(new Parameter("method", METHOD_GET_PHOTOS)); boolean signed = OAuthUtils.hasSigned(); if (signed) { parameters.add(new Parameter(OAuthInterface.PARAM_OAUTH_CONSUMER_KEY, apiKey)); } else { parameters.add(new Parameter("api_key", apiKey)); } parameters.add(new Parameter("photoset_id", photosetId)); if (perPage > 0) { parameters.add(new Parameter("per_page", Integer.valueOf(perPage))); } if (page > 0) { parameters.add(new Parameter("page", Integer.valueOf(page))); } if (privacy_filter > 0) { parameters.add(new Parameter("privacy_filter", "" + privacy_filter)); } if (extras != null && !extras.isEmpty()) { parameters.add(new Parameter(Extras.KEY_EXTRAS, StringUtilities.join(extras, ","))); } if (signed) { OAuthUtils.addOAuthToken(parameters); } Response response = signed ? transportAPI.postJSON(sharedSecret, parameters) : transportAPI.get(transportAPI.getPath(), parameters); if (response.isError()) { throw new FlickrException(response.getErrorCode(), response.getErrorMessage()); } JSONObject photoset = response.getData().getJSONObject("photoset"); JSONArray photoElements = photoset.optJSONArray("photo"); photos.setPage(photoset.getString("page")); photos.setPages(photoset.getString("pages")); photos.setPerPage(photoset.getString("per_page")); photos.setTotal(photoset.getString("total")); for (int i = 0; photoElements != null && i < photoElements.length(); i++) { JSONObject photoElement = photoElements.getJSONObject(i); photos.add(PhotoUtils.createPhoto(photoElement)); } return photos; } /** * Convenience method. * * Calls getPhotos() with Extras.MIN_EXTRAS and Flickr.PRIVACY_LEVEL_NO_FILTER. * * This method does not require authentication. * * @see com.gmail.yuyang226.flickr.photos.Extras * @see com.gmail.yuyang226.flickr.Flickr#PRIVACY_LEVEL_NO_FILTER * @see com.gmail.yuyang226.flickr.Flickr#PRIVACY_LEVEL_PUBLIC * @see com.gmail.yuyang226.flickr.Flickr#PRIVACY_LEVEL_FRIENDS * @see com.gmail.yuyang226.flickr.Flickr#PRIVACY_LEVEL_FRIENDS_FAMILY * @see com.gmail.yuyang226.flickr.Flickr#PRIVACY_LEVEL_FAMILY * @see com.gmail.yuyang226.flickr.Flickr#PRIVACY_LEVEL_FRIENDS * @param photosetId * The photoset ID * @param perPage * The number of photos per page * @param page * The page offset * @return PhotoList The Collection of Photo objects * @throws IOException * @throws FlickrException * @throws JSONException */ public PhotoList getPhotos(String photosetId, int perPage, int page) throws IOException, FlickrException, JSONException { return getPhotos(photosetId, Extras.MIN_EXTRAS, Flickr.PRIVACY_LEVEL_NO_FILTER, perPage, page); } /** * Set the order in which sets are returned for the user. * * This method requires authentication with 'write' permission. * * @param photosetIds * An array of Ids * @throws IOException * @throws FlickrException * @throws JSONException */ public void orderSets(String[] photosetIds) throws IOException, FlickrException, JSONException { List<Parameter> parameters = new ArrayList<Parameter>(); parameters.add(new Parameter("method", METHOD_ORDER_SETS)); parameters.add(new Parameter(OAuthInterface.PARAM_OAUTH_CONSUMER_KEY, apiKey)); parameters.add(new Parameter("photoset_ids", StringUtilities.join(photosetIds, ","))); OAuthUtils.addOAuthToken(parameters); Response response = transportAPI.postJSON(sharedSecret, parameters); if (response.isError()) { throw new FlickrException(response.getErrorCode(), response.getErrorMessage()); } } /** * Set the order in which sets are returned for the user. * * This method requires authentication with 'write' permission. * * @param photosetIds * An array of Ids * @throws IOException * @throws FlickrException * @throws JSONException */ public void reorderPhotos(String photosetId, List<String> photoIds) throws IOException, FlickrException, JSONException { List<Parameter> parameters = new ArrayList<Parameter>(); parameters.add(new Parameter("method", METHOD_REORDER_PHOTOS)); parameters.add(new Parameter(OAuthInterface.PARAM_OAUTH_CONSUMER_KEY, apiKey)); parameters.add(new Parameter("photoset_id", photosetId)); parameters.add(new Parameter("photo_ids", StringUtilities.join(photoIds, ","))); OAuthUtils.addOAuthToken(parameters); Response response = transportAPI.postJSON(sharedSecret, parameters); if (response.isError()) { throw new FlickrException(response.getErrorCode(), response.getErrorMessage()); } } /** * Remove a photo from the set. * * @param photosetId * The photoset ID * @param photoId * The photo ID * @throws IOException * @throws FlickrException * @throws JSONException */ public void removePhoto(String photosetId, String photoId) throws IOException, FlickrException, JSONException { List<Parameter> parameters = new ArrayList<Parameter>(); parameters.add(new Parameter("method", METHOD_REMOVE_PHOTO)); parameters.add(new Parameter(OAuthInterface.PARAM_OAUTH_CONSUMER_KEY, apiKey)); parameters.add(new Parameter("photoset_id", photosetId)); parameters.add(new Parameter("photo_id", photoId)); OAuthUtils.addOAuthToken(parameters); Response response = transportAPI.postJSON(sharedSecret, parameters); if (response.isError()) { throw new FlickrException(response.getErrorCode(), response.getErrorMessage()); } } public void setPrimaryPhoto(String photosetId, String photoId) throws IOException, FlickrException, JSONException { List<Parameter> parameters = new ArrayList<Parameter>(); parameters.add(new Parameter("method", METHOD_SET_PRIMARY_PHOTO)); parameters.add(new Parameter(OAuthInterface.PARAM_OAUTH_CONSUMER_KEY, apiKey)); parameters.add(new Parameter("photoset_id", photosetId)); parameters.add(new Parameter("photo_id", photoId)); OAuthUtils.addOAuthToken(parameters); Response response = transportAPI.postJSON(sharedSecret, parameters); if (response.isError()) { throw new FlickrException(response.getErrorCode(), response.getErrorMessage()); } } }