diff --git a/exchangerate.py b/exchangerate.py new file mode 100644 index 0000000..8dfc450 --- /dev/null +++ b/exchangerate.py @@ -0,0 +1,185 @@ +#!/usr/bin/env python3 + +#import urllib.request +import requests +import json +import random +import sys +import os +import time + +#bitcoin stuff +#import pycoin.key +#os.environ["PYCOIN_NATIVE"]="openssl" +#from cashaddress import convert + +#dataset +import dataset +from stuf import stuf + +db_name = 'sqlite:///pyxpub.db?check_same_thread=False' + +CRYPTOCOMPARE = ["EUR", "USD", "GBP", "AUD", "BRL", "CAD", "CHF", "CLP", "CNY", "CZK", "DKK", "HKD", "HUF", "IDR", "ILS", "INR", "JPY", "KRW", "MXN", "MYR", "NOK", "NZD", "PHP", "PKR", "PLN", "RUB", "SEK", "SGD", "THB", "TRY", "TWD", "ZAR"] + +COINBASE = ["EUR", "USD"] + +KRAKEN = ["EUR", "USD"] + + +def is_supported(currency, source): + _db = dataset.connect(db_name, row_type=stuf) + _table = _db[source] + _record = _table.find_one(currency=currency) + + if _record: + return True + else: + return False + +def get_currencies(source): + if source == "cryptocompare": + return {'currencies': CRYPTOCOMPARE} + elif source == "coinbase": + return {'currencies': COINBASE} + elif source == "kraken": + return {'currencies': KRAKEN} + +def update_cryptocompare(): + _db = dataset.connect(db_name, row_type=stuf) + _table = _db['cryptocompare'] + + _api = "https://min-api.cryptocompare.com/data/price?fsym=BCH&tsyms={currencies}" + _string = ','.join(map(str, CRYPTOCOMPARE)) + _currencies = {'currencies': _string} + _query = _api.format(**_currencies) + + print("PYXPUB - FETCH: " + _query) + _response = requests.get(_query) + _json = _response.json() + + for key in _json: + _record = _table.find_one(currency=key) + if not _record: + print('INSERT: ' + key) + with dataset.connect(db_name, row_type=stuf) as tx: + tx['cryptocompare'].insert(dict(currency=key, rate=_json[key], timestamp=time.time())) + else: + _table.update(dict(currency=key, rate=_json[key], timestamp=time.time()), ['currency']) + #print('UPDATE: ' + key) + +def update_coinbase(): + _db = dataset.connect(db_name, row_type=stuf) + _table = _db['coinbase'] + + _api = "https://min-api.cryptocompare.com/data/price?fsym=BCH&tsyms={currencies}&e=Coinbase" + _string = ','.join(map(str, COINBASE)) + _currencies = {'currencies': _string} + _query = _api.format(**_currencies) + + print("PYXPUB - FETCH: " + _query) + _response = requests.get(_query) + _json = _response.json() + + for key in _json: + _record = _table.find_one(currency=key) + if not _record: + print('INSERT: ' + key) + with dataset.connect(db_name, row_type=stuf) as tx: + tx['coinbase'].insert(dict(currency=key, rate=_json[key], timestamp=time.time())) + else: + _table.update(dict(currency=key, rate=_json[key], timestamp=time.time()), ['currency']) + #print('UPDATE: ' + key) + +def update_kraken(): + _db = dataset.connect(db_name, row_type=stuf) + _table = _db['kraken'] + + _api = "https://min-api.cryptocompare.com/data/price?fsym=BCH&tsyms={currencies}&e=Kraken" + _string = ','.join(map(str, KRAKEN)) + _currencies = {'currencies': _string} + _query = _api.format(**_currencies) + + print("PYXPUB - FETCH: " + _query) + _response = requests.get(_query) + _json = _response.json() + + for key in _json: + _record = _table.find_one(currency=key) + if not _record: + print('INSERT: ' + key) + with dataset.connect(db_name, row_type=stuf) as tx: + tx['kraken'].insert(dict(currency=key, rate=_json[key], timestamp=time.time())) + else: + _table.update(dict(currency=key, rate=_json[key], timestamp=time.time()), ['currency']) + #print('UPDATE: ' + key) + + +def get_rate(currency, source): + _db = dataset.connect(db_name, row_type=stuf) + _table = _db[source] + _record = _table.find_one(currency=currency) + _now = time.time() + + if source == "cryptocompare": + if not _record: + print("PYXPUB - TABLE: {} ENTRY: {} NOT FOUND - UPDATING".format(source, currency)) + update_cryptocompare() + _record = _table.find_one(currency=currency) + else: + if ((_now - _record.timestamp) > 30): + print("PYXPUB - TABLE {} OUTDATED - UPDATING".format(source)) + update_cryptocompare() + _record = _table.find_one(currency=currency) + else: + _record = _table.find_one(currency=currency) + + elif source == "coinbase": + if not _record: + print("PYXPUB - TABLE: {} ENTRY: {} NOT FOUND - UPDATING".format(source, currency)) + update_coinbase() + _record = _table.find_one(currency=currency) + else: + if ((_now - _record.timestamp) > 30): + print("PYXPUB - TABLE {} OUTDATED - UPDATING".format(source)) + update_coinbase() + _record = _table.find_one(currency=currency) + else: + _record = _table.find_one(currency=currency) + + elif source == "kraken": + if not _record: + print("PYXPUB - TABLE: {} ENTRY: {} NOT FOUND - UPDATING".format(source, currency)) + update_kraken() + _record = _table.find_one(currency=currency) + else: + if ((_now - _record.timestamp) > 30): + print("PYXPUB - TABLE {} OUTDATED - UPDATING".format(source)) + update_kraken() + _record = _table.find_one(currency=currency) + else: + _record = _table.find_one(currency=currency) + + return _record + + + +def main(): + _curr = "USD" + + try: + _curr = sys.argv[1] + except: + print('No currency specified. Using: ' + _curr) + + _ticker = get_live_ticker(_curr) + + print("{:.2f}".format(float(_ticker['price_' + _curr.lower()]))) + + update_cryptocompare() + + #for f in fiat: + #_ticker = get_live_ticker(f) + #print("%3s: %.2f" % (f, float(_ticker[0]['price_' + f.lower()]))) + +if __name__ == '__main__': + main() diff --git a/pyxpub.db b/pyxpub.db index bad9b25..0353933 100644 Binary files a/pyxpub.db and b/pyxpub.db differ diff --git a/xpub.py b/xpub.py index a073a8e..4b9fb95 100644 --- a/xpub.py +++ b/xpub.py @@ -31,6 +31,7 @@ from cashaddress import convert import verify_tx +import exchangerate debug(True) @@ -320,6 +321,7 @@ def generate_verify(parameters, ip_addr): else: abort(400, "Incorrect use of API, RTFM!") + # TODO: return more payment details. see verify_tx.verify() if _payment.received == 1: return json.dumps({"received": 1}) else: @@ -339,6 +341,28 @@ def generate_verify(parameters, ip_addr): return json.dumps(_received) else: return json.dumps({"received": 0}) + +def generate_rate(parameters, ip_addr): + _currency = "" + _source = "" + if 'currency' in parameters and 'source' in parameters: + if not exchangerate.is_supported(parameters.currency, parameters.source): + abort(400, "ERROR: Unsupported Currency! => " + parameters.currency) + else: + _r = exchangerate.get_rate(parameters.currency, parameters.source) + _price = { + 'currency': _r.currency, + 'price' : _r.rate, + } + return _price + elif 'source' in parameters: + _r = exchangerate.get_currencies(parameters.source) + return _r + else: + abort(400, "ERROR: Incorrect use of api! ") + + + def set_headers(environ): if 'HTTP_ORIGIN' in environ: @@ -348,7 +372,6 @@ def set_headers(environ): #response.set_header("Access-Control-Allow-Origin", "*") #response.set_header("Access-Control-Allow-Credentials", "true") -#def start_server(): # Init bottle framework app = application = Bottle() @@ -416,6 +439,17 @@ def ledger(): return _ledger +@app.route('/api/rate') +def rate(): + set_headers(request.environ) + response.content_type = 'application/json' + + _ip = request.environ.get('REMOTE_ADDR') + _parameters = request.query + _rate = generate_rate(_parameters, _ip) + + return _rate + # Serve static files @app.route('/static/') def send_static(filename): @@ -441,7 +475,7 @@ def main(): app.run(server=MTServer, host='0.0.0.0', port=8080, thread_count=3) # Paste wsgi server - #httpserver.serve(app, host='0.0.0.0', port=8082) + #httpserver.serve(app, host='0.0.0.0', port=8080) #start_server()