package cgeo.geocaching.connector.oc; import cgeo.geocaching.Geocache; import cgeo.geocaching.cgData; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.connector.IConnector; import cgeo.geocaching.enumerations.LoadFlags; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.geopoint.GeopointFormatter; import cgeo.geocaching.network.Network; import cgeo.geocaching.network.Parameters; import cgeo.geocaching.utils.IOUtils; import cgeo.geocaching.utils.Log; import ch.boye.httpclientandroidlib.HttpResponse; import org.apache.commons.lang3.StringUtils; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Collection; import java.util.Collections; import java.util.Locale; import java.util.zip.GZIPInputStream; public class OCXMLClient { private static final String SERVICE_CACHE = "/xml/ocxml11.php"; // Url for single cache requests // http://www.opencaching.de/xml/ocxml11.php?modifiedsince=20060320000000&user=0&cache=1&cachedesc=1&cachelog=1&picture=1&removedobject=0&session=0&doctype=0&charset=utf-8&wp=OCC9BE public static Geocache getCache(final String geoCode) { try { final Parameters params = getOCXmlQueryParameters(true, true, true); params.put("wp", geoCode); final InputStream data = request(ConnectorFactory.getConnector(geoCode), SERVICE_CACHE, params); if (data == null) { return null; } final BufferedInputStream stream = new BufferedInputStream(new GZIPInputStream(data)); Collection caches = OC11XMLParser.parseCaches(stream); if (caches.iterator().hasNext()) { Geocache cache = caches.iterator().next(); cgData.saveCache(cache, LoadFlags.SAVE_ALL); IOUtils.closeQuietly(stream); return cache; } return null; } catch (IOException e) { Log.e("Error parsing cache '" + geoCode + "'", e); return null; } } public static Collection getCachesAround(final Geopoint center, final double distance) { try { final Parameters params = getOCXmlQueryParameters(false, false, false); params.put("lat", GeopointFormatter.format(GeopointFormatter.Format.LAT_DECDEGREE_RAW, center)); params.put("lon", GeopointFormatter.format(GeopointFormatter.Format.LON_DECDEGREE_RAW, center)); params.put("distance", String.format(Locale.US, "%f", distance)); final InputStream data = request(ConnectorFactory.getConnector("OCXXX"), SERVICE_CACHE, params); if (data == null) { return Collections.emptyList(); } final BufferedInputStream stream = new BufferedInputStream(new GZIPInputStream(data)); final Collection result = OC11XMLParser.parseCachesFiltered(stream); IOUtils.closeQuietly(stream); return result; } catch (IOException e) { Log.e("Error parsing nearby search result", e); return Collections.emptyList(); } } private static InputStream request(final IConnector connector, final String service, final Parameters params) { if (connector == null) { return null; } if (!(connector instanceof OCXMLApiConnector)) { return null; } final String host = connector.getHost(); if (StringUtils.isBlank(host)) { return null; } final String uri = "http://" + host + service; HttpResponse resp = Network.getRequest(uri, params); if (resp != null) { try { return resp.getEntity().getContent(); } catch (IllegalStateException e) { // fall through and return null } catch (IOException e) { // fall through and return null } } return null; } private static Parameters getOCXmlQueryParameters(final boolean withDescription, final boolean withLogs, final boolean withImages) { return new Parameters("modifiedsince", "20000101000000", "user", "0", "cache", "1", "cachedesc", withDescription ? "1" : "0", "cachelog", withLogs ? "1" : "0", "picture", withImages ? "1" : "0", "removedobject", "0", "session", "0", "doctype", "0", "charset", "utf-8", "zip", "gzip", "picturefromcachelog", withImages ? "1" : "0"); } }