manage exchange plugins, make sure ui doesn't stall while saving seed
and numerous other small fixes.
This commit is contained in:
@@ -2,109 +2,240 @@
|
||||
|
||||
'''Module exchange_rate:
|
||||
|
||||
This module is responsible for getting the conversion rates between different
|
||||
currencies.
|
||||
This module is responsible for getting the conversion rates from different
|
||||
bitcoin exchanges.
|
||||
'''
|
||||
|
||||
from kivy.network.urlrequest import UrlRequest
|
||||
#kivy.event import EventDispatcher
|
||||
from kivy.event import EventDispatcher
|
||||
from kivy.properties import (OptionProperty, StringProperty, AliasProperty,
|
||||
ListProperty)
|
||||
from kivy.clock import Clock
|
||||
import decimal
|
||||
import json
|
||||
|
||||
class Exchanger(object):
|
||||
'''
|
||||
EXCHANGES = ["BitcoinAverage",
|
||||
"BitcoinVenezuela",
|
||||
"BitPay",
|
||||
"Blockchain",
|
||||
"BTCChina",
|
||||
"CaVirtEx",
|
||||
"Coinbase",
|
||||
"CoinDesk",
|
||||
"LocalBitcoins",
|
||||
"Winkdex"]
|
||||
|
||||
|
||||
class Exchanger(EventDispatcher):
|
||||
''' Provide exchanges rate between crypto and different national
|
||||
currencies. See Module Documentation for details.
|
||||
'''
|
||||
|
||||
symbols = {'ALL': 'Lek', 'AED': 'د.إ', 'AFN':'؋', 'ARS': '$', 'AMD': '֏',
|
||||
'AWG': 'ƒ', 'ANG': 'ƒ', 'AOA': 'Kz', 'BDT': '৳', 'BHD': 'BD',
|
||||
'BIF': 'FBu', 'BTC': 'BTC', 'BTN': 'Nu',
|
||||
'AUD': '$', 'AZN': 'ман', 'BSD': '$', 'BBD': '$', 'BYR': 'p',
|
||||
'BIF': 'FBu', 'BTC': 'BTC', 'BTN': 'Nu', 'CDF': 'FC', 'CHF': 'CHF',
|
||||
'CLF': 'UF', 'CLP':'$', 'CVE': '$', 'DJF':'Fdj', 'DZD': 'دج',
|
||||
'AUD': '$', 'AZN': 'ман', 'BSD': '$', 'BBD': '$', 'BYR': 'p', 'CRC': '₡',
|
||||
'BZD': 'BZ$', 'BMD': '$', 'BOB': '$b', 'BAM': 'KM', 'BWP': 'P',
|
||||
'BGN': 'лв', 'BRL': 'R$', 'BND': '$', 'KHR': '៛', 'CAD': '$',
|
||||
'KYD': '$', 'USD': '$', 'CLP': '$', 'CNY': '¥', 'COP': '$', 'CRC': '₡',
|
||||
'ERN': 'Nfk', 'ETB': 'Br', 'KYD': '$', 'USD': '$', 'CLP': '$',
|
||||
'HRK': 'kn', 'CUP':'₱', 'CZK': 'Kč', 'DKK': 'kr', 'DOP': 'RD$',
|
||||
'XCD': '$', 'EGP': '£', 'SVC': '$' , 'EEK': 'kr', 'EUR': '€',
|
||||
'FKP': '£', 'FJD': '$', 'GHC': '¢', 'GIP': '£', 'GTQ': 'Q', 'GBP': '£',
|
||||
'GYD': '$', 'HNL': 'L', 'HKD': '$', 'HUF': 'Ft', 'ISK': 'kr',
|
||||
'INR': '₹', 'IDR': 'Rp', 'IRR': '﷼', 'IMP': '£', 'ILS': '₪',
|
||||
'INR': '₹', 'IDR': 'Rp', 'IRR': '﷼', 'IMP': '£', 'ILS': '₪', 'COP': '$',
|
||||
'JMD': 'J$', 'JPY': '¥', 'JEP': '£', 'KZT': 'лв', 'KPW': '₩',
|
||||
'KRW': '₩', 'KGS': 'лв', 'LAK': '₭', 'LVL': 'Ls'}
|
||||
'KRW': '₩', 'KGS': 'лв', 'LAK': '₭', 'LVL': 'Ls', 'CNY': '¥'}
|
||||
|
||||
_use_exchange = OptionProperty('Blockchain', options=EXCHANGES)
|
||||
'''This is the exchange to be used for getting the currency exchange rates
|
||||
'''
|
||||
|
||||
_currency = StringProperty('EUR')
|
||||
'''internal use only
|
||||
'''
|
||||
|
||||
def _set_currency(self, value):
|
||||
exchanger = self.exchanger
|
||||
if self.use_exchange == 'CoinDesk':
|
||||
self._update_cd_currency(self.currency)
|
||||
return
|
||||
try:
|
||||
self._currency = value
|
||||
self.electrum_cinfig.set_key('currency', value, True)
|
||||
except AttributeError:
|
||||
self._currency = 'EUR'
|
||||
|
||||
def _get_currency(self):
|
||||
try:
|
||||
self._currency = self.electrum_config.get('currency', 'EUR')
|
||||
except AttributeError:
|
||||
pass
|
||||
finally:
|
||||
return self._currency
|
||||
|
||||
currency = AliasProperty(_get_currency, _set_currency, bind=('_currency',))
|
||||
|
||||
currencies = ListProperty(['EUR', 'GBP', 'USD'])
|
||||
'''List of currencies supported by the current exchanger plugin.
|
||||
|
||||
:attr:`currencies` is a `ListProperty` default to ['Eur', 'GBP'. 'USD'].
|
||||
'''
|
||||
|
||||
def _get_useex(self):
|
||||
if not self.parent:
|
||||
return self._use_exchange
|
||||
|
||||
self._use_exchange = self.parent.electrum_config.get('use_exchange',
|
||||
'Blockchain')
|
||||
return self._use_exchange
|
||||
|
||||
def _set_useex(self, value):
|
||||
if not self.parent:
|
||||
return self._use_exchange
|
||||
self.parent.electrum_config.set_key('use_exchange', value, True)
|
||||
self._use_exchange = value
|
||||
|
||||
use_exchange = AliasProperty(_get_useex, _set_useex,
|
||||
bind=('_use_exchange', ))
|
||||
|
||||
def __init__(self, parent):
|
||||
super(Exchanger, self).__init__()
|
||||
self.parent = parent
|
||||
self.quote_currencies = None
|
||||
self.exchanges = ('BlockChain', 'Coinbase', 'CoinDesk')
|
||||
try:
|
||||
self.use_exchange = parent.electrum_config.get('use_exchange',
|
||||
'BlockChain')
|
||||
except AttributeError:
|
||||
self.use_exchange = 'BlockChain'
|
||||
self.currencies = self.symbols.keys()
|
||||
self.exchanges = EXCHANGES
|
||||
|
||||
def exchange(self, btc_amount, quote_currency):
|
||||
if self.quote_currencies is None:
|
||||
return None
|
||||
|
||||
quote_currencies = self.quote_currencies.copy()
|
||||
if quote_currency not in quote_currencies:
|
||||
return None
|
||||
if self.use_exchange == "CoinDesk":
|
||||
try:
|
||||
connection = httplib.HTTPSConnection('api.coindesk.com')
|
||||
connection.request("GET", "/v1/bpi/currentprice/" + str(quote_currency) + ".json")
|
||||
except Exception:
|
||||
return
|
||||
resp = connection.getresponse()
|
||||
if resp.reason == httplib.responses[httplib.NOT_FOUND]:
|
||||
return
|
||||
try:
|
||||
resp_rate = json.loads(resp.read())
|
||||
except Exception:
|
||||
return
|
||||
return btc_amount * decimal.Decimal(str(resp_rate["bpi"][str(quote_currency)]["rate_float"]))
|
||||
|
||||
return btc_amount * decimal.Decimal(quote_currencies[quote_currency])
|
||||
|
||||
def check_rates(self, dt):
|
||||
if self.use_exchange == 'BlockChain':
|
||||
self.check_blockchain()
|
||||
elif self.use_exchange == 'CoinDesk':
|
||||
self.check_coindesk()
|
||||
elif self.use_exchange == 'Coinbase':
|
||||
self.check_coinbase()
|
||||
def update_rate(self, dt):
|
||||
''' This is called from :method:`start` every X seconds; to update the
|
||||
rates for currencies for the currently selected exchange.
|
||||
'''
|
||||
update_rates = {
|
||||
"BitcoinAverage": self.update_ba,
|
||||
"BitcoinVenezuela": self.update_bv,
|
||||
"BitPay": self.update_bp,
|
||||
"Blockchain": self.update_bc,
|
||||
"BTCChina": self.update_CNY,
|
||||
"CaVirtEx": self.update_cv,
|
||||
"CoinDesk": self.update_cd,
|
||||
"Coinbase": self.update_cb,
|
||||
"LocalBitcoins": self.update_lb,
|
||||
"Winkdex": self.update_wd,
|
||||
}
|
||||
try:
|
||||
update_rates[self.use_exchange]()
|
||||
except KeyError:
|
||||
return
|
||||
|
||||
def check_coindesk(self):
|
||||
def update_wd(self):
|
||||
|
||||
def _lookup_rate(response, quote_id):
|
||||
return decimal.Decimal(str(response[str(quote_id)]["15m"]))
|
||||
def on_success(request, response):
|
||||
response = json.loads(response)
|
||||
quote_currencies = {'USD': 0.0}
|
||||
lenprices = len(response["prices"])
|
||||
usdprice = response['prices'][lenprices-1]['y']
|
||||
|
||||
try:
|
||||
quote_currencies["USD"] = decimal.Decimal(usdprice)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
self.quote_currencies = quote_currencies
|
||||
self.parent.set_currencies(quote_currencies)
|
||||
|
||||
req = UrlRequest(
|
||||
url='https://winkdex.com/static/data/0_600_288.json',
|
||||
on_success=on_success,
|
||||
timeout=5)
|
||||
|
||||
def update_cd_currency(self, currency):
|
||||
|
||||
def on_success(request, response):
|
||||
response = json.loads(response)
|
||||
quote_currencies = self.quote_currencies
|
||||
quote_currencies[currency] =\
|
||||
str(response['bpi'][str(currency)]['rate_float'])
|
||||
self.parent.set_currencies(quote_currencies)
|
||||
|
||||
req = UrlRequest(
|
||||
url='https://api.coindesk.com/v1/bpi/currentprice/'\
|
||||
+ str(currency) + '.json',on_success=on_success, timeout=5)
|
||||
|
||||
def update_cd(self):
|
||||
|
||||
def on_success(request, response):
|
||||
quote_currencies = {}
|
||||
response = json.loads(response)
|
||||
|
||||
for cur in response:
|
||||
quote_currencies[str(cur["currency"])] = 0.0
|
||||
|
||||
self.quote_currencies = quote_currencies
|
||||
self.update_cd_currency(self.currency)
|
||||
|
||||
req = UrlRequest(
|
||||
url='https://api.coindesk.com/v1/bpi/supported-currencies.json',
|
||||
on_success=on_success,
|
||||
timeout=5)
|
||||
|
||||
def update_cv(self):
|
||||
def on_success(request, response):
|
||||
response = json.loads(response)
|
||||
quote_currencies = {"CAD": 0.0}
|
||||
cadprice = response["last"]
|
||||
try:
|
||||
for r in response:
|
||||
quote_currencies[r] = _lookup_rate(response, r)
|
||||
quote_currencies["CAD"] = decimal.Decimal(cadprice)
|
||||
self.quote_currencies = quote_currencies
|
||||
except KeyError:
|
||||
pass
|
||||
self.parent.set_currencies(quote_currencies)
|
||||
|
||||
def on_failure(*args):
|
||||
pass
|
||||
|
||||
def on_error(*args):
|
||||
pass
|
||||
|
||||
def on_redirect(*args):
|
||||
pass
|
||||
|
||||
req = UrlRequest(
|
||||
url='https://api.coindesk.com/v1/bpi/supported-currencies.json',
|
||||
req = UrlRequest(url='https://www.cavirtex.com/api/CAD/ticker.json',
|
||||
on_success=on_success,
|
||||
on_failure=on_failure,
|
||||
on_error=on_error,
|
||||
on_redirect=on_redirect,
|
||||
timeout=5)
|
||||
|
||||
def check_coinbase(self):
|
||||
def update_CNY(self):
|
||||
|
||||
def on_success(request, response):
|
||||
quote_currencies = {"CNY": 0.0}
|
||||
cnyprice = response["ticker"]["last"]
|
||||
try:
|
||||
quote_currencies["CNY"] = decimal.Decimal(cnyprice)
|
||||
self.quote_currencies = quote_currencies
|
||||
except KeyError:
|
||||
pass
|
||||
self.parent.set_currencies(quote_currencies)
|
||||
|
||||
req = UrlRequest(url='https://data.btcchina.com/data/ticker',
|
||||
on_success=on_success,
|
||||
timeout=5)
|
||||
|
||||
def update_bp(self):
|
||||
|
||||
def on_success(request, response):
|
||||
quote_currencies = {}
|
||||
try:
|
||||
for r in response:
|
||||
quote_currencies[str(r['code'])] = decimal.Decimal(r['rate'])
|
||||
self.quote_currencies = quote_currencies
|
||||
except KeyError:
|
||||
pass
|
||||
self.parent.set_currencies(quote_currencies)
|
||||
|
||||
req = UrlRequest(url='https://bitpay.com/api/rates',
|
||||
on_success=on_success,
|
||||
timeout=5)
|
||||
|
||||
def update_cb(self):
|
||||
|
||||
def _lookup_rate(response, quote_id):
|
||||
return decimal.Decimal(str(response[str(quote_id)]))
|
||||
@@ -121,24 +252,12 @@ class Exchanger(object):
|
||||
pass
|
||||
self.parent.set_currencies(quote_currencies)
|
||||
|
||||
def on_failure(*args):
|
||||
pass
|
||||
|
||||
def on_error(*args):
|
||||
pass
|
||||
|
||||
def on_redirect(*args):
|
||||
pass
|
||||
|
||||
req = UrlRequest(
|
||||
url='https://coinbase.com/api/v1/currencies/exchange_rates',
|
||||
on_success=on_success,
|
||||
on_failure=on_failure,
|
||||
on_error=on_error,
|
||||
on_redirect=on_redirect,
|
||||
timeout=5)
|
||||
|
||||
def check_blockchain(self):
|
||||
def update_bc(self):
|
||||
|
||||
def _lookup_rate(response, quote_id):
|
||||
return decimal.Decimal(str(response[str(quote_id)]["15m"]))
|
||||
@@ -153,27 +272,69 @@ class Exchanger(object):
|
||||
pass
|
||||
self.parent.set_currencies(quote_currencies)
|
||||
|
||||
def on_failure(*args):
|
||||
pass
|
||||
|
||||
def on_error(*args):
|
||||
pass
|
||||
|
||||
def on_redirect(*args):
|
||||
pass
|
||||
|
||||
req = UrlRequest(url='https://blockchain.info/ticker',
|
||||
on_success=on_success,
|
||||
on_failure=on_failure,
|
||||
on_error=on_error,
|
||||
on_redirect=on_redirect,
|
||||
timeout=5)
|
||||
|
||||
def update_lb(self):
|
||||
def _lookup_rate(response, quote_id):
|
||||
return decimal.Decimal(response[str(quote_id)]["rates"]["last"])
|
||||
|
||||
def on_success(request, response):
|
||||
quote_currencies = {}
|
||||
try:
|
||||
for r in response:
|
||||
quote_currencies[r] = _lookup_rate(response, r)
|
||||
self.quote_currencies = quote_currencies
|
||||
except KeyError:
|
||||
pass
|
||||
self.parent.set_currencies(quote_currencies)
|
||||
|
||||
req = UrlRequest(
|
||||
url='https://localbitcoins.com/bitcoinaverage/ticker-all-currencies/',
|
||||
on_success=on_success,
|
||||
timeout=5)
|
||||
|
||||
|
||||
def update_ba(self):
|
||||
|
||||
def on_success(request, response):
|
||||
quote_currencies = {}
|
||||
try:
|
||||
for r in response:
|
||||
quote_currencies[r] = decimal.Decimal(response[r][u'last'])
|
||||
self.quote_currencies = quote_currencies
|
||||
except TypeError:
|
||||
pass
|
||||
self.parent.set_currencies(quote_currencies)
|
||||
|
||||
req = UrlRequest(url='https://api.bitcoinaverage.com/ticker/global/all',
|
||||
on_success=on_success,
|
||||
timeout=5)
|
||||
|
||||
def update_bv(self):
|
||||
|
||||
def on_success(request, response):
|
||||
quote_currencies = {}
|
||||
try:
|
||||
for r in response["BTC"]:
|
||||
quote_currencies[r] = decimal.Decimal(response['BTC'][r])
|
||||
self.quote_currencies = quote_currencies
|
||||
except KeyError:
|
||||
pass
|
||||
self.parent.set_currencies(quote_currencies)
|
||||
|
||||
req = UrlRequest(url='https://api.bitcoinvenezuela.com/',
|
||||
on_success=on_success,
|
||||
timeout=5)
|
||||
|
||||
def start(self):
|
||||
# check every 5 seconds
|
||||
self.check_rates(0)
|
||||
Clock.schedule_interval(self.check_rates, 5)
|
||||
# check rates every few seconds
|
||||
self.update_rate(0)
|
||||
# check every few seconds
|
||||
Clock.unschedule(self.update_rate)
|
||||
Clock.schedule_interval(self.update_rate, 20)
|
||||
|
||||
def stop(self):
|
||||
Clock.unschedule(self.check_rates)
|
||||
Clock.unschedule(self.update_rate)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user