diff options
| author | Bananeweizen <bananeweizen@gmx.de> | 2012-05-04 17:09:38 +0200 |
|---|---|---|
| committer | Bananeweizen <bananeweizen@gmx.de> | 2012-05-04 17:09:38 +0200 |
| commit | 84c6bd6cc358b2cde2926a62990e4c151c47d6d1 (patch) | |
| tree | 5d5a44f145fb347279d5c4c3a44e8a567a619930 /main/src/cgeo/geocaching/connector/oc/OkapiClient.java | |
| parent | 8f7c6b683f23356864a7b6a94a4071c4614b24db (diff) | |
| download | cgeo-84c6bd6cc358b2cde2926a62990e4c151c47d6d1.zip cgeo-84c6bd6cc358b2cde2926a62990e4c151c47d6d1.tar.gz cgeo-84c6bd6cc358b2cde2926a62990e4c151c47d6d1.tar.bz2 | |
refactoring: unify connector naming
Diffstat (limited to 'main/src/cgeo/geocaching/connector/oc/OkapiClient.java')
| -rw-r--r-- | main/src/cgeo/geocaching/connector/oc/OkapiClient.java | 313 |
1 files changed, 313 insertions, 0 deletions
diff --git a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java new file mode 100644 index 0000000..46214cc --- /dev/null +++ b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java @@ -0,0 +1,313 @@ +package cgeo.geocaching.connector.oc; + +import cgeo.geocaching.LogEntry; +import cgeo.geocaching.cgCache; +import cgeo.geocaching.cgImage; +import cgeo.geocaching.cgeoapplication; +import cgeo.geocaching.connector.ConnectorFactory; +import cgeo.geocaching.connector.IConnector; +import cgeo.geocaching.enumerations.CacheSize; +import cgeo.geocaching.enumerations.CacheType; +import cgeo.geocaching.enumerations.LoadFlags.SaveFlag; +import cgeo.geocaching.enumerations.LogType; +import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.geopoint.GeopointFormatter; +import cgeo.geocaching.network.Network; +import cgeo.geocaching.network.Parameters; +import cgeo.geocaching.utils.Log; + +import org.apache.commons.lang3.StringUtils; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import android.net.Uri; +import android.text.Html; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.EnumSet; +import java.util.List; +import java.util.Locale; + +final public class OkapiClient { + private static final String CACHE_SIZE = "size"; + private static final String CACHE_VOTES = "rating_votes"; + private static final String CACHE_NOTFOUNDS = "notfounds"; + private static final String CACHE_FOUNDS = "founds"; + private static final String CACHE_HIDDEN = "date_hidden"; + private static final String CACHE_LATEST_LOGS = "latest_logs"; + private static final String CACHE_IMAGE_URL = "url"; + private static final String CACHE_IMAGE_CAPTION = "caption"; + private static final String CACHE_IMAGE_IS_SPOILER = "is_spoiler"; + private static final String CACHE_IMAGES = "images"; + private static final String CACHE_HINT = "hint"; + private static final String CACHE_DESCRIPTION = "description"; + private static final String CACHE_RECOMMENDATIONS = "recommendations"; + private static final String CACHE_RATING = "rating"; + private static final String CACHE_TERRAIN = "terrain"; + private static final String CACHE_DIFFICULTY = "difficulty"; + private static final String CACHE_OWNER = "owner"; + private static final String CACHE_STATUS = "status"; + private static final String CACHE_TYPE = "type"; + private static final String CACHE_LOCATION = "location"; + private static final String CACHE_NAME = "name"; + private static final String CACHE_CODE = "code"; + + private static final String LOG_TYPE = "type"; + private static final String LOG_COMMENT = "comment"; + private static final String LOG_DATE = "date"; + private static final String LOG_USER = "user"; + + private static final String USER_USERNAME = "username"; + + private static final String SERVICE_CACHE = "/okapi/services/caches/geocache"; + private static final String SERVICE_CACHE_FIELDS = "code|name|location|type|status|owner|founds|notfounds|size|difficulty|terrain|rating|rating_votes|recommendations|description|hint|images|latest_logs|date_hidden"; + + private static final String SERVICE_NEAREST = "/okapi/services/caches/search/nearest"; + + public static cgCache getCache(final String geoCode) { + final Parameters params = new Parameters("cache_code", geoCode, "fields", SERVICE_CACHE_FIELDS); + final JSONObject data = request(ConnectorFactory.getConnector(geoCode), SERVICE_CACHE, params); + + if (data == null) { + return null; + } + + return parseCache(data); + } + + public static List<cgCache> getCachesAround(final Geopoint center, IConnector connector) { + String centerString = GeopointFormatter.format(GeopointFormatter.Format.LAT_DECDEGREE_RAW, center) + "|" + GeopointFormatter.format(GeopointFormatter.Format.LON_DECDEGREE_RAW, center); + final Parameters params = new Parameters("center", centerString); + final JSONObject data = request(connector, SERVICE_NEAREST, params); + + if (data == null) { + return null; + } + + return parseCaches(data); + } + + private static List<cgCache> parseCaches(final JSONObject response) { + try { + final JSONArray cachesResponse = response.getJSONArray("results"); + if (cachesResponse != null) { + ArrayList<String> geocodes = new ArrayList<String>(cachesResponse.length()); + for (int i = 0; i < cachesResponse.length(); i++) { + String geocode = cachesResponse.getString(i); + if (StringUtils.isNotBlank(geocode)) { + geocodes.add(geocode); + } + } + List<cgCache> caches = new ArrayList<cgCache>(geocodes.size()); + for (String geocode : geocodes) { + cgCache cache = getCache(geocode); + if (cache != null) { + caches.add(cache); + } + } + return caches; + } + } catch (JSONException e) { + Log.e("OkapiClient.parseCaches", e); + } + return null; + } + + private static cgCache parseCache(final JSONObject response) { + final cgCache cache = new cgCache(); + cache.setReliableLatLon(true); + try { + cache.setGeocode(response.getString(CACHE_CODE)); + cache.setName(response.getString(CACHE_NAME)); + // not used: names + setLocation(cache, response.getString(CACHE_LOCATION)); + cache.setType(getCacheType(response.getString(CACHE_TYPE))); + + final String status = response.getString(CACHE_STATUS); + cache.setDisabled(status.equalsIgnoreCase("Temporarily unavailable")); + cache.setArchived(status.equalsIgnoreCase("Archived")); + + // not used: url + final JSONObject owner = response.getJSONObject(CACHE_OWNER); + cache.setOwner(parseUser(owner)); + + cache.getLogCounts().put(LogType.FOUND_IT, response.getInt(CACHE_FOUNDS)); + cache.getLogCounts().put(LogType.DIDNT_FIND_IT, response.getInt(CACHE_NOTFOUNDS)); + cache.setSize(getCacheSize(response)); + cache.setDifficulty((float) response.getDouble(CACHE_DIFFICULTY)); + cache.setTerrain((float) response.getDouble(CACHE_TERRAIN)); + if (!response.isNull(CACHE_RATING)) { + cache.setRating((float) response.getDouble(CACHE_RATING)); + } + cache.setVotes(response.getInt(CACHE_VOTES)); + + cache.setFavoritePoints(response.getInt(CACHE_RECOMMENDATIONS)); + // not used: req_password + cache.setDescription(response.getString(CACHE_DESCRIPTION)); + cache.setHint(Html.fromHtml(response.getString(CACHE_HINT)).toString()); + // not used: hints + + final JSONArray images = response.getJSONArray(CACHE_IMAGES); + if (images != null) { + JSONObject imageResponse; + for (int i = 0; i < images.length(); i++) { + imageResponse = images.getJSONObject(i); + if (imageResponse.getBoolean(CACHE_IMAGE_IS_SPOILER)) { + final String title = imageResponse.getString(CACHE_IMAGE_CAPTION); + final String url = absoluteUrl(imageResponse.getString(CACHE_IMAGE_URL), cache.getGeocode()); + final cgImage image = new cgImage(url, title); + if (cache.getSpoilers() == null) { + cache.setSpoilers(new ArrayList<cgImage>()); + } + cache.getSpoilers().add(image); + } + } + } + + // not used: attrnames + cache.setLogs(parseLogs(response.getJSONArray(CACHE_LATEST_LOGS))); + cache.setHidden(parseDate(response.getString(CACHE_HIDDEN))); + + cache.setUpdated(System.currentTimeMillis()); + cache.setDetailedUpdate(cache.getUpdated()); + cache.setDetailed(true); + + // save full detailed caches + cgeoapplication.getInstance().saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); + } catch (JSONException e) { + Log.e("OkapiClient.parseCache", e); + } + return cache; + } + + private static String absoluteUrl(String url, String geocode) { + final Uri uri = Uri.parse(url); + + if (!uri.isAbsolute()) { + final IConnector connector = ConnectorFactory.getConnector(geocode); + final String host = connector.getHost(); + if (StringUtils.isNotBlank(host)) { + return "http://" + host + "/" + url; + } + } + return url; + } + + private static String parseUser(JSONObject user) throws JSONException { + return user.getString(USER_USERNAME); + } + + private static List<LogEntry> parseLogs(JSONArray logsJSON) { + List<LogEntry> result = null; + for (int i = 0; i < logsJSON.length(); i++) { + try { + JSONObject logResponse = logsJSON.getJSONObject(i); + LogEntry log = new LogEntry( + parseUser(logResponse.getJSONObject(LOG_USER)), + parseDate(logResponse.getString(LOG_DATE)).getTime(), + parseLogType(logResponse.getString(LOG_TYPE)), + logResponse.getString(LOG_COMMENT).trim()); + if (result == null) { + result = new ArrayList<LogEntry>(); + } + result.add(log); + } catch (JSONException e) { + Log.e("OkapiClient.parseLogs", e); + } + } + return result; + } + + private static LogType parseLogType(String logType) { + if ("Found it".equalsIgnoreCase(logType)) { + return LogType.FOUND_IT; + } + if ("Didn't find it".equalsIgnoreCase(logType)) { + return LogType.DIDNT_FIND_IT; + } + return LogType.NOTE; + } + + private static Date parseDate(final String date) { + final SimpleDateFormat ISO8601DATEFORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.getDefault()); + final String strippedDate = date.replaceAll("\\+0([0-9]){1}\\:00", "+0$100"); + try { + return ISO8601DATEFORMAT.parse(strippedDate); + } catch (ParseException e) { + Log.e("OkapiClient.parseDate", e); + } + return null; + } + + private static void setLocation(final cgCache cache, final String location) { + final String latitude = StringUtils.substringBefore(location, "|"); + final String longitude = StringUtils.substringAfter(location, "|"); + // FIXME: the next line should be a setter at cgCache + cache.setCoords(new Geopoint(latitude, longitude)); + } + + private static CacheSize getCacheSize(final JSONObject response) { + if (response.isNull(CACHE_SIZE)) { + return CacheSize.NOT_CHOSEN; + } + double size = 0; + try { + size = response.getDouble(CACHE_SIZE); + } catch (JSONException e) { + Log.e("OkapiClient.getCacheSize", e); + } + switch ((int) Math.round(size)) { + case 1: + return CacheSize.MICRO; + case 2: + return CacheSize.SMALL; + case 3: + return CacheSize.REGULAR; + case 4: + return CacheSize.LARGE; + case 5: + return CacheSize.LARGE; + default: + break; + } + return CacheSize.NOT_CHOSEN; + } + + private static CacheType getCacheType(final String cacheType) { + if (cacheType.equalsIgnoreCase("Traditional")) { + return CacheType.TRADITIONAL; + } + if (cacheType.equalsIgnoreCase("Multi")) { + return CacheType.MULTI; + } + if (cacheType.equalsIgnoreCase("Quiz")) { + return CacheType.MYSTERY; + } + if (cacheType.equalsIgnoreCase("Virtual")) { + return CacheType.VIRTUAL; + } + return CacheType.UNKNOWN; + } + + private static JSONObject request(final IConnector connector, final String service, final Parameters params) { + if (connector == null) { + return null; + } + if (!(connector instanceof OCApiConnector)) { + return null; + } + + final String host = connector.getHost(); + if (StringUtils.isBlank(host)) { + return null; + } + + final String uri = "http://" + host + service; + ((OCApiConnector) connector).addAuthentication(params); + return Network.requestJSON(uri, params); + } +} |
