diff --git a/README.md b/README.md index 9c72f4e..673155e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # MMGen Node Tools -Helper utilities for Bitcoin and forkcoin full nodes. +### Terminal-based utilities for Bitcoin and forkcoin full nodes Requires modules from the [MMGen online/offline cryptocurrency wallet][6]. diff --git a/mmgen_node_tools/Ticker.py b/mmgen_node_tools/Ticker.py index 14163eb..7fe8b1d 100755 --- a/mmgen_node_tools/Ticker.py +++ b/mmgen_node_tools/Ticker.py @@ -31,7 +31,7 @@ from collections import namedtuple from mmgen.opts import opt from mmgen.globalvars import g from mmgen.color import * -from mmgen.util import die,fmt_list,msg,msg_r,Msg,do_pager,suf,fmt +from mmgen.util import die,fmt_list,msg,msg_r,Msg,vmsg,suf,fmt,stdout_or_pager homedir = os.getenv('HOME') cachedir = os.path.join(homedir,'.cache','mmgen-node-tools') @@ -189,6 +189,7 @@ def get_src_data(curl_cmd): elapsed = int(time.time() - os.stat(fn).st_mtime) if elapsed >= timeout: msg_r(f'Fetching data from {api_host}...') + vmsg('') try: cp = run(curl_cmd,check=True,stdout=PIPE) except CalledProcessError as e: @@ -244,10 +245,10 @@ def main(cfg_parm,cfg_in_parm): 'curl', '--tr-encoding', '--compressed', # adds 'Accept-Encoding: gzip' - '--silent', '--header', 'Accept: application/json', ] + (['--proxy', cfg.proxy] if cfg.proxy else []) + + (['--silent'] if not opt.verbose else []) + [api_url + ('/btc-bitcoin' if cfg.btc_only else '')] ) @@ -276,14 +277,15 @@ def main(cfg_parm,cfg_in_parm): parsed_json = [get_src_data(curl_cmd)] if cfg.btc_only else get_src_data(curl_cmd) if opt.list_ids: + from mmgen.ui import do_pager do_pager('\n'.join(e['id'] for e in parsed_json)) return global now now = 1659465400 if g.test_suite else time.time() # 1659524400 1659445900 - (do_pager if opt.pager else Msg)( - '\n'.join(getattr(Ticker,cfg.clsname)(dict(gen_data(parsed_json))).gen_output()) + stdout_or_pager( + '\n'.join(getattr(Ticker,cfg.clsname)(dict(gen_data(parsed_json))).gen_output()) + '\n' ) def make_cfg(cmd_args,cfg_in): @@ -481,7 +483,7 @@ class Ticker: def format_last_update_col(self,cross_assets=()): if opt.elapsed: - from .Util import format_elapsed_hr + from mmgen.util2 import format_elapsed_hr fmt_func = format_elapsed_hr else: fmt_func = lambda t,now: time.strftime('%F %X',time.gmtime(t)) # ticker API diff --git a/mmgen_node_tools/Util.py b/mmgen_node_tools/Util.py index 7fdc409..9060f68 100755 --- a/mmgen_node_tools/Util.py +++ b/mmgen_node_tools/Util.py @@ -33,19 +33,6 @@ def get_day_hms(t=None,utc=False): ret = (time.localtime,time.gmtime)[utc](secs) return '{:04}-{:02}-{:02} {:02}:{:02}:{:02}'.format(*ret[0:6]) -def format_elapsed_hr(t,now=None,cached={}): - now = now or time.time() - e = int(now - t) - if not e in cached: - h = abs(e) // 3600 - m = abs(e) // 60 % 60 - cached[e] = '{a}{b} minute{c} {d}'.format( - a = '{} hour{}, '.format(h,suf(h)) if h else '', - b = m, - c = suf(m), - d = 'ago' if e > 0 else 'in the future' ) if (h or m) else 'just now' - return cached[e] - def do_system(cmd,testing=False,shell=False): if testing: from mmgen.util import msg diff --git a/mmgen_node_tools/data/version b/mmgen_node_tools/data/version index 2590359..58dfba3 100644 --- a/mmgen_node_tools/data/version +++ b/mmgen_node_tools/data/version @@ -1 +1 @@ -3.1.dev6 +3.1.dev7 diff --git a/mmgen_node_tools/main_addrbal.py b/mmgen_node_tools/main_addrbal.py index c638ed6..4218f6a 100755 --- a/mmgen_node_tools/main_addrbal.py +++ b/mmgen_node_tools/main_addrbal.py @@ -121,7 +121,7 @@ async def main(req_addrs): height = await rpc.call('getblockcount') Msg(f'{proto.coin} {proto.network.upper()} [height {height}]') - from mmgen.base_proto.bitcoin.misc import scantxoutset + from mmgen.proto.btc.misc import scantxoutset res = await scantxoutset( rpc, [f'addr({addr})' for addr in addrs] ) if not res['success']: @@ -138,7 +138,7 @@ async def main(req_addrs): addr = re.match('addr\((.*?)\)',unspent['desc'])[1] addr_data[addr].append(unspent) else: - from mmgen.base_proto.bitcoin.tx.base import scriptPubKey2addr + from mmgen.proto.btc.tx.base import scriptPubKey2addr for unspent in sorted(res['unspents'],key=lambda x: x['height']): addr = scriptPubKey2addr( proto, unspent['scriptPubKey'] )[0] addr_data[addr].append(unspent) @@ -165,6 +165,6 @@ if len(cmd_args) < 1: from mmgen.obj import CoinTxID,Int try: - run_session(main(cmd_args)) + async_run(main(cmd_args)) except KeyboardInterrupt: sys.stderr.write('\n') diff --git a/mmgen_node_tools/main_blocks_info.py b/mmgen_node_tools/main_blocks_info.py index a7dff8d..117da98 100755 --- a/mmgen_node_tools/main_blocks_info.py +++ b/mmgen_node_tools/main_blocks_info.py @@ -176,4 +176,4 @@ async def main(): m.finalize_output() -run_session(main()) +async_run(main()) diff --git a/mmgen_node_tools/main_feeview.py b/mmgen_node_tools/main_feeview.py index 276c870..e5f2f00 100755 --- a/mmgen_node_tools/main_feeview.py +++ b/mmgen_node_tools/main_feeview.py @@ -21,6 +21,7 @@ mmnode-feeview: Visualize the fee structure of a node’s mempool """ from mmgen.common import * +from mmgen.util2 import int2bytespec,parse_bytespec min_prec,max_prec,dfl_prec = (0,6,4) fee_brackets = [ @@ -213,10 +214,8 @@ async def main(): log(mempool,'mempool.json') data = create_data(proto.coin_amt,mempool) - - (do_pager if opt.pager else print)( + stdout_or_pager( '\n'.join(gen_header(c.host,await c.call('getblockcount'))) + '\n' + - '\n'.join(gen_body(data)) - ) + '\n'.join(gen_body(data)) + '\n' ) -run_session(main()) +async_run(main()) diff --git a/mmgen_node_tools/main_halving_calculator.py b/mmgen_node_tools/main_halving_calculator.py index 423df0e..c804d8f 100755 --- a/mmgen_node_tools/main_halving_calculator.py +++ b/mmgen_node_tools/main_halving_calculator.py @@ -179,4 +179,4 @@ async def main(): else: print_current_stats() -run_session(main()) +async_run(main()) diff --git a/mmgen_node_tools/main_netrate.py b/mmgen_node_tools/main_netrate.py index b1fb919..fd86983 100755 --- a/mmgen_node_tools/main_netrate.py +++ b/mmgen_node_tools/main_netrate.py @@ -68,6 +68,6 @@ async def main(): rs,ss,ts = r,s,t try: - run_session(main()) + async_run(main()) except KeyboardInterrupt: sys.stderr.write('\n') diff --git a/mmgen_node_tools/main_peerblocks.py b/mmgen_node_tools/main_peerblocks.py index 87df582..b775b29 100755 --- a/mmgen_node_tools/main_peerblocks.py +++ b/mmgen_node_tools/main_peerblocks.py @@ -171,7 +171,7 @@ ERASE_ALL,ERASE_LINE,CUR_HOME,CUR_HIDE,CUR_SHOW = ( '\033[J','\033[K','\033[H','\033[?25l','\033[?25h') try: - run_session(main()) + async_run(main()) except: from subprocess import run run(['stty','sane']) diff --git a/mmgen_node_tools/main_ticker.py b/mmgen_node_tools/main_ticker.py index 9a32c04..a25e884 100755 --- a/mmgen_node_tools/main_ticker.py +++ b/mmgen_node_tools/main_ticker.py @@ -52,6 +52,7 @@ opts_data = { -T, --thousands-comma Use comma as a thousands separator -u, --update-time Include UPDATED (last update time) column -U, --print-curl Print cURL command to standard output and exit +-v, --verbose Be more verbose -w, --wide Display all optional columns (equivalent to -punT) -x, --proxy=P Connect via proxy ‘P’. Set to the empty string to disable. Consult the curl manpage for --proxy usage. diff --git a/mmgen_node_tools/main_txfind.py b/mmgen_node_tools/main_txfind.py index 3c7935d..2672a11 100755 --- a/mmgen_node_tools/main_txfind.py +++ b/mmgen_node_tools/main_txfind.py @@ -91,4 +91,4 @@ msgs = msg_data['quiet' if opt.quiet else 'normal'] if len(cmd_args) != 1: die(1,'One transaction ID must be specified') -sys.exit(run_session(main(cmd_args[0]))) +sys.exit(async_run(main(cmd_args[0]))) diff --git a/setup.cfg b/setup.cfg index 628ebe0..f3d9a66 100644 --- a/setup.cfg +++ b/setup.cfg @@ -23,7 +23,7 @@ python_requires = >=3.7 include_package_data = True install_requires = - mmgen>=13.2.dev12 + mmgen>=13.3.dev6 packages = mmgen_node_tools diff --git a/test/test-release.d/cfg.sh b/test/test-release.d/cfg.sh index f0c11d7..53dd32a 100755 --- a/test/test-release.d/cfg.sh +++ b/test/test-release.d/cfg.sh @@ -8,6 +8,16 @@ # https://github.com/mmgen/mmgen-node-tools # https://gitlab.com/mmgen/mmgen-node-tools +# Testing status +# mmnode-addrbal OK +# mmnode-blocks-info - +# mmnode-feeview - +# mmnode-halving-calculator OK +# mmnode-netrate - +# mmnode-peerblocks - +# mmnode-ticker OK +# mmnode-txfind - + list_avail_tests() { echo "AVAILABLE TESTS:" echo " unit - unit tests" diff --git a/test/test_py_d/ts_misc.py b/test/test_py_d/ts_misc.py index 0d39c7e..7801f64 100755 --- a/test/test_py_d/ts_misc.py +++ b/test/test_py_d/ts_misc.py @@ -257,7 +257,7 @@ class TestSuiteScripts(TestSuiteBase): ['--btc','--wide','--portfolio','--elapsed'], [ 'PRICES', - r'BITCOIN 23,368.86 \+6.05 -1.87 33 hours, 2 minutes ago', + r'BITCOIN 23,368.86 \+6.05 -1.87 1 day 9 hours 2 minutes ago', 'PORTFOLIO', r'BITCOIN 28,850.44 \+6.05 -1.87 1.23456789' ]) @@ -271,8 +271,8 @@ class TestSuiteScripts(TestSuiteBase): r'BTC \(BITCOIN\) = 23,368.86 USD', 'Offered price differs from spot by -3.72%', 'SPOT PRICE OFFERED PRICE UPDATED', - 'BITCOIN 2.00000000 1.92563954 33 hours, 2 minutes ago ' + - 'US DOLLAR 46,737.71911598 45,000.00000000 33 hours, 2 minutes ago', + 'BITCOIN 2.00000000 1.92563954 1 day 9 hours 2 minutes ago ' + + 'US DOLLAR 46,737.71911598 45,000.00000000 1 day 9 hours 2 minutes ago', ]) def ticker16(self):