/* Copyright (c) 2008 Google Inc. * * 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 sample.photos; import com.google.gdata.client.photos.PicasawebService; import com.google.gdata.data.Link; import com.google.gdata.data.photos.AlbumEntry; import com.google.gdata.data.photos.AlbumFeed; import com.google.gdata.data.photos.CommentEntry; import com.google.gdata.data.photos.GphotoEntry; import com.google.gdata.data.photos.GphotoFeed; import com.google.gdata.data.photos.PhotoEntry; import com.google.gdata.data.photos.TagEntry; import com.google.gdata.data.photos.UserFeed; import com.google.gdata.util.AuthenticationException; import com.google.gdata.util.ServiceException; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.List; /** * This is a simple client that provides high-level operations on the Picasa Web * Albums GData API. It can also be used as a command-line application to test * out some of the features of the API. * * */ public class PicasawebClient { private static final String API_PREFIX = "https://picasaweb.google.com/data/feed/api/user/"; private final PicasawebService service; /** * Constructs a new un-authenticated client. */ public PicasawebClient(PicasawebService service) { this(service, null, null); } /** * Constructs a new client with the given username and password. */ public PicasawebClient(PicasawebService service, String uname, String passwd) { this.service = service; if (uname != null && passwd != null) { try { service.setUserCredentials(uname, passwd); } catch (AuthenticationException e) { throw new IllegalArgumentException( "Illegal username/password combination."); } } } /** * Retrieves the albums for the given user. */ public List<AlbumEntry> getAlbums(String username) throws IOException, ServiceException { String albumUrl = API_PREFIX + username; UserFeed userFeed = getFeed(albumUrl, UserFeed.class); List<GphotoEntry> entries = userFeed.getEntries(); List<AlbumEntry> albums = new ArrayList<AlbumEntry>(); for (GphotoEntry entry : entries) { GphotoEntry adapted = entry.getAdaptedEntry(); if (adapted instanceof AlbumEntry) { albums.add((AlbumEntry) adapted); } } return albums; } /** * Retrieves the albums for the currently logged-in user. This is equivalent * to calling {@link #getAlbums(String)} with "default" as the username. */ public List<AlbumEntry> getAlbums() throws IOException, ServiceException { return getAlbums("default"); } /** * Retrieves the tags for the given user. These are tags aggregated across * the entire account. */ public List<TagEntry> getTags(String uname) throws IOException, ServiceException { String tagUrl = API_PREFIX + uname + "?kind=tag"; UserFeed userFeed = getFeed(tagUrl, UserFeed.class); List<GphotoEntry> entries = userFeed.getEntries(); List<TagEntry> tags = new ArrayList<TagEntry>(); for (GphotoEntry entry : entries) { GphotoEntry adapted = entry.getAdaptedEntry(); if (adapted instanceof TagEntry) { tags.add((TagEntry) adapted); } } return tags; } /** * Retrieves the tags for the currently logged-in user. This is equivalent * to calling {@link #getTags(String)} with "default" as the username. */ public List<TagEntry> getTags() throws IOException, ServiceException { return getTags("default"); } /** * Retrieves the photos for the given album. */ public List<PhotoEntry> getPhotos(AlbumEntry album) throws IOException, ServiceException { String feedHref = getLinkByRel(album.getLinks(), Link.Rel.FEED); AlbumFeed albumFeed = getFeed(feedHref, AlbumFeed.class); List<GphotoEntry> entries = albumFeed.getEntries(); List<PhotoEntry> photos = new ArrayList<PhotoEntry>(); for (GphotoEntry entry : entries) { GphotoEntry adapted = entry.getAdaptedEntry(); if (adapted instanceof PhotoEntry) { photos.add((PhotoEntry) adapted); } } return photos; } /** * Retrieves the comments for the given photo. */ public List<CommentEntry> getComments(PhotoEntry photo) throws IOException, ServiceException { String feedHref = getLinkByRel(photo.getLinks(), Link.Rel.FEED); AlbumFeed albumFeed = getFeed(feedHref, AlbumFeed.class); List<GphotoEntry> entries = albumFeed.getEntries(); List<CommentEntry> comments = new ArrayList<CommentEntry>(); for (GphotoEntry entry : entries) { GphotoEntry adapted = entry.getAdaptedEntry(); if (adapted instanceof CommentEntry) { comments.add((CommentEntry) adapted); } } return comments; } /** * Retrieves the tags for the given taggable entry. This is valid on user, * album, and photo entries only. */ public List<TagEntry> getTags(GphotoEntry<?> parent) throws IOException, ServiceException { String feedHref = getLinkByRel(parent.getLinks(), Link.Rel.FEED); feedHref = addKindParameter(feedHref, "tag"); AlbumFeed albumFeed = getFeed(feedHref, AlbumFeed.class); List<GphotoEntry> entries = albumFeed.getEntries(); List<TagEntry> tags = new ArrayList<TagEntry>(); for (GphotoEntry entry : entries) { GphotoEntry adapted = entry.getAdaptedEntry(); if (adapted instanceof TagEntry) { tags.add((TagEntry) adapted); } } return tags; } /** * Album-specific insert method to insert into the gallery of the current * user, this bypasses the need to have a top-level entry object for parent. */ public AlbumEntry insertAlbum(AlbumEntry album) throws IOException, ServiceException { String feedUrl = API_PREFIX + "default"; return service.insert(new URL(feedUrl), album); } /** * Insert an entry into another entry. Because our entries are a hierarchy, * this lets you insert a photo into an album even if you only have the * album entry and not the album feed, making it quicker to traverse the * hierarchy. */ public <T extends GphotoEntry> T insert(GphotoEntry<?> parent, T entry) throws IOException, ServiceException { String feedUrl = getLinkByRel(parent.getLinks(), Link.Rel.FEED); return service.insert(new URL(feedUrl), entry); } /** * Helper function to allow retrieval of a feed by string url, which will * create the URL object for you. Most of the Link objects have a string * href which must be converted into a URL by hand, this does the conversion. */ public <T extends GphotoFeed> T getFeed(String feedHref, Class<T> feedClass) throws IOException, ServiceException { System.out.println("Get Feed URL: " + feedHref); return service.getFeed(new URL(feedHref), feedClass); } /** * Helper function to add a kind parameter to a url. */ public String addKindParameter(String url, String kind) { if (url.contains("?")) { return url + "&kind=" + kind; } else { return url + "?kind=" + kind; } } /** * Helper function to get a link by a rel value. */ public String getLinkByRel(List<Link> links, String relValue) { for (Link link : links) { if (relValue.equals(link.getRel())) { return link.getHref(); } } throw new IllegalArgumentException("Missing " + relValue + " link."); } }