tracking wallet classes: reorder methods, cleanups
This commit is contained in:
parent
69b15a4ff9
commit
d513035aad
4 changed files with 83 additions and 85 deletions
|
|
@ -27,7 +27,6 @@ class TwAddresses(TwView,metaclass=AsyncInit):
|
|||
hdr_lbl = 'tracking wallet addresses'
|
||||
desc = 'address list'
|
||||
item_desc = 'address'
|
||||
txid_w = 64
|
||||
sort_key = 'twmmid'
|
||||
update_widths_on_age_toggle = True
|
||||
print_output_types = ('detail',)
|
||||
|
|
@ -79,10 +78,9 @@ class TwAddresses(TwView,metaclass=AsyncInit):
|
|||
|
||||
async def __init__(self,proto,minconf=1,mmgen_addrs='',wallet=None,get_data=False):
|
||||
|
||||
self.proto = proto
|
||||
self.minconf = NonNegativeInt(minconf)
|
||||
self.usr_addr_list = []
|
||||
self.rpc = await rpc_init(proto)
|
||||
self.proto = proto
|
||||
self.minconf = NonNegativeInt(minconf)
|
||||
self.rpc = await rpc_init(proto)
|
||||
|
||||
from .ctl import TrackingWallet
|
||||
self.wallet = wallet or await TrackingWallet(proto,mode='w')
|
||||
|
|
@ -96,6 +94,8 @@ class TwAddresses(TwView,metaclass=AsyncInit):
|
|||
'(must be in form <seed ID>:[<type>:]<idx list>)' )
|
||||
from ..addrlist import AddrIdxList
|
||||
self.usr_addr_list = [MMGenID(self.proto,f'{a[0]}:{i}') for i in AddrIdxList(a[1])]
|
||||
else:
|
||||
self.usr_addr_list = []
|
||||
|
||||
if get_data:
|
||||
await self.get_data()
|
||||
|
|
|
|||
|
|
@ -12,13 +12,11 @@
|
|||
tw.txhistory: Tracking wallet transaction history class for the MMGen suite
|
||||
"""
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
from ..util import fmt
|
||||
from ..base_obj import AsyncInit
|
||||
from ..objmethods import MMGenObject
|
||||
from ..obj import CoinTxID,MMGenList,Int
|
||||
from ..rpc import rpc_init
|
||||
from ..obj import NonNegativeInt
|
||||
from .view import TwView
|
||||
|
||||
class TwTxHistory(TwView,metaclass=AsyncInit):
|
||||
|
|
@ -35,7 +33,7 @@ class TwTxHistory(TwView,metaclass=AsyncInit):
|
|||
def __new__(cls,proto,*args,**kwargs):
|
||||
return MMGenObject.__new__(proto.base_proto_subclass(cls,'tw','txhistory'))
|
||||
|
||||
txid_w = 64
|
||||
has_wallet = False
|
||||
show_txid = False
|
||||
show_unconfirmed = False
|
||||
show_total_amt = False
|
||||
|
|
@ -44,9 +42,9 @@ class TwTxHistory(TwView,metaclass=AsyncInit):
|
|||
filters = ('show_unconfirmed',)
|
||||
|
||||
async def __init__(self,proto,sinceblock=0):
|
||||
self.proto = proto
|
||||
self.rpc = await rpc_init(proto)
|
||||
self.sinceblock = Int( sinceblock if sinceblock >= 0 else self.rpc.blockcount + sinceblock )
|
||||
self.proto = proto
|
||||
self.rpc = await rpc_init(proto)
|
||||
self.sinceblock = NonNegativeIntInt( sinceblock if sinceblock >= 0 else self.rpc.blockcount + sinceblock )
|
||||
|
||||
@property
|
||||
def no_rpcdata_errmsg(self):
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ from ..obj import (
|
|||
ListItemAttr,
|
||||
MMGenListItem,
|
||||
TwComment,
|
||||
get_obj,
|
||||
HexStr,
|
||||
CoinTxID,
|
||||
NonNegativeInt )
|
||||
|
|
@ -52,7 +51,6 @@ class TwUnspentOutputs(TwView,metaclass=AsyncInit):
|
|||
return MMGenObject.__new__(proto.base_proto_subclass(cls,'tw','unspent'))
|
||||
|
||||
show_mmid = True
|
||||
txid_w = 64
|
||||
no_rpcdata_errmsg = """
|
||||
No spendable outputs found! Import addresses with balances into your
|
||||
watch-only wallet using 'mmgen-addrimport' and then re-run this program.
|
||||
|
|
|
|||
164
mmgen/tw/view.py
164
mmgen/tw/view.py
|
|
@ -32,10 +32,28 @@ from ..util import msg,msg_r,fmt,die,capfirst,make_timestr
|
|||
# base class for TwUnspentOutputs,TwAddresses,TwTxHistory:
|
||||
class TwView(MMGenObject):
|
||||
|
||||
class display_type:
|
||||
|
||||
class squeezed:
|
||||
detail = False
|
||||
fmt_method = 'gen_squeezed_display'
|
||||
need_column_widths = True
|
||||
item_separator = '\n'
|
||||
print_header = '[screen print truncated to width {}]\n'
|
||||
|
||||
class detail:
|
||||
detail = True
|
||||
fmt_method = 'gen_detail_display'
|
||||
need_column_widths = True
|
||||
item_separator = '\n'
|
||||
print_header = ''
|
||||
|
||||
has_wallet = True
|
||||
dates_set = False
|
||||
cols = None
|
||||
reverse = False
|
||||
group = False
|
||||
txid_w = 64
|
||||
sort_key = 'age'
|
||||
interactive = False
|
||||
_display_data = {}
|
||||
|
|
@ -91,48 +109,6 @@ class TwView(MMGenObject):
|
|||
Please resize your screen to at least {} characters and hit any key:
|
||||
"""
|
||||
|
||||
class display_type:
|
||||
|
||||
class squeezed:
|
||||
detail = False
|
||||
fmt_method = 'gen_squeezed_display'
|
||||
need_column_widths = True
|
||||
item_separator = '\n'
|
||||
print_header = '[screen print truncated to width {}]\n'
|
||||
|
||||
class detail:
|
||||
detail = True
|
||||
fmt_method = 'gen_detail_display'
|
||||
need_column_widths = True
|
||||
item_separator = '\n'
|
||||
print_header = ''
|
||||
|
||||
def age_disp(self,o,age_fmt):
|
||||
if age_fmt == 'confs':
|
||||
return o.confs or '-'
|
||||
elif age_fmt == 'block':
|
||||
return self.rpc.blockcount + 1 - o.confs if o.confs else '-'
|
||||
else:
|
||||
return self.date_formatter[age_fmt](self.rpc,o.date)
|
||||
|
||||
async def get_data(self,sort_key=None,reverse_sort=False):
|
||||
|
||||
rpc_data = await self.get_rpc_data()
|
||||
|
||||
if not rpc_data:
|
||||
die(0,fmt(self.no_rpcdata_errmsg).strip())
|
||||
|
||||
lbl_id = ('account','label')['label_api' in self.rpc.caps]
|
||||
|
||||
res = self.gen_data(rpc_data,lbl_id)
|
||||
self.data = MMGenList(await res if type(res).__name__ == 'coroutine' else res)
|
||||
self.disp_data = list(self.filter_data())
|
||||
|
||||
if not self.data:
|
||||
die(1,self.no_data_errmsg)
|
||||
|
||||
self.do_sort(key=sort_key,reverse=reverse_sort)
|
||||
|
||||
@property
|
||||
def age_w(self):
|
||||
return self.age_col_params[self.age_fmt][0]
|
||||
|
|
@ -155,9 +131,69 @@ class TwView(MMGenObject):
|
|||
f'{val!r}: invalid age format for {op_desc} operation (must be one of {ok_vals!r})' )
|
||||
self._age_fmt = val
|
||||
|
||||
def age_disp(self,o,age_fmt):
|
||||
if age_fmt == 'confs':
|
||||
return o.confs or '-'
|
||||
elif age_fmt == 'block':
|
||||
return self.rpc.blockcount + 1 - o.confs if o.confs else '-'
|
||||
else:
|
||||
return self.date_formatter[age_fmt](self.rpc,o.date)
|
||||
|
||||
def get_disp_prec(self,wide):
|
||||
return self.proto.coin_amt.max_prec
|
||||
|
||||
sort_disp = {
|
||||
'addr': 'Addr',
|
||||
'age': 'Age',
|
||||
'amt': 'Amt',
|
||||
'txid': 'TxID',
|
||||
'twmmid': 'MMGenID',
|
||||
}
|
||||
|
||||
sort_funcs = {
|
||||
'addr': lambda i: i.addr,
|
||||
'age': lambda i: 0 - i.confs,
|
||||
'amt': lambda i: i.amt,
|
||||
'txid': lambda i: f'{i.txid} {i.vout:04}',
|
||||
'twmmid': lambda i: i.twmmid.sort_key
|
||||
}
|
||||
|
||||
def sort_info(self,include_group=True):
|
||||
ret = ([],['Reverse'])[self.reverse]
|
||||
ret.append(self.sort_disp[self.sort_key])
|
||||
if include_group and self.group and (self.sort_key in ('addr','txid','twmmid')):
|
||||
ret.append('Grouped')
|
||||
return ret
|
||||
|
||||
def do_sort(self,key=None,reverse=False):
|
||||
key = key or self.sort_key
|
||||
if key not in self.sort_funcs:
|
||||
die(1,f'{key!r}: invalid sort key. Valid options: {" ".join(self.sort_funcs)}')
|
||||
self.sort_key = key
|
||||
assert type(reverse) == bool
|
||||
self.data.sort(key=self.sort_funcs[key],reverse=reverse or self.reverse)
|
||||
|
||||
async def get_data(self,sort_key=None,reverse_sort=False):
|
||||
|
||||
rpc_data = await self.get_rpc_data()
|
||||
|
||||
if not rpc_data:
|
||||
die(0,fmt(self.no_rpcdata_errmsg).strip())
|
||||
|
||||
lbl_id = ('account','label')['label_api' in self.rpc.caps]
|
||||
|
||||
res = self.gen_data(rpc_data,lbl_id)
|
||||
self.data = MMGenList(await res if type(res).__name__ == 'coroutine' else res)
|
||||
self.disp_data = list(self.filter_data())
|
||||
|
||||
if not self.data:
|
||||
die(1,self.no_data_errmsg)
|
||||
|
||||
self.do_sort(key=sort_key,reverse=reverse_sort)
|
||||
|
||||
def filter_data(self):
|
||||
return self.data.copy()
|
||||
|
||||
def get_term_columns(self,min_cols):
|
||||
from ..term import get_terminal_size,get_char_raw
|
||||
while True:
|
||||
|
|
@ -172,37 +208,6 @@ class TwView(MMGenObject):
|
|||
else:
|
||||
return min_cols
|
||||
|
||||
sort_disp = {
|
||||
'addr': 'Addr',
|
||||
'age': 'Age',
|
||||
'amt': 'Amt',
|
||||
'txid': 'TxID',
|
||||
'twmmid': 'MMGenID',
|
||||
}
|
||||
|
||||
def sort_info(self,include_group=True):
|
||||
ret = ([],['Reverse'])[self.reverse]
|
||||
ret.append(self.sort_disp[self.sort_key])
|
||||
if include_group and self.group and (self.sort_key in ('addr','txid','twmmid')):
|
||||
ret.append('Grouped')
|
||||
return ret
|
||||
|
||||
sort_funcs = {
|
||||
'addr': lambda i: i.addr,
|
||||
'age': lambda i: 0 - i.confs,
|
||||
'amt': lambda i: i.amt,
|
||||
'txid': lambda i: f'{i.txid} {i.vout:04}',
|
||||
'twmmid': lambda i: i.twmmid.sort_key
|
||||
}
|
||||
|
||||
def do_sort(self,key=None,reverse=False):
|
||||
key = key or self.sort_key
|
||||
if key not in self.sort_funcs:
|
||||
die(1,f'{key!r}: invalid sort key. Valid options: {" ".join(self.sort_funcs)}')
|
||||
self.sort_key = key
|
||||
assert type(reverse) == bool
|
||||
self.data.sort(key=self.sort_funcs[key],reverse=reverse or self.reverse)
|
||||
|
||||
def compute_column_widths(self,widths,maxws,minws,maxws_nice={},wide=False):
|
||||
|
||||
def do_ret(freews):
|
||||
|
|
@ -284,8 +289,11 @@ class TwView(MMGenObject):
|
|||
def subheader(self,color):
|
||||
return ''
|
||||
|
||||
def filter_data(self):
|
||||
return self.data.copy()
|
||||
def footer(self,color):
|
||||
return '\nTOTAL: {} {}\n'.format(
|
||||
self.total.hl(color=color) if hasattr(self,'total') else None,
|
||||
self.proto.dcoin
|
||||
) if hasattr(self,'total') else ''
|
||||
|
||||
async def format(self,display_type,color=True,cached=False,interactive=False):
|
||||
|
||||
|
|
@ -320,12 +328,6 @@ class TwView(MMGenObject):
|
|||
|
||||
return self._display_data[display_type] + ('' if interactive else self.footer(color))
|
||||
|
||||
def footer(self,color):
|
||||
return '\nTOTAL: {} {}\n'.format(
|
||||
self.total.hl(color=color) if hasattr(self,'total') else None,
|
||||
self.proto.dcoin
|
||||
) if hasattr(self,'total') else ''
|
||||
|
||||
async def view_filter_and_sort(self):
|
||||
from ..opts import opt
|
||||
from ..term import get_char
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue