aboutsummaryrefslogtreecommitdiffstats
path: root/main/src
diff options
context:
space:
mode:
authorBananeweizen <bananeweizen@gmx.de>2013-10-26 14:52:38 +0200
committerBananeweizen <bananeweizen@gmx.de>2013-10-26 14:52:38 +0200
commite054988257da663b6c998cc2c0da84cf264bc23b (patch)
tree97d9aba71e004ad590b9519d50e5c715c7f8d6b2 /main/src
parent88d07a7a59fa7e8ceb93d2b219fd8e2c593caecd (diff)
parentbd09f1887a8e6a8e9b919d4605c04155a3e73760 (diff)
downloadcgeo-e054988257da663b6c998cc2c0da84cf264bc23b.zip
cgeo-e054988257da663b6c998cc2c0da84cf264bc23b.tar.gz
cgeo-e054988257da663b6c998cc2c0da84cf264bc23b.tar.bz2
Merge remote-tracking branch 'mucek4/fix2830'
* fix HTML parsing * simplify activity API * disable the action for non premium members
Diffstat (limited to 'main/src')
-rw-r--r--main/src/cgeo/geocaching/CacheListActivity.java20
-rw-r--r--main/src/cgeo/geocaching/Intents.java1
-rw-r--r--main/src/cgeo/geocaching/MainActivity.java21
-rw-r--r--main/src/cgeo/geocaching/PocketQueryList.java125
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCConstants.java1
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCParser.java50
-rw-r--r--main/src/cgeo/geocaching/enumerations/CacheListType.java1
-rw-r--r--main/src/cgeo/geocaching/loaders/AbstractSearchLoader.java1
-rw-r--r--main/src/cgeo/geocaching/loaders/PocketGeocacheListLoader.java28
9 files changed, 248 insertions, 0 deletions
diff --git a/main/src/cgeo/geocaching/CacheListActivity.java b/main/src/cgeo/geocaching/CacheListActivity.java
index 33535ad..59f7297 100644
--- a/main/src/cgeo/geocaching/CacheListActivity.java
+++ b/main/src/cgeo/geocaching/CacheListActivity.java
@@ -26,6 +26,7 @@ import cgeo.geocaching.loaders.KeywordGeocacheListLoader;
import cgeo.geocaching.loaders.NextPageGeocacheListLoader;
import cgeo.geocaching.loaders.OfflineGeocacheListLoader;
import cgeo.geocaching.loaders.OwnerGeocacheListLoader;
+import cgeo.geocaching.loaders.PocketGeocacheListLoader;
import cgeo.geocaching.loaders.RemoveFromHistoryLoader;
import cgeo.geocaching.loaders.UsernameGeocacheListLoader;
import cgeo.geocaching.maps.CGeoMap;
@@ -1570,6 +1571,19 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
context.startActivity(cachesIntent);
}
+ public static void startActivityPocket(final AbstractActivity context, final @NonNull PocketQueryList pq) {
+ final String guid = pq.getGuid();
+ if (guid == null) {
+ context.showToast(CgeoApplication.getInstance().getString(R.string.warn_pocket_query_select));
+ return;
+ }
+ final Intent cachesIntent = new Intent(context, CacheListActivity.class);
+ cachesIntent.putExtra(Intents.EXTRA_LIST_TYPE, CacheListType.POCKET);
+ cachesIntent.putExtra(Intents.EXTRA_NAME, pq.getName());
+ cachesIntent.putExtra(Intents.EXTRA_POCKET_GUID, guid);
+ context.startActivity(cachesIntent);
+ }
+
// Loaders
@Override
@@ -1650,6 +1664,12 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
case NEXT_PAGE:
loader = new NextPageGeocacheListLoader(app, search);
break;
+ case POCKET:
+ final String guid = extras.getString(Intents.EXTRA_POCKET_GUID);
+ final String pocket_name = extras.getString(Intents.EXTRA_NAME);
+ title = pocket_name;
+ loader = new PocketGeocacheListLoader(app, guid);
+ break;
default:
throw new IllegalStateException();
}
diff --git a/main/src/cgeo/geocaching/Intents.java b/main/src/cgeo/geocaching/Intents.java
index a700451..d9d9829 100644
--- a/main/src/cgeo/geocaching/Intents.java
+++ b/main/src/cgeo/geocaching/Intents.java
@@ -28,4 +28,5 @@ public class Intents {
public static final String EXTRA_USERNAME = PREFIX + "username";
public static final String EXTRA_WAYPOINT_ID = PREFIX + "waypoint_id";
public static final String EXTRA_CACHELIST = PREFIX + "cache_list";
+ public static final String EXTRA_POCKET_GUID = PREFIX + "pocket_guid";
}
diff --git a/main/src/cgeo/geocaching/MainActivity.java b/main/src/cgeo/geocaching/MainActivity.java
index 8a79786..0daa124 100644
--- a/main/src/cgeo/geocaching/MainActivity.java
+++ b/main/src/cgeo/geocaching/MainActivity.java
@@ -27,6 +27,7 @@ import com.google.zxing.integration.android.IntentResult;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
+import org.eclipse.jdt.annotation.NonNull;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
@@ -512,6 +513,26 @@ public class MainActivity extends AbstractActivity {
}
});
nearestView.setBackgroundResource(R.drawable.main_nearby);
+
+ nearestView.setOnLongClickListener(new View.OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View v) {
+ if (!Settings.isPremiumMember()) {
+ return true;
+ }
+ new PocketQueryList.UserInterface(MainActivity.this).promptForListSelection(new RunnableWithArgument<PocketQueryList>() {
+
+ @Override
+ public void run(final @NonNull PocketQueryList pql) {
+ CacheListActivity.startActivityPocket(MainActivity.this, pql);
+ }
+ });
+ return true;
+ }
+ });
+ nearestView.setLongClickable(true);
+
}
navType.setText(res.getString(geo.getLocationProvider().resourceId));
diff --git a/main/src/cgeo/geocaching/PocketQueryList.java b/main/src/cgeo/geocaching/PocketQueryList.java
new file mode 100644
index 0000000..e1a921c
--- /dev/null
+++ b/main/src/cgeo/geocaching/PocketQueryList.java
@@ -0,0 +1,125 @@
+package cgeo.geocaching;
+
+import cgeo.geocaching.activity.ActivityMixin;
+import cgeo.geocaching.connector.gc.GCParser;
+import cgeo.geocaching.utils.RunnableWithArgument;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.ProgressDialog;
+import android.content.DialogInterface;
+import android.content.res.Resources;
+import android.os.Handler;
+import android.os.Message;
+
+import java.util.List;
+
+public final class PocketQueryList {
+
+ private final String guid;
+ private final int maxCaches;
+ private final String name;
+
+ public PocketQueryList(String guid, String name, int maxCaches) {
+ this.guid = guid;
+ this.name = name;
+ this.maxCaches = maxCaches;
+ }
+
+ public static class UserInterface {
+
+ List<PocketQueryList> pocketQueryList = null;
+ RunnableWithArgument<PocketQueryList> runAfterwards;
+
+ private Handler loadPocketQueryHandler = new Handler() {
+
+ @Override
+ public void handleMessage(Message msg) {
+ if ((pocketQueryList == null) || (pocketQueryList.size() == 0)) {
+ if (waitDialog != null) {
+ waitDialog.dismiss();
+ }
+
+ ActivityMixin.showToast(activity, res.getString(R.string.warn_no_pocket_query_found));
+
+ return;
+ }
+
+ if (waitDialog != null) {
+ waitDialog.dismiss();
+ }
+
+ final CharSequence[] items = new CharSequence[pocketQueryList.size()];
+
+ for (int i = 0; i < pocketQueryList.size(); i++) {
+ PocketQueryList pq = pocketQueryList.get(i);
+
+ items[i] = pq.name + " (" + pq.maxCaches + ")";
+ }
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+ builder.setTitle(res.getString(R.string.search_pocket_select));
+ builder.setItems(items, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialogInterface, int itemId) {
+ final PocketQueryList query = pocketQueryList.get(itemId);
+ dialogInterface.dismiss();
+ runAfterwards.run(query);
+ }
+ });
+ builder.create().show();
+
+ }
+ };
+
+ private class LoadPocketQueryListThread extends Thread {
+ final private Handler handler;
+
+ public LoadPocketQueryListThread(Handler handlerIn) {
+ handler = handlerIn;
+ }
+
+ @Override
+ public void run() {
+ pocketQueryList = GCParser.searchPocketQueryList();
+ handler.sendMessage(Message.obtain());
+ }
+ }
+
+ private final Activity activity;
+ private final CgeoApplication app;
+ private final Resources res;
+ private ProgressDialog waitDialog = null;
+
+ public UserInterface(final Activity activity) {
+ this.activity = activity;
+ app = CgeoApplication.getInstance();
+ res = app.getResources();
+ }
+
+ public void promptForListSelection(final RunnableWithArgument<PocketQueryList> runAfterwards) {
+
+ this.runAfterwards = runAfterwards;
+
+ waitDialog = ProgressDialog.show(activity, res.getString(R.string.search_pocket_title), res.getString(R.string.search_pocket_loading), true, true);
+
+ LoadPocketQueryListThread thread = new LoadPocketQueryListThread(loadPocketQueryHandler);
+ thread.start();
+ }
+
+
+ }
+
+ public String getGuid() {
+ return guid;
+ }
+
+ public int getMaxCaches() {
+ return maxCaches;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/connector/gc/GCConstants.java b/main/src/cgeo/geocaching/connector/gc/GCConstants.java
index 601bebe..152b8a2 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCConstants.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCConstants.java
@@ -158,6 +158,7 @@ public final class GCConstants {
public final static Pattern PATTERN_VIEWSTATEFIELDCOUNT = Pattern.compile("id=\"__VIEWSTATEFIELDCOUNT\"[^(value)]+value=\"(\\d+)\"[^>]+>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
public final static Pattern PATTERN_VIEWSTATES = Pattern.compile("id=\"__VIEWSTATE(\\d*)\"[^(value)]+value=\"([^\"]+)\"[^>]+>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
public final static Pattern PATTERN_USERTOKEN = Pattern.compile("userToken\\s*=\\s*'([^']+)'");
+ public final static Pattern PATTERN_LIST_PQ = Pattern.compile(Pattern.quote("pocket_query.png") + ".*?" + Pattern.quote("(") + "(.*?)" + Pattern.quote(")") + ".*?guid=([^\"]*)\".*?>([^<]*)<");
/** Live Map since 14.02.2012 */
public final static Pattern PATTERN_USERSESSION = Pattern.compile("UserSession\\('([^']+)'");
diff --git a/main/src/cgeo/geocaching/connector/gc/GCParser.java b/main/src/cgeo/geocaching/connector/gc/GCParser.java
index bfbcaa4..869d27d 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCParser.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCParser.java
@@ -5,6 +5,7 @@ import cgeo.geocaching.DataStore;
import cgeo.geocaching.Geocache;
import cgeo.geocaching.Image;
import cgeo.geocaching.LogEntry;
+import cgeo.geocaching.PocketQueryList;
import cgeo.geocaching.R;
import cgeo.geocaching.SearchResult;
import cgeo.geocaching.Trackable;
@@ -906,6 +907,17 @@ public abstract class GCParser {
return searchByAny(cacheType, isSearchForMyCaches(userName), showCaptcha, params, recaptchaReceiver);
}
+ public static SearchResult searchByPocket(final String pocketGuid, final CacheType cacheType, final boolean showCaptcha, RecaptchaReceiver recaptchaReceiver) {
+ if (StringUtils.isBlank(pocketGuid)) {
+ Log.e("GCParser.searchByPocket: No guid name given");
+ return null;
+ }
+
+ final Parameters params = new Parameters("pq", pocketGuid);
+
+ return searchByAny(cacheType, false, showCaptcha, params, recaptchaReceiver);
+ }
+
public static SearchResult searchByOwner(final String userName, final CacheType cacheType, final boolean showCaptcha, RecaptchaReceiver recaptchaReceiver) {
if (StringUtils.isBlank(userName)) {
Log.e("GCParser.searchByOwner: No user name given");
@@ -980,6 +992,44 @@ public abstract class GCParser {
return trackable;
}
+ public static List<PocketQueryList> searchPocketQueryList() {
+
+ final Parameters params = new Parameters();
+
+ final String page = Login.getRequestLogged("http://www.geocaching.com/pocket/default.aspx", params);
+
+ if (StringUtils.isBlank(page)) {
+ Log.e("GCParser.searchPocketQueryList: No data from server");
+ return null;
+ }
+
+ String subPage = StringUtils.substringAfter(page, "class=\"PocketQueryListTable");
+ if (StringUtils.isEmpty(subPage)) {
+ Log.e("GCParser.searchPocketQueryList: class \"PocketQueryListTable\" not found on page");
+ return Collections.emptyList();
+ }
+
+ List<PocketQueryList> list = new ArrayList<PocketQueryList>();
+
+ final MatcherWrapper matcherPocket = new MatcherWrapper(GCConstants.PATTERN_LIST_PQ, subPage);
+
+ while (matcherPocket.find()) {
+ int maxCaches;
+ try {
+ maxCaches = Integer.parseInt(matcherPocket.group(1));
+ } catch (NumberFormatException e) {
+ maxCaches = 0;
+ Log.e("GCParser.searchPocketQueryList: Unable to parse max caches", e);
+ }
+ final String guid = Html.fromHtml(matcherPocket.group(2)).toString();
+ final String name = Html.fromHtml(matcherPocket.group(3)).toString();
+ final PocketQueryList pqList = new PocketQueryList(guid, name, maxCaches);
+ list.add(pqList);
+ }
+
+ return list;
+ }
+
public static ImmutablePair<StatusCode, String> postLog(final String geocode, final String cacheid, final String[] viewstates,
final LogType logType, final int year, final int month, final int day,
final String log, final List<TrackableLog> trackables) {
diff --git a/main/src/cgeo/geocaching/enumerations/CacheListType.java b/main/src/cgeo/geocaching/enumerations/CacheListType.java
index b75c118..f482d5b 100644
--- a/main/src/cgeo/geocaching/enumerations/CacheListType.java
+++ b/main/src/cgeo/geocaching/enumerations/CacheListType.java
@@ -2,6 +2,7 @@ package cgeo.geocaching.enumerations;
public enum CacheListType {
OFFLINE(true),
+ POCKET(false),
HISTORY(true),
NEAREST(false),
COORDINATE(false),
diff --git a/main/src/cgeo/geocaching/loaders/AbstractSearchLoader.java b/main/src/cgeo/geocaching/loaders/AbstractSearchLoader.java
index ebf29d1..1cc9706 100644
--- a/main/src/cgeo/geocaching/loaders/AbstractSearchLoader.java
+++ b/main/src/cgeo/geocaching/loaders/AbstractSearchLoader.java
@@ -17,6 +17,7 @@ public abstract class AbstractSearchLoader extends AsyncTaskLoader<SearchResult>
public enum CacheListLoaderType {
OFFLINE,
+ POCKET,
HISTORY,
NEAREST,
COORDINATE,
diff --git a/main/src/cgeo/geocaching/loaders/PocketGeocacheListLoader.java b/main/src/cgeo/geocaching/loaders/PocketGeocacheListLoader.java
new file mode 100644
index 0000000..9256189
--- /dev/null
+++ b/main/src/cgeo/geocaching/loaders/PocketGeocacheListLoader.java
@@ -0,0 +1,28 @@
+package cgeo.geocaching.loaders;
+
+import cgeo.geocaching.SearchResult;
+import cgeo.geocaching.connector.gc.GCParser;
+import cgeo.geocaching.settings.Settings;
+
+import android.content.Context;
+
+public class PocketGeocacheListLoader extends AbstractSearchLoader {
+ private final String guid;
+
+ public PocketGeocacheListLoader(Context context, String guid) {
+ super(context);
+ this.guid = guid;
+ }
+
+ @Override
+ public SearchResult runSearch() {
+
+ if (Settings.isGCConnectorActive()) {
+ return GCParser.searchByPocket(guid, Settings.getCacheType(), Settings.isShowCaptcha(), this);
+ }
+
+ return new SearchResult();
+
+ }
+
+}