You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

154 lines
5.0 KiB

from datetime import datetime
from decimal import Decimal
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject
from electrum.bitcoin import COIN
from electrum.exchange_rate import FxThread
from electrum.logging import get_logger
from electrum.simple_config import SimpleConfig
from .qetypes import QEAmount
from .util import QtEventListener, event_listener
class QEFX(QObject, QtEventListener):
_logger = get_logger(__name__)
quotesUpdated = pyqtSignal()
def __init__(self, fxthread: FxThread, config: SimpleConfig, parent=None):
super().__init__(parent)
self.fx = fxthread
self.config = config
self.register_callbacks()
self.destroyed.connect(lambda: self.on_destroy())
def on_destroy(self):
self.unregister_callbacks()
@event_listener
def on_event_on_quotes(self, *args):
self._logger.debug('new quotes')
self.quotesUpdated.emit()
historyUpdated = pyqtSignal()
@event_listener
def on_event_on_history(self, *args):
self._logger.debug('new history')
self.historyUpdated.emit()
currenciesChanged = pyqtSignal()
@pyqtProperty('QVariantList', notify=currenciesChanged)
def currencies(self):
return self.fx.get_currencies(self.historicRates)
rateSourcesChanged = pyqtSignal()
@pyqtProperty('QVariantList', notify=rateSourcesChanged)
def rateSources(self):
return self.fx.get_exchanges_by_ccy(self.fiatCurrency, self.historicRates)
fiatCurrencyChanged = pyqtSignal()
@pyqtProperty(str, notify=fiatCurrencyChanged)
def fiatCurrency(self):
return self.fx.get_currency()
@fiatCurrency.setter
def fiatCurrency(self, currency):
if currency != self.fiatCurrency:
self.fx.set_currency(currency)
self.enabled = self.enabled and currency != ''
self.fiatCurrencyChanged.emit()
self.rateSourcesChanged.emit()
historicRatesChanged = pyqtSignal()
@pyqtProperty(bool, notify=historicRatesChanged)
def historicRates(self):
return self.fx.config.get('history_rates', True)
@historicRates.setter
def historicRates(self, checked):
if checked != self.historicRates:
self.fx.config.set_key('history_rates', bool(checked))
self.historicRatesChanged.emit()
self.rateSourcesChanged.emit()
rateSourceChanged = pyqtSignal()
@pyqtProperty(str, notify=rateSourceChanged)
def rateSource(self):
return self.fx.config_exchange()
@rateSource.setter
def rateSource(self, source):
if source != self.rateSource:
self.fx.set_exchange(source)
self.rateSourceChanged.emit()
enabledUpdated = pyqtSignal() # curiously, enabledChanged is clashing, so name it enabledUpdated
@pyqtProperty(bool, notify=enabledUpdated)
def enabled(self):
return self.fx.is_enabled()
@enabled.setter
def enabled(self, enable):
if enable != self.enabled:
self.fx.set_enabled(enable)
self.enabledUpdated.emit()
@pyqtSlot(str, result=str)
@pyqtSlot(str, bool, result=str)
@pyqtSlot(QEAmount, result=str)
@pyqtSlot(QEAmount, bool, result=str)
def fiatValue(self, satoshis, plain=True):
rate = self.fx.exchange_rate()
if isinstance(satoshis, QEAmount):
satoshis = satoshis.msatsInt / 1000 if satoshis.msatsInt != 0 else satoshis.satsInt
else:
try:
sd = Decimal(satoshis)
except:
return ''
if plain:
return self.fx.ccy_amount_str(self.fx.fiat_value(satoshis, rate), add_thousands_sep=False)
else:
return self.fx.value_str(satoshis, rate)
@pyqtSlot(str, str, result=str)
@pyqtSlot(str, str, bool, result=str)
@pyqtSlot(QEAmount, str, result=str)
@pyqtSlot(QEAmount, str, bool, result=str)
def fiatValueHistoric(self, satoshis, timestamp, plain=True):
if isinstance(satoshis, QEAmount):
satoshis = satoshis.msatsInt / 1000 if satoshis.msatsInt != 0 else satoshis.satsInt
else:
try:
sd = Decimal(satoshis)
except:
return ''
try:
td = Decimal(timestamp)
if td == 0:
return ''
except:
return ''
dt = datetime.fromtimestamp(int(td))
if plain:
return self.fx.ccy_amount_str(self.fx.historical_value(satoshis, dt), add_thousands_sep=False)
else:
return self.fx.historical_value_str(satoshis, dt)
@pyqtSlot(str, result=str)
@pyqtSlot(str, bool, result=str)
def satoshiValue(self, fiat, plain=True):
rate = self.fx.exchange_rate()
try:
fd = Decimal(fiat)
except:
return ''
v = fd / Decimal(rate) * COIN
if v.is_nan():
return ''
if plain:
return str(v.to_integral_value())
else:
return self.config.format_amount(v)