Skip to content

Commit

Permalink
closes #56
Browse files Browse the repository at this point in the history
* Switch data provider to https://iextrading.com/developer/docs/
  • Loading branch information
Nitesh Patel committed Nov 4, 2017
1 parent 912999c commit 476ad09
Show file tree
Hide file tree
Showing 9 changed files with 277 additions and 17 deletions.
4 changes: 2 additions & 2 deletions src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="nitezh.ministock"
android:versionCode="70"
android:versionName="70">
android:versionCode="71"
android:versionName="71">

<uses-sdk android:minSdkVersion="10" />

Expand Down
33 changes: 31 additions & 2 deletions src/main/java/nitezh/ministock/activities/PreferencesActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,7 @@ public class PreferencesActivity extends PreferenceActivity implements OnSharedP
// + "New features:<br/><br/>"
// + "• TODO.<br/><br/>"
+ "Multiple bug fixes:<br/><br/>"
+ "• Input keyboard no longer restricts the number separator for some languages.<br/><br/>"
+ "• Data retrieval for IXIC and DJI fixed after provider API removal.";
+ "• Switched data source to https://iextrading.com/developer/docs/";

// Fields for time pickers
private TimePickerDialog.OnTimeSetListener mTimeSetListener;
Expand Down Expand Up @@ -301,6 +300,18 @@ private void showDisclaimer() {
DialogTools.showSimpleDialog(this, title, body);
}

private void showAttributions() {
String title = "Attributions";
String body = "Data provided for free by IEX (https://iextrading.com/developer).";
DialogTools.showSimpleDialog(this, title, body);
}

private void showTermsOfService() {
String title = "Terms of Service (data)";
String body = "See https://iextrading.com/api-exhibit-a";
DialogTools.showSimpleDialog(this, title, body);
}

