Browse Source

tw.view: new `squeezed_col_hdr`, `detail_col_hdr` methods

The MMGen Project 2 years ago
parent
commit
2632786800
5 changed files with 97 additions and 61 deletions
  1. 16 14
      mmgen/tw/addresses.py
  2. 36 24
      mmgen/tw/txhistory.py
  3. 18 16
      mmgen/tw/unspent.py
  4. 11 7
      mmgen/tw/view.py
  5. 16 0
      test/test_py_d/ts_regtest.py

+ 16 - 14
mmgen/tw/addresses.py

@@ -155,9 +155,8 @@ class TwAddresses(TwView):
 		else:
 		else:
 			return ''
 			return ''
 
 
-	def gen_squeezed_display(self,data,cw,hdr_fs,fs,color):
-
-		yield hdr_fs.format(
+	def squeezed_col_hdr(self,cw,fs,color):
+		return fs.format(
 			n  = '',
 			n  = '',
 			m  = 'MMGenID',
 			m  = 'MMGenID',
 			u  = 'Used',
 			u  = 'Used',
@@ -166,6 +165,19 @@ class TwAddresses(TwView):
 			A  = 'Balance',
 			A  = 'Balance',
 			d  = self.age_hdr )
 			d  = self.age_hdr )
 
 
+	def detail_col_hdr(self,cw,fs,color):
+		return fs.format(
+			n  = '',
+			m  = 'MMGenID',
+			u  = 'Used',
+			a  = 'Address',
+			c  = 'Comment',
+			A  = 'Balance',
+			b  = 'Block',
+			D  = 'Date/Time' )
+
+	def gen_squeezed_display(self,data,cw,fs,color):
+
 		yes,no = (red('Yes '),green('No  ')) if color else ('Yes ','No  ')
 		yes,no = (red('Yes '),green('No  ')) if color else ('Yes ','No  ')
 		id_save = data[0].al_id
 		id_save = data[0].al_id
 
 
@@ -183,17 +195,7 @@ class TwAddresses(TwView):
 				d = self.age_disp( d, self.age_fmt )
 				d = self.age_disp( d, self.age_fmt )
 			)
 			)
 
 
-	def gen_detail_display(self,data,cw,hdr_fs,fs,color):
-
-		yield hdr_fs.format(
-			n  = '',
-			m  = 'MMGenID',
-			u  = 'Used',
-			a  = 'Address',
-			c  = 'Comment',
-			A  = 'Balance',
-			b  = 'Block',
-			D  = 'Date/Time' )
+	def gen_detail_display(self,data,cw,fs,color):
 
 
 		yes,no = (red('Yes '),green('No  ')) if color else ('Yes ','No  ')
 		yes,no = (red('Yes '),green('No  ')) if color else ('Yes ','No  ')
 		id_save = data[0].al_id
 		id_save = data[0].al_id

+ 36 - 24
mmgen/tw/txhistory.py

@@ -25,9 +25,11 @@ class TwTxHistory(TwView):
 
 
 		class squeezed(TwView.display_type.squeezed):
 		class squeezed(TwView.display_type.squeezed):
 			cols = ('num','txid','date','inputs','amt','outputs','comment')
 			cols = ('num','txid','date','inputs','amt','outputs','comment')
+			hdr_fmt_method = 'squeezed_hdr'
 
 
 		class detail(TwView.display_type.detail):
 		class detail(TwView.display_type.detail):
 			need_column_widths = False
 			need_column_widths = False
+			hdr_fmt_method = 'detail_hdr'
 			item_separator = '\n\n'
 			item_separator = '\n\n'
 
 
 	has_wallet = False
 	has_wallet = False
@@ -89,25 +91,39 @@ class TwTxHistory(TwView):
 
 
 		return self.compute_column_widths(widths,maxws,minws,maxws_nice,wide=wide)
 		return self.compute_column_widths(widths,maxws,minws,maxws_nice,wide=wide)
 
 
