package org.ripple.power.txns; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.math.BigDecimal; import java.text.DateFormat; import java.text.DecimalFormat; import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.ripple.power.collection.ArrayMap; import org.ripple.power.config.LSystem; import org.ripple.power.utils.HttpRequest; import org.ripple.power.utils.HttpRequest.HttpRequestException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import com.ripple.core.coretypes.RippleDate; public class OtherData { final static String ELEMENT_SEPARATOR = "\001"; final static String ROW_SEPARATOR = "\002"; final static String REGEX_TABLE = "<table.*?>\\s*?((<tr.*?>.*?</tr>)+?)\\s*?</table>"; final static String REGEX_ROW = "<tr.*?>\\s*?(.*?)\\s*?</tr>"; final static String REGEX_ELE = "(?:<th.*?>|<td.*?>)(?:\\s*<.*?>)*(?: )?(.*?)(?: )?(?:\\s*<.*?>)*?\\s*(?:</th>|</td>)"; public static class LegalTenderCurrency { public String code; public String name; public int unit; public String currencyCode; public String country; public double rate; public double change; public String toHTMLString() { StringBuffer sbr = new StringBuffer(); sbr.append("name:"); sbr.append(name); sbr.append("<br>"); sbr.append("unit:"); sbr.append(unit); sbr.append("<br>"); sbr.append("country:"); sbr.append(country); sbr.append("<br>"); sbr.append("rate:"); sbr.append(rate); sbr.append("<br>"); sbr.append("change"); sbr.append(change); return sbr.toString(); } public String toString() { StringBuffer sbr = new StringBuffer(); sbr.append("name:"); sbr.append(name); sbr.append(" "); sbr.append("unit:"); sbr.append(unit); sbr.append(" "); sbr.append("country:"); sbr.append(country); sbr.append(" "); sbr.append("rate:"); sbr.append(rate); sbr.append(" "); sbr.append("change"); sbr.append(change); return sbr.toString(); } } public static class CoinmarketcapData { public int position = 0; public String marketCap; public String change7d; public String currency; public String id; public String change1h; public long timestamp; public String volume24; public String price; public String name; public String change7h; public String totalSupply; public String change24; public static CoinmarketcapData from(JSONObject o) { if (o != null) { CoinmarketcapData data = new CoinmarketcapData(); data.position = o.getInt("position"); data.marketCap = o.getString("marketCap"); data.change7d = o.getString("change7d"); data.volume24 = o.getString("volume24"); data.currency = o.getString("currency"); data.id = o.getString("id"); data.change1h = o.getString("change1h"); data.timestamp = o.getLong("timestamp"); data.price = o.getString("price"); if (data.price.toLowerCase().indexOf("e") != -1) { data.price = LSystem.getNumber(new BigDecimal(data.price)); } data.name = o.getString("name"); data.change7h = o.getString("change7h"); data.totalSupply = o.getString("totalSupply"); data.change24 = o.getString("change24"); return data; } return null; } public String toHTMLString() { return name + "/" + currency.toUpperCase() + "<br>" + " Week:" + change7d + "%<br>" + "7hour:" + change7h + "%<br>" + "1hour:" + change1h + "%<br>" + price + "/" + currency.toUpperCase() + "==1/" + name + "<br>" + "totalSupply:" + totalSupply + "<br>" + RippleDate.now().getTimeString(); } public String toString() { return name + "/" + currency.toUpperCase() + " " + " Week:" + change7d + "% " + " 7hour:" + change7h + "% " + " 1hour:" + change1h + "% " + price + "/" + currency.toUpperCase() + "==1/" + name + " " + "totalSupply:" + totalSupply + " " + RippleDate.now().getTimeString(); } } protected static ArrayList<Store> _storage = new ArrayList<Store>(); protected static class Store { protected double price; protected String name; protected long date = 0; public Store(double p, String str) { this.price = p; this.name = str; this.date = System.currentTimeMillis(); } public boolean equals(Store other) { return price == other.price && name.equals(other.name); } } private final static ArrayList<String> _coinmarketcap_limits = new ArrayList<String>( 10); static { _coinmarketcap_limits.add("usd"); _coinmarketcap_limits.add("eur"); _coinmarketcap_limits.add("cny"); _coinmarketcap_limits.add("cad"); _coinmarketcap_limits.add("rub"); _coinmarketcap_limits.add("btc"); } private final static HashMap<String, String> _coinmarketcap_names = new HashMap<String, String>( 10); static { _coinmarketcap_names.put("ripple", "xrp"); _coinmarketcap_names.put("bitcoin", "btc"); _coinmarketcap_names.put("litecoin", "ltc"); _coinmarketcap_names.put("dog", "doge"); _coinmarketcap_names.put("dogecoin", "doge"); _coinmarketcap_names.put("nxtcoin", "nxt"); _coinmarketcap_names.put("bts", "btsx"); } public static double reset(String name) { for (Store s : _storage) { if (s.name.equals(name) && (System.currentTimeMillis() - s.date) <= LSystem.MINUTE) { return s.price; } else if (s.name.equals(name)) { _storage.remove(s); return -1; } } return -1; } public static void addStorage(Store s) { _storage.add(s); if (_storage.size() > 20) { _storage.remove(0); } } public static double getLegaltenderCurrencyToUSD(String name) { if (name == null) { return -1; } try { name = name.trim().toLowerCase(); if (_coinmarketcap_names.containsKey(name)) { name = _coinmarketcap_names.get(name); } double ret = reset(name + "currency"); if (ret != -1) { return ret; } HttpRequest request = HttpRequest .get("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20('" + name + "')&format=json&diagnostics=false&env=http://datatables.org/alltables.env"); if (request.ok()) { String result = request.body(); JSONObject obj = new JSONObject(result); obj = obj.getJSONObject("query"); obj = obj.getJSONObject("results"); obj = obj.getJSONObject("rate"); if (obj.has("Rate")) { addStorage(new Store(obj.getDouble("Rate"), name + "currency")); return obj.getDouble("Rate"); } } } catch (Exception e) { e.printStackTrace(); } return -1; } public static String getCoinmarketcapCoinToUSD(String name) { if (name == null) { return null; } try { name = name.toLowerCase(); if (_coinmarketcap_names.containsKey(name)) { name = _coinmarketcap_names.get(name); } double ret = reset(name + "coin"); if (ret != -1) { return String.valueOf(ret); } HttpRequest request = HttpRequest .get("http://coinmarketcap.northpole.ro/api/" + name + ".json"); if (request.ok()) { JSONObject a = new JSONObject(request.body()); if (a.has("price")) { double result = a.getDouble("price"); double realprice = -1; // Prevent coinmarketcap price fixing if (LSystem.nativeCurrency.equalsIgnoreCase(name) || "ripple".equalsIgnoreCase(name)) { realprice = RippleChartsAPI.getXRPtoUSD(); } result = Math.max(result, realprice); addStorage(new Store(result, name + "coin")); return LSystem.getNumber(new BigDecimal(result)); } } } catch (Exception e) { } return null; } public static CoinmarketcapData getCoinmarketcapTo(String cur, String name) throws HttpRequestException, JSONException, IOException { if (cur == null || name == null) { return null; } cur = cur.toLowerCase(); name = name.toLowerCase(); if (!_coinmarketcap_limits.contains(cur)) { cur = "usd"; } if (_coinmarketcap_names.containsKey(name)) { name = _coinmarketcap_names.get(name); } HttpRequest request = HttpRequest.get(String.format( "http://coinmarketcap.northpole.ro/api/%s/%s.json", cur, name)); if (request.ok()) { JSONObject obj = new JSONObject(request.body()); CoinmarketcapData data = CoinmarketcapData.from(obj); return data; } return null; } public static ArrayList<CoinmarketcapData> getCoinmarketcapAllTo(int limit) throws Exception { if (limit <= 0) { limit = 1; } HttpRequest request = HttpRequest .get("http://coinmarketcap.northpole.ro/api/all.json"); request.acceptGzipEncoding(); if (request.ok()) { request.uncompress(true); JSONObject obj = new JSONObject(request.body()); JSONArray arrays = obj.optJSONArray("markets"); final int size = arrays.length(); ArrayList<CoinmarketcapData> list = new ArrayList<CoinmarketcapData>( size); for (int i = size - 1; i > -1; i--) { JSONObject o = arrays.getJSONObject(i); if (Integer.valueOf(o.optString("position")) <= limit) { CoinmarketcapData data = CoinmarketcapData.from(o); list.add(data); } } return list; } return null; } private static String FromNodeValue(Element el, String name) { return el.getElementsByTagName(name).item(0).getFirstChild() .getNodeValue(); } public static LegalTenderCurrency[] getBoiAllLegalTenderRates() throws Exception { DocumentBuilder dBuilder = DocumentBuilderFactory.newInstance() .newDocumentBuilder(); Document doc; HttpRequest request = HttpRequest .get("http://www.boi.org.il/currency.xml"); if (request.ok()) { doc = dBuilder.parse(request.stream()); NodeList currencies = doc.getElementsByTagName("CURRENCY"); LegalTenderCurrency result[] = new LegalTenderCurrency[currencies .getLength()]; for (int i = 0; i < currencies.getLength(); i++) { Element el = (Element) currencies.item(i); result[i] = new LegalTenderCurrency(); result[i].name = FromNodeValue(el, "NAME"); result[i].country = FromNodeValue(el, "COUNTRY"); result[i].currencyCode = FromNodeValue(el, "CURRENCYCODE"); result[i].unit = Integer.parseInt(FromNodeValue(el, ("UNIT"))); result[i].rate = Double .parseDouble(FromNodeValue(el, ("RATE"))); result[i].change = Double.parseDouble(FromNodeValue(el, ("CHANGE"))); } return result; } return null; } private static String find(int nStartLine, int nEndLine, BufferedReader br) throws IOException { String line; String target = ""; String elements = ""; int i = 0; while ((line = br.readLine()) != null) { ++i; if (i < nStartLine) { continue; } line.trim(); target = target + line; if (i >= nEndLine) { break; } } Pattern r = Pattern.compile(REGEX_TABLE, Pattern.CASE_INSENSITIVE); Matcher mTable = r.matcher(target); if (mTable.find()) { String strRows = mTable.group(1).trim(); Matcher mRow = Pattern.compile(REGEX_ROW, Pattern.CASE_INSENSITIVE) .matcher(strRows); while (mRow.find()) { boolean firstEle = true; String strEle = mRow.group(1).trim(); Matcher mEle = Pattern.compile(REGEX_ELE, Pattern.CASE_INSENSITIVE).matcher(strEle); if (!elements.equals("")) elements = elements + ROW_SEPARATOR; while (mEle.find()) { String result = mEle.group(1).trim(); if (firstEle) elements = elements + result; else elements = elements + ELEMENT_SEPARATOR + result; firstEle = false; } if (!elements.equals("")) { int len = elements.length(); elements = elements.substring(0, len - 2); } } } return new String(elements); } private final static DecimalFormat NUMBER_FORMAT = new DecimalFormat( "0.00000"); public static ArrayList<String> getAllLegalTenderRateHTML() throws Exception { HttpRequest request = HttpRequest.get("http://www.usd-cny.com/"); request.acceptGzipEncoding(); request.uncompress(true); if (!request.ok()) { return null; } BufferedReader br = new BufferedReader(new InputStreamReader( request.stream(), "gb2312")); String result = find(78, 313, br); String strRows[] = result.split(ROW_SEPARATOR); String strCur, strRate; NumberFormat numFormat = NumberFormat.getNumberInstance(); Number numb = null; ArrayList<String> hashTable = new ArrayList<String>(); for (int i = 1; i < strRows.length; i++) { String strEle[] = strRows[i].split(ELEMENT_SEPARATOR); if (strEle[3].equals("")) { break; } strCur = strEle[0].split(" ")[1]; strRate = strEle[3]; numb = numFormat.parse(strRate); strRate = numb.toString(); hashTable.add("1/" + strCur + "<br>Rate<br>" + NUMBER_FORMAT.format(Double.valueOf(strRate) / 100.0d) + "/CNY"); hashTable.add("1/CNY" + "<br>Rate<br>" + NUMBER_FORMAT.format(100.0d / Double.valueOf(strRate)) + "/" + strCur); } br.close(); return hashTable; } private static String getCharacterDataFromElement(Element e) { try { Node child = e.getFirstChild(); if (child instanceof org.w3c.dom.CharacterData) { org.w3c.dom.CharacterData cd = (org.w3c.dom.CharacterData) child; return cd.getData(); } } catch (Exception ex) { } return ""; } protected float getFloat(String value) { if (value != null && !value.equals("")) return Float.parseFloat(value); else return 0; } protected static String getElementValue(Element parent, String label) { return getCharacterDataFromElement((Element) parent .getElementsByTagName(label).item(0)); } public static String converterMoney(String src, String cur) throws Exception { if (src == null || cur == null) { return null; } String query = (cur + "/" + src).toUpperCase(); double ret = reset(query); if (ret != -1) { return String.valueOf(ret); } HttpRequest request = HttpRequest.get(String.format( "http://themoneyconverter.com/rss-feed/%s/rss.xml", src)); request.acceptGzipEncoding(); request.uncompress(true); if (!request.ok()) { return null; } DocumentBuilder builder = DocumentBuilderFactory.newInstance() .newDocumentBuilder(); Document doc = builder.parse(request.stream()); NodeList nodes = doc.getElementsByTagName("item"); for (int i = 0; i < nodes.getLength(); i++) { Element element = (Element) nodes.item(i); String description = getElementValue(element, "description"); if (query.equals(getElementValue(element, "title"))) { String[] leftright = description.split("="); String[] rightWords = leftright[1].split(" "); addStorage(new Store(Double.parseDouble(rightWords[1]), query)); return rightWords[1]; } } return null; } private static HashMap<String, String> _coin_names = new HashMap<String, String>( 10); static { _coin_names.put("xrp", "ripple"); _coin_names.put("btc", "bitcoin"); _coin_names.put("dog", "dogecoin"); _coin_names.put("doge", "dogecoin"); _coin_names.put("ppc", "peercoin"); _coin_names.put("ltc", "litecoin"); _coin_names.put("btsx", "bitshares-x"); _coin_names.put("bitsharesx", "bitshares-x"); } public static ArrayMap getCapitalization(int day, String name) throws Exception { return getCapitalization(day, name, -1); } // coinmarketcap data not update…… public static ArrayMap getCapitalization(int day, String name, int trend_limit) throws Exception { if (name == null) { return null; } name = name.trim().toLowerCase(); if (_coin_names.containsKey(name)) { name = _coin_names.get(name); } DateFormat YYYY_MM_DD_HHMM = new SimpleDateFormat("yyyy-MM-dd HH:mm"); ArrayMap list = new ArrayMap(100); JSONArray arrays = CoinmarketcapAPI .getCoinmarketcapMarketCap(name, day); if (arrays != null) { if (trend_limit > 0) { for (int i = arrays.length() - trend_limit; i < arrays.length(); i++) { JSONArray result = arrays.getJSONArray(i); list.put(result.getLong(0), result.getDouble(1)); } } else { for (int i = 0; i < arrays.length(); i++) { JSONArray result = arrays.getJSONArray(i); String key = YYYY_MM_DD_HHMM.format(new Date(result .getLong(0))); String value = String.valueOf(result.getDouble(1)); list.put(key, value); } } } return list; } }