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
032
033import java.net.MalformedURLException;
034import java.net.URL;
035import java.text.ParseException;
036import java.util.HashMap;
037import java.util.HashSet;
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.aetrion.flickr.Flickr;
048import com.aetrion.flickr.REST;
049import com.aetrion.flickr.collections.CollectionsInterface;
050import com.aetrion.flickr.collections.CollectionsSearchParameters;
051import com.aetrion.flickr.collections.PhotoCollection;
052import com.aetrion.flickr.galleries.GalleriesInterface;
053import com.aetrion.flickr.galleries.SearchParameters;
054import com.aetrion.flickr.photos.Photo;
055import com.aetrion.flickr.photos.PhotoList;
056import com.aetrion.flickr.photosets.Photoset;
057import com.aetrion.flickr.photosets.PhotosetsInterface;
058
059
060public abstract class FlickrWebpageImageCollection extends AbstractWebpageImageCollection {
061        
062        
063        protected Flickr flickr;
064
065        @Override
066        public void setup(ImageCollectionConfig config) throws ImageCollectionSetupException {
067                
068                try {
069                        String apikey = config.read("webpage.flickr.apikey");
070                        String secret = config.read("webpage.flickr.secret");
071                        flickr = new Flickr(apikey, secret, new REST(Flickr.DEFAULT_HOST));
072                        
073                } catch (Exception e) {
074                        throw new ImageCollectionSetupException("Faile to setup, error creating the flickr client");
075                }
076                
077                super.setup(config);
078        }
079        @Override
080        public Set<IndependentPair<URL, Map<String, String>>> prepareURLs(URL url) throws ImageCollectionSetupException {
081                System.out.println("Flickr query was: " + url.getFile());
082                PhotoList results = null;
083                try {
084                        results = flickrProcess(url.getPath()); 
085                } catch (Exception e) {
086                        e.printStackTrace();
087                        System.err.println("Failed performing flickr query");
088                        return null;
089                }
090                Set<IndependentPair<URL, Map<String, String>>> urls = new HashSet<IndependentPair<URL, Map<String, String>>>();
091                for (int i = 0; i < results.size(); i++) {
092                        Map<String,String> meta = new HashMap<String,String>();
093                        Photo photo = (Photo) results.get(i) ;
094                        meta.put("flickr_photo_id", photo.getId());
095                        try {
096                                urls.add(IndependentPair.pair(new URL(photo.getMediumUrl()),meta));
097                        } catch (MalformedURLException e) {
098                                
099                        }
100                }
101                return urls;
102        }
103        
104        protected abstract PhotoList flickrProcess(String string);
105
106        @Override
107        public int useable(ImageCollectionConfig config) {
108                String urlStr;
109                String apiKey = null;
110                String secret = null;
111                try {
112                        urlStr = config.read("webpage.url");
113                        apiKey = config.read("webpage.flickr.apikey");
114                        secret = config.read("webpage.flickr.secret");
115                } catch (ParseException e) {
116                        return -1;
117                }
118                if(urlStr==null || apiKey == null || secret == null) return -1;
119                
120                URL url;
121                try {
122                        url = new URL(urlStr);
123                } catch (MalformedURLException e) {
124                        return -1;
125                }
126                if(url.getHost().endsWith("flickr.com")) {
127                        return flickrUseable(url.getPath());
128                }
129                return -1;      
130        }
131        
132        @Override
133        public int useable(String rawInput) {
134                return flickrUseable(rawInput);
135        }
136        
137        @Override
138        public ImageCollectionConfig defaultConfig(String rawInput) {
139                return new ImageCollectionConfig(String.format("{webpage{url:%s,flickr:{apikey:%s,secret:%s}}}",rawInput,"a","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                @Override
147                public int flickrUseable(String path) {
148                        return r.matcher(path).matches() ? 1000 : -1;
149                }
150                @Override
151                protected PhotoList flickrProcess(String path) {
152                        try{
153                                GalleriesInterface galleriesInterface = flickr.getGalleriesInterface();
154                                String galleryId = flickr.getUrlsInterface().lookupGallery(path);
155                                SearchParameters params = new SearchParameters();
156                                params.setGalleryId(galleryId);
157                                return galleriesInterface.getPhotos(params, 18, 0);
158                        }
159                        catch(Exception e){
160                                e.printStackTrace();
161                        }
162                        return null;
163                }
164        }
165        public static class FlickrPhotoSet extends FlickrWebpageImageCollection{
166                Pattern r = Pattern.compile(".*/photos/.*/sets/([0-9]*)(/|$)");
167                @Override
168                public int flickrUseable(String path) {
169                        return r.matcher(path).matches() ? 1000 : -1;
170                }
171                @Override
172                protected PhotoList flickrProcess(String path) {
173                        try{
174                                PhotosetsInterface setsInterface = flickr.getPhotosetsInterface();
175                                Matcher matcher = r.matcher(path);
176                                matcher.find();
177                                String setId = matcher.group(1);
178                                Photoset set = setsInterface.getInfo(setId);
179                                return setsInterface.getPhotos(setId, set.getPhotoCount(), 0);
180                        }
181                        catch(Exception e){
182                                e.printStackTrace();
183                        }
184                        return null;
185                }
186        }
187        
188        public static class FlickrPhotoCollection extends FlickrWebpageImageCollection{
189                Pattern r = Pattern.compile(".*/photos/(.*)/collections/([0-9]*)(/|$)");
190                @Override
191                public int flickrUseable(String path) {
192                        return r.matcher(path).matches() ? 1000 : -1;
193                }
194                @Override
195                protected PhotoList flickrProcess(String path) {
196                        try{CollectionsInterface collectionsInterface = flickr.getCollectionsInterface();                               
197                                Matcher matcher = r.matcher(path);
198                                matcher.find();
199                                String userName = matcher.group(1);
200                                String collectionsId = matcher.group(2);
201                                CollectionsSearchParameters params = new CollectionsSearchParameters();
202                                params.setCollectionId(collectionsId);
203                                params.setUserId(flickr.getPeopleInterface().findByUsername(userName).getId());
204                                PhotoCollection c = collectionsInterface.getTree(params);
205                                return c.getPhotoUrls(flickr.getPhotosetsInterface());
206                        }
207                        catch(Exception e){
208                                e.printStackTrace();
209                        }
210                        return null;
211                }
212                
213                @Override
214                public ImageCollectionConfig defaultConfig(String rawInput) {
215                        // TODO Auto-generated method stub
216                        return null;
217                }
218        }
219}