-	def gen_squeezed_display(self,data,cw,hdr_fs,fs,color):
-
-		if self.sinceblock:
-			yield f'Displaying transactions since block {self.sinceblock.hl(color=color)}'
-		yield 'Only wallet-related outputs are shown'
-		yield 'Comment is from first wallet address in outputs or inputs'
-		if (cw.inputs < self.varcol_maxwidths['inputs'] or
-			cw.outputs < self.varcol_maxwidths['outputs'] ):
-			yield 'Due to screen width limitations, not all addresses could be displayed'
-		yield ''
-
-		yield hdr_fs.format(
-			n = '',
-			t = 'TxID',
-			d = self.age_hdr,
-			i = 'Inputs',
-			A = 'Amt({})'.format('TX' if self.show_total_amt else 'Wallet'),
-			o = 'Outputs',
-			c = 'Comment' )
+	def squeezed_hdr(self,cw,fs,color):
+
+		def gen():
+			if self.sinceblock:
+				yield f'Displaying transactions since block {self.sinceblock.hl(color=color)}'
+			yield 'Only wallet-related outputs are shown'
+			yield 'Comment is from first wallet address in outputs or inputs'
+			if (cw.inputs < self.varcol_maxwidths['inputs'] or
+				cw.outputs < self.varcol_maxwidths['outputs'] ):
+				yield 'Due to screen width limitations, not all addresses could be displayed'
+			yield ''
+
+			yield fs.format(
+				n = '',
+				t = 'TxID',
+				d = self.age_hdr,
+				i = 'Inputs',
+				A = 'Amt({})'.format('TX' if self.show_total_amt else 'Wallet'),
+				o = 'Outputs',
+				c = 'Comment' )
+
+		return '\n'.join(gen())
+
+	def detail_hdr(self,cw,fs,color):
+
+		def gen():
+			if self.sinceblock:
+				yield f'Displaying transactions since block {self.sinceblock.hl(color=color)}'
+			yield 'Only wallet-related outputs are shown'
+
+		return '\n'.join(gen()) + '\n\n'
+
+	def gen_squeezed_display(self,data,cw,fs,color):
 
 
 		for n,d in enumerate(data,1):
 		for n,d in enumerate(data,1):
 			yield fs.format(
 			yield fs.format(
@@ -119,11 +135,7 @@ class TwTxHistory(TwView):
 				o = d.vouts_disp( 'outputs', width=cw.outputs, color=color ),
 				o = d.vouts_disp( 'outputs', width=cw.outputs, color=color ),
 				c = d.comment.fmt( width=cw.comment, color=color, nullrepl='-' ) )
 				c = d.comment.fmt( width=cw.comment, color=color, nullrepl='-' ) )
 
 
-	def gen_detail_display(self,data,cw,hdr_fs,fs,color):
-
-		if self.sinceblock:
-			yield f'Displaying transactions since block {self.sinceblock.hl(color=color)}'
-		yield 'Only wallet-related outputs are shown'
+	def gen_detail_display(self,data,cw,fs,color):
 
 
 		fs = fmt("""
 		fs = fmt("""
 		{n}
 		{n}

+ 18 - 16
mmgen/tw/unspent.py

@@ -153,9 +153,8 @@ class TwUnspentOutputs(TwView):
 			wide = wide,
 			wide = wide,
 		)
 		)
 
 
-	def gen_squeezed_display(self,data,cw,hdr_fs,fs,color):
-
-		yield hdr_fs.format(
+	def squeezed_col_hdr(self,cw,fs,color):
+		return fs.format(
 			n = '',
 			n = '',
 			t = 'TxID',
 			t = 'TxID',
 			v = 'Vout',
 			v = 'Vout',
@@ -166,6 +165,21 @@ class TwUnspentOutputs(TwView):
 			B = 'Amt({})'.format(self.proto.coin),
 			B = 'Amt({})'.format(self.proto.coin),
 			d = self.age_hdr )
 			d = self.age_hdr )
 
 
