package com.ambergleam.android.photogallery.web; import android.net.Uri; import com.ambergleam.android.photogallery.BaseConstants; import com.ambergleam.android.photogallery.model.Photo; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserFactory; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.StringReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import timber.log.Timber; public class FlickrFetchr { public static final String PREF_SEARCH_QUERY = "searchQuery"; public static final String PREF_LAST_RESULT_ID = "lastResultId"; private static final String ENDPOINT = "https://api.flickr.com/services/rest/"; private static final String METHOD_GET_RECENT = "flickr.photos.getRecent"; private static final String METHOD_SEARCH = "flickr.photos.search"; private static final String PARAM_EXTRAS = "extras"; private static final String PARAM_TEXT = "text"; private static final String EXTRA_SMALL_URL = "url_q"; private static final String EXTRA_LARGE_URL = "url_z"; private static final String XML_PHOTO = "photo"; public byte[] getUrlBytes(String urlSpec) throws IOException { URL url = new URL(urlSpec); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); try { ByteArrayOutputStream out = new ByteArrayOutputStream(); InputStream in = connection.getInputStream(); if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { return null; } int bytesRead; byte[] buffer = new byte[1024]; while ((bytesRead = in.read(buffer)) > 0) { out.write(buffer, 0, bytesRead); } out.close(); return out.toByteArray(); } finally { connection.disconnect(); } } private String getUrl(String urlSpec) throws IOException { return new String(getUrlBytes(urlSpec)); } public ArrayList<Photo> getPhotos() { String url = Uri.parse(ENDPOINT).buildUpon() .appendQueryParameter("method", METHOD_GET_RECENT) .appendQueryParameter("api_key", BaseConstants.FLICKR_API_KEY) .appendQueryParameter(PARAM_EXTRAS, EXTRA_SMALL_URL + "," + EXTRA_LARGE_URL) .build().toString(); return downloadGalleryItems(url); } public ArrayList<Photo> getPhotos(String query) { String url = Uri.parse(ENDPOINT).buildUpon() .appendQueryParameter("method", METHOD_SEARCH) .appendQueryParameter("api_key", BaseConstants.FLICKR_API_KEY) .appendQueryParameter(PARAM_EXTRAS, EXTRA_SMALL_URL + "," + EXTRA_LARGE_URL) .appendQueryParameter(PARAM_TEXT, query) .build().toString(); return downloadGalleryItems(url); } private ArrayList<Photo> downloadGalleryItems(String url) { ArrayList<Photo> items = new ArrayList<>(); try { String xmlString = getUrl(url); Timber.i("Received xml: " + xmlString); XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); XmlPullParser parser = factory.newPullParser(); parser.setInput(new StringReader(xmlString)); parseItems(items, parser); } catch (IOException ioe) { Timber.e("Failed to fetch items", ioe); } catch (XmlPullParserException xppe) { Timber.e("Failed to parse items", xppe); } return items; } private void parseItems(ArrayList<Photo> items, XmlPullParser parser) throws XmlPullParserException, IOException { int eventType = parser.next(); while (eventType != XmlPullParser.END_DOCUMENT) { if (eventType == XmlPullParser.START_TAG && XML_PHOTO.equals(parser.getName())) { String id = parser.getAttributeValue(null, "id"); String caption = parser.getAttributeValue(null, "title"); String smallUrl = parser.getAttributeValue(null, EXTRA_SMALL_URL); String largeUrl = parser.getAttributeValue(null, EXTRA_LARGE_URL); String largeUrlWidth = parser.getAttributeValue(null, "width_z"); String largeUrlHeight = parser.getAttributeValue(null, "height_z"); String owner = parser.getAttributeValue(null, "owner"); if (id != null && caption != null && smallUrl != null && largeUrl != null && largeUrlWidth != null && largeUrlHeight != null && owner != null ) { Photo item = new Photo(); item.setId(id); item.setCaption(caption); item.setSmallUrl(smallUrl); item.setLargeUrl(largeUrl); item.setLargeUrlWidth(Integer.parseInt(largeUrlWidth)); item.setLargeUrlHeight(Integer.parseInt(largeUrlHeight)); item.setOwner(owner); items.add(item); } } eventType = parser.next(); } } }