import com.flickr4java.flickr.Flickr; import com.flickr4java.flickr.FlickrException; import com.flickr4java.flickr.REST; import com.flickr4java.flickr.RequestContext; import com.flickr4java.flickr.auth.Auth; import com.flickr4java.flickr.auth.AuthInterface; import com.flickr4java.flickr.auth.Permission; import com.flickr4java.flickr.photos.Photo; import com.flickr4java.flickr.photos.PhotoList; import com.flickr4java.flickr.photos.PhotosInterface; import com.flickr4java.flickr.photos.Size; import com.flickr4java.flickr.photosets.Photoset; import com.flickr4java.flickr.photosets.PhotosetsInterface; import com.flickr4java.flickr.util.AuthStore; import com.flickr4java.flickr.util.FileAuthStore; import org.scribe.model.Token; import org.scribe.model.Verifier; import org.xml.sax.SAXException; import java.io.BufferedInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Scanner; /** * A simple program to backup all of a users private and public photos in a photoset aware manner. If photos are classified in multiple photosets, they will be * copied. Its a sample, its not perfect :-) * * This sample also uses the AuthStore interface, so users will only be asked to authorize on the first run. * * @author Matthew MacKenzie * @version $Id: Backup.java,v 1.6 2009/01/01 16:44:57 x-mago Exp $ */ public class Backup { private final String nsid; private final Flickr flickr; private AuthStore authStore; public Backup(String apiKey, String nsid, String sharedSecret, File authsDir) throws FlickrException { flickr = new Flickr(apiKey, sharedSecret, new REST()); this.nsid = nsid; if (authsDir != null) { this.authStore = new FileAuthStore(authsDir); } } private void authorize() throws IOException, SAXException, FlickrException { AuthInterface authInterface = flickr.getAuthInterface(); Token accessToken = authInterface.getRequestToken(); String url = authInterface.getAuthorizationUrl(accessToken, Permission.READ); System.out.println("Follow this URL to authorise yourself on Flickr"); System.out.println(url); System.out.println("Paste in the token it gives you:"); System.out.print(">>"); String tokenKey = new Scanner(System.in).nextLine(); Token requestToken = authInterface.getAccessToken(accessToken, new Verifier(tokenKey)); Auth auth = authInterface.checkToken(requestToken); RequestContext.getRequestContext().setAuth(auth); this.authStore.store(auth); System.out.println("Thanks. You probably will not have to do this every time. Now starting backup."); } public void doBackup(File directory) throws Exception { if (!directory.exists()) { directory.mkdir(); } RequestContext rc = RequestContext.getRequestContext(); if (this.authStore != null) { Auth auth = this.authStore.retrieve(this.nsid); if (auth == null) { this.authorize(); } else { rc.setAuth(auth); } } PhotosetsInterface pi = flickr.getPhotosetsInterface(); PhotosInterface photoInt = flickr.getPhotosInterface(); Map<String, Collection> allPhotos = new HashMap<String, Collection>(); Iterator sets = pi.getList(this.nsid).getPhotosets().iterator(); while (sets.hasNext()) { Photoset set = (Photoset) sets.next(); PhotoList photos = pi.getPhotos(set.getId(), 500, 1); allPhotos.put(set.getTitle(), photos); } int notInSetPage = 1; Collection notInASet = new ArrayList(); while (true) { Collection nis = photoInt.getNotInSet(50, notInSetPage); notInASet.addAll(nis); if (nis.size() < 50) { break; } notInSetPage++; } allPhotos.put("NotInASet", notInASet); Iterator allIter = allPhotos.keySet().iterator(); while (allIter.hasNext()) { String setTitle = (String) allIter.next(); String setDirectoryName = makeSafeFilename(setTitle); Collection currentSet = allPhotos.get(setTitle); Iterator setIterator = currentSet.iterator(); File setDirectory = new File(directory, setDirectoryName); setDirectory.mkdir(); while (setIterator.hasNext()) { Photo p = (Photo) setIterator.next(); String url = p.getLargeUrl(); URL u = new URL(url); String filename = u.getFile(); filename = filename.substring(filename.lastIndexOf("/") + 1, filename.length()); System.out.println("Now writing " + filename + " to " + setDirectory.getCanonicalPath()); BufferedInputStream inStream = new BufferedInputStream(photoInt.getImageAsStream(p, Size.LARGE)); File newFile = new File(setDirectory, filename); FileOutputStream fos = new FileOutputStream(newFile); int read; while ((read = inStream.read()) != -1) { fos.write(read); } fos.flush(); fos.close(); inStream.close(); } } } private String makeSafeFilename(String input) { byte[] fname = input.getBytes(); byte[] bad = new byte[] { '\\', '/', '"' }; byte replace = '_'; for (int i = 0; i < fname.length; i++) { for (byte element : bad) { if (fname[i] == element) { fname[i] = replace; } } } return new String(fname); } public static void main(String[] args) throws Exception { if (args.length < 4) { System.out.println("Usage: java " + Backup.class.getName() + " api_key nsid shared_secret output_dir"); System.exit(1); } Backup bf = new Backup(args[0], args[1], args[2], new File(System.getProperty("user.home") + File.separatorChar + ".flickrAuth")); bf.doBackup(new File(args[3])); } }