diff options
author | keith.paterson <keith.paterson@saxsys.de> | 2011-09-26 22:17:36 +0200 |
---|---|---|
committer | keith.paterson <keith.paterson@saxsys.de> | 2011-09-26 22:17:36 +0200 |
commit | 5478bf91bbe8462cffbec49c73e254fd261fd28c (patch) | |
tree | d33a9fc6e4c2a2d728e2baf415cad4bdf8c92a23 /main | |
parent | e60711d56393800c903fa0dd813c1f3fbb918681 (diff) | |
parent | 2bbf2b345c2392b16e01e6021c9e6de18e0d76d6 (diff) | |
download | cgeo-5478bf91bbe8462cffbec49c73e254fd261fd28c.zip cgeo-5478bf91bbe8462cffbec49c73e254fd261fd28c.tar.gz cgeo-5478bf91bbe8462cffbec49c73e254fd261fd28c.tar.bz2 |
Merge remote-tracking branch 'upstream/master' into database-optimization
Diffstat (limited to 'main')
31 files changed, 529 insertions, 1097 deletions
diff --git a/main/res/values-de/strings.xml b/main/res/values-de/strings.xml index ebf3e3d..b92ebe4 100644 --- a/main/res/values-de/strings.xml +++ b/main/res/values-de/strings.xml @@ -225,8 +225,7 @@ <string name="warn_search_help_user">Name eines Benutzers auf Geocaching.com eingeben.</string> <string name="warn_search_help_tb">Code des Trackables eingeben, z.B. \"TB29QMZ\".</string> <string name="warn_log_text_fill">Bitte Text einfügen.</string> - <string name="warn_load_log_image">c:geo konnte das Log-Bild nicht laden.</string> - <string name="warn_load_spoiler_image">c:geo konnte das Spoiler-Bild nicht laden.</string> + <string name="warn_load_images">c:geo konnte die Bilder nicht laden.</string> <string name="info_altitude">Momentane Höhe</string> <string name="info_distance">Gereiste Strecke</string> diff --git a/main/res/values-es/strings.xml b/main/res/values-es/strings.xml index 19b8af4..ba960d5 100644 --- a/main/res/values-es/strings.xml +++ b/main/res/values-es/strings.xml @@ -224,8 +224,7 @@ <string name="warn_search_help_user">Escribe el nombre de usuario de Geocaching.com.</string> <string name="warn_search_help_tb">Escribe el código del rastreable. Por ejemplo \"TB29QMZ\".</string> <string name="warn_log_text_fill">Escribe algún texto de registro.</string> - <string name="warn_load_log_image">Error al cargar la imagen del registro.</string> - <string name="warn_load_spoiler_image">Error al cargar la imagen reveladora.</string> + <string name="warn_load_images">Error al cargar las imágenes.</string> <string name="info_altitude">Altitud actual</string> <string name="info_distance">Distancia recorrida</string> diff --git a/main/res/values-fr/strings.xml b/main/res/values-fr/strings.xml index f33d0a7..56ebb07 100644 --- a/main/res/values-fr/strings.xml +++ b/main/res/values-fr/strings.xml @@ -150,6 +150,7 @@ <string name="err_auth_process">Echec de la demande d\'autorisation.</string> <string name="err_cannot_log_visit">c:geo n\'a pas assez d\'information pour logger votre visite. Faites le depuis le détail de la cache, s\'il vous plait!</string> <string name="err_init_cleared">Désolé, c:geo ne peux pas effacer votre nom d\'utilisateur.</string> + <string name="warn_load_images">Désolé, c:geo n\'a pas pu charger les images.</string> <!-- location service --> <string name="loc_last">dernière pos. connue</string> @@ -351,6 +352,8 @@ <string name="cache_attributes">attributs</string> <string name="cache_inventory">inventaire</string> <string name="cache_log_offline">enregistrement hors ligne</string> + <string name="cache_log_images_loading">Chargement des images du carnet…</string> + <string name="cache_log_images_title">Images du carnet</string> <string name="cache_description">description</string> <string name="cache_description_long">description longue</string> <string name="cache_waypoints">étapes</string> diff --git a/main/res/values-nl/strings.xml b/main/res/values-nl/strings.xml index 5c5f4b9..1a39900 100644 --- a/main/res/values-nl/strings.xml +++ b/main/res/values-nl/strings.xml @@ -225,8 +225,6 @@ <string name="warn_search_help_user">Voer een gebruikersnaam in van een Geocaching.com gebruiker.</string> <string name="warn_search_help_tb">Voer de trackable code in. Bijvoorbeeld \"TB29QMZ\".</string> <string name="warn_log_text_fill">Voer s.v.p. een logtekst in.</string> - <string name="warn_load_log_image">Sorry, c:geo kon de logafbeelding niet laden.</string> - <string name="warn_load_spoiler_image">Sorry, c:geo kon de spoilerafbeelding niet laden.</string> <string name="info_altitude">Huidige hoogte</string> <string name="info_distance">Afgelegde afstand</string> diff --git a/main/res/values-pl/strings.xml b/main/res/values-pl/strings.xml index d646c8d..258781c 100644 --- a/main/res/values-pl/strings.xml +++ b/main/res/values-pl/strings.xml @@ -222,8 +222,6 @@ <string name="warn_search_help_user">Wpisz nazwę użytkownika serwisu Geocaching.com.</string> <string name="warn_search_help_tb">Wpisz kod przedmiotu podróżnego. Na przykład \"TB29QMZ\".</string> <string name="warn_log_text_fill">Proszę wypełnić jakimś tekstem.</string> - <string name="warn_load_log_image">Przepraszam, c:geo nie mógł załadować zdjęcia.</string> - <string name="warn_load_spoiler_image">Przepraszam, c:geo nie mógł załadować zdjęcia z spoilerem.</string> <string name="info_altitude">Aktualna wysokość</string> <string name="info_distance">Przebyta odległość</string> diff --git a/main/res/values-pt/strings.xml b/main/res/values-pt/strings.xml index 37e1f05..8d65d90 100644 --- a/main/res/values-pt/strings.xml +++ b/main/res/values-pt/strings.xml @@ -222,8 +222,6 @@ <string name="warn_search_help_user">Preencha o nome de utilizador em Geocaching.com.</string> <string name="warn_search_help_tb">Preencha o código do trackable. Por exemplo \"TB29QMZ\".</string> <string name="warn_log_text_fill">Por favor, preencha algum texto para o registo.</string> - <string name="warn_load_log_image">Desculpe, o c:geo falhou o carregamento da imagem do log.</string> - <string name="warn_load_spoiler_image">Desculpe, o c:geo falhou o carregamento da imagem spoiler.</string> <string name="info_altitude">Altitude corrente</string> <string name="info_distance">Distância percorrida</string> diff --git a/main/res/values-sk/strings.xml b/main/res/values-sk/strings.xml index ba66879..a28abed 100644 --- a/main/res/values-sk/strings.xml +++ b/main/res/values-sk/strings.xml @@ -228,8 +228,6 @@ <string name="warn_search_help_user">Zadajte meno používateľa z Geocaching.com.</string> <string name="warn_search_help_tb">Zadajte kód trasovateľného objektu. Napríklad „TB29QMZ“.</string> <string name="warn_log_text_fill">Prosím, vyplňte nejaký text do logu.</string> - <string name="warn_load_log_image">Prepáčte, c:geo sa nepodarilo načítať obrázok záznamu.</string> - <string name="warn_load_spoiler_image">Prepáčte, c:geo sa nepodarilo načítať spoilerový obrázok.</string> <string name="info_altitude">Súčasná nadmorská výška</string> <string name="info_distance">Precestovaná vzdialenosť</string> diff --git a/main/res/values-sv/strings.xml b/main/res/values-sv/strings.xml index 7f3ced6..5c5052f 100755 --- a/main/res/values-sv/strings.xml +++ b/main/res/values-sv/strings.xml @@ -225,8 +225,6 @@ <string name="warn_search_help_user">Ange en användare på Geocaching.com.</string> <string name="warn_search_help_tb">Ange koden för en trackable. Tex \"TB29QMZ\".</string> <string name="warn_log_text_fill">Vänligen skriv någon text i loggen.</string> - <string name="warn_load_log_image">Tyvärr misslyckades c:geo att ladda loggbilder.</string> - <string name="warn_load_spoiler_image">Tyvärr misslyckades c:geo att ladda spoilerbilder.</string> <string name="info_altitude">Nuvarande höjd</string> <string name="info_distance">Rest sträcka</string> diff --git a/main/res/values/strings.xml b/main/res/values/strings.xml index 28d2924..b327ed8 100644 --- a/main/res/values/strings.xml +++ b/main/res/values/strings.xml @@ -228,8 +228,7 @@ <string name="warn_search_help_user">Fill name of user at Geocaching.com.</string> <string name="warn_search_help_tb">Fill code of trackable. For example \"TB29QMZ\".</string> <string name="warn_log_text_fill">Please, fill some log text.</string> - <string name="warn_load_log_image">Sorry, c:geo failed to load log image.</string> - <string name="warn_load_spoiler_image">Sorry, c:geo failed to load spoiler image.</string> + <string name="warn_load_images">Sorry, c:geo failed to load images.</string> <string name="info_altitude">Current altitude</string> <string name="info_distance">Distance traveled</string> @@ -507,8 +506,8 @@ <string name="cache_inventory">Inventory</string> <string name="cache_inventory_loading">loading cache inventory…</string> <string name="cache_log_offline">Offline log</string> - <string name="cache_log_images_loading">Loading log Image …</string> - <string name="cache_log_images_title">Log image</string> + <string name="cache_log_images_loading">Loading log images …</string> + <string name="cache_log_images_title">Log images</string> <string name="cache_log_image_default_title">Photo</string> <string name="cache_personal_note">Personal note</string> <string name="cache_description">Description</string> diff --git a/main/src/cgeo/geocaching/CookieJar.java b/main/src/cgeo/geocaching/CookieJar.java deleted file mode 100644 index b6ccf8f..0000000 --- a/main/src/cgeo/geocaching/CookieJar.java +++ /dev/null @@ -1,100 +0,0 @@ -package cgeo.geocaching; - -import org.apache.commons.lang3.StringUtils; - -import android.content.SharedPreferences; -import android.util.Log; - -import java.net.URLConnection; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Handle cookies obtained from web sites. - * - * No other place should touch cookies directly, as we want to make sure - * that the stored information is up-to-date. - * - */ -final public class CookieJar { - - static private boolean cookiesLoaded = false; - final static private HashMap<String, String> cookies = new HashMap<String, String>(); - - static private String cache = null; // Cache information, or null if it has been invalidated - - static private void loadCookiesIfNeeded(final SharedPreferences prefs) { - if (!cookiesLoaded) { - cookies.clear(); - for (final Map.Entry<String, ?> entry : prefs.getAll().entrySet()) { - if (entry.getKey().startsWith("cookie_")) { - cookies.put(entry.getKey().substring(7), (String) entry.getValue()); - } - } - cookiesLoaded = true; - } - } - - static public synchronized void setCookie(final SharedPreferences prefs, final String name, final String value) { - loadCookiesIfNeeded(prefs); - if (!cookies.containsKey(name) || !cookies.get(name).equals(value)) { - final SharedPreferences.Editor editor = prefs.edit(); - cookies.put(name, value); - editor.putString(name, value); - cache = null; - editor.commit(); - } - } - - static public synchronized void setCookie(final SharedPreferences prefs, final String headerField) { - final int semiIndex = headerField.indexOf(';'); - final String cookie = semiIndex == -1 ? headerField : headerField.substring(0, semiIndex); - final int equalIndex = headerField.indexOf('='); - if (equalIndex > 0) { - setCookie(prefs, cookie.substring(0, equalIndex), cookie.substring(equalIndex + 1)); - } else { - Log.w(cgSettings.tag, "CookieJar.setCookie: ignoring header " + headerField); - } - } - - static public synchronized void setCookies(final SharedPreferences prefs, final URLConnection uc) { - final Map<String, List<String>> headers = uc.getHeaderFields(); - if (headers == null) { - // If a request failed, there might not be headers. - return; - } - for (final Map.Entry<String, List<String>> entry : headers.entrySet()) { - if ("set-cookie".equalsIgnoreCase(entry.getKey())) { - for (final String field : entry.getValue()) { - setCookie(prefs, field); - } - } - } - } - - static public synchronized String getCookiesAsString(final SharedPreferences prefs) { - if (cache == null) { - loadCookiesIfNeeded(prefs); - final ArrayList<String> built = new ArrayList<String>(); - for (final Map.Entry<String, String> entry : cookies.entrySet()) { - built.add(entry.getKey() + "=" + entry.getValue()); - } - cache = StringUtils.join(built, ';'); - } - return cache; - } - - static public synchronized void deleteCookies(final SharedPreferences prefs) { - loadCookiesIfNeeded(prefs); - final SharedPreferences.Editor editor = prefs.edit(); - for (final String key : cookies.keySet()) { - editor.remove("cookie_" + key); - } - editor.commit(); - cookies.clear(); - cache = ""; - } - -} diff --git a/main/src/cgeo/geocaching/LogTemplateProvider.java b/main/src/cgeo/geocaching/LogTemplateProvider.java index 76ba0e0..db65ac7 100644 --- a/main/src/cgeo/geocaching/LogTemplateProvider.java +++ b/main/src/cgeo/geocaching/LogTemplateProvider.java @@ -4,7 +4,6 @@ import org.apache.commons.lang3.StringUtils; import android.util.Log; -import java.net.URI; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; @@ -15,8 +14,6 @@ import java.util.regex.Pattern; * */ public class LogTemplateProvider { - private static final URI URI_GC_EMAIL = cgBase.buildURI(false, "www.geocaching.com", "/email/"); - public static abstract class LogTemplate { private String template; private int resourceId; @@ -91,7 +88,7 @@ public class LogTemplateProvider { } String findCount = ""; final Map<String, String> params = new HashMap<String, String>(); - final String page = base.request(URI_GC_EMAIL, "GET", params, false, false, false).getData(); + final String page = cgBase.getResponseData(base.request("http://www.geocaching.com/email/", params, false, false, false)); int current = parseFindCount(page); if (current >= 0) { diff --git a/main/src/cgeo/geocaching/Parameters.java b/main/src/cgeo/geocaching/Parameters.java new file mode 100644 index 0000000..3339a5e --- /dev/null +++ b/main/src/cgeo/geocaching/Parameters.java @@ -0,0 +1,16 @@ +package cgeo.geocaching; + +import org.apache.http.NameValuePair; +import org.apache.http.message.BasicNameValuePair; + +import java.util.ArrayList; + +public class Parameters extends ArrayList<NameValuePair> { + + private static final long serialVersionUID = 1L; + + public void put(final String name, final String value) { + add(new BasicNameValuePair(name, value)); + } + +} diff --git a/main/src/cgeo/geocaching/activity/AbstractActivity.java b/main/src/cgeo/geocaching/activity/AbstractActivity.java index 358aba3..be3a8f9 100644 --- a/main/src/cgeo/geocaching/activity/AbstractActivity.java +++ b/main/src/cgeo/geocaching/activity/AbstractActivity.java @@ -72,7 +72,7 @@ public abstract class AbstractActivity extends Activity implements IAbstractActi app = (cgeoapplication) this.getApplication(); prefs = getSharedPreferences(cgSettings.preferences, Context.MODE_PRIVATE); settings = new cgSettings(this, prefs); - base = new cgBase(app, settings, prefs); + base = new cgBase(app, settings); } final public cgSettings getSettings() { diff --git a/main/src/cgeo/geocaching/activity/AbstractListActivity.java b/main/src/cgeo/geocaching/activity/AbstractListActivity.java index 0afa69c..25c188b 100644 --- a/main/src/cgeo/geocaching/activity/AbstractListActivity.java +++ b/main/src/cgeo/geocaching/activity/AbstractListActivity.java @@ -69,7 +69,7 @@ public abstract class AbstractListActivity extends ListActivity implements app = (cgeoapplication) this.getApplication(); prefs = getSharedPreferences(cgSettings.preferences, Context.MODE_PRIVATE); settings = new cgSettings(this, prefs); - base = new cgBase(app, settings, prefs); + base = new cgBase(app, settings); } final public void setTitle(final String title) { diff --git a/main/src/cgeo/geocaching/cgBase.java b/main/src/cgeo/geocaching/cgBase.java index 328a4d4..595d17e 100644 --- a/main/src/cgeo/geocaching/cgBase.java +++ b/main/src/cgeo/geocaching/cgBase.java @@ -1,3 +1,4 @@ +// $codepro.audit.disable logExceptions package cgeo.geocaching; import cgeo.geocaching.activity.ActivityMixin; @@ -12,6 +13,29 @@ import cgeo.geocaching.utils.CollectionUtils; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpResponse; +import org.apache.http.HttpVersion; +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.conn.ClientConnectionManager; +import org.apache.http.conn.scheme.PlainSocketFactory; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.ssl.SSLSocketFactory; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.BasicCookieStore; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; +import org.apache.http.params.BasicHttpParams; +import org.apache.http.params.HttpParams; +import org.apache.http.params.HttpProtocolParams; +import org.apache.http.protocol.HTTP; +import org.apache.http.util.EntityUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -19,7 +43,6 @@ import org.json.JSONObject; import android.app.Activity; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.res.Resources; @@ -40,12 +63,11 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; -import java.net.URI; -import java.net.URISyntaxException; import java.net.URL; import java.net.URLConnection; import java.net.URLDecoder; @@ -131,16 +153,7 @@ public class cgBase { private final static Pattern PATTERN_TRACKABLE_Distance = Pattern.compile("<h4[^>]*\\W*Tracking History \\(([0-9.,]+(km|mi))[^\\)]*\\)", Pattern.CASE_INSENSITIVE); private final static Pattern PATTERN_TRACKABLE_Log = Pattern.compile("<tr class=\"Data.+?src=\"/images/icons/([^.]+)\\.gif[^>]+> ([^<]+)</td>.+?guid.+?>([^<]+)</a>.+?(?:guid=([^\"]+)\">([^<]+)</a>.+?)?<td colspan=\"4\">(.+?)(?:<ul.+?ul>)?\\s*</td>\\s*</tr>", Pattern.CASE_INSENSITIVE); - private static final URI URI_GC_LOGIN_DEFAULT = buildURI(true, "www.geocaching.com", "/login/default.aspx"); - private static final URI URI_GC_DEFAULT = buildURI(false, "www.geocaching.com", "/default.aspx"); - private static final URI URI_GOOGLE_RECAPTCHA = buildURI(false, "www.google.com", "/recaptcha/api/challenge"); - private static final URI URI_GC_MAP_DEFAULT = buildURI(false, "www.geocaching.com", "/map/default.aspx"); - private static final URI URI_GC_SEEK_NEAREST = buildURI(false, "www.geocaching.com", "/seek/nearest.aspx"); - private static final URI URI_GC_SEEK_LOGBOOK = buildURI(false, "www.geocaching.com", "/seek/geocache.logbook"); - private static final URI URI_GC_PREFERENCES = buildURI(false, "www.geocaching.com", "/account/ManagePreferences.aspx"); - private static final URI URI_GCVOTE_GETVOTES = buildURI(false, "gcvote.com", "/getVotes.php"); - private static final URI URI_GO4CACHE_GET = buildURI(false, "api.go4cache.com", "/get.php"); - private static final URI URI_GC_TRACK_DETAILS = buildURI(false, "www.geocaching.com", "/track/details.aspx"); + private static final String passMatch = "(?<=[\\?&])[Pp]ass(w(or)?d)?=[^&#$]+"; public final static Map<String, String> cacheTypes = new HashMap<String, String>(); public final static Map<String, String> cacheIDs = new HashMap<String, String>(); @@ -186,7 +199,6 @@ public class cgBase { public final static SimpleDateFormat dateTbIn2 = new SimpleDateFormat("EEEEE, MMMMM dd, yyyy", Locale.ENGLISH); // Saturday, March 28, 2009 public final static SimpleDateFormat dateSqlIn = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 2010-07-25 14:44:01 private Resources res = null; - private static final String passMatch = "[/\\?&]*[Pp]ass(word)?=[^&^#^$]+"; private static final Pattern patternLoggedIn = Pattern.compile("<span class=\"Success\">You are logged in as[^<]*<strong[^>]*>([^<]+)</strong>[^<]*</span>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); private static final Pattern patternLogged2In = Pattern.compile("<strong>\\W*Hello,[^<]*<a[^>]+>([^<]+)</a>[^<]*</strong>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); private static final Pattern patternViewstateFieldCount = Pattern.compile("id=\"__VIEWSTATEFIELDCOUNT\"[^(value)]+value=\"(\\d+)\"[^>]+>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); @@ -201,7 +213,6 @@ public class cgBase { public static final float erad = 6371.0f; private cgeoapplication app = null; private cgSettings settings = null; - private SharedPreferences prefs = null; public String version = null; private String idBrowser = "Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.86 Safari/533.4"; Context context = null; @@ -230,7 +241,9 @@ public class cgBase { public static final int LOG_WEBCAM_PHOTO_TAKEN = 11; public static final int LOG_ANNOUNCEMENT = 74; - public cgBase(cgeoapplication appIn, cgSettings settingsIn, SharedPreferences prefsIn) { + private static final int NB_DOWNLOAD_RETRIES = 4; + + public cgBase(cgeoapplication appIn, cgSettings settingsIn) { context = appIn.getBaseContext(); res = appIn.getBaseContext().getResources(); @@ -367,14 +380,14 @@ public class cgBase { // init app = appIn; settings = settingsIn; - prefs = prefsIn; try { - PackageManager manager = app.getPackageManager(); - PackageInfo info = manager.getPackageInfo(app.getPackageName(), 0); + final PackageManager manager = app.getPackageManager(); + final PackageInfo info = manager.getPackageInfo(app.getPackageName(), 0); version = info.versionName; - } catch (Exception e) { - // nothing + } catch (PackageManager.NameNotFoundException e) { + Log.e(cgSettings.tag, "unable to get version information", e); + version = null; } if (settings.asBrowser == 1) { @@ -399,6 +412,10 @@ public class cgBase { } } + public static String hidePassword(final String message) { + return message.replaceAll(passMatch, "password=***"); + } + /** * read all viewstates from page * @@ -436,7 +453,7 @@ public class cgBase { /** * put viewstates into request parameters */ - private static void setViewstates(String[] viewstates, Map<String, String> params) { + private static void setViewstates(final String[] viewstates, final Parameters params) { if (ArrayUtils.isEmpty(viewstates)) return; params.put("__VIEWSTATE", viewstates[0]); @@ -451,7 +468,7 @@ public class cgBase { * transfers the viewstates variables from a page (response) to parameters * (next request) */ - public static void transferViewstates(String page, Map<String, String> params) { + public static void transferViewstates(final String page, final Parameters params) { setViewstates(getViewstates(page), params); } @@ -481,7 +498,7 @@ public class cgBase { } public int login() { - cgResponse loginResponse = null; + HttpResponse loginResponse = null; String loginData = null; String[] viewstates = null; @@ -492,8 +509,8 @@ public class cgBase { return -3; // no login information stored } - loginResponse = request(URI_GC_LOGIN_DEFAULT, "GET", new HashMap<String, String>(), false, false, false); - loginData = loginResponse.getData(); + loginResponse = request("https://www.geocaching.com/login/default.aspx", new HashMap<String, String>(), false, false, false); + loginData = getResponseData(loginResponse); if (StringUtils.isNotBlank(loginData)) { if (checkLogin(loginData)) { Log.i(cgSettings.tag, "Already logged in Geocaching.com as " + loginStart.get("username")); @@ -515,14 +532,15 @@ public class cgBase { } final Map<String, String> login = settings.getLogin(); - final Map<String, String> params = new HashMap<String, String>(); if (login == null || StringUtils.isEmpty(login.get("username")) || StringUtils.isEmpty(login.get("password"))) { Log.e(cgSettings.tag, "cgeoBase.login: No login information stored"); return -3; } - CookieJar.deleteCookies(prefs); + clearCookies(); + + final Parameters params = new Parameters(); params.put("__EVENTTARGET", ""); params.put("__EVENTARGUMENT", ""); @@ -532,8 +550,8 @@ public class cgBase { params.put("ctl00$SiteContent$cbRememberMe", "on"); params.put("ctl00$SiteContent$btnSignIn", "Login"); - loginResponse = request(URI_GC_LOGIN_DEFAULT, "POST", params, false, false, false); - loginData = loginResponse.getData(); + loginResponse = postRequest("https://www.geocaching.com/login/default.aspx", params); + loginData = getResponseData(loginResponse); if (StringUtils.isNotBlank(loginData)) { if (checkLogin(loginData)) { @@ -591,13 +609,13 @@ public class cgBase { } public String switchToEnglish(String[] viewstates) { - final Map<String, String> params = new HashMap<String, String>(); + final Parameters params = new Parameters(); setViewstates(viewstates, params); params.put("__EVENTTARGET", "ctl00$uxLocaleList$uxLocaleList$ctl00$uxLocaleItem"); // switch to english params.put("__EVENTARGUMENT", ""); - return request(URI_GC_DEFAULT, "POST", params, false, false, false).getData(); + return cgBase.getResponseData(postRequest("http://www.geocaching.com/default.aspx", params)); } public cgCacheWrap parseSearch(cgSearchThread thread, String url, String page, boolean showCaptcha) { @@ -640,7 +658,7 @@ public class cgBase { } if (recaptchaJsParam != null) { - final String recaptchaJs = request(URI_GOOGLE_RECAPTCHA, "GET", "k=" + urlencode_rfc3986(recaptchaJsParam.trim()), 0, true).getData(); + final String recaptchaJs = cgBase.getResponseData(request("http://www.google.com/recaptcha/api/challenge", "k=" + urlencode_rfc3986(recaptchaJsParam.trim()), true)); if (StringUtils.isNotBlank(recaptchaJs)) { final Matcher matcherRecaptchaChallenge = patternRecaptchaChallenge.matcher(recaptchaJs); @@ -891,33 +909,29 @@ public class cgBase { try { // get coordinates for parsed caches - final StringBuilder params = new StringBuilder(); - params.append("__EVENTTARGET=&__EVENTARGUMENT="); + final Parameters params = new Parameters(); + params.put("__EVENTTARGET", ""); + params.put("__EVENTARGUMENT", ""); if (ArrayUtils.isNotEmpty(caches.viewstates)) { - params.append("&__VIEWSTATE="); - params.append(urlencode_rfc3986(caches.viewstates[0])); + params.put("__VIEWSTATE", caches.viewstates[0]); if (caches.viewstates.length > 1) { for (int i = 1; i < caches.viewstates.length; i++) { - params.append("&__VIEWSTATE" + i + "="); - params.append(urlencode_rfc3986(caches.viewstates[i])); + params.put("__VIEWSTATE" + i, caches.viewstates[i]); } - params.append("&__VIEWSTATEFIELDCOUNT=" + caches.viewstates.length); + params.put("__VIEWSTATEFIELDCOUNT", "" + caches.viewstates.length); } } for (String cid : cids) { - params.append("&CID="); - params.append(urlencode_rfc3986(cid)); + params.put("CID", cid); } if (recaptchaChallenge != null && StringUtils.isNotBlank(recaptchaText)) { - params.append("&recaptcha_challenge_field="); - params.append(urlencode_rfc3986(recaptchaChallenge)); - params.append("&recaptcha_response_field="); - params.append(urlencode_rfc3986(recaptchaText)); + params.put("recaptcha_challenge_field", recaptchaChallenge); + params.put("recaptcha_response_field", recaptchaText); } - params.append("&ctl00%24ContentBody%24uxDownloadLoc=Download+Waypoints"); + params.put("ctl00$ContentBody$uxDownloadLoc", "Download Waypoints"); - final String coordinates = request(URI_GC_SEEK_NEAREST, "POST", params.toString(), 0, true).getData(); + final String coordinates = getResponseData(postRequest("http://www.geocaching.com/seek/nearest.aspx", params)); 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")) { @@ -972,14 +986,14 @@ public class cgBase { return caches; } - public static cgCacheWrap parseMapJSON(final URI uri, final String data) { + public static cgCacheWrap parseMapJSON(final String uri, final String data) { if (StringUtils.isEmpty(data)) { Log.e(cgSettings.tag, "cgeoBase.parseMapJSON: No page given"); return null; } final cgCacheWrap caches = new cgCacheWrap(); - caches.url = uri.toString(); + caches.url = uri; try { final JSONObject yoDawg = new JSONObject(data); @@ -1049,7 +1063,7 @@ public class cgBase { caches.totalCnt = caches.cacheList.size(); } } catch (Exception e) { - Log.e(cgSettings.tag, "cgBase.parseMapJSON: " + e.toString()); + Log.e(cgSettings.tag, "cgBase.parseMapJSON", e); } return caches; @@ -1669,17 +1683,20 @@ public class cgBase { params.put("tkn", userToken); params.put("idx", "1"); params.put("num", "35"); - params.put("sp", "0"); - params.put("sf", "0"); - params.put("decrypt", "1"); - final cgResponse response = request(URI_GC_SEEK_LOGBOOK, "GET", params, false, false, false); - if (response.getStatusCode() != 200) { - Log.e(cgSettings.tag, "cgBase.loadLogsFromDetails: error " + response.getStatusCode() + " when requesting log information"); + params.put("decrypt", "true"); + final HttpResponse response = request("http://www.geocaching.com/seek/geocache.logbook", params, false, false, false); + if (response == null) { + Log.e(cgSettings.tag, "cgBase.loadLogsFromDetails: cannot log logs, response is null"); + return; + } + final int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode != 200) { + Log.e(cgSettings.tag, "cgBase.loadLogsFromDetails: error " + statusCode + " when requesting log information"); return; } try { - final JSONObject resp = new JSONObject(response.getData()); + final JSONObject resp = new JSONObject(cgBase.getResponseData(response)); if (!resp.getString("status").equals("success")) { Log.e(cgSettings.tag, "cgBase.loadLogsFromDetails: status is " + resp.getString("status")); return; @@ -1820,7 +1837,7 @@ public class cgBase { public void detectGcCustomDate() { - final String result = request(URI_GC_PREFERENCES, "GET", null, false, false, false).getData(); + final String result = getResponseData(request("http://www.geocaching.com/account/ManagePreferences.aspx", null, false, false, false)); if (null == result) { Log.w(cgSettings.tag, "cgeoBase.detectGcCustomDate: result is null"); @@ -1877,12 +1894,12 @@ public class cgBase { } } if (CollectionUtils.isNotEmpty(guids)) { - params.put("cacheIds", implode(",", guids.toArray())); + params.put("cacheIds", StringUtils.join(guids.toArray(), ',')); } else { - params.put("waypoints", implode(",", geocodes.toArray())); + params.put("waypoints", StringUtils.join(geocodes.toArray(), ',')); } params.put("version", "cgeo"); - final String votes = request(URI_GCVOTE_GETVOTES, "GET", params, false, false, false).getData(); + final String votes = getResponseData(request("http://gcvote.com/getVotes.php", params, false, false, false)); if (votes == null) { return null; } @@ -2483,7 +2500,7 @@ public class cgBase { public UUID searchByNextPage(cgSearchThread thread, final UUID searchId, int reason, boolean showCaptcha) { final String[] viewstates = app.getViewstates(searchId); - String url = app.getUrl(searchId); + final String url = app.getUrl(searchId); if (StringUtils.isBlank(url)) { Log.e(cgSettings.tag, "cgeoBase.searchByNextPage: No url found"); @@ -2495,42 +2512,19 @@ public class cgBase { return searchId; } - String host = "www.geocaching.com"; - String path = "/"; - final String method = "POST"; + // As in the original code, remove the query string + final String uri = Uri.parse(url).buildUpon().query(null).build().toString(); - int dash = -1; - if (url.startsWith("http://")) { - url = url.substring(7); - } - - dash = url.indexOf("/"); - if (dash > -1) { - host = url.substring(0, dash); - url = url.substring(dash); - } else { - host = url; - url = ""; - } - - dash = url.indexOf("?"); - if (dash > -1) { - path = url.substring(0, dash); - } else { - path = url; - } - - final Map<String, String> params = new HashMap<String, String>(); + final Parameters params = new Parameters(); setViewstates(viewstates, params); params.put("__EVENTTARGET", "ctl00$ContentBody$pgrBottom$ctl08"); params.put("__EVENTARGUMENT", ""); - final URI uri = buildURI(false, host, path); - String page = request(uri, method, params, false, false, true).getData(); + String page = getResponseData(postRequest(uri, params)); if (checkLogin(page) == false) { int loginState = login(); if (loginState == 1) { - page = request(uri, method, params, false, false, true).getData(); + page = getResponseData(postRequest(uri, params)); } else if (loginState == -3) { Log.i(cgSettings.tag, "Working as guest."); } else { @@ -2662,9 +2656,6 @@ public class cgBase { cacheType = null; } - final String host = "www.geocaching.com"; - final String path = "/seek/nearest.aspx"; - final String method = "GET"; final Map<String, String> params = new HashMap<String, String>(); if (cacheType != null && cacheIDs.containsKey(cacheType)) { params.put("tx", cacheIDs.get(cacheType)); @@ -2674,16 +2665,16 @@ public class cgBase { params.put("lat", latitude); params.put("lng", longitude); - final String url = "http://" + host + path + "?" + prepareParameters(params, false, true); - final URI uri = buildURI(false, host, path); - String page = requestLogged(uri, method, params, false, false, true); + final String uri = "http://www.geocaching.com/seek/nearest.aspx"; + final String fullUri = uri + "?" + prepareParameters(params, false, true); + String page = requestLogged(uri, params, false, false, true); if (StringUtils.isBlank(page)) { Log.e(cgSettings.tag, "cgeoBase.searchByCoords: No data from server"); return null; } - final cgCacheWrap caches = parseSearch(thread, url, page, showCaptcha); + final cgCacheWrap caches = parseSearch(thread, fullUri, page, showCaptcha); if (caches == null || caches.cacheList == null || caches.cacheList.isEmpty()) { Log.e(cgSettings.tag, "cgeoBase.searchByCoords: No cache parsed"); } @@ -2714,9 +2705,6 @@ public class cgBase { cacheType = null; } - final String host = "www.geocaching.com"; - final String path = "/seek/nearest.aspx"; - final String method = "GET"; final Map<String, String> params = new HashMap<String, String>(); if (cacheType != null && cacheIDs.containsKey(cacheType)) { params.put("tx", cacheIDs.get(cacheType)); @@ -2725,16 +2713,16 @@ public class cgBase { } params.put("key", keyword); - final String url = "http://" + host + path + "?" + prepareParameters(params, false, true); - final URI uri = cgBase.buildURI(false, host, path); - String page = requestLogged(uri, method, params, false, false, true); + final String uri = "http://www.geocaching.com/seek/nearest.aspx"; + final String fullUri = uri + "?" + prepareParameters(params, false, true); + String page = requestLogged(uri, params, false, false, true); if (StringUtils.isBlank(page)) { Log.e(cgSettings.tag, "cgeoBase.searchByKeyword: No data from server"); return null; } - final cgCacheWrap caches = parseSearch(thread, url, page, showCaptcha); + final cgCacheWrap caches = parseSearch(thread, fullUri, page, showCaptcha); if (caches == null || caches.cacheList == null || caches.cacheList.isEmpty()) { Log.e(cgSettings.tag, "cgeoBase.searchByKeyword: No cache parsed"); } @@ -2765,9 +2753,6 @@ public class cgBase { cacheType = null; } - final String host = "www.geocaching.com"; - final String path = "/seek/nearest.aspx"; - final String method = "GET"; final Map<String, String> params = new HashMap<String, String>(); if (cacheType != null && cacheIDs.containsKey(cacheType)) { params.put("tx", cacheIDs.get(cacheType)); @@ -2782,16 +2767,16 @@ public class cgBase { Log.i(cgSettings.tag, "cgBase.searchByUsername: Overriding users choice, downloading all caches."); } - final String url = "http://" + host + path + "?" + prepareParameters(params, my, true); - final URI uri = buildURI(false, host, path); - String page = requestLogged(uri, method, params, false, my, true); + final String uri = "http://www.geocaching.com/seek/nearest.aspx"; + final String fullUri = uri + "?" + prepareParameters(params, my, true); + String page = requestLogged(uri, params, false, my, true); if (StringUtils.isBlank(page)) { Log.e(cgSettings.tag, "cgeoBase.searchByUsername: No data from server"); return null; } - final cgCacheWrap caches = parseSearch(thread, url, page, showCaptcha); + final cgCacheWrap caches = parseSearch(thread, fullUri, page, showCaptcha); if (caches == null || caches.cacheList == null || caches.cacheList.isEmpty()) { Log.e(cgSettings.tag, "cgeoBase.searchByUsername: No cache parsed"); } @@ -2822,9 +2807,6 @@ public class cgBase { cacheType = null; } - final String host = "www.geocaching.com"; - final String path = "/seek/nearest.aspx"; - final String method = "GET"; final Map<String, String> params = new HashMap<String, String>(); if (cacheType != null && cacheIDs.containsKey(cacheType)) { params.put("tx", cacheIDs.get(cacheType)); @@ -2833,16 +2815,16 @@ public class cgBase { } params.put("u", userName); - final String url = "http://" + host + path + "?" + prepareParameters(params, false, true); - final URI uri = buildURI(false, host, path); - String page = requestLogged(uri, method, params, false, false, true); + final String uri = "http://www.geocaching.com/seek/nearest.aspx"; + final String fullUri = uri + "?" + prepareParameters(params, false, true); + String page = requestLogged(uri, params, false, false, true); if (StringUtils.isBlank(page)) { Log.e(cgSettings.tag, "cgeoBase.searchByOwner: No data from server"); return null; } - final cgCacheWrap caches = parseSearch(thread, url, page, showCaptcha); + final cgCacheWrap caches = parseSearch(thread, fullUri, page, showCaptcha); if (caches == null || caches.cacheList == null) { Log.e(cgSettings.tag, "cgeoBase.searchByOwner: No cache parsed"); } @@ -2880,12 +2862,9 @@ public class cgBase { return null; } - final String host = "www.geocaching.com"; - final String path = "/map/default.aspx/MapAction"; - - String params = "{\"dto\":{\"data\":{\"c\":1,\"m\":\"\",\"d\":\"" + latMax + "|" + latMin + "|" + lonMax + "|" + lonMin + "\"},\"ut\":\"" + usertoken + "\"}}"; + final String params = "{\"dto\":{\"data\":{\"c\":1,\"m\":\"\",\"d\":\"" + latMax + "|" + latMin + "|" + lonMax + "|" + lonMin + "\"},\"ut\":\"" + usertoken + "\"}}"; - final URI uri = buildURI(false, host, path); + final String uri = "http://www.geocaching.com/map/default.aspx/MapAction"; page = requestJSONgc(uri, params); if (StringUtils.isBlank(page)) { @@ -2893,7 +2872,7 @@ public class cgBase { return null; } - final cgCacheWrap caches = parseMapJSON(buildURI(false, host, path, params), page); + final cgCacheWrap caches = parseMapJSON(Uri.parse(uri).buildUpon().encodedQuery(params).build().toString(), page); if (caches == null || caches.cacheList == null || caches.cacheList.isEmpty()) { Log.e(cgSettings.tag, "cgeoBase.searchByViewport: No cache parsed"); } @@ -2910,6 +2889,23 @@ public class cgBase { return search.getCurrentId(); } + private String requestJSONgc(final String uri, final String params) { + String page; + final HttpPost request = new HttpPost("http://www.geocaching.com/map/default.aspx/MapAction"); + try { + request.setEntity(new StringEntity(params, HTTP.UTF_8)); + } catch (UnsupportedEncodingException e) { + Log.e(cgSettings.tag, "cgeoBase.searchByViewport", e); + } + + request.addHeader("Content-Type", "application/json; charset=UTF-8"); + request.addHeader("X-Requested-With", "XMLHttpRequest"); + request.addHeader("Accept", "application/json, text/javascript, */*; q=0.01"); + request.addHeader("Referer", uri); + page = getResponseData(request(request)); + return page; + } + public List<cgUser> getGeocachersInViewport(String username, Double latMin, Double latMax, Double lonMin, Double lonMax) { final List<cgUser> users = new ArrayList<cgUser>(); @@ -2920,7 +2916,7 @@ public class cgBase { return users; } - final Map<String, String> params = new HashMap<String, String>(); + final Parameters params = new Parameters(); params.put("u", username); params.put("ltm", String.format((Locale) null, "%.6f", latMin)); @@ -2928,7 +2924,7 @@ public class cgBase { params.put("lnm", String.format((Locale) null, "%.6f", lonMin)); params.put("lnx", String.format((Locale) null, "%.6f", lonMax)); - final String data = request(URI_GO4CACHE_GET, "POST", params, false, false, false).getData(); + final String data = getResponseData(postRequest("http://api.go4cache.com/get.php", params)); if (StringUtils.isBlank(data)) { Log.e(cgSettings.tag, "cgeoBase.getGeocachersInViewport: No data from server"); @@ -3017,7 +3013,7 @@ public class cgBase { params.put("id", id); } - String page = requestLogged(URI_GC_TRACK_DETAILS, "GET", params, false, false, false); + String page = requestLogged("http://www.geocaching.com/track/details.aspx", params, false, false, false); if (StringUtils.isBlank(page)) { Log.e(cgSettings.tag, "cgeoBase.searchTrackable: No data from server"); @@ -3075,7 +3071,7 @@ public class cgBase { Log.i(cgSettings.tag, "Trying to post log for cache #" + cacheid + " - action: " + logType + "; date: " + year + "." + month + "." + day + ", log: " + log + "; trackables: 0"); } - final Map<String, String> params = new HashMap<String, String>(); + final Parameters params = new Parameters(); setViewstates(viewstates, params); params.put("__EVENTTARGET", ""); @@ -3105,12 +3101,12 @@ public class cgBase { params.put("ctl00$ContentBody$LogBookPanel1$uxTrackables$hdnCurrentFilter", ""); } - final URI uri = buildURI(false, "www.geocaching.com", "/seek/log.aspx", "ID=" + cacheid); - String page = request(uri, "POST", params, false, false, false).getData(); - if (checkLogin(page) == false) { + 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 (!checkLogin(page)) { int loginState = login(); if (loginState == 1) { - page = request(uri, "POST", params, false, false, false).getData(); + page = getResponseData(postRequest(uri, params)); } else { Log.e(cgSettings.tag, "cgeoBase.postLog: Can not log in geocaching (error: " + loginState + ")"); return loginState; @@ -3167,7 +3163,7 @@ public class cgBase { params.put("ctl00$ContentBody$LogBookPanel1$uxTrackables$hdnCurrentFilter", ""); } - page = request(uri, "POST", params, false, false, false).getData(); + page = getResponseData(postRequest(uri, params)); } } catch (Exception e) { Log.e(cgSettings.tag, "cgeoBase.postLog.confim: " + e.toString()); @@ -3215,7 +3211,7 @@ public class cgBase { log = log.replace("\n", "\r\n"); // windows' eol final Calendar currentDate = Calendar.getInstance(); - final Map<String, String> params = new HashMap<String, String>(); + final Parameters params = new Parameters(); setViewstates(viewstates, params); params.put("__EVENTTARGET", ""); @@ -3235,12 +3231,12 @@ public class cgBase { params.put("ctl00$ContentBody$LogBookPanel1$LogButton", "Submit Log Entry"); params.put("ctl00$ContentBody$uxVistOtherListingGC", ""); - final URI uri = buildURI(false, "www.geocaching.com", "/track/log.aspx", "wid=" + tbid); - String page = request(uri, "POST", params, false, false, false).getData(); + 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 (checkLogin(page) == false) { int loginState = login(); if (loginState == 1) { - page = request(uri, "POST", params, false, false, false).getData(); + page = getResponseData(postRequest(uri, params)); } else { Log.e(cgSettings.tag, "cgeoBase.postLogTrackable: Can not log in geocaching (error: " + loginState + ")"); return loginState; @@ -3275,9 +3271,8 @@ public class cgBase { * @return -1: error occured */ public int addToWatchlist(cgCache cache) { - final URI uri = buildURI(false, "www.geocaching.com", "/my/watchlist.aspx", "w=" + cache.cacheId); - String page = requestLogged(uri, - "POST", null, false, false, false); + final String uri = "http://www.geocaching.com/my/watchlist.aspx?w=" + cache.cacheId; + String page = postRequestLogged(uri); if (StringUtils.isBlank(page)) { Log.e(cgSettings.tag, "cgBase.addToWatchlist: No data from server"); @@ -3302,8 +3297,8 @@ public class cgBase { * @return -1: error occured */ public int removeFromWatchlist(cgCache cache) { - final URI uri = buildURI(false, "www.geocaching.com", "/my/watchlist.aspx", "ds=1&action=rem&id=" + cache.cacheId); - String page = requestLogged(uri, "POST", null, false, false, false); + final String uri = "http://www.geocaching.com/my/watchlist.aspx?ds=1&action=rem&id=" + cache.cacheId; + String page = postRequestLogged(uri); if (StringUtils.isBlank(page)) { Log.e(cgSettings.tag, "cgBase.removeFromWatchlist: No data from server"); @@ -3311,13 +3306,13 @@ public class cgBase { } // removing cache from list needs approval by hitting "Yes" button - final Map<String, String> params = new HashMap<String, String>(); + final Parameters params = new Parameters(); transferViewstates(page, params); params.put("__EVENTTARGET", ""); params.put("__EVENTARGUMENT", ""); params.put("ctl00$ContentBody$btnYes", "Yes"); - page = request(uri, "POST", params, false, false, false).getData(); + page = getResponseData(postRequest(uri, params)); boolean guidOnPage = cache.isGuidContainedInPage(page); if (!guidOnPage) { Log.i(cgSettings.tag, "cgBase.removeFromWatchlist: cache removed from watchlist"); @@ -3469,16 +3464,11 @@ public class cgBase { } private static void readIntoBuffer(BufferedReader br, StringBuffer buffer) throws IOException { - int bufferSize = 1024 * 16; - char[] bytes = new char[bufferSize]; + final int bufferSize = 1024 * 16; + final char[] bytes = new char[bufferSize]; int bytesRead; while ((bytesRead = br.read(bytes)) > 0) { - if (bytesRead == bufferSize) { - buffer.append(bytes); - } - else { - buffer.append(bytes, 0, bytesRead); - } + buffer.append(bytes, 0, bytesRead); } } @@ -3500,22 +3490,6 @@ public class cgBase { return null; } - public static String implode(String delim, Object[] array) { - StringBuilder out = new StringBuilder(); - - try { - for (int i = 0; i < array.length; i++) { - if (i != 0) { - out.append(delim); - } - out.append(array[i].toString()); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoBase.implode: " + e.toString()); - } - return out.toString(); - } - public static String urlencode_rfc3986(String text) { final String encoded = URLEncoder.encode(text).replace("+", "%20").replaceAll("%7E", "~"); @@ -3555,7 +3529,7 @@ public class cgBase { paramsEncoded.add(key + "=" + urlencode_rfc3986(value)); } - paramsDone = implode("&", paramsEncoded.toArray()); + paramsDone = StringUtils.join(paramsEncoded.toArray(), '&'); } else { paramsDone = ""; } @@ -3563,36 +3537,45 @@ public class cgBase { return paramsDone; } - public static URI buildURI(final boolean secure, final String host, final String path, final String query) { + public String[] requestViewstates(final String uri, Map<String, String> params, boolean xContentType, boolean my) { + final HttpResponse response = request(uri, params, xContentType, my, false); + + return getViewstates(getResponseData(response)); + } + + static public String getResponseData(final HttpResponse response) { + if (response == null) { + return null; + } try { - return new URI(secure ? "https" : "http", host, path, query, null); - } catch (URISyntaxException e) { - // This should never happen as we only use trusted URI components. - Log.e(cgSettings.tag, "buildURI", e); + return replaceWhitespace(EntityUtils.toString(response.getEntity(), HTTP.UTF_8)); + } catch (Exception e) { + Log.e(cgSettings.tag, "getResponseData", e); return null; } } - public static URI buildURI(boolean secure, String host, String path) { - final String pathComponents[] = StringUtils.split(path, "?", 2); - return buildURI(secure, host, pathComponents[0], pathComponents.length > 1 ? pathComponents[1] : null); - } - - public String[] requestViewstates(final URI uri, String method, Map<String, String> params, boolean xContentType, boolean my) { - final cgResponse response = request(uri, method, params, xContentType, my, false); - - return getViewstates(response.getData()); + public String postRequestLogged(final String uri) { + final String data = getResponseData(postRequest(uri, null)); + if (!checkLogin(data)) { + if (login() == 1) { + return getResponseData(postRequest(uri, null)); + } else { + Log.i(cgSettings.tag, "Working as guest."); + } + } + return data; } - public String requestLogged(final URI uri, String method, Map<String, String> params, boolean xContentType, boolean my, boolean addF) { - cgResponse response = request(uri, method, params, xContentType, my, addF); - String data = response.getData(); + public String requestLogged(final String uri, Map<String, String> params, boolean xContentType, boolean my, boolean addF) { + HttpResponse response = request(uri, params, xContentType, my, addF); + String data = getResponseData(response); if (checkLogin(data) == false) { int loginState = login(); if (loginState == 1) { - response = request(uri, method, params, xContentType, my, addF); - data = response.getData(); + response = request(uri, params, xContentType, my, addF); + data = getResponseData(response); } else { Log.i(cgSettings.tag, "Working as guest."); } @@ -3601,169 +3584,95 @@ public class cgBase { return data; } - public cgResponse request(final URI uri, String method, Map<String, String> params, boolean xContentType, boolean my, boolean addF) { - // prepare parameters - final String paramsDone = prepareParameters(params, my, addF); - return request(uri, method, paramsDone, 0, xContentType); - } - - public cgResponse request(final URI uri, String method, Map<String, String> params, int requestId, boolean xContentType, boolean my, boolean addF) { + public HttpResponse request(final String uri, Map<String, String> params, boolean xContentType, boolean my, boolean addF) { final String paramsDone = prepareParameters(params, my, addF); - return request(uri, method, paramsDone, requestId, xContentType); + return request(uri, paramsDone, xContentType); } - public cgResponse request(final URI uri, String method, String params, int requestId, Boolean xContentType) { - URL u = null; - int httpCode = -1; - String httpMessage = null; - String httpLocation = null; - - if (requestId == 0) { - requestId = (int) (Math.random() * 1000); + private static ClientConnectionManager clientConnectionManager; + private static HttpParams clientParams; + private static CookieStore cookieStore; + + public static HttpClient getHttpClient() { + if (clientConnectionManager == null) { + synchronized (cgBase.class) { + if (clientConnectionManager == null) { + clientParams = new BasicHttpParams(); + HttpProtocolParams.setVersion(clientParams, HttpVersion.HTTP_1_1); + final SchemeRegistry registry = new SchemeRegistry(); + registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); + registry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); + cookieStore = new BasicCookieStore(); + clientConnectionManager = new ThreadSafeClientConnManager(clientParams, registry); + } + } } + final DefaultHttpClient client = new DefaultHttpClient(clientConnectionManager, clientParams); + client.setCookieStore(cookieStore); + return client; + } - if (method == null || (method.equalsIgnoreCase("GET") == false && method.equalsIgnoreCase("POST") == false)) { - method = "POST"; - } else { - method = method.toUpperCase(); + public static void clearCookies() { + if (cookieStore == null) { + // If cookie store has not been created yet, force its creation + getHttpClient(); } + cookieStore.clear(); + } - String cookiesDone = CookieJar.getCookiesAsString(prefs); - - URLConnection uc = null; - HttpURLConnection connection = null; - Integer timeout = 30000; - StringBuffer buffer = null; - - for (int i = 0; i < 5; i++) { - if (i > 0) { - Log.w(cgSettings.tag, "Failed to download data, retrying. Attempt #" + (i + 1)); + public 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(cgSettings.tag, "postRequest", e); + return null; + } + } - buffer = new StringBuffer(); - timeout = 30000 + (i * 10000); - - try { - if (method.equals("GET")) { - // GET - u = new URI(uri.getScheme(), uri.getAuthority(), uri.getPath(), params, null).toURL(); - uc = u.openConnection(); - - uc.setRequestProperty("Host", uri.getHost()); - uc.setRequestProperty("Cookie", cookiesDone); - if (xContentType) { - uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); - } - - if (settings.asBrowser == 1) { - uc.setRequestProperty("Accept", "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"); - // uc.setRequestProperty("Accept-Encoding", "gzip"); // not supported via cellular network - uc.setRequestProperty("Accept-Charset", "utf-8, iso-8859-1, utf-16, *;q=0.7"); - uc.setRequestProperty("Accept-Language", "en-US"); - uc.setRequestProperty("User-Agent", idBrowser); - uc.setRequestProperty("Connection", "keep-alive"); - uc.setRequestProperty("Keep-Alive", "300"); - } - - connection = (HttpURLConnection) uc; - connection.setReadTimeout(timeout); - connection.setRequestMethod(method); - HttpURLConnection.setFollowRedirects(false); - connection.setDoInput(true); - connection.setDoOutput(false); - } else { - // POST - u = uri.toURL(); - uc = u.openConnection(); - - uc.setRequestProperty("Host", uri.getHost()); - uc.setRequestProperty("Cookie", cookiesDone); - if (xContentType) { - uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); - } - - if (settings.asBrowser == 1) { - uc.setRequestProperty("Accept", "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"); - // uc.setRequestProperty("Accept-Encoding", "gzip"); // not supported via cellular network - uc.setRequestProperty("Accept-Charset", "utf-8, iso-8859-1, utf-16, *;q=0.7"); - uc.setRequestProperty("Accept-Language", "en-US"); - uc.setRequestProperty("User-Agent", idBrowser); - uc.setRequestProperty("Connection", "keep-alive"); - uc.setRequestProperty("Keep-Alive", "300"); - } - - connection = (HttpURLConnection) uc; - connection.setReadTimeout(timeout); - connection.setRequestMethod(method); - HttpURLConnection.setFollowRedirects(false); - connection.setDoInput(true); - connection.setDoOutput(true); - - final OutputStream out = connection.getOutputStream(); - final OutputStreamWriter wr = new OutputStreamWriter(out); - wr.write(params); - wr.flush(); - wr.close(); - } - - CookieJar.setCookies(prefs, uc); - - InputStream ins = getInputstreamFromConnection(connection); - final InputStreamReader inr = new InputStreamReader(ins); - final BufferedReader br = new BufferedReader(inr, 16 * 1024); - - readIntoBuffer(br, buffer); + public HttpResponse request(final String uri, final String params, final Boolean xContentType) { + final HttpRequestBase request = new HttpGet(Uri.parse(uri).buildUpon().encodedQuery(params).build().toString()); - httpCode = connection.getResponseCode(); - httpMessage = connection.getResponseMessage(); - httpLocation = uc.getHeaderField("Location"); + request.setHeader("X-Requested-With", "XMLHttpRequest"); - final String paramsLog = params.replaceAll(passMatch, "password=***"); - Log.i(cgSettings.tag + "|" + requestId, "[" + method + " " + (int) (params.length() / 1024) + "k | " + httpCode + " | " + (int) (buffer.length() / 1024) + "k] Downloaded " + uri + "?" + paramsLog); + if (xContentType) { + request.setHeader("Content-Type", "application/x-www-form-urlencoded"); + } - connection.disconnect(); - br.close(); - ins.close(); - inr.close(); - } catch (IOException e) { - Log.e(cgSettings.tag, "cgeoBase.request.IOException", e); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoBase.request", e); - } + return request(request); + } - if (buffer.length() > 0) { - break; - } + private HttpResponse request(final HttpRequestBase request) { + if (settings.asBrowser == 1) { + request.setHeader("Accept-Charset", "utf-8, iso-8859-1, utf-16, *;q=0.7"); + request.setHeader("Accept-Language", "en-US"); + request.setHeader("User-Agent", idBrowser); } + return doRequest(request); + } - cgResponse response = new cgResponse(); + static public HttpResponse doRequest(final HttpRequestBase request) { + Log.d(cgSettings.tag, "request: " + request.getMethod() + " " + hidePassword(request.getURI().toString())); - try { - if (httpCode == 302 && httpLocation != null) { - final URI newLocation = uri.resolve(httpLocation); - response = request(newLocation, - "GET", new HashMap<String, String>(), requestId, false, false, false); - } else { - if (StringUtils.isNotEmpty(buffer)) { - replaceWhitespace(buffer); - String data = buffer.toString(); - buffer = null; - - if (data != null) { - response.setData(data); - } else { - response.setData(""); - } - response.setStatusCode(httpCode); - response.setStatusMessage(httpMessage); - response.setUrl(u.toString()); + final HttpClient client = getHttpClient(); + for (int i = 0; i <= NB_DOWNLOAD_RETRIES; i++) { + try { + return client.execute(request); + } catch (IOException e) { + if (i == NB_DOWNLOAD_RETRIES) { + Log.e(cgSettings.tag, "cgeoBase.request", e); + } else { + Log.e(cgSettings.tag, "cgeoBase.request: failed to download data (" + e.getMessage() + "), retrying"); } } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoBase.page", e); } - return response; + return null; } /** @@ -3772,272 +3681,26 @@ public class cgBase { * @param buffer * The data */ - public static void replaceWhitespace(final StringBuffer buffer) { - final int length = buffer.length(); - final char[] chars = new char[length]; - buffer.getChars(0, length, chars, 0); - int resultSize = 0; - boolean lastWasWhitespace = false; - for (char c : chars) { - if (c == ' ' || c == '\n' || c == '\r' || c == '\t') { - if (!lastWasWhitespace) { - chars[resultSize++] = ' '; - } - lastWasWhitespace = true; - } else { - chars[resultSize++] = c; - lastWasWhitespace = false; - } - } - buffer.setLength(0); - buffer.append(chars); + public static String replaceWhitespace(final String data) { + return StringUtils.join(StringUtils.split(data, " \n\r\t"), ' '); } - public String requestJSONgc(final URI uri, String params) { - int httpCode = -1; - String httpLocation = null; - - final String cookiesDone = CookieJar.getCookiesAsString(prefs); - - URLConnection uc = null; - HttpURLConnection connection = null; - Integer timeout = 30000; - final StringBuffer buffer = new StringBuffer(); - - for (int i = 0; i < 3; i++) { - if (i > 0) { - Log.w(cgSettings.tag, "Failed to download data, retrying. Attempt #" + (i + 1)); - } - - buffer.delete(0, buffer.length()); - timeout = 30000 + (i * 15000); - - try { - // POST - final URL u = uri.toURL(); - uc = u.openConnection(); - - uc.setRequestProperty("Host", uri.getHost()); - uc.setRequestProperty("Cookie", cookiesDone); - uc.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); - uc.setRequestProperty("X-Requested-With", "XMLHttpRequest"); - uc.setRequestProperty("Accept", "application/json, text/javascript, */*; q=0.01"); - uc.setRequestProperty("Referer", uri.getHost() + "/" + uri.getPath()); - - if (settings.asBrowser == 1) { - uc.setRequestProperty("Accept-Charset", "utf-8, iso-8859-1, utf-16, *;q=0.7"); - uc.setRequestProperty("Accept-Language", "en-US"); - uc.setRequestProperty("User-Agent", idBrowser); - uc.setRequestProperty("Connection", "keep-alive"); - uc.setRequestProperty("Keep-Alive", "300"); - } - - connection = (HttpURLConnection) uc; - connection.setReadTimeout(timeout); - connection.setRequestMethod("POST"); - HttpURLConnection.setFollowRedirects(false); // TODO: Fix these (FilCab) - connection.setDoInput(true); - connection.setDoOutput(true); - - final OutputStream out = connection.getOutputStream(); - final OutputStreamWriter wr = new OutputStreamWriter(out); - wr.write(params); - wr.flush(); - wr.close(); - - CookieJar.setCookies(prefs, uc); - - InputStream ins = getInputstreamFromConnection(connection); - final InputStreamReader inr = new InputStreamReader(ins); - final BufferedReader br = new BufferedReader(inr); - - readIntoBuffer(br, buffer); - - httpCode = connection.getResponseCode(); - httpLocation = uc.getHeaderField("Location"); - - final String paramsLog = params.replaceAll(passMatch, "password=***"); - Log.i(cgSettings.tag + " | JSON", "[POST " + (int) (params.length() / 1024) + "k | " + httpCode + " | " + (int) (buffer.length() / 1024) + "k] Downloaded " + uri.toString() + "?" + paramsLog); - - connection.disconnect(); - br.close(); - ins.close(); - inr.close(); - } catch (IOException e) { - Log.e(cgSettings.tag, "cgeoBase.requestJSONgc.IOException: " + e.toString()); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoBase.requestJSONgc: " + e.toString()); - } - - if (buffer != null && buffer.length() > 0) { - break; - } - } - - String page = null; - if (httpCode == 302 && httpLocation != null) { - final URI newLocation = uri.resolve(httpLocation); - page = requestJSONgc(newLocation, params); - } else { - replaceWhitespace(buffer); - page = buffer.toString(); - } - - if (page != null) { - return page; - } else { - return ""; - } - } - - private static InputStream getInputstreamFromConnection(HttpURLConnection connection) throws IOException { - final String encoding = connection.getContentEncoding(); - InputStream ins; - - if (encoding != null && encoding.equalsIgnoreCase("gzip")) { - ins = new GZIPInputStream(connection.getInputStream()); - } else if (encoding != null && encoding.equalsIgnoreCase("deflate")) { - ins = new InflaterInputStream(connection.getInputStream(), new Inflater(true)); - } else { - ins = connection.getInputStream(); - } - return ins; - } - - public static String requestJSON(String host, String path, String params) { - return requestJSON("http://", host, path, "GET", params); - } - - public static String requestJSON(String scheme, String host, String path, String method, String params) { - int httpCode = -1; - //String httpLocation = null; - - if (method == null) { - method = "GET"; - } else { - method = method.toUpperCase(); - } - - boolean methodPost = false; - if (method.equalsIgnoreCase("POST")) { - methodPost = true; - } - - URLConnection uc = null; - HttpURLConnection connection = null; - Integer timeout = 30000; - final StringBuffer buffer = new StringBuffer(); - - for (int i = 0; i < 3; i++) { - if (i > 0) { - Log.w(cgSettings.tag, "Failed to download data, retrying. Attempt #" + (i + 1)); - } - - buffer.delete(0, buffer.length()); - timeout = 30000 + (i * 15000); + public static JSONObject requestJSON(final String uri) { + final HttpGet request = new HttpGet(uri); + 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 { - try { - URL u = null; - if (methodPost) { - u = new URL(scheme + host + path); - } else { - u = new URL(scheme + host + path + "?" + params); - } - - if (u.getProtocol().toLowerCase().equals("https")) { - trustAllHosts(); - HttpsURLConnection https = (HttpsURLConnection) u.openConnection(); - https.setHostnameVerifier(doNotVerify); - uc = https; - } else { - uc = (HttpURLConnection) u.openConnection(); - } - - uc.setRequestProperty("Host", host); - uc.setRequestProperty("Accept", "application/json, text/javascript, */*; q=0.01"); - if (methodPost) { - uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); - uc.setRequestProperty("Content-Length", Integer.toString(params.length())); - uc.setRequestProperty("X-HTTP-Method-Override", "GET"); - } else { - uc.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); - } - uc.setRequestProperty("X-Requested-With", "XMLHttpRequest"); - - connection = (HttpURLConnection) uc; - connection.setReadTimeout(timeout); - connection.setRequestMethod(method); - HttpURLConnection.setFollowRedirects(false); // TODO: Fix these (FilCab) - connection.setDoInput(true); - if (methodPost) { - connection.setDoOutput(true); - - final OutputStream out = connection.getOutputStream(); - final OutputStreamWriter wr = new OutputStreamWriter(out); - wr.write(params); - wr.flush(); - wr.close(); - } else { - connection.setDoOutput(false); - } - - InputStream ins = getInputstreamFromConnection(connection); - final InputStreamReader inr = new InputStreamReader(ins); - final BufferedReader br = new BufferedReader(inr, 1024); - - readIntoBuffer(br, buffer); - - httpCode = connection.getResponseCode(); - - final String paramsLog = params.replaceAll(passMatch, "password=***"); - Log.i(cgSettings.tag + " | JSON", "[POST " + (int) (params.length() / 1024) + "k | " + httpCode + " | " + (int) (buffer.length() / 1024) + "k] Downloaded " + "http://" + host + path + "?" + paramsLog); - - connection.disconnect(); - br.close(); - ins.close(); - inr.close(); - } catch (IOException e) { - httpCode = connection.getResponseCode(); - - Log.e(cgSettings.tag, "cgeoBase.requestJSON.IOException: " + httpCode + ": " + connection.getResponseMessage() + " ~ " + e.toString()); - } - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoBase.requestJSON: " + e.toString()); - } - - if (StringUtils.isNotBlank(buffer)) { - break; - } - - if (httpCode == 403) { - // we're not allowed to download content, so let's move - break; + return new JSONObject(getResponseData(response)); + } catch (JSONException e) { + Log.e(cgSettings.tag, "cgeoBase.requestJSON", e); } } - String page = null; - //This is reported as beeing deadCode (httpLocation is always null) - //2011-08-09 - 302 is redirect so something should probably be done - /* - * if (httpCode == 302 && httpLocation != null) { - * final Uri newLocation = Uri.parse(httpLocation); - * if (newLocation.isRelative()) { - * page = requestJSONgc(host, path, params); - * } else { - * page = requestJSONgc(newLocation.getHost(), newLocation.getPath(), params); - * } - * } else { - */ - replaceWhitespace(buffer); - page = buffer.toString(); - //} - - if (page != null) { - return page; - } else { - return ""; - } + return null; } public static boolean deleteDirectory(File path) { @@ -4165,47 +3828,26 @@ public class cgBase { } } - public static boolean isCacheInViewPort(int centerLat, int centerLon, int spanLat, int spanLon, final Geopoint cacheCoords) { - if (cacheCoords == null) { - return false; - } - - // viewport is defined by center, span and some (10%) reserve on every side - int minLat = centerLat - (spanLat / 2) - (spanLat / 10); - int maxLat = centerLat + (spanLat / 2) + (spanLat / 10); - int minLon = centerLon - (spanLon / 2) - (spanLon / 10); - int maxLon = centerLon + (spanLon / 2) + (spanLon / 10); - final int cLat = cacheCoords.getLatitudeE6(); - final int cLon = cacheCoords.getLongitudeE6(); - int mid = 0; - - if (maxLat < minLat) { - mid = minLat; - minLat = maxLat; - maxLat = mid; - } - - if (maxLon < minLon) { - mid = minLon; - minLon = maxLon; - maxLon = mid; - } - - boolean latOk = false; - boolean lonOk = false; - - if (cLat >= minLat && cLat <= maxLat) { - latOk = true; - } - if (cLon >= minLon && cLon <= maxLon) { - lonOk = true; - } - - if (latOk && lonOk) { - return true; - } else { - return false; - } + // viewport is defined by center, span and some (10%) reserve on every side + /** + * Check if coordinates are located in a viewport (defined by its center and span + * in each direction). The viewport also includes a 10% extension on each side. + * + * @param centerLat + * the viewport center latitude + * @param centerLon + * the viewport center longitude + * @param spanLat + * the latitude span + * @param spanLon + * the longitude span + * @param coords + * the coordinates to check + * @return true if the coordinates are in the viewport + */ + public static boolean isCacheInViewPort(int centerLat, int centerLon, int spanLat, int spanLon, final Geopoint coords) { + return Math.abs(coords.getLatitudeE6() - centerLat) <= Math.abs(spanLat) * 0.6 && + Math.abs(coords.getLongitudeE6() - centerLon) <= Math.abs(spanLon) * 0.6; } private static char[] base64map1 = new char[64]; @@ -4495,8 +4137,8 @@ public class cgBase { } public String getMapUserToken(Handler noTokenHandler) { - final cgResponse response = request(URI_GC_MAP_DEFAULT, "GET", "", 0, false); - final String data = response.getData(); + final HttpResponse response = request("http://www.geocaching.com/map/default.aspx", "", false); + final String data = getResponseData(response); String usertoken = null; if (StringUtils.isNotBlank(data)) { @@ -4519,19 +4161,16 @@ public class cgBase { public static Double getElevation(final Geopoint coords) { try { - final String host = "maps.googleapis.com"; - final String path = "/maps/api/elevation/json"; - final String params = "sensor=false&locations=" + + final String uri = "http://maps.googleapis.com/maps/api/elevation/json?sensor=false&locations=" + String.format((Locale) null, "%.6f", coords.getLatitude()) + "," + String.format((Locale) null, "%.6f", coords.getLongitude()); - final String data = requestJSON(host, path, params); + final JSONObject response = requestJSON(uri); - if (StringUtils.isBlank(data)) { + if (response == null) { return null; } - JSONObject response = new JSONObject(data); String status = response.getString("status"); if (status == null || status.equalsIgnoreCase("OK") == false) { diff --git a/main/src/cgeo/geocaching/cgCache.java b/main/src/cgeo/geocaching/cgCache.java index f44585b..8bea2e3 100644 --- a/main/src/cgeo/geocaching/cgCache.java +++ b/main/src/cgeo/geocaching/cgCache.java @@ -76,7 +76,7 @@ public class cgCache implements ICache { public boolean onWatchlist = false; public List<String> attributes = null; public List<cgWaypoint> waypoints = null; - public List<cgImage> spoilers = null; + public ArrayList<cgImage> spoilers = null; public List<cgLog> logs = null; public List<cgTrackable> inventory = null; public Map<Integer, Integer> logCounts = new HashMap<Integer, Integer>(); diff --git a/main/src/cgeo/geocaching/cgData.java b/main/src/cgeo/geocaching/cgData.java index 2d7a653..e4e6311 100644 --- a/main/src/cgeo/geocaching/cgData.java +++ b/main/src/cgeo/geocaching/cgData.java @@ -2884,7 +2884,7 @@ public class cgData { if (size > 0) { Log.d(cgSettings.tag, "Database clean: removing " + size + " geocaches"); - String geocodeList = cgBase.implode(", ", geocodes.toArray()); + String geocodeList = StringUtils.join(geocodes.toArray(), ", "); databaseRW.execSQL("delete from " + dbTableCaches + " where geocode in (" + geocodeList + ")"); databaseRW.execSQL("delete from " + dbTableAttributes + " where geocode in (" + geocodeList + ")"); databaseRW.execSQL("delete from " + dbTableSpoilers + " where geocode in (" + geocodeList + ")"); @@ -2945,7 +2945,7 @@ public class cgData { } if (CollectionUtils.isNotEmpty(geocodes)) { - String geocodeList = cgBase.implode(", ", geocodes.toArray()); + String geocodeList = StringUtils.join(geocodes.toArray(), ", "); databaseRW.execSQL("delete from " + dbTableCaches + " where geocode in (" + geocodeList + ")"); databaseRW.execSQL("delete from " + dbTableAttributes + " where geocode in (" + geocodeList + ")"); databaseRW.execSQL("delete from " + dbTableSpoilers + " where geocode in (" + geocodeList + ")"); diff --git a/main/src/cgeo/geocaching/cgGeo.java b/main/src/cgeo/geocaching/cgGeo.java index c458108..c5cc7a0 100644 --- a/main/src/cgeo/geocaching/cgGeo.java +++ b/main/src/cgeo/geocaching/cgGeo.java @@ -15,11 +15,8 @@ import android.location.LocationManager; import android.os.Bundle; import android.util.Log; -import java.net.URI; -import java.util.HashMap; import java.util.Iterator; import java.util.Locale; -import java.util.Map; public class cgGeo { @@ -52,8 +49,6 @@ public class cgGeo { public Integer satellitesFixed = null; public double distanceNow = 0d; - private static final URI URI_GO4CACHE = cgBase.buildURI(false, "api.go4cache.com", "/"); - public cgGeo(Context contextIn, cgeoapplication appIn, cgUpdateLoc geoUpdateIn, cgBase baseIn, cgSettings settingsIn, int timeIn, int distanceIn) { context = contextIn; app = appIn; @@ -393,7 +388,7 @@ public class cgGeo { final String username = settings.getUsername(); if (username != null) { - final Map<String, String> params = new HashMap<String, String>(); + final Parameters params = new Parameters(); final String latStr = String.format((Locale) null, "%.6f", coordsNow.getLatitude()); final String lonStr = String.format((Locale) null, "%.6f", coordsNow.getLongitude()); params.put("u", username); @@ -404,7 +399,7 @@ public class cgGeo { if (base.version != null) { params.put("v", base.version); } - final String res = base.request(URI_GO4CACHE, "POST", params, false, false, false).getData(); + final String res = cgBase.getResponseData(base.postRequest("http://api.go4cache.com/", params)); if (StringUtils.isNotBlank(res)) { lastGo4cacheCoords = coordsNow; diff --git a/main/src/cgeo/geocaching/cgHtmlImg.java b/main/src/cgeo/geocaching/cgHtmlImg.java index 1196598..880d5b4 100644 --- a/main/src/cgeo/geocaching/cgHtmlImg.java +++ b/main/src/cgeo/geocaching/cgHtmlImg.java @@ -7,10 +7,8 @@ import cgeo.geocaching.utils.CryptUtils; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.entity.BufferedHttpEntity; -import org.apache.http.impl.client.DefaultHttpClient; import android.app.Activity; import android.content.Context; @@ -32,19 +30,16 @@ import java.util.Date; public class cgHtmlImg implements Html.ImageGetter { - private Activity activity = null; - private String geocode = null; - private boolean placement = true; - private int reason = 0; - private boolean onlySave = false; - private boolean save = true; - private BitmapFactory.Options bfOptions = new BitmapFactory.Options(); - private Display display = null; - private int maxWidth = 0; - private int maxHeight = 0; - private double ratio = 1.0d; - private int width = 0; - private int height = 0; + final private Activity activity; + final private String geocode; + final private boolean placement; + final private int reason; + final private boolean onlySave; + final private boolean save; + final private BitmapFactory.Options bfOptions; + final private Display display; + final private int maxWidth; + final private int maxHeight; public cgHtmlImg(Activity activityIn, String geocodeIn, boolean placementIn, int reasonIn, boolean onlySaveIn) { this(activityIn, geocodeIn, placementIn, reasonIn, onlySaveIn, true); @@ -58,6 +53,7 @@ public class cgHtmlImg implements Html.ImageGetter { onlySave = onlySaveIn; save = saveIn; + bfOptions = new BitmapFactory.Options(); bfOptions.inTempStorage = new byte[16 * 1024]; display = ((WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); @@ -166,7 +162,6 @@ public class cgHtmlImg implements Html.ImageGetter { // download image and save it to the cache if ((imagePre == null && reason == 0) || onlySave) { Uri uri = null; - HttpClient client = null; HttpGet getMethod = null; HttpResponse httpResponse = null; HttpEntity entity = null; @@ -191,9 +186,8 @@ public class cgHtmlImg implements Html.ImageGetter { } try { - client = new DefaultHttpClient(); getMethod = new HttpGet(url); - httpResponse = client.execute(getMethod); + httpResponse = cgBase.doRequest(getMethod); entity = httpResponse.getEntity(); bufferedEntity = new BufferedHttpEntity(entity); @@ -271,7 +265,11 @@ public class cgHtmlImg implements Html.ImageGetter { final int imgWidth = imagePre.getWidth(); final int imgHeight = imagePre.getHeight(); + int width; + int height; + if (imgWidth > maxWidth || imgHeight > maxHeight) { + double ratio; if ((maxWidth / imgWidth) > (maxHeight / imgHeight)) { ratio = (double) maxHeight / (double) imgHeight; } else { diff --git a/main/src/cgeo/geocaching/cgImage.java b/main/src/cgeo/geocaching/cgImage.java index b5874d6..3dba437 100644 --- a/main/src/cgeo/geocaching/cgImage.java +++ b/main/src/cgeo/geocaching/cgImage.java @@ -1,7 +1,42 @@ package cgeo.geocaching; -public class cgImage { +import android.os.Parcel; +import android.os.Parcelable; + +public class cgImage implements Parcelable { public String url = ""; public String title = ""; public String description = ""; + + public cgImage() { + } + + public cgImage(final Parcel in) { + url = in.readString(); + title = in.readString(); + description = in.readString(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(url); + dest.writeString(title); + dest.writeString(description); + } + + public static final Parcelable.Creator<cgImage> CREATOR = new Parcelable.Creator<cgImage>() { + public cgImage createFromParcel(Parcel in) { + return new cgImage(in); + } + + @Override + public cgImage[] newArray(int size) { + return new cgImage[size]; + } + }; } diff --git a/main/src/cgeo/geocaching/cgOAuth.java b/main/src/cgeo/geocaching/cgOAuth.java index b5fcc98..c06e011 100644 --- a/main/src/cgeo/geocaching/cgOAuth.java +++ b/main/src/cgeo/geocaching/cgOAuth.java @@ -2,6 +2,8 @@ package cgeo.geocaching; import cgeo.geocaching.utils.CryptUtils; +import org.apache.commons.lang3.StringUtils; + import java.util.ArrayList; import java.util.Arrays; import java.util.Date; @@ -48,12 +50,12 @@ public class cgOAuth { keysPacked = cgSettings.keyConsumerSecret + "&" + tokenSecret; // both even if empty some of them! if (https) - requestPacked = method + "&" + cgBase.urlencode_rfc3986("https://" + host + path) + "&" + cgBase.urlencode_rfc3986(cgBase.implode("&", paramsEncoded.toArray())); + requestPacked = method + "&" + cgBase.urlencode_rfc3986("https://" + host + path) + "&" + cgBase.urlencode_rfc3986(StringUtils.join(paramsEncoded.toArray(), '&')); else - requestPacked = method + "&" + cgBase.urlencode_rfc3986("http://" + host + path) + "&" + cgBase.urlencode_rfc3986(cgBase.implode("&", paramsEncoded.toArray())); + requestPacked = method + "&" + cgBase.urlencode_rfc3986("http://" + host + path) + "&" + cgBase.urlencode_rfc3986(StringUtils.join(paramsEncoded.toArray(), '&')); paramsEncoded.add("oauth_signature=" + cgBase.urlencode_rfc3986(cgBase.base64Encode(CryptUtils.hashHmac(requestPacked, keysPacked)))); - paramsDone = cgBase.implode("&", paramsEncoded.toArray()); + paramsDone = StringUtils.join(paramsEncoded.toArray(), '&'); return paramsDone; } diff --git a/main/src/cgeo/geocaching/cgResponse.java b/main/src/cgeo/geocaching/cgResponse.java deleted file mode 100644 index 3ac7770..0000000 --- a/main/src/cgeo/geocaching/cgResponse.java +++ /dev/null @@ -1,40 +0,0 @@ -package cgeo.geocaching; - -public class cgResponse { - private String url; - private int statusCode; - private String statusMessage; - private String data; - - public void setUrl(String url) { - this.url = url; - } - - public String getUrl() { - return url; - } - - public void setStatusCode(int code) { - statusCode = code; - } - - public int getStatusCode() { - return statusCode; - } - - public void setStatusMessage(String message) { - statusMessage = message; - } - - public String getStatusMessage() { - return statusMessage; - } - - public void setData(String data) { - this.data = data; - } - - public String getData() { - return data; - } -} diff --git a/main/src/cgeo/geocaching/cgeocaches.java b/main/src/cgeo/geocaching/cgeocaches.java index 3e12b2d..726a660 100644 --- a/main/src/cgeo/geocaching/cgeocaches.java +++ b/main/src/cgeo/geocaching/cgeocaches.java @@ -27,6 +27,7 @@ import cgeo.geocaching.sorting.VoteComparator; import cgeo.geocaching.utils.CollectionUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpResponse; import android.app.AlertDialog; import android.app.ProgressDialog; @@ -61,7 +62,6 @@ import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; -import java.net.URI; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; @@ -141,8 +141,6 @@ public class cgeocaches extends AbstractListActivity { private static final int CONTEXT_MENU_MOVE_TO_LIST = 1000; private static final int MENU_MOVE_SELECTED_OR_ALL_TO_LIST = 1200; - private static final URI URI_SEND2CGEO_READ = cgBase.buildURI(false, "send2.cgeo.org", "/read.html"); - private String action = null; private String type = null; private Geopoint coords = null; @@ -222,14 +220,14 @@ public class cgeocaches extends AbstractListActivity { dialog.setNegativeButton(res.getString(R.string.license_dismiss), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { - CookieJar.deleteCookies(prefs); + cgBase.clearCookies(); dialog.cancel(); } }); dialog.setPositiveButton(res.getString(R.string.license_show), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { - CookieJar.deleteCookies(prefs); + cgBase.clearCookies(); startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/software/agreement.aspx?ID=0"))); } }); @@ -2086,12 +2084,13 @@ public class cgeocaches extends AbstractListActivity { if (deviceCode == null) { deviceCode = ""; } - cgResponse responseFromWeb = base.request(URI_SEND2CGEO_READ, "GET", "code=" + cgBase.urlencode_rfc3986(deviceCode), 0, true); + HttpResponse responseFromWeb = base.request("http://send2.cgeo.org/read.html", "code=" + cgBase.urlencode_rfc3986(deviceCode), true); - if (responseFromWeb.getStatusCode() == 200) { - if (responseFromWeb.getData().length() > 2) { + if (responseFromWeb.getStatusLine().getStatusCode() == 200) { + final String response = cgBase.getResponseData(responseFromWeb); + if (response.length() > 2) { - String GCcode = responseFromWeb.getData(); + String GCcode = response; delay = 1; Message mes = new Message(); @@ -2108,7 +2107,7 @@ public class cgeocaches extends AbstractListActivity { mes1.obj = GCcode; handler.sendMessage(mes1); yield(); - } else if ("RG".equals(responseFromWeb.getData())) { + } else if ("RG".equals(cgBase.getResponseData(responseFromWeb))) { //Server returned RG (registration) and this device no longer registered. settings.setWebNameCode(null, null); needToStop = true; @@ -2120,7 +2119,7 @@ public class cgeocaches extends AbstractListActivity { yield(); } } - if (responseFromWeb.getStatusCode() != 200) { + if (responseFromWeb.getStatusLine().getStatusCode() != 200) { needToStop = true; handler.sendEmptyMessage(-2); return; diff --git a/main/src/cgeo/geocaching/cgeodetail.java b/main/src/cgeo/geocaching/cgeodetail.java index 0c5a252..676d719 100644 --- a/main/src/cgeo/geocaching/cgeodetail.java +++ b/main/src/cgeo/geocaching/cgeodetail.java @@ -1231,27 +1231,30 @@ public class cgeodetail extends AbstractActivity { LinearLayout logLayout = (LinearLayout) rowView.findViewById(R.id.log_layout); if ((log.logImages != null) && (!log.logImages.isEmpty())) { + + final ArrayList<cgImage> logImages = new ArrayList<cgImage>(log.logImages); + + final View.OnClickListener listener = new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent logImgIntent = new Intent(cgeodetail.this, cgeoimages.class); + logImgIntent.putExtra("geocode", geocode.toUpperCase()); + logImgIntent.putExtra("type", cgeoimages.LOG_IMAGES); + logImgIntent.putParcelableArrayListExtra("images", logImages); + startActivity(logImgIntent); + } + }; + for (int i_img_cnt = 0; i_img_cnt < log.logImages.size(); i_img_cnt++) { String img_title = log.logImages.get(i_img_cnt).title; if (img_title.equals("")) { img_title = res.getString(R.string.cache_log_image_default_title); } final String title = img_title; - final String url = log.logImages.get(i_img_cnt).url; LinearLayout log_imgView = (LinearLayout) inflater.inflate(R.layout.log_img, null); TextView log_img_title = (TextView) log_imgView.findViewById(R.id.title); log_img_title.setText(title); - log_img_title.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent logImgIntent = new Intent(cgeodetail.this, cgeoimages.class); - logImgIntent.putExtra("geocode", geocode.toUpperCase()); - logImgIntent.putExtra("type", cgeoimages.LOG_IMAGE); - logImgIntent.putExtra("title", title); - logImgIntent.putExtra("url", url); - startActivity(logImgIntent); - } - }); + log_img_title.setOnClickListener(listener); logLayout.addView(log_imgView); } } @@ -1618,7 +1621,8 @@ public class cgeodetail extends AbstractActivity { Intent spoilersIntent = new Intent(this, cgeoimages.class); spoilersIntent.putExtra("geocode", geocode.toUpperCase()); - spoilersIntent.putExtra("type", cgeoimages.SPOILER_IMAGE); + spoilersIntent.putExtra("type", cgeoimages.SPOILER_IMAGES); + spoilersIntent.putParcelableArrayListExtra("images", cache.spoilers); startActivity(spoilersIntent); } diff --git a/main/src/cgeo/geocaching/cgeoimages.java b/main/src/cgeo/geocaching/cgeoimages.java index c1a6bee..c177bf2 100644 --- a/main/src/cgeo/geocaching/cgeoimages.java +++ b/main/src/cgeo/geocaching/cgeoimages.java @@ -6,14 +6,14 @@ import org.apache.commons.lang3.StringUtils; import android.app.ProgressDialog; import android.content.Intent; +import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.net.Uri; +import android.os.AsyncTask; import android.os.Bundle; import android.os.Environment; -import android.os.Handler; -import android.os.Message; import android.text.Html; import android.util.Log; import android.view.LayoutInflater; @@ -26,240 +26,79 @@ import android.widget.TextView; import java.io.File; import java.io.FileOutputStream; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.List; public class cgeoimages extends AbstractActivity { - public static final int LOG_IMAGE = 1; - public static final int SPOILER_IMAGE = 2; + private static final int UNKNOWN_TYPE = 0; + public static final int LOG_IMAGES = 1; + public static final int SPOILER_IMAGES = 2; - private int img_type; - private List<cgImage> images = new ArrayList<cgImage>(); private String geocode = null; - private String title = null; - private String url = null; private LayoutInflater inflater = null; private ProgressDialog progressDialog = null; - private ProgressDialog waitDialog = null; private LinearLayout imagesView = null; - private int offline = 0; - private boolean save = true; private int count = 0; private int countDone = 0; - private String load_process_string; - private Handler loadImagesHandler = new Handler() { + static private Collection<Bitmap> bitmaps = Collections.synchronizedCollection(new ArrayList<Bitmap>()); - @Override - public void handleMessage(Message msg) { - try { - if (images.isEmpty()) { - if (waitDialog != null) { - waitDialog.dismiss(); - } - switch (img_type) { - case LOG_IMAGE: - showToast(res.getString(R.string.warn_load_log_image)); - break; - case SPOILER_IMAGE: - showToast(res.getString(R.string.warn_load_spoiler_image)); - break; - } - - finish(); - return; - } else { - if (waitDialog != null) { - waitDialog.dismiss(); - } - - if (app.isOffline(geocode, null)) { - offline = 1; - if ((img_type == LOG_IMAGE) && (settings.storelogimages == false)) { - offline = 0; - } - } else { - offline = 0; - } - - count = images.size(); - progressDialog = new ProgressDialog(cgeoimages.this); - progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); - progressDialog.setMessage(load_process_string); - progressDialog.setCancelable(true); - progressDialog.setMax(count); - progressDialog.show(); - - LinearLayout rowView = null; - for (final cgImage img : images) { - rowView = (LinearLayout) inflater.inflate(R.layout.cache_image_item, null); - - ((TextView) rowView.findViewById(R.id.title)).setText(Html.fromHtml(img.title)); - - if (StringUtils.isNotBlank(img.description)) { - final TextView descView = (TextView) rowView.findViewById(R.id.description); - descView.setText(Html.fromHtml(img.description), TextView.BufferType.SPANNABLE); - descView.setVisibility(View.VISIBLE); - } - - final Handler handler = new onLoadHandler(rowView, img); - - new Thread() { + private void loadImages(final List<cgImage> images, final int progressMessage, final boolean save, final boolean offline) { - @Override - public void run() { - BitmapDrawable image = null; - try { - cgHtmlImg imgGetter = new cgHtmlImg(cgeoimages.this, geocode, true, offline, false, save); + count = images.size(); + progressDialog = new ProgressDialog(cgeoimages.this); + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); + progressDialog.setMessage(res.getString(progressMessage)); + progressDialog.setCancelable(true); + progressDialog.setMax(count); + progressDialog.show(); - image = imgGetter.getDrawable(img.url); - Message message = handler.obtainMessage(0, image); - handler.sendMessage(message); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoimages.onCreate.onClick.run: " + e.toString()); - } + LinearLayout rowView = null; + for (final cgImage img : images) { + rowView = (LinearLayout) inflater.inflate(R.layout.cache_image_item, null); - } - }.start(); + ((TextView) rowView.findViewById(R.id.title)).setText(Html.fromHtml(img.title)); - imagesView.addView(rowView); - } - } - } catch (Exception e) { - if (waitDialog != null) { - waitDialog.dismiss(); - } - Log.e(cgSettings.tag, "cgeoimages.loadImagesHandler: " + e.toString()); + if (StringUtils.isNotBlank(img.description)) { + final TextView descView = (TextView) rowView.findViewById(R.id.description); + descView.setText(Html.fromHtml(img.description), TextView.BufferType.SPANNABLE); + descView.setVisibility(View.VISIBLE); } - } - }; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // init - setTheme(); - setContentView(R.layout.spoilers); - - // get parameters - Bundle extras = getIntent().getExtras(); - // try to get data from extras - if (extras != null) { - geocode = extras.getString("geocode"); - img_type = extras.getInt("type", 0); - } - - // google analytics - if (img_type == SPOILER_IMAGE) - { - setTitle(res.getString(R.string.cache_spoiler_images_title)); - } else if (img_type == LOG_IMAGE) { - setTitle(res.getString(R.string.cache_log_images_title)); - } - - if (geocode == null) { - showToast("Sorry, c:geo forgot for what cache you want to load spoiler images."); - finish(); - return; - } - switch (img_type) { - case LOG_IMAGE: - title = extras.getString("title"); - url = extras.getString("url"); - if ((title == null) || (url == null)) { - showToast("Sorry, c:geo forgot which logimage you wanted to load."); - finish(); - return; - } - break; - } - - inflater = getLayoutInflater(); - if (imagesView == null) { - imagesView = (LinearLayout) findViewById(R.id.spoiler_list); - } - - switch (img_type) { - case SPOILER_IMAGE: - load_process_string = res.getString(R.string.cache_spoiler_images_loading); - save = true; - break; - case LOG_IMAGE: - load_process_string = res.getString(R.string.cache_log_images_loading); - if (settings.storelogimages) { - save = true; - } else { - save = false; - } - break; - default: - load_process_string = "Loading..."; - } - waitDialog = ProgressDialog.show(this, null, load_process_string, true); - waitDialog.setCancelable(true); - - switch (img_type) { - case LOG_IMAGE: - cgImage logimage = new cgImage(); - logimage.title = title; - logimage.url = url; - logimage.description = ""; - images.add(logimage); - try { - loadImagesHandler.sendMessage(new Message()); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoimages.loadImagesHandler.sendMessage: " + e.toString()); - } - break; - case SPOILER_IMAGE: - (new loadSpoilers()).start(); - break; - default: - showToast("Sorry, can't load unknown image type."); - finish(); + new AsyncImgLoader(rowView, img, save, offline).execute(); + imagesView.addView(rowView); } - - } - - @Override - public void onResume() { - super.onResume(); - - settings.load(); } - private class loadSpoilers extends Thread { + private class AsyncImgLoader extends AsyncTask<Void, Void, BitmapDrawable> { - @Override - public void run() { - try { - images = app.loadSpoilers(geocode); + final private LinearLayout view; + final private cgImage img; + final private boolean save; + final boolean offline; - loadImagesHandler.sendMessage(new Message()); - } catch (Exception e) { - Log.e(cgSettings.tag, "cgeoimages.loadSpoilers.run: " + e.toString()); - } + public AsyncImgLoader(final LinearLayout view, final cgImage img, final boolean save, final boolean offline) { + this.view = view; + this.img = img; + this.save = save; + this.offline = offline; } - } - - private class onLoadHandler extends Handler { - LinearLayout view = null; - - public onLoadHandler(LinearLayout view, cgImage image) { - this.view = view; + @Override + protected BitmapDrawable doInBackground(Void... params) { + final cgHtmlImg imgGetter = new cgHtmlImg(cgeoimages.this, geocode, true, offline ? 1 : 0, false, save); + return imgGetter.getDrawable(img.url); } @Override - public void handleMessage(Message message) { - final BitmapDrawable image = (BitmapDrawable) message.obj; + protected void onPostExecute(final BitmapDrawable image) { if (image != null) { - ImageView image_view = null; - image_view = (ImageView) inflater.inflate(R.layout.image_item, null); + bitmaps.add(image.getBitmap()); + final ImageView image_view = (ImageView) inflater.inflate(R.layout.image_item, null); - Rect bounds = image.getBounds(); + final Rect bounds = image.getBounds(); image_view.setImageResource(R.drawable.image_not_loaded); image_view.setClickable(true); @@ -293,11 +132,81 @@ public class cgeoimages extends AbstractActivity { view.addView(image_view); } - countDone++; - progressDialog.setProgress(countDone); - if (progressDialog.getProgress() >= count) { - progressDialog.dismiss(); + synchronized (cgeoimages.this) { + countDone++; + progressDialog.setProgress(countDone); + if (progressDialog.getProgress() >= count) { + progressDialog.dismiss(); + } } } } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // get parameters + Bundle extras = getIntent().getExtras(); + + // try to get data from extras + int img_type = UNKNOWN_TYPE; + if (extras != null) { + geocode = extras.getString("geocode"); + img_type = extras.getInt("type", 0); + } + + if (extras == null || geocode == null) { + showToast("Sorry, c:geo forgot for what cache you want to load spoiler images."); + finish(); + return; + } + + if (img_type != SPOILER_IMAGES && img_type != LOG_IMAGES) { + showToast("Sorry, can't load unknown image type."); + finish(); + return; + } + + // init + setTheme(); + setContentView(R.layout.spoilers); + setTitle(res.getString(img_type == SPOILER_IMAGES ? R.string.cache_spoiler_images_title : R.string.cache_log_images_title)); + + inflater = getLayoutInflater(); + if (imagesView == null) { + imagesView = (LinearLayout) findViewById(R.id.spoiler_list); + } + + final ArrayList<cgImage> images = extras.getParcelableArrayList("images"); + if (images == null || images.isEmpty()) { + showToast(res.getString(R.string.warn_load_images)); + finish(); + return; + } + + final int message = img_type == SPOILER_IMAGES ? R.string.cache_spoiler_images_loading : R.string.cache_log_images_loading; + final boolean offline = app.isOffline(geocode, null) && (img_type == SPOILER_IMAGES || settings.storelogimages); + final boolean save = img_type == SPOILER_IMAGES ? true : settings.storelogimages; + + loadImages(images, message, save, offline); + } + + @Override + public void onDestroy() { + // Reclaim native memory faster than the finalizers would + for (Bitmap b : bitmaps) { + b.recycle(); + } + bitmaps.clear(); + super.onDestroy(); + } + + @Override + public void onResume() { + super.onResume(); + + settings.load(); + } + } diff --git a/main/src/cgeo/geocaching/cgeoinit.java b/main/src/cgeo/geocaching/cgeoinit.java index 20d231c..43a9e7a 100644 --- a/main/src/cgeo/geocaching/cgeoinit.java +++ b/main/src/cgeo/geocaching/cgeoinit.java @@ -6,6 +6,7 @@ import cgeo.geocaching.activity.AbstractActivity; import cgeo.geocaching.compatibility.Compatibility; import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpResponse; import android.app.ProgressDialog; import android.content.Intent; @@ -31,14 +32,11 @@ import android.widget.Spinner; import android.widget.TextView; import java.io.File; -import java.net.URI; public class cgeoinit extends AbstractActivity { private final int SELECT_MAPFILE_REQUEST = 1; - private static final URI URI_SEND2CGEO_AUTH = cgBase.buildURI(false, "send2.cgeo.org", "/auth.html"); - private ProgressDialog loginDialog = null; private ProgressDialog webDialog = null; private Handler logInHandler = new Handler() { @@ -1030,7 +1028,7 @@ public class cgeoinit extends AbstractActivity { loginDialog.setCancelable(false); settings.setLogin(username, password); - CookieJar.deleteCookies(prefs); + cgBase.clearCookies(); (new Thread() { @@ -1072,12 +1070,12 @@ public class cgeoinit extends AbstractActivity { String params = "name=" + cgBase.urlencode_rfc3986(nam) + "&code=" + cgBase.urlencode_rfc3986(cod); - cgResponse response = base.request(URI_SEND2CGEO_AUTH, "GET", params, 0, true); + HttpResponse response = base.request("http://send2.cgeo.org/auth.html", params, true); - if (response.getStatusCode() == 200) + if (response.getStatusLine().getStatusCode() == 200) { //response was OK - String[] strings = response.getData().split(","); + String[] strings = cgBase.getResponseData(response).split(","); try { pin = Integer.parseInt(strings[1].trim()); } catch (Exception e) { diff --git a/main/src/cgeo/geocaching/cgeotouch.java b/main/src/cgeo/geocaching/cgeotouch.java index 5c62087..827a765 100644 --- a/main/src/cgeo/geocaching/cgeotouch.java +++ b/main/src/cgeo/geocaching/cgeotouch.java @@ -20,7 +20,6 @@ import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; -import java.net.URI; import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; @@ -28,8 +27,6 @@ import java.util.List; import java.util.Map; public class cgeotouch extends cgLogForm { - private static final URI URI_GC_TRACK_LOG = cgBase.buildURI(false, "www.geocaching.com", "/track/log.aspx"); - private cgTrackable trackable = null; private List<Integer> types = new ArrayList<Integer>(); private ProgressDialog waitDialog = null; @@ -389,7 +386,7 @@ public class cgeotouch extends cgLogForm { return; } - final String page = base.request(URI_GC_TRACK_LOG, "GET", params, false, false, false).getData(); + final String page = cgBase.getResponseData(base.request("http://www.geocaching.com/track/log.aspx", params, false, false, false)); viewstates = cgBase.getViewstates(page); diff --git a/main/src/cgeo/geocaching/cgeovisit.java b/main/src/cgeo/geocaching/cgeovisit.java index 9689e96..e8104ab 100644 --- a/main/src/cgeo/geocaching/cgeovisit.java +++ b/main/src/cgeo/geocaching/cgeovisit.java @@ -25,7 +25,6 @@ import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; -import java.net.URI; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; @@ -43,8 +42,6 @@ public class cgeovisit extends cgLogForm { private static final int MENU_SIGNATURE = 1; private static final int SUBMENU_VOTE = 2; - private static final URI URI_GC_SEEK_LOG = cgBase.buildURI(false, "www.geocaching.com", "/seek/log.aspx"); - private LayoutInflater inflater = null; private cgCache cache = null; private List<Integer> types = new ArrayList<Integer>(); @@ -223,7 +220,6 @@ public class cgeovisit extends cgLogForm { } } }; - private static final URI URI_GCVOTE_SETVOTE = cgBase.buildURI(false, "gcvote.com", "/setVote.php"); public cgeovisit() { super("c:geo-log"); @@ -385,7 +381,7 @@ public class cgeovisit extends cgLogForm { params.put("voteUser", String.format("%.1f", rating).replace(',', '.')); params.put("version", "cgeo"); - final String result = base.request(URI_GCVOTE_SETVOTE, "GET", params, false, false, false).getData(); + final String result = cgBase.getResponseData(base.request("http://gcvote.com/setVote.php", params, false, false, false)); return result.trim().equalsIgnoreCase("ok"); } @@ -717,7 +713,7 @@ public class cgeovisit extends cgLogForm { return; } - final String page = base.request(URI_GC_SEEK_LOG, "GET", params, false, false, false).getData(); + final String page = cgBase.getResponseData(base.request("http://www.geocaching.com/seek/log.aspx", params, false, false, false)); viewstates = cgBase.getViewstates(page); trackables = cgBase.parseTrackableLog(page); diff --git a/main/src/cgeo/geocaching/connector/GCConnector.java b/main/src/cgeo/geocaching/connector/GCConnector.java index 3aca3d7..27f3aae 100644 --- a/main/src/cgeo/geocaching/connector/GCConnector.java +++ b/main/src/cgeo/geocaching/connector/GCConnector.java @@ -11,7 +11,6 @@ import org.apache.commons.lang3.StringUtils; import android.util.Log; -import java.net.URI; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -20,8 +19,6 @@ import java.util.UUID; public class GCConnector extends AbstractConnector implements IConnector { - private static final URI URI_GC_SEEK_CACHE_DETAILS = cgBase.buildURI(false, "www.geocaching.com", "/seek/cache_details.aspx"); - @Override public boolean canHandle(String geocode) { return StringUtils.isNotBlank(geocode) && StringUtils.startsWithIgnoreCase(geocode, "GC"); @@ -77,7 +74,7 @@ public class GCConnector extends AbstractConnector implements IConnector { } params.put("decrypt", "y"); - String page = base.requestLogged(URI_GC_SEEK_CACHE_DETAILS, "GET", params, false, false, false); + String page = base.requestLogged("http://www.geocaching.com/seek/cache_details.aspx", params, false, false, false); if (StringUtils.isEmpty(page)) { if (app.isThere(geocode, guid, true, false)) { diff --git a/main/src/cgeo/geocaching/connector/opencaching/OkapiClient.java b/main/src/cgeo/geocaching/connector/opencaching/OkapiClient.java index e9dcded..fffbc20 100644 --- a/main/src/cgeo/geocaching/connector/opencaching/OkapiClient.java +++ b/main/src/cgeo/geocaching/connector/opencaching/OkapiClient.java @@ -59,9 +59,9 @@ final public class OkapiClient { public static cgCache getCache(final String geoCode) { final String params = "cache_code=" + geoCode + "&" + SERVICE_CACHE_FIELDS; - final String data = request(geoCode, SERVICE_CACHE, params, 1); + final JSONObject data = request(geoCode, SERVICE_CACHE, params, 1); - if (StringUtils.isBlank(data)) { + if (data == null) { return null; } @@ -73,10 +73,9 @@ final public class OkapiClient { return cache; } - private static cgCache parseCache(final String data) { + private static cgCache parseCache(final JSONObject response) { final cgCache cache = new cgCache(); try { - final JSONObject response = new JSONObject(data); cache.geocode = response.getString(CACHE_CODE); cache.name = response.getString(CACHE_NAME); // not used: names @@ -246,7 +245,7 @@ final public class OkapiClient { return "other"; } - private static String request(final String geoCode, final String service, final String params, final int level) { + private static JSONObject request(final String geoCode, final String service, final String params, final int level) { final IConnector connector = ConnectorFactory.getConnector(geoCode); if (connector == null) { return null; @@ -255,6 +254,7 @@ final public class OkapiClient { return null; } - return cgBase.requestJSON(connector.getHost(), service, params + ((ApiOpenCachingConnector) connector).getAuthentication(level)); + final String uri = "http://" + connector.getHost() + service + "?" + ((ApiOpenCachingConnector) connector).getAuthentication(level); + return cgBase.requestJSON(uri); } } diff --git a/main/src/cgeo/geocaching/maps/CGeoMap.java b/main/src/cgeo/geocaching/maps/CGeoMap.java index 4e0d99d..ed5586d 100644 --- a/main/src/cgeo/geocaching/maps/CGeoMap.java +++ b/main/src/cgeo/geocaching/maps/CGeoMap.java @@ -245,7 +245,7 @@ public class CGeoMap extends AbstractMap implements OnDragListener, ViewFactory app = (cgeoapplication) activity.getApplication(); app.setAction(null); settings = new cgSettings(activity, activity.getSharedPreferences(cgSettings.preferences, Context.MODE_PRIVATE)); - base = new cgBase(app, settings, activity.getSharedPreferences(cgSettings.preferences, Context.MODE_PRIVATE)); + base = new cgBase(app, settings); prefsEdit = activity.getSharedPreferences(cgSettings.preferences, Context.MODE_PRIVATE).edit(); MapFactory mapFactory = settings.getMapFactory(); |