mirror of
https://github.com/aaPanel/aaPanel.git
synced 2026-08-25 09:02:26 +02:00
1185 lines
47 KiB
Python
1185 lines
47 KiB
Python
#!/usr/bin/env python
|
|
#coding:utf-8
|
|
# +-------------------------------------------------------------------
|
|
# | 宝塔Linux面板
|
|
# +-------------------------------------------------------------------
|
|
# | Copyright (c) 2015-2016 宝塔软件(http://bt.cn) All rights reserved.
|
|
# +-------------------------------------------------------------------
|
|
# | Author: 黄文良 <287962566@qq.com>
|
|
# +-------------------------------------------------------------------
|
|
import sys,os,public,time,json,pwd,cgi
|
|
from BTPanel import session,request
|
|
class files:
|
|
#检查敏感目录
|
|
def CheckDir(self,path):
|
|
path = path.replace('//','/');
|
|
if path[-1:] == '/':
|
|
path = path[:-1]
|
|
|
|
nDirs = ('',
|
|
'/',
|
|
'/*',
|
|
'/www',
|
|
'/root',
|
|
'/boot',
|
|
'/bin',
|
|
'/etc',
|
|
'/home',
|
|
'/dev',
|
|
'/sbin',
|
|
'/var',
|
|
'/usr',
|
|
'/tmp',
|
|
'/sys',
|
|
'/proc',
|
|
'/media',
|
|
'/mnt',
|
|
'/opt',
|
|
'/lib',
|
|
'/srv',
|
|
'/selinux',
|
|
'/www/server',
|
|
'/www/server/data',
|
|
public.GetConfigValue('logs_path'),
|
|
public.GetConfigValue('setup_path'))
|
|
|
|
return not path in nDirs
|
|
|
|
#检测文件名
|
|
def CheckFileName(self,filename):
|
|
nots = ['\\','&','*','|',';','"',"'",'<','>']
|
|
if filename.find('/') != -1: filename = filename.split('/')[-1]
|
|
for n in nots:
|
|
if n in filename: return False
|
|
return True
|
|
|
|
#名称输出过滤
|
|
def xssencode(self,text):
|
|
list=['<','>']
|
|
ret=[]
|
|
for i in text:
|
|
if i in list:
|
|
i=''
|
|
ret.append(i)
|
|
str_convert = ''.join(ret)
|
|
text2=cgi.escape(str_convert, quote=True)
|
|
return text2
|
|
|
|
#上传文件
|
|
def UploadFile(self,get):
|
|
from werkzeug.utils import secure_filename
|
|
from flask import request
|
|
if sys.version_info[0] == 2: get.path = get.path.encode('utf-8');
|
|
if not os.path.exists(get.path): os.makedirs(get.path)
|
|
f = request.files['zunfile']
|
|
filename = os.path.join(get.path, f.filename)
|
|
if sys.version_info[0] == 2: filename = filename.encode('utf-8');
|
|
s_path = get.path
|
|
if os.path.exists(filename):s_path = filename
|
|
p_stat = os.stat(s_path)
|
|
f.save(filename)
|
|
os.chown(filename,p_stat.st_uid,p_stat.st_gid)
|
|
os.chmod(filename,p_stat.st_mode)
|
|
public.WriteLog('TYPE_FILE','FILE_UPLOAD_SUCCESS',(filename,get['path']));
|
|
return public.returnMsg(True,'FILE_UPLOAD_SUCCESS');
|
|
|
|
|
|
|
|
#上传文件2
|
|
def upload(self,args):
|
|
if sys.version_info[0] == 2:
|
|
args.f_name = args.f_name.encode('utf-8')
|
|
args.f_path = args.f_path.encode('utf-8')
|
|
if args.f_name.find('./') != -1 or args.f_path.find('./') != -1:
|
|
return public.returnMsg(False,'错误的参数')
|
|
if not os.path.exists(args.f_path):
|
|
os.makedirs(args.f_path,493)
|
|
if not 'dir_mode' in args or not 'file_mode' in args:
|
|
self.set_mode(args.f_path)
|
|
|
|
save_path = os.path.join(args.f_path,args.f_name + '.' + str(int(args.f_size)) + '.upload.tmp')
|
|
d_size = 0
|
|
if os.path.exists(save_path): d_size = os.path.getsize(save_path)
|
|
if d_size != int(args.f_start): return d_size
|
|
upload_files = request.files.getlist("blob")
|
|
f = open(save_path,'ab')
|
|
for tmp_f in upload_files:
|
|
f.write(tmp_f.read())
|
|
f.close()
|
|
f_size = os.path.getsize(save_path)
|
|
if f_size != int(args.f_size): return f_size
|
|
new_name = os.path.join(args.f_path ,args.f_name)
|
|
if os.path.exists(new_name):
|
|
if new_name.find('.user.ini') != -1:
|
|
public.ExecShell("chattr -i " + new_name)
|
|
os.remove(new_name)
|
|
os.renames(save_path, new_name)
|
|
if 'dir_mode' in args and 'file_mode' in args:
|
|
mode_tmp1 = args.dir_mode.split(',')
|
|
public.ExecShell("chmod " + mode_tmp1[0] + " " + args.f_path )
|
|
public.ExecShell("chown " + mode_tmp1[1] + ":" + mode_tmp1[1] + " " + args.f_path)
|
|
mode_tmp2 = args.file_mode.split(',')
|
|
public.ExecShell("chmod " + mode_tmp2[0] + " " + new_name )
|
|
public.ExecShell("chown " + mode_tmp2[1] + ":" + mode_tmp2[1] + " " + new_name )
|
|
|
|
else:
|
|
self.set_mode(new_name)
|
|
if new_name.find('.user.ini') != -1:
|
|
public.ExecShell("chattr +i " + new_name)
|
|
|
|
public.WriteLog('TYPE_FILE','FILE_UPLOAD_SUCCESS',(args.f_name,args.f_path));
|
|
return public.returnMsg(True,'Upload Success!')
|
|
|
|
#设置文件和目录权限
|
|
def set_mode(self,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 GetDir(self,get):
|
|
if not hasattr(get,'path'):
|
|
#return public.returnMsg(False,'错误的参数!')
|
|
get.path = '/www/wwwroot'
|
|
if sys.version_info[0] == 2: get.path = get.path.encode('utf-8');
|
|
if get.path == '': get.path = '/www';
|
|
if not os.path.exists(get.path):
|
|
return public.ReturnMsg(False,'DIR_NOT_EXISTS')
|
|
|
|
import pwd
|
|
dirnames = []
|
|
filenames = []
|
|
|
|
search = None
|
|
if hasattr(get,'search'): search = get.search.strip().lower();
|
|
if hasattr(get,'all'): return self.SearchFiles(get)
|
|
|
|
#包含分页类
|
|
import page
|
|
#实例化分页类
|
|
page = page.Page();
|
|
info = {}
|
|
info['count'] = self.GetFilesCount(get.path,search);
|
|
info['row'] = 100
|
|
info['p'] = 1
|
|
if hasattr(get,'p'):
|
|
try:
|
|
info['p'] = int(get['p'])
|
|
except:
|
|
info['p'] = 1
|
|
|
|
info['uri'] = {}
|
|
info['return_js'] = ''
|
|
if hasattr(get,'tojs'):
|
|
info['return_js'] = get.tojs
|
|
if hasattr(get,'showRow'):
|
|
info['row'] = int(get.showRow);
|
|
|
|
#获取分页数据
|
|
data = {}
|
|
data['PAGE'] = page.GetPage(info,'1,2,3,4,5,6,7,8')
|
|
|
|
i = 0;
|
|
n = 0;
|
|
|
|
if not hasattr(get,'reverse'):
|
|
for filename in os.listdir(get.path):
|
|
filename = self.xssencode(filename)
|
|
|
|
|
|
|
|
if search:
|
|
if filename.lower().find(search) == -1: continue;
|
|
i += 1;
|
|
if n >= page.ROW: break;
|
|
if i < page.SHIFT: continue;
|
|
|
|
try:
|
|
if sys.version_info[0] == 2: filename = filename.encode('utf-8');
|
|
filePath = get.path+'/'+filename
|
|
link = '';
|
|
if os.path.islink(filePath):
|
|
filePath = os.readlink(filePath);
|
|
link = ' -> ' + filePath;
|
|
if not os.path.exists(filePath): filePath = get.path + '/' + filePath;
|
|
if not os.path.exists(filePath): continue;
|
|
|
|
stat = os.stat(filePath)
|
|
accept = str(oct(stat.st_mode)[-3:]);
|
|
mtime = str(int(stat.st_mtime))
|
|
user = ''
|
|
try:
|
|
user = pwd.getpwuid(stat.st_uid).pw_name
|
|
except:
|
|
user = str(stat.st_uid)
|
|
size = str(stat.st_size)
|
|
if os.path.isdir(filePath):
|
|
dirnames.append(filename+';'+size+';'+mtime+';'+accept+';'+user+';'+link);
|
|
else:
|
|
filenames.append(filename+';'+size+';'+mtime+';'+accept+';'+user+';'+link);
|
|
n += 1;
|
|
except:
|
|
continue;
|
|
|
|
|
|
data['DIR'] = sorted(dirnames);
|
|
data['FILES'] = sorted(filenames);
|
|
else:
|
|
reverse = bool(get.reverse)
|
|
if get.reverse == 'False': reverse = False
|
|
for file_info in self.__list_dir(get.path,get.sort,reverse):
|
|
filename = os.path.join(get.path,file_info['name'])
|
|
if not os.path.exists(filename): continue
|
|
if search:
|
|
if file_info['name'].lower().find(search) == -1: continue;
|
|
i += 1;
|
|
if n >= page.ROW: break;
|
|
if i < page.SHIFT: continue;
|
|
|
|
r_file = file_info['name'] + ';' + str(file_info['size']) + ';' + str(file_info['mtime']) + ';' + str(file_info['accept']) + ';' + file_info['user']+ ';' + file_info['link']
|
|
if os.path.isdir(filename):
|
|
dirnames.append(r_file)
|
|
else:
|
|
filenames.append(r_file)
|
|
n += 1;
|
|
|
|
data['DIR'] = dirnames
|
|
data['FILES'] = filenames
|
|
|
|
data['PATH'] = str(get.path)
|
|
if hasattr(get,'disk'):
|
|
import system
|
|
data['DISK'] = system.system().GetDiskInfo();
|
|
return data
|
|
|
|
|
|
def __list_dir(self,path,my_sort = 'name',reverse = False):
|
|
if not os.path.exists(path): return []
|
|
py_v = sys.version_info[0]
|
|
tmp_files = []
|
|
tmp_dirs = []
|
|
for f_name in os.listdir(path):
|
|
if py_v == 2: f_name = f_name.encode('utf-8');
|
|
filename = os.path.join(path,f_name)
|
|
if not os.path.exists(filename): continue
|
|
file_info = self.__format_stat(filename,path)
|
|
if not file_info: continue
|
|
if os.path.isdir(filename):
|
|
tmp_dirs.append(file_info)
|
|
else:
|
|
tmp_files.append(file_info)
|
|
tmp_dirs = sorted(tmp_dirs,key=lambda x:x[my_sort],reverse=reverse)
|
|
tmp_files = sorted(tmp_files,key=lambda x:x[my_sort],reverse=reverse)
|
|
|
|
for f in tmp_files: tmp_dirs.append(f)
|
|
return tmp_dirs
|
|
|
|
|
|
def __format_stat(self,filename,path):
|
|
try:
|
|
stat = self.__get_stat(filename,path)
|
|
if not stat: return None
|
|
tmp_stat = stat.split(';')
|
|
file_info = {'name': self.xssencode(tmp_stat[0].replace('/','')),'size':int(tmp_stat[1]),'mtime':int(tmp_stat[2]),'accept':int(tmp_stat[3]),'user':tmp_stat[4],'link':tmp_stat[5]}
|
|
return file_info
|
|
except: return None
|
|
|
|
|
|
def SearchFiles(self,get):
|
|
if not hasattr(get,'path'): get.path = '/www/wwwroot'
|
|
if sys.version_info[0] == 2: get.path = get.path.encode('utf-8');
|
|
if not os.path.exists(get.path): get.path = '/www';
|
|
search = get.search.strip().lower();
|
|
my_dirs = []
|
|
my_files = []
|
|
count = 0
|
|
max = 3000
|
|
for d_list in os.walk(get.path):
|
|
if count >= max: break;
|
|
for d in d_list[1]:
|
|
if count >= max: break;
|
|
d = self.xssencode(d)
|
|
if d.lower().find(search) != -1:
|
|
my_dirs.append(self.__get_stat(d_list[0] + '/' + d,get.path))
|
|
count += 1
|
|
|
|
for f in d_list[2]:
|
|
if count >= max: break;
|
|
f = self.xssencode(f)
|
|
if f.lower().find(search) != -1:
|
|
my_files.append(self.__get_stat(d_list[0] + '/' + f,get.path))
|
|
count += 1
|
|
data = {}
|
|
data['DIR'] = sorted(my_dirs)
|
|
data['FILES'] = sorted(my_files)
|
|
data['PATH'] = str(get.path)
|
|
data['PAGE'] = public.get_page(len(my_dirs) + len(my_files),1,max,'GetFiles')['page']
|
|
return data
|
|
|
|
|
|
def __get_stat(self,filename,path = None):
|
|
stat = os.stat(filename)
|
|
accept = str(oct(stat.st_mode)[-3:]);
|
|
mtime = str(int(stat.st_mtime))
|
|
user = ''
|
|
try:
|
|
user = pwd.getpwuid(stat.st_uid).pw_name
|
|
except:
|
|
user = str(stat.st_uid)
|
|
size = str(stat.st_size)
|
|
link = '';
|
|
if os.path.islink(filename): link = ' -> ' + os.readlink(filename)
|
|
tmp_path = (path + '/').replace('//','/')
|
|
if path and tmp_path != '/':filename = filename.replace(tmp_path,'')
|
|
return filename + ';' + size + ';' + mtime+ ';' +accept+ ';' +user+ ';' +link
|
|
|
|
|
|
#计算文件数量
|
|
def GetFilesCount(self,path,search):
|
|
i=0;
|
|
for name in os.listdir(path):
|
|
if search:
|
|
if name.lower().find(search) == -1: continue;
|
|
i += 1;
|
|
return i;
|
|
|
|
#创建文件
|
|
def CreateFile(self,get):
|
|
if sys.version_info[0] == 2: get.path = get.path.encode('utf-8').strip();
|
|
try:
|
|
if not self.CheckFileName(get.path): return public.returnMsg(False,'FILE_NAME_SPECIAL_CHARACTRES');
|
|
if os.path.exists(get.path):
|
|
return public.returnMsg(False,'FILE_EXISTS')
|
|
path = os.path.dirname(get.path)
|
|
if not os.path.exists(path):
|
|
os.makedirs(path)
|
|
open(get.path,'w+').close()
|
|
self.SetFileAccept(get.path);
|
|
public.WriteLog('TYPE_FILE','FILE_CREATE_SUCCESS',(get.path,))
|
|
return public.returnMsg(True,'FILE_CREATE_SUCCESS')
|
|
except:
|
|
return public.returnMsg(False,'FILE_CREATE_ERR')
|
|
|
|
#创建目录
|
|
def CreateDir(self,get):
|
|
if sys.version_info[0] == 2: get.path = get.path.encode('utf-8').strip();
|
|
try:
|
|
if not self.CheckFileName(get.path): return public.returnMsg(False,'DIR_NAME_SPECIAL_CHARACTRES');
|
|
if os.path.exists(get.path):
|
|
return public.returnMsg(False,'DIR_EXISTS')
|
|
os.makedirs(get.path)
|
|
self.SetFileAccept(get.path);
|
|
public.WriteLog('TYPE_FILE','DIR_CREATE_SUCCESS',(get.path,))
|
|
return public.returnMsg(True,'DIR_CREATE_SUCCESS')
|
|
except:
|
|
return public.returnMsg(False,'DIR_CREATE_ERR')
|
|
|
|
|
|
#删除目录
|
|
def DeleteDir(self,get) :
|
|
if sys.version_info[0] == 2: get.path = get.path.encode('utf-8');
|
|
#if get.path.find('/www/wwwroot') == -1: return public.returnMsg(False,'此为演示服务器,禁止删除此目录!');
|
|
if not os.path.exists(get.path):
|
|
return public.returnMsg(False,'DIR_NOT_EXISTS')
|
|
|
|
#检查是否敏感目录
|
|
if not self.CheckDir(get.path):
|
|
return public.returnMsg(False,'FILE_DANGER');
|
|
|
|
try:
|
|
#检查是否存在.user.ini
|
|
if os.path.exists(get.path+'/.user.ini'):
|
|
os.system("chattr -i '"+get.path+"/.user.ini'")
|
|
if hasattr(get,'empty'):
|
|
if not self.delete_empty(get.path): return public.returnMsg(False,'DIR_ERR_NOT_EMPTY');
|
|
|
|
if os.path.exists('data/recycle_bin.pl'):
|
|
if self.Mv_Recycle_bin(get): return public.returnMsg(True,'DIR_MOVE_RECYCLE_BIN');
|
|
|
|
import shutil
|
|
shutil.rmtree(get.path)
|
|
public.WriteLog('TYPE_FILE','DIR_DEL_SUCCESS',(get.path,))
|
|
return public.returnMsg(True,'DIR_DEL_SUCCESS')
|
|
except:
|
|
return public.returnMsg(False,'DIR_DEL_ERR')
|
|
|
|
#删除 空目录
|
|
def delete_empty(self,path):
|
|
if sys.version_info[0] == 2: get.path = get.path.encode('utf-8');
|
|
for files in os.listdir(path):
|
|
return False
|
|
return True
|
|
|
|
#删除文件
|
|
def DeleteFile(self,get):
|
|
if sys.version_info[0] == 2: get.path = get.path.encode('utf-8');
|
|
if not os.path.exists(get.path):
|
|
return public.returnMsg(False,'FILE_NOT_EXISTS')
|
|
|
|
#检查是否为.user.ini
|
|
if get.path.find('.user.ini') != -1:
|
|
os.system("chattr -i '"+get.path+"'")
|
|
try:
|
|
if os.path.exists('data/recycle_bin.pl'):
|
|
if self.Mv_Recycle_bin(get): return public.returnMsg(True,'FILE_MOVE_RECYCLE_BIN');
|
|
os.remove(get.path)
|
|
public.WriteLog('TYPE_FILE','FILE_DEL_SUCCESS',(get.path,))
|
|
return public.returnMsg(True,'FILE_DEL_SUCCESS')
|
|
except:
|
|
return public.returnMsg(False,'FILE_DEL_ERR')
|
|
|
|
#移动到回收站
|
|
def Mv_Recycle_bin(self,get):
|
|
rPath = '/www/Recycle_bin/'
|
|
if not os.path.exists(rPath): os.system('mkdir -p ' + rPath);
|
|
rFile = rPath + get.path.replace('/','_bt_') + '_t_' + str(time.time());
|
|
try:
|
|
import shutil
|
|
shutil.move(get.path, rFile)
|
|
public.WriteLog('TYPE_FILE','FILE_MOVE_RECYCLE_BIN',(get.path,))
|
|
return True;
|
|
except:
|
|
public.WriteLog('TYPE_FILE','FILE_MOVE_RECYCLE_BIN_ERR',(get.path,))
|
|
return False;
|
|
|
|
#从回收站恢复
|
|
def Re_Recycle_bin(self,get):
|
|
rPath = '/www/Recycle_bin/'
|
|
if sys.version_info[0] == 2: get.path = get.path.encode('utf-8');
|
|
dFile = get.path.replace('_bt_','/').split('_t_')[0];
|
|
get.path = rPath + get.path
|
|
if dFile.find('BTDB_') != -1:
|
|
import database;
|
|
return database.database().RecycleDB(get.path);
|
|
try:
|
|
import shutil
|
|
shutil.move(get.path, dFile)
|
|
public.WriteLog('TYPE_FILE','FILE_RE_RECYCLE_BIN',(dFile,))
|
|
return public.returnMsg(True,'FILE_RE_RECYCLE_BIN');
|
|
except:
|
|
public.WriteLog('TYPE_FILE','FILE_RE_RECYCLE_BIN_ERR',(dFile,))
|
|
return public.returnMsg(False,'FILE_RE_RECYCLE_BIN_ERR');
|
|
|
|
#获取回收站信息
|
|
def Get_Recycle_bin(self,get):
|
|
rPath = '/www/Recycle_bin/'
|
|
if not os.path.exists(rPath): os.system('mkdir -p ' + rPath);
|
|
data = {};
|
|
data['dirs'] = [];
|
|
data['files'] = [];
|
|
data['status'] = os.path.exists('data/recycle_bin.pl');
|
|
data['status_db'] = os.path.exists('data/recycle_bin_db.pl');
|
|
for file in os.listdir(rPath):
|
|
file = self.xssencode(file)
|
|
try:
|
|
tmp = {};
|
|
fname = rPath + file;
|
|
tmp1 = file.split('_bt_');
|
|
tmp2 = tmp1[len(tmp1)-1].split('_t_');
|
|
tmp['rname'] = file;
|
|
tmp['dname'] = file.replace('_bt_','/').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:
|
|
continue;
|
|
return data;
|
|
|
|
#彻底删除
|
|
def Del_Recycle_bin(self,get):
|
|
rPath = '/www/Recycle_bin/'
|
|
if sys.version_info[0] == 2: get.path = get.path.encode('utf-8');
|
|
dFile = get.path.split('_t_')[0];
|
|
if dFile.find('BTDB_') != -1:
|
|
import database;
|
|
return database.database().DeleteTo(rPath+get.path);
|
|
if not self.CheckDir(rPath + get.path):
|
|
return public.returnMsg(False,'FILE_DANGER');
|
|
os.system('chattr -R -i ' + rPath + get.path)
|
|
if os.path.isdir(rPath + get.path):
|
|
import shutil
|
|
shutil.rmtree(rPath + get.path);
|
|
else:
|
|
os.remove(rPath + get.path);
|
|
|
|
tfile = get.path.replace('_bt_','/').split('_t_')[0];
|
|
public.WriteLog('TYPE_FILE','FILE_DEL_RECYCLE_BIN',(tfile,));
|
|
return public.returnMsg(True,'FILE_DEL_RECYCLE_BIN',(tfile,));
|
|
|
|
#清空回收站
|
|
def Close_Recycle_bin(self,get):
|
|
rPath = '/www/Recycle_bin/'
|
|
os.system('chattr -R -i ' + rPath)
|
|
import database,shutil;
|
|
rlist = os.listdir(rPath)
|
|
i = 0;
|
|
l = len(rlist);
|
|
for name in rlist:
|
|
i += 1;
|
|
path = rPath + name;
|
|
public.writeSpeed(name,i,l);
|
|
if name.find('BTDB_') != -1:
|
|
database.database().DeleteTo(path);
|
|
continue;
|
|
if os.path.isdir(path):
|
|
#os.system('rm -rf ' + path);
|
|
shutil.rmtree(path);
|
|
else:
|
|
#os.system('rm -f ' + path);
|
|
os.remove(path);
|
|
public.writeSpeed(None,0,0);
|
|
public.WriteLog('TYPE_FILE','FILE_CLOSE_RECYCLE_BIN');
|
|
return public.returnMsg(True,'FILE_CLOSE_RECYCLE_BIN');
|
|
|
|
#回收站开关
|
|
def Recycle_bin(self,get):
|
|
c = 'data/recycle_bin.pl';
|
|
if hasattr(get,'db'): c = 'data/recycle_bin_db.pl';
|
|
if os.path.exists(c):
|
|
os.remove(c)
|
|
public.WriteLog('TYPE_FILE','FILE_OFF_RECYCLE_BIN');
|
|
return public.returnMsg(True,'FILE_OFF_RECYCLE_BIN');
|
|
else:
|
|
public.writeFile(c,'True');
|
|
public.WriteLog('TYPE_FILE','FILE_ON_RECYCLE_BIN');
|
|
return public.returnMsg(True,'FILE_ON_RECYCLE_BIN');
|
|
|
|
#复制文件
|
|
def CopyFile(self,get) :
|
|
if sys.version_info[0] == 2:
|
|
get.sfile = get.sfile.encode('utf-8');
|
|
get.dfile = get.dfile.encode('utf-8');
|
|
if not os.path.exists(get.sfile):
|
|
return public.returnMsg(False,'FILE_NOT_EXISTS')
|
|
|
|
#if os.path.exists(get.dfile):
|
|
# return public.returnMsg(False,'FILE_EXISTS')
|
|
|
|
if os.path.isdir(get.sfile):
|
|
return self.CopyDir(get)
|
|
|
|
import shutil
|
|
try:
|
|
shutil.copyfile(get.sfile, get.dfile)
|
|
public.WriteLog('TYPE_FILE','FILE_COPY_SUCCESS',(get.sfile,get.dfile))
|
|
stat = os.stat(get.sfile)
|
|
os.chown(get.dfile,stat.st_uid,stat.st_gid)
|
|
return public.returnMsg(True,'FILE_COPY_SUCCESS')
|
|
except:
|
|
return public.returnMsg(False,'FILE_COPY_ERR')
|
|
|
|
#复制文件夹
|
|
def CopyDir(self,get):
|
|
if sys.version_info[0] == 2:
|
|
get.sfile = get.sfile.encode('utf-8');
|
|
get.dfile = get.dfile.encode('utf-8');
|
|
if not os.path.exists(get.sfile):
|
|
return public.returnMsg(False,'DIR_NOT_EXISTS');
|
|
|
|
if os.path.exists(get.dfile):
|
|
return public.returnMsg(False,'DIR_EXISTS');
|
|
|
|
#if not self.CheckDir(get.dfile):
|
|
# return public.returnMsg(False,'FILE_DANGER');
|
|
|
|
import shutil
|
|
try:
|
|
shutil.copytree(get.sfile, get.dfile)
|
|
stat = os.stat(get.sfile)
|
|
os.chown(get.dfile,stat.st_uid,stat.st_gid)
|
|
public.WriteLog('TYPE_FILE','DIR_COPY_SUCCESS',(get.sfile,get.dfile))
|
|
return public.returnMsg(True,'DIR_COPY_SUCCESS')
|
|
except:
|
|
return public.returnMsg(False,'DIR_COPY_ERR')
|
|
|
|
|
|
|
|
#移动文件或目录
|
|
def MvFile(self,get):
|
|
if sys.version_info[0] == 2:
|
|
get.sfile = get.sfile.encode('utf-8');
|
|
get.dfile = get.dfile.encode('utf-8');
|
|
if not self.CheckFileName(get.dfile): return public.returnMsg(False,'FILE_NAME_SPECIAL_CHARACTRES');
|
|
if not os.path.exists(get.sfile):
|
|
return public.returnMsg(False,'FILE_NOT_EXISTS')
|
|
|
|
#if os.path.exists(get.dfile):
|
|
# return public.returnMsg(False,'FILE_EXISTS')
|
|
|
|
if not self.CheckDir(get.sfile):
|
|
return public.returnMsg(False,'FILE_DANGER');
|
|
|
|
import shutil
|
|
try:
|
|
shutil.move(get.sfile, get.dfile)
|
|
|
|
if hasattr(get,'rename'):
|
|
public.WriteLog('TYPE_FILE','RENAME',(get.sfile,get.dfile))
|
|
return public.returnMsg(True,'RENAME_SUCCESS')
|
|
else:
|
|
public.WriteLog('TYPE_FILE','MOVE_SUCCESS',(get.sfile,get.dfile))
|
|
return public.returnMsg(True,'MOVE_SUCCESS')
|
|
except:
|
|
return public.returnMsg(False,'MOVE_ERR')
|
|
|
|
#检查文件是否存在
|
|
def CheckExistsFiles(self,get):
|
|
if sys.version_info[0] == 2: get.dfile = get.dfile.encode('utf-8');
|
|
data = [];
|
|
filesx = [];
|
|
if not hasattr(get,'filename'):
|
|
filesx = json.loads(session['selected']['data']);
|
|
else:
|
|
filesx.append(get.filename);
|
|
|
|
for fn in filesx:
|
|
if fn == '.': continue
|
|
filename = get.dfile + '/' + fn;
|
|
if os.path.exists(filename):
|
|
tmp = {}
|
|
stat = os.stat(filename)
|
|
tmp['filename'] = fn;
|
|
tmp['size'] = os.path.getsize(filename);
|
|
tmp['mtime'] = str(int(stat.st_mtime));
|
|
data.append(tmp);
|
|
return data;
|
|
|
|
|
|
#获取文件内容
|
|
def GetFileBody(self,get) :
|
|
if sys.version_info[0] == 2: get.path = get.path.encode('utf-8');
|
|
if not os.path.exists(get.path):
|
|
if get.path.find('rewrite') == -1:
|
|
return public.returnMsg(False,'FILE_NOT_EXISTS',(get.path,))
|
|
public.writeFile(get.path,'');
|
|
|
|
if os.path.getsize(get.path) > 2097152: return public.returnMsg(False,'CANT_EDIT_ONLINE_FILE');
|
|
fp = open(get.path,'rb')
|
|
data = {}
|
|
data['status'] = True
|
|
|
|
try:
|
|
if fp:
|
|
from chardet.universaldetector import UniversalDetector
|
|
detector = UniversalDetector()
|
|
srcBody = b""
|
|
for line in fp.readlines():
|
|
detector.feed(line)
|
|
srcBody += line
|
|
detector.close()
|
|
char = detector.result
|
|
data['encoding'] = char['encoding']
|
|
if char['encoding'] == 'GB2312' or not char['encoding'] or char['encoding'] == 'TIS-620' or char['encoding'] == 'ISO-8859-9': data['encoding'] = 'GBK';
|
|
if char['encoding'] == 'ascii' or char['encoding'] == 'ISO-8859-1': data['encoding'] = 'utf-8';
|
|
if char['encoding'] == 'Big5': data['encoding'] = 'BIG5';
|
|
if not char['encoding'] in ['GBK','utf-8','BIG5']: data['encoding'] = 'utf-8';
|
|
try:
|
|
if sys.version_info[0] == 2:
|
|
data['data'] = srcBody.decode(data['encoding']).encode('utf-8',errors='ignore');
|
|
else:
|
|
data['data'] = srcBody.decode(data['encoding'])
|
|
except:
|
|
data['encoding'] = char['encoding'];
|
|
if sys.version_info[0] == 2:
|
|
data['data'] = srcBody.decode(data['encoding']).encode('utf-8',errors='ignore');
|
|
else:
|
|
data['data'] = srcBody.decode(data['encoding'])
|
|
else:
|
|
if sys.version_info[0] == 2:
|
|
data['data'] = srcBody.decode('utf-8').encode('utf-8');
|
|
else:
|
|
data['data'] = srcBody.decode('utf-8')
|
|
data['encoding'] = u'utf-8';
|
|
|
|
return data;
|
|
except Exception as ex:
|
|
return public.returnMsg(False,'INCOMPATIBLE_FILECODE',(str(ex)),)
|
|
|
|
|
|
#保存文件
|
|
def SaveFileBody(self,get):
|
|
if sys.version_info[0] == 2: get.path = get.path.encode('utf-8');
|
|
if not os.path.exists(get.path):
|
|
if get.path.find('.htaccess') == -1:
|
|
return public.returnMsg(False,'FILE_NOT_EXISTS')
|
|
|
|
try:
|
|
isConf = -1
|
|
if os.path.exists('/etc/init.d/nginx') or os.path.exists('/etc/init.d/httpd'):
|
|
isConf = get.path.find('nginx');
|
|
if isConf == -1: isConf = get.path.find('apache');
|
|
if isConf == -1: isConf = get.path.find('rewrite');
|
|
if isConf != -1:
|
|
os.system('\\cp -a '+get.path+' /tmp/backup.conf');
|
|
|
|
data = get.data;
|
|
userini = False;
|
|
if get.path.find('.user.ini') != -1:
|
|
userini = True;
|
|
public.ExecShell('chattr -i ' + get.path);
|
|
|
|
|
|
if get.path.find('/www/server/cron') != -1:
|
|
try:
|
|
import crontab
|
|
data = crontab.crontab().CheckScript(data);
|
|
except:
|
|
pass
|
|
|
|
if get.encoding == 'ascii':get.encoding = 'utf-8';
|
|
if sys.version_info[0] == 2:
|
|
data = data.encode(get.encoding,errors='ignore');
|
|
fp = open(get.path,'w+')
|
|
else:
|
|
data = data.encode(get.encoding,errors='ignore').decode(get.encoding);
|
|
fp = open(get.path,'w+',encoding=get.encoding)
|
|
fp.write(data)
|
|
fp.close()
|
|
|
|
if isConf != -1:
|
|
isError = public.checkWebConfig();
|
|
if isError != True:
|
|
os.system('\\cp -a /tmp/backup.conf '+get.path);
|
|
return public.returnMsg(False,'ERROR:<br><font style="color:red;">'+isError.replace("\n",'<br>')+'</font>');
|
|
public.serviceReload();
|
|
|
|
if userini: public.ExecShell('chattr +i ' + get.path);
|
|
|
|
public.WriteLog('TYPE_FILE','FILE_SAVE_SUCCESS',(get.path,));
|
|
return public.returnMsg(True,'FILE_SAVE_SUCCESS');
|
|
except Exception as ex:
|
|
return public.returnMsg(False,'FILE_SAVE_ERR' + str(ex));
|
|
|
|
|
|
#文件压缩
|
|
def Zip(self,get) :
|
|
if not 'z_type' in get: get.z_type = 'rar'
|
|
import panelTask
|
|
task_obj = panelTask.bt_task()
|
|
task_obj.create_task(public.GetMsg("COMPRESSION_FILE"),3,get.path,json.dumps({"sfile":get.sfile,"dfile":get.dfile,"z_type":get.z_type}))
|
|
public.WriteLog("TYPE_FILE", 'ZIP_SUCCESS',(get.sfile,get.dfile));
|
|
return public.returnMsg(True,'ADD_COMPRESSION_TO_LINEUP')
|
|
|
|
|
|
#文件解压
|
|
def UnZip(self,get):
|
|
import panelTask
|
|
if not 'password' in get:get.password = ''
|
|
task_obj = panelTask.bt_task()
|
|
task_obj.create_task(public.GetMsg("DECOMPRESSION_FILE"),2,get.sfile,json.dumps({"dfile":get.dfile,"password":get.password}))
|
|
public.WriteLog("TYPE_FILE", 'UNZIP_SUCCESS',(get.sfile,get.dfile));
|
|
return public.returnMsg(True,'ADD_DECOMPRESSION_TO_LINEUP')
|
|
|
|
|
|
#获取文件/目录 权限信息
|
|
def GetFileAccess(self,get):
|
|
if sys.version_info[0] == 2: get.filename = get.filename.encode('utf-8');
|
|
data = {}
|
|
try:
|
|
import pwd
|
|
stat = os.stat(get.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 SetFileAccess(self,get,all = '-R'):
|
|
if sys.version_info[0] == 2: get.filename = get.filename.encode('utf-8');
|
|
if 'all' in get:
|
|
if get.all == 'False': all = ''
|
|
try:
|
|
if not self.CheckDir(get.filename): return public.returnMsg(False,'FILE_DANGER');
|
|
if not os.path.exists(get.filename):
|
|
return public.returnMsg(False,'FILE_NOT_EXISTS')
|
|
os.system('chmod '+all+' '+get.access+" '"+get.filename+"'")
|
|
os.system('chown '+all+' '+get.user+':'+get.user+" '"+get.filename+"'")
|
|
public.WriteLog('TYPE_FILE','FILE_ACCESS_SUCCESS',(get.filename,get.access,get.user))
|
|
return public.returnMsg(True,'SET_SUCCESS')
|
|
except:
|
|
return public.returnMsg(False,'SET_ERROR')
|
|
|
|
def SetFileAccept(self,filename):
|
|
os.system('chown -R www:www ' + filename)
|
|
os.system('chmod -R 755 ' + filename)
|
|
|
|
|
|
|
|
#取目录大小
|
|
def GetDirSize(self,get):
|
|
if sys.version_info[0] == 2: get.path = get.path.encode('utf-8');
|
|
tmp = public.ExecShell('du -sbh '+ get.path)
|
|
return tmp[0].split()[0]
|
|
|
|
#取目录大小2
|
|
def get_path_size(self,get):
|
|
if sys.version_info[0] == 2: get.path = get.path.encode('utf-8');
|
|
data = {}
|
|
data['path'] = get.path
|
|
data['size'] = public.get_path_size(get.path)
|
|
return data
|
|
|
|
def CloseLogs(self,get):
|
|
get.path = public.GetConfigValue('root_path')
|
|
os.system('rm -f '+public.GetConfigValue('logs_path')+'/*')
|
|
if public.get_webserver() == 'nginx':
|
|
os.system('kill -USR1 `cat '+public.GetConfigValue('setup_path')+'/nginx/logs/nginx.pid`');
|
|
else:
|
|
os.system('/etc/init.d/httpd reload');
|
|
|
|
public.WriteLog('TYPE_FILE','SITE_LOG_CLOSE')
|
|
get.path = public.GetConfigValue('logs_path')
|
|
return self.GetDirSize(get)
|
|
|
|
#批量操作
|
|
def SetBatchData(self,get):
|
|
if sys.version_info[0] == 2: get.path = get.path.encode('utf-8');
|
|
if get.type == '1' or get.type == '2':
|
|
session['selected'] = get
|
|
return public.returnMsg(True,'FILE_ALL_TIPS')
|
|
elif get.type == '3':
|
|
for key in json.loads(get.data):
|
|
try:
|
|
if sys.version_info[0] == 2: key = key.encode('utf-8')
|
|
filename = get.path+'/'+key
|
|
if not self.CheckDir(filename): return public.returnMsg(False,'FILE_DANGER');
|
|
os.system('chmod -R '+get.access+" '"+filename+"'")
|
|
os.system('chown -R '+get.user+':'+get.user+" '"+filename+"'")
|
|
except:
|
|
continue;
|
|
public.WriteLog('TYPE_FILE','FILE_ALL_ACCESS')
|
|
return public.returnMsg(True,'FILE_ALL_ACCESS')
|
|
else:
|
|
import shutil
|
|
isRecyle = os.path.exists('data/recycle_bin.pl')
|
|
path = get.path
|
|
get.data = json.loads(get.data)
|
|
l = len(get.data);
|
|
i = 0;
|
|
for key in get.data:
|
|
try:
|
|
if sys.version_info[0] == 2: key = key.encode('utf-8')
|
|
filename = path + '/'+key
|
|
get.path = filename;
|
|
if not os.path.exists(filename): continue
|
|
i += 1;
|
|
public.writeSpeed(key,i,l);
|
|
if os.path.isdir(filename):
|
|
if not self.CheckDir(filename): return public.returnMsg(False,'FILE_DANGER');
|
|
if isRecyle:
|
|
self.Mv_Recycle_bin(get)
|
|
else:
|
|
shutil.rmtree(filename)
|
|
else:
|
|
if key == '.user.ini': os.system('chattr -i ' + filename);
|
|
if isRecyle:
|
|
|
|
self.Mv_Recycle_bin(get)
|
|
else:
|
|
os.remove(filename)
|
|
except:
|
|
continue;
|
|
public.writeSpeed(None,0,0);
|
|
public.WriteLog('TYPE_FILE','FILE_ALL_DEL')
|
|
return public.returnMsg(True,'FILE_ALL_DEL')
|
|
|
|
|
|
#批量粘贴
|
|
def BatchPaste(self,get):
|
|
import shutil
|
|
if sys.version_info[0] == 2: get.path = get.path.encode('utf-8');
|
|
if not self.CheckDir(get.path): return public.returnMsg(False,'FILE_DANGER');
|
|
i = 0;
|
|
myfiles = json.loads(session['selected']['data'])
|
|
l = len(myfiles);
|
|
if get.type == '1':
|
|
for key in myfiles:
|
|
i += 1
|
|
public.writeSpeed(key,i,l);
|
|
try:
|
|
if sys.version_info[0] == 2:
|
|
sfile = session['selected']['path'] + '/' + key.encode('utf-8')
|
|
dfile = get.path + '/' + key.encode('utf-8')
|
|
else:
|
|
sfile = session['selected']['path'] + '/' + key
|
|
dfile = get.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;
|
|
public.WriteLog('TYPE_FILE','FILE_ALL_COPY',(session['selected']['path'],get.path))
|
|
else:
|
|
for key in myfiles:
|
|
try:
|
|
i += 1
|
|
public.writeSpeed(key,i,l);
|
|
if sys.version_info[0] == 2:
|
|
sfile = session['selected']['path'] + '/' + key.encode('utf-8')
|
|
dfile = get.path + '/' + key.encode('utf-8')
|
|
else:
|
|
sfile = session['selected']['path'] + '/' + key
|
|
dfile = get.path + '/' + key
|
|
shutil.move(sfile,dfile)
|
|
except:
|
|
continue;
|
|
public.WriteLog('TYPE_FILE','FILE_ALL_MOTE',(session['selected']['path'],get.path))
|
|
public.writeSpeed(None,0,0);
|
|
errorCount = len(myfiles) - i
|
|
del(session['selected'])
|
|
return public.returnMsg(True,'FILE_ALL',(str(i),str(errorCount)));
|
|
|
|
#下载文件
|
|
def DownloadFile(self,get):
|
|
import panelTask
|
|
task_obj = panelTask.bt_task()
|
|
task_obj.create_task(public.GetMsg("DOWNLOAD_FILE"),1,get.url,get.path + '/' + get.filename)
|
|
#if sys.version_info[0] == 2: get.path = get.path.encode('utf-8');
|
|
#import db,time
|
|
#isTask = '/tmp/panelTask.pl'
|
|
#execstr = get.url +'|bt|'+get.path+'/'+get.filename
|
|
#sql = db.Sql()
|
|
#sql.table('tasks').add('name,type,status,addtime,execstr',('下载文件['+get.filename+']','download','0',time.strftime('%Y-%m-%d %H:%M:%S'),execstr))
|
|
#public.writeFile(isTask,'True')
|
|
#self.SetFileAccept(get.path+'/'+get.filename);
|
|
public.WriteLog('TYPE_FILE','FILE_DOWNLOAD',(get.url , get.path));
|
|
return public.returnMsg(True,'FILE_DOANLOAD')
|
|
|
|
#添加安装任务
|
|
def InstallSoft(self,get):
|
|
import db,time
|
|
path = public.GetConfigValue('setup_path') + '/php'
|
|
if not os.path.exists(path): os.system("mkdir -p " + path);
|
|
if session['server_os']['x'] != 'RHEL': get.type = '3'
|
|
apacheVersion='false';
|
|
if public.get_webserver() == 'apache':
|
|
apacheVersion = public.readFile(public.GetConfigValue('setup_path')+'/apache/version.pl');
|
|
public.writeFile('/var/bt_apacheVersion.pl',apacheVersion)
|
|
public.writeFile('/var/bt_setupPath.conf',public.GetConfigValue('root_path'))
|
|
isTask = '/tmp/panelTask.pl'
|
|
execstr = "cd " + public.GetConfigValue('setup_path') + "/panel/install && /bin/bash install_soft.sh " + get.type + " install " + get.name + " "+ get.version;
|
|
sql = db.Sql()
|
|
if hasattr(get,'id'):
|
|
id = get.id;
|
|
else:
|
|
id = None;
|
|
sql.table('tasks').add('id,name,type,status,addtime,execstr',(None,'安装['+get.name+'-'+get.version+']','execshell','0',time.strftime('%Y-%m-%d %H:%M:%S'),execstr))
|
|
public.writeFile(isTask,'True')
|
|
public.WriteLog('TYPE_SETUP','PLUGIN_ADD',(get.name,get.version));
|
|
time.sleep(0.1);
|
|
return public.returnMsg(True,'PLUGIN_ADD');
|
|
|
|
#删除任务队列
|
|
def RemoveTask(self,get):
|
|
try:
|
|
name = public.M('tasks').where('id=?',(get.id,)).getField('name');
|
|
status = public.M('tasks').where('id=?',(get.id,)).getField('status');
|
|
public.M('tasks').delete(get.id);
|
|
if status == '-1':
|
|
os.system("kill `ps -ef |grep 'python panelSafe.pyc'|grep -v grep|grep -v panelExec|awk '{print $2}'`");
|
|
os.system("kill `ps -ef |grep 'install_soft.sh'|grep -v grep|grep -v panelExec|awk '{print $2}'`");
|
|
os.system("kill `ps aux | grep 'python task.pyc$'|awk '{print $2}'`");
|
|
os.system('''
|
|
pids=`ps aux | grep 'sh'|grep -v grep|grep install|awk '{print $2}'`
|
|
arr=($pids)
|
|
|
|
for p in ${arr[@]}
|
|
do
|
|
kill -9 $p
|
|
done
|
|
''');
|
|
|
|
os.system('rm -f ' + name.replace('扫描目录[','').replace(']','') + '/scan.pl');
|
|
isTask = '/tmp/panelTask.pl';
|
|
public.writeFile(isTask,'True');
|
|
os.system('/etc/init.d/bt start');
|
|
except:
|
|
os.system('/etc/init.d/bt start');
|
|
return public.returnMsg(True,'PLUGIN_DEL');
|
|
|
|
#重新激活任务
|
|
def ActionTask(self,get):
|
|
isTask = '/tmp/panelTask.pl'
|
|
public.writeFile(isTask,'True');
|
|
return public.returnMsg(True,'PLUGIN_ACTION');
|
|
|
|
|
|
#卸载软件
|
|
def UninstallSoft(self,get):
|
|
public.writeFile('/var/bt_setupPath.conf',public.GetConfigValue('root_path'))
|
|
get.type = '0'
|
|
if session['server_os']['x'] != 'RHEL': get.type = '3'
|
|
execstr = "cd " + public.GetConfigValue('setup_path') + "/panel/install && /bin/bash install_soft.sh "+get.type+" uninstall " + get.name.lower() + " "+ get.version.replace('.','');
|
|
os.system(execstr);
|
|
public.WriteLog('TYPE_SETUP','PLUGIN_UNINSTALL',(get.name,get.version));
|
|
return public.returnMsg(True,"PLUGIN_UNINSTALL");
|
|
|
|
|
|
#取任务队列进度
|
|
def GetTaskSpeed(self,get):
|
|
tempFile = '/tmp/panelExec.log'
|
|
freshFile = '/tmp/panelFresh'
|
|
import db
|
|
find = db.Sql().table('tasks').where('status=? OR status=?',('-1','0')).field('id,type,name,execstr').find()
|
|
if not len(find): return public.returnMsg(False,'NO_TASK_AT_LINEUP',("-2",))
|
|
isTask = '/tmp/panelTask.pl'
|
|
public.writeFile(isTask,'True');
|
|
echoMsg = {}
|
|
echoMsg['name'] = find['name']
|
|
echoMsg['execstr'] = find['execstr']
|
|
if find['type'] == 'download':
|
|
try:
|
|
tmp = public.readFile(tempFile)
|
|
if len(tmp) < 10:
|
|
return public.returnMsg(False,'NO_TASK_AT_LINEUP',("-3",))
|
|
echoMsg['msg'] = json.loads(tmp)
|
|
echoMsg['isDownload'] = True
|
|
except:
|
|
db.Sql().table('tasks').where("id=?",(find['id'],)).save('status',('0',))
|
|
return public.returnMsg(False,'NO_TASK_AT_LINEUP',("-4",))
|
|
else:
|
|
echoMsg['msg'] = self.GetLastLine(tempFile,20)
|
|
echoMsg['isDownload'] = False
|
|
|
|
echoMsg['task'] = public.M('tasks').where("status!=?",('1',)).field('id,status,name,type').order("id asc").select()
|
|
return echoMsg
|
|
|
|
#取执行日志
|
|
def GetExecLog(self,get):
|
|
return self.GetLastLine('/tmp/panelExec.log',100);
|
|
|
|
#读文件指定倒数行数
|
|
def GetLastLine(self,inputfile,lineNum):
|
|
result = public.GetNumLines(inputfile,lineNum)
|
|
if len(result) < 1:
|
|
return public.getMsg('TASK_SLEEP');
|
|
return result
|
|
|
|
|
|
#执行SHELL命令
|
|
def ExecShell(self,get):
|
|
disabled = ['vi','vim','top','passwd','su']
|
|
get.shell = get.shell.strip()
|
|
tmp = get.shell.split(' ');
|
|
if tmp[0] in disabled: return public.returnMsg(False,'FILE_SHELL_ERR',(tmp[0],));
|
|
shellStr = '''#!/bin/bash
|
|
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
|
export PATH
|
|
cd %s
|
|
%s
|
|
''' % (get.path,get.shell)
|
|
public.writeFile('/tmp/panelShell.sh',shellStr);
|
|
os.system('nohup bash /tmp/panelShell.sh > /tmp/panelShell.pl 2>&1 &');
|
|
return public.returnMsg(True,'FILE_SHELL_EXEC');
|
|
|
|
#取SHELL执行结果
|
|
def GetExecShellMsg(self,get):
|
|
fileName = '/tmp/panelShell.pl';
|
|
if not os.path.exists(fileName): return 'FILE_SHELL_EMPTY';
|
|
status = not public.process_exists('bash',None,'/tmp/panelShell.sh')
|
|
return public.returnMsg(status,public.GetNumLines(fileName,200));
|
|
|
|
#文件搜索
|
|
def GetSearch(self,get):
|
|
if not os.path.exists(get.path): return public.returnMsg(False,'DIR_NOT_EXISTS');
|
|
return public.ExecShell("find "+get.path+" -name '*"+get.search+"*'");
|
|
|
|
#保存草稿
|
|
def SaveTmpFile(self,get):
|
|
save_path = '/www/server/panel/temp'
|
|
if not os.path.exists(save_path): os.makedirs(save_path)
|
|
get.path = os.path.join(save_path,public.Md5(get.path) + '.tmp')
|
|
public.writeFile(get.path,get.body)
|
|
return public.returnMsg(True,'HAVE_BEEN_SAVE')
|
|
|
|
#获取草稿
|
|
def GetTmpFile(self,get):
|
|
self.CleanOldTmpFile()
|
|
save_path = '/www/server/panel/temp'
|
|
if not os.path.exists(save_path): os.makedirs(save_path)
|
|
src_path = get.path
|
|
get.path = os.path.join(save_path,public.Md5(get.path) + '.tmp')
|
|
if not os.path.exists(get.path): return public.returnMsg(False,'HAVE_NOT_DRAFT')
|
|
data = self.GetFileInfo(get.path)
|
|
data['file'] = src_path
|
|
if 'rebody' in get: data['body'] = public.readFile(get.path)
|
|
return data
|
|
|
|
#清除过期草稿
|
|
def CleanOldTmpFile(self):
|
|
if 'clean_tmp_file' in session: return True
|
|
save_path = '/www/server/panel/temp'
|
|
max_time = 86400 * 30
|
|
now_time = time.time()
|
|
for tmpFile in os.listdir(save_path):
|
|
filename = os.path.join(save_path,tmpFile)
|
|
fileInfo = self.GetFileInfo(filename)
|
|
if now_time - fileInfo['modify_time'] > max_time: os.remove(filename)
|
|
session['clean_tmp_file'] = True
|
|
return True
|
|
|
|
#取指定文件信息
|
|
def GetFileInfo(self,path):
|
|
if not os.path.exists(path): return False
|
|
stat = os.stat(path)
|
|
fileInfo = {}
|
|
fileInfo['modify_time'] = int(stat.st_mtime)
|
|
fileInfo['size'] = os.path.getsize(path)
|
|
return fileInfo
|
|
|
|
#安装rar组件
|
|
def install_rar(self,get):
|
|
unrar_file = '/www/server/rar/unrar'
|
|
rar_file = '/www/server/rar/rar'
|
|
bin_unrar = '/usr/local/bin/unrar'
|
|
bin_rar = '/usr/local/bin/rar'
|
|
if os.path.exists(unrar_file) and os.path.exists(bin_unrar):
|
|
try:
|
|
import rarfile
|
|
except:
|
|
os.system("pip install rarfile")
|
|
return True
|
|
|
|
import platform
|
|
os_bit = ''
|
|
if platform.machine() == 'x86_64': os_bit = '-x64';
|
|
download_url = public.get_url() + '/src/rarlinux'+os_bit+'-5.6.1.tar.gz';
|
|
|
|
tmp_file = '/tmp/bt_rar.tar.gz'
|
|
os.system('wget -O ' + tmp_file + ' ' + download_url)
|
|
if os.path.exists(unrar_file): os.system("rm -rf /www/server/rar")
|
|
os.system("tar xvf " + tmp_file + ' -C /www/server/')
|
|
if os.path.exists(tmp_file): os.remove(tmp_file)
|
|
if not os.path.exists(unrar_file): return False
|
|
|
|
if os.path.exists(bin_unrar): os.remove(bin_unrar)
|
|
if os.path.exists(bin_rar): os.remove(bin_rar)
|
|
|
|
os.system('ln -sf ' + unrar_file + ' ' + bin_unrar)
|
|
os.system('ln -sf ' + rar_file + ' ' + bin_rar)
|
|
os.system("pip install rarfile")
|
|
#public.writeFile('data/restart.pl','True')
|
|
return True
|
|
|
|
|