diff options
Diffstat (limited to 'main/src/cgeo/geocaching/connector/ec/ECApi.java')
| -rw-r--r-- | main/src/cgeo/geocaching/connector/ec/ECApi.java | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/main/src/cgeo/geocaching/connector/ec/ECApi.java b/main/src/cgeo/geocaching/connector/ec/ECApi.java new file mode 100644 index 0000000..f91bcdb --- /dev/null +++ b/main/src/cgeo/geocaching/connector/ec/ECApi.java @@ -0,0 +1,220 @@ +package cgeo.geocaching.connector.ec; + +import cgeo.geocaching.DataStore; +import cgeo.geocaching.Geocache; +import cgeo.geocaching.connector.LogResult; +import cgeo.geocaching.enumerations.CacheType; +import cgeo.geocaching.enumerations.LoadFlags.SaveFlag; +import cgeo.geocaching.enumerations.LogType; +import cgeo.geocaching.enumerations.StatusCode; +import cgeo.geocaching.files.GPX10Parser; +import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.geopoint.Viewport; +import cgeo.geocaching.list.StoredList; +import cgeo.geocaching.network.Network; +import cgeo.geocaching.network.Parameters; +import cgeo.geocaching.utils.Log; + +import ch.boye.httpclientandroidlib.HttpResponse; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.FastDateFormat; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumSet; +import java.util.List; +import java.util.Locale; +import java.util.TimeZone; + +public class ECApi { + + private static final String API_HOST = "http://extremcaching.com/exports/"; + + private static final FastDateFormat LOG_DATE_FORMAT = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss.SSSZ", TimeZone.getTimeZone("UTC"), Locale.US); + + public static String cleanCode(String geocode) { + return geocode.replace("EC", ""); + } + + public static Geocache searchByGeoCode(final String geocode) { + final Parameters params = new Parameters("id", cleanCode(geocode), "cgeo", "1"); + final HttpResponse response = apiRequest("gpx.php", params); + + final Collection<Geocache> caches = importCachesFromGPXResponse(response); + if (CollectionUtils.isNotEmpty(caches)) { + return caches.iterator().next(); + } + return null; + } + + public static Collection<Geocache> searchByBBox(final Viewport viewport) { + + if (viewport.getLatitudeSpan() == 0 || viewport.getLongitudeSpan() == 0) { + return Collections.emptyList(); + } + + final Parameters params = new Parameters("fnc", "bbox"); + params.add("lat1", String.valueOf(viewport.getLatitudeMin())); + params.add("lat2", String.valueOf(viewport.getLatitudeMax())); + params.add("lon1", String.valueOf(viewport.getLongitudeMin())); + params.add("lon2", String.valueOf(viewport.getLongitudeMax())); + final HttpResponse response = apiRequest(params); + + return importCachesFromJSON(response); + } + + + public static Collection<Geocache> searchByCenter(final Geopoint center) { + + final Parameters params = new Parameters("fnc", "center"); + params.add("distance", "20"); + params.add("lat", String.valueOf(center.getLatitude())); + params.add("lon", String.valueOf(center.getLongitude())); + final HttpResponse response = apiRequest(params); + + return importCachesFromJSON(response); + } + + public static LogResult postLog(final Geocache cache, final LogType logType, final Calendar date, final String log) { + return postLog(cache, logType, date, log, false); + } + + public static LogResult postLog(final Geocache cache, final LogType logType, final Calendar date, final String log, boolean isRetry) { + final Parameters params = new Parameters("cache_id", cache.getGeocode()); + params.add("type", logType.type); + params.add("log", log); + params.add("date", LOG_DATE_FORMAT.format(date.getTime())); + + final String uri = API_HOST + "log.php"; + final HttpResponse response = Network.postRequest(uri, params); + + if (response == null) { + return new LogResult(StatusCode.LOG_POST_ERROR_EC, ""); + } + if (!isRetry && response.getStatusLine().getStatusCode() == 403) { + if (ECLogin.getInstance().login() == StatusCode.NO_ERROR) { + apiRequest(uri, params, true); + } + } + if (response.getStatusLine().getStatusCode() != 200) { + return new LogResult(StatusCode.LOG_POST_ERROR_EC, ""); + } + + final String data = Network.getResponseDataAlways(response); + if (!StringUtils.isBlank(data) && StringUtils.contains(data, "success")) { + final String uid = StringUtils.remove(data, "success:"); + return new LogResult(StatusCode.NO_ERROR, uid); + } + + return new LogResult(StatusCode.LOG_POST_ERROR_EC, ""); + } + + + private static HttpResponse apiRequest(final Parameters params) { + return apiRequest("api.php", params, false); + } + + private static HttpResponse apiRequest(final String uri, final Parameters params) { + return apiRequest(uri, params, false); + } + + private static HttpResponse apiRequest(final String uri, final Parameters params, final boolean isRetry) { + final HttpResponse response = Network.getRequest(API_HOST + uri, params); + + if (response == null) { + return null; + } + if (!isRetry && response.getStatusLine().getStatusCode() == 403) { + if (ECLogin.getInstance().login() == StatusCode.NO_ERROR) { + apiRequest(uri, params, true); + } + } + if (response.getStatusLine().getStatusCode() != 200) { + return null; + } + return response; + } + + private static Collection<Geocache> importCachesFromGPXResponse(final HttpResponse response) { + if (response == null) { + return Collections.emptyList(); + } + + try { + return new GPX10Parser(StoredList.TEMPORARY_LIST_ID).parse(response.getEntity().getContent(), null); + } catch (Exception e) { + Log.e("Error importing gpx from extremcaching.com", e); + return Collections.emptyList(); + } + } + + private static List<Geocache> importCachesFromJSON(final HttpResponse response) { + + if (response != null) { + try { + final String data = Network.getResponseDataAlways(response); + if (StringUtils.isBlank(data) || StringUtils.equals(data, "[]")) { + return Collections.emptyList(); + } + final JSONArray json = new JSONArray(data); + final int len = json.length(); + final List<Geocache> caches = new ArrayList<Geocache>(len); + for (int i = 0; i < len; i++) { + final Geocache cache = parseCache(json.getJSONObject(i)); + if (cache != null) { + caches.add(cache); + } + } + return caches; + } catch (final JSONException e) { + Log.w("JSONResult", e); + } + } + + return Collections.emptyList(); + + } + + private static Geocache parseCache(final JSONObject response) { + final Geocache cache = new Geocache(); + cache.setReliableLatLon(true); + try { + cache.setGeocode("EC" + response.getString("cache_id")); + cache.setName(response.getString("title")); + cache.setCoords(new Geopoint(response.getString("lat"), response.getString("lon"))); + cache.setType(getCacheType(response.getString("type"))); + cache.setDifficulty((float) response.getDouble("difficulty")); + cache.setTerrain((float) response.getDouble("terrain")); + cache.setFound(response.getInt("found") == 1 ? true : false); + + DataStore.saveCache(cache, EnumSet.of(SaveFlag.SAVE_CACHE)); + } catch (final JSONException e) { + Log.e("ECApi.parseCache", e); + return null; + } + return cache; + } + + private static CacheType getCacheType(final String cacheType) { + if (cacheType.equalsIgnoreCase("Tradi")) { + return CacheType.TRADITIONAL; + } + if (cacheType.equalsIgnoreCase("Multi")) { + return CacheType.MULTI; + } + if (cacheType.equalsIgnoreCase("Event")) { + return CacheType.EVENT; + } + if (cacheType.equalsIgnoreCase("Mystery")) { + return CacheType.MYSTERY; + } + return CacheType.UNKNOWN; + } +} |
