|
|
|
# coding:utf-8
|
|
|
|
|
|
|
|
# ---------------------------------------------------------------------------------
|
|
|
|
# MW-Linux面板
|
|
|
|
# ---------------------------------------------------------------------------------
|
|
|
|
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
|
|
|
|
# ---------------------------------------------------------------------------------
|
|
|
|
# Author: midoks <midoks@163.com>
|
|
|
|
# ---------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
import os
|
|
|
|
import pwd
|
|
|
|
import time
|
|
|
|
import shutil
|
|
|
|
import json
|
|
|
|
import base64
|
|
|
|
|
|
|
|
import core.mw as mw
|
|
|
|
import thisdb
|
|
|
|
|
|
|
|
def uploadSegment(path,name,size,start,dir_mode,file_mode,b64_data,upload_files):
|
|
|
|
if not mw.fileNameCheck(name):
|
|
|
|
return mw.returnData(False, '文件名中不能包含特殊字符!')
|
|
|
|
|
|
|
|
if path == '/':
|
|
|
|
return mw.returnData(False, '不能直接上传文件到系统根目录!')
|
|
|
|
|
|
|
|
if name.find('./') != -1 or path.find('./') != -1:
|
|
|
|
return mw.returnData(False, '错误的参数')
|
|
|
|
|
|
|
|
if not os.path.exists(path):
|
|
|
|
os.makedirs(path, 493)
|
|
|
|
if not dir_mode != '' or not file_mode != '':
|
|
|
|
mw.setMode(path)
|
|
|
|
|
|
|
|
save_path = os.path.join(path, name + '.' + str(int(size)) + '.upload.tmp')
|
|
|
|
d_size = 0
|
|
|
|
if os.path.exists(save_path):
|
|
|
|
d_size = os.path.getsize(save_path)
|
|
|
|
|
|
|
|
if d_size != int(start):
|
|
|
|
return mw.returnData(True, 'size', d_size)
|
|
|
|
|
|
|
|
f = open(save_path, 'ab')
|
|
|
|
if b64_data == '1':
|
|
|
|
b64_data = base64.b64decode(b64_data)
|
|
|
|
f.write(b64_data)
|
|
|
|
else:
|
|
|
|
for tmp_f in upload_files:
|
|
|
|
f.write(tmp_f.read())
|
|
|
|
|
|
|
|
f.close()
|
|
|
|
f_size = os.path.getsize(save_path)
|
|
|
|
if f_size != int(size):
|
|
|
|
return mw.returnData(True, 'size', f_size)
|
|
|
|
|
|
|
|
new_name = os.path.join(path, name)
|
|
|
|
if os.path.exists(new_name):
|
|
|
|
if new_name.find('.user.ini') != -1:
|
|
|
|
mw.execShell("chattr -i " + new_name)
|
|
|
|
try:
|
|
|
|
os.remove(new_name)
|
|
|
|
except:
|
|
|
|
mw.execShell("rm -f %s" % new_name)
|
|
|
|
|
|
|
|
os.renames(save_path, new_name)
|
|
|
|
|
|
|
|
if dir_mode != '' and dir_mode != '':
|
|
|
|
mode_tmp1 = dir_mode.split(',')
|
|
|
|
mw.setMode(path, mode_tmp1[0])
|
|
|
|
mw.setOwn(path, mode_tmp1[1])
|
|
|
|
mode_tmp2 = file_mode.split(',')
|
|
|
|
mw.setMode(new_name, mode_tmp2[0])
|
|
|
|
mw.setOwn(new_name, mode_tmp2[1])
|
|
|
|
else:
|
|
|
|
setMode(new_name)
|
|
|
|
|
|
|
|
msg = mw.getInfo('上传文件[{1}] 到 [{2}]成功!', (new_name, path))
|
|
|
|
mw.writeLog('文件管理', msg)
|
|
|
|
return mw.returnData(True, '上传成功!', f_size)
|
|
|
|
|
|
|
|
|
|
|
|
def mvFile(sfile, dfile):
|
|
|
|
if not checkFileName(dfile):
|
|
|
|
return mw.returnData(False, '文件名中不能包含特殊字符!')
|
|
|
|
if not os.path.exists(sfile):
|
|
|
|
return mw.returnData(False, '指定文件不存在!')
|
|
|
|
|
|
|
|
if not checkDir(sfile):
|
|
|
|
return mw.returnData(False, 'FILE_DANGER')
|
|
|
|
|
|
|
|
try:
|
|
|
|
shutil.move(sfile, dfile)
|
|
|
|
msg = mw.getInfo('移动或重名命文件[{1}]到[{2}]成功!', (sfile, dfile,))
|
|
|
|
mw.writeLog('文件管理', msg)
|
|
|
|
return mw.returnData(True, '移动或重名命文件成功!')
|
|
|
|
except:
|
|
|
|
return mw.returnData(False, '移动或重名命文件失败!')
|
|
|
|
|
|
|
|
def uncompress(sfile, dfile, path):
|
|
|
|
if not os.path.exists(sfile):
|
|
|
|
return mw.returnData(False, '指定文件不存在!')
|
|
|
|
|
|
|
|
filename = os.path.basename(sfile)
|
|
|
|
extension = os.path.splitext(filename)[-1]
|
|
|
|
extension = extension.strip('.')
|
|
|
|
|
|
|
|
tar_gz = 'tar.gz'
|
|
|
|
tar_gz_len = len(tar_gz)
|
|
|
|
suffix_gz = sfile[-tar_gz_len:]
|
|
|
|
if suffix_gz == tar_gz:
|
|
|
|
extension = suffix_gz
|
|
|
|
|
|
|
|
if not extension in ['tar.gz', 'gz', 'zip', 'rar']:
|
|
|
|
return mw.returnData(False, '现在仅支持gz,zip,rar格式解压!')
|
|
|
|
|
|
|
|
if mw.isAppleSystem() and extension == 'rar':
|
|
|
|
return mw.returnData(False, 'macosx暂时不支持rar格式解压')
|
|
|
|
|
|
|
|
cmd = "cd " + path + " "
|
|
|
|
try:
|
|
|
|
tmps = mw.getPanelDir() + '/logs/panel_exec.log'
|
|
|
|
if extension == 'zip':
|
|
|
|
cmd += "&& unzip -o -d '" + dfile + "' '" + sfile + "' > " + tmps + " 2>&1 &"
|
|
|
|
mw.execShell(cmd)
|
|
|
|
if extension == 'tar.gz':
|
|
|
|
cmd += "&& tar -zxvf " + sfile + " -C " + dfile + " > " + tmps + " 2>&1 &"
|
|
|
|
mw.execShell(cmd)
|
|
|
|
if extension == 'gz':
|
|
|
|
cmd += "&& gunzip -k " + sfile + " > " + tmps + " 2>&1 &"
|
|
|
|
mw.execShell(cmd)
|
|
|
|
if extension == 'rar':
|
|
|
|
cmd += "&& unrar x " + sfile + " " + dfile + " > " + tmps + " 2>&1 &"
|
|
|
|
mw.execShell(cmd)
|
|
|
|
|
|
|
|
if os.path.exists(dfile):
|
|
|
|
setFileAccept(dfile)
|
|
|
|
mw.writeLog("文件管理", '文件[{1}]解压[{2}]成功!', (sfile, dfile,))
|
|
|
|
return mw.returnData(True, '文件解压成功!')
|
|
|
|
except Exception as e:
|
|
|
|
return mw.returnData(False, '文件解压失败!:' + str(e))
|
|
|
|
|
|
|
|
def setBatchData(path, stype, access, user, data):
|
|
|
|
from admin import session
|
|
|
|
if stype == '1' or stype == '2':
|
|
|
|
session['selected'] = {
|
|
|
|
'path': path,
|
|
|
|
'type': stype,
|
|
|
|
'access': access,
|
|
|
|
'user': user,
|
|
|
|
'data': data
|
|
|
|
}
|
|
|
|
return mw.returnData(True, '标记成功,请在目标目录点击粘贴所有按钮!')
|
|
|
|
elif stype == '3':
|
|
|
|
for key in json.loads(data):
|
|
|
|
try:
|
|
|
|
filename = path + '/' + key
|
|
|
|
if not checkDir(filename):
|
|
|
|
return mw.returnData(False, 'FILE_DANGER')
|
|
|
|
os.system('chmod -R ' + access + " '" + filename + "'")
|
|
|
|
os.system('chown -R ' + user + ':' + user + " '" + filename + "'")
|
|
|
|
except:
|
|
|
|
continue
|
|
|
|
mw.writeLog('文件管理', '批量设置权限成功!')
|
|
|
|
return mw.returnData(True, '批量设置权限成功!')
|
|
|
|
else:
|
|
|
|
recycle_bin = thisdb.getOption('recycle_bin')
|
|
|
|
is_recycle = False
|
|
|
|
if recycle_bin == 'open':
|
|
|
|
is_recycle = True
|
|
|
|
data = json.loads(data)
|
|
|
|
l = len(data)
|
|
|
|
i = 0
|
|
|
|
for key in data:
|
|
|
|
try:
|
|
|
|
filename = path + '/' + key
|
|
|
|
topath = filename
|
|
|
|
if not os.path.exists(filename):
|
|
|
|
continue
|
|
|
|
|
|
|
|
i += 1
|
|
|
|
mw.writeSpeed(key, i, l)
|
|
|
|
if os.path.isdir(filename):
|
|
|
|
if not checkDir(filename):
|
|
|
|
return mw.returnData(False, '请不要花样作死!')
|
|
|
|
if is_recycle:
|
|
|
|
mvRecycleBin(topath)
|
|
|
|
else:
|
|
|
|
shutil.rmtree(filename)
|
|
|
|
else:
|
|
|
|
if key == '.user.ini':
|
|
|
|
os.system('which chattr && chattr -i ' + filename)
|
|
|
|
if is_recycle:
|
|
|
|
mvRecycleBin(topath)
|
|
|
|
else:
|
|
|
|
os.remove(filename)
|
|
|
|
except:
|
|
|
|
continue
|
|
|
|
mw.writeSpeed(None, 0, 0)
|
|
|
|
mw.writeLog('文件管理', '批量删除成功!')
|
|
|
|
return mw.returnData(True, '批量删除成功!')
|
|
|
|
|
|
|
|
|
|
|
|
def copyDir(src_file, dst_file):
|
|
|
|
if not os.path.exists(src_file):
|
|
|
|
return mw.returnData(False, '指定目录不存在!')
|
|
|
|
|
|
|
|
if os.path.exists(dst_file):
|
|
|
|
return mw.returnData(False, '指定目录已存在!')
|
|
|
|
|
|
|
|
try:
|
|
|
|
shutil.copytree(src_file, dst_file)
|
|
|
|
stat = os.stat(src_file)
|
|
|
|
os.chown(dst_file, stat.st_uid, stat.st_gid)
|
|
|
|
msg = mw.getInfo('复制目录[{1}]到[{2}]成功!', (src_file, dst_file))
|
|
|
|
mw.writeLog('文件管理', msg)
|
|
|
|
return mw.returnData(True, '目录复制成功!')
|
|
|
|
except:
|
|
|
|
return mw.returnData(False, '目录复制失败!')
|
|
|
|
|
|
|
|
def copyFile(src_file, dst_file):
|
|
|
|
if src_file == dst_file:
|
|
|
|
return mw.returnJson(False, '源与目的一致!')
|
|
|
|
|
|
|
|
if not os.path.exists(src_file):
|
|
|
|
return mw.returnJson(False, '指定文件不存在!')
|
|
|
|
|
|
|
|
if os.path.isdir(src_file):
|
|
|
|
return copyDir(src_file, dst_file)
|
|
|
|
|
|
|
|
try:
|
|
|
|
shutil.copyfile(src_file, dst_file)
|
|
|
|
msg = mw.getInfo('复制文件[{1}]到[{2}]成功!', (src_file, dst_file,))
|
|
|
|
mw.writeLog('文件管理', msg)
|
|
|
|
stat = os.stat(src_file)
|
|
|
|
os.chown(dst_file, stat.st_uid, stat.st_gid)
|
|
|
|
return mw.returnData(True, '文件复制成功!')
|
|
|
|
except:
|
|
|
|
return mw.returnData(False, '文件复制失败!')
|
|
|
|
|
|
|
|
def setFileAccept(filename):
|
|
|
|
auth = 'www:www'
|
|
|
|
if mw.getOs() == 'darwin':
|
|
|
|
user = mw.execShell("who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
|
|
|
|
auth = user + ':staff'
|
|
|
|
os.system('chown -R ' + auth + ' ' + filename)
|
|
|
|
os.system('chmod -R 755 ' + filename)
|
|
|
|
|
|
|
|
def createFile(file_path):
|
|
|
|
try:
|
|
|
|
if not checkFileName(file_path):
|
|
|
|
return mw.returnData(False, '文件名中不能包含特殊字符!')
|
|
|
|
if os.path.exists(file_path):
|
|
|
|
return mw.returnData(False, '指定文件已存在!')
|
|
|
|
_path = os.path.dirname(file_path)
|
|
|
|
if not os.path.exists(_path):
|
|
|
|
os.makedirs(_path)
|
|
|
|
open(file_path, 'w+').close()
|
|
|
|
setFileAccept(file)
|
|
|
|
msg = mw.getInfo('创建文件[{1}]成功!', (file_path,))
|
|
|
|
mw.writeLog('文件管理', msg)
|
|
|
|
return mw.returnData(True, '文件创建成功!')
|
|
|
|
except Exception as e:
|
|
|
|
return mw.returnData(True, '文件创建失败:'+str(e))
|
|
|
|
|
|
|
|
def createDir(path):
|
|
|
|
try:
|
|
|
|
if not checkFileName(path):
|
|
|
|
return mw.returnData(False, '目录名中不能包含特殊字符!')
|
|
|
|
if os.path.exists(path):
|
|
|
|
return mw.returnData(False, '指定目录已存在!')
|
|
|
|
os.makedirs(path)
|
|
|
|
setFileAccept(path)
|
|
|
|
msg = mw.getInfo('创建目录[{1}]成功!', (path,))
|
|
|
|
mw.writeLog('文件管理', msg)
|
|
|
|
return mw.returnData(True, '目录创建成功!')
|
|
|
|
except Exception as e:
|
|
|
|
print(e)
|
|
|
|
return mw.returnData(False, '目录创建失败!')
|
|
|
|
|
|
|
|
# 检查敏感目录
|
|
|
|
def checkDir(path):
|
|
|
|
path = path.replace('//', '/')
|
|
|
|
if path[-1:] == '/':
|
|
|
|
path = path[:-1]
|
|
|
|
|
|
|
|
sense_dir = ('',
|
|
|
|
'/',
|
|
|
|
'/*',
|
|
|
|
'/www',
|
|
|
|
'/root',
|
|
|
|
'/boot',
|
|
|
|
'/bin',
|
|
|
|
'/etc',
|
|
|
|
'/home',
|
|
|
|
'/dev',
|
|
|
|
'/sbin',
|
|
|
|
'/var',
|
|
|
|
'/usr',
|
|
|
|
'/tmp',
|
|
|
|
'/sys',
|
|
|
|
'/proc',
|
|
|
|
'/media',
|
|
|
|
'/mnt',
|
|
|
|
'/opt',
|
|
|
|
'/lib',
|
|
|
|
'/srv',
|
|
|
|
'/selinux',
|
|
|
|
'/www/server',
|
|
|
|
mw.getRootDir())
|
|
|
|
return not path in sense_dir
|
|
|
|
|
|
|
|
def getFileBody(path):
|
|
|
|
if not os.path.exists(path):
|
|
|
|
return mw.returnData(False, '文件不存在', (path,))
|
|
|
|
|
|
|
|
if os.path.getsize(path) > 2097152:
|
|
|
|
return mw.returnData(False, '不能在线编辑大于2MB的文件!')
|
|
|
|
|
|
|
|
if os.path.isdir(path):
|
|
|
|
return mw.returnData(False, '这不是一个文件!')
|
|
|
|
|
|
|
|
fp = open(path, 'rb')
|
|
|
|
data = {}
|
|
|
|
data['status'] = True
|
|
|
|
if fp:
|
|
|
|
srcBody = fp.read()
|
|
|
|
fp.close()
|
|
|
|
|
|
|
|
encoding_list = ['utf-8', 'GBK', 'BIG5']
|
|
|
|
for el in encoding_list:
|
|
|
|
try:
|
|
|
|
data['encoding'] = el
|
|
|
|
data['data'] = srcBody.decode(data['encoding'])
|
|
|
|
break
|
|
|
|
except Exception as ex:
|
|
|
|
if el == 'BIG5':
|
|
|
|
return mw.returnData(False, '文件编码不被兼容,无法正确读取文件!' + str(ex))
|
|
|
|
else:
|
|
|
|
return mw.returnData(False, '文件未正常打开!')
|
|
|
|
return mw.returnData(True, 'OK', data)
|
|
|
|
|
|
|
|
def saveBody(path, data, encoding):
|
|
|
|
if not os.path.exists(path):
|
|
|
|
return mw.returnData(False, '文件不存在')
|
|
|
|
try:
|
|
|
|
if encoding == 'ascii':
|
|
|
|
encoding = 'utf-8'
|
|
|
|
|
|
|
|
data = data.encode(encoding, errors='ignore').decode(encoding)
|
|
|
|
fp = open(path, 'w+', encoding=encoding)
|
|
|
|
fp.write(data)
|
|
|
|
fp.close()
|
|
|
|
|
|
|
|
if path.find("web_conf") > 0:
|
|
|
|
mw.restartWeb()
|
|
|
|
mw.writeLog('文件管理', '文件[{1}]保存成功', (path,))
|
|
|
|
return mw.returnData(True, '文件保存成功')
|
|
|
|
except Exception as ex:
|
|
|
|
return mw.returnData(False, '文件保存错误:' + str(ex))
|
|
|
|
|
|
|
|
|
|
|
|
def sortFileList(path, ftype = 'mtime', sort = 'desc'):
|
|
|
|
flist = os.listdir(path)
|
|
|
|
if ftype == 'mtime':
|
|
|
|
if sort == 'desc':
|
|
|
|
flist = sorted(flist, key=lambda f: os.path.getmtime(os.path.join(path,f)), reverse=True)
|
|
|
|
if sort == 'asc':
|
|
|
|
flist = sorted(flist, key=lambda f: os.path.getmtime(os.path.join(path,f)), reverse=False)
|
|
|
|
|
|
|
|
if ftype == 'size':
|
|
|
|
if sort == 'desc':
|
|
|
|
flist = sorted(flist, key=lambda f: os.path.getsize(os.path.join(path,f)), reverse=True)
|
|
|
|
if sort == 'asc':
|
|
|
|
flist = sorted(flist, key=lambda f: os.path.getsize(os.path.join(path,f)), reverse=False)
|
|
|
|
|
|
|
|
if ftype == 'fname':
|
|
|
|
if sort == 'desc':
|
|
|
|
flist = sorted(flist, key=lambda f: os.path.join(path,f), reverse=True)
|
|
|
|
if sort == 'asc':
|
|
|
|
flist = sorted(flist, key=lambda f: os.path.join(path,f), reverse=False)
|
|
|
|
return flist
|
|
|
|
|
|
|
|
def sortAllFileList(path, ftype = 'mtime', sort = 'desc', search = '',limit = 3000):
|
|
|
|
count = 0
|
|
|
|
flist = []
|
|
|
|
for d_list in os.walk(path):
|
|
|
|
if count >= limit:
|
|
|
|
break
|
|
|
|
|
|
|
|
for d in d_list[1]:
|
|
|
|
if count >= limit:
|
|
|
|
break
|
|
|
|
if d.lower().find(search) != -1:
|
|
|
|
filename = d_list[0] + '/' + d
|
|
|
|
if not os.path.exists(filename):
|
|
|
|
continue
|
|
|
|
count += 1
|
|
|
|
flist.append(filename)
|
|
|
|
|
|
|
|
for f in d_list[2]:
|
|
|
|
if count >= limit:
|
|
|
|
break
|
|
|
|
|
|
|
|
if f.lower().find(search) != -1:
|
|
|
|
filename = d_list[0] + '/' + f
|
|
|
|
if not os.path.exists(filename):
|
|
|
|
continue
|
|
|
|
count += 1
|
|
|
|
flist.append(filename)
|
|
|
|
|
|
|
|
if ftype == 'mtime':
|
|
|
|
if sort == 'desc':
|
|
|
|
flist = sorted(flist, key=lambda f: os.path.getmtime(f), reverse=True)
|
|
|
|
if sort == 'asc':
|
|
|
|
flist = sorted(flist, key=lambda f: os.path.getmtime(f), reverse=False)
|
|
|
|
|
|
|
|
if ftype == 'size':
|
|
|
|
if sort == 'desc':
|
|
|
|
flist = sorted(flist, key=lambda f: os.path.getsize(f), reverse=True)
|
|
|
|
if sort == 'asc':
|
|
|
|
flist = sorted(flist, key=lambda f: os.path.getsize(f), reverse=False)
|
|
|
|
return flist
|
|
|
|
|
|
|
|
def getAllDirList(path, page=1, size=10, order = '', search=None):
|
|
|
|
if page < 1:
|
|
|
|
page == 1
|
|
|
|
|
|
|
|
data = {}
|
|
|
|
dirnames = []
|
|
|
|
filenames = []
|
|
|
|
|
|
|
|
max_limit = 3000
|
|
|
|
order_split = order.split(' ')
|
|
|
|
if len(order_split) < 2:
|
|
|
|
flist = sortAllFileList(path, order_split[0],'',search, max_limit)
|
|
|
|
else:
|
|
|
|
flist = sortAllFileList(path, order_split[0], order_split[1], search, max_limit)
|
|
|
|
|
|
|
|
count = len(flist)
|
|
|
|
start = (page - 1) * size
|
|
|
|
end = start + size
|
|
|
|
if end > count:
|
|
|
|
end = count
|
|
|
|
|
|
|
|
plist = flist[start:end]
|
|
|
|
for dst_file in plist:
|
|
|
|
if not os.path.exists(dst_file):
|
|
|
|
continue
|
|
|
|
stat = mw.getFileStatsDesc(dst_file, path)
|
|
|
|
if os.path.isdir(dst_file):
|
|
|
|
dirnames.append(stat)
|
|
|
|
else:
|
|
|
|
filenames.append(stat)
|
|
|
|
|
|
|
|
data['count'] = count
|
|
|
|
data['dir'] = dirnames
|
|
|
|
data['files'] = filenames
|
|
|
|
data['path'] = path.replace('//', '/')
|
|
|
|
return data
|
|
|
|
|
|
|
|
def getDirList(path, page=1, size=10, order = '', search=None):
|
|
|
|
if page < 1:
|
|
|
|
page == 1
|
|
|
|
|
|
|
|
data = {}
|
|
|
|
dirnames = []
|
|
|
|
filenames = []
|
|
|
|
|
|
|
|
count = getCount(path, search)
|
|
|
|
order_split = order.strip().split(' ')
|
|
|
|
if len(order_split) < 2:
|
|
|
|
flist = sortFileList(path, order_split[0], '')
|
|
|
|
else:
|
|
|
|
flist = sortFileList(path, order_split[0], order_split[1])
|
|
|
|
|
|
|
|
start = (page - 1) * size
|
|
|
|
end = start + size
|
|
|
|
if end > count:
|
|
|
|
end = count
|
|
|
|
|
|
|
|
|
|
|
|
if search or search != '':
|
|
|
|
nlist = []
|
|
|
|
for f in flist:
|
|
|
|
if f.lower().find(search) == -1:
|
|
|
|
continue
|
|
|
|
nlist.append(f)
|
|
|
|
plist = nlist[start:end]
|
|
|
|
else:
|
|
|
|
plist = flist[start:end]
|
|
|
|
|
|
|
|
for filename in plist:
|
|
|
|
abs_file = path + '/' + filename
|
|
|
|
if not os.path.exists(abs_file):
|
|
|
|
continue
|
|
|
|
|
|
|
|
stats = mw.getFileStatsDesc(abs_file, path)
|
|
|
|
if os.path.isdir(abs_file):
|
|
|
|
dirnames.append(stats)
|
|
|
|
else:
|
|
|
|
filenames.append(stats)
|
|
|
|
|
|
|
|
data['count'] = count
|
|
|
|
data['dir'] = dirnames
|
|
|
|
data['files'] = filenames
|
|
|
|
data['path'] = path.replace('//', '/')
|
|
|
|
return data
|
|
|
|
|
|
|
|
# 检测文件名
|
|
|
|
def checkFileName(filename):
|
|
|
|
nots = ['\\', '&', '*', '|', ';']
|
|
|
|
if filename.find('/') != -1:
|
|
|
|
filename = filename.split('/')[-1]
|
|
|
|
for n in nots:
|
|
|
|
if n in filename:
|
|
|
|
return False
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
# 获取目录大小
|
|
|
|
def getDirSize(filePath, size=0):
|
|
|
|
for root, dirs, files in os.walk(filePath):
|
|
|
|
for f in files:
|
|
|
|
size += os.path.getsize(os.path.join(root, f))
|
|
|
|
# print(f)
|
|
|
|
return size
|
|
|
|
|
|
|
|
# 获取目录大小(bash)
|
|
|
|
def getDirSizeByBash(path):
|
|
|
|
tmp = mw.execShell('du -sh ' + path)
|
|
|
|
return tmp[0].split()[0].lower()
|
|
|
|
|
|
|
|
# 计算文件数量
|
|
|
|
def getCount(path, search = None):
|
|
|
|
i = 0
|
|
|
|
for name in os.listdir(path):
|
|
|
|
if name == '.' or name == '..':
|
|
|
|
continue
|
|
|
|
if search:
|
|
|
|
if name.lower().find(search) == -1:
|
|
|
|
continue
|
|
|
|
i += 1
|
|
|
|
return i
|
|
|
|
|
|
|
|
# 获取文件权限
|
|
|
|
def getAccess(fname):
|
|
|
|
data = {}
|
|
|
|
try:
|
|
|
|
stat = os.stat(fname)
|
|
|
|
data['chmod'] = str(oct(stat.st_mode)[-3:])
|
|
|
|
data['chown'] = pwd.getpwuid(stat.st_uid).pw_name
|
|
|
|
except Exception as e:
|
|
|
|
# print(e)
|
|
|
|
data['chmod'] = 755
|
|
|
|
data['chown'] = 'www'
|
|
|
|
return data
|
|
|
|
|
|
|
|
def fileDelete(path):
|
|
|
|
if not os.path.exists(path):
|
|
|
|
return mw.returnData(False, '指定文件不存在!')
|
|
|
|
|
|
|
|
# 检查是否为.user.ini
|
|
|
|
if path.find('.user.ini') >= 0:
|
|
|
|
cmd = "which chattr && chattr -i {0}".format(path)
|
|
|
|
mw.execShell(cmd)
|
|
|
|
|
|
|
|
try:
|
|
|
|
recycle_bin = thisdb.getOption('recycle_bin')
|
|
|
|
if recycle_bin == 'open':
|
|
|
|
if mvRecycleBin(path):
|
|
|
|
return mw.returnData(True, '已将文件移动到回收站!')
|
|
|
|
return mw.returnData(False, '移动到回收站失败!')
|
|
|
|
os.remove(path)
|
|
|
|
mw.writeLog('文件管理', mw.getInfo('删除文件[{1}]成功!', (path,)))
|
|
|
|
return mw.returnData(True, '删除文件成功!')
|
|
|
|
except Exception as e:
|
|
|
|
return mw.returnData(False, '删除文件失败!')
|
|
|
|
|
|
|
|
def dirDelete(path):
|
|
|
|
if not os.path.exists(path):
|
|
|
|
return mw.returnData(False, '指定文件不存在!')
|
|
|
|
|
|
|
|
# 检查是否为.user.ini
|
|
|
|
if path.find('.user.ini'):
|
|
|
|
os.system("which chattr && chattr -i '" + path + "'")
|
|
|
|
try:
|
|
|
|
recycle_bin = thisdb.getOption('recycle_bin')
|
|
|
|
if recycle_bin == 'open':
|
|
|
|
if mvRecycleBin(path):
|
|
|
|
return mw.returnData(True, '已将文件移动到回收站!')
|
|
|
|
mw.execShell('rm -rf ' + path)
|
|
|
|
mw.writeLog('文件管理', '删除{1}成功!', (path,))
|
|
|
|
return mw.returnData(True, '删除文件成功!')
|
|
|
|
except:
|
|
|
|
return mw.returnData(False, '删除文件失败!')
|
|
|
|
|
|
|
|
# 关闭
|
|
|
|
def toggleRecycleBin():
|
|
|
|
recycle_bin = thisdb.getOption('recycle_bin')
|
|
|
|
if recycle_bin == 'open':
|
|
|
|
thisdb.setOption('recycle_bin','close')
|
|
|
|
mw.writeLog('文件管理', '已关闭回收站功能!')
|
|
|
|
return mw.returnData(True, '已关闭回收站功能!')
|
|
|
|
else:
|
|
|
|
thisdb.setOption('recycle_bin','open')
|
|
|
|
mw.writeLog('文件管理', '已开启回收站功能!')
|
|
|
|
return mw.returnData(True, '已开启回收站功能!')
|
|
|
|
|
|
|
|
def getRecycleBin():
|
|
|
|
rb_dir = mw.getRecycleBinDir()
|
|
|
|
recycle_bin = thisdb.getOption('recycle_bin')
|
|
|
|
|
|
|
|
data = {}
|
|
|
|
data['dirs'] = []
|
|
|
|
data['files'] = []
|
|
|
|
data['status'] = False
|
|
|
|
if recycle_bin == 'open':
|
|
|
|
data['status'] = True
|
|
|
|
|
|
|
|
for file in os.listdir(rb_dir):
|
|
|
|
try:
|
|
|
|
tmp = {}
|
|
|
|
fname = rb_dir+'/'+ file
|
|
|
|
tmp1 = file.split('_mw_')
|
|
|
|
tmp2 = tmp1[len(tmp1) - 1].split('_t_')
|
|
|
|
tmp['rname'] = file
|
|
|
|
tmp['dname'] = file.replace('_mw_', '/').split('_t_')[0]
|
|
|
|
tmp['name'] = tmp2[0]
|
|
|
|
tmp['time'] = int(float(tmp2[1]))
|
|
|
|
if os.path.islink(fname):
|
|
|
|
filePath = os.readlink(fname)
|
|
|
|
link = ' -> ' + filePath
|
|
|
|
if os.path.exists(filePath):
|
|
|
|
tmp['size'] = os.path.getsize(filePath)
|
|
|
|
else:
|
|
|
|
tmp['size'] = 0
|
|
|
|
else:
|
|
|
|
tmp['size'] = os.path.getsize(fname)
|
|
|
|
if os.path.isdir(fname):
|
|
|
|
data['dirs'].append(tmp)
|
|
|
|
else:
|
|
|
|
data['files'].append(tmp)
|
|
|
|
except Exception as e:
|
|
|
|
continue
|
|
|
|
|
|
|
|
return mw.returnJson(True, 'OK', data)
|
|
|
|
|
|
|
|
# 移动到回收站
|
|
|
|
def mvRecycleBin(path):
|
|
|
|
rb_dir = mw.getRecycleBinDir()
|
|
|
|
rb_file = rb_dir + '/' + path.replace('/', '_mw_') + '_t_' + str(time.time())
|
|
|
|
try:
|
|
|
|
import shutil
|
|
|
|
shutil.move(path, rb_file)
|
|
|
|
mw.writeLog('文件管理', mw.getInfo('移动[{1}]到回收站成功!', (path,)))
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
|
|
mw.writeLog('文件管理', mw.getInfo('移动[{1}]到回收站失败!', (path,)))
|
|
|
|
return False
|
|
|
|
|
|
|
|
# 回收站文件恢复
|
|
|
|
def reRecycleBin(path):
|
|
|
|
rb_dir = mw.getRecycleBinDir()
|
|
|
|
dst_file = path.replace('_mw_', '/').split('_t_')[0]
|
|
|
|
try:
|
|
|
|
import shutil
|
|
|
|
shutil.move(rb_dir + '/' + path, dst_file)
|
|
|
|
msg = mw.getInfo('移动文件[{1}]到回收站成功!', (dst_file,))
|
|
|
|
mw.writeLog('文件管理', msg)
|
|
|
|
return mw.returnData(True, '恢复成功!')
|
|
|
|
except Exception as e:
|
|
|
|
msg = mw.getInfo('从回收站恢复[{1}]失败!', (dst_file,))
|
|
|
|
mw.writeLog('文件管理', msg)
|
|
|
|
return mw.returnData(False, '恢复失败!')
|
|
|
|
|
|
|
|
|
|
|
|
def closeRecycleBin():
|
|
|
|
rb_dir = mw.getRecycleBinDir()
|
|
|
|
mw.execShell('which chattr && chattr -R -i ' + rb_dir)
|
|
|
|
rlist = os.listdir(rb_dir)
|
|
|
|
i = 0
|
|
|
|
l = len(rlist)
|
|
|
|
for name in rlist:
|
|
|
|
i += 1
|
|
|
|
path = rb_dir + '/' + name
|
|
|
|
mw.writeSpeed(name, i, l)
|
|
|
|
if os.path.isdir(path):
|
|
|
|
shutil.rmtree(path)
|
|
|
|
else:
|
|
|
|
os.remove(path)
|
|
|
|
mw.writeSpeed(None, 0, 0)
|
|
|
|
mw.writeLog('文件管理', '已清空回收站!')
|
|
|
|
return mw.returnJson(True, '已清空回收站!')
|
|
|
|
|
|
|
|
|
|
|
|
# 设置文件和目录权限
|
|
|
|
def setMode(path):
|
|
|
|
s_path = os.path.dirname(path)
|
|
|
|
p_stat = os.stat(s_path)
|
|
|
|
os.chown(path, p_stat.st_uid, p_stat.st_gid)
|
|
|
|
os.chmod(path, p_stat.st_mode)
|
|
|
|
|
|
|
|
|
|
|
|
def closeLogs():
|
|
|
|
log_file = mw.getLogsDir()
|
|
|
|
os.system('rm -rf ' + log_file + '/*')
|
|
|
|
mw.opWeb('reload')
|
|
|
|
# os.system('kill -USR1 `cat ' + mw.getServerDir() +'/openresty/nginx/logs/nginx.pid`')
|
|
|
|
mw.writeLog('文件管理', '网站日志已被清空!')
|
|
|
|
tmp = getDirSizeByBash(log_file)
|
|
|
|
return mw.returnData(True, tmp)
|