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/AbstractConnector.java8
-rw-r--r--main/src/cgeo/geocaching/connector/ConnectorFactory.java17
-rw-r--r--main/src/cgeo/geocaching/connector/IConnector.java45
-rw-r--r--main/src/cgeo/geocaching/connector/ILoggingManager.java5
-rw-r--r--main/src/cgeo/geocaching/connector/UnknownConnector.java8
-rw-r--r--main/src/cgeo/geocaching/connector/WaymarkingConnector.java17
-rw-r--r--main/src/cgeo/geocaching/connector/capability/ILogin.java4
-rw-r--r--main/src/cgeo/geocaching/connector/capability/IgnoreCapability.java14
-rw-r--r--main/src/cgeo/geocaching/connector/ec/ECConnector.java10
-rw-r--r--main/src/cgeo/geocaching/connector/ec/ECLogin.java1
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCConnector.java18
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCLogin.java8
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCMap.java23
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCParser.java47
-rw-r--r--main/src/cgeo/geocaching/connector/gc/Tile.java29
-rw-r--r--main/src/cgeo/geocaching/connector/gc/UTFGridPosition.java1
-rw-r--r--main/src/cgeo/geocaching/connector/gc/UncertainProperty.java1
-rw-r--r--main/src/cgeo/geocaching/connector/oc/IOCAuthParams.java9
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OCCZConnector.java34
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OCConnector.java22
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OkapiClient.java12
-rw-r--r--main/src/cgeo/geocaching/connector/ox/OXConnector.java11
-rw-r--r--main/src/cgeo/geocaching/connector/ox/OXGPXParser.java1
-rw-r--r--main/src/cgeo/geocaching/connector/trackable/GeokretyConnector.java10
-rw-r--r--main/src/cgeo/geocaching/connector/trackable/SwaggieConnector.java51
-rw-r--r--main/src/cgeo/geocaching/connector/trackable/SwaggieParser.java55
-rw-r--r--main/src/cgeo/geocaching/connector/trackable/TrackableConnector.java1
-rw-r--r--main/src/cgeo/geocaching/connector/trackable/TravelBugConnector.java1
-rw-r--r--main/src/cgeo/geocaching/connector/trackable/UnknownTrackableConnector.java2
29 files changed, 332 insertions, 133 deletions
diff --git a/main/src/cgeo/geocaching/connector/AbstractConnector.java b/main/src/cgeo/geocaching/connector/AbstractConnector.java
index 4984273..0583aa1 100644
--- a/main/src/cgeo/geocaching/connector/AbstractConnector.java
+++ b/main/src/cgeo/geocaching/connector/AbstractConnector.java
@@ -19,6 +19,7 @@ import cgeo.geocaching.location.Geopoint;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
import rx.functions.Action1;
@@ -129,7 +130,8 @@ public abstract class AbstractConnector implements IConnector {
}
@Override
- public String getGeocodeFromUrl(final String url) {
+ @Nullable
+ public String getGeocodeFromUrl(@NonNull final String url) {
final String urlPrefix = getCacheUrlPrefix();
if (StringUtils.isEmpty(urlPrefix) || StringUtils.startsWith(url, urlPrefix)) {
@NonNull final String geocode = url.substring(urlPrefix.length());
@@ -144,7 +146,7 @@ public abstract class AbstractConnector implements IConnector {
abstract protected String getCacheUrlPrefix();
@Override
- @NonNull
+ @Nullable
public String getLongCacheUrl(final @NonNull Geocache cache) {
return getCacheUrl(cache);
}
@@ -201,7 +203,7 @@ public abstract class AbstractConnector implements IConnector {
}
@Override
- public String getWaypointGpxId(final String prefix, final String geocode) {
+ public String getWaypointGpxId(final String prefix, @NonNull final String geocode) {
// Default: just return the prefix
return prefix;
}
diff --git a/main/src/cgeo/geocaching/connector/ConnectorFactory.java b/main/src/cgeo/geocaching/connector/ConnectorFactory.java
index b78b009..918911a 100644
--- a/main/src/cgeo/geocaching/connector/ConnectorFactory.java
+++ b/main/src/cgeo/geocaching/connector/ConnectorFactory.java
@@ -15,9 +15,11 @@ import cgeo.geocaching.connector.gc.GCConnector;
import cgeo.geocaching.connector.gc.MapTokens;
import cgeo.geocaching.connector.oc.OCApiConnector.ApiSupport;
import cgeo.geocaching.connector.oc.OCApiLiveConnector;
+import cgeo.geocaching.connector.oc.OCCZConnector;
import cgeo.geocaching.connector.oc.OCConnector;
import cgeo.geocaching.connector.ox.OXConnector;
import cgeo.geocaching.connector.trackable.GeokretyConnector;
+import cgeo.geocaching.connector.trackable.SwaggieConnector;
import cgeo.geocaching.connector.trackable.TrackableConnector;
import cgeo.geocaching.connector.trackable.TravelBugConnector;
import cgeo.geocaching.connector.trackable.UnknownTrackableConnector;
@@ -43,7 +45,7 @@ public final class ConnectorFactory {
new OCApiLiveConnector("opencaching.de", "www.opencaching.de", "OC", "CC BY-NC-ND, alle Logeinträge © jeweiliger Autor",
R.string.oc_de_okapi_consumer_key, R.string.oc_de_okapi_consumer_secret,
R.string.pref_connectorOCActive, R.string.pref_ocde_tokenpublic, R.string.pref_ocde_tokensecret, ApiSupport.current),
- new OCConnector("OpenCaching.CZ", "www.opencaching.cz", "OZ"),
+ new OCCZConnector(),
new OCApiLiveConnector("opencaching.org.uk", "www.opencaching.org.uk", "OK", "CC BY-NC-SA 2.5",
R.string.oc_uk_okapi_consumer_key, R.string.oc_uk_okapi_consumer_secret,
R.string.pref_connectorOCUKActive, R.string.pref_ocuk_tokenpublic, R.string.pref_ocuk_tokensecret, ApiSupport.oldapi),
@@ -74,8 +76,9 @@ public final class ConnectorFactory {
@NonNull
private static final Collection<TrackableConnector> TRACKABLE_CONNECTORS = Collections.unmodifiableCollection(Arrays.asList(new TrackableConnector[] {
- new GeokretyConnector(), // GK must be first, as it overlaps with the secret codes of travel bugs
- TravelBugConnector.getInstance(),
+ new GeokretyConnector(),
+ new SwaggieConnector(),
+ TravelBugConnector.getInstance(), // travel bugs last, as their secret codes overlap with other connectors
UNKNOWN_TRACKABLE_CONNECTOR // must be last
}));
@@ -212,9 +215,12 @@ public final class ConnectorFactory {
}
@Nullable
- public static String getGeocodeFromURL(final String url) {
+ public static String getGeocodeFromURL(@Nullable final String url) {
+ if (url == null) {
+ return null;
+ }
for (final IConnector connector : CONNECTORS) {
- final String geocode = connector.getGeocodeFromUrl(url);
+ @Nullable final String geocode = connector.getGeocodeFromUrl(url);
if (StringUtils.isNotBlank(geocode)) {
return geocode;
}
@@ -230,7 +236,6 @@ public final class ConnectorFactory {
/**
* Get the geocode of a trackable from a URL.
*
- * @param url
* @return {@code null} if the URL cannot be decoded
*/
@Nullable
diff --git a/main/src/cgeo/geocaching/connector/IConnector.java b/main/src/cgeo/geocaching/connector/IConnector.java
index 0863723..74b1028 100644
--- a/main/src/cgeo/geocaching/connector/IConnector.java
+++ b/main/src/cgeo/geocaching/connector/IConnector.java
@@ -6,6 +6,7 @@ import cgeo.geocaching.enumerations.LogType;
import cgeo.geocaching.location.Geopoint;
import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
import java.util.Collection;
import java.util.List;
@@ -14,7 +15,6 @@ public interface IConnector {
/**
* get name for display (currently only used in links)
*
- * @return
*/
@NonNull
public String getName();
@@ -31,32 +31,26 @@ public interface IConnector {
/**
* Get the browser URL for the given cache.
*
- * @param cache
- * @return
*/
- @NonNull
+ @Nullable
public String getCacheUrl(final @NonNull Geocache cache);
/**
* get long browser URL for the given cache
*
- * @param cache
- * @return
*/
- @NonNull
+ @Nullable
public String getLongCacheUrl(final @NonNull Geocache cache);
/**
* enable/disable watchlist controls in cache details
*
- * @return
*/
public boolean supportsWatchList();
/**
* Add the cache to the watchlist
*
- * @param cache
* @return True - success/False - failure
*/
public boolean addToWatchlist(@NonNull Geocache cache);
@@ -64,7 +58,6 @@ public interface IConnector {
/**
* Remove the cache from the watchlist
*
- * @param cache
* @return True - success/False - failure
*/
public boolean removeFromWatchlist(@NonNull Geocache cache);
@@ -72,28 +65,24 @@ public interface IConnector {
/**
* enable/disable favorite points controls in cache details
*
- * @return
*/
public boolean supportsFavoritePoints(@NonNull final Geocache cache);
/**
* enable/disable logging controls in cache details
*
- * @return
*/
public boolean supportsLogging();
/**
* enable/disable attaching image to log
*
- * @return
*/
public boolean supportsLogImages();
/**
* Get an ILoggingManager to guide the logging process.
*
- * @return
*/
@NonNull
public ILoggingManager getLoggingManager(@NonNull final LogCacheActivity activity, @NonNull final Geocache cache);
@@ -101,7 +90,6 @@ public interface IConnector {
/**
* Get host name of the connector server for dynamic loading of data.
*
- * @return
*/
@NonNull
public String getHost();
@@ -109,8 +97,6 @@ public interface IConnector {
/**
* Get cache data license text. This is displayed somewhere near the cache details.
*
- * @param cache
- * @return
*/
@NonNull
public String getLicenseText(final @NonNull Geocache cache);
@@ -118,8 +104,6 @@ public interface IConnector {
/**
* return true if this is a ZIP file containing a GPX file
*
- * @param fileName
- * @return
*/
public boolean isZippedGPXFile(@NonNull final String fileName);
@@ -128,17 +112,15 @@ public interface IConnector {
*
* @param cacheHasReliableLatLon
* flag of the cache
- * @return
*/
public boolean isReliableLatLon(boolean cacheHasReliableLatLon);
/**
* extract a geocode from the given URL, if this connector can handle that URL somehow
*
- * @param url
- * @return
*/
- public String getGeocodeFromUrl(final String url);
+ @Nullable
+ public String getGeocodeFromUrl(@NonNull final String url);
/**
* enable/disable uploading personal note
@@ -150,7 +132,6 @@ public interface IConnector {
/**
* Uploading personal note to website
*
- * @param cache
* @return success
*/
public boolean uploadPersonalNote(@NonNull Geocache cache);
@@ -165,7 +146,6 @@ public interface IConnector {
/**
* Resetting of modified coordinates on website to details
*
- * @param cache
* @return success
*/
public boolean deleteModifiedCoordinates(@NonNull Geocache cache);
@@ -173,8 +153,6 @@ public interface IConnector {
/**
* Uploading modified coordinates to website
*
- * @param cache
- * @param wpt
* @return success
*/
public boolean uploadModifiedCoordinates(@NonNull Geocache cache, @NonNull Geopoint wpt);
@@ -183,7 +161,6 @@ public interface IConnector {
* Return {@code true} if this connector is active for online interaction (download details, do searches, ...). If
* this is {@code false}, the connector will still be used for already stored offline caches.
*
- * @return
*/
public boolean isActive();
@@ -200,8 +177,6 @@ public interface IConnector {
* Check if the cache information is complete enough to be
* able to log online.
*
- * @param geocache
- * @return
*/
public boolean canLog(@NonNull Geocache geocache);
@@ -218,8 +193,6 @@ public interface IConnector {
* Get the list of <b>potentially</b> possible log types for a cache. Those may still be filtered further during the
* actual logging activity.
*
- * @param geocache
- * @return
*/
@NonNull
public List<LogType> getPossibleLogTypes(@NonNull Geocache geocache);
@@ -228,16 +201,12 @@ public interface IConnector {
* Get the GPX id for a waypoint when exporting. For some connectors there is an inherent name logic,
* for others its just the 'prefix'.
*
- * @param prefix
- * @return
*/
- public String getWaypointGpxId(String prefix, String geocode);
+ public String getWaypointGpxId(String prefix, @NonNull String geocode);
/**
* Get the 'prefix' (key) for a waypoint from the 'name' in the GPX file
*
- * @param name
- * @return
*/
@NonNull
public String getWaypointPrefix(String name);
@@ -245,14 +214,12 @@ public interface IConnector {
/**
* Get the maximum value for Terrain
*
- * @return
*/
public int getMaxTerrain();
/**
* Get a user readable collection of all online features of this connector.
*
- * @return
*/
@NonNull
public Collection<String> getCapabilities();
diff --git a/main/src/cgeo/geocaching/connector/ILoggingManager.java b/main/src/cgeo/geocaching/connector/ILoggingManager.java
index 40a5377..2b0a067 100644
--- a/main/src/cgeo/geocaching/connector/ILoggingManager.java
+++ b/main/src/cgeo/geocaching/connector/ILoggingManager.java
@@ -16,13 +16,8 @@ public interface ILoggingManager {
/**
* Post a log for a cache online
*
- * @param logType
- * @param date
- * @param log
* @param logPassword
* optional, maybe null
- * @param trackableLogs
- * @return
*/
@NonNull
LogResult postLog(@NonNull LogType logType,
diff --git a/main/src/cgeo/geocaching/connector/UnknownConnector.java b/main/src/cgeo/geocaching/connector/UnknownConnector.java
index fcf1152..cabf03e 100644
--- a/main/src/cgeo/geocaching/connector/UnknownConnector.java
+++ b/main/src/cgeo/geocaching/connector/UnknownConnector.java
@@ -4,6 +4,7 @@ import cgeo.geocaching.Geocache;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
class UnknownConnector extends AbstractConnector {
@@ -14,9 +15,9 @@ class UnknownConnector extends AbstractConnector {
}
@Override
- @NonNull
+ @Nullable
public String getCacheUrl(@NonNull final Geocache cache) {
- return StringUtils.EMPTY;
+ return null;
}
@Override
@@ -42,7 +43,8 @@ class UnknownConnector extends AbstractConnector {
}
@Override
- public String getGeocodeFromUrl(final String url) {
+ @Nullable
+ public String getGeocodeFromUrl(@NonNull final String url) {
return null;
}
diff --git a/main/src/cgeo/geocaching/connector/WaymarkingConnector.java b/main/src/cgeo/geocaching/connector/WaymarkingConnector.java
index 5a6f362..3361341 100644
--- a/main/src/cgeo/geocaching/connector/WaymarkingConnector.java
+++ b/main/src/cgeo/geocaching/connector/WaymarkingConnector.java
@@ -4,6 +4,7 @@ import cgeo.geocaching.Geocache;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
class WaymarkingConnector extends AbstractConnector {
@@ -41,4 +42,20 @@ class WaymarkingConnector extends AbstractConnector {
public boolean canHandle(@NonNull final String geocode) {
return StringUtils.startsWith(geocode, "WM");
}
+
+ @Override
+ @Nullable
+ public String getGeocodeFromUrl(@NonNull final String url) {
+ // coord.info URLs
+ String code = StringUtils.substringAfterLast(url, "coord.info/");
+ if (code != null && canHandle(code)) {
+ return code;
+ }
+ // waymarking URLs http://www.waymarking.com/waymarks/WMNCDT_American_Legion_Flagpole_1983_University_of_Oregon
+ code = StringUtils.substringBetween(url, "waymarks/", "_");
+ if (code != null && canHandle(code)) {
+ return code;
+ }
+ return null;
+ }
}
diff --git a/main/src/cgeo/geocaching/connector/capability/ILogin.java b/main/src/cgeo/geocaching/connector/capability/ILogin.java
index 003ccf4..437eec8 100644
--- a/main/src/cgeo/geocaching/connector/capability/ILogin.java
+++ b/main/src/cgeo/geocaching/connector/capability/ILogin.java
@@ -27,14 +27,12 @@ public interface ILogin extends IConnector {
/**
* Returns the status of the last {@link #login(Handler, Context)} request.
*
- * @return
*/
boolean isLoggedIn();
/**
* User-centered string describing the current login/connection status
*
- * @return
*/
String getLoginStatusString();
@@ -42,7 +40,6 @@ public interface ILogin extends IConnector {
* Name the user has in this connector or empty string if not applicable.
* It might be necessary to execute {@link #login(Handler, Context)} before this information is valid.
*
- * @return
*/
String getUserName();
@@ -51,7 +48,6 @@ public interface ILogin extends IConnector {
* Normally retrieved/updated with {@link #login(Handler, Context)}.
* Might be stale as changes on the connectors site are generally not notified.
*
- * @return
*/
int getCachesFound();
diff --git a/main/src/cgeo/geocaching/connector/capability/IgnoreCapability.java b/main/src/cgeo/geocaching/connector/capability/IgnoreCapability.java
new file mode 100644
index 0000000..5eca3f2
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/capability/IgnoreCapability.java
@@ -0,0 +1,14 @@
+package cgeo.geocaching.connector.capability;
+
+import cgeo.geocaching.Geocache;
+import cgeo.geocaching.connector.IConnector;
+
+import org.eclipse.jdt.annotation.NonNull;
+
+/**
+ * Connector capability to ignore caches.
+ */
+public interface IgnoreCapability extends IConnector {
+ public boolean canIgnoreCache(final @NonNull Geocache cache);
+ public void ignoreCache(final @NonNull Geocache cache);
+}
diff --git a/main/src/cgeo/geocaching/connector/ec/ECConnector.java b/main/src/cgeo/geocaching/connector/ec/ECConnector.java
index 15c2dc2..68dbee7 100644
--- a/main/src/cgeo/geocaching/connector/ec/ECConnector.java
+++ b/main/src/cgeo/geocaching/connector/ec/ECConnector.java
@@ -234,4 +234,14 @@ public class ECConnector extends AbstractConnector implements ISearchByGeocode,
return R.string.pref_ecpassword;
}
+ @Override
+ @Nullable
+ public String getGeocodeFromUrl(@NonNull final String url) {
+ final String geocode = "EC" + StringUtils.substringAfter(url, "extremcaching.com/index.php/output-2/");
+ if (canHandle(geocode)) {
+ return geocode;
+ }
+ return super.getGeocodeFromUrl(url);
+ }
+
}
diff --git a/main/src/cgeo/geocaching/connector/ec/ECLogin.java b/main/src/cgeo/geocaching/connector/ec/ECLogin.java
index 3ae8298..94b450b 100644
--- a/main/src/cgeo/geocaching/connector/ec/ECLogin.java
+++ b/main/src/cgeo/geocaching/connector/ec/ECLogin.java
@@ -88,7 +88,6 @@ public class ECLogin extends AbstractLogin {
/**
* Check if the user has been logged in when he retrieved the data.
*
- * @param data
* @return <code>true</code> if user is logged in, <code>false</code> otherwise
*/
private boolean getLoginStatus(@Nullable final String data) {
diff --git a/main/src/cgeo/geocaching/connector/gc/GCConnector.java b/main/src/cgeo/geocaching/connector/gc/GCConnector.java
index e43b9b5..2349392 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCConnector.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCConnector.java
@@ -19,6 +19,7 @@ import cgeo.geocaching.connector.capability.ISearchByGeocode;
import cgeo.geocaching.connector.capability.ISearchByKeyword;
import cgeo.geocaching.connector.capability.ISearchByOwner;
import cgeo.geocaching.connector.capability.ISearchByViewPort;
+import cgeo.geocaching.connector.capability.IgnoreCapability;
import cgeo.geocaching.enumerations.StatusCode;
import cgeo.geocaching.loaders.RecaptchaReceiver;
import cgeo.geocaching.location.Geopoint;
@@ -47,7 +48,7 @@ import java.io.File;
import java.util.List;
import java.util.regex.Pattern;
-public class GCConnector extends AbstractConnector implements ISearchByGeocode, ISearchByCenter, ISearchByViewPort, ISearchByKeyword, ILogin, ICredentials, ISearchByOwner, ISearchByFinder, FieldNotesCapability {
+public class GCConnector extends AbstractConnector implements ISearchByGeocode, ISearchByCenter, ISearchByViewPort, ISearchByKeyword, ILogin, ICredentials, ISearchByOwner, ISearchByFinder, FieldNotesCapability, IgnoreCapability {
@NonNull
private static final String CACHE_URL_SHORT = "http://coord.info/";
@@ -305,7 +306,8 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode,
}
@Override
- public String getGeocodeFromUrl(final String url) {
+ @Nullable
+ public String getGeocodeFromUrl(@NonNull final String url) {
// coord.info URLs
String code = StringUtils.substringAfterLast(url, "coord.info/");
if (code != null && canHandle(code)) {
@@ -375,7 +377,7 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode,
}
@Override
- public String getWaypointGpxId(final String prefix, final String geocode) {
+ public String getWaypointGpxId(final String prefix, @NonNull final String geocode) {
String gpxId = prefix;
if (StringUtils.isNotBlank(geocode) && geocode.length() > 2) {
gpxId += geocode.substring(2);
@@ -480,4 +482,14 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode,
return true;
}
+ @Override
+ public boolean canIgnoreCache(@NonNull final Geocache cache) {
+ return StringUtils.isNotEmpty(cache.getType().wptTypeId);
+ }
+
+ @Override
+ public void ignoreCache(@NonNull final Geocache cache) {
+ GCParser.ignoreCache(cache);
+ }
+
}
diff --git a/main/src/cgeo/geocaching/connector/gc/GCLogin.java b/main/src/cgeo/geocaching/connector/gc/GCLogin.java
index 035176b..71c31c1 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCLogin.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCLogin.java
@@ -166,7 +166,6 @@ public class GCLogin extends AbstractLogin {
/**
* Check if the user has been logged in when he retrieved the data.
*
- * @param page
* @return <code>true</code> if user is logged in, <code>false</code> otherwise
*/
boolean getLoginStatus(@Nullable final String page) {
@@ -412,8 +411,6 @@ public class GCLogin extends AbstractLogin {
/**
* POST HTTP request. Do the request a second time if the user is not logged in
*
- * @param uri
- * @return
*/
String postRequestLogged(final String uri, final Parameters params) {
final String data = Network.getResponseData(Network.postRequest(uri, params));
@@ -433,9 +430,6 @@ public class GCLogin extends AbstractLogin {
/**
* GET HTTP request. Do the request a second time if the user is not logged in
*
- * @param uri
- * @param params
- * @return
*/
@Nullable
String getRequestLogged(@NonNull final String uri, @Nullable final Parameters params) {
@@ -459,8 +453,6 @@ public class GCLogin extends AbstractLogin {
* Unfortunately the cache details page contains user generated whitespace in the personal note, therefore we cannot
* remove the white space from cache details pages.
*
- * @param uri
- * @return
*/
private static boolean canRemoveWhitespace(final String uri) {
return !StringUtils.contains(uri, "cache_details");
diff --git a/main/src/cgeo/geocaching/connector/gc/GCMap.java b/main/src/cgeo/geocaching/connector/gc/GCMap.java
index 1571faa..243d84c 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCMap.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCMap.java
@@ -11,8 +11,8 @@ import cgeo.geocaching.location.Geopoint;
import cgeo.geocaching.location.GeopointFormatter.Format;
import cgeo.geocaching.location.Units;
import cgeo.geocaching.location.Viewport;
-import cgeo.geocaching.maps.LiveMapStrategy.Strategy;
-import cgeo.geocaching.maps.LiveMapStrategy.StrategyFlag;
+import cgeo.geocaching.maps.LivemapStrategy;
+import cgeo.geocaching.maps.LivemapStrategy.Flag;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.sensors.Sensors;
import cgeo.geocaching.settings.Settings;
@@ -110,7 +110,7 @@ public class GCMap {
* Retrieved data.
* @return SearchResult. Never null.
*/
- public static SearchResult parseMapJSON(final String data, final Tile tile, final Bitmap bitmap, final Strategy strategy) {
+ public static SearchResult parseMapJSON(final String data, final Tile tile, final Bitmap bitmap, final LivemapStrategy strategy) {
final SearchResult searchResult = new SearchResult();
try {
@@ -185,7 +185,7 @@ public class GCMap {
cache.setGeocode(id);
cache.setName(nameCache.get(id));
cache.setCoords(tile.getCoord(xy), tile.getZoomLevel());
- if (strategy.flags.contains(StrategyFlag.PARSE_TILES) && bitmap != null) {
+ if (strategy.flags.contains(LivemapStrategy.Flag.PARSE_TILES) && bitmap != null) {
for (final UTFGridPosition singlePos : singlePositions.get(id)) {
if (IconDecoder.parseMapPNG(cache, bitmap, singlePos, tile.getZoomLevel())) {
break; // cache parsed
@@ -226,14 +226,13 @@ public class GCMap {
* Area to search
* @param tokens
* Live map tokens
- * @return
*/
@NonNull
public static SearchResult searchByViewport(final Viewport viewport, final MapTokens tokens) {
final int speed = (int) Sensors.getInstance().currentGeo().getSpeed() * 60 * 60 / 1000; // in km/h
- Strategy strategy = Settings.getLiveMapStrategy();
- if (strategy == Strategy.AUTO) {
- strategy = speed >= 30 ? Strategy.FAST : Strategy.DETAILED;
+ LivemapStrategy strategy = Settings.getLiveMapStrategy();
+ if (strategy == LivemapStrategy.AUTO) {
+ strategy = speed >= 30 ? LivemapStrategy.FAST : LivemapStrategy.DETAILED;
}
final SearchResult result = searchByViewport(viewport, tokens, strategy);
@@ -257,10 +256,9 @@ public class GCMap {
* Live map tokens
* @param strategy
* Strategy for data retrieval and parsing, @see Strategy
- * @return
*/
@NonNull
- private static SearchResult searchByViewport(final Viewport viewport, final MapTokens tokens, final Strategy strategy) {
+ private static SearchResult searchByViewport(final Viewport viewport, final MapTokens tokens, final LivemapStrategy strategy) {
Log.d("GCMap.searchByViewport" + viewport.toString());
final SearchResult searchResult = new SearchResult();
@@ -269,7 +267,7 @@ public class GCMap {
searchResult.setUrl(viewport.getCenter().format(Format.LAT_LON_DECMINUTE));
}
- if (strategy.flags.contains(StrategyFlag.LOAD_TILES)) {
+ if (strategy.flags.contains(LivemapStrategy.Flag.LOAD_TILES)) {
final Set<Tile> tiles = Tile.getTilesForViewport(viewport);
if (Settings.isDebug()) {
@@ -339,7 +337,7 @@ public class GCMap {
}
}
- if (strategy.flags.contains(StrategyFlag.SEARCH_NEARBY) && Settings.isGCPremiumMember()) {
+ if (strategy.flags.contains(Flag.SEARCH_NEARBY) && Settings.isGCPremiumMember()) {
final Geopoint center = viewport.getCenter();
if ((lastSearchViewport == null) || !lastSearchViewport.contains(center)) {
//FIXME We don't have a RecaptchaReceiver!?
@@ -360,7 +358,6 @@ public class GCMap {
*
* @param typeToDisplay
* - cache type to omit from exclusion list so it gets displayed
- * @return
*
* cache types for live map filter:
* 2 = traditional, 9 = ape, 5 = letterbox
diff --git a/main/src/cgeo/geocaching/connector/gc/GCParser.java b/main/src/cgeo/geocaching/connector/gc/GCParser.java
index d5ea8c4..d0a90bb 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCParser.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCParser.java
@@ -57,7 +57,6 @@ import rx.functions.Action1;
import rx.functions.Func0;
import rx.functions.Func2;
import rx.schedulers.Schedulers;
-import rx.util.async.Async;
import android.net.Uri;
import android.text.Html;
@@ -65,6 +64,7 @@ import android.text.Html;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.text.Collator;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
@@ -304,12 +304,13 @@ public abstract class GCParser {
if (!cids.isEmpty() && (Settings.isGCPremiumMember() || showCaptcha) && ((recaptchaReceiver == null || StringUtils.isBlank(recaptchaReceiver.getChallenge())) || StringUtils.isNotBlank(recaptchaText))) {
Log.i("Trying to get .loc for " + cids.size() + " caches");
- final Observable<Set<Geocache>> storedCaches = Async.start(new Func0<Set<Geocache>>() {
+ final Observable<Set<Geocache>> storedCaches = Observable.defer(new Func0<Observable<Set<Geocache>>>() {
@Override
- public Set<Geocache> call() {
- return DataStore.loadCaches(Geocache.getGeocodes(caches), LoadFlags.LOAD_CACHE_OR_DB);
+ public Observable<Set<Geocache>> call() {
+ return Observable.just(DataStore.loadCaches(Geocache.getGeocodes(caches), LoadFlags.LOAD_CACHE_OR_DB));
}
- }, Schedulers.io());
+ }).subscribeOn(Schedulers.io()).cache();
+ storedCaches.subscribe(); // Force asynchronous start of database loading
try {
// get coordinates for parsed caches
@@ -987,22 +988,22 @@ public abstract class GCParser {
* Observable that fetches a list of pocket queries. Returns a single element (which may be an empty list).
* Executes on the network scheduler.
*/
- public static final Observable<List<PocketQueryList>> searchPocketQueryListObservable = Async.fromCallable(new Func0<List<PocketQueryList>>() {
+ public static final Observable<List<PocketQueryList>> searchPocketQueryListObservable = Observable.defer(new Func0<Observable<List<PocketQueryList>>>() {
@Override
- public List<PocketQueryList> call() {
+ public Observable<List<PocketQueryList>> call() {
final Parameters params = new Parameters();
final String page = GCLogin.getInstance().getRequestLogged("http://www.geocaching.com/pocket/default.aspx", params);
if (StringUtils.isBlank(page)) {
Log.e("GCParser.searchPocketQueryList: No data from server");
- return Collections.emptyList();
+ return Observable.just(Collections.<PocketQueryList>emptyList());
}
final String subPage = StringUtils.substringAfter(page, "class=\"PocketQueryListTable");
if (StringUtils.isEmpty(subPage)) {
Log.e("GCParser.searchPocketQueryList: class \"PocketQueryListTable\" not found on page");
- return Collections.emptyList();
+ return Observable.just(Collections.<PocketQueryList>emptyList());
}
final List<PocketQueryList> list = new ArrayList<>();
@@ -1024,17 +1025,18 @@ public abstract class GCParser {
}
// just in case, lets sort the resulting list
+ final Collator collator = TextUtils.getCollator();
Collections.sort(list, new Comparator<PocketQueryList>() {
@Override
public int compare(final PocketQueryList left, final PocketQueryList right) {
- return String.CASE_INSENSITIVE_ORDER.compare(left.getName(), right.getName());
+ return collator.compare(left.getName(), right.getName());
}
});
- return list;
+ return Observable.just(list);
}
- }, RxUtils.networkScheduler);
+ }).subscribeOn(RxUtils.networkScheduler);
public static ImmutablePair<StatusCode, String> postLog(final String geocode, final String cacheid, final String[] viewstates,
final LogType logType, final int year, final int month, final int day,
@@ -1985,4 +1987,25 @@ public abstract class GCParser {
return false;
}
+ public static boolean ignoreCache(@NonNull final Geocache cache) {
+ final String uri = "http://www.geocaching.com/bookmarks/ignore.aspx?guid=" + cache.getGuid() + "&WptTypeID=" + cache.getType().wptTypeId;
+ final String page = GCLogin.getInstance().postRequestLogged(uri, null);
+
+ if (StringUtils.isBlank(page)) {
+ Log.e("GCParser.ignoreCache: No data from server");
+ return false;
+ }
+
+ final String[] viewstates = GCLogin.getViewstates(page);
+
+ final Parameters params = new Parameters(
+ "__EVENTTARGET", "",
+ "__EVENTARGUMENT", "",
+ "ctl00$ContentBody$btnYes", "Yes. Ignore it.");
+
+ GCLogin.putViewstates(params, viewstates);
+ final String response = Network.getResponseData(Network.postRequest(uri, params));
+
+ return StringUtils.contains(response, "<p class=\"Success\">");
+ }
}
diff --git a/main/src/cgeo/geocaching/connector/gc/Tile.java b/main/src/cgeo/geocaching/connector/gc/Tile.java
index 93b61f9..dd6371b 100644
--- a/main/src/cgeo/geocaching/connector/gc/Tile.java
+++ b/main/src/cgeo/geocaching/connector/gc/Tile.java
@@ -15,7 +15,6 @@ import org.eclipse.jdt.annotation.NonNull;
import rx.Observable;
import rx.functions.Func0;
-import rx.util.async.Async;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -144,7 +143,6 @@ public class Tile {
* First point
* @param right
* Second point
- * @return
*/
static int calcZoomLon(final Geopoint left, final Geopoint right, final int numberOfTiles) {
@@ -177,7 +175,6 @@ public class Tile {
* First point
* @param top
* Second point
- * @return
*/
static int calcZoomLat(final Geopoint bottom, final Geopoint top, final int numberOfTiles) {
@@ -208,8 +205,6 @@ public class Tile {
* Calculates the inverted hyperbolic sine
* (after Bronstein, Semendjajew: Taschenbuch der Mathematik)
*
- * @param x
- * @return
*/
private static double asinh(final double x) {
return Math.log(x + Math.sqrt(x * x + 1.0));
@@ -241,12 +236,12 @@ public class Tile {
static Observable<String> requestMapInfo(final String url, final Parameters params, final String referer) {
final HttpResponse response = Network.getRequest(url, params, new Parameters("Referer", referer));
- return Async.start(new Func0<String>() {
+ return Observable.defer(new Func0<Observable<String>>() {
@Override
- public String call() {
- return Network.getResponseData(response);
+ public Observable<String> call() {
+ return Observable.just(Network.getResponseData(response));
}
- }, RxUtils.networkScheduler);
+ }).subscribeOn(RxUtils.networkScheduler);
}
/** Request .png image for a tile. Return as soon as the request has been made, before the answer has been
@@ -256,17 +251,17 @@ public class Tile {
*/
static Observable<Bitmap> requestMapTile(final Parameters params) {
final HttpResponse response = Network.getRequest(GCConstants.URL_MAP_TILE, params, new Parameters("Referer", GCConstants.URL_LIVE_MAP));
- return Async.start(new Func0<Bitmap>() {
+ return Observable.defer(new Func0<Observable<Bitmap>>() {
@Override
- public Bitmap call() {
+ public Observable<Bitmap> call() {
try {
- return response != null ? BitmapFactory.decodeStream(response.getEntity().getContent()) : null;
+ return Observable.just(response != null ? BitmapFactory.decodeStream(response.getEntity().getContent()) : null);
} catch (final IOException e) {
Log.e("Tile.requestMapTile() ", e);
- return null;
+ return Observable.just(null);
}
}
- }, RxUtils.computationScheduler);
+ }).subscribeOn(RxUtils.computationScheduler);
}
public boolean containsPoint(final @NonNull ICoordinates point) {
@@ -281,8 +276,6 @@ public class Tile {
* Calculate needed tiles for the given viewport to cover it with
* max 2x2 tiles
*
- * @param viewport
- * @return
*/
protected static Set<Tile> getTilesForViewport(final Viewport viewport) {
return getTilesForViewport(viewport, 2, Tile.ZOOMLEVEL_MIN);
@@ -293,10 +286,6 @@ public class Tile {
* You can define the minimum number of tiles on the longer axis
* and/or the minimum zoom level.
*
- * @param viewport
- * @param tilesOnAxis
- * @param minZoom
- * @return
*/
protected static Set<Tile> getTilesForViewport(final Viewport viewport, final int tilesOnAxis, final int minZoom) {
final Set<Tile> tiles = new HashSet<>();
diff --git a/main/src/cgeo/geocaching/connector/gc/UTFGridPosition.java b/main/src/cgeo/geocaching/connector/gc/UTFGridPosition.java
index 9de7e1e..f5cd208 100644
--- a/main/src/cgeo/geocaching/connector/gc/UTFGridPosition.java
+++ b/main/src/cgeo/geocaching/connector/gc/UTFGridPosition.java
@@ -36,7 +36,6 @@ final class UTFGridPosition {
/**
* @param key
* Key in the format (xx, xx)
- * @return
*/
static UTFGridPosition fromString(final String key) {
final MatcherWrapper matcher = new MatcherWrapper(UTFGridPosition.PATTERN_JSON_KEY, key);
diff --git a/main/src/cgeo/geocaching/connector/gc/UncertainProperty.java b/main/src/cgeo/geocaching/connector/gc/UncertainProperty.java
index 71adcbd..c9e01a2 100644
--- a/main/src/cgeo/geocaching/connector/gc/UncertainProperty.java
+++ b/main/src/cgeo/geocaching/connector/gc/UncertainProperty.java
@@ -4,7 +4,6 @@ package cgeo.geocaching.connector.gc;
/**
* Property with certainty. When merging properties, the one with higher certainty wins.
*
- * @param <T>
*/
public class UncertainProperty<T> {
diff --git a/main/src/cgeo/geocaching/connector/oc/IOCAuthParams.java b/main/src/cgeo/geocaching/connector/oc/IOCAuthParams.java
index acf7b48..5e5151a 100644
--- a/main/src/cgeo/geocaching/connector/oc/IOCAuthParams.java
+++ b/main/src/cgeo/geocaching/connector/oc/IOCAuthParams.java
@@ -7,7 +7,6 @@ public interface IOCAuthParams {
/**
* The site name: 'www.opencaching...'
*
- * @return
*/
@NonNull
String getSite();
@@ -15,56 +14,48 @@ public interface IOCAuthParams {
/**
* ResId of the Consumer key
*
- * @return
*/
int getCKResId();
/**
* ResId of the Consumer secret
*
- * @return
*/
int getCSResId();
/**
* ResId of the Authorization title
*
- * @return
*/
int getAuthTitleResId();
/**
* Preference key of the public token
*
- * @return
*/
int getTokenPublicPrefKey();
/**
* Preference key of the secret token
*
- * @return
*/
int getTokenSecretPrefKey();
/**
* Preference key of the temporary public token (OAuth)
*
- * @return
*/
int getTempTokenPublicPrefKey();
/**
* Preference key of the temporary secret token (OAuth)
*
- * @return
*/
int getTempTokenSecretPrefKey();
/**
* The URI to use as a callback (OAuth)
*
- * @return
*/
@NonNull
String getCallbackUri();
diff --git a/main/src/cgeo/geocaching/connector/oc/OCCZConnector.java b/main/src/cgeo/geocaching/connector/oc/OCCZConnector.java
new file mode 100644
index 0000000..ee4330a
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/oc/OCCZConnector.java
@@ -0,0 +1,34 @@
+package cgeo.geocaching.connector.oc;
+
+import cgeo.geocaching.utils.Log;
+
+import org.apache.commons.lang3.StringUtils;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+
+public class OCCZConnector extends OCConnector {
+
+ private static final String GEOCODE_PREFIX = "OZ";
+
+ public OCCZConnector() {
+ super("OpenCaching.CZ", "www.opencaching.cz", GEOCODE_PREFIX);
+ }
+
+ @Override
+ @Nullable
+ public String getGeocodeFromUrl(@NonNull final String url) {
+ if (!StringUtils.containsIgnoreCase(url, "opencaching.cz")) {
+ return null;
+ }
+ final String id = StringUtils.substringAfter(url, "cacheid=");
+ try {
+ final String geocode = GEOCODE_PREFIX + StringUtils.leftPad(Integer.toHexString(Integer.parseInt(id)), 4, '0');
+ if (canHandle(geocode)) {
+ return geocode;
+ }
+ } catch (final NumberFormatException e) {
+ Log.e("Unexpected URL for opencaching.cz " + url);
+ }
+ return super.getGeocodeFromUrl(url);
+ }
+}
diff --git a/main/src/cgeo/geocaching/connector/oc/OCConnector.java b/main/src/cgeo/geocaching/connector/oc/OCConnector.java
index 8ac457b..6d7b23a 100644
--- a/main/src/cgeo/geocaching/connector/oc/OCConnector.java
+++ b/main/src/cgeo/geocaching/connector/oc/OCConnector.java
@@ -5,7 +5,9 @@ import cgeo.geocaching.R;
import cgeo.geocaching.connector.AbstractConnector;
import cgeo.geocaching.enumerations.LogType;
+import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
import java.util.Arrays;
import java.util.List;
@@ -83,4 +85,24 @@ public class OCConnector extends AbstractConnector {
return STANDARD_LOG_TYPES;
}
+
+ @Override
+ @Nullable
+ public String getGeocodeFromUrl(@NonNull final String url) {
+ // different opencaching installations have different supported URLs
+
+ // host.tld/geocode
+ final String shortHost = StringUtils.remove(getHost(), "www.");
+ String geocode = StringUtils.substringAfter(url, shortHost + "/");
+ if (canHandle(geocode)) {
+ return geocode;
+ }
+
+ // host.tld/viewcache.php?wp=geocode
+ geocode = StringUtils.substringAfter(url, shortHost + "/viewcache.php?wp=");
+ if (canHandle(geocode)) {
+ return geocode;
+ }
+ return super.getGeocodeFromUrl(url);
+ }
}
diff --git a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java
index 275a103..e7d4e6f 100644
--- a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java
+++ b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java
@@ -30,6 +30,7 @@ import cgeo.geocaching.network.OAuth;
import cgeo.geocaching.network.OAuthTokens;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.settings.Settings;
+import cgeo.geocaching.utils.HtmlUtils;
import cgeo.geocaching.utils.JsonUtils;
import cgeo.geocaching.utils.Log;
import cgeo.geocaching.utils.SynchronizedDateFormat;
@@ -62,8 +63,16 @@ import java.util.Map;
import java.util.TimeZone;
import java.util.regex.Pattern;
+/**
+ * Client for the OpenCaching API (Okapi).
+ *
+ * @see <a href="http://www.opencaching.de/okapi/introduction.html">Okapi overview</a>
+ *
+ */
final class OkapiClient {
+ private static final String PARAMETER_LOGCOUNT_VALUE = "all";
+ private static final String PARAMETER_LOGCOUNT_KEY = "lpc";
private static final char SEPARATOR = '|';
private static final String SEPARATOR_STRING = Character.toString(SEPARATOR);
private static final SynchronizedDateFormat LOG_DATE_FORMAT = new SynchronizedDateFormat("yyyy-MM-dd HH:mm:ss.SSSZ", TimeZone.getTimeZone("UTC"), Locale.US);
@@ -149,6 +158,7 @@ final class OkapiClient {
params.add("fields", getFullFields(ocapiConn));
params.add("attribution_append", "none");
+ params.add(PARAMETER_LOGCOUNT_KEY, PARAMETER_LOGCOUNT_VALUE);
final JSONResult result = request(ocapiConn, OkapiService.SERVICE_CACHE, params);
@@ -458,7 +468,7 @@ final class OkapiClient {
parseUser(logResponse.get(LOG_USER)),
parseDate(logResponse.get(LOG_DATE).asText()).getTime(),
parseLogType(logResponse.get(LOG_TYPE).asText()),
- logResponse.get(LOG_COMMENT).asText().trim());
+ HtmlUtils.removeExtraParagraph(logResponse.get(LOG_COMMENT).asText().trim()));
result.add(log);
} catch (final NullPointerException e) {
Log.e("OkapiClient.parseLogs", e);
diff --git a/main/src/cgeo/geocaching/connector/ox/OXConnector.java b/main/src/cgeo/geocaching/connector/ox/OXConnector.java
index 41035d1..d1db301 100644
--- a/main/src/cgeo/geocaching/connector/ox/OXConnector.java
+++ b/main/src/cgeo/geocaching/connector/ox/OXConnector.java
@@ -14,6 +14,7 @@ import cgeo.geocaching.location.Viewport;
import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.utils.CancellableHandler;
+import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
@@ -109,4 +110,14 @@ public class OXConnector extends AbstractConnector implements ISearchByCenter, I
}
return new SearchResult(caches);
}
+
+ @Override
+ @Nullable
+ public String getGeocodeFromUrl(@NonNull final String url) {
+ final String geocode = StringUtils.substringAfter(url, "http://www.opencaching.com/de/#!geocache/");
+ if (canHandle(geocode)) {
+ return geocode;
+ }
+ return super.getGeocodeFromUrl(url);
+ }
}
diff --git a/main/src/cgeo/geocaching/connector/ox/OXGPXParser.java b/main/src/cgeo/geocaching/connector/ox/OXGPXParser.java
index 7896826..25f66f4 100644
--- a/main/src/cgeo/geocaching/connector/ox/OXGPXParser.java
+++ b/main/src/cgeo/geocaching/connector/ox/OXGPXParser.java
@@ -29,7 +29,6 @@ public class OXGPXParser extends GPX10Parser {
* The short description of OX caches contains "title by owner, type(T/D/Awesomeness)". That is a lot of
* duplication. Additionally a space between type and (T/D/Awesomeness) is introduced.
*
- * @param cache
*/
private static void removeTitleFromShortDescription(final @NonNull Geocache cache) {
cache.setShortDescription(StringUtils.replace(StringUtils.trim(StringUtils.substringAfterLast(cache.getShortDescription(), ",")), "(", " ("));
diff --git a/main/src/cgeo/geocaching/connector/trackable/GeokretyConnector.java b/main/src/cgeo/geocaching/connector/trackable/GeokretyConnector.java
index b6792f0..6f9b21a 100644
--- a/main/src/cgeo/geocaching/connector/trackable/GeokretyConnector.java
+++ b/main/src/cgeo/geocaching/connector/trackable/GeokretyConnector.java
@@ -26,6 +26,7 @@ public class GeokretyConnector extends AbstractTrackableConnector {
}
@Override
+ @Nullable
public Trackable searchTrackable(final String geocode, final String guid, final String id) {
final String page = Network.getResponseData(Network.getRequest("http://geokrety.org/export2.php?gkid=" + getId(geocode)));
if (page == null) {
@@ -48,7 +49,12 @@ public class GeokretyConnector extends AbstractTrackableConnector {
public @Nullable
String getTrackableCodeFromUrl(@NonNull final String url) {
// http://geokrety.org/konkret.php?id=38545
- final String id = StringUtils.substringAfterLast(url, "konkret.php?id=");
+ String id = StringUtils.substringAfterLast(url, "konkret.php?id=");
+ if (StringUtils.isNumeric(id)) {
+ return geocode(Integer.parseInt(id));
+ }
+ // http://geokretymap.org/38545
+ id = StringUtils.substringAfterLast(url, "geokretymap.org/");
if (StringUtils.isNumeric(id)) {
return geocode(Integer.parseInt(id));
}
@@ -58,8 +64,6 @@ public class GeokretyConnector extends AbstractTrackableConnector {
/**
* Get geocode from geokrety id
*
- * @param id
- * @return
*/
public static String geocode(final int id) {
return String.format("GK%04X", id);
diff --git a/main/src/cgeo/geocaching/connector/trackable/SwaggieConnector.java b/main/src/cgeo/geocaching/connector/trackable/SwaggieConnector.java
new file mode 100644
index 0000000..dcd618c
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/trackable/SwaggieConnector.java
@@ -0,0 +1,51 @@
+package cgeo.geocaching.connector.trackable;
+
+import cgeo.geocaching.Trackable;
+import cgeo.geocaching.network.Network;
+
+import org.apache.commons.lang3.StringUtils;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+
+import java.util.regex.Pattern;
+
+public final class SwaggieConnector extends AbstractTrackableConnector {
+
+ private static final Pattern PATTERN_SW_CODE = Pattern.compile("SW[0-9]{4}");
+
+ @Override
+ public boolean canHandleTrackable(final String geocode) {
+ return geocode != null && PATTERN_SW_CODE.matcher(geocode).matches();
+ }
+
+ @Override
+ @NonNull
+ public String getUrl(@NonNull final Trackable trackable) {
+ return getUrl(trackable.getGeocode());
+ }
+
+ @Override
+ @Nullable
+ public Trackable searchTrackable(final String geocode, final String guid, final String id) {
+ final String page = Network.getResponseData(Network.getRequest(getUrl(geocode)));
+ if (page == null) {
+ return null;
+ }
+ return SwaggieParser.parse(page);
+ }
+
+ @Override
+ @Nullable
+ public String getTrackableCodeFromUrl(@NonNull final String url) {
+ final String geocode = StringUtils.upperCase(StringUtils.substringAfterLast(url, "swaggie/"));
+ if (canHandleTrackable(geocode)) {
+ return geocode;
+ }
+ return null;
+ }
+
+ private static String getUrl(final String geocode) {
+ return "http://geocaching.com.au/swaggie/" + geocode;
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/connector/trackable/SwaggieParser.java b/main/src/cgeo/geocaching/connector/trackable/SwaggieParser.java
new file mode 100644
index 0000000..1883056
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/trackable/SwaggieParser.java
@@ -0,0 +1,55 @@
+package cgeo.geocaching.connector.trackable;
+
+import cgeo.geocaching.Trackable;
+import cgeo.geocaching.utils.TextUtils;
+
+import org.apache.commons.lang3.StringUtils;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+
+import java.util.regex.Pattern;
+
+final class SwaggieParser {
+
+ private SwaggieParser() {
+ // utility class
+ }
+
+ private static final Pattern PATTERN_NAME = Pattern.compile(Pattern.quote("<h1><a") + ".*?>(.*?)<");
+ private static final Pattern PATTERN_GEOCODE = Pattern.compile(Pattern.quote("'/swaggie/") + "(.*?)'");
+ private static final Pattern PATTERN_DESCRIPTION = Pattern.compile(Pattern.quote("'swaggie_description'>") + "(.*?)</div");
+ private static final Pattern PATTERN_OWNER = Pattern.compile(">([^<]*?)</a> released");
+
+ @Nullable
+ public static Trackable parse(@NonNull final String page) {
+ final Trackable trackable = new Trackable();
+ final String name = TextUtils.getMatch(page, PATTERN_NAME, null);
+ if (StringUtils.isEmpty(name)) {
+ return null;
+ }
+ trackable.setName(name);
+
+ final String geocode = TextUtils.getMatch(page, PATTERN_GEOCODE, null);
+ if (StringUtils.isEmpty(geocode)) {
+ return null;
+ }
+ trackable.setGeocode(geocode);
+
+ final String description = StringUtils.trim(TextUtils.getMatch(page, PATTERN_DESCRIPTION, StringUtils.EMPTY));
+ if (StringUtils.isEmpty(description)) {
+ return null;
+ }
+ trackable.setDetails(description);
+
+ final String owner = StringUtils.trim(TextUtils.getMatch(page, PATTERN_OWNER, StringUtils.EMPTY));
+ if (StringUtils.isEmpty(owner)) {
+ return null;
+ }
+ trackable.setOwner(owner);
+
+ trackable.setType("Swaggie");
+
+ return trackable;
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/connector/trackable/TrackableConnector.java b/main/src/cgeo/geocaching/connector/trackable/TrackableConnector.java
index 01c1897..1281683 100644
--- a/main/src/cgeo/geocaching/connector/trackable/TrackableConnector.java
+++ b/main/src/cgeo/geocaching/connector/trackable/TrackableConnector.java
@@ -21,6 +21,7 @@ public interface TrackableConnector {
public boolean isLoggable();
+ @Nullable
public Trackable searchTrackable(String geocode, String guid, String id);
@Nullable
diff --git a/main/src/cgeo/geocaching/connector/trackable/TravelBugConnector.java b/main/src/cgeo/geocaching/connector/trackable/TravelBugConnector.java
index 5d825a3..665ebea 100644
--- a/main/src/cgeo/geocaching/connector/trackable/TravelBugConnector.java
+++ b/main/src/cgeo/geocaching/connector/trackable/TravelBugConnector.java
@@ -36,6 +36,7 @@ public class TravelBugConnector extends AbstractTrackableConnector {
}
@Override
+ @Nullable
public Trackable searchTrackable(final String geocode, final String guid, final String id) {
return GCParser.searchTrackable(geocode, guid, id);
}
diff --git a/main/src/cgeo/geocaching/connector/trackable/UnknownTrackableConnector.java b/main/src/cgeo/geocaching/connector/trackable/UnknownTrackableConnector.java
index 7e7e1b6..5fc7bf1 100644
--- a/main/src/cgeo/geocaching/connector/trackable/UnknownTrackableConnector.java
+++ b/main/src/cgeo/geocaching/connector/trackable/UnknownTrackableConnector.java
@@ -3,6 +3,7 @@ package cgeo.geocaching.connector.trackable;
import cgeo.geocaching.Trackable;
import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
public class UnknownTrackableConnector extends AbstractTrackableConnector {
@@ -18,6 +19,7 @@ public class UnknownTrackableConnector extends AbstractTrackableConnector {
}
@Override
+ @Nullable
public Trackable searchTrackable(final String geocode, final String guid, final String id) {
return null;
}