package org.wheelmap.android.net;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.wheelmap.android.activity.StartupActivity;
import org.wheelmap.android.app.WheelmapApp;
import org.wheelmap.android.mapping.node.SingleNode;
import org.wheelmap.android.service.RestServiceException;
import android.accounts.NetworkErrorException;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class MarkerIconExecutor extends SinglePageExecutor<SingleNode> implements
IExecutor {
private static final String MODIFIED_AT = "modified_at";
private static final String TYPE = "type";
private static final String MARKER = "icons";
public static final String CACHE_DIR = "filesdir";
private static final String TAG = MarkerIconExecutor.class.getSimpleName();
SharedPreferences prefs;
public MarkerIconExecutor(Context context, Bundle bundle) {
super(context, bundle, SingleNode.class);
}
@Override
public void prepareContent() {
}
@Override
public void execute(long id) throws RestServiceException {
prefs = WheelmapApp.getDefaultPrefs();
String request = getServer() + "/api/assets?api_key=" + getApiKey();
try {
org.apache.http.client.HttpClient client = mRequestProcessor.getRequestFactory().getHttpClient();
HttpGet get = new HttpGet(request);
HttpResponse response = client.execute(get);
if (response.getStatusLine().getStatusCode() == 200) {
String json = EntityUtils.toString(response.getEntity());
JSONObject jsonObject = new JSONObject(json);
JSONArray assets = jsonObject.getJSONArray("assets");
for (int i = 0; i < assets.length(); i++) {
JSONObject item = assets.getJSONObject(i);
//search marker
if (item.optString(TYPE, item.optString("name", "")).equals(MARKER)) {
long modified_at = item.getLong(MODIFIED_AT);
long current_data = prefs.getLong(MARKER + MODIFIED_AT, -1);
if (modified_at != current_data || StartupActivity.LOAD_AGAIN_DEBUG) {
boolean successfully = reloadMarkerAssets(item.getString("url"));
if (successfully) {
prefs.edit().putLong(MARKER + MODIFIED_AT, modified_at).commit();
} else {
processException(
RestServiceException.ERROR_NETWORK_FAILURE,
new NetworkErrorException(), true);
}
break;
}
}
}
} else {
processException(
RestServiceException.ERROR_NETWORK_FAILURE,
new NetworkErrorException(), true);
}
} catch (Exception e) {
e.printStackTrace();
processException(
RestServiceException.ERROR_NETWORK_FAILURE,
new NetworkErrorException(), true);
}
}
private boolean reloadMarkerAssets(String url) {
Context context = getContext();
File cachedir = context.getDir(CACHE_DIR, Context.MODE_PRIVATE);
File markerZip = new File(cachedir + "/icons.zip");
boolean download = downloadFile(markerZip, url);
if (!download) {
return false;
}
File marker_path = new File(cachedir + "/icons");
try {
unzipFile(markerZip, marker_path);
} catch (Exception e) {
e.printStackTrace();
return false;
}
markerZip.delete();
return true;
}
public static boolean markerIconsDownloaded() {
return WheelmapApp.getDefaultPrefs().getLong(MARKER + MODIFIED_AT, -1) > 0;
}
public static File getMarkerPath(Context context) {
File cachedir = context.getDir(CACHE_DIR, Context.MODE_PRIVATE);
File marker_path = new File(cachedir + "/icons/icons");
return marker_path;
}
private boolean downloadFile(File to, String fromUrl) {
Log.d(TAG, "load icons from: " + fromUrl);
try {
URL url = new URL(fromUrl);
URLConnection ucon = url.openConnection();
ucon.setReadTimeout(5000);
ucon.setConnectTimeout(10000);
InputStream is = ucon.getInputStream();
BufferedInputStream inStream = new BufferedInputStream(is, 1024 * 5);
File file = to;
if (file.exists()) {
file.delete();
}
file.createNewFile();
FileOutputStream outStream = new FileOutputStream(file);
byte[] buff = new byte[5 * 1024];
int len;
while ((len = inStream.read(buff)) != -1) {
outStream.write(buff, 0, len);
}
outStream.flush();
outStream.close();
inStream.close();
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
private void unzipFile(File zipfile, File to) throws Exception {
FileInputStream is;
ZipInputStream zis;
String filename;
is = new FileInputStream(zipfile);
zis = new ZipInputStream(is);
ZipEntry ze;
byte[] buffer = new byte[2048];
int count;
while ((ze = zis.getNextEntry()) != null) {
filename = ze.getName();
File file = new File(to + "/" + filename);
if (file.exists()) {
file.delete();
}
Log.d(getClass().getSimpleName(), "Full Issue Unzipping: " + file);
// make directory if necessary
new File(file.getParent()).mkdirs();
if (!ze.isDirectory() && !file.isDirectory()) {
FileOutputStream fout = new FileOutputStream(file);
while ((count = zis.read(buffer)) != -1) {
fout.write(buffer, 0, count);
}
fout.close();
}
zis.closeEntry();
}
is.close();
zis.close();
}
@Override
public void prepareDatabase() throws RestServiceException {
}
}