Merge pull request #8856 from osmandapp/dynamic_downloads

Dynamic downloads
This commit is contained in:
max-klaus 2020-04-28 18:35:27 +03:00 committed by GitHub
commit 764f413196
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 168 additions and 4 deletions

View file

@ -415,6 +415,18 @@ public class CustomOsmandPlugin extends OsmandPlugin {
}
}
}
for (WorldRegion region : customRegions) {
loadSubregionIndexItems(region);
}
}
private void loadSubregionIndexItems(WorldRegion region) {
if (region instanceof CustomRegion) {
((CustomRegion) region).loadDynamicIndexItems(app);
}
for (WorldRegion subregion : region.getSubregions()) {
loadSubregionIndexItems(subregion);
}
}
public void updateSuggestedDownloads(List<SuggestedDownloadItem> items) {

View file

@ -6,6 +6,8 @@ import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.AndroidNetworkUtils;
import net.osmand.AndroidNetworkUtils.OnRequestResultListener;
import net.osmand.JsonUtils;
import net.osmand.PlatformUtil;
import net.osmand.map.WorldRegion;
@ -24,6 +26,7 @@ import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@ -38,6 +41,9 @@ public class CustomRegion extends WorldRegion {
private String subfolder;
private JSONArray downloadItemsJson;
private JSONArray dynamicItemsJson;
private DynamicDownloadItems dynamicDownloadItems;
private DownloadDescriptionInfo descriptionInfo;
@ -102,6 +108,12 @@ public class CustomRegion extends WorldRegion {
region.headers = JsonUtils.getLocalizedMapFromJson("header", object);
region.downloadItemsJson = object.optJSONArray("items");
region.dynamicItemsJson = object.optJSONArray("dynamic-items");
JSONObject urlItemsJson = object.optJSONObject("items-url");
if (urlItemsJson != null) {
region.dynamicDownloadItems = DynamicDownloadItems.fromJson(urlItemsJson);
}
String headerColor = object.optString("header-color", null);
try {
@ -130,16 +142,26 @@ public class CustomRegion extends WorldRegion {
jsonObject.putOpt("description", descriptionInfo.toJson());
}
jsonObject.putOpt("items", downloadItemsJson);
jsonObject.putOpt("dynamic-items", dynamicItemsJson);
if (dynamicDownloadItems != null) {
jsonObject.putOpt("items-url", dynamicDownloadItems.toJson());
}
return jsonObject;
}
public List<IndexItem> loadIndexItems() {
List<IndexItem> items = new ArrayList<>();
if (downloadItemsJson != null) {
items.addAll(loadIndexItems(downloadItemsJson));
items.addAll(loadIndexItems(dynamicItemsJson));
return items;
}
private List<IndexItem> loadIndexItems(JSONArray itemsJson) {
List<IndexItem> items = new ArrayList<>();
if (itemsJson != null) {
try {
for (int i = 0; i < downloadItemsJson.length(); i++) {
JSONObject itemJson = downloadItemsJson.getJSONObject(i);
for (int i = 0; i < itemsJson.length(); i++) {
JSONObject itemJson = itemsJson.getJSONObject(i);
long timestamp = itemJson.optLong("timestamp") * 1000;
long contentSize = itemJson.optLong("contentSize");
@ -182,4 +204,131 @@ public class CustomRegion extends WorldRegion {
}
return items;
}
void loadDynamicIndexItems(final OsmandApplication app) {
if (dynamicItemsJson == null && dynamicDownloadItems != null
&& !Algorithms.isEmpty(dynamicDownloadItems.url)
&& app.getSettings().isInternetConnectionAvailable()) {
OnRequestResultListener resultListener = new OnRequestResultListener() {
@Override
public void onResult(String result) {
if (!Algorithms.isEmpty(result)) {
if ("json".equalsIgnoreCase(dynamicDownloadItems.format)) {
dynamicItemsJson = mapJsonItems(result);
}
}
}
};
AndroidNetworkUtils.sendRequestAsync(app, dynamicDownloadItems.getUrl(), null,
null, false, false, resultListener);
}
}
private JSONArray mapJsonItems(String jsonStr) {
try {
JSONObject json = new JSONObject(jsonStr);
JSONArray jsonArray = json.optJSONArray(dynamicDownloadItems.itemsPath);
if (jsonArray != null) {
JSONArray itemsJson = new JSONArray();
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
JSONObject itemJson = mapDynamicJsonItem(jsonObject, dynamicDownloadItems.mapping);
itemsJson.put(itemJson);
}
return itemsJson;
}
} catch (JSONException e) {
LOG.error(e);
}
return null;
}
private JSONObject mapDynamicJsonItem(JSONObject jsonObject, JSONObject mapping) throws JSONException {
JSONObject itemJson = new JSONObject();
for (Iterator<String> it = mapping.keys(); it.hasNext(); ) {
String key = it.next();
Object value = checkMappingValue(mapping.opt(key), jsonObject);
itemJson.put(key, value);
}
return itemJson;
}
private Object checkMappingValue(Object value, JSONObject json) throws JSONException {
if (value instanceof String) {
String key = (String) value;
int index = key.indexOf("@");
if (index != -1) {
key = key.substring(index + 1);
}
return json.opt(key);
} else if (value instanceof JSONObject) {
JSONObject checkedJsonObject = (JSONObject) value;
JSONObject objectJson = new JSONObject();
for (Iterator<String> iterator = checkedJsonObject.keys(); iterator.hasNext(); ) {
String key = iterator.next();
Object checkedValue = checkMappingValue(checkedJsonObject.opt(key), json);
objectJson.put(key, checkedValue);
}
return objectJson;
} else if (value instanceof JSONArray) {
JSONArray checkedJsonArray = new JSONArray();
JSONArray jsonArray = (JSONArray) value;
for (int i = 0; i < jsonArray.length(); i++) {
Object checkedValue = checkMappingValue(jsonArray.opt(i), json);
checkedJsonArray.put(i, checkedValue);
}
return checkedJsonArray;
}
return value;
}
public static class DynamicDownloadItems {
private String url;
private String format;
private String itemsPath;
private JSONObject mapping;
public String getUrl() {
return url;
}
public String getFormat() {
return format;
}
public String getItemsPath() {
return itemsPath;
}
public JSONObject getMapping() {
return mapping;
}
public static DynamicDownloadItems fromJson(JSONObject object) {
DynamicDownloadItems dynamicDownloadItems = new DynamicDownloadItems();
dynamicDownloadItems.url = object.optString("url", null);
dynamicDownloadItems.format = object.optString("format", null);
dynamicDownloadItems.itemsPath = object.optString("items-path", null);
dynamicDownloadItems.mapping = object.optJSONObject("mapping");
return dynamicDownloadItems;
}
public JSONObject toJson() throws JSONException {
JSONObject jsonObject = new JSONObject();
jsonObject.putOpt("url", url);
jsonObject.putOpt("format", format);
jsonObject.putOpt("items-path", itemsPath);
jsonObject.putOpt("mapping", mapping);
return jsonObject;
}
}
}

View file

@ -851,6 +851,9 @@ public class ImportHelper {
((ProfileSettingsItem) item).applyAdditionalPrefs();
}
}
if (!Algorithms.isEmpty(plugin.getDownloadMaps())) {
app.getDownloadThread().runReloadIndexFilesSilent();
}
if (activity != null) {
plugin.onInstall(app, activity);
}