Browse Source

tw/unspent.py: new `item_action` class

The MMGen Project 2 years ago
parent
commit
3a8cf584af
2 changed files with 70 additions and 71 deletions
  1. 22 38
      mmgen/tw/common.py
  2. 48 33
      mmgen/tw/unspent.py

+ 22 - 38
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'

+ 48 - 33
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'