Minor fixes and improvements
- mmgen-tool listaddresses: add 'show_age','show_days' options
- init_fail(): make 'silent' override 'MMGEN_TRACEBACK', fixing regression
introduced by 3909339
- test/test.py: improve formatting of --list output
- test/{test,objtest,scrambletest}.py, mmgen/tool.py: indentation (whitespace) fixes
This commit is contained in:
parent
65e2db0512
commit
f7e54cce93
8 changed files with 66 additions and 61 deletions
|
|
@ -150,9 +150,7 @@ if Command not in tool.cmd_data:
|
|||
die(1,"'%s': no such command" % Command.lower())
|
||||
|
||||
args,kwargs = tool.process_args(Command,cmd_args)
|
||||
try:
|
||||
ret = tool.__dict__[Command](*args,**kwargs)
|
||||
except Exception as e:
|
||||
die(1,'{}'.format(e))
|
||||
|
||||
sys.exit(0 if ret in (None,True) else 1) # some commands die, some return False on failure
|
||||
ret = tool.__dict__[Command](*args,**kwargs)
|
||||
|
||||
sys.exit((1,0)[ret in (None,True)]) # some commands die, some return False on failure
|
||||
|
|
|
|||
30
mmgen/obj.py
30
mmgen/obj.py
|
|
@ -110,17 +110,15 @@ class InitErrors(object):
|
|||
assert on_fail in ('die','return','silent','raise'),'arg_chk in class {}'.format(cls.__name__)
|
||||
|
||||
@staticmethod
|
||||
def init_fail(m,on_fail,silent=False):
|
||||
def init_fail(m,on_fail):
|
||||
if os.getenv('MMGEN_TRACEBACK'): on_fail == 'raise'
|
||||
from mmgen.util import die,msg
|
||||
if silent: m = ''
|
||||
if os.getenv('MMGEN_TRACEBACK'):
|
||||
raise ValueError,m
|
||||
elif on_fail == 'die': die(1,m)
|
||||
if on_fail == 'silent': return None # TODO: return False instead?
|
||||
elif on_fail == 'raise': raise ValueError,m
|
||||
elif on_fail == 'die': die(1,m)
|
||||
elif on_fail == 'return':
|
||||
if m: msg(m)
|
||||
return None # TODO: change to False
|
||||
elif on_fail == 'silent': return None # same here
|
||||
elif on_fail == 'raise': raise ValueError,m
|
||||
return None # TODO: here too?
|
||||
|
||||
class Hilite(object):
|
||||
|
||||
|
|
@ -134,11 +132,11 @@ class Hilite(object):
|
|||
center=False,nullrepl='',app='',appcolor=False):
|
||||
if width == None: width = cls.width
|
||||
if trunc_ok == None: trunc_ok = cls.trunc_ok
|
||||
assert width > 0
|
||||
assert width > 0,'Width must be > 0'
|
||||
if s == '' and nullrepl:
|
||||
s,center = nullrepl,True
|
||||
if center: s = s.center(width)
|
||||
assert type(encl) is str and len(encl) in (0,2)
|
||||
assert type(encl) is str and len(encl) in (0,2),'type(encl) must be str and len(encl) be in (0,2)'
|
||||
a,b = list(encl) if encl else ('','')
|
||||
if trunc_ok and len(s) > width: s = s[:width]
|
||||
if app:
|
||||
|
|
@ -310,9 +308,9 @@ class BTCAmt(Decimal,Hilite,InitErrors):
|
|||
raise NotImplementedError
|
||||
|
||||
def fmt(self,fs='3.8',color=False,suf=''):
|
||||
s = self.__str__(color=False)
|
||||
s = str(int(self)) if int(self) == self else self.normalize().__format__('f')
|
||||
if '.' in fs:
|
||||
p1,p2 = [int(i) for i in fs.split('.',1)]
|
||||
p1,p2 = map(int,fs.split('.',1))
|
||||
ss = s.split('.',1)
|
||||
if len(ss) == 2:
|
||||
a,b = ss
|
||||
|
|
@ -327,11 +325,9 @@ class BTCAmt(Decimal,Hilite,InitErrors):
|
|||
return self.__str__(color=color)
|
||||
|
||||
def __str__(self,color=False): # format simply, no exponential notation
|
||||
if int(self) == self:
|
||||
ret = str(int(self))
|
||||
else:
|
||||
ret = self.normalize().__format__('f')
|
||||
return self.colorize(ret,color=color)
|
||||
return self.colorize(
|
||||
str(int(self)) if int(self) == self else self.normalize().__format__('f'),
|
||||
color=color)
|
||||
|
||||
def __repr__(self):
|
||||
return "{}('{}')".format(type(self).__name__,self.__str__())
|
||||
|
|
|
|||
|
|
@ -77,8 +77,8 @@ cmd_data = OrderedDict([
|
|||
('Mn_stats', ["wordlist [str='electrum']"]),
|
||||
('Mn_printlist', ["wordlist [str='electrum']"]),
|
||||
|
||||
('Listaddress',['<{} address> [str]'.format(pnm),'minconf [int=1]','pager [bool=False]','showempty [bool=True]''showbtcaddr [bool=True]']),
|
||||
('Listaddresses',["addrs [str='']",'minconf [int=1]','showempty [bool=False]','pager [bool=False]','showbtcaddrs [bool=True]','all_labels [bool=False]',"sort [str=''] (options: reverse, age)"]),
|
||||
('Listaddress',['<{} address> [str]'.format(pnm),'minconf [int=1]','pager [bool=False]','showempty [bool=True]','showbtcaddr [bool=True]','show_age [bool=False]','show_days [bool=True]']),
|
||||
('Listaddresses',["addrs [str='']",'minconf [int=1]','showempty [bool=False]','pager [bool=False]','showbtcaddrs [bool=True]','all_labels [bool=False]',"sort [str=''] (options: reverse, age)",'show_age [bool=False]','show_days [bool=True]']),
|
||||
('Getbalance', ['minconf [int=1]','quiet [bool=False]']),
|
||||
('Txview', ['<{} TX file(s)> [str]'.format(pnm),'pager [bool=False]','terse [bool=False]',"sort [str='mtime'] (options: ctime, atime)",'MARGS']),
|
||||
('Twview', ["sort [str='age']",'reverse [bool=False]','show_days [bool=True]','show_mmid [bool=True]','minconf [int=1]','wide [bool=False]','pager [bool=False]']),
|
||||
|
|
@ -625,11 +625,16 @@ def monero_wallet_ops(infile,op,blockheight=None,addrs=None):
|
|||
|
||||
# ================ RPC commands ================== #
|
||||
|
||||
def Listaddress(addr,minconf=1,pager=False,showempty=True,showbtcaddr=True):
|
||||
return Listaddresses(addrs=addr,minconf=minconf,pager=pager,showempty=showempty,showbtcaddrs=showbtcaddr)
|
||||
def Listaddress(addr,minconf=1,pager=False,showempty=True,showbtcaddr=True,show_age=False,show_days=None):
|
||||
return Listaddresses(addrs=addr,minconf=minconf,pager=pager,
|
||||
showempty=showempty,showbtcaddrs=showbtcaddr,show_age=show_age,show_days=show_days)
|
||||
|
||||
# List MMGen addresses and their balances. TODO: move this code to AddrList
|
||||
def Listaddresses(addrs='',minconf=1,showempty=False,pager=False,showbtcaddrs=True,all_labels=False,sort=None):
|
||||
def Listaddresses(addrs='',minconf=1,
|
||||
showempty=False,pager=False,showbtcaddrs=True,all_labels=False,sort=None,show_age=False,show_days=None):
|
||||
|
||||
if show_days == None: show_days = False # user-set show_days triggers show_age
|
||||
else: show_age = True
|
||||
|
||||
if sort:
|
||||
sort = set(sort.split(','))
|
||||
|
|
@ -716,15 +721,19 @@ def Listaddresses(addrs='',minconf=1,showempty=False,pager=False,showbtcaddrs=Tr
|
|||
|
||||
out = ([],[green('Chain: {}'.format(g.chain.upper()))])[g.chain in ('testnet','regtest')]
|
||||
|
||||
fs = ('{mid} {cmt} {amt}','{mid} {addr} {cmt} {amt}')[showbtcaddrs]
|
||||
fs = '{{mid}}{} {{cmt}} {{amt}}{}'.format(('',' {addr}')[showbtcaddrs],('',' {age}')[show_age])
|
||||
mmaddrs = [k for k in addrs.keys() if k.type == 'mmgen']
|
||||
max_mmid_len = max(len(k) for k in mmaddrs) + 2 if mmaddrs else 10
|
||||
max_cmt_len = max(max(len(addrs[k]['lbl'].comment) for k in addrs),7)
|
||||
max_cmt_len = max(max(len(v['lbl'].comment) for v in addrs.values()),7)
|
||||
# pmsg([a.split('.')[1] for a in [str(v['amt']) for v in addrs.values()] if '.' in a])
|
||||
# fp: fractional part
|
||||
max_fp_len = max([len(a.split('.')[1]) for a in [str(v['amt']) for v in addrs.values()] if '.' in a] or [1])
|
||||
out += [fs.format(
|
||||
mid=MMGenID.fmtc('MMGenID',width=max_mmid_len),
|
||||
addr=CoinAddr.fmtc('ADDRESS'),
|
||||
cmt=TwComment.fmtc('COMMENT',width=max_cmt_len),
|
||||
amt='BALANCE'
|
||||
amt='{:{w}}'.format('BALANCE',w=max_fp_len+4),
|
||||
age=('CONFS','AGE')[show_days],
|
||||
)]
|
||||
|
||||
def sort_algo(j):
|
||||
|
|
@ -737,6 +746,7 @@ def Listaddresses(addrs='',minconf=1,showempty=False,pager=False,showbtcaddrs=Tr
|
|||
return j.sort_key
|
||||
|
||||
al_id_save = None
|
||||
confs_per_day = 60*60*24 / g.proto.secs_per_block
|
||||
for mmid in sorted(addrs,key=sort_algo,reverse=bool(sort and 'reverse' in sort)):
|
||||
if mmid.type == 'mmgen':
|
||||
if al_id_save and al_id_save != mmid.obj.al_id:
|
||||
|
|
@ -748,11 +758,14 @@ def Listaddresses(addrs='',minconf=1,showempty=False,pager=False,showbtcaddrs=Tr
|
|||
out.append('')
|
||||
al_id_save = None
|
||||
mmid_disp = 'Non-MMGen'
|
||||
e = addrs[mmid]
|
||||
out.append(fs.format(
|
||||
mid = MMGenID.fmtc(mmid_disp,width=max_mmid_len,color=True),
|
||||
addr=(addrs[mmid]['addr'].fmt(color=True) if showbtcaddrs else None),
|
||||
cmt=addrs[mmid]['lbl'].comment.fmt(width=max_cmt_len,color=True,nullrepl='-'),
|
||||
amt=addrs[mmid]['amt'].fmt('3.0',color=True)))
|
||||
mid=MMGenID.fmtc(mmid_disp,width=max_mmid_len,color=True),
|
||||
addr=(e['addr'].fmt(color=True) if showbtcaddrs else None),
|
||||
cmt=e['lbl'].comment.fmt(width=max_cmt_len,color=True,nullrepl='-'),
|
||||
amt=e['amt'].fmt('3.{}'.format(max_fp_len),color=True),
|
||||
age=mmid.confs / (1,confs_per_day)[show_days] if hasattr(mmid,'confs') else '-'
|
||||
))
|
||||
out.append('\nTOTAL: {} {}'.format(total.hl(color=True),g.coin))
|
||||
o = '\n'.join(out)
|
||||
return do_pager(o) if pager else Msg(o)
|
||||
|
|
|
|||
|
|
@ -860,13 +860,13 @@ def rpc_init(reinit=False):
|
|||
g.rpch = conn
|
||||
return conn
|
||||
|
||||
def format_text(s,indent=0,width=80):
|
||||
def format_par(s,indent=0,width=80,as_list=False):
|
||||
words,lines = s.split(),[]
|
||||
assert width >= indent + 4,'width must be >= indent + 4'
|
||||
while words:
|
||||
line = ''
|
||||
while len(line) <= (width-indent) and words:
|
||||
if len(line) + len(words[0]) + 1 > width-indent: break
|
||||
if line and len(line) + len(words[0]) + 1 > width-indent: break
|
||||
line += ('',' ')[bool(line)] + words.pop(0)
|
||||
lines.append(' '*indent + line)
|
||||
return '\n'.join(lines) + '\n'
|
||||
return lines if as_list else '\n'.join(lines) + '\n'
|
||||
|
|
|
|||
|
|
@ -5,12 +5,14 @@ sys.path.insert(0,'.')
|
|||
if 'TMUX' in os.environ: del os.environ['TMUX']
|
||||
os.environ['MMGEN_TRACEBACK'] = '1'
|
||||
|
||||
f = open('my.err','w')
|
||||
tb_source = open(sys.argv[1])
|
||||
tb_file = open('my.err','w')
|
||||
|
||||
try:
|
||||
sys.argv.pop(0)
|
||||
execfile(sys.argv[0])
|
||||
exec tb_source
|
||||
except SystemExit:
|
||||
# pass
|
||||
e = sys.exc_info()
|
||||
sys.exit(int(str(e[1])))
|
||||
except:
|
||||
|
|
@ -19,5 +21,5 @@ except:
|
|||
def red(s): return '{e}[31;1m{}{e}[0m'.format(s,e='\033')
|
||||
def yellow(s): return '{e}[33;1m{}{e}[0m'.format(s,e='\033')
|
||||
sys.stdout.write('{}{}'.format(yellow(''.join(l)),red(exc)))
|
||||
traceback.print_exc(file=f)
|
||||
traceback.print_exc(file=tb_file)
|
||||
sys.exit(1)
|
||||
|
|
|
|||
|
|
@ -193,19 +193,19 @@ tests = OrderedDict([
|
|||
'bad': ({'wif':1},),
|
||||
'good': ({
|
||||
'btc': (({'wif':'5KXEpVzjWreTcQoG5hX357s1969MUKNLuSfcszF6yu84kpsNZKb',
|
||||
'ret':'e0aef965b905a2fedf907151df8e0a6bac832aa697801c51f58bd2ecb4fd381c'},
|
||||
'ret':'e0aef965b905a2fedf907151df8e0a6bac832aa697801c51f58bd2ecb4fd381c'},
|
||||
{'wif':'KwWr9rDh8KK5TtDa3HLChEvQXNYcUXpwhRFUPc5uSNnMtqNKLFhk',
|
||||
'ret':'08d0ed83b64b68d56fa064be48e2385060ed205be2b1e63cd56d218038c3a05f'}),
|
||||
'ret':'08d0ed83b64b68d56fa064be48e2385060ed205be2b1e63cd56d218038c3a05f'}),
|
||||
({'wif':'93HsQEpH75ibaUJYi3QwwiQxnkW4dUuYFPXZxcbcKds7XrqHkY6',
|
||||
'ret':'e0aef965b905a2fedf907151df8e0a6bac832aa697801c51f58bd2ecb4fd381c'},
|
||||
'ret':'e0aef965b905a2fedf907151df8e0a6bac832aa697801c51f58bd2ecb4fd381c'},
|
||||
{'wif':'cMsqcmDYZP1LdKgqRh9L4ZRU9br28yvdmTPwW2YQwVSN9aQiMAoR',
|
||||
'ret':'08d0ed83b64b68d56fa064be48e2385060ed205be2b1e63cd56d218038c3a05f'})),
|
||||
'ltc': (({'wif':'6ufJhtQQiRYA3w2QvDuXNXuLgPFp15i3HR1Wp8An2mx1JnhhJAh',
|
||||
'ret':'470a974ffca9fca1299b706b09142077bea3acbab6d6480b87dbba79d5fd279b'},
|
||||
'ret':'470a974ffca9fca1299b706b09142077bea3acbab6d6480b87dbba79d5fd279b'},
|
||||
{'wif':'T41Fm7J3mtZLKYPMCLVSFARz4QF8nvSDhLAfW97Ds56Zm9hRJgn8',
|
||||
'ret':'1c6feab55a4c3b4ad1823d4ecacd1565c64228c01828cf44fb4db1e2d82c3d56'}),
|
||||
'ret':'1c6feab55a4c3b4ad1823d4ecacd1565c64228c01828cf44fb4db1e2d82c3d56'}),
|
||||
({'wif':'92iqzh6NqiKawyB1ronw66YtEHrU4rxRJ5T4aHniZqvuSVZS21f',
|
||||
'ret':'95b2aa7912550eacdd3844dcc14bee08ce7bc2434ad4858beb136021e945afeb'},
|
||||
'ret':'95b2aa7912550eacdd3844dcc14bee08ce7bc2434ad4858beb136021e945afeb'},
|
||||
{'wif':'cSaJAXBAm9ooHpVJgoxqjDG3AcareFy29Cz8mhnNTRijjv2HLgta',
|
||||
'ret':'94fa8b90c11fea8fb907c9376b919534b0a75b9a9621edf71a78753544b4101c'})),
|
||||
}[g.coin.lower()][bool(g.testnet)],
|
||||
|
|
@ -234,7 +234,7 @@ tests = OrderedDict([
|
|||
'bad': ('This text is too long for a transaction comment. '*2,),
|
||||
'good': (u'UTF-8 is OK: я','a good comment',)
|
||||
}),
|
||||
('MMGenPWIDString', { # forbidden = list(u' :/\\')
|
||||
('MMGenPWIDString', { # forbidden = list(u' :/\\')
|
||||
'bad': ('foo/','foo:','foo:\\'),
|
||||
'good': (u'qwerty@яяя',)
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -106,5 +106,5 @@ start_time = int(time.time())
|
|||
run_tests()
|
||||
|
||||
t = int(time.time()) - start_time
|
||||
m = '\nAll requested tests finished OK, elapsed time: {:02}:{:02}'
|
||||
m = '\nAll requested tests finished OK, elapsed time: {:02}:{:02}'
|
||||
msg(green(m.format(t/60,t%60)))
|
||||
|
|
|
|||
22
test/test.py
22
test/test.py
|
|
@ -907,6 +907,7 @@ if opt.list_cmds:
|
|||
from mmgen.term import get_terminal_size
|
||||
tw = get_terminal_size()[0]
|
||||
fs = ' {:<{w}} - {}'
|
||||
|
||||
Msg(green('AVAILABLE COMMANDS:'))
|
||||
w = max([len(i) for i in cmd_data])
|
||||
for cmd in cmd_data:
|
||||
|
|
@ -916,24 +917,19 @@ if opt.list_cmds:
|
|||
continue
|
||||
Msg(' '+fs.format(cmd,cmd_data[cmd][1],w=w))
|
||||
|
||||
w = max([len(i) for i in meta_cmds])
|
||||
Msg('\n'+green('AVAILABLE METACOMMANDS:'))
|
||||
for cmd in meta_cmds:
|
||||
ft = format_text(' '.join(meta_cmds[cmd]),width=tw,indent=4).lstrip()
|
||||
sep = '\n' if not ft else ' ' if len(ft.splitlines()[0]) + len(cmd) < tw - 4 else '\n '
|
||||
Msg_r(' {}{}{}'.format(yellow(cmd+':'),sep,ft))
|
||||
|
||||
w = max([len(i) for i in cmd_list])
|
||||
Msg('\n'+green('AVAILABLE COMMAND GROUPS:'))
|
||||
for cmd in cmd_list:
|
||||
ft = format_text(' '.join(cmd_list[cmd]),width=tw,indent=4).lstrip()
|
||||
sep = '\n' if not ft else ' ' if len(ft.splitlines()[0]) + len(cmd) < tw - 4 else '\n '
|
||||
Msg_r(' {}{}{}'.format(yellow(cmd+':'),sep,ft))
|
||||
for cl,lbl in ((meta_cmds,'METACOMMANDS'),(cmd_list,'COMMAND GROUPS')):
|
||||
w = max([len(i) for i in cl])
|
||||
Msg('\n'+green('AVAILABLE {}:'.format(lbl)))
|
||||
for cmd in cl:
|
||||
ft = format_par(' '.join(cl[cmd]),width=tw,indent=4,as_list=True)
|
||||
sep = '' if not ft else ' ' if len(ft[0]) + len(cmd) < tw - 4 else '\n '
|
||||
Msg(' {}{}{}'.format(yellow(cmd+':'),sep,'\n'.join(ft).lstrip()))
|
||||
|
||||
Msg('\n'+green('AVAILABLE UTILITIES:'))
|
||||
w = max([len(i) for i in utils])
|
||||
for cmd in sorted(utils):
|
||||
Msg(fs.format(cmd,utils[cmd],w=w))
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
NL = ('\r\n','\n')[g.platform=='linux' and bool(opt.popen_spawn)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue