aboutsummaryrefslogtreecommitdiffstats
path: root/main/src
diff options
context:
space:
mode:
authorrsudev <rasch@munin-soft.de>2013-05-28 23:17:56 -0700
committerrsudev <rasch@munin-soft.de>2013-05-28 23:17:56 -0700
commitf6779ac30d6ac1357d67654ea17afa1f1d6fa770 (patch)
treee1e84fca95948ef7ba13be7e12809388b24d3267 /main/src
parentd6f1bc648361076c3b2038a6ab9b175e1de39b3d (diff)
parenta7de49db675048db5ae0c05ccd730a8579e6876e (diff)
downloadcgeo-f6779ac30d6ac1357d67654ea17afa1f1d6fa770.zip
cgeo-f6779ac30d6ac1357d67654ea17afa1f1d6fa770.tar.gz
cgeo-f6779ac30d6ac1357d67654ea17afa1f1d6fa770.tar.bz2
Merge pull request #2787 from rsudev/ocde_okapi_2
Implements OKAPI access for opencaching.de
Diffstat (limited to 'main/src')
-rw-r--r--main/src/cgeo/geocaching/CacheDetailActivity.java32
-rw-r--r--main/src/cgeo/geocaching/Geocache.java11
-rw-r--r--main/src/cgeo/geocaching/MainActivity.java4
-rw-r--r--main/src/cgeo/geocaching/Settings.java83
-rw-r--r--main/src/cgeo/geocaching/SettingsActivity.java31
-rw-r--r--main/src/cgeo/geocaching/VisitCacheActivity.java74
-rw-r--r--main/src/cgeo/geocaching/connector/AbstractConnector.java27
-rw-r--r--main/src/cgeo/geocaching/connector/ConnectorFactory.java5
-rw-r--r--main/src/cgeo/geocaching/connector/IConnector.java41
-rw-r--r--main/src/cgeo/geocaching/connector/ILoggingManager.java32
-rw-r--r--main/src/cgeo/geocaching/connector/ImageResult.java23
-rw-r--r--main/src/cgeo/geocaching/connector/LogResult.java23
-rw-r--r--main/src/cgeo/geocaching/connector/NoLoggingManager.java46
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCConnector.java26
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCLoggingManager.java132
-rw-r--r--main/src/cgeo/geocaching/connector/oc/AttributeParser.java327
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OC11XMLParser.java762
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OCApiConnector.java6
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OCApiLiveConnector.java82
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OCAuthorizationActivity.java109
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OCXMLApiConnector.java67
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OCXMLClient.java122
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OkapiClient.java371
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OkapiLoggingManager.java69
-rw-r--r--main/src/cgeo/geocaching/enumerations/LogType.java62
-rw-r--r--main/src/cgeo/geocaching/loaders/CoordsGeocacheListLoader.java6
-rw-r--r--main/src/cgeo/geocaching/maps/CGeoMap.java2
-rw-r--r--main/src/cgeo/geocaching/network/OAuth.java16
-rw-r--r--main/src/cgeo/geocaching/network/OAuthAuthorizationActivity.java326
-rw-r--r--main/src/cgeo/geocaching/twitter/Twitter.java2
-rw-r--r--main/src/cgeo/geocaching/twitter/TwitterAuthorizationActivity.java299
31 files changed, 1880 insertions, 1338 deletions
diff --git a/main/src/cgeo/geocaching/CacheDetailActivity.java b/main/src/cgeo/geocaching/CacheDetailActivity.java
index fe6693b..33a6504 100644
--- a/main/src/cgeo/geocaching/CacheDetailActivity.java
+++ b/main/src/cgeo/geocaching/CacheDetailActivity.java
@@ -117,7 +117,7 @@ import java.util.regex.Pattern;
* e.g. details, description, logs, waypoints, inventory...
*/
public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailActivity.Page>
- implements EditNoteDialogListener {
+ implements EditNoteDialogListener {
private static final int MENU_FIELD_COPY = 1;
private static final int MENU_FIELD_TRANSLATE = 2;
@@ -259,6 +259,23 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
finish();
return;
}
+ } else if (uriHost.contains("opencaching.de")) {
+ if (uriPath != null && uriPath.startsWith("/oc")) {
+ geocode = uriPath.substring(1).toUpperCase(Locale.US);
+ } else {
+ geocode = uri.getQueryParameter("wp");
+ if (StringUtils.isNotBlank(geocode)) {
+ geocode = geocode.toUpperCase(Locale.US);
+ } else {
+ showToast(res.getString(R.string.err_detail_open));
+ finish();
+ return;
+ }
+ }
+ } else {
+ showToast(res.getString(R.string.err_detail_open));
+ finish();
+ return;
}
}
@@ -1472,7 +1489,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
@Override
public void run() {
- handler.sendEmptyMessage(GCConnector.addToWatchlist(cache) ? 1 : -1);
+ handler.sendEmptyMessage(ConnectorFactory.getConnector(cache).addToWatchlist(cache) ? 1 : -1);
}
}
@@ -1486,7 +1503,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
@Override
public void run() {
- handler.sendEmptyMessage(GCConnector.removeFromWatchlist(cache) ? 1 : -1);
+ handler.sendEmptyMessage(ConnectorFactory.getConnector(cache).removeFromWatchlist(cache) ? 1 : -1);
}
}
@@ -2242,8 +2259,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
}
/**
- * Read the position of the cursor pointed to by this holder.
- * <br/>
+ * Read the position of the cursor pointed to by this holder. <br/>
* This must be called by the UI thread.
*
* @return the cursor position
@@ -2253,11 +2269,11 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
}
/**
- * Set the position of the cursor pointed to by this holder.
- * <br/>
+ * Set the position of the cursor pointed to by this holder. <br/>
* This must be called by the UI thread.
*
- * @param position the cursor position
+ * @param position
+ * the cursor position
*/
public void setPosition(final int position) {
this.position = position;
diff --git a/main/src/cgeo/geocaching/Geocache.java b/main/src/cgeo/geocaching/Geocache.java
index 304f940..ac1c9b1 100644
--- a/main/src/cgeo/geocaching/Geocache.java
+++ b/main/src/cgeo/geocaching/Geocache.java
@@ -5,6 +5,7 @@ import cgeo.geocaching.activity.ActivityMixin;
import cgeo.geocaching.activity.IAbstractActivity;
import cgeo.geocaching.connector.ConnectorFactory;
import cgeo.geocaching.connector.IConnector;
+import cgeo.geocaching.connector.ILoggingManager;
import cgeo.geocaching.connector.capability.ISearchByCenter;
import cgeo.geocaching.connector.capability.ISearchByGeocode;
import cgeo.geocaching.connector.gc.GCConnector;
@@ -455,7 +456,7 @@ public class Geocache implements ICache, IWaypoint {
}
public void logVisit(final IAbstractActivity fromActivity) {
- if (StringUtils.isBlank(cacheId)) {
+ if (!getConnector().canLog(this)) {
fromActivity.showToast(((Activity) fromActivity).getResources().getString(R.string.err_cannot_log_visit));
return;
}
@@ -562,6 +563,10 @@ public class Geocache implements ICache, IWaypoint {
return getConnector().supportsLogging();
}
+ public boolean supportsLogImages() {
+ return getConnector().supportsLogImages();
+ }
+
public boolean supportsOwnCoordinates() {
return getConnector().supportsOwnCoordinates();
}
@@ -570,6 +575,10 @@ public class Geocache implements ICache, IWaypoint {
return getConnector().getCacheRealm();
}
+ public ILoggingManager getLoggingManager(Activity activity) {
+ return getConnector().getLoggingManager(activity, this);
+ }
+
@Override
public float getDifficulty() {
return difficulty;
diff --git a/main/src/cgeo/geocaching/MainActivity.java b/main/src/cgeo/geocaching/MainActivity.java
index 9b23554..4393eda 100644
--- a/main/src/cgeo/geocaching/MainActivity.java
+++ b/main/src/cgeo/geocaching/MainActivity.java
@@ -697,6 +697,10 @@ public class MainActivity extends AbstractActivity {
return;
}
+ if (!Settings.isGCConnectorActive()) {
+ return;
+ }
+
// login
final StatusCode status = Login.login();
diff --git a/main/src/cgeo/geocaching/Settings.java b/main/src/cgeo/geocaching/Settings.java
index b5c8a6e..65283da 100644
--- a/main/src/cgeo/geocaching/Settings.java
+++ b/main/src/cgeo/geocaching/Settings.java
@@ -40,8 +40,8 @@ import java.util.Locale;
*/
public final class Settings {
- private static final String KEY_TEMP_TOKEN_SECRET = "temp-token-secret";
- private static final String KEY_TEMP_TOKEN_PUBLIC = "temp-token-public";
+ private static final String KEY_TEMP_TWITTER_TOKEN_SECRET = "temp-token-secret";
+ private static final String KEY_TEMP_TWITTER_TOKEN_PUBLIC = "temp-token-public";
private static final String KEY_HELP_SHOWN = "helper";
private static final String KEY_ANYLONGITUDE = "anylongitude";
private static final String KEY_ANYLATITUDE = "anylatitude";
@@ -110,9 +110,14 @@ public final class Settings {
private static final String KEY_PLAIN_LOGS = "plainLogs";
private static final String KEY_NATIVE_UA = "nativeUa";
private static final String KEY_MAP_DIRECTORY = "mapDirectory";
+ private static final String KEY_CONNECTOR_GC_ACTIVE = "connectorGCActive";
private static final String KEY_CONNECTOR_OC_ACTIVE = "connectorOCActive";
- private static final String KEY_CONNECTOR_OC_USER = "connectorOCUser";
private static final String KEY_LOG_IMAGE_SCALE = "logImageScale";
+ private static final String KEY_OCDE_TOKEN_SECRET = "ocde_tokensecret";
+ private static final String KEY_OCDE_TOKEN_PUBLIC = "ocde_tokenpublic";
+ private static final String KEY_TEMP_OCDE_TOKEN_SECRET = "ocde-temp-token-secret";
+ private static final String KEY_TEMP_OCDE_TOKEN_PUBLIC = "ocde-temp-token-public";
+
private final static int unitsMetric = 1;
@@ -163,8 +168,8 @@ public final class Settings {
final SharedPreferences old = cgeoapplication.getInstance().getSharedPreferences(oldPreferencesName, Context.MODE_PRIVATE);
final Editor e = sharedPrefs.edit();
- e.putString(KEY_TEMP_TOKEN_SECRET, old.getString(KEY_TEMP_TOKEN_SECRET, null));
- e.putString(KEY_TEMP_TOKEN_PUBLIC, old.getString(KEY_TEMP_TOKEN_PUBLIC, null));
+ e.putString(KEY_TEMP_TWITTER_TOKEN_SECRET, old.getString(KEY_TEMP_TWITTER_TOKEN_SECRET, null));
+ e.putString(KEY_TEMP_TWITTER_TOKEN_PUBLIC, old.getString(KEY_TEMP_TWITTER_TOKEN_PUBLIC, null));
e.putBoolean(KEY_HELP_SHOWN, old.getInt(KEY_HELP_SHOWN, 0) != 0);
e.putFloat(KEY_ANYLONGITUDE, old.getFloat(KEY_ANYLONGITUDE, 0));
e.putFloat(KEY_ANYLATITUDE, old.getFloat(KEY_ANYLATITUDE, 0));
@@ -284,6 +289,20 @@ public final class Settings {
});
}
+ public static boolean isGCConnectorActive() {
+ return sharedPrefs.getBoolean(KEY_CONNECTOR_GC_ACTIVE, true);
+ }
+
+ public static boolean setGCConnectorActive(final boolean isActive) {
+ return editSharedSettings(new PrefRunnable() {
+
+ @Override
+ public void edit(Editor edit) {
+ edit.putBoolean(KEY_CONNECTOR_GC_ACTIVE, isActive);
+ }
+ });
+ }
+
public static boolean isPremiumMember() {
// Basic Member, Premium Member, ???
String memberStatus = Settings.getMemberStatus();
@@ -325,26 +344,44 @@ public final class Settings {
});
}
- public static String getOCConnectorUserName() {
- String ocConnectorUser = sharedPrefs.getString(KEY_CONNECTOR_OC_USER, null);
- if (StringUtils.isBlank(ocConnectorUser)) {
- return StringUtils.EMPTY;
- }
- return ocConnectorUser;
+ public static String getOCDETokenPublic() {
+ return sharedPrefs.getString(KEY_OCDE_TOKEN_PUBLIC, "");
}
- public static boolean setOCConnectorUserName(final String userName) {
- return editSharedSettings(new PrefRunnable() {
+ public static String getOCDETokenSecret() {
+ return sharedPrefs.getString(KEY_OCDE_TOKEN_SECRET, "");
+ }
+
+ public static void setOCDETokens(final String tokenPublic, final String tokenSecret, boolean enableOcDe) {
+ editSharedSettings(new PrefRunnable() {
@Override
public void edit(Editor edit) {
- if (StringUtils.isBlank(userName)) {
- edit.remove(KEY_CONNECTOR_OC_USER);
- } else {
- edit.putString(KEY_CONNECTOR_OC_USER, userName);
+ edit.putString(KEY_OCDE_TOKEN_PUBLIC, tokenPublic);
+ edit.putString(KEY_OCDE_TOKEN_SECRET, tokenSecret);
+ if (tokenPublic != null) {
+ edit.remove(KEY_TEMP_OCDE_TOKEN_PUBLIC);
+ edit.remove(KEY_TEMP_OCDE_TOKEN_SECRET);
}
}
});
+ setOCConnectorActive(enableOcDe);
+ }
+
+ public static void setOCDETempTokens(final String tokenPublic, final String tokenSecret) {
+ editSharedSettings(new PrefRunnable() {
+ @Override
+ public void edit(Editor edit) {
+ edit.putString(KEY_TEMP_OCDE_TOKEN_PUBLIC, tokenPublic);
+ edit.putString(KEY_TEMP_OCDE_TOKEN_SECRET, tokenSecret);
+ }
+ });
+ }
+
+ public static ImmutablePair<String, String> getTempOCDEToken() {
+ String tokenPublic = sharedPrefs.getString(KEY_TEMP_OCDE_TOKEN_PUBLIC, null);
+ String tokenSecret = sharedPrefs.getString(KEY_TEMP_OCDE_TOKEN_SECRET, null);
+ return new ImmutablePair<String, String>(tokenPublic, tokenSecret);
}
public static boolean isGCvoteLogin() {
@@ -1122,8 +1159,8 @@ public final class Settings {
edit.putString(KEY_TWITTER_TOKEN_PUBLIC, tokenPublic);
edit.putString(KEY_TWITTER_TOKEN_SECRET, tokenSecret);
if (tokenPublic != null) {
- edit.remove(KEY_TEMP_TOKEN_PUBLIC);
- edit.remove(KEY_TEMP_TOKEN_SECRET);
+ edit.remove(KEY_TEMP_TWITTER_TOKEN_PUBLIC);
+ edit.remove(KEY_TEMP_TWITTER_TOKEN_SECRET);
}
}
});
@@ -1134,15 +1171,15 @@ public final class Settings {
editSharedSettings(new PrefRunnable() {
@Override
public void edit(Editor edit) {
- edit.putString(KEY_TEMP_TOKEN_PUBLIC, tokenPublic);
- edit.putString(KEY_TEMP_TOKEN_SECRET, tokenSecret);
+ edit.putString(KEY_TEMP_TWITTER_TOKEN_PUBLIC, tokenPublic);
+ edit.putString(KEY_TEMP_TWITTER_TOKEN_SECRET, tokenSecret);
}
});
}
public static ImmutablePair<String, String> getTempToken() {
- String tokenPublic = sharedPrefs.getString(KEY_TEMP_TOKEN_PUBLIC, null);
- String tokenSecret = sharedPrefs.getString(KEY_TEMP_TOKEN_SECRET, null);
+ String tokenPublic = sharedPrefs.getString(KEY_TEMP_TWITTER_TOKEN_PUBLIC, null);
+ String tokenSecret = sharedPrefs.getString(KEY_TEMP_TWITTER_TOKEN_SECRET, null);
return new ImmutablePair<String, String>(tokenPublic, tokenSecret);
}
diff --git a/main/src/cgeo/geocaching/SettingsActivity.java b/main/src/cgeo/geocaching/SettingsActivity.java
index f09f7d6..aa163ad 100644
--- a/main/src/cgeo/geocaching/SettingsActivity.java
+++ b/main/src/cgeo/geocaching/SettingsActivity.java
@@ -5,6 +5,7 @@ import cgeo.geocaching.apps.cache.navi.NavigationAppFactory;
import cgeo.geocaching.apps.cache.navi.NavigationAppFactory.NavigationAppsEnum;
import cgeo.geocaching.compatibility.Compatibility;
import cgeo.geocaching.connector.gc.Login;
+import cgeo.geocaching.connector.oc.OCAuthorizationActivity;
import cgeo.geocaching.enumerations.StatusCode;
import cgeo.geocaching.files.SimpleDirChooser;
import cgeo.geocaching.maps.MapProviderFactory;
@@ -169,7 +170,6 @@ public class SettingsActivity extends AbstractActivity {
((EditText) findViewById(R.id.username)).setText("");
((EditText) findViewById(R.id.password)).setText("");
((EditText) findViewById(R.id.passvote)).setText("");
- ((EditText) findViewById(R.id.oc_username)).setText("");
if (saveValues()) {
showToast(res.getString(R.string.init_cleared));
@@ -213,6 +213,15 @@ public class SettingsActivity extends AbstractActivity {
public void init() {
// geocaching.com settings
+ final CheckBox gcCheck = (CheckBox) findViewById(R.id.gc_option);
+ gcCheck.setChecked(Settings.isGCConnectorActive());
+ gcCheck.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ Settings.setGCConnectorActive(gcCheck.isChecked());
+ }
+ });
final ImmutablePair<String, String> login = Settings.getLogin();
if (login != null) {
((EditText) findViewById(R.id.username)).setText(login.left);
@@ -242,10 +251,9 @@ public class SettingsActivity extends AbstractActivity {
Settings.setOCConnectorActive(ocCheck.isChecked());
}
});
- EditText ocUserEdit = (EditText) findViewById(R.id.oc_username);
- if (ocUserEdit.getText().length() == 0) {
- ocUserEdit.setText(Settings.getOCConnectorUserName());
- }
+
+ Button checkOCUser = (Button) findViewById(R.id.register_oc_de);
+ checkOCUser.setOnClickListener(new OCDEAuthorizeCgeoListener());
// gcvote settings
final ImmutablePair<String, String> gcvoteLogin = Settings.getGCvoteLogin();
@@ -829,7 +837,6 @@ public class SettingsActivity extends AbstractActivity {
String signatureNew = ((EditText) findViewById(R.id.signature)).getText().toString();
String mapDirectoryNew = StringUtils.trimToEmpty(((EditText) findViewById(R.id.map_directory)).getText().toString());
String themesDirectoryNew = StringUtils.trimToEmpty(((EditText) findViewById(R.id.themefolder)).getText().toString());
- String ocUserName = StringUtils.trimToEmpty(((EditText) findViewById(R.id.oc_username)).getText().toString());
String altitudeNew = StringUtils.trimToNull(((EditText) findViewById(R.id.altitude)).getText().toString());
int altitudeNewInt = parseNumber(altitudeNew, 0);
@@ -843,7 +850,6 @@ public class SettingsActivity extends AbstractActivity {
final boolean status4 = Settings.setAltCorrection(altitudeNewInt);
final boolean status5 = Settings.setMapFileDirectory(mapDirectoryNew);
final boolean status6 = Settings.setCustomRenderThemeBaseFolder(themesDirectoryNew);
- final boolean status7 = Settings.setOCConnectorUserName(ocUserName);
Settings.setShowWaypointsThreshold(waypointThreshold);
String importNew = StringUtils.trimToEmpty(((EditText) findViewById(R.id.gpx_importdir)).getText().toString());
@@ -851,7 +857,7 @@ public class SettingsActivity extends AbstractActivity {
Settings.setGpxImportDir(importNew);
Settings.setGpxExportDir(exportNew);
- return status1 && status2 && status3 && status4 && status5 && status6 && status7;
+ return status1 && status2 && status3 && status4 && status5 && status6;
}
/**
@@ -920,6 +926,15 @@ public class SettingsActivity extends AbstractActivity {
}
}
+ private class OCDEAuthorizeCgeoListener implements View.OnClickListener {
+
+ @Override
+ public void onClick(View v) {
+ Intent authIntent = new Intent(SettingsActivity.this, OCAuthorizationActivity.class);
+ startActivity(authIntent);
+ }
+ }
+
private class WebAuthListener implements View.OnClickListener {
@Override
diff --git a/main/src/cgeo/geocaching/VisitCacheActivity.java b/main/src/cgeo/geocaching/VisitCacheActivity.java
index c19cceb..e99da8d 100644
--- a/main/src/cgeo/geocaching/VisitCacheActivity.java
+++ b/main/src/cgeo/geocaching/VisitCacheActivity.java
@@ -1,14 +1,13 @@
package cgeo.geocaching;
-import cgeo.geocaching.connector.gc.GCParser;
-import cgeo.geocaching.connector.gc.Login;
+import cgeo.geocaching.connector.ILoggingManager;
+import cgeo.geocaching.connector.ImageResult;
+import cgeo.geocaching.connector.LogResult;
import cgeo.geocaching.enumerations.LoadFlags;
import cgeo.geocaching.enumerations.LogType;
import cgeo.geocaching.enumerations.LogTypeTrackable;
import cgeo.geocaching.enumerations.StatusCode;
import cgeo.geocaching.gcvote.GCVote;
-import cgeo.geocaching.loaders.UrlLoader;
-import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.twitter.Twitter;
import cgeo.geocaching.ui.Formatter;
import cgeo.geocaching.ui.dialog.DateDialog;
@@ -20,7 +19,6 @@ import cgeo.geocaching.utils.LogTemplateProvider.LogContext;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.tuple.ImmutablePair;
import android.app.Activity;
import android.app.AlertDialog;
@@ -31,8 +29,6 @@ import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
-import android.support.v4.app.LoaderManager;
-import android.support.v4.content.Loader;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -51,7 +47,7 @@ import java.util.Date;
import java.util.List;
import java.util.Locale;
-public class VisitCacheActivity extends AbstractLoggingActivity implements DateDialog.DateDialogParent, LoaderManager.LoaderCallbacks<String> {
+public class VisitCacheActivity extends AbstractLoggingActivity implements DateDialog.DateDialogParent {
static final String EXTRAS_GEOCODE = "geocode";
static final String EXTRAS_ID = "id";
@@ -71,7 +67,6 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
private String geocode = null;
private String text = null;
private List<LogType> possibleLogTypes = new ArrayList<LogType>();
- private String[] viewstates = null;
private List<TrackableLog> trackables = null;
private Button postButton = null;
private CheckBox tweetCheck = null;
@@ -79,6 +74,8 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
private boolean tbChanged = false;
private SparseArray<TrackableLog> actionButtons;
+ private ILoggingManager loggingManager;
+
// Data to be saved while reconfiguring
private double rating;
private LogType typeSelected;
@@ -87,30 +84,16 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
private String imageDescription;
private Uri imageUri;
- @Override
- public Loader<String> onCreateLoader(final int id, final Bundle args) {
- if (!Settings.isLogin()) { // allow offline logging
- showToast(res.getString(R.string.err_login));
- return null;
- }
- return new UrlLoader(getBaseContext(), "http://www.geocaching.com/seek/log.aspx", new Parameters("ID", cacheid));
- }
- @Override
- public void onLoaderReset(final Loader<String> loader) {
- // Nothing to do
- }
+ public void onLoadFinished() {
- @Override
- public void onLoadFinished(final Loader<String> loader, final String page) {
- if (page == null) {
+ if (loggingManager.hasLoaderError()) {
showErrorLoadingData();
return;
}
- viewstates = Login.getViewstates(page);
- trackables = GCParser.parseTrackableLog(page);
- possibleLogTypes = GCParser.parseTypes(page);
+ trackables = loggingManager.getTrackables();
+ possibleLogTypes = loggingManager.getPossibleLogTypes();
if (possibleLogTypes.isEmpty()) {
showErrorLoadingData();
@@ -229,7 +212,7 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
if (!postButton.isEnabled()) {
return res.getString(R.string.log_post_not_possible);
}
- if (typeSelected != LogType.FOUND_IT || !Settings.isGCvoteLogin()) {
+ if (typeSelected != LogType.FOUND_IT || !Settings.isGCvoteLogin() || !cache.supportsGCVote()) {
return res.getString(R.string.log_post);
}
if (rating == 0) {
@@ -295,7 +278,7 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
}
}
updatePostButtonText();
- setImageButtonText();
+ updateImageButton();
enablePostButton(false);
final Button typeButton = (Button) findViewById(R.id.type);
@@ -347,7 +330,9 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
}
});
- getSupportLoaderManager().initLoader(0, null, this);
+ loggingManager = cache.getLoggingManager(this);
+
+ loggingManager.init();
}
private void setDefaultValues() {
@@ -393,7 +378,7 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
final EditText logView = (EditText) findViewById(R.id.log);
logView.setText(StringUtils.EMPTY);
- setImageButtonText();
+ updateImageButton();
showToast(res.getString(R.string.info_log_cleared));
}
@@ -433,7 +418,7 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
- final boolean voteAvailable = Settings.isGCvoteLogin() && typeSelected == LogType.FOUND_IT && StringUtils.isNotBlank(cache.getGuid());
+ final boolean voteAvailable = Settings.isGCvoteLogin() && typeSelected == LogType.FOUND_IT && StringUtils.isNotBlank(cache.getGuid()) && cache.supportsGCVote();
menu.findItem(SUBMENU_VOTE).setVisible(voteAvailable);
return true;
@@ -536,11 +521,9 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
protected StatusCode doInBackgroundInternal(final String[] logTexts) {
final String log = logTexts[0];
try {
- final ImmutablePair<StatusCode, String> postResult = GCParser.postLog(geocode, cacheid, viewstates, typeSelected,
- date.get(Calendar.YEAR), (date.get(Calendar.MONTH) + 1), date.get(Calendar.DATE),
- log, trackables);
+ final LogResult logResult = loggingManager.postLog(cache, typeSelected, date, log, trackables);
- if (postResult.left == StatusCode.NO_ERROR) {
+ if (logResult.getPostLogResult() == StatusCode.NO_ERROR) {
final LogEntry logNow = new LogEntry(date, typeSelected, log);
cache.getLogs().add(0, logNow);
@@ -560,17 +543,17 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
}
if (StringUtils.isNotBlank(imageUri.getPath())) {
- ImmutablePair<StatusCode, String> imageResult = GCParser.uploadLogImage(postResult.right, imageCaption, imageDescription, imageUri);
- final String uploadedImageUrl = imageResult.right;
+ ImageResult imageResult = loggingManager.postLogImage(logResult.getLogId(), imageCaption, imageDescription, imageUri);
+ final String uploadedImageUrl = imageResult.getImageUri();
if (StringUtils.isNotEmpty(uploadedImageUrl)) {
logNow.addLogImage(new Image(uploadedImageUrl, imageCaption, imageDescription));
cgData.saveChangedCache(cache);
}
- return imageResult.left;
+ return imageResult.getPostResult();
}
}
- return postResult.left;
+ return logResult.getPostLogResult();
} catch (Exception e) {
Log.e("cgeovisit.postLogFn", e);
}
@@ -705,14 +688,19 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
// Image capture failed, advise user
showToast(getResources().getString(R.string.err_select_logimage_failed));
}
- setImageButtonText();
+ updateImageButton();
}
}
- private void setImageButtonText() {
+ private void updateImageButton() {
final Button imageButton = (Button) findViewById(R.id.image_btn);
- imageButton.setText(StringUtils.isNotBlank(imageUri.getPath()) ?
+ if (cache.supportsLogImages()) {
+ imageButton.setVisibility(View.VISIBLE);
+ imageButton.setText(StringUtils.isNotBlank(imageUri.getPath()) ?
res.getString(R.string.log_image_edit) : res.getString(R.string.log_image_attach));
+ } else {
+ imageButton.setVisibility(View.GONE);
+ }
}
}
diff --git a/main/src/cgeo/geocaching/connector/AbstractConnector.java b/main/src/cgeo/geocaching/connector/AbstractConnector.java
index 413291c..905382f 100644
--- a/main/src/cgeo/geocaching/connector/AbstractConnector.java
+++ b/main/src/cgeo/geocaching/connector/AbstractConnector.java
@@ -6,6 +6,8 @@ import cgeo.geocaching.geopoint.Geopoint;
import org.apache.commons.lang3.StringUtils;
+import android.app.Activity;
+
public abstract class AbstractConnector implements IConnector {
@Override
@@ -19,6 +21,16 @@ public abstract class AbstractConnector implements IConnector {
}
@Override
+ public boolean addToWatchlist(Geocache cache) {
+ return false;
+ }
+
+ @Override
+ public boolean removeFromWatchlist(Geocache cache) {
+ return false;
+ }
+
+ @Override
public boolean supportsOwnCoordinates() {
return false;
}
@@ -54,6 +66,21 @@ public abstract class AbstractConnector implements IConnector {
}
@Override
+ public boolean supportsLogImages() {
+ return false;
+ }
+
+ @Override
+ public boolean canLog(Geocache cache) {
+ return false;
+ }
+
+ @Override
+ public ILoggingManager getLoggingManager(Activity activity, Geocache cache) {
+ return new NoLoggingManager();
+ }
+
+ @Override
public String getLicenseText(final Geocache cache) {
return null;
}
diff --git a/main/src/cgeo/geocaching/connector/ConnectorFactory.java b/main/src/cgeo/geocaching/connector/ConnectorFactory.java
index 561bae2..50f56af 100644
--- a/main/src/cgeo/geocaching/connector/ConnectorFactory.java
+++ b/main/src/cgeo/geocaching/connector/ConnectorFactory.java
@@ -1,14 +1,15 @@
package cgeo.geocaching.connector;
import cgeo.geocaching.ICache;
+import cgeo.geocaching.R;
import cgeo.geocaching.SearchResult;
import cgeo.geocaching.Trackable;
import cgeo.geocaching.connector.capability.ISearchByCenter;
import cgeo.geocaching.connector.capability.ISearchByViewPort;
import cgeo.geocaching.connector.gc.GCConnector;
import cgeo.geocaching.connector.oc.OCApiConnector;
+import cgeo.geocaching.connector.oc.OCApiLiveConnector;
import cgeo.geocaching.connector.oc.OCConnector;
-import cgeo.geocaching.connector.oc.OCXMLApiConnector;
import cgeo.geocaching.connector.ox.OXConnector;
import cgeo.geocaching.geopoint.Viewport;
@@ -21,7 +22,7 @@ public final class ConnectorFactory {
private static final UnknownConnector UNKNOWN_CONNECTOR = new UnknownConnector();
private static final IConnector[] connectors = new IConnector[] {
GCConnector.getInstance(),
- new OCXMLApiConnector("OpenCaching.DE", "www.opencaching.de", "OC"),
+ new OCApiLiveConnector("Opencaching.de", "www.opencaching.de", "OC", R.string.oc_de_okapi_consumer_key, R.string.oc_de_okapi_consumer_secret),
new OCConnector("OpenCaching.CZ", "www.opencaching.cz", "OZ"),
new OCApiConnector("OpenCaching.CO.UK", "www.opencaching.org.uk", "OK", "arU4okouc4GEjMniE2fq"),
new OCConnector("OpenCaching.ES", "www.opencachingspain.es", "OC"),
diff --git a/main/src/cgeo/geocaching/connector/IConnector.java b/main/src/cgeo/geocaching/connector/IConnector.java
index 9169b4a..011c507 100644
--- a/main/src/cgeo/geocaching/connector/IConnector.java
+++ b/main/src/cgeo/geocaching/connector/IConnector.java
@@ -5,6 +5,8 @@ import cgeo.geocaching.ICache;
import cgeo.geocaching.enumerations.CacheRealm;
import cgeo.geocaching.geopoint.Geopoint;
+import android.app.Activity;
+
public interface IConnector {
/**
* get name for display (currently only used in links)
@@ -45,6 +47,22 @@ public interface IConnector {
public boolean supportsWatchList();
/**
+ * Add the cache to the watchlist
+ *
+ * @param cache
+ * @return True - success/False - failure
+ */
+ public boolean addToWatchlist(Geocache cache);
+
+ /**
+ * Remove the cache from the watchlist
+ *
+ * @param cache
+ * @return True - success/False - failure
+ */
+ public boolean removeFromWatchlist(Geocache cache);
+
+ /**
* enable/disable favorite points controls in cache details
*
* @return
@@ -59,6 +77,20 @@ public interface IConnector {
public boolean supportsLogging();
/**
+ * enable/disable attaching image to log
+ *
+ * @return
+ */
+ public boolean supportsLogImages();
+
+ /**
+ * Get an ILoggingManager to guide the logging process.
+ *
+ * @return
+ */
+ public ILoggingManager getLoggingManager(Activity activity, Geocache cache);
+
+ /**
* get host name of the connector server for dynamic loading of data
*
* @return
@@ -159,4 +191,13 @@ public interface IConnector {
* @return <code>true</code> if the current user is the cache owner, <code>false</code> otherwise
*/
public boolean isOwner(final ICache cache);
+
+ /**
+ * Check if the cache information is complete enough to be
+ * able to log online.
+ *
+ * @param geocache
+ * @return
+ */
+ public boolean canLog(Geocache geocache);
}
diff --git a/main/src/cgeo/geocaching/connector/ILoggingManager.java b/main/src/cgeo/geocaching/connector/ILoggingManager.java
new file mode 100644
index 0000000..f0029f9
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/ILoggingManager.java
@@ -0,0 +1,32 @@
+package cgeo.geocaching.connector;
+
+import cgeo.geocaching.Geocache;
+import cgeo.geocaching.TrackableLog;
+import cgeo.geocaching.enumerations.LogType;
+
+import android.net.Uri;
+
+import java.util.Calendar;
+import java.util.List;
+
+public interface ILoggingManager {
+
+ LogResult postLog(Geocache cache,
+ LogType logType,
+ Calendar date,
+ String log,
+ List<TrackableLog> trackableLogs);
+
+ ImageResult postLogImage(String logId,
+ String imageCaption,
+ String imageDescription,
+ Uri imageUri);
+
+ public boolean hasLoaderError();
+
+ public List<TrackableLog> getTrackables();
+
+ public List<LogType> getPossibleLogTypes();
+
+ public void init();
+}
diff --git a/main/src/cgeo/geocaching/connector/ImageResult.java b/main/src/cgeo/geocaching/connector/ImageResult.java
new file mode 100644
index 0000000..9314cad
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/ImageResult.java
@@ -0,0 +1,23 @@
+package cgeo.geocaching.connector;
+
+import cgeo.geocaching.enumerations.StatusCode;
+
+public class ImageResult {
+
+ private final StatusCode postResult;
+ private final String imageUri;
+
+ public ImageResult(StatusCode postResult, String imageUri) {
+ this.postResult = postResult;
+ this.imageUri = imageUri;
+ }
+
+ public StatusCode getPostResult() {
+ return postResult;
+ }
+
+ public String getImageUri() {
+ return imageUri;
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/connector/LogResult.java b/main/src/cgeo/geocaching/connector/LogResult.java
new file mode 100644
index 0000000..62111a4
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/LogResult.java
@@ -0,0 +1,23 @@
+package cgeo.geocaching.connector;
+
+import cgeo.geocaching.enumerations.StatusCode;
+
+public class LogResult {
+
+ private final StatusCode postLogResult;
+ private final String logId;
+
+ public LogResult(StatusCode postLogResult, String logId) {
+ this.postLogResult = postLogResult;
+ this.logId = logId;
+ }
+
+ public StatusCode getPostLogResult() {
+ return postLogResult;
+ }
+
+ public String getLogId() {
+ return logId;
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/connector/NoLoggingManager.java b/main/src/cgeo/geocaching/connector/NoLoggingManager.java
new file mode 100644
index 0000000..bfea4ca
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/NoLoggingManager.java
@@ -0,0 +1,46 @@
+package cgeo.geocaching.connector;
+
+import cgeo.geocaching.Geocache;
+import cgeo.geocaching.TrackableLog;
+import cgeo.geocaching.enumerations.LogType;
+import cgeo.geocaching.enumerations.StatusCode;
+
+import android.net.Uri;
+
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.List;
+
+public class NoLoggingManager implements ILoggingManager {
+
+ @Override
+ public void init() {
+ // nothing to do
+ }
+
+ @Override
+ public LogResult postLog(Geocache cache, LogType logType, Calendar date, String log, List<TrackableLog> trackableLogs) {
+ return new LogResult(StatusCode.LOG_POST_ERROR, "");
+ }
+
+ @Override
+ public ImageResult postLogImage(String logId, String imageCaption, String imageDescription, Uri imageUri) {
+ return new ImageResult(StatusCode.LOG_POST_ERROR, "");
+ }
+
+ @Override
+ public boolean hasLoaderError() {
+ return true;
+ }
+
+ @Override
+ public List<TrackableLog> getTrackables() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List<LogType> getPossibleLogTypes() {
+ return Collections.emptyList();
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/connector/gc/GCConnector.java b/main/src/cgeo/geocaching/connector/gc/GCConnector.java
index a2df060..82bd52a 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCConnector.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCConnector.java
@@ -7,6 +7,7 @@ import cgeo.geocaching.SearchResult;
import cgeo.geocaching.Settings;
import cgeo.geocaching.cgData;
import cgeo.geocaching.connector.AbstractConnector;
+import cgeo.geocaching.connector.ILoggingManager;
import cgeo.geocaching.connector.capability.ISearchByCenter;
import cgeo.geocaching.connector.capability.ISearchByGeocode;
import cgeo.geocaching.connector.capability.ISearchByViewPort;
@@ -20,6 +21,8 @@ import cgeo.geocaching.utils.Log;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
+import android.app.Activity;
+
import java.util.regex.Pattern;
public class GCConnector extends AbstractConnector implements ISearchByGeocode, ISearchByCenter, ISearchByViewPort {
@@ -82,6 +85,21 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode,
}
@Override
+ public boolean supportsLogImages() {
+ return true;
+ }
+
+ @Override
+ public ILoggingManager getLoggingManager(Activity activity, Geocache cache) {
+ return new GCLoggingManager(activity, cache);
+ }
+
+ @Override
+ public boolean canLog(Geocache cache) {
+ return StringUtils.isNotBlank(cache.getCacheId());
+ }
+
+ @Override
public String getName() {
return "GeoCaching.com";
}
@@ -153,7 +171,8 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode,
}
- public static boolean addToWatchlist(Geocache cache) {
+ @Override
+ public boolean addToWatchlist(Geocache cache) {
final boolean added = GCParser.addToWatchlist(cache);
if (added) {
cgData.saveChangedCache(cache);
@@ -161,7 +180,8 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode,
return added;
}
- public static boolean removeFromWatchlist(Geocache cache) {
+ @Override
+ public boolean removeFromWatchlist(Geocache cache) {
final boolean removed = GCParser.removeFromWatchlist(cache);
if (removed) {
cgData.saveChangedCache(cache);
@@ -244,6 +264,6 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode,
@Override
public boolean isActivated() {
- return true;
+ return Settings.isGCConnectorActive();
}
}
diff --git a/main/src/cgeo/geocaching/connector/gc/GCLoggingManager.java b/main/src/cgeo/geocaching/connector/gc/GCLoggingManager.java
new file mode 100644
index 0000000..0fbd718
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/gc/GCLoggingManager.java
@@ -0,0 +1,132 @@
+package cgeo.geocaching.connector.gc;
+
+import cgeo.geocaching.Geocache;
+import cgeo.geocaching.R;
+import cgeo.geocaching.Settings;
+import cgeo.geocaching.TrackableLog;
+import cgeo.geocaching.VisitCacheActivity;
+import cgeo.geocaching.activity.ActivityMixin;
+import cgeo.geocaching.connector.ILoggingManager;
+import cgeo.geocaching.connector.ImageResult;
+import cgeo.geocaching.connector.LogResult;
+import cgeo.geocaching.enumerations.LogType;
+import cgeo.geocaching.enumerations.StatusCode;
+import cgeo.geocaching.loaders.UrlLoader;
+import cgeo.geocaching.network.Parameters;
+import cgeo.geocaching.utils.Log;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+
+import android.app.Activity;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.Loader;
+
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.List;
+
+public class GCLoggingManager implements ILoggingManager, LoaderManager.LoaderCallbacks<String> {
+
+ private final VisitCacheActivity activity;
+ private final Geocache cache;
+
+ private String[] viewstates;
+ private List<TrackableLog> trackables;
+ private List<LogType> possibleLogTypes;
+ private boolean hasLoaderError = true;
+
+ public GCLoggingManager(Activity activity, Geocache cache) {
+ this.activity = (VisitCacheActivity) activity;
+ this.cache = cache;
+ }
+
+ @Override
+ public Loader<String> onCreateLoader(int arg0, Bundle arg1) {
+ if (!Settings.isLogin()) { // allow offline logging
+ ActivityMixin.showToast(activity, activity.getResources().getString(R.string.err_login));
+ return null;
+ }
+ return new UrlLoader(activity.getBaseContext(), "http://www.geocaching.com/seek/log.aspx", new Parameters("ID", cache.getCacheId()));
+ }
+
+ @Override
+ public void onLoadFinished(Loader<String> arg0, String page) {
+
+ if (page == null) {
+ hasLoaderError = true;
+ } else {
+
+ viewstates = Login.getViewstates(page);
+ trackables = GCParser.parseTrackableLog(page);
+ possibleLogTypes = GCParser.parseTypes(page);
+
+ hasLoaderError = possibleLogTypes.isEmpty();
+ }
+
+ activity.onLoadFinished();
+ }
+
+ @Override
+ public void onLoaderReset(Loader<String> arg0) {
+ // nothing to do
+ }
+
+ @Override
+ public void init() {
+ activity.getSupportLoaderManager().initLoader(0, null, this);
+ }
+
+ @Override
+ public LogResult postLog(Geocache cache, LogType logType, Calendar date, String log, List<TrackableLog> trackableLogs) {
+
+ try {
+ final ImmutablePair<StatusCode, String> postResult = GCParser.postLog(cache.getGeocode(), cache.getCacheId(), viewstates, logType,
+ date.get(Calendar.YEAR), (date.get(Calendar.MONTH) + 1), date.get(Calendar.DATE),
+ log, trackableLogs);
+
+ return new LogResult(postResult.left, postResult.right);
+ } catch (Exception e) {
+ Log.e("GCLoggingManager.postLog", e);
+ }
+
+ return new LogResult(StatusCode.LOG_POST_ERROR, "");
+ }
+
+ @Override
+ public ImageResult postLogImage(String logId, String imageCaption, String imageDescription, Uri imageUri) {
+
+ if (StringUtils.isNotBlank(imageUri.getPath())) {
+
+ ImmutablePair<StatusCode, String> imageResult = GCParser.uploadLogImage(logId, imageCaption, imageDescription, imageUri);
+
+ return new ImageResult(imageResult.left, imageResult.right);
+ }
+
+ return new ImageResult(StatusCode.LOGIMAGE_POST_ERROR, "");
+ }
+
+ @Override
+ public boolean hasLoaderError() {
+ return hasLoaderError;
+ }
+
+ @Override
+ public List<TrackableLog> getTrackables() {
+ if (hasLoaderError) {
+ return Collections.emptyList();
+ }
+ return trackables;
+ }
+
+ @Override
+ public List<LogType> getPossibleLogTypes() {
+ if (hasLoaderError) {
+ return Collections.emptyList();
+ }
+ return possibleLogTypes;
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/connector/oc/AttributeParser.java b/main/src/cgeo/geocaching/connector/oc/AttributeParser.java
new file mode 100644
index 0000000..63bee77
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/oc/AttributeParser.java
@@ -0,0 +1,327 @@
+// This is a generated file, do not change manually!
+
+package cgeo.geocaching.connector.oc;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class AttributeParser {
+
+ private final static Map<String, Integer> attrMapDe;
+ private final static Map<String, Integer> attrMapPl;
+
+ static {
+ attrMapDe = new HashMap<String, Integer>();
+ attrMapPl = new HashMap<String, Integer>();
+
+ // last header line
+ attrMapDe.put("Listed at Opencaching only", 6);
+ attrMapDe.put("Dostępna tylko na Opencaching", 6);
+ attrMapDe.put("Nur bei Opencaching logbar", 6);
+ attrMapDe.put("Solo loggeable en Opencaching", 6);
+ attrMapDe.put("Loggabile solo su Opencaching", 6);
+ attrMapPl.put("Near a Survey Marker", 54);
+ attrMapPl.put("W pobliżu punktu geodezyjnego", 54);
+ attrMapPl.put("Whereigo Cache", 55);
+ attrMapPl.put("Whereigo Cache", 55);
+ attrMapPl.put("Whereigo Cache", 55);
+ attrMapDe.put("Letterbox Cache", 8);
+ attrMapPl.put("Letterbox Cache", 56);
+ attrMapDe.put("Skrzynka typu Letterbox", 8);
+ attrMapPl.put("Skrzynka typu Letterbox", 56);
+ attrMapDe.put("Letterbox (benötigt Stempel)", 8);
+ attrMapPl.put("Letterbox (benötigt Stempel)", 56);
+ attrMapDe.put("Letterbox (necesita un estampador)", 8);
+ attrMapPl.put("Letterbox (necesita un estampador)", 56);
+ attrMapDe.put("Letterbox (richiede un timbro)", 8);
+ attrMapPl.put("Letterbox (richiede un timbro)", 56);
+ attrMapPl.put("GeoHotel", 43);
+ attrMapPl.put("GeoHotel", 43);
+ attrMapPl.put("GeoHotel", 43);
+ attrMapPl.put("Magnetic cache", 49);
+ attrMapPl.put("Przyczepiona magnesem", 49);
+ attrMapPl.put("magnetischer Cache", 49);
+ attrMapPl.put("Description contains an audio file", 50);
+ attrMapPl.put("Opis zawiera plik audio", 50);
+ attrMapPl.put("Offset cache", 51);
+ attrMapPl.put("Offset cache", 51);
+ attrMapPl.put("Peilungscache", 51);
+ attrMapPl.put("Garmin's wireless beacon", 52);
+ attrMapPl.put("Beacon - Garmin Chirp", 52);
+ attrMapPl.put("Funksignal – Garmin Chirp", 52);
+ attrMapPl.put("Dead Drop USB cache", 53);
+ attrMapPl.put("Dead Drop USB skrzynka", 53);
+ attrMapDe.put("Has a moving target", 31);
+ attrMapDe.put("bewegliches Ziel", 31);
+ attrMapDe.put("Objetivo en movimiento", 31);
+ attrMapDe.put("Oggetto in movimento", 31);
+ attrMapDe.put("Webcam Cache", 32);
+ attrMapDe.put("Webcam Cache", 32);
+ attrMapDe.put("Webcam Cache", 32);
+ attrMapDe.put("Webcam Cache", 32);
+ attrMapDe.put("Other cache type", 57);
+ attrMapDe.put("sonstiger Cachetyp", 57);
+ attrMapDe.put("Otro tipo de cache", 57);
+ attrMapDe.put("Altro tipo di cache", 57);
+ attrMapDe.put("Investigation required", 54);
+ attrMapDe.put("Recherche", 54);
+ attrMapDe.put("Investigación", 54);
+ attrMapDe.put("Ricerca", 54);
+ attrMapDe.put("Puzzle / Mystery", 55);
+ attrMapDe.put("Rätsel", 55);
+ attrMapDe.put("Puzzle / Misterio", 55);
+ attrMapDe.put("Puzzle / Mystery", 55);
+ attrMapDe.put("Arithmetical problem", 56);
+ attrMapDe.put("Rechenaufgabe", 56);
+ attrMapDe.put("Problema matemático", 56);
+ attrMapDe.put("Problema matematico", 56);
+ attrMapDe.put("Ask owner for start conditions", 58);
+ attrMapDe.put("Startbedingungen beim Owner erfragen", 58);
+ attrMapDe.put("Ask owner for start conditions", 58);
+ attrMapDe.put("Ask owner for start conditions", 58);
+ attrMapPl.put("Wheelchair accessible", 44);
+ attrMapPl.put("Dostępna dla niepełnosprawnych", 44);
+ attrMapPl.put("rollstuhltauglich", 44);
+ attrMapDe.put("Near the parking area", 24);
+ attrMapDe.put("nahe beim Auto", 24);
+ attrMapDe.put("Cerca de un Parking", 24);
+ attrMapDe.put("Vicino all'area di parcheggio", 24);
+ attrMapPl.put("Access only by walk", 84);
+ attrMapPl.put("Dostępna tylko pieszo", 84);
+ attrMapDe.put("Long walk", 25);
+ attrMapDe.put("längere Wanderung", 25);
+ attrMapDe.put("Larga caminata", 25);
+ attrMapDe.put("Lunga camminata", 25);
+ attrMapDe.put("Swamp, marsh or wading", 26);
+ attrMapDe.put("sumpfig/matschiges Gelände / waten", 26);
+ attrMapDe.put("Pantano / terreno fangoso", 26);
+ attrMapDe.put("Palude o marcita", 26);
+ attrMapDe.put("Hilly area", 27);
+ attrMapDe.put("hügeliges Gelände", 27);
+ attrMapDe.put("Terreno montañoso", 27);
+ attrMapDe.put("Area collinare", 27);
+ attrMapDe.put("Some climbing (no gear needed)", 28);
+ attrMapDe.put("leichtes Klettern (ohne Ausrüstung)", 28);
+ attrMapDe.put("fácil de subir (sin equipo)", 28);
+ attrMapDe.put("Arrampicata (attrezzatura non necessaria)", 28);
+ attrMapDe.put("Swimming required", 29);
+ attrMapDe.put("Schwimmen erforderlich", 29);
+ attrMapDe.put("Requiere nadar", 29);
+ attrMapDe.put("Nuoto necessario", 29);
+ attrMapDe.put("Access or parking fee", 36);
+ attrMapDe.put("Zugangs- bzw. Parkentgelt", 36);
+ attrMapDe.put("Acceso o parking pagando", 36);
+ attrMapDe.put("Tassa di ingresso o di parcheggio", 36);
+ attrMapPl.put("Bikes allowed", 85);
+ attrMapPl.put("Dostępna rowerem", 85);
+ attrMapPl.put("Hidden in natural surroundings (forests, mountains, etc.)", 60);
+ attrMapPl.put("Umiejscowiona na łonie natury (lasy, góry, itp.)", 60);
+ attrMapPl.put("Historic site", 61);
+ attrMapPl.put("Miejsce historyczne", 61);
+ attrMapDe.put("Point of interest", 30);
+ attrMapDe.put("interessanter Ort", 30);
+ attrMapDe.put("Punto de interes", 30);
+ attrMapDe.put("Punto di interesse", 30);
+ attrMapDe.put("Hidden wihin enclosed rooms (caves, buildings etc.)", 33);
+ attrMapDe.put("in geschlossenen Räumen (Höhle, Gebäude, etc.)", 33);
+ attrMapDe.put("en espacios confinados (cuevas, edificios, etc)", 33);
+ attrMapDe.put("All'interno di stanze chiuse (caverne, edifici, ecc.)", 33);
+ attrMapDe.put("Hidden under water", 34);
+ attrMapDe.put("Im Wasser versteckt", 34);
+ attrMapDe.put("En el agua", 34);
+ attrMapDe.put("Nell'acqua", 34);
+ attrMapDe.put("Parking area nearby", 18);
+ attrMapDe.put("Parkplatz in der Nähe", 18);
+ attrMapDe.put("Parking cercano", 18);
+ attrMapDe.put("Parcheggio nei pressi", 18);
+ attrMapDe.put("Public transportation", 19);
+ attrMapDe.put("erreichbar mit ÖVM", 19);
+ attrMapDe.put("Transporte Público", 19);
+ attrMapDe.put("Trasporto pubblico", 19);
+ attrMapDe.put("Drinking water nearby", 20);
+ attrMapDe.put("Trinkwasser in der Nähe", 20);
+ attrMapDe.put("Agua potable en las cercanias", 20);
+ attrMapDe.put("Acqua potabile nei pressi", 20);
+ attrMapDe.put("Public restrooms nearby", 21);
+ attrMapDe.put("öffentliche Toilette in der Nähe", 21);
+ attrMapDe.put("Aseos públicos cercanos", 21);
+ attrMapDe.put("Bagni pubblici nei pressi", 21);
+ attrMapDe.put("Public phone nearby", 22);
+ attrMapDe.put("Telefon in der Nähe", 22);
+ attrMapDe.put("Teléfono Público en las cercanias", 22);
+ attrMapDe.put("Telefono pubblico nei pressi", 22);
+ attrMapDe.put("First aid available", 23);
+ attrMapDe.put("Erste Hilfe verfügbar", 23);
+ attrMapDe.put("Disponible socorro rapido", 23);
+ attrMapDe.put("Disponibile pronto soccorso", 23);
+ attrMapDe.put("Available 24/7", 38);
+ attrMapDe.put("rund um die Uhr machbar", 38);
+ attrMapDe.put("Disponible las 24 horas", 38);
+ attrMapDe.put("Disponibile 24 ore", 38);
+ attrMapDe.put("Not 24/7", 39);
+ attrMapPl.put("Not 24/7", 80);
+ attrMapDe.put("Dostępna w określonych godzinach", 39);
+ attrMapPl.put("Dostępna w określonych godzinach", 80);
+ attrMapDe.put("nur zu bestimmten Uhrzeiten", 39);
+ attrMapPl.put("nur zu bestimmten Uhrzeiten", 80);
+ attrMapDe.put("Sólo disponible a ciertas horas", 39);
+ attrMapPl.put("Sólo disponible a ciertas horas", 80);
+ attrMapDe.put("Disponibile solo in certi orari", 39);
+ attrMapPl.put("Disponibile solo in certi orari", 80);
+ attrMapDe.put("Not recommended at night", 40);
+ attrMapDe.put("nur tagüber", 40);
+ attrMapDe.put("solo por el día", 40);
+ attrMapDe.put("solo di giorno", 40);
+ attrMapPl.put("Recommended at night", 91);
+ attrMapPl.put("Zalecane szukanie nocÄ…", 91);
+ attrMapPl.put("am besten nachts findbar", 91);
+ attrMapDe.put("Only at night", 1);
+ attrMapDe.put("nur bei Nacht", 1);
+ attrMapDe.put("Sólo por la noche", 1);
+ attrMapDe.put("Solo di notte", 1);
+ attrMapDe.put("All seasons", 42);
+ attrMapDe.put("ganzjähig zugänglich", 42);
+ attrMapDe.put("Todas las temporadas", 42);
+ attrMapDe.put("Tutte le stagioni", 42);
+ attrMapDe.put("Only available during specified seasons", 60);
+ attrMapDe.put("Nur zu bestimmten Zeiten im Jahr", 60);
+ attrMapDe.put("Sólo disponible durante las estaciones especificadas", 60);
+ attrMapDe.put("Disponibile solo in certe stagioni", 60);
+ attrMapDe.put("Breeding season / protected nature", 43);
+ attrMapDe.put("Brutsaison / Naturschutz", 43);
+ attrMapDe.put("Temporada de reproducción / protección de la naturaleza", 43);
+ attrMapDe.put("Stagione di riproduzione / natura protetta", 43);
+ attrMapDe.put("Available during winter", 44);
+ attrMapDe.put("schneesicheres Versteck", 44);
+ attrMapDe.put("Nieve en el escondite", 44);
+ attrMapDe.put("Luogo a prova di neve", 44);
+ attrMapDe.put("Not at high water level", 41);
+ attrMapDe.put("nicht bei Hochwasser oder Flut", 41);
+ attrMapDe.put("Compass required", 47);
+ attrMapPl.put("Compass required", 47);
+ attrMapDe.put("Potrzebny kompas", 47);
+ attrMapPl.put("Potrzebny kompas", 47);
+ attrMapDe.put("Kompass", 47);
+ attrMapPl.put("Kompass", 47);
+ attrMapDe.put("Brújula", 47);
+ attrMapPl.put("Brújula", 47);
+ attrMapDe.put("Bussola", 47);
+ attrMapPl.put("Bussola", 47);
+ attrMapPl.put("Take something to write", 48);
+ attrMapPl.put("Weź coś do pisania", 48);
+ attrMapPl.put("You may need a shovel", 81);
+ attrMapPl.put("Potrzebna łopatka", 81);
+ attrMapDe.put("Flashlight required", 48);
+ attrMapPl.put("Flashlight required", 82);
+ attrMapDe.put("Potrzebna latarka", 48);
+ attrMapPl.put("Potrzebna latarka", 82);
+ attrMapDe.put("Taschenlampe", 48);
+ attrMapPl.put("Taschenlampe", 82);
+ attrMapDe.put("Linterna", 48);
+ attrMapPl.put("Linterna", 82);
+ attrMapDe.put("Lampada tascabile", 48);
+ attrMapPl.put("Lampada tascabile", 82);
+ attrMapDe.put("Climbing gear required", 49);
+ attrMapDe.put("Kletterzeug", 49);
+ attrMapDe.put("Equipo de escalada", 49);
+ attrMapDe.put("Attrezzatura per arrampicata", 49);
+ attrMapDe.put("Cave equipment required", 50);
+ attrMapDe.put("Höhlenzeug", 50);
+ attrMapDe.put("Equipación para cuevas", 50);
+ attrMapDe.put("Attrezzatura per grotta", 50);
+ attrMapDe.put("Diving equipment required", 51);
+ attrMapDe.put("Taucherausrüstung", 51);
+ attrMapDe.put("Diving equipment", 51);
+ attrMapDe.put("Equipo de buceo", 51);
+ attrMapDe.put("Special tools required", 46);
+ attrMapPl.put("Special tools required", 83);
+ attrMapDe.put("Wymagany dodatkowy sprzęt", 46);
+ attrMapPl.put("Wymagany dodatkowy sprzęt", 83);
+ attrMapDe.put("spezielle Ausrüstung", 46);
+ attrMapPl.put("spezielle Ausrüstung", 83);
+ attrMapDe.put("Equipamiento especial", 46);
+ attrMapPl.put("Equipamiento especial", 83);
+ attrMapDe.put("Equipaggiamento speciale", 46);
+ attrMapPl.put("Equipaggiamento speciale", 83);
+ attrMapDe.put("Requires a boat", 52);
+ attrMapPl.put("Requires a boat", 86);
+ attrMapDe.put("Wymaga sprzętu pływającego", 52);
+ attrMapPl.put("Wymaga sprzętu pływającego", 86);
+ attrMapDe.put("Wasserfahrzeug", 52);
+ attrMapPl.put("Wasserfahrzeug", 86);
+ attrMapDe.put("Barca", 52);
+ attrMapPl.put("Barca", 86);
+ attrMapDe.put("Barca", 52);
+ attrMapPl.put("Barca", 86);
+ attrMapDe.put("No GPS required", 35);
+ attrMapDe.put("ohne GPS findbar", 35);
+ attrMapDe.put("Sin GPS", 35);
+ attrMapDe.put("Senza GPS", 35);
+ attrMapDe.put("Dangerous area", 9);
+ attrMapPl.put("Dangerous area", 90);
+ attrMapDe.put("Skrzynka niebezpieczna", 9);
+ attrMapPl.put("Skrzynka niebezpieczna", 90);
+ attrMapDe.put("gefährliches Gebiet", 9);
+ attrMapPl.put("gefährliches Gebiet", 90);
+ attrMapDe.put("Zona Peligrosa", 9);
+ attrMapPl.put("Zona Peligrosa", 90);
+ attrMapDe.put("Area pericolosa", 9);
+ attrMapPl.put("Area pericolosa", 90);
+ attrMapDe.put("Active railway nearby", 10);
+ attrMapDe.put("aktive Eisenbahnlinie in der Nähe", 10);
+ attrMapDe.put("Cerca del ferrocarril activo", 10);
+ attrMapDe.put("Ferrovia attiva nei pressi", 10);
+ attrMapDe.put("Cliff / Rocks", 11);
+ attrMapDe.put("Klippen / Felsen", 11);
+ attrMapDe.put("Acantilado / Rocas", 11);
+ attrMapDe.put("Scogliera / Rocce", 11);
+ attrMapDe.put("Hunting", 12);
+ attrMapDe.put("Jagdgebiet", 12);
+ attrMapDe.put("Zona de Caza", 12);
+ attrMapDe.put("Caccia", 12);
+ attrMapDe.put("Thorns", 13);
+ attrMapDe.put("Dornen", 13);
+ attrMapDe.put("Espinas", 13);
+ attrMapDe.put("Spine", 13);
+ attrMapDe.put("Ticks", 14);
+ attrMapDe.put("Zecken", 14);
+ attrMapDe.put("Garrapatas", 14);
+ attrMapDe.put("Zecche", 14);
+ attrMapDe.put("Abandoned mines", 15);
+ attrMapDe.put("Folgen des Bergbaus", 15);
+ attrMapDe.put("Mina abandonada", 15);
+ attrMapDe.put("Miniere abbandonate", 15);
+ attrMapDe.put("Poisonous plants", 16);
+ attrMapDe.put("giftige Pflanzen", 16);
+ attrMapDe.put("Planta venenosa", 16);
+ attrMapDe.put("Piante velenose", 16);
+ attrMapDe.put("Dangerous animals", 17);
+ attrMapDe.put("giftige/gefährliche Tiere", 17);
+ attrMapDe.put("Animales Peligrosos", 17);
+ attrMapDe.put("Animali pericolosi", 17);
+ attrMapPl.put("Quick cache", 40);
+ attrMapPl.put("Szybka skrzynka", 40);
+ attrMapDe.put("Overnight stay necessary", 37);
+ attrMapDe.put("Übernachtung erforderlich", 37);
+ attrMapDe.put("Necesario pernoctar", 37);
+ attrMapDe.put("Necessario pernottamento", 37);
+ attrMapPl.put("Take your children", 41);
+ attrMapPl.put("Można zabrać dzieci", 41);
+ attrMapDe.put("Suited for children (10-12 yo)", 59);
+ attrMapDe.put("kindgerecht (10-12 Jahre)", 59);
+ attrMapDe.put("Apto para niños (10-12 años)", 59);
+ attrMapDe.put("Suited for children (10-12 anni)", 59);
+ // first trailer line
+
+ }
+
+ public static int getOcDeId(final String name) {
+
+ int result = 0;
+
+ if (attrMapDe.containsKey(name)) {
+ result = attrMapDe.get(name);
+ }
+ return result;
+ }
+}
diff --git a/main/src/cgeo/geocaching/connector/oc/OC11XMLParser.java b/main/src/cgeo/geocaching/connector/oc/OC11XMLParser.java
deleted file mode 100644
index d03062f..0000000
--- a/main/src/cgeo/geocaching/connector/oc/OC11XMLParser.java
+++ /dev/null
@@ -1,762 +0,0 @@
-package cgeo.geocaching.connector.oc;
-
-import cgeo.geocaching.Geocache;
-import cgeo.geocaching.Image;
-import cgeo.geocaching.LogEntry;
-import cgeo.geocaching.R;
-import cgeo.geocaching.Settings;
-import cgeo.geocaching.cgeoapplication;
-import cgeo.geocaching.connector.ConnectorFactory;
-import cgeo.geocaching.connector.IConnector;
-import cgeo.geocaching.connector.gc.GCConnector;
-import cgeo.geocaching.enumerations.CacheAttribute;
-import cgeo.geocaching.enumerations.CacheSize;
-import cgeo.geocaching.enumerations.CacheType;
-import cgeo.geocaching.enumerations.LogType;
-import cgeo.geocaching.geopoint.Geopoint;
-import cgeo.geocaching.utils.Log;
-
-import org.apache.commons.lang3.StringUtils;
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-
-import android.content.res.Resources;
-import android.sax.Element;
-import android.sax.EndElementListener;
-import android.sax.EndTextElementListener;
-import android.sax.RootElement;
-import android.sax.StartElementListener;
-import android.util.Xml;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.TimeZone;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class OC11XMLParser {
-
- private static final String[] MARKUP = new String[] { "p", "span" };
- private static Pattern STRIP_DATE = Pattern.compile("\\+0([0-9]){1}\\:00");
- private static Pattern LOCAL_URL = Pattern.compile("href=\"(.*)\"");
- private static final int CACHE_PARSE_LIMIT = 250;
- private static final Resources res = cgeoapplication.getInstance().getResources();
- private static final Pattern WHITESPACE = Pattern.compile("<p>(\\s|&nbsp;)*</p>");
-
-
- private static ImageHolder imageHolder = null;
-
- private static class CacheHolder {
- public Geocache cache;
- public String latitude;
- public String longitude;
- }
-
- private static class CacheLog {
- public String id;
- public String cacheId;
- public LogEntry logEntry;
- }
-
- private static class CacheDescription {
- public String cacheId;
- public String shortDesc;
- public String desc;
- public String hint;
- }
-
- private static class ImageHolder {
- public String url;
- public String objectId;
- protected String title;
- protected boolean isSpoiler = false;
- }
-
- private static Date parseFullDate(final String date) {
- final SimpleDateFormat ISO8601DATEFORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
- ISO8601DATEFORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
- final String strippedDate = STRIP_DATE.matcher(date).replaceAll("+0$100");
- try {
- return ISO8601DATEFORMAT.parse(strippedDate);
- } catch (ParseException e) {
- Log.e("OC11XMLParser.parseFullDate", e);
- }
- return null;
- }
-
- private static Date parseDayDate(final String date) {
- final SimpleDateFormat ISO8601DATEFORMAT = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
- ISO8601DATEFORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
- final String strippedDate = STRIP_DATE.matcher(date).replaceAll("+0$100");
- try {
- return ISO8601DATEFORMAT.parse(strippedDate);
- } catch (ParseException e) {
- Log.e("OC11XMLParser.parseDayDate", e);
- }
- return null;
- }
-
- private static CacheSize getCacheSize(final String sizeId) {
- try {
- int size = Integer.parseInt(sizeId);
-
- switch (size) {
- case 1:
- return CacheSize.OTHER;
- case 2:
- return CacheSize.MICRO;
- case 3:
- return CacheSize.SMALL;
- case 4:
- return CacheSize.REGULAR;
- case 5:
- case 6:
- return CacheSize.LARGE;
- case 8:
- return CacheSize.VIRTUAL;
- default:
- break;
- }
- } catch (NumberFormatException e) {
- Log.e("OC11XMLParser.getCacheSize", e);
- }
- return CacheSize.NOT_CHOSEN;
- }
-
- private static CacheType getCacheType(final String typeId) {
- try {
- int type = Integer.parseInt(typeId);
- switch (type) {
- case 1: // Other/unbekannter Cachetyp
- return CacheType.UNKNOWN;
- case 2: // Trad./normaler Cache
- return CacheType.TRADITIONAL;
- case 3: // Multi/Multicache
- return CacheType.MULTI;
- case 4: // Virt./virtueller Cache
- return CacheType.VIRTUAL;
- case 5: // ICam./Webcam-Cache
- return CacheType.WEBCAM;
- case 6: // Event/Event-Cache
- return CacheType.EVENT;
- case 7: // Quiz/Rätselcache
- return CacheType.MYSTERY;
- case 8: // Math/Mathe-/Physikcache
- return CacheType.MYSTERY;
- case 9: // Moving/beweglicher Cache
- return CacheType.VIRTUAL;
- case 10: // Driv./Drive-In
- return CacheType.TRADITIONAL;
- default:
- return CacheType.UNKNOWN;
- }
- } catch (NumberFormatException e) {
- Log.e("OC11XMLParser.getCacheType", e);
- }
- return CacheType.UNKNOWN;
- }
-
- private static LogType getLogType(final int typeId) {
- switch (typeId) {
- case 1:
- return LogType.FOUND_IT;
- case 2:
- return LogType.DIDNT_FIND_IT;
- case 3:
- return LogType.NOTE;
- case 7:
- return LogType.ATTENDED;
- case 8:
- return LogType.WILL_ATTEND;
- default:
- return LogType.UNKNOWN;
- }
- }
-
- private static void setCacheStatus(final int statusId, final Geocache cache) {
- switch (statusId) {
- case 1:
- cache.setArchived(false);
- cache.setDisabled(false);
- break;
- case 2:
- cache.setArchived(false);
- cache.setDisabled(true);
- break;
- default:
- cache.setArchived(true);
- cache.setDisabled(false);
- break;
- }
- }
-
- private static void resetCache(final CacheHolder cacheHolder) {
- cacheHolder.cache = new Geocache(null);
- cacheHolder.cache.setReliableLatLon(true);
- cacheHolder.cache.setDescription(StringUtils.EMPTY);
- cacheHolder.latitude = "0.0";
- cacheHolder.longitude = "0.0";
- }
-
- private static void resetLog(final CacheLog log) {
- log.cacheId = StringUtils.EMPTY;
- log.logEntry = new LogEntry("", 0, LogType.UNKNOWN, "");
- }
-
- private static void resetDesc(final CacheDescription desc) {
- desc.cacheId = StringUtils.EMPTY;
- desc.shortDesc = StringUtils.EMPTY;
- desc.desc = StringUtils.EMPTY;
- desc.hint = StringUtils.EMPTY;
- }
-
- private static int attributeId;
-
- public static Collection<Geocache> parseCaches(final InputStream stream) throws IOException {
- // parse and return caches without filtering
- return parseCaches(stream, true);
- }
-
- public static Collection<Geocache> parseCachesFiltered(final InputStream stream) throws IOException {
- // parse caches and filter result
- return parseCaches(stream, false);
- }
-
- private static Collection<Geocache> parseCaches(final InputStream stream, boolean ignoreFiltersIn) throws IOException {
-
- final Map<String, Geocache> caches = new HashMap<String, Geocache>();
- final Map<String, LogEntry> logs = new HashMap<String, LogEntry>();
-
- final CacheHolder cacheHolder = new CacheHolder();
- final CacheLog logHolder = new CacheLog();
- final CacheDescription descHolder = new CacheDescription();
-
- final RootElement root = new RootElement("oc11xml");
- final Element cacheNode = root.getChild("cache");
-
- final boolean ignoreFilters = ignoreFiltersIn;
-
- // cache
- cacheNode.setStartElementListener(new StartElementListener() {
-
- @Override
- public void start(Attributes attributes) {
- resetCache(cacheHolder);
- }
-
- });
-
- cacheNode.setEndElementListener(new EndElementListener() {
-
- @Override
- public void end() {
- Geocache cache = cacheHolder.cache;
- Geopoint coords = new Geopoint(cacheHolder.latitude, cacheHolder.longitude);
- cache.setCoords(coords);
- if (caches.size() < CACHE_PARSE_LIMIT && isValid(cache) && (ignoreFilters || !isExcluded(cache))) {
- cache.setDetailedUpdatedNow();
- caches.put(cache.getCacheId(), cache);
- }
- }
-
- private boolean isExcluded(Geocache cache) {
- if (cache.isArchived()) {
- return true;
- }
- if (cache.isDisabled() && Settings.isExcludeDisabledCaches()) {
- return true;
- }
- if ((cache.isFound() || cache.isOwner()) && Settings.isExcludeMyCaches()) {
- return true;
- }
- return !Settings.getCacheType().contains(cache);
- }
-
- private boolean isValid(Geocache cache) {
- return StringUtils.isNotBlank(cache.getGeocode()) && !cache.getCoords().equals(Geopoint.ZERO);
- }
- });
-
- // cache.id
- cacheNode.getChild("id").setEndTextElementListener(new EndTextElementListener() {
-
- @Override
- public void end(String body) {
- cacheHolder.cache.setCacheId(body);
- }
- });
-
- // cache.longitude
- cacheNode.getChild("longitude").setEndTextElementListener(new EndTextElementListener() {
-
- @Override
- public void end(String body) {
- String longitude = body.trim();
- if (StringUtils.isNotBlank(longitude)) {
- cacheHolder.longitude = longitude;
- }
- }
- });
-
- // cache.latitude
- cacheNode.getChild("latitude").setEndTextElementListener(new EndTextElementListener() {
-
- @Override
- public void end(String body) {
- String latitude = body.trim();
- if (StringUtils.isNotBlank(latitude)) {
- cacheHolder.latitude = latitude;
- }
- }
- });
-
- // cache.name
- cacheNode.getChild("name").setEndTextElementListener(new EndTextElementListener() {
-
- @Override
- public void end(String body) {
- final String content = body.trim();
- cacheHolder.cache.setName(content);
- }
- });
-
- // cache.waypoints[oc]
- cacheNode.getChild("waypoints").setStartElementListener(new StartElementListener() {
-
- @Override
- public void start(Attributes attrs) {
- if (attrs.getIndex("oc") > -1) {
- cacheHolder.cache.setGeocode(attrs.getValue("oc"));
- }
- if (attrs.getIndex("gccom") > -1) {
- String gccode = attrs.getValue("gccom");
- if (!StringUtils.isBlank(gccode)) {
- cacheHolder.cache.setDescription(res.getString(R.string.cache_listed_on, GCConnector.getInstance().getName()) + ": <a href=\"http://coord.info/" + gccode + "\">" + gccode + "</a><br /><br />");
- }
- }
- }
- });
-
- // cache.type[id]
- cacheNode.getChild("type").setStartElementListener(new StartElementListener() {
-
- @Override
- public void start(Attributes attrs) {
- if (attrs.getIndex("id") > -1) {
- final String typeId = attrs.getValue("id");
- cacheHolder.cache.setType(getCacheType(typeId));
- }
- }
- });
-
- // cache.status[id]
- cacheNode.getChild("status").setStartElementListener(new StartElementListener() {
-
- @Override
- public void start(Attributes attrs) {
- if (attrs.getIndex("id") > -1) {
- try {
- final int statusId = Integer.parseInt(attrs.getValue("id"));
- setCacheStatus(statusId, cacheHolder.cache);
- } catch (NumberFormatException e) {
- Log.w(String.format("Failed to parse status of cache '%s'.", cacheHolder.cache.getGeocode()));
- }
- }
- }
- });
-
- // cache.size[id]
- cacheNode.getChild("size").setStartElementListener(new StartElementListener() {
-
- @Override
- public void start(Attributes attrs) {
- if (attrs.getIndex("id") > -1) {
- final String typeId = attrs.getValue("id");
- cacheHolder.cache.setSize(getCacheSize(typeId));
- }
- }
- });
-
- // cache.difficulty
- cacheNode.getChild("difficulty").setEndTextElementListener(new EndTextElementListener() {
-
- @Override
- public void end(String body) {
- final String content = body.trim();
- try {
- cacheHolder.cache.setDifficulty(Float.valueOf(content));
- } catch (NumberFormatException e) {
- Log.e("OC11XMLParser: unknown difficulty " + content, e);
- }
- }
- });
-
- // cache.terrain
- cacheNode.getChild("terrain").setEndTextElementListener(new EndTextElementListener() {
-
- @Override
- public void end(String body) {
- final String content = body.trim();
- try {
- cacheHolder.cache.setTerrain(Float.valueOf(content));
- } catch (NumberFormatException e) {
- Log.e("OC11XMLParser: unknown terrain " + content, e);
- }
- }
- });
-
- // cache.datehidden
- cacheNode.getChild("datehidden").setEndTextElementListener(new EndTextElementListener() {
-
- @Override
- public void end(String body) {
- final String content = body.trim();
- cacheHolder.cache.setHidden(parseFullDate(content));
- }
- });
-
- // cache.userid
- final Element useridNode = cacheNode.getChild("userid");
-
- useridNode.setStartElementListener(new StartElementListener() {
-
- @Override
- public void start(Attributes attributes) {
- if (attributes.getIndex("id") > -1) {
- cacheHolder.cache.setOwnerUserId(attributes.getValue("id"));
- }
- }
- });
-
- useridNode.setEndTextElementListener(new EndTextElementListener() {
-
- @Override
- public void end(String body) {
- cacheHolder.cache.setOwnerDisplayName(body);
- }
- });
-
- // cache.attributes.attribute
- final Element attributeNode = cacheNode.getChild("attributes").getChild("attribute");
-
- attributeNode.setStartElementListener(new StartElementListener() {
-
- @Override
- public void start(Attributes attributes) {
- if (attributes.getIndex("id") > -1) {
- try {
- attributeId = Integer.parseInt(attributes.getValue("id"));
- } catch (NumberFormatException e) {
- Log.w(String.format("Failed to parse attribute id of cache '%s'.", cacheHolder.cache.getGeocode()));
- }
- }
- }
- });
-
- attributeNode.setEndTextElementListener(new EndTextElementListener() {
- @Override
- public void end(String body) {
- CacheAttribute attribute = CacheAttribute.getByOcId(attributeId);
- if (attribute != null) {
- // semantic of attributes on opencaching is always "yes"
- cacheHolder.cache.getAttributes().add(attribute.getAttributeName(true));
- }
- else {
- if (StringUtils.isNotBlank(body)) {
- cacheHolder.cache.getAttributes().add(body.trim());
- }
- }
- }
- });
-
- // cachedesc
- final Element cacheDesc = root.getChild("cachedesc");
-
- cacheDesc.setStartElementListener(new StartElementListener() {
-
- @Override
- public void start(Attributes attributes) {
- resetDesc(descHolder);
- }
- });
-
- cacheDesc.setEndElementListener(new EndElementListener() {
-
- @Override
- public void end() {
- final Geocache cache = caches.get(descHolder.cacheId);
- if (cache != null) {
- cache.setShortDescription(descHolder.shortDesc);
- cache.setDescription(cache.getDescription() + descHolder.desc);
- cache.setHint(descHolder.hint);
- }
- }
- });
-
- // cachedesc.cacheid
- cacheDesc.getChild("cacheid").setEndTextElementListener(new EndTextElementListener() {
-
- @Override
- public void end(String body) {
- descHolder.cacheId = body;
- }
- });
-
- // cachedesc.desc
- cacheDesc.getChild("shortdesc").setEndTextElementListener(new EndTextElementListener() {
-
- @Override
- public void end(String body) {
- final String content = body.trim();
- descHolder.shortDesc = linkify(stripEmptyText(content));
- }
- });
-
- // cachedesc.desc
- cacheDesc.getChild("desc").setEndTextElementListener(new EndTextElementListener() {
-
- @Override
- public void end(String body) {
- final String content = body.trim();
- descHolder.desc = linkify(stripEmptyText(content));
- }
- });
-
- // cachedesc.hint
- cacheDesc.getChild("hint").setEndTextElementListener(new EndTextElementListener() {
-
- @Override
- public void end(String body) {
- descHolder.hint = body.trim();
- }
- });
-
- // cachelog
- final Element cacheLog = root.getChild("cachelog");
-
- cacheLog.setStartElementListener(new StartElementListener() {
-
- @Override
- public void start(Attributes attrs) {
- resetLog(logHolder);
- }
- });
-
- cacheLog.setEndElementListener(new EndElementListener() {
-
- @Override
- public void end() {
- final Geocache cache = caches.get(logHolder.cacheId);
- if (cache != null && logHolder.logEntry.type != LogType.UNKNOWN) {
- logs.put(logHolder.id, logHolder.logEntry);
- cache.getLogs().add(0, logHolder.logEntry);
- if ((logHolder.logEntry.type == LogType.FOUND_IT || logHolder.logEntry.type == LogType.ATTENDED)
- && StringUtils.equalsIgnoreCase(logHolder.logEntry.author, Settings.getOCConnectorUserName())) {
- cache.setFound(true);
- cache.setVisitedDate(logHolder.logEntry.date);
- }
- }
- }
- });
-
- // cachelog.id
- cacheLog.getChild("id").setEndTextElementListener(new EndTextElementListener() {
-
- @Override
- public void end(String body) {
- logHolder.id = StringUtils.trim(body);
- }
- });
-
- // cachelog.cacheid
- cacheLog.getChild("cacheid").setEndTextElementListener(new EndTextElementListener() {
-
- @Override
- public void end(String body) {
- logHolder.cacheId = body;
- }
- });
-
- // cachelog.date
- cacheLog.getChild("date").setEndTextElementListener(new EndTextElementListener() {
-
- @Override
- public void end(String body) {
- try {
- logHolder.logEntry.date = parseDayDate(body).getTime();
- } catch (NullPointerException e) {
- Log.w("Failed to parse log date", e);
- }
- }
- });
-
- // cachelog.logtype
- cacheLog.getChild("logtype").setStartElementListener(new StartElementListener() {
-
- @Override
- public void start(Attributes attrs) {
- if (attrs.getIndex("id") > -1) {
- final String id = attrs.getValue("id");
- try {
- final int typeId = Integer.parseInt(id);
- logHolder.logEntry.type = getLogType(typeId);
- } catch (NumberFormatException e) {
- Log.e("OC11XMLParser, unknown logtype " + id, e);
- }
- }
- }
- });
-
- // cachelog.userid
- cacheLog.getChild("userid").setEndTextElementListener(new EndTextElementListener() {
-
- @Override
- public void end(String finderName) {
- logHolder.logEntry.author = finderName;
- }
- });
-
- // cachelog.text
- cacheLog.getChild("text").setEndTextElementListener(new EndTextElementListener() {
-
- @Override
- public void end(String logText) {
- logHolder.logEntry.log = stripEmptyText(logText);
- }
- });
-
- // pictures
- final Element picture = root.getChild("picture");
-
- picture.setStartElementListener(new StartElementListener() {
-
- @Override
- public void start(Attributes attrs) {
- imageHolder = new ImageHolder();
- }
- });
-
- picture.setEndElementListener(new EndElementListener() {
-
- @Override
- public void end() {
- if (imageHolder.isSpoiler) {
- final Geocache cache = caches.get(imageHolder.objectId);
- if (cache != null) {
- Image spoiler = new Image(imageHolder.url, imageHolder.title);
- cache.addSpoiler(spoiler);
- }
- }
- else {
- final LogEntry log = logs.get(imageHolder.objectId);
- if (log != null) {
- log.addLogImage(new Image(imageHolder.url, imageHolder.title));
- }
- }
- }
- });
-
- // picture.object
- picture.getChild("object").setEndTextElementListener(new EndTextElementListener() {
-
- @Override
- public void end(String body) {
- imageHolder.objectId = StringUtils.trim(body);
- }
- });
-
- // picture.title
- picture.getChild("title").setEndTextElementListener(new EndTextElementListener() {
-
- @Override
- public void end(String body) {
- imageHolder.title = StringUtils.trim(body);
- }
- });
-
- // picture.url
- picture.getChild("url").setEndTextElementListener(new EndTextElementListener() {
-
- @Override
- public void end(String body) {
- imageHolder.url = StringUtils.trim(body);
- }
- });
-
- // picture.attributes
- picture.getChild("attributes").setStartElementListener(new StartElementListener() {
-
- @Override
- public void start(Attributes attributes) {
- if (attributes.getIndex("spoiler") > -1) {
- String spoiler = attributes.getValue("spoiler");
- imageHolder.isSpoiler = ("1".equals(spoiler));
- }
- }
- });
-
- try {
- Xml.parse(stream, Xml.Encoding.UTF_8, root.getContentHandler());
- return caches.values();
- } catch (SAXException e) {
- Log.e("Cannot parse .gpx file as oc11xml: could not parse XML", e);
- return null;
- }
- }
-
- /**
- * Converts local links to absolute links targeting the OC website.
- */
- private static String linkify(String input) {
- String result = input;
- Matcher matcher = LOCAL_URL.matcher(result);
- while (matcher.find()) {
- String url = matcher.group(1);
- if (!url.contains(":/")) {
- IConnector ocConnector = ConnectorFactory.getConnector("OCXXX");
- String prefix = "http://" + ocConnector.getHost() + "/";
- result = StringUtils.replace(result, url, prefix + url);
- matcher = LOCAL_URL.matcher(result);
- }
- }
- return result;
- }
-
- /**
- * Removes some unneeded markup and whitespace. Log texts are typically encapsulated in paragraph tags which lead to
- * more empty space on rendering.
- */
- protected static String stripEmptyText(String input) {
- final Matcher matcher = WHITESPACE.matcher(input);
- String result = matcher.replaceAll("").trim();
- if (!StringUtils.startsWith(result, "<")) {
- return result;
- }
- return stripMarkup(result);
- }
-
- private static String stripMarkup(final String input) {
- String result = input;
- for (String tagName : MARKUP) {
- final String startTag = "<" + tagName + ">";
- if (StringUtils.startsWith(result, startTag)) {
- final String endTag = "</" + tagName + ">";
- if (StringUtils.endsWith(result, endTag)) {
- String inner = result.substring(startTag.length(), result.length() - endTag.length()).trim();
- String nested = stripMarkup(inner);
- if (!nested.contains(startTag)) {
- result = nested;
- }
- }
- }
- }
- return result;
- }
-} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/connector/oc/OCApiConnector.java b/main/src/cgeo/geocaching/connector/oc/OCApiConnector.java
index 69cf8a4..3780c4d 100644
--- a/main/src/cgeo/geocaching/connector/oc/OCApiConnector.java
+++ b/main/src/cgeo/geocaching/connector/oc/OCApiConnector.java
@@ -23,7 +23,7 @@ public class OCApiConnector extends OCConnector implements ISearchByGeocode {
@Override
public String getLicenseText(final Geocache cache) {
// NOT TO BE TRANSLATED
- return "<a href=\"" + getCacheUrl(cache) + "\">" + getName() + "</a> data licensed under the Creative Commons BY-SA 3.0 License";
+ return "© " + cache.getOwnerDisplayName() + ", <a href=\"" + getCacheUrl(cache) + "\">" + getName() + "</a>, CC-BY-NC-ND, alle Logeinträge © jeweiliger Autor";
}
@Override
@@ -40,4 +40,8 @@ public class OCApiConnector extends OCConnector implements ISearchByGeocode {
// currently always active, but only for details download
return true;
}
+
+ public String getCK() {
+ return CryptUtils.rot13(cK);
+ }
}
diff --git a/main/src/cgeo/geocaching/connector/oc/OCApiLiveConnector.java b/main/src/cgeo/geocaching/connector/oc/OCApiLiveConnector.java
new file mode 100644
index 0000000..4e57831
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/oc/OCApiLiveConnector.java
@@ -0,0 +1,82 @@
+package cgeo.geocaching.connector.oc;
+
+import cgeo.geocaching.Geocache;
+import cgeo.geocaching.SearchResult;
+import cgeo.geocaching.cgData;
+import cgeo.geocaching.cgeoapplication;
+import cgeo.geocaching.connector.ILoggingManager;
+import cgeo.geocaching.connector.capability.ISearchByCenter;
+import cgeo.geocaching.connector.capability.ISearchByViewPort;
+import cgeo.geocaching.geopoint.Geopoint;
+import cgeo.geocaching.geopoint.Viewport;
+import cgeo.geocaching.utils.CryptUtils;
+
+import android.app.Activity;
+
+public class OCApiLiveConnector extends OCApiConnector implements ISearchByCenter, ISearchByViewPort {
+
+ private String cS;
+
+ public OCApiLiveConnector(String name, String host, String prefix, int cKResId, int cSResId) {
+ super(name, host, prefix, CryptUtils.rot13(cgeoapplication.getInstance().getResources().getString(cKResId)));
+
+ cS = CryptUtils.rot13(cgeoapplication.getInstance().getResources().getString(cSResId));
+ }
+
+ @Override
+ public SearchResult searchByViewport(Viewport viewport, String[] tokens) {
+ return new SearchResult(OkapiClient.getCachesBBox(viewport, this));
+ }
+
+ @Override
+ public SearchResult searchByCenter(Geopoint center) {
+
+ return new SearchResult(OkapiClient.getCachesAround(center, this));
+ }
+
+ public String getCS() {
+ return CryptUtils.rot13(cS);
+ }
+
+ @Override
+ public boolean supportsWatchList() {
+ return true;
+ }
+
+ @Override
+ public boolean addToWatchlist(Geocache cache) {
+ final boolean added = OkapiClient.setWatchState(cache, true, this);
+
+ if (added) {
+ cgData.saveChangedCache(cache);
+ }
+
+ return added;
+ }
+
+ @Override
+ public boolean removeFromWatchlist(Geocache cache) {
+ final boolean removed = OkapiClient.setWatchState(cache, false, this);
+
+ if (removed) {
+ cgData.saveChangedCache(cache);
+ }
+
+ return removed;
+ }
+
+ @Override
+ public boolean supportsLogging() {
+ return true;
+ }
+
+ @Override
+ public ILoggingManager getLoggingManager(Activity activity, Geocache cache) {
+ return new OkapiLoggingManager(activity, this, cache);
+ }
+
+ @Override
+ public boolean canLog(Geocache cache) {
+ return true;
+ }
+}
diff --git a/main/src/cgeo/geocaching/connector/oc/OCAuthorizationActivity.java b/main/src/cgeo/geocaching/connector/oc/OCAuthorizationActivity.java
new file mode 100644
index 0000000..779c1c5
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/oc/OCAuthorizationActivity.java
@@ -0,0 +1,109 @@
+package cgeo.geocaching.connector.oc;
+
+import cgeo.geocaching.R;
+import cgeo.geocaching.Settings;
+import cgeo.geocaching.cgeoapplication;
+import cgeo.geocaching.network.OAuthAuthorizationActivity;
+
+import org.apache.commons.lang3.tuple.ImmutablePair;
+
+public class OCAuthorizationActivity extends OAuthAuthorizationActivity {
+
+ private final int siteResId = R.string.auth_ocde;
+
+ public OCAuthorizationActivity() {
+ super("www.opencaching.de",
+ "/okapi/services/oauth/request_token",
+ "/okapi/services/oauth/authorize",
+ "/okapi/services/oauth/access_token",
+ false,
+ cgeoapplication.getInstance().getResources().getString(R.string.oc_de_okapi_consumer_key),
+ cgeoapplication.getInstance().getResources().getString(R.string.oc_de_okapi_consumer_secret));
+ }
+
+ @Override
+ protected ImmutablePair<String, String> getTempToken() {
+ return Settings.getTempOCDEToken();
+ }
+
+ @Override
+ protected void setTempTokens(String tokenPublic, String tokenSecret) {
+ Settings.setOCDETempTokens(tokenPublic, tokenSecret);
+ }
+
+ @Override
+ protected void setTokens(String tokenPublic, String tokenSecret, boolean enable) {
+ Settings.setOCDETokens(tokenPublic, tokenSecret, enable);
+ }
+
+ @Override
+ protected String getAuthTitle() {
+ return res.getString(siteResId);
+ }
+
+ @Override
+ protected String getAuthAgain() {
+ return res.getString(R.string.auth_again_oc);
+ }
+
+ @Override
+ protected String getErrAuthInitialize() {
+ return res.getString(R.string.err_auth_initialize);
+ }
+
+ @Override
+ protected String getAuthStart() {
+ return res.getString(R.string.auth_start_oc);
+ }
+
+ @Override
+ protected String getAuthDialogCompleted() {
+ return res.getString(R.string.auth_dialog_completed_oc, getAuthTitle());
+ }
+
+ @Override
+ protected String getErrAuthProcess() {
+ return res.getString(R.string.err_auth_process);
+ }
+
+ @Override
+ protected String getAuthDialogWait() {
+ return res.getString(R.string.auth_dialog_wait_oc, getAuthTitle());
+ }
+
+ @Override
+ protected String getAuthDialogPinTitle() {
+ return res.getString(R.string.auth_dialog_pin_title_oc);
+ }
+
+ @Override
+ protected String getAuthDialogPinMessage() {
+ return res.getString(R.string.auth_dialog_pin_message_oc, getAuthTitle());
+ }
+
+ @Override
+ protected String getAboutAuth1() {
+ return res.getString(R.string.about_auth_1_oc, getAuthTitle());
+ }
+
+ @Override
+ protected String getAboutAuth2() {
+ return res.getString(R.string.about_auth_2_oc, getAuthTitle(), getAuthTitle());
+ }
+
+ @Override
+ protected String getAuthAuthorize() {
+ return res.getString(R.string.auth_authorize_oc);
+ }
+
+ @Override
+ protected String getAuthPinHint() {
+ return res.getString(R.string.auth_pin_hint_oc, getAuthTitle());
+ }
+
+ @Override
+ protected String getAuthFinish() {
+ return res.getString(R.string.auth_finish_oc);
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/connector/oc/OCXMLApiConnector.java b/main/src/cgeo/geocaching/connector/oc/OCXMLApiConnector.java
deleted file mode 100644
index 43fdcfc..0000000
--- a/main/src/cgeo/geocaching/connector/oc/OCXMLApiConnector.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package cgeo.geocaching.connector.oc;
-
-import cgeo.geocaching.Geocache;
-import cgeo.geocaching.ICache;
-import cgeo.geocaching.SearchResult;
-import cgeo.geocaching.Settings;
-import cgeo.geocaching.connector.capability.ISearchByCenter;
-import cgeo.geocaching.connector.capability.ISearchByGeocode;
-import cgeo.geocaching.connector.capability.ISearchByViewPort;
-import cgeo.geocaching.geopoint.Geopoint;
-import cgeo.geocaching.geopoint.Viewport;
-import cgeo.geocaching.ui.Formatter;
-import cgeo.geocaching.utils.CancellableHandler;
-
-import org.apache.commons.lang3.StringUtils;
-
-public class OCXMLApiConnector extends OCConnector implements ISearchByGeocode, ISearchByCenter, ISearchByViewPort {
-
- private final static double SEARCH_DISTANCE_LIMIT = 15.0;
- private final static double NEARBY_SEARCH_DISTANCE = 5.0;
-
- public OCXMLApiConnector(String name, String host, String prefix) {
- super(name, host, prefix);
- }
-
- @Override
- public SearchResult searchByGeocode(final String geocode, final String guid, CancellableHandler handler) {
- final Geocache cache = OCXMLClient.getCache(geocode);
- if (cache == null) {
- return null;
- }
- return new SearchResult(cache);
- }
-
- @Override
- public SearchResult searchByCenter(final Geopoint center) {
- return new SearchResult(OCXMLClient.getCachesAround(center, NEARBY_SEARCH_DISTANCE));
- }
-
- @Override
- public SearchResult searchByViewport(final Viewport viewport, final String[] tokens) {
- final Geopoint center = viewport.getCenter();
- double distance = center.distanceTo(viewport.bottomLeft) * 1.15;
- if (distance > SEARCH_DISTANCE_LIMIT) {
- distance = SEARCH_DISTANCE_LIMIT;
- }
- return new SearchResult(OCXMLClient.getCachesAround(center, distance));
- }
-
- @Override
- public boolean isActivated() {
- // currently only tested and working with oc.de
- return Settings.isOCConnectorActive();
- }
-
- @Override
- public boolean isOwner(ICache cache) {
- return StringUtils.equalsIgnoreCase(cache.getOwnerDisplayName(), Settings.getOCConnectorUserName());
- }
-
- @Override
- public String getLicenseText(Geocache cache) {
- // not to be translated
- return "© " + cache.getOwnerDisplayName() + ", " + "<a href=\"" + getCacheUrl(cache) + "\">www.opencaching.de</a>, CC-BY-NC-ND, Stand: " + Formatter.formatFullDate(cache.getUpdated());
- }
-
-}
diff --git a/main/src/cgeo/geocaching/connector/oc/OCXMLClient.java b/main/src/cgeo/geocaching/connector/oc/OCXMLClient.java
deleted file mode 100644
index df75682..0000000
--- a/main/src/cgeo/geocaching/connector/oc/OCXMLClient.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package cgeo.geocaching.connector.oc;
-
-import cgeo.geocaching.Geocache;
-import cgeo.geocaching.cgData;
-import cgeo.geocaching.connector.ConnectorFactory;
-import cgeo.geocaching.connector.IConnector;
-import cgeo.geocaching.enumerations.LoadFlags;
-import cgeo.geocaching.geopoint.Geopoint;
-import cgeo.geocaching.geopoint.GeopointFormatter;
-import cgeo.geocaching.network.Network;
-import cgeo.geocaching.network.Parameters;
-import cgeo.geocaching.utils.IOUtils;
-import cgeo.geocaching.utils.Log;
-
-import ch.boye.httpclientandroidlib.HttpResponse;
-
-import org.apache.commons.lang3.StringUtils;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Locale;
-import java.util.zip.GZIPInputStream;
-
-public class OCXMLClient {
-
- private static final String SERVICE_CACHE = "/xml/ocxml11.php";
-
- // Url for single cache requests
- // http://www.opencaching.de/xml/ocxml11.php?modifiedsince=20060320000000&user=0&cache=1&cachedesc=1&cachelog=1&picture=1&removedobject=0&session=0&doctype=0&charset=utf-8&wp=OCC9BE
-
- public static Geocache getCache(final String geoCode) {
- try {
- final Parameters params = getOCXmlQueryParameters(true, true, true);
- params.put("wp", geoCode);
- final InputStream data = request(ConnectorFactory.getConnector(geoCode), SERVICE_CACHE, params);
-
- if (data == null) {
- return null;
- }
-
- final BufferedInputStream stream = new BufferedInputStream(new GZIPInputStream(data));
- Collection<Geocache> caches = OC11XMLParser.parseCaches(stream);
- if (caches.iterator().hasNext()) {
- Geocache cache = caches.iterator().next();
- cgData.saveCache(cache, LoadFlags.SAVE_ALL);
- IOUtils.closeQuietly(stream);
- return cache;
- }
- return null;
- } catch (IOException e) {
- Log.e("Error parsing cache '" + geoCode + "'", e);
- return null;
- }
- }
-
- public static Collection<Geocache> getCachesAround(final Geopoint center, final double distance) {
- try {
- final Parameters params = getOCXmlQueryParameters(false, false, false);
- params.put("lat", GeopointFormatter.format(GeopointFormatter.Format.LAT_DECDEGREE_RAW, center));
- params.put("lon", GeopointFormatter.format(GeopointFormatter.Format.LON_DECDEGREE_RAW, center));
- params.put("distance", String.format(Locale.US, "%f", distance));
- final InputStream data = request(ConnectorFactory.getConnector("OCXXX"), SERVICE_CACHE, params);
-
- if (data == null) {
- return Collections.emptyList();
- }
-
- final BufferedInputStream stream = new BufferedInputStream(new GZIPInputStream(data));
- final Collection<Geocache> result = OC11XMLParser.parseCachesFiltered(stream);
- IOUtils.closeQuietly(stream);
- return result;
- } catch (IOException e) {
- Log.e("Error parsing nearby search result", e);
- return Collections.emptyList();
- }
- }
-
- private static InputStream request(final IConnector connector, final String service, final Parameters params) {
- if (connector == null) {
- return null;
- }
- if (!(connector instanceof OCXMLApiConnector)) {
- return null;
- }
-
- final String host = connector.getHost();
- if (StringUtils.isBlank(host)) {
- return null;
- }
-
- final String uri = "http://" + host + service;
- HttpResponse resp = Network.getRequest(uri, params);
- if (resp != null) {
- try {
- return resp.getEntity().getContent();
- } catch (IllegalStateException e) {
- // fall through and return null
- } catch (IOException e) {
- // fall through and return null
- }
- }
- return null;
- }
-
- private static Parameters getOCXmlQueryParameters(final boolean withDescription, final boolean withLogs, final boolean withImages) {
- return new Parameters("modifiedsince", "20000101000000",
- "user", "0",
- "cache", "1",
- "cachedesc", withDescription ? "1" : "0",
- "cachelog", withLogs ? "1" : "0",
- "picture", withImages ? "1" : "0",
- "removedobject", "0",
- "session", "0",
- "doctype", "0",
- "charset", "utf-8",
- "zip", "gzip",
- "picturefromcachelog", withImages ? "1" : "0");
- }
-}
diff --git a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java
index 0673605..d8d92e1 100644
--- a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java
+++ b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java
@@ -3,16 +3,27 @@ package cgeo.geocaching.connector.oc;
import cgeo.geocaching.Geocache;
import cgeo.geocaching.Image;
import cgeo.geocaching.LogEntry;
+import cgeo.geocaching.R;
+import cgeo.geocaching.Settings;
+import cgeo.geocaching.Waypoint;
import cgeo.geocaching.cgData;
+import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.connector.ConnectorFactory;
import cgeo.geocaching.connector.IConnector;
+import cgeo.geocaching.connector.LogResult;
+import cgeo.geocaching.connector.gc.GCConnector;
+import cgeo.geocaching.enumerations.CacheAttribute;
import cgeo.geocaching.enumerations.CacheSize;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.enumerations.LoadFlags.SaveFlag;
import cgeo.geocaching.enumerations.LogType;
+import cgeo.geocaching.enumerations.StatusCode;
+import cgeo.geocaching.enumerations.WaypointType;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.GeopointFormatter;
+import cgeo.geocaching.geopoint.Viewport;
import cgeo.geocaching.network.Network;
+import cgeo.geocaching.network.OAuth;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.utils.Log;
@@ -22,17 +33,40 @@ import org.json.JSONException;
import org.json.JSONObject;
import android.net.Uri;
-import android.text.Html;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
+import java.util.TimeZone;
final public class OkapiClient {
+
+ private static final SimpleDateFormat logDateFormat;
+
+ static {
+ logDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSZ", Locale.US);
+ logDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
+ }
+
+ private static final String CACHE_ATTRNAMES = "attrnames";
+ private static final String WPT_LOCATION = "location";
+ private static final String WPT_DESCRIPTION = "description";
+ private static final String WPT_TYPE = "type";
+ private static final String WPT_NAME = "name";
+ private static final String CACHE_IS_WATCHED = "is_watched";
+ private static final String CACHE_WPTS = "alt_wpts";
+ private static final String CACHE_STATUS_ARCHIVED = "Archived";
+ private static final String CACHE_STATUS_DISABLED = "Temporarily unavailable";
+ private static final String CACHE_IS_FOUND = "is_found";
private static final String CACHE_SIZE = "size";
private static final String CACHE_VOTES = "rating_votes";
private static final String CACHE_NOTFOUNDS = "notfounds";
@@ -64,12 +98,22 @@ final public class OkapiClient {
private static final String USER_USERNAME = "username";
private static final String SERVICE_CACHE = "/okapi/services/caches/geocache";
- private static final String SERVICE_CACHE_FIELDS = "code|name|location|type|status|owner|founds|notfounds|size|difficulty|terrain|rating|rating_votes|recommendations|description|hint|images|latest_logs|date_hidden";
- private static final String SERVICE_NEAREST = "/okapi/services/caches/search/nearest";
+ private static final String SERVICE_CACHE_CORE_FIELDS = "code|name|location|type|status|difficulty|terrain|size|is_found";
+ private static final String SERVICE_CACHE_FIELDS = SERVICE_CACHE_CORE_FIELDS + "|owner|founds|notfounds|rating|rating_votes|recommendations|description|hint|images|latest_logs|date_hidden|attribution_note|alt_wpts|is_watched|attrnames|gc_code";
+
+ private static final String SERVICE_SEARCH_AND_RETRIEVE = "/okapi/services/caches/shortcuts/search_and_retrieve";
+
+ private static final String METHOD_SEARCH_NEAREST = "services/caches/search/nearest";
+ private static final String METHOD_SEARCH_BBOX = "services/caches/search/bbox";
+ private static final String METHOD_RETRIEVE_CACHES = "services/caches/geocaches";
+
+ private static final String SERVICE_MARK_CACHE = "/okapi/services/caches/mark";
+
+ private static final String SERVICE_SUBMIT_LOG = "/okapi/services/logs/submit";
public static Geocache getCache(final String geoCode) {
- final Parameters params = new Parameters("cache_code", geoCode, "fields", SERVICE_CACHE_FIELDS);
+ final Parameters params = new Parameters("cache_code", geoCode, "fields", SERVICE_CACHE_FIELDS, "attribution_append", "none");
final JSONObject data = request(ConnectorFactory.getConnector(geoCode), SERVICE_CACHE, params);
if (data == null) {
@@ -81,30 +125,115 @@ final public class OkapiClient {
public static List<Geocache> getCachesAround(final Geopoint center, IConnector connector) {
String centerString = GeopointFormatter.format(GeopointFormatter.Format.LAT_DECDEGREE_RAW, center) + "|" + GeopointFormatter.format(GeopointFormatter.Format.LON_DECDEGREE_RAW, center);
- final Parameters params = new Parameters("center", centerString);
- final JSONObject data = request(connector, SERVICE_NEAREST, params);
+ final Parameters params = new Parameters("search_method", METHOD_SEARCH_NEAREST);
+ final Map<String, String> valueMap = new LinkedHashMap<String, String>();
+ valueMap.put("center", centerString);
+ valueMap.put("limit", "20");
+
+ addFilterParams(valueMap);
+
+ params.add("search_params", new JSONObject(valueMap).toString());
+
+ addRetrieveParams(params);
+
+ final JSONObject data = request(connector, SERVICE_SEARCH_AND_RETRIEVE, params);
if (data == null) {
- return null;
+ return Collections.emptyList();
+ }
+
+ return parseCaches(data);
+ }
+
+ public static List<Geocache> getCachesBBox(final Viewport viewport, IConnector connector) {
+
+ if (viewport.getLatitudeSpan() == 0 || viewport.getLongitudeSpan() == 0) {
+ return Collections.emptyList();
+ }
+
+ String bboxString = GeopointFormatter.format(GeopointFormatter.Format.LAT_DECDEGREE_RAW, viewport.bottomLeft)
+ + "|" + GeopointFormatter.format(GeopointFormatter.Format.LON_DECDEGREE_RAW, viewport.bottomLeft)
+ + "|" + GeopointFormatter.format(GeopointFormatter.Format.LAT_DECDEGREE_RAW, viewport.topRight)
+ + "|" + GeopointFormatter.format(GeopointFormatter.Format.LON_DECDEGREE_RAW, viewport.topRight);
+ final Parameters params = new Parameters("search_method", METHOD_SEARCH_BBOX);
+ final Map<String, String> valueMap = new LinkedHashMap<String, String>();
+ valueMap.put("bbox", bboxString);
+
+ addFilterParams(valueMap);
+
+ params.add("search_params", new JSONObject(valueMap).toString());
+
+ addRetrieveParams(params);
+
+ final JSONObject data = request(connector, SERVICE_SEARCH_AND_RETRIEVE, params);
+
+ if (data == null) {
+ return Collections.emptyList();
}
return parseCaches(data);
}
+ public static boolean setWatchState(final Geocache cache, final boolean watched, IConnector connector) {
+ final Parameters params = new Parameters("cache_code", cache.getGeocode());
+ params.add("watched", watched ? "true" : "false");
+
+ final JSONObject data = request(connector, SERVICE_MARK_CACHE, params);
+
+ if (data == null) {
+ return false;
+ }
+
+ cache.setOnWatchlist(watched);
+
+ return true;
+ }
+
+ public static LogResult postLog(final Geocache cache, LogType logType, Calendar date, String log, IConnector connector) {
+ final Parameters params = new Parameters("cache_code", cache.getGeocode());
+ params.add("logtype", logType.oc_type);
+ params.add("comment", log);
+ params.add("comment_format", "plaintext");
+ params.add("when", logDateFormat.format(date.getTime()));
+ if (logType.equals(LogType.NEEDS_MAINTENANCE)) {
+ params.add("needs_maintenance", "true");
+ }
+
+ final JSONObject data = request(connector, SERVICE_SUBMIT_LOG, params);
+
+ if (data == null) {
+ return new LogResult(StatusCode.LOG_POST_ERROR, "");
+ }
+
+ try {
+ if (data.getBoolean("success")) {
+ return new LogResult(StatusCode.NO_ERROR, data.getString("log_uuid"));
+ }
+
+ return new LogResult(StatusCode.LOG_POST_ERROR, "");
+ } catch (JSONException e) {
+ Log.e("OkapiClient.postLog", e);
+ }
+ return new LogResult(StatusCode.LOG_POST_ERROR, "");
+ }
+
private static List<Geocache> parseCaches(final JSONObject response) {
try {
- final JSONArray cachesResponse = response.getJSONArray("results");
+ // Check for empty result
+ final String result = response.getString("results");
+ if (StringUtils.isBlank(result) || StringUtils.equals(result, "[]")) {
+ return Collections.emptyList();
+ }
+
+ // Get and iterate result list
+ final JSONObject cachesResponse = response.getJSONObject("results");
if (cachesResponse != null) {
- ArrayList<String> geocodes = new ArrayList<String>(cachesResponse.length());
- for (int i = 0; i < cachesResponse.length(); i++) {
- String geocode = cachesResponse.getString(i);
- if (StringUtils.isNotBlank(geocode)) {
- geocodes.add(geocode);
- }
- }
- List<Geocache> caches = new ArrayList<Geocache>(geocodes.size());
- for (String geocode : geocodes) {
- Geocache cache = getCache(geocode);
+ List<Geocache> caches = new ArrayList<Geocache>(cachesResponse.length());
+ @SuppressWarnings("unchecked")
+ Iterator<String> keys = cachesResponse.keys();
+ while (keys.hasNext()) {
+ String key = keys.next();
+ Geocache cache = parseSmallCache(cachesResponse.getJSONObject(key));
if (cache != null) {
caches.add(cache);
}
@@ -112,24 +241,31 @@ final public class OkapiClient {
return caches;
}
} catch (JSONException e) {
- Log.e("OkapiClient.parseCaches", e);
+ Log.e("OkapiClient.parseCachesResult", e);
}
- return null;
+ return Collections.emptyList();
+ }
+
+ private static Geocache parseSmallCache(final JSONObject response) {
+ final Geocache cache = new Geocache();
+ cache.setReliableLatLon(true);
+ try {
+
+ parseCoreCache(response, cache);
+
+ cgData.saveCache(cache, EnumSet.of(SaveFlag.SAVE_CACHE));
+ } catch (JSONException e) {
+ Log.e("OkapiClient.parseSmallCache", e);
+ }
+ return cache;
}
private static Geocache parseCache(final JSONObject response) {
final Geocache cache = new Geocache();
cache.setReliableLatLon(true);
try {
- cache.setGeocode(response.getString(CACHE_CODE));
- cache.setName(response.getString(CACHE_NAME));
- // not used: names
- setLocation(cache, response.getString(CACHE_LOCATION));
- cache.setType(getCacheType(response.getString(CACHE_TYPE)));
- final String status = response.getString(CACHE_STATUS);
- cache.setDisabled(status.equalsIgnoreCase("Temporarily unavailable"));
- cache.setArchived(status.equalsIgnoreCase("Archived"));
+ parseCoreCache(response, cache);
// not used: url
final JSONObject owner = response.getJSONObject(CACHE_OWNER);
@@ -137,9 +273,7 @@ final public class OkapiClient {
cache.getLogCounts().put(LogType.FOUND_IT, response.getInt(CACHE_FOUNDS));
cache.getLogCounts().put(LogType.DIDNT_FIND_IT, response.getInt(CACHE_NOTFOUNDS));
- cache.setSize(getCacheSize(response));
- cache.setDifficulty((float) response.getDouble(CACHE_DIFFICULTY));
- cache.setTerrain((float) response.getDouble(CACHE_TERRAIN));
+
if (!response.isNull(CACHE_RATING)) {
cache.setRating((float) response.getDouble(CACHE_RATING));
}
@@ -147,8 +281,22 @@ final public class OkapiClient {
cache.setFavoritePoints(response.getInt(CACHE_RECOMMENDATIONS));
// not used: req_password
- cache.setDescription(response.getString(CACHE_DESCRIPTION));
- cache.setHint(Html.fromHtml(response.getString(CACHE_HINT)).toString());
+ // Prepend gc-link to description if available
+ StringBuilder description = new StringBuilder(500);
+ if (!response.isNull("gc_code")) {
+ String gccode = response.getString("gc_code");
+ description.append(cgeoapplication.getInstance().getResources()
+ .getString(R.string.cache_listed_on, GCConnector.getInstance().getName()))
+ .append(": <a href=\"http://coord.info/")
+ .append(gccode)
+ .append("\">")
+ .append(gccode)
+ .append("</a><br /><br />");
+ }
+ description.append(response.getString(CACHE_DESCRIPTION));
+ cache.setDescription(description.toString());
+
+ cache.setHint(response.getString(CACHE_HINT));
// not used: hints
final JSONArray images = response.getJSONArray(CACHE_IMAGES);
@@ -163,9 +311,13 @@ final public class OkapiClient {
}
}
- // not used: attrnames
+ cache.setAttributes(parseAttributes(response.getJSONArray(CACHE_ATTRNAMES)));
cache.setLogs(parseLogs(response.getJSONArray(CACHE_LATEST_LOGS)));
cache.setHidden(parseDate(response.getString(CACHE_HIDDEN)));
+ //TODO: Store license per cache
+ //cache.setLicense(response.getString("attribution_note"));
+ cache.setWaypoints(parseWaypoints(response.getJSONArray(CACHE_WPTS)), false);
+ cache.setOnWatchlist(response.getBoolean(CACHE_IS_WATCHED));
cache.setDetailedUpdatedNow();
// save full detailed caches
@@ -176,6 +328,24 @@ final public class OkapiClient {
return cache;
}
+ private static void parseCoreCache(final JSONObject response, final Geocache cache) throws JSONException {
+ cache.setGeocode(response.getString(CACHE_CODE));
+ cache.setName(response.getString(CACHE_NAME));
+ // not used: names
+ setLocation(cache, response.getString(CACHE_LOCATION));
+ cache.setType(getCacheType(response.getString(CACHE_TYPE)));
+
+ final String status = response.getString(CACHE_STATUS);
+ cache.setDisabled(status.equalsIgnoreCase(CACHE_STATUS_DISABLED));
+ cache.setArchived(status.equalsIgnoreCase(CACHE_STATUS_ARCHIVED));
+
+ cache.setSize(getCacheSize(response));
+ cache.setDifficulty((float) response.getDouble(CACHE_DIFFICULTY));
+ cache.setTerrain((float) response.getDouble(CACHE_TERRAIN));
+
+ cache.setFound(response.getBoolean(CACHE_IS_FOUND));
+ }
+
private static String absoluteUrl(String url, String geocode) {
final Uri uri = Uri.parse(url);
@@ -214,6 +384,30 @@ final public class OkapiClient {
return result;
}
+ private static List<Waypoint> parseWaypoints(JSONArray wptsJson) {
+ List<Waypoint> result = null;
+ for (int i = 0; i < wptsJson.length(); i++) {
+ try {
+ JSONObject wptResponse = wptsJson.getJSONObject(i);
+ Waypoint wpt = new Waypoint(wptResponse.getString(WPT_NAME),
+ parseWptType(wptResponse.getString(WPT_TYPE)),
+ false);
+ wpt.setNote(wptResponse.getString(WPT_DESCRIPTION));
+ Geopoint pt = parseCoords(wptResponse.getString(WPT_LOCATION));
+ if (pt != null) {
+ wpt.setCoords(pt);
+ }
+ if (result == null) {
+ result = new ArrayList<Waypoint>();
+ }
+ result.add(wpt);
+ } catch (JSONException e) {
+ Log.e("OkapiClient.parseWaypoints", e);
+ }
+ }
+ return result;
+ }
+
private static LogType parseLogType(String logType) {
if ("Found it".equalsIgnoreCase(logType)) {
return LogType.FOUND_IT;
@@ -224,6 +418,31 @@ final public class OkapiClient {
return LogType.NOTE;
}
+ private static WaypointType parseWptType(String wptType) {
+ if ("parking".equalsIgnoreCase(wptType)) {
+ return WaypointType.PARKING;
+ }
+ if ("path".equalsIgnoreCase(wptType)) {
+ return WaypointType.TRAILHEAD;
+ }
+ if ("stage".equalsIgnoreCase(wptType)) {
+ return WaypointType.STAGE;
+ }
+ if ("physical-stage".equalsIgnoreCase(wptType)) {
+ return WaypointType.STAGE;
+ }
+ if ("virtual-stage".equalsIgnoreCase(wptType)) {
+ return WaypointType.PUZZLE;
+ }
+ if ("final".equalsIgnoreCase(wptType)) {
+ return WaypointType.FINAL;
+ }
+ if ("poi".equalsIgnoreCase(wptType)) {
+ return WaypointType.TRAILHEAD;
+ }
+ return WaypointType.WAYPOINT;
+ }
+
private static Date parseDate(final String date) {
final SimpleDateFormat ISO8601DATEFORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.getDefault());
final String strippedDate = date.replaceAll("\\+0([0-9]){1}\\:00", "+0$100");
@@ -235,6 +454,36 @@ final public class OkapiClient {
return null;
}
+ private static Geopoint parseCoords(final String location) {
+ final String latitude = StringUtils.substringBefore(location, "|");
+ final String longitude = StringUtils.substringAfter(location, "|");
+ if (StringUtils.isNotBlank(latitude) && StringUtils.isNotBlank(longitude)) {
+ return new Geopoint(latitude, longitude);
+ }
+
+ return null;
+ }
+
+ private static List<String> parseAttributes(JSONArray nameList) {
+
+ List<String> result = new ArrayList<String>();
+
+ for (int i = 0; i < nameList.length(); i++) {
+ try {
+ String name = nameList.getString(i);
+ CacheAttribute attr = CacheAttribute.getByOcId(AttributeParser.getOcDeId(name));
+
+ if (attr != null) {
+ result.add(attr.rawName);
+ }
+ } catch (JSONException e) {
+ Log.e("OkapiClient.parseAttributes", e);
+ }
+ }
+
+ return result;
+ }
+
private static void setLocation(final Geocache cache, final String location) {
final String latitude = StringUtils.substringBefore(location, "|");
final String longitude = StringUtils.substringAfter(location, "|");
@@ -281,6 +530,18 @@ final public class OkapiClient {
if (cacheType.equalsIgnoreCase("Virtual")) {
return CacheType.VIRTUAL;
}
+ if (cacheType.equalsIgnoreCase("Event")) {
+ return CacheType.EVENT;
+ }
+ if (cacheType.equalsIgnoreCase("Webcam")) {
+ return CacheType.WEBCAM;
+ }
+ if (cacheType.equalsIgnoreCase("Math/Physics")) {
+ return CacheType.MYSTERY;
+ }
+ if (cacheType.equalsIgnoreCase("Drive-In")) {
+ return CacheType.TRADITIONAL;
+ }
return CacheType.UNKNOWN;
}
@@ -297,9 +558,10 @@ final public class OkapiClient {
return null;
}
- ((OCApiConnector) connector).addAuthentication(params);
params.add("langpref", getPreferredLanguage());
+ OAuth.signOAuth(host, service, "GET", false, params, Settings.getOCDETokenPublic(), Settings.getOCDETokenSecret(), ((OCApiLiveConnector) connector).getCK(), ((OCApiLiveConnector) connector).getCS());
+
final String uri = "http://" + host + service;
return Network.requestJSON(uri, params);
}
@@ -311,4 +573,43 @@ final public class OkapiClient {
}
return "en";
}
+
+ private static void addFilterParams(final Map<String, String> valueMap) {
+ if (!Settings.isExcludeDisabledCaches()) {
+ valueMap.put("status", "Available|Temporarily unavailable");
+ }
+ if (Settings.isExcludeMyCaches()) {
+ valueMap.put("exclude_my_own", "true");
+ valueMap.put("found_status", "notfound_only");
+ }
+ if (Settings.getCacheType() != CacheType.ALL) {
+ valueMap.put("type", getFilterFromType(Settings.getCacheType()));
+ }
+ }
+
+ private static void addRetrieveParams(final Parameters params) {
+ params.add("retr_method", METHOD_RETRIEVE_CACHES);
+ params.add("retr_params", "{\"fields\": \"" + SERVICE_CACHE_CORE_FIELDS + "\"}");
+ params.add("wrap", "true");
+ }
+
+ private static String getFilterFromType(CacheType cacheType) {
+ switch (cacheType) {
+ case EVENT:
+ return "Event";
+ case MULTI:
+ return "Multi";
+ case MYSTERY:
+ return "Quiz";
+ case TRADITIONAL:
+ return "Traditional";
+ case VIRTUAL:
+ return "Virtual";
+ case WEBCAM:
+ return "Webcam";
+ default:
+ return "";
+ }
+ }
+
}
diff --git a/main/src/cgeo/geocaching/connector/oc/OkapiLoggingManager.java b/main/src/cgeo/geocaching/connector/oc/OkapiLoggingManager.java
new file mode 100644
index 0000000..24c6b79
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/oc/OkapiLoggingManager.java
@@ -0,0 +1,69 @@
+package cgeo.geocaching.connector.oc;
+
+import cgeo.geocaching.Geocache;
+import cgeo.geocaching.TrackableLog;
+import cgeo.geocaching.VisitCacheActivity;
+import cgeo.geocaching.connector.IConnector;
+import cgeo.geocaching.connector.ILoggingManager;
+import cgeo.geocaching.connector.ImageResult;
+import cgeo.geocaching.connector.LogResult;
+import cgeo.geocaching.enumerations.LogType;
+import cgeo.geocaching.enumerations.StatusCode;
+
+import android.app.Activity;
+import android.net.Uri;
+
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.List;
+
+public class OkapiLoggingManager implements ILoggingManager {
+
+ private final IConnector connector;
+ private final Geocache cache;
+ private VisitCacheActivity activity;
+
+ private final static List<LogType> standardLogTypes = Arrays.asList(LogType.FOUND_IT, LogType.DIDNT_FIND_IT, LogType.NOTE, LogType.NEEDS_MAINTENANCE);
+ private final static List<LogType> eventLogTypes = Arrays.asList(LogType.WILL_ATTEND, LogType.ATTENDED, LogType.NOTE);
+
+ public OkapiLoggingManager(Activity activity, IConnector connector, Geocache cache) {
+ this.connector = connector;
+ this.cache = cache;
+ this.activity = (VisitCacheActivity) activity;
+ }
+
+ @Override
+ public void init() {
+ activity.onLoadFinished();
+ }
+
+ @Override
+ public LogResult postLog(Geocache cache, LogType logType, Calendar date, String log, List<TrackableLog> trackableLogs) {
+ return OkapiClient.postLog(cache, logType, date, log, connector);
+ }
+
+ @Override
+ public ImageResult postLogImage(String logId, String imageCaption, String imageDescription, Uri imageUri) {
+ return new ImageResult(StatusCode.LOG_POST_ERROR, "");
+ }
+
+ @Override
+ public boolean hasLoaderError() {
+ return false;
+ }
+
+ @Override
+ public List<TrackableLog> getTrackables() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List<LogType> getPossibleLogTypes() {
+ if (cache.isEventCache()) {
+ return eventLogTypes;
+ }
+
+ return standardLogTypes;
+ }
+}
diff --git a/main/src/cgeo/geocaching/enumerations/LogType.java b/main/src/cgeo/geocaching/enumerations/LogType.java
index 71a5146..9902d3f 100644
--- a/main/src/cgeo/geocaching/enumerations/LogType.java
+++ b/main/src/cgeo/geocaching/enumerations/LogType.java
@@ -15,50 +15,52 @@ import java.util.Map;
*/
public enum LogType {
- FOUND_IT(2, "2", "found it", R.string.log_found, R.drawable.mark_green),
- DIDNT_FIND_IT(3, "3", "didn't find it", R.string.log_dnf, R.drawable.mark_red),
- NOTE(4, "4", "write note", R.string.log_note),
- PUBLISH_LISTING(1003, "24", "publish listing", R.string.log_published, R.drawable.mark_green_more),
- ENABLE_LISTING(23, "23", "enable listing", R.string.log_enabled, R.drawable.mark_green_more),
- ARCHIVE(5, "5", "archive", R.string.log_archived, R.drawable.mark_red_more),
- UNARCHIVE(12, "12", "unarchive", R.string.log_unarchived, R.drawable.mark_green_more),
- TEMP_DISABLE_LISTING(22, "22", "temporarily disable listing", R.string.log_disabled, R.drawable.mark_red_more),
- NEEDS_ARCHIVE(7, "7", "needs archived", R.string.log_needs_archived, R.drawable.mark_red),
- WILL_ATTEND(9, "9", "will attend", R.string.log_attend),
- ATTENDED(10, "10", "attended", R.string.log_attended, R.drawable.mark_green),
- RETRIEVED_IT(13, "13", "retrieved it", R.string.log_retrieved, R.drawable.mark_green_more),
- PLACED_IT(14, "14", "placed it", R.string.log_placed, R.drawable.mark_green_more),
- GRABBED_IT(19, "19", "grabbed it", R.string.log_grabbed, R.drawable.mark_green_more),
- NEEDS_MAINTENANCE(45, "45", "needs maintenance", R.string.log_maintenance_needed, R.drawable.mark_red),
- OWNER_MAINTENANCE(46, "46", "owner maintenance", R.string.log_maintained, R.drawable.mark_green_more),
- UPDATE_COORDINATES(47, "47", "update coordinates", R.string.log_update),
- DISCOVERED_IT(48, "48", "discovered it", R.string.log_discovered, R.drawable.mark_green),
- POST_REVIEWER_NOTE(18, "68", "post reviewer note", R.string.log_reviewer),
- VISIT(1001, "75", "visit", R.string.log_tb_visit, R.drawable.mark_green),
- WEBCAM_PHOTO_TAKEN(11, "11", "webcam photo taken", R.string.log_webcam, R.drawable.mark_green),
- ANNOUNCEMENT(74, "74", "announcement", R.string.log_announcement),
- MOVE_COLLECTION(69, "69", "unused_collection", R.string.log_movecollection),
- MOVE_INVENTORY(70, "70", "unused_inventory", R.string.log_moveinventory),
- RETRACT(25, "25", "retract listing", R.string.log_retractlisting),
- MARKED_MISSING(16, "16", "marked missing", R.string.log_marked_missing, R.drawable.mark_red),
- UNKNOWN(0, "unknown", "", R.string.err_unknown, R.drawable.mark_red); // LogType not init. yet
+ FOUND_IT(2, "2", "found it", "Found it", R.string.log_found, R.drawable.mark_green),
+ DIDNT_FIND_IT(3, "3", "didn't find it", "Didn't find it", R.string.log_dnf, R.drawable.mark_red),
+ NOTE(4, "4", "write note", "Comment", R.string.log_note),
+ PUBLISH_LISTING(1003, "24", "publish listing", "", R.string.log_published, R.drawable.mark_green_more),
+ ENABLE_LISTING(23, "23", "enable listing", "", R.string.log_enabled, R.drawable.mark_green_more),
+ ARCHIVE(5, "5", "archive", "", R.string.log_archived, R.drawable.mark_red_more),
+ UNARCHIVE(12, "12", "unarchive", "", R.string.log_unarchived, R.drawable.mark_green_more),
+ TEMP_DISABLE_LISTING(22, "22", "temporarily disable listing", "", R.string.log_disabled, R.drawable.mark_red_more),
+ NEEDS_ARCHIVE(7, "7", "needs archived", "", R.string.log_needs_archived, R.drawable.mark_red),
+ WILL_ATTEND(9, "9", "will attend", "Will attend", R.string.log_attend),
+ ATTENDED(10, "10", "attended", "Attended", R.string.log_attended, R.drawable.mark_green),
+ RETRIEVED_IT(13, "13", "retrieved it", "", R.string.log_retrieved, R.drawable.mark_green_more),
+ PLACED_IT(14, "14", "placed it", "", R.string.log_placed, R.drawable.mark_green_more),
+ GRABBED_IT(19, "19", "grabbed it", "", R.string.log_grabbed, R.drawable.mark_green_more),
+ NEEDS_MAINTENANCE(45, "45", "needs maintenance", "Comment", R.string.log_maintenance_needed, R.drawable.mark_red),
+ OWNER_MAINTENANCE(46, "46", "owner maintenance", "", R.string.log_maintained, R.drawable.mark_green_more),
+ UPDATE_COORDINATES(47, "47", "update coordinates", "", R.string.log_update),
+ DISCOVERED_IT(48, "48", "discovered it", "", R.string.log_discovered, R.drawable.mark_green),
+ POST_REVIEWER_NOTE(18, "68", "post reviewer note", "", R.string.log_reviewer),
+ VISIT(1001, "75", "visit", "", R.string.log_tb_visit, R.drawable.mark_green),
+ WEBCAM_PHOTO_TAKEN(11, "11", "webcam photo taken", "", R.string.log_webcam, R.drawable.mark_green),
+ ANNOUNCEMENT(74, "74", "announcement", "", R.string.log_announcement),
+ MOVE_COLLECTION(69, "69", "unused_collection", "", R.string.log_movecollection),
+ MOVE_INVENTORY(70, "70", "unused_inventory", "", R.string.log_moveinventory),
+ RETRACT(25, "25", "retract listing", "", R.string.log_retractlisting),
+ MARKED_MISSING(16, "16", "marked missing", "", R.string.log_marked_missing, R.drawable.mark_red),
+ UNKNOWN(0, "unknown", "", "", R.string.err_unknown, R.drawable.mark_red); // LogType not init. yet
public final int id;
public final String iconName;
public final String type;
+ public final String oc_type;
private final int stringId;
public final int markerId;
- LogType(int id, String iconName, String type, int stringId, int markerId) {
+ LogType(int id, String iconName, String type, String oc_type, int stringId, int markerId) {
this.id = id;
this.iconName = iconName;
this.type = type;
+ this.oc_type = oc_type;
this.stringId = stringId;
this.markerId = markerId;
}
- LogType(int id, String iconName, String type, int stringId) {
- this(id, iconName, type, stringId, R.drawable.mark_gray);
+ LogType(int id, String iconName, String type, String oc_type, int stringId) {
+ this(id, iconName, type, oc_type, stringId, R.drawable.mark_gray);
}
private final static Map<String, LogType> FIND_BY_ICONNAME;
diff --git a/main/src/cgeo/geocaching/loaders/CoordsGeocacheListLoader.java b/main/src/cgeo/geocaching/loaders/CoordsGeocacheListLoader.java
index ca2461c..09ea459 100644
--- a/main/src/cgeo/geocaching/loaders/CoordsGeocacheListLoader.java
+++ b/main/src/cgeo/geocaching/loaders/CoordsGeocacheListLoader.java
@@ -19,7 +19,11 @@ public class CoordsGeocacheListLoader extends AbstractSearchLoader {
@Override
public SearchResult runSearch() {
- SearchResult search = GCParser.searchByCoords(coords, Settings.getCacheType(), Settings.isShowCaptcha(), this);
+
+ SearchResult search = new SearchResult();
+ if (Settings.isGCConnectorActive()) {
+ search = GCParser.searchByCoords(coords, Settings.getCacheType(), Settings.isShowCaptcha(), this);
+ }
for (ISearchByCenter centerConn : ConnectorFactory.getSearchByCenterConnectors()) {
if (centerConn.isActivated()) {
diff --git a/main/src/cgeo/geocaching/maps/CGeoMap.java b/main/src/cgeo/geocaching/maps/CGeoMap.java
index 0af0e6c..ea51375 100644
--- a/main/src/cgeo/geocaching/maps/CGeoMap.java
+++ b/main/src/cgeo/geocaching/maps/CGeoMap.java
@@ -1146,7 +1146,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
searchResult = ConnectorFactory.searchByViewport(viewport.resize(0.8), tokens);
if (searchResult != null) {
downloaded = true;
- if (searchResult.getError() == StatusCode.NOT_LOGGED_IN) {
+ if (searchResult.getError() == StatusCode.NOT_LOGGED_IN && Settings.isGCConnectorActive()) {
Login.login();
tokens = null;
} else {
diff --git a/main/src/cgeo/geocaching/network/OAuth.java b/main/src/cgeo/geocaching/network/OAuth.java
index 0b7a261..6740096 100644
--- a/main/src/cgeo/geocaching/network/OAuth.java
+++ b/main/src/cgeo/geocaching/network/OAuth.java
@@ -1,9 +1,9 @@
package cgeo.geocaching.network;
-import cgeo.geocaching.Settings;
import cgeo.geocaching.utils.CryptUtils;
import ch.boye.httpclientandroidlib.NameValuePair;
+
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
@@ -11,9 +11,17 @@ import java.util.Date;
import java.util.List;
public class OAuth {
- public static void signOAuth(final String host, final String path, final String method, final boolean https, final Parameters params, final String token, final String tokenSecret) {
+ public static void signOAuth(final String host,
+ final String path,
+ final String method,
+ final boolean https,
+ final Parameters params,
+ final String token,
+ final String tokenSecret,
+ final String consumerKey,
+ final String consumerSecret) {
params.put(
- "oauth_consumer_key", Settings.getKeyConsumerPublic(),
+ "oauth_consumer_key", consumerKey,
"oauth_nonce", CryptUtils.md5(Long.toString(System.currentTimeMillis())),
"oauth_signature_method", "HMAC-SHA1",
"oauth_timestamp", Long.toString(new Date().getTime() / 1000),
@@ -26,7 +34,7 @@ public class OAuth {
paramsEncoded.add(nameValue.getName() + "=" + Network.rfc3986URLEncode(nameValue.getValue()));
}
- final String keysPacked = Settings.getKeyConsumerSecret() + "&" + StringUtils.defaultString(tokenSecret); // both even if empty some of them!
+ final String keysPacked = consumerSecret + "&" + StringUtils.defaultString(tokenSecret); // both even if empty some of them!
final String requestPacked = method + "&" + Network.rfc3986URLEncode((https ? "https" : "http") + "://" + host + path) + "&" + Network.rfc3986URLEncode(StringUtils.join(paramsEncoded.toArray(), '&'));
params.put("oauth_signature", CryptUtils.base64Encode(CryptUtils.hashHmac(requestPacked, keysPacked)));
}
diff --git a/main/src/cgeo/geocaching/network/OAuthAuthorizationActivity.java b/main/src/cgeo/geocaching/network/OAuthAuthorizationActivity.java
new file mode 100644
index 0000000..751443e
--- /dev/null
+++ b/main/src/cgeo/geocaching/network/OAuthAuthorizationActivity.java
@@ -0,0 +1,326 @@
+package cgeo.geocaching.network;
+
+import cgeo.geocaching.R;
+import cgeo.geocaching.activity.AbstractActivity;
+import cgeo.geocaching.utils.Log;
+import cgeo.geocaching.utils.MatcherWrapper;
+
+import ch.boye.httpclientandroidlib.client.entity.UrlEncodedFormEntity;
+import ch.boye.httpclientandroidlib.util.EntityUtils;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+
+import android.app.ProgressDialog;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import java.util.regex.Pattern;
+
+public abstract class OAuthAuthorizationActivity extends AbstractActivity {
+
+ private String host;
+ private String pathRequest;
+ private String pathAuthorize;
+ private String pathAccess;
+ private boolean https;
+ private String consumerKey;
+ private String consumerSecret;
+ private String OAtoken = null;
+ private String OAtokenSecret = null;
+ private final Pattern paramsPattern1 = Pattern.compile("oauth_token=([a-zA-Z0-9\\-\\_.]+)");
+ private final Pattern paramsPattern2 = Pattern.compile("oauth_token_secret=([a-zA-Z0-9\\-\\_.]+)");
+ private Button startButton = null;
+ private EditText pinEntry = null;
+ private Button pinEntryButton = null;
+ private ProgressDialog requestTokenDialog = null;
+ private ProgressDialog changeTokensDialog = null;
+ private Handler requestTokenHandler = new Handler() {
+
+ @Override
+ public void handleMessage(Message msg) {
+ if (requestTokenDialog != null && requestTokenDialog.isShowing()) {
+ requestTokenDialog.dismiss();
+ }
+
+ startButton.setOnClickListener(new StartListener());
+ startButton.setEnabled(true);
+
+ if (msg.what == 1) {
+ startButton.setText(getAuthAgain());
+
+ pinEntry.setVisibility(View.VISIBLE);
+ pinEntryButton.setVisibility(View.VISIBLE);
+ pinEntryButton.setOnClickListener(new ConfirmPINListener());
+ } else {
+ showToast(getErrAuthInitialize());
+ startButton.setText(getAuthStart());
+ }
+ }
+
+ };
+ private Handler changeTokensHandler = new Handler() {
+
+ @Override
+ public void handleMessage(Message msg) {
+ if (changeTokensDialog != null && changeTokensDialog.isShowing()) {
+ changeTokensDialog.dismiss();
+ }
+
+ pinEntryButton.setOnClickListener(new ConfirmPINListener());
+ pinEntryButton.setEnabled(true);
+
+ if (msg.what == 1) {
+ showToast(getAuthDialogCompleted());
+
+ pinEntryButton.setVisibility(View.GONE);
+
+ finish();
+ } else {
+ showToast(getErrAuthProcess());
+
+ pinEntry.setVisibility(View.GONE);
+ pinEntryButton.setVisibility(View.GONE);
+ startButton.setText(getAuthStart());
+ }
+ }
+ };
+
+ public OAuthAuthorizationActivity(String host,
+ String pathRequest,
+ String pathAuthorize,
+ String pathAccess,
+ boolean https,
+ String consumerKey,
+ String consumerSecret) {
+ this.host = host;
+ this.pathRequest = pathRequest;
+ this.pathAuthorize = pathAuthorize;
+ this.pathAccess = pathAccess;
+ this.https = https;
+ this.consumerKey = consumerKey;
+ this.consumerSecret = consumerSecret;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState, R.layout.authorization_activity);
+
+ setTitle(getAuthTitle());
+
+ init();
+ }
+
+ private void init() {
+ startButton = (Button) findViewById(R.id.start);
+ pinEntry = (EditText) findViewById(R.id.pin);
+ pinEntryButton = (Button) findViewById(R.id.pin_button);
+
+ TextView auth = (TextView) findViewById(R.id.auth_1);
+ auth.setText(getAboutAuth1());
+ auth = (TextView) findViewById(R.id.auth_2);
+ auth.setText(getAboutAuth2());
+
+ ImmutablePair<String, String> tempToken = getTempToken();
+ OAtoken = tempToken.left;
+ OAtokenSecret = tempToken.right;
+
+ startButton.setText(getAuthAuthorize());
+ pinEntryButton.setText(getAuthFinish());
+
+ startButton.setEnabled(true);
+ startButton.setOnClickListener(new StartListener());
+
+ if (StringUtils.isBlank(OAtoken) && StringUtils.isBlank(OAtokenSecret)) {
+ // start authorization process
+ startButton.setText(getAuthStart());
+ } else {
+ // already have temporary tokens, continue from pin
+ startButton.setText(getAuthAgain());
+
+ pinEntry.setHint(getAuthPinHint());
+ pinEntry.setVisibility(View.VISIBLE);
+ pinEntryButton.setVisibility(View.VISIBLE);
+ pinEntryButton.setOnClickListener(new ConfirmPINListener());
+ }
+ }
+
+ private void requestToken() {
+
+ int status = 0;
+ try {
+ final Parameters params = new Parameters();
+ params.put("oauth_callback", "oob");
+ final String method = "GET";
+ OAuth.signOAuth(host, pathRequest, method, https, params, null, null, consumerKey, consumerSecret);
+ final String line = Network.getResponseData(Network.getRequest(getUrlPrefix() + host + pathRequest, params));
+
+ if (StringUtils.isNotBlank(line)) {
+ final MatcherWrapper paramsMatcher1 = new MatcherWrapper(paramsPattern1, line);
+ if (paramsMatcher1.find()) {
+ OAtoken = paramsMatcher1.group(1);
+ }
+ final MatcherWrapper paramsMatcher2 = new MatcherWrapper(paramsPattern2, line);
+ if (paramsMatcher2.find()) {
+ OAtokenSecret = paramsMatcher2.group(1);
+ }
+
+ if (StringUtils.isNotBlank(OAtoken) && StringUtils.isNotBlank(OAtokenSecret)) {
+ setTempTokens(OAtoken, OAtokenSecret);
+ try {
+ final Parameters paramsBrowser = new Parameters();
+ paramsBrowser.put("oauth_token", OAtoken);
+ final String encodedParams = EntityUtils.toString(new UrlEncodedFormEntity(paramsBrowser));
+ startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getUrlPrefix() + host + pathAuthorize + "?" + encodedParams)));
+ status = 1;
+ } catch (Exception e) {
+ Log.e("OAuthAuthorizationActivity.requestToken(2)", e);
+ }
+ }
+ }
+ } catch (Exception e) {
+ Log.e("OAuthAuthorizationActivity.requestToken(1)", e);
+ }
+
+ requestTokenHandler.sendEmptyMessage(status);
+ }
+
+ private void changeToken() {
+
+ int status = 0;
+
+ try {
+ final Parameters params = new Parameters("oauth_verifier", pinEntry.getText().toString());
+
+ final String method = "POST";
+ OAuth.signOAuth(host, pathAccess, method, https, params, OAtoken, OAtokenSecret, consumerKey, consumerSecret);
+ final String line = StringUtils.defaultString(Network.getResponseData(Network.postRequest(getUrlPrefix() + host + pathAccess, params)));
+
+ OAtoken = "";
+ OAtokenSecret = "";
+
+ final MatcherWrapper paramsMatcher1 = new MatcherWrapper(paramsPattern1, line);
+ if (paramsMatcher1.find()) {
+ OAtoken = paramsMatcher1.group(1);
+ }
+ final MatcherWrapper paramsMatcher2 = new MatcherWrapper(paramsPattern2, line);
+ if (paramsMatcher2.find() && paramsMatcher2.groupCount() > 0) {
+ OAtokenSecret = paramsMatcher2.group(1);
+ }
+
+ if (StringUtils.isBlank(OAtoken) && StringUtils.isBlank(OAtokenSecret)) {
+ OAtoken = "";
+ OAtokenSecret = "";
+ setTokens(null, null, false);
+ } else {
+ setTokens(OAtoken, OAtokenSecret, true);
+ status = 1;
+ }
+ } catch (Exception e) {
+ Log.e("OAuthAuthorizationActivity.changeToken", e);
+ }
+
+ changeTokensHandler.sendEmptyMessage(status);
+ }
+
+ private String getUrlPrefix() {
+ return https ? "https://" : "http://";
+ }
+
+ private class StartListener implements View.OnClickListener {
+
+ @Override
+ public void onClick(View arg0) {
+ if (requestTokenDialog == null) {
+ requestTokenDialog = new ProgressDialog(OAuthAuthorizationActivity.this);
+ requestTokenDialog.setCancelable(false);
+ requestTokenDialog.setMessage(getAuthDialogWait());
+ }
+ requestTokenDialog.show();
+ startButton.setEnabled(false);
+ startButton.setOnTouchListener(null);
+ startButton.setOnClickListener(null);
+
+ setTempTokens(null, null);
+ (new Thread() {
+
+ @Override
+ public void run() {
+ requestToken();
+ }
+ }).start();
+ }
+ }
+
+ private class ConfirmPINListener implements View.OnClickListener {
+
+ @Override
+ public void onClick(View arg0) {
+ if (StringUtils.isEmpty(((EditText) findViewById(R.id.pin)).getText().toString())) {
+ helpDialog(getAuthDialogPinTitle(), getAuthDialogPinMessage());
+ return;
+ }
+
+ if (changeTokensDialog == null) {
+ changeTokensDialog = new ProgressDialog(OAuthAuthorizationActivity.this);
+ changeTokensDialog.setCancelable(false);
+ changeTokensDialog.setMessage(getAuthDialogWait());
+ }
+ changeTokensDialog.show();
+ pinEntryButton.setEnabled(false);
+ pinEntryButton.setOnTouchListener(null);
+ pinEntryButton.setOnClickListener(null);
+
+ (new Thread() {
+
+ @Override
+ public void run() {
+ changeToken();
+ }
+ }).start();
+ }
+ }
+
+ protected abstract ImmutablePair<String, String> getTempToken();
+
+ protected abstract void setTempTokens(String tokenPublic, String tokenSecret);
+
+ protected abstract void setTokens(String tokenPublic, String tokenSecret, boolean enable);
+
+ // get resources from derived class
+
+ protected abstract String getAuthTitle();
+
+ protected abstract String getAuthAgain();
+
+ protected abstract String getErrAuthInitialize();
+
+ protected abstract String getAuthStart();
+
+ protected abstract String getAuthDialogCompleted();
+
+ protected abstract String getErrAuthProcess();
+
+ protected abstract String getAuthDialogWait();
+
+ protected abstract String getAuthDialogPinTitle();
+
+ protected abstract String getAuthDialogPinMessage();
+
+ protected abstract String getAboutAuth1();
+
+ protected abstract String getAboutAuth2();
+
+ protected abstract String getAuthAuthorize();
+
+ protected abstract String getAuthPinHint();
+
+ protected abstract String getAuthFinish();
+}
diff --git a/main/src/cgeo/geocaching/twitter/Twitter.java b/main/src/cgeo/geocaching/twitter/Twitter.java
index e3d3f77..525b7f0 100644
--- a/main/src/cgeo/geocaching/twitter/Twitter.java
+++ b/main/src/cgeo/geocaching/twitter/Twitter.java
@@ -38,7 +38,7 @@ public final class Twitter {
"display_coordinates", "true");
}
- OAuth.signOAuth("api.twitter.com", "/1/statuses/update.json", "POST", false, parameters, Settings.getTokenPublic(), Settings.getTokenSecret());
+ OAuth.signOAuth("api.twitter.com", "/1/statuses/update.json", "POST", false, parameters, Settings.getTokenPublic(), Settings.getTokenSecret(), Settings.getKeyConsumerPublic(), Settings.getKeyConsumerSecret());
final HttpResponse httpResponse = Network.postRequest("http://api.twitter.com/1/statuses/update.json", parameters);
if (httpResponse != null && httpResponse.getStatusLine().getStatusCode() == 200) {
Log.i("Tweet posted");
diff --git a/main/src/cgeo/geocaching/twitter/TwitterAuthorizationActivity.java b/main/src/cgeo/geocaching/twitter/TwitterAuthorizationActivity.java
index 3bc1dec..7146a62 100644
--- a/main/src/cgeo/geocaching/twitter/TwitterAuthorizationActivity.java
+++ b/main/src/cgeo/geocaching/twitter/TwitterAuthorizationActivity.java
@@ -2,258 +2,105 @@ package cgeo.geocaching.twitter;
import cgeo.geocaching.R;
import cgeo.geocaching.Settings;
-import cgeo.geocaching.activity.AbstractActivity;
-import cgeo.geocaching.network.Network;
-import cgeo.geocaching.network.OAuth;
-import cgeo.geocaching.network.Parameters;
-import cgeo.geocaching.utils.Log;
-import cgeo.geocaching.utils.MatcherWrapper;
+import cgeo.geocaching.network.OAuthAuthorizationActivity;
-import ch.boye.httpclientandroidlib.client.entity.UrlEncodedFormEntity;
-import ch.boye.httpclientandroidlib.util.EntityUtils;
-
-import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
-import android.app.ProgressDialog;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.view.View;
-import android.widget.Button;
-import android.widget.EditText;
-
-import java.util.regex.Pattern;
-
-public class TwitterAuthorizationActivity extends AbstractActivity {
- private String OAtoken = null;
- private String OAtokenSecret = null;
- private final Pattern paramsPattern1 = Pattern.compile("oauth_token=([a-zA-Z0-9\\-\\_.]+)");
- private final Pattern paramsPattern2 = Pattern.compile("oauth_token_secret=([a-zA-Z0-9\\-\\_.]+)");
- private Button startButton = null;
- private EditText pinEntry = null;
- private Button pinEntryButton = null;
- private ProgressDialog requestTokenDialog = null;
- private ProgressDialog changeTokensDialog = null;
- private Handler requestTokenHandler = new Handler() {
-
- @Override
- public void handleMessage(Message msg) {
- if (requestTokenDialog != null && requestTokenDialog.isShowing()) {
- requestTokenDialog.dismiss();
- }
-
- startButton.setOnClickListener(new StartListener());
- startButton.setEnabled(true);
-
- if (msg.what == 1) {
- startButton.setText(res.getString(R.string.auth_again));
-
- pinEntry.setVisibility(View.VISIBLE);
- pinEntryButton.setVisibility(View.VISIBLE);
- pinEntryButton.setOnClickListener(new ConfirmPINListener());
- } else {
- showToast(res.getString(R.string.err_auth_initialize));
- startButton.setText(res.getString(R.string.auth_start));
- }
- }
- };
- private Handler changeTokensHandler = new Handler() {
+public class TwitterAuthorizationActivity extends OAuthAuthorizationActivity {
- @Override
- public void handleMessage(Message msg) {
- if (changeTokensDialog != null && changeTokensDialog.isShowing()) {
- changeTokensDialog.dismiss();
- }
-
- pinEntryButton.setOnClickListener(new ConfirmPINListener());
- pinEntryButton.setEnabled(true);
-
- if (msg.what == 1) {
- showToast(res.getString(R.string.auth_dialog_completed));
-
- pinEntryButton.setVisibility(View.GONE);
-
- finish();
- } else {
- showToast(res.getString(R.string.err_auth_process));
-
- pinEntry.setVisibility(View.GONE);
- pinEntryButton.setVisibility(View.GONE);
- startButton.setText(res.getString(R.string.auth_start));
- }
- }
- };
+ public TwitterAuthorizationActivity() {
+ super("api.twitter.com",
+ "/oauth/request_token",
+ "/oauth/authorize",
+ "/oauth/access_token",
+ true,
+ Settings.getKeyConsumerPublic(),
+ Settings.getKeyConsumerSecret());
+ }
@Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState, R.layout.twitter_authorization_activity);
-
- init();
+ protected ImmutablePair<String, String> getTempToken() {
+ return Settings.getTempToken();
}
- private void init() {
- startButton = (Button) findViewById(R.id.start);
- pinEntry = (EditText) findViewById(R.id.pin);
- pinEntryButton = (Button) findViewById(R.id.pin_button);
-
- ImmutablePair<String, String> tempToken = Settings.getTempToken();
- OAtoken = tempToken.left;
- OAtokenSecret = tempToken.right;
-
- startButton.setEnabled(true);
- startButton.setOnClickListener(new StartListener());
-
- if (StringUtils.isBlank(OAtoken) && StringUtils.isBlank(OAtokenSecret)) {
- // start authorization process
- startButton.setText(res.getString(R.string.auth_start));
- } else {
- // already have temporary tokens, continue from pin
- startButton.setText(res.getString(R.string.auth_again));
-
- pinEntry.setVisibility(View.VISIBLE);
- pinEntryButton.setVisibility(View.VISIBLE);
- pinEntryButton.setOnClickListener(new ConfirmPINListener());
- }
+ @Override
+ protected void setTempTokens(String tokenPublic, String tokenSecret) {
+ Settings.setTwitterTempTokens(tokenPublic, tokenSecret);
}
- private void requestToken() {
-
- int status = 0;
- try {
- final Parameters params = new Parameters();
- final String method = "GET";
- final String pathRequest = "/oauth/request_token";
- final String host = "api.twitter.com";
- OAuth.signOAuth(host, pathRequest, method, true, params, null, null);
- final String line = Network.getResponseData(Network.getRequest("https://" + host + pathRequest, params));
-
-
- if (StringUtils.isNotBlank(line)) {
- final MatcherWrapper paramsMatcher1 = new MatcherWrapper(paramsPattern1, line);
- if (paramsMatcher1.find()) {
- OAtoken = paramsMatcher1.group(1);
- }
- final MatcherWrapper paramsMatcher2 = new MatcherWrapper(paramsPattern2, line);
- if (paramsMatcher2.find()) {
- OAtokenSecret = paramsMatcher2.group(1);
- }
-
- if (StringUtils.isNotBlank(OAtoken) && StringUtils.isNotBlank(OAtokenSecret)) {
- Settings.setTwitterTempTokens(OAtoken, OAtokenSecret);
- try {
- final Parameters paramsBrowser = new Parameters();
- paramsBrowser.put("oauth_callback", "oob");
- final String pathAuthorize = "/oauth/authorize";
- OAuth.signOAuth(host, pathAuthorize, "GET", true, paramsBrowser, OAtoken, OAtokenSecret);
- final String encodedParams = EntityUtils.toString(new UrlEncodedFormEntity(paramsBrowser));
- startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://" + host + pathAuthorize + "?" + encodedParams)));
- status = 1;
- } catch (Exception e) {
- Log.e("TwitterAuthorizationActivity.requestToken(2)", e);
- }
- }
- }
- } catch (Exception e) {
- Log.e("TwitterAuthorizationActivity.requestToken(1)", e);
- }
-
- requestTokenHandler.sendEmptyMessage(status);
+ @Override
+ protected void setTokens(String tokenPublic, String tokenSecret, boolean enable) {
+ Settings.setTwitterTokens(tokenPublic, tokenSecret, enable);
}
- private void changeToken() {
-
- int status = 0;
-
- try {
- final Parameters params = new Parameters("oauth_verifier", pinEntry.getText().toString());
-
- final String method = "POST";
- final String path = "/oauth/access_token";
- final String host = "api.twitter.com";
- OAuth.signOAuth(host, path, method, true, params, OAtoken, OAtokenSecret);
- final String line = StringUtils.defaultString(Network.getResponseData(Network.postRequest("https://" + host + path, params)));
+ @Override
+ protected String getAuthTitle() {
+ return res.getString(R.string.auth_twitter);
+ }
- OAtoken = "";
- OAtokenSecret = "";
+ @Override
+ protected String getAuthAgain() {
+ return res.getString(R.string.auth_again);
+ }
- final MatcherWrapper paramsMatcher1 = new MatcherWrapper(paramsPattern1, line);
- if (paramsMatcher1.find()) {
- OAtoken = paramsMatcher1.group(1);
- }
- final MatcherWrapper paramsMatcher2 = new MatcherWrapper(paramsPattern2, line);
- if (paramsMatcher2.find() && paramsMatcher2.groupCount() > 0) {
- OAtokenSecret = paramsMatcher2.group(1);
- }
+ @Override
+ protected String getErrAuthInitialize() {
+ return res.getString(R.string.err_auth_initialize);
+ }
- if (StringUtils.isBlank(OAtoken) && StringUtils.isBlank(OAtokenSecret)) {
- OAtoken = "";
- OAtokenSecret = "";
- Settings.setTwitterTokens(null, null, false);
- } else {
- Settings.setTwitterTokens(OAtoken, OAtokenSecret, true);
- status = 1;
- }
- } catch (Exception e) {
- Log.e("TwitterAuthorizationActivity.changeToken", e);
- }
+ @Override
+ protected String getAuthStart() {
+ return res.getString(R.string.auth_start);
+ }
- changeTokensHandler.sendEmptyMessage(status);
+ @Override
+ protected String getAuthDialogCompleted() {
+ return res.getString(R.string.auth_dialog_completed);
}
- private class StartListener implements View.OnClickListener {
+ @Override
+ protected String getErrAuthProcess() {
+ return res.getString(R.string.err_auth_process);
+ }
- @Override
- public void onClick(View arg0) {
- if (requestTokenDialog == null) {
- requestTokenDialog = new ProgressDialog(TwitterAuthorizationActivity.this);
- requestTokenDialog.setCancelable(false);
- requestTokenDialog.setMessage(res.getString(R.string.auth_dialog_wait));
- }
- requestTokenDialog.show();
- startButton.setEnabled(false);
- startButton.setOnTouchListener(null);
- startButton.setOnClickListener(null);
+ @Override
+ protected String getAuthDialogWait() {
+ return res.getString(R.string.auth_dialog_wait);
+ }
- Settings.setTwitterTempTokens(null, null);
- (new Thread() {
+ @Override
+ protected String getAuthDialogPinTitle() {
+ return res.getString(R.string.auth_dialog_pin_title);
+ }
- @Override
- public void run() {
- requestToken();
- }
- }).start();
- }
+ @Override
+ protected String getAuthDialogPinMessage() {
+ return res.getString(R.string.auth_dialog_pin_message);
}
- private class ConfirmPINListener implements View.OnClickListener {
+ @Override
+ protected String getAboutAuth1() {
+ return res.getString(R.string.about_auth_1);
+ }
- @Override
- public void onClick(View arg0) {
- if (StringUtils.isEmpty(((EditText) findViewById(R.id.pin)).getText().toString())) {
- helpDialog(res.getString(R.string.auth_dialog_pin_title), res.getString(R.string.auth_dialog_pin_message));
- return;
- }
+ @Override
+ protected String getAboutAuth2() {
+ return res.getString(R.string.about_auth_2);
+ }
- if (changeTokensDialog == null) {
- changeTokensDialog = new ProgressDialog(TwitterAuthorizationActivity.this);
- changeTokensDialog.setCancelable(false);
- changeTokensDialog.setMessage(res.getString(R.string.auth_dialog_wait));
- }
- changeTokensDialog.show();
- pinEntryButton.setEnabled(false);
- pinEntryButton.setOnTouchListener(null);
- pinEntryButton.setOnClickListener(null);
+ @Override
+ protected String getAuthAuthorize() {
+ return res.getString(R.string.auth_authorize);
+ }
- (new Thread() {
+ @Override
+ protected String getAuthPinHint() {
+ return res.getString(R.string.auth_pin_hint);
+ }
- @Override
- public void run() {
- changeToken();
- }
- }).start();
- }
+ @Override
+ protected String getAuthFinish() {
+ return res.getString(R.string.auth_finish);
}
+
}