Пример #1
0
 private static void addFilterParams(
     final Map<String, String> valueMap, final OCApiConnector connector) {
   if (!Settings.isExcludeDisabledCaches()) {
     valueMap.put("status", "Available|Temporarily unavailable");
   }
   if (Settings.isExcludeMyCaches() && connector.getSupportedAuthLevel() == OAuthLevel.Level3) {
     valueMap.put("exclude_my_own", "true");
     valueMap.put("found_status", "notfound_only");
   }
   if (Settings.getCacheType() != CacheType.ALL) {
     valueMap.put("type", getFilterFromType(Settings.getCacheType()));
   }
 }
Пример #2
0
  private static List<Geocache> requestCaches(
      final OCApiConnector connector,
      final Parameters params,
      final Map<String, String> valueMap,
      final boolean my) {
    // if a global type filter is set, and OKAPI does not know that type, then return an empty list
    // instead of all caches
    if (Settings.getCacheType() != CacheType.ALL && StringUtils.isBlank(getFilterFromType())) {
      return Collections.emptyList();
    }

    addFilterParams(valueMap, connector, my);
    try {
      params.add("search_params", JsonUtils.writer.writeValueAsString(valueMap));
    } catch (final JsonProcessingException e) {
      Log.e("requestCaches", e);
      return Collections.emptyList();
    }
    addRetrieveParams(params, connector);

    final ObjectNode data =
        request(connector, OkapiService.SERVICE_SEARCH_AND_RETRIEVE, params).data;

    if (data == null) {
      return Collections.emptyList();
    }

    return parseCaches(data);
  }
Пример #3
0
  protected void selectGlobalTypeFilter() {
    final List<CacheType> cacheTypes = new ArrayList<CacheType>();

    // first add the most used types
    cacheTypes.add(CacheType.ALL);
    cacheTypes.add(CacheType.TRADITIONAL);
    cacheTypes.add(CacheType.MULTI);
    cacheTypes.add(CacheType.MYSTERY);

    // then add all other cache types sorted alphabetically
    final List<CacheType> sorted = new ArrayList<CacheType>();
    sorted.addAll(Arrays.asList(CacheType.values()));
    sorted.removeAll(cacheTypes);

    Collections.sort(
        sorted,
        new Comparator<CacheType>() {

          @Override
          public int compare(final CacheType left, final CacheType right) {
            return left.getL10n().compareToIgnoreCase(right.getL10n());
          }
        });

    cacheTypes.addAll(sorted);

    int checkedItem = cacheTypes.indexOf(Settings.getCacheType());
    if (checkedItem < 0) {
      checkedItem = 0;
    }

    final String[] items = new String[cacheTypes.size()];
    for (int i = 0; i < cacheTypes.size(); i++) {
      items[i] = cacheTypes.get(i).getL10n();
    }

    final Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(R.string.menu_filter);
    builder.setSingleChoiceItems(
        items,
        checkedItem,
        new DialogInterface.OnClickListener() {

          @Override
          public void onClick(final DialogInterface dialog, final int position) {
            final CacheType cacheType = cacheTypes.get(position);
            Settings.setCacheType(cacheType);
            setFilterTitle();
            dialog.dismiss();
          }
        });
    builder.create().show();
  }
Пример #4
0
 private static String getFilterFromType() {
   switch (Settings.getCacheType()) {
     case EVENT:
       return "Event";
     case MULTI:
       return "Multi";
     case MYSTERY:
       return "Quiz";
     case TRADITIONAL:
       return "Traditional";
     case VIRTUAL:
       return "Virtual";
     case WEBCAM:
       return "Webcam";
     default:
       return "";
   }
 }
