diff --git a/spug_api/apps/file/utils.py b/spug_api/apps/file/utils.py index 7d648a1..6288cb1 100644 --- a/spug_api/apps/file/utils.py +++ b/spug_api/apps/file/utils.py @@ -4,6 +4,7 @@ from django.http import FileResponse import stat import time +import os KB = 1024 MB = 1024 * 1024 @@ -25,21 +26,21 @@ def parse_mode(obj): if obj.st_mode: mt = stat.S_IFMT(obj.st_mode) if mt == stat.S_IFIFO: - kind = "p" + kind = 'p' elif mt == stat.S_IFCHR: - kind = "c" + kind = 'c' elif mt == stat.S_IFDIR: - kind = "d" + kind = 'd' elif mt == stat.S_IFBLK: - kind = "b" + kind = 'b' elif mt == stat.S_IFREG: - kind = "-" + kind = '-' elif mt == stat.S_IFLNK: - kind = "l" + kind = 'l' elif mt == stat.S_IFSOCK: - kind = "s" + kind = 's' else: - kind = "?" + kind = '?' code = obj._rwx( (obj.st_mode & 448) >> 6, obj.st_mode & stat.S_ISUID ) @@ -49,10 +50,9 @@ def parse_mode(obj): code += obj._rwx( obj.st_mode & 7, obj.st_mode & stat.S_ISVTX, True ) + return kind + code else: - kind = "?" - code = '---------' - return kind, code + return '?---------' def format_size(size): @@ -70,18 +70,32 @@ def format_size(size): return '' -def parse_sftp_attr(obj): - if (obj.st_mtime is None) or (obj.st_mtime == int(0xffffffff)): - date = "(unknown date)" - else: - date = time.strftime('%Y/%m/%d %H:%M:%S', time.localtime(obj.st_mtime)) - kind, code = parse_mode(obj) - is_dir = stat.S_ISDIR(obj.st_mode) if obj.st_mode else False - size = obj.st_size or '' - return { - 'name': getattr(obj, 'filename', '?'), - 'size': '' if is_dir else format_size(size), - 'date': date, - 'kind': kind, - 'code': code - } +def fetch_dir_list(host, path): + with host.get_ssh() as ssh: + objects = [] + for item in ssh.list_dir_attr(path): + code = parse_mode(item) + kind, is_link, name = '?', False, getattr(item, 'filename', '?') + if stat.S_ISLNK(item.st_mode): + is_link = True + try: + item = ssh.sftp_stat(os.path.join(path, name)) + except FileNotFoundError: + pass + if stat.S_ISREG(item.st_mode): + kind = '-' + elif stat.S_ISDIR(item.st_mode): + kind = 'd' + if (item.st_mtime is None) or (item.st_mtime == int(0xffffffff)): + date = '(unknown date)' + else: + date = time.strftime('%Y/%m/%d %H:%M:%S', time.localtime(item.st_mtime)) + objects.append({ + 'name': name, + 'size': '' if kind == 'd' else format_size(item.st_size or ''), + 'date': date, + 'kind': kind, + 'code': code, + 'is_link': is_link + }) + return objects diff --git a/spug_api/apps/file/views.py b/spug_api/apps/file/views.py index aa405f6..990aa4d 100644 --- a/spug_api/apps/file/views.py +++ b/spug_api/apps/file/views.py @@ -5,7 +5,7 @@ from django.views.generic import View from django_redis import get_redis_connection from apps.host.models import Host from apps.account.utils import has_host_perm -from apps.file.utils import FileResponseAfter, FileResponse, parse_sftp_attr +from apps.file.utils import FileResponseAfter, fetch_dir_list from libs import json_response, JsonParser, Argument from functools import partial import os @@ -23,9 +23,8 @@ class FileView(View): host = Host.objects.get(pk=form.id) if not host: return json_response(error='未找到指定主机') - with host.get_ssh() as ssh: - objects = ssh.list_dir_attr(form.path) - return json_response([parse_sftp_attr(x) for x in objects]) + objects = fetch_dir_list(host, form.path) + return json_response(objects) return json_response(error=error) diff --git a/spug_web/src/pages/ssh/FileManager.js b/spug_web/src/pages/ssh/FileManager.js index d5c31c4..169aeab 100644 --- a/spug_web/src/pages/ssh/FileManager.js +++ b/spug_web/src/pages/ssh/FileManager.js @@ -39,8 +39,8 @@ class FileManager extends React.Component { key: 'name', render: info => info.kind === 'd' ? (
this.handleChdir(info.name, '1')} style={{cursor: 'pointer'}}> - - {info.name} + + {info.name}
) : ( @@ -61,8 +61,7 @@ class FileManager extends React.Component { width: 190 }, { title: '属性', - key: 'attr', - render: info => `${info.kind}${info.code}`, + dataIndex: 'code', width: 110 }, { title: '操作',