mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-08-23 17:47:31 +00:00
manage exchange plugins, make sure ui doesn't stall while saving seed
and numerous other small fixes.
This commit is contained in:
parent
1bbb211671
commit
1179a4cf9e
7 changed files with 321 additions and 124 deletions
|
@ -192,7 +192,7 @@ class InfoBubble(Bubble):
|
||||||
anim.start(self)
|
anim.start(self)
|
||||||
|
|
||||||
|
|
||||||
def hide(self, *dt):
|
def hide(self, now=False):
|
||||||
''' Auto fade out the Bubble
|
''' Auto fade out the Bubble
|
||||||
'''
|
'''
|
||||||
def on_stop(*l):
|
def on_stop(*l):
|
||||||
|
@ -205,6 +205,8 @@ class InfoBubble(Bubble):
|
||||||
App.get_running_app().stop()
|
App.get_running_app().stop()
|
||||||
import sys
|
import sys
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
if now:
|
||||||
|
return on_stop()
|
||||||
|
|
||||||
anim = Animation(opacity=0, d=.25)
|
anim = Animation(opacity=0, d=.25)
|
||||||
anim.bind(on_complete=on_stop)
|
anim.bind(on_complete=on_stop)
|
||||||
|
|
|
@ -82,11 +82,13 @@ class Drawer(StencilView):
|
||||||
if app.ui_mode[0] == 't':
|
if app.ui_mode[0] == 't':
|
||||||
return super(Drawer, self).on_touch_down(touch)
|
return super(Drawer, self).on_touch_down(touch)
|
||||||
|
|
||||||
|
state = self.state
|
||||||
touch.ud['send_touch_down'] = False
|
touch.ud['send_touch_down'] = False
|
||||||
|
start = 0 if state[0] == 'c' else self._hidden_widget.right
|
||||||
drag_area = ((self.width * self.drag_area)
|
drag_area = ((self.width * self.drag_area)
|
||||||
if self.state[0] == 'c' else
|
if self.state[0] == 'c' else
|
||||||
self._hidden_widget.width)
|
self.width)
|
||||||
if touch.x > drag_area:
|
if touch.x not in range(int(start), int(drag_area)):
|
||||||
return super(Drawer, self).on_touch_down(touch)
|
return super(Drawer, self).on_touch_down(touch)
|
||||||
self._touch = touch
|
self._touch = touch
|
||||||
Clock.schedule_once(self._change_touch_mode,
|
Clock.schedule_once(self._change_touch_mode,
|
||||||
|
@ -106,8 +108,13 @@ class Drawer(StencilView):
|
||||||
if not touch.ud.get('in_drag_area', None):
|
if not touch.ud.get('in_drag_area', None):
|
||||||
return super(Drawer, self).on_touch_move(touch)
|
return super(Drawer, self).on_touch_move(touch)
|
||||||
|
|
||||||
self._overlay_widget.x = min(self._hidden_widget.width,
|
ov = self._overlay_widget
|
||||||
max(self._overlay_widget.x + touch.dx*2, 0))
|
ov.x=min(self._hidden_widget.width,
|
||||||
|
max(ov.x + touch.dx*2, 0))
|
||||||
|
#_anim = Animation(x=x, duration=1/60)
|
||||||
|
#_anim.cancel_all(ov)
|
||||||
|
#_anim.start(ov)
|
||||||
|
|
||||||
if abs(touch.x - touch.ox) < self.scroll_distance:
|
if abs(touch.x - touch.ox) < self.scroll_distance:
|
||||||
return
|
return
|
||||||
touch.ud['send_touch_down'] = False
|
touch.ud['send_touch_down'] = False
|
||||||
|
|
|
@ -45,10 +45,16 @@ class InstallWizard(Widget):
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def target():
|
def target():
|
||||||
|
|
||||||
# run your threaded function
|
# run your threaded function
|
||||||
task()
|
try:
|
||||||
|
task()
|
||||||
|
except Exception as err:
|
||||||
|
Clock.schedule_once(lambda dt: app.show_error(str(err)))
|
||||||
|
|
||||||
# on completion hide message
|
# on completion hide message
|
||||||
Clock.schedule_once(lambda dt: app.info_bubble.hide())
|
Clock.schedule_once(lambda dt: app.info_bubble.hide(now=True), -1)
|
||||||
|
|
||||||
# call completion routine
|
# call completion routine
|
||||||
if on_complete:
|
if on_complete:
|
||||||
Clock.schedule_once(lambda dt: on_complete())
|
Clock.schedule_once(lambda dt: on_complete())
|
||||||
|
@ -138,14 +144,14 @@ class InstallWizard(Widget):
|
||||||
|
|
||||||
brainwallet = seed
|
brainwallet = seed
|
||||||
|
|
||||||
msg2 = _("[color=#414141][b]"+\
|
msg2 = _("[color=#414141]"+\
|
||||||
"[b]PLEASE WRITE DOWN YOUR SEED PASS[/b][/color]"+\
|
"[b]PLEASE WRITE DOWN YOUR SEED PASS[/b][/color]"+\
|
||||||
"[size=9]\n\n[/size]" +\
|
"[size=9]\n\n[/size]" +\
|
||||||
"[color=#929292]If you ever forget your pincode, your seed" +\
|
"[color=#929292]If you ever forget your pincode, your seed" +\
|
||||||
" phrase will be the [color=#EB984E]"+\
|
" phrase will be the [color=#EB984E]"+\
|
||||||
"[b]only way to recover[/b][/color] your wallet. Your " +\
|
"[b]only way to recover[/b][/color] your wallet. Your " +\
|
||||||
" [color=#EB984E][b]Bitcoins[/b][/color] will otherwise be" +\
|
" [color=#EB984E][b]Bitcoins[/b][/color] will otherwise be" +\
|
||||||
" [color=#EB984E]lost forever![/color]")
|
" [color=#EB984E][b]lost forever![/b][/color]")
|
||||||
|
|
||||||
if wallet.imported_keys:
|
if wallet.imported_keys:
|
||||||
msg2 += "[b][color=#ff0000ff]" + _("WARNING") + "[/color]:[/b] " +\
|
msg2 += "[b][color=#ff0000ff]" + _("WARNING") + "[/color]:[/b] " +\
|
||||||
|
@ -234,13 +240,13 @@ class InstallWizard(Widget):
|
||||||
return app.show_error(_('Passwords do not match'), duration=.5)
|
return app.show_error(_('Passwords do not match'), duration=.5)
|
||||||
|
|
||||||
if mode == 'restore':
|
if mode == 'restore':
|
||||||
try:
|
def on_complete(*l):
|
||||||
wallet.save_seed(new_password)
|
_dlg.close()
|
||||||
except Exception as err:
|
self.load_network(wallet, mode='restore')
|
||||||
app.show_error(str(err))
|
|
||||||
return
|
self.waiting_dialog(lambda: wallet.save_seed(new_password),
|
||||||
_dlg.close()
|
msg=_("saving seed"),
|
||||||
self.load_network(wallet, mode='restore')
|
on_complete=on_complete)
|
||||||
return
|
return
|
||||||
if not instance:
|
if not instance:
|
||||||
# create
|
# create
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#:import _ electrum.i18n._
|
#:import _ electrum.i18n._
|
||||||
#:import partial functools.partial
|
#:import partial functools.partial
|
||||||
|
|
||||||
|
|
||||||
# Custom Global Widgets
|
# Custom Global Widgets
|
||||||
|
|
||||||
<VGridLayout@GridLayout>:
|
<VGridLayout@GridLayout>:
|
||||||
|
@ -27,7 +28,7 @@
|
||||||
|
|
||||||
<Label>
|
<Label>
|
||||||
markup: True
|
markup: True
|
||||||
font_name: 'data/fonts/Roboto.ttf'
|
font_name: 'Roboto'
|
||||||
font_size: '16sp'
|
font_size: '16sp'
|
||||||
|
|
||||||
<ListItemButton>
|
<ListItemButton>
|
||||||
|
|
|
@ -93,7 +93,7 @@ class ElectrumWindow(App):
|
||||||
'While trying to save value to config')
|
'While trying to save value to config')
|
||||||
|
|
||||||
base_unit = AliasProperty(_get_bu, _set_bu, bind=('decimal_point',))
|
base_unit = AliasProperty(_get_bu, _set_bu, bind=('decimal_point',))
|
||||||
'''BTC or UBTC or ...
|
'''BTC or UBTC or mBTC...
|
||||||
|
|
||||||
:attr:`base_unit` is a `AliasProperty` defaults to the unit set in
|
:attr:`base_unit` is a `AliasProperty` defaults to the unit set in
|
||||||
electrum config.
|
electrum config.
|
||||||
|
@ -148,13 +148,13 @@ class ElectrumWindow(App):
|
||||||
self.network = network = kwargs.get('network')
|
self.network = network = kwargs.get('network')
|
||||||
self.electrum_config = config = kwargs.get('config')
|
self.electrum_config = config = kwargs.get('config')
|
||||||
|
|
||||||
# create triggers so as to minimize updation a max of 5 times a sec
|
# create triggers so as to minimize updation a max of 2 times a sec
|
||||||
self._trigger_update_status =\
|
self._trigger_update_status =\
|
||||||
Clock.create_trigger(self.update_status, .2)
|
Clock.create_trigger(self.update_status, .5)
|
||||||
self._trigger_update_console =\
|
self._trigger_update_console =\
|
||||||
Clock.create_trigger(self.update_console, .2)
|
Clock.create_trigger(self.update_console, .5)
|
||||||
self._trigger_notify_transactions = \
|
self._trigger_notify_transactions = \
|
||||||
Clock.create_trigger(self.notify_transactions, .2)
|
Clock.create_trigger(self.notify_transactions, .5)
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
from kivy.lang import Builder
|
from kivy.lang import Builder
|
||||||
|
@ -174,6 +174,15 @@ class ElectrumWindow(App):
|
||||||
Window.bind(size=self.on_size,
|
Window.bind(size=self.on_size,
|
||||||
on_keyboard=self.on_keyboard)
|
on_keyboard=self.on_keyboard)
|
||||||
Window.bind(on_key_down=self.on_key_down)
|
Window.bind(on_key_down=self.on_key_down)
|
||||||
|
|
||||||
|
# register fonts
|
||||||
|
from kivy.core.text import Label
|
||||||
|
Label.register('Roboto',
|
||||||
|
'data/fonts/Roboto.ttf',
|
||||||
|
'data/fonts/Roboto.ttf',
|
||||||
|
'data/fonts/Roboto-Bold.ttf',
|
||||||
|
'data/fonts/Roboto-Bold.ttf')
|
||||||
|
|
||||||
if platform == 'android':
|
if platform == 'android':
|
||||||
#
|
#
|
||||||
Window.bind(keyboard_height=self.on_keyboard_height)
|
Window.bind(keyboard_height=self.on_keyboard_height)
|
||||||
|
@ -261,17 +270,20 @@ class ElectrumWindow(App):
|
||||||
|
|
||||||
self.load_wallet(wallet)
|
self.load_wallet(wallet)
|
||||||
|
|
||||||
# check and remove this load_wallet calls update_wallet no
|
#TODO: URI handling
|
||||||
# need for this here
|
|
||||||
#Clock.schedule_once(update_wallet)
|
|
||||||
|
|
||||||
#self.windows.append(w)
|
#self.windows.append(w)
|
||||||
#if url: w.set_url(url)
|
#if url: w.set_url(url)
|
||||||
#w.app = self.app
|
|
||||||
#w.connect_slots(s)
|
|
||||||
#w.update_wallet()
|
|
||||||
|
|
||||||
#self.app.exec_()
|
# TODO:remove properties are used instead
|
||||||
|
#Clock.schedule_interval(self.timer_actions, .5)
|
||||||
|
|
||||||
|
|
||||||
|
#TODO: remove not needed properties allow on_property events
|
||||||
|
#def timer_actions(self):
|
||||||
|
# if self.need_update.is_set():
|
||||||
|
# self.update_wallet()
|
||||||
|
# self.need_update.clear()
|
||||||
|
# run_hook('timer_actions')
|
||||||
|
|
||||||
def init_ui(self):
|
def init_ui(self):
|
||||||
''' Initialize The Ux part of electrum. This function performs the basic
|
''' Initialize The Ux part of electrum. This function performs the basic
|
||||||
|
@ -326,12 +338,12 @@ class ElectrumWindow(App):
|
||||||
from electrum_gui.kivy.plugins.exchange_rate import Exchanger
|
from electrum_gui.kivy.plugins.exchange_rate import Exchanger
|
||||||
self.exchanger = Exchanger(self)
|
self.exchanger = Exchanger(self)
|
||||||
self.exchanger.start()
|
self.exchanger.start()
|
||||||
quote_currency = self.electrum_config.get("currency", 'EUR')
|
quote_currency = self.exchanger.currency
|
||||||
quote_balance = self.exchanger.exchange(btc_balance, quote_currency)
|
quote_balance = self.exchanger.exchange(btc_balance, quote_currency)
|
||||||
|
|
||||||
if mode == 'symbol':
|
if quote_currency and mode == 'symbol':
|
||||||
if quote_currency:
|
quote_currency = self.exchanger.symbols.get(quote_currency,
|
||||||
quote_currency = self.exchanger.symbols[quote_currency]
|
quote_currency)
|
||||||
|
|
||||||
if quote_balance is None:
|
if quote_balance is None:
|
||||||
quote_text = ""
|
quote_text = ""
|
||||||
|
@ -340,8 +352,9 @@ class ElectrumWindow(App):
|
||||||
return quote_text
|
return quote_text
|
||||||
|
|
||||||
def set_currencies(self, quote_currencies):
|
def set_currencies(self, quote_currencies):
|
||||||
self._trigger_update_status
|
#TODO remove this and just directly update a observable property
|
||||||
#self.currencies = sorted(quote_currencies.keys())
|
self._trigger_update_status()
|
||||||
|
self.currencies = sorted(quote_currencies.keys())
|
||||||
|
|
||||||
def update_console(self, *dt):
|
def update_console(self, *dt):
|
||||||
if self.console:
|
if self.console:
|
||||||
|
@ -399,7 +412,7 @@ class ElectrumWindow(App):
|
||||||
#if quote:
|
#if quote:
|
||||||
# text += " (%s)"%quote
|
# text += " (%s)"%quote
|
||||||
|
|
||||||
self.notify(_("Balance: ") + text)
|
#self.notify(_("Balance: ") + text)
|
||||||
#icon = QIcon(":icons/status_connected.png")
|
#icon = QIcon(":icons/status_connected.png")
|
||||||
else:
|
else:
|
||||||
text = _("Not connected")
|
text = _("Not connected")
|
||||||
|
|
|
@ -2,109 +2,240 @@
|
||||||
|
|
||||||
'''Module exchange_rate:
|
'''Module exchange_rate:
|
||||||
|
|
||||||
This module is responsible for getting the conversion rates between different
|
This module is responsible for getting the conversion rates from different
|
||||||
currencies.
|
bitcoin exchanges.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from kivy.network.urlrequest import UrlRequest
|
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
|
from kivy.clock import Clock
|
||||||
import decimal
|
import decimal
|
||||||
import json
|
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': '֏',
|
symbols = {'ALL': 'Lek', 'AED': 'د.إ', 'AFN':'؋', 'ARS': '$', 'AMD': '֏',
|
||||||
'AWG': 'ƒ', 'ANG': 'ƒ', 'AOA': 'Kz', 'BDT': '৳', 'BHD': 'BD',
|
'AWG': 'ƒ', 'ANG': 'ƒ', 'AOA': 'Kz', 'BDT': '৳', 'BHD': 'BD',
|
||||||
'BIF': 'FBu', 'BTC': 'BTC', 'BTN': 'Nu',
|
'BIF': 'FBu', 'BTC': 'BTC', 'BTN': 'Nu', 'CDF': 'FC', 'CHF': 'CHF',
|
||||||
'AUD': '$', 'AZN': 'ман', 'BSD': '$', 'BBD': '$', 'BYR': 'p',
|
'CLF': 'UF', 'CLP':'$', 'CVE': '$', 'DJF':'Fdj', 'DZD': 'دج',
|
||||||
|
'AUD': '$', 'AZN': 'ман', 'BSD': '$', 'BBD': '$', 'BYR': 'p', 'CRC': '₡',
|
||||||
'BZD': 'BZ$', 'BMD': '$', 'BOB': '$b', 'BAM': 'KM', 'BWP': 'P',
|
'BZD': 'BZ$', 'BMD': '$', 'BOB': '$b', 'BAM': 'KM', 'BWP': 'P',
|
||||||
'BGN': 'лв', 'BRL': 'R$', 'BND': '$', 'KHR': '៛', 'CAD': '$',
|
'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$',
|
'HRK': 'kn', 'CUP':'₱', 'CZK': 'Kč', 'DKK': 'kr', 'DOP': 'RD$',
|
||||||
'XCD': '$', 'EGP': '£', 'SVC': '$' , 'EEK': 'kr', 'EUR': '€',
|
'XCD': '$', 'EGP': '£', 'SVC': '$' , 'EEK': 'kr', 'EUR': '€',
|
||||||
'FKP': '£', 'FJD': '$', 'GHC': '¢', 'GIP': '£', 'GTQ': 'Q', 'GBP': '£',
|
'FKP': '£', 'FJD': '$', 'GHC': '¢', 'GIP': '£', 'GTQ': 'Q', 'GBP': '£',
|
||||||
'GYD': '$', 'HNL': 'L', 'HKD': '$', 'HUF': 'Ft', 'ISK': 'kr',
|
'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': '₩',
|
'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):
|
def __init__(self, parent):
|
||||||
|
super(Exchanger, self).__init__()
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.quote_currencies = None
|
self.quote_currencies = None
|
||||||
self.exchanges = ('BlockChain', 'Coinbase', 'CoinDesk')
|
self.exchanges = EXCHANGES
|
||||||
try:
|
|
||||||
self.use_exchange = parent.electrum_config.get('use_exchange',
|
|
||||||
'BlockChain')
|
|
||||||
except AttributeError:
|
|
||||||
self.use_exchange = 'BlockChain'
|
|
||||||
self.currencies = self.symbols.keys()
|
|
||||||
|
|
||||||
def exchange(self, btc_amount, quote_currency):
|
def exchange(self, btc_amount, quote_currency):
|
||||||
if self.quote_currencies is None:
|
if self.quote_currencies is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
quote_currencies = self.quote_currencies.copy()
|
quote_currencies = self.quote_currencies.copy()
|
||||||
if quote_currency not in quote_currencies:
|
if quote_currency not in quote_currencies:
|
||||||
return None
|
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])
|
return btc_amount * decimal.Decimal(quote_currencies[quote_currency])
|
||||||
|
|
||||||
def check_rates(self, dt):
|
def update_rate(self, dt):
|
||||||
if self.use_exchange == 'BlockChain':
|
''' This is called from :method:`start` every X seconds; to update the
|
||||||
self.check_blockchain()
|
rates for currencies for the currently selected exchange.
|
||||||
elif self.use_exchange == 'CoinDesk':
|
'''
|
||||||
self.check_coindesk()
|
update_rates = {
|
||||||
elif self.use_exchange == 'Coinbase':
|
"BitcoinAverage": self.update_ba,
|
||||||
self.check_coinbase()
|
"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):
|
def on_success(request, response):
|
||||||
return decimal.Decimal(str(response[str(quote_id)]["15m"]))
|
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):
|
def on_success(request, response):
|
||||||
quote_currencies = {}
|
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:
|
try:
|
||||||
for r in response:
|
quote_currencies["CAD"] = decimal.Decimal(cadprice)
|
||||||
quote_currencies[r] = _lookup_rate(response, r)
|
|
||||||
self.quote_currencies = quote_currencies
|
self.quote_currencies = quote_currencies
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
self.parent.set_currencies(quote_currencies)
|
self.parent.set_currencies(quote_currencies)
|
||||||
|
|
||||||
def on_failure(*args):
|
req = UrlRequest(url='https://www.cavirtex.com/api/CAD/ticker.json',
|
||||||
pass
|
|
||||||
|
|
||||||
def on_error(*args):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def on_redirect(*args):
|
|
||||||
pass
|
|
||||||
|
|
||||||
req = UrlRequest(
|
|
||||||
url='https://api.coindesk.com/v1/bpi/supported-currencies.json',
|
|
||||||
on_success=on_success,
|
on_success=on_success,
|
||||||
on_failure=on_failure,
|
|
||||||
on_error=on_error,
|
|
||||||
on_redirect=on_redirect,
|
|
||||||
timeout=5)
|
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):
|
def _lookup_rate(response, quote_id):
|
||||||
return decimal.Decimal(str(response[str(quote_id)]))
|
return decimal.Decimal(str(response[str(quote_id)]))
|
||||||
|
@ -121,24 +252,12 @@ class Exchanger(object):
|
||||||
pass
|
pass
|
||||||
self.parent.set_currencies(quote_currencies)
|
self.parent.set_currencies(quote_currencies)
|
||||||
|
|
||||||
def on_failure(*args):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def on_error(*args):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def on_redirect(*args):
|
|
||||||
pass
|
|
||||||
|
|
||||||
req = UrlRequest(
|
req = UrlRequest(
|
||||||
url='https://coinbase.com/api/v1/currencies/exchange_rates',
|
url='https://coinbase.com/api/v1/currencies/exchange_rates',
|
||||||
on_success=on_success,
|
on_success=on_success,
|
||||||
on_failure=on_failure,
|
|
||||||
on_error=on_error,
|
|
||||||
on_redirect=on_redirect,
|
|
||||||
timeout=5)
|
timeout=5)
|
||||||
|
|
||||||
def check_blockchain(self):
|
def update_bc(self):
|
||||||
|
|
||||||
def _lookup_rate(response, quote_id):
|
def _lookup_rate(response, quote_id):
|
||||||
return decimal.Decimal(str(response[str(quote_id)]["15m"]))
|
return decimal.Decimal(str(response[str(quote_id)]["15m"]))
|
||||||
|
@ -153,27 +272,69 @@ class Exchanger(object):
|
||||||
pass
|
pass
|
||||||
self.parent.set_currencies(quote_currencies)
|
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',
|
req = UrlRequest(url='https://blockchain.info/ticker',
|
||||||
on_success=on_success,
|
on_success=on_success,
|
||||||
on_failure=on_failure,
|
timeout=5)
|
||||||
on_error=on_error,
|
|
||||||
on_redirect=on_redirect,
|
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)
|
timeout=5)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
# check every 5 seconds
|
# check rates every few seconds
|
||||||
self.check_rates(0)
|
self.update_rate(0)
|
||||||
Clock.schedule_interval(self.check_rates, 5)
|
# check every few seconds
|
||||||
|
Clock.unschedule(self.update_rate)
|
||||||
|
Clock.schedule_interval(self.update_rate, 20)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
Clock.unschedule(self.check_rates)
|
Clock.unschedule(self.update_rate)
|
||||||
|
|
||||||
|
|
|
@ -142,6 +142,13 @@ def user_dir():
|
||||||
elif "LOCALAPPDATA" in os.environ:
|
elif "LOCALAPPDATA" in os.environ:
|
||||||
return os.path.join(os.environ["LOCALAPPDATA"], "Electrum")
|
return os.path.join(os.environ["LOCALAPPDATA"], "Electrum")
|
||||||
elif 'ANDROID_DATA' in os.environ:
|
elif 'ANDROID_DATA' in os.environ:
|
||||||
|
try:
|
||||||
|
import jnius
|
||||||
|
env = jnius.autoclass('android.os.Environment')
|
||||||
|
_dir = env.getExternalStorageDirectory().getPath()
|
||||||
|
return _dir + '/electrum/'
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
return "/sdcard/electrum/"
|
return "/sdcard/electrum/"
|
||||||
else:
|
else:
|
||||||
#raise Exception("No home directory found in environment variables.")
|
#raise Exception("No home directory found in environment variables.")
|
||||||
|
|
Loading…
Add table
Reference in a new issue