Пример #5
0
  private void download() {
    try {
      showProgress();

      final SearchResult searchResult =
          DataStore.loadCachedInViewport(getViewport(), Settings.getCacheType());

      if (Settings.isGCConnectorActive() && tokens == null) {
        tokens = GCLogin.getInstance().getMapTokens();
        if (StringUtils.isEmpty(tokens.getUserSession())
            || StringUtils.isEmpty(tokens.getSessionToken())) {
          tokens = null;
          // TODO: show missing map token toast
          //                    if (!noMapTokenShowed) {
          //                        ActivityMixin.showToast(activity,
          // res.getString(R.string.map_token_err));
          //                        noMapTokenShowed = true;
          //                    }
        }
      }
      searchResult.addSearchResult(
          ConnectorFactory.searchByViewport(getViewport().resize(1.2), tokens));

      final Set<Geocache> result =
          searchResult.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB);
      AbstractCachesOverlay.filter(result);
      // update the caches
      // first remove filtered out
      final Set<String> filteredCodes = searchResult.getFilteredGeocodes();
      Log.d("Filtering out " + filteredCodes.size() + " caches: " + filteredCodes.toString());
      DataStore.removeCaches(filteredCodes, EnumSet.of(RemoveFlag.CACHE));

      Log.d(String.format(Locale.ENGLISH, "Live caches found: %d", result.size()));

      // render
      fill(result);

    } finally {
      hideProgress();
    }
  }
Пример #6
0
 private void setFilterTitle() {
   filterTitle.setText(Settings.getCacheType().getL10n());
 }
Пример #7
0
  /**
   * Searches the view port on the live map for caches. The strategy dictates if only live map
   * information is used or if an additional searchByCoordinates query is issued.
   *
   * @param viewport Area to search
   * @param tokens Live map tokens
   * @param strategy Strategy for data retrieval and parsing, @see Strategy
   */
  @NonNull
  private static SearchResult searchByViewport(
      final Viewport viewport, final MapTokens tokens, final LivemapStrategy strategy) {
    Log.d("GCMap.searchByViewport" + viewport.toString());

    final SearchResult searchResult = new SearchResult();

    if (Settings.isDebug()) {
      searchResult.setUrl(viewport.getCenter().format(Format.LAT_LON_DECMINUTE));
    }

    if (strategy.flags.contains(LivemapStrategy.Flag.LOAD_TILES)) {
      final Set<Tile> tiles = Tile.getTilesForViewport(viewport);

      if (Settings.isDebug()) {
        searchResult.setUrl(
            new StringBuilder()
                .append(tiles.iterator().next().getZoomLevel())
                .append(Formatter.SEPARATOR)
                .append(searchResult.getUrl())
                .toString());
      }

      for (final Tile tile : tiles) {
        if (!Tile.cache.contains(tile)) {
          final Parameters params =
              new Parameters(
                  "x", String.valueOf(tile.getX()),
                  "y", String.valueOf(tile.getY()),
                  "z", String.valueOf(tile.getZoomLevel()),
                  "ep", "1",
                  "app", "cgeo");
          if (tokens != null) {
            params.put("k", tokens.getUserSession(), "st", tokens.getSessionToken());
          }
          if (Settings.isExcludeMyCaches()) { // works only for PM
            params.put("hf", "1", "hh", "1"); // hide found, hide hidden
          }
          // ect: exclude cache type (probably), comma separated list
          if (Settings.getCacheType() != CacheType.ALL) {
            params.put("ect", getCacheTypeFilter(Settings.getCacheType()));
          }
          if (tile.getZoomLevel() != 14) {
            params.put("_", String.valueOf(System.currentTimeMillis()));
          }

          // The PNG must be requested first, otherwise the following request would always return
          // with 204 - No Content
          final Single<Bitmap> bitmapObs =
              Tile.requestMapTile(params).onErrorResumeNext(Single.<Bitmap>just(null));
          final Single<String> dataObs =
              Tile.requestMapInfo(GCConstants.URL_MAP_INFO, params, GCConstants.URL_LIVE_MAP)
                  .onErrorResumeNext(Single.just(""));
          try {
            Single.zip(
                    bitmapObs,
                    dataObs,
                    new Func2<Bitmap, String, Void>() {
                      @Override
                      public Void call(final Bitmap bitmap, final String data) {
                        final boolean validBitmap =
                            bitmap != null
                                && bitmap.getWidth() == Tile.TILE_SIZE
                                && bitmap.getHeight() == Tile.TILE_SIZE;

                        if (StringUtils.isEmpty(data)) {
                          Log.w(
                              "GCMap.searchByViewport: No data from server for tile ("
                                  + tile.getX()
                                  + "/"
                                  + tile.getY()
                                  + ")");
                        } else {
                          final SearchResult search =
                              parseMapJSON(data, tile, validBitmap ? bitmap : null, strategy);
                          if (CollectionUtils.isEmpty(search.getGeocodes())) {
                            Log.e(
                                "GCMap.searchByViewport: No cache parsed for viewport " + viewport);
                          } else {
                            synchronized (searchResult) {
                              searchResult.addSearchResult(search);
                            }
                          }
                          synchronized (Tile.cache) {
                            Tile.cache.add(tile);
                          }
                        }

                        // release native bitmap memory
                        if (bitmap != null) {
                          bitmap.recycle();
                        }

                        return null;
                      }
                    })
                .toBlocking()
                .value();
          } catch (final Exception e) {
            Log.e("GCMap.searchByViewPort: connection error");
          }
        }
      }

      // Check for vanished found caches
      if (tiles.iterator().next().getZoomLevel() >= Tile.ZOOMLEVEL_MIN_PERSONALIZED) {
        searchResult.addFilteredGeocodes(
            DataStore.getCachedMissingFromSearch(
                searchResult,
                tiles,
                GCConnector.getInstance(),
                Tile.ZOOMLEVEL_MIN_PERSONALIZED - 1));
      }
    }

    if (strategy.flags.contains(Flag.SEARCH_NEARBY) && Settings.isGCPremiumMember()) {
      final Geopoint center = viewport.getCenter();
      if ((lastSearchViewport == null) || !lastSearchViewport.contains(center)) {
        // FIXME We don't have a RecaptchaReceiver!?
        final SearchResult search =
            GCParser.searchByCoords(center, Settings.getCacheType(), false, null);
        if (search != null && !search.isEmpty()) {
          final Set<String> geocodes = search.getGeocodes();
          lastSearchViewport = DataStore.getBounds(geocodes);
          searchResult.addGeocodes(geocodes);
        }
      }
    }

    return searchResult;
  }
