Added Bitcurex and Bitmarket exchanges
[electrum-nvc.git] / plugins / exchange_rate.py
1 from PyQt4.QtGui import *
2 from PyQt4.QtCore import *
3
4 import datetime
5 import decimal
6 import httplib
7 import json
8 import threading
9 import re
10 from decimal import Decimal
11 from electrum.plugins import BasePlugin
12 from electrum.i18n import _
13 from electrum_gui.qt.util import *
14 from electrum_gui.qt.amountedit import AmountEdit
15
16
17 EXCHANGES = ["BitcoinAverage",
18              "BitcoinVenezuela",
19              "Bitcurex",
20              "Bitmarket",
21              "BitPay",
22              "Blockchain",
23              "BTCChina",
24              "CaVirtEx",
25              "Coinbase",
26              "CoinDesk",
27              "LocalBitcoins",
28              "Winkdex"]
29
30
31 class Exchanger(threading.Thread):
32
33     def __init__(self, parent):
34         threading.Thread.__init__(self)
35         self.daemon = True
36         self.parent = parent
37         self.quote_currencies = None
38         self.lock = threading.Lock()
39         self.query_rates = threading.Event()
40         self.use_exchange = self.parent.config.get('use_exchange', "Blockchain")
41         self.parent.exchanges = EXCHANGES
42         self.parent.currencies = ["EUR","GBP","USD","PLN"]
43         self.parent.win.emit(SIGNAL("refresh_exchanges_combo()"))
44         self.parent.win.emit(SIGNAL("refresh_currencies_combo()"))
45         self.is_running = False
46
47     def get_json(self, site, get_string):
48         try:
49             connection = httplib.HTTPSConnection(site)
50             connection.request("GET", get_string)
51         except Exception:
52             raise
53         resp = connection.getresponse()
54         if resp.reason == httplib.responses[httplib.NOT_FOUND]:
55             raise
56         try:
57             json_resp = json.loads(resp.read())
58         except Exception:
59             raise
60         return json_resp
61
62
63     def exchange(self, btc_amount, quote_currency):
64         with self.lock:
65             if self.quote_currencies is None:
66                 return None
67             quote_currencies = self.quote_currencies.copy()
68         if quote_currency not in quote_currencies:
69             return None
70         if self.use_exchange == "CoinDesk":
71             try:
72                 resp_rate = self.get_json('api.coindesk.com', "/v1/bpi/currentprice/" + str(quote_currency) + ".json")
73             except Exception:
74                 return
75             return btc_amount * decimal.Decimal(str(resp_rate["bpi"][str(quote_currency)]["rate_float"]))
76         return btc_amount * decimal.Decimal(str(quote_currencies[quote_currency]))
77
78     def stop(self):
79         self.is_running = False
80
81     def update_rate(self):
82         self.use_exchange = self.parent.config.get('use_exchange', "Blockchain")
83         update_rates = {
84             "BitcoinAverage": self.update_ba,
85             "BitcoinVenezuela": self.update_bv,
86             "Bitcurex": self.update_bx,
87             "Bitmarket": self.update_bm,
88             "BitPay": self.update_bp,
89             "Blockchain": self.update_bc,
90             "BTCChina": self.update_CNY,
91             "CaVirtEx": self.update_cv,
92             "CoinDesk": self.update_cd,
93             "Coinbase": self.update_cb,
94             "LocalBitcoins": self.update_lb,
95             "Winkdex": self.update_wd,
96         }
97         try:
98             update_rates[self.use_exchange]()
99         except KeyError:
100             return
101
102     def run(self):
103         self.is_running = True
104         while self.is_running:
105             self.query_rates.clear()
106             self.update_rate()
107             self.query_rates.wait(150)
108
109
110     def update_cd(self):
111         try:
112             resp_currencies = self.get_json('api.coindesk.com', "/v1/bpi/supported-currencies.json")
113         except Exception:
114             return
115
116         quote_currencies = {}
117         for cur in resp_currencies:
118             quote_currencies[str(cur["currency"])] = 0.0
119         with self.lock:
120             self.quote_currencies = quote_currencies
121         self.parent.set_currencies(quote_currencies)
122
123     def update_wd(self):
124         try:
125             winkresp = self.get_json('winkdex.com', "/static/data/0_600_288.json")
126             ####could need nonce value in GET, no Docs available
127         except Exception:
128             return
129         quote_currencies = {"USD": 0.0}
130         ####get y of highest x in "prices"
131         lenprices = len(winkresp["prices"])
132         usdprice = winkresp["prices"][lenprices-1]["y"]
133         try:
134             quote_currencies["USD"] = decimal.Decimal(str(usdprice))
135             with self.lock:
136                 self.quote_currencies = quote_currencies
137         except KeyError:
138             pass
139         self.parent.set_currencies(quote_currencies)
140
141     def update_cv(self):
142         try:
143             jsonresp = self.get_json('www.cavirtex.com', "/api/CAD/ticker.json")
144         except Exception:
145             return
146         quote_currencies = {"CAD": 0.0}
147         cadprice = jsonresp["last"]
148         try:
149             quote_currencies["CAD"] = decimal.Decimal(str(cadprice))
150             with self.lock:
151                 self.quote_currencies = quote_currencies
152         except KeyError:
153             pass
154         self.parent.set_currencies(quote_currencies)
155
156     def update_bm(self):
157         try:
158             jsonresp = self.get_json('www.bitmarket.pl', "/json/BTCPLN/ticker.json")
159         except Exception:
160             return
161         quote_currencies = {"PLN": 0.0}
162         pln_price = jsonresp["last"]
163         try:
164             quote_currencies["PLN"] = decimal.Decimal(str(pln_price))
165             with self.lock:
166                 self.quote_currencies = quote_currencies
167         except KeyError:
168             pass
169         self.parent.set_currencies(quote_currencies)
170
171     def update_bx(self):
172         try:
173             jsonresp = self.get_json('pln.bitcurex.com', "/data/ticker.json")
174         except Exception:
175             return
176         quote_currencies = {"PLN": 0.0}
177         pln_price = jsonresp["last"]
178         try:
179             quote_currencies["PLN"] = decimal.Decimal(str(pln_price))
180             with self.lock:
181                 self.quote_currencies = quote_currencies
182         except KeyError:
183             pass
184         self.parent.set_currencies(quote_currencies)
185
186     def update_CNY(self):
187         try:
188             jsonresp = self.get_json('data.btcchina.com', "/data/ticker")
189         except Exception:
190             return
191         quote_currencies = {"CNY": 0.0}
192         cnyprice = jsonresp["ticker"]["last"]
193         try:
194             quote_currencies["CNY"] = decimal.Decimal(str(cnyprice))
195             with self.lock:
196                 self.quote_currencies = quote_currencies
197         except KeyError:
198             pass
199         self.parent.set_currencies(quote_currencies)
200
201     def update_bp(self):
202         try:
203             jsonresp = self.get_json('bitpay.com', "/api/rates")
204         except Exception:
205             return
206         quote_currencies = {}
207         try:
208             for r in jsonresp:
209                 quote_currencies[str(r["code"])] = decimal.Decimal(r["rate"])
210             with self.lock:
211                 self.quote_currencies = quote_currencies
212         except KeyError:
213             pass
214         self.parent.set_currencies(quote_currencies)
215
216     def update_cb(self):
217         try:
218             jsonresp = self.get_json('coinbase.com', "/api/v1/currencies/exchange_rates")
219         except Exception:
220             return
221
222         quote_currencies = {}
223         try:
224             for r in jsonresp:
225                 if r[:7] == "btc_to_":
226                     quote_currencies[r[7:].upper()] = self._lookup_rate_cb(jsonresp, r)
227             with self.lock:
228                 self.quote_currencies = quote_currencies
229         except KeyError:
230             pass
231         self.parent.set_currencies(quote_currencies)
232
233
234     def update_bc(self):
235         try:
236             jsonresp = self.get_json('blockchain.info', "/ticker")
237         except Exception:
238             return
239         quote_currencies = {}
240         try:
241             for r in jsonresp:
242                 quote_currencies[r] = self._lookup_rate(jsonresp, r)
243             with self.lock:
244                 self.quote_currencies = quote_currencies
245         except KeyError:
246             pass
247         self.parent.set_currencies(quote_currencies)
248         # print "updating exchange rate", self.quote_currencies["USD"]
249
250     def update_lb(self):
251         try:
252             jsonresp = self.get_json('localbitcoins.com', "/bitcoinaverage/ticker-all-currencies/")
253         except Exception:
254             return
255         quote_currencies = {}
256         try:
257             for r in jsonresp:
258                 quote_currencies[r] = self._lookup_rate_lb(jsonresp, r)
259             with self.lock:
260                 self.quote_currencies = quote_currencies
261         except KeyError:
262             pass
263         self.parent.set_currencies(quote_currencies)
264
265
266     def update_bv(self):
267         try:
268             jsonresp = self.get_json('api.bitcoinvenezuela.com', "/")
269         except Exception:
270             return
271         quote_currencies = {}
272         try:
273             for r in jsonresp["BTC"]:
274                 quote_currencies[r] = Decimal(jsonresp["BTC"][r])
275             with self.lock:
276                 self.quote_currencies = quote_currencies
277         except KeyError:
278             pass
279         self.parent.set_currencies(quote_currencies)
280
281
282     def update_ba(self):
283         try:
284             jsonresp = self.get_json('api.bitcoinaverage.com', "/ticker/global/all")
285         except Exception:
286             return
287         quote_currencies = {}
288         try:
289             for r in jsonresp:
290                 if not r == "timestamp":
291                     quote_currencies[r] = self._lookup_rate_ba(jsonresp, r)
292             with self.lock:
293                 self.quote_currencies = quote_currencies
294         except KeyError:
295             pass
296         self.parent.set_currencies(quote_currencies)
297
298
299     def get_currencies(self):
300         return [] if self.quote_currencies == None else sorted(self.quote_currencies.keys())
301
302     def _lookup_rate(self, response, quote_id):
303         return decimal.Decimal(str(response[str(quote_id)]["15m"]))
304     def _lookup_rate_cb(self, response, quote_id):
305         return decimal.Decimal(str(response[str(quote_id)]))
306     def _lookup_rate_ba(self, response, quote_id):
307         return decimal.Decimal(response[str(quote_id)]["last"])
308     def _lookup_rate_lb(self, response, quote_id):
309         return decimal.Decimal(response[str(quote_id)]["rates"]["last"])
310
311
312 class Plugin(BasePlugin):
313
314     def fullname(self):
315         return "Exchange rates"
316
317     def description(self):
318         return """exchange rates, retrieved from blockchain.info, CoinDesk, or Coinbase"""
319
320
321     def __init__(self,a,b):
322         BasePlugin.__init__(self,a,b)
323         self.currencies = [self.config.get('currency', "EUR")]
324         self.exchanges = [self.config.get('use_exchange', "Blockchain")]
325
326     def init(self):
327         self.win = self.gui.main_window
328         self.win.connect(self.win, SIGNAL("refresh_currencies()"), self.win.update_status)
329         self.btc_rate = Decimal("0.0")
330         # Do price discovery
331         self.exchanger = Exchanger(self)
332         self.exchanger.start()
333         self.gui.exchanger = self.exchanger #
334
335     def set_currencies(self, currency_options):
336         self.currencies = sorted(currency_options)
337         self.win.emit(SIGNAL("refresh_currencies()"))
338         self.win.emit(SIGNAL("refresh_currencies_combo()"))
339
340     def get_fiat_balance_text(self, btc_balance, r):
341         # return balance as: 1.23 USD
342         r[0] = self.create_fiat_balance_text(Decimal(btc_balance) / 100000000)
343
344     def get_fiat_price_text(self, r):
345         # return BTC price as: 123.45 USD
346         r[0] = self.create_fiat_balance_text(1)
347         quote = r[0]
348         if quote:
349             r[0] = "%s"%quote
350
351     def get_fiat_status_text(self, btc_balance, r2):
352         # return status as:   (1.23 USD)    1 BTC~123.45 USD
353         text = ""
354         r = {}
355         self.get_fiat_price_text(r)
356         quote = r.get(0)
357         if quote:
358             price_text = "1 BTC~%s"%quote
359             fiat_currency = quote[-3:]
360             btc_price = quote[:-4]
361             fiat_balance = Decimal(btc_price) * (Decimal(btc_balance)/100000000)
362             balance_text = "(%.2f %s)" % (fiat_balance,fiat_currency)
363             text = "  " + balance_text + "     " + price_text + " "
364         r2[0] = text
365
366     def create_fiat_balance_text(self, btc_balance):
367         quote_currency = self.config.get("currency", "EUR")
368         self.exchanger.use_exchange = self.config.get("use_exchange", "Blockchain")
369         cur_rate = self.exchanger.exchange(Decimal("1.0"), quote_currency)
370         if cur_rate is None:
371             quote_text = ""
372         else:
373             quote_balance = btc_balance * Decimal(cur_rate)
374             self.btc_rate = cur_rate
375             quote_text = "%.2f %s" % (quote_balance, quote_currency)
376         return quote_text
377
378     def load_wallet(self, wallet):
379         self.wallet = wallet
380         tx_list = {}
381         for item in self.wallet.get_tx_history(self.wallet.storage.get("current_account", None)):
382             tx_hash, conf, is_mine, value, fee, balance, timestamp = item
383             tx_list[tx_hash] = {'value': value, 'timestamp': timestamp, 'balance': balance}
384
385         self.tx_list = tx_list
386
387
388     def requires_settings(self):
389         return True
390
391
392     def toggle(self):
393         out = BasePlugin.toggle(self)
394         self.win.update_status()
395         if self.config.get('use_exchange_rate'):
396             try:
397                 self.fiat_button
398             except:
399                 self.gui.main_window.show_message(_("To see fiat amount when sending bitcoin, please restart Electrum to activate the new GUI settings."))
400         return out
401
402
403     def close(self):
404         self.exchanger.stop()
405
406     def history_tab_update(self):
407         if self.config.get('history_rates', 'unchecked') == "checked":
408             cur_exchange = self.config.get('use_exchange', "Blockchain")
409             try:
410                 tx_list = self.tx_list
411             except Exception:
412                 return
413
414             try:
415                 mintimestr = datetime.datetime.fromtimestamp(int(min(tx_list.items(), key=lambda x: x[1]['timestamp'])[1]['timestamp'])).strftime('%Y-%m-%d')
416             except Exception:
417                 return
418             maxtimestr = datetime.datetime.now().strftime('%Y-%m-%d')
419
420             if cur_exchange == "CoinDesk":
421                 try:
422                     resp_hist = self.exchanger.get_json('api.coindesk.com', "/v1/bpi/historical/close.json?start=" + mintimestr + "&end=" + maxtimestr)
423                 except Exception:
424                     return
425             elif cur_exchange == "Winkdex":
426                 try:
427                     resp_hist = self.exchanger.get_json('winkdex.com', "/static/data/0_86400_730.json")['prices']
428                 except Exception:
429                     return
430             elif cur_exchange == "BitcoinVenezuela":
431                 cur_currency = self.config.get('currency', "EUR")
432                 if cur_currency == "VEF":
433                     try:
434                         resp_hist = self.exchanger.get_json('api.bitcoinvenezuela.com', "/historical/index.php")['VEF_BTC']
435                     except Exception:
436                         return
437                 elif cur_currency == "ARS":
438                     try:
439                         resp_hist = self.exchanger.get_json('api.bitcoinvenezuela.com', "/historical/index.php")['ARS_BTC']
440                     except Exception:
441                         return
442                 else:
443                     return
444
445             self.gui.main_window.is_edit = True
446             self.gui.main_window.history_list.setColumnCount(6)
447             self.gui.main_window.history_list.setHeaderLabels( [ '', _('Date'), _('Description') , _('Amount'), _('Balance'), _('Fiat Amount')] )
448             root = self.gui.main_window.history_list.invisibleRootItem()
449             childcount = root.childCount()
450             for i in range(childcount):
451                 item = root.child(i)
452                 try:
453                     tx_info = tx_list[str(item.data(0, Qt.UserRole).toPyObject())]
454                 except Exception:
455                     newtx = self.wallet.get_tx_history()
456                     v = newtx[[x[0] for x in newtx].index(str(item.data(0, Qt.UserRole).toPyObject()))][3]
457
458                     tx_info = {'timestamp':int(datetime.datetime.now().strftime("%s")), 'value': v }
459                     pass
460                 tx_time = int(tx_info['timestamp'])
461                 if cur_exchange == "CoinDesk":
462                     tx_time_str = datetime.datetime.fromtimestamp(tx_time).strftime('%Y-%m-%d')
463                     try:
464                         tx_USD_val = "%.2f %s" % (Decimal(str(tx_info['value'])) / 100000000 * Decimal(resp_hist['bpi'][tx_time_str]), "USD")
465                     except KeyError:
466                         tx_USD_val = "%.2f %s" % (self.btc_rate * Decimal(str(tx_info['value']))/100000000 , "USD")
467                 elif cur_exchange == "Winkdex":
468                     tx_time_str = int(tx_time) - (int(tx_time) % (60 * 60 * 24))
469                     try:
470                         tx_rate = resp_hist[[x['x'] for x in resp_hist].index(tx_time_str)]['y']
471                         tx_USD_val = "%.2f %s" % (Decimal(tx_info['value']) / 100000000 * Decimal(tx_rate), "USD")
472                     except ValueError:
473                         tx_USD_val = "%.2f %s" % (self.btc_rate * Decimal(tx_info['value'])/100000000 , "USD")
474                 elif cur_exchange == "BitcoinVenezuela":
475                     tx_time_str = datetime.datetime.fromtimestamp(tx_time).strftime('%Y-%m-%d')
476                     try:
477                         num = resp_hist[tx_time_str].replace(',','')
478                         tx_BTCVEN_val = "%.2f %s" % (Decimal(str(tx_info['value'])) / 100000000 * Decimal(num), cur_currency)
479                     except KeyError:
480                         tx_BTCVEN_val = _("No data")
481
482                 if cur_exchange == "CoinDesk" or cur_exchange == "Winkdex":
483                     item.setText(5, tx_USD_val)
484                 elif cur_exchange == "BitcoinVenezuela":
485                     item.setText(5, tx_BTCVEN_val)
486                 if Decimal(str(tx_info['value'])) < 0:
487                     item.setForeground(5, QBrush(QColor("#BC1E1E")))
488
489             for i, width in enumerate(self.gui.main_window.column_widths['history']):
490                 self.gui.main_window.history_list.setColumnWidth(i, width)
491             self.gui.main_window.history_list.setColumnWidth(4, 140)
492             self.gui.main_window.history_list.setColumnWidth(5, 120)
493             self.gui.main_window.is_edit = False
494
495
496     def settings_widget(self, window):
497         return EnterButton(_('Settings'), self.settings_dialog)
498
499     def settings_dialog(self):
500         d = QDialog()
501         d.setWindowTitle("Settings")
502         layout = QGridLayout(d)
503         layout.addWidget(QLabel(_('Exchange rate API: ')), 0, 0)
504         layout.addWidget(QLabel(_('Currency: ')), 1, 0)
505         layout.addWidget(QLabel(_('History Rates: ')), 2, 0)
506         combo = QComboBox()
507         combo_ex = QComboBox()
508         hist_checkbox = QCheckBox()
509         hist_checkbox.setEnabled(False)
510         if self.config.get('history_rates', 'unchecked') == 'unchecked':
511             hist_checkbox.setChecked(False)
512         else:
513             hist_checkbox.setChecked(True)
514         ok_button = QPushButton(_("OK"))
515
516         def on_change(x):
517             try:
518                 cur_request = str(self.currencies[x])
519             except Exception:
520                 return
521             if cur_request != self.config.get('currency', "EUR"):
522                 self.config.set_key('currency', cur_request, True)
523                 cur_exchange = self.config.get('use_exchange', "Blockchain")
524                 if cur_request == "USD" and (cur_exchange == "CoinDesk" or cur_exchange == "Winkdex"):
525                     hist_checkbox.setEnabled(True)
526                 elif cur_request == "VEF" and (cur_exchange == "BitcoinVenezuela"):
527                     hist_checkbox.setEnabled(True)
528                 elif cur_request == "ARS" and (cur_exchange == "BitcoinVenezuela"):
529                     hist_checkbox.setEnabled(True)
530                 else:
531                     hist_checkbox.setChecked(False)
532                     hist_checkbox.setEnabled(False)
533                 self.win.update_status()
534                 try:
535                     self.fiat_button
536                 except:
537                     pass
538                 else:
539                     self.fiat_button.setText(cur_request)
540
541         def disable_check():
542             hist_checkbox.setChecked(False)
543             hist_checkbox.setEnabled(False)
544
545         def on_change_ex(x):
546             cur_request = str(self.exchanges[x])
547             if cur_request != self.config.get('use_exchange', "Blockchain"):
548                 self.config.set_key('use_exchange', cur_request, True)
549                 self.currencies = []
550                 combo.clear()
551                 self.exchanger.query_rates.set()
552                 cur_currency = self.config.get('currency', "EUR")
553                 if cur_request == "CoinDesk" or cur_request == "Winkdex":
554                     if cur_currency == "USD":
555                         hist_checkbox.setEnabled(True)
556                     else:
557                         disable_check()
558                 elif cur_request == "BitcoinVenezuela":
559                     if cur_currency == "VEF" or cur_currency == "ARS":
560                         hist_checkbox.setEnabled(True)
561                     else:
562                         disable_check()
563                 else:
564                     disable_check()
565                 set_currencies(combo)
566                 self.win.update_status()
567
568         def on_change_hist(checked):
569             if checked:
570                 self.config.set_key('history_rates', 'checked')
571                 self.history_tab_update()
572             else:
573                 self.config.set_key('history_rates', 'unchecked')
574                 self.gui.main_window.history_list.setHeaderLabels( [ '', _('Date'), _('Description') , _('Amount'), _('Balance')] )
575                 self.gui.main_window.history_list.setColumnCount(5)
576                 for i,width in enumerate(self.gui.main_window.column_widths['history']):
577                     self.gui.main_window.history_list.setColumnWidth(i, width)
578
579         def set_hist_check(hist_checkbox):
580             cur_exchange = self.config.get('use_exchange', "Blockchain")
581             if cur_exchange == "CoinDesk" or cur_exchange == "Winkdex":
582                 hist_checkbox.setEnabled(True)
583             elif cur_exchange == "BitcoinVenezuela":
584                 hist_checkbox.setEnabled(True)
585             else:
586                 hist_checkbox.setEnabled(False)
587
588         def set_currencies(combo):
589             current_currency = self.config.get('currency', "EUR")
590             try:
591                 combo.clear()
592             except Exception:
593                 return
594             combo.addItems(self.currencies)
595             try:
596                 index = self.currencies.index(current_currency)
597             except Exception:
598                 index = 0
599             combo.setCurrentIndex(index)
600
601         def set_exchanges(combo_ex):
602             try:
603                 combo_ex.clear()
604             except Exception:
605                 return
606             combo_ex.addItems(self.exchanges)
607             try:
608                 index = self.exchanges.index(self.config.get('use_exchange', "Blockchain"))
609             except Exception:
610                 index = 0
611             combo_ex.setCurrentIndex(index)
612
613         def ok_clicked():
614             d.accept();
615
616         set_exchanges(combo_ex)
617         set_currencies(combo)
618         set_hist_check(hist_checkbox)
619         combo.currentIndexChanged.connect(on_change)
620         combo_ex.currentIndexChanged.connect(on_change_ex)
621         hist_checkbox.stateChanged.connect(on_change_hist)
622         combo.connect(self.win, SIGNAL('refresh_currencies_combo()'), lambda: set_currencies(combo))
623         combo_ex.connect(d, SIGNAL('refresh_exchanges_combo()'), lambda: set_exchanges(combo_ex))
624         ok_button.clicked.connect(lambda: ok_clicked())
625         layout.addWidget(combo,1,1)
626         layout.addWidget(combo_ex,0,1)
627         layout.addWidget(hist_checkbox,2,1)
628         layout.addWidget(ok_button,3,1)
629
630         if d.exec_():
631             return True
632         else:
633             return False
634
635     def fiat_unit(self):
636         quote_currency = self.config.get("currency", "???")
637         return quote_currency
638
639     def fiat_dialog(self):
640         if not self.config.get('use_exchange_rate'):
641           self.gui.main_window.show_message(_("To use this feature, first enable the exchange rate plugin."))
642           return
643
644         if not self.gui.main_window.network.is_connected():
645           self.gui.main_window.show_message(_("To use this feature, you must have a network connection."))
646           return
647
648         quote_currency = self.fiat_unit()
649
650         d = QDialog(self.gui.main_window)
651         d.setWindowTitle("Fiat")
652         vbox = QVBoxLayout(d)
653         text = "Amount to Send in " + quote_currency
654         vbox.addWidget(QLabel(_(text)+':'))
655
656         grid = QGridLayout()
657         fiat_e = AmountEdit(self.fiat_unit)
658         grid.addWidget(fiat_e, 1, 0)
659
660         r = {}
661         self.get_fiat_price_text(r)
662         quote = r.get(0)
663         if quote:
664           text = "1 BTC~%s"%quote
665           grid.addWidget(QLabel(_(text)), 4, 0, 3, 0)
666         else:
667             self.gui.main_window.show_message(_("Exchange rate not available.  Please check your network connection."))
668             return
669
670         vbox.addLayout(grid)
671         vbox.addLayout(ok_cancel_buttons(d))
672
673         if not d.exec_():
674             return
675
676         fiat = str(fiat_e.text())
677
678         if str(fiat) == "" or str(fiat) == ".":
679             fiat = "0"
680
681         quote = quote[:-4]
682         btcamount = Decimal(fiat) / Decimal(quote)
683         if str(self.gui.main_window.base_unit()) == "mBTC":
684             btcamount = btcamount * 1000
685         quote = "%.8f"%btcamount
686         self.gui.main_window.amount_e.setText( quote )
687
688     def exchange_rate_button(self, grid):
689         quote_currency = self.config.get("currency", "EUR")
690         self.fiat_button = EnterButton(_(quote_currency), self.fiat_dialog)
691         grid.addWidget(self.fiat_button, 4, 3, Qt.AlignHCenter)