diff options
Diffstat (limited to 'main/src/cgeo/geocaching/cgBase.java')
| -rw-r--r-- | main/src/cgeo/geocaching/cgBase.java | 983 |
1 files changed, 42 insertions, 941 deletions
diff --git a/main/src/cgeo/geocaching/cgBase.java b/main/src/cgeo/geocaching/cgBase.java index befdabb..91c61c0 100644 --- a/main/src/cgeo/geocaching/cgBase.java +++ b/main/src/cgeo/geocaching/cgBase.java @@ -19,10 +19,10 @@ import cgeo.geocaching.gcvote.GCVote; import cgeo.geocaching.gcvote.GCVoteRating; import cgeo.geocaching.geopoint.DistanceParser; import cgeo.geocaching.geopoint.Geopoint; -import cgeo.geocaching.geopoint.GeopointFormatter.Format; import cgeo.geocaching.network.HtmlImage; +import cgeo.geocaching.network.Login; +import cgeo.geocaching.network.Network; import cgeo.geocaching.network.Parameters; -import cgeo.geocaching.twitter.Twitter; import cgeo.geocaching.ui.DirectionImage; import cgeo.geocaching.utils.BaseUtils; import cgeo.geocaching.utils.CancellableHandler; @@ -30,34 +30,7 @@ import cgeo.geocaching.utils.CancellableHandler; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.apache.http.Header; -import org.apache.http.HeaderElement; -import org.apache.http.HttpEntity; -import org.apache.http.HttpException; -import org.apache.http.HttpRequest; -import org.apache.http.HttpRequestInterceptor; import org.apache.http.HttpResponse; -import org.apache.http.HttpResponseInterceptor; -import org.apache.http.NameValuePair; -import org.apache.http.client.CookieStore; -import org.apache.http.client.HttpClient; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.methods.HttpRequestBase; -import org.apache.http.cookie.Cookie; -import org.apache.http.entity.HttpEntityWrapper; -import org.apache.http.impl.client.BasicCookieStore; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.impl.cookie.BasicClientCookie; -import org.apache.http.params.BasicHttpParams; -import org.apache.http.params.CoreConnectionPNames; -import org.apache.http.params.CoreProtocolPNames; -import org.apache.http.params.HttpParams; -import org.apache.http.protocol.HTTP; -import org.apache.http.protocol.HttpContext; -import org.apache.http.util.EntityUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -69,9 +42,6 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.drawable.BitmapDrawable; import android.net.Uri; import android.os.Handler; import android.os.Message; @@ -81,83 +51,29 @@ import android.text.Spanned; import android.text.format.DateUtils; import android.text.style.StrikethroughSpan; import android.util.Log; -import android.view.LayoutInflater; -import android.widget.EditText; -import android.widget.ImageView; -import android.widget.LinearLayout; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.InetAddress; -import java.net.NetworkInterface; -import java.net.SocketException; + import java.net.URLDecoder; -import java.net.URLEncoder; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; -import java.util.Collections; -import java.util.Date; import java.util.EnumSet; -import java.util.Enumeration; -import java.util.HashMap; import java.util.List; import java.util.Locale; -import java.util.Map; import java.util.Set; import java.util.regex.Matcher; -import java.util.zip.GZIPInputStream; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.SSLSession; public class cgBase { - private static final String passMatch = "(?<=[\\?&])[Pp]ass(w(or)?d)?=[^&#$]+"; - - private final static Map<String, SimpleDateFormat> gcCustomDateFormats; - static { - final String[] formats = new String[] { - "MM/dd/yyyy", - "yyyy-MM-dd", - "yyyy/MM/dd", - "dd/MMM/yyyy", - "MMM/dd/yyyy", - "dd MMM yy", - "dd/MM/yyyy" - }; - - Map<String, SimpleDateFormat> map = new HashMap<String, SimpleDateFormat>(); - - for (String format : formats) { - map.put(format, new SimpleDateFormat(format, Locale.ENGLISH)); - } - - gcCustomDateFormats = Collections.unmodifiableMap(map); - } private final static SimpleDateFormat dateTbIn1 = new SimpleDateFormat("EEEEE, dd MMMMM yyyy", Locale.ENGLISH); // Saturday, 28 March 2009 private final static SimpleDateFormat dateTbIn2 = new SimpleDateFormat("EEEEE, MMMMM dd, yyyy", Locale.ENGLISH); // Saturday, March 28, 2009 public static String version = null; private static Context context; - private static Resources res; - - private static final int NB_DOWNLOAD_RETRIES = 4; + public static Resources res; public static final int UPDATE_LOAD_PROGRESS_DETAIL = 42186; - // false = not logged in - private static boolean actualLoginStatus = false; - private static String actualUserName = ""; - private static String actualMemberStatus = ""; - private static int actualCachesFound = -1; - private static String actualStatus = ""; - - /** User agent id */ - public final static String USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1"; - private cgBase() { //initialize(app); throw new UnsupportedOperationException(); // static class, not to be instantiated @@ -182,10 +98,6 @@ public class cgBase { } } - public static String hidePassword(final String message) { - return message.replaceAll(passMatch, "password=***"); - } - public static void sendLoadProgressDetail(final Handler handler, final int str) { if (null != handler) { handler.obtainMessage(UPDATE_LOAD_PROGRESS_DETAIL, cgeoapplication.getInstance().getString(str)).sendToTarget(); @@ -193,72 +105,6 @@ public class cgBase { } /** - * read all viewstates from page - * - * @return String[] with all view states - */ - public static String[] getViewstates(String page) { - // Get the number of viewstates. - // If there is only one viewstate, __VIEWSTATEFIELDCOUNT is not present - - if (page == null) { // no network access - return null; - } - - int count = 1; - final Matcher matcherViewstateCount = GCConstants.PATTERN_VIEWSTATEFIELDCOUNT.matcher(page); - if (matcherViewstateCount.find()) { - count = Integer.parseInt(matcherViewstateCount.group(1)); - } - - String[] viewstates = new String[count]; - - // Get the viewstates - int no; - final Matcher matcherViewstates = GCConstants.PATTERN_VIEWSTATES.matcher(page); - while (matcherViewstates.find()) { - String sno = matcherViewstates.group(1); // number of viewstate - if (sno.length() == 0) { - no = 0; - } - else { - no = Integer.parseInt(sno); - } - viewstates[no] = matcherViewstates.group(2); - } - - if (viewstates.length != 1 || viewstates[0] != null) { - return viewstates; - } - // no viewstates were present - return null; - } - - /** - * put viewstates into request parameters - */ - private static void putViewstates(final Parameters params, final String[] viewstates) { - if (ArrayUtils.isEmpty(viewstates)) { - return; - } - params.put("__VIEWSTATE", viewstates[0]); - if (viewstates.length > 1) { - for (int i = 1; i < viewstates.length; i++) { - params.put("__VIEWSTATE" + i, viewstates[i]); - } - params.put("__VIEWSTATEFIELDCOUNT", String.valueOf(viewstates.length)); - } - } - - /** - * transfers the viewstates variables from a page (response) to parameters - * (next request) - */ - public static void transferViewstates(final String page, final Parameters params) { - putViewstates(params, getViewstates(page)); - } - - /** * checks if an Array of Strings is empty or not. Empty means: * - Array is null * - or all elements are null or empty strings @@ -276,157 +122,6 @@ public class cgBase { return true; } - public static StatusCode login() { - final ImmutablePair<String, String> login = Settings.getLogin(); - - if (login == null || StringUtils.isEmpty(login.left) || StringUtils.isEmpty(login.right)) { - cgBase.setActualStatus(res.getString(R.string.err_login)); - Log.e(Settings.tag, "cgeoBase.login: No login information stored"); - return StatusCode.NO_LOGIN_INFO_STORED; - } - - // res is null during the unit tests - if (res != null) { - cgBase.setActualStatus(res.getString(R.string.init_login_popup_working)); - } - HttpResponse loginResponse = request("https://www.geocaching.com/login/default.aspx", null, false, false, false); - String loginData = getResponseData(loginResponse); - if (loginResponse != null && loginResponse.getStatusLine().getStatusCode() == 503 && BaseUtils.matches(loginData, GCConstants.PATTERN_MAINTENANCE)) { - return StatusCode.MAINTENANCE; - } - - if (StringUtils.isBlank(loginData)) { - Log.e(Settings.tag, "cgeoBase.login: Failed to retrieve login page (1st)"); - return StatusCode.CONNECTION_FAILED; // no loginpage - } - - if (getLoginStatus(loginData)) { - Log.i(Settings.tag, "Already logged in Geocaching.com as " + login.left); - switchToEnglish(loginData); - return StatusCode.NO_ERROR; // logged in - } - - clearCookies(); - Settings.setCookieStore(null); - - final Parameters params = new Parameters( - "__EVENTTARGET", "", - "__EVENTARGUMENT", "", - "ctl00$ContentBody$tbUsername", login.left, - "ctl00$ContentBody$tbPassword", login.right, - "ctl00$ContentBody$cbRememberMe", "on", - "ctl00$ContentBody$btnSignIn", "Login"); - final String[] viewstates = getViewstates(loginData); - if (isEmpty(viewstates)) { - Log.e(Settings.tag, "cgeoBase.login: Failed to find viewstates"); - return StatusCode.LOGIN_PARSE_ERROR; // no viewstates - } - putViewstates(params, viewstates); - - loginResponse = postRequest("https://www.geocaching.com/login/default.aspx", params); - loginData = getResponseData(loginResponse); - - if (StringUtils.isNotBlank(loginData)) { - if (getLoginStatus(loginData)) { - Log.i(Settings.tag, "Successfully logged in Geocaching.com as " + login.left); - - switchToEnglish(loginData); - Settings.setCookieStore(dumpCookieStore()); - - return StatusCode.NO_ERROR; // logged in - } else { - if (loginData.contains("Your username/password combination does not match.")) { - Log.i(Settings.tag, "Failed to log in Geocaching.com as " + login.left + " because of wrong username/password"); - return StatusCode.WRONG_LOGIN_DATA; // wrong login - } else { - Log.i(Settings.tag, "Failed to log in Geocaching.com as " + login.left + " for some unknown reason"); - return StatusCode.UNKNOWN_ERROR; // can't login - } - } - } else { - Log.e(Settings.tag, "cgeoBase.login: Failed to retrieve login page (2nd)"); - // FIXME: should it be CONNECTION_FAILED to match the first attempt? - return StatusCode.COMMUNICATION_ERROR; // no login page - } - } - - public static StatusCode logout() { - HttpResponse logoutResponse = request("https://www.geocaching.com/login/default.aspx?RESET=Y&redir=http%3a%2f%2fwww.geocaching.com%2fdefault.aspx%3f", null, false, false, false); - String logoutData = getResponseData(logoutResponse); - if (logoutResponse != null && logoutResponse.getStatusLine().getStatusCode() == 503 && BaseUtils.matches(logoutData, GCConstants.PATTERN_MAINTENANCE)) { - return StatusCode.MAINTENANCE; - } - - clearCookies(); - Settings.setCookieStore(null); - return StatusCode.NO_ERROR; - } - - /** - * Check if the user has been logged in when he retrieved the data. - * - * @param page - * @return <code>true</code> if user is logged in, <code>false</code> otherwise - */ - private static boolean getLoginStatus(final String page) { - if (StringUtils.isBlank(page)) { - Log.e(Settings.tag, "cgeoBase.checkLogin: No page given"); - return false; - } - - // res is null during the unit tests - if (res != null) { - setActualStatus(res.getString(R.string.init_login_popup_ok)); - } - - // on every page except login page - setActualLoginStatus(BaseUtils.matches(page, GCConstants.PATTERN_LOGIN_NAME)); - if (isActualLoginStatus()) { - setActualUserName(BaseUtils.getMatch(page, GCConstants.PATTERN_LOGIN_NAME, true, "???")); - setActualMemberStatus(BaseUtils.getMatch(page, GCConstants.PATTERN_MEMBER_STATUS, true, "???")); - setActualCachesFound(Integer.parseInt(BaseUtils.getMatch(page, GCConstants.PATTERN_CACHES_FOUND, true, "0").replaceAll("[,.]", ""))); - return true; - } - - // login page - setActualLoginStatus(BaseUtils.matches(page, GCConstants.PATTERN_LOGIN_NAME_LOGIN_PAGE)); - if (isActualLoginStatus()) { - setActualUserName(Settings.getUsername()); - setActualMemberStatus(Settings.getMemberStatus()); - // number of caches found is not part of this page - return true; - } - - // res is null during the unit tests - if (res != null) { - setActualStatus(res.getString(R.string.init_login_popup_failed)); - } - return false; - } - - public static void switchToEnglish(String previousPage) { - final String ENGLISH = "English▼"; - if (previousPage != null && previousPage.indexOf(ENGLISH) >= 0) { - Log.i(Settings.tag, "Geocaching.com language already set to English"); - // get find count - getLoginStatus(getResponseData(request("http://www.geocaching.com/email/", null, false))); - } else { - final String page = getResponseData(request("http://www.geocaching.com/default.aspx", null, false)); - getLoginStatus(page); - if (page == null) { - Log.e(Settings.tag, "Failed to read viewstates to set geocaching.com language"); - } - final Parameters params = new Parameters( - "__EVENTTARGET", "ctl00$uxLocaleList$uxLocaleList$ctl00$uxLocaleItem", // switch to english - "__EVENTARGUMENT", ""); - transferViewstates(page, params); - final HttpResponse response = postRequest("http://www.geocaching.com/default.aspx", params); - if (!isSuccess(response)) { - Log.e(Settings.tag, "Failed to set geocaching.com language to English"); - } - } - } - private static SearchResult parseSearch(final cgSearchThread thread, final String url, final String pageContent, final boolean showCaptcha) { if (StringUtils.isBlank(pageContent)) { Log.e(Settings.tag, "cgeoBase.parseSearch: No page given"); @@ -441,7 +136,7 @@ public class cgBase { final SearchResult searchResult = new SearchResult(); searchResult.setUrl(url); - searchResult.viewstates = getViewstates(page); + searchResult.viewstates = Login.getViewstates(page); // recaptcha if (showCaptcha) { @@ -449,7 +144,7 @@ public class cgBase { if (recaptchaJsParam != null) { final Parameters params = new Parameters("k", recaptchaJsParam.trim()); - final String recaptchaJs = cgBase.getResponseData(request("http://www.google.com/recaptcha/api/challenge", params, true)); + final String recaptchaJs = Network.getResponseData(Network.request("http://www.google.com/recaptcha/api/challenge", params, true)); if (StringUtils.isNotBlank(recaptchaJs)) { recaptchaChallenge = BaseUtils.getMatch(recaptchaJs, GCConstants.PATTERN_SEARCH_RECAPTCHACHALLENGE, true, 1, null, true); @@ -649,7 +344,7 @@ public class cgBase { } params.put("ctl00$ContentBody$uxDownloadLoc", "Download Waypoints"); - final String coordinates = getResponseData(postRequest("http://www.geocaching.com/seek/nearest.aspx", params), false); + final String coordinates = Network.getResponseData(Network.postRequest("http://www.geocaching.com/seek/nearest.aspx", params), false); if (StringUtils.isNotBlank(coordinates)) { if (coordinates.contains("You have not agreed to the license agreement. The license agreement is required before you can start downloading GPX or LOC files from Geocaching.com")) { @@ -795,13 +490,13 @@ public class cgBase { try { String hiddenString = BaseUtils.getMatch(tableInside, GCConstants.PATTERN_HIDDEN, true, null); if (StringUtils.isNotBlank(hiddenString)) { - cache.setHidden(parseGcCustomDate(hiddenString)); + cache.setHidden(Login.parseGcCustomDate(hiddenString)); } if (cache.getHiddenDate() == null) { // event date hiddenString = BaseUtils.getMatch(tableInside, GCConstants.PATTERN_HIDDENEVENT, true, null); if (StringUtils.isNotBlank(hiddenString)) { - cache.setHidden(parseGcCustomDate(hiddenString)); + cache.setHidden(Login.parseGcCustomDate(hiddenString)); } } } catch (ParseException e) { @@ -1105,7 +800,7 @@ public class cgBase { } sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_elevation); if (cache.getCoords() != null) { - cache.setElevation(getElevation(cache.getCoords())); + cache.setElevation(cache.getCoords().getElevation()); } } @@ -1152,7 +847,7 @@ public class cgBase { // "sp", Boolean.toString(personal), // personal logs "sf", Boolean.toString(friends)); - final HttpResponse response = request("http://www.geocaching.com/seek/geocache.logbook", params, false, false, false); + final HttpResponse response = Network.request("http://www.geocaching.com/seek/geocache.logbook", params, false, false, false); if (response == null) { Log.e(Settings.tag, "cgBase.loadLogsFromDetails: cannot log logs, response is null"); return null; @@ -1162,7 +857,7 @@ public class cgBase { Log.e(Settings.tag, "cgBase.loadLogsFromDetails: error " + statusCode + " when requesting log information"); return null; } - rawResponse = cgBase.getResponseData(response); + rawResponse = Network.getResponseData(response); if (rawResponse == null) { Log.e(Settings.tag, "cgBase.loadLogsFromDetails: unable to read whole response"); return null; @@ -1194,7 +889,7 @@ public class cgBase { logDone.type = LogType.getByIconName(logIconName); try { - logDone.date = parseGcCustomDate(entry.getString("Visited")).getTime(); + logDone.date = Login.parseGcCustomDate(entry.getString("Visited")).getTime(); } catch (ParseException e) { Log.e(Settings.tag, "cgBase.loadLogsFromDetails: failed to parse log date."); } @@ -1267,73 +962,6 @@ public class cgBase { } } - public static Date parseGcCustomDate(final String input, final String format) throws ParseException { - if (StringUtils.isBlank(input)) { - throw new ParseException("Input is null", 0); - } - - final String trimmed = input.trim(); - - if (gcCustomDateFormats.containsKey(format)) { - try { - return gcCustomDateFormats.get(format).parse(trimmed); - } catch (ParseException e) { - } - } - - for (SimpleDateFormat sdf : gcCustomDateFormats.values()) { - try { - return sdf.parse(trimmed); - } catch (ParseException e) { - } - } - - throw new ParseException("No matching pattern", 0); - } - - public static Date parseGcCustomDate(final String input) throws ParseException { - return parseGcCustomDate(input, Settings.getGcCustomDate()); - } - - /** - * Detect user date settings on geocaching.com - */ - public static void detectGcCustomDate() { - - final String result = getResponseData(request("http://www.geocaching.com/account/ManagePreferences.aspx", null, false, false, false)); - - if (null == result) { - Log.w(Settings.tag, "cgeoBase.detectGcCustomDate: result is null"); - return; - } - - String customDate = BaseUtils.getMatch(result, GCConstants.PATTERN_CUSTOMDATE, true, null); - if (null != customDate) { - Settings.setGcCustomDate(customDate); - } - } - - public static BitmapDrawable downloadAvatarAndGetMemberStatus(final Context context) { - try { - final String profile = BaseUtils.replaceWhitespace(getResponseData(request("http://www.geocaching.com/my/", null, false))); - - Settings.setMemberStatus(BaseUtils.getMatch(profile, GCConstants.PATTERN_MEMBER_STATUS, true, null)); - - setActualCachesFound(Integer.parseInt(BaseUtils.getMatch(profile, GCConstants.PATTERN_CACHES_FOUND, true, "-1").replaceAll("[,.]", ""))); - - final String avatarURL = BaseUtils.getMatch(profile, GCConstants.PATTERN_AVATAR_IMAGE_PROFILE_PAGE, false, null); - if (null != avatarURL) { - final HtmlImage imgGetter = new HtmlImage(context, "", false, 0, false); - return imgGetter.getDrawable(avatarURL); - } - // No match? There may be no avatar set by user. - Log.d(Settings.tag, "No avatar set for user"); - } catch (Exception e) { - Log.w(Settings.tag, "Error when retrieving user avatar", e); - } - return null; - } - /** * Parse a trackable HTML description into a cgTrackable object * @@ -1479,7 +1107,7 @@ public class cgBase { try { - logDone.date = parseGcCustomDate(matcherLogs.group(2)).getTime(); + logDone.date = Login.parseGcCustomDate(matcherLogs.group(2)).getTime(); } catch (ParseException e) { } @@ -1648,13 +1276,13 @@ public class cgBase { final Parameters params = new Parameters( "__EVENTTARGET", "ctl00$ContentBody$pgrBottom$ctl08", "__EVENTARGUMENT", ""); - putViewstates(params, viewstates); + Login.putViewstates(params, viewstates); - String page = getResponseData(postRequest(uri, params)); - if (!getLoginStatus(page)) { - final StatusCode loginState = login(); + String page = Network.getResponseData(Network.postRequest(uri, params)); + if (!Login.getLoginStatus(page)) { + final StatusCode loginState = Login.login(); if (loginState == StatusCode.NO_ERROR) { - page = getResponseData(postRequest(uri, params)); + page = Network.getResponseData(Network.postRequest(uri, params)); } else if (loginState == StatusCode.NO_LOGIN_INFO_STORED) { Log.i(Settings.tag, "Working as guest."); } else { @@ -1725,7 +1353,7 @@ public class cgBase { final String uri = "http://www.geocaching.com/seek/nearest.aspx"; final String fullUri = uri + "?" + addFToParams(params, false, true); - String page = requestLogged(uri, params, false, my, true); + String page = Network.requestLogged(uri, params, false, my, true); if (StringUtils.isBlank(page)) { Log.e(Settings.tag, "cgeoBase.searchByAny: No data from server"); @@ -1740,7 +1368,7 @@ public class cgBase { final SearchResult search = searchResult.filterSearchResults(Settings.isExcludeDisabledCaches(), false, cacheType); - getLoginStatus(page); + Login.getLoginStatus(page); return search; } @@ -1787,30 +1415,6 @@ public class cgBase { return searchByAny(thread, cacheType, false, showCaptcha, params); } - /** Request .png image for a tile. */ - public static Bitmap requestMapTile(final String url, final String referer) { - final HttpGet request = new HttpGet(url); - request.addHeader("Accept", "image/png,image/*;q=0.8,*/*;q=0.5"); - request.addHeader("Referer", referer); - request.addHeader("X-Requested-With", "XMLHttpRequest"); - final HttpResponse response = request(request); - try { - return response != null ? BitmapFactory.decodeStream(response.getEntity().getContent()) : null; - } catch (IOException e) { - Log.e(Settings.tag, "cgBase.requestMapTile() " + e.getMessage()); - } - return null; - } - - /** Request JSON informations for a tile */ - public static String requestMapInfo(final String url, final String referer) { - final HttpGet request = new HttpGet(url); - request.addHeader("Accept", "application/json, text/javascript, */*; q=0.01"); - request.addHeader("Referer", referer); - request.addHeader("X-Requested-With", "XMLHttpRequest"); - return getResponseData(request(request), false); - } - public static cgTrackable searchTrackable(final String geocode, final String guid, final String id) { if (StringUtils.isBlank(geocode) && StringUtils.isBlank(guid) && StringUtils.isBlank(id)) { Log.w(Settings.tag, "cgeoBase.searchTrackable: No geocode nor guid nor id given"); @@ -1829,7 +1433,7 @@ public class cgBase { params.put("id", id); } - String page = requestLogged("http://www.geocaching.com/track/details.aspx", params, false, false, false); + String page = Network.requestLogged("http://www.geocaching.com/track/details.aspx", params, false, false, false); if (StringUtils.isBlank(page)) { Log.e(Settings.tag, "cgeoBase.searchTrackable: No data from server"); @@ -1894,7 +1498,7 @@ public class cgBase { "ctl00$ContentBody$LogBookPanel1$uxLogInfo", logInfo, "ctl00$ContentBody$LogBookPanel1$LogButton", "Submit Log Entry", "ctl00$ContentBody$uxVistOtherListingGC", ""); - putViewstates(params, viewstates); + Login.putViewstates(params, viewstates); if (trackables != null && !trackables.isEmpty()) { // we have some trackables to proceed final StringBuilder hdnSelected = new StringBuilder(); @@ -1911,11 +1515,11 @@ public class cgBase { } final String uri = new Uri.Builder().scheme("http").authority("www.geocaching.com").path("/seek/log.aspx").encodedQuery("ID=" + cacheid).build().toString(); - String page = getResponseData(postRequest(uri, params)); - if (!getLoginStatus(page)) { - final StatusCode loginState = login(); + String page = Network.getResponseData(Network.postRequest(uri, params)); + if (!Login.getLoginStatus(page)) { + final StatusCode loginState = Login.login(); if (loginState == StatusCode.NO_ERROR) { - page = getResponseData(postRequest(uri, params)); + page = Network.getResponseData(Network.postRequest(uri, params)); } else { Log.e(Settings.tag, "cgeoBase.postLog: Can not log in geocaching (error: " + loginState + ")"); return loginState; @@ -1933,7 +1537,7 @@ public class cgBase { try { if (matcher.find() && matcher.groupCount() > 0) { - final String[] viewstatesConfirm = getViewstates(page); + final String[] viewstatesConfirm = Login.getViewstates(page); if (isEmpty(viewstatesConfirm)) { Log.e(Settings.tag, "cgeoBase.postLog: No viewstate for confirm log"); @@ -1941,7 +1545,7 @@ public class cgBase { } params.clear(); - putViewstates(params, viewstatesConfirm); + Login.putViewstates(params, viewstatesConfirm); params.put("__EVENTTARGET", ""); params.put("__EVENTARGUMENT", ""); params.put("__LASTFOCUS", ""); @@ -1972,7 +1576,7 @@ public class cgBase { params.put("ctl00$ContentBody$LogBookPanel1$uxTrackables$hdnCurrentFilter", ""); } - page = getResponseData(postRequest(uri, params)); + page = Network.getResponseData(Network.postRequest(uri, params)); } } catch (Exception e) { Log.e(Settings.tag, "cgeoBase.postLog.confim: " + e.toString()); @@ -1988,10 +1592,10 @@ public class cgBase { cgeoapplication.getInstance().saveVisitDate(geocode); } - getLoginStatus(page); + Login.getLoginStatus(page); // the log-successful-page contains still the old value - if (getActualCachesFound() >= 0) { - setActualCachesFound(getActualCachesFound() + 1); + if (Login.getActualCachesFound() >= 0) { + Login.setActualCachesFound(Login.getActualCachesFound() + 1); } return StatusCode.NO_ERROR; } @@ -2026,7 +1630,7 @@ public class cgBase { "__LASTFOCUS", "", "ctl00$ContentBody$LogBookPanel1$ddLogType", Integer.toString(logType.id), "ctl00$ContentBody$LogBookPanel1$tbCode", trackingCode); - putViewstates(params, viewstates); + Login.putViewstates(params, viewstates); if (currentDate.get(Calendar.YEAR) == year && (currentDate.get(Calendar.MONTH) + 1) == month && currentDate.get(Calendar.DATE) == day) { params.put("ctl00$ContentBody$LogBookPanel1$DateTimeLogged", ""); } else { @@ -2041,11 +1645,11 @@ public class cgBase { "ctl00$ContentBody$uxVistOtherListingGC", ""); final String uri = new Uri.Builder().scheme("http").authority("www.geocaching.com").path("/track/log.aspx").encodedQuery("wid=" + tbid).build().toString(); - String page = getResponseData(postRequest(uri, params)); - if (!getLoginStatus(page)) { - final StatusCode loginState = login(); + String page = Network.getResponseData(Network.postRequest(uri, params)); + if (!Login.getLoginStatus(page)) { + final StatusCode loginState = Login.login(); if (loginState == StatusCode.NO_ERROR) { - page = getResponseData(postRequest(uri, params)); + page = Network.getResponseData(Network.postRequest(uri, params)); } else { Log.e(Settings.tag, "cgeoBase.postLogTrackable: Can not log in geocaching (error: " + loginState + ")"); return loginState; @@ -2081,7 +1685,7 @@ public class cgBase { */ public static int addToWatchlist(final cgCache cache) { final String uri = "http://www.geocaching.com/my/watchlist.aspx?w=" + cache.getCacheId(); - String page = postRequestLogged(uri); + String page = Network.postRequestLogged(uri); if (StringUtils.isBlank(page)) { Log.e(Settings.tag, "cgBase.addToWatchlist: No data from server"); @@ -2107,7 +1711,7 @@ public class cgBase { */ public static int removeFromWatchlist(final cgCache cache) { final String uri = "http://www.geocaching.com/my/watchlist.aspx?ds=1&action=rem&id=" + cache.getCacheId(); - String page = postRequestLogged(uri); + String page = Network.postRequestLogged(uri); if (StringUtils.isBlank(page)) { Log.e(Settings.tag, "cgBase.removeFromWatchlist: No data from server"); @@ -2119,9 +1723,9 @@ public class cgBase { "__EVENTTARGET", "", "__EVENTARGUMENT", "", "ctl00$ContentBody$btnYes", "Yes"); - transferViewstates(page, params); + Login.transferViewstates(page, params); - page = getResponseData(postRequest(uri, params)); + page = Network.getResponseData(Network.postRequest(uri, params)); boolean guidOnPage = cache.isGuidContainedInPage(page); if (!guidOnPage) { Log.i(Settings.tag, "cgBase.removeFromWatchlist: cache removed from watchlist"); @@ -2132,75 +1736,6 @@ public class cgBase { return guidOnPage ? -1 : 0; // on watchlist (=error) / not on watchlist } - final public static HostnameVerifier doNotVerify = new HostnameVerifier() { - - public boolean verify(String hostname, SSLSession session) { - return true; - } - }; - - public static void postTweetCache(String geocode) { - final cgCache cache = cgeoapplication.getInstance().loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); - String status; - final String url = cache.getUrl(); - if (url.length() >= 100) { - status = "I found " + url; - } - else { - String name = cache.getName(); - status = "I found " + name + " (" + url + ")"; - if (status.length() > Twitter.MAX_TWEET_SIZE) { - name = name.substring(0, name.length() - (status.length() - Twitter.MAX_TWEET_SIZE) - 3) + "..."; - } - status = "I found " + name + " (" + url + ")"; - status = Twitter.appendHashTag(status, "cgeo"); - status = Twitter.appendHashTag(status, "geocaching"); - } - - Twitter.postTweet(cgeoapplication.getInstance(), status, null); - } - - public static void postTweetTrackable(String geocode) { - final cgTrackable trackable = cgeoapplication.getInstance().getTrackableByGeocode(geocode); - String name = trackable.getName(); - if (name.length() > 82) { - name = name.substring(0, 79) + "..."; - } - StringBuilder builder = new StringBuilder("I touched "); - builder.append(name); - if (trackable.getUrl() != null) { - builder.append(" (").append(trackable.getUrl()).append(')'); - } - builder.append('!'); - String status = Twitter.appendHashTag(builder.toString(), "cgeo"); - status = Twitter.appendHashTag(status, "geocaching"); - Twitter.postTweet(cgeoapplication.getInstance(), status, null); - } - - public static String getLocalIpAddress() { - try { - for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { - NetworkInterface intf = en.nextElement(); - for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) { - InetAddress inetAddress = enumIpAddr.nextElement(); - if (!inetAddress.isLoopbackAddress()) { - return inetAddress.getHostAddress(); - } - } - } - } catch (SocketException e) { - // nothing - } - - return null; - } - - public static String urlencode_rfc3986(String text) { - final String encoded = StringUtils.replace(URLEncoder.encode(text).replace("+", "%20"), "%7E", "~"); - - return encoded; - } - /** * Possibly hide caches found or hidden by user. This mutates its params argument when possible. * @@ -2222,324 +1757,6 @@ public class cgBase { return params; } - static private String prepareParameters(final String baseUri, final Parameters params) { - return CollectionUtils.isNotEmpty(params) ? baseUri + "?" + params.toString() : baseUri; - } - - static public String[] requestViewstates(final String uri, final Parameters params, boolean xContentType, boolean my) { - final HttpResponse response = request(uri, params, xContentType, my, false); - - return getViewstates(getResponseData(response)); - } - - static private String getResponseDataNoError(final HttpResponse response, boolean replaceWhitespace) { - try { - String data = EntityUtils.toString(response.getEntity(), HTTP.UTF_8); - return replaceWhitespace ? BaseUtils.replaceWhitespace(data) : data; - } catch (Exception e) { - Log.e(Settings.tag, "getResponseData", e); - return null; - } - } - - static public String getResponseData(final HttpResponse response) { - return getResponseData(response, true); - } - - static public String getResponseData(final HttpResponse response, boolean replaceWhitespace) { - if (!isSuccess(response)) { - return null; - } - return getResponseDataNoError(response, replaceWhitespace); - } - - /** - * POST HTTP request. Do the request a second time if the user is not logged in - * - * @param uri - * @return - */ - public static String postRequestLogged(final String uri) { - HttpResponse response = postRequest(uri, null); - String data = getResponseData(response); - - if (!getLoginStatus(data)) { - if (login() == StatusCode.NO_ERROR) { - response = postRequest(uri, null); - data = getResponseData(response); - } else { - Log.i(Settings.tag, "Working as guest."); - } - } - return data; - } - - /** - * GET HTTP request. Do the request a second time if the user is not logged in - * - * @param uri - * @param params - * @param xContentType - * @param my - * @param addF - * @return - */ - public static String requestLogged(final String uri, final Parameters params, boolean xContentType, boolean my, boolean addF) { - HttpResponse response = request(uri, params, xContentType, my, addF); - String data = getResponseData(response); - - if (!getLoginStatus(data)) { - if (login() == StatusCode.NO_ERROR) { - response = request(uri, params, xContentType, my, addF); - data = getResponseData(response); - } else { - Log.i(Settings.tag, "Working as guest."); - } - } - return data; - } - - /** - * GET HTTP request - * - * @param uri - * @param params - * @param xContentType - * @param my - * @param addF - * @return - */ - public static HttpResponse request(final String uri, final Parameters params, boolean xContentType, boolean my, boolean addF) { - return request(uri, addFToParams(params, my, addF), xContentType); - } - - final private static CookieStore cookieStore = new BasicCookieStore(); - private static boolean cookieStoreRestored = false; - final private static HttpParams clientParams = new BasicHttpParams(); - - static { - clientParams.setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, HTTP.UTF_8); - clientParams.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 30000); - clientParams.setParameter(CoreConnectionPNames.SO_TIMEOUT, 30000); - } - - public static HttpClient getHttpClient() { - final DefaultHttpClient client = new DefaultHttpClient(); - client.setCookieStore(cookieStore); - client.setParams(clientParams); - - client.addRequestInterceptor(new HttpRequestInterceptor() { - - @Override - public void process( - final HttpRequest request, - final HttpContext context) throws HttpException, IOException { - if (!request.containsHeader("Accept-Encoding")) { - request.addHeader("Accept-Encoding", "gzip"); - } - } - }); - client.addResponseInterceptor(new HttpResponseInterceptor() { - - public void process( - final HttpResponse response, - final HttpContext context) throws HttpException, IOException { - HttpEntity entity = response.getEntity(); - if (null != entity) { - Header ceheader = entity.getContentEncoding(); - if (ceheader != null) { - HeaderElement[] codecs = ceheader.getElements(); - for (int i = 0; i < codecs.length; i++) { - if (codecs[i].getName().equalsIgnoreCase("gzip")) { - Log.d(Settings.tag, "Decompressing response"); - response.setEntity( - new GzipDecompressingEntity(response.getEntity())); - return; - } - } - } - } - } - - }); - - return client; - } - - static class GzipDecompressingEntity extends HttpEntityWrapper { - public GzipDecompressingEntity(final HttpEntity entity) { - super(entity); - } - - @Override - public InputStream getContent() throws IOException, IllegalStateException { - // the wrapped entity's getContent() decides about repeatability - InputStream wrappedin = wrappedEntity.getContent(); - return new GZIPInputStream(wrappedin); - } - - @Override - public long getContentLength() { - // length of ungzipped content is not known - return -1; - } - } - - public static void restoreCookieStore(final String oldCookies) { - if (!cookieStoreRestored) { - clearCookies(); - if (oldCookies != null) { - for (final String cookie : StringUtils.split(oldCookies, ';')) { - final String[] split = StringUtils.split(cookie, "=", 3); - if (split.length == 3) { - final BasicClientCookie newCookie = new BasicClientCookie(split[0], split[1]); - newCookie.setDomain(split[2]); - cookieStore.addCookie(newCookie); - } - } - } - cookieStoreRestored = true; - } - } - - public static String dumpCookieStore() { - StringBuilder cookies = new StringBuilder(); - for (final Cookie cookie : cookieStore.getCookies()) { - cookies.append(cookie.getName()); - cookies.append('='); - cookies.append(cookie.getValue()); - cookies.append('='); - cookies.append(cookie.getDomain()); - cookies.append(';'); - } - return cookies.toString(); - } - - public static void clearCookies() { - cookieStore.clear(); - } - - /** - * POST HTTP request - * - * @param uri - * @param params - * @return - */ - public static HttpResponse postRequest(final String uri, final List<? extends NameValuePair> params) { - try { - HttpPost request = new HttpPost(uri); - if (params != null) { - request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8)); - } - request.setHeader("X-Requested-With", "XMLHttpRequest"); - return request(request); - } catch (Exception e) { - // Can be UnsupportedEncodingException, ClientProtocolException or IOException - Log.e(Settings.tag, "postRequest", e); - return null; - } - } - - /** - * GET HTTP request - * - * @param uri - * @param params - * @param xContentType - * @return - */ - public static HttpResponse request(final String uri, final Parameters params, final boolean xContentType) { - final String fullUri = params == null ? uri : Uri.parse(uri).buildUpon().encodedQuery(params.toString()).build().toString(); - final HttpRequestBase request = new HttpGet(fullUri); - - request.setHeader("X-Requested-With", "XMLHttpRequest"); - - if (xContentType) { - request.setHeader("Content-Type", "application/x-www-form-urlencoded"); - } - - return request(request); - } - - private static HttpResponse request(final HttpRequestBase request) { - request.setHeader("Accept-Charset", "utf-8,iso-8859-1;q=0.8,utf-16;q=0.8,*;q=0.7"); - request.setHeader("Accept-Language", "en-US,*;q=0.9"); - request.getParams().setParameter(CoreProtocolPNames.USER_AGENT, cgBase.USER_AGENT); - return doRequest(request); - } - - static private String formatTimeSpan(final long before) { - // don't use String.format in a pure logging routine, it has very bad performance - return " (" + (System.currentTimeMillis() - before) + " ms) "; - } - - static public boolean isSuccess(final HttpResponse response) { - return response != null && response.getStatusLine().getStatusCode() == 200; - } - - static public HttpResponse doRequest(final HttpRequestBase request) { - final String reqLogStr = request.getMethod() + " " + hidePassword(request.getURI().toString()); - Log.d(Settings.tag, reqLogStr); - - final HttpClient client = getHttpClient(); - for (int i = 0; i <= NB_DOWNLOAD_RETRIES; i++) { - final long before = System.currentTimeMillis(); - try { - final HttpResponse response = client.execute(request); - int status = response.getStatusLine().getStatusCode(); - if (status == 200) { - Log.d(Settings.tag, status + formatTimeSpan(before) + reqLogStr); - } else { - Log.w(Settings.tag, status + " [" + response.getStatusLine().getReasonPhrase() + "]" + formatTimeSpan(before) + reqLogStr); - } - return response; - } catch (IOException e) { - final String timeSpan = formatTimeSpan(before); - final String tries = (i + 1) + "/" + (NB_DOWNLOAD_RETRIES + 1); - if (i == NB_DOWNLOAD_RETRIES) { - Log.e(Settings.tag, "Failure " + tries + timeSpan + reqLogStr, e); - } else { - Log.e(Settings.tag, "Failure " + tries + " (" + e.toString() + ")" + timeSpan + "- retrying " + reqLogStr); - } - } - } - - return null; - } - - public static JSONObject requestJSON(final String uri, final Parameters params) { - final HttpGet request = new HttpGet(prepareParameters(uri, params)); - request.setHeader("Accept", "application/json, text/javascript, */*; q=0.01"); - request.setHeader("Content-Type", "application/json; charset=UTF-8"); - request.setHeader("X-Requested-With", "XMLHttpRequest"); - - final HttpResponse response = doRequest(request); - if (response != null && response.getStatusLine().getStatusCode() == 200) { - try { - return new JSONObject(getResponseData(response)); - } catch (JSONException e) { - Log.e(Settings.tag, "cgeoBase.requestJSON", e); - } - } - - return null; - } - - public static boolean deleteDirectory(File path) { - if (path.exists()) { - for (final File file : path.listFiles()) { - if (file.isDirectory()) { - deleteDirectory(file); - } else { - file.delete(); - } - } - } - - return path.delete(); - } - public static void storeCache(Activity activity, cgCache origCache, String geocode, int listId, CancellableHandler handler) { try { cgCache cache; @@ -2685,34 +1902,6 @@ public class cgBase { return false; } - public static Double getElevation(final Geopoint coords) { - try { - final String uri = "http://maps.googleapis.com/maps/api/elevation/json"; - final Parameters params = new Parameters( - "sensor", "false", - "locations", coords.format(Format.LAT_LON_DECDEGREE_COMMA)); - final JSONObject response = requestJSON(uri, params); - - if (response == null) { - return null; - } - - if (!StringUtils.equalsIgnoreCase(response.getString("status"), "OK")) { - return null; - } - - if (response.has("results")) { - JSONArray results = response.getJSONArray("results"); - JSONObject result = results.getJSONObject(0); - return result.getDouble("elevation"); - } - } catch (Exception e) { - Log.w(Settings.tag, "cgBase.getElevation: " + e.toString()); - } - - return null; - } - /** * Generate a time string according to system-wide settings (locale, 12/24 hour) * such as "13:24". @@ -2779,94 +1968,6 @@ public class cgBase { } /** - * insert text into the EditText at the current cursor position - * - * @param editText - * @param insertText - * @param moveCursor - * place the cursor after the inserted text - */ - public static void insertAtPosition(final EditText editText, final String insertText, final boolean moveCursor) { - int selectionStart = editText.getSelectionStart(); - int selectionEnd = editText.getSelectionEnd(); - int start = Math.min(selectionStart, selectionEnd); - int end = Math.max(selectionStart, selectionEnd); - - final String content = editText.getText().toString(); - String completeText; - if (start > 0 && !Character.isWhitespace(content.charAt(start - 1))) { - completeText = " " + insertText; - } else { - completeText = insertText; - } - - editText.getText().replace(start, end, completeText); - int newCursor = moveCursor ? start + completeText.length() : start; - editText.setSelection(newCursor, newCursor); - } - - public static LinearLayout createStarRating(final float value, final int count, final Context context) { - LayoutInflater inflater = LayoutInflater.from(context); - LinearLayout starsContainer = new LinearLayout(context); - starsContainer.setOrientation(LinearLayout.HORIZONTAL); - - for (int i = 0; i < count; i++) { - ImageView star = (ImageView) inflater.inflate(R.layout.star, null); - if (value - i >= 0.75) { - star.setImageResource(R.drawable.star_on); - } else if (value - i >= 0.25) { - star.setImageResource(R.drawable.star_half); - } else { - star.setImageResource(R.drawable.star_off); - } - starsContainer.addView(star); - } - - return starsContainer; - } - - public static boolean isActualLoginStatus() { - return actualLoginStatus; - } - - private static void setActualLoginStatus(boolean actualLoginStatus) { - cgBase.actualLoginStatus = actualLoginStatus; - } - - public static String getActualUserName() { - return actualUserName; - } - - private static void setActualUserName(String actualUserName) { - cgBase.actualUserName = actualUserName; - } - - public static String getActualMemberStatus() { - return actualMemberStatus; - } - - private static void setActualMemberStatus(final String actualMemberStatus) { - cgBase.actualMemberStatus = actualMemberStatus; - } - - public static int getActualCachesFound() { - return actualCachesFound; - } - - private static void setActualCachesFound(final int actualCachesFound) { - cgBase.actualCachesFound = actualCachesFound; - } - - public static String getActualStatus() { - return actualStatus; - } - - private static void setActualStatus(final String actualStatus) { - cgBase.actualStatus = actualStatus; - } - - - /** * Indicates whether the specified action can be used as an intent. This * method queries the package manager for installed packages that can * respond to an intent with the specified action. If no suitable package is |
