tw.common,tw.unspent: various changes and cleanups
This commit is contained in:
parent
310f6f59c5
commit
d4cae73cf0
6 changed files with 195 additions and 132 deletions
|
|
@ -36,13 +36,26 @@ Display options: toggle [D]ays/date, show [g]roup, show [m]mgen addr, r[e]draw
|
|||
Actions: [q]uit view, [p]rint to file, pager [v]iew, [w]ide view, add [l]abel:
|
||||
"""
|
||||
key_mappings = {
|
||||
't':'s_txid','a':'s_amt','d':'s_addr','A':'s_age','r':'d_reverse','M':'s_twmmid',
|
||||
'D':'d_days','g':'d_group','m':'d_mmid','e':'d_redraw',
|
||||
'q':'a_quit','p':'a_print','v':'a_view','w':'a_view_wide','l':'a_lbl_add' }
|
||||
't':'s_txid',
|
||||
'a':'s_amt',
|
||||
'd':'s_addr',
|
||||
'A':'s_age',
|
||||
'r':'d_reverse',
|
||||
'M':'s_twmmid',
|
||||
'D':'d_days',
|
||||
'g':'d_group',
|
||||
'm':'d_mmid',
|
||||
'e':'d_redraw',
|
||||
'q':'a_quit',
|
||||
'p':'a_print_detail',
|
||||
'v':'a_view',
|
||||
'w':'a_view_detail',
|
||||
'l':'a_lbl_add' }
|
||||
|
||||
col_adj = 38
|
||||
display_fs_fs = ' {{n:{cw}}} {{t:{tw}}} {{v:2}} {{a}} {{A}} {{c:<}}'
|
||||
display_hdr_fs_fs = ' {{n:{cw}}} {{t:{tw}}} {{a}} {{A}} {{c:<}}'
|
||||
print_fs_fs = ' {{n:4}} {{t:{tw}}} {{a}} {{m}} {{A:{aw}}} {cf}{{b:<8}} {{D:<19}} {{l}}'
|
||||
squeezed_fs_fs = ' {{n:{cw}}} {{t:{tw}}} {{v:2}} {{a}} {{A}} {{c:<}}'
|
||||
squeezed_hdr_fs_fs = ' {{n:{cw}}} {{t:{tw}}} {{a}} {{A}} {{c:<}}'
|
||||
wide_fs_fs = ' {{n:4}} {{t:{tw}}} {{a}} {{m}} {{A:{aw}}} {cf}{{b:<8}} {{D:<19}} {{l}}'
|
||||
|
||||
async def get_rpc_data(self):
|
||||
# bitcoin-cli help listunspent:
|
||||
|
|
|
|||
|
|
@ -44,13 +44,22 @@ Actions: [q]uit view, [p]rint to file, pager [v]iew, [w]ide view,
|
|||
add [l]abel, [D]elete address, [R]efresh balance:
|
||||
"""
|
||||
key_mappings = {
|
||||
'a':'s_amt','d':'s_addr','r':'d_reverse','M':'s_twmmid',
|
||||
'm':'d_mmid','e':'d_redraw',
|
||||
'q':'a_quit','p':'a_print','v':'a_view','w':'a_view_wide',
|
||||
'l':'a_lbl_add','D':'a_addr_delete','R':'a_balance_refresh' }
|
||||
display_fs_fs = ' {{n:{cw}}} {{a}} {{A}}'
|
||||
print_fs_fs = ' {{n:4}} {{a}} {{m}} {{A:{aw}}} {{l}}'
|
||||
display_hdr_fs_fs = display_fs_fs
|
||||
'a':'s_amt',
|
||||
'd':'s_addr',
|
||||
'r':'d_reverse',
|
||||
'M':'s_twmmid',
|
||||
'm':'d_mmid',
|
||||
'e':'d_redraw',
|
||||
'q':'a_quit',
|
||||
'p':'a_print_detail',
|
||||
'v':'a_view',
|
||||
'w':'a_view_detail',
|
||||
'l':'a_lbl_add',
|
||||
'D':'a_addr_delete',
|
||||
'R':'a_balance_refresh' }
|
||||
|
||||
squeezed_fs_fs = squeezed_hdr_fs_fs = ' {{n:{cw}}} {{a}} {{A}}'
|
||||
wide_fs_fs = ' {{n:4}} {{a}} {{m}} {{A:{aw}}} {{l}}'
|
||||
no_data_errmsg = 'No accounts in tracking wallet!'
|
||||
|
||||
async def __init__(self,proto,*args,**kwargs):
|
||||
|
|
@ -82,9 +91,8 @@ class EthereumTokenTwUnspentOutputs(EthereumTwUnspentOutputs):
|
|||
|
||||
prompt_fs = 'Total to spend: {} {}\n\n'
|
||||
col_adj = 37
|
||||
display_fs_fs = ' {{n:{cw}}} {{a}} {{A}} {{A2}}'
|
||||
print_fs_fs = ' {{n:4}} {{a}} {{m}} {{A:{aw}}} {{A2:{aw}}} {{l}}'
|
||||
display_hdr_fs_fs = display_fs_fs
|
||||
squeezed_fs_fs = squeezed_hdr_fs_fs = ' {{n:{cw}}} {{a}} {{A}} {{A2}}'
|
||||
wide_fs_fs = ' {{n:4}} {{a}} {{m}} {{A:{aw}}} {{A2:{aw}}} {{l}}'
|
||||
|
||||
async def __init__(self,proto,*args,**kwargs):
|
||||
await super().__init__(proto,*args,**kwargs)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
13.1.0
|
||||
13.2.dev1
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ class tool_cmd(tool_cmd_base):
|
|||
return await al.format( showbtcaddrs, sort, show_age, age_fmt or 'confs' )
|
||||
|
||||
async def twops(self,
|
||||
obj,pager,reverse,wide,sort,age_fmt,show_mmid,wide_show_confs,interactive):
|
||||
obj,pager,reverse,detail,sort,age_fmt,interactive,show_mmid):
|
||||
|
||||
obj.interactive = interactive
|
||||
obj.reverse = reverse
|
||||
|
|
@ -109,10 +109,10 @@ class tool_cmd(tool_cmd_base):
|
|||
if interactive:
|
||||
await obj.view_and_sort()
|
||||
return True
|
||||
elif wide:
|
||||
return await obj.format_for_printing( color=True, show_confs=wide_show_confs )
|
||||
elif detail:
|
||||
return await obj.format_detail( color=True )
|
||||
else:
|
||||
return await obj.format_for_display()
|
||||
return await obj.format_squeezed()
|
||||
|
||||
async def twview(self,
|
||||
pager = False,
|
||||
|
|
@ -121,15 +121,14 @@ class tool_cmd(tool_cmd_base):
|
|||
minconf = 1,
|
||||
sort = 'age',
|
||||
age_fmt: options_annot_str(TwCommon.age_fmts) = 'confs',
|
||||
show_mmid = True,
|
||||
wide_show_confs = True,
|
||||
interactive = False ):
|
||||
interactive = False,
|
||||
show_mmid = True ):
|
||||
"view tracking wallet unspent outputs"
|
||||
|
||||
from ..tw.unspent import TwUnspentOutputs
|
||||
obj = await TwUnspentOutputs(self.proto,minconf=minconf)
|
||||
ret = await self.twops(
|
||||
obj,pager,reverse,wide,sort,age_fmt,show_mmid,wide_show_confs,interactive)
|
||||
obj,pager,reverse,wide,sort,age_fmt,interactive,show_mmid)
|
||||
del obj.wallet
|
||||
return ret
|
||||
|
||||
|
|
|
|||
|
|
@ -25,15 +25,13 @@ import sys,time
|
|||
from ..globalvars import g
|
||||
from ..objmethods import Hilite,InitErrors,MMGenObject
|
||||
from ..obj import TwComment,get_obj,MMGenIdx,MMGenList
|
||||
from ..color import nocolor,red,yellow,green
|
||||
from ..color import nocolor,yellow,green
|
||||
from ..util import msg,msg_r,fmt,die,line_input,do_pager,capfirst,make_timestr
|
||||
from ..addr import MMGenID
|
||||
|
||||
# mixin class for TwUnspentOutputs,TwAddrList:
|
||||
class TwCommon:
|
||||
|
||||
fmt_display = ''
|
||||
fmt_print = ''
|
||||
cols = None
|
||||
reverse = False
|
||||
group = False
|
||||
|
|
@ -45,6 +43,14 @@ class TwCommon:
|
|||
age_fmts_interactive = ('confs','block','days','date')
|
||||
_age_fmt = 'confs'
|
||||
|
||||
age_col_params = {
|
||||
'confs': (7, 'Confs'),
|
||||
'block': (8, 'Block'),
|
||||
'days': (6, 'Age(d)'),
|
||||
'date': (8, 'Date'),
|
||||
'date_time': (16, 'Date/Time'),
|
||||
}
|
||||
|
||||
date_formatter = {
|
||||
'days': lambda rpc,secs: (rpc.cur_date - secs) // 86400 if secs else 0,
|
||||
'date': (
|
||||
|
|
@ -72,7 +78,8 @@ class TwCommon:
|
|||
|
||||
lbl_id = ('account','label')['label_api' in self.rpc.caps]
|
||||
|
||||
self.data = MMGenList(self.gen_data(rpc_data,lbl_id))
|
||||
res = self.gen_data(rpc_data,lbl_id)
|
||||
self.data = MMGenList(await res if type(res).__name__ == 'coroutine' else res)
|
||||
|
||||
if not self.data:
|
||||
die(1,self.no_data_errmsg)
|
||||
|
|
@ -88,6 +95,14 @@ class TwCommon:
|
|||
for idx,o in enumerate(us):
|
||||
o.date = dates[idx]
|
||||
|
||||
@property
|
||||
def age_w(self):
|
||||
return self.age_col_params[self.age_fmt][0]
|
||||
|
||||
@property
|
||||
def age_hdr(self):
|
||||
return self.age_col_params[self.age_fmt][1]
|
||||
|
||||
@property
|
||||
def age_fmt(self):
|
||||
return self._age_fmt
|
||||
|
|
@ -124,9 +139,17 @@ class TwCommon:
|
|||
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(capfirst(self.sort_key).replace('Twmmid','MMGenID'))
|
||||
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
|
||||
|
|
@ -147,49 +170,54 @@ class TwCommon:
|
|||
assert type(reverse) == bool
|
||||
self.data.sort(key=self.sort_funcs[key],reverse=reverse or self.reverse)
|
||||
|
||||
async def format_for_display(self):
|
||||
data = self.data
|
||||
if self.has_age and self.age_fmt in self.age_fmts_date_dependent:
|
||||
await self.set_dates(self.rpc,data)
|
||||
async def format_squeezed(self,color=True,cached=False):
|
||||
|
||||
if not getattr(self,'column_params',None):
|
||||
self.set_column_params()
|
||||
if not cached:
|
||||
data = self.data
|
||||
if self.has_age and self.age_fmt in self.age_fmts_date_dependent:
|
||||
await self.set_dates(self.rpc,data)
|
||||
|
||||
if self.group and (self.sort_key in ('addr','txid','twmmid')):
|
||||
for a,b in [(data[i],data[i+1]) for i in range(len(data)-1)]:
|
||||
for k in ('addr','txid','twmmid'):
|
||||
if self.sort_key == k and getattr(a,k) == getattr(b,k):
|
||||
b.skip = (k,'addr')[k=='twmmid']
|
||||
if not getattr(self,'column_params',None):
|
||||
self.set_column_params()
|
||||
|
||||
self.fmt_display = (
|
||||
self.hdr_fmt.format(
|
||||
a = ' '.join(self.sort_info()),
|
||||
b = self.proto.dcoin,
|
||||
c = self.total.hl() if hasattr(self,'total') else None )
|
||||
+ ('\nChain: '+green(self.proto.chain_name.upper()) if self.proto.chain_name != 'mainnet' else '')
|
||||
+ '\n' + '\n'.join(self.gen_display_output(self.column_params))
|
||||
+ '\n'
|
||||
)
|
||||
if self.group and (self.sort_key in ('addr','txid','twmmid')):
|
||||
for a,b in [(data[i],data[i+1]) for i in range(len(data)-1)]:
|
||||
for k in ('addr','txid','twmmid'):
|
||||
if self.sort_key == k and getattr(a,k) == getattr(b,k):
|
||||
b.skip = (k,'addr')[k=='twmmid']
|
||||
|
||||
return self.fmt_display
|
||||
self._format_squeezed_display_data = (
|
||||
self.hdr_fmt.format(
|
||||
a = ' '.join(self.sort_info()),
|
||||
b = self.proto.dcoin,
|
||||
c = self.total.hl() if hasattr(self,'total') else None )
|
||||
+ '\nNetwork: {}'.format((nocolor,green)[color](
|
||||
self.proto.coin + ' ' +
|
||||
self.proto.chain_name.upper() ))
|
||||
+ '\n' + '\n'.join(self.gen_squeezed_display(self.column_params,color=color))
|
||||
+ '\n'
|
||||
)
|
||||
|
||||
async def format_for_printing(self,color=False,show_confs=True):
|
||||
return self._format_squeezed_display_data
|
||||
|
||||
async def format_detail(self,color):
|
||||
if self.has_age:
|
||||
await self.set_dates(self.rpc,self.data)
|
||||
|
||||
self.fmt_print = self.print_hdr_fs.format(
|
||||
sep = self.detail_display_separator
|
||||
|
||||
return self.print_hdr_fs.format(
|
||||
a = capfirst(self.desc),
|
||||
b = self.rpc.blockcount,
|
||||
c = make_timestr(self.rpc.cur_date),
|
||||
d = ('' if self.proto.chain_name == 'mainnet' else
|
||||
'Chain: {}\n'.format((nocolor,green)[color](self.proto.chain_name.upper())) ),
|
||||
d = 'Network: {}\n'.format((nocolor,green)[color](
|
||||
self.proto.coin + ' ' +
|
||||
self.proto.chain_name.upper() )),
|
||||
e = ' '.join(self.sort_info(include_group=False)),
|
||||
f = '\n'.join(self.gen_print_output(color,show_confs)),
|
||||
f = sep.join(self.gen_detail_display(color)),
|
||||
g = self.proto.dcoin,
|
||||
h = self.total.hl(color=color) if hasattr(self,'total') else None )
|
||||
|
||||
return self.fmt_print
|
||||
|
||||
async def view_and_sort(self):
|
||||
from ..opts import opt
|
||||
from ..term import get_char
|
||||
|
|
@ -201,10 +229,10 @@ class TwCommon:
|
|||
ERASE_ALL = '\033[0J'
|
||||
|
||||
while True:
|
||||
msg_r('' if self.no_output else '\n\n' if opt.no_blank else CUR_HOME+ERASE_ALL)
|
||||
msg_r('' if self.no_output else '\n\n' if (opt.no_blank or g.test_suite) else CUR_HOME+ERASE_ALL)
|
||||
reply = get_char(
|
||||
'' if self.no_output else (
|
||||
await self.format_for_display()
|
||||
await self.format_squeezed()
|
||||
+ '\n'
|
||||
+ (self.oneshot_msg or '')
|
||||
+ self.prompt
|
||||
|
|
@ -219,67 +247,73 @@ class TwCommon:
|
|||
continue
|
||||
|
||||
action = self.key_mappings[reply]
|
||||
if action.startswith('s_'):
|
||||
if hasattr(self.action,action):
|
||||
await self.action().run(self,action)
|
||||
elif action.startswith('s_'): # put here to allow overriding by action method
|
||||
self.do_sort(action[2:])
|
||||
if action == 's_twmmid':
|
||||
self.show_mmid = True
|
||||
elif action == 'd_days':
|
||||
af = self.age_fmts_interactive
|
||||
self.age_fmt = af[(af.index(self.age_fmt) + 1) % len(af)]
|
||||
if self.update_params_on_age_toggle:
|
||||
self.set_column_params()
|
||||
elif action == 'd_mmid':
|
||||
self.show_mmid = not self.show_mmid
|
||||
elif action == 'd_group':
|
||||
if self.can_group:
|
||||
self.group = not self.group
|
||||
elif action == 'd_redraw':
|
||||
elif hasattr(self.item_action,action):
|
||||
await self.item_action().run(self,action)
|
||||
self.set_column_params()
|
||||
elif action == 'd_reverse':
|
||||
self.data.reverse()
|
||||
self.reverse = not self.reverse
|
||||
elif action == 'a_quit':
|
||||
msg('')
|
||||
return self.data
|
||||
elif hasattr(self.action,action):
|
||||
await self.action(self).run(action)
|
||||
elif hasattr(self.item_action,action):
|
||||
await self.item_action(self).run(action)
|
||||
self.set_column_params()
|
||||
|
||||
class action:
|
||||
|
||||
def __init__(self,parent):
|
||||
self.parent = parent
|
||||
async def run(self,parent,action):
|
||||
ret = getattr(self,action)(parent)
|
||||
if type(ret).__name__ == 'coroutine':
|
||||
await ret
|
||||
|
||||
async def run(self,action):
|
||||
await getattr(self,action)(self.parent)
|
||||
def d_days(self,parent):
|
||||
af = parent.age_fmts_interactive
|
||||
parent.age_fmt = af[(af.index(parent.age_fmt) + 1) % len(af)]
|
||||
if parent.update_params_on_age_toggle:
|
||||
parent.set_column_params()
|
||||
|
||||
async def a_print(self,parent):
|
||||
outfile = '{}-{}{}[{}].out'.format(
|
||||
def d_redraw(self,parent):
|
||||
parent.set_column_params()
|
||||
|
||||
def d_reverse(self,parent):
|
||||
parent.data.reverse()
|
||||
parent.reverse = not parent.reverse
|
||||
|
||||
async def a_print_detail(self,parent):
|
||||
return await self._print(parent,output_type='detail')
|
||||
|
||||
async def a_print_squeezed(self,parent):
|
||||
return await self._print(parent,output_type='squeezed')
|
||||
|
||||
async def _print(self,parent,output_type):
|
||||
outfile = '{}{}-{}{}[{}].out'.format(
|
||||
parent.dump_fn_pfx,
|
||||
f'-{output_type}' if len(parent.print_output_types) > 1 else '',
|
||||
parent.proto.dcoin,
|
||||
('' if parent.proto.network == 'mainnet' else '-'+parent.proto.network.upper()),
|
||||
','.join(parent.sort_info(include_group=False)).lower() )
|
||||
','.join(parent.sort_info(include_group=False)).replace(' ','') )
|
||||
msg('')
|
||||
from ..fileutil import write_data_to_file
|
||||
from ..exception import UserNonConfirmation
|
||||
hdr = {
|
||||
'squeezed': f'[screen print truncated to width {parent.cols}]\n',
|
||||
'detail': '',
|
||||
}[output_type]
|
||||
try:
|
||||
write_data_to_file(
|
||||
outfile,
|
||||
await parent.format_for_printing(color=False),
|
||||
desc = f'{parent.desc} listing' )
|
||||
outfile = outfile,
|
||||
data = hdr + await getattr(parent,f'format_{output_type}')(color=False),
|
||||
desc = f'{parent.desc} listing' )
|
||||
except UserNonConfirmation as e:
|
||||
parent.oneshot_msg = red(f'File {outfile!r} not overwritten by user request\n\n')
|
||||
parent.oneshot_msg = yellow(f'File {outfile!r} not overwritten by user request\n\n')
|
||||
else:
|
||||
parent.oneshot_msg = yellow(f'Data written to {outfile!r}\n\n')
|
||||
parent.oneshot_msg = green(f'Data written to {outfile!r}\n\n')
|
||||
|
||||
async def a_view(self,parent):
|
||||
do_pager(parent.fmt_display)
|
||||
do_pager( await parent.format_squeezed(color=True,cached=True) )
|
||||
self.post_view(parent)
|
||||
|
||||
async def a_view_wide(self,parent):
|
||||
do_pager( await parent.format_for_printing(color=True) )
|
||||
async def a_view_detail(self,parent):
|
||||
do_pager( await parent.format_detail(color=True) )
|
||||
self.post_view(parent)
|
||||
|
||||
def post_view(self,parent):
|
||||
|
|
@ -290,19 +324,16 @@ class TwCommon:
|
|||
|
||||
class item_action:
|
||||
|
||||
def __init__(self,parent):
|
||||
self.parent = parent
|
||||
|
||||
async def run(self,action):
|
||||
async def run(self,parent,action):
|
||||
msg('')
|
||||
while True:
|
||||
ret = line_input(f'Enter {self.parent.item_desc} number (or RETURN to return to main menu): ')
|
||||
ret = line_input(f'Enter {parent.item_desc} number (or RETURN to return to main menu): ')
|
||||
if ret == '':
|
||||
return None
|
||||
idx = get_obj(MMGenIdx,n=ret,silent=True)
|
||||
if not idx or idx < 1 or idx > len(self.parent.data):
|
||||
msg(f'Choice must be a single number between 1 and {len(self.parent.data)}')
|
||||
elif (await getattr(self,action)(self.parent,idx)) != 'redo':
|
||||
if not idx or idx < 1 or idx > len(parent.data):
|
||||
msg(f'Choice must be a single number between 1 and {len(parent.data)}')
|
||||
elif (await getattr(self,action)(parent,idx)) != 'redo':
|
||||
break
|
||||
|
||||
class TwMMGenID(str,Hilite,InitErrors,MMGenObject):
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ class TwUnspentOutputs(MMGenObject,TwCommon,metaclass=AsyncInit):
|
|||
watch-only wallet using 'mmgen-addrimport' and then re-run this program.
|
||||
"""
|
||||
update_params_on_age_toggle = False
|
||||
detail_display_separator = '\n'
|
||||
print_output_types = ('detail',)
|
||||
|
||||
class MMGenTwUnspentOutput(MMGenListItem):
|
||||
txid = ListItemAttr(CoinTxID)
|
||||
|
|
@ -136,23 +138,16 @@ class TwUnspentOutputs(MMGenObject,TwCommon,metaclass=AsyncInit):
|
|||
['col1_w','mmid_w','addr_w','btaddr_w','label_w','tx_w','txdots']
|
||||
)(col1_w, mmid_w, addr_w, btaddr_w, label_w, tx_w, txdots)
|
||||
|
||||
def gen_display_output(self,c):
|
||||
fs = self.display_fs_fs.format( cw=c.col1_w, tw=c.tx_w )
|
||||
hdr_fs = self.display_hdr_fs_fs.format( cw=c.col1_w, tw=c.tx_w )
|
||||
def gen_squeezed_display(self,c,color):
|
||||
fs = self.squeezed_fs_fs.format( cw=c.col1_w, tw=c.tx_w )
|
||||
hdr_fs = self.squeezed_hdr_fs_fs.format( cw=c.col1_w, tw=c.tx_w )
|
||||
yield hdr_fs.format(
|
||||
n = 'Num',
|
||||
t = 'TXid'.ljust(c.tx_w - 2) + ' Vout',
|
||||
a = 'Address'.ljust(c.addr_w),
|
||||
A = f'Amt({self.proto.dcoin})'.ljust(self.disp_prec+5),
|
||||
A2 = f' Amt({self.proto.coin})'.ljust(self.disp_prec+4),
|
||||
c = {
|
||||
'confs': 'Confs',
|
||||
'block': 'Block',
|
||||
'days': 'Age(d)',
|
||||
'date': 'Date',
|
||||
'date_time': 'Date',
|
||||
}[self.age_fmt],
|
||||
).rstrip()
|
||||
c = self.age_hdr ).rstrip()
|
||||
|
||||
for n,i in enumerate(self.data):
|
||||
addr_dots = '|' + '.'*(c.addr_w-1)
|
||||
|
|
@ -163,20 +158,20 @@ class TwUnspentOutputs(MMGenObject,TwCommon,metaclass=AsyncInit):
|
|||
f'Non-{g.proj_name}'
|
||||
),
|
||||
width = c.mmid_w,
|
||||
color = True )
|
||||
color = color )
|
||||
|
||||
if self.show_mmid:
|
||||
addr_out = '{} {}{}'.format((
|
||||
type(i.addr).fmtc(addr_dots,width=c.btaddr_w,color=True) if i.skip == 'addr' else
|
||||
i.addr.fmt(width=c.btaddr_w,color=True)
|
||||
type(i.addr).fmtc(addr_dots,width=c.btaddr_w,color=color) if i.skip == 'addr' else
|
||||
i.addr.fmt(width=c.btaddr_w,color=color)
|
||||
),
|
||||
mmid_disp,
|
||||
(' ' + i.label.fmt(width=c.label_w,color=True)) if c.label_w > 0 else ''
|
||||
(' ' + i.label.fmt(width=c.label_w,color=color)) if c.label_w > 0 else ''
|
||||
)
|
||||
else:
|
||||
addr_out = (
|
||||
type(i.addr).fmtc(addr_dots,width=c.addr_w,color=True) if i.skip=='addr' else
|
||||
i.addr.fmt(width=c.addr_w,color=True) )
|
||||
type(i.addr).fmtc(addr_dots,width=c.addr_w,color=color) if i.skip=='addr' else
|
||||
i.addr.fmt(width=c.addr_w,color=color) )
|
||||
|
||||
yield fs.format(
|
||||
n = str(n+1)+')',
|
||||
|
|
@ -186,18 +181,21 @@ class TwUnspentOutputs(MMGenObject,TwCommon,metaclass=AsyncInit):
|
|||
i.txid[:c.tx_w-len(c.txdots)] + c.txdots ),
|
||||
v = i.vout,
|
||||
a = addr_out,
|
||||
A = i.amt.fmt(color=True,prec=self.disp_prec),
|
||||
A2 = (i.amt2.fmt(color=True,prec=self.disp_prec) if i.amt2 is not None else ''),
|
||||
A = i.amt.fmt(color=color,prec=self.disp_prec),
|
||||
A2 = (i.amt2.fmt(color=color,prec=self.disp_prec) if i.amt2 is not None else ''),
|
||||
c = self.age_disp(i,self.age_fmt),
|
||||
).rstrip()
|
||||
|
||||
def gen_print_output(self,color,show_confs):
|
||||
def gen_detail_display(self,color):
|
||||
|
||||
addr_w = max(len(i.addr) for i in self.data)
|
||||
mmid_w = max(len(('',i.twmmid)[i.twmmid.type=='mmgen']) for i in self.data) or 12 # DEADBEEF:S:1
|
||||
fs = self.print_fs_fs.format(
|
||||
|
||||
fs = self.wide_fs_fs.format(
|
||||
tw = self.txid_w + 3,
|
||||
cf = '{c:<8} ' if show_confs else '',
|
||||
cf = '{c:<8} ',
|
||||
aw = self.proto.coin_amt.max_prec + 5 )
|
||||
|
||||
yield fs.format(
|
||||
n = 'Num',
|
||||
t = 'Tx ID,Vout',
|
||||
|
|
@ -211,6 +209,7 @@ class TwUnspentOutputs(MMGenObject,TwCommon,metaclass=AsyncInit):
|
|||
l = 'Label' )
|
||||
|
||||
max_lbl_len = max([len(i.label) for i in self.data if i.label] or [2])
|
||||
|
||||
for n,i in enumerate(self.data):
|
||||
yield fs.format(
|
||||
n = str(n+1) + ')',
|
||||
|
|
@ -244,6 +243,19 @@ class TwUnspentOutputs(MMGenObject,TwCommon,metaclass=AsyncInit):
|
|||
len(self.data),
|
||||
suf(self.data) ))
|
||||
|
||||
class action(TwCommon.action):
|
||||
|
||||
def s_twmmid(self,parent):
|
||||
parent.do_sort('twmmid')
|
||||
parent.show_mmid = True
|
||||
|
||||
def d_mmid(self,parent):
|
||||
parent.show_mmid = not parent.show_mmid
|
||||
|
||||
def d_group(self,parent):
|
||||
if parent.can_group:
|
||||
parent.group = not parent.group
|
||||
|
||||
class item_action(TwCommon.item_action):
|
||||
|
||||
async def a_balance_refresh(self,uo,idx):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue