Browse Source

manage exchange plugins, make sure ui doesn't stall while saving seed

and numerous other small fixes.
283
qua-non 11 years ago
committed by ThomasV
parent
commit
1179a4cf9e
  1. 4
      gui/kivy/dialog.py
  2. 15
      gui/kivy/drawer.py
  3. 22
      gui/kivy/installwizard.py
  4. 3
      gui/kivy/main.kv
  5. 53
      gui/kivy/main_window.py
  6. 311
      gui/kivy/plugins/exchange_rate.py
  7. 7
      lib/util.py

4
gui/kivy/dialog.py

@ -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)

15
gui/kivy/drawer.py

@ -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

22
gui/kivy/installwizard.py

@ -45,10 +45,16 @@ class InstallWizard(Widget):
''' '''
def target(): def target():
# run your threaded function # run your threaded function
try:
task() 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)
except Exception as err:
app.show_error(str(err))
return
_dlg.close() _dlg.close()
self.load_network(wallet, mode='restore') self.load_network(wallet, mode='restore')
self.waiting_dialog(lambda: wallet.save_seed(new_password),
msg=_("saving seed"),
on_complete=on_complete)
return return
if not instance: if not instance:
# create # create

3
gui/kivy/main.kv

@ -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>

53
gui/kivy/main_window.py

@ -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")

311
gui/kivy/plugins/exchange_rate.py

@ -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': '', 'DKK': 'kr', 'DOP': 'RD$', 'HRK': 'kn', 'CUP':'', 'CZK': '', '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":
return btc_amount * decimal.Decimal(quote_currencies[quote_currency])
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: try:
connection = httplib.HTTPSConnection('api.coindesk.com') update_rates[self.use_exchange]()
connection.request("GET", "/v1/bpi/currentprice/" + str(quote_currency) + ".json") except KeyError:
except Exception:
return
resp = connection.getresponse()
if resp.reason == httplib.responses[httplib.NOT_FOUND]:
return return
def update_wd(self):
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: try:
resp_rate = json.loads(resp.read()) quote_currencies["USD"] = decimal.Decimal(usdprice)
except Exception: except KeyError:
return pass
return btc_amount * decimal.Decimal(str(resp_rate["bpi"][str(quote_currency)]["rate_float"]))
return btc_amount * decimal.Decimal(quote_currencies[quote_currency]) self.quote_currencies = quote_currencies
self.parent.set_currencies(quote_currencies)
def check_rates(self, dt): req = UrlRequest(
if self.use_exchange == 'BlockChain': url='https://winkdex.com/static/data/0_600_288.json',
self.check_blockchain() on_success=on_success,
elif self.use_exchange == 'CoinDesk': timeout=5)
self.check_coindesk()
elif self.use_exchange == 'Coinbase':
self.check_coinbase()
def check_coindesk(self): def update_cd_currency(self, currency):
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 = 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 on_success=on_success,
timeout=5)
def on_error(*args): 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 pass
self.parent.set_currencies(quote_currencies)
def on_redirect(*args): 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 pass
self.parent.set_currencies(quote_currencies)
req = UrlRequest( req = UrlRequest(url='https://bitpay.com/api/rates',
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_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): req = UrlRequest(url='https://blockchain.info/ticker',
on_success=on_success,
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 pass
self.parent.set_currencies(quote_currencies)
req = UrlRequest(
url='https://localbitcoins.com/bitcoinaverage/ticker-all-currencies/',
on_success=on_success,
timeout=5)
def on_error(*args): 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 pass
self.parent.set_currencies(quote_currencies)
req = UrlRequest(url='https://api.bitcoinaverage.com/ticker/global/all',
on_success=on_success,
timeout=5)
def on_redirect(*args): 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 pass
self.parent.set_currencies(quote_currencies)
req = UrlRequest(url='https://blockchain.info/ticker', req = UrlRequest(url='https://api.bitcoinvenezuela.com/',
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 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)

7
lib/util.py

@ -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…
Cancel
Save