1919import paramiko
2020
2121from socket import socket
22- from enum import Enum
22+
2323from threading import Thread
2424from typing import TextIO
2525from openstack_cli .modules .apputils .terminal .get_terminal_size import get_terminal_size
26+ from openstack_cli .modules .apputils .terminal .getch import getch as _getch , FUNC_KEYS , NCODE_KEYS , VTKEYS
2627
2728
28- def _find_getch ():
29- try : # UNIX like
30- import termios
31- except ImportError : # Windows
32- import msvcrt
33- import ctypes
34-
35- kernel32 = ctypes .windll .kernel32
36- kernel32 .SetConsoleMode (kernel32 .GetStdHandle (- 11 ), 7 )
37- return msvcrt .getch
38-
39- import sys , tty
40- def _getch ():
41- fd = sys .stdin .fileno ()
42- old_settings = termios .tcgetattr (fd )
43- try :
44- tty .setraw (fd )
45- ch = sys .stdin .read (1 )
46- finally :
47- termios .tcsetattr (fd , termios .TCSADRAIN , old_settings )
48- return ch
49-
50- return _getch
51-
52- _getch = _find_getch ()
53-
54- LL = False
29+ F12MENU = False
5530SIGINT = False
5631
57-
58- def generate_ch_seq (arr ):
59- return '' .join ([chr (x ) for x in arr ])
60-
61- # check https://gist.github.com/hapylestat/1101cc1a5bde125cc5d56c6a401a4f35 tool for obtaining key sequences
62-
63- NCODE_F_KEYS = 0
64- NCODE_SP_KEYS = 224
65-
66- class FKEYS (Enum ): #NCODE_F_KEYS
67- F1 = 59
68- F2 = 60
69- F3 = 61
70- F4 = 62
71- F5 = 63
72- F6 = 64
73- F7 = 65
74- F8 = 66
75- F9 = 67
76- F10 = 68
77- F12 = 134
78-
79- class ARROWS (Enum ): #NCODE_SP_KEYS
80- UP = 72
81- DOWN = 80
82- RIGHT = 77
83- LEFT = 75
84-
85- class KEYS (Enum ): # NCODE_SP_KEYS
86- INSERT = 82
87- DELETE = 83
88- HOME = 71
89- END = 79
90- PAGEUP = 73
91- PAGEDOWN = 81
92-
93- class NCODE_KEYS (Enum ):
94- TAB = 9
95- ENTER = 13
96- BACKSPACE = 8
97- ESC = 27
98-
99-
100- fkeys = {
101- FKEYS .F1 .value : generate_ch_seq ([27 , 79 , 80 ]), # F1
102- FKEYS .F2 .value : generate_ch_seq ([27 , 79 , 81 ]), # F2
103- FKEYS .F3 .value : generate_ch_seq ([27 , 79 , 82 ]), # F3
104- FKEYS .F4 .value : generate_ch_seq ([27 , 79 , 83 ]), # F4
105- FKEYS .F5 .value : generate_ch_seq ([27 , 91 , 49 , 53 , 126 ]), # F5
106- FKEYS .F6 .value : generate_ch_seq ([27 , 91 , 49 , 55 , 126 ]), # F6
107- FKEYS .F7 .value : generate_ch_seq ([27 , 91 , 49 , 56 , 126 ]), # F7
108- FKEYS .F8 .value : generate_ch_seq ([27 , 91 , 49 , 57 , 126 ]), # F8
109- FKEYS .F9 .value : generate_ch_seq ([27 , 91 , 50 , 48 , 126 ]), # F9
110- FKEYS .F10 .value : generate_ch_seq ([27 , 91 , 50 , 49 , 126 ]) # F10
111- }
112-
113- # escape seq
114- arrows = {
115- ARROWS .UP .value : "\033 [A" , # up
116- ARROWS .DOWN .value : "\033 [B" , # down
117- ARROWS .RIGHT .value : "\033 [C" , # right
118- ARROWS .LEFT .value : "\033 [D" # left
119- }
120-
121- # 224 code subspace
122- nav_keys = {
123- KEYS .INSERT .value : generate_ch_seq ([27 , 91 , 50 , 126 ]), # insert
124- KEYS .DELETE .value : generate_ch_seq ([27 , 91 , 51 , 126 ]), # delete
125- KEYS .HOME .value : generate_ch_seq ([27 , 91 , 72 ]), # home
126- KEYS .END .value : generate_ch_seq ([27 , 91 , 70 ]), # end
127- KEYS .PAGEUP .value : generate_ch_seq ([27 , 91 , 53 , 126 ]), # PageUp
128- KEYS .PAGEDOWN .value : generate_ch_seq ([27 , 91 , 54 , 126 ]), # PageDown
129- }
130-
131- """
132- Requirements:
133-
134- export TERM=xterm-noapp
135- """
136-
137-
138- def _special_commands (channel : paramiko .Channel ):
139- global LL
32+ def _f12_commands (channel : paramiko .Channel ):
33+ global F12MENU
14034 global SIGINT
141- _k = ord (_getch ())
142- if _k == NCODE_SP_KEYS and ord (_getch ()) == FKEYS .F12 .value :
143- LL = not LL
144- print ("\n Character code debugging is: {}" .format (LL ))
145- if LL :
35+ _k = _getch ()
36+
37+ if _k == FUNC_KEYS .F12 .value :
38+ F12MENU = not F12MENU
39+ print (f"\n Character code debugging is: { F12MENU } " )
40+ if F12MENU :
14641 print ("> " , end = '' , flush = True )
147- elif _k == NCODE_F_KEYS and ord ( getch ()) == FKEYS .F5 .value :
42+ elif _k == FUNC_KEYS .F5 .value :
14843 channel .resize_pty (* get_terminal_size ())
149- elif _k == 99 : # C:
44+ elif _k == ( 99 ,) : # C:
15045 SIGINT = True
151- elif _k == 105 : # I
46+ elif _k == ( 105 ,) : # I
15247 t : paramiko .Transport = channel .get_transport ()
15348 sock : socket = t .sock
15449 localname , peername = sock .getsockname (), sock .getpeername ()
@@ -167,62 +62,36 @@ def _special_commands(channel: paramiko.Channel):
16762 else :
16863 return chr (7 )
16964
170- # check pynput code
17165
172- def getch (cmd : TextIO , channel : paramiko .Channel ):
66+ def getch (channel : paramiko .Channel ):
17367 global SIGINT
17468
17569 if SIGINT :
17670 SIGINT = False
17771 return chr (3 )
17872
17973 ch = _getch ()
180- n = ord (ch )
181- nn = None
182-
183- if n in (NCODE_F_KEYS , NCODE_SP_KEYS ): # some sequences return several codes
184- nn = ord (_getch ())
185-
186- if LL and not (n == NCODE_SP_KEYS and nn == FKEYS .F12 .value ):
187- if nn :
188- print ("{} {} " .format (n , nn ), end = '' , flush = True )
189- else :
190- print ("{} " .format (n ), end = '' , flush = True )
19174
75+ if F12MENU and ch != FUNC_KEYS .F12 .value :
76+ print (f"{ ch } " , end = '' , flush = True )
19277 return
193- elif n == NCODE_SP_KEYS : # next will come arrow keys
194- if nn in arrows :
195- return arrows [nn ]
196-
197- if nn in nav_keys :
198- return nav_keys [nn ]
199-
200- if nn == FKEYS .F12 .value : # F12 CUSTOM COMMANDS
201- return _special_commands (channel )
202- elif n == NCODE_F_KEYS : # F1-F12
203- if nn in fkeys :
204- return fkeys [nn ]
205- elif n == NCODE_KEYS .TAB .value :
78+ elif ch == FUNC_KEYS .F12 .value :
79+ return _f12_commands (channel )
80+ elif ch in VTKEYS :
81+ return VTKEYS [ch ]
82+ elif ch == NCODE_KEYS .TAB .value :
20683 return "\t "
207- elif n in (NCODE_KEYS .ENTER .value , NCODE_KEYS .BACKSPACE .value , NCODE_KEYS .ESC .value ):
84+ elif ch in (NCODE_KEYS .ENTER .value , NCODE_KEYS .BACKSPACE .value , NCODE_KEYS .ESC .value ):
20885 pass
209- # elif n < 32 or n > 177:
210- # print("Unknown char! Char code: {}".format(n))
21186
212-
213- return ch
87+ return "" .join ([chr (c ) for c in ch ])
21488
21589
21690def _sigint (signum , frame ):
21791 global SIGINT
21892 SIGINT = True
21993
22094
221- def _sigwinch (* args ):
222- print ("EE:" )
223- print (args )
224-
225-
22695def __buffered_reader (stdread : paramiko .ChannelFile , stdwrite : TextIO ):
22796 global SIGINT
22897 import select
@@ -242,7 +111,7 @@ def __buffered_reader(stdread: paramiko.ChannelFile, stdwrite: TextIO):
242111def __input_handler (stdin : TextIO , rstdin : TextIO , channel : paramiko .Channel ):
243112 global SIGINT
244113 while not SIGINT :
245- buff = getch (stdin , channel )
114+ buff = getch (channel )
246115 if buff :
247116 if isinstance (buff , str ):
248117 buff = buff .encode ("UTF-8" )
0 commit comments