37
37
38
38
_orig_stdout = sys .stdout
39
39
40
+
40
41
def set_window_title (s ):
41
42
print ("\033 ]2;%s\007 " % (s ,), file = _orig_stdout )
42
43
43
- # Workarond for ncurses bug that show error on output to the last position on the screen
44
44
45
- def ignore_curses_err (f , * args , ** kwargs ):
46
- try :
47
- return f (* args , ** kwargs )
48
- except curses .error :
49
- pass
45
+ def ignore_curses_err (f ):
46
+ def _f (* args , ** kwargs ):
47
+ try :
48
+ return f (* args , ** kwargs )
49
+ except curses .error :
50
+ pass
51
+ return _f
52
+
53
+
54
+ @ignore_curses_err
55
+ def addstr_noerr (window , y , x , s , * attrs ):
56
+ for i , c in enumerate (s , x ):
57
+ window .addch (y , i , c , * attrs )
50
58
51
- def addcstr (window , s , attrs = 0 ):
59
+
60
+ def addstr_centered (window , s , attrs = 0 ):
52
61
h , w = window .getmaxyx ()
53
- addstr (window , h // 2 , max ((w - len (s )) // 2 , 0 ), s , attrs )
62
+ addstr_noerr (window , h // 2 , max ((w - len (s )) // 2 , 0 ), s , attrs )
63
+
54
64
55
- def addmcstr (window , y , x , s , attrs = 0 ):
65
+ @ignore_curses_err
66
+ def addstr_markup (window , y , x , s , attrs = 0 ):
56
67
for c in s :
57
68
if c == '{' :
58
69
attrs |= curses .A_BOLD
@@ -86,17 +97,14 @@ def rectangle(win, uly, ulx, lry, lrx):
86
97
win .vline (uly + 1 , lrx , curses .ACS_VLINE , lry - uly - 1 )
87
98
win .addch (uly , ulx , curses .ACS_ULCORNER )
88
99
win .addch (uly , lrx , curses .ACS_URCORNER )
89
- ignore_curses_err (win .addch , lry , lrx , curses .ACS_LRCORNER )
90
- win .addch (lry , ulx , curses .ACS_LLCORNER )
91
100
92
-
93
- def addstr (window , y , x , s , * attrs ):
101
+ # Workarond for ncurses bug that show error on output to the last position on the screen
94
102
try :
95
- for i , c in enumerate (s , x ):
96
- window .addch (y , i , c , * attrs )
103
+ win .addch (lry , lrx , curses .ACS_LRCORNER )
97
104
except curses .error :
98
105
pass
99
106
107
+ win .addch (lry , ulx , curses .ACS_LLCORNER )
100
108
101
109
102
110
def human_rate (r ):
@@ -140,7 +148,7 @@ def draw_rx(self, attrs):
140
148
return
141
149
142
150
window .erase ()
143
- addstr (window , 0 , 0 , ' pkt/s pkt' , curses . A_BOLD )
151
+ addstr_markup (window , 0 , 0 , ' { pkt/s pkt}' )
144
152
145
153
msg_l = (('{recv} %4d$ (%d)' % tuple (p ['all' ]), 0 ),
146
154
('{udp} %4d$ (%d)' % tuple (p ['out' ]), 0 ),
@@ -152,32 +160,32 @@ def draw_rx(self, attrs):
152
160
ymax = window .getmaxyx ()[0 ]
153
161
for y , (msg , attr ) in enumerate (msg_l , 1 ):
154
162
if y < ymax :
155
- addmcstr (window , y , 0 , msg , attr )
163
+ addstr_markup (window , y , 0 , msg , attr )
164
+
156
165
157
- window .addstr (0 , 20 , 'Flow: ' , curses .A_BOLD )
158
- window .addstr ('%s -> %s ' % \
159
- (human_rate (p ['all_bytes' ][0 ]),
160
- human_rate (p ['out_bytes' ][0 ])))
166
+ flow_str = '{Flow:} %s -> %s ' % \
167
+ (human_rate (p ['all_bytes' ][0 ]),
168
+ human_rate (p ['out_bytes' ][0 ]))
161
169
162
170
if session_d :
163
- window .addstr ('FEC: ' , curses .A_BOLD )
164
- window .addstr ('%(fec_k)d/%(fec_n)d' % (session_d ))
171
+ flow_str += 'FEC: %(fec_k)d/%(fec_n)d' % (session_d )
165
172
173
+ addstr_markup (window , 0 , 20 , flow_str )
166
174
167
175
if stats_d :
168
- addmcstr (window , 2 , 20 , '{Freq MCS BW [ANT] pkt/s} {RSSI} [dBm] {SNR} [dB]' )
176
+ addstr_markup (window , 2 , 20 , '{Freq MCS BW [ANT] pkt/s} {RSSI} [dBm] {SNR} [dB]' )
169
177
for y , (((freq , mcs_index , bandwith ), ant_id ), v ) in enumerate (sorted (stats_d .items ()), 3 ):
170
178
pkt_s , rssi_min , rssi_avg , rssi_max , snr_min , snr_avg , snr_max = v
171
179
if y < ymax :
172
180
active_tx = (ant_id >> 8 ) == tx_ant
173
- addmcstr (window , y , 20 , '%04d %3d %2d %s%04x%s %4d %3d < {%3d} < %3d %3d < {%3d} < %3d' % \
181
+ addstr_markup (window , y , 20 , '%04d %3d %2d %s%04x%s %4d %3d < {%3d} < %3d %3d < {%3d} < %3d' % \
174
182
(freq , mcs_index , bandwith ,
175
183
'{' if active_tx else '' , ant_id , '}' if active_tx else '' ,
176
184
pkt_s ,
177
185
rssi_min , rssi_avg , rssi_max ,
178
186
snr_min , snr_avg , snr_max ), 0 if active_tx else curses .A_DIM )
179
187
else :
180
- addstr (window , 2 , 20 , '[No data]' , curses .A_REVERSE )
188
+ addstr_noerr (window , 2 , 20 , '[No data]' , curses .A_REVERSE )
181
189
182
190
window .refresh ()
183
191
@@ -191,7 +199,7 @@ def draw_tx(self, attrs):
191
199
return
192
200
193
201
window .erase ()
194
- addstr (window , 0 , 0 , ' pkt/s pkt' , curses .A_BOLD )
202
+ addstr_noerr (window , 0 , 0 , ' pkt/s pkt' , curses .A_BOLD )
195
203
196
204
msg_l = (('{sent} %4d$ (%d)' % tuple (p ['injected' ]), 0 ),
197
205
('{udp} %4d$ (%d)' % tuple (p ['incoming' ]), 0 ),
@@ -202,22 +210,22 @@ def draw_tx(self, attrs):
202
210
ymax = window .getmaxyx ()[0 ]
203
211
for y , (msg , attr ) in enumerate (msg_l , 1 ):
204
212
if y < ymax :
205
- addmcstr (window , y , 0 , msg , attr )
213
+ addstr_markup (window , y , 0 , msg , attr )
206
214
207
- window . addstr ( 0 , 20 , 'Flow: ' , curses . A_BOLD )
208
- window . addstr ( ' %s -> %s' % \
209
- (human_rate (p ['incoming_bytes' ][0 ]),
210
- human_rate (p ['injected_bytes' ][0 ])))
215
+ addstr_markup ( window , 0 , 20 ,
216
+ '{Flow:} %s -> %s' % \
217
+ (human_rate (p ['incoming_bytes' ][0 ]),
218
+ human_rate (p ['injected_bytes' ][0 ])))
211
219
212
220
if latency_d :
213
- addmcstr (window , 2 , 20 , '{[ANT] pkt/s} {Injection} [us]' )
221
+ addstr_markup (window , 2 , 20 , '{[ANT] pkt/s} {Injection} [us]' )
214
222
for y , (k , v ) in enumerate (sorted (latency_d .items ()), 3 ):
215
223
k = int (k ) # json doesn't support int keys
216
224
injected , dropped , lat_min , lat_avg , lat_max = v
217
225
if y < ymax :
218
- addmcstr (window , y , 21 , '{%02x}(xx ) %4d %4d < {%4d} < %4d' % (k >> 8 , injected , lat_min , lat_avg , lat_max ))
226
+ addstr_markup (window , y , 21 , '{%02x}(XX ) %4d %4d < {%4d} < %4d' % (k >> 8 , injected , lat_min , lat_avg , lat_max ))
219
227
else :
220
- addstr (window , 2 , 20 , '[No data]' , curses .A_REVERSE )
228
+ addstr_noerr (window , 2 , 20 , '[No data]' , curses .A_REVERSE )
221
229
222
230
223
231
window .refresh ()
@@ -244,7 +252,7 @@ def init_windows(self):
244
252
245
253
if not service_list :
246
254
rectangle (self .stdscr , 0 , 0 , height - 1 , width - 1 )
247
- addstr (self .stdscr , 0 , 3 , '[%s not configured]' % (self .profile ,), curses .A_REVERSE )
255
+ addstr_noerr (self .stdscr , 0 , 3 , '[%s not configured]' % (self .profile ,), curses .A_REVERSE )
248
256
self .stdscr .refresh ()
249
257
return
250
258
@@ -287,7 +295,7 @@ def init_windows(self):
287
295
window .scrollok (1 )
288
296
289
297
rectangle (self .stdscr , hoff_int , xoff , hoff_int + wh - 1 , xoff + ww )
290
- addstr (self .stdscr , hoff_int , 3 + xoff , '[%s: %s %s]' % (txrx .upper (), self .profile , name ), curses .A_BOLD )
298
+ addstr_noerr (self .stdscr , hoff_int , 3 + xoff , '[%s: %s %s]' % (txrx .upper (), self .profile , name ), curses .A_BOLD )
291
299
292
300
self .windows ['%s %s' % (name , txrx )] = window
293
301
whl .append (wh )
@@ -300,15 +308,15 @@ def startedConnecting(self, connector):
300
308
301
309
for window in self .windows .values ():
302
310
window .erase ()
303
- addcstr (window , 'Connecting...' , curses .A_DIM )
311
+ addstr_centered (window , 'Connecting...' , curses .A_DIM )
304
312
window .refresh ()
305
313
306
314
def buildProtocol (self , addr ):
307
315
set_window_title ('Connected to %s' % (addr ,))
308
316
309
317
for window in self .windows .values ():
310
318
window .erase ()
311
- addcstr (window , 'Waiting for data...' , curses .A_DIM )
319
+ addstr_centered (window , 'Waiting for data...' , curses .A_DIM )
312
320
window .refresh ()
313
321
314
322
self .resetDelay ()
@@ -321,7 +329,7 @@ def clientConnectionLost(self, connector, reason):
321
329
322
330
for window in self .windows .values ():
323
331
window .erase ()
324
- addcstr (window , '[Connection lost]' , curses .A_REVERSE )
332
+ addstr_centered (window , '[Connection lost]' , curses .A_REVERSE )
325
333
window .refresh ()
326
334
327
335
ReconnectingClientFactory .clientConnectionLost (self , connector , reason )
@@ -331,7 +339,7 @@ def clientConnectionFailed(self, connector, reason):
331
339
332
340
for window in self .windows .values ():
333
341
window .erase ()
334
- addcstr (window , '[Connection failed]' , curses .A_REVERSE )
342
+ addstr_centered (window , '[Connection failed]' , curses .A_REVERSE )
335
343
window .refresh ()
336
344
337
345
ReconnectingClientFactory .clientConnectionFailed (self , connector , reason )
0 commit comments