Пример #8
0
  /**
   * @param data Retrieved data.
   * @return SearchResult. Never null.
   */
  public static SearchResult parseMapJSON(
      final String data, final Tile tile, final Bitmap bitmap, final LivemapStrategy strategy) {
    final SearchResult searchResult = new SearchResult();

    try {

      final LeastRecentlyUsedMap<String, String> nameCache =
          new LeastRecentlyUsedMap.LruCache<>(2000); // JSON id, cache name

      if (StringUtils.isEmpty(data)) {
        throw new ParserException("No page given");
      }

      // Example JSON information
      // {"grid":[....],
      //
      // "keys":["","55_55","55_54","17_25","55_53","17_27","17_26","57_53","57_55","3_62","3_61","57_54","3_60","15_27","15_26","15_25","4_60","4_61","4_62","16_25","16_26","16_27","2_62","2_60","2_61","56_53","56_54","56_55"],
      //  "data":{"55_55":[{"i":"gEaR","n":"Spiel & Sport"}],"55_54":[{"i":"gEaR","n":"Spiel &
      // Sport"}],"17_25":[{"i":"Rkzt","n":"EDSSW:  Rathaus "}],"55_53":[{"i":"gEaR","n":"Spiel &
      // Sport"}],"17_27":[{"i":"Rkzt","n":"EDSSW:  Rathaus "}],"17_26":[{"i":"Rkzt","n":"EDSSW:
      // Rathaus "}],"57_53":[{"i":"gEaR","n":"Spiel & Sport"}],"57_55":[{"i":"gEaR","n":"Spiel &
      // Sport"}],"3_62":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was
      // -"}],"3_61":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was
      // -"}],"57_54":[{"i":"gEaR","n":"Spiel & Sport"}],"3_60":[{"i":"gOWz","n":"Baumarktserie -
      // Wer Wo Was -"}],"15_27":[{"i":"Rkzt","n":"EDSSW:  Rathaus
      // "}],"15_26":[{"i":"Rkzt","n":"EDSSW:  Rathaus "}],"15_25":[{"i":"Rkzt","n":"EDSSW:  Rathaus
      // "}],"4_60":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was
      // -"}],"4_61":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was
      // -"}],"4_62":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was
      // -"}],"16_25":[{"i":"Rkzt","n":"EDSSW:  Rathaus "}],"16_26":[{"i":"Rkzt","n":"EDSSW:
      // Rathaus "}],"16_27":[{"i":"Rkzt","n":"EDSSW:  Rathaus
      // "}],"2_62":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was
      // -"}],"2_60":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was
      // -"}],"2_61":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was
      // -"}],"56_53":[{"i":"gEaR","n":"Spiel & Sport"}],"56_54":[{"i":"gEaR","n":"Spiel &
      // Sport"}],"56_55":[{"i":"gEaR","n":"Spiel & Sport"}]}
      //  }

      final ObjectNode json = (ObjectNode) JsonUtils.reader.readTree(data);

      final ArrayNode grid = (ArrayNode) json.get("grid");
      if (grid == null || grid.size() != (UTFGrid.GRID_MAXY + 1)) {
        throw new ParserException("No grid inside JSON");
      }
      final ArrayNode keys = (ArrayNode) json.get("keys");
      if (keys == null) {
        throw new ParserException("No keys inside JSON");
      }
      final ObjectNode dataObject = (ObjectNode) json.get("data");
      if (dataObject == null) {
        throw new ParserException("No data inside JSON");
      }

      // iterate over the data and construct all caches in this tile
      final Map<String, List<UTFGridPosition>> positions = new HashMap<>(); // JSON id as key
      final Map<String, List<UTFGridPosition>> singlePositions = new HashMap<>(); // JSON id as key

      for (final JsonNode rawKey : keys) {
        final String key = rawKey.asText();
        if (StringUtils.isNotBlank(key)) { // index 0 is empty
          final UTFGridPosition pos = UTFGridPosition.fromString(key);
          final ArrayNode dataForKey = (ArrayNode) dataObject.get(key);
          for (final JsonNode cacheInfo : dataForKey) {
            final String id = cacheInfo.get("i").asText();
            nameCache.put(id, cacheInfo.get("n").asText());

            List<UTFGridPosition> listOfPositions = positions.get(id);
            List<UTFGridPosition> singleListOfPositions = singlePositions.get(id);

            if (listOfPositions == null) {
              listOfPositions = new ArrayList<>();
              positions.put(id, listOfPositions);
              singleListOfPositions = new ArrayList<>();
              singlePositions.put(id, singleListOfPositions);
            }

            listOfPositions.add(pos);
            if (dataForKey.size() == 1) {
              singleListOfPositions.add(pos);
            }
          }
        }
      }

      final List<Geocache> caches = new ArrayList<>();
      for (final Entry<String, List<UTFGridPosition>> entry : positions.entrySet()) {
        final String id = entry.getKey();
        final List<UTFGridPosition> pos = entry.getValue();
        final UTFGridPosition xy = UTFGrid.getPositionInGrid(pos);
        final Geocache cache = new Geocache();
        cache.setDetailed(false);
        cache.setReliableLatLon(false);
        cache.setGeocode(id);
        cache.setName(nameCache.get(id));
        cache.setCoords(tile.getCoord(xy), tile.getZoomLevel());
        if (strategy.flags.contains(LivemapStrategy.Flag.PARSE_TILES) && bitmap != null) {
          for (final UTFGridPosition singlePos : singlePositions.get(id)) {
            if (IconDecoder.parseMapPNG(cache, bitmap, singlePos, tile.getZoomLevel())) {
              break; // cache parsed
            }
          }
        } else {
          cache.setType(CacheType.UNKNOWN, tile.getZoomLevel());
        }

        boolean exclude = false;
        if (Settings.isExcludeMyCaches()
            && (cache.isFound() || cache.isOwner())) { // workaround for BM
          exclude = true;
        }
        if (Settings.isExcludeDisabledCaches() && cache.isDisabled()) {
          exclude = true;
        }
        if (!Settings.getCacheType().contains(cache)
            && cache.getType() != CacheType.UNKNOWN) { // workaround for BM
          exclude = true;
        }
        if (!exclude) {
          caches.add(cache);
        }
      }
      searchResult.addAndPutInCache(caches);
      Log.d("Retrieved " + searchResult.getCount() + " caches for tile " + tile.toString());

    } catch (RuntimeException | ParserException | IOException e) {
      Log.e("GCMap.parseMapJSON", e);
    }

    return searchResult;
  }