diff options
author | Bananeweizen <bananeweizen@gmx.de> | 2012-04-18 20:23:18 +0200 |
---|---|---|
committer | Bananeweizen <bananeweizen@gmx.de> | 2012-04-18 20:23:18 +0200 |
commit | 45e1a0dc358e4a02b2394ae5c140692931eed8e7 (patch) | |
tree | efbc3dfdc569f3ca915587f1788dcdd7da2f1d84 /main | |
parent | fd79c341e2890516494ead8559b108c225549aa8 (diff) | |
download | cgeo-45e1a0dc358e4a02b2394ae5c140692931eed8e7.zip cgeo-45e1a0dc358e4a02b2394ae5c140692931eed8e7.tar.gz cgeo-45e1a0dc358e4a02b2394ae5c140692931eed8e7.tar.bz2 |
refactoring: rest in peace, cgBase
Diffstat (limited to 'main')
22 files changed, 818 insertions, 839 deletions
diff --git a/main/src/cgeo/geocaching/CacheDetailActivity.java b/main/src/cgeo/geocaching/CacheDetailActivity.java index 55b8861..7028b32 100644 --- a/main/src/cgeo/geocaching/CacheDetailActivity.java +++ b/main/src/cgeo/geocaching/CacheDetailActivity.java @@ -7,6 +7,7 @@ import cgeo.geocaching.apps.cache.GeneralAppsFactory; import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.connector.IConnector; +import cgeo.geocaching.connector.gc.GCParser; import cgeo.geocaching.enumerations.LoadFlags; import cgeo.geocaching.enumerations.LoadFlags.SaveFlag; import cgeo.geocaching.enumerations.LogType; @@ -38,6 +39,8 @@ import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.graphics.Bitmap; import android.graphics.Typeface; import android.graphics.drawable.BitmapDrawable; @@ -606,7 +609,7 @@ public class CacheDetailActivity extends AbstractActivity { private class LoadCacheHandler extends CancellableHandler { @Override public void handleRegularMessage(final Message msg) { - if (cgBase.UPDATE_LOAD_PROGRESS_DETAIL == msg.what && msg.obj instanceof String) { + if (UPDATE_LOAD_PROGRESS_DETAIL == msg.what && msg.obj instanceof String) { updateStatusMsg((String) msg.obj); } else { if (search == null) { @@ -772,14 +775,43 @@ public class CacheDetailActivity extends AbstractActivity { @Override public void run() { - search = cgBase.searchByGeocode(geocode, StringUtils.isBlank(geocode) ? guid : null, 0, false, handler); + search = cgCache.searchByGeocode(geocode, StringUtils.isBlank(geocode) ? guid : null, 0, false, handler); handler.sendMessage(Message.obtain()); } } + /** + * Indicates whether the specified action can be used as an intent. This + * method queries the package manager for installed packages that can + * respond to an intent with the specified action. If no suitable package is + * found, this method returns false. + * + * @param context + * The application's environment. + * @param action + * The Intent action to check for availability. + * @param uri + * The Intent URI to check for availability. + * + * @return True if an Intent with the specified action can be sent and + * responded to, false otherwise. + */ + private static boolean isIntentAvailable(Context context, String action, Uri uri) { + final PackageManager packageManager = context.getPackageManager(); + final Intent intent; + if (uri == null) { + intent = new Intent(action); + } else { + intent = new Intent(action, uri); + } + List<ResolveInfo> list = packageManager.queryIntentActivities(intent, + PackageManager.MATCH_DEFAULT_ONLY); + return list.size() > 0; + } + private void addToCalendarWithIntent() { - final boolean calendarAddOnAvailable = cgBase.isIntentAvailable(this, ICalendar.INTENT, Uri.parse(ICalendar.URI_SCHEME + "://" + ICalendar.URI_HOST)); + final boolean calendarAddOnAvailable = isIntentAvailable(this, ICalendar.INTENT, Uri.parse(ICalendar.URI_SCHEME + "://" + ICalendar.URI_HOST)); if (calendarAddOnAvailable) { final Parameters params = new Parameters( @@ -1426,7 +1458,7 @@ public class CacheDetailActivity extends AbstractActivity { if (cache.getHiddenDate() != null) { long time = cache.getHiddenDate().getTime(); if (time > 0) { - String dateString = cgBase.formatFullDate(time); + String dateString = Formatter.formatFullDate(time); if (cache.isEventCache()) { dateString = DateUtils.formatDateTime(cgeoapplication.getInstance().getBaseContext(), time, DateUtils.FORMAT_SHOW_WEEKDAY) + ", " + dateString; } @@ -1525,7 +1557,7 @@ public class CacheDetailActivity extends AbstractActivity { private class StoreCacheHandler extends CancellableHandler { @Override public void handleRegularMessage(Message msg) { - if (cgBase.UPDATE_LOAD_PROGRESS_DETAIL == msg.what && msg.obj instanceof String) { + if (UPDATE_LOAD_PROGRESS_DETAIL == msg.what && msg.obj instanceof String) { updateStatusMsg((String) msg.obj); } else { storeThread = null; @@ -1543,7 +1575,7 @@ public class CacheDetailActivity extends AbstractActivity { private class RefreshCacheHandler extends CancellableHandler { @Override public void handleRegularMessage(Message msg) { - if (cgBase.UPDATE_LOAD_PROGRESS_DETAIL == msg.what && msg.obj instanceof String) { + if (UPDATE_LOAD_PROGRESS_DETAIL == msg.what && msg.obj instanceof String) { updateStatusMsg((String) msg.obj); } else { refreshThread = null; @@ -1627,7 +1659,7 @@ public class CacheDetailActivity extends AbstractActivity { @Override public void run() { - cgBase.refreshCache(CacheDetailActivity.this, cache.getGeocode(), cache.getListId(), handler); + cache.refresh(CacheDetailActivity.this, cache.getListId(), handler); handler.sendEmptyMessage(0); } @@ -1657,7 +1689,7 @@ public class CacheDetailActivity extends AbstractActivity { @Override public void run() { - cgBase.dropCache(cache, handler); + cache.drop(handler); } } @@ -1713,7 +1745,7 @@ public class CacheDetailActivity extends AbstractActivity { @Override public void run() { - handler.sendEmptyMessage(cgBase.addToWatchlist(cache)); + handler.sendEmptyMessage(GCParser.addToWatchlist(cache)); } } @@ -1727,7 +1759,7 @@ public class CacheDetailActivity extends AbstractActivity { @Override public void run() { - handler.sendEmptyMessage(cgBase.removeFromWatchlist(cache)); + handler.sendEmptyMessage(GCParser.removeFromWatchlist(cache)); } } @@ -2176,7 +2208,7 @@ public class CacheDetailActivity extends AbstractActivity { final cgLog log = getItem(position); if (log.date > 0) { - holder.date.setText(cgBase.formatShortDate(log.date)); + holder.date.setText(Formatter.formatShortDate(log.date)); holder.date.setVisibility(View.VISIBLE); } else { holder.date.setVisibility(View.GONE); diff --git a/main/src/cgeo/geocaching/SearchResult.java b/main/src/cgeo/geocaching/SearchResult.java index 556ef32..2e56c7c 100644 --- a/main/src/cgeo/geocaching/SearchResult.java +++ b/main/src/cgeo/geocaching/SearchResult.java @@ -1,5 +1,6 @@ package cgeo.geocaching; +import cgeo.geocaching.connector.gc.Login; import cgeo.geocaching.enumerations.CacheType; import cgeo.geocaching.enumerations.LoadFlags; import cgeo.geocaching.enumerations.LoadFlags.LoadFlag; @@ -128,7 +129,7 @@ public class SearchResult implements Parcelable { } public void setViewstates(String[] viewstates) { - if (cgBase.isEmpty(viewstates)) { + if (Login.isEmpty(viewstates)) { return; } diff --git a/main/src/cgeo/geocaching/VisitCacheActivity.java b/main/src/cgeo/geocaching/VisitCacheActivity.java index 5d5d8ba..891081e 100644 --- a/main/src/cgeo/geocaching/VisitCacheActivity.java +++ b/main/src/cgeo/geocaching/VisitCacheActivity.java @@ -1,6 +1,7 @@ package cgeo.geocaching; import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.connector.gc.GCParser; import cgeo.geocaching.connector.gc.Login; import cgeo.geocaching.enumerations.LoadFlags; import cgeo.geocaching.enumerations.LoadFlags.RemoveFlag; @@ -13,6 +14,7 @@ import cgeo.geocaching.network.Network; import cgeo.geocaching.network.Parameters; import cgeo.geocaching.twitter.Twitter; import cgeo.geocaching.ui.DateDialog; +import cgeo.geocaching.ui.Formatter; import cgeo.geocaching.utils.Log; import cgeo.geocaching.utils.LogTemplateProvider; import cgeo.geocaching.utils.LogTemplateProvider.LogTemplate; @@ -88,13 +90,13 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D showToast(res.getString(R.string.info_log_type_changed)); } - if (cgBase.isEmpty(viewstates) && attempts < 2) { + if (Login.isEmpty(viewstates) && attempts < 2) { final LoadDataThread thread; thread = new LoadDataThread(); thread.start(); return; - } else if (cgBase.isEmpty(viewstates) && attempts >= 2) { + } else if (Login.isEmpty(viewstates) && attempts >= 2) { showToast(res.getString(R.string.err_log_load_data)); showProgress(false); @@ -507,7 +509,7 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D }); final Button dateButton = (Button) findViewById(R.id.date); - dateButton.setText(cgBase.formatShortDate(date.getTime().getTime())); + dateButton.setText(Formatter.formatShortDate(date.getTime().getTime())); dateButton.setOnClickListener(new DateListener()); final EditText logView = (EditText) findViewById(R.id.log); @@ -522,7 +524,7 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D lastState.restore(this); } - if (cgBase.isEmpty(viewstates)) { + if (Login.isEmpty(viewstates)) { enablePostButton(false); new LoadDataThread().start(); } else { @@ -545,7 +547,7 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D date = dateIn; final Button dateButton = (Button) findViewById(R.id.date); - dateButton.setText(cgBase.formatShortDate(date.getTime().getTime())); + dateButton.setText(Formatter.formatShortDate(date.getTime().getTime())); } public void setType(LogType type) { @@ -609,7 +611,7 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D setType(typeSelected); final Button dateButton = (Button) findViewById(R.id.date); - dateButton.setText(cgBase.formatShortDate(date.getTime().getTime())); + dateButton.setText(Formatter.formatShortDate(date.getTime().getTime())); dateButton.setOnClickListener(new DateListener()); final EditText logView = (EditText) findViewById(R.id.log); @@ -659,9 +661,9 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D final String page = Network.getResponseData(Network.getRequest("http://www.geocaching.com/seek/log.aspx", params)); viewstates = Login.getViewstates(page); - trackables = cgBase.parseTrackableLog(page); + trackables = GCParser.parseTrackableLog(page); - final List<LogType> typesPre = cgBase.parseTypes(page); + final List<LogType> typesPre = GCParser.parseTypes(page); if (CollectionUtils.isNotEmpty(typesPre)) { possibleLogTypes.clear(); possibleLogTypes.addAll(typesPre); @@ -695,7 +697,7 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D public StatusCode postLogFn(String log) { try { - final StatusCode status = cgBase.postLog(geocode, cacheid, viewstates, typeSelected, + final StatusCode status = GCParser.postLog(geocode, cacheid, viewstates, typeSelected, date.get(Calendar.YEAR), (date.get(Calendar.MONTH) + 1), date.get(Calendar.DATE), log, trackables); diff --git a/main/src/cgeo/geocaching/activity/AbstractActivity.java b/main/src/cgeo/geocaching/activity/AbstractActivity.java index 8985955..8ddd21a 100644 --- a/main/src/cgeo/geocaching/activity/AbstractActivity.java +++ b/main/src/cgeo/geocaching/activity/AbstractActivity.java @@ -2,7 +2,6 @@ package cgeo.geocaching.activity; import cgeo.geocaching.R; import cgeo.geocaching.Settings; -import cgeo.geocaching.cgBase; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.compatibility.Compatibility; @@ -85,8 +84,6 @@ public abstract class AbstractActivity extends Activity implements IAbstractActi res = this.getResources(); app = (cgeoapplication) this.getApplication(); - cgBase.initialize(app); - // Restore cookie store if needed Cookies.restoreCookieStore(Settings.getCookieStore()); diff --git a/main/src/cgeo/geocaching/activity/AbstractListActivity.java b/main/src/cgeo/geocaching/activity/AbstractListActivity.java index b3bbb3f..7af75b8 100644 --- a/main/src/cgeo/geocaching/activity/AbstractListActivity.java +++ b/main/src/cgeo/geocaching/activity/AbstractListActivity.java @@ -1,6 +1,5 @@ package cgeo.geocaching.activity; -import cgeo.geocaching.cgBase; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.compatibility.Compatibility; @@ -73,7 +72,6 @@ public abstract class AbstractListActivity extends ListActivity implements // init res = this.getResources(); app = (cgeoapplication) this.getApplication(); - cgBase.initialize(app); ActivityMixin.keepScreenOn(this, keepScreenOn); } diff --git a/main/src/cgeo/geocaching/cgCache.java b/main/src/cgeo/geocaching/cgCache.java index 8eeee8d..09102f1 100644 --- a/main/src/cgeo/geocaching/cgCache.java +++ b/main/src/cgeo/geocaching/cgCache.java @@ -9,11 +9,14 @@ import cgeo.geocaching.connector.gc.GCConnector; import cgeo.geocaching.connector.gc.Tile; import cgeo.geocaching.enumerations.CacheSize; import cgeo.geocaching.enumerations.CacheType; +import cgeo.geocaching.enumerations.LoadFlags; import cgeo.geocaching.enumerations.LoadFlags.RemoveFlag; +import cgeo.geocaching.enumerations.LoadFlags.SaveFlag; import cgeo.geocaching.enumerations.LogType; import cgeo.geocaching.enumerations.WaypointType; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.geopoint.GeopointParser; +import cgeo.geocaching.network.HtmlImage; import cgeo.geocaching.utils.CancellableHandler; import cgeo.geocaching.utils.Log; import cgeo.geocaching.utils.LogTemplateProvider; @@ -26,6 +29,8 @@ import android.content.Intent; import android.content.res.Resources; import android.net.Uri; import android.os.Handler; +import android.os.Message; +import android.text.Html; import android.text.Spannable; import java.util.ArrayList; @@ -381,7 +386,7 @@ public class cgCache implements ICache, IWaypoint { * * @return true: page contains guid of cache, false: otherwise */ - boolean isGuidContainedInPage(final String page) { + public boolean isGuidContainedInPage(final String page) { if (StringUtils.isBlank(page)) { return false; } @@ -1397,7 +1402,7 @@ public class cgCache implements ICache, IWaypoint { public void store(Activity activity, CancellableHandler handler) { final int listId = Math.max(getListId(), StoredList.STANDARD_LIST_ID); - cgBase.storeCache(activity, this, null, listId, false, handler); + storeCache(activity, this, null, listId, false, handler); } public void setZoomlevel(int zoomlevel) { @@ -1418,4 +1423,171 @@ public class cgCache implements ICache, IWaypoint { public String getCoordType() { return "cache"; } + + public void drop(Handler handler) { + try { + cgeoapplication.getInstance().markDropped(getGeocode()); + cgeoapplication.getInstance().removeCache(getGeocode(), EnumSet.of(RemoveFlag.REMOVE_CACHE)); + + handler.sendMessage(Message.obtain()); + } catch (Exception e) { + Log.e("cache.drop: ", e); + } + } + + public void checkFields() { + if (StringUtils.isBlank(getGeocode())) { + Log.e("cgBase.loadLogsFromDetails: geo code not parsed correctly"); + } + if (StringUtils.isBlank(getName())) { + Log.e("name not parsed correctly"); + } + if (StringUtils.isBlank(getGuid())) { + Log.e("guid not parsed correctly"); + } + if (getTerrain() == 0.0) { + Log.e("terrain not parsed correctly"); + } + if (getDifficulty() == 0.0) { + Log.e("difficulty not parsed correctly"); + } + if (StringUtils.isBlank(getOwner())) { + Log.e("owner not parsed correctly"); + } + if (StringUtils.isBlank(getOwnerReal())) { + Log.e("owner real not parsed correctly"); + } + if (getHiddenDate() == null) { + Log.e("hidden not parsed correctly"); + } + if (getFavoritePoints() < 0) { + Log.e("favoriteCount not parsed correctly"); + } + if (getSize() == null) { + Log.e("size not parsed correctly"); + } + if (getType() == null || getType() == CacheType.UNKNOWN) { + Log.e("type not parsed correctly"); + } + if (getCoords() == null) { + Log.e("coordinates not parsed correctly"); + } + if (StringUtils.isBlank(getLocation())) { + Log.e("location not parsed correctly"); + } + } + + public void refresh(Activity activity, int newListId, CancellableHandler handler) { + cgeoapplication.getInstance().removeCache(geocode, EnumSet.of(RemoveFlag.REMOVE_CACHE)); + storeCache(activity, null, geocode, newListId, true, handler); + } + + public static void storeCache(Activity activity, cgCache origCache, String geocode, int listId, boolean forceRedownload, CancellableHandler handler) { + try { + cgCache cache; + // get cache details, they may not yet be complete + if (origCache != null) { + // only reload the cache if it was already stored or doesn't have full details (by checking the description) + if (origCache.getListId() >= StoredList.STANDARD_LIST_ID || StringUtils.isBlank(origCache.getDescription())) { + final SearchResult search = searchByGeocode(origCache.getGeocode(), null, listId, false, handler); + cache = search.getFirstCacheFromResult(LoadFlags.LOAD_CACHE_OR_DB); + } else { + cache = origCache; + } + } else if (StringUtils.isNotBlank(geocode)) { + final SearchResult search = searchByGeocode(geocode, null, listId, forceRedownload, handler); + cache = search.getFirstCacheFromResult(LoadFlags.LOAD_CACHE_OR_DB); + } else { + cache = null; + } + + if (cache == null) { + if (handler != null) { + handler.sendMessage(Message.obtain()); + } + + return; + } + + if (CancellableHandler.isCancelled(handler)) { + return; + } + + final HtmlImage imgGetter = new HtmlImage(activity, cache.getGeocode(), false, listId, true); + + // store images from description + if (StringUtils.isNotBlank(cache.getDescription())) { + Html.fromHtml(cache.getDescription(), imgGetter, null); + } + + if (CancellableHandler.isCancelled(handler)) { + return; + } + + // store spoilers + if (CollectionUtils.isNotEmpty(cache.getSpoilers())) { + for (cgImage oneSpoiler : cache.getSpoilers()) { + imgGetter.getDrawable(oneSpoiler.getUrl()); + } + } + + if (CancellableHandler.isCancelled(handler)) { + return; + } + + // store images from logs + if (Settings.isStoreLogImages()) { + for (cgLog log : cache.getLogs(true)) { + if (CollectionUtils.isNotEmpty(log.logImages)) { + for (cgImage oneLogImg : log.logImages) { + imgGetter.getDrawable(oneLogImg.getUrl()); + } + } + } + } + + if (CancellableHandler.isCancelled(handler)) { + return; + } + + // store map previews + StaticMapsProvider.downloadMaps(cache, activity); + + if (CancellableHandler.isCancelled(handler)) { + return; + } + + cache.setListId(listId); + cgeoapplication.getInstance().saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); + + if (handler != null) { + handler.sendMessage(Message.obtain()); + } + } catch (Exception e) { + Log.e("cgBase.storeCache"); + } + } + + public static SearchResult searchByGeocode(final String geocode, final String guid, final int listId, final boolean forceReload, final CancellableHandler handler) { + if (StringUtils.isBlank(geocode) && StringUtils.isBlank(guid)) { + Log.e("cgeoBase.searchByGeocode: No geocode nor guid given"); + return null; + } + + cgeoapplication app = cgeoapplication.getInstance(); + if (!forceReload && listId == StoredList.TEMPORARY_LIST_ID && (app.isOffline(geocode, guid) || app.isThere(geocode, guid, true, true))) { + final SearchResult search = new SearchResult(); + final String realGeocode = StringUtils.isNotBlank(geocode) ? geocode : app.getGeocode(guid); + search.addGeocode(realGeocode); + return search; + } + + // if we have no geocode, we can't dynamically select the handler, but must explicitly use GC + if (geocode == null && guid != null) { + return GCConnector.getInstance().searchByGeocode(null, guid, app, handler); + } + + return ConnectorFactory.getConnector(geocode).searchByGeocode(geocode, guid, app, handler); + } + } diff --git a/main/src/cgeo/geocaching/cgeocaches.java b/main/src/cgeo/geocaching/cgeocaches.java index 184d254..70bf892 100644 --- a/main/src/cgeo/geocaching/cgeocaches.java +++ b/main/src/cgeo/geocaching/cgeocaches.java @@ -6,6 +6,7 @@ import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.activity.Progress; import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; import cgeo.geocaching.apps.cachelist.CacheListAppFactory; +import cgeo.geocaching.connector.gc.GCParser; import cgeo.geocaching.enumerations.CacheListType; import cgeo.geocaching.enumerations.CacheType; import cgeo.geocaching.enumerations.LoadFlags; @@ -674,7 +675,7 @@ public class cgeocaches extends AbstractListActivity { // refresh standard list if it has changed (new caches downloaded) if (type == CacheListType.OFFLINE && listId >= StoredList.STANDARD_LIST_ID && search != null) { - SearchResult newSearch = cgBase.searchByStored(coords, cacheType, listId); + SearchResult newSearch = cgeoapplication.getInstance().getBatchOfStoredCaches(true, coords, cacheType, listId); if (newSearch != null && newSearch.getTotal() != search.getTotal()) { refreshCurrentList(); } @@ -1097,7 +1098,7 @@ public class cgeocaches extends AbstractListActivity { return true; } else if (id == MENU_DROP_CACHE) { - cgBase.dropCache(getCacheFromAdapter(adapterInfo), new Handler() { + getCacheFromAdapter(adapterInfo).drop(new Handler() { @Override public void handleMessage(Message msg) { refreshCurrentList(); @@ -1505,7 +1506,7 @@ public class cgeocaches extends AbstractListActivity { @Override public void run() { - search = cgBase.searchByStored(coords, Settings.getCacheType(), listId); + search = cgeoapplication.getInstance().getBatchOfStoredCaches(true, coords, Settings.getCacheType(), listId); handler.sendMessage(Message.obtain()); } } @@ -1535,7 +1536,7 @@ public class cgeocaches extends AbstractListActivity { @Override public void run() { - search = cgBase.searchByNextPage(this, search, Settings.isShowCaptcha()); + search = GCParser.searchByNextPage(this, search, Settings.isShowCaptcha()); handler.sendMessage(Message.obtain()); } @@ -1562,7 +1563,7 @@ public class cgeocaches extends AbstractListActivity { @Override public void run() { - search = cgBase.searchByCoords(this, coords, cacheType, Settings.isShowCaptcha()); + search = GCParser.searchByCoords(this, coords, cacheType, Settings.isShowCaptcha()); handler.sendMessage(Message.obtain()); } @@ -1589,7 +1590,7 @@ public class cgeocaches extends AbstractListActivity { @Override public void run() { - search = cgBase.searchByKeyword(this, keyword, cacheType, Settings.isShowCaptcha()); + search = GCParser.searchByKeyword(this, keyword, cacheType, Settings.isShowCaptcha()); handler.sendMessage(Message.obtain()); } } @@ -1615,7 +1616,7 @@ public class cgeocaches extends AbstractListActivity { @Override public void run() { - search = cgBase.searchByUsername(this, username, cacheType, Settings.isShowCaptcha()); + search = GCParser.searchByUsername(this, username, cacheType, Settings.isShowCaptcha()); handler.sendMessage(Message.obtain()); } } @@ -1647,7 +1648,7 @@ public class cgeocaches extends AbstractListActivity { params.put("cacheType", cacheType.id); } - search = cgBase.searchByOwner(this, username, cacheType, Settings.isShowCaptcha()); + search = GCParser.searchByOwner(this, username, cacheType, Settings.isShowCaptcha()); handler.sendMessage(Message.obtain()); } @@ -1717,7 +1718,7 @@ public class cgeocaches extends AbstractListActivity { } detailProgress++; - cgBase.refreshCache(cgeocaches.this, cache.getGeocode(), listIdLD, null); + cache.refresh(cgeocaches.this, listIdLD, null); handler.sendEmptyMessage(cacheList.indexOf(cache)); @@ -1780,7 +1781,7 @@ public class cgeocaches extends AbstractListActivity { handler.sendMessage(handler.obtainMessage(1, GCcode)); yield(); - cgBase.storeCache(cgeocaches.this, null, GCcode, listIdLFW, false, null); + cgCache.storeCache(cgeocaches.this, null, GCcode, listIdLFW, false, null); handler.sendMessage(handler.obtainMessage(2, GCcode)); yield(); diff --git a/main/src/cgeo/geocaching/cgeoinit.java b/main/src/cgeo/geocaching/cgeoinit.java index 5afe12a..6493582 100644 --- a/main/src/cgeo/geocaching/cgeoinit.java +++ b/main/src/cgeo/geocaching/cgeoinit.java @@ -12,6 +12,7 @@ import cgeo.geocaching.network.Cookies; import cgeo.geocaching.network.Network; import cgeo.geocaching.network.Parameters; import cgeo.geocaching.twitter.TwitterAuthorizationActivity; +import cgeo.geocaching.ui.Formatter; import cgeo.geocaching.utils.Log; import cgeo.geocaching.utils.LogTemplateProvider; import cgeo.geocaching.utils.LogTemplateProvider.LogTemplate; @@ -733,7 +734,7 @@ public class cgeoinit extends AbstractActivity { TextView lastBackup = (TextView) findViewById(R.id.backup_last); File lastBackupFile = cgeoapplication.isRestoreFile(); if (lastBackupFile != null) { - lastBackup.setText(res.getString(R.string.init_backup_last) + " " + cgBase.formatTime(lastBackupFile.lastModified()) + ", " + cgBase.formatDate(lastBackupFile.lastModified())); + lastBackup.setText(res.getString(R.string.init_backup_last) + " " + Formatter.formatTime(lastBackupFile.lastModified()) + ", " + Formatter.formatDate(lastBackupFile.lastModified())); } else { lastBackup.setText(res.getString(R.string.init_backup_last_no)); } diff --git a/main/src/cgeo/geocaching/cgeopoint.java b/main/src/cgeo/geocaching/cgeopoint.java index 73c0b18..d501d03 100644 --- a/main/src/cgeo/geocaching/cgeopoint.java +++ b/main/src/cgeo/geocaching/cgeopoint.java @@ -6,6 +6,7 @@ import cgeo.geocaching.geopoint.DistanceParser; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.geopoint.GeopointFormatter; import cgeo.geocaching.geopoint.GeopointParser; +import cgeo.geocaching.ui.Formatter; import cgeo.geocaching.utils.Log; import org.apache.commons.lang3.StringUtils; @@ -70,7 +71,7 @@ public class cgeopoint extends AbstractActivity { longitude.setText(lonString); latitude.setText(latString); - date.setText(cgBase.formatShortDateTime(getContext(), loc.getDate())); + date.setText(Formatter.formatShortDateTime(getContext(), loc.getDate())); return v; } diff --git a/main/src/cgeo/geocaching/cgeopopup.java b/main/src/cgeo/geocaching/cgeopopup.java index c1a5b01..99e75d8 100644 --- a/main/src/cgeo/geocaching/cgeopopup.java +++ b/main/src/cgeo/geocaching/cgeopopup.java @@ -596,7 +596,7 @@ public class cgeopopup extends AbstractActivity { @Override public void run() { - cgBase.dropCache(cache, handler); + cache.drop(handler); } } diff --git a/main/src/cgeo/geocaching/cgeotouch.java b/main/src/cgeo/geocaching/cgeotouch.java index 570df1c..56b5ba1 100644 --- a/main/src/cgeo/geocaching/cgeotouch.java +++ b/main/src/cgeo/geocaching/cgeotouch.java @@ -1,6 +1,7 @@ package cgeo.geocaching; import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.connector.gc.GCParser; import cgeo.geocaching.connector.gc.Login; import cgeo.geocaching.enumerations.LogType; import cgeo.geocaching.enumerations.StatusCode; @@ -8,6 +9,7 @@ import cgeo.geocaching.network.Network; import cgeo.geocaching.network.Parameters; import cgeo.geocaching.twitter.Twitter; import cgeo.geocaching.ui.DateDialog; +import cgeo.geocaching.ui.Formatter; import cgeo.geocaching.utils.Log; import org.apache.commons.lang3.StringUtils; @@ -63,7 +65,7 @@ public class cgeotouch extends AbstractActivity implements DateDialog.DateDialog setType((LogType) msg.obj); showToast(res.getString(R.string.info_log_type_changed)); } else { - if (cgBase.isEmpty(viewstates) && attempts < 2) { + if (Login.isEmpty(viewstates) && attempts < 2) { showToast(res.getString(R.string.err_log_load_data_again)); loadData thread; @@ -71,7 +73,7 @@ public class cgeotouch extends AbstractActivity implements DateDialog.DateDialog thread.start(); return; - } else if (cgBase.isEmpty(viewstates) && attempts >= 2) { + } else if (Login.isEmpty(viewstates) && attempts >= 2) { showToast(res.getString(R.string.err_log_load_data)); showProgress(false); @@ -203,8 +205,8 @@ public class cgeotouch extends AbstractActivity implements DateDialog.DateDialog textContent = text.getText().toString(); final long now = System.currentTimeMillis(); - dateString = cgBase.formatDate(now); - timeString = cgBase.formatTime(now); + dateString = Formatter.formatDate(now); + timeString = Formatter.formatTime(now); if ((id & 0x4) == 0x4) { addText += dateString; @@ -287,7 +289,7 @@ public class cgeotouch extends AbstractActivity implements DateDialog.DateDialog }); Button dateButton = (Button) findViewById(R.id.date); - dateButton.setText(cgBase.formatShortDate(date.getTime().getTime())); + dateButton.setText(Formatter.formatShortDate(date.getTime().getTime())); dateButton.setOnClickListener(new cgeotouchDateListener()); if (tweetBox == null) { @@ -299,7 +301,7 @@ public class cgeotouch extends AbstractActivity implements DateDialog.DateDialog tweetCheck.setChecked(true); Button buttonPost = (Button) findViewById(R.id.post); - if (cgBase.isEmpty(viewstates)) { + if (Login.isEmpty(viewstates)) { buttonPost.setEnabled(false); buttonPost.setOnTouchListener(null); buttonPost.setOnClickListener(null); @@ -319,7 +321,7 @@ public class cgeotouch extends AbstractActivity implements DateDialog.DateDialog date = dateIn; final Button dateButton = (Button) findViewById(R.id.date); - dateButton.setText(cgBase.formatShortDate(date.getTime().getTime())); + dateButton.setText(Formatter.formatShortDate(date.getTime().getTime())); } public void setType(LogType type) { @@ -396,7 +398,7 @@ public class cgeotouch extends AbstractActivity implements DateDialog.DateDialog viewstates = Login.getViewstates(page); - final List<LogType> typesPre = cgBase.parseTypes(page); + final List<LogType> typesPre = GCParser.parseTypes(page); if (typesPre.size() > 0) { logTypes.clear(); logTypes.addAll(typesPre); @@ -442,7 +444,7 @@ public class cgeotouch extends AbstractActivity implements DateDialog.DateDialog tweetCheck = (CheckBox) findViewById(R.id.tweet); } - final StatusCode status = cgBase.postLogTrackable(guid, tracking, viewstates, typeSelected, date.get(Calendar.YEAR), (date.get(Calendar.MONTH) + 1), date.get(Calendar.DATE), log); + final StatusCode status = GCParser.postLogTrackable(guid, tracking, viewstates, typeSelected, date.get(Calendar.YEAR), (date.get(Calendar.MONTH) + 1), date.get(Calendar.DATE), log); if (status == StatusCode.NO_ERROR && Settings.isUseTwitter() && Settings.isTwitterLoginValid() && diff --git a/main/src/cgeo/geocaching/cgeotrackable.java b/main/src/cgeo/geocaching/cgeotrackable.java index 8306217..5eeec9a 100644 --- a/main/src/cgeo/geocaching/cgeotrackable.java +++ b/main/src/cgeo/geocaching/cgeotrackable.java @@ -1,8 +1,10 @@ package cgeo.geocaching; import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.connector.gc.GCParser; import cgeo.geocaching.geopoint.HumanDistance; import cgeo.geocaching.network.HtmlImage; +import cgeo.geocaching.ui.Formatter; import cgeo.geocaching.utils.Log; import org.apache.commons.collections.CollectionUtils; @@ -155,7 +157,7 @@ public class cgeotrackable extends AbstractActivity { // trackable released if (trackable.getReleased() != null) { - addDetail(R.string.trackable_released, cgBase.formatDate(trackable.getReleased().getTime())); + addDetail(R.string.trackable_released, Formatter.formatDate(trackable.getReleased().getTime())); } // trackable distance @@ -428,7 +430,7 @@ public class cgeotrackable extends AbstractActivity { trackable = cgeoapplication.getInstance().getTrackableByGeocode(geocode); if ((trackable == null || trackable.isLoggable()) && !StringUtils.startsWithIgnoreCase(geocode, "GK")) { - trackable = cgBase.searchTrackable(geocode, guid, id); + trackable = GCParser.searchTrackable(geocode, guid, id); } handler.sendMessage(Message.obtain()); } @@ -446,7 +448,7 @@ public class cgeotrackable extends AbstractActivity { rowView = (RelativeLayout) inflater.inflate(R.layout.trackable_logs_item, null); if (log.date > 0) { - ((TextView) rowView.findViewById(R.id.added)).setText(cgBase.formatShortDate(log.date)); + ((TextView) rowView.findViewById(R.id.added)).setText(Formatter.formatShortDate(log.date)); } ((TextView) rowView.findViewById(R.id.type)).setText(log.type.getL10n()); diff --git a/main/src/cgeo/geocaching/connector/gc/GCBase.java b/main/src/cgeo/geocaching/connector/gc/GCBase.java index e038573..2f22c52 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCBase.java +++ b/main/src/cgeo/geocaching/connector/gc/GCBase.java @@ -2,7 +2,6 @@ package cgeo.geocaching.connector.gc; import cgeo.geocaching.SearchResult; import cgeo.geocaching.Settings; -import cgeo.geocaching.cgBase; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.enumerations.CacheSize; @@ -185,7 +184,7 @@ public class GCBase { if (strategy.flags.contains(StrategyFlag.SEARCH_NEARBY)) { Geopoint center = viewport.getCenter(); if ((lastSearchViewport == null) || !lastSearchViewport.contains(center)) { - SearchResult search = cgBase.searchByCoords(null, center, Settings.getCacheType(), false); + SearchResult search = GCParser.searchByCoords(null, center, Settings.getCacheType(), false); if (search != null && !search.isEmpty()) { final Set<String> geocodes = search.getGeocodes(); if (Settings.isPremiumMember()) { diff --git a/main/src/cgeo/geocaching/connector/gc/GCConnector.java b/main/src/cgeo/geocaching/connector/gc/GCConnector.java index f539d58..a431359 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCConnector.java +++ b/main/src/cgeo/geocaching/connector/gc/GCConnector.java @@ -3,7 +3,6 @@ package cgeo.geocaching.connector.gc; import cgeo.geocaching.R; import cgeo.geocaching.SearchResult; import cgeo.geocaching.Settings; -import cgeo.geocaching.cgBase; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.connector.AbstractConnector; @@ -101,7 +100,7 @@ public class GCConnector extends AbstractConnector { params.put("log", "y"); params.put("numlogs", String.valueOf(GCConstants.NUMBER_OF_LOGS)); - cgBase.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_loadpage); + CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_loadpage); final String page = Login.getRequestLogged("http://www.geocaching.com/seek/cache_details.aspx", params); @@ -124,7 +123,7 @@ public class GCConnector extends AbstractConnector { return search; } - final SearchResult searchResult = cgBase.parseCache(page, handler); + final SearchResult searchResult = GCParser.parseCache(page, handler); if (searchResult == null || CollectionUtils.isEmpty(searchResult.getGeocodes())) { Log.e("cgeoBase.searchByGeocode: No cache parsed"); diff --git a/main/src/cgeo/geocaching/cgBase.java b/main/src/cgeo/geocaching/connector/gc/GCParser.java index eda6d81..b6d8f26 100644 --- a/main/src/cgeo/geocaching/cgBase.java +++ b/main/src/cgeo/geocaching/connector/gc/GCParser.java @@ -1,14 +1,19 @@ -// $codepro.audit.disable logExceptions -package cgeo.geocaching; - -import cgeo.geocaching.connector.ConnectorFactory; -import cgeo.geocaching.connector.gc.GCConnector; -import cgeo.geocaching.connector.gc.GCConstants; -import cgeo.geocaching.connector.gc.Login; +package cgeo.geocaching.connector.gc; + +import cgeo.geocaching.R; +import cgeo.geocaching.SearchResult; +import cgeo.geocaching.Settings; +import cgeo.geocaching.cgCache; +import cgeo.geocaching.cgImage; +import cgeo.geocaching.cgLog; +import cgeo.geocaching.cgSearchThread; +import cgeo.geocaching.cgTrackable; +import cgeo.geocaching.cgTrackableLog; +import cgeo.geocaching.cgWaypoint; +import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.enumerations.CacheSize; import cgeo.geocaching.enumerations.CacheType; import cgeo.geocaching.enumerations.LoadFlags; -import cgeo.geocaching.enumerations.LoadFlags.RemoveFlag; import cgeo.geocaching.enumerations.LoadFlags.SaveFlag; import cgeo.geocaching.enumerations.LogType; import cgeo.geocaching.enumerations.LogTypeTrackable; @@ -19,7 +24,6 @@ import cgeo.geocaching.gcvote.GCVote; import cgeo.geocaching.gcvote.GCVoteRating; import cgeo.geocaching.geopoint.DistanceParser; import cgeo.geocaching.geopoint.Geopoint; -import cgeo.geocaching.network.HtmlImage; import cgeo.geocaching.network.Network; import cgeo.geocaching.network.Parameters; import cgeo.geocaching.ui.DirectionImage; @@ -35,20 +39,10 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.res.Resources; import android.net.Uri; -import android.os.Handler; -import android.os.Message; import android.text.Html; import android.text.Spannable; import android.text.Spanned; -import android.text.format.DateUtils; import android.text.style.StrikethroughSpan; import java.net.URLDecoder; @@ -62,64 +56,9 @@ import java.util.Locale; import java.util.Set; import java.util.regex.Matcher; -public class cgBase { - +public abstract class GCParser { private final static SimpleDateFormat dateTbIn1 = new SimpleDateFormat("EEEEE, dd MMMMM yyyy", Locale.ENGLISH); // Saturday, 28 March 2009 private final static SimpleDateFormat dateTbIn2 = new SimpleDateFormat("EEEEE, MMMMM dd, yyyy", Locale.ENGLISH); // Saturday, March 28, 2009 - public static String version = null; - - private static Context context; - public static Resources res; - - public static final int UPDATE_LOAD_PROGRESS_DETAIL = 42186; - - private cgBase() { - //initialize(app); - throw new UnsupportedOperationException(); // static class, not to be instantiated - } - - /** - * Called from AbstractActivity.onCreate() and AbstractListActivity.onCreate() - * - * @param app - */ - public static void initialize(final cgeoapplication app) { - context = app.getBaseContext(); - res = app.getBaseContext().getResources(); - - try { - final PackageManager manager = app.getPackageManager(); - final PackageInfo info = manager.getPackageInfo(app.getPackageName(), 0); - version = info.versionName; - } catch (PackageManager.NameNotFoundException e) { - Log.e("unable to get version information", e); - version = null; - } - } - - public static void sendLoadProgressDetail(final Handler handler, final int str) { - if (null != handler) { - handler.obtainMessage(UPDATE_LOAD_PROGRESS_DETAIL, cgeoapplication.getInstance().getString(str)).sendToTarget(); - } - } - - /** - * checks if an Array of Strings is empty or not. Empty means: - * - Array is null - * - or all elements are null or empty strings - */ - public static boolean isEmpty(String[] a) { - if (a == null) { - return true; - } - - for (String s : a) { - if (StringUtils.isNotEmpty(s)) { - return false; - } - } - return true; - } private static SearchResult parseSearch(final cgSearchThread thread, final String url, final String pageContent, final boolean showCaptcha) { if (StringUtils.isBlank(pageContent)) { @@ -275,7 +214,7 @@ public class cgBase { cids.add(cache.getCacheId()); } - // favourite count + // favorite count try { result = BaseUtils.getMatch(row, GCConstants.PATTERN_SEARCH_FAVORITE, false, 1, null, true); if (null != result) { @@ -385,7 +324,7 @@ public class cgBase { } // update progress message so user knows we're still working. Otherwise it will remain on whatever was set // in getExtraOnlineInfo (which could be logs, gcvote, or elevation) - sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_render); + CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_render); // save full detailed caches cgeoapplication.getInstance().saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); } @@ -393,7 +332,7 @@ public class cgBase { } static SearchResult parseCacheFromText(final String page, final CancellableHandler handler) { - sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_details); + CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_details); if (StringUtils.isBlank(page)) { Log.e("cgeoBase.parseCache: No page given"); @@ -544,7 +483,7 @@ public class cgBase { } } - checkFields(cache); + cache.checkFields(); // cache personal note cache.setPersonalNote(BaseUtils.getMatch(page, GCConstants.PATTERN_PERSONALNOTE, true, cache.getPersonalNote())); @@ -591,7 +530,7 @@ public class cgBase { if (CancellableHandler.isCancelled(handler)) { return null; } - sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_spoilers); + CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_spoilers); final Matcher matcherSpoilersInside = GCConstants.PATTERN_SPOILERSINSIDE.matcher(spoilers); @@ -685,8 +624,7 @@ public class cgBase { final String originalCoords = BaseUtils.getMatch(page, GCConstants.PATTERN_LATLON_ORIG, false, null); if (null != originalCoords) { - // res is null during the unit tests - final cgWaypoint waypoint = new cgWaypoint(res != null ? res.getString(R.string.cache_coordinates_original) : "res = null", WaypointType.WAYPOINT, false); + final cgWaypoint waypoint = new cgWaypoint(cgeoapplication.getInstance().getString(R.string.cache_coordinates_original), WaypointType.WAYPOINT, false); waypoint.setCoords(new Geopoint(originalCoords)); cache.addWaypoint(waypoint, false); cache.setUserModifiedCoords(true); @@ -703,8 +641,7 @@ public class cgBase { if (CancellableHandler.isCancelled(handler)) { return null; } - sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_waypoints); - + CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_waypoints); String wpList = page.substring(wpBegin); @@ -731,7 +668,7 @@ public class cgBase { // waypoint name // res is null during the unit tests - final String name = BaseUtils.getMatch(wp[6], GCConstants.PATTERN_WPNAME, true, 1, res != null ? res.getString(R.string.waypoint) : "res = null", true); + final String name = BaseUtils.getMatch(wp[6], GCConstants.PATTERN_WPNAME, true, 1, cgeoapplication.getInstance().getString(R.string.waypoint), true); // waypoint type final String resulttype = BaseUtils.getMatch(wp[3], GCConstants.PATTERN_WPTYPE, null); @@ -779,485 +716,6 @@ public class cgBase { return searchResult; } - private static void getExtraOnlineInfo(final cgCache cache, final String page, final CancellableHandler handler) { - if (CancellableHandler.isCancelled(handler)) { - return; - } - - //cache.setLogs(loadLogsFromDetails(page, cache, false)); - if (Settings.isFriendLogsWanted()) { - sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_logs); - List<cgLog> allLogs = cache.getLogs(); - List<cgLog> friendLogs = loadLogsFromDetails(page, cache, true, false); - if (friendLogs != null) { - for (cgLog log : friendLogs) { - if (allLogs.contains(log)) { - allLogs.get(allLogs.indexOf(log)).friend = true; - } else { - allLogs.add(log); - } - } - } - } - - if (Settings.isElevationWanted()) { - if (CancellableHandler.isCancelled(handler)) { - return; - } - sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_elevation); - if (cache.getCoords() != null) { - cache.setElevation(cache.getCoords().getElevation()); - } - } - - if (Settings.isRatingWanted()) { - if (CancellableHandler.isCancelled(handler)) { - return; - } - sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_gcvote); - final GCVoteRating rating = GCVote.getRating(cache.getGuid(), cache.getGeocode()); - if (rating != null) { - cache.setRating(rating.getRating()); - cache.setVotes(rating.getVotes()); - cache.setMyVote(rating.getMyVote()); - } - } - } - - /** - * Load logs from a cache details page. - * - * @param page - * the text of the details page - * @param cache - * the cache object to put the logs in - * @param friends - * retrieve friend logs - */ - private static List<cgLog> loadLogsFromDetails(final String page, final cgCache cache, final boolean friends, final boolean getDataFromPage) { - String rawResponse = null; - - if (!getDataFromPage) { - final Matcher userTokenMatcher = GCConstants.PATTERN_USERTOKEN2.matcher(page); - if (!userTokenMatcher.find()) { - Log.e("cgBase.loadLogsFromDetails: unable to extract userToken"); - return null; - } - - final String userToken = userTokenMatcher.group(1); - final Parameters params = new Parameters( - "tkn", userToken, - "idx", "1", - "num", String.valueOf(GCConstants.NUMBER_OF_LOGS), - "decrypt", "true", - // "sp", Boolean.toString(personal), // personal logs - "sf", Boolean.toString(friends)); - - final HttpResponse response = Network.getRequest("http://www.geocaching.com/seek/geocache.logbook", params); - if (response == null) { - Log.e("cgBase.loadLogsFromDetails: cannot log logs, response is null"); - return null; - } - final int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode != 200) { - Log.e("cgBase.loadLogsFromDetails: error " + statusCode + " when requesting log information"); - return null; - } - rawResponse = Network.getResponseData(response); - if (rawResponse == null) { - Log.e("cgBase.loadLogsFromDetails: unable to read whole response"); - return null; - } - } else { - // extract embedded JSON data from page - rawResponse = BaseUtils.getMatch(page, GCConstants.PATTERN_LOGBOOK, ""); - } - - List<cgLog> logs = new ArrayList<cgLog>(); - - try { - final JSONObject resp = new JSONObject(rawResponse); - if (!resp.getString("status").equals("success")) { - Log.e("cgBase.loadLogsFromDetails: status is " + resp.getString("status")); - return null; - } - - final JSONArray data = resp.getJSONArray("data"); - - for (int index = 0; index < data.length(); index++) { - final JSONObject entry = data.getJSONObject(index); - final cgLog logDone = new cgLog(); - logDone.friend = friends; - - // FIXME: use the "LogType" field instead of the "LogTypeImage" one. - final String logIconNameExt = entry.optString("LogTypeImage", ".gif"); - final String logIconName = logIconNameExt.substring(0, logIconNameExt.length() - 4); - logDone.type = LogType.getByIconName(logIconName); - - try { - logDone.date = Login.parseGcCustomDate(entry.getString("Visited")).getTime(); - } catch (ParseException e) { - Log.e("cgBase.loadLogsFromDetails: failed to parse log date."); - } - - logDone.author = entry.getString("UserName"); - logDone.found = entry.getInt("GeocacheFindCount"); - logDone.log = entry.getString("LogText"); - - final JSONArray images = entry.getJSONArray("Images"); - for (int i = 0; i < images.length(); i++) { - final JSONObject image = images.getJSONObject(i); - String url = "http://img.geocaching.com/cache/log/" + image.getString("FileName"); - String title = image.getString("Name"); - final cgImage logImage = new cgImage(url, title); - if (logDone.logImages == null) { - logDone.logImages = new ArrayList<cgImage>(); - } - logDone.logImages.add(logImage); - } - - logs.add(logDone); - } - } catch (JSONException e) { - // failed to parse logs - Log.w("cgBase.loadLogsFromDetails: Failed to parse cache logs", e); - } - - return logs; - } - - private static void checkFields(cgCache cache) { - if (StringUtils.isBlank(cache.getGeocode())) { - Log.e("cgBase.loadLogsFromDetails: geo code not parsed correctly"); - } - if (StringUtils.isBlank(cache.getName())) { - Log.e("name not parsed correctly"); - } - if (StringUtils.isBlank(cache.getGuid())) { - Log.e("guid not parsed correctly"); - } - if (cache.getTerrain() == 0.0) { - Log.e("terrain not parsed correctly"); - } - if (cache.getDifficulty() == 0.0) { - Log.e("difficulty not parsed correctly"); - } - if (StringUtils.isBlank(cache.getOwner())) { - Log.e("owner not parsed correctly"); - } - if (StringUtils.isBlank(cache.getOwnerReal())) { - Log.e("owner real not parsed correctly"); - } - if (cache.getHiddenDate() == null) { - Log.e("hidden not parsed correctly"); - } - if (cache.getFavoritePoints() < 0) { - Log.e("favoriteCount not parsed correctly"); - } - if (cache.getSize() == null) { - Log.e("size not parsed correctly"); - } - if (cache.getType() == null || cache.getType() == CacheType.UNKNOWN) { - Log.e("type not parsed correctly"); - } - if (cache.getCoords() == null) { - Log.e("coordinates not parsed correctly"); - } - if (StringUtils.isBlank(cache.getLocation())) { - Log.e("location not parsed correctly"); - } - } - - /** - * Parse a trackable HTML description into a cgTrackable object - * - * @param page - * the HTML page to parse, already processed through {@link BaseUtils#replaceWhitespace} - * @param app - * if not null, the application to use to save the trackable - * @return the parsed trackable, or null if none could be parsed - */ - public static cgTrackable parseTrackable(final String page, final cgeoapplication app, final String possibleTrackingcode) { - if (StringUtils.isBlank(page)) { - Log.e("cgeoBase.parseTrackable: No page given"); - return null; - } - - final cgTrackable trackable = new cgTrackable(); - - // trackable geocode - trackable.setGeocode(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_GEOCODE, true, trackable.getGeocode()).toUpperCase()); - - // trackable id - trackable.setGuid(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_GUID, true, trackable.getGuid())); - - // trackable icon - trackable.setIconUrl(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_ICON, true, trackable.getIconUrl())); - - // trackable name - trackable.setName(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_NAME, true, trackable.getName())); - - // trackable type - if (StringUtils.isNotBlank(trackable.getName())) { - trackable.setType(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_TYPE, true, trackable.getType())); - } - - // trackable owner name - try { - final Matcher matcherOwner = GCConstants.PATTERN_TRACKABLE_OWNER.matcher(page); - if (matcherOwner.find() && matcherOwner.groupCount() > 0) { - trackable.setOwnerGuid(matcherOwner.group(1)); - trackable.setOwner(matcherOwner.group(2).trim()); - } - } catch (Exception e) { - // failed to parse trackable owner name - Log.w("cgeoBase.parseTrackable: Failed to parse trackable owner name"); - } - - // trackable origin - trackable.setOrigin(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_ORIGIN, true, trackable.getOrigin())); - - // trackable spotted - try { - final Matcher matcherSpottedCache = GCConstants.PATTERN_TRACKABLE_SPOTTEDCACHE.matcher(page); - if (matcherSpottedCache.find() && matcherSpottedCache.groupCount() > 0) { - trackable.setSpottedGuid(matcherSpottedCache.group(1)); - trackable.setSpottedName(matcherSpottedCache.group(2).trim()); - trackable.setSpottedType(cgTrackable.SPOTTED_CACHE); - } - - final Matcher matcherSpottedUser = GCConstants.PATTERN_TRACKABLE_SPOTTEDUSER.matcher(page); - if (matcherSpottedUser.find() && matcherSpottedUser.groupCount() > 0) { - trackable.setSpottedGuid(matcherSpottedUser.group(1)); - trackable.setSpottedName(matcherSpottedUser.group(2).trim()); - trackable.setSpottedType(cgTrackable.SPOTTED_USER); - } - - if (BaseUtils.matches(page, GCConstants.PATTERN_TRACKABLE_SPOTTEDUNKNOWN)) { - trackable.setSpottedType(cgTrackable.SPOTTED_UNKNOWN); - } - - if (BaseUtils.matches(page, GCConstants.PATTERN_TRACKABLE_SPOTTEDOWNER)) { - trackable.setSpottedType(cgTrackable.SPOTTED_OWNER); - } - } catch (Exception e) { - // failed to parse trackable last known place - Log.w("cgeoBase.parseTrackable: Failed to parse trackable last known place"); - } - - // released date - can be missing on the page - try { - String releaseString = BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_RELEASES, false, null); - if (releaseString != null) { - trackable.setReleased(dateTbIn1.parse(releaseString)); - if (trackable.getReleased() == null) { - trackable.setReleased(dateTbIn2.parse(releaseString)); - } - } - } catch (ParseException e1) { - trackable.setReleased(null); - } - - - // trackable distance - try { - final String distance = BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_DISTANCE, false, null); - if (null != distance) { - trackable.setDistance(DistanceParser.parseDistance(distance, Settings.isUseMetricUnits())); - } - } catch (NumberFormatException e) { - throw e; - } - - // trackable goal - trackable.setGoal(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_GOAL, true, trackable.getGoal())); - - // trackable details & image - try { - final Matcher matcherDetailsImage = GCConstants.PATTERN_TRACKABLE_DETAILSIMAGE.matcher(page); - if (matcherDetailsImage.find() && matcherDetailsImage.groupCount() > 0) { - final String image = StringUtils.trim(matcherDetailsImage.group(3)); - final String details = StringUtils.trim(matcherDetailsImage.group(4)); - - if (StringUtils.isNotEmpty(image)) { - trackable.setImage(image); - } - if (StringUtils.isNotEmpty(details) && !StringUtils.equals(details, "No additional details available.")) { - trackable.setDetails(details); - } - } - } catch (Exception e) { - // failed to parse trackable details & image - Log.w("cgeoBase.parseTrackable: Failed to parse trackable details & image"); - } - - // trackable logs - try - { - final Matcher matcherLogs = GCConstants.PATTERN_TRACKABLE_LOG.matcher(page); - /* - * 1. Type (img) - * 2. Date - * 3. Author - * 4. Cache-GUID - * 5. <ignored> (strike-through property for ancien caches) - * 6. Cache-name - * 7. Logtext - */ - while (matcherLogs.find()) - { - final cgLog logDone = new cgLog(); - - logDone.type = LogType.getByIconName(matcherLogs.group(1)); - logDone.author = Html.fromHtml(matcherLogs.group(3)).toString().trim(); - - try - { - logDone.date = Login.parseGcCustomDate(matcherLogs.group(2)).getTime(); - } catch (ParseException e) { - } - - logDone.log = matcherLogs.group(7).trim(); - - if (matcherLogs.group(4) != null && matcherLogs.group(6) != null) - { - logDone.cacheGuid = matcherLogs.group(4); - logDone.cacheName = matcherLogs.group(6); - } - - // Apply the pattern for images in a trackable log entry against each full log (group(0)) - final Matcher matcherLogImages = GCConstants.PATTERN_TRACKABLE_LOG_IMAGES.matcher(matcherLogs.group(0)); - /* - * 1. Image URL - * 2. Image title - */ - while (matcherLogImages.find()) - { - final cgImage logImage = new cgImage(matcherLogImages.group(1), matcherLogImages.group(2)); - if (logDone.logImages == null) { - logDone.logImages = new ArrayList<cgImage>(); - } - logDone.logImages.add(logImage); - } - - trackable.getLogs().add(logDone); - } - } catch (Exception e) { - // failed to parse logs - Log.w("cgeoBase.parseCache: Failed to parse cache logs" + e.toString()); - } - - // trackingcode - if (!StringUtils.equalsIgnoreCase(trackable.getGeocode(), possibleTrackingcode)) { - trackable.setTrackingcode(possibleTrackingcode); - } - - if (app != null) { - app.saveTrackable(trackable); - } - - return trackable; - } - - public static List<LogType> parseTypes(String page) { - if (StringUtils.isEmpty(page)) { - return null; - } - - final List<LogType> types = new ArrayList<LogType>(); - - final Matcher typeBoxMatcher = GCConstants.PATTERN_TYPEBOX.matcher(page); - String typesText = null; - if (typeBoxMatcher.find()) { - if (typeBoxMatcher.groupCount() > 0) { - typesText = typeBoxMatcher.group(1); - } - } - - if (typesText != null) { - - final Matcher typeMatcher = GCConstants.PATTERN_TYPE2.matcher(typesText); - while (typeMatcher.find()) { - if (typeMatcher.groupCount() > 1) { - final int type = Integer.parseInt(typeMatcher.group(2)); - - if (type > 0) { - types.add(LogType.getById(type)); - } - } - } - } - - return types; - } - - public static List<cgTrackableLog> parseTrackableLog(final String page) { - if (StringUtils.isEmpty(page)) { - return null; - } - - final List<cgTrackableLog> trackables = new ArrayList<cgTrackableLog>(); - - String table = StringUtils.substringBetween(page, "<table id=\"tblTravelBugs\"", "</table>"); - - // if no trackables are currently in the account, the table is not available, so return an empty list instead of null - if (StringUtils.isBlank(table)) { - return trackables; - } - - table = StringUtils.substringBetween(table, "<tbody>", "</tbody>"); - if (StringUtils.isBlank(table)) { - Log.e("cgeoBase.parseTrackableLog: tbody not found on page"); - return null; - } - - final Matcher trackableMatcher = GCConstants.PATTERN_TRACKABLE.matcher(page); - while (trackableMatcher.find()) { - if (trackableMatcher.groupCount() > 0) { - final cgTrackableLog trackableLog = new cgTrackableLog(); - - if (trackableMatcher.group(1) != null) { - trackableLog.trackCode = trackableMatcher.group(1); - } else { - continue; - } - if (trackableMatcher.group(2) != null) { - trackableLog.name = Html.fromHtml(trackableMatcher.group(2)).toString(); - } else { - continue; - } - if (trackableMatcher.group(3) != null) { - trackableLog.ctl = Integer.valueOf(trackableMatcher.group(3)); - } else { - continue; - } - if (trackableMatcher.group(5) != null) { - trackableLog.id = Integer.valueOf(trackableMatcher.group(5)); - } else { - continue; - } - - Log.i("Trackable in inventory (#" + trackableLog.ctl + "/" + trackableLog.id + "): " + trackableLog.trackCode + " - " + trackableLog.name); - - trackables.add(trackableLog); - } - } - - return trackables; - } - - /** - * Insert the right cache type restriction in parameters - * - * @param params - * the parameters to insert the restriction into - * @param cacheType - * the type of cache, or null to include everything - */ - static private void insertCacheType(final Parameters params, final CacheType cacheType) { - params.put("tx", cacheType.guid); - } - public static SearchResult searchByNextPage(cgSearchThread thread, final SearchResult search, boolean showCaptcha) { if (search == null) { return search; @@ -1271,7 +729,7 @@ public class cgBase { return search; } - if (isEmpty(viewstates)) { + if (Login.isEmpty(viewstates)) { Log.e("cgeoBase.searchByNextPage: No viewstate given"); return search; } @@ -1318,30 +776,25 @@ public class cgBase { return search; } - public static SearchResult searchByGeocode(final String geocode, final String guid, final int listId, final boolean forceReload, final CancellableHandler handler) { - if (StringUtils.isBlank(geocode) && StringUtils.isBlank(guid)) { - Log.e("cgeoBase.searchByGeocode: No geocode nor guid given"); - return null; - } - - cgeoapplication app = cgeoapplication.getInstance(); - if (!forceReload && listId == StoredList.TEMPORARY_LIST_ID && (app.isOffline(geocode, guid) || app.isThere(geocode, guid, true, true))) { - final SearchResult search = new SearchResult(); - final String realGeocode = StringUtils.isNotBlank(geocode) ? geocode : app.getGeocode(guid); - search.addGeocode(realGeocode); - return search; - } - - // if we have no geocode, we can't dynamically select the handler, but must explicitly use GC - if (geocode == null && guid != null) { - return GCConnector.getInstance().searchByGeocode(null, guid, app, handler); + /** + * Possibly hide caches found or hidden by user. This mutates its params argument when possible. + * + * @param params + * the parameters to mutate, or null to create a new Parameters if needed + * @param my + * @param addF + * @return the original params if not null, maybe augmented with f=1, or a new Parameters with f=1 or null otherwise + */ + public static Parameters addFToParams(final Parameters params, final boolean my, final boolean addF) { + if (!my && Settings.isExcludeMyCaches() && addF) { + if (params == null) { + return new Parameters("f", "1"); + } + params.put("f", "1"); + Log.i("Skipping caches found or hidden by user."); } - return ConnectorFactory.getConnector(geocode).searchByGeocode(geocode, guid, app, handler); - } - - public static SearchResult searchByStored(final Geopoint coords, final CacheType cacheType, final int list) { - return cgeoapplication.getInstance().getBatchOfStoredCaches(true, coords, cacheType, list); + return params; } /** @@ -1458,7 +911,7 @@ public class cgBase { public static StatusCode postLog(final String geocode, final String cacheid, final String[] viewstates, final LogType logType, final int year, final int month, final int day, final String log, final List<cgTrackableLog> trackables) { - if (isEmpty(viewstates)) { + if (Login.isEmpty(viewstates)) { Log.e("cgeoBase.postLog: No viewstate given"); return StatusCode.LOG_POST_ERROR; } @@ -1545,7 +998,7 @@ public class cgBase { if (matcher.find() && matcher.groupCount() > 0) { final String[] viewstatesConfirm = Login.getViewstates(page); - if (isEmpty(viewstatesConfirm)) { + if (Login.isEmpty(viewstatesConfirm)) { Log.e("cgeoBase.postLog: No viewstate for confirm log"); return StatusCode.LOG_POST_ERROR; } @@ -1615,7 +1068,7 @@ public class cgBase { public static StatusCode postLogTrackable(final String tbid, final String trackingCode, final String[] viewstates, final LogType logType, final int year, final int month, final int day, final String log) { - if (isEmpty(viewstates)) { + if (Login.isEmpty(viewstates)) { Log.e("cgeoBase.postLogTrackable: No viewstate given"); return StatusCode.LOG_POST_ERROR; } @@ -1743,221 +1196,439 @@ public class cgBase { } /** - * Possibly hide caches found or hidden by user. This mutates its params argument when possible. + * Parse a trackable HTML description into a cgTrackable object * - * @param params - * the parameters to mutate, or null to create a new Parameters if needed - * @param my - * @param addF - * @return the original params if not null, maybe augmented with f=1, or a new Parameters with f=1 or null otherwise + * @param page + * the HTML page to parse, already processed through {@link BaseUtils#replaceWhitespace} + * @param app + * if not null, the application to use to save the trackable + * @return the parsed trackable, or null if none could be parsed */ - public static Parameters addFToParams(final Parameters params, final boolean my, final boolean addF) { - if (!my && Settings.isExcludeMyCaches() && addF) { - if (params == null) { - return new Parameters("f", "1"); - } - params.put("f", "1"); - Log.i("Skipping caches found or hidden by user."); + public static cgTrackable parseTrackable(final String page, final cgeoapplication app, final String possibleTrackingcode) { + if (StringUtils.isBlank(page)) { + Log.e("cgeoBase.parseTrackable: No page given"); + return null; } - return params; - } + final cgTrackable trackable = new cgTrackable(); + + // trackable geocode + trackable.setGeocode(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_GEOCODE, true, trackable.getGeocode()).toUpperCase()); - public static void storeCache(Activity activity, cgCache origCache, String geocode, int listId, boolean forceRedownload, CancellableHandler handler) { + // trackable id + trackable.setGuid(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_GUID, true, trackable.getGuid())); + + // trackable icon + trackable.setIconUrl(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_ICON, true, trackable.getIconUrl())); + + // trackable name + trackable.setName(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_NAME, true, trackable.getName())); + + // trackable type + if (StringUtils.isNotBlank(trackable.getName())) { + trackable.setType(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_TYPE, true, trackable.getType())); + } + + // trackable owner name try { - cgCache cache; - // get cache details, they may not yet be complete - if (origCache != null) { - // only reload the cache if it was already stored or doesn't have full details (by checking the description) - if (origCache.getListId() >= StoredList.STANDARD_LIST_ID || StringUtils.isBlank(origCache.getDescription())) { - final SearchResult search = searchByGeocode(origCache.getGeocode(), null, listId, false, handler); - cache = search.getFirstCacheFromResult(LoadFlags.LOAD_CACHE_OR_DB); - } else { - cache = origCache; - } - } else if (StringUtils.isNotBlank(geocode)) { - final SearchResult search = searchByGeocode(geocode, null, listId, forceRedownload, handler); - cache = search.getFirstCacheFromResult(LoadFlags.LOAD_CACHE_OR_DB); - } else { - cache = null; + final Matcher matcherOwner = GCConstants.PATTERN_TRACKABLE_OWNER.matcher(page); + if (matcherOwner.find() && matcherOwner.groupCount() > 0) { + trackable.setOwnerGuid(matcherOwner.group(1)); + trackable.setOwner(matcherOwner.group(2).trim()); } + } catch (Exception e) { + // failed to parse trackable owner name + Log.w("cgeoBase.parseTrackable: Failed to parse trackable owner name"); + } - if (cache == null) { - if (handler != null) { - handler.sendMessage(Message.obtain()); - } + // trackable origin + trackable.setOrigin(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_ORIGIN, true, trackable.getOrigin())); - return; + // trackable spotted + try { + final Matcher matcherSpottedCache = GCConstants.PATTERN_TRACKABLE_SPOTTEDCACHE.matcher(page); + if (matcherSpottedCache.find() && matcherSpottedCache.groupCount() > 0) { + trackable.setSpottedGuid(matcherSpottedCache.group(1)); + trackable.setSpottedName(matcherSpottedCache.group(2).trim()); + trackable.setSpottedType(cgTrackable.SPOTTED_CACHE); } - if (CancellableHandler.isCancelled(handler)) { - return; + final Matcher matcherSpottedUser = GCConstants.PATTERN_TRACKABLE_SPOTTEDUSER.matcher(page); + if (matcherSpottedUser.find() && matcherSpottedUser.groupCount() > 0) { + trackable.setSpottedGuid(matcherSpottedUser.group(1)); + trackable.setSpottedName(matcherSpottedUser.group(2).trim()); + trackable.setSpottedType(cgTrackable.SPOTTED_USER); } - final HtmlImage imgGetter = new HtmlImage(activity, cache.getGeocode(), false, listId, true); - - // store images from description - if (StringUtils.isNotBlank(cache.getDescription())) { - Html.fromHtml(cache.getDescription(), imgGetter, null); + if (BaseUtils.matches(page, GCConstants.PATTERN_TRACKABLE_SPOTTEDUNKNOWN)) { + trackable.setSpottedType(cgTrackable.SPOTTED_UNKNOWN); } - if (CancellableHandler.isCancelled(handler)) { - return; + if (BaseUtils.matches(page, GCConstants.PATTERN_TRACKABLE_SPOTTEDOWNER)) { + trackable.setSpottedType(cgTrackable.SPOTTED_OWNER); } + } catch (Exception e) { + // failed to parse trackable last known place + Log.w("cgeoBase.parseTrackable: Failed to parse trackable last known place"); + } - // store spoilers - if (CollectionUtils.isNotEmpty(cache.getSpoilers())) { - for (cgImage oneSpoiler : cache.getSpoilers()) { - imgGetter.getDrawable(oneSpoiler.getUrl()); + // released date - can be missing on the page + try { + String releaseString = BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_RELEASES, false, null); + if (releaseString != null) { + trackable.setReleased(dateTbIn1.parse(releaseString)); + if (trackable.getReleased() == null) { + trackable.setReleased(dateTbIn2.parse(releaseString)); } } + } catch (ParseException e1) { + trackable.setReleased(null); + } - if (CancellableHandler.isCancelled(handler)) { - return; + // trackable distance + try { + final String distance = BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_DISTANCE, false, null); + if (null != distance) { + trackable.setDistance(DistanceParser.parseDistance(distance, Settings.isUseMetricUnits())); } + } catch (NumberFormatException e) { + throw e; + } - // store images from logs - if (Settings.isStoreLogImages()) { - for (cgLog log : cache.getLogs(true)) { - if (CollectionUtils.isNotEmpty(log.logImages)) { - for (cgImage oneLogImg : log.logImages) { - imgGetter.getDrawable(oneLogImg.getUrl()); - } - } + // trackable goal + trackable.setGoal(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_GOAL, true, trackable.getGoal())); + + // trackable details & image + try { + final Matcher matcherDetailsImage = GCConstants.PATTERN_TRACKABLE_DETAILSIMAGE.matcher(page); + if (matcherDetailsImage.find() && matcherDetailsImage.groupCount() > 0) { + final String image = StringUtils.trim(matcherDetailsImage.group(3)); + final String details = StringUtils.trim(matcherDetailsImage.group(4)); + + if (StringUtils.isNotEmpty(image)) { + trackable.setImage(image); + } + if (StringUtils.isNotEmpty(details) && !StringUtils.equals(details, "No additional details available.")) { + trackable.setDetails(details); } } + } catch (Exception e) { + // failed to parse trackable details & image + Log.w("cgeoBase.parseTrackable: Failed to parse trackable details & image"); + } - if (CancellableHandler.isCancelled(handler)) { - return; - } + // trackable logs + try + { + final Matcher matcherLogs = GCConstants.PATTERN_TRACKABLE_LOG.matcher(page); + /* + * 1. Type (img) + * 2. Date + * 3. Author + * 4. Cache-GUID + * 5. <ignored> (strike-through property for ancien caches) + * 6. Cache-name + * 7. Logtext + */ + while (matcherLogs.find()) + { + final cgLog logDone = new cgLog(); - // store map previews - StaticMapsProvider.downloadMaps(cache, activity); + logDone.type = LogType.getByIconName(matcherLogs.group(1)); + logDone.author = Html.fromHtml(matcherLogs.group(3)).toString().trim(); - if (CancellableHandler.isCancelled(handler)) { - return; - } + try + { + logDone.date = Login.parseGcCustomDate(matcherLogs.group(2)).getTime(); + } catch (ParseException e) { + } - cache.setListId(listId); - cgeoapplication.getInstance().saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); + logDone.log = matcherLogs.group(7).trim(); + + if (matcherLogs.group(4) != null && matcherLogs.group(6) != null) + { + logDone.cacheGuid = matcherLogs.group(4); + logDone.cacheName = matcherLogs.group(6); + } + + // Apply the pattern for images in a trackable log entry against each full log (group(0)) + final Matcher matcherLogImages = GCConstants.PATTERN_TRACKABLE_LOG_IMAGES.matcher(matcherLogs.group(0)); + /* + * 1. Image URL + * 2. Image title + */ + while (matcherLogImages.find()) + { + final cgImage logImage = new cgImage(matcherLogImages.group(1), matcherLogImages.group(2)); + if (logDone.logImages == null) { + logDone.logImages = new ArrayList<cgImage>(); + } + logDone.logImages.add(logImage); + } - if (handler != null) { - handler.sendMessage(Message.obtain()); + trackable.getLogs().add(logDone); } } catch (Exception e) { - Log.e("cgBase.storeCache"); + // failed to parse logs + Log.w("cgeoBase.parseCache: Failed to parse cache logs" + e.toString()); } - } - - public static void refreshCache(Activity activity, String geocode, int listId, CancellableHandler handler) { - cgeoapplication.getInstance().removeCache(geocode, EnumSet.of(RemoveFlag.REMOVE_CACHE)); - storeCache(activity, null, geocode, listId, true, handler); - } - public static void dropCache(final cgCache cache, final Handler handler) { - try { - cgeoapplication.getInstance().markDropped(cache.getGeocode()); - cgeoapplication.getInstance().removeCache(cache.getGeocode(), EnumSet.of(RemoveFlag.REMOVE_CACHE)); + // trackingcode + if (!StringUtils.equalsIgnoreCase(trackable.getGeocode(), possibleTrackingcode)) { + trackable.setTrackingcode(possibleTrackingcode); + } - handler.sendMessage(Message.obtain()); - } catch (Exception e) { - Log.e("cgBase.dropCache: " + e.toString()); + if (app != null) { + app.saveTrackable(trackable); } - } - /** - * Generate a time string according to system-wide settings (locale, 12/24 hour) - * such as "13:24". - * - * @param date - * milliseconds since the epoch - * @return the formatted string - */ - public static String formatTime(long date) { - return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_TIME); + return trackable; } /** - * Generate a date string according to system-wide settings (locale, date format) - * such as "20 December" or "20 December 2010". The year will only be included when necessary. + * Load logs from a cache details page. * - * @param date - * milliseconds since the epoch - * @return the formatted string + * @param page + * the text of the details page + * @param cache + * the cache object to put the logs in + * @param friends + * retrieve friend logs */ - public static String formatDate(long date) { - return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE); + private static List<cgLog> loadLogsFromDetails(final String page, final cgCache cache, final boolean friends, final boolean getDataFromPage) { + String rawResponse = null; + + if (!getDataFromPage) { + final Matcher userTokenMatcher = GCConstants.PATTERN_USERTOKEN2.matcher(page); + if (!userTokenMatcher.find()) { + Log.e("cgBase.loadLogsFromDetails: unable to extract userToken"); + return null; + } + + final String userToken = userTokenMatcher.group(1); + final Parameters params = new Parameters( + "tkn", userToken, + "idx", "1", + "num", String.valueOf(GCConstants.NUMBER_OF_LOGS), + "decrypt", "true", + // "sp", Boolean.toString(personal), // personal logs + "sf", Boolean.toString(friends)); + + final HttpResponse response = Network.getRequest("http://www.geocaching.com/seek/geocache.logbook", params); + if (response == null) { + Log.e("cgBase.loadLogsFromDetails: cannot log logs, response is null"); + return null; + } + final int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode != 200) { + Log.e("cgBase.loadLogsFromDetails: error " + statusCode + " when requesting log information"); + return null; + } + rawResponse = Network.getResponseData(response); + if (rawResponse == null) { + Log.e("cgBase.loadLogsFromDetails: unable to read whole response"); + return null; + } + } else { + // extract embedded JSON data from page + rawResponse = BaseUtils.getMatch(page, GCConstants.PATTERN_LOGBOOK, ""); + } + + List<cgLog> logs = new ArrayList<cgLog>(); + + try { + final JSONObject resp = new JSONObject(rawResponse); + if (!resp.getString("status").equals("success")) { + Log.e("cgBase.loadLogsFromDetails: status is " + resp.getString("status")); + return null; + } + + final JSONArray data = resp.getJSONArray("data"); + + for (int index = 0; index < data.length(); index++) { + final JSONObject entry = data.getJSONObject(index); + final cgLog logDone = new cgLog(); + logDone.friend = friends; + + // FIXME: use the "LogType" field instead of the "LogTypeImage" one. + final String logIconNameExt = entry.optString("LogTypeImage", ".gif"); + final String logIconName = logIconNameExt.substring(0, logIconNameExt.length() - 4); + logDone.type = LogType.getByIconName(logIconName); + + try { + logDone.date = Login.parseGcCustomDate(entry.getString("Visited")).getTime(); + } catch (ParseException e) { + Log.e("cgBase.loadLogsFromDetails: failed to parse log date."); + } + + logDone.author = entry.getString("UserName"); + logDone.found = entry.getInt("GeocacheFindCount"); + logDone.log = entry.getString("LogText"); + + final JSONArray images = entry.getJSONArray("Images"); + for (int i = 0; i < images.length(); i++) { + final JSONObject image = images.getJSONObject(i); + String url = "http://img.geocaching.com/cache/log/" + image.getString("FileName"); + String title = image.getString("Name"); + final cgImage logImage = new cgImage(url, title); + if (logDone.logImages == null) { + logDone.logImages = new ArrayList<cgImage>(); + } + logDone.logImages.add(logImage); + } + + logs.add(logDone); + } + } catch (JSONException e) { + // failed to parse logs + Log.w("cgBase.loadLogsFromDetails: Failed to parse cache logs", e); + } + + return logs; } - /** - * Generate a date string according to system-wide settings (locale, date format) - * such as "20 December 2010". The year will always be included, making it suitable - * to generate long-lived log entries. - * - * @param date - * milliseconds since the epoch - * @return the formatted string - */ - public static String formatFullDate(long date) { - return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE - | DateUtils.FORMAT_SHOW_YEAR); + public static List<LogType> parseTypes(String page) { + if (StringUtils.isEmpty(page)) { + return null; + } + + final List<LogType> types = new ArrayList<LogType>(); + + final Matcher typeBoxMatcher = GCConstants.PATTERN_TYPEBOX.matcher(page); + String typesText = null; + if (typeBoxMatcher.find()) { + if (typeBoxMatcher.groupCount() > 0) { + typesText = typeBoxMatcher.group(1); + } + } + + if (typesText != null) { + + final Matcher typeMatcher = GCConstants.PATTERN_TYPE2.matcher(typesText); + while (typeMatcher.find()) { + if (typeMatcher.groupCount() > 1) { + final int type = Integer.parseInt(typeMatcher.group(2)); + + if (type > 0) { + types.add(LogType.getById(type)); + } + } + } + } + + return types; } - /** - * Generate a numeric date string according to system-wide settings (locale, date format) - * such as "10/20/2010". - * - * @param date - * milliseconds since the epoch - * @return the formatted string - */ - public static String formatShortDate(long date) { - return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE - | DateUtils.FORMAT_NUMERIC_DATE); + public static List<cgTrackableLog> parseTrackableLog(final String page) { + if (StringUtils.isEmpty(page)) { + return null; + } + + final List<cgTrackableLog> trackables = new ArrayList<cgTrackableLog>(); + + String table = StringUtils.substringBetween(page, "<table id=\"tblTravelBugs\"", "</table>"); + + // if no trackables are currently in the account, the table is not available, so return an empty list instead of null + if (StringUtils.isBlank(table)) { + return trackables; + } + + table = StringUtils.substringBetween(table, "<tbody>", "</tbody>"); + if (StringUtils.isBlank(table)) { + Log.e("cgeoBase.parseTrackableLog: tbody not found on page"); + return null; + } + + final Matcher trackableMatcher = GCConstants.PATTERN_TRACKABLE.matcher(page); + while (trackableMatcher.find()) { + if (trackableMatcher.groupCount() > 0) { + final cgTrackableLog trackableLog = new cgTrackableLog(); + + if (trackableMatcher.group(1) != null) { + trackableLog.trackCode = trackableMatcher.group(1); + } else { + continue; + } + if (trackableMatcher.group(2) != null) { + trackableLog.name = Html.fromHtml(trackableMatcher.group(2)).toString(); + } else { + continue; + } + if (trackableMatcher.group(3) != null) { + trackableLog.ctl = Integer.valueOf(trackableMatcher.group(3)); + } else { + continue; + } + if (trackableMatcher.group(5) != null) { + trackableLog.id = Integer.valueOf(trackableMatcher.group(5)); + } else { + continue; + } + + Log.i("Trackable in inventory (#" + trackableLog.ctl + "/" + trackableLog.id + "): " + trackableLog.trackCode + " - " + trackableLog.name); + + trackables.add(trackableLog); + } + } + + return trackables; } /** - * Generate a numeric date and time string according to system-wide settings (locale, - * date format) such as "7 sept. at 12:35". + * Insert the right cache type restriction in parameters * - * @param context - * a Context - * @param date - * milliseconds since the epoch - * @return the formatted string + * @param params + * the parameters to insert the restriction into + * @param cacheType + * the type of cache, or null to include everything */ - public static String formatShortDateTime(Context context, long date) { - return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_ABBREV_ALL); + static private void insertCacheType(final Parameters params, final CacheType cacheType) { + params.put("tx", cacheType.guid); } - /** - * Indicates whether the specified action can be used as an intent. This - * method queries the package manager for installed packages that can - * respond to an intent with the specified action. If no suitable package is - * found, this method returns false. - * - * @param context - * The application's environment. - * @param action - * The Intent action to check for availability. - * @param uri - * The Intent URI to check for availability. - * - * @return True if an Intent with the specified action can be sent and - * responded to, false otherwise. - */ - public static boolean isIntentAvailable(Context context, String action, Uri uri) { - final PackageManager packageManager = context.getPackageManager(); - final Intent intent; - if (uri == null) { - intent = new Intent(action); - } else { - intent = new Intent(action, uri); + private static void getExtraOnlineInfo(final cgCache cache, final String page, final CancellableHandler handler) { + if (CancellableHandler.isCancelled(handler)) { + return; + } + + //cache.setLogs(loadLogsFromDetails(page, cache, false)); + if (Settings.isFriendLogsWanted()) { + CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_logs); + List<cgLog> allLogs = cache.getLogs(); + List<cgLog> friendLogs = loadLogsFromDetails(page, cache, true, false); + if (friendLogs != null) { + for (cgLog log : friendLogs) { + if (allLogs.contains(log)) { + allLogs.get(allLogs.indexOf(log)).friend = true; + } else { + allLogs.add(log); + } + } + } + } + + if (Settings.isElevationWanted()) { + if (CancellableHandler.isCancelled(handler)) { + return; + } + CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_elevation); + if (cache.getCoords() != null) { + cache.setElevation(cache.getCoords().getElevation()); + } + } + + if (Settings.isRatingWanted()) { + if (CancellableHandler.isCancelled(handler)) { + return; + } + CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_gcvote); + final GCVoteRating rating = GCVote.getRating(cache.getGuid(), cache.getGeocode()); + if (rating != null) { + cache.setRating(rating.getRating()); + cache.setVotes(rating.getVotes()); + cache.setMyVote(rating.getMyVote()); + } } - List<ResolveInfo> list = packageManager.queryIntentActivities(intent, - PackageManager.MATCH_DEFAULT_ONLY); - return list.size() > 0; } } - diff --git a/main/src/cgeo/geocaching/connector/gc/Login.java b/main/src/cgeo/geocaching/connector/gc/Login.java index 4605bc9..1e614df 100644 --- a/main/src/cgeo/geocaching/connector/gc/Login.java +++ b/main/src/cgeo/geocaching/connector/gc/Login.java @@ -2,7 +2,7 @@ package cgeo.geocaching.connector.gc; import cgeo.geocaching.R; import cgeo.geocaching.Settings; -import cgeo.geocaching.cgBase; +import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.enumerations.StatusCode; import cgeo.geocaching.network.Cookies; import cgeo.geocaching.network.HtmlImage; @@ -63,15 +63,12 @@ public abstract class Login { final ImmutablePair<String, String> login = Settings.getLogin(); if (login == null || StringUtils.isEmpty(login.left) || StringUtils.isEmpty(login.right)) { - Login.setActualStatus(cgBase.res.getString(R.string.err_login)); + Login.setActualStatus(cgeoapplication.getInstance().getString(R.string.err_login)); Log.e("cgeoBase.login: No login information stored"); return StatusCode.NO_LOGIN_INFO_STORED; } - // res is null during the unit tests - if (cgBase.res != null) { - Login.setActualStatus(cgBase.res.getString(R.string.init_login_popup_working)); - } + Login.setActualStatus(cgeoapplication.getInstance().getString(R.string.init_login_popup_working)); HttpResponse loginResponse = Network.getRequest("https://www.geocaching.com/login/default.aspx"); String loginData = Network.getResponseData(loginResponse); if (loginResponse != null && loginResponse.getStatusLine().getStatusCode() == 503 && BaseUtils.matches(loginData, GCConstants.PATTERN_MAINTENANCE)) { @@ -100,7 +97,7 @@ public abstract class Login { "ctl00$ContentBody$cbRememberMe", "on", "ctl00$ContentBody$btnSignIn", "Login"); final String[] viewstates = Login.getViewstates(loginData); - if (cgBase.isEmpty(viewstates)) { + if (isEmpty(viewstates)) { Log.e("cgeoBase.login: Failed to find viewstates"); return StatusCode.LOGIN_PARSE_ERROR; // no viewstates } @@ -189,10 +186,7 @@ public abstract class Login { return false; } - // res is null during the unit tests - if (cgBase.res != null) { - setActualStatus(cgBase.res.getString(R.string.init_login_popup_ok)); - } + setActualStatus(cgeoapplication.getInstance().getString(R.string.init_login_popup_ok)); // on every page except login page setActualLoginStatus(BaseUtils.matches(page, GCConstants.PATTERN_LOGIN_NAME)); @@ -210,10 +204,7 @@ public abstract class Login { return true; } - // res is null during the unit tests - if (cgBase.res != null) { - setActualStatus(cgBase.res.getString(R.string.init_login_popup_failed)); - } + setActualStatus(cgeoapplication.getInstance().getString(R.string.init_login_popup_failed)); return false; } @@ -307,6 +298,24 @@ public abstract class Login { } /** + * checks if an Array of Strings is empty or not. Empty means: + * - Array is null + * - or all elements are null or empty strings + */ + public static boolean isEmpty(String[] a) { + if (a == null) { + return true; + } + + for (String s : a) { + if (StringUtils.isNotEmpty(s)) { + return false; + } + } + return true; + } + + /** * read all viewstates from page * * @return String[] with all view states diff --git a/main/src/cgeo/geocaching/go4cache/Go4Cache.java b/main/src/cgeo/geocaching/go4cache/Go4Cache.java index 782919c..b0a7b35 100644 --- a/main/src/cgeo/geocaching/go4cache/Go4Cache.java +++ b/main/src/cgeo/geocaching/go4cache/Go4Cache.java @@ -1,7 +1,6 @@ package cgeo.geocaching.go4cache; import cgeo.geocaching.Settings; -import cgeo.geocaching.cgBase; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.geopoint.GeopointFormatter.Format; @@ -16,6 +15,8 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -41,6 +42,7 @@ public final class Go4Cache extends Thread { private final static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 2010-07-25 14:44:01 final private ArrayBlockingQueue<Geopoint> queue = new ArrayBlockingQueue<Geopoint>(1); + private String packageVersion; public static Go4Cache getInstance() { // no need to be synchronized return InstanceHolder.INSTANCE; @@ -48,10 +50,22 @@ public final class Go4Cache extends Thread { private Go4Cache() { // private singleton constructor super("Go4Cache"); + initializeVersion(); setPriority(Thread.MIN_PRIORITY); start(); } + private void initializeVersion() { + try { + final PackageManager manager = cgeoapplication.getInstance().getPackageManager(); + final PackageInfo info = manager.getPackageInfo(cgeoapplication.getInstance().getPackageName(), 0); + packageVersion = info.versionName; + } catch (PackageManager.NameNotFoundException e) { + Log.e("unable to get version information", e); + packageVersion = null; + } + } + /** * Send the coordinates to go4cache.com if the user opted in to do so. * @@ -96,8 +110,8 @@ public final class Go4Cache extends Thread { "ln", lonStr, "a", currentAction, "s", (CryptUtils.sha1(username + "|" + latStr + "|" + lonStr + "|" + currentAction + "|" + CryptUtils.md5("carnero: developing your dreams"))).toLowerCase()); - if (null != cgBase.version) { - params.put("v", cgBase.version); + if (null != packageVersion) { + params.put("v", packageVersion); } Network.postRequest("http://api.go4cache.com/", params); diff --git a/main/src/cgeo/geocaching/maps/CGeoMap.java b/main/src/cgeo/geocaching/maps/CGeoMap.java index d163a8a..e5f8701 100644 --- a/main/src/cgeo/geocaching/maps/CGeoMap.java +++ b/main/src/cgeo/geocaching/maps/CGeoMap.java @@ -8,7 +8,6 @@ import cgeo.geocaching.Settings; import cgeo.geocaching.StoredList; import cgeo.geocaching.UpdateDirectionCallback; import cgeo.geocaching.UpdateLocationCallback; -import cgeo.geocaching.cgBase; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgDirection; import cgeo.geocaching.cgGeo; @@ -1540,7 +1539,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto break; } - cgBase.storeCache(activity, null, geocode, StoredList.STANDARD_LIST_ID, false, handler); + cgCache.storeCache(activity, null, geocode, StoredList.STANDARD_LIST_ID, false, handler); } } catch (Exception e) { Log.e("cgeocaches.LoadDetails.run: " + e.toString()); diff --git a/main/src/cgeo/geocaching/ui/CacheListAdapter.java b/main/src/cgeo/geocaching/ui/CacheListAdapter.java index ee7a8b1..54f4505 100644 --- a/main/src/cgeo/geocaching/ui/CacheListAdapter.java +++ b/main/src/cgeo/geocaching/ui/CacheListAdapter.java @@ -3,7 +3,6 @@ package cgeo.geocaching.ui; import cgeo.geocaching.CacheDetailActivity; import cgeo.geocaching.R; import cgeo.geocaching.Settings; -import cgeo.geocaching.cgBase; import cgeo.geocaching.cgCache; import cgeo.geocaching.enumerations.CacheListType; import cgeo.geocaching.enumerations.CacheSize; @@ -578,8 +577,8 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> { if (cacheListType == CacheListType.HISTORY && cache.getVisitedDate() > 0) { ArrayList<String> infos = new ArrayList<String>(); infos.add(StringUtils.upperCase(cache.getGeocode())); - infos.add(cgBase.formatDate(cache.getVisitedDate())); - infos.add(cgBase.formatTime(cache.getVisitedDate())); + infos.add(Formatter.formatDate(cache.getVisitedDate())); + infos.add(Formatter.formatTime(cache.getVisitedDate())); holder.info.setText(StringUtils.join(infos, Formatter.SEPARATOR)); } else { ArrayList<String> infos = new ArrayList<String>(); @@ -597,7 +596,7 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> { if (cache.getSize() != CacheSize.UNKNOWN && cache.showSize()) { infos.add(cache.getSize().getL10n()); } else if (cache.isEventCache() && cache.getHiddenDate() != null) { - infos.add(cgBase.formatShortDate(cache.getHiddenDate().getTime())); + infos.add(Formatter.formatShortDate(cache.getHiddenDate().getTime())); } if (cache.isPremiumMembersOnly()) { diff --git a/main/src/cgeo/geocaching/ui/Formatter.java b/main/src/cgeo/geocaching/ui/Formatter.java index 661a9a0..6ee1a65 100644 --- a/main/src/cgeo/geocaching/ui/Formatter.java +++ b/main/src/cgeo/geocaching/ui/Formatter.java @@ -1,8 +1,80 @@ package cgeo.geocaching.ui; -public interface Formatter { +import cgeo.geocaching.cgeoapplication; + +import android.content.Context; +import android.text.format.DateUtils; + +public abstract class Formatter { /** Text separator used for formatting texts */ public static final String SEPARATOR = " ยท "; + private static final Context context = cgeoapplication.getInstance().getBaseContext(); + + /** + * Generate a time string according to system-wide settings (locale, 12/24 hour) + * such as "13:24". + * + * @param date + * milliseconds since the epoch + * @return the formatted string + */ + public static String formatTime(long date) { + return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_TIME); + } + + /** + * Generate a date string according to system-wide settings (locale, date format) + * such as "20 December" or "20 December 2010". The year will only be included when necessary. + * + * @param date + * milliseconds since the epoch + * @return the formatted string + */ + public static String formatDate(long date) { + return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE); + } + + /** + * Generate a date string according to system-wide settings (locale, date format) + * such as "20 December 2010". The year will always be included, making it suitable + * to generate long-lived log entries. + * + * @param date + * milliseconds since the epoch + * @return the formatted string + */ + public static String formatFullDate(long date) { + return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE + | DateUtils.FORMAT_SHOW_YEAR); + } + + /** + * Generate a numeric date string according to system-wide settings (locale, date format) + * such as "10/20/2010". + * + * @param date + * milliseconds since the epoch + * @return the formatted string + */ + public static String formatShortDate(long date) { + return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE + | DateUtils.FORMAT_NUMERIC_DATE); + } + + /** + * Generate a numeric date and time string according to system-wide settings (locale, + * date format) such as "7 sept. at 12:35". + * + * @param context + * a Context + * @param date + * milliseconds since the epoch + * @return the formatted string + */ + public static String formatShortDateTime(Context context, long date) { + return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_ABBREV_ALL); + } + } diff --git a/main/src/cgeo/geocaching/utils/CancellableHandler.java b/main/src/cgeo/geocaching/utils/CancellableHandler.java index d4915eb..8cf8f28 100644 --- a/main/src/cgeo/geocaching/utils/CancellableHandler.java +++ b/main/src/cgeo/geocaching/utils/CancellableHandler.java @@ -1,5 +1,7 @@ package cgeo.geocaching.utils; +import cgeo.geocaching.cgeoapplication; + import android.os.Handler; import android.os.Message; @@ -9,6 +11,7 @@ import android.os.Message; */ public abstract class CancellableHandler extends Handler { + protected static final int UPDATE_LOAD_PROGRESS_DETAIL = 42186; private volatile boolean cancelled = false; private static class CancelHolder { @@ -109,4 +112,9 @@ public abstract class CancellableHandler extends Handler { return handler != null && handler.isCancelled(); } + public static void sendLoadProgressDetail(final Handler handler, final int resourceId) { + if (null != handler) { + handler.obtainMessage(UPDATE_LOAD_PROGRESS_DETAIL, cgeoapplication.getInstance().getString(resourceId)).sendToTarget(); + } + } } diff --git a/main/src/cgeo/geocaching/utils/LogTemplateProvider.java b/main/src/cgeo/geocaching/utils/LogTemplateProvider.java index b8c4a25..60866e0 100644 --- a/main/src/cgeo/geocaching/utils/LogTemplateProvider.java +++ b/main/src/cgeo/geocaching/utils/LogTemplateProvider.java @@ -2,10 +2,10 @@ package cgeo.geocaching.utils; import cgeo.geocaching.R; import cgeo.geocaching.Settings; -import cgeo.geocaching.cgBase; import cgeo.geocaching.connector.gc.GCConstants; import cgeo.geocaching.connector.gc.Login; import cgeo.geocaching.network.Network; +import cgeo.geocaching.ui.Formatter; import org.apache.commons.lang3.StringUtils; @@ -55,14 +55,14 @@ public class LogTemplateProvider { @Override public String getValue(final boolean offline) { - return cgBase.formatFullDate(System.currentTimeMillis()); + return Formatter.formatFullDate(System.currentTimeMillis()); } }, new LogTemplate("TIME", R.string.init_signature_template_time) { @Override public String getValue(final boolean offline) { - return cgBase.formatTime(System.currentTimeMillis()); + return Formatter.formatTime(System.currentTimeMillis()); } }, new LogTemplate("DATETIME", R.string.init_signature_template_datetime) { @@ -70,7 +70,7 @@ public class LogTemplateProvider { @Override public String getValue(final boolean offline) { final long currentTime = System.currentTimeMillis(); - return cgBase.formatFullDate(currentTime) + " " + cgBase.formatTime(currentTime); + return Formatter.formatFullDate(currentTime) + " " + Formatter.formatTime(currentTime); } }, new LogTemplate("USER", R.string.init_signature_template_user) { |