aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/cgeo/geocaching/connector/gc/GCParser.java
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/cgeo/geocaching/connector/gc/GCParser.java')
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCParser.java159
1 files changed, 104 insertions, 55 deletions
diff --git a/main/src/cgeo/geocaching/connector/gc/GCParser.java b/main/src/cgeo/geocaching/connector/gc/GCParser.java
index 7fc06c1..44d634c 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCParser.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCParser.java
@@ -6,6 +6,7 @@ import cgeo.geocaching.SearchResult;
import cgeo.geocaching.Settings;
import cgeo.geocaching.TrackableLog;
import cgeo.geocaching.cgCache;
+import cgeo.geocaching.cgData;
import cgeo.geocaching.cgImage;
import cgeo.geocaching.cgTrackable;
import cgeo.geocaching.cgWaypoint;
@@ -43,12 +44,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;
@@ -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);
@@ -163,23 +158,26 @@ 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);
+ 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);
}
}
@@ -222,16 +220,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 +233,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 +242,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 {
@@ -326,7 +315,7 @@ public abstract class GCParser {
// 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 +334,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;
}
@@ -383,10 +372,12 @@ 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;
int pos = tableInside.indexOf(GCConstants.STRING_CACHEDETAILS);
@@ -401,13 +392,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 +431,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
@@ -503,15 +506,15 @@ public abstract class GCParser {
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);
@@ -620,7 +623,7 @@ public abstract class GCParser {
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 cgWaypoint waypoint = new cgWaypoint(cgeoapplication.getInstance().getString(R.string.cache_coordinates_original), WaypointType.ORIGINAL, false);
waypoint.setCoords(new Geopoint(originalCoords));
cache.addOrChangeWaypoint(waypoint, false);
cache.setUserModifiedCoords(true);
@@ -628,10 +631,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;
@@ -640,7 +640,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);
}
@@ -657,9 +657,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
@@ -750,7 +749,7 @@ 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;
}
@@ -917,7 +916,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;
}
@@ -1052,7 +1051,7 @@ public abstract class GCParser {
Log.i("Log successfully posted to cache #" + cacheid);
if (geocode != null) {
- cgeoapplication.getInstance().saveVisitDate(geocode);
+ cgData.saveVisitDate(geocode);
}
Login.getLoginStatus(page);
@@ -1205,6 +1204,8 @@ 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
@@ -1235,7 +1236,9 @@ 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
@@ -1250,8 +1253,6 @@ public abstract class GCParser {
*
* @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) {
@@ -1267,7 +1268,7 @@ public abstract class GCParser {
final cgTrackable trackable = new cgTrackable();
// 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()));
@@ -1398,7 +1399,8 @@ 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 Matcher matcherLogImages = GCConstants.PATTERN_TRACKABLE_LOG_IMAGES.matcher(logEntry);
/*
* 1. Image URL
* 2. Image title
@@ -1421,7 +1423,7 @@ public abstract class GCParser {
}
if (cgeoapplication.getInstance() != null) {
- cgeoapplication.getInstance().saveTrackable(trackable);
+ cgData.saveTrackable(trackable);
}
return trackable;
@@ -1560,10 +1562,13 @@ public abstract class GCParser {
final Matcher typeMatcher = GCConstants.PATTERN_TYPE2.matcher(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);
}
}
}
@@ -1673,4 +1678,48 @@ public abstract class GCParser {
}
}
+ public static boolean uploadModifiedCoordinates(cgCache cache, Geopoint wpt) {
+ return editModifiedCoordinates(cache, wpt);
+ }
+
+ public static boolean deleteModifiedCoordinates(cgCache cache) {
+ return editModifiedCoordinates(cache, null);
+ }
+
+ public static boolean editModifiedCoordinates(cgCache 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;
+ }
+
}