diff options
6 files changed, 173 insertions, 2 deletions
diff --git a/main/res/values/changelog_master.xml b/main/res/values/changelog_master.xml index ca0ac4e..0cb21e9 100644 --- a/main/res/values/changelog_master.xml +++ b/main/res/values/changelog_master.xml @@ -5,6 +5,7 @@ <b>Next feature release:</b>\n · New: confirmation on backup/restore\n · New: sort events of same date by time (if recognized from cache description)\n + · New: show rudimentary details for geocaching.com.au swaggies\n \n </string> </resources> diff --git a/main/src/cgeo/geocaching/connector/ConnectorFactory.java b/main/src/cgeo/geocaching/connector/ConnectorFactory.java index b78b009..f8806de 100644 --- a/main/src/cgeo/geocaching/connector/ConnectorFactory.java +++ b/main/src/cgeo/geocaching/connector/ConnectorFactory.java @@ -18,6 +18,7 @@ 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.SwaggieConnector; import cgeo.geocaching.connector.trackable.TrackableConnector; import cgeo.geocaching.connector.trackable.TravelBugConnector; import cgeo.geocaching.connector.trackable.UnknownTrackableConnector; @@ -74,8 +75,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 })); 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..01688c7 --- /dev/null +++ b/main/src/cgeo/geocaching/connector/trackable/SwaggieConnector.java @@ -0,0 +1,50 @@ +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 + 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/tests/src/cgeo/geocaching/connector/trackable/SwaggieConnectorTest.java b/tests/src/cgeo/geocaching/connector/trackable/SwaggieConnectorTest.java new file mode 100644 index 0000000..54c3319 --- /dev/null +++ b/tests/src/cgeo/geocaching/connector/trackable/SwaggieConnectorTest.java @@ -0,0 +1,29 @@ +package cgeo.geocaching.connector.trackable; + +import static org.assertj.core.api.Assertions.assertThat; + +import cgeo.geocaching.Trackable; + +import junit.framework.TestCase; + +public class SwaggieConnectorTest extends TestCase { + + public static void testCanHandleTrackable() { + assertThat(new SwaggieConnector().canHandleTrackable("SW0001")).isTrue(); + assertThat(new SwaggieConnector().canHandleTrackable("SWABCD")).isFalse(); + assertThat(new SwaggieConnector().canHandleTrackable("GK82A2")).isFalse(); + assertThat(new SwaggieConnector().canHandleTrackable("TB1234")).isFalse(); + assertThat(new SwaggieConnector().canHandleTrackable("UNKNOWN")).isFalse(); + } + + public static void testGetTrackableCodeFromUrl() throws Exception { + assertThat(new SwaggieConnector().getTrackableCodeFromUrl("http://geocaching.com.au/swaggie/sw0017")).isEqualTo("SW0017"); + } + + public static void testGetUrl() throws Exception { + final Trackable trackable = new Trackable(); + trackable.setGeocode("SW0017"); + assertThat(new SwaggieConnector().getUrl(trackable)).isEqualTo("http://geocaching.com.au/swaggie/SW0017"); + } + +} diff --git a/tests/src/cgeo/geocaching/connector/trackable/SwaggieParserTest.java b/tests/src/cgeo/geocaching/connector/trackable/SwaggieParserTest.java new file mode 100644 index 0000000..1e63b1c --- /dev/null +++ b/tests/src/cgeo/geocaching/connector/trackable/SwaggieParserTest.java @@ -0,0 +1,34 @@ +package cgeo.geocaching.connector.trackable; + +import static org.assertj.core.api.Assertions.assertThat; + +import cgeo.geocaching.Trackable; +import cgeo.geocaching.connector.ConnectorFactory; +import cgeo.geocaching.network.Network; + +import junit.framework.TestCase; + +public class SwaggieParserTest extends TestCase { + + public static void testParse() { + final Trackable trackableIn = new Trackable(); + trackableIn.setGeocode("SW0017"); + + final String cacheUrl = ConnectorFactory.getTrackableConnector(trackableIn.getGeocode()).getUrl(trackableIn); + assertThat(cacheUrl).isNotNull(); + + final String page = Network.getResponseData(Network.getRequest(cacheUrl)); + assertThat(page).isNotNull(); + + assert page != null; + final Trackable trackable = SwaggieParser.parse(page); + assertThat(trackable).isNotNull(); + assert trackable != null; + + assertThat(trackable.getName()).isEqualTo("Law and Order 1"); + assertThat(trackable.getGeocode()).isEqualTo("SW0017"); + assertThat(trackable.getDetails()).isEqualTo("A mini CD that may or may not contain a DivX .AVI of the Law and Order: CSI episode that features geocaching as part of the storyline."); + assertThat(trackable.getType()).isEqualTo("Swaggie"); + assertThat(trackable.getOwner()).isEqualTo("Bear_Left"); + } +} |