package com.llamacorp.equate.unit; import android.content.Context; import android.os.AsyncTask; import android.util.Log; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Date; import java.util.GregorianCalendar; public class UnitCurrency extends Unit { private static final String JSON_LAST_UPDATE = "updated"; public static final String DEFAULT_CURRENCY = "USD"; private Date mTimeLastUpdated; // private String mURLPrefix = "http://rate-exchange.appspot.com/currency?from=USD&to="; private String mURLPrefix = "http://rate-exchange.herokuapp.com/fetchRate?from=" + DEFAULT_CURRENCY + "&to="; //this is for communication with fragment hosting convert keys // OnConvertKeyUpdateFinishedListener mCallback; Context mContext; // // public interface OnConvertKeyUpdateFinishedListener { // public void updateDynamicUnitButtons(String text); // } //used to tell parent classes if the asyncRefresh is currently running private boolean mUpdating = false; public UnitCurrency(String name, String longName, double value) { super(name, longName, value); //Note that Jan = 0 in the Gregorian Calendar constructor below mTimeLastUpdated = new GregorianCalendar(2015, 3, 1, 1, 11).getTime(); } public UnitCurrency(String name, String longName, double value, String URL) { this(name, longName, value); mURLPrefix = URL; } /** * Load in the update time */ @Override public boolean loadJSON(JSONObject json) throws JSONException { boolean success = super.loadJSON(json); //only load in the time if the JSON object matches this UNIT if (success) setUpdateTime(new Date(json.getLong(JSON_LAST_UPDATE))); return success; } /** * Save the update time */ @Override public JSONObject toJSON() throws JSONException { JSONObject json = super.toJSON(); json.put(JSON_LAST_UPDATE, mTimeLastUpdated.getTime()); return json; } public void setUpdateTime(Date date) { mTimeLastUpdated = date; } public long getTimeOfUpdate() { if (mTimeLastUpdated != null) return mTimeLastUpdated.getTime(); else return 0; } public boolean isUpdating() { return mUpdating; } // // public void setCallback(OnConvertKeyUpdateFinishedListener callback) { // mCallback = callback; // } @Override public String convertTo(Unit toUnit, String expressionToConv) { return expressionToConv + "*" + toUnit.getValue() + "/" + getValue(); } public boolean isTimeoutReached(Context c) { mContext = c; Date now = new Date(); return !(mTimeLastUpdated != null && (now.getTime() - mTimeLastUpdated.getTime()) < (60 * 1000 * UnitTypeUpdater.UPDATE_TIMEOUT_MIN)); } /** * Asynchronously try to update the currency rate by fetching the * value via an HTTP JSON API call. Note that this call will take * some time to update the value, since it runs in the background. * Also note that the value may or may not even be updated, dependent * on Internet connection. */ public void asyncRefresh(Context c) { if (getAbbreviation().equals("") || getAbbreviation().equals(DEFAULT_CURRENCY)) return; if (mUpdating) return; mContext = c; mUpdating = true; // if(mCallback != null) // mCallback.updateDynamicUnitButtons("Updating"); new HttpAsyncTask().execute(getURL()); } private String getURL() { //crude method, want something better later if (getAbbreviation().equals("BTC")) return mURLPrefix; else return mURLPrefix + toString(); } /** * This class is used to create a background task that handles * the actual HTTP getting and JSON parsing */ private class HttpAsyncTask extends AsyncTask<String, Void, String> { //This method is called first @Override protected String doInBackground(String... urls) { return GET(urls[0]); } // This method is called after doInBackground completes @Override protected void onPostExecute(String result) { boolean updateSuccess = false; //this is crude, but works until we have more URLs each with unique formats if (getAbbreviation().equals("BTC")) try { setValue(Double.parseDouble(result)); updateSuccess = true; } catch (Exception e) { //System.out.println("Parsing Exception for BTC, result = " + result); } else updateSuccess = parseRateFromJSONString(result); //record time of update only if we actually updated if (updateSuccess){ setUpdateTime(new Date()); } //updating is complete mUpdating = false; // if(mCallback != null) // mCallback.updateDynamicUnitButtons("Updating"); } /** * Attempt to take a JSON string, parse it, and set the value * of this current Currency Unit */ private boolean parseRateFromJSONString(String result) { boolean updateSuccess = false; try { //System.out.println("Trying to parse \"" + result + "\""); JSONObject json = new JSONObject(result); final String JSON_URL_RATE_TAG = "Rate"; double rate = json.getDouble(JSON_URL_RATE_TAG); setValue(rate); updateSuccess = true; } catch (JSONException e) { // if(result.contains("Over Quota")){ // System.out.println("Over quota for " + getAbbreviation()); // } // else // System.out.println("Result didn't parse, result = " + result); } return updateSuccess; } /** * Helper function for above method */ private String GET(String url) { InputStream inputStream; String result = ""; try { // create HttpClient HttpClient httpclient = new DefaultHttpClient(); // make GET request to the given URL HttpResponse httpResponse = httpclient.execute(new HttpGet(url)); // receive response as inputStream inputStream = httpResponse.getEntity().getContent(); // convert inputstream to string if (inputStream != null) result = convertInputStreamToString(inputStream); else result = "Did not work!"; } catch (Exception e) { Log.d("InputStream", e.getLocalizedMessage()); } return result; } /** * Helper function for above method */ private String convertInputStreamToString(InputStream inputStream) throws IOException { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); String line; String result = ""; while ((line = bufferedReader.readLine()) != null) result += line; inputStream.close(); return result; } } }