diff options
Diffstat (limited to 'main/src/cgeo/geocaching/connector/gc/GCParser.java')
| -rw-r--r-- | main/src/cgeo/geocaching/connector/gc/GCParser.java | 90 |
1 files changed, 51 insertions, 39 deletions
diff --git a/main/src/cgeo/geocaching/connector/gc/GCParser.java b/main/src/cgeo/geocaching/connector/gc/GCParser.java index 219adc8..60fb8e1 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCParser.java +++ b/main/src/cgeo/geocaching/connector/gc/GCParser.java @@ -36,9 +36,7 @@ import cgeo.geocaching.utils.SynchronizedDateFormat; import cgeo.geocaching.utils.TextUtils; import ch.boye.httpclientandroidlib.HttpResponse; - import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringEscapeUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; @@ -63,12 +61,13 @@ import java.util.GregorianCalendar; import java.util.List; import java.util.Locale; import java.util.Set; +import java.util.regex.Pattern; public abstract class GCParser { private final static SynchronizedDateFormat dateTbIn1 = new SynchronizedDateFormat("EEEEE, dd MMMMM yyyy", Locale.ENGLISH); // Saturday, 28 March 2009 private final static SynchronizedDateFormat dateTbIn2 = new SynchronizedDateFormat("EEEEE, MMMMM dd, yyyy", Locale.ENGLISH); // Saturday, March 28, 2009 - private static SearchResult parseSearch(final String url, final String pageContent, final boolean showCaptcha, RecaptchaReceiver thread) { + private static SearchResult parseSearch(final String url, final String pageContent, final boolean showCaptcha, final RecaptchaReceiver recaptchaReceiver) { if (StringUtils.isBlank(pageContent)) { Log.e("GCParser.parseSearch: No page given"); return null; @@ -86,12 +85,12 @@ public abstract class GCParser { final String recaptchaJsParam = TextUtils.getMatch(page, GCConstants.PATTERN_SEARCH_RECAPTCHA, false, null); if (recaptchaJsParam != null) { - thread.setKey(recaptchaJsParam.trim()); + recaptchaReceiver.setKey(recaptchaJsParam.trim()); - thread.fetchChallenge(); + recaptchaReceiver.fetchChallenge(); } - if (thread != null && StringUtils.isNotBlank(thread.getChallenge())) { - thread.notifyNeed(); + if (recaptchaReceiver != null && StringUtils.isNotBlank(recaptchaReceiver.getChallenge())) { + recaptchaReceiver.notifyNeed(); } } @@ -277,12 +276,12 @@ public abstract class GCParser { } String recaptchaText = null; - if (thread != null && StringUtils.isNotBlank(thread.getChallenge())) { - thread.waitForUser(); - recaptchaText = thread.getText(); + if (recaptchaReceiver != null && StringUtils.isNotBlank(recaptchaReceiver.getChallenge())) { + recaptchaReceiver.waitForUser(); + recaptchaText = recaptchaReceiver.getText(); } - if (!cids.isEmpty() && (Settings.isPremiumMember() || showCaptcha) && ((thread == null || StringUtils.isBlank(thread.getChallenge())) || StringUtils.isNotBlank(recaptchaText))) { + 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"); try { @@ -290,21 +289,13 @@ public abstract class GCParser { final Parameters params = new Parameters( "__EVENTTARGET", "", "__EVENTARGUMENT", ""); - if (ArrayUtils.isNotEmpty(searchResult.viewstates)) { - params.put("__VIEWSTATE", searchResult.viewstates[0]); - if (searchResult.viewstates.length > 1) { - for (int i = 1; i < searchResult.viewstates.length; i++) { - params.put("__VIEWSTATE" + i, searchResult.viewstates[i]); - } - params.put("__VIEWSTATEFIELDCOUNT", String.valueOf(searchResult.viewstates.length)); - } - } + GCLogin.putViewstates(params, searchResult.viewstates); for (final String cid : cids) { params.put("CID", cid); } - if (thread != null && StringUtils.isNotBlank(thread.getChallenge()) && StringUtils.isNotBlank(recaptchaText)) { - params.put("recaptcha_challenge_field", thread.getChallenge()); + if (StringUtils.isNotBlank(recaptchaText) && recaptchaReceiver != null) { + params.put("recaptcha_challenge_field", recaptchaReceiver.getChallenge()); params.put("recaptcha_response_field", recaptchaText); } params.put("ctl00$ContentBody$uxDownloadLoc", "Download Waypoints"); @@ -347,6 +338,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 +735,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())) { @@ -1308,7 +1302,7 @@ public abstract class GCParser { return false; // error } - final boolean guidOnPage = cache.isGuidContainedInPage(page); + final boolean guidOnPage = isGuidContainedInPage(cache, page); if (guidOnPage) { Log.i("GCParser.addToWatchlist: cache is on watchlist"); cache.setOnWatchlist(true); @@ -1342,7 +1336,7 @@ public abstract class GCParser { GCLogin.transferViewstates(page, params); page = Network.getResponseData(Network.postRequest(uri, params)); - final boolean guidOnPage = cache.isGuidContainedInPage(page); + final boolean guidOnPage = isGuidContainedInPage(cache, page); if (!guidOnPage) { Log.i("GCParser.removeFromWatchlist: cache removed from watchlist"); cache.setOnWatchlist(false); @@ -1352,6 +1346,21 @@ public abstract class GCParser { return !guidOnPage; // on watch list (=error) / not on watch list } + /** + * Checks if a page contains the guid of a cache + * + * @param cache the geocache + * @param page + * the page to search in, may be null + * @return true if the page contains the guid of the cache, false otherwise + */ + private static boolean isGuidContainedInPage(final Geocache cache, final String page) { + if (StringUtils.isBlank(page) || StringUtils.isBlank(cache.getGuid())) { + return false; + } + return Pattern.compile(cache.getGuid(), Pattern.CASE_INSENSITIVE).matcher(page).find(); + } + @Nullable static String requestHtmlPage(@Nullable final String geocode, @Nullable final String guid, final String log, final String numlogs) { final Parameters params = new Parameters("decrypt", "y"); @@ -1380,8 +1389,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 +1408,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. * @@ -1617,19 +1630,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"); @@ -1716,7 +1730,7 @@ public abstract class GCParser { final JSONArray images = entry.getJSONArray("Images"); for (int i = 0; i < images.length(); i++) { final JSONObject image = images.getJSONObject(i); - final String url = "http://img.geocaching.com/cache/log/large/" + image.getString("FileName"); + final String url = "http://imgcdn.geocaching.com/cache/log/large/" + image.getString("FileName"); final String title = TextUtils.removeControlCharacters(image.getString("Name")); final Image logImage = new Image(url, title); logDone.addLogImage(logImage); @@ -1829,7 +1843,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)) { @@ -1864,8 +1878,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; } @@ -1900,8 +1913,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; } |
