mdserver-web/web/utils/file.py

935 lines
31 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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:
pass
except Exception as e:
raise e
try:
shutil.move(sfile, dfile)
msg = mw.getInfo('移动或重名命文件[{1}]到[{2}]成功!', (sfile, dfile,))
mw.writeLog('文件管理', msg)
return mw.returnData(True, '移动或重名命文件成功!')
except Exception as e:
return mw.returnData(False, '移动或重名命文件失败!'+str(e))
def unzip(sfile, dfile, stype, path):
if dfile == '' or dfile == '/':
return mw.returnData(False, '不能在根目录解压!')
if not os.path.exists(sfile):
return mw.returnData(False, '指定文件不存在!')
try:
tmps = mw.getPanelDir() + '/logs/panel_exec.log'
if stype == 'zip':
mw.execShell("cd " + path + " && unzip -o -d '" + dfile +"' '" + sfile + "' > " + tmps + " 2>&1 &")
else:
sfiles = ''
for sfile in sfile.split(','):
if not sfile:
continue
sfiles += " '" + sfile + "'"
mw.execShell("cd " + path + " && tar -zxvf " + sfiles +" -C " + dfile + " > " + tmps + " 2>&1 &")
if os.path.exists(dfile):
if dfile.startswith("/www/wwwroot"):
setFileAccept(dfile)
mw.writeLog("文件管理", '文件[{1}]解压[{2}]成功!', (sfile, dfile))
return mw.returnData(True, '文件解压成功!')
except:
return mw.returnData(False, '文件解压失败!')
def uncompress(sfile, dfile, path):
if dfile == '' or dfile == '/':
return mw.returnData(False, '不能在根目录解压!')
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', '7z', 'xz','bz2']:
return mw.returnData(False, '现在仅支持gz,zip,rar,7z,xz,bz2格式解压!')
if extension == 'rar' and not mw.checkBinExist('rar'):
return mw.returnData(False, 'rar解压命令不存在请安装!')
if extension == '7z' and not mw.checkBinExist('7z'):
return mw.returnData(False, '7z解压命令不存在请安装!')
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)
elif extension == 'tar.gz':
cmd += "&& tar -zxvf " + sfile + " -C " + dfile + " > " + tmps + " 2>&1 &"
mw.execShell(cmd)
elif extension == 'gz':
cmd += "&& gunzip -k " + sfile + " > " + tmps + " 2>&1 &"
mw.execShell(cmd)
elif extension == 'rar':
cmd += "&& unrar x " + sfile + " " + dfile + " > " + tmps + " 2>&1 &"
mw.execShell(cmd)
elif extension == '7z':
cmd += "&& 7z x " + sfile + " -r -o" + dfile + " > " + tmps + " 2>&1 &"
mw.execShell(cmd)
elif extension == 'xz':
cmd += "&& tar -Jxvf " + sfile + " -C " + dfile + " > " + tmps + " 2>&1 &"
mw.execShell(cmd)
elif extension == 'bz2':
cmd += "&& tar -xjvf " + sfile + " -C " + dfile + " > " + tmps + " 2>&1 &"
mw.execShell(cmd)
if os.path.exists(dfile):
if dfile.startswith("/www/wwwroot"):
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 batchPaste(path, stype):
from admin import session
if not checkDir(path):
return mw.returnData(False, '请不要花样作死!')
i = 0
myfiles = json.loads(session['selected']['data'])
l = len(myfiles)
if stype == '1':
for key in myfiles:
i += 1
mw.writeSpeed(key, i, l)
try:
sfile = session['selected'][
'path'] + '/' + key
dfile = path + '/' + key
if os.path.isdir(sfile):
shutil.copytree(sfile, dfile)
else:
shutil.copyfile(sfile, dfile)
stat = os.stat(sfile)
os.chown(dfile, stat.st_uid, stat.st_gid)
except:
continue
msg = mw.getInfo('从[{1}]批量复制到[{2}]成功',(session['selected']['path'], path,))
mw.writeLog('文件管理', msg)
else:
for key in myfiles:
try:
i += 1
mw.writeSpeed(key, i, l)
sfile = session['selected'][
'path'] + '/' + key
dfile = path + '/' + key
shutil.move(sfile, dfile)
except:
continue
msg = mw.getInfo('从[{1}]批量移动到[{2}]成功',(session['selected']['path'], path,))
mw.writeLog('文件管理', msg)
mw.writeSpeed(None, 0, 0)
errorCount = len(myfiles) - i
del(session['selected'])
msg = mw.getInfo('批量操作成功[{1}],失败[{2}]', (str(i), str(errorCount)))
return mw.returnData(True, msg)
def zip(sfile, dfile, stype, path):
tmps = mw.getPanelDir() + '/logs/panel_exec.log'
if sfile.find(',') == -1:
if stype == 'zip':
mw.execShell("cd '" + path + "' && zip '" + dfile + "' -r '" + sfile + "' > " + tmps + " 2>&1")
elif stype == '7z':
if not mw.checkBinExist('7z'):
return mw.returnData(False, '7z压缩命令不存在请安装!')
mw.execShell("cd '" + path + "' && 7z a '" + dfile + "' -r '" + sfile + "' > " + tmps + " 2>&1")
elif stype == 'tar_gz':
mw.execShell("cd '" + path + "' && tar -zcvf '" + dfile + "' " + sfile + " > " + tmps + " 2>&1")
elif stype == 'xz':
# if not mw.checkBinExist('xz'):
# return mw.returnData(False, 'xz压缩命令不存在请安装!')
# dfile = dfile.strip(".xz")
# cmd = "cd '" + path + "' && tar -cvf '" + dfile + ".tar' " + sfile + " && xz -z '" + dfile + ".tar' > " + tmps + " 2>&1 &"
cmd = "cd '" + path + "' && tar -cJf '" + dfile + "' " + sfile + " > " + tmps + " 2>&1"
# print(cmd)
mw.execShell(cmd)
elif stype == 'rar':
if not mw.checkBinExist('rar'):
return mw.returnData(False, 'rar压缩命令不存在请安装!')
mw.execShell("cd '" + path + "' && rar a '" + dfile + "' '" + sfile + "' > " + tmps + " 2>&1")
elif stype == 'bz2':
mw.execShell("cd '" + path + "' && tar -cjvf '" + dfile + "' " + sfile + " > " + tmps + " 2>&1")
else:
return mw.returnData(False, '未知压缩格式')
mw.writeLog("文件管理", '文件[{1}]压缩[{2}]成功!', (sfile, dfile))
else:
sfiles = ''
for sfile in sfile.split(','):
if not sfile:
continue
if not os.path.exists(sfile):
return mw.returnData(False, '指定文件不存在!')
sfiles += " '" + sfile.replace(path+'/','') + "'"
if stype == 'zip':
mw.execShell("cd '" + path + "' && zip '" + dfile + "' -r " + sfiles + " > " + tmps + " 2>&1")
elif stype == '7z':
if not mw.checkBinExist('7z'):
return mw.returnData(False, '7z压缩命令不存在请安装!')
mw.execShell("cd '" + path + "' && 7z a '" + dfile + "' -r " + sfiles + " > " + tmps + " 2>&1")
elif stype == 'tar_gz':
mw.execShell("cd '" + path + "' && tar -zcvf '" + dfile + "' " + sfiles + " > " + tmps + " 2>&1")
elif stype == 'rar':
if not mw.checkBinExist('rar'):
return mw.returnData(False, 'rar压缩命令不存在请安装!')
mw.execShell("cd '" + path + "' && rar a '" + dfile + "' " + sfiles + " > " + tmps + " 2>&1")
elif stype == 'bz2':
mw.execShell("cd '" + path + "' && tar -cjvf '" + dfile + "' " + sfiles + " > " + tmps + " 2>&1")
else:
return mw.returnData(False, '未知压缩格式')
mw.writeLog("文件管理", '文件[{1}]压缩[{2}]成功!', (sfiles, dfile))
setFileAccept(dfile)
return mw.returnData(True, '文件压缩成功!')
def getAccess(filename):
data = {}
try:
stat = os.stat(filename)
data['chmod'] = str(oct(stat.st_mode)[-3:])
data['chown'] = pwd.getpwuid(stat.st_uid).pw_name
except:
data['chmod'] = 755
data['chown'] = 'www'
return data
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':
try:
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)
except Exception as e:
if sort == 'desc':
flist = sorted(flist, key=lambda f: os.path.getctime(os.path.join(path,f)), reverse=True)
if sort == 'asc':
flist = sorted(flist, key=lambda f: os.path.getctime(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:
try:
size += os.path.getsize(os.path.join(root, f))
except Exception as e:
pass
# 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 setFileAccess(filename,user,access):
sall = '-R'
try:
if not checkDir(filename):
return mw.returnData(False, '请不要花样作死')
if not os.path.exists(filename):
return mw.returnData(False, '指定文件不存在!')
os.system('chmod ' + sall + ' ' + access + " '" + filename + "'")
os.system('chown ' + sall + ' ' + user + ':' + user + " '" + filename + "'")
msg = mw.getInfo('设置[{1}]权限为[{2}]所有者为[{3}]', (filename, access, user,))
mw.writeLog('文件管理', msg)
return mw.returnData(True, '设置成功!')
except Exception as e:
return mw.returnData(False, '设置失败!'+str(e))
def getSysUserList():
pwd_file = '/etc/passwd'
if os.path.exists(pwd_file):
content = mw.readFile(pwd_file)
clist = content.split('\n')
sys_users = []
for line in clist:
if line.find(":")<0:
continue
lines = line.split(":",1)
sys_users.append(lines[0])
return sys_users
return ['root','mysql','www']
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 delRecycleBin(path):
rb_dir = mw.getRecycleBinDir()
rb_file = rb_dir + '/' + path
if os.path.isdir(rb_file):
import shutil
shutil.rmtree(rb_file)
else:
os.remove(rb_file)
tfile = path.replace('_mw_', '/').split('_t_')[0]
msg = mw.getInfo('已彻底从回收站删除[{1}]!', (tfile,))
mw.writeLog('文件管理', msg)
return mw.returnJson(True, msg)
# 移动到回收站
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)