CoinAmt: improve columnar formatting
This commit is contained in:
parent
357f7806b8
commit
9c07442191
10 changed files with 43 additions and 34 deletions
27
mmgen/amt.py
27
mmgen/amt.py
|
|
@ -38,7 +38,6 @@ class CoinAmt(Decimal,Hilite,InitErrors): # abstract class
|
|||
max_prec = 0 # number of decimal places for this coin
|
||||
max_amt = None # coin supply if known, otherwise None
|
||||
units = () # defined unit names, e.g. ('satoshi',...)
|
||||
amt_fs = '0.0' # format string for the fmt() method
|
||||
|
||||
def __new__(cls,num,from_unit=None,from_decimal=False):
|
||||
if type(num) == cls:
|
||||
|
|
@ -73,21 +72,18 @@ class CoinAmt(Decimal,Hilite,InitErrors): # abstract class
|
|||
def fmtc(cls):
|
||||
cls.method_not_implemented()
|
||||
|
||||
def fmt(self,fs=None,color=False,suf='',prec=1000):
|
||||
if fs == None:
|
||||
fs = self.amt_fs
|
||||
def fmt(self,color=False,iwidth=1,prec=None): # iwidth: width of the integer part
|
||||
s = self.__str__()
|
||||
if '.' in fs:
|
||||
p1,p2 = list(map(int,fs.split('.',1)))
|
||||
ss = s.split('.',1)
|
||||
if len(ss) == 2:
|
||||
a,b = ss
|
||||
ret = a.rjust(p1) + '.' + ((b+suf).ljust(p2+len(suf)))[:prec]
|
||||
else:
|
||||
ret = s.rjust(p1) + suf + (' ' * (p2+1))[:prec+1-len(suf)]
|
||||
prec = prec or self.max_prec
|
||||
if '.' in s:
|
||||
a,b = s.split('.',1)
|
||||
return self.colorize(
|
||||
a.rjust(iwidth) + '.' + b.ljust(prec)[:prec], # truncation, not rounding!
|
||||
color = color )
|
||||
else:
|
||||
ret = s.ljust(int(fs))
|
||||
return self.colorize(ret,color=color)
|
||||
return self.colorize(
|
||||
s.rjust(iwidth).ljust(iwidth+prec+1),
|
||||
color = color )
|
||||
|
||||
def hl(self,color=True):
|
||||
return self.colorize(self.__str__(),color=color)
|
||||
|
|
@ -165,7 +161,6 @@ class BTCAmt(CoinAmt):
|
|||
max_amt = 21000000
|
||||
satoshi = Decimal('0.00000001')
|
||||
units = ('satoshi',)
|
||||
amt_fs = '4.8'
|
||||
|
||||
class BCHAmt(BTCAmt):
|
||||
pass
|
||||
|
|
@ -177,7 +172,6 @@ class XMRAmt(CoinAmt):
|
|||
max_prec = 12
|
||||
atomic = Decimal('0.000000000001')
|
||||
units = ('atomic',)
|
||||
amt_fs = '4.12'
|
||||
|
||||
# Kwei (babbage) 3, Mwei (lovelace) 6, Gwei (shannon) 9, µETH (szabo) 12, mETH (finney) 15, ETH 18
|
||||
class ETHAmt(CoinAmt):
|
||||
|
|
@ -189,7 +183,6 @@ class ETHAmt(CoinAmt):
|
|||
szabo = Decimal('0.000001')
|
||||
finney = Decimal('0.001')
|
||||
units = ('wei','Kwei','Mwei','Gwei','szabo','finney')
|
||||
amt_fs = '4.18'
|
||||
|
||||
def toWei(self):
|
||||
return int(Decimal(self) // self.wei)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
13.3.dev19
|
||||
13.3.dev20
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ Actions: [q]uit, r[e]draw, [D]elete address, add [l]abel:
|
|||
'num': max(2,len(str(len(data)))+1),
|
||||
'mmid': max(len(d.twmmid.disp) for d in data),
|
||||
'used': 0,
|
||||
'amt': self.disp_prec + 5,
|
||||
'amt': self.amt_widths['amt'],
|
||||
'date': 0,
|
||||
'block': 0,
|
||||
'date_time': 0,
|
||||
|
|
|
|||
|
|
@ -75,8 +75,8 @@ Actions: [q]uit view, [p]rint to file, pager [v]iew, [w]ide view,
|
|||
widths = { # fixed cols
|
||||
'num': max(2,len(str(len(data)))+1),
|
||||
'mmid': max(len(d.twmmid.disp) for d in data) if self.show_mmid else 0,
|
||||
'amt': self.disp_prec + 5,
|
||||
'amt2': self.disp_prec + 5 if self.has_amt2 else 0,
|
||||
'amt': self.amt_widths['amt'],
|
||||
'amt2': self.amt_widths.get('amt2',0),
|
||||
'spc': (5 if self.show_mmid else 3) + self.has_amt2, # 5(3) spaces in fs
|
||||
'txid': 0,
|
||||
'vout': 0,
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ class TwAddresses(TwView):
|
|||
'num': max(2,len(str(len(data)))+1),
|
||||
'mmid': max(len(d.twmmid.disp) for d in data),
|
||||
'used': 4,
|
||||
'amt': self.disp_prec + 5,
|
||||
'amt': self.amt_widths['amt'],
|
||||
'date': self.age_w if self.has_age else 0,
|
||||
'block': self.age_col_params['block'][0] if wide and self.has_age else 0,
|
||||
'date_time': self.age_col_params['date_time'][0] if wide and self.has_age else 0,
|
||||
|
|
@ -179,7 +179,7 @@ class TwAddresses(TwView):
|
|||
u = yes if d.recvd else no,
|
||||
a = d.addr.fmt( color=color, width=cw.addr ),
|
||||
c = d.comment.fmt( width=cw.comment, color=color, nullrepl='-' ),
|
||||
A = d.amt.fmt( color=color, prec=self.disp_prec ),
|
||||
A = d.amt.fmt( color=color, iwidth=cw.iwidth, prec=self.disp_prec ),
|
||||
d = self.age_disp( d, self.age_fmt )
|
||||
)
|
||||
|
||||
|
|
@ -208,7 +208,7 @@ class TwAddresses(TwView):
|
|||
u = yes if d.recvd else no,
|
||||
a = d.addr.fmt( color=color, width=cw.addr ),
|
||||
c = d.comment.fmt( width=cw.comment, color=color, nullrepl='-' ),
|
||||
A = d.amt.fmt( color=color, prec=self.disp_prec ),
|
||||
A = d.amt.fmt( color=color, iwidth=cw.iwidth, prec=self.disp_prec ),
|
||||
b = self.age_disp( d, 'block' ),
|
||||
D = self.age_disp( d, 'date_time' ),
|
||||
).rstrip()
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ class TwGetBalance(MMGenObject,metaclass=AsyncInit):
|
|||
return len(str(int(max(v[colname] for v in self.data.values())))) + iwidth_adj
|
||||
|
||||
def make_col(label,col):
|
||||
return(self.data[label][col].fmt(fs=f'{iwidths[col]}.{add_w-1}',color=color))
|
||||
return(self.data[label][col].fmt(iwidth=iwidths[col],color=color))
|
||||
|
||||
if color:
|
||||
from ..color import red,green,yellow
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
tw.txhistory: Tracking wallet transaction history class for the MMGen suite
|
||||
"""
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
from ..util import fmt
|
||||
from ..objmethods import MMGenObject
|
||||
from ..obj import NonNegativeInt
|
||||
|
|
@ -49,6 +51,10 @@ class TwTxHistory(TwView):
|
|||
def filter_data(self):
|
||||
return (d for d in self.data if d.confirmations > 0 or self.show_unconfirmed)
|
||||
|
||||
def set_amt_widths(self,data):
|
||||
amts_tuple = namedtuple('amts_data',['amt'])
|
||||
return super().set_amt_widths([amts_tuple(d.amt_disp(self.show_total_amt)) for d in data])
|
||||
|
||||
def get_column_widths(self,data,wide=False):
|
||||
|
||||
# var cols: inputs outputs comment [txid]
|
||||
|
|
@ -77,7 +83,7 @@ class TwTxHistory(TwView):
|
|||
widths = { # fixed cols
|
||||
'num': max(2,len(str(len(data)))+1),
|
||||
'date': self.age_w,
|
||||
'amt': self.disp_prec + 5,
|
||||
'amt': self.amt_widths['amt'],
|
||||
'spc': 6 + self.show_txid, # 5(6) spaces between cols + 1 leading space in fs
|
||||
}
|
||||
|
||||
|
|
@ -109,7 +115,7 @@ class TwTxHistory(TwView):
|
|||
t = d.txid_disp( width=cw.txid, color=color ) if hasattr(cw,'txid') else None,
|
||||
d = d.age_disp( self.age_fmt, width=self.age_w, color=color ),
|
||||
i = d.vouts_disp( 'inputs', width=cw.inputs, color=color ),
|
||||
A = d.amt_disp(self.show_total_amt).fmt( prec=self.disp_prec, color=color ),
|
||||
A = d.amt_disp(self.show_total_amt).fmt( iwidth=cw.iwidth, prec=self.disp_prec, color=color ),
|
||||
o = d.vouts_disp( 'outputs', width=cw.outputs, color=color ),
|
||||
c = d.comment.fmt( width=cw.comment, color=color, nullrepl='-' ) ).rstrip()
|
||||
|
||||
|
|
|
|||
|
|
@ -132,8 +132,8 @@ class TwUnspentOutputs(TwView):
|
|||
'num': max(2,len(str(len(data)))+1),
|
||||
'vout': 4,
|
||||
'mmid': max(len(d.twmmid.disp) for d in data) if self.show_mmid else 0,
|
||||
'amt': self.disp_prec + 5,
|
||||
'amt2': 0,
|
||||
'amt': self.amt_widths['amt'],
|
||||
'amt2': self.amt_widths.get('amt2',0),
|
||||
'block': self.age_col_params['block'][0] if wide else 0,
|
||||
'date_time': self.age_col_params['date_time'][0] if wide else 0,
|
||||
'date': self.age_w,
|
||||
|
|
@ -177,8 +177,8 @@ class TwUnspentOutputs(TwView):
|
|||
m = (MMGenID.fmtc( '.'*cw.mmid, color=color ) if d.skip == 'addr'
|
||||
else d.twmmid.fmt( width=cw.mmid, color=color )) if cw.mmid else None,
|
||||
c = d.comment.fmt( width=cw.comment, color=color, nullrepl='-' ) if cw.comment else None,
|
||||
A = d.amt.fmt( color=color, prec=self.disp_prec ),
|
||||
B = d.amt2.fmt( color=color, prec=self.disp_prec ) if cw.amt2 else None,
|
||||
A = d.amt.fmt( color=color, iwidth=cw.iwidth, prec=self.disp_prec ),
|
||||
B = d.amt2.fmt( color=color, iwidth=cw.iwidth2, prec=self.disp_prec ) if cw.amt2 else None,
|
||||
d = self.age_disp(d,self.age_fmt),
|
||||
)
|
||||
|
||||
|
|
@ -203,8 +203,8 @@ class TwUnspentOutputs(TwView):
|
|||
v = ' ' + d.vout.fmt( width=cw.vout-1, color=color ) if cw.vout else None,
|
||||
a = d.addr.fmt( width=cw.addr, color=color ),
|
||||
m = d.twmmid.fmt( width=cw.mmid, color=color ),
|
||||
A = d.amt.fmt( color=color, prec=self.disp_prec ),
|
||||
B = d.amt2.fmt( color=color, prec=self.disp_prec ) if cw.amt2 else None,
|
||||
A = d.amt.fmt( color=color, iwidth=cw.iwidth, prec=self.disp_prec ),
|
||||
B = d.amt2.fmt( color=color, iwidth=cw.iwidth2, prec=self.disp_prec ) if cw.amt2 else None,
|
||||
b = self.age_disp(d,'block'),
|
||||
D = self.age_disp(d,'date_time'),
|
||||
c = d.comment.fmt( width=cw.comment, color=color, nullrepl='-' ),
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ class TwView(MMGenObject,metaclass=AsyncInit):
|
|||
if self.has_wallet:
|
||||
from .ctl import TrackingWallet
|
||||
self.wallet = await TrackingWallet(proto,mode='w')
|
||||
self.amt_keys = {'amt':'iwidth','amt2':'iwidth2'} if self.has_amt2 else {'amt':'iwidth'}
|
||||
|
||||
@property
|
||||
def age_w(self):
|
||||
|
|
@ -225,10 +226,12 @@ class TwView(MMGenObject,metaclass=AsyncInit):
|
|||
|
||||
def do_ret(freews):
|
||||
widths.update({k:minws[k] + freews.get(k,0) for k in minws})
|
||||
widths.update({ikey: widths[key] - self.disp_prec - 1 for key,ikey in self.amt_keys.items()})
|
||||
return namedtuple('column_widths',widths.keys())(*widths.values())
|
||||
|
||||
def do_ret_max():
|
||||
widths.update({k:max(minws[k],maxws[k]) for k in minws})
|
||||
widths.update({ikey: widths[key] - self.disp_prec - 1 for key,ikey in self.amt_keys.items()})
|
||||
return namedtuple('column_widths',widths.keys())(*widths.values())
|
||||
|
||||
def get_freews(cols,varws,varw,minw):
|
||||
|
|
@ -308,6 +311,12 @@ class TwView(MMGenObject,metaclass=AsyncInit):
|
|||
self.proto.dcoin
|
||||
) if hasattr(self,'total') else ''
|
||||
|
||||
def set_amt_widths(self,data):
|
||||
# width of amts column: min(7,width of integer part) + len('.') + width of fractional part
|
||||
self.amt_widths = {k:
|
||||
min(7,max(len(str(getattr(d,k).to_integral_value())) for d in data)) + 1 + self.disp_prec
|
||||
for k in self.amt_keys}
|
||||
|
||||
async def format(self,display_type,color=True,cached=False,interactive=False):
|
||||
|
||||
if not cached:
|
||||
|
|
@ -322,6 +331,7 @@ class TwView(MMGenObject,metaclass=AsyncInit):
|
|||
data = self.disp_data = list(self.filter_data()) # method could be a generator
|
||||
|
||||
if data and dt.need_column_widths:
|
||||
self.set_amt_widths(data)
|
||||
cw = self.get_column_widths(data,wide=dt.detail)
|
||||
cwh = cw._asdict()
|
||||
fp = self.fs_params
|
||||
|
|
|
|||
|
|
@ -276,7 +276,7 @@ class MoneroWalletOps:
|
|||
uarg_info = xmrwallet_uarg_info
|
||||
|
||||
def fmt_amt(amt):
|
||||
return self.proto.coin_amt(amt,from_unit='atomic').fmt(fs='5.12',color=True)
|
||||
return self.proto.coin_amt(amt,from_unit='atomic').fmt( iwidth=5, prec=12, color=True )
|
||||
def hl_amt(amt):
|
||||
return self.proto.coin_amt(amt,from_unit='atomic').hl()
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue