mirror of https://github.com/openspug/spug
U 文件管理器链接文件可点击
parent
02828e6c6c
commit
0395eb5ab5
|
@ -4,6 +4,7 @@
|
||||||
from django.http import FileResponse
|
from django.http import FileResponse
|
||||||
import stat
|
import stat
|
||||||
import time
|
import time
|
||||||
|
import os
|
||||||
|
|
||||||
KB = 1024
|
KB = 1024
|
||||||
MB = 1024 * 1024
|
MB = 1024 * 1024
|
||||||
|
@ -25,21 +26,21 @@ def parse_mode(obj):
|
||||||
if obj.st_mode:
|
if obj.st_mode:
|
||||||
mt = stat.S_IFMT(obj.st_mode)
|
mt = stat.S_IFMT(obj.st_mode)
|
||||||
if mt == stat.S_IFIFO:
|
if mt == stat.S_IFIFO:
|
||||||
kind = "p"
|
kind = 'p'
|
||||||
elif mt == stat.S_IFCHR:
|
elif mt == stat.S_IFCHR:
|
||||||
kind = "c"
|
kind = 'c'
|
||||||
elif mt == stat.S_IFDIR:
|
elif mt == stat.S_IFDIR:
|
||||||
kind = "d"
|
kind = 'd'
|
||||||
elif mt == stat.S_IFBLK:
|
elif mt == stat.S_IFBLK:
|
||||||
kind = "b"
|
kind = 'b'
|
||||||
elif mt == stat.S_IFREG:
|
elif mt == stat.S_IFREG:
|
||||||
kind = "-"
|
kind = '-'
|
||||||
elif mt == stat.S_IFLNK:
|
elif mt == stat.S_IFLNK:
|
||||||
kind = "l"
|
kind = 'l'
|
||||||
elif mt == stat.S_IFSOCK:
|
elif mt == stat.S_IFSOCK:
|
||||||
kind = "s"
|
kind = 's'
|
||||||
else:
|
else:
|
||||||
kind = "?"
|
kind = '?'
|
||||||
code = obj._rwx(
|
code = obj._rwx(
|
||||||
(obj.st_mode & 448) >> 6, obj.st_mode & stat.S_ISUID
|
(obj.st_mode & 448) >> 6, obj.st_mode & stat.S_ISUID
|
||||||
)
|
)
|
||||||
|
@ -49,10 +50,9 @@ def parse_mode(obj):
|
||||||
code += obj._rwx(
|
code += obj._rwx(
|
||||||
obj.st_mode & 7, obj.st_mode & stat.S_ISVTX, True
|
obj.st_mode & 7, obj.st_mode & stat.S_ISVTX, True
|
||||||
)
|
)
|
||||||
|
return kind + code
|
||||||
else:
|
else:
|
||||||
kind = "?"
|
return '?---------'
|
||||||
code = '---------'
|
|
||||||
return kind, code
|
|
||||||
|
|
||||||
|
|
||||||
def format_size(size):
|
def format_size(size):
|
||||||
|
@ -70,18 +70,32 @@ def format_size(size):
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|
||||||
def parse_sftp_attr(obj):
|
def fetch_dir_list(host, path):
|
||||||
if (obj.st_mtime is None) or (obj.st_mtime == int(0xffffffff)):
|
with host.get_ssh() as ssh:
|
||||||
date = "(unknown date)"
|
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:
|
else:
|
||||||
date = time.strftime('%Y/%m/%d %H:%M:%S', time.localtime(obj.st_mtime))
|
date = time.strftime('%Y/%m/%d %H:%M:%S', time.localtime(item.st_mtime))
|
||||||
kind, code = parse_mode(obj)
|
objects.append({
|
||||||
is_dir = stat.S_ISDIR(obj.st_mode) if obj.st_mode else False
|
'name': name,
|
||||||
size = obj.st_size or ''
|
'size': '' if kind == 'd' else format_size(item.st_size or ''),
|
||||||
return {
|
|
||||||
'name': getattr(obj, 'filename', '?'),
|
|
||||||
'size': '' if is_dir else format_size(size),
|
|
||||||
'date': date,
|
'date': date,
|
||||||
'kind': kind,
|
'kind': kind,
|
||||||
'code': code
|
'code': code,
|
||||||
}
|
'is_link': is_link
|
||||||
|
})
|
||||||
|
return objects
|
||||||
|
|
|
@ -5,7 +5,7 @@ from django.views.generic import View
|
||||||
from django_redis import get_redis_connection
|
from django_redis import get_redis_connection
|
||||||
from apps.host.models import Host
|
from apps.host.models import Host
|
||||||
from apps.account.utils import has_host_perm
|
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 libs import json_response, JsonParser, Argument
|
||||||
from functools import partial
|
from functools import partial
|
||||||
import os
|
import os
|
||||||
|
@ -23,9 +23,8 @@ class FileView(View):
|
||||||
host = Host.objects.get(pk=form.id)
|
host = Host.objects.get(pk=form.id)
|
||||||
if not host:
|
if not host:
|
||||||
return json_response(error='未找到指定主机')
|
return json_response(error='未找到指定主机')
|
||||||
with host.get_ssh() as ssh:
|
objects = fetch_dir_list(host, form.path)
|
||||||
objects = ssh.list_dir_attr(form.path)
|
return json_response(objects)
|
||||||
return json_response([parse_sftp_attr(x) for x in objects])
|
|
||||||
return json_response(error=error)
|
return json_response(error=error)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -39,8 +39,8 @@ class FileManager extends React.Component {
|
||||||
key: 'name',
|
key: 'name',
|
||||||
render: info => info.kind === 'd' ? (
|
render: info => info.kind === 'd' ? (
|
||||||
<div onClick={() => this.handleChdir(info.name, '1')} style={{cursor: 'pointer'}}>
|
<div onClick={() => this.handleChdir(info.name, '1')} style={{cursor: 'pointer'}}>
|
||||||
<FolderOutlined style={{color: '#1890ff'}}/>
|
<FolderOutlined style={{color: info.is_link ? '#008b8b' : '#1890ff'}}/>
|
||||||
<span style={{color: '#1890ff', paddingLeft: 5}}>{info.name}</span>
|
<span style={{color: info.is_link ? '#008b8b' : '#1890ff', paddingLeft: 5}}>{info.name}</span>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
|
@ -61,8 +61,7 @@ class FileManager extends React.Component {
|
||||||
width: 190
|
width: 190
|
||||||
}, {
|
}, {
|
||||||
title: '属性',
|
title: '属性',
|
||||||
key: 'attr',
|
dataIndex: 'code',
|
||||||
render: info => `${info.kind}${info.code}`,
|
|
||||||
width: 110
|
width: 110
|
||||||
}, {
|
}, {
|
||||||
title: '操作',
|
title: '操作',
|
||||||
|
|
Loading…
Reference in New Issue