def add_fiat_edit(self): self.fiat_e = AmountEdit(self.fiat_unit) self.btc_e = self.win.amount_e grid = self.btc_e.parent() def fiat_changed(): try: fiat_amount = Decimal(str(self.fiat_e.text())) except: self.btc_e.setText("") return exchange_rate = self.exchanger.exchange(Decimal("1.0"), self.fiat_unit()) if exchange_rate is not None: btc_amount = fiat_amount / exchange_rate self.btc_e.setAmount(int(btc_amount * Decimal(100000000))) self.fiat_e.textEdited.connect(fiat_changed) def btc_changed(): btc_amount = self.btc_e.get_amount() if btc_amount is None: self.fiat_e.setText("") return fiat_amount = self.exchanger.exchange( Decimal(btc_amount) / Decimal(100000000), self.fiat_unit()) if fiat_amount is not None: self.fiat_e.setText("%.2f" % fiat_amount) self.btc_e.textEdited.connect(btc_changed) self.btc_e.frozen.connect( lambda: self.fiat_e.setFrozen(self.btc_e.isReadOnly())) self.win.send_grid.addWidget(self.fiat_e, 4, 3, Qt.AlignHCenter)
def setup_google_auth(self, window, _id, otp_secret): uri = "otpauth://totp/%s?secret=%s"%('trustedcoin.com', otp_secret) vbox = QVBoxLayout() window.set_layout(vbox) vbox.addWidget(QLabel("Please scan this QR code in Google Authenticator.")) qrw = QRCodeWidget(uri) vbox.addWidget(qrw, 1) #vbox.addWidget(QLabel(data), 0, Qt.AlignHCenter) hbox = QHBoxLayout() msg = _('Then, enter your Google Authenticator code:') hbox.addWidget(QLabel(msg)) pw = AmountEdit(None, is_int = True) pw.setFocus(True) hbox.addWidget(pw) hbox.addStretch(1) vbox.addLayout(hbox) hbox, b = ok_cancel_buttons2(window, _('Next')) b.setEnabled(False) vbox.addLayout(hbox) pw.textChanged.connect(lambda: b.setEnabled(len(pw.text())==6)) window.exec_() otp = pw.get_amount() try: server.auth(_id, otp) except: self.window.show_message('Incorrect password, aborting') return return True
def on_new_window(self, window): # Additional send and receive edit boxes if not hasattr(window, 'fiat_send_e'): send_e = AmountEdit(self.get_currency) window.send_grid.addWidget(send_e, 4, 2, Qt.AlignLeft) window.amount_e.frozen.connect( lambda: send_e.setFrozen(window.amount_e.isReadOnly())) receive_e = AmountEdit(self.get_currency) window.receive_grid.addWidget(receive_e, 2, 2, Qt.AlignLeft) window.fiat_send_e = send_e window.fiat_receive_e = receive_e self.connect_fields(window, window.amount_e, send_e, window.fee_e) self.connect_fields(window, window.receive_amount_e, receive_e, None) else: window.fiat_send_e.show() window.fiat_receive_e.show() window.history_list.refresh_headers() window.update_status() window.connect(self, SIGNAL('new_fx_quotes'), lambda: self.on_fx_quotes(window)) window.connect(self, SIGNAL('new_fx_history'), lambda: self.on_fx_history(window)) window.connect(self, SIGNAL('close_fx_plugin'), lambda: self.restore_window(window)) window.connect(self, SIGNAL('refresh_headers'), window.history_list.refresh_headers)
def add_send_edit(self): fiat_e = AmountEdit(self.fiat_unit) btc_e = self.win.amount_e fee_e = self.win.fee_e self.connect_fields(btc_e, fiat_e, fee_e) self.win.send_grid.addWidget(fiat_e, 4, 3, Qt.AlignHCenter) btc_e.frozen.connect(lambda: fiat_e.setFrozen(btc_e.isReadOnly()))
def fiat_dialog(self): if not self.config.get('use_exchange_rate'): self.gui.main_window.show_message( _("To use this feature, first enable the exchange rate plugin." )) return if not self.gui.main_window.network.is_connected(): self.gui.main_window.show_message( _("To use this feature, you must have a network connection.")) return quote_currency = self.fiat_unit() d = QDialog(self.gui.main_window) d.setWindowTitle("Fiat") vbox = QVBoxLayout(d) text = "Amount to Send in " + quote_currency vbox.addWidget(QLabel(_(text) + ':')) grid = QGridLayout() fiat_e = AmountEdit(self.fiat_unit) grid.addWidget(fiat_e, 1, 0) r = {} self.get_fiat_price_text(r) quote = r.get(0) if quote: text = "1 BTC~%s" % quote grid.addWidget(QLabel(_(text)), 4, 0, 3, 0) else: self.gui.main_window.show_message( _("Exchange rate not available. Please check your network connection." )) return vbox.addLayout(grid) vbox.addLayout(ok_cancel_buttons(d)) if not d.exec_(): return fiat = str(fiat_e.text()) if str(fiat) == "" or str(fiat) == ".": fiat = "0" quote = quote[:-4] btcamount = Decimal(fiat) / Decimal(quote) if str(self.gui.main_window.base_unit()) == "mBTC": btcamount = btcamount * 1000 quote = "%.8f" % btcamount self.gui.main_window.amount_e.setText(quote)
def fiat_dialog(self): if not self.config.get('use_exchange_rate'): self.gui.main_window.show_message(_("To use this feature, first enable the exchange rate plugin.")) return if not self.gui.main_window.network.is_connected(): self.gui.main_window.show_message(_("To use this feature, you must have a network connection.")) return quote_currency = self.config.get("currency", "EUR") d = QDialog(self.gui.main_window) d.setWindowTitle("Fiat") vbox = QVBoxLayout(d) text = "Amount to Send in " + quote_currency vbox.addWidget(QLabel(_(text)+':')) grid = QGridLayout() fiat_e = AmountEdit(self.fiat_unit) grid.addWidget(fiat_e, 1, 0) r = {} self.set_quote_text(100000000, r) quote = r.get(0) if quote: text = " 1 BTC=%s"%quote grid.addWidget(QLabel(_(text)), 4, 0, 3, 0) vbox.addLayout(grid) vbox.addLayout(ok_cancel_buttons(d)) if not d.exec_(): return fiat = str(fiat_e.text()) if str(fiat) == "" or str(fiat) == ".": fiat = "0" r = {} self.set_quote_text(100000000, r) quote = r.get(0) if not quote: self.gui.main_window.show_message(_("Exchange rate not available. Please check your network connection.")) return else: quote = quote[:-4] btcamount = Decimal(fiat) / Decimal(quote) if str(self.gui.main_window.base_unit()) == "mBTC": btcamount = btcamount * 1000 quote = "%.8f"%btcamount self.gui.main_window.amount_e.setText( quote )
def on_new_window(self, window): # Additional send and receive edit boxes send_e = AmountEdit(self.config_ccy) window.send_grid.addWidget(send_e, 4, 2, Qt.AlignLeft) window.amount_e.frozen.connect(lambda: send_e.setFrozen(window.amount_e.isReadOnly())) receive_e = AmountEdit(self.config_ccy) window.receive_grid.addWidget(receive_e, 2, 2, Qt.AlignLeft) self.windows[window] = {"edits": (send_e, receive_e), "last_edited": {}} self.connect_fields(window, window.amount_e, send_e, window.fee_e) self.connect_fields(window, window.receive_amount_e, receive_e, None) window.history_list.refresh_headers() window.update_status()
def auth_dialog(self, window): d = WindowModalDialog(window, _("Authorization")) vbox = QVBoxLayout(d) pw = AmountEdit(None, is_int = True) msg = _('Please enter your Google Authenticator code') vbox.addWidget(QLabel(msg)) grid = QGridLayout() grid.setSpacing(8) grid.addWidget(QLabel(_('Code')), 1, 0) grid.addWidget(pw, 1, 1) vbox.addLayout(grid) vbox.addLayout(Buttons(CancelButton(d), OkButton(d))) if not d.exec_(): return return pw.get_amount()
def on_new_window(self, window): # Additional send and receive edit boxes send_e = AmountEdit(self.config_ccy) window.send_grid.addWidget(send_e, 4, 2, Qt.AlignLeft) window.amount_e.frozen.connect( lambda: send_e.setFrozen(window.amount_e.isReadOnly())) receive_e = AmountEdit(self.config_ccy) window.receive_grid.addWidget(receive_e, 2, 2, Qt.AlignLeft) self.windows[window] = {'edits': (send_e, receive_e), 'last_edited': {}} self.connect_fields(window, window.amount_e, send_e, window.fee_e) self.connect_fields(window, window.receive_amount_e, receive_e, None) window.history_list.refresh_headers() window.update_status()
def auth_dialog(self, window): d = WindowModalDialog(window, _("Authorization")) vbox = QVBoxLayout(d) pw = AmountEdit(None, is_int=True) msg = _('Please enter your Google Authenticator code') vbox.addWidget(QLabel(msg)) grid = QGridLayout() grid.setSpacing(8) grid.addWidget(QLabel(_('Code')), 1, 0) grid.addWidget(pw, 1, 1) vbox.addLayout(grid) vbox.addLayout(Buttons(CancelButton(d), OkButton(d))) if not d.exec_(): return return pw.get_amount()
def auth_dialog(self ): d = QDialog(self.window) d.setModal(1) vbox = QVBoxLayout(d) pw = AmountEdit(None, is_int = True) msg = _('Please enter your Google Authenticator code') vbox.addWidget(QLabel(msg)) grid = QGridLayout() grid.setSpacing(8) grid.addWidget(QLabel(_('Code')), 1, 0) grid.addWidget(pw, 1, 1) vbox.addLayout(grid) vbox.addLayout(ok_cancel_buttons(d)) if not d.exec_(): return return pw.get_amount()
def add_fiat_edit(self): self.fiat_e = AmountEdit(self.fiat_unit) self.btc_e = self.win.amount_e grid = self.btc_e.parent() def fiat_changed(): try: fiat_amount = Decimal(str(self.fiat_e.text())) except: self.btc_e.setText("") return exchange_rate = self.exchanger.exchange(Decimal("1.0"), self.fiat_unit()) if exchange_rate is not None: btc_amount = fiat_amount/exchange_rate self.btc_e.setAmount(int(btc_amount*Decimal(100000000))) self.fiat_e.textEdited.connect(fiat_changed) def btc_changed(): btc_amount = self.btc_e.get_amount() if btc_amount is None: self.fiat_e.setText("") return fiat_amount = self.exchanger.exchange(Decimal(btc_amount)/Decimal(100000000), self.fiat_unit()) if fiat_amount is not None: self.fiat_e.setText("%.2f"%fiat_amount) self.btc_e.textEdited.connect(btc_changed) self.btc_e.frozen.connect(lambda: self.fiat_e.setFrozen(self.btc_e.isReadOnly())) self.win.send_grid.addWidget(self.fiat_e, 4, 3, Qt.AlignHCenter)
def auth_dialog(self): d = QDialog(self.window) d.setModal(1) vbox = QVBoxLayout(d) pw = AmountEdit(None, is_int=True) msg = _('Please enter your Google Authenticator code') vbox.addWidget(QLabel(msg)) grid = QGridLayout() grid.setSpacing(8) grid.addWidget(QLabel(_('Code')), 1, 0) grid.addWidget(pw, 1, 1) vbox.addLayout(grid) vbox.addLayout(ok_cancel_buttons(d)) if not d.exec_(): return return pw.get_amount()
def on_new_window(self, window): # Additional send and receive edit boxes send_e = AmountEdit(self.get_currency) window.send_grid.addWidget(send_e, 4, 2, Qt.AlignLeft) window.amount_e.frozen.connect(lambda: send_e.setFrozen(window.amount_e.isReadOnly())) receive_e = AmountEdit(self.get_currency) window.receive_grid.addWidget(receive_e, 2, 2, Qt.AlignLeft) window.fiat_send_e = send_e window.fiat_receive_e = receive_e self.connect_fields(window, window.amount_e, send_e, window.fee_e) self.connect_fields(window, window.receive_amount_e, receive_e, None) window.history_list.refresh_headers() window.update_status() window.connect(window.app, SIGNAL("new_fx_quotes"), lambda: self.on_fx_quotes(window)) window.connect(window.app, SIGNAL("new_fx_history"), lambda: self.on_fx_history(window)) window.connect(window.app, SIGNAL("close_fx_plugin"), lambda: self.restore_window(window)) window.connect(window.app, SIGNAL("refresh_headers"), window.history_list.refresh_headers)
def auth_dialog(self, window): d = WindowModalDialog(window, _("Authorization")) vbox = QVBoxLayout(d) pw = AmountEdit(None, is_int = True) msg = _('Please enter your Google Authenticator code') vbox.addWidget(QLabel(msg)) grid = QGridLayout() grid.setSpacing(8) grid.addWidget(QLabel(_('Code')), 1, 0) grid.addWidget(pw, 1, 1) vbox.addLayout(grid) msg = _('If you have lost your second factor, you need to restore your wallet from seed in order to request a new code.') label = QLabel(msg) label.setWordWrap(1) vbox.addWidget(label) vbox.addLayout(Buttons(CancelButton(d), OkButton(d))) if not d.exec_(): return return pw.get_amount()
def setup_google_auth(self, window, _id, otp_secret): vbox = QVBoxLayout() if otp_secret is not None: uri = "otpauth://totp/%s?secret=%s" % ('trustedcoin.com', otp_secret) l = QLabel( "Please scan the following QR code in Google Authenticator. You may as well use the following key: %s" % otp_secret) l.setWordWrap(True) vbox.addWidget(l) qrw = QRCodeWidget(uri) vbox.addWidget(qrw, 1) msg = _('Then, enter your Google Authenticator code:') else: label = QLabel( "This wallet is already registered, but it was never authenticated. To finalize your registration, please enter your Google Authenticator Code. If you do not have this code, delete the wallet file and start a new registration" ) label.setWordWrap(1) vbox.addWidget(label) msg = _('Google Authenticator code:') hbox = QHBoxLayout() hbox.addWidget(WWLabel(msg)) pw = AmountEdit(None, is_int=True) pw.setFocus(True) pw.setMaximumWidth(50) hbox.addWidget(pw) vbox.addLayout(hbox) def set_enabled(): window.next_button.setEnabled(len(pw.text()) == 6) pw.textChanged.connect(set_enabled) while True: if not window.set_main_layout( vbox, next_enabled=False, raise_on_cancel=False): return False otp = pw.get_amount() try: server.auth(_id, otp) return True except: window.show_message(_('Incorrect password')) pw.setText('')
def setup_google_auth(self, window, _id, otp_secret): uri = "otpauth://totp/%s?secret=%s" % ('trustedcoin.com', otp_secret) vbox = QVBoxLayout() window.set_layout(vbox) vbox.addWidget( QLabel("Please scan this QR code in Google Authenticator.")) qrw = QRCodeWidget(uri) vbox.addWidget(qrw, 1) #vbox.addWidget(QLabel(data), 0, Qt.AlignHCenter) hbox = QHBoxLayout() msg = _('Then, enter your Google Authenticator code:') hbox.addWidget(QLabel(msg)) pw = AmountEdit(None, is_int=True) pw.setFocus(True) hbox.addWidget(pw) hbox.addStretch(1) vbox.addLayout(hbox) hbox, b = ok_cancel_buttons2(window, _('Next')) b.setEnabled(False) vbox.addLayout(hbox) pw.textChanged.connect(lambda: b.setEnabled(len(pw.text()) == 6)) window.exec_() otp = pw.get_amount() try: server.auth(_id, otp) except: self.window.show_message('Incorrect password, aborting') return return True
def setup_google_auth(self, window, _id, otp_secret): vbox = QVBoxLayout() window.set_layout(vbox) if otp_secret is not None: uri = "otpauth://totp/%s?secret=%s" % ('trustedcoin.com', otp_secret) vbox.addWidget( QLabel("Please scan this QR code in Google Authenticator.")) qrw = QRCodeWidget(uri) vbox.addWidget(qrw, 1) msg = _('Then, enter your Google Authenticator code:') else: label = QLabel( "This wallet is already registered, but it was never authenticated. To finalize your registration, please enter your Google Authenticator Code. If you do not have this code, delete the wallet file and start a new registration" ) label.setWordWrap(1) vbox.addWidget(label) msg = _('Google Authenticator code:') hbox = QHBoxLayout() hbox.addWidget(QLabel(msg)) pw = AmountEdit(None, is_int=True) pw.setFocus(True) hbox.addWidget(pw) hbox.addStretch(1) vbox.addLayout(hbox) b = OkButton(window, _('Next')) b.setEnabled(False) vbox.addLayout(Buttons(CancelButton(window), b)) pw.textChanged.connect(lambda: b.setEnabled(len(pw.text()) == 6)) while True: if not window.exec_(): return False otp = pw.get_amount() try: server.auth(_id, otp) return True except: QMessageBox.information(self.window, _('Message'), _('Incorrect password'), _('OK')) pw.setText('')
def request_otp_dialog(self, window, _id, otp_secret): vbox = QVBoxLayout() if otp_secret is not None: uri = "otpauth://totp/%s?secret=%s" % ('trustedcoin.com', otp_secret) l = QLabel( "Please scan the following QR code in Google Authenticator. You may as well use the following key: %s" % otp_secret) l.setWordWrap(True) vbox.addWidget(l) qrw = QRCodeWidget(uri) vbox.addWidget(qrw, 1) msg = _('Then, enter your Google Authenticator code:') else: label = QLabel( "This wallet is already registered with Trustedcoin. " "To finalize wallet creation, please enter your Google Authenticator Code. " ) label.setWordWrap(1) vbox.addWidget(label) msg = _('Google Authenticator code:') hbox = QHBoxLayout() hbox.addWidget(WWLabel(msg)) pw = AmountEdit(None, is_int=True) pw.setFocus(True) pw.setMaximumWidth(50) hbox.addWidget(pw) vbox.addLayout(hbox) cb_lost = QCheckBox(_("I have lost my Google Authenticator account")) cb_lost.setToolTip( _("Check this box to request a new secret. You will need to retype your seed." )) vbox.addWidget(cb_lost) cb_lost.setVisible(otp_secret is None) def set_enabled(): b = True if cb_lost.isChecked() else len(pw.text()) == 6 window.next_button.setEnabled(b) pw.textChanged.connect(set_enabled) cb_lost.toggled.connect(set_enabled) window.exec_layout(vbox, next_enabled=False, raise_on_cancel=False) return pw.get_amount(), cb_lost.isChecked()
def setup_google_auth(self, window, _id, otp_secret): vbox = QVBoxLayout() if otp_secret is not None: uri = "otpauth://totp/%s?secret=%s"%('trustedcoin.com', otp_secret) l = QLabel("Please scan the following QR code in Google Authenticator. You may as well use the following key: %s"%otp_secret) l.setWordWrap(True) vbox.addWidget(l) qrw = QRCodeWidget(uri) vbox.addWidget(qrw, 1) msg = _('Then, enter your Google Authenticator code:') else: label = QLabel("This wallet is already registered, but it was never authenticated. To finalize your registration, please enter your Google Authenticator Code. If you do not have this code, delete the wallet file and start a new registration") label.setWordWrap(1) vbox.addWidget(label) msg = _('Google Authenticator code:') hbox = QHBoxLayout() hbox.addWidget(WWLabel(msg)) pw = AmountEdit(None, is_int = True) pw.setFocus(True) pw.setMaximumWidth(50) hbox.addWidget(pw) vbox.addLayout(hbox) def set_enabled(): window.next_button.setEnabled(len(pw.text()) == 6) pw.textChanged.connect(set_enabled) while True: if not window.set_main_layout(vbox, next_enabled=False, raise_on_cancel=False): return False otp = pw.get_amount() try: server.auth(_id, otp) return True except: window.show_message(_('Incorrect password')) pw.setText('')
def setup_google_auth(self, window, _id, otp_secret): vbox = QVBoxLayout() window.set_layout(vbox) if otp_secret is not None: uri = "otpauth://totp/%s?secret=%s" % ("trustedcoin.com", otp_secret) vbox.addWidget(QLabel("Please scan this QR code in Google Authenticator.")) qrw = QRCodeWidget(uri) vbox.addWidget(qrw, 1) msg = _("Then, enter your Google Authenticator code:") else: label = QLabel( "This wallet is already registered, but it was never authenticated. To finalize your registration, please enter your Google Authenticator Code. If you do not have this code, delete the wallet file and start a new registration" ) label.setWordWrap(1) vbox.addWidget(label) msg = _("Google Authenticator code:") hbox = QHBoxLayout() hbox.addWidget(QLabel(msg)) pw = AmountEdit(None, is_int=True) pw.setFocus(True) hbox.addWidget(pw) hbox.addStretch(1) vbox.addLayout(hbox) b = OkButton(window, _("Next")) b.setEnabled(False) vbox.addLayout(Buttons(CancelButton(window), b)) pw.textChanged.connect(lambda: b.setEnabled(len(pw.text()) == 6)) while True: if not window.exec_(): return False otp = pw.get_amount() try: server.auth(_id, otp) return True except: QMessageBox.information(self.window, _("Message"), _("Incorrect password"), _("OK")) pw.setText("")
def request_otp_dialog(self, window, _id, otp_secret): vbox = QVBoxLayout() if otp_secret is not None: uri = "otpauth://totp/%s?secret=%s"%('trustedcoin.com', otp_secret) l = QLabel("Please scan the following QR code in Google Authenticator. You may as well use the following key: %s"%otp_secret) l.setWordWrap(True) vbox.addWidget(l) qrw = QRCodeWidget(uri) vbox.addWidget(qrw, 1) msg = _('Then, enter your Google Authenticator code:') else: label = QLabel( "This wallet is already registered with Trustedcoin. " "To finalize wallet creation, please enter your Google Authenticator Code. " ) label.setWordWrap(1) vbox.addWidget(label) msg = _('Google Authenticator code:') hbox = QHBoxLayout() hbox.addWidget(WWLabel(msg)) pw = AmountEdit(None, is_int = True) pw.setFocus(True) pw.setMaximumWidth(50) hbox.addWidget(pw) vbox.addLayout(hbox) cb_lost = QCheckBox(_("I have lost my Google Authenticator account")) cb_lost.setToolTip(_("Check this box to request a new secret. You will need to retype your seed.")) vbox.addWidget(cb_lost) cb_lost.setVisible(otp_secret is None) def set_enabled(): b = True if cb_lost.isChecked() else len(pw.text()) == 6 window.next_button.setEnabled(b) pw.textChanged.connect(set_enabled) cb_lost.toggled.connect(set_enabled) window.exec_layout(vbox, next_enabled=False, raise_on_cancel=False) return pw.get_amount(), cb_lost.isChecked()
class Plugin(BasePlugin): def fullname(self): return "Exchange rates" def description(self): return """exchange rates, retrieved from blockchain.info, CoinDesk, or Coinbase""" def __init__(self,a,b): BasePlugin.__init__(self,a,b) self.currencies = [self.fiat_unit()] self.exchanges = [self.config.get('use_exchange', "Blockchain")] self.exchanger = None @hook def init_qt(self, gui): self.gui = gui self.win = self.gui.main_window self.win.connect(self.win, SIGNAL("refresh_currencies()"), self.win.update_status) self.btc_rate = Decimal("0.0") if self.exchanger is None: # Do price discovery self.exchanger = Exchanger(self) self.exchanger.start() self.gui.exchanger = self.exchanger # self.add_fiat_edit() self.win.update_status() def close(self): self.exchanger.stop() self.exchanger = None self.win.tabs.removeTab(1) self.win.tabs.insertTab(1, self.win.create_send_tab(), _('Send')) self.win.update_status() def set_currencies(self, currency_options): self.currencies = sorted(currency_options) self.win.emit(SIGNAL("refresh_currencies()")) self.win.emit(SIGNAL("refresh_currencies_combo()")) @hook def get_fiat_balance_text(self, btc_balance, r): # return balance as: 1.23 USD r[0] = self.create_fiat_balance_text(Decimal(btc_balance) / 100000000) def get_fiat_price_text(self, r): # return BTC price as: 123.45 USD r[0] = self.create_fiat_balance_text(1) quote = r[0] if quote: r[0] = "%s"%quote @hook def get_fiat_status_text(self, btc_balance, r2): # return status as: (1.23 USD) 1 BTC~123.45 USD text = "" r = {} self.get_fiat_price_text(r) quote = r.get(0) if quote: price_text = "1 BTC~%s"%quote fiat_currency = quote[-3:] btc_price = self.btc_rate fiat_balance = Decimal(btc_price) * (Decimal(btc_balance)/100000000) balance_text = "(%.2f %s)" % (fiat_balance,fiat_currency) text = " " + balance_text + " " + price_text + " " r2[0] = text def create_fiat_balance_text(self, btc_balance): quote_currency = self.fiat_unit() self.exchanger.use_exchange = self.config.get("use_exchange", "Blockchain") cur_rate = self.exchanger.exchange(Decimal("1.0"), quote_currency) if cur_rate is None: quote_text = "" else: quote_balance = btc_balance * Decimal(cur_rate) self.btc_rate = cur_rate quote_text = "%.2f %s" % (quote_balance, quote_currency) return quote_text @hook def load_wallet(self, wallet): self.wallet = wallet tx_list = {} for item in self.wallet.get_tx_history(self.wallet.storage.get("current_account", None)): tx_hash, conf, is_mine, value, fee, balance, timestamp = item tx_list[tx_hash] = {'value': value, 'timestamp': timestamp, 'balance': balance} self.tx_list = tx_list def requires_settings(self): return True @hook def history_tab_update(self): if self.config.get('history_rates', 'unchecked') == "checked": cur_exchange = self.config.get('use_exchange', "Blockchain") try: tx_list = self.tx_list except Exception: return try: mintimestr = datetime.datetime.fromtimestamp(int(min(tx_list.items(), key=lambda x: x[1]['timestamp'])[1]['timestamp'])).strftime('%Y-%m-%d') except Exception: return maxtimestr = datetime.datetime.now().strftime('%Y-%m-%d') if cur_exchange == "CoinDesk": try: resp_hist = self.exchanger.get_json('api.coindesk.com', "/v1/bpi/historical/close.json?start=" + mintimestr + "&end=" + maxtimestr) except Exception: return elif cur_exchange == "Winkdex": try: resp_hist = self.exchanger.get_json('winkdex.com', "/api/v0/series?start_time=1342915200")['series'][0]['results'] except Exception: return elif cur_exchange == "BitcoinVenezuela": cur_currency = self.fiat_unit() if cur_currency == "VEF": try: resp_hist = self.exchanger.get_json('api.bitcoinvenezuela.com', "/historical/index.php?coin=BTC")['VEF_BTC'] except Exception: return elif cur_currency == "ARS": try: resp_hist = self.exchanger.get_json('api.bitcoinvenezuela.com', "/historical/index.php?coin=BTC")['ARS_BTC'] except Exception: return else: return self.gui.main_window.is_edit = True self.gui.main_window.history_list.setColumnCount(6) self.gui.main_window.history_list.setHeaderLabels( [ '', _('Date'), _('Description') , _('Amount'), _('Balance'), _('Fiat Amount')] ) root = self.gui.main_window.history_list.invisibleRootItem() childcount = root.childCount() for i in range(childcount): item = root.child(i) try: tx_info = tx_list[str(item.data(0, Qt.UserRole).toPyObject())] except Exception: newtx = self.wallet.get_tx_history() v = newtx[[x[0] for x in newtx].index(str(item.data(0, Qt.UserRole).toPyObject()))][3] tx_info = {'timestamp':int(time.time()), 'value': v } pass tx_time = int(tx_info['timestamp']) if cur_exchange == "CoinDesk": tx_time_str = datetime.datetime.fromtimestamp(tx_time).strftime('%Y-%m-%d') try: tx_USD_val = "%.2f %s" % (Decimal(str(tx_info['value'])) / 100000000 * Decimal(resp_hist['bpi'][tx_time_str]), "USD") except KeyError: tx_USD_val = "%.2f %s" % (self.btc_rate * Decimal(str(tx_info['value']))/100000000 , "USD") elif cur_exchange == "Winkdex": tx_time_str = datetime.datetime.fromtimestamp(tx_time).strftime('%Y-%m-%d') + "T16:00:00-04:00" try: tx_rate = resp_hist[[x['timestamp'] for x in resp_hist].index(tx_time_str)]['price'] tx_USD_val = "%.2f %s" % (Decimal(tx_info['value']) / 100000000 * Decimal(tx_rate)/Decimal("100.0"), "USD") except ValueError: tx_USD_val = "%.2f %s" % (self.btc_rate * Decimal(tx_info['value'])/100000000 , "USD") except KeyError: tx_USD_val = _("No data") elif cur_exchange == "BitcoinVenezuela": tx_time_str = datetime.datetime.fromtimestamp(tx_time).strftime('%Y-%m-%d') try: num = resp_hist[tx_time_str].replace(',','') tx_BTCVEN_val = "%.2f %s" % (Decimal(str(tx_info['value'])) / 100000000 * Decimal(num), cur_currency) except KeyError: tx_BTCVEN_val = _("No data") if cur_exchange in ["CoinDesk", "Winkdex"]: item.setText(5, tx_USD_val) elif cur_exchange == "BitcoinVenezuela": item.setText(5, tx_BTCVEN_val) if Decimal(str(tx_info['value'])) < 0: item.setForeground(5, QBrush(QColor("#BC1E1E"))) for i, width in enumerate(self.gui.main_window.column_widths['history']): self.gui.main_window.history_list.setColumnWidth(i, width) self.gui.main_window.history_list.setColumnWidth(4, 140) self.gui.main_window.history_list.setColumnWidth(5, 120) self.gui.main_window.is_edit = False def settings_widget(self, window): return EnterButton(_('Settings'), self.settings_dialog) def settings_dialog(self): d = QDialog() d.setWindowTitle("Settings") layout = QGridLayout(d) layout.addWidget(QLabel(_('Exchange rate API: ')), 0, 0) layout.addWidget(QLabel(_('Currency: ')), 1, 0) layout.addWidget(QLabel(_('History Rates: ')), 2, 0) combo = QComboBox() combo_ex = QComboBox() hist_checkbox = QCheckBox() hist_checkbox.setEnabled(False) hist_checkbox.setChecked(self.config.get('history_rates', 'unchecked') != 'unchecked') ok_button = QPushButton(_("OK")) def on_change(x): try: cur_request = str(self.currencies[x]) except Exception: return if cur_request != self.fiat_unit(): self.config.set_key('currency', cur_request, True) cur_exchange = self.config.get('use_exchange', "Blockchain") if (cur_exchange, cur_request) in EXCH_SUPPORT_HIST: hist_checkbox.setEnabled(True) else: disable_check() self.win.update_status() try: self.fiat_button except: pass else: self.fiat_button.setText(cur_request) def disable_check(): hist_checkbox.setChecked(False) hist_checkbox.setEnabled(False) def on_change_ex(x): cur_request = str(self.exchanges[x]) if cur_request != self.config.get('use_exchange', "Blockchain"): self.config.set_key('use_exchange', cur_request, True) self.currencies = [] combo.clear() self.exchanger.query_rates.set() cur_currency = self.fiat_unit() if (cur_request, cur_currency) in EXCH_SUPPORT_HIST: hist_checkbox.setEnabled(True) else: disable_check() set_currencies(combo) self.win.update_status() def on_change_hist(checked): if checked: self.config.set_key('history_rates', 'checked') self.history_tab_update() else: self.config.set_key('history_rates', 'unchecked') self.gui.main_window.history_list.setHeaderLabels( [ '', _('Date'), _('Description') , _('Amount'), _('Balance')] ) self.gui.main_window.history_list.setColumnCount(5) for i,width in enumerate(self.gui.main_window.column_widths['history']): self.gui.main_window.history_list.setColumnWidth(i, width) def set_hist_check(hist_checkbox): cur_exchange = self.config.get('use_exchange', "Blockchain") hist_checkbox.setEnabled(cur_exchange in ["CoinDesk", "Winkdex", "BitcoinVenezuela"]) def set_currencies(combo): try: combo.blockSignals(True) current_currency = self.fiat_unit() combo.clear() except Exception: return combo.addItems(self.currencies) try: index = self.currencies.index(current_currency) except Exception: index = 0 combo.blockSignals(False) combo.setCurrentIndex(index) def set_exchanges(combo_ex): try: combo_ex.clear() except Exception: return combo_ex.addItems(self.exchanges) try: index = self.exchanges.index(self.config.get('use_exchange', "Blockchain")) except Exception: index = 0 combo_ex.setCurrentIndex(index) def ok_clicked(): if self.config.get('use_exchange', "Blockchain") in ["CoinDesk", "itBit"]: self.exchanger.query_rates.set() d.accept(); set_exchanges(combo_ex) set_currencies(combo) set_hist_check(hist_checkbox) combo.currentIndexChanged.connect(on_change) combo_ex.currentIndexChanged.connect(on_change_ex) hist_checkbox.stateChanged.connect(on_change_hist) combo.connect(self.win, SIGNAL('refresh_currencies_combo()'), lambda: set_currencies(combo)) combo_ex.connect(d, SIGNAL('refresh_exchanges_combo()'), lambda: set_exchanges(combo_ex)) ok_button.clicked.connect(lambda: ok_clicked()) layout.addWidget(combo,1,1) layout.addWidget(combo_ex,0,1) layout.addWidget(hist_checkbox,2,1) layout.addWidget(ok_button,3,1) if d.exec_(): return True else: return False def fiat_unit(self): return self.config.get("currency", "EUR") def add_fiat_edit(self): self.fiat_e = AmountEdit(self.fiat_unit) self.btc_e = self.win.amount_e grid = self.btc_e.parent() def fiat_changed(): try: fiat_amount = Decimal(str(self.fiat_e.text())) except: self.btc_e.setText("") return exchange_rate = self.exchanger.exchange(Decimal("1.0"), self.fiat_unit()) if exchange_rate is not None: btc_amount = fiat_amount/exchange_rate self.btc_e.setAmount(int(btc_amount*Decimal(100000000))) self.fiat_e.textEdited.connect(fiat_changed) def btc_changed(): btc_amount = self.btc_e.get_amount() if btc_amount is None: self.fiat_e.setText("") return fiat_amount = self.exchanger.exchange(Decimal(btc_amount)/Decimal(100000000), self.fiat_unit()) if fiat_amount is not None: self.fiat_e.setText("%.2f"%fiat_amount) self.btc_e.textEdited.connect(btc_changed) self.btc_e.frozen.connect(lambda: self.fiat_e.setFrozen(self.btc_e.isReadOnly())) self.win.send_grid.addWidget(self.fiat_e, 4, 3, Qt.AlignHCenter)
def add_receive_edit(self): self.receive_fiat_e = AmountEdit(self.fiat_unit) btc_e = self.win.receive_amount_e self.connect_fields(btc_e, self.receive_fiat_e, None) self.win.receive_grid.addWidget(self.receive_fiat_e, 2, 3, Qt.AlignHCenter)
class Plugin(BasePlugin): def __init__(self, a, b): BasePlugin.__init__(self, a, b) self.currencies = [self.fiat_unit()] self.exchanges = [self.config.get("use_exchange", "Blockchain")] # Do price discovery self.exchanger = Exchanger(self) self.exchanger.start() self.win = None @hook def init_qt(self, gui): self.gui = gui self.win = self.gui.main_window self.win.connect(self.win, SIGNAL("refresh_currencies()"), self.win.update_status) self.btc_rate = Decimal("0.0") self.resp_hist = {} self.tx_list = {} self.gui.exchanger = self.exchanger # self.add_send_edit() self.add_receive_edit() self.win.update_status() def close(self): BasePlugin.close(self) self.exchanger.stop() self.exchanger = None self.gui.exchanger = None self.send_fiat_e.hide() self.receive_fiat_e.hide() self.win.update_status() def set_currencies(self, currency_options): self.currencies = sorted(currency_options) if self.win: self.win.emit(SIGNAL("refresh_currencies()")) self.win.emit(SIGNAL("refresh_currencies_combo()")) @hook def get_fiat_balance_text(self, btc_balance, r): # return balance as: 1.23 USD r[0] = self.create_fiat_balance_text(Decimal(btc_balance) / COIN) def get_fiat_price_text(self, r): # return BTC price as: 123.45 USD r[0] = self.create_fiat_balance_text(1) quote = r[0] if quote: r[0] = "%s" % quote @hook def get_fiat_status_text(self, btc_balance, r2): # return status as: (1.23 USD) 1 BTC~123.45 USD text = "" r = {} self.get_fiat_price_text(r) quote = r.get(0) if quote: price_text = "1 BTC~%s" % quote fiat_currency = quote[-3:] btc_price = self.btc_rate fiat_balance = Decimal(btc_price) * Decimal(btc_balance) / COIN balance_text = "(%.2f %s)" % (fiat_balance, fiat_currency) text = " " + balance_text + " " + price_text + " " r2[0] = text def create_fiat_balance_text(self, btc_balance): quote_currency = self.fiat_unit() self.exchanger.use_exchange = self.config.get("use_exchange", "Blockchain") cur_rate = self.exchanger.exchange(Decimal("1.0"), quote_currency) if cur_rate is None: quote_text = "" else: quote_balance = btc_balance * Decimal(cur_rate) self.btc_rate = cur_rate quote_text = "%.2f %s" % (quote_balance, quote_currency) return quote_text @hook def load_wallet(self, wallet, window): tx_list = {} for item in self.wallet.get_history(self.wallet.storage.get("current_account", None)): tx_hash, conf, value, timestamp, balance = item tx_list[tx_hash] = {"value": value, "timestamp": timestamp} self.tx_list = tx_list self.cur_exchange = self.config.get("use_exchange", "Blockchain") t = threading.Thread(target=self.request_history_rates, args=()) t.setDaemon(True) t.start() def requires_settings(self): return True def request_history_rates(self): if self.config.get("history_rates") != "checked": return if not self.tx_list: return try: mintimestr = datetime.datetime.fromtimestamp( int(min(self.tx_list.items(), key=lambda x: x[1]["timestamp"])[1]["timestamp"]) ).strftime("%Y-%m-%d") except Exception: return maxtimestr = datetime.datetime.now().strftime("%Y-%m-%d") if self.cur_exchange == "CoinDesk": try: self.resp_hist = self.exchanger.get_json( "api.coindesk.com", "/v1/bpi/historical/close.json?start=" + mintimestr + "&end=" + maxtimestr ) except Exception: return elif self.cur_exchange == "Winkdex": try: self.resp_hist = self.exchanger.get_json("winkdex.com", "/api/v0/series?start_time=1342915200")[ "series" ][0]["results"] except Exception: return elif self.cur_exchange == "BitcoinVenezuela": cur_currency = self.fiat_unit() if cur_currency == "VEF": try: self.resp_hist = self.exchanger.get_json( "api.bitcoinvenezuela.com", "/historical/index.php?coin=BTC" )["VEF_BTC"] except Exception: return elif cur_currency == "ARS": try: self.resp_hist = self.exchanger.get_json( "api.bitcoinvenezuela.com", "/historical/index.php?coin=BTC" )["ARS_BTC"] except Exception: return else: return self.win.need_update.set() @hook def history_tab_update(self): if self.config.get("history_rates") != "checked": return if not self.resp_hist: return if not self.wallet: return self.win.is_edit = True self.win.history_list.setColumnCount(6) self.win.history_list.setHeaderLabels( ["", _("Date"), _("Description"), _("Amount"), _("Balance"), _("Fiat Amount")] ) root = self.win.history_list.invisibleRootItem() childcount = root.childCount() for i in range(childcount): item = root.child(i) try: tx_info = self.tx_list[str(item.data(0, Qt.UserRole).toPyObject())] except Exception: newtx = self.wallet.get_history() v = newtx[[x[0] for x in newtx].index(str(item.data(0, Qt.UserRole).toPyObject()))][2] tx_info = {"timestamp": int(time.time()), "value": v} pass tx_time = int(tx_info["timestamp"]) tx_value = Decimal(str(tx_info["value"])) / COIN if self.cur_exchange == "CoinDesk": tx_time_str = datetime.datetime.fromtimestamp(tx_time).strftime("%Y-%m-%d") try: tx_fiat_val = "%.2f %s" % (tx_value * Decimal(self.resp_hist["bpi"][tx_time_str]), "USD") except KeyError: tx_fiat_val = "%.2f %s" % (self.btc_rate * Decimal(str(tx_info["value"])) / COIN, "USD") elif self.cur_exchange == "Winkdex": tx_time_str = datetime.datetime.fromtimestamp(tx_time).strftime("%Y-%m-%d") + "T16:00:00-04:00" try: tx_rate = self.resp_hist[[x["timestamp"] for x in self.resp_hist].index(tx_time_str)]["price"] tx_fiat_val = "%.2f %s" % (tx_value * Decimal(tx_rate) / Decimal("100.0"), "USD") except ValueError: tx_fiat_val = "%.2f %s" % (self.btc_rate * Decimal(tx_info["value"]) / COIN, "USD") except KeyError: tx_fiat_val = _("No data") elif self.cur_exchange == "BitcoinVenezuela": tx_time_str = datetime.datetime.fromtimestamp(tx_time).strftime("%Y-%m-%d") try: num = self.resp_hist[tx_time_str].replace(",", "") tx_fiat_val = "%.2f %s" % (tx_value * Decimal(num), self.fiat_unit()) except KeyError: tx_fiat_val = _("No data") tx_fiat_val = " " * (12 - len(tx_fiat_val)) + tx_fiat_val item.setText(5, tx_fiat_val) item.setFont(5, QFont(MONOSPACE_FONT)) if Decimal(str(tx_info["value"])) < 0: item.setForeground(5, QBrush(QColor("#BC1E1E"))) self.win.history_list.setColumnWidth(5, 120) self.win.is_edit = False def settings_widget(self, window): return EnterButton(_("Settings"), self.settings_dialog) def settings_dialog(self): d = QDialog() d.setWindowTitle("Settings") layout = QGridLayout(d) layout.addWidget(QLabel(_("Exchange rate API: ")), 0, 0) layout.addWidget(QLabel(_("Currency: ")), 1, 0) layout.addWidget(QLabel(_("History Rates: ")), 2, 0) combo = QComboBox() combo_ex = QComboBox() hist_checkbox = QCheckBox() hist_checkbox.setEnabled(False) hist_checkbox.setChecked(self.config.get("history_rates", "unchecked") != "unchecked") ok_button = QPushButton(_("OK")) def on_change(x): try: cur_request = str(self.currencies[x]) except Exception: return if cur_request != self.fiat_unit(): self.config.set_key("currency", cur_request, True) cur_exchange = self.config.get("use_exchange", "Blockchain") if (cur_exchange, cur_request) in EXCH_SUPPORT_HIST: hist_checkbox.setEnabled(True) else: disable_check() self.win.update_status() try: self.fiat_button except: pass else: self.fiat_button.setText(cur_request) def disable_check(): hist_checkbox.setChecked(False) hist_checkbox.setEnabled(False) def on_change_ex(x): cur_request = str(self.exchanges[x]) if cur_request != self.config.get("use_exchange", "Blockchain"): self.config.set_key("use_exchange", cur_request, True) self.currencies = [] combo.clear() self.exchanger.query_rates.set() cur_currency = self.fiat_unit() if (cur_request, cur_currency) in EXCH_SUPPORT_HIST: hist_checkbox.setEnabled(True) else: disable_check() set_currencies(combo) self.win.update_status() def on_change_hist(checked): if checked: self.config.set_key("history_rates", "checked") self.request_history_rates() else: self.config.set_key("history_rates", "unchecked") self.win.history_list.setHeaderLabels(["", _("Date"), _("Description"), _("Amount"), _("Balance")]) self.win.history_list.setColumnCount(5) def set_hist_check(hist_checkbox): cur_exchange = self.config.get("use_exchange", "Blockchain") hist_checkbox.setEnabled(cur_exchange in ["CoinDesk", "Winkdex", "BitcoinVenezuela"]) def set_currencies(combo): try: combo.blockSignals(True) current_currency = self.fiat_unit() combo.clear() except Exception: return combo.addItems(self.currencies) try: index = self.currencies.index(current_currency) except Exception: index = 0 combo.blockSignals(False) combo.setCurrentIndex(index) def set_exchanges(combo_ex): try: combo_ex.clear() except Exception: return combo_ex.addItems(self.exchanges) try: index = self.exchanges.index(self.config.get("use_exchange", "Blockchain")) except Exception: index = 0 combo_ex.setCurrentIndex(index) def ok_clicked(): if self.config.get("use_exchange", "Blockchain") in ["CoinDesk", "itBit"]: self.exchanger.query_rates.set() d.accept() set_exchanges(combo_ex) set_currencies(combo) set_hist_check(hist_checkbox) combo.currentIndexChanged.connect(on_change) combo_ex.currentIndexChanged.connect(on_change_ex) hist_checkbox.stateChanged.connect(on_change_hist) combo.connect(self.win, SIGNAL("refresh_currencies_combo()"), lambda: set_currencies(combo)) combo_ex.connect(d, SIGNAL("refresh_exchanges_combo()"), lambda: set_exchanges(combo_ex)) ok_button.clicked.connect(lambda: ok_clicked()) layout.addWidget(combo, 1, 1) layout.addWidget(combo_ex, 0, 1) layout.addWidget(hist_checkbox, 2, 1) layout.addWidget(ok_button, 3, 1) if d.exec_(): return True else: return False def fiat_unit(self): return self.config.get("currency", "EUR") def add_send_edit(self): self.send_fiat_e = AmountEdit(self.fiat_unit) btc_e = self.win.amount_e fee_e = self.win.fee_e self.connect_fields(btc_e, self.send_fiat_e, fee_e) self.win.send_grid.addWidget(self.send_fiat_e, 4, 3, Qt.AlignHCenter) btc_e.frozen.connect(lambda: self.send_fiat_e.setFrozen(btc_e.isReadOnly())) def add_receive_edit(self): self.receive_fiat_e = AmountEdit(self.fiat_unit) btc_e = self.win.receive_amount_e self.connect_fields(btc_e, self.receive_fiat_e, None) self.win.receive_grid.addWidget(self.receive_fiat_e, 2, 3, Qt.AlignHCenter) def connect_fields(self, btc_e, fiat_e, fee_e): def fiat_changed(): fiat_e.setStyleSheet(BLACK_FG) try: fiat_amount = Decimal(str(fiat_e.text())) except: btc_e.setText("") if fee_e: fee_e.setText("") return exchange_rate = self.exchanger.exchange(Decimal("1.0"), self.fiat_unit()) if exchange_rate is not None: btc_amount = fiat_amount / exchange_rate btc_e.setAmount(int(btc_amount * Decimal(COIN))) btc_e.setStyleSheet(BLUE_FG) if fee_e: self.win.update_fee() fiat_e.textEdited.connect(fiat_changed) def btc_changed(): btc_e.setStyleSheet(BLACK_FG) if self.exchanger is None: return btc_amount = btc_e.get_amount() if btc_amount is None: fiat_e.setText("") return fiat_amount = self.exchanger.exchange(Decimal(btc_amount) / Decimal(COIN), self.fiat_unit()) if fiat_amount is not None: pos = fiat_e.cursorPosition() fiat_e.setText("%.2f" % fiat_amount) fiat_e.setCursorPosition(pos) fiat_e.setStyleSheet(BLUE_FG) btc_e.textEdited.connect(btc_changed) @hook def do_clear(self): self.send_fiat_e.setText("")
class Plugin(BasePlugin): def fullname(self): return "Exchange rates" def description(self): return """exchange rates, retrieved from blockchain.info, CoinDesk, Coinbase, or other publishers""" def __init__(self, a, b): BasePlugin.__init__(self, a, b) self.currencies = [self.fiat_unit()] self.exchanges = [self.config.get('use_exchange', "Blockchain")] self.exchanger = None @hook def init_qt(self, gui): self.gui = gui self.win = self.gui.main_window self.win.connect(self.win, SIGNAL("refresh_currencies()"), self.win.update_status) self.btc_rate = Decimal("0.0") self.resp_hist = {} self.tx_list = {} if self.exchanger is None: # Do price discovery self.exchanger = Exchanger(self) self.exchanger.start() self.gui.exchanger = self.exchanger # self.add_fiat_edit() self.win.update_status() def close(self): self.exchanger.stop() self.exchanger = None self.win.update_status() def set_currencies(self, currency_options): self.currencies = sorted(currency_options) self.win.emit(SIGNAL("refresh_currencies()")) self.win.emit(SIGNAL("refresh_currencies_combo()")) @hook def get_fiat_balance_text(self, btc_balance, r): # return balance as: 1.23 USD r[0] = self.create_fiat_balance_text(Decimal(btc_balance) / 100000000) def get_fiat_price_text(self, r): # return BTC price as: 123.45 USD r[0] = self.create_fiat_balance_text(1) quote = r[0] if quote: r[0] = "%s" % quote @hook def get_fiat_status_text(self, btc_balance, r2): # return status as: (1.23 USD) 1 BTC~123.45 USD text = "" r = {} self.get_fiat_price_text(r) quote = r.get(0) if quote: price_text = "1 BTC~%s" % quote fiat_currency = quote[-3:] btc_price = self.btc_rate fiat_balance = Decimal(btc_price) * (Decimal(btc_balance) / 100000000) balance_text = "(%.2f %s)" % (fiat_balance, fiat_currency) text = " " + balance_text + " " + price_text + " " r2[0] = text def create_fiat_balance_text(self, btc_balance): quote_currency = self.fiat_unit() self.exchanger.use_exchange = self.config.get("use_exchange", "Blockchain") cur_rate = self.exchanger.exchange(Decimal("1.0"), quote_currency) if cur_rate is None: quote_text = "" else: quote_balance = btc_balance * Decimal(cur_rate) self.btc_rate = cur_rate quote_text = "%.2f %s" % (quote_balance, quote_currency) return quote_text @hook def load_wallet(self, wallet): self.wallet = wallet tx_list = {} for item in self.wallet.get_tx_history( self.wallet.storage.get("current_account", None)): tx_hash, conf, is_mine, value, fee, balance, timestamp = item tx_list[tx_hash] = { 'value': value, 'timestamp': timestamp, 'balance': balance } self.tx_list = tx_list self.cur_exchange = self.config.get('use_exchange', "Blockchain") threading.Thread(target=self.request_history_rates, args=()).start() def requires_settings(self): return True def request_history_rates(self): if self.config.get('history_rates') != "checked": return if not self.tx_list: return try: mintimestr = datetime.datetime.fromtimestamp( int( min(self.tx_list.items(), key=lambda x: x[1]['timestamp']) [1]['timestamp'])).strftime('%Y-%m-%d') except Exception: return maxtimestr = datetime.datetime.now().strftime('%Y-%m-%d') if self.cur_exchange == "CoinDesk": try: self.resp_hist = self.exchanger.get_json( 'api.coindesk.com', "/v1/bpi/historical/close.json?start=" + mintimestr + "&end=" + maxtimestr) except Exception: return elif self.cur_exchange == "Winkdex": try: self.resp_hist = self.exchanger.get_json( 'winkdex.com', "/api/v0/series?start_time=1342915200" )['series'][0]['results'] except Exception: return elif self.cur_exchange == "BitcoinVenezuela": cur_currency = self.fiat_unit() if cur_currency == "VEF": try: self.resp_hist = self.exchanger.get_json( 'api.bitcoinvenezuela.com', "/historical/index.php?coin=BTC")['VEF_BTC'] except Exception: return elif cur_currency == "ARS": try: self.resp_hist = self.exchanger.get_json( 'api.bitcoinvenezuela.com', "/historical/index.php?coin=BTC")['ARS_BTC'] except Exception: return else: return self.win.need_update.set() @hook def history_tab_update(self): if self.config.get('history_rates') != "checked": return if not self.resp_hist: return self.win.is_edit = True self.win.history_list.setColumnCount(6) self.win.history_list.setHeaderLabels([ '', _('Date'), _('Description'), _('Amount'), _('Balance'), _('Fiat Amount') ]) root = self.win.history_list.invisibleRootItem() childcount = root.childCount() for i in range(childcount): item = root.child(i) try: tx_info = self.tx_list[str( item.data(0, Qt.UserRole).toPyObject())] except Exception: newtx = self.wallet.get_tx_history() v = newtx[[x[0] for x in newtx].index( str(item.data(0, Qt.UserRole).toPyObject()))][3] tx_info = {'timestamp': int(time.time()), 'value': v} pass tx_time = int(tx_info['timestamp']) if self.cur_exchange == "CoinDesk": tx_time_str = datetime.datetime.fromtimestamp( tx_time).strftime('%Y-%m-%d') try: tx_fiat_val = "%.2f %s" % ( Decimal(str(tx_info['value'])) / 100000000 * Decimal(self.resp_hist['bpi'][tx_time_str]), "USD") except KeyError: tx_fiat_val = "%.2f %s" % (self.btc_rate * Decimal( str(tx_info['value'])) / 100000000, "USD") elif self.cur_exchange == "Winkdex": tx_time_str = datetime.datetime.fromtimestamp( tx_time).strftime('%Y-%m-%d') + "T16:00:00-04:00" try: tx_rate = self.resp_hist[[ x['timestamp'] for x in self.resp_hist ].index(tx_time_str)]['price'] tx_fiat_val = "%.2f %s" % (Decimal(tx_info['value']) / 100000000 * Decimal(tx_rate) / Decimal("100.0"), "USD") except ValueError: tx_fiat_val = "%.2f %s" % (self.btc_rate * Decimal( tx_info['value']) / 100000000, "USD") except KeyError: tx_fiat_val = _("No data") elif self.cur_exchange == "BitcoinVenezuela": tx_time_str = datetime.datetime.fromtimestamp( tx_time).strftime('%Y-%m-%d') try: num = self.resp_hist[tx_time_str].replace(',', '') tx_fiat_val = "%.2f %s" % (Decimal(str(tx_info['value'])) / 100000000 * Decimal(num), cur_currency) except KeyError: tx_fiat_val = _("No data") tx_fiat_val = " " * (12 - len(tx_fiat_val)) + tx_fiat_val item.setText(5, tx_fiat_val) item.setFont(5, QFont(MONOSPACE_FONT)) if Decimal(str(tx_info['value'])) < 0: item.setForeground(5, QBrush(QColor("#BC1E1E"))) for i, width in enumerate(self.win.column_widths['history']): self.win.history_list.setColumnWidth(i, width) self.win.history_list.setColumnWidth(4, 140) self.win.history_list.setColumnWidth(5, 120) self.win.is_edit = False def settings_widget(self, window): return EnterButton(_('Settings'), self.settings_dialog) def settings_dialog(self): d = QDialog() d.setWindowTitle("Settings") layout = QGridLayout(d) layout.addWidget(QLabel(_('Exchange rate API: ')), 0, 0) layout.addWidget(QLabel(_('Currency: ')), 1, 0) layout.addWidget(QLabel(_('History Rates: ')), 2, 0) combo = QComboBox() combo_ex = QComboBox() hist_checkbox = QCheckBox() hist_checkbox.setEnabled(False) hist_checkbox.setChecked( self.config.get('history_rates', 'unchecked') != 'unchecked') ok_button = QPushButton(_("OK")) def on_change(x): try: cur_request = str(self.currencies[x]) except Exception: return if cur_request != self.fiat_unit(): self.config.set_key('currency', cur_request, True) cur_exchange = self.config.get('use_exchange', "Blockchain") if (cur_exchange, cur_request) in EXCH_SUPPORT_HIST: hist_checkbox.setEnabled(True) else: disable_check() self.win.update_status() try: self.fiat_button except: pass else: self.fiat_button.setText(cur_request) def disable_check(): hist_checkbox.setChecked(False) hist_checkbox.setEnabled(False) def on_change_ex(x): cur_request = str(self.exchanges[x]) if cur_request != self.config.get('use_exchange', "Blockchain"): self.config.set_key('use_exchange', cur_request, True) self.currencies = [] combo.clear() self.exchanger.query_rates.set() cur_currency = self.fiat_unit() if (cur_request, cur_currency) in EXCH_SUPPORT_HIST: hist_checkbox.setEnabled(True) else: disable_check() set_currencies(combo) self.win.update_status() def on_change_hist(checked): if checked: self.config.set_key('history_rates', 'checked') self.request_history_rates() else: self.config.set_key('history_rates', 'unchecked') self.win.history_list.setHeaderLabels([ '', _('Date'), _('Description'), _('Amount'), _('Balance') ]) self.win.history_list.setColumnCount(5) for i, width in enumerate(self.win.column_widths['history']): self.win.history_list.setColumnWidth(i, width) def set_hist_check(hist_checkbox): cur_exchange = self.config.get('use_exchange', "Blockchain") hist_checkbox.setEnabled( cur_exchange in ["CoinDesk", "Winkdex", "BitcoinVenezuela"]) def set_currencies(combo): try: combo.blockSignals(True) current_currency = self.fiat_unit() combo.clear() except Exception: return combo.addItems(self.currencies) try: index = self.currencies.index(current_currency) except Exception: index = 0 combo.blockSignals(False) combo.setCurrentIndex(index) def set_exchanges(combo_ex): try: combo_ex.clear() except Exception: return combo_ex.addItems(self.exchanges) try: index = self.exchanges.index( self.config.get('use_exchange', "Blockchain")) except Exception: index = 0 combo_ex.setCurrentIndex(index) def ok_clicked(): if self.config.get('use_exchange', "Blockchain") in ["CoinDesk", "itBit"]: self.exchanger.query_rates.set() d.accept() set_exchanges(combo_ex) set_currencies(combo) set_hist_check(hist_checkbox) combo.currentIndexChanged.connect(on_change) combo_ex.currentIndexChanged.connect(on_change_ex) hist_checkbox.stateChanged.connect(on_change_hist) combo.connect(self.win, SIGNAL('refresh_currencies_combo()'), lambda: set_currencies(combo)) combo_ex.connect(d, SIGNAL('refresh_exchanges_combo()'), lambda: set_exchanges(combo_ex)) ok_button.clicked.connect(lambda: ok_clicked()) layout.addWidget(combo, 1, 1) layout.addWidget(combo_ex, 0, 1) layout.addWidget(hist_checkbox, 2, 1) layout.addWidget(ok_button, 3, 1) if d.exec_(): return True else: return False def fiat_unit(self): return self.config.get("currency", "EUR") def add_fiat_edit(self): self.fiat_e = AmountEdit(self.fiat_unit) self.btc_e = self.win.amount_e grid = self.btc_e.parent() def fiat_changed(): try: fiat_amount = Decimal(str(self.fiat_e.text())) except: self.btc_e.setText("") return exchange_rate = self.exchanger.exchange(Decimal("1.0"), self.fiat_unit()) if exchange_rate is not None: btc_amount = fiat_amount / exchange_rate self.btc_e.setAmount(int(btc_amount * Decimal(100000000))) self.btc_e.textEdited.emit("") self.fiat_e.textEdited.connect(fiat_changed) def btc_changed(): btc_amount = self.btc_e.get_amount() if btc_amount is None: self.fiat_e.setText("") return fiat_amount = self.exchanger.exchange( Decimal(btc_amount) / Decimal(100000000), self.fiat_unit()) if fiat_amount is not None: pos = self.fiat_e.cursorPosition() self.fiat_e.setText("%.2f" % fiat_amount) self.fiat_e.setCursorPosition(pos) self.btc_e.textEdited.connect(btc_changed) self.btc_e.frozen.connect( lambda: self.fiat_e.setFrozen(self.btc_e.isReadOnly())) self.win.send_grid.addWidget(self.fiat_e, 4, 3, Qt.AlignHCenter)