From 3f76be1ab8e948a341688522573767f17fe5f9aa Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Fri, 13 Oct 2023 09:50:15 +0000 Subject: [PATCH] minor fixes and cleanups --- mmgen_node_tools/BlocksInfo.py | 93 +++++++++++++++++--------------- mmgen_node_tools/PollDisplay.py | 2 +- mmgen_node_tools/Ticker.py | 6 ++- mmgen_node_tools/main_addrbal.py | 2 + mmgen_node_tools/main_netrate.py | 4 +- mmgen_node_tools/main_ticker.py | 10 ++-- mmgen_node_tools/main_txfind.py | 4 +- setup.cfg | 1 + test/cmdtest_py_d/ct_regtest.py | 2 +- 9 files changed, 68 insertions(+), 56 deletions(-) diff --git a/mmgen_node_tools/BlocksInfo.py b/mmgen_node_tools/BlocksInfo.py index 25e1caf..40cc6e5 100755 --- a/mmgen_node_tools/BlocksInfo.py +++ b/mmgen_node_tools/BlocksInfo.py @@ -27,6 +27,52 @@ from time import strftime,gmtime from mmgen.util import msg,Msg,Msg_r,die,suf,secs_to_ms,secs_to_dhms,is_int from mmgen.rpc import json_encoder +class RangeParser: + + debug = False + + def __init__(self,caller,arg): + self.caller = caller + self.arg = self.orig_arg = arg + + def parse(self,target): + ret = getattr(self,'parse_'+target)() + if self.debug: + msg(f'arg after parse({target}): {self.arg}') + return ret + + def finalize(self): + if self.arg: + die(1,f'{self.orig_arg!r}: invalid range specifier') + + def parse_from_tip(self): + m = re.match(r'-([0-9]+)(.*)',self.arg) + if m: + res,self.arg = (m[1],m[2]) + return self.caller.check_nblocks(int(res)) + + def parse_abs_range(self): + m = re.match(r'([^+-]+)(-([^+-]+)){0,1}(.*)',self.arg) + if m: + if self.debug: + msg(f'abs_range parse: first={m[1]}, last={m[3]}') + self.arg = m[4] + return ( + self.caller.conv_blkspec(m[1]), + self.caller.conv_blkspec(m[3]) if m[3] else None + ) + return (None,None) + + def parse_add(self): + m = re.match(r'\+([0-9*]+)(.*)',self.arg) + if m: + res,self.arg = (m[1],m[2]) + if res.strip('*') != res: + die(1,f"'+{res}': malformed nBlocks specifier") + if len(res) > 30: + die(1,f"'+{res}': overly long nBlocks specifier") + return self.caller.check_nblocks(eval(res)) # res is only digits plus '*', so eval safe + class BlocksInfo: total_bytes = 0 @@ -298,49 +344,8 @@ class BlocksInfo: def parse_rangespec(self,arg): - class RangeParser: - debug = False + p = RangeParser(self,arg) - def __init__(rp,arg): - rp.arg = rp.orig_arg = arg - - def parse(rp,target): - ret = getattr(rp,'parse_'+target)() - if rp.debug: msg(f'arg after parse({target}): {rp.arg}') - return ret - - def finalize(rp): - if rp.arg: - die(1,f'{rp.orig_arg!r}: invalid range specifier') - - def parse_from_tip(rp): - m = re.match(r'-([0-9]+)(.*)',rp.arg) - if m: - res,rp.arg = (m[1],m[2]) - return self.check_nblocks(int(res)) - - def parse_abs_range(rp): - m = re.match(r'([^+-]+)(-([^+-]+)){0,1}(.*)',rp.arg) - if m: - if rp.debug: msg(f'abs_range parse: first={m[1]}, last={m[3]}') - rp.arg = m[4] - return ( - self.conv_blkspec(m[1]), - self.conv_blkspec(m[3]) if m[3] else None - ) - return (None,None) - - def parse_add(rp): - m = re.match(r'\+([0-9*]+)(.*)',rp.arg) - if m: - res,rp.arg = (m[1],m[2]) - if res.strip('*') != res: - die(1,f"'+{res}': malformed nBlocks specifier") - if len(res) > 30: - die(1,f"'+{res}': overly long nBlocks specifier") - return self.check_nblocks(eval(res)) # res is only digits plus '*', so eval safe - - p = RangeParser(arg) from_tip = p.parse('from_tip') first,last = (self.tip-from_tip,None) if from_tip else p.parse('abs_range') add1 = p.parse('add') @@ -708,8 +713,8 @@ class BlocksInfo: class JSONBlocksInfo(BlocksInfo): - def __init__(self,cfg,cmd_args,opt,rpc): - super().__init__(cfg,cmd_args,opt,rpc) + def __init__(self,cfg,cmd_args,rpc): + super().__init__(cfg,cmd_args,rpc) if self.cfg.json_raw: self.output_block = self.output_block_raw self.fmt_stat_item = self.fmt_stat_item_raw diff --git a/mmgen_node_tools/PollDisplay.py b/mmgen_node_tools/PollDisplay.py index 84a6023..5bbfecd 100755 --- a/mmgen_node_tools/PollDisplay.py +++ b/mmgen_node_tools/PollDisplay.py @@ -16,7 +16,7 @@ import sys,threading from mmgen.util import msg from mmgen.term import get_char -class PollDisplay(): +class PollDisplay: info = None input = None diff --git a/mmgen_node_tools/Ticker.py b/mmgen_node_tools/Ticker.py index 97b5dc5..1e21192 100755 --- a/mmgen_node_tools/Ticker.py +++ b/mmgen_node_tools/Ticker.py @@ -449,7 +449,7 @@ def main(): '\n'.join(getattr(Ticker,cfg.clsname)(data).gen_output()) + '\n' ) -def make_cfg(): +def make_cfg(gcfg_arg): query_tuple = namedtuple('query',['asset','to_asset']) asset_data = namedtuple('asset_data',['symbol','id','amount','rate','rate_asset','source']) @@ -578,7 +578,9 @@ def make_cfg(): 'proxy2', 'portfolio' ]) - global cfg_in,src_cls,cfg + global gcfg,cfg_in,src_cls,cfg + + gcfg = gcfg_arg src_cls = { k: getattr(DataSource,v) for k,v in DataSource.sources.items() } fi_pat = src_cls['fi'].asset_id_pat diff --git a/mmgen_node_tools/main_addrbal.py b/mmgen_node_tools/main_addrbal.py index a461e9e..34c6236 100755 --- a/mmgen_node_tools/main_addrbal.py +++ b/mmgen_node_tools/main_addrbal.py @@ -12,6 +12,8 @@ mmnode-addrbal: Get balances for arbitrary addresses in the blockchain """ +import sys + from mmgen.obj import CoinTxID,Int from mmgen.cfg import Config from mmgen.util import msg,Msg,die,suf,make_timestr,async_run diff --git a/mmgen_node_tools/main_netrate.py b/mmgen_node_tools/main_netrate.py index f1661c5..52b509d 100755 --- a/mmgen_node_tools/main_netrate.py +++ b/mmgen_node_tools/main_netrate.py @@ -49,7 +49,7 @@ async def main(): d = await c.call('getnettotals') return [float(e) for e in (d['totalbytesrecv'],d['totalbytessent'],d['timemillis'])] - rs = None + rs,ss,ts = (None,None,None) while True: r,s,t = await get_data() @@ -64,7 +64,7 @@ async def main(): if rs is not None: sys.stderr.write('{}{}{}'.format(ERASE_LINE,CUR_UP,ERASE_LINE)) - rs,ss,ts = r,s,t + rs,ss,ts = (r,s,t) try: async_run(main()) diff --git a/mmgen_node_tools/main_ticker.py b/mmgen_node_tools/main_ticker.py index f329e03..6a9d3aa 100755 --- a/mmgen_node_tools/main_ticker.py +++ b/mmgen_node_tools/main_ticker.py @@ -216,14 +216,14 @@ import os from mmgen.util import fmt_list,fmt_dict from mmgen.cfg import Config -import mmgen_node_tools.Ticker as tck +from . import Ticker -tck.gcfg = Config( opts_data=opts_data, do_post_init=True ) +gcfg = Config( opts_data=opts_data, do_post_init=True ) -tck.make_cfg() +Ticker.make_cfg(gcfg) from .Ticker import dfl_cachedir,homedir,DataSource,assets_list_gen,cfg_in,src_cls -tck.gcfg._post_init() +gcfg._post_init() -tck.main() +Ticker.main() diff --git a/mmgen_node_tools/main_txfind.py b/mmgen_node_tools/main_txfind.py index 57b691a..4a54430 100755 --- a/mmgen_node_tools/main_txfind.py +++ b/mmgen_node_tools/main_txfind.py @@ -20,8 +20,10 @@ mmnode-txfind: Find a transaction in the blockchain or mempool """ +import sys + from mmgen.cfg import Config -from mmgen.util import msg,Msg,die,is_hex_str +from mmgen.util import msg,Msg,die,is_hex_str,async_run opts_data = { 'text': { diff --git a/setup.cfg b/setup.cfg index aeebff5..7e91ea5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -24,6 +24,7 @@ include_package_data = True install_requires = mmgen>=14.0.dev6 + pyyaml yahooquery packages = diff --git a/test/cmdtest_py_d/ct_regtest.py b/test/cmdtest_py_d/ct_regtest.py index a03e3ff..b17b4c6 100755 --- a/test/cmdtest_py_d/ct_regtest.py +++ b/test/cmdtest_py_d/ct_regtest.py @@ -107,7 +107,7 @@ class CmdTestRegtest(CmdTestBase): CmdTestBase.__init__(self,trunner,cfgs,spawn) if trunner == None: return - if self.proto.testnet: + if cfg._proto.testnet: die(2,'--testnet and --regtest options incompatible with regtest test suite') self.proto = init_proto( cfg, self.proto.coin, network='regtest', need_amt=True ) self.addrs = gen_addrs(self.proto,'regtest',[1,2,3,4,5])