Commit b5221652 authored by ibuler's avatar ibuler

[Update] 优化coco中文显示

parent 0755d134
......@@ -19,7 +19,6 @@ logger = get_logger(__file__)
class BaseNamespace(Namespace):
clients = None
current_user = None
def on_connect(self):
......@@ -39,12 +38,6 @@ class BaseNamespace(Namespace):
user = app_service.check_user_with_token(token)
return user
def close(self):
try:
self.clients[request.sid]["client"].close()
except IndexError:
pass
class ProxyNamespace(BaseNamespace):
def __init__(self, *args, **kwargs):
......@@ -235,13 +228,6 @@ class ProxyNamespace(BaseNamespace):
del self.connections[request.sid][room_id]
del room
@staticmethod
def on_error_default(e):
traceback.print_exc()
logger.warn(e)
error_handler = on_error_default
class HttpServer:
# prepare may be rewrite it
......@@ -264,13 +250,17 @@ class HttpServer:
self.flask_app.config.update(config)
self.socket_io = SocketIO()
self.register_routes()
self.add_error_handler()
def register_routes(self):
self.socket_io.on_namespace(ProxyNamespace('/ssh'))
def add_error_handler(self):
self.socket_io.on_error_default(ProxyNamespace.on_error_default)
@staticmethod
def on_error_default(e):
traceback.print_exc()
logger.warn(e)
def register_error_handler(self):
self.socket_io.on_error_default(self.on_error_default)
def run(self):
host = self.flask_app.config["BIND_HOST"]
......@@ -282,4 +272,4 @@ class HttpServer:
self.socket_io.run(self.flask_app, port=port, host=host, debug=False)
def shutdown(self):
pass
self.socket_io.server.close()
......@@ -12,7 +12,8 @@ from . import char
from .utils import wrap_with_line_feed as wr, wrap_with_title as title, \
wrap_with_warning as warning, is_obj_attr_has, \
is_obj_attr_eq, sort_assets, TtyIOParser, \
ugettext as _, get_logger, net_input
ugettext as _, get_logger, net_input, format_with_zh, item_max_length, \
size_of_str_with_zh
from .ctx import current_app, app_service
from .proxy import ProxyServer
......@@ -56,11 +57,11 @@ class InteractiveServer:
banner = _("""\n {title} {user}, 欢迎使用Jumpserver开源跳板机系统 {end}\r\n\r
1) 输入 {green}ID{end} 直接登录 或 输入{green}部分 IP,主机名,备注{end} 进行搜索登录(如果唯一).\r
2) 输入 {green}/{end} + {green}IP, 主机名{end} or {green}备注 {end}搜索. 如: /ip\r
3) 输入 {green}P/p{end} 显示您有权限的主机.\r
4) 输入 {green}G/g{end} 显示您有权限的主机组.\r
5) 输入 {green}G/g{end} + {green}组ID{end} 显示该组下主机. 如: g1\r
6) 输入 {green}H/h{end} 帮助.\r
0) 输入 {green}Q/q{end} 退出.\r\n""").format(
3) 输入 {green}p{end} 显示您有权限的主机.\r
4) 输入 {green}g{end} 显示您有权限的主机组.\r
5) 输入 {green}g{end} + {green}组ID{end} 显示该节点下主机. 如: g1\r
6) 输入 {green}h{end} 帮助.\r
0) 输入 {green}q{end} 退出.\r\n""").format(
title="\033[1;32m", green="\033[32m",
end="\033[0m", user=self.client.user
)
......@@ -123,17 +124,25 @@ class InteractiveServer:
self.client.send(warning(_("无")))
return
fake_group = AssetGroup(name=_("Name"), assets_amount=_("Assets"), comment=_("Comment"))
id_max_length = max(len(str(len(self.asset_groups))), 5)
name_max_length = max(max([len(group.name) for group in self.asset_groups]), 15)
amount_max_length = max(len(str(max([group.assets_amount for group in self.asset_groups]))), 10)
header = '{1:>%d} {0.name:%d} {0.assets_amount:<%s} ' % (id_max_length, name_max_length, amount_max_length)
comment_length = max(self.request.meta["width"] - len(header.format(fake_group, id_max_length)), 2)
line = header + '{0.comment:%s}' % (comment_length // 2) # comment中可能有中文
header += "{0.comment:%s}" % comment_length
self.client.send(title(header.format(fake_group, "ID")))
id_length = max(len(str(len(self.asset_groups))), 5)
name_length = item_max_length(self.asset_groups, 15, key=lambda x: x.name)
amount_length = item_max_length(self.asset_groups, 10,
key=lambda x: x.assets_amount)
size_list = [id_length, name_length, amount_length]
fake_data = ['ID', _("Name"), _("Assets")]
header_without_comment = format_with_zh(size_list, *fake_data)
comment_length = max(
self.request.meta["width"] -
size_of_str_with_zh(header_without_comment) - 1,
2
)
size_list.append(comment_length)
fake_data.append(_("Comment"))
self.client.send(title(format_with_zh(size_list, *fake_data)))
for index, group in enumerate(self.asset_groups, 1):
self.client.send(wr(line.format(group, index)))
data = [index, group.name, group.assets_amount, group.comment]
self.client.send(wr(format_with_zh(size_list, *data)))
self.client.send(wr(_("总共: {}").format(len(self.asset_groups)), before=1))
def display_group_assets(self, _id):
......@@ -146,21 +155,30 @@ class InteractiveServer:
self.display_search_result()
def display_search_result(self):
self.search_result = sort_assets(self.search_result, current_app.config["ASSET_LIST_SORT_BY"])
fake_asset = Asset(hostname=_("Hostname"), ip=_("IP"), _system_users_name_list=_("LoginAs"),
comment=_("Comment"))
id_max_length = max(len(str(len(self.search_result))), 3)
hostname_max_length = max(max([len(asset.hostname) for asset in self.search_result + [fake_asset]]), 15)
sysuser_max_length = max([len(asset.system_users_name_list) for asset in self.search_result + [fake_asset]])
header = '{1:>%d} {0.hostname:%d} {0.ip:15} {0.system_users_name_list:%d} ' % \
(id_max_length, hostname_max_length, sysuser_max_length)
comment_length = self.request.meta["width"] - len(header.format(fake_asset, id_max_length))
comment_length = max([comment_length, 2])
line = header + '{0.comment:.%d}' % (comment_length // 2) # comment中可能有中文
header += '{0.comment:%s}' % comment_length
self.client.send(wr(title(header.format(fake_asset, "ID"))))
sort_by = current_app.config["ASSET_LIST_SORT_BY"]
self.search_result = sort_assets(self.search_result, sort_by)
fake_data = [_("ID"), _("Hostname"), _("IP"), _("LoginAs")]
id_length = max(len(str(len(self.search_result))), 4)
hostname_length = item_max_length(self.search_result, 15,
key=lambda x: x.hostname)
sysuser_length = item_max_length(self.search_result,
key=lambda x: x.system_users_name_list)
size_list = [id_length, hostname_length, 16, sysuser_length]
header_without_comment = format_with_zh(size_list, *fake_data)
comment_length = max(
self.request.meta["width"] -
size_of_str_with_zh(header_without_comment) - 1,
2
)
size_list.append(comment_length)
fake_data.append(_("Comment"))
self.client.send(wr(title(format_with_zh(size_list, *fake_data))))
for index, asset in enumerate(self.search_result, 1):
self.client.send(wr(line.format(asset, index)))
data = [
index, asset.hostname, asset.ip,
asset.system_users_name_list, asset.comment
]
self.client.send(wr(format_with_zh(size_list, *data)))
self.client.send(wr(_("总共: {} 匹配: {}").format(
len(self.assets), len(self.search_result)), before=1)
)
......@@ -242,7 +260,7 @@ class InteractiveServer:
self.display_banner()
while True:
try:
opt = net_input(self.client)
opt = net_input(self.client, prompt='Opt>', before=1)
rv = self.dispatch(opt)
if rv is self._sentinel:
break
......
......@@ -294,27 +294,14 @@ def get_logger(file_name):
return logging.getLogger('coco.'+file_name)
zh_pattern = re.compile(u'[\u4e00-\u9fa5]+')
def len_display(s):
length = 0
for i in s:
if zh_pattern.match(i):
length += 2
else:
length += 1
return length
def net_input(client, prompt='Opt> ', sensitive=False):
def net_input(client, prompt='Opt> ', sensitive=False, before=0, after=0):
"""实现了一个ssh input, 提示用户输入, 获取并返回
:return user input string
"""
input_data = []
parser = TtyIOParser()
client.send(wrap_with_line_feed(prompt, before=0, after=0))
client.send(wrap_with_line_feed(prompt, before=before, after=after))
while True:
data = client.recv(10)
......@@ -377,11 +364,59 @@ def register_service(service):
stack['service'] = service
def get_app():
if stack.get("app"):
return stack["app"]
else:
return ValueError("No app found")
zh_pattern = re.compile(r'[\u4e00-\u9fa5]')
def find_chinese(s):
return zh_pattern.findall(s)
def align_with_zh(s, length, addin=' '):
if not isinstance(s, str):
s = str(s)
zh_len = len(find_chinese(s))
padding = length - (len(s) - zh_len) - zh_len*2
padding_content = ''
if padding > 0:
padding_content = addin*padding
return s + padding_content
def format_with_zh(size_list, *args):
data = []
for length, s in zip(size_list, args):
data.append(align_with_zh(s, length))
return ' '.join(data)
def size_of_str_with_zh(s):
if isinstance(s, int):
s = str(s)
try:
chinese = find_chinese(s)
except TypeError:
print(type(s))
raise
return len(s) + len(chinese)
def item_max_length(_iter, maxi=None, mini=None, key=None):
if key:
_iter = [key(i) for i in _iter]
length = [size_of_str_with_zh(s) for s in _iter]
if maxi:
length.append(maxi)
length = max(length)
if mini and length < mini:
length = mini
return length
def int_length(i):
return len(str(i))
ugettext = _gettext()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment