001/**
002 * Copyright (c) 2011, The University of Southampton and the individual contributors.
003 * All rights reserved.
004 *
005 * Redistribution and use in source and binary forms, with or without modification,
006 * are permitted provided that the following conditions are met:
007 *
008 *   *  Redistributions of source code must retain the above copyright notice,
009 *      this list of conditions and the following disclaimer.
010 *
011 *   *  Redistributions in binary form must reproduce the above copyright notice,
012 *      this list of conditions and the following disclaimer in the documentation
013 *      and/or other materials provided with the distribution.
014 *
015 *   *  Neither the name of the University of Southampton nor the names of its
016 *      contributors may be used to endorse or promote products derived from this
017 *      software without specific prior written permission.
018 *
019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030package org.openimaj.tools.imagecollection.collection.webpage;
031
032import java.net.MalformedURLException;
033import java.net.URL;
034import java.text.ParseException;
035import java.util.HashMap;
036import java.util.HashSet;
037import java.util.List;
038import java.util.Map;
039import java.util.Set;
040import java.util.regex.Matcher;
041import java.util.regex.Pattern;
042
043import org.openimaj.tools.imagecollection.collection.ImageCollectionSetupException;
044import org.openimaj.tools.imagecollection.collection.config.ImageCollectionConfig;
045import org.openimaj.util.pair.IndependentPair;
046
047import com.flickr4java.flickr.Flickr;
048import com.flickr4java.flickr.REST;
049import com.flickr4java.flickr.collections.Collection;
050import com.flickr4java.flickr.collections.CollectionsInterface;
051import com.flickr4java.flickr.galleries.GalleriesInterface;
052import com.flickr4java.flickr.photos.Extras;
053import com.flickr4java.flickr.photos.Photo;
054import com.flickr4java.flickr.photos.PhotoList;
055import com.flickr4java.flickr.photosets.Photoset;
056import com.flickr4java.flickr.photosets.PhotosetsInterface;
057
058public abstract class FlickrWebpageImageCollection extends AbstractWebpageImageCollection {
059
060        protected Flickr flickr;
061
062        @Override
063        public void setup(ImageCollectionConfig config) throws ImageCollectionSetupException {
064
065                try {
066                        final String apikey = config.read("webpage.flickr.apikey");
067                        final String secret = config.read("webpage.flickr.secret");
068                        flickr = new Flickr(apikey, secret, new REST(Flickr.DEFAULT_HOST));
069
070                } catch (final Exception e) {
071                        throw new ImageCollectionSetupException("Faile to setup, error creating the flickr client");
072                }
073
074                super.setup(config);
075        }
076
077        @Override
078        public Set<IndependentPair<URL, Map<String, String>>> prepareURLs(URL url) throws ImageCollectionSetupException {
079                System.out.println("Flickr query was: " + url.getFile());
080                PhotoList<Photo> results = null;
081                try {
082                        results = flickrProcess(url.getPath());
083                } catch (final Exception e) {
084                        e.printStackTrace();
085                        System.err.println("Failed performing flickr query");
086                        return null;
087                }
088                final Set<IndependentPair<URL, Map<String, String>>> urls = new HashSet<IndependentPair<URL, Map<String, String>>>();
089                for (int i = 0; i < results.size(); i++) {
090                        final Map<String, String> meta = new HashMap<String, String>();
091                        final Photo photo = results.get(i);
092                        meta.put("flickr_photo_id", photo.getId());
093                        try {
094                                urls.add(IndependentPair.pair(new URL(photo.getMediumUrl()), meta));
095                        } catch (final MalformedURLException e) {
096
097                        }
098                }
099                return urls;
100        }
101
102        protected abstract PhotoList<Photo> flickrProcess(String string);
103
104        @Override
105        public int useable(ImageCollectionConfig config) {
106                String urlStr;
107                String apiKey = null;
108                String secret = null;
109                try {
110                        urlStr = config.read("webpage.url");
111                        apiKey = config.read("webpage.flickr.apikey");
112                        secret = config.read("webpage.flickr.secret");
113                } catch (final ParseException e) {
114                        return -1;
115                }
116                if (urlStr == null || apiKey == null || secret == null)
117                        return -1;
118
119                URL url;
120                try {
121                        url = new URL(urlStr);
122                } catch (final MalformedURLException e) {
123                        return -1;
124                }
125                if (url.getHost().endsWith("flickr.com")) {
126                        return flickrUseable(url.getPath());
127                }
128                return -1;
129        }
130
131        @Override
132        public int useable(String rawInput) {
133                return flickrUseable(rawInput);
134        }
135
136        @Override
137        public ImageCollectionConfig defaultConfig(String rawInput) {
138                return new ImageCollectionConfig(String.format("{webpage{url:%s,flickr:{apikey:%s,secret:%s}}}", rawInput, "a",
139                                "b"));
140        }
141
142        public abstract int flickrUseable(String path);
143
144        public static class Gallery extends FlickrWebpageImageCollection {
145                Pattern r = Pattern.compile(".*/photos/.*/galleries/[0-9]*(/|$)");
146
147                @Override
148                public int flickrUseable(String path) {
149                        return r.matcher(path).matches() ? 1000 : -1;
150                }
151
152                @Override
153                protected PhotoList<Photo> flickrProcess(String path) {
154                        try {
155                                final GalleriesInterface galleriesInterface = flickr.getGalleriesInterface();
156                                final com.flickr4java.flickr.galleries.Gallery gallery = flickr.getUrlsInterface().lookupGallery(path);
157
158                                return galleriesInterface.getPhotos(gallery.getId(), Extras.ALL_EXTRAS, 18, 0);
159                        } catch (final Exception e) {
160                                e.printStackTrace();
161                        }
162                        return null;
163                }
164        }
165
166        public static class FlickrPhotoSet extends FlickrWebpageImageCollection {
167                Pattern r = Pattern.compile(".*/photos/.*/sets/([0-9]*)(/|$)");
168
169                @Override
170                public int flickrUseable(String path) {
171                        return r.matcher(path).matches() ? 1000 : -1;
172                }
173
174                @Override
175                protected PhotoList<Photo> flickrProcess(String path) {
176                        try {
177                                final PhotosetsInterface setsInterface = flickr.getPhotosetsInterface();
178                                final Matcher matcher = r.matcher(path);
179                                matcher.find();
180                                final String setId = matcher.group(1);
181                                final Photoset set = setsInterface.getInfo(setId);
182                                return setsInterface.getPhotos(setId, set.getPhotoCount(), 0);
183                        } catch (final Exception e) {
184                                e.printStackTrace();
185                        }
186                        return null;
187                }
188        }
189
190        public static class FlickrPhotoCollection extends FlickrWebpageImageCollection {
191                Pattern r = Pattern.compile(".*/photos/(.*)/collections/([0-9]*)(/|$)");
192
193                @Override
194                public int flickrUseable(String path) {
195                        return r.matcher(path).matches() ? 1000 : -1;
196                }
197
198                @Override
199                protected PhotoList<Photo> flickrProcess(String path) {
200                        try {
201                                final CollectionsInterface collectionsInterface = flickr.getCollectionsInterface();
202                                final Matcher matcher = r.matcher(path);
203                                matcher.find();
204                                final String userName = matcher.group(1);
205                                final String collectionsId = matcher.group(2);
206
207                                final List<Collection> collections = collectionsInterface.getTree(collectionsId, userName);
208
209                                final PhotoList<Photo> pl = new PhotoList<Photo>();
210                                for (final Collection c : collections)
211                                        pl.addAll(c.getPhotos());
212
213                                return pl;
214                        } catch (final Exception e) {
215                                e.printStackTrace();
216                        }
217                        return null;
218                }
219
220                @Override
221                public ImageCollectionConfig defaultConfig(String rawInput) {
222                        // TODO Auto-generated method stub
223                        return null;
224                }
225        }
226}