private void showHelp() {
String title = "Entering stocks";
String body = "<b>Entering stock symbols</b><br/><br />Stock symbols must be in the Yahoo format, which you can look up on the Yahoo Finance website.";
Expand Down Expand Up @@ -622,6 +633,24 @@ public boolean onPreferenceClick(Preference preference) {
return true;
}
});
// Hook the Attributions preference to the Attributions dialog
Preference attributions = findPreference("attributions");
attributions.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
showAttributions();
return true;
}
});
// Hook the Terms of Service preference to the Terms of Service dialog
Preference termsOfService = findPreference("termsOfService");
termsOfService.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
showTermsOfService();
return true;
}
});
// Callback received when the user sets the time in the dialog
mTimeSetListener = new TimePickerDialog.OnTimeSetListener() {
@Override
Expand Down
121 changes: 121 additions & 0 deletions src/main/java/nitezh/ministock/dataaccess/IexStockQuoteRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
The MIT License
Copyright (c) 2013 Nitesh Patel http://niteshpatel.github.io/ministocks
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

package nitezh.ministock.dataaccess;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.List;
import java.util.Locale;

import nitezh.ministock.domain.StockQuote;
import nitezh.ministock.utils.Cache;
import nitezh.ministock.utils.UrlDataTools;


public class IexStockQuoteRepository {
private static final String BASE_URL = "https://api.iextrading.com/1.0/stock/market/batch";
private final FxChangeRepository fxChangeRepository;

public IexStockQuoteRepository(FxChangeRepository fxChangeRepository) {
this.fxChangeRepository = fxChangeRepository;
}

private String buildRequestUrl(List<String> symbols) {
StringBuilder sQuery = new StringBuilder();
for (String s : symbols) {
if (!s.equals("")) {
if (!sQuery.toString().equals("")) {
sQuery.append(",");
}
sQuery.append(s);
}
}
return String.format("%s?types=quote&symbols=%s", BASE_URL, sQuery);
}

public HashMap<String, StockQuote> getQuotes(Cache cache, List<String> symbols) {
HashMap<String, StockQuote> quotes = new HashMap<>();
HashMap<String, String> fxChanges = this.fxChangeRepository.getChanges(cache, symbols);
JSONArray jsonArray;
JSONObject quoteJson;

try {
jsonArray = this.retrieveQuotesAsJson(cache, symbols);
if (jsonArray != null) {
for (int i = 0; i < jsonArray.length(); i++) {
quoteJson = jsonArray.getJSONObject(i);
StockQuote quote = new StockQuote(
quoteJson.optString("symbol"),
quoteJson.optString("price"),
quoteJson.optString("change"),
quoteJson.optString("percent"),
quoteJson.optString("exchange"),
quoteJson.optString("volume"),
quoteJson.optString("name"),
fxChanges.get(quoteJson.optString("symbol")),
Locale.US);
quotes.put(quote.getSymbol(), quote);
}
}
} catch (JSONException e) {
return null;
}

return quotes;
}

JSONArray retrieveQuotesAsJson(Cache cache, List<String> symbols) throws JSONException {
String url = buildRequestUrl(symbols);
JSONObject quotesJson;

try {
String quotes = UrlDataTools.getCachedUrlData(url, cache, 300);
quotesJson = new JSONObject(quotes);
} catch (JSONException e) {
throw new JSONException("");
}

JSONArray quotes = new JSONArray();

for (String symbol : symbols) {
JSONObject quoteJson = quotesJson.getJSONObject(symbol).getJSONObject("quote");

JSONObject data = new JSONObject();
data.put("symbol", quoteJson.optString("symbol"));
data.put("price", quoteJson.optString("latestPrice"));
data.put("change", quoteJson.optString("change"));
data.put("percent", quoteJson.optString("changePercent"));
data.put("exchange", quoteJson.optString("primaryExchange"));
data.put("volume", quoteJson.optString("latestVolume"));
data.put("name", quoteJson.optString("companyName"));
quotes.put(data);
}

return quotes;
}
}
12 changes: 7 additions & 5 deletions src/main/java/nitezh/ministock/domain/StockQuoteRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ of this software and associated documentation files (the "Software"), to deal

package nitezh.ministock.domain;

import android.annotation.SuppressLint;

import com.google.common.collect.ImmutableBiMap;

import org.json.JSONException;
Expand All @@ -41,7 +43,7 @@ of this software and associated documentation files (the "Software"), to deal
import nitezh.ministock.Storage;
import nitezh.ministock.dataaccess.FxChangeRepository;
import nitezh.ministock.dataaccess.GoogleStockQuoteRepository;
import nitezh.ministock.dataaccess.YahooStockQuoteRepository;
import nitezh.ministock.dataaccess.IexStockQuoteRepository;
import nitezh.ministock.utils.Cache;


Expand All @@ -55,15 +57,15 @@ public class StockQuoteRepository {

private static String mTimeStamp;
private static HashMap<String, StockQuote> mCachedQuotes;
private final YahooStockQuoteRepository yahooRepository;
private final IexStockQuoteRepository iexRepository;
private final GoogleStockQuoteRepository googleRepository;

private final Storage appStorage;
private final Cache appCache;
private final WidgetRepository widgetRepository;

public StockQuoteRepository(Storage appStorage, Cache appCache, WidgetRepository widgetRepository) {
this.yahooRepository = new YahooStockQuoteRepository(new FxChangeRepository());
this.iexRepository = new IexStockQuoteRepository(new FxChangeRepository());
this.googleRepository = new GoogleStockQuoteRepository();
this.appStorage = appStorage;
this.appCache = appCache;
Expand All @@ -79,7 +81,7 @@ HashMap<String, StockQuote> getLiveQuotes(List<String> symbols) {
yahooSymbols.removeAll(GOOGLE_SYMBOLS.keySet());
googleSymbols.retainAll(GOOGLE_SYMBOLS.keySet());

HashMap<String, StockQuote> yahooQuotes = this.yahooRepository.getQuotes(this.appCache, yahooSymbols);
HashMap<String, StockQuote> yahooQuotes = this.iexRepository.getQuotes(this.appCache, yahooSymbols);
HashMap<String, StockQuote> googleQuotes = this.googleRepository.getQuotes(this.appCache, googleSymbols);
if (yahooQuotes != null) allQuotes.putAll(yahooQuotes);
if (googleQuotes != null) allQuotes.putAll(googleQuotes);
Expand Down Expand Up @@ -130,7 +132,7 @@ public HashMap<String, StockQuote> getQuotes(List<String> symbols, boolean noCac
if (quotes.isEmpty()) {
quotes = loadQuotes();
} else {
SimpleDateFormat format = new SimpleDateFormat("dd MMM HH:mm");
@SuppressLint("SimpleDateFormat") SimpleDateFormat format = new SimpleDateFormat("dd MMM HH:mm");
String timeStamp = format.format(new Date()).toUpperCase();
saveQuotes(quotes, timeStamp);
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/nitezh/ministock/utils/VersionTools.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ of this software and associated documentation files (the "Software"), to deal

public class VersionTools {

public static final String BUILD = "70";
public static final String BUILD = "71";

private VersionTools() {
}
Expand Down
9 changes: 8 additions & 1 deletion src/main/res/xml/preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,14 @@
android:key="about"
android:summary="View the license"
android:title="License" />
<Preference
android:key="termsOfService"
android:summary="View the terms of service (data)"
android:title="Terms of Service (data)" />
<Preference
android:key="attributions"
android:summary="View the attributions"
android:title="Attributions" />
</PreferenceScreen>
</PreferenceCategory>

</PreferenceScreen>
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
The MIT License
Copyright (c) 2013 Nitesh Patel http://niteshpatel.github.io/ministocks
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

package nitezh.ministock.dataaccess;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

import nitezh.ministock.domain.StockQuote;
import nitezh.ministock.mocks.MockCache;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;


public class IexStockQuoteRepositoryTests {

private IexStockQuoteRepository quoteRepository;

@Before
public void setUp() {
FxChangeRepository fxRepository = new FxChangeRepository();
quoteRepository = new IexStockQuoteRepository(fxRepository);
}

@Test
public void retrieveQuotesAsJson() {
// Arrange
List<String> symbols = Arrays.asList("AAPL", "GOOG");
JSONArray json = null;

// Act
try {
json = this.quoteRepository.retrieveQuotesAsJson(new MockCache(), symbols);
} catch (JSONException ignored) {
}

// Assert
assertNotNull(json);
assertEquals(2, json.length());

JSONObject aaplJson = json.optJSONObject(0);
assertEquals("AAPL", aaplJson.optString("symbol"));
assertTrue(Arrays.asList("NasdaqNM", "NMS", "Nasdaq Global Select").contains(aaplJson.optString("exchange")));
assertEquals("Apple Inc.", aaplJson.optString("name"));

JSONObject googJson = json.optJSONObject(1);
assertEquals("GOOG", googJson.optString("symbol"));
assertTrue(Arrays.asList("NasdaqNM", "NMS", "Nasdaq Global Select").contains(googJson.optString("exchange")));
assertEquals("Alphabet Inc.", googJson.optString("name"));
}

@Test
public void getQuotes() {
// Arrange
List<String> symbols = Arrays.asList("AAPL", "GOOG");

// Act
HashMap<String, StockQuote> stockQuotes = quoteRepository.getQuotes(new MockCache(), symbols);

// Assert
assertEquals(2, stockQuotes.size());

StockQuote aaplQuote = stockQuotes.get("AAPL");
assertEquals("AAPL", aaplQuote.getSymbol());
assertTrue(Arrays.asList("NasdaqNM", "NMS", "Nasdaq Global Select").contains(aaplQuote.getExchange()));
assertEquals("Apple Inc.", aaplQuote.getName());

StockQuote googQuote = stockQuotes.get("GOOG");
assertEquals("GOOG", googQuote.getSymbol());
assertTrue(Arrays.asList("NasdaqNM", "NMS", "Nasdaq Global Select").contains(googQuote.getExchange()));
assertEquals("Alphabet Inc.", googQuote.getName());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ public void setUp() {
yahooRepository = new YahooStockQuoteRepository(fxRepository);
}

@Test
public void retrieveQuotesAsJson() {
// Arrange
List<String> symbols = Arrays.asList("AAPL", "GOOG");
Expand All @@ -79,7 +78,6 @@ public void retrieveQuotesAsJson() {
assertEquals("Alphabet Inc.", googJson.optString("name"));
}

@Test
public void getQuotes() {
// Arrange
List<String> symbols = Arrays.asList("AAPL", "GOOG");
Expand Down
Loading

0 comments on commit 476ad09

Please sign in to comment.