import/export functions
This commit is contained in:
parent
2570bf5c1f
commit
42dbf61ba8
|
@ -86,6 +86,49 @@ def load_theme_paths():
|
||||||
return theme_paths
|
return theme_paths
|
||||||
|
|
||||||
|
|
||||||
|
def csv_transaction(wallet):
|
||||||
|
try:
|
||||||
|
fileName = QFileDialog.getSaveFileName(QWidget(), 'Select file to export your wallet transactions to', os.path.expanduser('~/'), "*.csv")
|
||||||
|
if fileName:
|
||||||
|
with open(fileName, "w+") as csvfile:
|
||||||
|
transaction = csv.writer(csvfile)
|
||||||
|
transaction.writerow(["transaction_hash","label", "confirmations", "value", "fee", "balance", "timestamp"])
|
||||||
|
for item in wallet.get_tx_history():
|
||||||
|
tx_hash, confirmations, is_mine, value, fee, balance, timestamp = item
|
||||||
|
if confirmations:
|
||||||
|
if timestamp is not None:
|
||||||
|
try:
|
||||||
|
time_string = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3]
|
||||||
|
except [RuntimeError, TypeError, NameError] as reason:
|
||||||
|
time_string = "unknown"
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
time_string = "unknown"
|
||||||
|
else:
|
||||||
|
time_string = "pending"
|
||||||
|
|
||||||
|
if value is not None:
|
||||||
|
value_string = format_satoshis(value, True, wallet.num_zeros)
|
||||||
|
else:
|
||||||
|
value_string = '--'
|
||||||
|
|
||||||
|
if fee is not None:
|
||||||
|
fee_string = format_satoshis(fee, True, wallet.num_zeros)
|
||||||
|
else:
|
||||||
|
fee_string = '0'
|
||||||
|
|
||||||
|
if tx_hash:
|
||||||
|
label, is_default_label = wallet.get_label(tx_hash)
|
||||||
|
else:
|
||||||
|
label = ""
|
||||||
|
|
||||||
|
balance_string = format_satoshis(balance, False, wallet.num_zeros)
|
||||||
|
transaction.writerow([tx_hash, label, confirmations, value_string, fee_string, balance_string, time_string])
|
||||||
|
QMessageBox.information(None,"CSV Export created", "Your CSV export has been succesfully created.")
|
||||||
|
except (IOError, os.error), reason:
|
||||||
|
QMessageBox.critical(None,"Unable to create csv", "Electrum was unable to produce a transaction export.\n" + str(reason))
|
||||||
|
|
||||||
|
|
||||||
class ElectrumGui(QObject):
|
class ElectrumGui(QObject):
|
||||||
|
|
||||||
def __init__(self, wallet, config):
|
def __init__(self, wallet, config):
|
||||||
|
@ -318,7 +361,7 @@ class MiniWindow(QDialog):
|
||||||
backup_wallet.triggered.connect(self.backup_wallet)
|
backup_wallet.triggered.connect(self.backup_wallet)
|
||||||
|
|
||||||
export_csv = extra_menu.addAction( _("&Export transactions to CSV") )
|
export_csv = extra_menu.addAction( _("&Export transactions to CSV") )
|
||||||
export_csv.triggered.connect(self.actuator.csv_transaction)
|
export_csv.triggered.connect(lambda: csv_transaction(self.wallet))
|
||||||
|
|
||||||
master_key = extra_menu.addAction( _("Copy master public key to clipboard") )
|
master_key = extra_menu.addAction( _("Copy master public key to clipboard") )
|
||||||
master_key.triggered.connect(self.actuator.copy_master_public_key)
|
master_key.triggered.connect(self.actuator.copy_master_public_key)
|
||||||
|
@ -769,47 +812,6 @@ class MiniActuator:
|
||||||
w.exec_()
|
w.exec_()
|
||||||
w.destroy()
|
w.destroy()
|
||||||
|
|
||||||
def csv_transaction(self):
|
|
||||||
try:
|
|
||||||
fileName = QFileDialog.getSaveFileName(QWidget(), 'Select file to export your wallet transactions to', os.path.expanduser('~/'), "*.csv")
|
|
||||||
if fileName:
|
|
||||||
with open(fileName, "w+") as csvfile:
|
|
||||||
transaction = csv.writer(csvfile)
|
|
||||||
transaction.writerow(["transaction_hash","label", "confirmations", "value", "fee", "balance", "timestamp"])
|
|
||||||
for item in self.wallet.get_tx_history():
|
|
||||||
tx_hash, confirmations, is_mine, value, fee, balance, timestamp = item
|
|
||||||
if confirmations:
|
|
||||||
if timestamp is not None:
|
|
||||||
try:
|
|
||||||
time_string = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3]
|
|
||||||
except [RuntimeError, TypeError, NameError] as reason:
|
|
||||||
time_string = "unknown"
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
time_string = "unknown"
|
|
||||||
else:
|
|
||||||
time_string = "pending"
|
|
||||||
|
|
||||||
if value is not None:
|
|
||||||
value_string = format_satoshis(value, True, self.wallet.num_zeros)
|
|
||||||
else:
|
|
||||||
value_string = '--'
|
|
||||||
|
|
||||||
if fee is not None:
|
|
||||||
fee_string = format_satoshis(fee, True, self.wallet.num_zeros)
|
|
||||||
else:
|
|
||||||
fee_string = '0'
|
|
||||||
|
|
||||||
if tx_hash:
|
|
||||||
label, is_default_label = self.wallet.get_label(tx_hash)
|
|
||||||
else:
|
|
||||||
label = ""
|
|
||||||
|
|
||||||
balance_string = format_satoshis(balance, False, self.wallet.num_zeros)
|
|
||||||
transaction.writerow([tx_hash, label, confirmations, value_string, fee_string, balance_string, time_string])
|
|
||||||
QMessageBox.information(None,"CSV Export created", "Your CSV export has been succesfully created.")
|
|
||||||
except (IOError, os.error), reason:
|
|
||||||
QMessageBox.critical(None,"Unable to create csv", "Electrum was unable to produce a transaction export.\n" + str(reason))
|
|
||||||
|
|
||||||
def send(self, address, amount, parent_window):
|
def send(self, address, amount, parent_window):
|
||||||
"""Send bitcoins to the target address."""
|
"""Send bitcoins to the target address."""
|
||||||
|
|
142
lib/gui_qt.py
142
lib/gui_qt.py
|
@ -19,6 +19,7 @@
|
||||||
import sys, time, datetime, re
|
import sys, time, datetime, re
|
||||||
from i18n import _
|
from i18n import _
|
||||||
from util import print_error
|
from util import print_error
|
||||||
|
import os.path, json, util
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import PyQt4
|
import PyQt4
|
||||||
|
@ -1503,6 +1504,34 @@ class ElectrumWindow(QMainWindow):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def do_import_labels(self):
|
||||||
|
labelsFile = QFileDialog.getOpenFileName(QWidget(), "Open text file", util.user_dir(), self.tr("Text Files (labels.dat)"))
|
||||||
|
if not labelsFile: return
|
||||||
|
try:
|
||||||
|
f = open(labelsFile, 'r')
|
||||||
|
data = f.read()
|
||||||
|
f.close()
|
||||||
|
self.wallet.labels = json.loads(data)
|
||||||
|
self.wallet.save()
|
||||||
|
QMessageBox.information(None, "Labels imported", "Your labels where imported from '%s'" % str(labelsFile))
|
||||||
|
except (IOError, os.error), reason:
|
||||||
|
QMessageBox.critical(None, "Unable to export labels", "Electrum was unable to export your labels.\n" + str(reason))
|
||||||
|
|
||||||
|
|
||||||
|
def do_export_labels(self):
|
||||||
|
labels = self.wallet.labels
|
||||||
|
try:
|
||||||
|
labelsFile = util.user_dir() + '/labels.dat'
|
||||||
|
f = open(labelsFile, 'w+')
|
||||||
|
json.dump(labels, f)
|
||||||
|
f.close()
|
||||||
|
QMessageBox.information(None, "Labels exported", "Your labels where exported to '%s'" % str(labelsFile))
|
||||||
|
except (IOError, os.error), reason:
|
||||||
|
QMessageBox.critical(None, "Unable to export labels", "Electrum was unable to export your labels.\n" + str(reason))
|
||||||
|
|
||||||
|
def do_export_history(self):
|
||||||
|
from gui_lite import csv_transaction
|
||||||
|
csv_transaction(self.wallet)
|
||||||
|
|
||||||
def settings_dialog(self):
|
def settings_dialog(self):
|
||||||
d = QDialog(self)
|
d = QDialog(self)
|
||||||
|
@ -1513,27 +1542,10 @@ class ElectrumWindow(QMainWindow):
|
||||||
tabs = QTabWidget(self)
|
tabs = QTabWidget(self)
|
||||||
vbox.addWidget(tabs)
|
vbox.addWidget(tabs)
|
||||||
|
|
||||||
tab2 = QWidget()
|
tab1 = QWidget()
|
||||||
grid_ui = QGridLayout(tab2)
|
grid_ui = QGridLayout(tab1)
|
||||||
grid_ui.setColumnStretch(0,1)
|
grid_ui.setColumnStretch(0,1)
|
||||||
tabs.addTab(tab2, _('Display') )
|
tabs.addTab(tab1, _('Display') )
|
||||||
|
|
||||||
tab = QWidget()
|
|
||||||
grid_wallet = QGridLayout(tab)
|
|
||||||
grid_wallet.setColumnStretch(0,1)
|
|
||||||
tabs.addTab(tab, _('Wallet') )
|
|
||||||
|
|
||||||
fee_label = QLabel(_('Transaction fee'))
|
|
||||||
grid_wallet.addWidget(fee_label, 2, 0)
|
|
||||||
fee_e = QLineEdit()
|
|
||||||
fee_e.setText("%s"% str( Decimal( self.wallet.fee)/100000000 ) )
|
|
||||||
grid_wallet.addWidget(fee_e, 2, 1)
|
|
||||||
msg = _('Fee per transaction input. Transactions involving multiple inputs tend to require a higher fee.') + ' ' \
|
|
||||||
+ _('Recommended value') + ': 0.001'
|
|
||||||
grid_wallet.addWidget(HelpButton(msg), 2, 2)
|
|
||||||
fee_e.textChanged.connect(lambda: numbify(fee_e,False))
|
|
||||||
if not self.config.is_modifiable('fee'):
|
|
||||||
for w in [fee_e, fee_label]: w.setEnabled(False)
|
|
||||||
|
|
||||||
nz_label = QLabel(_('Display zeros'))
|
nz_label = QLabel(_('Display zeros'))
|
||||||
grid_ui.addWidget(nz_label, 3, 0)
|
grid_ui.addWidget(nz_label, 3, 0)
|
||||||
|
@ -1546,33 +1558,6 @@ class ElectrumWindow(QMainWindow):
|
||||||
if not self.config.is_modifiable('num_zeros'):
|
if not self.config.is_modifiable('num_zeros'):
|
||||||
for w in [nz_e, nz_label]: w.setEnabled(False)
|
for w in [nz_e, nz_label]: w.setEnabled(False)
|
||||||
|
|
||||||
|
|
||||||
usechange_label = QLabel(_('Use change addresses'))
|
|
||||||
grid_wallet.addWidget(usechange_label, 5, 0)
|
|
||||||
usechange_combo = QComboBox()
|
|
||||||
usechange_combo.addItems(['Yes', 'No'])
|
|
||||||
usechange_combo.setCurrentIndex(not self.wallet.use_change)
|
|
||||||
grid_wallet.addWidget(usechange_combo, 5, 1)
|
|
||||||
grid_wallet.addWidget(HelpButton(_('Using change addresses makes it more difficult for other people to track your transactions. ')), 5, 2)
|
|
||||||
if not self.config.is_modifiable('use_change'): usechange_combo.setEnabled(False)
|
|
||||||
|
|
||||||
gap_label = QLabel(_('Gap limit'))
|
|
||||||
grid_wallet.addWidget(gap_label, 6, 0)
|
|
||||||
gap_e = QLineEdit()
|
|
||||||
gap_e.setText("%d"% self.wallet.gap_limit)
|
|
||||||
grid_wallet.addWidget(gap_e, 6, 1)
|
|
||||||
msg = _('The gap limit is the maximal number of contiguous unused addresses in your sequence of receiving addresses.') + '\n' \
|
|
||||||
+ _('You may increase it if you need more receiving addresses.') + '\n\n' \
|
|
||||||
+ _('Your current gap limit is') + ': %d'%self.wallet.gap_limit + '\n' \
|
|
||||||
+ _('Given the current status of your address sequence, the minimum gap limit you can use is: ') + '%d'%self.wallet.min_acceptable_gap() + '\n\n' \
|
|
||||||
+ _('Warning') + ': ' \
|
|
||||||
+ _('The gap limit parameter must be provided in order to recover your wallet from seed.') + ' ' \
|
|
||||||
+ _('Do not modify it if you do not understand what you are doing, or if you expect to recover your wallet without knowing it!') + '\n\n'
|
|
||||||
grid_wallet.addWidget(HelpButton(msg), 6, 2)
|
|
||||||
gap_e.textChanged.connect(lambda: numbify(nz_e,True))
|
|
||||||
if not self.config.is_modifiable('gap_limit'):
|
|
||||||
for w in [gap_e, gap_label]: w.setEnabled(False)
|
|
||||||
|
|
||||||
gui_label=QLabel(_('Default GUI') + ':')
|
gui_label=QLabel(_('Default GUI') + ':')
|
||||||
grid_ui.addWidget(gui_label , 7, 0)
|
grid_ui.addWidget(gui_label , 7, 0)
|
||||||
gui_combo = QComboBox()
|
gui_combo = QComboBox()
|
||||||
|
@ -1628,6 +1613,69 @@ class ElectrumWindow(QMainWindow):
|
||||||
|
|
||||||
grid_ui.addWidget(HelpButton(hh), 10, 2)
|
grid_ui.addWidget(HelpButton(hh), 10, 2)
|
||||||
|
|
||||||
|
# wallet tab
|
||||||
|
tab2 = QWidget()
|
||||||
|
grid_wallet = QGridLayout(tab2)
|
||||||
|
grid_wallet.setColumnStretch(0,1)
|
||||||
|
tabs.addTab(tab2, _('Wallet') )
|
||||||
|
|
||||||
|
fee_label = QLabel(_('Transaction fee'))
|
||||||
|
grid_wallet.addWidget(fee_label, 0, 0)
|
||||||
|
fee_e = QLineEdit()
|
||||||
|
fee_e.setText("%s"% str( Decimal( self.wallet.fee)/100000000 ) )
|
||||||
|
grid_wallet.addWidget(fee_e, 0, 1)
|
||||||
|
msg = _('Fee per transaction input. Transactions involving multiple inputs tend to require a higher fee.') + ' ' \
|
||||||
|
+ _('Recommended value') + ': 0.001'
|
||||||
|
grid_wallet.addWidget(HelpButton(msg), 0, 2)
|
||||||
|
fee_e.textChanged.connect(lambda: numbify(fee_e,False))
|
||||||
|
if not self.config.is_modifiable('fee'):
|
||||||
|
for w in [fee_e, fee_label]: w.setEnabled(False)
|
||||||
|
|
||||||
|
usechange_label = QLabel(_('Use change addresses'))
|
||||||
|
grid_wallet.addWidget(usechange_label, 1, 0)
|
||||||
|
usechange_combo = QComboBox()
|
||||||
|
usechange_combo.addItems(['Yes', 'No'])
|
||||||
|
usechange_combo.setCurrentIndex(not self.wallet.use_change)
|
||||||
|
grid_wallet.addWidget(usechange_combo, 1, 1)
|
||||||
|
grid_wallet.addWidget(HelpButton(_('Using change addresses makes it more difficult for other people to track your transactions. ')), 1, 2)
|
||||||
|
if not self.config.is_modifiable('use_change'): usechange_combo.setEnabled(False)
|
||||||
|
|
||||||
|
gap_label = QLabel(_('Gap limit'))
|
||||||
|
grid_wallet.addWidget(gap_label, 2, 0)
|
||||||
|
gap_e = QLineEdit()
|
||||||
|
gap_e.setText("%d"% self.wallet.gap_limit)
|
||||||
|
grid_wallet.addWidget(gap_e, 2, 1)
|
||||||
|
msg = _('The gap limit is the maximal number of contiguous unused addresses in your sequence of receiving addresses.') + '\n' \
|
||||||
|
+ _('You may increase it if you need more receiving addresses.') + '\n\n' \
|
||||||
|
+ _('Your current gap limit is') + ': %d'%self.wallet.gap_limit + '\n' \
|
||||||
|
+ _('Given the current status of your address sequence, the minimum gap limit you can use is: ') + '%d'%self.wallet.min_acceptable_gap() + '\n\n' \
|
||||||
|
+ _('Warning') + ': ' \
|
||||||
|
+ _('The gap limit parameter must be provided in order to recover your wallet from seed.') + ' ' \
|
||||||
|
+ _('Do not modify it if you do not understand what you are doing, or if you expect to recover your wallet without knowing it!') + '\n\n'
|
||||||
|
grid_wallet.addWidget(HelpButton(msg), 2, 2)
|
||||||
|
gap_e.textChanged.connect(lambda: numbify(nz_e,True))
|
||||||
|
if not self.config.is_modifiable('gap_limit'):
|
||||||
|
for w in [gap_e, gap_label]: w.setEnabled(False)
|
||||||
|
|
||||||
|
grid_wallet.setRowStretch(3,1)
|
||||||
|
|
||||||
|
|
||||||
|
# wallet tab
|
||||||
|
tab3 = QWidget()
|
||||||
|
grid_io = QGridLayout(tab3)
|
||||||
|
grid_io.setColumnStretch(0,1)
|
||||||
|
tabs.addTab(tab3, _('Import/Export') )
|
||||||
|
|
||||||
|
grid_io.addWidget(QLabel(_('Labels')), 1, 0)
|
||||||
|
grid_io.addWidget(EnterButton(_("Export"), self.do_export_labels), 1, 1)
|
||||||
|
grid_io.addWidget(EnterButton(_("Import"), self.do_import_labels), 1, 2)
|
||||||
|
grid_io.addWidget(HelpButton('Export your labels as json'), 1, 3)
|
||||||
|
|
||||||
|
grid_io.addWidget(QLabel(_('History')), 2, 0)
|
||||||
|
grid_io.addWidget(EnterButton(_("Export"), self.do_export_history), 2, 1)
|
||||||
|
grid_io.setRowStretch(3,1)
|
||||||
|
grid_io.addWidget(HelpButton('Export your transaction history as csv'), 2, 3)
|
||||||
|
|
||||||
vbox.addLayout(ok_cancel_buttons(d))
|
vbox.addLayout(ok_cancel_buttons(d))
|
||||||
d.setLayout(vbox)
|
d.setLayout(vbox)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue