diff options
Diffstat (limited to 'main/src/cgeo/geocaching/connector')
10 files changed, 126 insertions, 43 deletions
diff --git a/main/src/cgeo/geocaching/connector/ConnectorFactory.java b/main/src/cgeo/geocaching/connector/ConnectorFactory.java index 0081951..68e3142 100644 --- a/main/src/cgeo/geocaching/connector/ConnectorFactory.java +++ b/main/src/cgeo/geocaching/connector/ConnectorFactory.java @@ -27,6 +27,10 @@ import cgeo.geocaching.geopoint.Viewport; import org.apache.commons.lang3.StringUtils; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; +import rx.Observable; +import rx.concurrency.Schedulers; +import rx.util.functions.Func1; +import rx.util.functions.Func2; import java.util.ArrayList; import java.util.Arrays; @@ -176,14 +180,30 @@ public final class ConnectorFactory { } /** @see ISearchByViewPort#searchByViewport */ - public static SearchResult searchByViewport(final @NonNull Viewport viewport, final MapTokens tokens) { - final SearchResult result = new SearchResult(); - for (final ISearchByViewPort connector : searchByViewPortConns) { - if (connector.isActive()) { - result.addSearchResult(connector.searchByViewport(viewport, tokens)); + public static Observable<SearchResult> searchByViewport(final @NonNull Viewport viewport, final MapTokens tokens) { + return Observable.from(searchByViewPortConns).filter(new Func1<ISearchByViewPort, Boolean>() { + @Override + public Boolean call(final ISearchByViewPort connector) { + return connector.isActive(); } - } - return result; + }).parallel(new Func1<Observable<ISearchByViewPort>, Observable<SearchResult>>() { + @Override + public Observable<SearchResult> call(final Observable<ISearchByViewPort> connector) { + return connector.map(new Func1<ISearchByViewPort, SearchResult>() { + @Override + public SearchResult call(final ISearchByViewPort connector) { + return connector.searchByViewport(viewport, tokens); + } + }); + } + }, Schedulers.threadPoolForIO()).reduce(new SearchResult(), new Func2<SearchResult, SearchResult, SearchResult>() { + + @Override + public SearchResult call(final SearchResult result, final SearchResult searchResult) { + result.addSearchResult(searchResult); + return result; + } + }); } public static String getGeocodeFromURL(final String url) { @@ -200,6 +220,12 @@ public final class ConnectorFactory { return TRACKABLE_CONNECTORS; } + /** + * Get the geocode of a trackable from a URL. + * + * @param url + * @return {@code null} if the URL cannot be decoded + */ public static String getTrackableFromURL(final String url) { if (url == null) { return null; diff --git a/main/src/cgeo/geocaching/connector/gc/GCConnector.java b/main/src/cgeo/geocaching/connector/gc/GCConnector.java index e946748..9c6b831 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCConnector.java +++ b/main/src/cgeo/geocaching/connector/gc/GCConnector.java @@ -91,7 +91,7 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, @Override public boolean supportsPersonalNote() { - return Settings.isPremiumMember(); + return Settings.isGCPremiumMember(); } @Override @@ -285,7 +285,22 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, @Override protected String getCacheUrlPrefix() { - return CACHE_URL_SHORT; + return null; // UNUSED + } + + @Override + public String getGeocodeFromUrl(String url) { + // coord.info URLs + String code = StringUtils.substringAfterLast(url, "coord.info/"); + if (code != null && canHandle(code)) { + return code; + } + // expanded geocaching.com URLs + code = StringUtils.substringBetween(url, "/geocache/", "_"); + if (code != null && canHandle(code)) { + return code; + } + return null; } @Override diff --git a/main/src/cgeo/geocaching/connector/gc/GCLogin.java b/main/src/cgeo/geocaching/connector/gc/GCLogin.java index a7cf6cf..f747911 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCLogin.java +++ b/main/src/cgeo/geocaching/connector/gc/GCLogin.java @@ -97,7 +97,7 @@ public class GCLogin extends AbstractLogin { } if (getLoginStatus(loginData)) { - Log.i("Already logged in Geocaching.com as " + username + " (" + Settings.getMemberStatus() + ')'); + Log.i("Already logged in Geocaching.com as " + username + " (" + Settings.getGCMemberStatus() + ')'); if (switchToEnglish(loginData) && retry) { return login(false); } @@ -132,7 +132,7 @@ public class GCLogin extends AbstractLogin { assert loginData != null; // Caught above if (getLoginStatus(loginData)) { - Log.i("Successfully logged in Geocaching.com as " + username + " (" + Settings.getMemberStatus() + ')'); + Log.i("Successfully logged in Geocaching.com as " + username + " (" + Settings.getGCMemberStatus() + ')'); if (switchToEnglish(loginData) && retry) { return login(false); @@ -204,9 +204,9 @@ public class GCLogin extends AbstractLogin { Log.e("getLoginStatus: bad cache count", e); } setActualCachesFound(cachesCount); - Settings.setMemberStatus(TextUtils.getMatch(page, GCConstants.PATTERN_MEMBER_STATUS, true, null)); + Settings.setGCMemberStatus(TextUtils.getMatch(page, GCConstants.PATTERN_MEMBER_STATUS, true, null)); if ( page.contains(GCConstants.MEMBER_STATUS_RENEW) ) { - Settings.setMemberStatus(GCConstants.MEMBER_STATUS_PM); + Settings.setGCMemberStatus(GCConstants.MEMBER_STATUS_PM); } return true; } @@ -259,9 +259,9 @@ public class GCLogin extends AbstractLogin { final String responseData = StringUtils.defaultString(Network.getResponseData(Network.getRequest("http://www.geocaching.com/my/"))); final String profile = TextUtils.replaceWhitespace(responseData); - Settings.setMemberStatus(TextUtils.getMatch(profile, GCConstants.PATTERN_MEMBER_STATUS, true, null)); + Settings.setGCMemberStatus(TextUtils.getMatch(profile, GCConstants.PATTERN_MEMBER_STATUS, true, null)); if (profile.contains(GCConstants.MEMBER_STATUS_RENEW)) { - Settings.setMemberStatus(GCConstants.MEMBER_STATUS_PM); + Settings.setGCMemberStatus(GCConstants.MEMBER_STATUS_PM); } setActualCachesFound(Integer.parseInt(TextUtils.getMatch(profile, GCConstants.PATTERN_CACHES_FOUND, true, "-1").replaceAll("[,.]", ""))); diff --git a/main/src/cgeo/geocaching/connector/gc/GCMap.java b/main/src/cgeo/geocaching/connector/gc/GCMap.java index 6c94150..2782b64 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCMap.java +++ b/main/src/cgeo/geocaching/connector/gc/GCMap.java @@ -368,7 +368,7 @@ public class GCMap { } } - if (strategy.flags.contains(StrategyFlag.SEARCH_NEARBY) && Settings.isPremiumMember()) { + if (strategy.flags.contains(StrategyFlag.SEARCH_NEARBY) && Settings.isGCPremiumMember()) { final Geopoint center = viewport.getCenter(); if ((lastSearchViewport == null) || !lastSearchViewport.contains(center)) { //FIXME We don't have a RecaptchaReceiver!? diff --git a/main/src/cgeo/geocaching/connector/gc/GCParser.java b/main/src/cgeo/geocaching/connector/gc/GCParser.java index 62ccb14..fe962e6 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCParser.java +++ b/main/src/cgeo/geocaching/connector/gc/GCParser.java @@ -282,7 +282,7 @@ public abstract class GCParser { recaptchaText = thread.getText(); } - if (!cids.isEmpty() && (Settings.isPremiumMember() || showCaptcha) && ((thread == null || StringUtils.isBlank(thread.getChallenge())) || StringUtils.isNotBlank(recaptchaText))) { + if (!cids.isEmpty() && (Settings.isGCPremiumMember() || showCaptcha) && ((thread == null || StringUtils.isBlank(thread.getChallenge())) || StringUtils.isNotBlank(recaptchaText))) { Log.i("Trying to get .loc for " + cids.size() + " caches"); try { @@ -347,6 +347,9 @@ public abstract class GCParser { // attention: parseCacheFromText already stores implicitly through searchResult.addCache if (searchResult != null && !searchResult.getGeocodes().isEmpty()) { final Geocache cache = searchResult.getFirstCacheFromResult(LoadFlags.LOAD_CACHE_OR_DB); + if (cache == null) { + return null; + } getExtraOnlineInfo(cache, page, handler); // too late: it is already stored through parseCacheFromText cache.setDetailedUpdatedNow(); @@ -741,7 +744,7 @@ public abstract class GCParser { cache.parseWaypointsFromNote(); // logs - cache.setLogs(loadLogsFromDetails(page, cache, false, true)); + cache.setLogs(getLogsFromDetails(page, false)); // last check for necessary cache conditions if (StringUtils.isBlank(cache.getGeocode())) { @@ -1380,8 +1383,7 @@ 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 = TextUtils.getMatch(page, GCConstants.PATTERN_USERTOKEN, ""); + final String userToken = getUserToken(cache); if (StringUtils.isEmpty(userToken)) { return false; } @@ -1400,6 +1402,11 @@ public abstract class GCParser { return false; } + private static String getUserToken(final Geocache cache) { + final String page = requestHtmlPage(cache.getGeocode(), null, "n", "0"); + return TextUtils.getMatch(page, GCConstants.PATTERN_USERTOKEN, ""); + } + /** * Removes the cache from the favorites. * @@ -1613,19 +1620,20 @@ public abstract class GCParser { } /** - * Load logs from a cache details page. + * Extract logs from a cache details page. * * @param page * the text of the details page - * @param cache - * the cache object to put the logs in * @param friends - * retrieve friend logs + * return friends logs only (will require a network request) + * @return a list of log entries or <code>null</code> if the logs could not be retrieved + * */ - private static List<LogEntry> loadLogsFromDetails(final String page, final Geocache cache, final boolean friends, final boolean getDataFromPage) { + @Nullable + private static List<LogEntry> getLogsFromDetails(final String page, final boolean friends) { String rawResponse; - if (!getDataFromPage) { + if (friends) { final MatcherWrapper userTokenMatcher = new MatcherWrapper(GCConstants.PATTERN_USERTOKEN, page); if (!userTokenMatcher.find()) { Log.e("GCParser.loadLogsFromDetails: unable to extract userToken"); @@ -1825,7 +1833,7 @@ public abstract class GCParser { if (Settings.isFriendLogsWanted()) { CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_logs); final List<LogEntry> allLogs = cache.getLogs(); - final List<LogEntry> friendLogs = loadLogsFromDetails(page, cache, true, false); + final List<LogEntry> friendLogs = getLogsFromDetails(page, true); if (friendLogs != null) { for (final LogEntry log : friendLogs) { if (allLogs.contains(log)) { @@ -1860,8 +1868,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 = TextUtils.getMatch(page, GCConstants.PATTERN_USERTOKEN, ""); + final String userToken = getUserToken(cache); if (StringUtils.isEmpty(userToken)) { return false; } @@ -1896,8 +1903,7 @@ public abstract class GCParser { } public static boolean uploadPersonalNote(Geocache cache) { - final String page = requestHtmlPage(cache.getGeocode(), null, "n", "0"); - final String userToken = TextUtils.getMatch(page, GCConstants.PATTERN_USERTOKEN, ""); + final String userToken = getUserToken(cache); if (StringUtils.isEmpty(userToken)) { return false; } diff --git a/main/src/cgeo/geocaching/connector/trackable/AbstractTrackableConnector.java b/main/src/cgeo/geocaching/connector/trackable/AbstractTrackableConnector.java index 69efddc..fb554b9 100644 --- a/main/src/cgeo/geocaching/connector/trackable/AbstractTrackableConnector.java +++ b/main/src/cgeo/geocaching/connector/trackable/AbstractTrackableConnector.java @@ -4,6 +4,7 @@ import cgeo.geocaching.connector.AbstractConnector; import cgeo.geocaching.connector.UserAction; import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; import java.util.List; @@ -15,7 +16,8 @@ public abstract class AbstractTrackableConnector implements TrackableConnector { } @Override - public String getTrackableCodeFromUrl(@NonNull String url) { + public @Nullable + String getTrackableCodeFromUrl(@NonNull String url) { return null; } diff --git a/main/src/cgeo/geocaching/connector/trackable/GeokretyConnector.java b/main/src/cgeo/geocaching/connector/trackable/GeokretyConnector.java index 8387076..03052f9 100644 --- a/main/src/cgeo/geocaching/connector/trackable/GeokretyConnector.java +++ b/main/src/cgeo/geocaching/connector/trackable/GeokretyConnector.java @@ -4,6 +4,10 @@ import cgeo.geocaching.Trackable; import cgeo.geocaching.network.Network; import cgeo.geocaching.utils.Log; +import org.apache.commons.lang3.StringUtils; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; + import java.util.regex.Pattern; public class GeokretyConnector extends AbstractTrackableConnector { @@ -29,7 +33,7 @@ public class GeokretyConnector extends AbstractTrackableConnector { return GeokretyParser.parse(page); } - private static int getId(String geocode) { + protected static int getId(String geocode) { try { final String hex = geocode.substring(2); return Integer.parseInt(hex, 16); @@ -39,4 +43,25 @@ public class GeokretyConnector extends AbstractTrackableConnector { return -1; } + @Override + public @Nullable + String getTrackableCodeFromUrl(@NonNull String url) { + // http://geokrety.org/konkret.php?id=38545 + String id = StringUtils.substringAfterLast(url, "konkret.php?id="); + if (StringUtils.isNumeric(id)) { + return geocode(Integer.parseInt(id)); + } + return null; + } + + /** + * 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/GeokretyParser.java b/main/src/cgeo/geocaching/connector/trackable/GeokretyParser.java index ee8c8c0..0e64abd 100644 --- a/main/src/cgeo/geocaching/connector/trackable/GeokretyParser.java +++ b/main/src/cgeo/geocaching/connector/trackable/GeokretyParser.java @@ -37,8 +37,8 @@ public class GeokretyParser { public void start(Attributes attributes) { try { final String kretyId = attributes.getValue("id"); - if (StringUtils.isNotBlank(kretyId)) { - trackable.setGeocode(geocode(Integer.parseInt(kretyId))); + if (StringUtils.isNumeric(kretyId)) { + trackable.setGeocode(GeokretyConnector.geocode(Integer.parseInt(kretyId))); } final String distance = attributes.getValue("dist"); if (StringUtils.isNotBlank(distance)) { @@ -88,8 +88,4 @@ public class GeokretyParser { } 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 index 0990d96..6071b5f 100644 --- a/main/src/cgeo/geocaching/connector/trackable/TrackableConnector.java +++ b/main/src/cgeo/geocaching/connector/trackable/TrackableConnector.java @@ -4,6 +4,7 @@ import cgeo.geocaching.Trackable; import cgeo.geocaching.connector.UserAction; import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; import java.util.List; @@ -21,7 +22,8 @@ public interface TrackableConnector { public Trackable searchTrackable(String geocode, String guid, String id); - public String getTrackableCodeFromUrl(final @NonNull String url); + public @Nullable + String getTrackableCodeFromUrl(final @NonNull String url); public @NonNull List<UserAction> getUserActions(); diff --git a/main/src/cgeo/geocaching/connector/trackable/TravelBugConnector.java b/main/src/cgeo/geocaching/connector/trackable/TravelBugConnector.java index dad285c..77848d7 100644 --- a/main/src/cgeo/geocaching/connector/trackable/TravelBugConnector.java +++ b/main/src/cgeo/geocaching/connector/trackable/TravelBugConnector.java @@ -7,6 +7,7 @@ import cgeo.geocaching.connector.gc.GCParser; import org.apache.commons.lang3.StringUtils; import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; import java.util.List; import java.util.regex.Pattern; @@ -20,7 +21,7 @@ public class TravelBugConnector extends AbstractTrackableConnector { @Override public boolean canHandleTrackable(String geocode) { - return TravelBugConnector.PATTERN_TB_CODE.matcher(geocode).matches(); + return TravelBugConnector.PATTERN_TB_CODE.matcher(geocode).matches() && !StringUtils.startsWithIgnoreCase(geocode, "GC"); } @Override @@ -54,8 +55,18 @@ public class TravelBugConnector extends AbstractTrackableConnector { } @Override - public String getTrackableCodeFromUrl(@NonNull String url) { - return StringUtils.substringAfterLast(url, "?tracker="); + public @Nullable + String getTrackableCodeFromUrl(@NonNull String url) { + // coord.info URLs + String code = StringUtils.substringAfterLast(url, "coord.info/"); + if (code != null && canHandleTrackable(code)) { + return code; + } + code = StringUtils.substringAfterLast(url, "?tracker="); + if (code != null && canHandleTrackable(code)) { + return code; + } + return null; } @Override |
