260 lines
11 KiB
Python
260 lines
11 KiB
Python
|
|
# coding: utf-8
|
||
|
|
# +-------------------------------------------------------------------
|
||
|
|
# | version :1.0
|
||
|
|
# +-------------------------------------------------------------------
|
||
|
|
# | Author: liangkaiqiang <1249648969@yakpanel.com>
|
||
|
|
# +-------------------------------------------------------------------
|
||
|
|
# | 快速检索
|
||
|
|
# +--------------------------------------------------------------------
|
||
|
|
import os,public,re
|
||
|
|
import zipfile,time,json
|
||
|
|
import db
|
||
|
|
class panel_search:
|
||
|
|
__backup_path = '/www/server/panel/backup/panel_search/'
|
||
|
|
|
||
|
|
def __init__(self):
|
||
|
|
if not os.path.exists(self.__backup_path):
|
||
|
|
os.makedirs(self.__backup_path)
|
||
|
|
if not public.M('sqlite_master').where('type=? AND name=?', ('table', 'panel_search_log')).count():
|
||
|
|
csql = '''CREATE TABLE `panel_search_log` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `rtext` TEXT,`exts` TEXT,`path` TEXT,`mode` TEXT,`isword` TEXT,`iscase` TEXT,`noword` TEXT,`backup_path` TEXT,`time` TEXT)'''
|
||
|
|
public.M('sqlite_master').execute(csql,())
|
||
|
|
|
||
|
|
def dtchg(self, x):
|
||
|
|
try:
|
||
|
|
time_local = time.localtime(float(x))
|
||
|
|
dt = time.strftime("%Y-%m-%d %H:%M:%S", time_local)
|
||
|
|
return dt
|
||
|
|
except:
|
||
|
|
return False
|
||
|
|
|
||
|
|
def insert_settings(self, rtext, exts, path, mode, isword,iscase,noword,backup_path):
|
||
|
|
inser_time = self.dtchg(int(time.time()))
|
||
|
|
data = {"rtext": rtext, "exts": json.dumps(exts), "path": path, "mode": mode,
|
||
|
|
"isword": isword, "iscase": iscase,"noword":noword,"backup_path":backup_path,"time":inser_time}
|
||
|
|
return public.M('panel_search_log').insert(data)
|
||
|
|
|
||
|
|
'''目录下所有的文件'''
|
||
|
|
def get_dir(self, path,exts,text,mode=0,isword=0,iscase=0,noword=0,is_backup=0,rtext=False):
|
||
|
|
if rtext or noword:
|
||
|
|
result=[]
|
||
|
|
else:
|
||
|
|
result={}
|
||
|
|
if is_backup:
|
||
|
|
t = time.strftime('%Y%m%d%H%M%S')
|
||
|
|
back_zip = os.path.join(self.__backup_path, "%s.zip" % t)
|
||
|
|
zfile = zipfile.ZipFile(back_zip, "w", compression=zipfile.ZIP_DEFLATED)
|
||
|
|
else:
|
||
|
|
zfile=False
|
||
|
|
back_zip=False
|
||
|
|
return_data = []
|
||
|
|
[[return_data.append(os.path.join(root, file)) for file in files] for root, dirs, files in os.walk(path)]
|
||
|
|
for i in return_data:
|
||
|
|
for i2 in exts:
|
||
|
|
i3 = i.split('.')
|
||
|
|
if i3[-1] == i2:
|
||
|
|
|
||
|
|
temp = self.get_files_lin(i, text, mode, isword, iscase, noword,is_backup,rtext,zfile)
|
||
|
|
if temp:
|
||
|
|
if rtext or noword:
|
||
|
|
if isinstance(result,list):
|
||
|
|
result.append(temp)
|
||
|
|
else:
|
||
|
|
result[i] = temp
|
||
|
|
if is_backup:
|
||
|
|
if zfile:
|
||
|
|
zfile.close()
|
||
|
|
self.insert_settings(rtext, exts, path, mode, isword, iscase, noword, back_zip)
|
||
|
|
return True
|
||
|
|
return result
|
||
|
|
|
||
|
|
'''获取单目录'''
|
||
|
|
def get_dir_files(self,path,exts,text,mode=0,isword=0,iscase=0,noword=0,is_backup=0,rtext=False):
|
||
|
|
is_list = rtext or noword
|
||
|
|
if is_list:
|
||
|
|
result=[]
|
||
|
|
else:
|
||
|
|
result={}
|
||
|
|
if is_backup:
|
||
|
|
t = time.strftime('%Y%m%d%H%M%S')
|
||
|
|
back_zip = os.path.join(self.__backup_path, "%s.zip" % t)
|
||
|
|
zfile = zipfile.ZipFile(back_zip, "w", compression=zipfile.ZIP_DEFLATED)
|
||
|
|
else:
|
||
|
|
zfile=False
|
||
|
|
back_zip=False
|
||
|
|
list_data=[]
|
||
|
|
for root, dirs, files in os.walk(path):
|
||
|
|
list_data=files
|
||
|
|
break
|
||
|
|
for i in exts:
|
||
|
|
for i2 in list_data:
|
||
|
|
i3=i2.split('.')
|
||
|
|
if i3[-1]==i:
|
||
|
|
temp=self.get_files_lin(path+'/'+i2, text,mode,isword,iscase,noword,is_backup,rtext,zfile)
|
||
|
|
if temp:
|
||
|
|
if isinstance(result,list):
|
||
|
|
result.append(path+'/'+i2)
|
||
|
|
else:
|
||
|
|
result[path+'/'+i2]=temp
|
||
|
|
if is_backup:
|
||
|
|
if zfile:
|
||
|
|
zfile.close()
|
||
|
|
self.insert_settings(rtext, exts, path, mode, isword, iscase, noword, back_zip)
|
||
|
|
return result
|
||
|
|
'''
|
||
|
|
获取目录下所有的后缀文件
|
||
|
|
'''
|
||
|
|
def get_exts_files(self,path,exts,text,mode=0,isword=0,iscase=0,noword=0,is_subdir=0,is_backup=0,rtext=False):
|
||
|
|
if len(exts)==0:return []
|
||
|
|
if is_subdir==0:
|
||
|
|
return self.get_dir_files(path,exts,text,mode,isword,iscase,noword,is_backup,rtext)
|
||
|
|
elif is_subdir==1:
|
||
|
|
return self.get_dir(path,exts,text,mode,isword,iscase,noword,is_backup,rtext)
|
||
|
|
|
||
|
|
'''
|
||
|
|
获取文件内的关键词
|
||
|
|
'''
|
||
|
|
def get_files_lin(self, files, text,mode=0,isword=0,iscase=0,noword=0,is_backup=0,rtext=False,back_zip=False):
|
||
|
|
if not os.path.exists(files):return False
|
||
|
|
if os.path.getsize(files) > 1024 * 1024 * 20: return False
|
||
|
|
#文件替换部分
|
||
|
|
if rtext:
|
||
|
|
resutl=[]
|
||
|
|
try:
|
||
|
|
fp = open(files, 'r', encoding='UTF-8')
|
||
|
|
except:
|
||
|
|
fp = open(files, 'r')
|
||
|
|
content = fp.read()
|
||
|
|
fp.close()
|
||
|
|
if mode==2:
|
||
|
|
if iscase:
|
||
|
|
if not re.search(text, content, flags=re.I): return False
|
||
|
|
content = re.sub(text, rtext, content, flags=re.I)
|
||
|
|
else:
|
||
|
|
if not re.search(text, content): return False
|
||
|
|
content = re.sub(text, rtext, content)
|
||
|
|
else:
|
||
|
|
if content.find(text) == -1: return False
|
||
|
|
content = content.replace(text, rtext)
|
||
|
|
if is_backup and back_zip:
|
||
|
|
bf = files.strip('/')
|
||
|
|
back_zip.write(files, bf)
|
||
|
|
with open(files, 'w') as f:
|
||
|
|
f.write(content)
|
||
|
|
f.close()
|
||
|
|
return files
|
||
|
|
else:
|
||
|
|
#查找部分
|
||
|
|
if noword:
|
||
|
|
resutl = []
|
||
|
|
else:
|
||
|
|
resutl={}
|
||
|
|
try:
|
||
|
|
fp = open(files, 'r', encoding='UTF-8')
|
||
|
|
except:
|
||
|
|
fp = open(files, 'r')
|
||
|
|
i = 0
|
||
|
|
try:
|
||
|
|
for line in fp:
|
||
|
|
i += 1
|
||
|
|
if mode==1:
|
||
|
|
if iscase and not re.search(text, line, flags=re.I):
|
||
|
|
continue
|
||
|
|
elif not iscase and not re.search(text, line):
|
||
|
|
continue
|
||
|
|
else:
|
||
|
|
if line.find(text) == -1: continue
|
||
|
|
if noword:
|
||
|
|
return files
|
||
|
|
resutl[i]=line
|
||
|
|
except:
|
||
|
|
pass
|
||
|
|
if resutl:
|
||
|
|
return resutl
|
||
|
|
return False
|
||
|
|
'''
|
||
|
|
text 搜索内容
|
||
|
|
exts 后缀名 参数例子 php,html
|
||
|
|
path 目录
|
||
|
|
is_subdir 0 不包含子目录 1 包含子目录
|
||
|
|
mode 0 为普通模式 1 为正则模式
|
||
|
|
isword 1 全词匹配 0 默认
|
||
|
|
iscase 1 不区分大小写 0 默认
|
||
|
|
noword 1 不输出行信息 0 默认
|
||
|
|
'''
|
||
|
|
def get_search(self, args):
|
||
|
|
if 'text' not in args or not args.text: return {'error': 'Search information cannot be empty'}
|
||
|
|
if 'exts' not in args or not args.exts: return {'error': 'The suffix cannot be empty; please enter [*.*] for all files'}
|
||
|
|
if 'path' not in args or not args.path or args.path == '/': return {'error': 'Directory cannot be empty or cannot be /'}
|
||
|
|
if not os.path.isdir(args.path): return {'error': 'Directory does not exist'}
|
||
|
|
text=args.text
|
||
|
|
exts=args.exts
|
||
|
|
path=args.path
|
||
|
|
mode = int(args.mode) if 'mode' in args else 0
|
||
|
|
is_subdir = int(args.is_subdir) if 'is_subdir' in args else 0
|
||
|
|
iscase = int(args.iscase) if 'iscase' in args else 0
|
||
|
|
isword = int(args.isword) if 'isword' in args else 0
|
||
|
|
noword = int(args.noword) if 'noword' in args else 0
|
||
|
|
exts=exts.split(',')
|
||
|
|
is_tmpe_files=self.get_exts_files(path,exts,text,mode,isword,iscase,noword,is_subdir)
|
||
|
|
return is_tmpe_files
|
||
|
|
|
||
|
|
'''
|
||
|
|
text 搜索内容
|
||
|
|
rtext 替换成的内容
|
||
|
|
exts 后缀名 参数例子 php,html
|
||
|
|
path 目录
|
||
|
|
is_subdir 0 不包含子目录 1 包含子目录
|
||
|
|
mode 0 为普通模式 1 为正则模式
|
||
|
|
isword 1 全词匹配 0 默认
|
||
|
|
iscase 1 不区分大小写 0 默认
|
||
|
|
noword 1 不输出行信息 0 默认
|
||
|
|
'''
|
||
|
|
def get_replace(self, args):
|
||
|
|
if 'text' not in args or not args.text: return {'error': 'Search information cannot be empty'}
|
||
|
|
if 'rtext' not in args or not args.text: return {'error': 'The content to be replaced cannot be empty'}
|
||
|
|
if 'exts' not in args or not args.exts: return {'error': 'The suffix cannot be empty; please enter [*.*] for all files'}
|
||
|
|
if 'path' not in args or not args.path or args.path == '/': return {'error': 'Directory cannot be empty or cannot be /'}
|
||
|
|
if not os.path.isdir(args.path): return {'error': 'Directory does not exist'}
|
||
|
|
is_backup = int(args.isbackup) if 'isbackup' in args else 0
|
||
|
|
text = args.text
|
||
|
|
rtext = args.rtext
|
||
|
|
exts = args.exts
|
||
|
|
path = args.path
|
||
|
|
mode = int(args.mode) if 'mode' in args else 0
|
||
|
|
is_subdir = int(args.is_subdir) if 'is_subdir' in args else 0
|
||
|
|
iscase = int(args.iscase) if 'iscase' in args else 0
|
||
|
|
isword = int(args.isword) if 'isword' in args else 0
|
||
|
|
noword = int(args.noword) if 'noword' in args else 0
|
||
|
|
exts = exts.split(',')
|
||
|
|
is_tmpe_files = self.get_exts_files(path, exts, text, mode, isword, iscase, noword, is_subdir,is_backup,rtext)
|
||
|
|
return is_tmpe_files
|
||
|
|
|
||
|
|
#替換日志
|
||
|
|
def get_replace_logs(self,get):
|
||
|
|
import page
|
||
|
|
page = page.Page()
|
||
|
|
count = public.M('panel_search_log').order('id desc').count()
|
||
|
|
limit = 12
|
||
|
|
info = {}
|
||
|
|
info['count'] = count
|
||
|
|
info['row'] = limit
|
||
|
|
info['p'] = 1
|
||
|
|
if hasattr(get, 'p'):
|
||
|
|
info['p'] = int(get['p'])
|
||
|
|
info['uri'] = get
|
||
|
|
info['return_js'] = ''
|
||
|
|
if hasattr(get, 'tojs'):
|
||
|
|
info['return_js'] = get.tojs
|
||
|
|
data = {}
|
||
|
|
data['page'] = page.GetPage(info, '1,2,3,4,5,8')
|
||
|
|
data['data'] = public.M('panel_search_log').field('id,rtext,exts,path,mode,isword,iscase,noword,backup_path,time').order('id desc').limit(str(page.SHIFT) + ',' + str(page.ROW)).select()
|
||
|
|
if isinstance(data['data'],str): return public.returnMsg(False,[])
|
||
|
|
for i in data['data']:
|
||
|
|
if not isinstance(i,dict): continue
|
||
|
|
if 'backup_path' in i :
|
||
|
|
path=i['backup_path']
|
||
|
|
if os.path.exists(path):
|
||
|
|
i['is_path_status']=True
|
||
|
|
else:
|
||
|
|
i['is_path_status'] = False
|
||
|
|
return public.returnMsg(True, data)
|