diff options
Diffstat (limited to 'main/src')
11 files changed, 239 insertions, 116 deletions
diff --git a/main/src/cgeo/geocaching/SearchActivity.java b/main/src/cgeo/geocaching/SearchActivity.java index bc9f934..c2a7b6d 100644 --- a/main/src/cgeo/geocaching/SearchActivity.java +++ b/main/src/cgeo/geocaching/SearchActivity.java @@ -7,11 +7,10 @@ import cgeo.geocaching.activity.AbstractActivity; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.connector.IConnector; import cgeo.geocaching.connector.capability.ISearchByGeocode; -import cgeo.geocaching.connector.gc.GCConstants; +import cgeo.geocaching.connector.trackable.TrackableConnector; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.geopoint.GeopointFormatter; import cgeo.geocaching.ui.dialog.CoordinatesInputDialog; -import cgeo.geocaching.utils.TextUtils; import cgeo.geocaching.utils.EditUtils; import cgeo.geocaching.utils.GeoDirHandler; import cgeo.geocaching.utils.Log; @@ -61,7 +60,7 @@ public class SearchActivity extends AbstractActivity { super.onCreate(savedInstanceState); // search query - Intent intent = getIntent(); + final Intent intent = getIntent(); if (Intent.ACTION_SEARCH.equals(intent.getAction())) { final String query = intent.getStringExtra(SearchManager.QUERY); final boolean keywordSearch = intent.getBooleanExtra(Intents.EXTRA_KEYWORD_SEARCH, true); @@ -122,7 +121,7 @@ public class SearchActivity extends AbstractActivity { // otherwise see if this is a pure geocode if (StringUtils.isEmpty(geocode)) { - geocode = StringUtils.trim(query); + geocode = StringUtils.upperCase(StringUtils.trim(query)); } final IConnector connector = ConnectorFactory.getConnector(geocode); @@ -134,10 +133,10 @@ public class SearchActivity extends AbstractActivity { } // Check if the query is a TB code - final String trackable = TextUtils.getMatch(query, GCConstants.PATTERN_TB_CODE, true, 0, "", false); - if (StringUtils.isNotBlank(trackable)) { + final TrackableConnector trackableConnector = ConnectorFactory.getTrackableConnector(geocode); + if (trackableConnector != ConnectorFactory.UNKNOWN_TRACKABLE_CONNECTOR) { final Intent trackablesIntent = new Intent(this, TrackableActivity.class); - trackablesIntent.putExtra(Intents.EXTRA_GEOCODE, trackable.toUpperCase(Locale.US)); + trackablesIntent.putExtra(Intents.EXTRA_GEOCODE, geocode.toUpperCase(Locale.US)); startActivity(trackablesIntent); return true; } @@ -240,7 +239,7 @@ public class SearchActivity extends AbstractActivity { lonEdit.setHint(geo.getCoords().format(GeopointFormatter.Format.LON_DECMINUTE_RAW)); } } - } catch (Exception e) { + } catch (final Exception e) { Log.w("Failed to update location."); } } @@ -250,7 +249,7 @@ public class SearchActivity extends AbstractActivity { @Override public void onClick(View arg0) { - CoordinatesInputDialog coordsDialog = new CoordinatesInputDialog(SearchActivity.this, null, null, app.currentGeo()); + final CoordinatesInputDialog coordsDialog = new CoordinatesInputDialog(SearchActivity.this, null, null, app.currentGeo()); coordsDialog.setCancelable(true); coordsDialog.setOnCoordinateUpdate(new CoordinatesInputDialog.CoordinateUpdate() { @Override @@ -284,7 +283,7 @@ public class SearchActivity extends AbstractActivity { } else { try { cgeocaches.startActivityCoordinates(this, new Geopoint(StringUtils.trim(latText), StringUtils.trim(lonText))); - } catch (Geopoint.ParseException e) { + } catch (final Geopoint.ParseException e) { showToast(res.getString(e.resource)); } } @@ -300,7 +299,7 @@ public class SearchActivity extends AbstractActivity { private void findByKeywordFn() { // find caches by coordinates - String keyText = keywordEditText.getText().toString(); + final String keyText = keywordEditText.getText().toString(); if (StringUtils.isBlank(keyText)) { helpDialog(res.getString(R.string.warn_search_help_title), res.getString(R.string.warn_search_help_keyword)); diff --git a/main/src/cgeo/geocaching/Trackable.java b/main/src/cgeo/geocaching/Trackable.java index f777351..d532cda 100644 --- a/main/src/cgeo/geocaching/Trackable.java +++ b/main/src/cgeo/geocaching/Trackable.java @@ -1,7 +1,8 @@ package cgeo.geocaching; +import cgeo.geocaching.connector.ConnectorFactory; +import cgeo.geocaching.connector.trackable.TrackableConnector; import cgeo.geocaching.enumerations.LogType; -import cgeo.geocaching.utils.Log; import org.apache.commons.lang3.StringUtils; @@ -38,17 +39,11 @@ public class Trackable implements ILogable { private String trackingcode = null; public String getUrl() { - if (StringUtils.startsWithIgnoreCase(getGeocode(), "GK")) { - String hex = getGeocode().substring(3); - try { - int id = Integer.parseInt(hex, 16); - return "http://geokrety.org/konkret.php?id=" + id; - } catch (NumberFormatException e) { - Log.e("Trackable.getUrl", e); - return null; - } - } - return "http://www.geocaching.com//track/details.aspx?tracker=" + geocode; + return getConnector().getUrl(this); + } + + private TrackableConnector getConnector() { + return ConnectorFactory.getConnector(this); } public String getGuid() { @@ -208,7 +203,7 @@ public class Trackable implements ILogable { } public boolean isLoggable() { - return !StringUtils.startsWithIgnoreCase(getGeocode(), "GK"); + return getConnector().isLoggable(); } public String getTrackingcode() { @@ -220,7 +215,7 @@ public class Trackable implements ILogable { } static public List<LogType> getPossibleLogTypes() { - List<LogType> logTypes = new ArrayList<LogType>(); + final List<LogType> logTypes = new ArrayList<LogType>(); logTypes.add(LogType.RETRIEVED_IT); logTypes.add(LogType.GRABBED_IT); logTypes.add(LogType.NOTE); diff --git a/main/src/cgeo/geocaching/connector/ConnectorFactory.java b/main/src/cgeo/geocaching/connector/ConnectorFactory.java index 3319fe4..1849e4b 100644 --- a/main/src/cgeo/geocaching/connector/ConnectorFactory.java +++ b/main/src/cgeo/geocaching/connector/ConnectorFactory.java @@ -12,6 +12,10 @@ import cgeo.geocaching.connector.oc.OCApiConnector.ApiSupport; import cgeo.geocaching.connector.oc.OCApiLiveConnector; import cgeo.geocaching.connector.oc.OCConnector; import cgeo.geocaching.connector.ox.OXConnector; +import cgeo.geocaching.connector.trackable.GeokretyConnector; +import cgeo.geocaching.connector.trackable.TrackableConnector; +import cgeo.geocaching.connector.trackable.TravelBugConnector; +import cgeo.geocaching.connector.trackable.UnknownTrackableConnector; import cgeo.geocaching.geopoint.Viewport; import org.apache.commons.lang3.StringUtils; @@ -40,21 +44,28 @@ public final class ConnectorFactory { UNKNOWN_CONNECTOR // the unknown connector MUST be the last one }; + public static final UnknownTrackableConnector UNKNOWN_TRACKABLE_CONNECTOR = new UnknownTrackableConnector(); + private static final TrackableConnector[] TRACKABLE_CONNECTORS = new TrackableConnector[] { + new TravelBugConnector(), + new GeokretyConnector(), + UNKNOWN_TRACKABLE_CONNECTOR // must be last + }; + private static final ISearchByViewPort[] searchByViewPortConns; private static final ISearchByCenter[] searchByCenterConns; static { - List<ISearchByViewPort> vpConns = new ArrayList<ISearchByViewPort>(); - for (IConnector conn : connectors) { + final List<ISearchByViewPort> vpConns = new ArrayList<ISearchByViewPort>(); + for (final IConnector conn : connectors) { if (conn instanceof ISearchByViewPort) { vpConns.add((ISearchByViewPort) conn); } } searchByViewPortConns = vpConns.toArray(new ISearchByViewPort[vpConns.size()]); - List<ISearchByCenter> centerConns = new ArrayList<ISearchByCenter>(); - for (IConnector conn : connectors) { + final List<ISearchByCenter> centerConns = new ArrayList<ISearchByCenter>(); + for (final IConnector conn : connectors) { // GCConnector is handled specially, omit it here! if (conn instanceof ISearchByCenter && !(conn instanceof GCConnector)) { centerConns.add((ISearchByCenter) conn); @@ -75,7 +86,7 @@ public final class ConnectorFactory { if (isInvalidGeocode(geocode)) { return false; } - for (IConnector connector : connectors) { + for (final IConnector connector : connectors) { if (connector.canHandle(geocode)) { return true; } @@ -87,8 +98,17 @@ public final class ConnectorFactory { return getConnector(cache.getGeocode()); } - public static IConnector getConnector(Trackable trackable) { - return getConnector(trackable.getGeocode()); + public static TrackableConnector getConnector(Trackable trackable) { + return getTrackableConnector(trackable.getGeocode()); + } + + public static TrackableConnector getTrackableConnector(String geocode) { + for (final TrackableConnector connector : TRACKABLE_CONNECTORS) { + if (connector.canHandleTrackable(geocode)) { + return connector; + } + } + return UNKNOWN_TRACKABLE_CONNECTOR; // avoid null checks by returning a non implementing connector } public static IConnector getConnector(final String geocodeInput) { @@ -97,12 +117,12 @@ public final class ConnectorFactory { if (isInvalidGeocode(geocode)) { return UNKNOWN_CONNECTOR; } - for (IConnector connector : connectors) { + for (final IConnector connector : connectors) { if (connector.canHandle(geocode)) { return connector; } } - // in case of errors, take UNKNOWN + // in case of errors, take UNKNOWN to avoid null checks everywhere return UNKNOWN_CONNECTOR; } @@ -113,10 +133,10 @@ public final class ConnectorFactory { /** @see ISearchByViewPort#searchByViewport */ public static SearchResult searchByViewport(final Viewport viewport, final String[] tokens) { - SearchResult result = new SearchResult(); - for (ISearchByViewPort vpconn : searchByViewPortConns) { + final SearchResult result = new SearchResult(); + for (final ISearchByViewPort vpconn : searchByViewPortConns) { if (vpconn.isActivated()) { - SearchResult temp = vpconn.searchByViewport(viewport, tokens); + final SearchResult temp = vpconn.searchByViewport(viewport, tokens); if (temp != null) { result.addGeocodes(temp.getGeocodes()); } @@ -126,8 +146,8 @@ public final class ConnectorFactory { } public static String getGeocodeFromURL(final String url) { - for (IConnector connector : connectors) { - String geocode = connector.getGeocodeFromUrl(url); + for (final IConnector connector : connectors) { + final String geocode = connector.getGeocodeFromUrl(url); if (StringUtils.isNotBlank(geocode)) { return geocode; } diff --git a/main/src/cgeo/geocaching/connector/gc/GCConnector.java b/main/src/cgeo/geocaching/connector/gc/GCConnector.java index d7fbbab..fab4332 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCConnector.java +++ b/main/src/cgeo/geocaching/connector/gc/GCConnector.java @@ -35,6 +35,11 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, */ private static final Pattern gpxZipFilePattern = Pattern.compile("((\\d{7,})|(pocketquery))" + "(_.+)?" + "\\.zip", Pattern.CASE_INSENSITIVE); + /** + * Pattern for GC codes + */ + private final static Pattern PATTERN_GC_CODE = Pattern.compile("GC[0-9A-Z]+", Pattern.CASE_INSENSITIVE); + private GCConnector() { // singleton } @@ -55,7 +60,7 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, if (geocode == null) { return false; } - return GCConstants.PATTERN_GC_CODE.matcher(geocode).matches() || GCConstants.PATTERN_TB_CODE.matcher(geocode).matches(); + return GCConnector.PATTERN_GC_CODE.matcher(geocode).matches(); } @Override diff --git a/main/src/cgeo/geocaching/connector/gc/GCConstants.java b/main/src/cgeo/geocaching/connector/gc/GCConstants.java index b4f5845..f2e2e69 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCConstants.java +++ b/main/src/cgeo/geocaching/connector/gc/GCConstants.java @@ -84,6 +84,7 @@ public final class GCConstants { public final static String ERROR_TB_DOES_NOT_EXIST = "does not exist in the system"; public final static String ERROR_TB_ELEMENT_EXCEPTION = "ElementNotFound Exception"; public final static String ERROR_TB_ARITHMETIC_OVERFLOW = "operation resulted in an overflow"; + public final static String ERROR_TB_NOT_ACTIVATED = "hasn't been activated"; /** * some parts of the webpage don't correctly encode the name, therefore this pattern must be checked with a * trackable name that needs HTML encoding @@ -157,12 +158,6 @@ public final class GCConstants { public final static Pattern PATTERN_VIEWSTATES = Pattern.compile("id=\"__VIEWSTATE(\\d*)\"[^(value)]+value=\"([^\"]+)\"[^>]+>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); public final static Pattern PATTERN_USERTOKEN = Pattern.compile("userToken\\s*=\\s*'([^']+)'"); - /** - * Patterns for GC and TB codes - */ - public final static Pattern PATTERN_GC_CODE = Pattern.compile("GC[0-9A-Z]+", Pattern.CASE_INSENSITIVE); - public final static Pattern PATTERN_TB_CODE = Pattern.compile("TB[0-9A-Z]+", Pattern.CASE_INSENSITIVE); - /** Live Map since 14.02.2012 */ public final static Pattern PATTERN_USERSESSION = Pattern.compile("UserSession\\('([^']+)'"); public final static Pattern PATTERN_SESSIONTOKEN = Pattern.compile("sessionToken:'([^']+)'"); @@ -194,7 +189,7 @@ public final class GCConstants { */ public static long gccodeToGCId(final String gccode) { long base = GC_BASE31; - String geocodeWO = gccode.substring(2).toUpperCase(Locale.US); + final String geocodeWO = gccode.substring(2).toUpperCase(Locale.US); if ((geocodeWO.length() < 4) || (geocodeWO.length() == 4 && SEQUENCE_GCID.indexOf(geocodeWO.charAt(0)) < 16)) { base = GC_BASE16; diff --git a/main/src/cgeo/geocaching/connector/gc/GCParser.java b/main/src/cgeo/geocaching/connector/gc/GCParser.java index 7154b08..a58b2cc 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCParser.java +++ b/main/src/cgeo/geocaching/connector/gc/GCParser.java @@ -28,10 +28,10 @@ import cgeo.geocaching.loaders.RecaptchaReceiver; import cgeo.geocaching.network.Network; import cgeo.geocaching.network.Parameters; import cgeo.geocaching.ui.DirectionImage; -import cgeo.geocaching.utils.TextUtils; import cgeo.geocaching.utils.CancellableHandler; import cgeo.geocaching.utils.Log; import cgeo.geocaching.utils.MatcherWrapper; +import cgeo.geocaching.utils.TextUtils; import ch.boye.httpclientandroidlib.HttpResponse; @@ -79,7 +79,7 @@ public abstract class GCParser { // recaptcha String recaptchaChallenge = null; if (showCaptcha) { - String recaptchaJsParam = TextUtils.getMatch(page, GCConstants.PATTERN_SEARCH_RECAPTCHA, false, null); + final String recaptchaJsParam = TextUtils.getMatch(page, GCConstants.PATTERN_SEARCH_RECAPTCHA, false, null); if (recaptchaJsParam != null) { final Parameters params = new Parameters("k", recaptchaJsParam.trim()); @@ -109,7 +109,7 @@ public abstract class GCParser { page = page.substring(startPos); // cut on <table startPos = page.indexOf('>'); - int endPos = page.indexOf("ctl00_ContentBody_UnitTxt"); + final int endPos = page.indexOf("ctl00_ContentBody_UnitTxt"); if (startPos == -1 || endPos == -1) { Log.e("GCParser.parseSearch: ID \"ctl00_ContentBody_UnitTxt\" not found on page"); return null; @@ -122,7 +122,7 @@ public abstract class GCParser { for (int z = 1; z < rows_count; z++) { final Geocache cache = new Geocache(); - String row = rows[z]; + final String row = rows[z]; // check for cache type presence if (!row.contains("images/wpttypes")) { @@ -150,7 +150,7 @@ public abstract class GCParser { } } } - } catch (Exception e) { + } catch (final Exception e) { // failed to parse GUID and/or Disabled Log.w("GCParser.parseSearch: Failed to parse GUID and/or Disabled data"); } @@ -203,7 +203,7 @@ public abstract class GCParser { if (matcherTbs.groupCount() > 0) { try { cache.setInventoryItems(Integer.parseInt(matcherTbs.group(1))); - } catch (NumberFormatException e) { + } catch (final NumberFormatException e) { Log.e("Error parsing trackables count", e); } inventoryPre = matcherTbs.group(2); @@ -241,7 +241,7 @@ public abstract class GCParser { if (null != result) { cache.setFavoritePoints(Integer.parseInt(result)); } - } catch (NumberFormatException e) { + } catch (final NumberFormatException e) { Log.w("GCParser.parseSearch: Failed to parse favorite count"); } @@ -250,11 +250,11 @@ public abstract class GCParser { // total caches found try { - String result = TextUtils.getMatch(page, GCConstants.PATTERN_SEARCH_TOTALCOUNT, false, 1, null, true); + final String result = TextUtils.getMatch(page, GCConstants.PATTERN_SEARCH_TOTALCOUNT, false, 1, null, true); if (null != result) { searchResult.setTotal(Integer.parseInt(result)); } - } catch (NumberFormatException e) { + } catch (final NumberFormatException e) { Log.w("GCParser.parseSearch: Failed to parse cache count"); } @@ -284,7 +284,7 @@ public abstract class GCParser { params.put("__VIEWSTATEFIELDCOUNT", String.valueOf(searchResult.viewstates.length)); } } - for (String cid : cids) { + for (final String cid : cids) { params.put("CID", cid); } @@ -308,7 +308,7 @@ public abstract class GCParser { LocParser.parseLoc(searchResult, coordinates); - } catch (Exception e) { + } catch (final Exception e) { Log.e("GCParser.parseSearch.CIDs", e); } } @@ -316,7 +316,7 @@ public abstract class GCParser { // get direction images if (Settings.getLoadDirImg()) { final Set<Geocache> caches = searchResult.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB); - for (Geocache cache : caches) { + for (final Geocache cache : caches) { if (cache.getCoords() == null && StringUtils.isNotEmpty(cache.getDirectionImg())) { DirectionImage.getDrawable(cache.getDirectionImg()); } @@ -327,7 +327,7 @@ public abstract class GCParser { } private static Float parseStars(final String value) { - float floatValue = Float.parseFloat(StringUtils.replaceChars(value, ',', '.')); + final float floatValue = Float.parseFloat(StringUtils.replaceChars(value, ',', '.')); return floatValue >= 0.5 && floatValue <= 5.0 ? floatValue : null; } @@ -408,7 +408,7 @@ public abstract class GCParser { String tableInside = page; - int pos = tableInside.indexOf(GCConstants.STRING_CACHEDETAILS); + final int pos = tableInside.indexOf(GCConstants.STRING_CACHEDETAILS); if (pos == -1) { Log.e("GCParser.parseCache: ID \"cacheDetails\" not found on page"); return null; @@ -422,7 +422,7 @@ public abstract class GCParser { if (result != null) { try { cache.setTerrain(Float.parseFloat(StringUtils.replaceChars(result, '_', '.'))); - } catch (NumberFormatException e) { + } catch (final NumberFormatException e) { Log.e("Error parsing terrain value", e); } } @@ -432,7 +432,7 @@ public abstract class GCParser { if (result != null) { try { cache.setDifficulty(Float.parseFloat(StringUtils.replaceChars(result, '_', '.'))); - } catch (NumberFormatException e) { + } catch (final NumberFormatException e) { Log.e("Error parsing difficulty value", e); } } @@ -453,7 +453,7 @@ public abstract class GCParser { cache.setHidden(Login.parseGcCustomDate(hiddenString)); } } - } catch (ParseException e) { + } catch (final ParseException e) { // failed to parse cache hidden date Log.w("GCParser.parseCache: Failed to parse cache hidden (event) date"); } @@ -461,7 +461,7 @@ public abstract class GCParser { // favorite try { cache.setFavoritePoints(Integer.parseInt(TextUtils.getMatch(tableInside, GCConstants.PATTERN_FAVORITECOUNT, true, "0"))); - } catch (NumberFormatException e) { + } catch (final NumberFormatException e) { Log.e("Error parsing favorite count", e); } @@ -478,7 +478,7 @@ public abstract class GCParser { if (StringUtils.isNotBlank(foundDateString)) { cache.setVisitedDate(Login.parseGcCustomDate(foundDateString).getTime()); } - } catch (ParseException e) { + } catch (final ParseException e) { // failed to parse cache found date Log.w("GCParser.parseCache: Failed to parse cache found date"); } @@ -495,7 +495,7 @@ public abstract class GCParser { try { cache.setCoords(new Geopoint(latlon)); cache.setReliableLatLon(true); - } catch (Geopoint.GeopointException e) { + } catch (final Geopoint.GeopointException e) { Log.w("GCParser.parseCache: Failed to parse cache coordinates", e); } } @@ -504,10 +504,10 @@ public abstract class GCParser { cache.setLocation(TextUtils.getMatch(page, GCConstants.PATTERN_LOCATION, true, "")); // cache hint - String result = TextUtils.getMatch(page, GCConstants.PATTERN_HINT, false, null); + final String result = TextUtils.getMatch(page, GCConstants.PATTERN_HINT, false, null); if (result != null) { // replace linebreak and paragraph tags - String hint = GCConstants.PATTERN_LINEBREAK.matcher(result).replaceAll("\n"); + final String hint = GCConstants.PATTERN_LINEBREAK.matcher(result).replaceAll("\n"); if (hint != null) { cache.setHint(StringUtils.replace(hint, "</p>", "").trim()); } @@ -539,8 +539,8 @@ public abstract class GCParser { // if the image name can be recognized, use the image name as attribute final String imageName = matcherAttributesInside.group(1).trim(); if (StringUtils.isNotEmpty(imageName)) { - int start = imageName.lastIndexOf('/'); - int end = imageName.lastIndexOf('.'); + final int start = imageName.lastIndexOf('/'); + final int end = imageName.lastIndexOf('.'); if (start >= 0 && end >= 0) { attribute = imageName.substring(start + 1, end).replace('-', '_').toLowerCase(Locale.US); } @@ -550,7 +550,7 @@ public abstract class GCParser { } cache.setAttributes(attributes); } - } catch (Exception e) { + } catch (final Exception e) { // failed to parse cache attributes Log.w("GCParser.parseCache: Failed to parse cache attributes"); } @@ -567,7 +567,7 @@ public abstract class GCParser { while (matcherSpoilersInside.find()) { // the original spoiler URL (include .../display/... contains a low-resolution image // if we shorten the URL we get the original-resolution image - String url = matcherSpoilersInside.group(1).replace("/display", ""); + final String url = matcherSpoilersInside.group(1).replace("/display", ""); String title = null; if (matcherSpoilersInside.group(3) != null) { @@ -579,7 +579,7 @@ public abstract class GCParser { } cache.addSpoiler(new Image(url, title, description)); } - } catch (Exception e) { + } catch (final Exception e) { // failed to parse cache spoilers Log.w("GCParser.parseCache: Failed to parse cache spoilers"); } @@ -613,7 +613,7 @@ public abstract class GCParser { } } } - } catch (Exception e) { + } catch (final Exception e) { // failed to parse cache inventory Log.w("GCParser.parseCache: Failed to parse cache inventory (2)"); } @@ -625,8 +625,8 @@ public abstract class GCParser { final MatcherWrapper matcherLog = new MatcherWrapper(GCConstants.PATTERN_COUNTLOG, countlogs); while (matcherLog.find()) { - String typeStr = matcherLog.group(1); - String countStr = matcherLog.group(2).replaceAll("[.,]", ""); + final String typeStr = matcherLog.group(1); + final String countStr = matcherLog.group(2).replaceAll("[.,]", ""); if (StringUtils.isNotBlank(typeStr) && LogType.UNKNOWN != LogType.getByIconName(typeStr) @@ -635,7 +635,7 @@ public abstract class GCParser { } } } - } catch (Exception e) { + } catch (final Exception e) { // failed to parse logs Log.w("GCParser.parseCache: Failed to parse cache log count"); } @@ -653,7 +653,7 @@ public abstract class GCParser { cache.addOrChangeWaypoint(waypoint, false); cache.setUserModifiedCoords(true); } - } catch (Geopoint.GeopointException e) { + } catch (final Geopoint.GeopointException e) { } int wpBegin = page.indexOf("<table class=\"Table\" id=\"ctl00_ContentBody_Waypoints\">"); @@ -785,7 +785,7 @@ public abstract class GCParser { // save to application search.setError(searchResult.getError()); search.setViewstates(searchResult.viewstates); - for (String geocode : searchResult.getGeocodes()) { + for (final String geocode : searchResult.getGeocodes()) { search.addGeocode(geocode); } return search; @@ -896,7 +896,7 @@ public abstract class GCParser { return null; } try { - JSONObject response = Network.requestJSON("http://www.geocaching.com/api/geocode", new Parameters("q", address)); + final JSONObject response = Network.requestJSON("http://www.geocaching.com/api/geocode", new Parameters("q", address)); if (response == null) { return null; } @@ -906,12 +906,12 @@ public abstract class GCParser { if (!response.has("data")) { return null; } - JSONObject data = response.getJSONObject("data"); + final JSONObject data = response.getJSONObject("data"); if (data == null) { return null; } return searchByCoords(new Geopoint(data.getDouble("lat"), data.getDouble("lng")), cacheType, showCaptcha, recaptchaReceiver); - } catch (JSONException e) { + } catch (final JSONException e) { Log.w("GCParser.searchByAddress", e); } @@ -1036,7 +1036,7 @@ public abstract class GCParser { if (trackables != null && !trackables.isEmpty()) { // we have some trackables to proceed final StringBuilder hdnSelected = new StringBuilder(); - for (TrackableLog tb : trackables) { + for (final TrackableLog tb : trackables) { final String action = Integer.toString(tb.id) + tb.action.action; final StringBuilder paramText = new StringBuilder("ctl00$ContentBody$LogBookPanel1$uxTrackables$repTravelBugs$ctl"); @@ -1057,7 +1057,7 @@ public abstract class GCParser { page = Network.getResponseData(Network.postRequest(uri, params)); } - } catch (Exception e) { + } catch (final Exception e) { Log.e("GCParser.postLog.confim", e); } @@ -1081,7 +1081,7 @@ public abstract class GCParser { return new ImmutablePair<StatusCode, String>(StatusCode.NO_ERROR, logID); } - } catch (Exception e) { + } catch (final Exception e) { Log.e("GCParser.postLog.check", e); } @@ -1131,7 +1131,7 @@ public abstract class GCParser { final File image = new File(imageUri.getPath()); final String response = Network.getResponseData(Network.postRequest(uri, uploadParams, "ctl00$ContentBody$ImageUploadControl1$uxFileUpload", "image/jpeg", image)); - MatcherWrapper matcherUrl = new MatcherWrapper(GCConstants.PATTERN_IMAGE_UPLOAD_URL, response); + final MatcherWrapper matcherUrl = new MatcherWrapper(GCConstants.PATTERN_IMAGE_UPLOAD_URL, response); if (matcherUrl.find()) { Log.i("Logimage successfully uploaded."); @@ -1206,7 +1206,7 @@ public abstract class GCParser { Log.i("Log successfully posted to trackable #" + trackingCode); return StatusCode.NO_ERROR; } - } catch (Exception e) { + } catch (final Exception e) { Log.e("GCParser.postLogTrackable.check", e); } @@ -1223,14 +1223,14 @@ public abstract class GCParser { */ static boolean addToWatchlist(final Geocache cache) { final String uri = "http://www.geocaching.com/my/watchlist.aspx?w=" + cache.getCacheId(); - String page = Login.postRequestLogged(uri, null); + final String page = Login.postRequestLogged(uri, null); if (StringUtils.isBlank(page)) { Log.e("GCParser.addToWatchlist: No data from server"); return false; // error } - boolean guidOnPage = cache.isGuidContainedInPage(page); + final boolean guidOnPage = cache.isGuidContainedInPage(page); if (guidOnPage) { Log.i("GCParser.addToWatchlist: cache is on watchlist"); cache.setOnWatchlist(true); @@ -1264,7 +1264,7 @@ public abstract class GCParser { Login.transferViewstates(page, params); page = Network.getResponseData(Network.postRequest(uri, params)); - boolean guidOnPage = cache.isGuidContainedInPage(page); + final boolean guidOnPage = cache.isGuidContainedInPage(page); if (!guidOnPage) { Log.i("GCParser.removeFromWatchlist: cache removed from watchlist"); cache.setOnWatchlist(false); @@ -1309,7 +1309,7 @@ public abstract class GCParser { final String uri = "http://www.geocaching.com/datastore/favorites.svc/update?u=" + userToken + "&f=" + Boolean.toString(add); - HttpResponse response = Network.postRequest(uri, null); + final HttpResponse response = Network.postRequest(uri, null); if (response != null && response.getStatusLine().getStatusCode() == 200) { Log.i("GCParser.changeFavorite: cache added/removed to/from favorites"); @@ -1354,7 +1354,7 @@ public abstract class GCParser { final Trackable trackable = new Trackable(); // trackable geocode - trackable.setGeocode(TextUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_GEOCODE, true, trackable.getGeocode())); + trackable.setGeocode(TextUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_GEOCODE, true, StringUtils.upperCase(possibleTrackingcode))); // trackable id trackable.setGuid(TextUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_GUID, true, trackable.getGuid())); @@ -1377,7 +1377,7 @@ public abstract class GCParser { trackable.setOwnerGuid(matcherOwner.group(1)); trackable.setOwner(matcherOwner.group(2).trim()); } - } catch (Exception e) { + } catch (final Exception e) { // failed to parse trackable owner name Log.w("GCParser.parseTrackable: Failed to parse trackable owner name"); } @@ -1408,21 +1408,21 @@ public abstract class GCParser { if (TextUtils.matches(page, GCConstants.PATTERN_TRACKABLE_SPOTTEDOWNER)) { trackable.setSpottedType(Trackable.SPOTTED_OWNER); } - } catch (Exception e) { + } catch (final Exception e) { // failed to parse trackable last known place Log.w("GCParser.parseTrackable: Failed to parse trackable last known place"); } // released date - can be missing on the page try { - String releaseString = TextUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_RELEASES, false, null); + final String releaseString = TextUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_RELEASES, false, null); if (releaseString != null) { trackable.setReleased(dateTbIn1.parse(releaseString)); if (trackable.getReleased() == null) { trackable.setReleased(dateTbIn2.parse(releaseString)); } } - } catch (ParseException e1) { + } catch (final ParseException e1) { trackable.setReleased(null); } @@ -1431,7 +1431,7 @@ public abstract class GCParser { if (null != distance) { try { trackable.setDistance(DistanceParser.parseDistance(distance, Settings.isUseMetricUnits())); - } catch (NumberFormatException e) { + } catch (final NumberFormatException e) { Log.e("GCParser.parseTrackable: Failed to parse distance", e); } } @@ -1453,10 +1453,13 @@ public abstract class GCParser { trackable.setDetails(convertLinks(details)); } } - } catch (Exception e) { + } catch (final Exception e) { // failed to parse trackable details & image Log.w("GCParser.parseTrackable: Failed to parse trackable details & image"); } + if (StringUtils.isEmpty(trackable.getDetails()) && page.contains(GCConstants.ERROR_TB_NOT_ACTIVATED)) { + trackable.setDetails(cgeoapplication.getInstance().getString(R.string.trackable_not_activated)); + } // trackable logs try { @@ -1474,7 +1477,7 @@ public abstract class GCParser { long date = 0; try { date = Login.parseGcCustomDate(matcherLogs.group(2)).getTime(); - } catch (ParseException e) { + } catch (final ParseException e) { } final LogEntry logDone = new LogEntry( @@ -1502,7 +1505,7 @@ public abstract class GCParser { trackable.getLogs().add(logDone); } - } catch (Exception e) { + } catch (final Exception e) { // failed to parse logs Log.w("GCParser.parseCache: Failed to parse cache logs", e); } @@ -1575,7 +1578,7 @@ public abstract class GCParser { rawResponse = TextUtils.getMatch(page, GCConstants.PATTERN_LOGBOOK, ""); } - List<LogEntry> logs = new ArrayList<LogEntry>(); + final List<LogEntry> logs = new ArrayList<LogEntry>(); try { final JSONObject resp = new JSONObject(rawResponse); @@ -1596,7 +1599,7 @@ public abstract class GCParser { long date = 0; try { date = Login.parseGcCustomDate(entry.getString("Visited")).getTime(); - } catch (ParseException e) { + } catch (final ParseException e) { Log.e("GCParser.loadLogsFromDetails: failed to parse log date."); } @@ -1624,7 +1627,7 @@ public abstract class GCParser { logs.add(logDone); } - } catch (JSONException e) { + } catch (final JSONException e) { // failed to parse logs Log.w("GCParser.loadLogsFromDetails: Failed to parse cache logs", e); } @@ -1641,16 +1644,16 @@ public abstract class GCParser { final MatcherWrapper typeBoxMatcher = new MatcherWrapper(GCConstants.PATTERN_TYPEBOX, page); if (typeBoxMatcher.find() && typeBoxMatcher.groupCount() > 0) { - String typesText = typeBoxMatcher.group(1); + final String typesText = typeBoxMatcher.group(1); final MatcherWrapper typeMatcher = new MatcherWrapper(GCConstants.PATTERN_TYPE2, typesText); while (typeMatcher.find()) { if (typeMatcher.groupCount() > 1) { try { - int type = Integer.parseInt(typeMatcher.group(2)); + final int type = Integer.parseInt(typeMatcher.group(2)); if (type > 0) { types.add(LogType.getById(type)); } - } catch (NumberFormatException e) { + } catch (final NumberFormatException e) { Log.e("Error parsing log types", e); } } @@ -1698,7 +1701,7 @@ public abstract class GCParser { Log.i("Trackable in inventory (#" + entry.ctl + "/" + entry.id + "): " + entry.trackCode + " - " + entry.name); trackableLogs.add(entry); } - } catch (NumberFormatException e) { + } catch (final NumberFormatException e) { Log.e("GCParser.parseTrackableLog", e); } } @@ -1727,10 +1730,10 @@ public abstract class GCParser { //cache.setLogs(loadLogsFromDetails(page, cache, false)); if (Settings.isFriendLogsWanted()) { CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_logs); - List<LogEntry> allLogs = cache.getLogs(); - List<LogEntry> friendLogs = loadLogsFromDetails(page, cache, true, false); + final List<LogEntry> allLogs = cache.getLogs(); + final List<LogEntry> friendLogs = loadLogsFromDetails(page, cache, true, false); if (friendLogs != null) { - for (LogEntry log : friendLogs) { + for (final LogEntry log : friendLogs) { if (allLogs.contains(log)) { allLogs.get(allLogs.indexOf(log)).friend = true; } else { @@ -1793,7 +1796,7 @@ public abstract class GCParser { final String uriSuffix = wpt != null ? "SetUserCoordinate" : "ResetUserCoordinate"; final String uriPrefix = "http://www.geocaching.com/seek/cache_details.aspx/"; - HttpResponse response = Network.postJsonRequest(uriPrefix + uriSuffix, jo); + final HttpResponse response = Network.postJsonRequest(uriPrefix + uriSuffix, jo); Log.i("Sending to " + uriPrefix + uriSuffix + " :" + jo.toString()); if (response != null && response.getStatusLine().getStatusCode() == 200) { @@ -1801,7 +1804,7 @@ public abstract class GCParser { return true; } - } catch (JSONException e) { + } catch (final JSONException e) { Log.e("Unknown exception with json wrap code", e); } Log.e("GCParser.deleteModifiedCoordinates - cannot delete modified coords"); @@ -1816,7 +1819,7 @@ public abstract class GCParser { } try { - JSONObject jo = new JSONObject() + final JSONObject jo = new JSONObject() .put("dto", (new JSONObject() .put("et", cache.getPersonalNote()) .put("ut", userToken))); @@ -1824,7 +1827,7 @@ public abstract class GCParser { final String uriSuffix = "SetUserCacheNote"; final String uriPrefix = "http://www.geocaching.com/seek/cache_details.aspx/"; - HttpResponse response = Network.postJsonRequest(uriPrefix + uriSuffix, jo); + final HttpResponse response = Network.postJsonRequest(uriPrefix + uriSuffix, jo); Log.i("Sending to " + uriPrefix + uriSuffix + " :" + jo.toString()); if (response != null && response.getStatusLine().getStatusCode() == 200) { @@ -1832,7 +1835,7 @@ public abstract class GCParser { return true; } - } catch (JSONException e) { + } catch (final JSONException e) { Log.e("Unknown exception with json wrap code", e); } Log.e("GCParser.uploadPersonalNote - cannot upload personal note"); diff --git a/main/src/cgeo/geocaching/connector/trackable/AbstractTrackableConnector.java b/main/src/cgeo/geocaching/connector/trackable/AbstractTrackableConnector.java new file mode 100644 index 0000000..cd32d87 --- /dev/null +++ b/main/src/cgeo/geocaching/connector/trackable/AbstractTrackableConnector.java @@ -0,0 +1,10 @@ +package cgeo.geocaching.connector.trackable; + + +public abstract class AbstractTrackableConnector implements TrackableConnector { + + @Override + public boolean isLoggable() { + return false; + } +} diff --git a/main/src/cgeo/geocaching/connector/trackable/GeokretyConnector.java b/main/src/cgeo/geocaching/connector/trackable/GeokretyConnector.java new file mode 100644 index 0000000..a351ebd --- /dev/null +++ b/main/src/cgeo/geocaching/connector/trackable/GeokretyConnector.java @@ -0,0 +1,32 @@ +package cgeo.geocaching.connector.trackable; + +import cgeo.geocaching.Trackable; +import cgeo.geocaching.utils.Log; + +import java.util.regex.Pattern; + +public class GeokretyConnector extends AbstractTrackableConnector { + + private static final Pattern PATTERN_GK_CODE = Pattern.compile("GK[0-9A-F]{4,}"); + + @Override + public boolean canHandleTrackable(String geocode) { + return geocode != null && PATTERN_GK_CODE.matcher(geocode).matches(); + } + + @Override + public String getUrl(Trackable trackable) { + return "http://geokrety.org/konkret.php?id=" + getId(trackable); + } + + private static int getId(Trackable trackable) { + try { + final String hex = trackable.getGeocode().substring(2); + return Integer.parseInt(hex, 16); + } catch (final NumberFormatException e) { + Log.e("Trackable.getUrl", e); + } + return -1; + } + +} diff --git a/main/src/cgeo/geocaching/connector/trackable/TrackableConnector.java b/main/src/cgeo/geocaching/connector/trackable/TrackableConnector.java new file mode 100644 index 0000000..7df8560 --- /dev/null +++ b/main/src/cgeo/geocaching/connector/trackable/TrackableConnector.java @@ -0,0 +1,17 @@ +package cgeo.geocaching.connector.trackable; + +import cgeo.geocaching.Trackable; + +/** + * Methods to be implemented by any connector for handling trackables + * + */ +public interface TrackableConnector { + + public boolean canHandleTrackable(final String geocode); + + public String getUrl(final Trackable trackable); + + public boolean isLoggable(); + +} diff --git a/main/src/cgeo/geocaching/connector/trackable/TravelBugConnector.java b/main/src/cgeo/geocaching/connector/trackable/TravelBugConnector.java new file mode 100644 index 0000000..74e0ec5 --- /dev/null +++ b/main/src/cgeo/geocaching/connector/trackable/TravelBugConnector.java @@ -0,0 +1,28 @@ +package cgeo.geocaching.connector.trackable; + +import cgeo.geocaching.Trackable; + +import java.util.regex.Pattern; + +public class TravelBugConnector extends AbstractTrackableConnector { + + /** + * TB codes really start with TB1, there is no padding or minimum length + */ + private final static Pattern PATTERN_TB_CODE = Pattern.compile("TB[0-9A-Z]+", Pattern.CASE_INSENSITIVE); + + @Override + public boolean canHandleTrackable(String geocode) { + return TravelBugConnector.PATTERN_TB_CODE.matcher(geocode).matches(); + } + + @Override + public String getUrl(Trackable trackable) { + return "http://www.geocaching.com//track/details.aspx?tracker=" + trackable.getGeocode(); + } + + @Override + public boolean isLoggable() { + return true; + } +}
\ No newline at end of file diff --git a/main/src/cgeo/geocaching/connector/trackable/UnknownTrackableConnector.java b/main/src/cgeo/geocaching/connector/trackable/UnknownTrackableConnector.java new file mode 100644 index 0000000..17fa680 --- /dev/null +++ b/main/src/cgeo/geocaching/connector/trackable/UnknownTrackableConnector.java @@ -0,0 +1,19 @@ +package cgeo.geocaching.connector.trackable; + +import cgeo.geocaching.Trackable; + +import org.apache.commons.lang3.StringUtils; + +public class UnknownTrackableConnector extends AbstractTrackableConnector { + + @Override + public boolean canHandleTrackable(String geocode) { + return false; + } + + @Override + public String getUrl(Trackable trackable) { + return StringUtils.EMPTY; + } + +} |