+	def detail_col_hdr(self,cw,fs,color):
+		return fs.format(
+			n = '',
+			t = 'TxID',
+			v = 'Vout',
+			a = 'Address',
+			m = 'MMGenID',
+			A = 'Amt({})'.format(self.proto.dcoin),
+			B = 'Amt({})'.format(self.proto.coin),
+			b = 'Block',
+			D = 'Date/Time',
+			c = 'Comment' )
+
+	def gen_squeezed_display(self,data,cw,fs,color):
+
 		for n,d in enumerate(data):
 		for n,d in enumerate(data):
 			yield fs.format(
 			yield fs.format(
 				n = str(n+1) + ')',
 				n = str(n+1) + ')',
@@ -182,19 +196,7 @@ class TwUnspentOutputs(TwView):
 				d = self.age_disp(d,self.age_fmt),
 				d = self.age_disp(d,self.age_fmt),
 			)
 			)
 
 
-	def gen_detail_display(self,data,cw,hdr_fs,fs,color):
-
-		yield hdr_fs.format(
-			n = '',
-			t = 'TxID',
-			v = 'Vout',
-			a = 'Address',
-			m = 'MMGenID',
-			A = 'Amt({})'.format(self.proto.dcoin),
-			B = 'Amt({})'.format(self.proto.coin),
-			b = 'Block',
-			D = 'Date/Time',
-			c = 'Comment' )
+	def gen_detail_display(self,data,cw,fs,color):
 
 
 		for n,d in enumerate(data):
 		for n,d in enumerate(data):
 			yield fs.format(
 			yield fs.format(

+ 11 - 7
mmgen/tw/view.py

@@ -39,6 +39,7 @@ class TwView(MMGenObject,metaclass=AsyncInit):
 		class squeezed:
 		class squeezed:
 			detail = False
 			detail = False
 			fmt_method = 'gen_squeezed_display'
 			fmt_method = 'gen_squeezed_display'
+			hdr_fmt_method = 'squeezed_col_hdr'
 			need_column_widths = True
 			need_column_widths = True
 			item_separator = '\n'
 			item_separator = '\n'
 			print_header = '[screen print truncated to width {}]\n'
 			print_header = '[screen print truncated to width {}]\n'
@@ -46,6 +47,7 @@ class TwView(MMGenObject,metaclass=AsyncInit):
 		class detail:
 		class detail:
 			detail = True
 			detail = True
 			fmt_method = 'gen_detail_display'
 			fmt_method = 'gen_detail_display'
+			hdr_fmt_method = 'detail_col_hdr'
 			need_column_widths = True
 			need_column_widths = True
 			item_separator = '\n'
 			item_separator = '\n'
 			print_header = ''
 			print_header = ''
@@ -54,8 +56,8 @@ class TwView(MMGenObject,metaclass=AsyncInit):
 
 
 		class print:
 		class print:
 			color = False
 			color = False
-			def do(method,data,cw,hdr_fs,fs,color):
-				return [l.rstrip() for l in method(data,cw,hdr_fs,fs,color)]
+			def do(method,data,cw,fs,color):
+				return [l.rstrip() for l in method(data,cw,fs,color)]
 
 
 	has_wallet  = True
 	has_wallet  = True
 	has_amt2    = False
 	has_amt2    = False
@@ -343,7 +345,7 @@ class TwView(MMGenObject,metaclass=AsyncInit):
 				cwh = cw._asdict()
 				cwh = cw._asdict()
 				fp = self.fs_params
 				fp = self.fs_params
 				hdr_fs = ''.join(fp[name].hdr_fs % ((),cwh[name])[fp[name].hdr_fs_repl]
 				hdr_fs = ''.join(fp[name].hdr_fs % ((),cwh[name])[fp[name].hdr_fs_repl]
-					for name in dt.cols if cwh[name])
+					for name in dt.cols if cwh[name]) + '\n'
 				fs = ''.join(fp[name].fs % ((),cwh[name])[fp[name].fs_repl]
 				fs = ''.join(fp[name].fs % ((),cwh[name])[fp[name].fs_repl]
 					for name in dt.cols if cwh[name])
 					for name in dt.cols if cwh[name])
 			else:
 			else:
@@ -355,14 +357,15 @@ class TwView(MMGenObject,metaclass=AsyncInit):
 
 
 			def get_body(method):
 			def get_body(method):
 				if line_processing:
 				if line_processing:
-					return lp_cls.do(method,data,cw,hdr_fs,fs,color)
+					return lp_cls.do(method,data,cw,fs,color)
 				else:
 				else:
-					return method(data,cw,hdr_fs,fs,color)
+					return method(data,cw,fs,color)
 
 
-			self._display_data[display_type] = '{a}{b}\n{c}\n'.format(
+			self._display_data[display_type] = '{a}{b}\n{c}{d}\n'.format(
 				a = self.header(color),
 				a = self.header(color),
 				b = self.subheader(color),
 				b = self.subheader(color),
-				c = (
+				c = getattr(self,dt.hdr_fmt_method)(cw,hdr_fs,color) if data else '',
+				d = (
 					dt.item_separator.join(get_body(getattr(self,dt.fmt_method))) if data else
 					dt.item_separator.join(get_body(getattr(self,dt.fmt_method))) if data else
 					(nocolor,yellow)[color]('[no data for requested parameters]'))
 					(nocolor,yellow)[color]('[no data for requested parameters]'))
 			)
 			)
@@ -402,6 +405,7 @@ class TwView(MMGenObject,metaclass=AsyncInit):
 				continue
 				continue
 
 
 			action = self.key_mappings[reply]
 			action = self.key_mappings[reply]
+
 			if hasattr(self.action,action):
 			if hasattr(self.action,action):
 				await self.action().run(self,action)
 				await self.action().run(self,action)
 			elif action.startswith('s_'): # put here to allow overriding by action method
 			elif action.startswith('s_'): # put here to allow overriding by action method

+ 16 - 0
test/test_py_d/ts_regtest.py

@@ -336,6 +336,8 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared):
 	),
 	),
 	'view': (
 	'view': (
 		'viewing addresses and unspent outputs',
 		'viewing addresses and unspent outputs',
+		('alice_listaddresses_empty',     'listaddresses (no data)'),
+		('alice_listaddresses_menu',      'listaddresses (menu items)'),
 		('alice_listaddresses1',          'listaddresses'),
 		('alice_listaddresses1',          'listaddresses'),
 		('alice_listaddresses_days',      'listaddresses (age_fmt=days)'),
 		('alice_listaddresses_days',      'listaddresses (age_fmt=days)'),
 		('alice_listaddresses_date',      'listaddresses (age_fmt=date)'),
 		('alice_listaddresses_date',      'listaddresses (age_fmt=date)'),
@@ -1251,6 +1253,20 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared):
 		t.expect(r'\[q\]uit view, .*?:.','q',regex=True)
 		t.expect(r'\[q\]uit view, .*?:.','q',regex=True)
 		return t
 		return t
 
 
+	def _alice_listaddresses_interactive(self,expect=(),expect_menu=()):
+		t = self.spawn('mmgen-tool',['--alice','listaddresses','interactive=1'])
+		for s in expect_menu:
+			t.expect('abel:\b',s)
+		for p,s in expect:
+			t.expect(p,s)
+		return t
+
+	def alice_listaddresses_empty(self):
+		return self._alice_listaddresses_interactive(expect_menu='uuEq')
+
+	def alice_listaddresses_menu(self):
+		return self._alice_listaddresses_interactive(expect_menu='aAMrDDDDLeq')
+
 	def alice_listaddresses(self,args,expect):
 	def alice_listaddresses(self,args,expect):
 		t = self.spawn('mmgen-tool',['--alice','listaddresses','showempty=1'] + args)
 		t = self.spawn('mmgen-tool',['--alice','listaddresses','showempty=1'] + args)
 		expect_str = r'\D{}\D.*\b{}'.format(*expect)
 		expect_str = r'\D{}\D.*\b{}'.format(*expect)