Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
蜕变的菜鸟
glances
提交
f7f57251
G
glances
项目概览
蜕变的菜鸟
/
glances
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
glances
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
f7f57251
编写于
11月 15, 2014
作者:
N
Nicolargo
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Refactor Curses output for client browser
上级
5a950e6a
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
257 addition
and
232 deletion
+257
-232
glances/core/glances_autodiscover.py
glances/core/glances_autodiscover.py
+18
-19
glances/core/glances_client.py
glances/core/glances_client.py
+2
-2
glances/core/glances_client_browser.py
glances/core/glances_client_browser.py
+15
-27
glances/outputs/glances_curses.py
glances/outputs/glances_curses.py
+222
-184
未找到文件。
glances/core/glances_autodiscover.py
浏览文件 @
f7f57251
...
...
@@ -45,31 +45,30 @@ class AutoDiscovered(object):
"""Class to manage the auto discovered servers dict"""
def
__init__
(
self
):
# server_dict is a dict of dict
# !!! server_dict SHOULD BE REFACTOR to list of dict to be JSON compliant
# key: ip:port
# value: {'cpu': 3, 'mem': 34 ...}
self
.
_server_dict
=
{}
# server_dict is a list of dict (JSON compliant)
# [ {'key': 'zeroconf name', ip': '172.1.2.3', 'port': 61209, 'cpu': 3, 'mem': 34 ...} ... ]
self
.
_server_list
=
[]
def
get_servers_list
(
self
):
"""Return the current server list (
dic
t of dict)"""
return
self
.
_server_
dic
t
"""Return the current server list (
lis
t of dict)"""
return
self
.
_server_
lis
t
def
add_server
(
self
,
name
,
ip
,
port
):
"""Add a new server to the dict"""
try
:
self
.
_server_dict
[
name
]
=
{
'name'
:
name
.
split
(
':'
)[
0
],
'ip'
:
ip
,
'port'
:
port
}
logger
.
debug
(
"Servers list: %s"
%
self
.
_server_dict
)
except
KeyError
:
pass
"""Add a new server to the list"""
new_server
=
{
'key'
:
name
,
'name'
:
name
.
split
(
':'
)[
0
],
'ip'
:
ip
,
'port'
:
port
}
self
.
_server_list
.
append
(
new_server
)
logger
.
debug
(
"Servers list: %s"
%
self
.
_server_list
)
def
remove_server
(
self
,
name
):
"""Remove a server from the dict"""
try
:
del
(
self
.
_server_dict
[
name
])
logger
.
debug
(
"Servers list: %s"
%
self
.
_server_dict
)
except
KeyError
:
pass
for
i
in
self
.
_server_list
:
if
i
[
'key'
]
==
name
:
try
:
self
.
_server_list
.
remove
(
i
)
logger
.
debug
(
"Remove server %s from the list"
%
name
)
logger
.
debug
(
"Updated servers list: %s"
%
self
.
_server_list
)
except
ValueError
:
logger
.
error
(
"Can not remove server %s from the list"
%
name
)
class
GlancesAutoDiscoverListener
(
object
):
...
...
@@ -81,7 +80,7 @@ class GlancesAutoDiscoverListener(object):
self
.
servers
=
AutoDiscovered
()
def
get_servers_list
(
self
):
"""Return the current server list (
dic
t of dict)"""
"""Return the current server list (
lis
t of dict)"""
return
self
.
servers
.
get_servers_list
()
def
addService
(
self
,
zeroconf
,
srv_type
,
srv_name
):
...
...
glances/core/glances_client.py
浏览文件 @
f7f57251
...
...
@@ -37,7 +37,7 @@ except:
# Import Glances libs
from
glances.core.glances_globals
import
version
,
logger
from
glances.core.glances_stats
import
GlancesStatsClient
from
glances.outputs.glances_curses
import
GlancesCurses
from
glances.outputs.glances_curses
import
GlancesCurses
Client
from
glances.core.glances_autodiscover
import
GlancesAutoDiscoverServer
...
...
@@ -164,7 +164,7 @@ class GlancesClient(object):
self
.
stats
.
load_limits
(
self
.
config
)
# Init screen
self
.
screen
=
GlancesCurses
(
args
=
self
.
args
)
self
.
screen
=
GlancesCurses
Client
(
args
=
self
.
args
)
# Return result
return
ret
...
...
glances/core/glances_client_browser.py
浏览文件 @
f7f57251
...
...
@@ -23,14 +23,14 @@
import
json
import
socket
try
:
from
xmlrpc.client
import
Transport
,
ServerProxy
,
ProtocolError
,
Fault
from
xmlrpc.client
import
ServerProxy
,
Fault
except
ImportError
:
# Python 2
from
xmlrpclib
import
Transport
,
ServerProxy
,
ProtocolError
,
Fault
from
xmlrpclib
import
ServerProxy
,
Fault
# Import Glances libs
from
glances.core.glances_globals
import
logger
from
glances.outputs.glances_curses
import
GlancesCurses
from
glances.outputs.glances_curses
import
GlancesCurses
Browser
from
glances.core.glances_autodiscover
import
GlancesAutoDiscoverServer
from
glances.core.glances_client
import
GlancesClientTransport
...
...
@@ -49,7 +49,7 @@ class GlancesClientBrowser(object):
self
.
autodiscover_server
=
GlancesAutoDiscoverServer
()
# Init screen
self
.
screen
=
GlancesCurses
(
args
=
self
.
args
)
self
.
screen
=
GlancesCurses
Browser
(
args
=
self
.
args
)
def
get_servers_list
(
self
):
"""Return the current server list (dict of dict)"""
...
...
@@ -66,15 +66,9 @@ class GlancesClientBrowser(object):
# For each server in the list, grab elementary stats (CPU, LOAD, MEM)
# logger.debug(self.get_servers_list())
try
:
iteritems
=
self
.
get_servers_list
().
iteritems
()
except
AttributeError
:
iteritems
=
self
.
get_servers_list
().
items
()
# Dictionnary can change size during iteration...
try
:
for
k
,
v
in
iteritems
:
for
v
in
self
.
get_servers_list
():
# !!! Perhaps, it will be better to store the ServerProxy instance in the get_servers_list
uri
=
'http://%s:%s'
%
(
self
.
get_servers_list
()
[
k
][
'ip'
],
self
.
get_servers_list
()[
k
][
'port'
])
uri
=
'http://%s:%s'
%
(
v
[
'ip'
],
v
[
'port'
])
# Configure the server timeout to 3 seconds
t
=
GlancesClientTransport
()
t
.
set_timeout
(
3
)
...
...
@@ -82,31 +76,25 @@ class GlancesClientBrowser(object):
try
:
s
=
ServerProxy
(
uri
,
t
)
except
Exception
as
e
:
logger
.
warning
(
_
(
"Couldn't create socket {0}: {1}"
).
format
(
uri
,
e
))
logger
.
warning
(
"Couldn't create socket {0}: {1}"
.
format
(
uri
,
e
))
else
:
try
:
# LOAD
self
.
get_servers_list
()[
k
][
'load_min5'
]
=
json
.
loads
(
s
.
getLoad
())[
'min5'
]
v
[
'load_min5'
]
=
json
.
loads
(
s
.
getLoad
())[
'min5'
]
# CPU%
self
.
get_servers_list
()[
k
][
'cpu_percent'
]
=
100
-
json
.
loads
(
s
.
getCpu
())[
'idle'
]
v
[
'cpu_percent'
]
=
100
-
json
.
loads
(
s
.
getCpu
())[
'idle'
]
# MEM%
self
.
get_servers_list
()[
k
][
'mem_percent'
]
=
json
.
loads
(
s
.
getMem
())[
'percent'
]
v
[
'mem_percent'
]
=
json
.
loads
(
s
.
getMem
())[
'percent'
]
# OS (human readable name)
self
.
get_servers_list
()[
k
][
'hr_name'
]
=
json
.
loads
(
s
.
getSystem
())[
'hr_name'
]
v
[
'hr_name'
]
=
json
.
loads
(
s
.
getSystem
())[
'hr_name'
]
except
(
socket
.
error
,
Fault
,
KeyError
)
as
e
:
logger
.
warning
(
_
(
"Can not grab stats form {0}: {1}"
).
format
(
uri
,
e
))
logger
.
warning
(
"Can not grab stats form {0}: {1}"
.
format
(
uri
,
e
))
# List can change size during iteration...
except
RuntimeError
:
logger
.
debug
(
_
(
"Server list dictionnary change inside the loop (wait next update)"
))
logger
.
debug
(
"Server list dictionnary change inside the loop (wait next update)"
)
# Update the screen
self
.
screen
.
update
_browser
(
self
.
get_servers_list
())
self
.
screen
.
update
(
self
.
get_servers_list
())
def
end
(
self
):
"""End of the client session."""
...
...
glances/outputs/glances_curses.py
浏览文件 @
f7f57251
...
...
@@ -43,9 +43,12 @@ else:
curses
=
WCurseLight
()
class
GlancesCurses
(
object
):
class
_
GlancesCurses
(
object
):
"""This class manages the curses display (and key pressed)."""
"""
This class manages the curses display (and key pressed).
Note: It is a private class, use GlancesCursesClient or GlancesCursesBrowser
"""
def
__init__
(
self
,
args
=
None
):
# Init args
...
...
@@ -146,7 +149,7 @@ class GlancesCurses(object):
self
.
filter_color
=
A_BOLD
# Define the colors list (hash table) for stats
self
.
__
colors_list
=
{
self
.
colors_list
=
{
'DEFAULT'
:
self
.
no_color
,
'UNDERLINE'
:
curses
.
A_UNDERLINE
,
'BOLD'
:
A_BOLD
,
...
...
@@ -196,11 +199,8 @@ class GlancesCurses(object):
logger
.
error
(
'Stats history disabled because MatPlotLib is not installed'
)
# Init the cursor position for the client browser
self
.
cursor_init
()
def
set_cursor
(
self
,
value
):
"""Configure the curs
or
"""Configure the curs
e cursor apparence
0: invisible
1: visible
2: very visible
...
...
@@ -211,7 +211,7 @@ class GlancesCurses(object):
except
Exception
:
pass
def
__
get_key
(
self
,
window
):
def
get_key
(
self
,
window
):
# Catch ESC key AND numlock key (issue #163)
keycode
=
[
0
,
0
]
keycode
[
0
]
=
window
.
getch
()
...
...
@@ -228,7 +228,7 @@ class GlancesCurses(object):
def
__catch_key
(
self
):
# Catch the pressed key
self
.
pressedkey
=
self
.
__
get_key
(
self
.
term_window
)
self
.
pressedkey
=
self
.
get_key
(
self
.
term_window
)
# Actions...
if
self
.
pressedkey
==
ord
(
'
\x1b
'
)
or
self
.
pressedkey
==
ord
(
'q'
):
...
...
@@ -330,48 +330,6 @@ class GlancesCurses(object):
# Return the key code
return
self
.
pressedkey
def
cursor_init
(
self
):
"""Init the cursor position to the top of the list"""
self
.
cursor_position
=
0
def
cursor_get
(
self
):
"""Return the cursor position"""
return
self
.
cursor_position
def
cursor_up
(
self
):
"""Set the cursor to position N-1 in the list"""
if
self
.
cursor_position
>
0
:
self
.
cursor_position
-=
1
def
cursor_down
(
self
,
servers_list
):
"""Set the cursor to position N-1 in the list"""
if
self
.
cursor_position
<
len
(
servers_list
)
-
1
:
self
.
cursor_position
+=
1
def
__catch_key_browser
(
self
,
servers_list
):
# Catch the browser pressed key
self
.
pressedkey
=
self
.
__get_key
(
self
.
term_window
)
# Actions...
if
self
.
pressedkey
==
ord
(
'
\x1b
'
)
or
self
.
pressedkey
==
ord
(
'q'
):
# 'ESC'|'q' > Quit
self
.
end
()
logger
.
info
(
"Stop Glances client browser"
)
sys
.
exit
(
0
)
elif
self
.
pressedkey
==
10
:
# 'ENTER' > Run Glances on the selected server
logger
.
debug
(
"Line %s selected in the server list"
%
self
.
cursor_get
())
elif
self
.
pressedkey
==
259
:
# 'UP' > Up in the server list
logger
self
.
cursor_up
()
elif
self
.
pressedkey
==
258
:
# 'DOWN' > Down in the server list
self
.
cursor_down
(
servers_list
)
# Return the key code
return
self
.
pressedkey
def
end
(
self
):
"""Shutdown the curses window."""
if
hasattr
(
curses
,
'echo'
):
...
...
@@ -410,109 +368,6 @@ class GlancesCurses(object):
"""New column in the curses interface"""
self
.
column
=
self
.
next_column
def
display_browser
(
self
,
servers_list
):
"""Display the servers list
Return:
True if the stats have been displayed
False if the stats have not been displayed (no server available)
"""
# Init the internal line/column for Glances Curses
self
.
init_line_column
()
# Get the current screen size
screen_x
=
self
.
screen
.
getmaxyx
()[
1
]
screen_y
=
self
.
screen
.
getmaxyx
()[
0
]
# Init position
x
=
0
y
=
0
# Display top header
if
len
(
servers_list
)
==
0
:
msg
=
_
(
"No Glances server detected on your network"
)
elif
len
(
servers_list
)
==
1
:
msg
=
_
(
"One Glances server detected on your network"
)
else
:
msg
=
_
(
"%d Glances servers detected on your network"
%
len
(
servers_list
))
self
.
term_window
.
addnstr
(
y
,
x
,
msg
,
screen_x
-
x
,
self
.
__colors_list
[
'TITLE'
])
if
len
(
servers_list
)
==
0
:
return
False
# Display the Glances server list
#================================
# Table of table
# Item description: [stats_id, column name, column size]
column_def
=
[
[
'name'
,
_
(
'Name'
),
16
],
[
'load_min5'
,
_
(
'LOAD'
),
6
],
[
'cpu_percent'
,
_
(
'CPU%'
),
5
],
[
'mem_percent'
,
_
(
'MEM%'
),
5
],
[
'ip'
,
_
(
'IP'
),
15
],
[
'hr_name'
,
_
(
'OS'
),
16
],
]
y
=
2
# Display table header
cpt
=
0
xc
=
x
+
2
for
c
in
column_def
:
self
.
term_window
.
addnstr
(
y
,
xc
,
c
[
1
],
screen_x
-
x
,
self
.
__colors_list
[
'BOLD'
])
xc
+=
c
[
2
]
+
2
cpt
+=
1
y
+=
1
# Display table
line
=
0
try
:
iteritems
=
servers_list
.
iteritems
()
except
AttributeError
:
iteritems
=
servers_list
.
items
()
for
k
,
v
in
iteritems
:
# Get server stats
try
:
server_stat
=
{}
for
c
in
column_def
:
server_stat
[
c
[
0
]]
=
servers_list
[
k
][
c
[
0
]]
except
KeyError
as
e
:
logger
.
debug
(
_
(
"Can not grab stats %s from server (KeyError: %s)"
)
%
(
c
[
0
],
e
))
continue
# Display line for server stats
cpt
=
0
xc
=
x
# Is the line selected ?
if
line
==
self
.
cursor_get
():
# Display cursor
self
.
term_window
.
addnstr
(
y
,
xc
,
">"
,
screen_x
-
x
,
self
.
__colors_list
[
'BOLD'
])
xc
+=
2
for
c
in
column_def
:
# Display server stats
self
.
term_window
.
addnstr
(
y
,
xc
,
"%s"
%
server_stat
[
c
[
0
]],
screen_x
-
x
,
self
.
__colors_list
[
'DEFAULT'
])
xc
+=
c
[
2
]
+
2
cpt
+=
1
# Next line, next server...
y
+=
1
line
+=
1
return
True
def
display
(
self
,
stats
,
cs_status
=
"None"
):
"""Display stats on the screen.
...
...
@@ -767,7 +622,7 @@ class GlancesCurses(object):
if
is_input
and
not
is_windows
:
# Create a subwindow for the text field
subpop
=
popup
.
derwin
(
1
,
input_size
,
2
,
2
+
len
(
m
))
subpop
.
attron
(
self
.
__
colors_list
[
'FILTER'
])
subpop
.
attron
(
self
.
colors_list
[
'FILTER'
])
# Init the field with the current value
if
input_value
is
not
None
:
subpop
.
addnstr
(
0
,
0
,
input_value
,
len
(
input_value
))
...
...
@@ -856,7 +711,7 @@ class GlancesCurses(object):
m
[
'msg'
],
# Do not disply outside the screen
screen_x
-
x
,
self
.
__
colors_list
[
m
[
'decoration'
]])
self
.
colors_list
[
m
[
'decoration'
]])
except
:
pass
else
:
...
...
@@ -883,14 +738,6 @@ class GlancesCurses(object):
self
.
erase
()
self
.
display
(
stats
,
cs_status
=
cs_status
)
def
flush_browser
(
self
,
servers_list
):
"""Update the servers' list screen.
servers_list: Dict of dict with servers stats
"""
self
.
erase
()
self
.
display_browser
(
servers_list
)
def
update
(
self
,
stats
,
cs_status
=
"None"
):
"""Update the screen.
...
...
@@ -915,26 +762,6 @@ class GlancesCurses(object):
# Wait 100ms...
curses
.
napms
(
100
)
def
update_browser
(
self
,
servers_list
):
"""Update the servers' list screen.
Wait for __refresh_time sec / catch key every 100 ms.
servers_list: Dict of dict with servers stats
"""
# Flush display
self
.
flush_browser
(
servers_list
)
# Wait
countdown
=
Timer
(
self
.
__refresh_time
)
while
not
countdown
.
finished
():
# Getkey
if
self
.
__catch_key_browser
(
servers_list
)
>
-
1
:
# Redraw display
self
.
flush_browser
(
servers_list
)
# Wait 100ms...
curses
.
napms
(
100
)
def
get_stats_display_width
(
self
,
curse_msg
,
without_option
=
False
):
"""Return the width of the formatted curses message.
...
...
@@ -966,6 +793,217 @@ class GlancesCurses(object):
else
:
return
c
+
1
class
GlancesCursesClient
(
_GlancesCurses
):
"""Class for the Glances' curse client"""
pass
class
GlancesCursesBrowser
(
_GlancesCurses
):
"""Class for the Glances' curse client browser"""
def
__init__
(
self
,
args
=
None
):
# Init the father class
_GlancesCurses
.
__init__
(
self
,
args
=
args
)
# Init refresh time
self
.
__refresh_time
=
args
.
time
# Init the cursor position for the client browser
self
.
cursor_init
()
def
cursor_init
(
self
):
"""Init the cursor position to the top of the list"""
return
self
.
cursor_set
(
0
)
def
cursor_set
(
self
,
pos
):
"""Set the cursor position andd return it"""
self
.
cursor_position
=
pos
return
self
.
cursor_position
def
cursor_get
(
self
):
"""Return the cursor position"""
return
self
.
cursor_position
def
cursor_up
(
self
):
"""Set the cursor to position N-1 in the list"""
if
self
.
cursor_position
>
0
:
self
.
cursor_position
-=
1
return
self
.
cursor_position
def
cursor_down
(
self
,
servers_list
):
"""Set the cursor to position N-1 in the list"""
if
self
.
cursor_position
<
len
(
servers_list
)
-
1
:
self
.
cursor_position
+=
1
return
self
.
cursor_position
def
__catch_key
(
self
,
servers_list
):
# Catch the browser pressed key
self
.
pressedkey
=
self
.
get_key
(
self
.
term_window
)
# Actions...
if
self
.
pressedkey
==
ord
(
'
\x1b
'
)
or
self
.
pressedkey
==
ord
(
'q'
):
# 'ESC'|'q' > Quit
self
.
end
()
logger
.
info
(
"Stop Glances client browser"
)
sys
.
exit
(
0
)
elif
self
.
pressedkey
==
10
:
# 'ENTER' > Run Glances on the selected server
logger
.
debug
(
"Server number %s selected"
%
(
self
.
cursor_get
()
+
1
))
self
.
run_client
(
servers_list
[
self
.
cursor_get
()])
elif
self
.
pressedkey
==
259
:
# 'UP' > Up in the server list
logger
self
.
cursor_up
()
elif
self
.
pressedkey
==
258
:
# 'DOWN' > Down in the server list
self
.
cursor_down
(
servers_list
)
# Return the key code
return
self
.
pressedkey
def
run_client
(
self
,
server
):
"""Run the Glances client to the given server"""
logger
.
debug
(
"Run Glances client on %s"
%
server
)
def
update
(
self
,
servers_list
):
"""Update the servers' list screen.
Wait for __refresh_time sec / catch key every 100 ms.
servers_list: Dict of dict with servers stats
"""
# Flush display
self
.
flush
(
servers_list
)
# Wait
countdown
=
Timer
(
self
.
__refresh_time
)
while
not
countdown
.
finished
():
# Getkey
if
self
.
__catch_key
(
servers_list
)
>
-
1
:
# Redraw display
self
.
flush
(
servers_list
)
# Wait 100ms...
curses
.
napms
(
100
)
def
flush
(
self
,
servers_list
):
"""Update the servers' list screen.
servers_list: List of dict with servers stats
"""
self
.
erase
()
self
.
display
(
servers_list
)
def
display
(
self
,
servers_list
):
"""Display the servers list
Return:
True if the stats have been displayed
False if the stats have not been displayed (no server available)
"""
# Init the internal line/column for Glances Curses
self
.
init_line_column
()
# Get the current screen size
screen_x
=
self
.
screen
.
getmaxyx
()[
1
]
screen_y
=
self
.
screen
.
getmaxyx
()[
0
]
# Init position
x
=
0
y
=
0
# Display top header
if
len
(
servers_list
)
==
0
:
msg
=
_
(
"No Glances server detected on your network"
)
elif
len
(
servers_list
)
==
1
:
msg
=
_
(
"One Glances server detected on your network"
)
else
:
msg
=
_
(
"%d Glances servers detected on your network"
%
len
(
servers_list
))
self
.
term_window
.
addnstr
(
y
,
x
,
msg
,
screen_x
-
x
,
self
.
colors_list
[
'TITLE'
])
if
len
(
servers_list
)
==
0
:
return
False
# Display the Glances server list
#================================
# Table of table
# Item description: [stats_id, column name, column size]
column_def
=
[
[
'name'
,
_
(
'Name'
),
16
],
[
'load_min5'
,
_
(
'LOAD'
),
6
],
[
'cpu_percent'
,
_
(
'CPU%'
),
5
],
[
'mem_percent'
,
_
(
'MEM%'
),
5
],
[
'ip'
,
_
(
'IP'
),
15
],
[
'hr_name'
,
_
(
'OS'
),
16
],
]
y
=
2
# Display table header
cpt
=
0
xc
=
x
+
2
for
c
in
column_def
:
self
.
term_window
.
addnstr
(
y
,
xc
,
c
[
1
],
screen_x
-
x
,
self
.
colors_list
[
'BOLD'
])
xc
+=
c
[
2
]
+
self
.
space_between_column
cpt
+=
1
y
+=
1
# If a servers has been deleted from the list...
# ... and if the cursor is in the latest position
if
self
.
cursor_get
()
>
len
(
servers_list
)
-
1
:
# Set the cursor position to the latest item
self
.
cursor_set
(
len
(
servers_list
)
-
1
)
# Display table
line
=
0
for
v
in
servers_list
:
# Get server stats
try
:
server_stat
=
{}
for
c
in
column_def
:
server_stat
[
c
[
0
]]
=
v
[
c
[
0
]]
except
KeyError
as
e
:
logger
.
debug
(
"Can not grab stats %s from server (KeyError: %s)"
.
format
(
c
[
0
],
e
))
continue
# Display line for server stats
cpt
=
0
xc
=
x
# Is the line selected ?
if
line
==
self
.
cursor_get
():
# Display cursor
self
.
term_window
.
addnstr
(
y
,
xc
,
">"
,
screen_x
-
x
,
self
.
colors_list
[
'BOLD'
])
xc
+=
2
for
c
in
column_def
:
# Display server stats
self
.
term_window
.
addnstr
(
y
,
xc
,
"%s"
%
server_stat
[
c
[
0
]],
screen_x
-
x
,
self
.
colors_list
[
'DEFAULT'
])
xc
+=
c
[
2
]
+
self
.
space_between_column
cpt
+=
1
# Next line, next server...
y
+=
1
line
+=
1
return
True
if
not
is_windows
:
class
glances_textbox
(
Textbox
):
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录