From 3a8cf584afbe7a9876b168521a01ec8df4ea0907 Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Mon, 23 May 2022 16:28:52 +0000 Subject: [PATCH] tw/unspent.py: new `item_action` class --- mmgen/tw/common.py | 60 ++++++++++++--------------------- mmgen/tw/unspent.py | 81 +++++++++++++++++++++++++++------------------ 2 files changed, 70 insertions(+), 71 deletions(-) diff --git a/mmgen/tw/common.py b/mmgen/tw/common.py index 1937c174..f12be26e 100755 --- a/mmgen/tw/common.py +++ b/mmgen/tw/common.py @@ -24,7 +24,7 @@ import time from ..globalvars import g from ..objmethods import Hilite,InitErrors,MMGenObject -from ..obj import TwComment +from ..obj import TwComment,get_obj,MMGenIdx from ..color import red,yellow from ..util import msg,msg_r,die,line_input,do_pager,capfirst from ..addr import MMGenID @@ -112,12 +112,24 @@ class TwCommon: assert type(reverse) == bool self.data.sort(key=sort_funcs[key],reverse=reverse or self.reverse) + async def item_action_loop(self,action): + msg('') + while True: + ret = line_input(f'Enter {self.item_desc} number (or RETURN to return to main menu): ') + if ret == '': + return None + idx = get_obj(MMGenIdx,n=ret,silent=True) + if not idx or idx < 1 or idx > len(self.data): + msg(f'Choice must be a single number between 1 and {len(self.data)}') + elif (await action(self,idx)) != 'redo': + break + async def view_and_sort(self,tx): from ..opts import opt from ..term import get_char prompt = self.prompt.strip() + '\b' no_output = False - oneshot_msg = None + self.oneshot_msg = None CUR_HOME = '\033[H' ERASE_ALL = '\033[0J' CUR_RIGHT = lambda n: f'\033[{n}C' @@ -125,11 +137,11 @@ class TwCommon: while True: msg_r('' if no_output else '\n\n' if opt.no_blank else CUR_HOME+ERASE_ALL) reply = get_char( - '' if no_output else await self.format_for_display()+'\n'+(oneshot_msg or '')+prompt, + '' if no_output else await self.format_for_display()+'\n'+(self.oneshot_msg or '')+prompt, immed_chars=''.join(self.key_mappings.keys()) ) no_output = False - oneshot_msg = '' if oneshot_msg else None # tristate, saves previous state + self.oneshot_msg = '' if self.oneshot_msg else None # tristate, saves previous state if reply not in self.key_mappings: msg_r('\ninvalid keypress ') time.sleep(0.5) @@ -156,37 +168,6 @@ class TwCommon: elif action == 'a_quit': msg('') return self.data - elif action == 'a_balance_refresh': - idx = self.get_idx_from_user(action) - if idx: - e = self.data[idx-1] - bal = await self.wallet.get_balance(e.addr,force_rpc=True) - await self.get_data() - oneshot_msg = yellow(f'{self.proto.dcoin} balance for account #{idx} refreshed\n\n') - self.display_constants = self.get_display_constants() - elif action == 'a_lbl_add': - idx,lbl = self.get_idx_from_user(action) - if idx: - e = self.data[idx-1] - if await self.wallet.add_label(e.twmmid,lbl,addr=e.addr): - await self.get_data() - oneshot_msg = yellow('Label {} {} #{}\n\n'.format( - ('added to' if lbl else 'removed from'), - self.item_desc, - idx )) - else: - oneshot_msg = red('Label could not be added\n\n') - self.display_constants = self.get_display_constants() - elif action == 'a_addr_delete': - idx = self.get_idx_from_user(action) - if idx: - e = self.data[idx-1] - if await self.wallet.remove_address(e.addr): - await self.get_data() - oneshot_msg = yellow(f'{capfirst(self.item_desc)} #{idx} removed\n\n') - else: - oneshot_msg = red('Address could not be removed\n\n') - self.display_constants = self.get_display_constants() elif action == 'a_print': of = '{}-{}[{}].out'.format( self.dump_fn_pfx, @@ -201,16 +182,19 @@ class TwCommon: await self.format_for_printing(color=False), desc = f'{self.desc} listing' ) except UserNonConfirmation as e: - oneshot_msg = red(f'File {of!r} not overwritten by user request\n\n') + self.oneshot_msg = red(f'File {of!r} not overwritten by user request\n\n') else: - oneshot_msg = yellow(f'Data written to {of!r}\n\n') + self.oneshot_msg = yellow(f'Data written to {of!r}\n\n') elif action in ('a_view','a_view_wide'): do_pager( self.fmt_display if action == 'a_view' else await self.format_for_printing(color=True) ) - if g.platform == 'linux' and oneshot_msg == None: + if g.platform == 'linux' and self.oneshot_msg == None: msg_r(CUR_RIGHT(len(prompt.split('\n')[-1])-2)) no_output = True + elif hasattr(self,'item_action') and hasattr(self.item_action,action): + await self.item_action_loop(getattr(self.item_action(),action)) + self.display_constants = self.get_display_constants() class TwMMGenID(str,Hilite,InitErrors,MMGenObject): color = 'orange' diff --git a/mmgen/tw/unspent.py b/mmgen/tw/unspent.py index 1dee8416..d888f229 100755 --- a/mmgen/tw/unspent.py +++ b/mmgen/tw/unspent.py @@ -27,7 +27,6 @@ from ..globalvars import g from ..color import red,yellow,green from ..util import ( msg, - msg_r, die, capfirst, suf, @@ -35,7 +34,6 @@ from ..util import ( make_timestr, keypress_confirm, line_input, - do_pager, base_proto_tw_subclass ) from ..base_obj import AsyncInit @@ -298,36 +296,53 @@ class TwUnspentOutputs(MMGenObject,TwCommon,metaclass=AsyncInit): len(self.data), suf(self.data) )) - def get_idx_from_user(self,action): - msg('') - while True: - ret = line_input(f'Enter {self.item_desc} number (or RETURN to return to main menu): ') - if ret == '': - return (None,None) if action == 'a_lbl_add' else None - n = get_obj(MMGenIdx,n=ret,silent=True) - if not n or n < 1 or n > len(self.data): - msg(f'Choice must be a single number between 1 and {len(self.data)}') + class item_action: + + async def a_balance_refresh(self,uo,idx): + if not keypress_confirm( + f'Refreshing tracking wallet {uo.item_desc} #{idx}. Is this what you want?'): + return 'redo' + await uo.wallet.get_balance( uo.data[idx-1].addr, force_rpc=True ) + await uo.get_data() + uo.oneshot_msg = yellow(f'{uo.proto.dcoin} balance for account #{idx} refreshed\n\n') + + async def a_addr_delete(self,uo,idx): + if not keypress_confirm( + f'Removing {uo.item_desc} #{idx} from tracking wallet. Is this what you want?'): + return 'redo' + if await uo.wallet.remove_address( uo.data[idx-1].addr ): + await uo.get_data() + uo.oneshot_msg = yellow(f'{capfirst(uo.item_desc)} #{idx} removed\n\n') else: - if action == 'a_lbl_add': - cur_lbl = self.data[n-1].label - msg('Current label: {}'.format(cur_lbl.hl() if cur_lbl else '(none)')) - while True: - s = line_input( - "Enter label text (or 'q' to return to main menu): ", - insert_txt = cur_lbl ) - if s == 'q': - return None,None - elif s == '': - if keypress_confirm( - f'Removing label for {self.item_desc} #{n}. Is this what you want?'): - return n,s - elif s: - if get_obj(TwComment,s=s): - return n,s + import asyncio + await asyncio.sleep(3) + uo.oneshot_msg = red('Address could not be removed\n\n') + + async def a_lbl_add(self,uo,idx): + + async def do_lbl_add(lbl): + e = uo.data[idx-1] + if await uo.wallet.add_label( e.twmmid, lbl, addr=e.addr ): + await uo.get_data() + uo.oneshot_msg = yellow('Label {} {} #{}\n\n'.format( + ('added to' if lbl else 'removed from'), + uo.item_desc, + idx )) else: - if action == 'a_addr_delete': - fs = 'Removing {} #{} from tracking wallet. Is this what you want?' - elif action == 'a_balance_refresh': - fs = 'Refreshing tracking wallet {} #{}. Is this what you want?' - if keypress_confirm(fs.format(self.item_desc,n)): - return n + import asyncio + await asyncio.sleep(3) + uo.oneshot_msg = red('Label could not be added\n\n') + + cur_lbl = uo.data[idx-1].label + msg('Current label: {}'.format(cur_lbl.hl() if cur_lbl else '(none)')) + + res = line_input( + "Enter label text (or ENTER to return to main menu): ", + insert_txt = cur_lbl ) + if res == cur_lbl: + return None + elif res == '': + return (await do_lbl_add(res)) if keypress_confirm( + f'Removing label for {uo.item_desc} #{idx}. Is this what you want?') else 'redo' + else: + return (await do_lbl_add(res)) if get_obj(TwComment,s=res) else 'redo'