mmnode-blocks-info: --fields: support +<list>-<list>, 'all'-<list>
This commit is contained in:
parent
8809acc405
commit
ae03007bba
3 changed files with 70 additions and 18 deletions
|
|
@ -124,28 +124,42 @@ class BlocksInfo:
|
|||
|
||||
t_fmt = lambda self,t: f'{t/86400:.2f} days' if t > 172800 else f'{t/3600:.2f} hrs'
|
||||
|
||||
def __init__(self,cmd_args,opt,rpc):
|
||||
@classmethod
|
||||
def parse_cslist(cls,uarg,full_set,dfl_set,desc):
|
||||
|
||||
def parse_cslist(uarg,full_set,dfl_set,desc):
|
||||
m = re.match('([+-]){1}',uarg)
|
||||
pfx = m[1] if m else None
|
||||
usr_set = set((uarg[1:] if m else uarg).split(','))
|
||||
dfl_set = set(dfl_set)
|
||||
for e in usr_set:
|
||||
if e not in full_set:
|
||||
die(1,f'{e!r}: unrecognized {desc}')
|
||||
res = (
|
||||
dfl_set | usr_set if pfx == '+' else
|
||||
dfl_set - usr_set if pfx == '-' else
|
||||
usr_set
|
||||
)
|
||||
def make_list(m,func):
|
||||
groups_lc = [set(e.lower() for e in g.split(',')) for g in m.groups()]
|
||||
for group in groups_lc:
|
||||
for e in group:
|
||||
if e not in full_set_lc:
|
||||
die(1,f'{e!r}: unrecognized {desc}')
|
||||
# display elements in order:
|
||||
return [e for e in full_set if e in res]
|
||||
return [e for e in full_set if e.lower() in func(groups_lc)]
|
||||
|
||||
full_set_lc = set(e.lower() for e in full_set)
|
||||
dfl_set_lc = set(e.lower() for e in dfl_set)
|
||||
cspat = r'(\w+(?:,\w+)*)'
|
||||
|
||||
for pat,func in (
|
||||
( rf'{cspat}$', lambda g: g[0] ),
|
||||
( rf'\+{cspat}$', lambda g: dfl_set_lc | g[0] ),
|
||||
( rf'\-{cspat}$', lambda g: dfl_set_lc - g[0] ),
|
||||
( rf'\+{cspat}\-{cspat}$', lambda g: ( dfl_set_lc | g[0] ) - g[1] ),
|
||||
( rf'\-{cspat}\+{cspat}$', lambda g: ( dfl_set_lc - g[0] ) | g[1] ),
|
||||
( rf'all\-{cspat}$', lambda g: full_set_lc - g[0] )
|
||||
):
|
||||
m = re.match(pat,uarg,re.ASCII|re.IGNORECASE)
|
||||
if m:
|
||||
return make_list(m,func)
|
||||
else:
|
||||
die(1,f'{uarg}: invalid parameter')
|
||||
|
||||
def __init__(self,cmd_args,opt,rpc):
|
||||
|
||||
def parse_cs_uarg(uarg,full_set,dfl_set,desc):
|
||||
return (
|
||||
full_set if uarg == 'all' else [] if uarg == 'none' else
|
||||
parse_cslist(uarg,full_set,dfl_set,desc)
|
||||
self.parse_cslist(uarg,full_set,dfl_set,desc)
|
||||
)
|
||||
|
||||
def get_fields():
|
||||
|
|
|
|||
|
|
@ -57,7 +57,10 @@ opts_data = {
|
|||
See AVAILABLE FIELDS below. Prefix the list with '+'
|
||||
to add the fields to the defaults, or '-' to remove
|
||||
them. The special values 'all' and 'none' select all
|
||||
available fields or none, respectively.
|
||||
available fields or none, respectively. The '+' and
|
||||
'-'-prefixed lists may be concatenated to specify both
|
||||
addition and removal of fields. A single '-'-prefixed
|
||||
list may be additionally prefixed by 'all'.
|
||||
-s, --stats= Display the specified stats (comma-separated list).
|
||||
See AVAILABLE STATS below. The prefixes and special
|
||||
values available to the --fields option are recognized.
|
||||
|
|
@ -120,9 +123,16 @@ EXAMPLES:
|
|||
fields from the defaults and skipping stats:
|
||||
$ {p} -o -size,subsidy -s none +10
|
||||
|
||||
Display data for the last ten blocks, omitting the 'size' and 'version'
|
||||
fields from the defaults and adding the 'inputs' and 'utxo_inc' fields:
|
||||
$ {p} -o -version,size+utxo_inc,inputs +10
|
||||
|
||||
Display all fields and stats for the last ten blocks:
|
||||
$ {p} -o all -s all +10
|
||||
|
||||
Same as above, but omit the 'miner' and 'hash' fields:
|
||||
$ {p} -o all-miner,hash -s all +10
|
||||
|
||||
Same as above, but display only fields relating to stats:
|
||||
$ {p} -o none -s all -f +10
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,24 @@ range_vecs = (
|
|||
( '+144*10+12*12', (tip-1439, tip, None, 1440, 144 ), (tip-1439, tip, list(range(tip-1439,tip+1,144))) ),
|
||||
)
|
||||
|
||||
full_set = ['aa','bbb','ccc_P2','ddddd','eeeeee','ffffffff','gg']
|
||||
dfl_set = ['aa','ddddd','ffffffff']
|
||||
fields_vecs = (
|
||||
( 'Ccc_P2', ['ccc_P2'] ),
|
||||
( '+CCC_P2', ['aa','ccc_P2','ddddd','ffffffff'] ),
|
||||
( '+Aa', dfl_set ),
|
||||
( '+ddDDD,FffffffF', dfl_set ),
|
||||
( '+bBb', ['aa','bbb','ddddd','ffffffff'] ),
|
||||
( '-ddddd', ['aa','ffffffff'] ),
|
||||
( '-DDDDD,fFffffff', ['aa'] ),
|
||||
( '-ffffffff,AA,DdDdD', [] ),
|
||||
( '+aa,gG,ccC_P2', ['aa','ccc_P2','ddddd','ffffffff','gg'] ),
|
||||
( '+BBB,gg-dDddD,fFffffff', ['aa','bbb','gg'] ),
|
||||
( '-dDddD,fFffffff+BBB,gg', ['aa','bbb','gg'] ),
|
||||
( 'aLL-Ccc_P2', [e for e in full_set if e != 'ccc_P2'] ),
|
||||
( 'All-dDddd,aa', [e for e in full_set if e not in ('aa','ddddd')] ),
|
||||
)
|
||||
|
||||
class dummyRPC:
|
||||
blockcount = tip
|
||||
|
||||
|
|
@ -57,6 +75,16 @@ class dummyOpt:
|
|||
|
||||
class unit_tests:
|
||||
|
||||
def parse_field(self,name,ut):
|
||||
vmsg('{:28} => {}'.format('FULL SET:',full_set))
|
||||
vmsg('{:28} => {}'.format('DFL SET: ',dfl_set))
|
||||
b = BlocksInfo
|
||||
for opt,chk in fields_vecs:
|
||||
ret = b.parse_cslist(opt,full_set,dfl_set,'field')
|
||||
vmsg(f'{opt:28} => {ret}')
|
||||
assert ret == chk, f'{ret} != {chk}'
|
||||
return True
|
||||
|
||||
def parse_rangespec(self,name,ut):
|
||||
|
||||
b = BlocksInfo(0,dummyOpt(),dummyRPC())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue