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
This commit is contained in:
@@ -2494,32 +2494,13 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
|||||||
plt.show()
|
plt.show()
|
||||||
|
|
||||||
def do_export_history(self, wallet, fileName, is_csv):
|
def do_export_history(self, wallet, fileName, is_csv):
|
||||||
history = wallet.get_history()
|
history = wallet.export_history(fx=self.fx)
|
||||||
lines = []
|
lines = []
|
||||||
for item in history:
|
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:
|
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:
|
else:
|
||||||
lines.append({'txid':tx_hash, 'date':"%16s"%time_string, 'label':label, 'value':value_string})
|
lines.append(item)
|
||||||
|
|
||||||
with open(fileName, "w+") as f:
|
with open(fileName, "w+") as f:
|
||||||
if is_csv:
|
if is_csv:
|
||||||
@@ -2529,7 +2510,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
|||||||
transaction.writerow(line)
|
transaction.writerow(line)
|
||||||
else:
|
else:
|
||||||
import json
|
import json
|
||||||
f.write(json.dumps(lines, indent = 4))
|
f.write(json.dumps(lines, indent=4))
|
||||||
|
|
||||||
def sweep_key_dialog(self):
|
def sweep_key_dialog(self):
|
||||||
d = WindowModalDialog(self, title=_('Sweep private keys'))
|
d = WindowModalDialog(self, title=_('Sweep private keys'))
|
||||||
|
|||||||
@@ -440,46 +440,16 @@ class Commands:
|
|||||||
return tx.as_dict()
|
return tx.as_dict()
|
||||||
|
|
||||||
@command('w')
|
@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."""
|
"""Wallet history. Returns the transaction history of your wallet."""
|
||||||
balance = 0
|
kwargs = {'show_addresses': show_addresses}
|
||||||
out = []
|
if year:
|
||||||
for item in self.wallet.get_history():
|
import time
|
||||||
tx_hash, height, conf, timestamp, value, balance = item
|
start_date = datetime.datetime(year, 1, 1)
|
||||||
if timestamp:
|
end_date = datetime.datetime(year+1, 1, 1)
|
||||||
date = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3]
|
kwargs['from_timestamp'] = time.mktime(start_date.timetuple())
|
||||||
else:
|
kwargs['to_timestamp'] = time.mktime(end_date.timetuple())
|
||||||
date = "----"
|
return self.wallet.export_history(**kwargs)
|
||||||
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
|
|
||||||
|
|
||||||
@command('w')
|
@command('w')
|
||||||
def setlabel(self, key, label):
|
def setlabel(self, key, label):
|
||||||
@@ -736,6 +706,9 @@ command_options = {
|
|||||||
'pending': (None, "Show only pending requests."),
|
'pending': (None, "Show only pending requests."),
|
||||||
'expired': (None, "Show only expired requests."),
|
'expired': (None, "Show only expired requests."),
|
||||||
'paid': (None, "Show only paid 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"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -746,6 +719,7 @@ arg_types = {
|
|||||||
'num': int,
|
'num': int,
|
||||||
'nbits': int,
|
'nbits': int,
|
||||||
'imax': int,
|
'imax': int,
|
||||||
|
'year': int,
|
||||||
'entropy': int,
|
'entropy': int,
|
||||||
'tx': tx_from_str,
|
'tx': tx_from_str,
|
||||||
'pubkeys': json_loads,
|
'pubkeys': json_loads,
|
||||||
|
|||||||
@@ -914,6 +914,57 @@ class Abstract_Wallet(PrintError):
|
|||||||
|
|
||||||
return h2
|
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):
|
def get_label(self, tx_hash):
|
||||||
label = self.labels.get(tx_hash, '')
|
label = self.labels.get(tx_hash, '')
|
||||||
if label is '':
|
if label is '':
|
||||||
|
|||||||
Reference in New Issue
Block a user