This commit is contained in:
jose
2019-07-18 14:54:41 +08:00
parent df1ca5bbae
commit 27c43d08fc
17 changed files with 210 additions and 101 deletions
+6 -44
View File
@@ -80,7 +80,7 @@ cache.set('p_token','bmac_' + public.Md5(public.get_mac_address()))
admin_path_file = 'data/admin_path.pl'
admin_path = '/'
if os.path.exists(admin_path_file): admin_path = public.readFile(admin_path_file).strip()
admin_path_checks = ['/','/close','/task','/login','/config','/site','/sites','ftp','/public','/database','/data','/download_file','/control','/crontab','/firewall','/files','config','/soft','/ajax','/system','/panel_data','/code','/ssl','/plugin','/wxapp','/hook','/safe','/yield','/downloadApi','/pluginApi','/auth','/download','/cloud','/webssh','/connect_event','/panel']
admin_path_checks = ['/','/san','/monitor','/abnormal','/close','/task','/login','/config','/site','/sites','ftp','/public','/database','/data','/download_file','/control','/crontab','/firewall','/files','config','/soft','/ajax','/system','/panel_data','/code','/ssl','/plugin','/wxapp','/hook','/safe','/yield','/downloadApi','/pluginApi','/auth','/download','/cloud','/webssh','/connect_event','/panel']
if admin_path in admin_path_checks: admin_path = '/bt'
@app.route('/service_status',methods = method_get)
@@ -115,6 +115,7 @@ def home():
data['ftpCount'] = public.M('ftps').count()
data['databaseCount'] = public.M('databases').count()
data['lan'] = public.GetLan('index')
data['724'] = public.format_date("%m%d") == '0724'
return render_template( 'index.html',data = data)
@app.route('/close',methods=method_get)
@@ -321,7 +322,7 @@ def panel_monitor(pdata=None):
if comReturn: return comReturn
import monitor
dataObject = monitor.Monitor()
defs = ('get_access_ip', 'get_exception', 'get_exception_logs', 'get_attack_nums', 'php_count', 'return_php', 'mysql_client_count')
defs = ('get_spider', 'get_exception', 'get_request_count_qps', 'load_and_up_flow', 'get_request_count_by_hour')
return publicObject(dataObject, defs, None, pdata)
@@ -331,7 +332,7 @@ def san_baseline(pdata=None):
if comReturn: return comReturn
import san_baseline
dataObject = san_baseline.san_baseline()
defs = ('start', 'get_api_log', 'get_resut', 'get_ssh_errorlogin')
defs = ('start', 'get_api_log', 'get_resut', 'get_ssh_errorlogin','repair','repair_all')
return publicObject(dataObject, defs, None, pdata)
@@ -341,7 +342,7 @@ def abnormal(pdata=None):
if comReturn: return comReturn
import abnormal
dataObject = abnormal.abnormal()
defs = ( 'mysql_server', 'mysql_cpu', 'mysql_count', 'php_server', 'php_conn_max', 'php_cpu', 'CPU', 'Memory', 'disk', 'not_root_user','start')
defs = ('mysql_server', 'mysql_cpu', 'mysql_count', 'php_server', 'php_conn_max', 'php_cpu', 'CPU', 'Memory', 'disk', 'not_root_user', 'start')
return publicObject(dataObject, defs, None, pdata)
@app.route('/files',methods=method_all)
@@ -513,7 +514,7 @@ def plugin(pdata = None):
def panel_public():
get = get_input();
get.client_ip = public.GetClientIp();
if not public.path_safe_check("%s/%s" % (get.name,get.fun)): return abort(404)
if get.fun in ['scan_login','login_qrcode','set_login','is_scan_ok','blind']:
#检查是否验证过安全入口
if get.fun in ['login_qrcode','is_scan_ok']:
@@ -529,7 +530,6 @@ def panel_public():
import panelPlugin
plu = panelPlugin.panelPlugin()
get.s = '_check';
checks = plu.a(get)
if type(checks) != bool or not checks: return public.getJson(checks),json_header
get.s = get.fun
@@ -756,44 +756,6 @@ def check_token(data):
if result['token'] != token: return False;
return result;
@app.route('/yield',methods=method_all)
def panel_yield():
get = get_input()
import panelPlugin
plu = panelPlugin.panelPlugin()
get.s = '_check';
get.client_ip = public.GetClientIp()
checks = plu.a(get)
if type(checks) != bool or not checks: return
get.s = get.fun
filename = plu.a(get);
mimetype = 'application/octet-stream'
return send_file(filename,mimetype=mimetype, as_attachment=True,attachment_filename=os.path.basename(filename))
@app.route('/downloadApi',methods=method_all)
def panel_downloadApi():
get = get_input()
if not public.checkToken(get): get.filename = str(time.time());
filename = 'plugin/psync/backup/' + get.filename.encode('utf-8');
mimetype = 'application/octet-stream'
return send_file(filename,mimetype=mimetype, as_attachment=True,attachment_filename=os.path.basename(filename))
@app.route('/pluginApi',methods=method_all)
def panel_pluginApi():
get = get_input()
if not public.checkToken(get): return public.returnJson(False,'INIT_TOKEN_ERR');
infoFile = 'plugin/' + get.name + '/info.json';
if not os.path.exists(infoFile): return False;
import json
info = json.loads(public.readFile(infoFile));
if not info['api']: return public.returnJson(False,'INIT_PLU_ACC_ERR');
import panelPlugin
pluginObject = panelPlugin.panelPlugin()
defs = ('install','unInstall','getPluginList','getPluginInfo','getPluginStatus','setPluginStatus','a','getCloudPlugin','getConfigHtml','savePluginSort')
return publicObject(pluginObject,defs);
@app.route('/auth',methods=method_all)
def auth(pdata = None):
+1 -1
View File
@@ -468,7 +468,7 @@ function GetPanelApi() {
<div class="line">\
<span class="tname">'+lan.config.int_sk+'</span>\
<div class="info-r">\
<input disabled="disabled" name="panel_token_value" class="bt-input-text mr5 disable" type="text" style="width: 310px" value="'+rdata.token+'" disable>\
<input readonly="readonly" name="panel_token_value" class="bt-input-text mr5 disable" type="text" style="width: 310px" value="'+rdata.token+'" disable>\
<button class="btn btn-xs btn-success btn-sm" style="margin-left: -50px;" onclick="SetPanelApi(1)">'+lan.config.reset+'</button>\
</div>\
</div>\
+1 -2
View File
@@ -1,4 +1,3 @@
$(document).ready(function() {
$(".sub-menu a.sub-menu-a").click(function() {
$(this).next(".sub").slideToggle("slow").siblings(".sub:visible").slideUp("slow");
@@ -1632,7 +1631,7 @@ function ssh_login_def() {
pdata_socket['data'] = {};
pdata_socket['data']['ssh_user'] = $("input[name='ssh_user']").val();
pdata_socket['data']['ssh_passwd'] = $("input[name='ssh_passwd']").val();
if (!pdata_socket.ssh_user || !pdata_socket.ssh_passwd) {
if (!pdata_socket.data.ssh_user || !pdata_socket.data.ssh_passwd) {
layer.msg('The SSH username and password cannot be empty!');
return;
}
+2 -1
View File
@@ -4653,7 +4653,8 @@ bt.site = {
set_cert_ssl:function(certName,siteName,callback){
var loadT = bt.load(lan.public_backup.deploy_cert);
bt.send('SetCertToSite','ssl/SetCertToSite',{certName:certName,siteName:siteName},function(rdata){
loadT.close();
loadT.close();
site.reload();
if(callback) callback(rdata);
bt.msg(rdata);
})
+17 -9
View File
@@ -66,7 +66,7 @@ var site = {
var opt = '';
var _check = ' onclick="site.site_waf(\'' + item.name + '\')"';
//if (bt.os == 'Linux') opt += '<a href="javascript:;" ' + _check + ' class="btlink ">'+lan.site.firewalld+'</a> | ';
if (bt.os == 'Linux') opt += '<a href="javascript:;" ' + _check + ' class="btlink ">'+lan.site.firewalld+'</a> | ';
opt += '<a href="javascript:;" class="btlink" onclick="site.web_edit(this)">'+lan.site.set+' </a> | ';
opt += '<a href="javascript:;" class="btlink" onclick="site.del_site(' + item.id + ',\'' + item.name + '\')" title="'+lan.site.del_site+'">'+lan.site.del+'</a>';
return opt;
@@ -1490,15 +1490,23 @@ var site = {
})
if (ret.dns_names.length == 0) ret.dns_names.append('_acme-challenge.bt.cn')
$('.div_txt_jx').append(bt.render_help([lan.site.dns_resolve_tips4, lan.site.dns_resolve_tips2 + ret.dns_names[0].acme_name, lan.site.dns_resolve_tips3]));
$('.btn_check_txt').click(function () {
ddata['renew'] = 'True'
site.create_let(ddata, function (ldata) {
if (ldata.status) {
b_load.close();
site.reload()
}
});
})
var new_data = {
siteName: web.name,
domains: ddata.domains,
updateOf: 1,
email: ldata.email,
renew: 'True',
dnsapi:'dns'
}
site.create_let(new_data, function (ldata) {
if (ldata.status) {
b_load.close();
site.ssl.reload(1);
}
});
})
}, 100)
}
else {
+1 -1
View File
@@ -27,7 +27,7 @@ class panelSetup:
if ua:
ua = ua.lower();
if ua.find('spider') != -1 or ua.find('bot') != -1: return redirect('https://www.baidu.com');
g.version = '6.1.3'
g.version = '6.1.4'
g.title = public.GetConfigValue('title')
g.uri = request.path
session['version'] = g.version;
+4 -1
View File
@@ -421,6 +421,9 @@ class config:
os.system('rm -f ' + sslConf);
return public.returnMsg(True,'PANEL_SSL_CLOSE');
else:
os.system('pip install cffi');
os.system('pip install cryptography');
os.system('pip install pyOpenSSL');
try:
if not self.CreateSSL(): return public.returnMsg(False,'PANEL_SSL_ERR');
public.writeFile(sslConf,'True')
@@ -435,7 +438,7 @@ class config:
key.generate_key(OpenSSL.crypto.TYPE_RSA, 2048)
cert = OpenSSL.crypto.X509()
cert.set_serial_number(0)
cert.get_subject().CN = '120.27.27.98';
cert.get_subject().CN = public.GetLocalIp()
cert.set_issuer(cert.get_subject())
cert.gmtime_adj_notBefore( 0 )
cert.gmtime_adj_notAfter(86400 * 3650)
+7 -13
View File
@@ -259,26 +259,20 @@ class crontab:
def GetDataList(self,get):
data = {}
data['data'] = public.M(get['type']).field('name,ps').select()
data['orderOpt'] = []
data['orderOpt'] = [];
import json
tmp = public.readFile('data/libList.conf')
tmp = public.readFile('data/libList.conf');
libs = json.loads(tmp)
import imp
import imp;
for lib in libs:
try:
imp.find_module(lib['module'])
imp.find_module(lib['module']);
tmp = {}
tmp['name'] = lib['name']
tmp['name'] = lib['name'];
tmp['value']= lib['opt']
data['orderOpt'].append(tmp)
data['orderOpt'].append(tmp);
except:
import sys
if lib['module'] == "google.cloud" and "google.cloud" in sys.modules.keys():
tmp1 = {}
tmp1['name'] = lib['name']
tmp1['value'] = lib['opt']
data['orderOpt'].append(tmp1)
continue
continue;
return data
#取任务日志
+2 -1
View File
@@ -391,7 +391,7 @@ SetLink
fileName = name + '_' + time.strftime('%Y%m%d_%H%M%S',time.localtime()) + '.sql.gz'
backupName = session['config']['backup_path'] + '/database/' + fileName
public.ExecShell("/www/server/mysql/bin/mysqldump --force --opt \"" + name + "\" | gzip > " + backupName)
public.ExecShell("/www/server/mysql/bin/mysqldump --default-character-set="+ public.get_database_character(name) +" --force --opt \"" + name + "\" | gzip > " + backupName)
if not os.path.exists(backupName): return public.returnMsg(False,'BACKUP_ERROR');
self.mypass(False, root);
@@ -769,6 +769,7 @@ SetLink
if not os.path.exists(path): return public.returnMsg(False,'AJAX_LOG_FILR_NOT_EXISTS');
return public.returnMsg(True,public.GetNumLines(path,1000));
# 获取当前数据库信息
def GetInfo(self,get):
info=self.GetdataInfo(get)
+55 -3
View File
@@ -6,7 +6,7 @@
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# +-------------------------------------------------------------------
import system,psutil,time,public,db,os,sys,json,py_compile
import system,psutil,time,public,db,os,sys,json,py_compile,re
os.chdir('/www/server/panel')
sm = system.system();
taskConfig = json.loads(public.ReadFile('config/task.json'))
@@ -61,9 +61,61 @@ def control_init():
public.ExecShell("chmod -R 600 /www/server/cron/*.log")
public.ExecShell("chown -R root:root /www/server/panel/data")
public.ExecShell("chown -R root:root /www/server/panel/config")
#disable_putenv('putenv')
clean_session()
set_crond()
#默认禁用指定PHP函数
def disable_putenv(fun_name):
try:
is_set_disable = '/www/server/panel/data/disable_%s' % fun_name
if os.path.exists(is_set_disable): return True
php_vs = ('52','53','54','55','56','70','71','72','73','74')
php_ini = "/www/server/php/{0}/etc/php.ini"
rep = "disable_functions\s*=\s*.*"
for pv in php_vs:
php_ini_path = php_ini.format(pv)
if not os.path.exists(php_ini_path): continue
php_ini_body = public.readFile(php_ini_path)
tmp = re.search(rep,php_ini_body)
if not tmp: continue
disable_functions = tmp.group()
if disable_functions.find(fun_name) != -1: continue
print(disable_functions)
php_ini_body = php_ini_body.replace(disable_functions,disable_functions+',%s' % fun_name)
php_ini_body.find(fun_name)
public.writeFile(php_ini_path,php_ini_body)
public.phpReload(pv)
public.writeFile(is_set_disable,'True')
return True
except: return False
#创建计划任务
def set_crond():
try:
echo = public.md5(public.md5('renew_lets_ssl_bt'))
cron_id = public.M('crontab').where('echo=?',(echo,)).getField('id')
import crontab
args_obj = public.dict_obj()
if not cron_id:
cronPath = public.GetConfigValue('setup_path') + '/cron/' + echo
shell = 'python /www/server/panel/class/panelLets.py renew_lets_ssl'
public.writeFile(cronPath,shell)
args_obj.id = public.M('crontab').add('name,type,where1,where_hour,where_minute,echo,addtime,status,save,backupTo,sType,sName,sBody,urladdress',("续签Let's Encrypt证书",'day','','0','10',echo,time.strftime('%Y-%m-%d %X',time.localtime()),0,'','localhost','toShell','',shell,''))
crontab.crontab().set_cron_status(args_obj)
else:
cron_path = public.get_cron_path()
if os.path.exists(cron_path):
cron_s = public.readFile(cron_path)
if cron_s.find(echo) == -1:
public.M('crontab').where('echo=?',(echo,)).setField('status',0)
args_obj.id = cron_id
crontab.crontab().set_cron_status(args_obj)
except:
print(public.get_error_info())
#清理多余的session文件
def clean_session():
+37 -18
View File
@@ -15,7 +15,8 @@ from OpenSSL import crypto
try:
requests.packages.urllib3.disable_warnings()
except:pass
import BTPanel
if __name__ != '__main__':
import BTPanel
try:
import dns.resolver
except:
@@ -93,6 +94,9 @@ class panelLets:
return '<h2>The signing failed, and the number of attempts to apply for a certificate today has reached the limit!</h2>'
elif "DNS problem: NXDOMAIN looking up A for" in error or "No valid IP addresses found for" in error or "Invalid response from" in error:
return '<h2>The signing failed, the domain name resolution error, or the resolution is not valid, or the domain name is not filed!</h2>'
elif error.find('TLS Web Server Authentication') != -1:
public.restart_panel()
return "Failed to connect to the CA server, please try again later."
else:
return error;
@@ -100,6 +104,7 @@ class panelLets:
def get_dns_class(self,data):
if data['dnsapi'] == 'dns_ali':
import panelDnsapi
public.mod_reload(panelDnsapi)
dns_class = panelDnsapi.AliyunDns(key = data['dns_param'][0], secret = data['dns_param'][1])
return dns_class
elif data['dnsapi'] == 'dns_dp':
@@ -107,12 +112,14 @@ class panelLets:
return dns_class
elif data['dnsapi'] == 'dns_cx':
import panelDnsapi
public.mod_reload(panelDnsapi)
dns_class = panelDnsapi.CloudxnsDns(key = data['dns_param'][0] ,secret =data['dns_param'][1])
result = dns_class.get_domain_list()
if result['code'] == 1:
return dns_class
elif data['dnsapi'] == 'dns_bt':
import panelDnsapi
public.mod_reload(panelDnsapi)
dns_class = panelDnsapi.Dns_com()
return dns_class
return False
@@ -202,12 +209,10 @@ class panelLets:
#手动解析提前返回
result = self.crate_let_by_oper(data)
if 'status' in result and not result['status']: return result
result['status'] = True
public.writeFile(domain_path, json.dumps(result))
result['msg'] = 'Get successful, please manually resolve the domain name'
result['code'] = 2;
return result
elif get.dnsapi == 'dns_bt':
data['dnsapi'] = get.dnsapi
@@ -244,19 +249,32 @@ class panelLets:
public.writeFile(path + "/README","let")
#计划任务续签
echo = public.md5(public.md5('renew_lets_ssl_bt'))
crontab = public.M('crontab').where('echo=?',(echo,)).find()
if not crontab:
cronPath = public.GetConfigValue('setup_path') + '/cron/' + echo
shell = 'python %s/panel/class/panelLets.py renew_lets_ssl ' % (self.setupPath)
public.writeFile(cronPath,shell)
public.M('crontab').add('name,type,where1,where_hour,where_minute,echo,addtime,status,save,backupTo,sType,sName,sBody,urladdress',("Renew the Letter's Encrypt certificate",'day','','0','10',echo,time.strftime('%Y-%m-%d %X',time.localtime()),1,'','localhost','toShell','',shell,''))
self.set_crond()
return public.returnMsg(True, 'Successful application.')
#创建计划任务
def set_crond(self):
try:
echo = public.md5(public.md5('renew_lets_ssl_bt'))
cron_id = public.M('crontab').where('echo=?',(echo,)).getField('id')
import crontab
args_obj = public.dict_obj()
if not cron_id:
cronPath = public.GetConfigValue('setup_path') + '/cron/' + echo
shell = 'python %s/panel/class/panelLets.py renew_lets_ssl ' % (self.setupPath)
public.writeFile(cronPath,shell)
args_obj.id = public.M('crontab').add('name,type,where1,where_hour,where_minute,echo,addtime,status,save,backupTo,sType,sName,sBody,urladdress',("续签Let's Encrypt证书",'day','','0','10',echo,time.strftime('%Y-%m-%d %X',time.localtime()),0,'','localhost','toShell','',shell,''))
crontab.crontab().set_cron_status(args_obj)
else:
cron_path = public.get_cron_path()
if os.path.exists(cron_path):
cron_s = public.readFile(cron_path)
if cron_s.find(echo) == -1:
public.M('crontab').where('echo=?',(echo,)).setField('status',0)
args_obj.id = cron_id
crontab.crontab().set_cron_status(args_obj)
except:pass
#手动解析
def crate_let_by_oper(self,data):
@@ -285,7 +303,7 @@ class panelLets:
acme_keyauthorization, domain_dns_value = BTPanel.dns_client.get_keyauthorization(dns_token)
acme_name = self.get_acme_name(dns_name)
dns_names_to_delete.append({"dns_name": dns_name,"acme_name":acme_name, "domain_dns_value": domain_dns_value})
dns_names_to_delete.append({"dns_name": public.de_punycode(dns_name),"acme_name":acme_name, "domain_dns_value": domain_dns_value})
responders.append(
{
"authorization_url": authorization_url,
@@ -359,9 +377,9 @@ class panelLets:
dns_challenge_url = identifier_auth["dns_challenge_url"]
acme_keyauthorization, domain_dns_value = client.get_keyauthorization(dns_token)
dns_class.create_dns_record(dns_name, domain_dns_value)
dns_class.create_dns_record(public.de_punycode(dns_name), domain_dns_value)
self.check_dns(self.get_acme_name(dns_name),domain_dns_value)
dns_names_to_delete.append({"dns_name": dns_name, "domain_dns_value": domain_dns_value})
dns_names_to_delete.append({"dns_name": public.de_punycode(dns_name), "domain_dns_value": domain_dns_value})
responders.append({"authorization_url": authorization_url, "acme_keyauthorization": acme_keyauthorization,"dns_challenge_url": dns_challenge_url} )
n = 0
while n<2:
@@ -433,6 +451,7 @@ class panelLets:
wellknown_path = acme_dir + '/' + http_token
public.writeFile(wellknown_path,acme_keyauthorization)
wellknown_url = "http://{0}/.well-known/acme-challenge/{1}".format(http_name, http_token)
result['clecks'].append({'wellknown_url':wellknown_url,'http_token':http_token});
is_check = False
n = 0
@@ -446,6 +465,7 @@ class panelLets:
except :
pass
n += 1
time.sleep(1)
if is_check:
sucess_domains.append(http_name)
responders.append({"authorization_url": authorization_url, "acme_keyauthorization": acme_keyauthorization,"http_challenge_url": http_challenge_url})
@@ -517,9 +537,8 @@ class panelLets:
for j in ns.response.answer:
for i in j.items:
txt_value = i.to_text().replace('"','').strip()
print(txt_value)
if txt_value == value:
print("Successful verification",txt_value)
print("Successful verification%s" % txt_value)
return True
except:
try:
+4 -1
View File
@@ -88,7 +88,10 @@ class panelMysql:
self.__DB_CUR.execute(sql)
result = self.__DB_CUR.fetchall()
#将元组转换成列表
data = map(list,result)
if sys.version_info[0] == 2:
data = map(list,result)
else:
data = list(map(list,result))
self.__Close()
return data
except Exception as ex:
+1
View File
@@ -1552,6 +1552,7 @@ class panelPlugin:
def a(self,get):
if not hasattr(get,'name'): return public.returnMsg(False,'PLUGIN_INPUT_A');
try:
if not public.path_safe_check("%s/%s" % (get.name,get.s)): return public.returnMsg(False,'PLUGIN_INPUT_C');
path = self.__install_path + '/' + get.name
if not os.path.exists(path + '/'+get.name+'_main.py'): return public.returnMsg(False,'PLUGIN_INPUT_B');
if not self.check_accept(get):return public.returnMsg(False,public.to_string([24744, 26410, 36141, 20080, 91, 37, 115, 93, 25110, 25480, 26435, 24050, 21040, 26399, 33]) % (self.get_title_byname(get),))
+1
View File
@@ -884,6 +884,7 @@ class panelSite(panelRedirect):
self.check_ssl_pack()
import panelLets
public.mod_reload(panelLets)
lets = panelLets.panelLets()
result = lets.apple_lest_cert(get)
if result['status'] and not 'code' in result:
+6 -1
View File
@@ -199,12 +199,17 @@ class bt_task:
#清理任务日志
def clean_log(self):
import shutil
s_time = int(time.time())
timeout = 86400
for f in os.listdir(self.__task_path):
filename = self.__task_path + f
c_time = os.stat(filename).st_ctime
if s_time - c_time > timeout: os.remove(filename)
if s_time - c_time > timeout:
if os.path.isdir(filename):
shutil.rmtree(filename)
else:
os.remove(filename)
return True
#文件压缩
+13 -5
View File
@@ -70,11 +70,12 @@ class plugin_deployment:
def get_icon(self,pinfo):
path = '/www/server/panel/BTPanel/static/img/dep_ico'
if not os.path.exists(path): os.makedirs(path,384)
filename = path + '/' + pinfo['name'] + '.png'
filename = "%s/%s.png" % (path, pinfo['name'])
m_uri = pinfo['min_image']
pinfo['min_image'] = '/static/img/dep_ico/' + pinfo['name'] + '.png'
pinfo['min_image'] = '/static/img/dep_ico/%s.png' % pinfo['name']
if sys.version_info[0] == 2: filename = filename.encode('utf-8')
if os.path.exists(filename):
if os.path.getsize(filename) > 1024: return pinfo
if os.path.getsize(filename) > 100: return pinfo
os.system("wget -O " + filename + ' http://www.bt.cn' + m_uri + " &")
return pinfo
@@ -347,6 +348,13 @@ class plugin_deployment:
dwfile = self.__panelPath + '/vhost/rewrite/' + site_name + '.conf';
public.writeFile(dwfile,rewriteConf);
swfile = path + '/.htaccess';
if os.path.exists(swfile):
swpath = (path + '/'+ pinfo['run_path'] + '/.htaccess').replace('//','/')
if pinfo['run_path'] != '/' and not os.path.exists(swpath):
public.writeFile(swpath, public.readFile(swfile))
#删除伪静态文件
public.ExecShell("rm -f " + path + '/*.rewrite')
@@ -428,9 +436,9 @@ class plugin_deployment:
os.remove(p_info)
i_ndex_html = path + '/index.html'
if os.path.exists(i_ndex_html): os.remove(i_ndex_html)
public.ExecShell("\cp -a -r " + p_tmp + '/* ' + path + '/')
os.system("\cp -arf " + p_tmp + '/. ' + path + '/')
except: pass
public.ExecShell("rm -rf " + self.__tmp + '/*')
os.system("rm -rf " + self.__tmp + '/*')
return p_config
+52
View File
@@ -1274,3 +1274,55 @@ def path_safe_check(path):
if not re.match(rep,path): return False
return True
#取数据库字符集
def get_database_character(db_name):
try:
import panelMysql
tmp = panelMysql.panelMysql().query("show create database `%s`" % db_name.strip())
return str(re.findall("SET\s+(.+)\s",tmp[0][1])[0])
except:
return 'utf8'
def en_punycode(domain):
tmp = domain.split('.');
newdomain = '';
for dkey in tmp:
#匹配非ascii字符
match = re.search(u"[\x80-\xff]+",dkey);
if not match: match = re.search(u"[\u4e00-\u9fa5]+",dkey);
if not match:
newdomain += dkey + '.';
else:
newdomain += 'xn--' + dkey.encode('punycode').decode('utf-8') + '.'
return newdomain[0:-1];
#punycode 转中文
def de_punycode(domain):
tmp = domain.split('.');
newdomain = '';
for dkey in tmp:
if dkey.find('xn--') >=0:
newdomain += dkey.replace('xn--','').encode('utf-8').decode('punycode') + '.'
else:
newdomain += dkey + '.'
return newdomain[0:-1];
#取计划任务文件路径
def get_cron_path():
u_file = '/var/spool/cron/crontabs/root'
if not os.path.exists(u_file):
file='/var/spool/cron/root'
else:
file=u_file
return file
#取通用对象
class dict_obj:
def __contains__(self, key):
return getattr(self,key,None)
def __setitem__(self, key, value): setattr(self,key,value)
def __getitem__(self, key): return getattr(self,key,None)
def __delitem__(self,key): delattr(self,key)
def __delattr__(self, key): delattr(self,key)
def get_items(self): return self