diff options
Diffstat (limited to 'main/src/cgeo/geocaching/connector/gc/GCParser.java')
| -rw-r--r-- | main/src/cgeo/geocaching/connector/gc/GCParser.java | 313 |
1 files changed, 173 insertions, 140 deletions
diff --git a/main/src/cgeo/geocaching/connector/gc/GCParser.java b/main/src/cgeo/geocaching/connector/gc/GCParser.java index 158a201..2117053 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCParser.java +++ b/main/src/cgeo/geocaching/connector/gc/GCParser.java @@ -1,14 +1,15 @@ package cgeo.geocaching.connector.gc; +import cgeo.geocaching.Geocache; import cgeo.geocaching.LogEntry; import cgeo.geocaching.R; import cgeo.geocaching.SearchResult; import cgeo.geocaching.Settings; +import cgeo.geocaching.Trackable; import cgeo.geocaching.TrackableLog; -import cgeo.geocaching.cgCache; -import cgeo.geocaching.cgImage; -import cgeo.geocaching.cgTrackable; -import cgeo.geocaching.cgWaypoint; +import cgeo.geocaching.Waypoint; +import cgeo.geocaching.cgData; +import cgeo.geocaching.Image; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.enumerations.CacheSize; import cgeo.geocaching.enumerations.CacheType; @@ -30,6 +31,7 @@ import cgeo.geocaching.utils.BaseUtils; import cgeo.geocaching.utils.CancellableHandler; import cgeo.geocaching.utils.LazyInitializedList; import cgeo.geocaching.utils.Log; +import cgeo.geocaching.utils.MatcherWrapper; import ch.boye.httpclientandroidlib.HttpResponse; @@ -43,12 +45,7 @@ import org.json.JSONObject; import android.net.Uri; import android.text.Html; -import android.text.Spannable; -import android.text.Spanned; -import android.text.style.ForegroundColorSpan; -import android.text.style.StrikethroughSpan; -import java.net.URLDecoder; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -58,7 +55,6 @@ import java.util.EnumSet; import java.util.List; import java.util.Locale; import java.util.Set; -import java.util.regex.Matcher; public abstract class GCParser { private final static SimpleDateFormat dateTbIn1 = new SimpleDateFormat("EEEEE, dd MMMMM yyyy", Locale.ENGLISH); // Saturday, 28 March 2009 @@ -71,8 +67,6 @@ public abstract class GCParser { } final List<String> cids = new ArrayList<String>(); - String recaptchaChallenge = null; - String recaptchaText = null; String page = pageContent; final SearchResult searchResult = new SearchResult(); @@ -81,6 +75,7 @@ public abstract class GCParser { // recaptcha AbstractSearchThread thread = AbstractSearchThread.getCurrentInstance(); + String recaptchaChallenge = null; if (showCaptcha) { String recaptchaJsParam = BaseUtils.getMatch(page, GCConstants.PATTERN_SEARCH_RECAPTCHA, false, null); @@ -124,7 +119,7 @@ public abstract class GCParser { final int rows_count = rows.length; for (int z = 1; z < rows_count; z++) { - final cgCache cache = new cgCache(); + final Geocache cache = new Geocache(); String row = rows[z]; // check for cache type presence @@ -133,7 +128,7 @@ public abstract class GCParser { } try { - final Matcher matcherGuidAndDisabled = GCConstants.PATTERN_SEARCH_GUIDANDDISABLED.matcher(row); + final MatcherWrapper matcherGuidAndDisabled = new MatcherWrapper(GCConstants.PATTERN_SEARCH_GUIDANDDISABLED, row); while (matcherGuidAndDisabled.find()) { if (matcherGuidAndDisabled.groupCount() > 0) { @@ -163,29 +158,32 @@ public abstract class GCParser { continue; } - String inventoryPre = null; - - cache.setGeocode(BaseUtils.getMatch(row, GCConstants.PATTERN_SEARCH_GEOCODE, true, 1, cache.getGeocode(), true).toUpperCase()); + cache.setGeocode(BaseUtils.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 direction - image if (Settings.getLoadDirImg()) { - cache.setDirectionImg(URLDecoder.decode(BaseUtils.getMatch(row, GCConstants.PATTERN_SEARCH_DIRECTION, true, 1, cache.getDirectionImg(), true))); + cache.setDirectionImg(Network.decode(BaseUtils.getMatch(row, GCConstants.PATTERN_SEARCH_DIRECTION, true, 1, cache.getDirectionImg(), true))); } // cache inventory - final Matcher matcherTbs = GCConstants.PATTERN_SEARCH_TRACKABLES.matcher(row); + final MatcherWrapper matcherTbs = new MatcherWrapper(GCConstants.PATTERN_SEARCH_TRACKABLES, row); + String inventoryPre = null; while (matcherTbs.find()) { if (matcherTbs.groupCount() > 0) { - cache.setInventoryItems(Integer.parseInt(matcherTbs.group(1))); + try { + cache.setInventoryItems(Integer.parseInt(matcherTbs.group(1))); + } catch (NumberFormatException e) { + Log.e("Error parsing trackables count", e); + } inventoryPre = matcherTbs.group(2); } } if (StringUtils.isNotBlank(inventoryPre)) { - final Matcher matcherTbsInside = GCConstants.PATTERN_SEARCH_TRACKABLESINSIDE.matcher(inventoryPre); + final MatcherWrapper matcherTbsInside = new MatcherWrapper(GCConstants.PATTERN_SEARCH_TRACKABLESINSIDE, inventoryPre); while (matcherTbsInside.find()) { if (matcherTbsInside.groupCount() == 2 && matcherTbsInside.group(2) != null && @@ -202,9 +200,6 @@ public abstract class GCParser { // found it cache.setFound(row.contains("/images/icons/16/found.png")); - // own it - cache.setOwn(row.contains("/images/icons/16/placed.png")); - // id String result = BaseUtils.getMatch(row, GCConstants.PATTERN_SEARCH_ID, null); if (null != result) { @@ -222,16 +217,6 @@ public abstract class GCParser { Log.w("GCParser.parseSearch: Failed to parse favourite count"); } - if (cache.getNameSp() == null) { - cache.setNameSp((new Spannable.Factory()).newSpannable(cache.getName())); - if (cache.isDisabled() || cache.isArchived()) { // strike - cache.getNameSp().setSpan(new StrikethroughSpan(), 0, cache.getNameSp().toString().length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - } - if (cache.isArchived()) { - cache.getNameSp().setSpan(new ForegroundColorSpan(cgeoapplication.getInstance().getResources().getColor(R.color.archived_cache_color)), 0, cache.getNameSp().toString().length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - } - } - searchResult.addCache(cache); } @@ -245,6 +230,7 @@ public abstract class GCParser { Log.w("GCParser.parseSearch: Failed to parse cache count"); } + String recaptchaText = null; if (thread != null && recaptchaChallenge != null) { if (thread.getText() == null) { thread.waitForUser(); @@ -253,7 +239,7 @@ public abstract class GCParser { recaptchaText = thread.getText(); } - if (cids.size() > 0 && (Settings.isPremiumMember() || showCaptcha) && (recaptchaChallenge == null || StringUtils.isNotBlank(recaptchaText))) { + if (!cids.isEmpty() && (Settings.isPremiumMember() || showCaptcha) && (recaptchaChallenge == null || StringUtils.isNotBlank(recaptchaText))) { Log.i("Trying to get .loc for " + cids.size() + " caches"); try { @@ -295,14 +281,14 @@ public abstract class GCParser { LocParser.parseLoc(searchResult, coordinates); } catch (Exception e) { - Log.e("GCParser.parseSearch.CIDs: " + e.toString()); + Log.e("GCParser.parseSearch.CIDs", e); } } // get direction images if (Settings.getLoadDirImg()) { - final Set<cgCache> caches = searchResult.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB); - for (cgCache cache : caches) { + final Set<Geocache> caches = searchResult.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB); + for (Geocache cache : caches) { if (cache.getCoords() == null && StringUtils.isNotEmpty(cache.getDirectionImg())) { DirectionImage.getDrawable(cache.getGeocode(), cache.getDirectionImg()); } @@ -315,18 +301,16 @@ public abstract class GCParser { static SearchResult parseCache(final String page, final CancellableHandler handler) { final SearchResult searchResult = parseCacheFromText(page, handler); if (searchResult != null && !searchResult.getGeocodes().isEmpty()) { - final cgCache cache = searchResult.getFirstCacheFromResult(LoadFlags.LOAD_CACHE_OR_DB); + final Geocache cache = searchResult.getFirstCacheFromResult(LoadFlags.LOAD_CACHE_OR_DB); getExtraOnlineInfo(cache, page, handler); - cache.setUpdated(System.currentTimeMillis()); - cache.setDetailedUpdate(cache.getUpdated()); - cache.setDetailed(true); + cache.setDetailedUpdatedNow(); if (CancellableHandler.isCancelled(handler)) { return null; } // save full detailed caches CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_cache); - cgeoapplication.getInstance().saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); + cgData.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); // update progress message so user knows we're still working. This is more of a place holder than // actual indication of what the program is doing @@ -345,7 +329,7 @@ public abstract class GCParser { final SearchResult searchResult = new SearchResult(); - if (page.contains(GCConstants.STRING_UNPUBLISHED_OTHER) || page.contains(GCConstants.STRING_UNPUBLISHED_OWNER)) { + if (page.contains(GCConstants.STRING_UNPUBLISHED_OTHER) || page.contains(GCConstants.STRING_UNPUBLISHED_OWNER) || page.contains(GCConstants.STRING_UNPUBLISHED_FROM_SEARCH)) { searchResult.setError(StatusCode.UNPUBLISHED_CACHE); return searchResult; } @@ -361,7 +345,7 @@ public abstract class GCParser { return searchResult; } - final cgCache cache = new cgCache(); + final Geocache cache = new Geocache(); cache.setDisabled(page.contains(GCConstants.STRING_DISABLED)); cache.setArchived(page.contains(GCConstants.STRING_ARCHIVED)); @@ -383,9 +367,9 @@ public abstract class GCParser { cache.setName(cacheName); // owner real name - cache.setOwnerUserId(URLDecoder.decode(BaseUtils.getMatch(page, GCConstants.PATTERN_OWNER_USERID, true, cache.getOwnerUserId()))); + cache.setOwnerUserId(Network.decode(BaseUtils.getMatch(page, GCConstants.PATTERN_OWNER_USERID, true, cache.getOwnerUserId()))); - cache.setOwn(StringUtils.equalsIgnoreCase(cache.getOwnerUserId(), Settings.getUsername())); + cache.setUserModifiedCoords(false); String tableInside = page; @@ -401,13 +385,21 @@ public abstract class GCParser { // cache terrain String result = BaseUtils.getMatch(tableInside, GCConstants.PATTERN_TERRAIN, true, null); if (result != null) { - cache.setTerrain(Float.parseFloat(StringUtils.replaceChars(result, '_', '.'))); + try { + cache.setTerrain(Float.parseFloat(StringUtils.replaceChars(result, '_', '.'))); + } catch (NumberFormatException e) { + Log.e("Error parsing terrain value", e); + } } // cache difficulty result = BaseUtils.getMatch(tableInside, GCConstants.PATTERN_DIFFICULTY, true, null); if (result != null) { - cache.setDifficulty(Float.parseFloat(StringUtils.replaceChars(result, '_', '.'))); + try { + cache.setDifficulty(Float.parseFloat(StringUtils.replaceChars(result, '_', '.'))); + } catch (NumberFormatException e) { + Log.e("Error parsing difficulty value", e); + } } // owner @@ -432,10 +424,14 @@ public abstract class GCParser { } // favourite - cache.setFavoritePoints(Integer.parseInt(BaseUtils.getMatch(tableInside, GCConstants.PATTERN_FAVORITECOUNT, true, "0"))); + try { + cache.setFavoritePoints(Integer.parseInt(BaseUtils.getMatch(tableInside, GCConstants.PATTERN_FAVORITECOUNT, true, "0"))); + } catch (NumberFormatException e) { + Log.e("Error parsing favourite count", e); + } // cache size - cache.setSize(CacheSize.getById(BaseUtils.getMatch(tableInside, GCConstants.PATTERN_SIZE, true, CacheSize.NOT_CHOSEN.id).toLowerCase())); + cache.setSize(CacheSize.getById(BaseUtils.getMatch(tableInside, GCConstants.PATTERN_SIZE, true, CacheSize.NOT_CHOSEN.id))); } // cache found @@ -465,7 +461,7 @@ public abstract class GCParser { cache.setCoords(new Geopoint(cache.getLatlon())); cache.setReliableLatLon(true); } catch (Geopoint.GeopointException e) { - Log.w("GCParser.parseCache: Failed to parse cache coordinates: " + e.toString()); + Log.w("GCParser.parseCache: Failed to parse cache coordinates", e); } } @@ -497,21 +493,21 @@ public abstract class GCParser { try { final String attributesPre = BaseUtils.getMatch(page, GCConstants.PATTERN_ATTRIBUTES, true, null); if (null != attributesPre) { - final Matcher matcherAttributesInside = GCConstants.PATTERN_ATTRIBUTESINSIDE.matcher(attributesPre); + final MatcherWrapper matcherAttributesInside = new MatcherWrapper(GCConstants.PATTERN_ATTRIBUTESINSIDE, attributesPre); final ArrayList<String> attributes = new ArrayList<String>(); while (matcherAttributesInside.find()) { if (matcherAttributesInside.groupCount() > 1 && !matcherAttributesInside.group(2).equalsIgnoreCase("blank")) { // by default, use the tooltip of the attribute - String attribute = matcherAttributesInside.group(2).toLowerCase(); + String attribute = matcherAttributesInside.group(2).toLowerCase(Locale.US); // if the image name can be recognized, use the image name as attribute - String imageName = matcherAttributesInside.group(1).trim(); - if (imageName.length() > 0) { + final String imageName = matcherAttributesInside.group(1).trim(); + if (StringUtils.isNotEmpty(imageName)) { int start = imageName.lastIndexOf('/'); int end = imageName.lastIndexOf('.'); if (start >= 0 && end >= 0) { - attribute = imageName.substring(start + 1, end).replace('-', '_').toLowerCase(); + attribute = imageName.substring(start + 1, end).replace('-', '_').toLowerCase(Locale.US); } } attributes.add(attribute); @@ -531,26 +527,22 @@ public abstract class GCParser { } CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_spoilers); - final Matcher matcherSpoilersInside = GCConstants.PATTERN_SPOILER_IMAGE.matcher(page); + final MatcherWrapper matcherSpoilersInside = new MatcherWrapper(GCConstants.PATTERN_SPOILER_IMAGE, page); 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 - // - // Create a new string to avoid referencing the whole page though the matcher (@see BaseUtils.getMatch()) - String url = new String(matcherSpoilersInside.group(1).replace("/display", "")); + String url = matcherSpoilersInside.group(1).replace("/display", ""); String title = null; if (matcherSpoilersInside.group(3) != null) { - // Create a new string to avoid referencing the whole page though the matcher (@see BaseUtils.getMatch()) - title = new String(matcherSpoilersInside.group(3)); + title = matcherSpoilersInside.group(3); } String description = null; if (matcherSpoilersInside.group(4) != null) { - // Create a new string to avoid referencing the whole page though the matcher (@see BaseUtils.getMatch()) - description = new String(matcherSpoilersInside.group(4)); + description = matcherSpoilersInside.group(4); } - cache.addSpoiler(new cgImage(url, title, description)); + cache.addSpoiler(new Image(url, title, description)); } } catch (Exception e) { // failed to parse cache spoilers @@ -561,25 +553,23 @@ public abstract class GCParser { try { cache.setInventoryItems(0); - final Matcher matcherInventory = GCConstants.PATTERN_INVENTORY.matcher(page); + final MatcherWrapper matcherInventory = new MatcherWrapper(GCConstants.PATTERN_INVENTORY, page); if (matcherInventory.find()) { if (cache.getInventory() == null) { - cache.setInventory(new ArrayList<cgTrackable>()); + cache.setInventory(new ArrayList<Trackable>()); } if (matcherInventory.groupCount() > 1) { final String inventoryPre = matcherInventory.group(2); if (StringUtils.isNotBlank(inventoryPre)) { - final Matcher matcherInventoryInside = GCConstants.PATTERN_INVENTORYINSIDE.matcher(inventoryPre); + final MatcherWrapper matcherInventoryInside = new MatcherWrapper(GCConstants.PATTERN_INVENTORYINSIDE, inventoryPre); while (matcherInventoryInside.find()) { if (matcherInventoryInside.groupCount() > 0) { - final cgTrackable inventoryItem = new cgTrackable(); - // Create a new string to avoid referencing the whole page though the matcher (@see BaseUtils.getMatch()) - inventoryItem.setGuid(new String(matcherInventoryInside.group(1))); - // Create a new string to avoid referencing the whole page though the matcher (@see BaseUtils.getMatch()) - inventoryItem.setName(new String(matcherInventoryInside.group(2))); + final Trackable inventoryItem = new Trackable(); + inventoryItem.setGuid(matcherInventoryInside.group(1)); + inventoryItem.setName(matcherInventoryInside.group(2)); cache.getInventory().add(inventoryItem); cache.setInventoryItems(cache.getInventoryItems() + 1); @@ -594,14 +584,12 @@ public abstract class GCParser { } // cache logs counts - try - { + try { final String countlogs = BaseUtils.getMatch(page, GCConstants.PATTERN_COUNTLOGS, true, null); if (null != countlogs) { - final Matcher matcherLog = GCConstants.PATTERN_COUNTLOG.matcher(countlogs); + final MatcherWrapper matcherLog = new MatcherWrapper(GCConstants.PATTERN_COUNTLOG, countlogs); - while (matcherLog.find()) - { + while (matcherLog.find()) { String typeStr = matcherLog.group(1); String countStr = matcherLog.group(2).replaceAll("[.,]", ""); @@ -612,21 +600,20 @@ public abstract class GCParser { } } } - } catch (Exception e) - { + } catch (Exception e) { // failed to parse logs Log.w("GCParser.parseCache: Failed to parse cache log count"); } // waypoints - reset collection - cache.setWaypoints(Collections.<cgWaypoint> emptyList(), false); + cache.setWaypoints(Collections.<Waypoint> emptyList(), false); // 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); if (null != originalCoords) { - final cgWaypoint waypoint = new cgWaypoint(cgeoapplication.getInstance().getString(R.string.cache_coordinates_original), WaypointType.WAYPOINT, false); + final Waypoint waypoint = new Waypoint(cgeoapplication.getInstance().getString(R.string.cache_coordinates_original), WaypointType.ORIGINAL, false); waypoint.setCoords(new Geopoint(originalCoords)); cache.addOrChangeWaypoint(waypoint, false); cache.setUserModifiedCoords(true); @@ -634,10 +621,7 @@ public abstract class GCParser { } catch (Geopoint.GeopointException e) { } - int wpBegin; - int wpEnd; - - wpBegin = page.indexOf("<table class=\"Table\" id=\"ctl00_ContentBody_Waypoints\">"); + int wpBegin = page.indexOf("<table class=\"Table\" id=\"ctl00_ContentBody_Waypoints\">"); if (wpBegin != -1) { // parse waypoints if (CancellableHandler.isCancelled(handler)) { return null; @@ -646,7 +630,7 @@ public abstract class GCParser { String wpList = page.substring(wpBegin); - wpEnd = wpList.indexOf("</p>"); + int wpEnd = wpList.indexOf("</p>"); if (wpEnd > -1 && wpEnd <= wpList.length()) { wpList = wpList.substring(0, wpEnd); } @@ -663,9 +647,8 @@ public abstract class GCParser { final String[] wpItems = wpList.split("<tr"); - String[] wp; for (int j = 1; j < wpItems.length; j++) { - wp = wpItems[j].split("<td"); + String[] wp = wpItems[j].split("<td"); // waypoint name // res is null during the unit tests @@ -674,7 +657,7 @@ public abstract class GCParser { // waypoint type final String resulttype = BaseUtils.getMatch(wp[3], GCConstants.PATTERN_WPTYPE, null); - final cgWaypoint waypoint = new cgWaypoint(name, WaypointType.findById(resulttype), false); + 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)); @@ -756,12 +739,12 @@ public abstract class GCParser { final SearchResult searchResult = parseSearch(url, page, showCaptcha); if (searchResult == null || CollectionUtils.isEmpty(searchResult.getGeocodes())) { - Log.e("GCParser.searchByNextPage: No cache parsed"); + Log.w("GCParser.searchByNextPage: No cache parsed"); return search; } // search results don't need to be filtered so load GCVote ratings here - GCVote.loadRatings(new ArrayList<cgCache>(searchResult.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB))); + GCVote.loadRatings(new ArrayList<Geocache>(searchResult.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB))); // save to application search.setError(searchResult.getError()); @@ -896,13 +879,13 @@ public abstract class GCParser { return null; } - public static cgTrackable searchTrackable(final String geocode, final String guid, final String id) { + public static Trackable searchTrackable(final String geocode, final String guid, final String id) { if (StringUtils.isBlank(geocode) && StringUtils.isBlank(guid) && StringUtils.isBlank(id)) { Log.w("GCParser.searchTrackable: No geocode nor guid nor id given"); return null; } - cgTrackable trackable = new cgTrackable(); + Trackable trackable = new Trackable(); final Parameters params = new Parameters(); if (StringUtils.isNotBlank(geocode)) { @@ -923,7 +906,7 @@ public abstract class GCParser { trackable = parseTrackable(page, geocode); if (trackable == null) { - Log.e("GCParser.searchTrackable: No trackable parsed"); + Log.w("GCParser.searchTrackable: No trackable parsed"); return null; } @@ -1004,7 +987,7 @@ public abstract class GCParser { // maintenance, archived needs to be confirmed - final Matcher matcher = GCConstants.PATTERN_MAINTENANCE.matcher(page); + final MatcherWrapper matcher = new MatcherWrapper(GCConstants.PATTERN_MAINTENANCE, page); try { if (matcher.find() && matcher.groupCount() > 0) { @@ -1048,17 +1031,17 @@ public abstract class GCParser { page = Network.getResponseData(Network.postRequest(uri, params)); } } catch (Exception e) { - Log.e("GCParser.postLog.confim: " + e.toString()); + Log.e("GCParser.postLog.confim", e); } try { - final Matcher matcherOk = GCConstants.PATTERN_OK1.matcher(page); + final MatcherWrapper matcherOk = new MatcherWrapper(GCConstants.PATTERN_OK1, page); if (matcherOk.find()) { Log.i("Log successfully posted to cache #" + cacheid); if (geocode != null) { - cgeoapplication.getInstance().saveVisitDate(geocode); + cgData.saveVisitDate(geocode); } Login.getLoginStatus(page); @@ -1069,7 +1052,7 @@ public abstract class GCParser { return StatusCode.NO_ERROR; } } catch (Exception e) { - Log.e("GCParser.postLog.check: " + e.toString()); + Log.e("GCParser.postLog.check", e); } Log.e("GCParser.postLog: Failed to post log because of unknown error"); @@ -1122,13 +1105,13 @@ public abstract class GCParser { try { - final Matcher matcherOk = GCConstants.PATTERN_OK2.matcher(page); + final MatcherWrapper matcherOk = new MatcherWrapper(GCConstants.PATTERN_OK2, page); if (matcherOk.find()) { Log.i("Log successfully posted to trackable #" + trackingCode); return StatusCode.NO_ERROR; } } catch (Exception e) { - Log.e("GCParser.postLogTrackable.check: " + e.toString()); + Log.e("GCParser.postLogTrackable.check", e); } Log.e("GCParser.postLogTrackable: Failed to post log because of unknown error"); @@ -1142,7 +1125,7 @@ public abstract class GCParser { * the cache to add * @return <code>false</code> if an error occurred, <code>true</code> otherwise */ - static boolean addToWatchlist(final cgCache cache) { + 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); @@ -1168,7 +1151,7 @@ public abstract class GCParser { * the cache to remove * @return <code>false</code> if an error occurred, <code>true</code> otherwise */ - static boolean removeFromWatchlist(final cgCache cache) { + static boolean removeFromWatchlist(final Geocache cache) { final String uri = "http://www.geocaching.com/my/watchlist.aspx?ds=1&action=rem&id=" + cache.getCacheId(); String page = Login.postRequestLogged(uri, null); @@ -1211,15 +1194,17 @@ public abstract class GCParser { /** * Adds the cache to the favorites of the user. * + * This must not be called from the UI thread. + * * @param cache * the cache to add * @return <code>false</code> if an error occurred, <code>true</code> otherwise */ - static boolean addToFavorites(final cgCache cache) { + static boolean addToFavorites(final Geocache cache) { return changeFavorite(cache, true); } - private static boolean changeFavorite(final cgCache cache, final boolean add) { + 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, ""); if (StringUtils.isEmpty(userToken)) { @@ -1241,26 +1226,26 @@ public abstract class GCParser { } /** - * Removes the cache from the Favorites + * Removes the cache from the favorites. + * + * This must not be called from the UI thread. * * @param cache * the cache to remove * @return <code>false</code> if an error occurred, <code>true</code> otherwise */ - static boolean removeFromFavorites(final cgCache cache) { + static boolean removeFromFavorites(final Geocache cache) { return changeFavorite(cache, false); } /** - * Parse a trackable HTML description into a cgTrackable object + * Parse a trackable HTML description into a Trackable object * * @param page * the HTML page to parse, already processed through {@link BaseUtils#replaceWhitespace} - * @param app - * if not null, the application to use to save the trackable * @return the parsed trackable, or null if none could be parsed */ - static cgTrackable parseTrackable(final String page, final String possibleTrackingcode) { + static Trackable parseTrackable(final String page, final String possibleTrackingcode) { if (StringUtils.isBlank(page)) { Log.e("GCParser.parseTrackable: No page given"); return null; @@ -1270,10 +1255,10 @@ public abstract class GCParser { return null; } - final cgTrackable trackable = new cgTrackable(); + final Trackable trackable = new Trackable(); // trackable geocode - trackable.setGeocode(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_GEOCODE, true, trackable.getGeocode()).toUpperCase()); + trackable.setGeocode(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_GEOCODE, true, trackable.getGeocode())); // trackable id trackable.setGuid(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_GUID, true, trackable.getGuid())); @@ -1291,7 +1276,7 @@ public abstract class GCParser { // trackable owner name try { - final Matcher matcherOwner = GCConstants.PATTERN_TRACKABLE_OWNER.matcher(page); + final MatcherWrapper matcherOwner = new MatcherWrapper(GCConstants.PATTERN_TRACKABLE_OWNER, page); if (matcherOwner.find() && matcherOwner.groupCount() > 0) { trackable.setOwnerGuid(matcherOwner.group(1)); trackable.setOwner(matcherOwner.group(2).trim()); @@ -1306,26 +1291,26 @@ public abstract class GCParser { // trackable spotted try { - final Matcher matcherSpottedCache = GCConstants.PATTERN_TRACKABLE_SPOTTEDCACHE.matcher(page); + final MatcherWrapper matcherSpottedCache = new MatcherWrapper(GCConstants.PATTERN_TRACKABLE_SPOTTEDCACHE, page); if (matcherSpottedCache.find() && matcherSpottedCache.groupCount() > 0) { trackable.setSpottedGuid(matcherSpottedCache.group(1)); trackable.setSpottedName(matcherSpottedCache.group(2).trim()); - trackable.setSpottedType(cgTrackable.SPOTTED_CACHE); + trackable.setSpottedType(Trackable.SPOTTED_CACHE); } - final Matcher matcherSpottedUser = GCConstants.PATTERN_TRACKABLE_SPOTTEDUSER.matcher(page); + final MatcherWrapper matcherSpottedUser = new MatcherWrapper(GCConstants.PATTERN_TRACKABLE_SPOTTEDUSER, page); if (matcherSpottedUser.find() && matcherSpottedUser.groupCount() > 0) { trackable.setSpottedGuid(matcherSpottedUser.group(1)); trackable.setSpottedName(matcherSpottedUser.group(2).trim()); - trackable.setSpottedType(cgTrackable.SPOTTED_USER); + trackable.setSpottedType(Trackable.SPOTTED_USER); } if (BaseUtils.matches(page, GCConstants.PATTERN_TRACKABLE_SPOTTEDUNKNOWN)) { - trackable.setSpottedType(cgTrackable.SPOTTED_UNKNOWN); + trackable.setSpottedType(Trackable.SPOTTED_UNKNOWN); } if (BaseUtils.matches(page, GCConstants.PATTERN_TRACKABLE_SPOTTEDOWNER)) { - trackable.setSpottedType(cgTrackable.SPOTTED_OWNER); + trackable.setSpottedType(Trackable.SPOTTED_OWNER); } } catch (Exception e) { // failed to parse trackable last known place @@ -1356,7 +1341,7 @@ public abstract class GCParser { // trackable details & image try { - final Matcher matcherDetailsImage = GCConstants.PATTERN_TRACKABLE_DETAILSIMAGE.matcher(page); + final MatcherWrapper matcherDetailsImage = new MatcherWrapper(GCConstants.PATTERN_TRACKABLE_DETAILSIMAGE, page); if (matcherDetailsImage.find() && matcherDetailsImage.groupCount() > 0) { final String image = StringUtils.trim(matcherDetailsImage.group(3)); final String details = StringUtils.trim(matcherDetailsImage.group(4)); @@ -1375,7 +1360,7 @@ public abstract class GCParser { // trackable logs try { - final Matcher matcherLogs = GCConstants.PATTERN_TRACKABLE_LOG.matcher(page); + final MatcherWrapper matcherLogs = new MatcherWrapper(GCConstants.PATTERN_TRACKABLE_LOG, page); /* * 1. Type (image) * 2. Date @@ -1404,13 +1389,14 @@ public abstract class GCParser { } // Apply the pattern for images in a trackable log entry against each full log (group(0)) - final Matcher matcherLogImages = GCConstants.PATTERN_TRACKABLE_LOG_IMAGES.matcher(matcherLogs.group(0)); + final String logEntry = matcherLogs.group(0); + final MatcherWrapper matcherLogImages = new MatcherWrapper(GCConstants.PATTERN_TRACKABLE_LOG_IMAGES, logEntry); /* * 1. Image URL * 2. Image title */ while (matcherLogImages.find()) { - final cgImage logImage = new cgImage(matcherLogImages.group(1), matcherLogImages.group(2)); + final Image logImage = new Image(matcherLogImages.group(1), matcherLogImages.group(2)); logDone.addLogImage(logImage); } @@ -1418,7 +1404,7 @@ public abstract class GCParser { } } catch (Exception e) { // failed to parse logs - Log.w("GCParser.parseCache: Failed to parse cache logs" + e.toString()); + Log.w("GCParser.parseCache: Failed to parse cache logs", e); } // tracking code @@ -1427,7 +1413,7 @@ public abstract class GCParser { } if (cgeoapplication.getInstance() != null) { - cgeoapplication.getInstance().saveTrackable(trackable); + cgData.saveTrackable(trackable); } return trackable; @@ -1450,11 +1436,11 @@ public abstract class GCParser { * @param friends * retrieve friend logs */ - private static List<LogEntry> loadLogsFromDetails(final String page, final cgCache cache, final boolean friends, final boolean getDataFromPage) { + private static List<LogEntry> loadLogsFromDetails(final String page, final Geocache cache, final boolean friends, final boolean getDataFromPage) { String rawResponse; if (!getDataFromPage) { - final Matcher userTokenMatcher = GCConstants.PATTERN_USERTOKEN.matcher(page); + final MatcherWrapper userTokenMatcher = new MatcherWrapper(GCConstants.PATTERN_USERTOKEN, page); if (!userTokenMatcher.find()) { Log.e("GCParser.loadLogsFromDetails: unable to extract userToken"); return null; @@ -1532,7 +1518,7 @@ public abstract class GCParser { final JSONObject image = images.getJSONObject(i); String url = "http://img.geocaching.com/cache/log/" + image.getString("FileName"); String title = image.getString("Name"); - final cgImage logImage = new cgImage(url, title); + final Image logImage = new Image(url, title); logDone.addLogImage(logImage); } @@ -1553,7 +1539,7 @@ public abstract class GCParser { final List<LogType> types = new ArrayList<LogType>(); - final Matcher typeBoxMatcher = GCConstants.PATTERN_TYPEBOX.matcher(page); + final MatcherWrapper typeBoxMatcher = new MatcherWrapper(GCConstants.PATTERN_TYPEBOX, page); String typesText = null; if (typeBoxMatcher.find()) { if (typeBoxMatcher.groupCount() > 0) { @@ -1563,13 +1549,16 @@ public abstract class GCParser { if (typesText != null) { - final Matcher typeMatcher = GCConstants.PATTERN_TYPE2.matcher(typesText); + final MatcherWrapper typeMatcher = new MatcherWrapper(GCConstants.PATTERN_TYPE2, typesText); while (typeMatcher.find()) { if (typeMatcher.groupCount() > 1) { - final int type = Integer.parseInt(typeMatcher.group(2)); - - if (type > 0) { - types.add(LogType.getById(type)); + try { + int type = Integer.parseInt(typeMatcher.group(2)); + if (type > 0) { + types.add(LogType.getById(type)); + } + } catch (NumberFormatException e) { + Log.e("Error parsing log types", e); } } } @@ -1598,7 +1587,7 @@ public abstract class GCParser { final List<TrackableLog> trackableLogs = new ArrayList<TrackableLog>(); - final Matcher trackableMatcher = GCConstants.PATTERN_TRACKABLE.matcher(page); + final MatcherWrapper trackableMatcher = new MatcherWrapper(GCConstants.PATTERN_TRACKABLE, page); while (trackableMatcher.find()) { if (trackableMatcher.groupCount() > 0) { @@ -1634,7 +1623,7 @@ public abstract class GCParser { params.put("tx", cacheType.guid); } - private static void getExtraOnlineInfo(final cgCache cache, final String page, final CancellableHandler handler) { + private static void getExtraOnlineInfo(final Geocache cache, final String page, final CancellableHandler handler) { if (CancellableHandler.isCancelled(handler)) { return; } @@ -1642,7 +1631,7 @@ public abstract class GCParser { //cache.setLogs(loadLogsFromDetails(page, cache, false)); if (Settings.isFriendLogsWanted()) { CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_logs); - LazyInitializedList<LogEntry> allLogs = cache.getLogs(); + List<LogEntry> allLogs = cache.getLogs(); List<LogEntry> friendLogs = loadLogsFromDetails(page, cache, true, false); if (friendLogs != null) { for (LogEntry log : friendLogs) { @@ -1679,4 +1668,48 @@ public abstract class GCParser { } } + public static boolean uploadModifiedCoordinates(Geocache cache, Geopoint wpt) { + return editModifiedCoordinates(cache, wpt); + } + + public static boolean deleteModifiedCoordinates(Geocache cache) { + return editModifiedCoordinates(cache, null); + } + + 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, ""); + if (StringUtils.isEmpty(userToken)) { + return false; + } + + try { + JSONObject jo; + if (wpt != null) { + jo = new JSONObject().put("dto", (new JSONObject().put("ut", userToken) + .put("data", new JSONObject() + .put("lat", wpt.getLatitudeE6() / 1E6) + .put("lng", wpt.getLongitudeE6() / 1E6)))); + } else { + jo = new JSONObject().put("dto", (new JSONObject().put("ut", userToken))); + } + + 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); + Log.i("Sending to " + uriPrefix + uriSuffix + " :" + jo.toString()); + + if (response != null && response.getStatusLine().getStatusCode() == 200) { + Log.i("GCParser.editModifiedCoordinates - edited on GC.com"); + return true; + } + + } catch (JSONException e) { + Log.e("Unknown exception with json wrap code", e); + } + Log.e("GCParser.deleteModifiedCoordinates - cannot delete modified coords"); + return false; + } + } |
