tFactorize history export code used in GUI and command line. Add options to export history limits and exchange rate. Closes: #1752, #2604, Replaces: #2715, 3724 - electrum - Electrum Bitcoin wallet (HTM) git clone https://git.parazyd.org/electrum (DIR) Log (DIR) Files (DIR) Refs (DIR) Submodules --- (DIR) commit 3f954a8b3d39d2cb45927371a856802104f9182c (DIR) parent 670194b92037dba020ef8b6bfe5922560c7f5b26 (HTM) Author: ThomasV <thomasv@electrum.org> Date: Fri, 9 Feb 2018 15:28:28 +0100 Factorize history export code used in GUI and command line. Add options to export history limits and exchange rate. Closes: #1752, #2604, Replaces: #2715, 3724 Diffstat: M gui/qt/main_window.py | 27 ++++----------------------- M lib/commands.py | 52 ++++++++----------------------- M lib/wallet.py | 51 +++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 62 deletions(-) --- (DIR) diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py t@@ -2494,32 +2494,13 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): plt.show() def do_export_history(self, wallet, fileName, is_csv): - history = wallet.get_history() + history = wallet.export_history(fx=self.fx) lines = [] for item in history: - tx_hash, height, confirmations, timestamp, value, balance = item - if height>0: - if timestamp is not None: - time_string = format_time(timestamp) - else: - time_string = _("unverified") - else: - time_string = _("unconfirmed") - - if value is not None: - value_string = format_satoshis(value, True) - else: - value_string = '--' - - if tx_hash: - label = wallet.get_label(tx_hash) - else: - label = "" - if is_csv: - lines.append([tx_hash, label, confirmations, value_string, time_string]) + lines.append([item['txid'], item.get('label', ''), item['confirmations'], item['value'], item['date']]) else: - lines.append({'txid':tx_hash, 'date':"%16s"%time_string, 'label':label, 'value':value_string}) + lines.append(item) with open(fileName, "w+") as f: if is_csv: t@@ -2529,7 +2510,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): transaction.writerow(line) else: import json - f.write(json.dumps(lines, indent = 4)) + f.write(json.dumps(lines, indent=4)) def sweep_key_dialog(self): d = WindowModalDialog(self, title=_('Sweep private keys')) (DIR) diff --git a/lib/commands.py b/lib/commands.py t@@ -440,46 +440,16 @@ class Commands: return tx.as_dict() @command('w') - def history(self): + def history(self, year=None, show_addresses=False, show_fiat=False): """Wallet history. Returns the transaction history of your wallet.""" - balance = 0 - out = [] - for item in self.wallet.get_history(): - tx_hash, height, conf, timestamp, value, balance = item - if timestamp: - date = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3] - else: - date = "----" - label = self.wallet.get_label(tx_hash) - tx = self.wallet.transactions.get(tx_hash) - tx.deserialize() - input_addresses = [] - output_addresses = [] - for x in tx.inputs(): - if x['type'] == 'coinbase': continue - addr = x.get('address') - if addr == None: continue - if addr == "(pubkey)": - prevout_hash = x.get('prevout_hash') - prevout_n = x.get('prevout_n') - _addr = self.wallet.find_pay_to_pubkey_address(prevout_hash, prevout_n) - if _addr: - addr = _addr - input_addresses.append(addr) - for addr, v in tx.get_outputs(): - output_addresses.append(addr) - out.append({ - 'txid': tx_hash, - 'timestamp': timestamp, - 'date': date, - 'input_addresses': input_addresses, - 'output_addresses': output_addresses, - 'label': label, - 'value': str(Decimal(value)/COIN) if value is not None else None, - 'height': height, - 'confirmations': conf - }) - return out + kwargs = {'show_addresses': show_addresses} + if year: + import time + start_date = datetime.datetime(year, 1, 1) + end_date = datetime.datetime(year+1, 1, 1) + kwargs['from_timestamp'] = time.mktime(start_date.timetuple()) + kwargs['to_timestamp'] = time.mktime(end_date.timetuple()) + return self.wallet.export_history(**kwargs) @command('w') def setlabel(self, key, label): t@@ -736,6 +706,9 @@ command_options = { 'pending': (None, "Show only pending requests."), 'expired': (None, "Show only expired requests."), 'paid': (None, "Show only paid requests."), + 'show_addresses': (None, "Show input and output addresses"), + 'show_fiat': (None, "Show fiat value of transactions"), + 'year': (None, "Show history for a given year"), } t@@ -746,6 +719,7 @@ arg_types = { 'num': int, 'nbits': int, 'imax': int, + 'year': int, 'entropy': int, 'tx': tx_from_str, 'pubkeys': json_loads, (DIR) diff --git a/lib/wallet.py b/lib/wallet.py t@@ -914,6 +914,57 @@ class Abstract_Wallet(PrintError): return h2 + def export_history(self, domain=None, from_timestamp=None, to_timestamp=None, fx=None, show_addresses=False): + from decimal import Decimal + from .util import format_time, format_satoshis, timestamp_to_datetime + h = self.get_history(domain) + out = [] + for tx_hash, height, conf, timestamp, value, balance in h: + if from_timestamp and timestamp < from_timestamp: + continue + if to_timestamp and timestamp >= to_timestamp: + continue + item = { + 'txid':tx_hash, + 'height':height, + 'confirmations':conf, + 'timestamp':timestamp, + 'value': format_satoshis(value, True) if value is not None else '--', + 'balance': format_satoshis(balance) + } + if item['height']>0: + date_str = format_time(timestamp) if timestamp is not None else _("unverified") + else: + date_str = _("unconfirmed") + item['date'] = date_str + item['label'] = self.get_label(tx_hash) + if show_addresses: + tx = self.transactions.get(tx_hash) + tx.deserialize() + input_addresses = [] + output_addresses = [] + for x in tx.inputs(): + if x['type'] == 'coinbase': continue + addr = x.get('address') + if addr == None: continue + if addr == "(pubkey)": + prevout_hash = x.get('prevout_hash') + prevout_n = x.get('prevout_n') + _addr = self.wallet.find_pay_to_pubkey_address(prevout_hash, prevout_n) + if _addr: + addr = _addr + input_addresses.append(addr) + for addr, v in tx.get_outputs(): + output_addresses.append(addr) + item['input_addresses'] = input_addresses + item['output_addresses'] = output_addresses + if fx is not None: + date = timestamp_to_datetime(time.time() if conf <= 0 else timestamp) + item['fiat_value'] = fx.historical_value_str(value, date) + item['fiat_balance'] = fx.historical_value_str(balance, date) + out.append(item) + return out + def get_label(self, tx_hash): label = self.labels.get(tx_hash, '') if label is '':