aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/cgeo/geocaching/connector
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/cgeo/geocaching/connector')
-rw-r--r--main/src/cgeo/geocaching/connector/ConnectorFactory.java69
-rw-r--r--main/src/cgeo/geocaching/connector/ILoggingManager.java13
-rw-r--r--main/src/cgeo/geocaching/connector/NoLoggingManager.java2
-rw-r--r--main/src/cgeo/geocaching/connector/capability/ILogin.java57
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCConnector.java58
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCConstants.java9
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCLoggingManager.java4
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCParser.java272
-rw-r--r--main/src/cgeo/geocaching/connector/gc/Login.java76
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OCApiLiveConnector.java34
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OkapiClient.java120
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OkapiLoggingManager.java6
-rw-r--r--main/src/cgeo/geocaching/connector/oc/UserInfo.java41
-rw-r--r--main/src/cgeo/geocaching/connector/trackable/AbstractTrackableConnector.java10
-rw-r--r--main/src/cgeo/geocaching/connector/trackable/GeokretyConnector.java42
-rw-r--r--main/src/cgeo/geocaching/connector/trackable/GeokretyParser.java82
-rw-r--r--main/src/cgeo/geocaching/connector/trackable/TrackableConnector.java19
-rw-r--r--main/src/cgeo/geocaching/connector/trackable/TravelBugConnector.java50
-rw-r--r--main/src/cgeo/geocaching/connector/trackable/UnknownTrackableConnector.java24
19 files changed, 698 insertions, 290 deletions
diff --git a/main/src/cgeo/geocaching/connector/ConnectorFactory.java b/main/src/cgeo/geocaching/connector/ConnectorFactory.java
index 3319fe4..c5a083c 100644
--- a/main/src/cgeo/geocaching/connector/ConnectorFactory.java
+++ b/main/src/cgeo/geocaching/connector/ConnectorFactory.java
@@ -4,6 +4,7 @@ import cgeo.geocaching.ICache;
import cgeo.geocaching.R;
import cgeo.geocaching.SearchResult;
import cgeo.geocaching.Trackable;
+import cgeo.geocaching.connector.capability.ILogin;
import cgeo.geocaching.connector.capability.ISearchByCenter;
import cgeo.geocaching.connector.capability.ISearchByViewPort;
import cgeo.geocaching.connector.gc.GCConnector;
@@ -12,6 +13,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;
@@ -21,9 +26,9 @@ import java.util.List;
public final class ConnectorFactory {
private static final UnknownConnector UNKNOWN_CONNECTOR = new UnknownConnector();
- private static final IConnector[] connectors = new IConnector[] {
+ private static final IConnector[] CONNECTORS = new IConnector[] {
GCConnector.getInstance(),
- new OCApiLiveConnector("Opencaching.de", "www.opencaching.de", "OC", R.string.oc_de_okapi_consumer_key, R.string.oc_de_okapi_consumer_secret, ApiSupport.current),
+ new OCApiLiveConnector("opencaching.de", "www.opencaching.de", "OC", R.string.oc_de_okapi_consumer_key, R.string.oc_de_okapi_consumer_secret, ApiSupport.current),
new OCConnector("OpenCaching.CZ", "www.opencaching.cz", "OZ"),
new OCApiConnector("OpenCaching.CO.UK", "www.opencaching.org.uk", "OK", "arU4okouc4GEjMniE2fq", ApiSupport.oldapi),
new OCConnector("OpenCaching.ES", "www.opencachingspain.es", "OC"),
@@ -40,21 +45,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 GeokretyConnector(), // GK must be first, as it overlaps with the secret codes of travel bugs
+ TravelBugConnector.getInstance(),
+ 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);
@@ -64,18 +76,28 @@ public final class ConnectorFactory {
}
public static IConnector[] getConnectors() {
- return connectors;
+ return CONNECTORS;
}
public static ISearchByCenter[] getSearchByCenterConnectors() {
return searchByCenterConns;
}
+ public static ILogin[] getActiveLiveConnectors() {
+ final List<ILogin> liveConns = new ArrayList<ILogin>();
+ for (final IConnector conn : CONNECTORS) {
+ if (conn instanceof ILogin && conn.isActivated()) {
+ liveConns.add((ILogin) conn);
+ }
+ }
+ return liveConns.toArray(new ILogin[liveConns.size()]);
+ }
+
public static boolean canHandle(final String geocode) {
if (isInvalidGeocode(geocode)) {
return false;
}
- for (IConnector connector : connectors) {
+ for (final IConnector connector : CONNECTORS) {
if (connector.canHandle(geocode)) {
return true;
}
@@ -87,8 +109,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 +128,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 +144,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 +157,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;
}
@@ -135,4 +166,8 @@ public final class ConnectorFactory {
return null;
}
+ public static TrackableConnector[] getTrackableConnectors() {
+ return TRACKABLE_CONNECTORS;
+ }
+
}
diff --git a/main/src/cgeo/geocaching/connector/ILoggingManager.java b/main/src/cgeo/geocaching/connector/ILoggingManager.java
index f0029f9..c5586b3 100644
--- a/main/src/cgeo/geocaching/connector/ILoggingManager.java
+++ b/main/src/cgeo/geocaching/connector/ILoggingManager.java
@@ -11,10 +11,23 @@ import java.util.List;
public interface ILoggingManager {
+ /**
+ * Post a log for a cache online
+ *
+ * @param cache
+ * @param logType
+ * @param date
+ * @param log
+ * @param logPassword
+ * optional, maybe null
+ * @param trackableLogs
+ * @return
+ */
LogResult postLog(Geocache cache,
LogType logType,
Calendar date,
String log,
+ String logPassword,
List<TrackableLog> trackableLogs);
ImageResult postLogImage(String logId,
diff --git a/main/src/cgeo/geocaching/connector/NoLoggingManager.java b/main/src/cgeo/geocaching/connector/NoLoggingManager.java
index bfea4ca..04a73c1 100644
--- a/main/src/cgeo/geocaching/connector/NoLoggingManager.java
+++ b/main/src/cgeo/geocaching/connector/NoLoggingManager.java
@@ -19,7 +19,7 @@ public class NoLoggingManager implements ILoggingManager {
}
@Override
- public LogResult postLog(Geocache cache, LogType logType, Calendar date, String log, List<TrackableLog> trackableLogs) {
+ public LogResult postLog(Geocache cache, LogType logType, Calendar date, String log, String logPassword, List<TrackableLog> trackableLogs) {
return new LogResult(StatusCode.LOG_POST_ERROR, "");
}
diff --git a/main/src/cgeo/geocaching/connector/capability/ILogin.java b/main/src/cgeo/geocaching/connector/capability/ILogin.java
new file mode 100644
index 0000000..4a839c8
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/capability/ILogin.java
@@ -0,0 +1,57 @@
+package cgeo.geocaching.connector.capability;
+
+import cgeo.geocaching.connector.IConnector;
+
+import android.content.Context;
+import android.os.Handler;
+
+public interface ILogin extends IConnector {
+
+
+ /**
+ * Contacts the server the connector belongs to
+ * and verifies/establishes authentication and
+ * retrieves information about the current user
+ * (Name, found caches) if applicable.
+ *
+ * @param handler
+ * Handler to receive status feedback
+ * @param fromActivity
+ * Calling activity context
+ * @return true in case of success, false in case of failure
+ */
+ boolean login(Handler handler, Context fromActivity);
+
+ /**
+ * Returns the status of the last {@link}login() request
+ *
+ * @return
+ */
+ boolean isLoggedIn();
+
+ /**
+ * User-centered string describing the current login/connection status
+ *
+ * @return
+ */
+ String getLoginStatusString();
+
+ /**
+ * Name the user has in this connector or empty string if not applicable
+ * It might be necessary to execute login before this information is valid.
+ *
+ * @return
+ */
+ String getUserName();
+
+ /**
+ * Number of caches the user has found in this connector
+ * Normally retrieved/updated with (@see login).
+ * Might be out dated as changes on the connectors site
+ * are generally not notified.
+ *
+ * @return
+ */
+ int getCachesFound();
+
+}
diff --git a/main/src/cgeo/geocaching/connector/gc/GCConnector.java b/main/src/cgeo/geocaching/connector/gc/GCConnector.java
index 9b2a84a..33bb1ce 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCConnector.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCConnector.java
@@ -5,9 +5,12 @@ import cgeo.geocaching.ICache;
import cgeo.geocaching.R;
import cgeo.geocaching.SearchResult;
import cgeo.geocaching.Settings;
+import cgeo.geocaching.SettingsActivity;
import cgeo.geocaching.cgData;
+import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.connector.AbstractConnector;
import cgeo.geocaching.connector.ILoggingManager;
+import cgeo.geocaching.connector.capability.ILogin;
import cgeo.geocaching.connector.capability.ISearchByCenter;
import cgeo.geocaching.connector.capability.ISearchByGeocode;
import cgeo.geocaching.connector.capability.ISearchByViewPort;
@@ -21,10 +24,12 @@ import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import android.app.Activity;
+import android.content.Context;
+import android.os.Handler;
import java.util.regex.Pattern;
-public class GCConnector extends AbstractConnector implements ISearchByGeocode, ISearchByCenter, ISearchByViewPort {
+public class GCConnector extends AbstractConnector implements ISearchByGeocode, ISearchByCenter, ISearchByViewPort, ILogin {
private static final String CACHE_URL_SHORT = "http://coord.info/";
// Double slash is used to force open in browser
@@ -35,6 +40,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 +65,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
@@ -105,7 +115,7 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode,
@Override
public String getName() {
- return "GeoCaching.com";
+ return "geocaching.com";
}
@Override
@@ -282,4 +292,46 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode,
}
return R.drawable.marker;
}
+
+ @Override
+ public boolean login(Handler handler, Context fromActivity) {
+ // login
+ final StatusCode status = Login.login();
+
+ if (status == StatusCode.NO_ERROR) {
+ cgeoapplication.getInstance().firstRun = false;
+ Login.detectGcCustomDate();
+ }
+
+ if (cgeoapplication.getInstance().showLoginToast && handler != null) {
+ handler.sendMessage(handler.obtainMessage(0, status));
+ cgeoapplication.getInstance().showLoginToast = false;
+
+ // invoke settings activity to insert login details
+ if (status == StatusCode.NO_LOGIN_INFO_STORED && fromActivity != null) {
+ SettingsActivity.startActivity(fromActivity);
+ }
+ }
+ return status == StatusCode.NO_ERROR;
+ }
+
+ @Override
+ public String getUserName() {
+ return Login.getActualUserName();
+ }
+
+ @Override
+ public int getCachesFound() {
+ return Login.getActualCachesFound();
+ }
+
+ @Override
+ public String getLoginStatusString() {
+ return Login.getActualStatus();
+ }
+
+ @Override
+ public boolean isLoggedIn() {
+ return Login.isActualLoginStatus();
+ }
}
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/GCLoggingManager.java b/main/src/cgeo/geocaching/connector/gc/GCLoggingManager.java
index 4f2f8c4..dd150de 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCLoggingManager.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCLoggingManager.java
@@ -1,10 +1,10 @@
package cgeo.geocaching.connector.gc;
import cgeo.geocaching.Geocache;
+import cgeo.geocaching.LogCacheActivity;
import cgeo.geocaching.R;
import cgeo.geocaching.Settings;
import cgeo.geocaching.TrackableLog;
-import cgeo.geocaching.LogCacheActivity;
import cgeo.geocaching.activity.ActivityMixin;
import cgeo.geocaching.connector.ILoggingManager;
import cgeo.geocaching.connector.ImageResult;
@@ -80,7 +80,7 @@ public class GCLoggingManager implements ILoggingManager, LoaderManager.LoaderCa
}
@Override
- public LogResult postLog(Geocache cache, LogType logType, Calendar date, String log, List<TrackableLog> trackableLogs) {
+ public LogResult postLog(Geocache cache, LogType logType, Calendar date, String log, String logPassword, List<TrackableLog> trackableLogs) {
try {
final ImmutablePair<StatusCode, String> postResult = GCParser.postLog(cache.getGeocode(), cache.getCacheId(), viewstates, logType,
diff --git a/main/src/cgeo/geocaching/connector/gc/GCParser.java b/main/src/cgeo/geocaching/connector/gc/GCParser.java
index 15958ba..3e26eb2 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.BaseUtils;
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,14 +79,14 @@ public abstract class GCParser {
// recaptcha
String recaptchaChallenge = null;
if (showCaptcha) {
- String recaptchaJsParam = BaseUtils.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());
final String recaptchaJs = Network.getResponseData(Network.getRequest("http://www.google.com/recaptcha/api/challenge", params));
if (StringUtils.isNotBlank(recaptchaJs)) {
- recaptchaChallenge = BaseUtils.getMatch(recaptchaJs, GCConstants.PATTERN_SEARCH_RECAPTCHACHALLENGE, true, 1, null, true);
+ recaptchaChallenge = TextUtils.getMatch(recaptchaJs, GCConstants.PATTERN_SEARCH_RECAPTCHACHALLENGE, true, 1, null, true);
}
}
if (thread != null && StringUtils.isNotBlank(recaptchaChallenge)) {
@@ -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");
}
@@ -160,21 +160,21 @@ public abstract class GCParser {
continue;
}
- cache.setGeocode(BaseUtils.getMatch(row, GCConstants.PATTERN_SEARCH_GEOCODE, true, 1, cache.getGeocode(), true));
+ cache.setGeocode(TextUtils.getMatch(row, GCConstants.PATTERN_SEARCH_GEOCODE, true, 1, cache.getGeocode(), true));
// cache type
- cache.setType(CacheType.getByPattern(BaseUtils.getMatch(row, GCConstants.PATTERN_SEARCH_TYPE, true, 1, null, true)));
+ cache.setType(CacheType.getByPattern(TextUtils.getMatch(row, GCConstants.PATTERN_SEARCH_TYPE, true, 1, null, true)));
// cache direction - image
if (Settings.getLoadDirImg()) {
- final String direction = BaseUtils.getMatch(row, GCConstants.PATTERN_SEARCH_DIRECTION_DISTANCE, false, 1, null, false);
+ final String direction = TextUtils.getMatch(row, GCConstants.PATTERN_SEARCH_DIRECTION_DISTANCE, false, 1, null, false);
if (direction != null) {
cache.setDirectionImg(direction);
}
}
// cache distance - estimated distance for basic members
- final String distance = BaseUtils.getMatch(row, GCConstants.PATTERN_SEARCH_DIRECTION_DISTANCE, false, 2, null, false);
+ final String distance = TextUtils.getMatch(row, GCConstants.PATTERN_SEARCH_DIRECTION_DISTANCE, false, 2, null, false);
if (distance != null) {
cache.setDistance(DistanceParser.parseDistance(distance, Settings.isUseMetricUnits()));
}
@@ -193,7 +193,7 @@ public abstract class GCParser {
}
// size
- final String container = BaseUtils.getMatch(row, GCConstants.PATTERN_SEARCH_CONTAINER, false, 1, null, false);
+ final String container = TextUtils.getMatch(row, GCConstants.PATTERN_SEARCH_CONTAINER, false, 1, null, false);
cache.setSize(CacheSize.getById(container));
// cache inventory
@@ -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);
@@ -229,7 +229,7 @@ public abstract class GCParser {
cache.setFound(row.contains("/images/icons/16/found.png"));
// id
- String result = BaseUtils.getMatch(row, GCConstants.PATTERN_SEARCH_ID, null);
+ String result = TextUtils.getMatch(row, GCConstants.PATTERN_SEARCH_ID, null);
if (null != result) {
cache.setCacheId(result);
cids.add(cache.getCacheId());
@@ -237,11 +237,11 @@ public abstract class GCParser {
// favorite count
try {
- result = BaseUtils.getMatch(row, GCConstants.PATTERN_SEARCH_FAVORITE, false, 1, null, true);
+ result = TextUtils.getMatch(row, GCConstants.PATTERN_SEARCH_FAVORITE, false, 1, null, true);
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 = BaseUtils.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;
}
@@ -374,7 +374,7 @@ public abstract class GCParser {
return searchResult;
}
- final String cacheName = Html.fromHtml(BaseUtils.getMatch(page, GCConstants.PATTERN_NAME, true, "")).toString();
+ final String cacheName = Html.fromHtml(TextUtils.getMatch(page, GCConstants.PATTERN_NAME, true, "")).toString();
if (GCConstants.STRING_UNKNOWN_ERROR.equalsIgnoreCase(cacheName)) {
searchResult.setError(StatusCode.UNKNOWN_ERROR);
return searchResult;
@@ -385,30 +385,30 @@ public abstract class GCParser {
cache.setArchived(page.contains(GCConstants.STRING_ARCHIVED));
- cache.setPremiumMembersOnly(BaseUtils.matches(page, GCConstants.PATTERN_PREMIUMMEMBERS));
+ cache.setPremiumMembersOnly(TextUtils.matches(page, GCConstants.PATTERN_PREMIUMMEMBERS));
- cache.setFavorite(BaseUtils.matches(page, GCConstants.PATTERN_FAVORITE));
+ cache.setFavorite(TextUtils.matches(page, GCConstants.PATTERN_FAVORITE));
// cache geocode
- cache.setGeocode(BaseUtils.getMatch(page, GCConstants.PATTERN_GEOCODE, true, cache.getGeocode()));
+ cache.setGeocode(TextUtils.getMatch(page, GCConstants.PATTERN_GEOCODE, true, cache.getGeocode()));
// cache id
- cache.setCacheId(BaseUtils.getMatch(page, GCConstants.PATTERN_CACHEID, true, cache.getCacheId()));
+ cache.setCacheId(TextUtils.getMatch(page, GCConstants.PATTERN_CACHEID, true, cache.getCacheId()));
// cache guid
- cache.setGuid(BaseUtils.getMatch(page, GCConstants.PATTERN_GUID, true, cache.getGuid()));
+ cache.setGuid(TextUtils.getMatch(page, GCConstants.PATTERN_GUID, true, cache.getGuid()));
// name
cache.setName(cacheName);
// owner real name
- cache.setOwnerUserId(Network.decode(BaseUtils.getMatch(page, GCConstants.PATTERN_OWNER_USERID, true, cache.getOwnerUserId())));
+ cache.setOwnerUserId(Network.decode(TextUtils.getMatch(page, GCConstants.PATTERN_OWNER_USERID, true, cache.getOwnerUserId())));
cache.setUserModifiedCoords(false);
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;
@@ -418,96 +418,96 @@ public abstract class GCParser {
if (StringUtils.isNotBlank(tableInside)) {
// cache terrain
- String result = BaseUtils.getMatch(tableInside, GCConstants.PATTERN_TERRAIN, true, null);
+ String result = TextUtils.getMatch(tableInside, GCConstants.PATTERN_TERRAIN, true, null);
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);
}
}
// cache difficulty
- result = BaseUtils.getMatch(tableInside, GCConstants.PATTERN_DIFFICULTY, true, null);
+ result = TextUtils.getMatch(tableInside, GCConstants.PATTERN_DIFFICULTY, true, null);
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);
}
}
// owner
- cache.setOwnerDisplayName(StringEscapeUtils.unescapeHtml4(BaseUtils.getMatch(tableInside, GCConstants.PATTERN_OWNER_DISPLAYNAME, true, cache.getOwnerDisplayName())));
+ cache.setOwnerDisplayName(StringEscapeUtils.unescapeHtml4(TextUtils.getMatch(tableInside, GCConstants.PATTERN_OWNER_DISPLAYNAME, true, cache.getOwnerDisplayName())));
// hidden
try {
- String hiddenString = BaseUtils.getMatch(tableInside, GCConstants.PATTERN_HIDDEN, true, null);
+ String hiddenString = TextUtils.getMatch(tableInside, GCConstants.PATTERN_HIDDEN, true, null);
if (StringUtils.isNotBlank(hiddenString)) {
cache.setHidden(Login.parseGcCustomDate(hiddenString));
}
if (cache.getHiddenDate() == null) {
// event date
- hiddenString = BaseUtils.getMatch(tableInside, GCConstants.PATTERN_HIDDENEVENT, true, null);
+ hiddenString = TextUtils.getMatch(tableInside, GCConstants.PATTERN_HIDDENEVENT, true, null);
if (StringUtils.isNotBlank(hiddenString)) {
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");
}
// favorite
try {
- cache.setFavoritePoints(Integer.parseInt(BaseUtils.getMatch(tableInside, GCConstants.PATTERN_FAVORITECOUNT, true, "0")));
- } catch (NumberFormatException e) {
+ cache.setFavoritePoints(Integer.parseInt(TextUtils.getMatch(tableInside, GCConstants.PATTERN_FAVORITECOUNT, true, "0")));
+ } catch (final NumberFormatException e) {
Log.e("Error parsing favorite count", e);
}
// cache size
- cache.setSize(CacheSize.getById(BaseUtils.getMatch(tableInside, GCConstants.PATTERN_SIZE, true, CacheSize.NOT_CHOSEN.id)));
+ cache.setSize(CacheSize.getById(TextUtils.getMatch(tableInside, GCConstants.PATTERN_SIZE, true, CacheSize.NOT_CHOSEN.id)));
}
// cache found
- cache.setFound(BaseUtils.matches(page, GCConstants.PATTERN_FOUND) || BaseUtils.matches(page, GCConstants.PATTERN_FOUND_ALTERNATIVE));
+ cache.setFound(TextUtils.matches(page, GCConstants.PATTERN_FOUND) || TextUtils.matches(page, GCConstants.PATTERN_FOUND_ALTERNATIVE));
// cache found date
try {
- final String foundDateString = BaseUtils.getMatch(page, GCConstants.PATTERN_FOUND_DATE, true, null);
+ final String foundDateString = TextUtils.getMatch(page, GCConstants.PATTERN_FOUND_DATE, true, null);
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");
}
// cache type
- cache.setType(CacheType.getByPattern(BaseUtils.getMatch(page, GCConstants.PATTERN_TYPE, true, cache.getType().id)));
+ cache.setType(CacheType.getByPattern(TextUtils.getMatch(page, GCConstants.PATTERN_TYPE, true, cache.getType().id)));
// on watchlist
- cache.setOnWatchlist(BaseUtils.matches(page, GCConstants.PATTERN_WATCHLIST));
+ cache.setOnWatchlist(TextUtils.matches(page, GCConstants.PATTERN_WATCHLIST));
// latitude and longitude. Can only be retrieved if user is logged in
- String latlon = BaseUtils.getMatch(page, GCConstants.PATTERN_LATLON, true, "");
+ String latlon = TextUtils.getMatch(page, GCConstants.PATTERN_LATLON, true, "");
if (StringUtils.isNotEmpty(latlon)) {
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);
}
}
// cache location
- cache.setLocation(BaseUtils.getMatch(page, GCConstants.PATTERN_LOCATION, true, ""));
+ cache.setLocation(TextUtils.getMatch(page, GCConstants.PATTERN_LOCATION, true, ""));
// cache hint
- String result = BaseUtils.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());
}
@@ -516,17 +516,17 @@ public abstract class GCParser {
cache.checkFields();
// cache personal note
- cache.setPersonalNote(BaseUtils.getMatch(page, GCConstants.PATTERN_PERSONALNOTE, true, cache.getPersonalNote()));
+ cache.setPersonalNote(TextUtils.getMatch(page, GCConstants.PATTERN_PERSONALNOTE, true, cache.getPersonalNote()));
// cache short description
- cache.setShortDescription(BaseUtils.getMatch(page, GCConstants.PATTERN_SHORTDESC, true, ""));
+ cache.setShortDescription(TextUtils.getMatch(page, GCConstants.PATTERN_SHORTDESC, true, ""));
// cache description
- cache.setDescription(BaseUtils.getMatch(page, GCConstants.PATTERN_DESC, true, ""));
+ cache.setDescription(TextUtils.getMatch(page, GCConstants.PATTERN_DESC, true, ""));
// cache attributes
try {
- final String attributesPre = BaseUtils.getMatch(page, GCConstants.PATTERN_ATTRIBUTES, true, null);
+ final String attributesPre = TextUtils.getMatch(page, GCConstants.PATTERN_ATTRIBUTES, true, null);
if (null != attributesPre) {
final MatcherWrapper matcherAttributesInside = new MatcherWrapper(GCConstants.PATTERN_ATTRIBUTESINSIDE, attributesPre);
@@ -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,20 +613,20 @@ 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)");
}
// cache logs counts
try {
- final String countlogs = BaseUtils.getMatch(page, GCConstants.PATTERN_COUNTLOGS, true, null);
+ final String countlogs = TextUtils.getMatch(page, GCConstants.PATTERN_COUNTLOGS, true, null);
if (null != countlogs) {
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");
}
@@ -645,7 +645,7 @@ public abstract class GCParser {
// add waypoint for original coordinates in case of user-modified listing-coordinates
try {
- final String originalCoords = BaseUtils.getMatch(page, GCConstants.PATTERN_LATLON_ORIG, false, null);
+ final String originalCoords = TextUtils.getMatch(page, GCConstants.PATTERN_LATLON_ORIG, false, null);
if (null != originalCoords) {
final Waypoint waypoint = new Waypoint(cgeoapplication.getInstance().getString(R.string.cache_coordinates_original), WaypointType.ORIGINAL, false);
@@ -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\">");
@@ -687,21 +687,21 @@ public abstract class GCParser {
// waypoint name
// res is null during the unit tests
- final String name = BaseUtils.getMatch(wp[6], GCConstants.PATTERN_WPNAME, true, 1, cgeoapplication.getInstance().getString(R.string.waypoint), true);
+ final String name = TextUtils.getMatch(wp[6], GCConstants.PATTERN_WPNAME, true, 1, cgeoapplication.getInstance().getString(R.string.waypoint), true);
// waypoint type
- final String resulttype = BaseUtils.getMatch(wp[3], GCConstants.PATTERN_WPTYPE, null);
+ final String resulttype = TextUtils.getMatch(wp[3], GCConstants.PATTERN_WPTYPE, null);
final Waypoint waypoint = new Waypoint(name, WaypointType.findById(resulttype), false);
// waypoint prefix
- waypoint.setPrefix(BaseUtils.getMatch(wp[4], GCConstants.PATTERN_WPPREFIXORLOOKUPORLATLON, true, 2, waypoint.getPrefix(), false));
+ waypoint.setPrefix(TextUtils.getMatch(wp[4], GCConstants.PATTERN_WPPREFIXORLOOKUPORLATLON, true, 2, waypoint.getPrefix(), false));
// waypoint lookup
- waypoint.setLookup(BaseUtils.getMatch(wp[5], GCConstants.PATTERN_WPPREFIXORLOOKUPORLATLON, true, 2, waypoint.getLookup(), false));
+ waypoint.setLookup(TextUtils.getMatch(wp[5], GCConstants.PATTERN_WPPREFIXORLOOKUPORLATLON, true, 2, waypoint.getLookup(), false));
// waypoint latitude and logitude
- latlon = Html.fromHtml(BaseUtils.getMatch(wp[7], GCConstants.PATTERN_WPPREFIXORLOOKUPORLATLON, false, 2, "", false)).toString().trim();
+ latlon = Html.fromHtml(TextUtils.getMatch(wp[7], GCConstants.PATTERN_WPPREFIXORLOOKUPORLATLON, false, 2, "", false)).toString().trim();
if (!StringUtils.startsWith(latlon, "???")) {
waypoint.setLatlon(latlon);
waypoint.setCoords(new Geopoint(latlon));
@@ -713,7 +713,7 @@ public abstract class GCParser {
}
// waypoint note
- waypoint.setNote(BaseUtils.getMatch(wp[3], GCConstants.PATTERN_WPNOTE, waypoint.getNote()));
+ waypoint.setNote(TextUtils.getMatch(wp[3], GCConstants.PATTERN_WPNOTE, waypoint.getNote()));
cache.addOrChangeWaypoint(waypoint, false);
}
@@ -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);
}
@@ -1008,7 +1008,7 @@ public abstract class GCParser {
final String uri = new Uri.Builder().scheme("http").authority("www.geocaching.com").path("/seek/log.aspx").encodedQuery("ID=" + cacheid).build().toString();
String page = Login.postRequestLogged(uri, params);
if (!Login.getLoginStatus(page)) {
- Log.e("GCParser.postLogTrackable: Can not log in geocaching");
+ Log.e("GCParser.postLog: Cannot log in geocaching");
return new ImmutablePair<StatusCode, String>(StatusCode.NOT_LOGGED_IN, "");
}
@@ -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);
}
@@ -1077,11 +1077,11 @@ public abstract class GCParser {
Login.setActualCachesFound(Login.getActualCachesFound() + 1);
}
- final String logID = BaseUtils.getMatch(page, GCConstants.PATTERN_LOG_IMAGE_UPLOAD, "");
+ final String logID = TextUtils.getMatch(page, GCConstants.PATTERN_LOG_IMAGE_UPLOAD, "");
return new ImmutablePair<StatusCode, String>(StatusCode.NO_ERROR, logID);
}
- } catch (Exception e) {
+ } catch (final Exception e) {
Log.e("GCParser.postLog.check", e);
}
@@ -1103,19 +1103,12 @@ public abstract class GCParser {
* @return status code to indicate success or failure
*/
public static ImmutablePair<StatusCode, String> uploadLogImage(final String logId, final String caption, final String description, final Uri imageUri) {
- final String uri = new Uri.Builder().scheme("http").authority("www.geocaching.com").path("/seek/upload.aspx").encodedQuery("LID=" + logId).build().toString();
-
- String page = Network.getResponseData(Network.getRequest(uri));
+ final String uri = new Uri.Builder().scheme("http").authority("www.geocaching.com").path("/seek/upload.aspx").build().toString();
- if (!Login.getLoginStatus(page)) {
- // Login.isActualLoginStatus() was wrong, we are not logged in
- final StatusCode loginState = Login.login();
- if (loginState == StatusCode.NO_ERROR) {
- page = Network.getResponseData(Network.getRequest(uri));
- } else {
- Log.e("Image upload: No login (error: " + loginState + ')');
- return ImmutablePair.of(StatusCode.NOT_LOGGED_IN, null);
- }
+ final String page = Login.getRequestLogged(uri, new Parameters("LID=", logId));
+ if (StringUtils.isBlank(page)) {
+ Log.e("GCParser.uploadLogImage: No data from server");
+ return new ImmutablePair<StatusCode, String>(StatusCode.UNKNOWN_ERROR, null);
}
final String[] viewstates = Login.getViewstates(page);
@@ -1131,7 +1124,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.");
@@ -1195,7 +1188,7 @@ public abstract class GCParser {
final String uri = new Uri.Builder().scheme("http").authority("www.geocaching.com").path("/track/log.aspx").encodedQuery("wid=" + tbid).build().toString();
final String page = Login.postRequestLogged(uri, params);
if (!Login.getLoginStatus(page)) {
- Log.e("GCParser.postLogTrackable: Can not log in geocaching");
+ Log.e("GCParser.postLogTrackable: Cannot log in geocaching");
return StatusCode.NOT_LOGGED_IN;
}
@@ -1206,7 +1199,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 +1216,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 +1257,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);
@@ -1302,14 +1295,14 @@ public abstract class GCParser {
private static boolean changeFavorite(final Geocache cache, final boolean add) {
final String page = requestHtmlPage(cache.getGeocode(), null, "n", "0");
- final String userToken = BaseUtils.getMatch(page, GCConstants.PATTERN_USERTOKEN, "");
+ final String userToken = TextUtils.getMatch(page, GCConstants.PATTERN_USERTOKEN, "");
if (StringUtils.isEmpty(userToken)) {
return false;
}
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");
@@ -1338,7 +1331,7 @@ public abstract class GCParser {
* Parse a trackable HTML description into a Trackable object
*
* @param page
- * the HTML page to parse, already processed through {@link BaseUtils#replaceWhitespace}
+ * the HTML page to parse, already processed through {@link TextUtils#replaceWhitespace}
* @return the parsed trackable, or null if none could be parsed
*/
static Trackable parseTrackable(final String page, final String possibleTrackingcode) {
@@ -1354,20 +1347,20 @@ public abstract class GCParser {
final Trackable trackable = new Trackable();
// trackable geocode
- trackable.setGeocode(BaseUtils.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(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_GUID, true, trackable.getGuid()));
+ trackable.setGuid(TextUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_GUID, true, trackable.getGuid()));
// trackable icon
- trackable.setIconUrl(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_ICON, true, trackable.getIconUrl()));
+ trackable.setIconUrl(TextUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_ICON, true, trackable.getIconUrl()));
// trackable name
- trackable.setName(Html.fromHtml(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_NAME, true, "")).toString());
+ trackable.setName(Html.fromHtml(TextUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_NAME, true, "")).toString());
// trackable type
if (StringUtils.isNotBlank(trackable.getName())) {
- trackable.setType(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_TYPE, true, trackable.getType()));
+ trackable.setType(TextUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_TYPE, true, trackable.getType()));
}
// trackable owner name
@@ -1377,13 +1370,13 @@ 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");
}
// trackable origin
- trackable.setOrigin(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_ORIGIN, true, trackable.getOrigin()));
+ trackable.setOrigin(TextUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_ORIGIN, true, trackable.getOrigin()));
// trackable spotted
try {
@@ -1401,43 +1394,43 @@ public abstract class GCParser {
trackable.setSpottedType(Trackable.SPOTTED_USER);
}
- if (BaseUtils.matches(page, GCConstants.PATTERN_TRACKABLE_SPOTTEDUNKNOWN)) {
+ if (TextUtils.matches(page, GCConstants.PATTERN_TRACKABLE_SPOTTEDUNKNOWN)) {
trackable.setSpottedType(Trackable.SPOTTED_UNKNOWN);
}
- if (BaseUtils.matches(page, GCConstants.PATTERN_TRACKABLE_SPOTTEDOWNER)) {
+ 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 = BaseUtils.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);
}
// trackable distance
- final String distance = BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_DISTANCE, false, null);
+ final String distance = TextUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_DISTANCE, false, null);
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);
}
}
// trackable goal
- trackable.setGoal(convertLinks(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_GOAL, true, trackable.getGoal())));
+ trackable.setGoal(convertLinks(TextUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_GOAL, true, trackable.getGoal())));
// trackable details & image
try {
@@ -1453,10 +1446,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 +1470,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 +1498,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);
}
@@ -1572,10 +1568,10 @@ public abstract class GCParser {
}
} else {
// extract embedded JSON data from page
- rawResponse = BaseUtils.getMatch(page, GCConstants.PATTERN_LOGBOOK, "");
+ 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 +1592,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 +1620,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 +1637,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 +1694,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 +1723,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 {
@@ -1774,7 +1770,7 @@ public abstract class GCParser {
public static boolean editModifiedCoordinates(Geocache cache, Geopoint wpt) {
final String page = requestHtmlPage(cache.getGeocode(), null, "n", "0");
- final String userToken = BaseUtils.getMatch(page, GCConstants.PATTERN_USERTOKEN, "");
+ final String userToken = TextUtils.getMatch(page, GCConstants.PATTERN_USERTOKEN, "");
if (StringUtils.isEmpty(userToken)) {
return false;
}
@@ -1793,7 +1789,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 +1797,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");
@@ -1810,13 +1806,13 @@ public abstract class GCParser {
public static boolean uploadPersonalNote(Geocache cache) {
final String page = requestHtmlPage(cache.getGeocode(), null, "n", "0");
- final String userToken = BaseUtils.getMatch(page, GCConstants.PATTERN_USERTOKEN, "");
+ final String userToken = TextUtils.getMatch(page, GCConstants.PATTERN_USERTOKEN, "");
if (StringUtils.isEmpty(userToken)) {
return false;
}
try {
- JSONObject jo = new JSONObject()
+ final JSONObject jo = new JSONObject()
.put("dto", (new JSONObject()
.put("et", cache.getPersonalNote())
.put("ut", userToken)));
@@ -1824,7 +1820,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 +1828,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/gc/Login.java b/main/src/cgeo/geocaching/connector/gc/Login.java
index 7351311..3146712 100644
--- a/main/src/cgeo/geocaching/connector/gc/Login.java
+++ b/main/src/cgeo/geocaching/connector/gc/Login.java
@@ -8,9 +8,9 @@ import cgeo.geocaching.network.Cookies;
import cgeo.geocaching.network.HtmlImage;
import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.Parameters;
-import cgeo.geocaching.utils.BaseUtils;
import cgeo.geocaching.utils.Log;
import cgeo.geocaching.utils.MatcherWrapper;
+import cgeo.geocaching.utils.TextUtils;
import ch.boye.httpclientandroidlib.HttpResponse;
@@ -52,9 +52,9 @@ public abstract class Login {
"dd/MM/yyyy"
};
- Map<String, SimpleDateFormat> map = new HashMap<String, SimpleDateFormat>();
+ final Map<String, SimpleDateFormat> map = new HashMap<String, SimpleDateFormat>();
- for (String format : formats) {
+ for (final String format : formats) {
map.put(format, new SimpleDateFormat(format, Locale.ENGLISH));
}
@@ -77,7 +77,7 @@ public abstract class Login {
Login.setActualStatus(cgeoapplication.getInstance().getString(R.string.init_login_popup_working));
HttpResponse loginResponse = Network.getRequest("https://www.geocaching.com/login/default.aspx");
String loginData = Network.getResponseData(loginResponse);
- if (loginResponse != null && loginResponse.getStatusLine().getStatusCode() == 503 && BaseUtils.matches(loginData, GCConstants.PATTERN_MAINTENANCE)) {
+ if (loginResponse != null && loginResponse.getStatusLine().getStatusCode() == 503 && TextUtils.matches(loginData, GCConstants.PATTERN_MAINTENANCE)) {
return StatusCode.MAINTENANCE;
}
@@ -147,9 +147,9 @@ public abstract class Login {
}
public static StatusCode logout() {
- HttpResponse logoutResponse = Network.getRequest("https://www.geocaching.com/login/default.aspx?RESET=Y&redir=http%3a%2f%2fwww.geocaching.com%2fdefault.aspx%3f");
- String logoutData = Network.getResponseData(logoutResponse);
- if (logoutResponse != null && logoutResponse.getStatusLine().getStatusCode() == 503 && BaseUtils.matches(logoutData, GCConstants.PATTERN_MAINTENANCE)) {
+ final HttpResponse logoutResponse = Network.getRequest("https://www.geocaching.com/login/default.aspx?RESET=Y&redir=http%3a%2f%2fwww.geocaching.com%2fdefault.aspx%3f");
+ final String logoutData = Network.getResponseData(logoutResponse);
+ if (logoutResponse != null && logoutResponse.getStatusLine().getStatusCode() == 503 && TextUtils.matches(logoutData, GCConstants.PATTERN_MAINTENANCE)) {
return StatusCode.MAINTENANCE;
}
@@ -205,17 +205,17 @@ public abstract class Login {
setActualStatus(cgeoapplication.getInstance().getString(R.string.init_login_popup_ok));
// on every page except login page
- setActualLoginStatus(BaseUtils.matches(page, GCConstants.PATTERN_LOGIN_NAME));
+ setActualLoginStatus(TextUtils.matches(page, GCConstants.PATTERN_LOGIN_NAME));
if (isActualLoginStatus()) {
- setActualUserName(BaseUtils.getMatch(page, GCConstants.PATTERN_LOGIN_NAME, true, "???"));
+ setActualUserName(TextUtils.getMatch(page, GCConstants.PATTERN_LOGIN_NAME, true, "???"));
int cachesCount = 0;
try {
- cachesCount = Integer.parseInt(BaseUtils.getMatch(page, GCConstants.PATTERN_CACHES_FOUND, true, "0").replaceAll("[,.]", ""));
- } catch (NumberFormatException e) {
+ cachesCount = Integer.parseInt(TextUtils.getMatch(page, GCConstants.PATTERN_CACHES_FOUND, true, "0").replaceAll("[,.]", ""));
+ } catch (final NumberFormatException e) {
Log.e("getLoginStatus: bad cache count", e);
}
setActualCachesFound(cachesCount);
- Settings.setMemberStatus(BaseUtils.getMatch(page, GCConstants.PATTERN_MEMBER_STATUS, true, null));
+ Settings.setMemberStatus(TextUtils.getMatch(page, GCConstants.PATTERN_MEMBER_STATUS, true, null));
if ( page.contains(GCConstants.MEMBER_STATUS_RENEW) ) {
Settings.setMemberStatus(GCConstants.MEMBER_STATUS_PM);
}
@@ -223,7 +223,7 @@ public abstract class Login {
}
// login page
- setActualLoginStatus(BaseUtils.matches(page, GCConstants.PATTERN_LOGIN_NAME_LOGIN_PAGE));
+ setActualLoginStatus(TextUtils.matches(page, GCConstants.PATTERN_LOGIN_NAME_LOGIN_PAGE));
if (isActualLoginStatus()) {
setActualUserName(Settings.getUsername());
// number of caches found is not part of this page
@@ -260,23 +260,23 @@ public abstract class Login {
public static BitmapDrawable downloadAvatarAndGetMemberStatus() {
try {
- final String profile = BaseUtils.replaceWhitespace(Network.getResponseData(Network.getRequest("http://www.geocaching.com/my/")));
+ final String profile = TextUtils.replaceWhitespace(Network.getResponseData(Network.getRequest("http://www.geocaching.com/my/")));
- Settings.setMemberStatus(BaseUtils.getMatch(profile, GCConstants.PATTERN_MEMBER_STATUS, true, null));
+ Settings.setMemberStatus(TextUtils.getMatch(profile, GCConstants.PATTERN_MEMBER_STATUS, true, null));
if (profile.contains(GCConstants.MEMBER_STATUS_RENEW)) {
Settings.setMemberStatus(GCConstants.MEMBER_STATUS_PM);
}
- setActualCachesFound(Integer.parseInt(BaseUtils.getMatch(profile, GCConstants.PATTERN_CACHES_FOUND, true, "-1").replaceAll("[,.]", "")));
+ setActualCachesFound(Integer.parseInt(TextUtils.getMatch(profile, GCConstants.PATTERN_CACHES_FOUND, true, "-1").replaceAll("[,.]", "")));
- final String avatarURL = BaseUtils.getMatch(profile, GCConstants.PATTERN_AVATAR_IMAGE_PROFILE_PAGE, false, null);
+ final String avatarURL = TextUtils.getMatch(profile, GCConstants.PATTERN_AVATAR_IMAGE_PROFILE_PAGE, false, null);
if (null != avatarURL) {
final HtmlImage imgGetter = new HtmlImage("", false, 0, false);
return imgGetter.getDrawable(avatarURL);
}
// No match? There may be no avatar set by user.
Log.d("No avatar set for user");
- } catch (Exception e) {
+ } catch (final Exception e) {
Log.w("Error when retrieving user avatar", e);
}
return null;
@@ -294,7 +294,7 @@ public abstract class Login {
return;
}
- String customDate = BaseUtils.getMatch(result, GCConstants.PATTERN_CUSTOMDATE, true, null);
+ final String customDate = TextUtils.getMatch(result, GCConstants.PATTERN_CUSTOMDATE, true, null);
if (null != customDate) {
Settings.setGcCustomDate(customDate);
}
@@ -310,14 +310,14 @@ public abstract class Login {
if (gcCustomDateFormats.containsKey(format)) {
try {
return gcCustomDateFormats.get(format).parse(trimmed);
- } catch (ParseException e) {
+ } catch (final ParseException e) {
}
}
- for (SimpleDateFormat sdf : gcCustomDateFormats.values()) {
+ for (final SimpleDateFormat sdf : gcCustomDateFormats.values()) {
try {
return sdf.parse(trimmed);
- } catch (ParseException e) {
+ } catch (final ParseException e) {
}
}
@@ -347,7 +347,7 @@ public abstract class Login {
return true;
}
- for (String s : a) {
+ for (final String s : a) {
if (StringUtils.isNotEmpty(s)) {
return false;
}
@@ -373,24 +373,24 @@ public abstract class Login {
if (matcherViewstateCount.find()) {
try {
count = Integer.parseInt(matcherViewstateCount.group(1));
- } catch (NumberFormatException e) {
+ } catch (final NumberFormatException e) {
Log.e("getViewStates", e);
}
}
- String[] viewstates = new String[count];
+ final String[] viewstates = new String[count];
// Get the viewstates
final MatcherWrapper matcherViewstates = new MatcherWrapper(GCConstants.PATTERN_VIEWSTATES, page);
while (matcherViewstates.find()) {
- String sno = matcherViewstates.group(1); // number of viewstate
+ final String sno = matcherViewstates.group(1); // number of viewstate
int no;
if (StringUtils.isEmpty(sno)) {
no = 0;
} else {
try {
no = Integer.parseInt(sno);
- } catch (NumberFormatException e) {
+ } catch (final NumberFormatException e) {
Log.e("getViewStates", e);
no = 0;
}
@@ -436,17 +436,17 @@ public abstract class Login {
* @return
*/
public static String postRequestLogged(final String uri, final Parameters params) {
- HttpResponse response = Network.postRequest(uri, params);
- String data = Network.getResponseData(response);
+ final String data = Network.getResponseData(Network.postRequest(uri, params));
- if (!getLoginStatus(data)) {
- if (login() == StatusCode.NO_ERROR) {
- response = Network.postRequest(uri, params);
- data = Network.getResponseData(response);
- } else {
- Log.i("Working as guest.");
- }
+ if (getLoginStatus(data)) {
+ return data;
}
+
+ if (login() == StatusCode.NO_ERROR) {
+ return Network.getResponseData(Network.postRequest(uri, params));
+ }
+
+ Log.i("Working as guest.");
return data;
}
@@ -476,8 +476,8 @@ public abstract class Login {
public static String[] getMapTokens() {
final HttpResponse response = Network.getRequest(GCConstants.URL_LIVE_MAP);
final String data = Network.getResponseData(response);
- final String userSession = BaseUtils.getMatch(data, GCConstants.PATTERN_USERSESSION, "");
- final String sessionToken = BaseUtils.getMatch(data, GCConstants.PATTERN_SESSIONTOKEN, "");
+ final String userSession = TextUtils.getMatch(data, GCConstants.PATTERN_USERSESSION, "");
+ final String sessionToken = TextUtils.getMatch(data, GCConstants.PATTERN_SESSIONTOKEN, "");
return new String[] { userSession, sessionToken };
}
}
diff --git a/main/src/cgeo/geocaching/connector/oc/OCApiLiveConnector.java b/main/src/cgeo/geocaching/connector/oc/OCApiLiveConnector.java
index 4c6db97..5f30934 100644
--- a/main/src/cgeo/geocaching/connector/oc/OCApiLiveConnector.java
+++ b/main/src/cgeo/geocaching/connector/oc/OCApiLiveConnector.java
@@ -6,9 +6,10 @@ import cgeo.geocaching.Settings;
import cgeo.geocaching.cgData;
import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.connector.ILoggingManager;
+import cgeo.geocaching.connector.capability.ILogin;
import cgeo.geocaching.connector.capability.ISearchByCenter;
import cgeo.geocaching.connector.capability.ISearchByViewPort;
-import cgeo.geocaching.connector.oc.OkapiClient.UserInfo;
+import cgeo.geocaching.connector.oc.UserInfo.UserInfoStatus;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.Viewport;
import cgeo.geocaching.utils.CryptUtils;
@@ -16,11 +17,13 @@ import cgeo.geocaching.utils.CryptUtils;
import org.apache.commons.lang3.StringUtils;
import android.app.Activity;
+import android.content.Context;
+import android.os.Handler;
-public class OCApiLiveConnector extends OCApiConnector implements ISearchByCenter, ISearchByViewPort {
+public class OCApiLiveConnector extends OCApiConnector implements ISearchByCenter, ISearchByViewPort, ILogin {
private String cS;
- private UserInfo userInfo = new UserInfo(StringUtils.EMPTY, 0, false);
+ private UserInfo userInfo = new UserInfo(StringUtils.EMPTY, 0, UserInfoStatus.NOT_RETRIEVED);
public OCApiLiveConnector(String name, String host, String prefix, int cKResId, int cSResId, ApiSupport apiSupport) {
super(name, host, prefix, CryptUtils.rot13(cgeoapplication.getInstance().getResources().getString(cKResId)), apiSupport);
@@ -104,16 +107,33 @@ public class OCApiLiveConnector extends OCApiConnector implements ISearchByCente
return getSupportedAuthLevel() == OAuthLevel.Level3;
}
- public boolean retrieveUserInfo() {
- userInfo = OkapiClient.getUserInfo(this);
- return userInfo.isRetrieveSuccessful();
+ @Override
+ public boolean login(Handler handler, Context fromActivity) {
+ if (supportsPersonalization()) {
+ userInfo = OkapiClient.getUserInfo(this);
+ } else {
+ userInfo = new UserInfo(StringUtils.EMPTY, 0, UserInfoStatus.NOT_SUPPORTED);
+ }
+ return userInfo.getStatus() == UserInfoStatus.SUCCESSFUL;
}
- public Object getUserName() {
+ @Override
+ public String getUserName() {
return userInfo.getName();
}
+ @Override
public int getCachesFound() {
return userInfo.getFinds();
}
+
+ @Override
+ public String getLoginStatusString() {
+ return cgeoapplication.getInstance().getString(userInfo.getStatus().resId);
+ }
+
+ @Override
+ public boolean isLoggedIn() {
+ return userInfo.getStatus() == UserInfoStatus.SUCCESSFUL;
+ }
}
diff --git a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java
index 3c99bc9..b6f9711 100644
--- a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java
+++ b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java
@@ -14,6 +14,7 @@ import cgeo.geocaching.connector.LogResult;
import cgeo.geocaching.connector.gc.GCConnector;
import cgeo.geocaching.connector.oc.OCApiConnector.ApiSupport;
import cgeo.geocaching.connector.oc.OCApiConnector.OAuthLevel;
+import cgeo.geocaching.connector.oc.UserInfo.UserInfoStatus;
import cgeo.geocaching.enumerations.CacheAttribute;
import cgeo.geocaching.enumerations.CacheSize;
import cgeo.geocaching.enumerations.CacheType;
@@ -93,6 +94,7 @@ final public class OkapiClient {
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 CACHE_REQ_PASSWORD = "req_passwd";
private static final String LOG_TYPE = "type";
private static final String LOG_COMMENT = "comment";
@@ -108,7 +110,7 @@ final public class OkapiClient {
// Additional: additional fields for full cache (L3 - only for level 3 auth, current - only for connectors with current api)
private static final String SERVICE_CACHE_CORE_FIELDS = "code|name|location|type|status|difficulty|terrain|size";
private static final String SERVICE_CACHE_CORE_L3_FIELDS = "is_found";
- private static final String SERVICE_CACHE_ADDITIONAL_FIELDS = "owner|founds|notfounds|rating|rating_votes|recommendations|description|hint|images|latest_logs|date_hidden|alt_wpts|attrnames";
+ private static final String SERVICE_CACHE_ADDITIONAL_FIELDS = "owner|founds|notfounds|rating|rating_votes|recommendations|description|hint|images|latest_logs|date_hidden|alt_wpts|attrnames|req_passwd";
private static final String SERVICE_CACHE_ADDITIONAL_CURRENT_FIELDS = "gc_code|attribution_note";
private static final String SERVICE_CACHE_ADDITIONAL_L3_FIELDS = "is_watched";
@@ -118,12 +120,12 @@ final public class OkapiClient {
public static Geocache getCache(final String geoCode) {
final Parameters params = new Parameters("cache_code", geoCode);
- IConnector connector = ConnectorFactory.getConnector(geoCode);
+ final IConnector connector = ConnectorFactory.getConnector(geoCode);
if (!(connector instanceof OCApiConnector)) {
return null;
}
- OCApiConnector ocapiConn = (OCApiConnector) connector;
+ final OCApiConnector ocapiConn = (OCApiConnector) connector;
params.add("fields", getFullFields(ocapiConn));
params.add("attribution_append", "none");
@@ -138,16 +140,18 @@ final public class OkapiClient {
}
public static List<Geocache> getCachesAround(final Geopoint center, OCApiConnector connector) {
- String centerString = GeopointFormatter.format(GeopointFormatter.Format.LAT_DECDEGREE_RAW, center) + SEPARATOR + GeopointFormatter.format(GeopointFormatter.Format.LON_DECDEGREE_RAW, center);
+ final String centerString = GeopointFormatter.format(GeopointFormatter.Format.LAT_DECDEGREE_RAW, center) + SEPARATOR + GeopointFormatter.format(GeopointFormatter.Format.LON_DECDEGREE_RAW, center);
final Parameters params = new Parameters("search_method", METHOD_SEARCH_NEAREST);
final Map<String, String> valueMap = new LinkedHashMap<String, String>();
valueMap.put("center", centerString);
valueMap.put("limit", "20");
- addFilterParams(valueMap, connector);
+ return requestCaches(connector, params, valueMap);
+ }
+ private static List<Geocache> requestCaches(OCApiConnector connector, final Parameters params, final Map<String, String> valueMap) {
+ addFilterParams(valueMap, connector);
params.add("search_params", new JSONObject(valueMap).toString());
-
addRetrieveParams(params, connector);
final JSONObject data = request(connector, OkapiService.SERVICE_SEARCH_AND_RETRIEVE, params);
@@ -166,7 +170,7 @@ final public class OkapiClient {
return Collections.emptyList();
}
- String bboxString = GeopointFormatter.format(GeopointFormatter.Format.LAT_DECDEGREE_RAW, viewport.bottomLeft)
+ final String bboxString = GeopointFormatter.format(GeopointFormatter.Format.LAT_DECDEGREE_RAW, viewport.bottomLeft)
+ SEPARATOR + GeopointFormatter.format(GeopointFormatter.Format.LON_DECDEGREE_RAW, viewport.bottomLeft)
+ SEPARATOR + GeopointFormatter.format(GeopointFormatter.Format.LAT_DECDEGREE_RAW, viewport.topRight)
+ SEPARATOR + GeopointFormatter.format(GeopointFormatter.Format.LON_DECDEGREE_RAW, viewport.topRight);
@@ -174,19 +178,7 @@ final public class OkapiClient {
final Map<String, String> valueMap = new LinkedHashMap<String, String>();
valueMap.put("bbox", bboxString);
- addFilterParams(valueMap, connector);
-
- params.add("search_params", new JSONObject(valueMap).toString());
-
- addRetrieveParams(params, connector);
-
- final JSONObject data = request(connector, OkapiService.SERVICE_SEARCH_AND_RETRIEVE, params);
-
- if (data == null) {
- return Collections.emptyList();
- }
-
- return parseCaches(data);
+ return requestCaches(connector, params, valueMap);
}
public static boolean setWatchState(final Geocache cache, final boolean watched, OCApiConnector connector) {
@@ -204,7 +196,7 @@ final public class OkapiClient {
return true;
}
- public static LogResult postLog(final Geocache cache, LogType logType, Calendar date, String log, OCApiConnector connector) {
+ public static LogResult postLog(final Geocache cache, LogType logType, Calendar date, String log, String logPassword, OCApiConnector connector) {
final Parameters params = new Parameters("cache_code", cache.getGeocode());
params.add("logtype", logType.oc_type);
params.add("comment", log);
@@ -213,6 +205,9 @@ final public class OkapiClient {
if (logType.equals(LogType.NEEDS_MAINTENANCE)) {
params.add("needs_maintenance", "true");
}
+ if (logPassword != null) {
+ params.add("password", logPassword);
+ }
final JSONObject data = request(connector, OkapiService.SERVICE_SUBMIT_LOG, params);
@@ -226,7 +221,7 @@ final public class OkapiClient {
}
return new LogResult(StatusCode.LOG_POST_ERROR, "");
- } catch (JSONException e) {
+ } catch (final JSONException e) {
Log.e("OkapiClient.postLog", e);
}
return new LogResult(StatusCode.LOG_POST_ERROR, "");
@@ -243,19 +238,20 @@ final public class OkapiClient {
// Get and iterate result list
final JSONObject cachesResponse = response.getJSONObject("results");
if (cachesResponse != null) {
- List<Geocache> caches = new ArrayList<Geocache>(cachesResponse.length());
+ final List<Geocache> caches = new ArrayList<Geocache>(cachesResponse.length());
@SuppressWarnings("unchecked")
+ final
Iterator<String> keys = cachesResponse.keys();
while (keys.hasNext()) {
- String key = keys.next();
- Geocache cache = parseSmallCache(cachesResponse.getJSONObject(key));
+ final String key = keys.next();
+ final Geocache cache = parseSmallCache(cachesResponse.getJSONObject(key));
if (cache != null) {
caches.add(cache);
}
}
return caches;
}
- } catch (JSONException e) {
+ } catch (final JSONException e) {
Log.e("OkapiClient.parseCachesResult", e);
}
return Collections.emptyList();
@@ -269,7 +265,7 @@ final public class OkapiClient {
parseCoreCache(response, cache);
cgData.saveCache(cache, EnumSet.of(SaveFlag.SAVE_CACHE));
- } catch (JSONException e) {
+ } catch (final JSONException e) {
Log.e("OkapiClient.parseSmallCache", e);
}
return cache;
@@ -297,9 +293,9 @@ final public class OkapiClient {
cache.setFavoritePoints(response.getInt(CACHE_RECOMMENDATIONS));
// not used: req_password
// Prepend gc-link to description if available
- StringBuilder description = new StringBuilder(500);
+ final StringBuilder description = new StringBuilder(500);
if (!response.isNull("gc_code")) {
- String gccode = response.getString("gc_code");
+ final String gccode = response.getString("gc_code");
description.append(cgeoapplication.getInstance().getResources()
.getString(R.string.cache_listed_on, GCConnector.getInstance().getName()))
.append(": <a href=\"http://coord.info/")
@@ -318,7 +314,7 @@ final public class OkapiClient {
final JSONArray images = response.getJSONArray(CACHE_IMAGES);
if (images != null) {
for (int i = 0; i < images.length(); i++) {
- JSONObject imageResponse = images.getJSONObject(i);
+ final JSONObject 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());
@@ -336,11 +332,12 @@ final public class OkapiClient {
if (!response.isNull(CACHE_IS_WATCHED)) {
cache.setOnWatchlist(response.getBoolean(CACHE_IS_WATCHED));
}
+ cache.setLogPasswordRequired(response.getBoolean(CACHE_REQ_PASSWORD));
cache.setDetailedUpdatedNow();
// save full detailed caches
cgData.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB));
- } catch (JSONException e) {
+ } catch (final JSONException e) {
Log.e("OkapiClient.parseCache", e);
}
return cache;
@@ -387,8 +384,8 @@ final public class OkapiClient {
List<LogEntry> result = null;
for (int i = 0; i < logsJSON.length(); i++) {
try {
- JSONObject logResponse = logsJSON.getJSONObject(i);
- LogEntry log = new LogEntry(
+ final JSONObject logResponse = logsJSON.getJSONObject(i);
+ final LogEntry log = new LogEntry(
parseUser(logResponse.getJSONObject(LOG_USER)),
parseDate(logResponse.getString(LOG_DATE)).getTime(),
parseLogType(logResponse.getString(LOG_TYPE)),
@@ -397,7 +394,7 @@ final public class OkapiClient {
result = new ArrayList<LogEntry>();
}
result.add(log);
- } catch (JSONException e) {
+ } catch (final JSONException e) {
Log.e("OkapiClient.parseLogs", e);
}
}
@@ -408,12 +405,12 @@ final public class OkapiClient {
List<Waypoint> result = null;
for (int i = 0; i < wptsJson.length(); i++) {
try {
- JSONObject wptResponse = wptsJson.getJSONObject(i);
- Waypoint wpt = new Waypoint(wptResponse.getString(WPT_NAME),
+ final JSONObject wptResponse = wptsJson.getJSONObject(i);
+ final Waypoint wpt = new Waypoint(wptResponse.getString(WPT_NAME),
parseWptType(wptResponse.getString(WPT_TYPE)),
false);
wpt.setNote(wptResponse.getString(WPT_DESCRIPTION));
- Geopoint pt = parseCoords(wptResponse.getString(WPT_LOCATION));
+ final Geopoint pt = parseCoords(wptResponse.getString(WPT_LOCATION));
if (pt != null) {
wpt.setCoords(pt);
}
@@ -421,7 +418,7 @@ final public class OkapiClient {
result = new ArrayList<Waypoint>();
}
result.add(wpt);
- } catch (JSONException e) {
+ } catch (final JSONException e) {
Log.e("OkapiClient.parseWaypoints", e);
}
}
@@ -468,7 +465,7 @@ final public class OkapiClient {
final String strippedDate = date.replaceAll("\\+0([0-9]){1}\\:00", "+0$100");
try {
return ISO8601DATEFORMAT.parse(strippedDate);
- } catch (ParseException e) {
+ } catch (final ParseException e) {
Log.e("OkapiClient.parseDate", e);
}
return null;
@@ -486,17 +483,17 @@ final public class OkapiClient {
private static List<String> parseAttributes(JSONArray nameList) {
- List<String> result = new ArrayList<String>();
+ final List<String> result = new ArrayList<String>();
for (int i = 0; i < nameList.length(); i++) {
try {
- String name = nameList.getString(i);
- CacheAttribute attr = CacheAttribute.getByOcId(AttributeParser.getOcDeId(name));
+ final String name = nameList.getString(i);
+ final CacheAttribute attr = CacheAttribute.getByOcId(AttributeParser.getOcDeId(name));
if (attr != null) {
result.add(attr.rawName);
}
- } catch (JSONException e) {
+ } catch (final JSONException e) {
Log.e("OkapiClient.parseAttributes", e);
}
}
@@ -517,7 +514,7 @@ final public class OkapiClient {
double size = 0;
try {
size = response.getDouble(CACHE_SIZE);
- } catch (JSONException e) {
+ } catch (final JSONException e) {
Log.e("OkapiClient.getCacheSize", e);
}
switch ((int) Math.round(size)) {
@@ -584,7 +581,7 @@ final public class OkapiClient {
return StringUtils.EMPTY;
}
- StringBuilder res = new StringBuilder(500);
+ final StringBuilder res = new StringBuilder(500);
res.append(SERVICE_CACHE_CORE_FIELDS);
res.append(SEPARATOR).append(SERVICE_CACHE_ADDITIONAL_FIELDS);
@@ -673,7 +670,7 @@ final public class OkapiClient {
final JSONObject data = request(connector, OkapiService.SERVICE_USER, params);
if (data == null) {
- return new UserInfo(StringUtils.EMPTY, 0, false);
+ return new UserInfo(StringUtils.EMPTY, 0, UserInfoStatus.FAILED);
}
String name = StringUtils.EMPTY;
@@ -683,7 +680,7 @@ final public class OkapiClient {
if (!data.isNull(USER_USERNAME)) {
try {
name = data.getString(USER_USERNAME);
- } catch (JSONException e) {
+ } catch (final JSONException e) {
Log.e("OkapiClient.getUserInfo - name", e);
success = false;
}
@@ -694,7 +691,7 @@ final public class OkapiClient {
if (!data.isNull(USER_CACHES_FOUND)) {
try {
finds = data.getInt(USER_CACHES_FOUND);
- } catch (JSONException e) {
+ } catch (final JSONException e) {
Log.e("OkapiClient.getUserInfo - finds", e);
success = false;
}
@@ -702,32 +699,7 @@ final public class OkapiClient {
success = false;
}
- return new UserInfo(name, finds, success);
- }
-
- public static class UserInfo {
-
- private final String name;
- private final int finds;
- private final boolean retrieveSuccessful;
-
- UserInfo(String name, int finds, boolean retrieveSuccessful) {
- this.name = name;
- this.finds = finds;
- this.retrieveSuccessful = retrieveSuccessful;
- }
-
- public String getName() {
- return name;
- }
-
- public int getFinds() {
- return finds;
- }
-
- public boolean isRetrieveSuccessful() {
- return retrieveSuccessful;
- }
+ return new UserInfo(name, finds, success ? UserInfoStatus.SUCCESSFUL : UserInfoStatus.FAILED);
}
}
diff --git a/main/src/cgeo/geocaching/connector/oc/OkapiLoggingManager.java b/main/src/cgeo/geocaching/connector/oc/OkapiLoggingManager.java
index 8a94218..c4bf91f 100644
--- a/main/src/cgeo/geocaching/connector/oc/OkapiLoggingManager.java
+++ b/main/src/cgeo/geocaching/connector/oc/OkapiLoggingManager.java
@@ -1,8 +1,8 @@
package cgeo.geocaching.connector.oc;
import cgeo.geocaching.Geocache;
-import cgeo.geocaching.TrackableLog;
import cgeo.geocaching.LogCacheActivity;
+import cgeo.geocaching.TrackableLog;
import cgeo.geocaching.connector.ILoggingManager;
import cgeo.geocaching.connector.ImageResult;
import cgeo.geocaching.connector.LogResult;
@@ -38,8 +38,8 @@ public class OkapiLoggingManager implements ILoggingManager {
}
@Override
- public LogResult postLog(Geocache cache, LogType logType, Calendar date, String log, List<TrackableLog> trackableLogs) {
- return OkapiClient.postLog(cache, logType, date, log, connector);
+ public LogResult postLog(Geocache cache, LogType logType, Calendar date, String log, String logPassword, List<TrackableLog> trackableLogs) {
+ return OkapiClient.postLog(cache, logType, date, log, logPassword, connector);
}
@Override
diff --git a/main/src/cgeo/geocaching/connector/oc/UserInfo.java b/main/src/cgeo/geocaching/connector/oc/UserInfo.java
new file mode 100644
index 0000000..0dc0440
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/oc/UserInfo.java
@@ -0,0 +1,41 @@
+package cgeo.geocaching.connector.oc;
+
+import cgeo.geocaching.R;
+
+public class UserInfo {
+
+ public enum UserInfoStatus {
+ NOT_RETRIEVED(R.string.init_login_popup_working),
+ SUCCESSFUL(R.string.init_login_popup_ok),
+ FAILED(R.string.init_login_popup_failed),
+ NOT_SUPPORTED(R.string.init_login_popup_not_authorized);
+
+ public final int resId;
+
+ UserInfoStatus(int resId) {
+ this.resId = resId;
+ }
+ }
+
+ private final String name;
+ private final int finds;
+ private final UserInfoStatus status;
+
+ UserInfo(String name, int finds, UserInfoStatus status) {
+ this.name = name;
+ this.finds = finds;
+ this.status = status;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public int getFinds() {
+ return finds;
+ }
+
+ public UserInfoStatus getStatus() {
+ return status;
+ }
+}
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..8387076
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/trackable/GeokretyConnector.java
@@ -0,0 +1,42 @@
+package cgeo.geocaching.connector.trackable;
+
+import cgeo.geocaching.Trackable;
+import cgeo.geocaching.network.Network;
+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.getGeocode());
+ }
+
+ @Override
+ public Trackable searchTrackable(String geocode, String guid, String id) {
+ final String page = Network.getResponseData(Network.getRequest("http://geokrety.org/export2.php?gkid=" + getId(geocode)));
+ if (page == null) {
+ return null;
+ }
+ return GeokretyParser.parse(page);
+ }
+
+ private static int getId(String geocode) {
+ try {
+ final String hex = geocode.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/GeokretyParser.java b/main/src/cgeo/geocaching/connector/trackable/GeokretyParser.java
new file mode 100644
index 0000000..66ca5f7
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/trackable/GeokretyParser.java
@@ -0,0 +1,82 @@
+package cgeo.geocaching.connector.trackable;
+
+import cgeo.geocaching.R;
+import cgeo.geocaching.Trackable;
+import cgeo.geocaching.cgeoapplication;
+import cgeo.geocaching.utils.Log;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import android.sax.Element;
+import android.sax.EndTextElementListener;
+import android.sax.RootElement;
+import android.sax.StartElementListener;
+import android.util.Xml;
+
+public class GeokretyParser {
+
+ public static Trackable parse(final String page) {
+ final Trackable trackable = new Trackable();
+
+ final RootElement root = new RootElement("gkxml");
+ final Element geokret = root.getChild("geokrety").getChild("geokret");
+
+ geokret.setEndTextElementListener(new EndTextElementListener() {
+
+ @Override
+ public void end(String name) {
+ trackable.setName(name);
+ }
+ });
+
+ geokret.setStartElementListener(new StartElementListener() {
+
+ @Override
+ public void start(Attributes attributes) {
+ try {
+ if (attributes.getIndex("id") > -1) {
+ trackable.setGeocode(geocode(Integer.valueOf(attributes.getValue("id"))));
+ }
+ if (attributes.getIndex("dist") > -1) {
+ trackable.setDistance(Float.valueOf(attributes.getValue("dist")));
+ }
+ if (attributes.getIndex("type") > -1) {
+ trackable.setType(getType(Integer.valueOf(attributes.getValue("type"))));
+ }
+ } catch (final NumberFormatException e) {
+ Log.e("Parsing geokret", e);
+ }
+ }
+ });
+
+ try {
+ Xml.parse(page, root.getContentHandler());
+ return trackable;
+ } catch (final SAXException e) {
+ Log.w("Cannot parse geokrety", e);
+ }
+
+ return null;
+ }
+
+ protected static String getType(int type) {
+ switch (type) {
+ case 0:
+ return cgeoapplication.getInstance().getString(R.string.geokret_type_traditional);
+ case 1:
+ return cgeoapplication.getInstance().getString(R.string.geokret_type_book_or_media);
+ case 2:
+ return cgeoapplication.getInstance().getString(R.string.geokret_type_human);
+ case 3:
+ return cgeoapplication.getInstance().getString(R.string.geokret_type_coin);
+ case 4:
+ return cgeoapplication.getInstance().getString(R.string.geokret_type_post);
+ }
+ return null;
+ }
+
+ protected static String geocode(final int id) {
+ return String.format("GK%04X", id);
+ }
+}
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..c09dc07
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/trackable/TrackableConnector.java
@@ -0,0 +1,19 @@
+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();
+
+ public Trackable searchTrackable(String geocode, String guid, String id);
+
+}
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..0dac6cc
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/trackable/TravelBugConnector.java
@@ -0,0 +1,50 @@
+package cgeo.geocaching.connector.trackable;
+
+import cgeo.geocaching.Trackable;
+import cgeo.geocaching.connector.gc.GCParser;
+
+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]+)|([0-9A-Z]{6})", 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;
+ }
+
+ @Override
+ public Trackable searchTrackable(String geocode, String guid, String id) {
+ return GCParser.searchTrackable(geocode, guid, id);
+ }
+
+ /**
+ * initialization on demand holder pattern
+ */
+ private static class Holder {
+ private static final TravelBugConnector INSTANCE = new TravelBugConnector();
+ }
+
+ private TravelBugConnector() {
+ // singleton
+ }
+
+ public static TravelBugConnector getInstance() {
+ return Holder.INSTANCE;
+ }
+
+} \ 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..0295927
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/trackable/UnknownTrackableConnector.java
@@ -0,0 +1,24 @@
+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;
+ }
+
+ @Override
+ public Trackable searchTrackable(String geocode, String guid, String id) {
+ return null;
+ }
+
+}