v6.8.8
1. Add user login function. 2. Add the first professional plug-in Nginx WAF. 3. Release a new version of the online editor. 4. Fixed some bugs.
@@ -12,13 +12,13 @@ import os
|
||||
import time
|
||||
import re
|
||||
import uuid
|
||||
import threading
|
||||
import socket
|
||||
os.chdir('/www/server/panel')
|
||||
if not os.name in ['nt']:
|
||||
os.chdir('/www/server/panel')
|
||||
if not 'class/' in sys.path:
|
||||
sys.path.insert(0,'class/')
|
||||
|
||||
from flask import Flask,session,render_template,send_file,request,redirect,g,make_response,render_template_string,abort,Response as Resp
|
||||
from flask import Config, Flask, session, render_template, send_file, request, redirect, g, make_response, \
|
||||
render_template_string, abort, Response as Resp
|
||||
from cachelib import SimpleCache
|
||||
from werkzeug.wrappers import Response
|
||||
from flask_session import Session
|
||||
@@ -27,8 +27,9 @@ from flask_sockets import Sockets
|
||||
|
||||
cache = SimpleCache()
|
||||
import public
|
||||
#初始化Flask应用
|
||||
app = Flask(__name__,template_folder="templates/" + public.GetConfigValue('template'))
|
||||
|
||||
# 初始化Flask应用
|
||||
app = Flask(__name__, template_folder="templates/{}".format(public.GetConfigValue('template')))
|
||||
Compress(app)
|
||||
sockets = Sockets(app)
|
||||
|
||||
@@ -57,12 +58,9 @@ app.config['SESSION_PERMANENT'] = True
|
||||
app.config['SESSION_USE_SIGNER'] = True
|
||||
app.config['SESSION_KEY_PREFIX'] = 'BT_:'
|
||||
app.config['SESSION_COOKIE_NAME'] = "SESSIONID"
|
||||
app.config['PERMANENT_SESSION_LIFETIME'] = 86400
|
||||
app.config['PERMANENT_SESSION_LIFETIME'] = 86400 * 30
|
||||
Session(app)
|
||||
|
||||
|
||||
from datetime import datetime
|
||||
import socket
|
||||
import common
|
||||
|
||||
#初始化路由
|
||||
@@ -130,6 +128,7 @@ if admin_path in admin_path_checks: admin_path = '/bt'
|
||||
#Flask请求勾子
|
||||
@app.before_request
|
||||
def request_check():
|
||||
g.request_time = time.time()
|
||||
#路由和URI长度过滤
|
||||
if len(request.path) > 128: return abort(403)
|
||||
if len(request.url) > 1024: return abort(403)
|
||||
@@ -171,9 +170,14 @@ def request_check():
|
||||
#Flask 请求结束勾子
|
||||
@app.teardown_request
|
||||
def request_end(reques = None):
|
||||
if request.path in ['/service_status']: return
|
||||
not_acts = ['GetTaskSpeed','GetNetWork','check_pay_status','get_re_order_status','get_order_stat']
|
||||
key = request.args.get('action')
|
||||
if not key in not_acts and request.full_path.find('/static/') == -1: public.write_request_log()
|
||||
if not key in not_acts and request.full_path.find('/static/') == -1:
|
||||
public.write_request_log()
|
||||
if 'api_request' in g:
|
||||
if g.api_request:
|
||||
session.clear()
|
||||
|
||||
#Flask 404页面勾子
|
||||
@app.errorhandler(404)
|
||||
@@ -190,31 +194,11 @@ def notfound(e):
|
||||
}
|
||||
return Response(errorStr,status=404,headers=headers)
|
||||
|
||||
#@app.errorhandler(500)
|
||||
# def internalerror(e):
|
||||
# public.submit_error()
|
||||
# errorStr = public.ReadFile('./BTPanel/templates/' + public.GetConfigValue('template') + '/error.html')
|
||||
# try:
|
||||
# if not app.config['DEBUG']:
|
||||
# errorStr = errorStr.format(public.getMsg('PAGE_ERR_500_TITLE'),
|
||||
# public.getMsg('PAGE_ERR_500_H1'),
|
||||
# public.getMsg('PAGE_ERR_500_P1'),
|
||||
# public.getMsg('NAME'),
|
||||
# public.getMsg('PAGE_ERR_HELP'))
|
||||
# else:
|
||||
# errorStr = errorStr.format(public.getMsg('PAGE_ERR_500_TITLE'),
|
||||
# str(e),
|
||||
# '<pre>'+public.get_error_info() + '</pre>',
|
||||
# public.getMsg('INIT_DEBUG_INFO'),public.getMsg('INIT_VERSION_LAST') + public.version())
|
||||
# except IndexError:pass
|
||||
# return errorStr,500
|
||||
|
||||
#===================================Flask HOOK========================#
|
||||
# ===================================Flask HOOK========================#
|
||||
|
||||
|
||||
|
||||
#===================================普通路由区========================#
|
||||
@app.route('/',methods=method_all)
|
||||
# ===================================普通路由区========================#
|
||||
@app.route('/', methods=method_all)
|
||||
def home():
|
||||
#面板首页
|
||||
comReturn = comm.local()
|
||||
@@ -225,6 +209,7 @@ def home():
|
||||
data['ftpCount'] = public.M('ftps').count()
|
||||
data['databaseCount'] = public.M('databases').count()
|
||||
data['lan'] = public.GetLan('index')
|
||||
data['js_random'] = get_js_random()
|
||||
public.auto_backup_panel()
|
||||
return render_template( 'index.html',data = data)
|
||||
|
||||
@@ -297,9 +282,11 @@ def site(pdata = None):
|
||||
comReturn = comm.local()
|
||||
if comReturn: return comReturn
|
||||
if request.method == method_get[0] and not pdata:
|
||||
data = {}
|
||||
import system
|
||||
data = system.system().GetConcifInfo()
|
||||
data['isSetup'] = True
|
||||
data['lan'] = public.getLan('site')
|
||||
data['js_random'] = get_js_random()
|
||||
if os.path.exists(public.GetConfigValue('setup_path')+'/nginx') == False \
|
||||
and os.path.exists(public.GetConfigValue('setup_path')+'/apache') == False \
|
||||
and os.path.exists(public.GetConfigValue('openlitespeed_path')+'/lsws') == False:
|
||||
@@ -308,7 +295,10 @@ def site(pdata = None):
|
||||
import panelSite
|
||||
siteObject = panelSite.panelSite()
|
||||
|
||||
defs = ('get_site_domains','GetRedirectFile','SaveRedirectFile','DeleteRedirect','GetRedirectList','CreateRedirect','ModifyRedirect',
|
||||
defs = ('upload_csv','create_website_multiple','del_redirect_multiple','del_proxy_multiple','delete_dir_auth_multiple',
|
||||
'delete_dir_bind_multiple','delete_domain_multiple','set_site_etime_multiple','set_site_php_version_multiple',
|
||||
'delete_website_multiple','set_site_status_multiple','get_site_err_log','get_site_domains','GetRedirectFile',
|
||||
'SaveRedirectFile','DeleteRedirect','GetRedirectList','CreateRedirect','ModifyRedirect',
|
||||
'set_dir_auth','delete_dir_auth','get_dir_auth','modify_dir_auth_pass',
|
||||
'GetSiteLogs','GetSiteDomains','GetSecurity','SetSecurity','ProxyCache','CloseToHttps','HttpToHttps','SetEdate',
|
||||
'SetRewriteTel','GetCheckSafe','CheckSafe','GetDefaultSite','SetDefaultSite','CloseTomcat','SetTomcat','apacheAddPort',
|
||||
@@ -329,6 +319,7 @@ def ftp(pdata = None):
|
||||
FtpPort()
|
||||
data = {}
|
||||
data['isSetup'] = True
|
||||
data['js_random'] = get_js_random()
|
||||
if os.path.exists(public.GetConfigValue('setup_path') + '/pure-ftpd') == False: data['isSetup'] = False
|
||||
data['lan'] = public.GetLan('ftp')
|
||||
return render_template('ftp.html',data=data)
|
||||
@@ -354,10 +345,11 @@ def database(pdata = None):
|
||||
data['isSetup'] = os.path.exists(public.GetConfigValue('setup_path') + '/mysql/bin')
|
||||
data['mysql_root'] = public.M('config').where('id=?',(1,)).getField('mysql_root')
|
||||
data['lan'] = public.GetLan('database')
|
||||
data['js_random'] = get_js_random()
|
||||
return render_template('database.html',data=data)
|
||||
import database
|
||||
databaseObject = database.database()
|
||||
defs = ('check_mysql_ssl_status','write_ssl_to_mysql','GetdataInfo','GetInfo','ReTable','OpTable','AlTable','GetSlowLogs','GetRunStatus',
|
||||
defs = ('get_mysql_user','check_mysql_ssl_status','write_ssl_to_mysql','GetdataInfo','GetInfo','ReTable','OpTable','AlTable','GetSlowLogs','GetRunStatus',
|
||||
'SetDbConf','GetDbStatus','BinLog','GetErrorLog','GetMySQLInfo','SetDataDir','SetMySQLPort',
|
||||
'AddDatabase','DeleteDatabase','SetupPassword','ResDatabasePassword','ToBackup','DelBackup',
|
||||
'InputSql','SyncToDatabases','SyncGetDatabases','GetDatabaseAccess','SetDatabaseAccess')
|
||||
@@ -375,7 +367,6 @@ def acme(pdata = None):
|
||||
'get_auths','auth_domain','check_auth_status','download_cert','apply_cert','renew_cert','apply_cert_api','apply_dns_auth')
|
||||
return publicObject(acme_v2_object,defs,None,pdata)
|
||||
|
||||
|
||||
@app.route('/message/<action>',methods=method_all)
|
||||
def message(action = None):
|
||||
#提示消息管理
|
||||
@@ -404,6 +395,7 @@ def control(pdata = None):
|
||||
if request.method == method_get[0]:
|
||||
data = {}
|
||||
data['lan'] = public.GetLan('control')
|
||||
data['js_random'] = get_js_random()
|
||||
return render_template( 'control.html',data=data)
|
||||
|
||||
@app.route('/firewall',methods=method_all)
|
||||
@@ -414,6 +406,7 @@ def firewall(pdata = None):
|
||||
if request.method == method_get[0] and not pdata:
|
||||
data = {}
|
||||
data['lan'] = public.GetLan('firewall')
|
||||
data['js_random'] = get_js_random()
|
||||
return render_template( 'firewall.html',data=data)
|
||||
import firewalls
|
||||
firewallObject = firewalls.firewalls()
|
||||
@@ -429,6 +422,7 @@ def ssh_security(pdata = None):
|
||||
if request.method == method_get[0] and not pdata:
|
||||
data = {}
|
||||
data['lan'] = public.GetLan('firewall')
|
||||
data['js_random'] = get_js_random()
|
||||
return render_template( 'firewall.html',data=data)
|
||||
import ssh_security
|
||||
firewallObject = ssh_security.ssh_security()
|
||||
@@ -437,23 +431,6 @@ def ssh_security(pdata = None):
|
||||
return publicObject(firewallObject,defs,None,pdata)
|
||||
|
||||
|
||||
# @app.route('/firewall_new',methods=method_all)
|
||||
# def firewall_new(pdata = None):
|
||||
# comReturn = comm.local()
|
||||
# if comReturn: return comReturn
|
||||
# if request.method == method_get[0] and not pdata:
|
||||
# data = {}
|
||||
# data['lan'] = public.GetLan('firewall')
|
||||
# return render_template( 'firewall_new.html',data=data)
|
||||
# import firewall_new
|
||||
# firewallObject = firewall_new.firewalls()
|
||||
# defs = ('GetList','AddDropAddress','DelDropAddress','FirewallReload','SetFirewallStatus',
|
||||
# 'AddAcceptPort','DelAcceptPort','SetSshStatus','SetPing','SetSshPort','GetSshInfo',
|
||||
# 'AddSpecifiesIp','DelSpecifiesIp'
|
||||
# )
|
||||
# return publicObject(firewallObject,defs,None,pdata)
|
||||
|
||||
|
||||
@app.route('/monitor', methods=method_all)
|
||||
def panel_monitor(pdata=None):
|
||||
#云控统计信息
|
||||
@@ -535,13 +512,14 @@ def files(pdata = None):
|
||||
data = {}
|
||||
data['recycle_bin'] = os.path.exists('data/recycle_bin.pl')
|
||||
data['lan'] = public.GetLan('files')
|
||||
data['js_random'] = get_js_random()
|
||||
return render_template('files.html',data=data)
|
||||
import files
|
||||
filesObject = files.files()
|
||||
defs = ('get_progress','restore_website','fix_permissions','get_all_back','restore_path_permissions','del_path_premissions','get_path_premissions','back_path_permissions',
|
||||
'CheckExistsFiles','GetExecLog','GetSearch','ExecShell','GetExecShellMsg','exec_git','exec_composer','create_download_url',
|
||||
'UploadFile','GetDir','CreateFile','CreateDir','DeleteDir','DeleteFile','get_download_url_list','remove_download_url','modify_download_url',
|
||||
'CopyFile','CopyDir','MvFile','GetFileBody','SaveFileBody','Zip','UnZip','get_download_url_find',
|
||||
'CopyFile','CopyDir','MvFile','GetFileBody','SaveFileBody','Zip','UnZip','get_download_url_find','set_file_ps',
|
||||
'SearchFiles','upload','read_history','re_history','auto_save_temp','get_auto_save_body','get_videos',
|
||||
'GetFileAccess','SetFileAccess','GetDirSize','SetBatchData','BatchPaste','install_rar','get_path_size',
|
||||
'DownloadFile','GetTaskSpeed','CloseLogs','InstallSoft','UninstallSoft','SaveTmpFile','get_composer_version','exec_composer','update_composer',
|
||||
@@ -559,6 +537,7 @@ def crontab(pdata = None):
|
||||
if request.method == method_get[0] and not pdata:
|
||||
data = {}
|
||||
data['lan'] = public.GetLan('crontab')
|
||||
data['js_random'] = get_js_random()
|
||||
return render_template( 'crontab.html',data=data)
|
||||
import crontab
|
||||
crontabObject = crontab.crontab()
|
||||
@@ -575,6 +554,7 @@ def soft(pdata = None):
|
||||
if request.method == method_get[0] and not pdata:
|
||||
data={}
|
||||
data['lan'] = public.GetLan('soft')
|
||||
data['js_random'] = get_js_random()
|
||||
return render_template( 'soft.html',data=data)
|
||||
|
||||
@app.route('/config',methods=method_all)
|
||||
@@ -595,9 +575,6 @@ def config(pdata = None):
|
||||
data['ipv6'] = ''
|
||||
sess_out_path = 'data/session_timeout.pl'
|
||||
if not os.path.exists(sess_out_path): public.writeFile(sess_out_path,'86400')
|
||||
workers_p = 'data/workers.pl'
|
||||
if not os.path.exists(workers_p): public.writeFile(workers_p,'1')
|
||||
data['workers'] = int(public.readFile(workers_p))
|
||||
s_time_tmp = public.readFile(sess_out_path)
|
||||
if not s_time_tmp: s_time_tmp = '0'
|
||||
data['session_timeout'] = int(s_time_tmp)
|
||||
@@ -607,25 +584,32 @@ def config(pdata = None):
|
||||
data['basic_auth']['value'] = public.getMsg('CLOSED')
|
||||
if data['basic_auth']['open']: data['basic_auth']['value'] = public.getMsg('OPENED')
|
||||
data['debug'] = ''
|
||||
data['js_random'] = get_js_random()
|
||||
if app.config['DEBUG']: data['debug'] = 'checked'
|
||||
data['is_local'] = ''
|
||||
if public.is_local(): data['is_local'] = 'checked'
|
||||
return render_template( 'config.html',data=data)
|
||||
import config
|
||||
defs = ('get_ols_private_cache_status','get_ols_value','set_ols_value','get_ols_private_cache','get_ols_static_cache','set_ols_static_cache','switch_ols_private_cache','set_ols_private_cache',
|
||||
'set_coll_open','get_qrcode_data','check_two_step','set_two_step_auth','create_user','remove_user','modify_user',
|
||||
'get_key','get_php_session_path','set_php_session_path','get_cert_source','get_users',
|
||||
'set_local','set_debug','get_panel_error_logs','clean_panel_error_logs',
|
||||
'get_basic_auth_stat','set_basic_auth','get_cli_php_version','get_tmp_token',
|
||||
'set_cli_php_version','DelOldSession', 'GetSessionCount', 'SetSessionConf',
|
||||
'GetSessionConf','get_ipv6_listen','set_ipv6_status','GetApacheValue','SetApacheValue',
|
||||
'GetNginxValue','SetNginxValue','get_token','set_token','set_admin_path','is_pro',
|
||||
'get_php_config','get_config','SavePanelSSL','GetPanelSSL','GetPHPConf','SetPHPConf',
|
||||
'GetPanelList','AddPanelInfo','SetPanelInfo','DelPanelInfo','ClickPanelInfo','SetPanelSSL',
|
||||
'SetTemplates','Set502','setPassword','setUsername','setPanel','setPathInfo','setPHPMaxSize',
|
||||
'getFpmConfig','setFpmConfig','setPHPMaxTime','syncDate','setPHPDisable','SetControl',
|
||||
'ClosePanel','AutoUpdatePanel','SetPanelLock','return_mail_list','del_mail_list','add_mail_address','user_mail_send','get_user_mail','set_dingding','get_dingding','get_settings','user_stmp_mail_send','user_dingding_send'
|
||||
)
|
||||
defs = (
|
||||
'get_panel_ssl_status','set_file_deny', 'del_file_deny', 'get_file_deny',
|
||||
'get_httpd_access_log_format_parameter','set_httpd_format_log_to_website','get_httpd_access_log_format',
|
||||
'del_httpd_access_log_format','add_httpd_access_log_format','get_nginx_access_log_format_parameter',
|
||||
'set_format_log_to_website','get_nginx_access_log_format','del_nginx_access_log_format',
|
||||
'add_nginx_access_log_format','get_ols_private_cache_status','get_ols_value','set_ols_value',
|
||||
'get_ols_private_cache','get_ols_static_cache','set_ols_static_cache','switch_ols_private_cache','set_ols_private_cache',
|
||||
'set_coll_open','get_qrcode_data','check_two_step','set_two_step_auth','create_user','remove_user','modify_user',
|
||||
'get_key','get_php_session_path','set_php_session_path','get_cert_source','get_users',
|
||||
'set_local','set_debug','get_panel_error_logs','clean_panel_error_logs','get_menu_list','set_hide_menu_list',
|
||||
'get_basic_auth_stat','set_basic_auth','get_cli_php_version','get_tmp_token','get_temp_login','set_temp_login','remove_temp_login','clear_temp_login','get_temp_login_logs',
|
||||
'set_cli_php_version','DelOldSession', 'GetSessionCount', 'SetSessionConf',
|
||||
'GetSessionConf','get_ipv6_listen','set_ipv6_status','GetApacheValue','SetApacheValue',
|
||||
'GetNginxValue','SetNginxValue','get_token','set_token','set_admin_path','is_pro',
|
||||
'get_php_config','get_config','SavePanelSSL','GetPanelSSL','GetPHPConf','SetPHPConf',
|
||||
'GetPanelList','AddPanelInfo','SetPanelInfo','DelPanelInfo','ClickPanelInfo','SetPanelSSL',
|
||||
'SetTemplates','Set502','setPassword','setUsername','setPanel','setPathInfo','setPHPMaxSize',
|
||||
'getFpmConfig','setFpmConfig','setPHPMaxTime','syncDate','setPHPDisable','SetControl',
|
||||
'ClosePanel','AutoUpdatePanel','SetPanelLock','return_mail_list','del_mail_list','add_mail_address','user_mail_send','get_user_mail','set_dingding','get_dingding','get_settings','user_stmp_mail_send','user_dingding_send'
|
||||
)
|
||||
return publicObject(config.config(),defs,None,pdata)
|
||||
|
||||
@app.route('/ajax',methods=method_all)
|
||||
@@ -686,7 +670,7 @@ def ssl(pdata = None):
|
||||
if comReturn: return comReturn
|
||||
import panelSSL
|
||||
toObject = panelSSL.panelSSL()
|
||||
defs = ('RemoveCert','renew_lets_ssl','SetCertToSite','GetCertList','SaveCert','GetCert','GetCertName',
|
||||
defs = ('check_url_txt','RemoveCert','renew_lets_ssl','SetCertToSite','GetCertList','SaveCert','GetCert','GetCertName','again_verify',
|
||||
'DelToken','GetToken','GetUserInfo','GetOrderList','GetDVSSL','Completed','SyncOrder','download_cert','set_cert','cancel_cert_order',
|
||||
'get_order_list','get_order_find','apply_order_pay','get_pay_status','apply_order','get_verify_info','get_verify_result','get_product_list','set_verify_info',
|
||||
'GetSSLInfo','downloadCRT','GetSSLProduct','Renew_SSL','Get_Renew_SSL')
|
||||
@@ -746,7 +730,7 @@ def auth(pdata = None):
|
||||
if comReturn: return comReturn
|
||||
import panelAuth
|
||||
toObject = panelAuth.panelAuth()
|
||||
defs = ('get_re_order_status_plugin','create_plugin_other_order','get_order_stat',
|
||||
defs = ('auth_activate','get_product_auth','get_stripe_session_id','get_re_order_status_plugin','create_plugin_other_order','get_order_stat',
|
||||
'get_voucher_plugin','create_order_voucher_plugin','get_product_discount_by',
|
||||
'get_re_order_status','create_order_voucher','create_order','get_order_status',
|
||||
'get_voucher','flush_pay_status','create_serverid','check_serverid',
|
||||
@@ -766,7 +750,7 @@ def download():
|
||||
if filename.find('|') != -1:
|
||||
filename = filename.split('|')[1]
|
||||
if not filename: return public.ReturnJson(False,"INIT_ARGS_ERR"),json_header
|
||||
if filename in ['alioss','qiniu','upyun','txcos','ftp']: return panel_cloud()
|
||||
if filename in ['alioss','qiniu','upyun','txcos','ftp','msonedrive','gcloud_storage', 'gdrive', 'aws_s3']: return panel_cloud()
|
||||
if not os.path.exists(filename): return public.ReturnJson(False,"FILE_NOT_EXISTS"),json_header
|
||||
|
||||
if request.args.get('play') == 'true':
|
||||
@@ -779,6 +763,8 @@ def download():
|
||||
if extName in ['png','gif','jpeg','jpg']: mimetype = None
|
||||
return send_file(filename,mimetype=mimetype,
|
||||
as_attachment=True,
|
||||
add_etags=True,
|
||||
conditional=True,
|
||||
attachment_filename=os.path.basename(filename),
|
||||
cache_timeout=0)
|
||||
|
||||
@@ -831,15 +817,15 @@ def login():
|
||||
if admin_path != '/bt' and os.path.exists(admin_path_file) and not 'admin_auth' in session:
|
||||
is_auth_path = True
|
||||
num_key = public.md5(public.GetClientIp() + '_auth_path')
|
||||
if not public.get_error_num(num_key,20): return public.returnMsg(False,'连续20次安全入口验证失败,禁止1小时')
|
||||
if not public.get_error_num(num_key,20): return public.returnMsg(False,'AUTH_FAILED1')
|
||||
#登录输入验证
|
||||
if request.method == method_post[0]:
|
||||
v_list = ['username','password','code','vcode','cdn_url']
|
||||
for v in v_list:
|
||||
pv = request.form.get(v,'').strip()
|
||||
if v == 'cdn_url':
|
||||
if len(pv) > 32: return public.returnMsg(False,'错误的参数长度!'),json_header
|
||||
if not re.match(r"^[\w\.-]+$",pv): public.returnJson(False,'错误的参数格式'),json_header
|
||||
if len(pv) > 32: return public.returnMsg(False,'PARAMETER_LEN_ERR'),json_header
|
||||
if not re.match(r"^[\w\.-]+$",pv): public.returnJson(False,'PARAMETER_FORMAT_ERR'),json_header
|
||||
continue
|
||||
|
||||
if not pv: continue
|
||||
@@ -847,14 +833,14 @@ def login():
|
||||
if v == 'code': p_len = 4
|
||||
if v == 'vcode': p_len = 6
|
||||
if len(pv) != p_len:
|
||||
if v == 'code': return public.returnJson(False,'验证码长度错误'),json_header
|
||||
return public.returnJson(False,'错误的参数长度'),json_header
|
||||
if v == 'code': return public.returnJson(False,'VCODE_LEN_ERR'),json_header
|
||||
return public.returnJson(False,'PARAMETER_LEN_ERR'),json_header
|
||||
if not re.match(r"^\w+$",pv):
|
||||
return public.returnJson(False,'错误的参数格式'),json_header
|
||||
return public.returnJson(False,'PARAMETER_FORMAT_ERR'),json_header
|
||||
|
||||
for n in request.form.keys():
|
||||
if not n in v_list:
|
||||
return public.returnJson(False,'登录参数中不能有多余参数'),json_header
|
||||
return public.returnJson(False,'EXTRA_PARAMETER_ERR'),json_header
|
||||
|
||||
get = get_input()
|
||||
import userlogin
|
||||
@@ -869,10 +855,12 @@ def login():
|
||||
if session['login'] != False:
|
||||
session['login'] = False
|
||||
cache.set('dologin',True)
|
||||
public.WriteLog('用户登出','客户端:{},已手动退出面板'.format(public.GetClientIp()+ ":" + str(request.environ.get('REMOTE_PORT'))))
|
||||
public.WriteLog('TYPE_LOGOUT','MANUALLY_LOGOUT',(public.GetClientIp()+ ":" + str(request.environ.get('REMOTE_PORT')),))
|
||||
if 'tmp_login_expire' in session:
|
||||
s_file = 'data/session/{}'.format(session['tmp_login_id'])
|
||||
if os.path.exists(s_file):
|
||||
os.remove(s_file)
|
||||
session.clear()
|
||||
session_path = r'/dev/shm/session_py' + str(sys.version_info[0])
|
||||
if os.path.exists(session_path): public.ExecShell("rm -f " + session_path + '/*')
|
||||
sess_file = 'data/sess_files/' + public.get_sess_key()
|
||||
if os.path.exists(sess_file):
|
||||
try:
|
||||
@@ -883,11 +871,17 @@ def login():
|
||||
|
||||
if is_auth_path:
|
||||
if route_path != request.path and route_path + '/' != request.path:
|
||||
public.set_error_num(num_key)
|
||||
#return abort(404)
|
||||
data = {}
|
||||
data['lan'] = public.getLan('close')
|
||||
return render_template('autherr.html',data=data)
|
||||
referer = request.headers.get('Referer','err')
|
||||
referer_tmp = referer.split('/')
|
||||
referer_path = referer_tmp[-1]
|
||||
if referer_path == '':
|
||||
referer_path = referer_tmp[-2]
|
||||
if route_path != '/'+referer_path:
|
||||
public.set_error_num(num_key)
|
||||
#return abort(404)
|
||||
data = {}
|
||||
data['lan'] = public.getLan('close')
|
||||
return render_template('autherr.html',data=data)
|
||||
session['admin_auth'] = True
|
||||
public.set_error_num(num_key,True)
|
||||
comReturn = common.panelSetup().init()
|
||||
@@ -929,16 +923,19 @@ def tips():
|
||||
return render_template('tips.html')
|
||||
|
||||
|
||||
@app.route('/get_app_bind_status',methods=method_all)
|
||||
def get_app_bind_status(pdata = None):
|
||||
#APP绑定状态查询
|
||||
@app.route('/get_app_bind_status', methods=method_all)
|
||||
def get_app_bind_status(pdata=None):
|
||||
# APP绑定状态查询
|
||||
if not public.check_app('app_bind'):return public.returnMsg(False, 'API_DISABLED')
|
||||
import panelApi
|
||||
api_object = panelApi.panelApi()
|
||||
return json.dumps(api_object.get_app_bind_status(get_input())),json_header
|
||||
|
||||
@app.route('/check_bind',methods=method_all)
|
||||
def check_bind(pdata = None):
|
||||
#APP绑定查询
|
||||
|
||||
@app.route('/check_bind', methods=method_all)
|
||||
def check_bind(pdata=None):
|
||||
# APP绑定查询
|
||||
if not public.check_app('app_bind'):return public.returnMsg(False, 'API_DISABLED')
|
||||
import panelApi
|
||||
api_object = panelApi.panelApi()
|
||||
return json.dumps(api_object.check_bind(get_input())),json_header
|
||||
@@ -1098,6 +1095,7 @@ def panel_public():
|
||||
return data,json_header
|
||||
|
||||
if get.name != 'app': return abort(404)
|
||||
if not public.check_app('wxapp'): return public.returnMsg(False, 'UNBOUND_USER')
|
||||
import panelPlugin
|
||||
plu = panelPlugin.panelPlugin()
|
||||
get.s = '_check'
|
||||
@@ -1126,6 +1124,10 @@ def send_favicon():
|
||||
@app.route('/service_status',methods = method_get)
|
||||
def service_status():
|
||||
#检查面板当前状态
|
||||
try:
|
||||
if not 'login' in session: session.clear()
|
||||
except:
|
||||
pass
|
||||
return 'True'
|
||||
|
||||
@app.route('/coll',methods=method_all)
|
||||
@@ -1140,7 +1142,7 @@ def panel_other(name=None,fun = None,stype=None):
|
||||
args = None
|
||||
else:
|
||||
args = get_input()
|
||||
args_list = ['mail_from','password','mail_to','subject','content','subtype']
|
||||
args_list = ['mail_from','password','mail_to','subject','content','subtype','data']
|
||||
for k in args.__dict__:
|
||||
if not k in args_list: return abort(404)
|
||||
|
||||
@@ -1256,6 +1258,7 @@ def panel_hook():
|
||||
@app.route('/install',methods=method_all)
|
||||
def install():
|
||||
#初始化面板接口
|
||||
if not os.path.exists('install.pl'): return redirect('/login')
|
||||
if public.M('config').where("id=?",('1',)).getField('status') == 1:
|
||||
if os.path.exists('install.pl'): os.remove('install.pl')
|
||||
session.clear()
|
||||
@@ -1311,7 +1314,8 @@ def get_dir_down(filename,token,find):
|
||||
import files
|
||||
args = public.dict_obj()
|
||||
args.path = filename
|
||||
to_path = filename.replace(find['filename'],'').strip('/')
|
||||
args.share = True
|
||||
to_path = filename.replace(find['filename'], '').strip('/')
|
||||
|
||||
if request.args.get('play') == 'true':
|
||||
pdata = files.files().get_videos(args)
|
||||
@@ -1322,7 +1326,7 @@ def get_dir_down(filename,token,find):
|
||||
pdata['token'] = token
|
||||
pdata['src_path'] = find['filename']
|
||||
pdata['to_path'] = to_path
|
||||
if find['expire'] > (time.time() + (86400 * 365 * 10)):
|
||||
if find['expire'] < (time.time() + (86400 * 365 * 10)):
|
||||
pdata['expire'] = public.format_date(times=find['expire'])
|
||||
else:
|
||||
pdata['expire'] = public.getMsg('NEVER_EXPIRES')
|
||||
@@ -1380,6 +1384,8 @@ class run_exec:
|
||||
result = eval(fun)
|
||||
else:
|
||||
result = eval(fun)
|
||||
r_type = type(result)
|
||||
if r_type == Resp: return result
|
||||
result = public.GetJson(result),json_header
|
||||
break
|
||||
if not result:
|
||||
@@ -1387,12 +1393,12 @@ class run_exec:
|
||||
if g.is_aes:
|
||||
result = public.aes_encrypt(result[0],g.aes_key),json_header
|
||||
else:
|
||||
if os.path.exists('pyenv/bin/python') and sys.version_info[0] == 3:
|
||||
if not os.path.exists('data/debug.pl'):
|
||||
x_token = request.headers.get('x-http-token')
|
||||
if x_token:
|
||||
aes_pwd = x_token[:8] + x_token[40:48]
|
||||
result = "BT-CRT"+public.aes_encrypt(result[0],aes_pwd),{'Content-Type':'text/plain; charset=utf-8'}
|
||||
# if os.path.exists('pyenv/bin/python') and sys.version_info[0] == 3:
|
||||
# if not os.path.exists('data/debug.pl'):
|
||||
# x_token = request.headers.get('x-http-token')
|
||||
# if x_token:
|
||||
# aes_pwd = x_token[:8] + x_token[40:48]
|
||||
# result = "BT-CRT"+public.aes_encrypt(result[0],aes_pwd),{'Content-Type':'text/plain; charset=utf-8'}
|
||||
pass
|
||||
return result
|
||||
|
||||
@@ -1430,10 +1436,7 @@ def publicObject(toObject,defs,action=None,get = None):
|
||||
|
||||
if hasattr(toObject,'site_path_check'):
|
||||
if not toObject.site_path_check(get): return public.ReturnJson(False,'INIT_ACCEPT_NOT'),json_header
|
||||
p = run_exec()
|
||||
result = p.run(toObject,defs,get)
|
||||
del p
|
||||
return result
|
||||
return run_exec().run(toObject,defs,get)
|
||||
|
||||
|
||||
|
||||
@@ -1578,6 +1581,14 @@ def is_login(result):
|
||||
result.set_cookie('request_token',request_token,max_age=86400*30)
|
||||
return result
|
||||
|
||||
# js随机数模板使用,用于不更新版本号时更新前端文件不需要用户强制刷新浏览器
|
||||
def get_js_random():
|
||||
js_random = public.readFile('data/js_random.pl')
|
||||
if not js_random or js_random == '1':
|
||||
js_random = public.GetRandomString(16)
|
||||
public.writeFile('data/js_random.pl',js_random)
|
||||
return js_random
|
||||
|
||||
#获取输入数据
|
||||
def get_input():
|
||||
data = public.dict_obj()
|
||||
@@ -1585,17 +1596,17 @@ def get_input():
|
||||
for key in request.args.keys():
|
||||
data[key] = str(request.args.get(key,''))
|
||||
try:
|
||||
x_token = request.headers.get('x-http-token')
|
||||
if x_token:
|
||||
aes_pwd = x_token[:8] + x_token[40:48]
|
||||
# x_token = request.headers.get('x-http-token')
|
||||
# if x_token:
|
||||
# aes_pwd = x_token[:8] + x_token[40:48]
|
||||
|
||||
for key in request.form.keys():
|
||||
if key in exludes: continue
|
||||
data[key] = str(request.form.get(key,''))
|
||||
if x_token:
|
||||
if len(data[key]) > 5:
|
||||
if data[key][:6] == 'BT-CRT':
|
||||
data[key] = public.aes_decrypt(data[key][6:],aes_pwd)
|
||||
# if x_token:
|
||||
# if len(data[key]) > 5:
|
||||
# if data[key][:6] == 'BT-CRT':
|
||||
# data[key] = public.aes_decrypt(data[key][6:],aes_pwd)
|
||||
except:
|
||||
try:
|
||||
post = request.form.to_dict()
|
||||
@@ -1609,7 +1620,6 @@ def get_input():
|
||||
for k in g.form_data.keys():
|
||||
data[k] = str(g.form_data[k])
|
||||
|
||||
|
||||
if not hasattr(data,'data'): data.data = []
|
||||
return data
|
||||
|
||||
|
||||
@@ -28,6 +28,12 @@
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: iconfont;
|
||||
src: url("../icons/iconfont.woff");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
.binary-icon:before {
|
||||
font-family: "Octicons Regular";
|
||||
font-size: 16px;
|
||||
@@ -4939,4 +4945,121 @@
|
||||
color: #6a9fb5;
|
||||
font-family: octicons;
|
||||
content: "\f0c9";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* 文件目录图标 */
|
||||
.iconfont {
|
||||
font-family: "iconfont" !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-houtui:before {
|
||||
content: "\e60f";
|
||||
}
|
||||
|
||||
.icon-search1:before {
|
||||
content: "\e60e";
|
||||
}
|
||||
|
||||
.icon-lishi:before {
|
||||
content: "\e652";
|
||||
}
|
||||
|
||||
.icon-shoucang:before {
|
||||
content: "\e648";
|
||||
}
|
||||
|
||||
.icon-wenjian:before {
|
||||
content: "\e6ab";
|
||||
}
|
||||
|
||||
.icon-vscode:before {
|
||||
content: "\e609";
|
||||
}
|
||||
|
||||
.icon-fenxiang:before {
|
||||
content: "\e62a";
|
||||
}
|
||||
|
||||
.icon-tishi:before {
|
||||
content: "\e63f";
|
||||
}
|
||||
|
||||
.icon-guanbi:before {
|
||||
content: "\e60c";
|
||||
}
|
||||
|
||||
.icon-favorites:before {
|
||||
content: "\e66c";
|
||||
}
|
||||
|
||||
.icon-share1:before {
|
||||
content: "\e607";
|
||||
}
|
||||
|
||||
.icon-authority:before {
|
||||
content: "\e606";
|
||||
}
|
||||
|
||||
.icon-dir_kill:before {
|
||||
content: "\e643";
|
||||
}
|
||||
|
||||
.icon-zhixiang-zuo:before {
|
||||
content: "\e6fd";
|
||||
}
|
||||
|
||||
.icon-next:before {
|
||||
content: "\e772";
|
||||
}
|
||||
|
||||
.icon-prev:before {
|
||||
content: "\e7b4";
|
||||
}
|
||||
|
||||
.icon-lajitong-copy:before {
|
||||
content: "\e605";
|
||||
}
|
||||
|
||||
.icon-xingxing:before {
|
||||
content: "\e602";
|
||||
}
|
||||
|
||||
.icon-triangle-right:before {
|
||||
content: "\e601";
|
||||
}
|
||||
|
||||
.icon-search:before {
|
||||
content: "\e60d";
|
||||
}
|
||||
|
||||
.icon-arrow-down:before {
|
||||
content: "\e7b2";
|
||||
}
|
||||
|
||||
.icon-arrow-right:before {
|
||||
content: "\e743";
|
||||
}
|
||||
|
||||
.icon-arrow-lift:before {
|
||||
content: "\e744";
|
||||
}
|
||||
|
||||
.icon-terminal:before {
|
||||
content: "\e600";
|
||||
}
|
||||
|
||||
.icon-iconfont53:before {
|
||||
content: "\e75e";
|
||||
}
|
||||
|
||||
.icon-xiala:before {
|
||||
content: "\e62e";
|
||||
}
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 512 B |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 7.8 KiB |
|
After Width: | Height: | Size: 421 B |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 297 B |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 800 B |
|
After Width: | Height: | Size: 344 B |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 460 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 911 B |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 281 B |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 574 B |
@@ -376,7 +376,7 @@ function bindBTName(a,type){
|
||||
closeBtn: 2,
|
||||
shift: 5,
|
||||
shadeClose: false,
|
||||
content: "<div class='bt-form pd20 pb70'><div class='line'><span class='tname'>"+lan.public.user+"</span><div class='info-r'><input class='bt-input-text' type='text' name='username' id='p1' value='' placeholder='"+lan.config.user_bt+"' style='width:100%'/></div></div><div class='line'><span class='tname'>"+lan.public.pass+"</span><div class='info-r'><input class='bt-input-text' type='password' name='password' id='p2' value='' placeholder='"+lan.config.pass_bt+"' style='width:100%'/></div></div><div class='bt-form-submit-btn'><button type='button' class='btn btn-danger btn-sm' onclick=\"layer.closeAll()\">"+lan.public.cancel+"</button> "+btn+"</div></div>"
|
||||
content: "<div class='bt-form pd20 pb70'><div class='line'><span class='tname' style='width:100px;'>"+lan.public.user+"</span><div class='info-r' style='margin-left:100px;'><input class='bt-input-text' type='text' name='username' id='p1' value='' placeholder='"+lan.config.user_bt+"' style='width:100%'/></div></div><div class='line'><span class='tname' style='width:100px;'>"+lan.public.pass+"</span><div class='info-r' style='margin-left:100px;'><input class='bt-input-text' type='password' name='password' id='p2' value='' placeholder='"+lan.config.pass_bt+"' style='width:100%'/></div></div><div class='bt-form-submit-btn'><button type='button' class='btn btn-danger btn-sm' onclick=\"layer.closeAll()\">"+lan.public.cancel+"</button> "+btn+"</div></div>"
|
||||
})
|
||||
}
|
||||
//解除绑定宝塔账号
|
||||
@@ -385,7 +385,10 @@ function UnboundBt(){
|
||||
layer.confirm(lan.config.binding_un_msg,{closeBtn:2,icon:3,title:lan.config.binding_un},function(){
|
||||
$.get("/ssl?action=DelToken",function(b){
|
||||
layer.msg(b.msg,{icon:b.status? 1:2})
|
||||
$("input[name='btusername']").val('');
|
||||
if(b.status){
|
||||
window.location.reload();
|
||||
$("input[name='btusername']").val('');
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -574,11 +577,11 @@ function SavePanelSSL(){
|
||||
}
|
||||
|
||||
function SetDebug() {
|
||||
var status_s = {false:'Open',true:'Close'}
|
||||
var status_s = {false:'open',true:'close'}
|
||||
var debug_stat = $("#panelDebug").prop('checked');
|
||||
bt.confirm({
|
||||
title: status_s[debug_stat] + "Developer mode",
|
||||
msg: "Do you really want "+ status_s[debug_stat]+" developer mode?",
|
||||
title: (debug_stat?'Open':'Close') + " developer mode",
|
||||
msg: "Do you confirm to "+ (debug_stat?'open':'close') +" developer mode?",
|
||||
cancel: function () {
|
||||
$("#panelDebug").prop('checked',debug_stat);
|
||||
}}, function () {
|
||||
@@ -772,11 +775,11 @@ function open_wxapp(){
|
||||
|
||||
$(function () {
|
||||
|
||||
$.get("/ssl?action=GetUserInfo", function (b) {
|
||||
$.get("/ssl?action=GetUserInfo", function (b) {
|
||||
if (b.status) {
|
||||
$("input[name='btusername']").val(b.data.username);
|
||||
$("input[name='btusername']").next().text(lan.public.edit).attr("onclick", "bindBTName(2,'c')").css({ "margin-left": "-82px" });
|
||||
$("input[name='btusername']").next().after('<span class="btn btn-xs btn-success" onclick="UnboundBt()" style="vertical-align: 0px;">' + lan.config.binding_un + '</span>');
|
||||
$("input[name='btusername']").next().text(lan.public.edit).attr("onclick", "bindBTName(2,'c')").css({ "right": "57px" });
|
||||
$("input[name='btusername']").next().after('<span class="modify btn btn-xs btn-success" onclick="UnboundBt()" style="vertical-align: 0px;">' + lan.config.binding_un + '</span>');
|
||||
}
|
||||
else {
|
||||
$("input[name='btusername']").next().text(lan.config.binding).attr("onclick", "bindBTName(2,'b')").removeAttr("style");
|
||||
@@ -804,7 +807,7 @@ function GetPanelApi() {
|
||||
isOpen = rdata.open ? 'checked' : '';
|
||||
layer.open({
|
||||
type: 1,
|
||||
area: "500px",
|
||||
area: "522px",
|
||||
title: lan.config.set_api,
|
||||
closeBtn: 2,
|
||||
shift: 5,
|
||||
@@ -814,7 +817,7 @@ function GetPanelApi() {
|
||||
<span class="tname">'+lan.config.api+'</span>\
|
||||
<div class="info-r" style="height:28px;">\
|
||||
<input class="btswitch btswitch-ios" id="panelApi_s" type="checkbox" '+ isOpen+'>\
|
||||
<label style="position: relative;top: 5px;" class="btswitch-btn" for="panelApi_s" onclick="SetPanelApi(2)"></label>\
|
||||
<label style="position: relative;top: 5px;" class="btswitch-btn" for="panelApi_s" onclick="SetPanelApi(2,1)"></label>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="line">\
|
||||
@@ -872,10 +875,12 @@ function SetPanelApi(t_type,index) {
|
||||
return false
|
||||
}
|
||||
set_token_req(pdata,function(rdata){
|
||||
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
|
||||
if (rdata.msg == lan.config.open_successfully) {
|
||||
if(t_type == 2 && index != '0') GetPanelApi();
|
||||
}
|
||||
layer.close(layer.index);
|
||||
if (rdata.msg == 'Open success!') {
|
||||
if(t_type == 2 && index != '1') GetPanelApi();
|
||||
}
|
||||
if(t_type == 2) $('#panelApi').prop('checked',rdata.msg == 'Open success!'?true:false);
|
||||
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1259,3 +1264,329 @@ function show_basic_auth(rdata) {
|
||||
</div>'
|
||||
})
|
||||
}
|
||||
function get_panel_hide_list(){
|
||||
var loadT = bt.load('Getting panel menu bar, please wait...'),arry = [];
|
||||
$.post('/config?action=get_menu_list',function(rdata){
|
||||
loadT.close();
|
||||
$.each(rdata,function(index,item){
|
||||
if(!item.show) arry.push(item.title)
|
||||
});
|
||||
$('#panel_menu_hide').val(arry.length > 0?arry.join('/'):'No hidden bar');
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
get_panel_hide_list();
|
||||
|
||||
// 设置面板菜单显示功能
|
||||
function set_panel_ground(){
|
||||
var loadT = bt.load('Getting panel menu bar, please wait...');
|
||||
$.post('/config?action=get_menu_list',function(rdata){
|
||||
var html = '',arry = ["dologin","memuAconfig","memuAsoft","memuA"],is_option = '';
|
||||
loadT.close();
|
||||
$.each(rdata,function(index,item){
|
||||
is_option = '<div class="index-item" style="float:right;"><input class="btswitch btswitch-ios" id="'+ item.id +'0000" name="'+ item.id +'" type="checkbox" '+ (item.show?'checked':'') +'><label class="btswitch-btn" for="'+ item.id +'0000"></label></div>'
|
||||
|
||||
if(item.id == 'dologin' || item.id == 'memuAconfig' || item.id == 'memuAsoft' || item.id == 'memuA') is_option = 'Inoperable';
|
||||
html += '<tr><td>'+ item.title +'</td><td><div style="float:right;">'+ is_option +'</div></td></tr>';
|
||||
});
|
||||
layer.open({
|
||||
type:1,
|
||||
title:'Manage panel menu bar',
|
||||
area:['350px','536px'],
|
||||
shadeClose:false,
|
||||
closeBtn:2,
|
||||
content:'<div class="divtable softlist" id="panel_menu_tab" style="padding: 20px 15px;"><table class="table table-hover"><thead><tr><th>Menu bar</th><th style="text-align:right;width:120px;">Display</th></tr></thead><tbody>'+ html +'</tbody></table></div>',
|
||||
success:function(){
|
||||
$('#panel_menu_tab input').click(function(){
|
||||
var arry = [];
|
||||
$(this).parents('tr').siblings().each(function(index,el){
|
||||
if($(this).find('input').length >0 && !$(this).find('input').prop('checked')){
|
||||
arry.push($(this).find('input').attr('name'));
|
||||
}
|
||||
});
|
||||
if(!$(this).prop('checked')){
|
||||
arry.push($(this).attr('name'));
|
||||
}
|
||||
var loadT = bt.load('Setting panel menu bar display status, please wait...');
|
||||
$.post('/config?action=set_hide_menu_list',{hide_list:JSON.stringify(arry)},function(rdata){
|
||||
loadT.close();
|
||||
bt.msg(rdata);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @description 获取临时授权列表
|
||||
* @param {Function} callback 回调函数列表
|
||||
* @returns void
|
||||
*/
|
||||
function get_temp_login(data,callback){
|
||||
var loadT = bt.load('Get temporary authorization list, please wait...');
|
||||
bt.send('get_temp_login','config/get_temp_login',data,function(res){
|
||||
if(res.status === false){
|
||||
layer.closeAll();
|
||||
bt.msg(res);
|
||||
return false;
|
||||
}
|
||||
loadT.close();
|
||||
if(callback) callback(res)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 设置临时链接
|
||||
* @param {Function} callback 回调函数列表
|
||||
* @returns void
|
||||
*/
|
||||
function set_temp_login(callback){
|
||||
var loadT = bt.load('Setting temporary links, please wait...');
|
||||
bt.send('set_temp_login','config/set_temp_login',{},function(res){
|
||||
loadT.close();
|
||||
if(callback) callback(res)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 设置临时链接
|
||||
* @param {Object} data 传入参数,id
|
||||
* @param {Function} callback 回调函数列表
|
||||
* @returns void
|
||||
*/
|
||||
function remove_temp_login(data,callback){
|
||||
var loadT = bt.load('Deleting temporary authorization record, please wait...');
|
||||
bt.send('remove_temp_login','config/remove_temp_login',{id:data.id},function(res){
|
||||
loadT.close();
|
||||
if(callback) callback(res)
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @description 强制用户登出
|
||||
* @param {Object} data 传入参数,id
|
||||
* @param {Function} callback 回调函数列表
|
||||
* @returns void
|
||||
*/
|
||||
function clear_temp_login(data,callback){
|
||||
var loadT = bt.load('Forcing user to log out, please wait...');
|
||||
bt.send('clear_temp_login','config/clear_temp_login',{id:data.id},function(res){
|
||||
loadT.close();
|
||||
if(callback) callback(res)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 渲染授权管理列表
|
||||
* @param {Object} data 传入参数,id
|
||||
* @param {Function} callback 回调函数列表
|
||||
* @returns void
|
||||
*/
|
||||
function reader_temp_list(data,callback){
|
||||
if(typeof data == 'function') callback = data,data = {p:1};
|
||||
get_temp_login(data,function(rdata){
|
||||
var html = '';
|
||||
$.each(rdata.data,function(index,item){
|
||||
html += '<tr><td>'+ (item.login_addr || 'Not login') +'</td><td>'+ (function(){
|
||||
switch(item.state){
|
||||
case 0:
|
||||
return 'Not login';
|
||||
break;
|
||||
case 1:
|
||||
return 'Logged in';
|
||||
break;
|
||||
case -1:
|
||||
return 'Expired';
|
||||
break;
|
||||
}
|
||||
}()) +'</td><td >'+ (item.login_time == 0?'Not login':bt.format_data(item.login_time)) +'</td><td>'+ bt.format_data(item.expire) +'</td><td style="text-align:right;">'+ (function(){
|
||||
if(item.state != 1){
|
||||
return '<a href="javascript:;" class="btlink remove_temp_login" data-ip="'+ item.login_addr +'" data-id="'+ item.id +'">Del</a>';
|
||||
}
|
||||
if(item.online_state){
|
||||
return '<a href="javascript:;" class="btlink clear_temp_login" style="color:red" data-ip="'+ item.login_addr +'" data-id="'+ item.id +'">Force logout </a> | <a href="javascript:;" class="btlink logs_temp_login" data-ip="'+ item.login_addr +'" data-id="'+ item.id +'">Logs</a>';
|
||||
}
|
||||
return '<a href="javascript:;" class="btlink logs_temp_login" data-ip="'+ item.login_addr +'" data-id="'+ item.id +'">Logs</a>';
|
||||
}()) +'</td></tr>';
|
||||
});
|
||||
$('#temp_login_view_tbody').html(html);
|
||||
$('.temp_login_view_page').html(rdata.page);
|
||||
if(callback) callback()
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @description 获取操作日志
|
||||
* @param {Object} data 传入参数,id
|
||||
* @param {Function} callback 回调函数列表
|
||||
* @returns void
|
||||
*/
|
||||
function get_temp_login_logs(data,callback){
|
||||
var loadT = bt.load('Getting operation log, please wait...');
|
||||
bt.send('clear_temp_login','config/get_temp_login_logs',{id:data.id},function(res){
|
||||
loadT.close();
|
||||
if(callback) callback(res)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 渲染操作日志
|
||||
* @param {Object} data 传入参数,id
|
||||
* @param {Function} callback 回调函数列表
|
||||
* @returns void
|
||||
*/
|
||||
function reader_temp_login_logs(data,callback){
|
||||
get_temp_login_logs(data,function(res){
|
||||
var html = '';
|
||||
$.each(res,function(index,item){
|
||||
html += '<tr><td>'+ item.type +'</td><td>'+ item.addtime +'</td><td><span title="'+ item.log +'" style="white-space: pre;">'+ item.log +'</span></td></tr>';
|
||||
});
|
||||
if(callback) callback({tbody:html,data:res});
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @description 设置临时链接
|
||||
* @param {Function} callback 回调函数列表
|
||||
* @returns void
|
||||
*/
|
||||
function get_temp_login_view(){
|
||||
layer.open({
|
||||
type: 1,
|
||||
area:["700px",'600px'],
|
||||
title: "Temporary authorization management",
|
||||
closeBtn: 2,
|
||||
shift: 5,
|
||||
shadeClose: false,
|
||||
content:'<div class="login_view_table pd15">'+
|
||||
'<button class="btn btn-success btn-sm va0 create_temp_login" >Create authorization</button>'+
|
||||
'<div class="divtable mt10">'+
|
||||
'<table class="table table-hover">'+
|
||||
'<thead><tr><th>Login IP</th><th>Status</th><th>Login time</th><th>Expiration time</th><th style="text-align:right;">Opt</th></tr></thead>'+
|
||||
'<tbody id="temp_login_view_tbody"></tbody>'+
|
||||
'</table>'+
|
||||
'<div class="temp_login_view_page page"></div>'+
|
||||
'</div>'+
|
||||
'</div>',
|
||||
success:function(){
|
||||
reader_temp_list();
|
||||
// 创建临时授权
|
||||
$('.create_temp_login').click(function(){
|
||||
bt.confirm({title:'Risk tips',msg:'<span style="color:red">Note 1: Abuse of temporary authorization may lead to security risks.</br>Note 2: Not publish temporary authorized connections in public</span></br>Temporary authorization connection is about to be created. Continue?'},function(){
|
||||
layer.open({
|
||||
type: 1,
|
||||
area:'570px',
|
||||
title: "Create temporary authorization",
|
||||
closeBtn: 2,
|
||||
shift: 5,
|
||||
shadeClose: false,
|
||||
content:'<div class="bt-form create_temp_view">'+
|
||||
'<div class="line"><span class="tname" style="width: auto;">Temporary authorized address</span><div class="info-r ml0"><textarea id="temp_link" class="bt-input-text mr20" style="margin: 0px;width: 500px;height: 50px;line-height: 19px;"></textarea></div></div>'+
|
||||
'<div class="line"><button type="submit" class="btn btn-success btn-sm btn-copy-temp-link" data-clipboard-text="">Copy address</button></div>'+
|
||||
'<ul class="help-info-text c7"><li>The temporary authorization is valid within 1 hour after it is generated. It is a one-time authorization and will be invalid immediately after use</li><li>Use temporary authorization to log in to the panel within 1 hour. Do not publish temporary authorization connection in public</li><li>The authorized connection information is only displayed here once. If you forget it before use, please regenerate it</li></ul>'+
|
||||
'</div>',
|
||||
success:function(){
|
||||
set_temp_login(function(res){
|
||||
if(res.status){
|
||||
var temp_link = location.origin+ '/login?tmp_token=' + res.token;
|
||||
$('#temp_link').val(temp_link);
|
||||
$('.btn-copy-temp-link').attr('data-clipboard-text',temp_link);
|
||||
}
|
||||
});
|
||||
var clipboard = new ClipboardJS('.btn');
|
||||
clipboard.on('success', function(e) {
|
||||
bt.msg({status:true,msg:'Copy succeeded!'});
|
||||
e.clearSelection();
|
||||
});
|
||||
clipboard.on('error', function(e) {
|
||||
bt.msg({status:false,msg:'Copy failed, please copy address manually'});
|
||||
});
|
||||
},
|
||||
end:function(){
|
||||
reader_temp_list();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
// 操作日志
|
||||
$('#temp_login_view_tbody').on('click','.logs_temp_login',function(){
|
||||
var id = $(this).data('id'),ip = $(this).data('ip');
|
||||
layer.open({
|
||||
type: 1,
|
||||
area:['700px','550px'],
|
||||
title:'Operation logs ['+ ip +']',
|
||||
closeBtn: 2,
|
||||
shift: 5,
|
||||
shadeClose: false,
|
||||
content:'<div class="pd15">'+
|
||||
'<button class="btn btn-default btn-sm va0 refresh_login_logs">Refresh logs</button>'+
|
||||
'<div class="divtable mt10 tablescroll" style="max-height: 420px;overflow-y: auto;border:none">'+
|
||||
'<table class="table table-hover" id="logs_login_view_table">'+
|
||||
'<thead><tr><th width="90px">Operation</th><th width="150px">Time</th><th>logs</th></tr></thead>'+
|
||||
'<tbody ></tbody>'+
|
||||
'</table>'+
|
||||
'</div>'+
|
||||
'</div>',
|
||||
success:function(){
|
||||
reader_temp_login_logs({id:id},function(data){
|
||||
$('#logs_login_view_table tbody').html(data.tbody);
|
||||
});
|
||||
$('.refresh_login_logs').click(function(){
|
||||
reader_temp_login_logs({id:id},function(data){
|
||||
$('#logs_login_view_table tbody').html(data.tbody);
|
||||
});
|
||||
});
|
||||
bt.fixed_table('logs_login_view_table');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
//删除授权记录,仅未使用的授权记录
|
||||
$('#temp_login_view_tbody').on('click','.remove_temp_login',function(){
|
||||
var id = $(this).data('id');
|
||||
bt.confirm({
|
||||
title:'Remove unused licenses',
|
||||
msg:'Delete unused authorization record, continue?'
|
||||
},function(){
|
||||
remove_temp_login({id:id},function(res){
|
||||
reader_temp_list(function(){
|
||||
bt.msg(res);
|
||||
})
|
||||
})
|
||||
})
|
||||
});
|
||||
//强制下线,强制登录的用户下线
|
||||
$('#temp_login_view_tbody').on('click','.clear_temp_login',function(){
|
||||
var id = $(this).data('id'),ip= $(this).data('ip');
|
||||
bt.confirm({
|
||||
title:'Force logout [ '+ ip +' ]',
|
||||
msg:'Confirm to force logout [ '+ ip +' ]?'
|
||||
},function(){
|
||||
clear_temp_login({id:id},function(res){
|
||||
reader_temp_list(function(){
|
||||
bt.msg(res);
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
||||
// 分页操作
|
||||
$('.temp_login_view_page').on('click','a',function(ev){
|
||||
var href = $(this).attr('href'),reg = /([0-9]*)$/,page = reg.exec(href)[0];
|
||||
reader_temp_list({p:page});
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
@@ -900,7 +900,7 @@ function toBackup(type){
|
||||
sBody += '<p class="clearfix plan">\
|
||||
<div class="textname pull-left mr20" style="margin-left: 29px; font-size: 14px;">'+lan.crontab.exclusion_rule+'</div>\
|
||||
<div class="dropdown planBackupTo pull-left mr20">\
|
||||
<span><textarea style=" height: 112px;width:300px;line-height:22px;" class="bt-input-text" type="text" name="sBody" id="exclude" placeholder="'+lan.crontab.exclusion_rule_tips+'\ndata/config.php\nstatic/upload\n *.log\n"></textarea></span>\
|
||||
<span><textarea style=" height: 113px;width:300px;line-height:22px;" class="bt-input-text" type="text" name="sBody" id="exclude" placeholder="'+lan.crontab.exclusion_rule_tips+'\ndata/config.php\nstatic/upload\n *.log\n"></textarea></span>\
|
||||
</div>\
|
||||
</p>';
|
||||
}
|
||||
|
||||
@@ -18,26 +18,27 @@ var database = {
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'password', width: '15%', title: lan.database.add_pass, templet: function (item) {
|
||||
var _html = '<span class="password" data-pw="' + item.password + '">**********</span>';
|
||||
field: 'password', title: lan.database.add_pass, templet: function (item) {
|
||||
var _html = '<span class="dataBase"><span class="password" data-pw="' + item.password + '">**********</span>';
|
||||
_html += '<span onclick="bt.pub.show_hide_pass(this)" class="glyphicon glyphicon-eye-open cursor pw-ico" style="margin-left:10px"></span>';
|
||||
_html += '<span class="ico-copy cursor btcopy" style="margin-left:10px" title="'+lan.database.copy_pass+'" data-pw="' + item.password + '" onclick="bt.pub.copy_pass(\'' + item.password + '\')"></span>';
|
||||
_html += '<span class="ico-copy cursor btcopy" style="margin-left:10px" title="'+lan.database.copy_pass+'" data-pw="' + item.password + '" onclick="bt.pub.copy_pass(\'' + item.password + '\')"></span></span>';
|
||||
return _html;
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'backup', title: lan.database.backup, templet: function (item) {
|
||||
var backup = '';
|
||||
var backup = '<span class="dataBase">';
|
||||
var _msg = lan.database.backup_empty;
|
||||
if (item.backup_count > 0) _msg = lan.database.backup_ok;
|
||||
backup = "<a href='javascript:;' class='btlink' onclick=\"database.database_detail('" + item.id + "','" + item.name + "')\">" + _msg + "</a> | "
|
||||
backup += "<a href='javascript:;' class='btlink' onclick=\"database.database_detail('" + item.id + "','" + item.name + "')\">" + _msg + "</a> | "
|
||||
backup += "<a class='btlink' href=\"javascript:database.input_database('" + item.name + "');\" title='" + lan.database.input_title + "'>" + lan.database.input + "</a>";
|
||||
backup += '</span>';
|
||||
return backup;
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'ps', title: lan.database.add_ps, templet: function (item) {
|
||||
var _ps = "<span class='c9 input-edit' onclick=\"bt.pub.set_data_by_key('databases','ps',this)\" >"
|
||||
var _ps = "<span class='c9 input-edit webNote' onclick=\"bt.pub.set_data_by_key('databases','ps',this)\" >"
|
||||
if (item.password) {
|
||||
_ps += item.ps
|
||||
} else {
|
||||
@@ -48,18 +49,22 @@ var database = {
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'opt', width: 300, title: lan.database.operation, align: 'right', templet: function (item) {
|
||||
var option = "<a href=\"javascript:;\" class=\"btlink\" onclick=\"bt.database.open_phpmyadmin('" + item.name + "','" + item.username + "','" + item.password + "')\" title=\""+lan.database.admin_title+"\">"+lan.database.admin+"</a> | ";
|
||||
field: 'opt', title: lan.database.operation, align: 'right', templet: function (item) {
|
||||
var option = "<span class=\"dataBase\"><a href=\"javascript:;\" class=\"btlink\" onclick=\"bt.database.open_phpmyadmin('" + item.name + "','" + item.username + "','" + item.password + "')\" title=\""+lan.database.admin_title+"\">"+lan.database.admin+"</a> | ";
|
||||
option += "<a href=\"javascript:;\" class=\"btlink\" onclick=\"database.rep_tools('" + item.name + "')\" title=\""+lan.database.mysql_tools+"\">"+lan.database.tools+"</a> | ";
|
||||
option += "<a href=\"javascript:;\" class=\"btlink\" onclick=\"bt.database.set_data_access('" + item.username + "')\" title=\""+lan.database.set_db_auth+"\">"+lan.database.auth+"</a> | ";
|
||||
option += "<a href=\"javascript:;\" class=\"btlink\" onclick=\"database.set_data_pass(" + item.id + ",'" + item.username + "','" + item.password + "')\" title=\""+lan.database.edit_pass_title+"\">"+lan.database.edit_pass+"</a> | ";
|
||||
option += "<a href=\"javascript:;\" class=\"btlink\" onclick=\"database.del_database(" + item.id + ",'" + item.name + "')\" title=\""+lan.database.del_title+"\">"+lan.database.del+"</a>";
|
||||
option += "<a href=\"javascript:;\" class=\"btlink\" onclick=\"database.del_database(" + item.id + ",'" + item.name + "')\" title=\""+lan.database.del_title+"\">"+lan.database.del+"</a></span>";
|
||||
return option;
|
||||
}
|
||||
},
|
||||
],
|
||||
data: rdata.data
|
||||
})
|
||||
});
|
||||
$(window).resize(function() {
|
||||
database.forSize();
|
||||
});
|
||||
database.forSize();
|
||||
})
|
||||
},
|
||||
rep_tools: function (db_name, res) {
|
||||
@@ -303,7 +308,11 @@ var database = {
|
||||
var _tab = bt.render({
|
||||
table: '#DataBackupList',
|
||||
columns: [
|
||||
{ field: 'name', title: lan.database.backup_name },
|
||||
{ field: 'name', title: lan.database.backup_name, templet: function (item) {
|
||||
var _opt = '<span class="btlink" style="display: inline-block;max-width: 265px;">'+item.name+'</span>'
|
||||
return _opt;
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'size', title: lan.database.backup_size, templet: function (item) {
|
||||
return bt.format_size(item.size);
|
||||
@@ -325,6 +334,7 @@ var database = {
|
||||
bt.database.backup_data(id, dataname, function (rdata) {
|
||||
if (rdata.status) database.database_detail(id, dataname);
|
||||
database.get_list();
|
||||
if (!rdata.status) layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
|
||||
})
|
||||
})
|
||||
}, 100)
|
||||
@@ -431,5 +441,11 @@ var database = {
|
||||
database.input_database(name);
|
||||
});
|
||||
});
|
||||
},
|
||||
//浏览器窗口大小变化时调整内容宽度
|
||||
forSize:function(){
|
||||
var ticket_with = $('#DataBody').parent().width(),
|
||||
td_width = ticket_with*0.8-30-$('#DataBody th:eq(2)').width()-$('#DataBody th:eq(3)').width()-$('#DataBody th:eq(4)').width()-$('#DataBody th:eq(6)').width();
|
||||
$('#DataBody .webNote').css('max-width',td_width);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,11 @@
|
||||
bt.pub.check_install(function (rdata) {
|
||||
if (rdata === false) bt.index.rec_install();
|
||||
})
|
||||
$("select[name='network-io']").change(function(){
|
||||
var net_key = $(this).val();
|
||||
if(net_key == 'all') net_key = '';
|
||||
bt.set_cookie('network_io_key',net_key);
|
||||
});
|
||||
var interval_stop = false;
|
||||
var index = {
|
||||
warning_list:[],
|
||||
@@ -245,7 +250,25 @@ var index = {
|
||||
if (_lval > 100) _lval = 100;
|
||||
index.set_val(_loadbox, { usage: _lval, items: load_arr })
|
||||
_loadbox.parents('ul').data('data', net);
|
||||
var net_key = bt.get_cookie('network_io_key');
|
||||
if(net_key){
|
||||
console.log(net_key,net.network[net_key])
|
||||
net.up = net.network[net_key].up;
|
||||
net.down = net.network[net_key].down;
|
||||
net.downTotal = net.network[net_key].downTotal;
|
||||
net.upTotal = net.network[net_key].upTotal;
|
||||
net.downPackets = net.network[net_key].downPackets;
|
||||
net.upPackets = net.network[net_key].upPackets;
|
||||
net.downAll = net.network[net_key].downTotal;
|
||||
net.upAll = net.network[net_key].upTotal;
|
||||
}
|
||||
var net_option = '<option value="all">All</option>';
|
||||
$.each(net.network,function(k,v){
|
||||
var act = (k == net_key)?'selected':'';
|
||||
net_option += '<option value="'+k+'" '+act+'>'+k+'</option>';
|
||||
});
|
||||
|
||||
$('select[name="network-io"]').html(net_option);
|
||||
//刷新流量
|
||||
$("#upSpeed").html(net.up + ' KB');
|
||||
$("#downSpeed").html(net.down + ' KB');
|
||||
@@ -484,8 +507,8 @@ var index = {
|
||||
<div class="update_title"><i class="layui-layer-ico layui-layer-ico1"></i><span>'+lan.index.last_version_now+'</span></div>\
|
||||
<div class="update_version">'+lan.index.this_version+'<a href="https://forum.aapanel.com/d/9-aapanel-linux-panel-6-1-5-installation-tutorial/36" target="_blank" class="btlink" title="'+lan.index.check_this_version_log+'">'+lan.index.bt_linux+ (rdata.msg.is_beta == 1 ? lan.index.test_version+' ' + rdata.msg.beta.version : lan.index.final_version+' ' + rdata.msg.version) + '</a> '+ lan.index.release_time + (rdata.msg.is_beta == 1 ? rdata.msg.beta.uptime : rdata.msg.uptime) + '</div>\
|
||||
<div class="update_conter">\
|
||||
<div class="update_tips">'+ (is_beta != 1 ? lan.index.test_version : lan.index.final_version) + lan.index.last_version_is + (result.msg.is_beta != 1 ? result.msg.beta.version : result.msg.version) + ' '+lan.index.update_time+' ' + (is_beta != 1 ? result.msg.beta.uptime : result.msg.uptime) + '</div>\
|
||||
'+ (is_beta !== 1 ? '<span>'+lan.index.update_verison_click+'<a href="javascript:;" onclick="index.beta_msg()" class="btlink btn_update_testPanel">'+lan.index.check_detail+'</a></span>' : '<span>'+lan.index.change_final_click+'<a href="javascript:;" onclick="index.to_not_beta()" class="btlink btn_update_testPanel">'+lan.index.change_final+'</a></span>') + '\
|
||||
<div class="update_tips">'+ (is_beta != 1 ? lan.index.test_version : lan.index.final_version) + lan.index.last_version_is + (result.msg.is_beta != 1 ? result.msg.beta.version : result.msg.version) + ' '+lan.index.update_time+' ' + (is_beta != 1 ? result.msg.beta.uptime : result.msg.uptime) + '</div>\
|
||||
'+ (is_beta !== 1 ? '<span>'+lan.index.update_verison_click+'<a href="javascript:;" onclick="index.beta_msg()" class="btlink btn_update_testPanel">'+lan.index.check_detail+'</a></span>' : '<span>'+lan.index.change_final_click+'<a href="javascript:;" onclick="index.to_not_beta()" class="btlink btn_update_testPanel"> '+lan.index.change_final+'</a></span>') + '\
|
||||
</div>\
|
||||
<div class="bt-form-submit-btn">\
|
||||
<button type="button" class="btn btn-danger btn-sm btn-title" onclick="layer.closeAll()">'+ lan.public.cancel + '</button>\
|
||||
@@ -547,7 +570,7 @@ var index = {
|
||||
layer.closeAll();
|
||||
bt.system.to_update(function (rdata) {
|
||||
if (rdata.status) {
|
||||
bt.msg({ msg: lan.index.update_ok, icon: 1 })
|
||||
bt.msg({ msg: rdata.msg, icon: 1 })
|
||||
$("#btversion").html(rdata.version);
|
||||
$("#toUpdate").html('');
|
||||
bt.system.reload_panel();
|
||||
@@ -578,7 +601,7 @@ var index = {
|
||||
bt.send('get_beta_logs', 'ajax/get_beta_logs', {}, function (data) {
|
||||
var my_list = '';
|
||||
new_load.close();
|
||||
if(data.status === false){
|
||||
if(data.status == false){
|
||||
layer.msg(data.msg,{icon: 2});
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
/*!
|
||||
* jQuery Contextify v1.0.8 (http://contextify.js.org)
|
||||
* jQuery Contextify v1.0.7 (http://contextify.js.org)
|
||||
* Copyright (c) 2016 Adam Bouqdib
|
||||
* Licensed under GPL-2.0 (http://abemedia.co.uk/license)
|
||||
*/
|
||||
|
||||
|
||||
!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery,window)}(function(a,b){function c(b,c){this.element=b,this.options=a.extend({},e,c),this._defaults=e,this._name=d,this.init()}var d="contextify",e={items:[],action:"contextmenu",menuId:"contextify-menu",menuClass:"dropdown-menu",headerClass:"dropdown-header",dividerClass:"divider",before:!1},f=0,g=a(b);c.prototype.init=function(){var b=a.extend({},this.options,a(this.element).data());b.id=f,a(this.element).attr("data-contextify-id",b.id).on("contextmenu",function(c){c.preventDefault(),"function"==typeof b.before&&b.before(this,b);var d=a('<ul class="'+b.menuClass+'" role="menu" id="'+b.menuId+'" data-contextify-id="'+b.id+'"/>');d.data(b);var e,f=b.items.length;for(e=0;e<f;e++){var h=b.items[e],i=a("<li/>");if(h.divider)i.addClass(b.dividerClass);else if(h.header)i.addClass(b.headerClass),i.html(h.header);else{i.append("<a/>");var j=i.find("a");if(h.href&&j.attr("href",h.href),h.onclick&&(j.on("click",b,h.onclick),j.css("cursor","pointer")),h.data){for(var k in h.data)d.attr("data-"+k,h.data[k]);j.data(h.data)}j.html(h.text)}d.append(i)}var l=a("#"+b.menuId);l.length>0?l!==d&&l.replaceWith(d):a("body").append(d);var m=g.width(),n=g.height(),o=d.outerWidth(),p=d.outerHeight(),q=o+c.clientX<m?c.clientX:m-o,r=p+c.clientY<n?c.clientY:n-p;d.css("top",r).css("left",q).css("position","fixed").show();if($("#rmenu").is(":visible")) d.hide()}).parents().on("mouseup",function(){a("#"+b.menuId).hide()}),g.on("scroll",function(){a("#"+b.menuId).hide()}),f++},c.prototype.destroy=function(){var b=a(this.element),c=a.extend({},this.options,b.data());b.removeAttr("data-contextify-id").off("contextmenu").parents().off("mouseup",function(){a("#"+c.menuId).hide()}),g.off("scroll",function(){a("#"+c.menuId).hide()}),a("#"+c.menuId).remove()},a.fn[d]=function(b){return this.each(function(){a.data(this,"plugin_"+d)&&"[object String]"===Object.prototype.toString.call(b)?a.data(this,"plugin_"+d)[b]():a.data(this,"plugin_"+d)||a.data(this,"plugin_"+d,new c(this,b))})}});
|
||||
//# sourceMappingURL=jquery.contextify.min.js.map
|
||||
(function(factory){if(typeof define==="function"&&define.amd){define(["jquery"],factory)}else{factory(jQuery,window)}}(function($,window){var pluginName="contextify",defaults={items:[],action:"contextmenu",menuId:"contextify-menu",menuClass:"dropdown-menu",headerClass:"dropdown-header",dividerClass:"divider",before:false},contextifyId=0;function Plugin(element,options){this.element=element;this.options=$.extend({},defaults,options);this._defaults=defaults;this._name=pluginName;this.init()}Plugin.prototype.init=function(){var options=$.extend({},this.options,$(this.element).data()),that=$(this);options.id=contextifyId;$(this.element).attr("data-contextify-id",options.id).on("contextmenu",function(e){e.preventDefault();if(typeof(options.before)==="function"){options.before(this,options)}var menu=$('<ul class="'+options.menuClass+'" role="menu" id="'+options.menuId+'" data-contextify-id="'+options.id+'"/>');menu.data(options);var l=options.items.length;var i;for(i=0;i<l;i++){var item=options.items[i];var el=$("<li/>");if(item.divider){el.addClass(options.dividerClass)}else{if(item.header){el.addClass(options.headerClass);el.html(item.header)}else{el.append("<a/>");var a=el.find("a");if(item.href){a.attr("href",item.href)}if(item.onclick){a.on("click",options,item.onclick);a.css("cursor","pointer")}if(item.data){for(var data in item.data){menu.attr("data-"+data,item.data[data])}a.data(item.data)}a.html(item.text)}}menu.append(el)}var currentMenu=$("#"+options.menuId);if(currentMenu.length>0){if(currentMenu!==menu){currentMenu.replaceWith(menu)}}else{$("body").append(menu)}var clientTop=$(window).scrollTop()+e.clientY,x=(menu.width()+e.clientX<$(window).width())?e.clientX:e.clientX-menu.width(),y=(menu.height()+e.clientY<$(window).height())?clientTop:clientTop-menu.height();menu.css("top",y).css("left",x).css("position","fixed").show();$(document).one("click",function(e){$("#"+options.menuId).hide();e.preventDefault()})}).one("click",function(e){$("#"+options.menuId).hide();e.preventDefault()});contextifyId++};Plugin.prototype.destroy=function(){var el=$(this.element),options=$.extend({},this.options,el.data()),menu=$("#"+options.menuId);el.removeAttr("data-contextify-id").off("contextmenu").parents().off("mouseup",function(){menu.hide()});menu.remove()};$.fn[pluginName]=function(options){return this.each(function(){if($.data(this,"plugin_"+pluginName)&&Object.prototype.toString.call(options)==="[object String]"){$.data(this,"plugin_"+pluginName)[options]()}else{if(!$.data(this,"plugin_"+pluginName)){$.data(this,"plugin_"+pluginName,new Plugin(this,options))}}})}}));
|
||||
@@ -1,7 +1,103 @@
|
||||
$(document).ready(function() {
|
||||
$(".sub-menu a.sub-menu-a").click(function() {
|
||||
$(this).next(".sub").slideToggle("slow").siblings(".sub:visible").slideUp("slow");
|
||||
$(function(){
|
||||
$.fn.extend({
|
||||
fixedThead:function(options){
|
||||
var _that = $(this);
|
||||
console.log(_that);
|
||||
var option = {
|
||||
height:400,
|
||||
shadow:true,
|
||||
resize:true
|
||||
};
|
||||
options = $.extend(option,options);
|
||||
if($(this).find('table').length === 0){
|
||||
return false;
|
||||
}
|
||||
var _height = $(this)[0].style.height,_table_config = _height.match(/([0-9]+)([%\w]+)/);
|
||||
if(_table_config === null){
|
||||
_table_config = [null,options.height,'px'];
|
||||
}else{
|
||||
$(this).css({
|
||||
'boxSizing': 'content-box',
|
||||
'paddingBottom':$(this).find('thead').height()
|
||||
});
|
||||
}
|
||||
$(this).css({'position':'relative'});
|
||||
var _thead = $(this).find('thead')[0].outerHTML,
|
||||
_tbody = $(this).find('tbody')[0].outerHTML,
|
||||
_thead_div = $('<div class="thead_div"><table class="table table-hover mb0"></table></div>'),
|
||||
_shadow_top = $('<div class="tbody_shadow_top"></div>'),
|
||||
_tbody_div = $('<div class="tbody_div" style="height:'+ _table_config[1] + _table_config[2] +';"><table class="table table-hover mb0" style="margin-top:-'+ $(this).find('thead').height() +'px"></table></div>'),
|
||||
_shadow_bottom = $('<div class="tbody_shadow_bottom"></div>');
|
||||
_thead_div.find('table').append(_thead);
|
||||
_tbody_div.find('table').append(_thead);
|
||||
_tbody_div.find('table').append(_tbody);
|
||||
$(this).html('');
|
||||
$(this).append(_thead_div);
|
||||
$(this).append(_shadow_top);
|
||||
$(this).append(_tbody_div);
|
||||
$(this).append(_shadow_bottom);
|
||||
var _table_width = _that.find('.thead_div table')[0].offsetWidth,
|
||||
_body_width = _that.find('.tbody_div table')[0].offsetWidth,
|
||||
_length = _that.find('tbody tr:eq(0)>td').length;
|
||||
$(this).find('tbody tr:eq(0)>td').each(function(index,item){
|
||||
var _item = _that.find('thead tr:eq(0)>th').eq(index);
|
||||
if(index === (_length-1)){
|
||||
_item.attr('width',$(item)[0].clientWidth + (_table_width - _body_width));
|
||||
}else{
|
||||
_item.attr('width',$(item)[0].offsetWidth);
|
||||
}
|
||||
});
|
||||
if(options.resize){
|
||||
$(window).resize(function(){
|
||||
var _table_width = _that.find('.thead_div table')[0].offsetWidth,
|
||||
_body_width = _that.find('.tbody_div table')[0].offsetWidth,
|
||||
_length = _that.find('tbody tr:eq(0)>td').length;
|
||||
_that.find('tbody tr:eq(0)>td').each(function(index,item){
|
||||
var _item = _that.find('thead tr:eq(0)>th').eq(index);
|
||||
if(index === (_length-1)){
|
||||
_item.attr('width',$(item)[0].clientWidth + (_table_width - _body_width));
|
||||
}else{
|
||||
_item.attr('width',$(item)[0].offsetWidth);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
if(options.shadow){
|
||||
var table_body = $(this).find('.tbody_div')[0];
|
||||
if(_table_config[1] >= table_body.scrollHeight){
|
||||
$(this).find('.tbody_shadow_top').hide();
|
||||
$(this).find('.tbody_shadow_bottom').hide();
|
||||
}else{
|
||||
$(this).find('.tbody_shadow_top').hide();
|
||||
$(this).find('.tbody_shadow_bottom').show();
|
||||
}
|
||||
$(this).find('.tbody_div').scroll(function(e){
|
||||
var _scrollTop = $(this)[0].scrollTop,
|
||||
_scrollHeight = $(this)[0].scrollHeight,
|
||||
_clientHeight = $(this)[0].clientHeight,
|
||||
_shadow_top = _that.find('.tbody_shadow_top'),
|
||||
_shadow_bottom = _that.find('.tbody_shadow_bottom');
|
||||
if(_scrollTop == 0){
|
||||
_shadow_top.hide();
|
||||
_shadow_bottom.show();
|
||||
}else if(_scrollTop > 0 && _scrollTop < (_scrollHeight - _clientHeight)){
|
||||
_shadow_top.show();
|
||||
_shadow_bottom.show();
|
||||
}else if(_scrollTop == (_scrollHeight - _clientHeight)){
|
||||
_shadow_top.show();
|
||||
_shadow_bottom.hide();
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}(jQuery))
|
||||
|
||||
$(document).ready(function() {
|
||||
$(".sub-menu a.sub-menu-a").click(function() {
|
||||
$(this).next(".sub").slideToggle("slow").siblings(".sub:visible").slideUp("slow");
|
||||
});
|
||||
});
|
||||
var aceEditor = {
|
||||
layer_view: '',
|
||||
@@ -83,57 +179,67 @@ var aceEditor = {
|
||||
// 事件编辑器-方法,事件绑定
|
||||
eventEditor: function() {
|
||||
var _this = this,_icon = '<span class="icon"><i class="glyphicon glyphicon-ok" aria-hidden="true"></i></span>';
|
||||
$(window).resize(function() {
|
||||
var _id = $('.ace_conter_menu .active').attr('data-id');
|
||||
if (_id != undefined) {
|
||||
aceEditor.editor['ace_editor_' + _id].ace.resize();
|
||||
//_this.setEditorView()
|
||||
$(window).resize(function(){
|
||||
if(_this.ace_active != undefined) _this.setEditorView()
|
||||
if( $('.aceEditors .layui-layer-maxmin').length >0){
|
||||
$('.aceEditors').css({
|
||||
'top':0,
|
||||
'left':0,
|
||||
'width':$(this)[0].innerWidth,
|
||||
'height':$(this)[0].innerHeight
|
||||
});
|
||||
}
|
||||
});
|
||||
$('.ace_editor_main').on('click',function(){
|
||||
})
|
||||
$(document).click(function(e){
|
||||
$('.ace_toolbar_menu').hide();
|
||||
$('.ace_conter_editor .ace_editors').css('fontSize', _this.aceConfig.aceEditor.fontSize + 'px');
|
||||
$('.ace_toolbar_menu .menu-tabs,.ace_toolbar_menu .menu-encoding,.ace_toolbar_menu .menu-files').hide();
|
||||
});
|
||||
$('.ace_editor_main').on('click',function(){
|
||||
$('.ace_toolbar_menu').hide();
|
||||
});
|
||||
$(document).click(function(e) {
|
||||
$('.ace_toolbar_menu').hide();
|
||||
$('.ace_toolbar_menu .menu-tabs,.ace_toolbar_menu .menu-encoding,.ace_toolbar_menu .menu-files').hide();
|
||||
})
|
||||
// 显示工具条
|
||||
$('.ace_header .pull-down').click(function() {
|
||||
if ($(this).find('i').hasClass('glyphicon-menu-down')) {
|
||||
$('.ace_header').css({ 'marginTop': '-35px', 'height': '0' });
|
||||
$(this).css({ 'top': '35px', 'height': '40px', 'line-height': '40px' });
|
||||
$(this).find('i').addClass('glyphicon-menu-up').removeClass('glyphicon-menu-down');
|
||||
} else {
|
||||
$('.ace_header').removeAttr('style');
|
||||
$('.ace_toolbar_menu').click(function(e){
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
});
|
||||
// 显示工具条
|
||||
$('.ace_header .pull-down').click(function(){
|
||||
if($(this).find('i').hasClass('glyphicon-menu-down')){
|
||||
$('.ace_header').css({'top':'-35px'});
|
||||
$('.ace_overall').css({'top':'0'});
|
||||
$(this).css({'top':'35px','height':'40px','line-height':'40px'});
|
||||
$(this).find('i').addClass('glyphicon-menu-up').removeClass('glyphicon-menu-down');
|
||||
}else{
|
||||
$('.ace_header').css({'top':'0'});
|
||||
$('.ace_overall').css({'top':'35px'});
|
||||
$(this).removeAttr('style');
|
||||
$(this).find('i').addClass('glyphicon-menu-down').removeClass('glyphicon-menu-up');
|
||||
}
|
||||
_this.setEditorView();
|
||||
});
|
||||
$(this).find('i').addClass('glyphicon-menu-down').removeClass('glyphicon-menu-up');
|
||||
}
|
||||
_this.setEditorView();
|
||||
});
|
||||
// 切换TAB视图
|
||||
$('.ace_conter_menu').on('click', '.item', function(e) {
|
||||
var _id = $(this).attr('data-id'),
|
||||
_item = _this.editor['ace_editor_' + _id]
|
||||
$('.item_tab_' + _id).addClass('active').siblings().removeClass('active');
|
||||
$('#ace_editor_' + _id).addClass('active').siblings().removeClass('active');
|
||||
_this.ace_active = _id;
|
||||
_this.currentStatusBar(_id);
|
||||
_this.is_file_history(_item);
|
||||
});
|
||||
// 移上TAB按钮变化,仅文件被修改后
|
||||
$('.ace_conter_menu').on('mouseover', '.item .icon-tool', function() {
|
||||
var type = $(this).attr('data-file-state');
|
||||
if (type != '0') {
|
||||
$(this).removeClass('glyphicon-exclamation-sign').addClass('glyphicon-remove');
|
||||
}
|
||||
});
|
||||
// 移出tab按钮变化,仅文件被修改后
|
||||
$('.ace_conter_menu').on('mouseout', '.item .icon-tool', function() {
|
||||
var type = $(this).attr('data-file-state');
|
||||
if (type != '0') {
|
||||
$(this).removeClass('glyphicon-remove').addClass('glyphicon-exclamation-sign');
|
||||
}
|
||||
});
|
||||
$('.ace_conter_menu').on('click', '.item', function (e) {
|
||||
var _id = $(this).attr('data-id'),_item = _this.editor['ace_editor_' + _id];
|
||||
$('.item_tab_'+ _id).addClass('active').siblings().removeClass('active');
|
||||
$('#ace_editor_'+ _id).addClass('active').siblings().removeClass('active');
|
||||
_this.ace_active = _id;
|
||||
_this.currentStatusBar(_id);
|
||||
_this.is_file_history(_item);
|
||||
});
|
||||
// 移上TAB按钮变化,仅文件被修改后
|
||||
$('.ace_conter_menu').on('mouseover', '.item .icon-tool', function () {
|
||||
var type = $(this).attr('data-file-state');
|
||||
if (type != '0') {
|
||||
$(this).removeClass('glyphicon-exclamation-sign').addClass('glyphicon-remove');
|
||||
}
|
||||
});
|
||||
// 移出tab按钮变化,仅文件被修改后
|
||||
$('.ace_conter_menu').on('mouseout', '.item .icon-tool', function () {
|
||||
var type = $(this).attr('data-file-state');
|
||||
if (type != '0') {
|
||||
$(this).removeClass('glyphicon-remove').addClass('glyphicon-exclamation-sign');
|
||||
}
|
||||
});
|
||||
// 关闭编辑视图
|
||||
$('.ace_conter_menu').on('click', '.item .icon-tool', function(e) {
|
||||
var file_type = $(this).attr('data-file-state');
|
||||
@@ -192,8 +298,16 @@ var aceEditor = {
|
||||
});
|
||||
break;
|
||||
}
|
||||
e.stopPropagation();
|
||||
$('.ace_toolbar_menu').hide();
|
||||
$('.ace_toolbar_menu .menu-tabs,.ace_toolbar_menu .menu-encoding,.ace_toolbar_menu .menu-files').hide();
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
});
|
||||
$(window).keyup(function(e){
|
||||
if(e.keyCode === 116 && $('#ace_conter').length == 1){
|
||||
layer.msg('Unable to refresh in editor mode. Please close and try again');
|
||||
}
|
||||
});
|
||||
// 新建编辑器视图
|
||||
$('.ace_editor_add').click(function() {
|
||||
_this.addEditorView();
|
||||
@@ -327,7 +441,7 @@ var aceEditor = {
|
||||
_this.searchRelevance()
|
||||
});
|
||||
// 顶部状态栏
|
||||
$('.ace_header span').click(function(e) {
|
||||
$('.ace_header>span').click(function(e) {
|
||||
var type = $(this).attr('class'),
|
||||
editor_item = _this.editor['ace_editor_' + _this.ace_active];
|
||||
var _icon = '<span class="icon"><i class="glyphicon glyphicon-ok" aria-hidden="true"></i></span>';
|
||||
@@ -2095,7 +2209,8 @@ function format_form_data(form_data){
|
||||
|
||||
function ajax_encrypt(request){
|
||||
if(!this.type || !this.data || !this.contentType) return;
|
||||
if($("#panel_debug").attr("data") == 'True') return;
|
||||
if($("#panel_debug").attr("data") == 'True') return;
|
||||
if($("#panel_debug").attr("data-pyversion") == '2') return;
|
||||
if(this.type == 'POST' && this.data.length > 1){
|
||||
this.data = format_form_data(this.data);
|
||||
}
|
||||
@@ -2118,8 +2233,8 @@ function ajaxSetup() {
|
||||
if (my_headers) {
|
||||
$.ajaxSetup({
|
||||
headers: my_headers,
|
||||
dataFilter: ajax_decrypt,
|
||||
beforeSend: ajax_encrypt
|
||||
// dataFilter: ajax_decrypt,
|
||||
// beforeSend: ajax_encrypt
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -2269,6 +2384,11 @@ function GetDiskList(b) {
|
||||
var a = "";
|
||||
var c = "path=" + b + "&disk=True";
|
||||
$.post("/files?action=GetDir", c, function(h) {
|
||||
if(h.status == false) {
|
||||
layer.close(layer.index);
|
||||
layer.msg(h.msg,{icon: 2});
|
||||
return false;
|
||||
}
|
||||
if (h.DISK != undefined) {
|
||||
for (var f = 0; f < h.DISK.length; f++) {
|
||||
a += "<dd onclick=\"GetDiskList('" + h.DISK[f].path + "')\"><span class='glyphicon glyphicon-hdd'></span> " + h.DISK[f].path + "</dd>"
|
||||
@@ -2995,7 +3115,7 @@ function setUserName(a) {
|
||||
var checks = ['admin', 'root', 'admin123', '123456'];
|
||||
|
||||
if ($.inArray(p1, checks) >= 0) {
|
||||
layer.msg(lan.index.usually_username_ban, {
|
||||
layer.msg(lan.public.usually_username_ban, {
|
||||
icon: 2
|
||||
});
|
||||
return;
|
||||
@@ -3812,7 +3932,7 @@ var Term = {
|
||||
route: '/webssh', //被访问的方法
|
||||
term: null,
|
||||
term_box: null,
|
||||
ssh_info: null,
|
||||
ssh_info: {},
|
||||
last_body:false,
|
||||
last_cd:null,
|
||||
config:{
|
||||
@@ -3864,8 +3984,8 @@ var Term = {
|
||||
//连接服务器成功
|
||||
on_open:function(ws_event){
|
||||
Term.send(JSON.stringify(Term.ssh_info || {}))
|
||||
Term.term.FitAddon.fit();
|
||||
Term.resize();
|
||||
// Term.term.FitAddon.fit();
|
||||
// Term.resize();
|
||||
var f_path = $("#fileInputPath").val();
|
||||
if(f_path){
|
||||
Term.last_cd = "cd " + f_path;
|
||||
@@ -3892,7 +4012,13 @@ var Term = {
|
||||
// }
|
||||
// },
|
||||
on_message: function (ws_event) {
|
||||
result = ws_event.data;
|
||||
result = ws_event.data;
|
||||
if ((result.indexOf("@127.0.0.1:") != -1 || result.indexOf("@localhost:") != -1) && result.indexOf('Authentication failed') != -1) {
|
||||
Term.term.write(result);
|
||||
Term.localhost_login_form(result);
|
||||
Term.close();
|
||||
return;
|
||||
}
|
||||
if(Term.last_cd){
|
||||
if(result.indexOf(Term.last_cd) != -1 && result.length - Term.last_cd.length < 3) {
|
||||
Term.last_cd = null;
|
||||
@@ -3956,7 +4082,7 @@ var Term = {
|
||||
Term.term.FitAddon.fit()
|
||||
Term.send(JSON.stringify({resize:1,rows:Term.term.rows,cols:Term.term.cols}));
|
||||
Term.term.focus();
|
||||
},200)
|
||||
},100)
|
||||
},
|
||||
// resize: function() {
|
||||
// var m_width = 100;
|
||||
@@ -4046,26 +4172,26 @@ var Term = {
|
||||
],function(){
|
||||
layer.close(loadT);
|
||||
Term.term = new Terminal({
|
||||
rendererType: "canvas",
|
||||
cols: 100,
|
||||
rows: 34,
|
||||
fontSize:15,
|
||||
screenKeys: true,
|
||||
useStyle: true ,
|
||||
});
|
||||
rendererType: "canvas",
|
||||
cols: 100,
|
||||
rows: 31,
|
||||
fontSize:15,
|
||||
screenKeys: true,
|
||||
useStyle: true ,
|
||||
});
|
||||
Term.term.setOption('cursorBlink', true);
|
||||
Term.last_body = false;
|
||||
Term.term_box = layer.open({
|
||||
type: 1,
|
||||
title: lan.public.terminal,
|
||||
area: ['920px', '630px'],
|
||||
area: ['925px', '630px'],
|
||||
closeBtn: 2,
|
||||
shadeClose: false,
|
||||
skin:'term_box_all',
|
||||
content: '<link rel="stylesheet" href="/static/css/xterm.css" />\
|
||||
<div class="term-box" style="background-color:#000" id="term"></div>',
|
||||
<div class="term-box" style="background-color:#000;padding-top: 7px;" id="term"></div>',
|
||||
cancel: function (index,lay) {
|
||||
bt.confirm({msg:'Closing the SSH session, the command in progress in the current command line session may be aborted. Continute?',title: "Cofirm to close the SSH session?"},function(ix){
|
||||
bt.confirm({msg:'<div style="word-break: break-word;">Closing the SSH session, the command in progress in the current command line session may be aborted. Continute?</div>',title: "Cofirm to close the SSH session?"},function(ix){
|
||||
Term.term.dispose();
|
||||
layer.close(index);
|
||||
layer.close(ix);
|
||||
@@ -4080,6 +4206,7 @@ var Term = {
|
||||
Term.term.loadAddon(Term.term.FitAddon);
|
||||
Term.term.WebLinksAddon = new WebLinksAddon.WebLinksAddon()
|
||||
Term.term.loadAddon(Term.term.WebLinksAddon)
|
||||
Term.term.focus();
|
||||
}
|
||||
});
|
||||
Term.term.onData(function (data) {
|
||||
@@ -4114,7 +4241,121 @@ var Term = {
|
||||
Term.term.scrollToBottom();
|
||||
Term.term.focus();
|
||||
});
|
||||
},
|
||||
localhost_login_form:function(result){
|
||||
var template = '<div class="localhost-form-shade"><div class="localhost-form-view bt-form-2x"><div class="localhost-form-title"><i class="localhost-form_tip"></i><span style="vertical-align: middle;">Login failed, please fill the local server information!</span></div>\
|
||||
<div class="line input_group">\
|
||||
<span class="tname">Server IP</span>\
|
||||
<div class="info-r">\
|
||||
<input type="text" name="host" class="bt-input-text mr5" style="width:240px" placeholder="Server IP" value="127.0.0.1" autocomplete="off" />\
|
||||
<input type="text" name="port" class="bt-input-text mr5" style="width:60px" placeholder="Port" value="22" autocomplete="off"/>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="line">\
|
||||
<span class="tname">SSH account</span>\
|
||||
<div class="info-r">\
|
||||
<input type="text" name="username" class="bt-input-text mr5" style="width:305px" placeholder="SSH account" value="root" autocomplete="off"/>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="line">\
|
||||
<span class="tname">Verification</span>\
|
||||
<div class="info-r ">\
|
||||
<div class="btn-group">\
|
||||
<button type="button" tabindex="-1" class="btn btn-sm auth_type_checkbox btn-success" data-ctype="0">Password</button>\
|
||||
<button type="button" tabindex="-1" class="btn btn-sm auth_type_checkbox btn-default data-ctype="1">Server key</button>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="line c_password_view show">\
|
||||
<span class="tname">Password</span>\
|
||||
<div class="info-r">\
|
||||
<input type="text" name="password" class="bt-input-text mr5" placeholder="SSH Password" style="width:305px;" value="" autocomplete="off"/>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="line c_pkey_view hidden">\
|
||||
<span class="tname">Private key</span>\
|
||||
<div class="info-r">\
|
||||
<textarea rows="4" name="pkey" class="bt-input-text mr5" placeholder="SSH server key" style="width:305px;height: 80px;line-height: 18px;padding-top:10px;"></textarea>\
|
||||
</div>\
|
||||
</div><button type="submit" class="btn btn-sm btn-success">Login</button></div></div>';
|
||||
$('.term-box').after(template);
|
||||
$('.auth_type_checkbox').click(function(){
|
||||
var index = $(this).index();
|
||||
$(this).addClass('btn-success').removeClass('btn-default').siblings().removeClass('btn-success').addClass('btn-default')
|
||||
switch(index){
|
||||
case 0:
|
||||
$('.c_password_view').addClass('show').removeClass('hidden');
|
||||
$('.c_pkey_view').addClass('hidden').removeClass('show').find('input').val('');
|
||||
break;
|
||||
case 1:
|
||||
$('.c_password_view').addClass('hidden').removeClass('show').find('input').val('');
|
||||
$('.c_pkey_view').addClass('show').removeClass('hidden');
|
||||
break;
|
||||
}
|
||||
});
|
||||
$('.localhost-form-view > button').click(function(){
|
||||
var form = {};
|
||||
$('.localhost-form-view input,.localhost-form-view textarea').each(function(index,el){
|
||||
var name = $(this).attr('name'),value = $(this).val();
|
||||
form[name] = value;
|
||||
switch(name){
|
||||
case 'port':
|
||||
if(!bt.check_port(value)){
|
||||
bt.msg({status:false,msg:'Server port format error!'});
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'username':
|
||||
if(value == ''){
|
||||
bt.msg({status:false,msg:'Server user name cannot be empty!'});
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'password':
|
||||
if(value == '' && $('.c_password_view').hasClass('show')){
|
||||
bt.msg({status:false,msg:'Server password cannot be empty!'});
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'pkey':
|
||||
if(value == '' && $('.c_pkey_view').hasClass('show')){
|
||||
bt.msg({status:false,msg:'The server key cannot be empty!'});
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
form.ps = 'Local server';
|
||||
|
||||
if(result){
|
||||
if(result.indexOf('@127.0.0.1') != -1){
|
||||
var user = result.split('@')[0].split(',')[1];
|
||||
var port = result.split('1:')[1]
|
||||
$("input[name='username']").val(user);
|
||||
$("input[name='port']").val(port);
|
||||
}
|
||||
}
|
||||
var loadT = bt.load('Adding server information, please wait...');
|
||||
bt.send('create_host','xterm/create_host',form,function(res){
|
||||
loadT.close();
|
||||
bt.msg(res);
|
||||
if(res.status){
|
||||
bt.msg({status:true,msg:'Login successful!'});
|
||||
$('.layui-layer-shade').remove();
|
||||
$('.term_box_all').remove();
|
||||
Term.term.dispose();
|
||||
Term.close();
|
||||
web_shell();
|
||||
}
|
||||
});
|
||||
});
|
||||
$('.localhost-form-view [name="password"]').keyup(function(e){
|
||||
if(e.keyCode == 13){
|
||||
$('.localhost-form-view > button').click();
|
||||
}
|
||||
}).focus()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function web_shell() {
|
||||
|
||||
@@ -7,45 +7,33 @@ var soft = {
|
||||
if (search == undefined || search == 'null' || search == 'undefined' || search == '') search = undefined;
|
||||
var _this = this;
|
||||
var istype = getCookie('softType');
|
||||
if (istype == 'undefined' || istype == 'null' || !istype) {
|
||||
if(istype == 'undefined' || istype == 'null' || !istype){
|
||||
istype = 0;
|
||||
}
|
||||
if (type == 0) type = bt.get_cookie('softType');
|
||||
if (page == 0) page = bt.get_cookie('p' + type);
|
||||
if (type == '11') {
|
||||
soft.get_dep_list(1)
|
||||
if (type == '11'){
|
||||
soft.get_dep_list(1);
|
||||
return;
|
||||
}
|
||||
soft.is_install = false;
|
||||
console.log(type)
|
||||
bt.soft.get_soft_list(page, type, search, function(rdata) {
|
||||
if (rdata.pro < 0) {
|
||||
$("#updata_pro_info").html('');
|
||||
} else if (rdata.pro === -2) {
|
||||
$("#updata_pro_info").html('<div class="alert alert-success" style="margin-bottom:15px"><strong>' + lan.soft.pro_expire + '</strong><button class="btn btn-success btn-xs va0 updata_pro" onclick="bt.soft.updata_pro()" title="' + lan.soft.renew_pro + '" style="margin-left:8px">' + lan.soft.renew_now + '</button>');
|
||||
} else if (rdata.pro === -1) {
|
||||
$("#updata_pro_info").html('<div class="alert alert-success" style="margin-bottom:15px"><strong > ' + lan.soft.upgrade_pro + '</strong><button class="btn btn-success btn-xs va0 updata_pro" onclick="bt.soft.updata_pro()" title="' + lan.soft.upgrade_pro_now + '" style="margin-left:8px">' + lan.soft.upgrade_now + '</button>\</div>');
|
||||
}
|
||||
soft.set_soft_tips('#updata_pro_info',type);
|
||||
// if (rdata.pro < 0) {
|
||||
// $("#updata_pro_info").html('');
|
||||
// } else if (rdata.pro === -2) {
|
||||
// $("#updata_pro_info").html('<div class="alert alert-success" style="margin-bottom:15px"><strong>' + lan.soft.pro_expire + '</strong><button class="btn btn-success btn-xs va0 updata_pro" onclick="bt.soft.updata_pro()" title="' + lan.soft.renew_pro + '" style="margin-left:8px">' + lan.soft.renew_now + '</button>');
|
||||
// } else if (rdata.pro === -1) {
|
||||
// $("#updata_pro_info").html('<div class="alert alert-success" style="margin-bottom:15px"><strong > ' + lan.soft.upgrade_pro + '</strong><button class="btn btn-success btn-xs va0 updata_pro" onclick="bt.soft.updata_pro()" title="' + lan.soft.upgrade_pro_now + '" style="margin-left:8px">' + lan.soft.upgrade_now + '</button>\</div>');
|
||||
// }
|
||||
|
||||
if (type == 10) {
|
||||
$("#updata_pro_info").html('<div class="alert alert-danger" style="margin-bottom:15px"><strong>' + lan.soft.bt_developer + '</strong><a class="btn btn-success btn-xs va0" href="https://www.aapanel.com" title="' + lan.soft.get_third_party_apps + '" style="margin-left: 8px" target="_blank">' + lan.soft.get_third_party_apps + '</a><input type="file" style="display:none;" accept=".zip,.tar.gz" id="update_zip" multiple="multiple"><button class="btn btn-success btn-xs" onclick="soft.update_zip_open()" style="margin-left:8px">' + lan.soft.import_plug + '</button></div>')
|
||||
} else if (type == 11) {
|
||||
$("#updata_pro_info").html('<div class="alert alert-info" style="margin-bottom:15px"><strong>' + lan.soft.comingsoon + '</strong></div>')
|
||||
}
|
||||
// if (type == 10) {
|
||||
// $("#updata_pro_info").html('<div class="alert alert-danger" style="margin-bottom:15px"><strong>' + lan.soft.bt_developer + '</strong><a class="btn btn-success btn-xs va0" href="https://www.aapanel.com" title="' + lan.soft.get_third_party_apps + '" style="margin-left: 8px" target="_blank">' + lan.soft.get_third_party_apps + '</a><input type="file" style="display:none;" accept=".zip,.tar.gz" id="update_zip" multiple="multiple"><button class="btn btn-success btn-xs" onclick="soft.update_zip_open()" style="margin-left:8px">' + lan.soft.import_plug + '</button></div>')
|
||||
// } else if (type == 11) {
|
||||
// $("#updata_pro_info").html('<div class="alert alert-info" style="margin-bottom:15px"><strong>' + lan.soft.comingsoon + '</strong></div>')
|
||||
// }
|
||||
var tBody = '';
|
||||
rdata.type.unshift({
|
||||
icon: 'icon',
|
||||
id: 0,
|
||||
ps: lan.soft.all,
|
||||
sort: 1,
|
||||
title: lan.soft.all
|
||||
}, {
|
||||
icon: 'icon',
|
||||
id: -1,
|
||||
ps: 'Installed',
|
||||
sort: 1,
|
||||
title: 'Installed'
|
||||
})
|
||||
rdata.type.unshift({icon: 'icon',id: 0,ps: lan.soft.all,sort: 1,title: lan.soft.all}, {icon: 'icon',id: -1,ps: 'Installed',sort: 1,title: 'Installed'})
|
||||
for (var i = 0; i < rdata.type.length; i++) {
|
||||
var c = '';
|
||||
if (istype == rdata.type[i].id) {
|
||||
@@ -53,7 +41,7 @@ var soft = {
|
||||
}
|
||||
// 注释软件管理的付费插件,第三方插件,一键部署
|
||||
// if (rdata.type[i].id != "11" && rdata.type[i].id != "10" && rdata.type[i].id != "8") {
|
||||
if (rdata.type[i].id != "11" && rdata.type[i].id != "8") {
|
||||
if (rdata.type[i].id != "11") {
|
||||
tBody += '<span typeid="' + rdata.type[i].id + '" ' + c + '>' + rdata.type[i].title + '</span>';
|
||||
}
|
||||
}
|
||||
@@ -130,7 +118,7 @@ var soft = {
|
||||
{
|
||||
field: 'price',
|
||||
title: 'Developer',
|
||||
width: 92,
|
||||
width: 110,
|
||||
templet: function(item) {
|
||||
if (!item.author) return 'official'
|
||||
return item.author;
|
||||
@@ -164,17 +152,17 @@ var soft = {
|
||||
templet: function(item) {
|
||||
var price = lan.soft.free;
|
||||
if (item.price > 0) {
|
||||
price = '<span style="color:#fc6d26">¥' + item.price + '</span>';
|
||||
price = '<span style="color:#fc6d26">$' + item.price + '</span>';
|
||||
}
|
||||
return price;
|
||||
}
|
||||
},
|
||||
(type == 10 ? {
|
||||
field: 'sort',
|
||||
width: 60,
|
||||
title: 'Score',
|
||||
width: 80,
|
||||
title: 'Rated',
|
||||
templet: function(item) {
|
||||
return item.sort !== undefined ? ('<a href="javascript:;" onclick="score.open_score_view(' + item.pid + ',\'' + item.title + '\',' + item.count + ')" class="btlink open_sort_view">' + (item.sort <= 0 || item.sort > 5 ? '无评分' : item.sort.toFixed(1)) + '</a>') : '--';
|
||||
return item.sort !== undefined ? ('<a href="javascript:;" onclick="score.open_score_view(' + item.pid + ',\'' + item.title + '\',' + item.count + ')" class="btlink open_sort_view">' + (item.sort <= 0 || item.sort > 5 ? lan.soft.not_rated : item.sort.toFixed(1)) + '</a>') : '--';
|
||||
}
|
||||
} : ''),
|
||||
{
|
||||
@@ -186,9 +174,9 @@ var soft = {
|
||||
if (item.pid > 0) {
|
||||
if (item.endtime > 0) {
|
||||
if (item.type != 10) {
|
||||
endtime = bt.format_data(item.endtime, 'yyyy/MM/dd') + '<a class="btlink" onclick="bt.soft.re_plugin_pay(\'' + item.title + '\',\'' + item.pid + '\',1)"> (' + lan.soft.renew + ')</a>';
|
||||
endtime = bt.format_data(item.endtime, 'yyyy/MM/dd') ;
|
||||
} else {
|
||||
endtime = bt.format_data(item.endtime, 'yyyy/MM/dd') + '<a class="btlink" onclick="bt.soft.re_plugin_pay_other(\'' + item.title + '\',\'' + item.pid + '\',1,' + item.price + ')"> (' + lan.soft.renew + ')</a>';
|
||||
endtime = bt.format_data(item.endtime, 'yyyy/MM/dd') ;
|
||||
}
|
||||
} else if (item.endtime === 0) {
|
||||
endtime = lan.soft.permanent;
|
||||
@@ -196,9 +184,9 @@ var soft = {
|
||||
endtime = lan.soft.not_open;
|
||||
} else if (item.endtime === -2) {
|
||||
if (item.type != 10) {
|
||||
endtime = lan.soft.already_expire + '<a class="btlink" onclick="bt.soft.re_plugin_pay(\'' + item.title + '\',\'' + item.pid + '\',1)"> (' + lan.soft.renew + ')</a>';
|
||||
endtime = lan.soft.already_expire ;
|
||||
} else {
|
||||
endtime = lan.soft.already_expire + '<a class="btlink" onclick="bt.soft.re_plugin_pay_other(\'' + item.title + '\',\'' + item.pid + '\',1,' + item.price + ')"> (' + lan.soft.renew + ')</a>';
|
||||
endtime = lan.soft.already_expire ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -270,7 +258,7 @@ var soft = {
|
||||
break;
|
||||
}
|
||||
if (item.type != 10) {
|
||||
pay_opt = '<a class="btlink" onclick="bt.soft.re_plugin_pay(\'' + item.title + '\',\'' + item.pid + '\',' + re_status + ')">' + re_msg + '</a>';
|
||||
pay_opt = '<a class="btlink" onclick=\'bt.soft.product_pay_view('+ JSON.stringify({name:item.title,pid:item.pid,type:item.type,plugin:true,renew:item.endtime}) +')\'>' + re_msg + '</a>';
|
||||
} else {
|
||||
pay_opt = '<a class="btlink" onclick="bt.soft.re_plugin_pay_other(\'' + item.title + '\',\'' + item.pid + '\',' + re_status + ',' + item.price + ')">' + re_msg + '</a>';
|
||||
}
|
||||
@@ -405,6 +393,191 @@ var soft = {
|
||||
}
|
||||
})
|
||||
},
|
||||
// 渲染列表
|
||||
render_promote_list:function(data){
|
||||
if($('#soft_recom_list').length > 0) $('#soft_recom_list').remove();
|
||||
var html = $('<ul id="soft_recom_list" class="recom_list"></ul>'),that = this;
|
||||
for(var i=0;i< data.length;i++){
|
||||
var type = '', item = data[i];
|
||||
(function(item){
|
||||
switch (item.type) {
|
||||
case 'link': // 链接推荐
|
||||
type = $('<a href="'+ item.data +'" target="_blank" title="'+ (item.title || '') +'"><span>'+ (item.title || '') +'</span></a>');
|
||||
break;
|
||||
case 'soft': // 软件推荐
|
||||
case 'other': // 第三方推荐
|
||||
case 'onekey': // 一键部署推荐
|
||||
type = $('<a href="javascript:;" class="btlink" title="'+ (item.title || '') +'"><span>'+ (item.title || '') +'</span></a>').click(function(){
|
||||
that.render_promote_view(item);
|
||||
});
|
||||
break;
|
||||
}
|
||||
html.append($('<li></li>').append(type));
|
||||
}(item))
|
||||
// html.append($('<li><img src="'+ item.image +'"></li>').append(type));
|
||||
}
|
||||
$('#updata_pro_info').before(html);
|
||||
},
|
||||
// 渲染软件列表
|
||||
render_promote_view:function(find){
|
||||
var that = this,is_single_product = find.data.length > 1,find_data = find.data;
|
||||
if(is_single_product){
|
||||
layer.open({
|
||||
title:find.title,
|
||||
area:'800px',
|
||||
btn:false,
|
||||
closeBtn:2,
|
||||
shadeClose:false,
|
||||
content: (function(){
|
||||
var html = '';
|
||||
for(var i=0;i<find_data.length;i++){
|
||||
var item = find_data[i],thtml = '';
|
||||
if(!item.setup){
|
||||
thtml = '<button type="button" class="btn btn-success btn-xs" onclick="bt.soft.install(\''+ item.name +'\',this)">Install</button>';
|
||||
}else{
|
||||
if(item.pid != 0){
|
||||
if(item.endtime == 0){ //永久
|
||||
thtml = '<button type="button" class="btn btn-success btn-xs" onclick="bt.soft.set_lib_config(\''+ item.name +'\',\''+ item.title +'\')">Setting</button>';
|
||||
}else if(item.endtime > 0){ //已购买
|
||||
thtml = '<button type="button" class="btn btn-success btn-xs" onclick="bt.soft.set_lib_config(\''+ item.name +'\',\''+ item.title +'\')">Setting</button>';
|
||||
}else if(item.endtime == -1){ //未购买
|
||||
thtml = '<button type="button" class="btn btn-success btn-xs" onclick=\'bt.soft.product_pay_view('+ JSON.stringify({name:item.title,pid:item.pid,type:item.type,pulgin:true,renew:item.endtime}) +');\'>Upgrade now</button>';
|
||||
}else if(item.endtime == -2){ //已过期
|
||||
thtml = '<button type="button" class="btn btn-success btn-xs" onclick=\'bt.soft.product_pay_view('+ JSON.stringify({name:item.title,pid:item.pid,type:item.type,pulgin:true,renew:item.endtime}) +');\'>立即续费</button>';
|
||||
}
|
||||
}else{
|
||||
thtml = '<button type="button" class="btn btn-success btn-xs" onclick="bt.soft.set_lib_config(\''+ item.name +'\',\''+ item.title +'\')">Setting</button>';
|
||||
}
|
||||
}
|
||||
html += '<div class="recom_item_box">' +
|
||||
'<div class="recom_item_left">' +
|
||||
'<div class="recom_item_images"><img src="/static/img/'+(find.type == 'onekey'?'dep_ico':'soft_ico')+'/ico-'+ item.name +'.png" /></div>' +
|
||||
'<div class="recom_item_pay"><a href="javascript:;" class="btlink" style="color:'+(item.setup?'#20a53a':'#666')+'">'+ (item.setup?'Installed':'Not installed') +'</a></div>'+
|
||||
'</div>' +
|
||||
'<div class="recom_item_right">' +
|
||||
'<div class="recom_item_title">' +
|
||||
'<div class="recom_item_text">'+ item.title + ' v'+ item.version +'</div>' +
|
||||
'<div class="recom_item_price">$<span>'+ item.price +'</span>/month</div>' +
|
||||
'</div>' +
|
||||
'<div class="recom_item_info" title="'+ item.ps +'">'+ item.ps +'</div>'+
|
||||
'<div class="recom_item_btn">'+ thtml +'</div>'+
|
||||
'</div>' +
|
||||
'</div>'
|
||||
}
|
||||
return html;
|
||||
})(),
|
||||
});
|
||||
}
|
||||
},
|
||||
set_soft_tips:function(el,type){
|
||||
var tips_info = $('<div class="alert" style="margin-bottom:15px"><div class="soft_tips_text"></div><div class="btn-ground" style="display:inline-block;"></div></div>'), explain = tips_info.find('.soft_tips_text'), btn_ground = tips_info.find('.btn-ground');
|
||||
$(el).empty();
|
||||
type = parseInt(type);
|
||||
if(type != 11) $(el).next('.onekey-menu-sub').remove();
|
||||
if(type == 10){
|
||||
explain.text('Security Reminder: aaPanel officially conducted a security audit before the third-party plug-in was put on the shelves, but there may be security risks. Please check it out before using it in the production environment.');
|
||||
btn_ground = soft.render_tips_btn(btn_ground,[
|
||||
//{title:'免费入驻',href:'https://www.bt.cn/developer/',rel:'noreferrer noopener',target:'_blank',btn:'免费入驻',class:'btn btn-success btn-xs va0',style:"margin-left:10px;"},
|
||||
{title:'Get third-party apps',rel:'noreferrer noopener',href:'https://www.bt.cn/bbs/forum-40-1.html',target:'_blank',btn:'Get third-party apps',class:'btn btn-success btn-xs va0 ml15',style:"margin-left:10px;"},
|
||||
{title:'Import plugins',href:'javascript:;',btn:'Import plugins','class':'btn btn-success btn-xs va0 ml15','style':"margin-left:10px;",click:function(e){
|
||||
var input = $('<input type="file" style="display:none;" accept=".zip,.tar.gz" id="update_zip" multiple="multiple">').change(function (e) {
|
||||
var files =$(this)[0].files;
|
||||
if (files.length == 0) return;
|
||||
soft.update_zip(files[0]);
|
||||
}).click();
|
||||
}}
|
||||
]);
|
||||
$(el).append(tips_info.addClass('alert-danger'));
|
||||
}else if(type == 11){
|
||||
explain.text('BT one click宝塔一键部署已上线,诚邀全球优秀项目入驻(限项目官方) ');
|
||||
btn_ground = soft.render_tips_btn(btn_ground,[
|
||||
{title:'免费入驻',href:'https://www.bt.cn/bbs/thread-33063-1-1.html',rel:'noreferrer noopener',target:'_blank',btn:'免费入驻',class:'btn btn-success btn-xs va0',style:"margin-left:10px;"},
|
||||
{title:'导入项目',href:'javascript:;',rel:'noreferrer noopener',btn:'导入项目',class:'btn btn-success btn-xs va0',style:"margin-left:10px;",click:soft.input_package}
|
||||
]);
|
||||
$(el).append(tips_info.addClass('alert-info'));
|
||||
}else{
|
||||
var ltd = parseInt(bt.get_cookie('ltd_end')),pro = parseInt(bt.get_cookie('pro_end')),todayDate = parseInt(new Date().getTime()/1000),_ltd = null;
|
||||
if((ltd > 0 && (ltd == pro || pro < 0)) || (ltd < 0 && pro >= 0) || (ltd > 0 && pro >= 0)){
|
||||
_ltd = ((ltd > 0 && (ltd == pro || pro < 0)) || (ltd > 0 && pro >= 0))?1:0;
|
||||
explain.html('当前为'+ (_ltd?'Pro':'专业版') +','+ (_ltd?'Pro':'专业版') +'可以免费使用'+ (_ltd?'专业版及企业版插件':'专业版插件') + (!(pro == 0 && ltd < 0)?(',过期时间:'+ (bt.format_data((_ltd?ltd:pro),'yyyy/MM/dd') ) +''+((((_ltd?ltd:pro) - todayDate) <= 15*24*60*60)?(',<span style="color:red">距离过期仅剩'+ Math.round(((_ltd?ltd:pro) - todayDate) / (24*60*60)) +'天</span>'):'')):',过期时间:<span style="color: #fc6d26;font-weight: bold;">永久授权</span>'));
|
||||
}else if(ltd == -1 && pro == -1){
|
||||
explain.html('Upgrade to Pro edition, all plugins, free to use!');
|
||||
}else if(pro == 0 && ltd < 0){
|
||||
_ltd = 2;
|
||||
explain.html('当前为专业版,专业版可以免费使用专业版插件,过期时间:永久授权。'+(type == 12?' <span style="color:#af8e48">升级企业版,企业可以免费试用企业版插件及专业版插件。</span>':''));
|
||||
if(type == 12){
|
||||
btn_ground = soft.render_tips_btn(btn_ground,{title:'立即升级',href:'javascript:;',btn:'立即升级','class':'btn btn-success btn-xs va0 ml15','style':"margin-left:10px;",click:bt.soft.updata_ltd});
|
||||
}
|
||||
}else if(ltd == -2 || pro == -2){
|
||||
_ltd = (ltd == -2)?1:0;
|
||||
explain.html('当前为'+ (_ltd?'企业版':'专业版') +','+ (_ltd?'企业版':'专业版') +'可以免费使用'+ (_ltd?'专业版及企业版插件':'专业版插件') +',<span style="color:red">'+ (_ltd?'企业版':'专业版') +'已过期</span>');
|
||||
}
|
||||
var btn_config = {title:null,href:'javascript:;',btn:null,'class':'btn btn-success btn-xs va0 ml15','style':"margin-left:10px;",click:null};
|
||||
var set_btn_style = function(res){
|
||||
if(!res.status || !res){
|
||||
$.extend(btn_config,{title:'立即登录',btn:'立即登录',click:function(){
|
||||
bt.pub.bind_btname(function(){
|
||||
window.location.reload();
|
||||
});
|
||||
}});
|
||||
}else{
|
||||
if(type == 12 && (ltd < 0 && pro >=0)){
|
||||
explain.html('企业版可以免费使用专业版及企业版插件,了解专业版和企业版的区别,请点击<a href="https://www.bt.cn/download/linux.html" target="_blank" class="btlink ml5">查看详情</a>。<a href="https://www.bt.cn/bbs/forum.php?mod=viewthread&tid=50342&page=1&extra=#pid179211" target="_blank" class="btlink ml5">《专业版升级企业版教程》</a>');
|
||||
$(el).append(tips_info.addClass('alert-ltd-success'));
|
||||
return false;
|
||||
}else{
|
||||
if(_ltd != 2){
|
||||
var fun = '';
|
||||
switch(_ltd){
|
||||
case null:
|
||||
fun = bt.soft.updata_commercial_view
|
||||
break;
|
||||
case 1:
|
||||
fun = bt.soft.updata_ltd
|
||||
break;
|
||||
case 0:
|
||||
fun = bt.soft.updata_pro
|
||||
break;
|
||||
}
|
||||
$.extend(btn_config,{title:_ltd == null?'Upgrade now':'立即续费',btn:_ltd == null?'Upgrade now':'立即续费',click:fun})
|
||||
}
|
||||
}
|
||||
}
|
||||
if(_ltd != 2){
|
||||
if(!(pro == 0 && ltd < 0)){
|
||||
btn_ground = soft.render_tips_btn(btn_ground,btn_config);
|
||||
}
|
||||
}
|
||||
$(el).append(tips_info.addClass(_ltd == 1?'alert-ltd-success':'alert-success'));
|
||||
}
|
||||
var bt_user_info = bt.get_cookie('bt_user_info');
|
||||
if(!bt_user_info){
|
||||
bt.pub.get_user_info(function(res){
|
||||
if(!res.status){
|
||||
set_btn_style(false);
|
||||
return false;
|
||||
}
|
||||
bt.set_cookie('bt_user_info',JSON.stringify(res),300000);
|
||||
set_btn_style(res);
|
||||
});
|
||||
}else{
|
||||
set_btn_style(JSON.parse(bt.get_cookie('bt_user_info')));
|
||||
}
|
||||
}
|
||||
},
|
||||
render_tips_btn:function(node,arry){
|
||||
if(!Array.isArray(arry)) arry = [arry]
|
||||
for(var i=0;i<arry.length;i++){
|
||||
var item = arry[i], btn = '<a ';
|
||||
for(var key in item){ if(key != 'click' && key != 'btn') btn += item[key]?(key+'="'+item[key]+'" '):'' }
|
||||
btn += '>'+item['btn'] +'</a>';
|
||||
if(item.click){
|
||||
btn = $(btn).on('click',item.click)
|
||||
}
|
||||
node.append(btn);
|
||||
}
|
||||
return node
|
||||
},
|
||||
get_dep_list: function(p) {
|
||||
var loadT = layer.msg('Getting list <img src="/static/img/ing.gif">', {
|
||||
icon: 16,
|
||||
@@ -783,6 +956,10 @@ var soft = {
|
||||
type: 'apache_status',
|
||||
title: lan.soft.nginx_status
|
||||
},
|
||||
{
|
||||
type: 'apache_format_log',
|
||||
title: 'Logs format'
|
||||
},
|
||||
{
|
||||
type: 'log',
|
||||
title: lan.soft.run_log
|
||||
@@ -796,6 +973,10 @@ var soft = {
|
||||
type: 'nginx_status',
|
||||
title: lan.soft.nginx_status
|
||||
},
|
||||
{
|
||||
type: 'nginx_format_log',
|
||||
title: 'Logs format'
|
||||
},
|
||||
{
|
||||
type: 'log',
|
||||
title: lan.soft.err_log
|
||||
@@ -865,6 +1046,10 @@ var soft = {
|
||||
val: ver,
|
||||
title: lan.soft.php_main4
|
||||
},
|
||||
{ type: 'fpm_config',
|
||||
val: ver,
|
||||
title: 'FPM profile'
|
||||
},
|
||||
{
|
||||
type: 'set_dis_fun',
|
||||
val: ver,
|
||||
@@ -912,14 +1097,14 @@ var soft = {
|
||||
}
|
||||
]
|
||||
|
||||
var phpSort = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
|
||||
var phpSort = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
|
||||
webcache = bt.get_cookie('serverType') == 'openlitespeed' ? true : false;
|
||||
for (var i = 0; i < phpSort.length; i++) {
|
||||
var item = opt_list[i];
|
||||
if (item) {
|
||||
if (item.os == undefined || item['os'] == bt.os) {
|
||||
if (name.indexOf("5.2") >= 0 && item.php53) continue;
|
||||
if (webcache && item.type=='set_fpm_config' || item.type=='get_php_status') continue;
|
||||
if (webcache && (item.type=='set_fpm_config' || item.type=='get_php_status')) continue;
|
||||
var apache24 = item.apache24 ? 'class="apache24"' : '';
|
||||
menu.append($('<p data-id="' + i + '" ' + apache24 + ' onclick="soft.get_tab_contents(\'' + item.type + '\',this)" >' + item.title + '</p>').data('item', item))
|
||||
}
|
||||
@@ -1037,6 +1222,23 @@ var soft = {
|
||||
});
|
||||
})
|
||||
break;
|
||||
case 'fpm_config':
|
||||
var tabCon = $(".soft-man-con").empty();
|
||||
tabCon.append('<p style="color: #666; margin-bottom: 7px">' + lan.bt.edit_ps + '</p>');
|
||||
tabCon.append('<div class="bt-input-text ace_config_editor_scroll" style="line-height:18px;" id="textBody"></div>')
|
||||
tabCon.append('<button id="OnlineEditFileBtn" class="btn btn-success btn-sm" style="margin-top:10px;">' + lan.public.save + '</button>')
|
||||
var _arry = ['If you do not understand the php-fpm configuration file, please do not modify it!'];
|
||||
tabCon.append(bt.render_help(_arry))
|
||||
$('.return_php_info').click(function(){
|
||||
$('.bt-soft-menu p:eq(12)').click();
|
||||
});
|
||||
var fileName = bt.soft.get_config_path(version).replace('php.ini','php-fpm.conf');
|
||||
var loadT = bt.load(lan.soft.get);
|
||||
var config = bt.aceEditor({el:'textBody',path:fileName});
|
||||
$("#OnlineEditFileBtn").click(function () {
|
||||
bt.saveEditor(config);
|
||||
});
|
||||
break;
|
||||
case 'change_version':
|
||||
var _list = [];
|
||||
var opt_version = '';
|
||||
@@ -1201,7 +1403,7 @@ var soft = {
|
||||
var title11 = ((1 - rdata.Key_reads / rdata.Key_read_requests) * 100).toFixed(2);
|
||||
var title12 = ((1 - rdata.Innodb_buffer_pool_reads / rdata.Innodb_buffer_pool_read_requests) * 100).toFixed(2);
|
||||
var title14 = ((rdata.Created_tmp_disk_tables / rdata.Created_tmp_tables) * 100).toFixed(2);
|
||||
var Con = '<div class="divtable"><table class="table table-hover table-bordered" style="margin-bottom:10px;background-color:#fafafa">\
|
||||
var Con = '<div class="divtable"><table class="table table-hover table-bordered" style="background-color:#fafafa">\
|
||||
<tbody>\
|
||||
<tr><th>' + lan.soft.mysql_status_title1 + '</th><td>' + getLocalTime(rdata.Run) + '</td><th>' + lan.soft.mysql_status_title5 + '</th><td>' + parseInt(rdata.Questions / rdata.Uptime) + '</td></tr>\
|
||||
<tr><th>' + lan.soft.mysql_status_title2 + '</th><td>' + rdata.Connections + '</td><th>' + lan.soft.mysql_status_title6 + '</th><td>' + parseInt((parseInt(rdata.Com_commit) + parseInt(rdata.Com_rollback)) / rdata.Uptime) + '</td></tr>\
|
||||
@@ -1209,20 +1411,20 @@ var soft = {
|
||||
<tr><th>' + lan.soft.mysql_status_title4 + '</th><td>' + ToSize(rdata.Bytes_received) + '</td><th>' + lan.soft.mysql_status_title8 + '</th><td>' + rdata.Position + '</td></tr>\
|
||||
</tbody>\
|
||||
</table>\
|
||||
<table class="table table-hover table-bordered" style="margin-bottom: 10px;">\
|
||||
<thead style="display:none;"><th></th><th></th><th></th><th></th></thead>\
|
||||
<table class="table table-hover table-bordered">\
|
||||
<thead style="visibility: hidden;"><th width="225"></th><th></th><th></th></thead>\
|
||||
<tbody>\
|
||||
<tr><th>' + lan.soft.mysql_status_title9 + '</th><td>' + rdata.Threads_running + '/' + rdata.Max_used_connections + '</td><td colspan="2">' + lan.soft.mysql_status_ps1 + '</td></tr>\
|
||||
<tr><th>' + lan.soft.mysql_status_title10 + '</th><td>' + (!isNaN(title10) ? title10 : '0') + '%</td><td colspan="2">' + lan.soft.mysql_status_ps2 + '</td></tr>\
|
||||
<tr><th>' + lan.soft.mysql_status_title11 + '</th><td>' + (!isNaN(title11) ? title11 : '0') + '%</td><td colspan="2">' + lan.soft.mysql_status_ps3 + '</td></tr>\
|
||||
<tr><th>' + lan.soft.mysql_status_title12 + '</th><td>' + (!isNaN(title12) ? title12 : '0') + '%</td><td colspan="2">' + lan.soft.mysql_status_ps4 + '</td></tr>\
|
||||
<tr><th>' + lan.soft.mysql_status_title13 + '</th><td>' + cache_size + '</td><td colspan="2">' + lan.soft.mysql_status_ps5 + '</td></tr>\
|
||||
<tr><th>' + lan.soft.mysql_status_title14 + '</th><td>' + (!isNaN(title14) ? title14 : '0') + '%</td><td colspan="2">' + lan.soft.mysql_status_ps6 + '</td></tr>\
|
||||
<tr><th>' + lan.soft.mysql_status_title15 + '</th><td>' + rdata.Open_tables + '</td><td colspan="2">' + lan.soft.mysql_status_ps7 + '</td></tr>\
|
||||
<tr><th>' + lan.soft.mysql_status_title16 + '</th><td>' + rdata.Select_full_join + '</td><td colspan="2">' + lan.soft.mysql_status_ps8 + '</td></tr>\
|
||||
<tr><th>' + lan.soft.mysql_status_title17 + '</th><td>' + rdata.Select_range_check + '</td><td colspan="2">' + lan.soft.mysql_status_ps9 + '</td></tr>\
|
||||
<tr><th>' + lan.soft.mysql_status_title18 + '</th><td>' + rdata.Sort_merge_passes + '</td><td colspan="2">' + lan.soft.mysql_status_ps10 + '</td></tr>\
|
||||
<tr><th>' + lan.soft.mysql_status_title19 + '</th><td>' + rdata.Table_locks_waited + '</td><td colspan="2">' + lan.soft.mysql_status_ps11 + '</td></tr>\
|
||||
<tr><th>' + lan.soft.mysql_status_title9 + '</th><td>' + rdata.Threads_running + '/' + rdata.Max_used_connections + '</td><td>' + lan.soft.mysql_status_ps1 + '</td></tr>\
|
||||
<tr><th>' + lan.soft.mysql_status_title10 + '</th><td>' + (!isNaN(title10) ? title10 : '0') + '%</td><td>' + lan.soft.mysql_status_ps2 + '</td></tr>\
|
||||
<tr><th>' + lan.soft.mysql_status_title11 + '</th><td>' + (!isNaN(title11) ? title11 : '0') + '%</td><td>' + lan.soft.mysql_status_ps3 + '</td></tr>\
|
||||
<tr><th>' + lan.soft.mysql_status_title12 + '</th><td>' + (!isNaN(title12) ? title12 : '0') + '%</td><td>' + lan.soft.mysql_status_ps4 + '</td></tr>\
|
||||
<tr><th>' + lan.soft.mysql_status_title13 + '</th><td>' + cache_size + '</td><td>' + lan.soft.mysql_status_ps5 + '</td></tr>\
|
||||
<tr><th>' + lan.soft.mysql_status_title14 + '</th><td>' + (!isNaN(title14) ? title14 : '0') + '%</td><td>' + lan.soft.mysql_status_ps6 + '</td></tr>\
|
||||
<tr><th>' + lan.soft.mysql_status_title15 + '</th><td>' + rdata.Open_tables + '</td><td>' + lan.soft.mysql_status_ps7 + '</td></tr>\
|
||||
<tr><th>' + lan.soft.mysql_status_title16 + '</th><td>' + rdata.Select_full_join + '</td><td>' + lan.soft.mysql_status_ps8 + '</td></tr>\
|
||||
<tr><th>' + lan.soft.mysql_status_title17 + '</th><td>' + rdata.Select_range_check + '</td><td>' + lan.soft.mysql_status_ps9 + '</td></tr>\
|
||||
<tr><th>' + lan.soft.mysql_status_title18 + '</th><td>' + rdata.Sort_merge_passes + '</td><td>' + lan.soft.mysql_status_ps10 + '</td></tr>\
|
||||
<tr><th>' + lan.soft.mysql_status_title19 + '</th><td>' + rdata.Table_locks_waited + '</td><td>' + lan.soft.mysql_status_ps11 + '</td></tr>\
|
||||
<tbody>\
|
||||
</table></div>'
|
||||
$(".soft-man-con").html(Con);
|
||||
@@ -1647,6 +1849,451 @@ var soft = {
|
||||
bt.render_table("tab-nginx-status", arrs);
|
||||
})
|
||||
break;
|
||||
case 'nginx_format_log':
|
||||
var loadT = bt.load();
|
||||
bt.send('get_nginx_access_log_format', 'config/get_nginx_access_log_format', {}, function(rdata) {
|
||||
$(".soft-man-con").html("<button class='btn btn-success btn-sm mb15 table-add-format'>Add format</button><div class='divtable' style='max-height: 570px;overflow: auto;'><table id='tab-nginx-logs-format' class='table table-hover'><thead><tr><th width='15%'>Name</th><th>Format</th><th width='120' style='text-align:right;'>Opt</th></tr></thead><tbody></tbody></table></div>");
|
||||
bt.send('get_nginx_access_log_format_parameter', 'config/get_nginx_access_log_format_parameter', {}, function(res) {
|
||||
loadT.close();
|
||||
var _format_ul = '<ul class="bt-select-list">';
|
||||
Object.keys(res).map(function(key){
|
||||
_format_ul += '<li data-val="'+key+'">'+key+' : '+res[key]+'</li>';
|
||||
})
|
||||
_format_ul += '</ul>';
|
||||
for (const j in rdata) {
|
||||
if (rdata.hasOwnProperty(j)) {
|
||||
const result = rdata[j];
|
||||
var _format = result.map(function(item, index){
|
||||
return Object.keys(item)[0];
|
||||
});
|
||||
var element = '<span class="nginx-one-format">' + _format.join('</span><span class="nginx-one-format">') + '</span>',
|
||||
_td = '<tr><td>'+j+'</td>\
|
||||
<td>'+element+'</td>\
|
||||
<td align="right" data-name="'+j+'"><a class="btlink table-apply-format">Apply</a> | <a class="btlink table-set-format">Set</a> | <a class="btlink table-del-format">Del</a></td></tr>';
|
||||
$("#tab-nginx-logs-format tbody").append(_td);
|
||||
//表格头固定
|
||||
$('#tab-nginx-logs-format').parent().on('scroll', function () {
|
||||
var scrollTop = $('#tab-nginx-logs-format').parent().scrollTop();
|
||||
$('#tab-nginx-logs-format thead').css({"transform":"translateY("+scrollTop+"px)","position":"relative","z-index":"1"});
|
||||
});
|
||||
}
|
||||
}
|
||||
$('.table-add-format, .table-set-format').click(function() {
|
||||
if($(this).hasClass('table-set-format')) {
|
||||
var format_title = 'Set format',
|
||||
first_format = '',
|
||||
add_type = 'edit',
|
||||
td_format = $(this).parent().prev().find('.nginx-one-format');
|
||||
format_name = $(this).parent().attr('data-name');
|
||||
for (var i = 0; i < td_format.length; i++) {
|
||||
first_format += '<div class="line">\
|
||||
<div class="bt-select">\
|
||||
<div class="bt-select-input plr10">\
|
||||
<div class="bt-select-val" data-active="'+td_format.eq(i).text()+'">'+td_format.eq(i).text()+'</div>\
|
||||
<span class="bt-down-icon"></span>\
|
||||
</div>\
|
||||
</div>\
|
||||
<a href="javascript:;" class="del-format">Del</a>\
|
||||
</div>';
|
||||
}
|
||||
}else{
|
||||
var format_title = 'Add format',
|
||||
format_name = '',
|
||||
add_type = 'add',
|
||||
first_format = '',
|
||||
format_list = ['$http_x_forwarded_for','$remote_addr','-','[$time_local]','$request','$status','$body_bytes_sent','$http_referer','$http_user_agent'];
|
||||
for (var i = 0; i < format_list.length; i++) {
|
||||
first_format += '<div class="line">\
|
||||
<div class="bt-select">\
|
||||
<div class="bt-select-input plr10">\
|
||||
<div class="bt-select-val" data-active="'+format_list[i]+'">'+format_list[i]+'</div>\
|
||||
<span class="bt-down-icon"></span>\
|
||||
</div>\
|
||||
</div>\
|
||||
<a href="javascript:;" class="del-format">Del</a>\
|
||||
</div>';
|
||||
}
|
||||
|
||||
}
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: format_title,
|
||||
closeBtn: 2,
|
||||
area: '375px',
|
||||
btn: ['Confirm', 'Cancel'],
|
||||
content: '<div class="bt-form pd20 nginx-add-format" style="position: relative;">\
|
||||
<div class="line" style="font-size: 13px;">\
|
||||
<span style="text-align: right;display: inline-block;margin-right: 7px;width: 50px;">Name: </span>\
|
||||
<input name="log_format_name" class="bt-input-text" type="text" style="width:274px" placeholder = "Please enter the format name.">\
|
||||
</div>\
|
||||
<span style="position: absolute;top: 70px;left: 25px;">Format:</span>\
|
||||
<div style="position: relative;margin-left: 60px;">\
|
||||
<div class="format-table">'+first_format+'</div>\
|
||||
'+_format_ul+'\
|
||||
</div>\
|
||||
<button class="btn btn-success btn-sm btn-title btn-add-format" type="button" style="margin-top: 10px;margin-left: 60px;"><span class="glyphicon cursor glyphicon-plus mr5"></span>Add parameter</button>\
|
||||
<ul class="help-info-text c7"><li>The format are executed in the order of parameters.</li></ul>\
|
||||
</div>',
|
||||
success: function(index, layero) {
|
||||
$('.nginx-add-format [name=log_format_name]').val(format_name);
|
||||
$('.nginx-add-format').parents('.layui-layer-content').css('overflow','inherit');
|
||||
$('.nginx-add-format').on('click', '.bt-select-input', function (e) {
|
||||
if($(this).hasClass('active')){
|
||||
$('.nginx-add-format .bt-select-list').removeClass('active');
|
||||
$(this).removeClass('active').find('.bt-down-icon').css('transform','rotate(-45deg)');
|
||||
}else{
|
||||
var _choose = $(this).find('.bt-select-val').text();
|
||||
$('.bt-select-list li').removeClass('active');
|
||||
$('.active.bt-select-input').removeClass('active').find('.bt-down-icon').css('transform','rotate(-45deg)')
|
||||
$('.bt-select-list li:contains('+_choose+')').addClass('active');
|
||||
$('.nginx-add-format .bt-select-list').addClass('active').css('top',$(this).offset().top-$('.format-table').offset().top+33);
|
||||
$(this).addClass('active').find('.bt-down-icon').css('transform','rotate(135deg)');
|
||||
}
|
||||
e.stopPropagation();
|
||||
$(document).click(function(e){
|
||||
$('.active.bt-select-list').removeClass('active');
|
||||
$(this).find('.bt-down-icon').css('transform','rotate(-45deg)');
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
});
|
||||
});
|
||||
$('.nginx-add-format').on('click', '.bt-select-list li', function (e) {
|
||||
var _value = $(this).attr('data-val');
|
||||
$('.active.bt-select-input').find('.bt-select-val').attr('data-active',_value).text(_value);
|
||||
$('.nginx-add-format .bt-select-list,.active.bt-select-input').removeClass('active');
|
||||
});
|
||||
$('.btn-add-format').click(function (e) {
|
||||
var _new_line = '<div class="line">\
|
||||
<div class="bt-select">\
|
||||
<div class="bt-select-input plr10">\
|
||||
<div class="bt-select-val" data-active="$server_name">$server_name</div>\
|
||||
<span class="bt-down-icon" ></span>\
|
||||
</div>\
|
||||
</div>\
|
||||
<a href="javascript:;" class="del-format">Del</a>\
|
||||
</div>';
|
||||
$('.format-table').append(_new_line);
|
||||
$('.format-table').scrollTop(10000000)
|
||||
});
|
||||
$('.nginx-add-format').on('click', '.del-format', function (e) {
|
||||
if ($('.del-format').length == 1) {
|
||||
layer.msg('This is the last parameter.', {icon: 2});
|
||||
return false;
|
||||
}
|
||||
$(this).parent().remove();
|
||||
});
|
||||
},
|
||||
yes: function(index, layero) {
|
||||
if ($('.nginx-add-format [name=log_format_name]').val()=='') {
|
||||
layer.msg('The format name cannot be empty!', {icon: 2});
|
||||
return false;
|
||||
}
|
||||
var log_format = [];
|
||||
$(".nginx-add-format .format-table .bt-select-val").each(function(){
|
||||
log_format.push($(this).attr("data-active"));
|
||||
});
|
||||
var format_data = {
|
||||
"log_format_name": $('.nginx-add-format [name=log_format_name]').val(),
|
||||
"log_format": JSON.stringify(log_format),
|
||||
"act": add_type
|
||||
}
|
||||
bt.send('add_nginx_access_log_format', 'config/add_nginx_access_log_format', format_data, function(res) {
|
||||
layer.close(index);
|
||||
$('.bt-soft-menu p:contains("Logs format")').click();
|
||||
layer.msg(res.msg, {icon: res.status ? 1 : 2});
|
||||
})
|
||||
}
|
||||
})
|
||||
});
|
||||
$('#tab-nginx-logs-format').on('click', '.table-del-format', function (e) {
|
||||
var log_format_name = $(this).parent().attr('data-name'),
|
||||
loadP = layer.confirm('Confirm to delete【'+log_format_name+'】this logs format?', {
|
||||
title: 'Confirm Delete?',
|
||||
closeBtn: 2
|
||||
}, function() {
|
||||
layer.close(loadP);
|
||||
bt.send('del_nginx_access_log_format', 'config/del_nginx_access_log_format', {'log_format_name': log_format_name}, function(res) {
|
||||
if(res.status) $('.bt-soft-menu p:contains("Logs format")').click();
|
||||
layer.msg(res.msg, {icon: res.status ? 1 : 2});
|
||||
});
|
||||
});
|
||||
});
|
||||
$('#tab-nginx-logs-format').on('click', '.table-apply-format', function (e) {
|
||||
var log_format_name = $(this).parent().attr('data-name');
|
||||
bt.send('get_nginx_access_log_format_parameter', 'config/get_nginx_access_log_format_parameter', {'log_format_name':log_format_name}, function(res) {
|
||||
if (Object.keys(res.site_list).length == 0) {
|
||||
layer.msg('There is no site can apply!', {icon: 2});
|
||||
return false;
|
||||
}
|
||||
var _site_ul = '<ul class="format-site-list">';
|
||||
Object.keys(res.site_list).map(function(key){
|
||||
_site_ul += '<li style="padding: 10px"><div class="bt_checkbox_groups'+(res.site_list[key]?' active':'')+'" data-val="'+key+'"></div>'+key+'</li>';
|
||||
});
|
||||
_site_ul += '</ul>';
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: 'Website apply format',
|
||||
closeBtn: 2,
|
||||
btn: ['Confirm', 'Cancel'],
|
||||
content: '<div class="bt-form pd20 nginx-add-site" style="font-size: 13px;">\
|
||||
<div class="line">\
|
||||
<span style="text-align: right;display: inline-block;position: absolute;">Site: </span>\
|
||||
'+_site_ul+'\
|
||||
</div>\
|
||||
<div class="line c7">The checked site would used the format.</div>\
|
||||
</div>',
|
||||
success: function(index, layero) {
|
||||
$('.nginx-add-site').on('click', '.format-site-list li', function (e) {
|
||||
if ($(this).find('.bt_checkbox_groups').hasClass('active')) {
|
||||
$(this).find('.bt_checkbox_groups').removeClass('active');
|
||||
} else {
|
||||
$(this).find('.bt_checkbox_groups').addClass('active');
|
||||
}
|
||||
});
|
||||
},
|
||||
yes: function(index, layero) {
|
||||
var sites = [];
|
||||
$(".nginx-add-site .format-site-list .bt_checkbox_groups.active").each(function(){
|
||||
sites.push($(this).attr("data-val"));
|
||||
});
|
||||
var format_data = {
|
||||
"log_format_name": log_format_name,
|
||||
"sites": JSON.stringify(sites)
|
||||
}
|
||||
bt.send('set_format_log_to_website', 'config/set_format_log_to_website', format_data, function(res) {
|
||||
layer.close(index);
|
||||
if(res.status) $('.bt-soft-menu p:contains("Logs format")').click();
|
||||
layer.msg(res.msg, {icon: res.status ? 1 : 2});
|
||||
})
|
||||
}
|
||||
})
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
break;
|
||||
case 'apache_format_log':
|
||||
var loadT = bt.load();
|
||||
bt.send('get_httpd_access_log_format', 'config/get_httpd_access_log_format', {}, function(rdata) {
|
||||
$(".soft-man-con").html("<button class='btn btn-success btn-sm mb15 table-add-format'>Add format</button><div class='divtable' style='max-height: 570px;overflow: auto;'><table id='tab-nginx-logs-format' class='table table-hover'><thead><tr><th width='15%'>Name</th><th>Format</th><th width='120' style='text-align:right;'>Opt</th></tr></thead><tbody></tbody></table></div>");
|
||||
bt.send('get_httpd_access_log_format_parameter', 'config/get_httpd_access_log_format_parameter', {}, function(res) {
|
||||
loadT.close();
|
||||
var _format_ul = '<ul class="bt-select-list">';
|
||||
Object.keys(res).map(function(key){
|
||||
_format_ul += '<li data-val="'+key+'">'+key+' : '+res[key]+'</li>';
|
||||
})
|
||||
_format_ul += '</ul>';
|
||||
for (const j in rdata) {
|
||||
if (rdata.hasOwnProperty(j)) {
|
||||
const result = rdata[j];
|
||||
var _format = result.map(function(item, index){
|
||||
return Object.keys(item)[0];
|
||||
});
|
||||
var element = '<span class="nginx-one-format">' + _format.join('</span><span class="nginx-one-format">') + '</span>',
|
||||
_td = '<tr><td>'+j+'</td>\
|
||||
<td>'+element+'</td>\
|
||||
<td align="right" data-name="'+j+'"><a class="btlink table-apply-format">Apply</a> | <a class="btlink table-set-format">Set</a> | <a class="btlink table-del-format">Del</a></td></tr>';
|
||||
$("#tab-nginx-logs-format tbody").append(_td);
|
||||
//表格头固定
|
||||
$('#tab-nginx-logs-format').parent().on('scroll', function () {
|
||||
var scrollTop = $('#tab-nginx-logs-format').parent().scrollTop();
|
||||
$('#tab-nginx-logs-format thead').css({"transform":"translateY("+scrollTop+"px)","position":"relative","z-index":"1"});
|
||||
});
|
||||
}
|
||||
}
|
||||
$('.table-add-format, .table-set-format').click(function() {
|
||||
if($(this).hasClass('table-set-format')) {
|
||||
var format_title = 'Set format',
|
||||
first_format = '',
|
||||
add_type = 'edit',
|
||||
td_format = $(this).parent().prev().find('.nginx-one-format');
|
||||
format_name = $(this).parent().attr('data-name');
|
||||
for (var i = 0; i < td_format.length; i++) {
|
||||
first_format += '<div class="line">\
|
||||
<div class="bt-select">\
|
||||
<div class="bt-select-input plr10">\
|
||||
<div class="bt-select-val" data-active="'+td_format.eq(i).text()+'">'+td_format.eq(i).text()+'</div>\
|
||||
<span class="bt-down-icon"></span>\
|
||||
</div>\
|
||||
</div>\
|
||||
<a href="javascript:;" class="del-format">Del</a>\
|
||||
</div>';
|
||||
}
|
||||
}else{
|
||||
var format_title = 'Add format',
|
||||
format_name = '',
|
||||
add_type = 'add',
|
||||
first_format = '',
|
||||
format_list = ['%{X-Forwarded-For}i','%h','%l','%u','%t','%r','%>s','%b','%{Referer}i','%{User-agent}i'];
|
||||
for (var i = 0; i < format_list.length; i++) {
|
||||
first_format += '<div class="line">\
|
||||
<div class="bt-select">\
|
||||
<div class="bt-select-input plr10">\
|
||||
<div class="bt-select-val" data-active="'+format_list[i]+'">'+format_list[i]+'</div>\
|
||||
<span class="bt-down-icon"></span>\
|
||||
</div>\
|
||||
</div>\
|
||||
<a href="javascript:;" class="del-format">Del</a>\
|
||||
</div>';
|
||||
}
|
||||
}
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: format_title,
|
||||
closeBtn: 2,
|
||||
area: '375px',
|
||||
btn: ['Confirm', 'Cancel'],
|
||||
content: '<div class="bt-form pd20 nginx-add-format" style="position: relative;">\
|
||||
<div class="line" style="font-size: 13px;">\
|
||||
<span style="text-align: right;display: inline-block;margin-right: 7px;width: 50px;">Name: </span>\
|
||||
<input name="log_format_name" class="bt-input-text" type="text" style="width:274px" placeholder = "Please enter the format name.">\
|
||||
</div>\
|
||||
<span style="position: absolute;top: 70px;left: 25px;">Format:</span>\
|
||||
<div style="position: relative;margin-left: 60px;">\
|
||||
<div class="format-table">'+first_format+'</div>\
|
||||
'+_format_ul+'\
|
||||
</div>\
|
||||
<button class="btn btn-success btn-sm btn-title btn-add-format" type="button" style="margin-top: 10px;margin-left: 60px;"><span class="glyphicon cursor glyphicon-plus mr5"></span>Add parameter</button>\
|
||||
<ul class="help-info-text c7"><li>The format are executed in the order of parameters.</li></ul>\
|
||||
</div>',
|
||||
success: function(index, layero) {
|
||||
$('.nginx-add-format [name=log_format_name]').val(format_name);
|
||||
$('.nginx-add-format').parents('.layui-layer-content').css('overflow','inherit');
|
||||
$('.nginx-add-format').on('click', '.bt-select-input', function (e) {
|
||||
if($(this).hasClass('active')){
|
||||
$('.nginx-add-format .bt-select-list').removeClass('active');
|
||||
$(this).removeClass('active').find('.bt-down-icon').css('transform','rotate(-45deg)');
|
||||
}else{
|
||||
var _choose = $(this).find('.bt-select-val').text();
|
||||
$('.bt-select-list li').removeClass('active');
|
||||
$('.active.bt-select-input').removeClass('active').find('.bt-down-icon').css('transform','rotate(-45deg)')
|
||||
$('.bt-select-list li:contains('+_choose+')').addClass('active');
|
||||
$('.nginx-add-format .bt-select-list').addClass('active').css('top',$(this).offset().top-$('.format-table').offset().top+33);
|
||||
$(this).addClass('active').find('.bt-down-icon').css('transform','rotate(135deg)');
|
||||
}
|
||||
e.stopPropagation();
|
||||
$(document).click(function(e){
|
||||
$('.active.bt-select-list').removeClass('active');
|
||||
$(this).find('.bt-down-icon').css('transform','rotate(-45deg)');
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
});
|
||||
});
|
||||
$('.nginx-add-format').on('click', '.bt-select-list li', function (e) {
|
||||
var _value = $(this).attr('data-val');
|
||||
$('.active.bt-select-input').find('.bt-select-val').attr('data-active',_value).text(_value);
|
||||
$('.nginx-add-format .bt-select-list,.active.bt-select-input').removeClass('active');
|
||||
});
|
||||
$('.btn-add-format').click(function (e) {
|
||||
var _new_line = '<div class="line">\
|
||||
<div class="bt-select">\
|
||||
<div class="bt-select-input plr10">\
|
||||
<div class="bt-select-val" data-active="%>s">%>s</div>\
|
||||
<span class="bt-down-icon" ></span>\
|
||||
</div>\
|
||||
</div>\
|
||||
<a href="javascript:;" class="del-format">Del</a>\
|
||||
</div>';
|
||||
$('.format-table').append(_new_line);
|
||||
$('.format-table').scrollTop(10000000)
|
||||
});
|
||||
$('.nginx-add-format').on('click', '.del-format', function (e) {
|
||||
if ($('.del-format').length == 1) {
|
||||
layer.msg('This is the last parameter.', {icon: 2});
|
||||
return false;
|
||||
}
|
||||
$(this).parent().remove();
|
||||
});
|
||||
},
|
||||
yes: function(index, layero) {
|
||||
if ($('.nginx-add-format [name=log_format_name]').val()=='') {
|
||||
layer.msg('The format name cannot be empty!', {icon: 2});
|
||||
return false;
|
||||
}
|
||||
var log_format = [];
|
||||
$(".nginx-add-format .format-table .bt-select-val").each(function(){
|
||||
log_format.push($(this).attr("data-active"));
|
||||
});
|
||||
var format_data = {
|
||||
"log_format_name": $('.nginx-add-format [name=log_format_name]').val(),
|
||||
"log_format": JSON.stringify(log_format),
|
||||
'act':add_type
|
||||
}
|
||||
bt.send('add_httpd_access_log_format', 'config/add_httpd_access_log_format', format_data, function(res) {
|
||||
layer.close(index);
|
||||
if(res.status) $('.bt-soft-menu p:contains("Logs format")').click();
|
||||
layer.msg(res.msg, {icon: res.status ? 1 : 2});
|
||||
})
|
||||
}
|
||||
})
|
||||
});
|
||||
$('#tab-nginx-logs-format').on('click', '.table-del-format', function (e) {
|
||||
var log_format_name = $(this).parent().attr('data-name'),
|
||||
loadP = layer.confirm('Confirm to delete【'+log_format_name+'】this logs format?', {
|
||||
title: 'Confirm Delete?',
|
||||
closeBtn: 2
|
||||
}, function() {
|
||||
layer.close(loadP);
|
||||
bt.send('del_httpd_access_log_format', 'config/del_httpd_access_log_format', {'log_format_name': log_format_name}, function(res) {
|
||||
if(res.status) $('.bt-soft-menu p:contains("Logs format")').click();
|
||||
layer.msg(res.msg, {icon: res.status ? 1 : 2});
|
||||
});
|
||||
});
|
||||
});
|
||||
$('#tab-nginx-logs-format').on('click', '.table-apply-format', function (e) {
|
||||
var log_format_name = $(this).parent().attr('data-name');
|
||||
bt.send('get_httpd_access_log_format_parameter', 'config/get_httpd_access_log_format_parameter', {'log_format_name':log_format_name}, function(res) {
|
||||
if (Object.keys(res.site_list).length == 0) {
|
||||
layer.msg('There is no site can apply!', {icon: 2});
|
||||
return false;
|
||||
}
|
||||
var _site_ul = '<ul class="format-site-list">';
|
||||
Object.keys(res.site_list).map(function(key){
|
||||
_site_ul += '<li style="padding: 10px"><div class="bt_checkbox_groups'+(res.site_list[key]?' active':'')+'" data-val="'+key+'"></div>'+key+'</li>';
|
||||
});
|
||||
_site_ul += '</ul>';
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: 'Website apply format',
|
||||
closeBtn: 2,
|
||||
btn: ['Confirm', 'Cancel'],
|
||||
content: '<div class="bt-form pd20 nginx-add-site" style="font-size: 13px;">\
|
||||
<div class="line">\
|
||||
<span style="text-align: right;display: inline-block;position: absolute;">Site: </span>\
|
||||
'+_site_ul+'\
|
||||
</div>\
|
||||
<div class="line c7">The checked site would used the format.</div>\
|
||||
</div>',
|
||||
success: function(index, layero) {
|
||||
$('.nginx-add-site').on('click', '.format-site-list li', function (e) {
|
||||
if ($(this).find('.bt_checkbox_groups').hasClass('active')) {
|
||||
$(this).find('.bt_checkbox_groups').removeClass('active');
|
||||
} else {
|
||||
$(this).find('.bt_checkbox_groups').addClass('active');
|
||||
}
|
||||
});
|
||||
},
|
||||
yes: function(index, layero) {
|
||||
var sites = [];
|
||||
$(".nginx-add-site .format-site-list .bt_checkbox_groups.active").each(function(){
|
||||
sites.push($(this).attr("data-val"));
|
||||
});
|
||||
var format_data = {
|
||||
"log_format_name": log_format_name,
|
||||
"sites": JSON.stringify(sites)
|
||||
}
|
||||
bt.send('set_httpd_format_log_to_website', 'config/set_httpd_format_log_to_website', format_data, function(res) {
|
||||
layer.close(index);
|
||||
if(res.status) $('.bt-soft-menu p:contains("Logs format")').click();
|
||||
layer.msg(res.msg, {icon: res.status ? 1 : 2});
|
||||
})
|
||||
}
|
||||
})
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
break;
|
||||
case 'apache_status':
|
||||
var loadT = bt.load();
|
||||
bt.send('GetApacheStatus', 'ajax/GetApacheStatus', {}, function(rdata) {
|
||||
@@ -2199,10 +2846,10 @@ var soft = {
|
||||
bt.open({
|
||||
type: 1,
|
||||
title: "PHP-" + version + "-PHPINFO",
|
||||
area: ['70%', '90%'],
|
||||
area: ['73%', '90%'],
|
||||
closeBtn: 2,
|
||||
shadeClose: true,
|
||||
content: '<div style="white-space: pre-wrap;">'+content+'</div>'
|
||||
content: '<div style="white-space: pre-wrap;padding:0 10px;">'+content+'</div>'
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -2474,6 +3121,17 @@ var soft = {
|
||||
for (var sk in item) $('.' + sk).val(item[sk]);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Connection',
|
||||
name: 'listen',
|
||||
value: rdata.unix,
|
||||
type: 'select',
|
||||
items: [
|
||||
{ title: 'UNIX socket', value: 'unix' },
|
||||
{ title: 'TCP socket', value: 'tcp' }
|
||||
],
|
||||
ps: '* UNIX socket recommended'
|
||||
},
|
||||
{
|
||||
title: lan.soft.php_fpm_model,
|
||||
name: 'pm',
|
||||
@@ -2587,14 +3245,14 @@ var soft = {
|
||||
clicks = clicks.concat(_form.clicks);
|
||||
}
|
||||
_c_form.append('<ul class="help-info-text c7">\
|
||||
<li>[Max num of child processes] The larger the number, the stronger the concurrency, but max_children should not exceed 5000</li>\
|
||||
<li>[Ram] Each PHP child process needs about 20MB of Ram, too large max_children will cause server instability</li>\
|
||||
<li>[Static mode] In the static mode, the set number of child processes is always maintained, which has a large Ram overhead, but has a good concurrency capability.</li>\
|
||||
<li>[Dynamic mode] will recover the process according to the set max number of idle processes, the Ram overhead is small, it is recommended to use a small Ram machine</li>\
|
||||
<li>[Max num of child processes] The larger the number, the stronger the concurrency,<br> but max_children should not exceed 5000.</li>\
|
||||
<li>[Ram] Each PHP child process needs about 20MB of Ram,<br> too large max_children will cause server instability.</li>\
|
||||
<li>[Static mode] In the static mode, the set number of child processes is always maintained,<br> which has a large Ram overhead, but has a good concurrency capability.</li>\
|
||||
<li>[Dynamic mode] will recover the process according to the set max number of idle processes,<br> the Ram overhead is small, it is recommended to use a small Ram machine.</li>\
|
||||
<li>[64GB Ram recommended value] max_children <= 1000, start / min_spare = 50, max_spare <= 200</li>\
|
||||
<li>[Multi-PHP Version] If you have installed multiple PHP versions and are using them, it is recommended to reduce the concurrent configuration appropriately.</li>\
|
||||
<li>[No database] If no database such as mysql is installed, it is recommended to set 2 times the recommended concurrency</li>\
|
||||
<li>[Note] The above are the recommended configuration instructions. The online projects are complex and diverse. Please adjust according to actual conditions.</li>\
|
||||
<li>[Multi-PHP Version] If you have installed multiple PHP versions and are using them,<br> it is recommended to reduce the concurrent configuration appropriately.</li>\
|
||||
<li>[No database] If no database such as mysql is installed,<br> it is recommended to set 2 times the recommended concurrency.</li>\
|
||||
<li>[Note] The above are the recommended configuration instructions.<br> The online projects are complex and diverse. Please adjust according to actual conditions.</li>\
|
||||
</ul>')
|
||||
tabCon.append(_c_form);
|
||||
|
||||
@@ -2932,26 +3590,17 @@ var soft = {
|
||||
});
|
||||
},
|
||||
|
||||
input_zip: function(plugin_name, tmp_path) {
|
||||
bt.soft.show_speed_window('Installing, this may take a few minutes...', function() {
|
||||
$.post('/plugin?action=input_zip', {
|
||||
plugin_name: plugin_name,
|
||||
tmp_path: tmp_path
|
||||
}, function(rdata) {
|
||||
input_zip: function (plugin_name,tmp_path,data) {
|
||||
bt.soft.show_speed_window({title:'Installing, this may take a few minutes...',status:true},function(){
|
||||
$.post('/plugin?action=input_zip', { plugin_name: plugin_name, tmp_path: tmp_path }, function (rdata) {
|
||||
layer.closeAll()
|
||||
if (rdata.status) {
|
||||
soft.get_list();
|
||||
}
|
||||
setTimeout(function() {
|
||||
layer.msg(rdata.msg, {
|
||||
icon: rdata.status ? 1 : 2
|
||||
})
|
||||
}, 1000);
|
||||
setTimeout(function () { layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 }) }, 1000);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
function soft_td_width_auto() {
|
||||
|
||||
@@ -35,7 +35,14 @@ Terms.prototype = {
|
||||
//服务器消息事件
|
||||
on_message: function (ws_event){
|
||||
result = ws_event.data;
|
||||
if (result === "\rServer connection failed!\r" || result == "\rWrong user name or password!\r") {
|
||||
if(!result) return;
|
||||
// if (result === "\rServer connection failed!\r" || result == "\rWrong user name or password!\r") {
|
||||
// this.close();
|
||||
// return;
|
||||
// }
|
||||
if ((result.indexOf("@127.0.0.1:") != -1 || result.indexOf("@localhost:") != -1) && result.indexOf('Authentication failed') != -1) {
|
||||
this.term.write(result);
|
||||
host_trem.localhost_login_form(result);
|
||||
this.close();
|
||||
return;
|
||||
}
|
||||
@@ -102,7 +109,6 @@ Terms.prototype = {
|
||||
if (!this.bws || this.bws.readyState == 3 || this.bws.readyState == 2) {
|
||||
this.connect();
|
||||
}
|
||||
|
||||
//判断当前连接状态,如果!=1,则100ms后尝试重新发送
|
||||
if (this.bws.readyState === 1) {
|
||||
this.bws.send(data);
|
||||
@@ -158,6 +164,7 @@ var host_trem = {
|
||||
host_list:[],
|
||||
command_list:[],
|
||||
sort_time:null,
|
||||
is_full:false,
|
||||
command_form:{
|
||||
title:'',
|
||||
shell:'',
|
||||
@@ -172,22 +179,69 @@ var host_trem = {
|
||||
},
|
||||
init:function(){
|
||||
var that = this,isMousemove = true;
|
||||
$(window).resize(function(){
|
||||
var win = $(window)[0],win_width = win.innerHeight,win_height = win.innerHeight;
|
||||
$('.main-content .safe').height(win_height - 105);
|
||||
$('#term_box_view,.term_tootls').height(win_height - 105);
|
||||
$('.tootls_commonly_list').height(win_height - 563);
|
||||
Object.defineProperty(host_trem,'is_full',{
|
||||
get:function(val){
|
||||
return val;
|
||||
},
|
||||
set:function(newValue) {
|
||||
if(newValue){
|
||||
$('body').addClass('full_term_view');
|
||||
var win = $(window)[0],win_width = win.innerHeight,win_height = win.innerHeight;
|
||||
$('.main-content .safe').height(win_height);
|
||||
$('#term_box_view,.term_tootls').height(win_height);
|
||||
$('.tootls_host_list').height((win_height - 80) * .75);
|
||||
$('.tootls_commonly_list').height((win_height - 80) * .25);
|
||||
$('.tab_tootls .glyphicon').removeClass('glyphicon-resize-full').addClass('glyphicon-resize-small').attr('title','Exit full screen');
|
||||
}else{
|
||||
$('body').removeClass('full_term_view');
|
||||
$('.tab_tootls .glyphicon').removeClass('glyphicon-resize-small').addClass('glyphicon-resize-full').attr('title','Full Screen');
|
||||
}
|
||||
}
|
||||
});
|
||||
document.onkeydown = function(e){
|
||||
e = e || window.event;
|
||||
if ((e.metaKey && e.keyCode == 82) || e.keyCode == 116){
|
||||
return false;
|
||||
}
|
||||
if(that.is_full && e.keyCode == 27){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$(window).resize(function(ev){
|
||||
var win = $(window)[0],win_width = win.innerHeight,win_height = win.innerHeight,host_commonly = win_height - 185;
|
||||
if(that.isFullScreen()){
|
||||
$('.main-content .safe').height(win_height);
|
||||
$('#term_box_view,.term_tootls').height(win_height);
|
||||
$('.tootls_host_list').height((win_height - 80) * .75);
|
||||
$('.tootls_commonly_list').height((win_height - 80) * .25);
|
||||
}else{
|
||||
$('.main-content .safe').height(win_height - 105);
|
||||
$('#term_box_view,.term_tootls').height(win_height - 105);
|
||||
$('.tootls_host_list').height(host_commonly * .75);
|
||||
$('.tootls_commonly_list').height(host_commonly * .25);
|
||||
}
|
||||
var id = $('.term_item_tab .active').data('id');
|
||||
var item_term = that.host_term[id].term;
|
||||
item_term.FitAddon.fit();
|
||||
that.host_term[id].resize({cols:item_term.cols, rows:item_term.rows});
|
||||
});
|
||||
$('.tab_tootls').on('click','.glyphicon-resize-full',function(){
|
||||
$(this).removeClass('glyphicon-resize-full').addClass('glyphicon-resize-small').attr('title','Exit full Screen');
|
||||
$('body').addClass('full_term_view');
|
||||
that.requestFullScreen();
|
||||
});
|
||||
$('.tab_tootls').on('click','.glyphicon-resize-small',function(){
|
||||
$(this).removeClass('glyphicon-resize-small').addClass('glyphicon-resize-full').attr('title','Full Screen');
|
||||
$('body').removeClass('full_term_view');
|
||||
that.exitFullscreen();
|
||||
});
|
||||
|
||||
$(document).ready(function (e) {
|
||||
var win = $(window)[0],win_width = win.innerHeight,win_height = win.innerHeight;
|
||||
var win = $(window)[0],win_width = win.innerHeight,win_height = win.innerHeight,host_commonly = win_height - 185;
|
||||
$('.main-content .safe').height(win_height - 105);
|
||||
$('#term_box_view,.term_tootls').height(win_height - 105);
|
||||
$('.tootls_commonly_list').height(win_height - 563);
|
||||
$('.tootls_host_list').height(host_commonly * .75);
|
||||
$('.tootls_commonly_list').height(host_commonly * .25);
|
||||
that.open_term_view();
|
||||
});
|
||||
|
||||
@@ -361,6 +415,134 @@ var host_trem = {
|
||||
this.reader_host_list();
|
||||
this.reader_command_list();
|
||||
},
|
||||
// 判断全屏状态
|
||||
isFullScreen:function() {
|
||||
var is_full = document.isFullScreen || document.mozIsFullScreen || document.webkitIsFullScreen;
|
||||
this.is_full = is_full
|
||||
return is_full;
|
||||
},
|
||||
|
||||
// 进入全屏
|
||||
requestFullScreen:function(element){
|
||||
if(element == undefined) element = document.documentElement;
|
||||
// 判断各种浏览器,找到正确的方法
|
||||
var requestMethod = element.requestFullScreen || //W3C
|
||||
element.webkitRequestFullScreen || //FireFox
|
||||
element.mozRequestFullScreen || //Chrome等
|
||||
element.msRequestFullScreen; //IE11
|
||||
if (requestMethod) {
|
||||
requestMethod.call(element);
|
||||
} else if (typeof window.ActiveXObject !== "undefined") { //for Internet Explorer
|
||||
var wscript = new ActiveXObject("WScript.Shell");
|
||||
if (wscript !== null) {
|
||||
wscript.SendKeys("{F11}");
|
||||
}
|
||||
}
|
||||
this.is_full = true;
|
||||
},
|
||||
// 退出全屏
|
||||
exitFullscreen:function(element) {
|
||||
if(element == undefined) element = document.documentElement;
|
||||
// 判断各种浏览器,找到正确的方法
|
||||
var exitMethod = document.exitFullscreen || //W3C
|
||||
document.mozCancelFullScreen || //FireFox
|
||||
document.webkitExitFullscreen || //Chrome等
|
||||
document.webkitExitFullscreen; //IE11
|
||||
if (exitMethod) {
|
||||
exitMethod.call(document);
|
||||
} else if (typeof window.ActiveXObject !== "undefined") { //for Internet Explorer
|
||||
var wscript = new ActiveXObject("WScript.Shell");
|
||||
if (wscript !== null) {
|
||||
wscript.SendKeys("{F11}");
|
||||
}
|
||||
}
|
||||
this.is_full = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* @name 本地服务器登录表单
|
||||
* @author chudong<2020-08-10>
|
||||
* @return void
|
||||
*/
|
||||
localhost_login_form:function(result){
|
||||
var that = this,form = $(this.render_template({html:host_form_view.innerHTML,data:{form:$.extend(that.host_form,{host:'127.0.0.1'})}})),id = $('.localhost_item').data('id')
|
||||
form.find('.ssh_ps_tips').remove();
|
||||
form.prepend('<div class="localhost-form-title"><i class="localhost-form_tip"></i><span style="vertical-align: middle;">Login failed, please fill the local server information!</span></div>');
|
||||
form.append('<button type="submit" class="btn btn-sm btn-success">Login</button>');
|
||||
$('#'+id).append('<div class="localhost-form-shade"><div class="localhost-form-view bt-form-2x">'+ form[0].innerHTML +'</div></div>');
|
||||
if(result){
|
||||
if(result.indexOf('@127.0.0.1') != -1){
|
||||
var user = result.split('@')[0].split(',')[1];
|
||||
var port = result.split('1:')[1]
|
||||
$("input[name='username']").val(user);
|
||||
$("input[name='port']").val(port);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
$('.auth_type_checkbox').click(function(){
|
||||
var index = $(this).index();
|
||||
$(this).addClass('btn-success').removeClass('btn-default').siblings().removeClass('btn-success').addClass('btn-default')
|
||||
switch(index){
|
||||
case 0:
|
||||
$('.c_password_view').addClass('show').removeClass('hidden');
|
||||
$('.c_pkey_view').addClass('hidden').removeClass('show').find('input').val('');
|
||||
break;
|
||||
case 1:
|
||||
$('.c_password_view').addClass('hidden').removeClass('show').find('input').val('');
|
||||
$('.c_pkey_view').addClass('show').removeClass('hidden');
|
||||
break;
|
||||
}
|
||||
});
|
||||
$('.localhost-form-view > button').click(function(){
|
||||
var form = {};
|
||||
$('.localhost-form-view input,.localhost-form-view textarea').each(function(index,el){
|
||||
var name = $(this).attr('name'),value = $(this).val();
|
||||
form[name] = value;
|
||||
switch(name){
|
||||
case 'port':
|
||||
if(!bt.check_port(value)){
|
||||
bt.msg({status:false,msg:'Server port format error!'});
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'username':
|
||||
if(value == ''){
|
||||
bt.msg({status:false,msg:'Server user name cannot be empty!'});
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'password':
|
||||
if(value == '' && $('.c_password_view').hasClass('show')){
|
||||
bt.msg({status:false,msg:'Server password cannot be empty!'});
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'pkey':
|
||||
if(value == '' && $('.c_pkey_view').hasClass('show')){
|
||||
bt.msg({status:false,msg:'The server key cannot be empty!'});
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
delete form.sort
|
||||
form.ps = 'Local server';
|
||||
that.create_host(form,function(res){
|
||||
bt.msg(res);
|
||||
if(res.status){
|
||||
bt.msg({status:true,msg:'Login successful!'});
|
||||
$('.localhost_item .icon-trem-close').click();
|
||||
that.open_term_view();
|
||||
}
|
||||
});
|
||||
});
|
||||
$('.localhost-form-view [name="password"]').keyup(function(e){
|
||||
if(e.keyCode == 13){
|
||||
$('.localhost-form-view > button').click();
|
||||
}
|
||||
}).focus();
|
||||
},
|
||||
|
||||
reader_right_menu:function(config,callback){
|
||||
var menu = $('<ul class="menu_right_list" id="term_title_menu"></ul>').css({'top':config.position[1],'left':config.position[0]}),html = '';
|
||||
@@ -612,7 +794,7 @@ var host_trem = {
|
||||
tab_content.find('.term_item').removeClass('active').siblings().removeClass('active');
|
||||
tab_content.append('<div class="term_item active" id="'+ random +'" data-host="'+ info.host +'"></div>');
|
||||
item_list.find('.item').removeClass('active');
|
||||
item_list.append('<span class="active item" data-host="'+ info.host +'" data-id="'+ random +'"><i class="icon icon-sucess"></i><div class="content"><span>'+ info.ps +'</span></div><span class="icon-trem-close"></span></span>');
|
||||
item_list.append('<span class="active item '+ (info.host =='127.0.0.1'?'localhost_item':'') +'" data-host="'+ info.host +'" data-id="'+ random +'"><i class="icon icon-sucess"></i><div class="content"><span>'+ info.ps +'</span></div><span class="icon-trem-close"></span></span>');
|
||||
this.host_term[random] = new Terms('#'+random,{ssh_info:{host:info.host,ps:info.ps,id:random}});
|
||||
},
|
||||
/**
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"TYPE_PANEL":"Panel configuration",
|
||||
"TYPE_PHP":"PHP configuration",
|
||||
"TYPE_CRON":"Cron job",
|
||||
"USER_MANAGE": "User Management",
|
||||
"TYPE_FIREWALL":"Firewall manager",
|
||||
"DOMAIN_ADD_SUCCESS":"Site [{1}] added domain [{2}] successfully!",
|
||||
"DOMAIN_DEL_SUCCESS":"Site [{1}] deleted domain [{2}] successfully!",
|
||||
@@ -150,10 +151,24 @@
|
||||
"MODIFY_SSH_INFO": "Modify the SSH information of HOST: {1}",
|
||||
"ADD_SSH_INFO": "Add the SSH information of HOST: {1}",
|
||||
"DEL_SSH_INFO": "Delete the SSH information of HOST: {1}",
|
||||
"TYPE_TERMINAL": "aaPanel terminal",
|
||||
"ADD_COMMAND_COMMAND": "Add common commands [{1}]",
|
||||
"EDIT_COMMAND_COMMAND": "Modify common commands [{1}]",
|
||||
"DEL_COMMAND_COMMAND": "Delete common commands [{1}]",
|
||||
"OPEN_FILE": "Open File",
|
||||
"TASK_QUEUE": "Task queue"
|
||||
"TASK_QUEUE": "Task queue",
|
||||
"SSH_LOGIN": "Successfully logged in to the SSH server [{1}:{2}]",
|
||||
"EDIT_MENU_SUCCESS": "Successfully modify the panel menu display list",
|
||||
"TMP_LOGIN": "Generate temporary connection, expiration time: {1}",
|
||||
"TMP_LOGIN1": "Temporary login URL has been generated",
|
||||
"TMP_LOGIN2": "Failed to generate temporary login URL",
|
||||
"TMP_LOGIN3": "Delete temporary login URL",
|
||||
"LOGOUT_TMP_UESR": "Force logout of temporary users:{1}",
|
||||
"CREATE_USER": "Create new user {1}",
|
||||
"DEL_USER": "Delete users[{1}]",
|
||||
"EDIT_USER": "Edit user{1}",
|
||||
"ADD_COMPILATION_PARA": "Add custom compilation parameters: {1}:{2}",
|
||||
"REMOVE_PARA": "Remove custom compilation parameters: {1}:{2}",
|
||||
"SET_SOFTWARE_COMPILATION": "Setup software: Custom compilation parameters for {1} are configured as: {2}",
|
||||
"SET_FILE_NOTES": "Set the file name [{1}], notes: {2}",
|
||||
"CLEAR_FILE_NOTES": "Clear file notes [{1}]"
|
||||
}
|
||||
|
||||
@@ -185,6 +185,7 @@
|
||||
"DATABASE_NAME_ERR":"Database name is illegal!",
|
||||
"DATABASE_NAME_ERR_T":"Database name cannot contain special characters!",
|
||||
"DATABASE_NAME_EXISTS":"Database exists!",
|
||||
"DATABASE_USERNAME_EXISTS": "The user name already exists. For security reasons, we do not allow one database user to manage multiple databases",
|
||||
"DATABASE_NAME_LEN":"Database name cannot be more than 16 characters!",
|
||||
"DATABASE_ERR_CONNECT":"ERROR to connect database, pls check database status!",
|
||||
"DATABASE_ERR_PASS":"Mysql root or user password is incorrect, please try to reset!",
|
||||
@@ -474,7 +475,6 @@
|
||||
"AUTO_INSTALL_ACME_FAIL": "Trying to automatically install ACME failed, please try to install manually by the following command<p>Installation command",
|
||||
"SET_API_FIRST": "Please set this API first",
|
||||
"INSTALL_CLOUDDNS_FIRST": "Please install the [CloudDNS] plugin first.",
|
||||
"CHOOSE_DOMAIN": "Please choose domain",
|
||||
"CHECK_SSL_ERR": "Wildcard domain cannot use the method of [file verification] to apply for a certificate!",
|
||||
"RESOLVE_DOMAIN_BYF": "Successfully got, please manually resolve the domain name",
|
||||
"GET_FAIL": "Failed to get!",
|
||||
@@ -970,7 +970,6 @@
|
||||
"SSH_LOGIN_ERR4": "The protocol header response timed out, and the network quality with the target server was too bad: {1}",
|
||||
"SSH_LOGIN_ERR5": "The SSH protocol handshake timed out, and the network quality with the target server is too bad",
|
||||
"SSH_LOGIN_ERR6": "unknown error: {1}",
|
||||
"SSH_LOGIN": "Successfully logged in to the SSH server [{1}:{2}]",
|
||||
"LOGIN_SUCCESS2": "Login success\n",
|
||||
"CONNECTION_SUCCEEDED": "connection succeeded",
|
||||
"RECONNECT_SSH": "The connection is disconnected, press enter to try to reconnect!",
|
||||
@@ -984,5 +983,241 @@
|
||||
"UNBOUND_DEVICE": "Unbound device",
|
||||
"KEY_ERR": "Key verification failed",
|
||||
"FORM_DATA_ERR": "No form_data data found",
|
||||
"WRONG_RESPONSE": "Wrong response: {1}"
|
||||
"WRONG_RESPONSE": "Wrong response: {1}",
|
||||
"TYPE_TERMINAL": "aaPanel terminal",
|
||||
"WRONG_CONN_ADDR": "Wrong connection address",
|
||||
"RECONN_TIMES": "Reconnection attempts:{1}",
|
||||
"RECONN_FAILED": "Retry connection failed, {1}",
|
||||
"CONN_FAIL": "Connection failure: {1}",
|
||||
"CONN_FAIL1": "Connection failure: {1}:{2}",
|
||||
"AUTH_PRI_KEY": "Authenticating private key",
|
||||
"AUTH_PASSWD": "Authenticating password",
|
||||
"AUTH_FAIL": "Authentication failed {1}",
|
||||
"SSH_LOGIN_ERR10": "The protocol header response timed out",
|
||||
"SSH_LOGIN_ERR11": "The SSH protocol handshake timed out",
|
||||
"SSH_LOGIN_INFO3": "The authentication is successful and the session channel is being constructed",
|
||||
"SSH_LOGIN_INFO2": "Channel is built",
|
||||
"SSH_LOGIN_ERR14": "Channel disconnected",
|
||||
"SSH_LOGIN_INFO": "Session interrupted",
|
||||
"SSH_LOGIN_ERR15": "Error reading tty buffer data, {1}",
|
||||
"SSH_LOGIN_INFO1": "The client has actively disconnected",
|
||||
"SSH_LOGIN_ERR16": "An error occurred while reading data from websocket. Retrying",
|
||||
"SSH_LOGIN_ERR17": "An error occurred while writing data to the buffer: {1}",
|
||||
"DB_EXIST1": "The specified database already exists in MySQL, please change the name!",
|
||||
"LOGOUT_TMP_USER": "Temporary user has been forcibly logged out:{1}",
|
||||
"TMP_USER_NOT_LOGIN": "The specified user is not currently logged in!",
|
||||
"PERMISSION_DENIED": "Permission denied!",
|
||||
"PARAMETER_LEN_ERR": "Wrong parameter length!",
|
||||
"PARAMETER_FORMAT_ERR": "Wrong parameter format!",
|
||||
"VCODE_LEN_ERR": "Verification code length error!",
|
||||
"EXTRA_PARAMETER_ERR": "There can be no extra parameters in the login parameters",
|
||||
"USER_OR_PASSWD_ERR": "Username or Password incorrect: {1}",
|
||||
"NGINX_CONF_NOT_EXISTS": "Nginx configuration file does not exist!",
|
||||
"PARAMETER_WEBNAME_ERR": "The format of the webname parameter is incorrect, it should be a parseable JSON string",
|
||||
"WEBSITE_TRAFFIC_LIMIT_ERR": "Concurrency restrictions, IP restrictions, traffic restrictions must be greater than 0",
|
||||
"INDEX_FILE_ERR": "Failed to get, there is no default document in the configuration file",
|
||||
"STATIC": "Static",
|
||||
"PHP_SETUP_FAILED": "Setup failed, no enable-php-xx related configuration items were found in the website configuration file!",
|
||||
"GET_RUN_PATH_FAILED": "Get Site run path false",
|
||||
"ANTI_THEFT_EMPTY_ERR": "Anti-theft chain domain name cannot be empty!",
|
||||
"ANTI_THEFT_ERR": "Please turn on anti-theft first!",
|
||||
"SSL_ORDER_GET_FAILED": "Failed to get, please try again later!",
|
||||
"SSL_ORDER_HTTPS_ERR": "[Force HTTPS] is enabled on the current website, please turn off this function before applying for an SSL certificate!",
|
||||
"SSL_ERR_MSG": "Cannot access verification file correctly",
|
||||
"SSL_ERR_MSG1": "Possible reason:",
|
||||
"SSL_ERR_MSG2": "1. The resolution is not correct, or the resolution is not effective [Please resolve the domain name correctly, or wait for the resolution to take effect and try again]",
|
||||
"SSL_ERR_MSG3": "2. Check if there is 301/302 redirection set up [please temporarily turn off the redirection related configuration]",
|
||||
"SSL_ERR_MSG4": "3. Check whether the website is set to force HTTPS [please turn off the force HTTPS function temporarily]",
|
||||
"SSL_RENEW_ERR": "There are currently no certificates to renew!",
|
||||
"WEBSITE_SSL_RENEW_ERR": "There is no certificate that can be renewed on the current website..",
|
||||
"MYSQL_SSL_ERR": "SSL is not enabled in the database, please open it in the Mysql manager first",
|
||||
"MYSQL_SSL_OPEN_SUCCESS": "Open successfully, take effect after manually restarting the database",
|
||||
"MYSQL_CONF_ERR": "Database configuration file failed to get checked, please check if MySQL configuration file exists [/etc/my.cnf]",
|
||||
"MYSQL_DATA_DIR_ERR": "The database directory does not exist!",
|
||||
"MYSQL_BINLOG_ERR": "Please uninstall the Mysql master-slave replication plugin before closing the binary log! !",
|
||||
"MYSQL_PARAMETER_ERR": "innodb_log_buffer_size cannot be less than 8MB",
|
||||
"NONSUPPORT51": "Nonsupport mysql5.1!",
|
||||
"START_BACKUP": "Start backup",
|
||||
"BACKUP_COMPLETED": "Backup completed",
|
||||
"BACKUP_DIR_NOT_EXIST": "The specified directory {1} does not exist!",
|
||||
"BACKUP_UPLOADING": "Uploading to {1}, please wait ...",
|
||||
"BACKUP_UPLOAD_SUCCESS": "Successfully uploaded to {1}",
|
||||
"BACKUP_UPLOAD_FAILED": "Error: File upload failed, skip this backup!",
|
||||
"BACKUP_DEL": "User settings do not retain local backups, deleted {1}",
|
||||
"BACKUP_CLEAN_ERR": "Failed to clean expired backup, error: {1}",
|
||||
"BACKUP_KEEP": "Keep the latest number of backups: {1} copies",
|
||||
"BACKUP_CLEAN": "Expired backup files have been cleaned from disk: {1}",
|
||||
"BACKUP_CLEAN_REMOVE": "Expired backup files have been cleaned from {1}: {2}",
|
||||
"BACKUP_SITE": "Backup site: {1}",
|
||||
"WEBSITE_DIR": "Website root directory: {1}",
|
||||
"BACKUP_DIR": "Backup directory: {1}",
|
||||
"DIR_SIZE": "Directory size: {1}",
|
||||
"BACKUP_EXCLUSION": "Exclusion setting: {1}",
|
||||
"PARTITION_INFO": "Partition {1} available disk space is: {2}, available Inode is: {3}",
|
||||
"PARTITION_LESS_THEN": "The available disk space of the target partition is less than {1}, and the backup cannot be completed. Please increase the disk capacity or change the default backup directory on the settings page!",
|
||||
"INODE_LESS_THEN": "The available Inode of the target partition is less than {1}, and the backup cannot be completed. Please increase the disk capacity or change the default backup directory on the settings page!",
|
||||
"START_COMPRESS": "Start compressing files: {1}",
|
||||
"COMPRESS_TIME": "Compression completed, took {1} seconds, compressed package size: {2}",
|
||||
"WEBSITE_BACKUP_TO": "Site backed up to: {1}",
|
||||
"DIR_BACKUP_TO": "Directory has been backed up to: {1}",
|
||||
"DB_BACKUP_ERR": "The specified database [ {1} ] has no data!",
|
||||
"DB_BACKUP": "Backup database:{1}",
|
||||
"DB_SIZE": "Database size: {1}",
|
||||
"DB_CHARACTER": "Database character set: {1}",
|
||||
"EXPORT_DB": "Start exporting database: {1}",
|
||||
"EXPORT_DB_ERR": "Database export failed!",
|
||||
"DB_BACKUP_TO": "Database has been backed up to: {1}",
|
||||
"EMAIL_NOT_EXISTS": "Email does not exist",
|
||||
"INPUT_EMAIL": "Please input your email",
|
||||
"EMAIL_ERR": "Please enter your vaild email",
|
||||
"EMAIL_EXISTS": "Email already exists",
|
||||
"COMPLETE_INFO": "Please complete the information",
|
||||
"TEST_MAIL_TITLE": "aaPanel Alert Test Email",
|
||||
"TEST_MAIL_CONTENT": "aaPanel Alert Test Email",
|
||||
"TEST_MAIL_SEND_ERR": "Email sending failed, please check if the STMP password is correct or the hosts are correct",
|
||||
"NO_DATA": "No Data",
|
||||
"MAILBOX_NOT_EXIST": "The mailbox does not exist, please add it to the mailbox list",
|
||||
"EMAIL_TITLE_ERR": "Please fill in the email title",
|
||||
"EMAIL_CONTENT_ERR": "Please enter the email content",
|
||||
"SMTP_INFO_ERR": "STMP information was not found, please re-add custom mail STMP information in the settings",
|
||||
"SEND_SUCCESS": "Sent successfully",
|
||||
"SEND_FAILED": "Failed to send",
|
||||
"USERNAME_ERR": "User name must be at least 2 characters",
|
||||
"PASSWORD_ERR": "Password must be at least 8 characters",
|
||||
"USERNAME_EXIST": "The specified username already exists!",
|
||||
"USERNAME_NOT_EXIST": "The specified username not exists!",
|
||||
"CREATE_USER_SUCCESS": "Create new user {1} success!",
|
||||
"DEL_USER_ERR": "Cannot delete initial default user!",
|
||||
"DEL_USER_SUCCESS": "Delete user {1} success!",
|
||||
"DEL_USER_FAILED": "User deletion failed!",
|
||||
"CREATE_USER_FAILED": "Create new user failed!",
|
||||
"NO_CHANGE_SUBMITTED": "No changes submitted",
|
||||
"WRONG_MODE": "Wrong operating mode",
|
||||
"EMAIL_FORMAT_ERR": "The E-Mail format is illegal",
|
||||
"GET_PHP_VER_ERR": "Failed to get php version!",
|
||||
"DEVELOPER_MODE": "{1} Developer mode(DeBug)",
|
||||
"OFFLINE_MODE": "{1} Offline mode",
|
||||
"KEY_NOT_EXIST": "The key does not exist. Please turn on and try again.",
|
||||
"USERNAME_NOT_EXIST1": "The username does not exist. Please turn on and try again.",
|
||||
"SELECT_MODE": "Please enter the operation mode",
|
||||
"GENERATE_KEY_ERR": "Failed to generate key or username. Please check if the hard disk space is insufficient or the directory cannot be written.[ {1} ]",
|
||||
"CLOSE_SUCCESS": "Closed successfully",
|
||||
"GOOGLE_AUTH_ERR": "Did not open Google authentication",
|
||||
"TURN_ON_GOOGLE_AUTH": "Google authentication has been turned on",
|
||||
"QR_CODE_ERR": "No QR code data, please re-open",
|
||||
"MYSQL_ROOT_PASSWD_EMTPY_ERR": "Root password cannot be empty",
|
||||
"DB_PASSWD_EMPTY_ERR": "Database [{1}] password cannot be empty",
|
||||
"NGINX_NOT_INSTALL": "Nginx is not install",
|
||||
"CREATE_SITE_DIR_ERR": "Failed to create site root directory, {1}",
|
||||
"CHOOSE_DOMAIN": "Please choose a domain name",
|
||||
"CHOOSE_PORT": "Please choose a port",
|
||||
"CERT_ERR": "Certificate error, please paste the correct PEM format certificate!",
|
||||
"SSL_FILE_V_ERR": "A generic domain name cannot be used to apply for a certificate using [File Validation]!",
|
||||
"SSL_FILE_V_ERR_PROXY": "Sites that have reverse proxy turned on cannot request SSL!",
|
||||
"API_ERR": "Please set the API interface parameters of [{1}] first.",
|
||||
"CLOUD_DNS_ERR": "Please go to the software store to install [Cloud Resolution] and complete the domain name NS binding.",
|
||||
"REQUEST_MODULE_ERR": "Missing requests component, please try to repair the panel!",
|
||||
"WEBSITE_CONF_NOT_EXIST": "The specified website profile does not exist",
|
||||
"RESPONSE_ERR": "Response resources should use URI path or HTTP status code, such as: /test.png or 404",
|
||||
"PHP_NOT_FOUND": "No compatible PHP version found, please install first",
|
||||
"COMPLIANT_NAME_ERR": "Non-compliant names can only be numbers, letters, underscores",
|
||||
"PARA_NOT_EXIST": "The specified custom compilation parameters do not exist!",
|
||||
"WRONG_PARAMETER": "Wrong parameter",
|
||||
"UPLOAD_DIR_ERR": "Cannot upload files to the system root directory!",
|
||||
"RECYCLE_BIN_ERR": "This is the recycle bin directory, please press the [Recycle Bin] button in the upper right corner to open",
|
||||
"DIR_ERR": "This is not a directory",
|
||||
"FILE_EXIST_ERR": "The target file name already exists!",
|
||||
"MEANINGLESS_OPERA": "Meaningless operation",
|
||||
"FILE_ONLINE_EDIT_ERR": "The file format does not support online editing!",
|
||||
"FILE_ERR": "This is not a file!",
|
||||
"FILE_ERR1": "File encoding is not compatible and cannot be read correctly!",
|
||||
"FILE_ERR2": "Failed to open file, file may be occupied by other processes!",
|
||||
"PATH_PARA_ERR": "[path] parameter cannot be empty!",
|
||||
"HISTORY_DIR_ERR": "Cannot modify history copy directly!",
|
||||
"FILE_ERR3": "Wrong file content, please save again!",
|
||||
"HISTORY_ERR": "The specified historical copy does not exist!",
|
||||
"NOT_EDIT": "Not Edit",
|
||||
"AUTO_SAVE": "Automatically saved successfully!",
|
||||
"COPY_PRESS_ERR": "The operation failed, please re-copy the copy or cut process",
|
||||
"OPERA_FAILED": "The operation failed, please re-operate",
|
||||
"PHP_EXTENSION_UNINSTALL_ERR": "This extension is the default extension of OLS and cannot be uninstalled",
|
||||
"QUERY_ERR": "Query error, {1}",
|
||||
"FILE_DIR_NOT_EXIST": "File or directory does not exist!",
|
||||
"ADD_REPEATEDLY": "Do not add it repeatedly!",
|
||||
"FAVORITE_NOT_FOUND": "This favorite object could not be found!",
|
||||
"ADDRESS_NOT_EXIST": "The specified address does not exist!",
|
||||
"PASSWD_ERR": "The extract password length cannot be less than 4 bits",
|
||||
"ALREADY_SHARED": "Already shared!",
|
||||
"COMMAND_SENT": "Command has been sent!",
|
||||
"NO_COMPOSER_AVAILABLE": "No composer available!",
|
||||
"PHP_VER_NOT_FOUND": "No available PHP version was found, or the specified PHP version was not installed!",
|
||||
"COMPOSER_CONF_NOT_FOUND": "The composer.json configuration file was not found in the specified directory!",
|
||||
"COMPOSER_UPDATE_ERR": "Currently the latest version, no upgrade required!",
|
||||
"COMPOSER_UPDATE": "Upgrade composer from {1} to {2}",
|
||||
"SITE_SSL_ERR_3011": "The website has been redirected, please close it before applying!",
|
||||
"DEL_ERROR1": "There was an error deleting, please try again.",
|
||||
"DEL_WEBSITE_MULTIPLE": "Delete website [{1}] successfully",
|
||||
"DEL_DOMAIN_MULTIPLE": "Delete domain [{1}] successfully",
|
||||
"ENABLE_WEBSITE_MULTIPLE": "Enable website [{1}] successfully",
|
||||
"DISABLE_WEBSITE_MULTIPLE": "Disable website [{1}] successfully",
|
||||
"DEL_SUBDIRBIND": "Delete [{}] subdirectory binding successfully",
|
||||
"SET_ERROR1": "There was an error setting, please try again.",
|
||||
"SET_PHPV_MULTIPLE": "Set up website [{1}] PHP version successfully",
|
||||
"SET_EDATE_MULTIPLE": "Set the website [{1}] expiration time successfully",
|
||||
"CREATE_WEBSITE_ERR": "There was an error creating, please try again.",
|
||||
"CREATE_WEBSITE_MULTIPLE": "Create the website [ {1} ] successfully",
|
||||
"DEL_PROXY_MULTIPLE": "Delete [ {1} ] proxy successfully",
|
||||
"DEL_DIR_AUTH_MULTIPLE": "Delete [ {} ] dir auth successfully",
|
||||
"DEL_REDIRECT_MULTIPLE": "Delete redirects [{1}] successfully",
|
||||
"ALARM_TEST": "aaPanel alarm test",
|
||||
"MAIL_ADD_FAILED": "Add failed, please check if the URL is correct",
|
||||
"RENEW_FAILED": "The renewal failed and the certificate directory does not exist.",
|
||||
"RENEW_FAILED1": "Renewal failed, missing account_key.",
|
||||
"RENEW_SUCCESS1": "[ {1} ] The certificate renewal was successful.",
|
||||
"APPLY_SSL": "Ready to apply for SSL, domain name {1}",
|
||||
"APPLY_SSL_DOMAIN_ERR": "The list of applied domain names cannot be empty.",
|
||||
"MANUALLY_RESOLVE_DOMAIN": "Get successful, please manually resolve the domain name",
|
||||
"SAVEING_SSL": "|-Saving certificate..",
|
||||
"SET_AUTORENEW": "|-Setting up auto-renewal configuration..",
|
||||
"DEPLOY_SSL_TO_SITE": "|-The application is successful and it is being automatically deployed to the website!",
|
||||
"APPLY_SSL_SUCCESS": "Application successful.",
|
||||
"INIT_ACME": "|-Initializing ACME protocol...",
|
||||
"REGISTER_ACCOUNT": "|-Registering account...",
|
||||
"GET_VERIFICATION_INFO": "|-Getting verification information...",
|
||||
"RETURN_VERIFICATION_INFO": "|-Return the verification information to the front end, wait for the user to manually resolve the domain name and complete the verification...",
|
||||
"SUBMIT_V_REQUEST": "|-User submits verification request...",
|
||||
"CA_V_DOMAIN": "|-Requesting CA to verify domain name [{1}]...",
|
||||
"GET_CA_V_RES": "|-Get CA verification results [{1}]...",
|
||||
"ALL_DOMAIN_V_PASS": "|-All domain names are verified and CSR is being sent...",
|
||||
"GET_CERT_CONTENT": "|-Getting certificate content...",
|
||||
"CERT_APPLY_ERR": "Certificate acquisition failed, please try again later.",
|
||||
"CERT_APPLY_ERR1": "|-Error: {1}, exited the application process.",
|
||||
"DNS_CONNECT_ERR": "|-The DNS verification failed. Please check if the key is correct.",
|
||||
"EXIT_APPLY_PROCESS": "|-Exited the application process!",
|
||||
"DNS_CONNECT_ERR1": "The DNS verification failed. Please check if the key is correct.",
|
||||
"ADD_TXT_RECORD": "|-Adding resolution record, domain name [{1}], record value [{2}]...",
|
||||
"CHECK_TXT_RECORD": "|-Attempt to verify the resolution result, domain name [{}], record value [{}]...",
|
||||
"CA_CHECK_RECORD": "|-Request CA to verify domain name [{1}]...",
|
||||
"CHECK_CA_RES": "|-Check CA verification results [{1}]...",
|
||||
"APPLY_WITH_DNS_ERR": "|-An error occurred, try again [{1}]",
|
||||
"FETCH_CERT_CONTENT": "|-Fetching certificate content...",
|
||||
"CLEAR_RESOLVE_HISTORY": "|-Clearing resolve history [{1}]",
|
||||
"DNS_APPLY_ERR": "|-Error: {1}, exit the application process.",
|
||||
"CREATE_V_FILE": "|-Writing verification file [{1}]...",
|
||||
"CHECK_FILE_CONTENT": "|-Attempt to verify file contents via HTTP [{1}]...",
|
||||
"CHECK_FILE_CONTENT1": "|-Verified, content [{1}]...",
|
||||
"APPLY_SSL_ERROR_MSG": "The signing failed, we were unable to verify your domain name:<p>1. Check if the domain name is bound to the corresponding site.</p><p>2. Check if the domain name is correctly resolved to the server, or the resolution is not fully effective.</p><p>3. If your site has a reverse proxy set up, or if you are using a CDN, please turn it off first.</p><p>4. If your site has a 301 redirect, please turn it off first</p><p>5. If the above checks confirm that there is no problem, please try to change the DNS service provider.</p>'",
|
||||
"SUCCESS_V": "|-Successful verification, domain name [{1}], record type [{2}], record value [{3}]!",
|
||||
"NO_ORDER_RENEW": "|-There are currently no certificates to renew.",
|
||||
"TOTAL_RENEW": "|-{1} Total [{2}] renewal of visa tasks",
|
||||
"SSL_NOT_EXPIRED_OR_NOT_USE": "|-[{1}] Not expired or the site does not use the Let\\'s Encrypt certificate.",
|
||||
"WAIT_RENEW1": "|-{1} Waiting for renewal [{2}].",
|
||||
"RENEW_COMPLETED": "|-After the task is completed, a total of renewals are required.[{1}], renewal success [%s], renewal failed [{2}]. ",
|
||||
"RENEW_SUCCESS2": "|-Renewal success:{1}",
|
||||
"RENEW_FAILED2": "|-Renewal failed:",
|
||||
"DIR_END_WITH": "The end of the website directory cannot be \".\"",
|
||||
"File_END_WITH": "It is not recommended to use \".\" at the end of the file because there may be security risks",
|
||||
"DIR_END_WITH1": "It is not recommended to use \".\" at the end of the directory, because there may be safety risks",
|
||||
"API_DISABLED": "API has been disabled",
|
||||
"UNBOUND_USER": "Unbound user"
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"NET3":"Download speed",
|
||||
"NET4":"Total sent",
|
||||
"NET5":"Total received",
|
||||
"BT_ACCOUNT":"BT account",
|
||||
"ACCOUNT":"Account",
|
||||
"FREE":"Free",
|
||||
"INVITATION_REWARD":"Invitation reward",
|
||||
"WECHAT":"WeChat",
|
||||
@@ -139,7 +139,7 @@
|
||||
"CT8":"Server time",
|
||||
"CT9":"Panel user",
|
||||
"CT10":"Panel password",
|
||||
"CT11":"Bind BT account",
|
||||
"CT11":"Bind account",
|
||||
"CT12":"Panel template",
|
||||
"CY1":"Take alias for aaPanel",
|
||||
"CY2":"Suggested port: 8888-65535",
|
||||
|
||||
@@ -1144,7 +1144,7 @@ var lan = {
|
||||
"site_menu_1": "Subdirectory binding",
|
||||
"site_menu_2": "Website directory",
|
||||
"site_menu_3": "Traffic control",
|
||||
"site_menu_4": "URL rewirte",
|
||||
"site_menu_4": "URL rewrite",
|
||||
"site_menu_5": "Default indexes",
|
||||
"site_menu_6": "Configuration file",
|
||||
"site_menu_7": "SSL",
|
||||
@@ -1191,7 +1191,7 @@ var lan = {
|
||||
"limit_net_14": "Traffic control",
|
||||
"limit_net_15": "Limit the max traffic limit per request (unit: KB)",
|
||||
"subdirectories": "Subdirectories",
|
||||
"url_rewrite_alter": "Are you sure to create a independent URL rewirte rule for this subdirectory?",
|
||||
"url_rewrite_alter": "Are you sure to create a independent URL rewrite rule for this subdirectory?",
|
||||
"rule_cov_tool": "Rewrite rule converter",
|
||||
"a_c_n": "Apache to Nginx",
|
||||
"save_as_template": "Save as template",
|
||||
|
||||
@@ -299,7 +299,7 @@
|
||||
show: false,
|
||||
showBottom: true,
|
||||
btns: ["clear", "now", "confirm"],
|
||||
lang: "cn",
|
||||
lang: "en",
|
||||
theme: "default",
|
||||
position: null,
|
||||
calendar: false,
|
||||
@@ -1424,7 +1424,7 @@
|
||||
}
|
||||
} else {
|
||||
if(lay(btn).hasClass(DISABLED)) {
|
||||
return that.hint("不在有效日期或时间范围内")
|
||||
return that.hint("Not in the valid date or time range!")
|
||||
}
|
||||
}
|
||||
that.done();
|
||||
|
||||
@@ -103,15 +103,19 @@
|
||||
<span class="set-info c7">{{data['lan']['CY15']}}</span>
|
||||
</div>
|
||||
<div class="mtb15">
|
||||
<span class="set-tit text-right" title="{{data['lan']['BASICAUTH_TIPS1']}}">{{data['lan']['BASICAUTH']}}</span>
|
||||
<input id="basic_auth" name="basic_auth" class="inputtxt bt-input-text disable" type="text" value="{{data['basic_auth']['value']}}" disabled>
|
||||
<span class="modify btn btn-xs btn-success basic_auth" onclick="modify_basic_auth()" style=" margin-left: -38px;">{{data['lan']['CONFIG']}}</span>
|
||||
<span class="set-tit text-right" title="{{data['lan']['BASICAUTH_TIPS1']}}">{{data['lan']['BASICAUTH']}}</span>
|
||||
<div class="btn_tips">
|
||||
<input id="basic_auth" name="basic_auth" class="inputtxt bt-input-text disable" type="text" value="{{data['basic_auth']['value']}}" disabled>
|
||||
<span class="modify btn btn-xs btn-success basic_auth" onclick="modify_basic_auth()" style="margin-left: -38px;">{{data['lan']['CONFIG']}}</span>
|
||||
</div>
|
||||
<span class="set-info c7" style="margin-left: 25px;">{{data['lan']['BASICAUTH_TIPS1']}}</span>
|
||||
</div>
|
||||
<div class="mtb15">
|
||||
<span class="set-tit text-right" title="Message channel">Message channel</span>
|
||||
<input id="channel_auth" name="channel_auth" class="inputtxt bt-input-text disable" type="text" value="" disabled>
|
||||
<span class="modify btn btn-xs btn-success channel_auth" style="margin-left: -38px;" onclick="open_three_channel_auth()">Set</span>
|
||||
<span class="set-tit text-right" title="Message channel">Message channel</span>
|
||||
<div class="btn_tips">
|
||||
<input id="channel_auth" name="channel_auth" class="inputtxt bt-input-text disable" type="text" value="" disabled>
|
||||
<span class="modify btn btn-xs btn-success channel_auth" style="margin-left: -38px;" onclick="open_three_channel_auth()">Set</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mtb15">
|
||||
<span class="set-tit text-right" title="{{data['lan']['CT3']}}">{{data['lan']['CT3']}}</span>
|
||||
@@ -160,7 +164,28 @@
|
||||
<input name="password_" class="inputtxt bt-input-text disable" type="text" value="******" disabled>
|
||||
<span class="modify btn btn-xs btn-success" onclick="setPassword()">{{data['lan']['CY10']}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mtb15">
|
||||
<span class="set-tit text-right" title="{{data['lan']['CT10']}}">{{data['lan']['CT11']}}</span>
|
||||
<div class="btn_tips">
|
||||
<input name="btusername" class="inputtxt bt-input-text disable" type="text" value="" disabled>
|
||||
<span class="modify btn btn-xs btn-success mr5" onclick="bindBTName(2,'b')">{{data['lan']['CY11']}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mtb15">
|
||||
<span class="set-tit text-right">Menu bar hidden</span>
|
||||
<div class="btn_tips">
|
||||
<input class="inputtxt bt-input-text disable" id="panel_menu_hide" type="text" disabled>
|
||||
<span class="modify btn btn-xs btn-success" onclick="set_panel_ground()" style="margin-left: -35px;">Set</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mtb15">
|
||||
<span class="set-tit text-right">Temporary login</span>
|
||||
<div class="btn_tips">
|
||||
<input class="inputtxt bt-input-text disable" type="text" value="Temporary authorization for vistor" disabled>
|
||||
<span class="modify btn btn-xs btn-success" onclick="get_temp_login_view()">Modify</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--<p class="mtb15"><span class="set-tit text-right" title="{{data['lan']['CT11']}}">{{data['lan']['CT11']}}</span><input name="btusername" class="inputtxt bt-input-text disable" type="text" value="" disabled><span class="modify btn btn-xs btn-success mr5" onclick="bindBTName(2,'b')">{{data['lan']['CY11']}}</span></p>-->
|
||||
<!--<p class="mtb15 wxapp_p"><span class="set-tit text-right">{{data['lan']['WECHAT']}}</span><input class="inputtxt bt-input-text disable" type="text" value="{{data['wx']}}" disabled><span class="modify btn btn-xs btn-success mr5" onclick="open_wxapp()">{{data['lan']['CY11']}}</span></p>-->
|
||||
@@ -367,6 +392,20 @@
|
||||
margin: 0 0 10px 35px;
|
||||
font-size: 22px;
|
||||
}
|
||||
#panel_menu_tab .table>tbody>tr>td{
|
||||
height: auto;
|
||||
padding: 8px;
|
||||
}
|
||||
.create_temp_view{
|
||||
padding:15px 20px;
|
||||
}
|
||||
.create_temp_view .line .tname{
|
||||
text-align: left;
|
||||
float: inherit;
|
||||
}
|
||||
.create_temp_view .info-r {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
@@ -168,7 +168,7 @@
|
||||
<th>{{data['lan']['TH3']}}</th>
|
||||
<th>{{data['lan']['TH7']}}</th>
|
||||
<th>{{data['lan']['TH8']}}</th>
|
||||
<th>{{data['lan']['TH4']}}</th>
|
||||
<th>Last execution time</th>
|
||||
<th width="190">{{data['lan']['TH5']}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
{% extends "layout.html" %}
|
||||
|
||||
{% block content %}
|
||||
<style>
|
||||
#DataBody .dataBase,#DataBody .webNote{
|
||||
white-space: nowrap;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
min-width: auto;
|
||||
}
|
||||
</style>
|
||||
<div class="main-content pb55">
|
||||
<div class="container-fluid">
|
||||
<div class="pos-box bgw mtb15">
|
||||
@@ -22,7 +31,7 @@
|
||||
<button onclick="database.add_database()" title="{{data['lan']['BTNT1']}}" class="btn btn-success btn-sm" type="button" style="margin-right: 5px;">{{data['lan']['BTN1']}}</button>
|
||||
<button onclick="bt.database.set_root()" title="{{data['lan']['BTNT2']}}" class="btn btn-default btn-sm" type="button" style="margin-right: 5px;">{{data['lan']['BTN2']}}</button>
|
||||
<button onclick="bt.database.open_phpmyadmin('','root','{{data['mysql_root']}}')" title="{{data['lan']['BTNT3']}}" class="btn btn-default btn-sm" type="button" style="margin-right: 5px;">{{data['lan']['BTN3']}}</button>
|
||||
<!-- <a href="/adminer/index.php" target="_blank" title="Lightweight database management tool that supports remote database management" class="btn btn-default btn-sm" type="button" style="margin-right: 5px;">Adminer</a> -->
|
||||
<!--<a href="/adminer/index.php" target="_blank" title="Lightweight database management tool that supports remote database management" class="btn btn-default btn-sm" type="button" style="margin-right: 5px;">Adminer</a>-->
|
||||
<span style="float:right">
|
||||
<button batch="true" style="float: right;display: none;margin-left:10px;" onclick="database.batch_database('del');" title="{{data['lan']['BTNT4']}}" class="btn btn-default btn-sm">{{data['lan']['BTN4']}}</button>
|
||||
<button onclick="bt.recycle_bin.open_recycle_bin(6)" id="dataRecycle" title="{{data['lan']['BTNT4']}}" class="btn btn-default btn-sm" style="margin-left: 5px;"><span class="glyphicon glyphicon-trash" style="margin-right: 5px;"></span>{{data['lan']['RECYCLE_BIN']}}</button>
|
||||
|
||||
@@ -1,104 +1,308 @@
|
||||
{% extends "layout.html" %}
|
||||
{% block content %}
|
||||
<link rel="stylesheet" href="{{g.cdn_url}}/ace/styles/icons.css">
|
||||
<link rel="stylesheet" type="text/css" href="{{g.cdn_url}}/css/files_style.min.css">
|
||||
<style id="file_list_info">.file_checkbox{width:40px !important;}.file_name{width:300px !important;}.file_ps{width:200px !important;}.file_size{width:100px !important;}.file_mtime{width:180px !important;}.file_user{width:80px !important;}.file_accept{width:80px !important;}.file_operation{width:220px !important;}.file_table_view.list_view .file_list_content .file_tr{width:auto;}.file_table_view.list_view .file_list_content{width:auto;}</style>
|
||||
<div class="main-content">
|
||||
<div class="container-fluid" style="padding-bottom:50px">
|
||||
<div class="file-box bgw mtb15" style="position:relative; padding-top:110px">
|
||||
<div id="tipTools" class="plr15">
|
||||
<div class="ptb15">
|
||||
<div class="clearfix">
|
||||
<div class="pull-left">
|
||||
<button id="backBtn" class="backBtn btn btn-default btn-sm glyphicon glyphicon-arrow-left pull-left" title="{{data['lan']['BTN1']}}" onClick="BackDir()"></button>
|
||||
<button class="backBtn refreshBtn btn btn-default btn-sm glyphicon glyphicon-refresh pull-right" title="{{data['lan']['BTN2']}}" style="margin-left:-1px;"></button>
|
||||
<span id='DirPathPlace' class="pull-left"><input id="fileInputPath" type="text"></span>
|
||||
<span id='PathPlaceBtn' class="pull-left"></span>
|
||||
</div>
|
||||
<div class="pull-left mlr15" style="line-height:26px"><span id='DirInfo'></span></div>
|
||||
<div class="search pull-right" style="position: absolute; top: 6px; right: 5px;">
|
||||
<div class="search_box">
|
||||
<input id="search_all" type="checkbox">
|
||||
<label for="search_all">{{data['lan']['CONTAIN_SUBDIR']}}</label>
|
||||
<a style="display: none;" id="recycle_bin" data="{{data['recycle_bin']}}"></a>
|
||||
<div class="bt_file_updated">
|
||||
<div class="updated_icon">
|
||||
<div class="btn download">
|
||||
<div class="cloud">
|
||||
<div class="file"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="updated_title">Release the mouse to upload files or folders</div>
|
||||
</div>
|
||||
<!-- aceEditors -->
|
||||
<div class="file_bodys">
|
||||
<div class="file_path_views">
|
||||
<div class="file_path_upper" title="Back">
|
||||
<span class="glyphicon glyphicon-arrow-left"></span>
|
||||
<!-- <span>Back</span> -->
|
||||
</div>
|
||||
<div class="file_path_input">
|
||||
<div class="file_path_shadow"></div>
|
||||
<div class="file_dir_view"></div>
|
||||
<input type="text" data-path="/www/wwwroot" data-backspace class="path_input" id="fileInputPath"/>
|
||||
</div>
|
||||
<div class="file_path_refresh" title="Refresh"><i class="icon-file icon-file-refresh"></i></div>
|
||||
<div class="search_path_views">
|
||||
<input type="text" placeholder="Search file content" class="file_search_input">
|
||||
<span class="iconfont icon-shezhi1 is_search_children"></span>
|
||||
<button type="submit" class="path_btn"><i class="iconfont icon-search"></i></button>
|
||||
<div class="file_search_config">
|
||||
<div id="search_all" class="file_search_checked"></div>
|
||||
<label for="search_all">Include SubDir</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="file_nav_view">
|
||||
<div class="nav_group">
|
||||
<div class="nav_btn upload_file">
|
||||
<span class="nav_btn_title">Upload</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="nav_group">
|
||||
<div class="nav_btn upload_download">
|
||||
<span class="nav_btn_title">Remote download</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="nav_group">
|
||||
<div class="nav_btn create_file_or_dir">
|
||||
<span class="nav_btn_title">New</span><i class="iconfont icon-xiala"></i>
|
||||
<ul class="nav_down_list" data-menu="newFileType">
|
||||
<li data-type="newBlankDir"><i class="file_menu_icon create_file_icon"></i><span>New directory</span></li>
|
||||
<li data-type="newBlankFile"><i class="file_new_icon"></i><span>New blank file</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="nav_group">
|
||||
<div class="nav_btn favorites_file_path">
|
||||
<span class="nav_btn_title" data-menu="favorites">Favorites</span><i class="iconfont icon-xiala"></i>
|
||||
<ul class="nav_down_list"></ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="nav_group">
|
||||
<div class="nav_btn share_file_list">
|
||||
<span class="nav_btn_title">Share List</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="nav_group ">
|
||||
<div class="nav_btn terminal_view">
|
||||
<i class="iconfont icon-terminal"></i>
|
||||
<span class="nav_btn_title">Terminal</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 挂载磁盘列表 -->
|
||||
<div class="nav_group mount_disk_list"></div>
|
||||
<div class="float_r menu-header-foot">
|
||||
<div class="nav_group multi hide">
|
||||
<div class="batch_multi_title">
|
||||
<span>Please choose</span>
|
||||
<i class="iconfont icon-xiala"></i>
|
||||
<div class="batch_group_list">
|
||||
<div class="nav_btn_group" data-type="copy"><i class="file_menu_icon copy_file_icon"></i><span
|
||||
class="nav_btn_title">Copy</span></div>
|
||||
<div class="nav_btn_group" data-type="shear"><i class="file_menu_icon shear_file_icon"></i><span
|
||||
class="nav_btn_title">Cut</span></div>
|
||||
<div class="nav_btn_group" data-type="compress"><i class="file_menu_icon compress_file_icon"></i><span
|
||||
class="nav_btn_title">Compress</span></div>
|
||||
<div class="nav_btn_group" data-type="authority"><i class="file_menu_icon power_file_icon"></i><span
|
||||
class="nav_btn_title">Permission</span></div>
|
||||
<div class="nav_btn_group" data-type="del"><i class="file_menu_icon del_file_icon"></i><span
|
||||
class="nav_btn_title">Del</span></div>
|
||||
<div class="nav_btn_group hide" style="padding-left:10px;border-left: 1px solid #cfcfcf;margin-left: -1px;">
|
||||
<span class="nav_btn_title">More</span><i class="iconfont icon-xiala"></i>
|
||||
<ul class="nav_down_list">
|
||||
<li data-type="copy"><i class="file_menu_icon copy_file_icon"></i><span>Copy</span></li>
|
||||
<li data-type="shear"><i class="file_menu_icon shear_file_icon"></i><span>Cut</span></li>
|
||||
<li data-type="compress"><i class="file_menu_icon compress_file_icon"></i><span>Compress</span></li>
|
||||
<li data-type="authority"><i class="file_menu_icon power_file_icon"></i><span>Permission</span></li>
|
||||
<li data-type="del"><i class="file_menu_icon del_file_icon"></i><span>Del</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
<form target="hid" onsubmit='GetFiles(1)'>
|
||||
<input type="text" id="SearchValue" class="ser-text pull-left" placeholder="" style="padding-right: 159px;" />
|
||||
<button type="button" class="ser-sub pull-left" onclick='GetFiles(1)'></button>
|
||||
</form>
|
||||
<iframe name='hid' id="hid" style="display:none"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix ptb10">
|
||||
<button class="btn btn-default btn-sm pull-left" onclick="UploadFiles()">{{data['lan']['BTN3']}}</button>
|
||||
<button class="btn btn-default btn-sm pull-left" onclick="DownloadFile()" title="{{data['lan']['TI1']}}" style="margin:0 5px">{{data['lan']['BTN4']}}</button>
|
||||
<span id='BarTools'></span>
|
||||
<span id='Batch' style="background-color:#fff;position:absolute;right:217px;z-index:10"></span>
|
||||
<span id='comlist' class="comlist"></span>
|
||||
<div class="btn-group btn-group-sm pull-right" style="margin-right:5px;">
|
||||
<button id="set_icon" title="{{data['lan']['TI2']}}" type="button" class="btn btn-default">
|
||||
<i class="glyphicon glyphicon-th"></i>
|
||||
</button>
|
||||
<button id="set_list" title="{{data['lan']['TI3']}}" type="button" class="btn btn-default active">
|
||||
<i class="glyphicon glyphicon-th-list"></i>
|
||||
</button>
|
||||
<div class="nav_group file_all_paste hide">
|
||||
<div class="nav_btn_group">
|
||||
<i class="file_menu_icon paste_file_icon"></i><span class="nav_btn_title">Paste</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="nav_group manage_backup">
|
||||
<div class="nav_btn"><span class="glyphicon glyphicon-trash"></span><span class="nav_btn_title">Backup PMSN</span></div>
|
||||
</div>
|
||||
<div class="nav_group recycle_bin">
|
||||
<div class="nav_btn"><span class="glyphicon glyphicon-trash"></span><span class="nav_btn_title">Recycle bin</span></div>
|
||||
</div>
|
||||
<div class="nav_group btn-group btn-group-sm">
|
||||
<div class="btn btn-default cut_view_model" data-type="icon"><i class="glyphicon glyphicon-th"></i></div>
|
||||
<div class="btn btn-default cut_view_model" data-type="list"><i class="glyphicon glyphicon-th-list"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="file_table_view">
|
||||
<div class="file_list_header">
|
||||
<div class="file_main_title">
|
||||
<div class="file_checkbox file_th">
|
||||
<div class="file_check" data-type="all" data-checkbox="0"></div>
|
||||
</div>
|
||||
<div class="file_name file_th" data-tid="name">
|
||||
<span>File name</span>
|
||||
<div class="icon_sort"></div>
|
||||
</div>
|
||||
<!-- <div class="file_width_resize"></div>
|
||||
<div class="file_type file_th" data-tid="type">
|
||||
<span>类型</span>
|
||||
<div class="icon_sort"></div>
|
||||
</div> -->
|
||||
<div class="file_width_resize"></div>
|
||||
<div class="file_accept file_th" data-tid="accept">
|
||||
<span>PMSN/Owner</span>
|
||||
<div class="icon_sort"></div>
|
||||
</div>
|
||||
<div class="file_width_resize"></div>
|
||||
<div class="file_size file_th" data-tid="size">
|
||||
<span>Size</span>
|
||||
<div class="icon_sort"></div>
|
||||
</div>
|
||||
<div class="file_width_resize"></div>
|
||||
<div class="file_mtime file_th" data-tid="mtime">
|
||||
<span>Modification time</span>
|
||||
<div class="icon_sort"></div>
|
||||
</div>
|
||||
<div class="file_width_resize"></div>
|
||||
<div class="file_ps file_th" data-tid="ps">
|
||||
<span>Ps</span>
|
||||
<div class="icon_sort"></div>
|
||||
</div>
|
||||
<div class="file_width_resize"></div>
|
||||
<div class="file_operation file_th align-right" data-tid="operation">
|
||||
<span>Opt</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="divtable pd15" id="fileCon"></div>
|
||||
<div class="dataTables_paginate paging_bootstrap pagination plr15" style="position: relative; top: -15px;">
|
||||
<ul id="filePage" class="page"></ul>
|
||||
</div>
|
||||
<div class="file_list_shadow file_shadow_top" style="opacity: 0;"></div>
|
||||
<div class="file_list_content"></div>
|
||||
<div class="file_list_shadow file_shadow_bottom" style="opacity: 0;"></div>
|
||||
<div class="onselectstart"></div>
|
||||
</div>
|
||||
<div class="file_right_menu file_menu_list">
|
||||
<ul class="set_group">
|
||||
<!-- <li data-id="open_file"><i class="file_menu_icon open_file_icon"></i><span>打开文件夹</span></li> -->
|
||||
<li data-id="edit_file"><i class="file_menu_icon edit_file_icon"></i><span>Open</span></li>
|
||||
<li data-id="download_file"><i class="file_menu_icon download_file_icon"></i><span>Download</span></li>
|
||||
<li class="separate"></li>
|
||||
<li data-id="copy_file"><i class="file_menu_icon copy_file_icon"></i><span>Copy</span></li>
|
||||
<li data-id="paste_file"><i class="file_menu_icon paste_file_icon"></i><span>Paste</span></li>
|
||||
<!-- 判断类型是文件夹时,提示是否复制文件至该文件夹 -->
|
||||
<li data-id="shear_file"><i class="file_menu_icon shear_file_icon"></i><span>Cut</span></li>
|
||||
<li class="separate"></li>
|
||||
<li data-id="rename_file"><i class="file_menu_icon rename_file_icon"></i><span>Rename</span></li>
|
||||
<li data-id="power_file"><i class="file_menu_icon power_file_icon"></i><span>Permission</span></li>
|
||||
<li data-id="decompression_file"><i
|
||||
class="file_menu_icon decompression_file_icon"></i><span>Decompress</span></li>
|
||||
<li data-id="compress_file">
|
||||
<i class="file_menu_icon compress_file_icon"></i><span>Compress</span>
|
||||
<div class="file_menu_down">
|
||||
<span class="glyphicon glyphicon-triangle-right" aria-hidden="true"></span>
|
||||
<ul class="set_group">
|
||||
<li><i class="file_menu_icon compress_file_icon"></i><span>tar.gz (Default)</span></li>
|
||||
<li><i class="file_menu_icon compress_file_icon"></i><span>zip (General format)</span></li>
|
||||
<li><i class="file_menu_icon compress_file_icon"></i><span>rar (WinRAR is compatible with Chinese)</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li data-id="del_file"><i class="file_menu_icon del_file_icon"></i><span>Del</span></li>
|
||||
<li class="separate"></li>
|
||||
<li data-id="add_favorites"><i class="file_menu_icon add_favorites_icon"></i><span>Favorites</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="selection_right_menu file_menu_list">
|
||||
<ul class="set_group">
|
||||
<li data-id="copy_file"><i class="file_menu_icon copy_file_icon"></i><span>Copy</span></li>
|
||||
<li data-id="paste_file"><i class="file_menu_icon shear_file_icon"></i><span>Cut</span></li>
|
||||
<li data-id="download_file"><i class="file_menu_icon download_file_icon"></i><span>Download</span></li>
|
||||
<li class="separate"></li>
|
||||
<li data-id="del_file"><i class="file_menu_icon del_file_icon"></i><span>Del</span></li>
|
||||
<li class="separate"></li>
|
||||
<li data-id="paste_file"><i class="file_menu_icon copy_file_icon"></i><span>Copy to</span></li>
|
||||
<li data-id="paste_file"><i class="file_menu_icon shear_file_icon"></i><span>Move to</span></li>
|
||||
<li class="separate"></li>
|
||||
<li data-id="compress_file">
|
||||
<i class="file_menu_icon compress_file_icon"></i><span>Compress</span>
|
||||
<div class="file_menu_down"><span class="glyphicon glyphicon-triangle-right"
|
||||
aria-hidden="true"></span></div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="content_right_menu file_menu_list">
|
||||
<ul class="set_group">
|
||||
<li data-id="refresh_file"><i class="file_menu_icon refresh_file_icon"></i><span>Refresh</span></li>
|
||||
<li class="separate"></li>
|
||||
<li data-id="upload_file"><i class="file_menu_icon upload_file_icon"></i><span>Upload</span></li>
|
||||
<li data-id="newly_file"><i class="file_menu_icon newly_file_icon"></i><span>New file/directory</span></li>
|
||||
<li class="separate"></li>
|
||||
<li data-id="paste_file"><i class="file_menu_icon paste_file_icon"></i><span>Paste</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="filePage pagination page"></div>
|
||||
</div>
|
||||
</div>
|
||||
<ul id="rmenu" class="dropdown-menu" style="display:none">
|
||||
<li onclick="javascript:Batch(1);"><a style="cursor: pointer;">{{data['lan']['L1']}}</a></li>
|
||||
<li onclick="javascript:Batch(2);"><a style="cursor: pointer;">{{data['lan']['L2']}}</a></li>
|
||||
<li onclick="javascript:Batch(5);"><a style="cursor: pointer;">{{data['lan']['L3']}}</a></li>
|
||||
<li onclick="javascript:Batch(3);"><a style="cursor: pointer;">{{data['lan']['L4']}}</a></li>
|
||||
<li onclick="javascript:Batch(4);"><a style="cursor: pointer;">{{data['lan']['L5']}}</a></li>
|
||||
</ul>
|
||||
<link rel="stylesheet" href="./static/ace/styles/icons.css">
|
||||
<script type="text/tmplate" id="aceTmplate">
|
||||
<script type="text/template" id="upload_file_template">
|
||||
<div class="upload_or_download_view">
|
||||
<div class="upload_or_download_content active" data-type="upload">
|
||||
<div class="upload_btn_groud">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary btn-sm upload_file_btn">Upload file</button>
|
||||
<button type="button" class="btn btn-primary btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="caret"></span>
|
||||
<span class="sr-only">Toggle Dropdown</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#" data-type="file">Upload file</a></li>
|
||||
<li><a href="#" data-type="dir">Upload directory</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="file_upload_info" style="display:none;">
|
||||
<span>Total press <i class="uploadProgress"></i>, uploading <i class="uploadNumber"></i>,</span>
|
||||
<span style="display:none">Fail <i class="uploadError"></i></span>
|
||||
<span>Speed <i class="uploadSpeed">getting</i>,</span>
|
||||
<span>Expect time <i class="uploadEstimate">getting</i></span><i></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="upload_file_body active"><span>Please drag the file here</span></div>
|
||||
<div class="upload_btn_group"><button type="button" class="btn btn-danger btn-sm upload_file_clear">Cancel upload</button><button type="button" class="btn btn-success btn-sm upload_file_submit">Start upload</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
<script type="text/template" id="aceTmplate">
|
||||
<div id="ace_conter">
|
||||
<div class="ace_header">
|
||||
<span class="saveFile"><i class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></i>Save</span>
|
||||
<span class="saveFileAll"><i class="glyphicon glyphicon-duplicate" aria-hidden="true"></i>Save All</span>
|
||||
<span class="refreshs"><i class="glyphicon glyphicon-refresh" aria-hidden="true"></i>Refresh</span>
|
||||
<span class="searchs"><i class="glyphicon glyphicon-search" aria-hidden="true"></i>Search</span>
|
||||
<span class="replaces"><i class="glyphicon glyphicon-retweet" aria-hidden="true"></i>Replace</span>
|
||||
<span class="jumpLine"><i class="glyphicon glyphicon-pushpin" aria-hidden="true"></i>JumpLine</span>
|
||||
<span class="fontSize"><i class="glyphicon glyphicon-text-width" aria-hidden="true"></i>Font</span>
|
||||
<span class="themes"><i class="glyphicon glyphicon-magnet" aria-hidden="true"></i>Theme</span>
|
||||
<span class="setUp"><i class="glyphicon glyphicon-cog" aria-hidden="true"></i>Set</span>
|
||||
<span class="helps"><i class="glyphicon glyphicon-question-sign" aria-hidden="true"></i>Help</span>
|
||||
<div class="pull-down" title="Hide toolbar"><i class="glyphicon glyphicon-menu-down" aria-hidden="true"></i></div>
|
||||
<div class="ace_header" style="top: 0">
|
||||
<span class="saveFile"><i class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></i><span>Save</span></span>
|
||||
<span class="saveFileAll"><i class="glyphicon glyphicon-duplicate" aria-hidden="true"></i><span>Save All</span></span>
|
||||
<span class="refreshs"><i class="glyphicon glyphicon-refresh" aria-hidden="true"></i><span>Refresh</span></span>
|
||||
<span class="searchs"><i class="glyphicon glyphicon-search" aria-hidden="true"></i><span>Search</span></span>
|
||||
<span class="replaces"><i class="glyphicon glyphicon-retweet" aria-hidden="true"></i><span>Replace</span></span>
|
||||
<span class="jumpLine"><i class="glyphicon glyphicon-pushpin" aria-hidden="true"></i><span>JumpLine</span></span>
|
||||
<span class="fontSize"><i class="glyphicon glyphicon-text-width" aria-hidden="true"></i><span>Font</span></span>
|
||||
<span class="themes"><i class="glyphicon glyphicon-magnet" aria-hidden="true"></i><span>Theme</span></span>
|
||||
<span class="setUp"><i class="glyphicon glyphicon-cog" aria-hidden="true"></i><span>Set</span></span>
|
||||
<span class="helps"><i class="glyphicon glyphicon-question-sign" aria-hidden="true"></i><span>Help</span></span>
|
||||
<div class="pull-down" title="Hide toolbar" style="top: 0"><i class="glyphicon glyphicon-menu-down" aria-hidden="true"></i></div>
|
||||
</div>
|
||||
<div class="ace_overall" style="top: 35px;">
|
||||
<!-- 编辑器目录 -->
|
||||
<div class="ace_catalogue">
|
||||
<div class="ace_catalogue" style="left:0px">
|
||||
<div class="ace_catalogue_title">Directory<div class="dir-menu-right"><span class="glyphicon glyphicon-minus" aria-hidden="true"></span></div></div>
|
||||
<div class="ace_dir_tools">
|
||||
<div class="upper_level" title="Back">
|
||||
<div class="ace_dir_tools">
|
||||
<div class="upper_level" title="Return to parent directory">
|
||||
<i class="glyphicon glyphicon-share-alt" aria-hidden="true"></i>
|
||||
<span>Back</span>
|
||||
</div>
|
||||
<div class="search_file" title="Search">
|
||||
<div class="search_file" title="搜索内容">
|
||||
<i class="glyphicon glyphicon-search" aria-hidden="true"></i>
|
||||
<span>Search</span>
|
||||
</div>
|
||||
<div class="new_folder" title="New Folder/File">
|
||||
<div class="new_folder" title="新建文件/目录">
|
||||
<i class="glyphicon glyphicon-plus" aria-hidden="true"></i>
|
||||
<span>New</span>
|
||||
<ul class="folder_down_up">
|
||||
<li data-type="2"><i class="folder-icon"></i>New Folder</li>
|
||||
<li data-type="3"><i class="text-icon"></i>New File</li>
|
||||
<li data-type="2"><i class="folder-icon"></i>新建文件夹</li>
|
||||
<li data-type="3"><i class="text-icon"></i>新建文件</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="refresh_dir" title="ReFresh">
|
||||
<div class="refresh_dir" title="刷新当前目录">
|
||||
<span class="glyphicon glyphicon-refresh" aria-hidden="true"></span>
|
||||
<span>ReFresh</span>
|
||||
<span>Refresh</span>
|
||||
</div>
|
||||
<span class="ace_editor_main_storey"></span>
|
||||
</div>
|
||||
|
||||
<div class="ace_catalogue_list">
|
||||
<ul class="cd-accordion-menu"></ul>
|
||||
<ul class="ace_catalogue_menu">
|
||||
@@ -113,15 +317,13 @@
|
||||
</div>
|
||||
<div class="ace_catalogue_drag_icon">
|
||||
<div class="drag_icon_conter"></div>
|
||||
<span class="fold_icon_conter" title="Hide Directory"></span>
|
||||
<span class="fold_icon_conter" title="Hide file directory"></span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- 编辑内容 -->
|
||||
<div class="ace_editor_main">
|
||||
<div class="ace_conter_menu">
|
||||
<div class="ace_editor_add" style="display:none;"><i class="fa fa-plus-square" aria-hidden="true"></i></div>
|
||||
</div>
|
||||
<ul class="ace_conter_menu"></ul>
|
||||
<div class="ace_conter_tips"><div class="tips"></div></div>
|
||||
<div class="ace_editor_main_storey"></div>
|
||||
<div class="ace_conter_editor"></div>
|
||||
@@ -211,44 +413,13 @@
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block scripts %}
|
||||
<!--<link rel="stylesheet" type="text/css" href="https://at.alicdn.com/t/font_1628000_cso2y4bz1wk.css">-->
|
||||
<script type="text/javascript" src="/static/js/jquery-ui.min.js"></script>
|
||||
<script type="text/javascript" src="/static/js/jquery.contextify.min.js"></script>
|
||||
<script type="text/javascript" src="/static/js/files.js?date20191219={{g.version}}"></script>
|
||||
<!-- <script type="text/javascript" src="/static/js/bt_upload.js?version={{g['version']}}"></script> -->
|
||||
<script type="text/javascript" src="/static/ace/ace.js?date={{g.version}}"></script>
|
||||
<script type="text/javascript" src="/static/ace/ext-language_tools.js?date={{g.version}}"></script>
|
||||
<script type="text/javascript" src="/static/js/clipboard.min.js"></script>
|
||||
<script type="text/javascript" src="/static/js/jquery.dragsort-0.5.2.min.js"></script>
|
||||
<script type="text/javascript" src="/static/js/polyfill.js"></script>
|
||||
<script type="text/javascript">
|
||||
setTimeout(function(){
|
||||
GetDisk();
|
||||
},500);
|
||||
var xPath = getCookie('Path');
|
||||
setTimeout(function(){
|
||||
GetFiles((xPath!=undefined?xPath:'/www/wwwroot'));
|
||||
},800);
|
||||
|
||||
PathPlaceBtn((xPath!=undefined?xPath:'/www/wwwroot'));
|
||||
setCookie('uploadSize',1024 * 1024 * 1024);
|
||||
if(getCookie('rank') == undefined || getCookie('rank') == null){
|
||||
setCookie('rank','a');
|
||||
}
|
||||
$("#set_icon").click(function(){
|
||||
setCookie('rank','b');
|
||||
$(this).addClass("active");
|
||||
$("#set_list").removeClass("active");
|
||||
GetFiles(getCookie('Path'));
|
||||
});
|
||||
$("#set_list").click(function(){
|
||||
setCookie('rank','a');
|
||||
$(this).addClass("active");
|
||||
$("#set_icon").removeClass("active");
|
||||
GetFiles(getCookie('Path'));
|
||||
});
|
||||
$(".refreshBtn").click(function(){
|
||||
GetFiles(getCookie('Path'));
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
<script type="text/javascript" src="{{g.cdn_url}}/js/jquery.dragsort-0.5.2.min.js" defer></script>
|
||||
<script type="text/javascript" src="{{g.cdn_url}}/js/jquery.qrcode.min.js" defer></script>
|
||||
<script type="text/javascript" src="{{g.cdn_url}}/js/public.js?version={{g['version']}}&repair={{data['js_random']}}"></script>
|
||||
<script type="text/javascript" src="{{g.cdn_url}}/js/public_backup.js?version={{g['version']}}&repair={{data['js_random']}}"></script>
|
||||
<script type="text/javascript" src="{{g.cdn_url}}/js/clipboard.min.js" defer></script>
|
||||
<script type="text/javascript" src="{{g.cdn_url}}/js/polyfill.js"></script>
|
||||
<script type="text/javascript" src="{{g.cdn_url}}/ace/ace.js" defer></script>
|
||||
<script type="text/javascript" src="{{g.cdn_url}}/ace/ext-language_tools.js" defer></script>
|
||||
<script type="text/javascript" src="{{g.cdn_url}}/js/files.min.js?version={{g['version']}}&repair={{data['js_random']}}"></script>
|
||||
{% endblock %}
|
||||
@@ -128,10 +128,11 @@
|
||||
</div>
|
||||
<div class="divtable pd15">
|
||||
<div class="firewall-port-box">
|
||||
<select id="firewalldType" class="bt-input-text c5 mr5" name="type" style="width:80px;">
|
||||
<select id="firewalldType" class="bt-input-text c5 mr5" name="type">
|
||||
<option value="port">{{data['lan']['F1']}}</option>
|
||||
<option value="address">{{data['lan']['F2']}}</option>
|
||||
</select><input type="text" class="bt-input-text mr5" style="width: 117px;" id="AcceptPort" placeholder="{{data['lan']['F3']}}"><input type="text" class="bt-input-text mr5" id="Ps" placeholder="{{data['lan']['F4']}}"><button id="toAccept" onclick="firewall.add_accept_port()" class="btn btn-default btn-sm va0" type="button">{{data['lan']['F5']}}</button>
|
||||
</select><input type="text" class="bt-input-text mr5" style="width: 117px;" id="AcceptPort" placeholder="{{data['lan']['F3']}}"><input type="text" class="bt-input-text mr5" id="Ps" placeholder="{{data['lan']['F4']}}"><button id="toAccept" onclick="firewall.add_accept_port()" class="btn btn-default btn-sm va0" type="button">{{data['lan']['F5']}}</button>
|
||||
<button class="btn btn-default btn-sm sys_firewall" type="button">SYS Firewall</button>
|
||||
<span id="f-ps" class="c9" style="margin-left: 10px;">{{data['lan']['F6']}}</span>
|
||||
</div>
|
||||
<div class="tablescroll">
|
||||
@@ -208,7 +209,19 @@
|
||||
firewall.flush_init();
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
$('.sys_firewall').on('click', function () {
|
||||
$.post('/plugin?action=getConfigHtml', {name: 'firewall'}, function (rdata) {
|
||||
if(rdata.status == false) {
|
||||
layer.confirm('The SYS Firewall plugin is not installed, <br>please leave to "<a href="/soft" class="btlink">APP Store > Tools</a>"<br> install SYS Firewall plugin first.',
|
||||
{title: 'No SYS Firewall', icon: 7, closeBtn: 2,}, function () {
|
||||
window.location.href = '/soft';
|
||||
});
|
||||
} else {
|
||||
bt.soft.set_lib_config('firewall','SYS Firewall');
|
||||
}
|
||||
});
|
||||
});
|
||||
$("#firewalldType").change(function(){
|
||||
var type = $(this).val();
|
||||
var w = '120px';
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
{% extends "layout.html" %}
|
||||
|
||||
{% block content %}
|
||||
<style>
|
||||
#ftpData .webPath,#ftpData .webNote,#ftpData .ftpStatus{
|
||||
white-space: nowrap;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
min-width: auto;
|
||||
}
|
||||
</style>
|
||||
<div class="main-content pb55">
|
||||
<div class="container-fluid">
|
||||
<div class="pos-box bgw mtb15">
|
||||
@@ -26,7 +35,7 @@
|
||||
</span>
|
||||
<div class="divtable mtb10">
|
||||
<div class="tablescroll">
|
||||
<table id="ftpData" class="table table-hover" style="min-width: 900px;border: 0 none;">
|
||||
<table id="ftpData" class="table table-hover" style="min-width: 700px;border: 0 none;">
|
||||
</table>
|
||||
</div>
|
||||
<div class="dataTables_paginate paging_bootstrap page">
|
||||
@@ -58,7 +67,7 @@
|
||||
return _html;
|
||||
}},
|
||||
{ field: 'status', title: lan.ftp.status,templet:function(item){
|
||||
var _status = '<a href="javascript:;" title="'+lan.ftp.ftp_user+'"';
|
||||
var _status = '<a class="ftpStatus" href="javascript:;" title="'+lan.ftp.ftp_user+'"';
|
||||
if(item.status=='1'){
|
||||
_status+=' onclick="ftp.stop_user('+item.id+',\''+item.name+'\') " >';
|
||||
_status+='<span style="color:#5CB85C">'+lan.ftp.start+' </span><span style="color:#5CB85C" class="glyphicon glyphicon-play"></span>';
|
||||
@@ -73,10 +82,10 @@
|
||||
}},
|
||||
{ field: 'path', title: lan.ftp.add_path,templet:function(item){
|
||||
var _path = bt.format_path(item.path);
|
||||
return '<a class="btlink" title="'+lan.ftp.open_path+'" href="javascript:openPath(\''+_path+'\');">'+_path+'</a>';
|
||||
return '<a class="btlink webPath" title="'+lan.ftp.open_path+'" href="javascript:openPath(\''+_path+'\');">'+_path+'</a>';
|
||||
}},
|
||||
{ field: 'ps', title: lan.ftp.add_ps,templet : function(item){
|
||||
return "<span class='c9 input-edit' onclick=\"bt.pub.set_data_by_key('ftps','ps',this)\">"+item.ps+ "</span>";
|
||||
return "<span class='c9 input-edit webNote' onclick=\"bt.pub.set_data_by_key('ftps','ps',this)\">"+item.ps+ "</span>";
|
||||
}},
|
||||
{ field: 'opt',width:130, title: lan.ftp.operate,align:'right',templet:function(item){
|
||||
var option = "<a href=\"javascript:;\" class=\"btlink\" onclick=\"ftp.set_password("+item.id+",'"+item.name+"','"+item.password+"')\" title="+lan.ftp.change_pass+">"+lan.ftp.edit_pass+"</a> | ";
|
||||
@@ -85,8 +94,9 @@
|
||||
}},
|
||||
],
|
||||
data:rdata.data
|
||||
})
|
||||
})
|
||||
});
|
||||
ftp.forSize();
|
||||
});
|
||||
},
|
||||
batch_ftp:function(type,arr,result){
|
||||
if(arr == undefined){
|
||||
@@ -160,15 +170,26 @@
|
||||
bt.ftp.set_status(id,username,1,function(rdata){
|
||||
if(rdata.status) ftp.get_list();
|
||||
})
|
||||
},
|
||||
//浏览器窗口大小变化时调整内容宽度
|
||||
forSize:function(){
|
||||
var ticket_with = $('#ftpData').parent().width(),
|
||||
td_width = ticket_with*0.6-160-$('#ftpData th:eq(3)').width(),
|
||||
path_width = td_width/2 > $('#ftpData th:eq(4)').width() ? $('#ftpData th:eq(4)').width() : td_width/2;
|
||||
$('#ftpData .webPath').css('max-width',path_width);
|
||||
$('#ftpData .webNote').css('max-width',td_width-$('#ftpData .webPath').width());
|
||||
}
|
||||
|
||||
}
|
||||
bt.set_cookie('sites_path',"{{session['config']['sites_path']}}");
|
||||
$(window).resize(function() {
|
||||
ftp.forSize();
|
||||
});
|
||||
{% if not data['isSetup'] %}
|
||||
layer.msg('{{data["lan"]["JS1"]}}<a href="/soft" style="color:#20a53a; float: right;">{{data["lan"]["JS2"]}}</a>',{icon:7,time:0,shade: [0.3, '#000']});
|
||||
$(".layui-layer-shade").css("margin-left", "180px");
|
||||
$(".layui-layer-shade").css("margin-left", "180px");
|
||||
{% else %}
|
||||
ftp.get_list();
|
||||
ftp.get_list();
|
||||
|
||||
{% endif %}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
<div class="main-content">
|
||||
<div class="index-pos-box bgw">
|
||||
<div class="position f12 c6 pull-left" style="background:none;padding-left:15px">
|
||||
<!--<span class="bind-user c4">-->
|
||||
<!--<a href="javascript:bt.pub.bind_btname();" class="btlink">{{data['lan']['BT_ACCOUNT']}}</a>-->
|
||||
<!--</span>-->
|
||||
{% if data['pd'].find("{{data['lan']['BT_ACCOUNT']}}") != -1 %}
|
||||
<span class="bind-user c4">
|
||||
<a href="javascript:bt.pub.bind_btname();" class="btlink">{{data['lan']['ACCOUNT']}}</a>
|
||||
</span>
|
||||
{% if data['pd'].find("{{data['lan']['ACCOUNT']}}") != -1 %}
|
||||
<span class="bt-dashi">
|
||||
<a class="btlink" href="https://www.bt.cn/invite" target="_blank" style="margin-left:5px">{{data['lan']['INVITATION_REWARD']}}</a>
|
||||
</span>
|
||||
@@ -117,7 +117,7 @@
|
||||
<div class="col-xs-12 col-sm-12 col-md-6 pull-left pd0">
|
||||
<div class="pl7">
|
||||
<div class="bgw" style="height:491px">
|
||||
<div class="title c6 f16 plr15">{{data['lan']['FLOW']}}</div>
|
||||
<div class="title c6 f16 plr15">{{data['lan']['FLOW']}}<span class="pull-right"><select class="bt-input-text" name="network-io" style="font-size: 12px;"></select></span></div>
|
||||
<div class="bw-info">
|
||||
<div class="col-sm-6 col-md-3"><p class="c9"><span class="ico-up"></span>{{data['lan']['UPLOAD']}}</p><a id="upSpeed">{{data['lan']['S2']}}</a></div>
|
||||
<div class="col-sm-6 col-md-3"><p class="c9"><span class="ico-down"></span>{{data['lan']['DOWNLOAD']}}</p><a id="downSpeed">{{data['lan']['S2']}}</a></div>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<title>{{g.title}}</title>
|
||||
<link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon" />
|
||||
<link href="{{g.cdn_url}}/bootstrap-3.3.5/css/bootstrap.min.css" rel="stylesheet" />
|
||||
<link href="{{g.cdn_url}}/css/site.css?20191127={{g['version']}}" rel="stylesheet" />
|
||||
<link href="{{g.cdn_url}}/css/site.css?version={{g['version']}}&repair={{data['js_random']}}" rel="stylesheet" />
|
||||
<link href="{{g.cdn_url}}/codemirror/lib/codemirror.css?20191127={{g['version']}}" rel="stylesheet" />
|
||||
<!--[if lte IE 9]>
|
||||
<script src="/static/js/requestAnimationFrame.js"></script>
|
||||
@@ -68,7 +68,7 @@
|
||||
<body>
|
||||
<div class="bt-warp bge6">
|
||||
<div class="top-tips">The current version of IE browser is too low, some functions cannot be displayed, please change to other browsers!</div>
|
||||
<a style="display:none;" id="panel_debug" data="{{g['debug']}}"></a>
|
||||
<a style="display:none;" id="panel_debug" data="{{g['debug']}}" data-pyversion="{{g['pyversion']}}"></a>
|
||||
<a style="display:none;" id="request_token_head" token="{{session['request_token_head']}}"></a>
|
||||
<div id="container" class="container-fluid">
|
||||
<div class="sidebar-scroll">
|
||||
@@ -76,11 +76,13 @@
|
||||
<div id="task" class="task cw" onclick="messagebox()">0</div>
|
||||
<h3 class="mypcip"><span class="f14 cw">{{session['address']}}</span></h3>
|
||||
<ul class="menu">
|
||||
{% for menu in session['menus'] %} {% if menu['href'] == g.uri %}
|
||||
<li id="{{menu['id']}}" class="current"> <a class="{{menu['class']}}" href="{{menu['href']}}">{{menu['title']}}</a></li>
|
||||
{% else %}
|
||||
<li id="{{menu['id']}}"> <a class="{{menu['class']}}" href="{{menu['href']}}">{{menu['title']}}</a></li>
|
||||
{% endif %} {% endfor %}
|
||||
{% for menu in g['menus'] %}
|
||||
{% if menu['href'] == g.uri %}
|
||||
<li id="{{menu['id']}}" class="current"> <a class="{{menu['class']}}" href="{{menu['href']}}">{{menu['title']}}</a></li>
|
||||
{% else %}
|
||||
<li id="{{menu['id']}}"> <a class="{{menu['class']}}" href="{{menu['href']}}">{{menu['title']}}</a></li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<div id="newbtpc"></div>
|
||||
<div class="btpc-plus" onclick="bindBTPanel(0,'b')">+</div>
|
||||
@@ -94,14 +96,19 @@
|
||||
<a style="margin-left:20px;color:#20a53a;" href="https://doc.aapanel.com/web/#/3?page_id=117" target="_blank">User manual</a>
|
||||
</div>
|
||||
</div>
|
||||
<script src="{{g.cdn_url}}/js/aes.js?version={{g['version']}}"></script>
|
||||
<script src="{{g.cdn_url}}/js/jquery-1.10.2.min.js"></script>
|
||||
<script src="{{g.cdn_url}}/js/bootstrap.min.js"></script>
|
||||
<script src="{{g.cdn_url}}/language/{{session['lan']}}/lan.js?date={{g['version']}}"></script>
|
||||
<script src="{{g.cdn_url}}/layer/layer.js?date={{g['version']}}"></script>
|
||||
<script src="{{g.cdn_url}}/js/public.js?version={{g['version']}}"></script>
|
||||
<script src="{{g.cdn_url}}/js/public_backup.js?version={{g['version']}}"></script>
|
||||
<script src="{{g.cdn_url}}/codemirror/lib/codemirror.js?version={{g['version']}}"></script>
|
||||
<script src="{{g.cdn_url}}/layer/layer.js?version={{g['version']}}"></script>
|
||||
<script src="{{g.cdn_url}}/language/{{session['lan']}}/lan.js?version={{g['version']}}&repair={{data['js_random']}}"></script>
|
||||
<script src="{{g.cdn_url}}/js/clipboard.min.js" defer></script>
|
||||
<script src="{{g.cdn_url}}/laydate/laydate.js" defer></script>
|
||||
<script src="{{g.cdn_url}}/js/jquery.qrcode.min.js" defer></script>
|
||||
<!-- 以下文件未来将被剔除 -->
|
||||
<script src="{{g.cdn_url}}/js/bootstrap.min.js"></script>
|
||||
<script src="{{g.cdn_url}}/js/public.js?version={{g['version']}}&repair={{data['js_random']}}"></script>
|
||||
<script src="{{g.cdn_url}}/js/public_backup.js?version={{g['version']}}&repair={{data['js_random']}}"></script>
|
||||
<script src="{{g.cdn_url}}/codemirror/lib/codemirror.js" defer></script>
|
||||
<!-- End -->
|
||||
<script type="text/javascript" src="{{g.cdn_url}}/js/tools.min.js?version={{g['version']}}&repair={{data['js_random']}}"></script>
|
||||
{% block scripts %}{% endblock %}
|
||||
<script type="text/javascript">
|
||||
if (navigator.appName == "Microsoft Internet Explorer" && parseInt(navigator.appVersion.split(";")[1].replace(/[ ]/g, "").replace("MSIE", "")) < 9) {
|
||||
|
||||
@@ -1,13 +1,23 @@
|
||||
{% extends "layout.html" %}
|
||||
|
||||
{% block content %}
|
||||
<link rel="stylesheet" type="text/css" href="https://at.alicdn.com/t/font_1508259_3g6fa6pdt7k.css" />
|
||||
<style>
|
||||
#webBody .webPath,#webBody .ssl_tips{
|
||||
white-space: nowrap;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
min-width: auto;
|
||||
}
|
||||
</style>
|
||||
<div class="main-content pb55">
|
||||
<div class="container-fluid">
|
||||
<div class="pos-box bgw mtb15">
|
||||
<div class="position f14 c9 pull-left">
|
||||
<a class="plr10 c4" href="/">{{data['lan']['H1']}}</a>/<span class="plr10 c4">{{data['lan']['H2']}}</span>
|
||||
</div>
|
||||
<div class="search pull-right">
|
||||
<div class="search pull-right" style="display: none;">
|
||||
<form target="hid" onsubmit='site.get_list(1,$("#SearchValue").val())'>
|
||||
<input type="text" id="SearchValue" class="ser-text pull-left" placeholder="{{data['lan']['SEARCH']}}" />
|
||||
<button type="button" class="ser-sub pull-left" onclick='site.get_list(1,$("#SearchValue").val())'></button>
|
||||
@@ -15,30 +25,11 @@
|
||||
<iframe name='hid' id="hid" style="display:none"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bgw mtb15 pd15">
|
||||
<div class="site_table_view bgw mtb15 pd15">
|
||||
<div class="info-title-tips">
|
||||
<p><span class="glyphicon glyphicon-alert" style="color: #f39c12; margin-right: 10px;"></span> {{data['lan']['PS']}}<a class="btlink" href="/crontab">[Cron]</a></p>
|
||||
</div>
|
||||
<button onclick="site.add_site()" class="btn btn-success btn-sm btn-title" type="button">{{data['lan']['BTN1']}}</button>
|
||||
<button onclick="site.set_default_page()" class="btn btn-default btn-sm btn-title" type="button">{{data['lan']['BTN2']}}</button>
|
||||
<button onclick="site.set_default_site()" class="btn btn-default btn-sm btn-title" type="button">{{data['lan']['BTN3']}}</button>
|
||||
<button onclick="site.set_class_type()" class="btn btn-default btn-sm btn-title" type="button">{{data['lan']['BTN5']}}</button>
|
||||
<button onclick="site.get_cli_version()" class="btn btn-default btn-sm btn-title" type="button">{{data['lan']['PHP_CLI_VER']}}</button>
|
||||
<span id="allDelete">
|
||||
<button batch="true" style="float: right;display: none;margin-left:10px;" class="btn btn-default btn-sm" onclick="site.batch_site('del');">{{data['lan']['BTN4']}}</button>
|
||||
</span>
|
||||
<div class="move_class">
|
||||
<button batch="false" style="float: right;margin-left:10px;display: none;" class="btn btn-default btn-sm" onclick="site.batch_site('site_type')">{{data['lan']['MOVE_TO']}}</button>
|
||||
<!-- <select class="bt-input-text mr5" name="defaultSite" style="width:100px"><option value="off">默认分类</option></select> -->
|
||||
</div>
|
||||
<div class="divtable mtb10">
|
||||
<div class="tablescroll">
|
||||
<table id="webBody" class="table table-hover" style="min-width: 900px;border: 0 none;"></table>
|
||||
</div>
|
||||
<div class="dataTables_paginate paging_bootstrap page">
|
||||
|
||||
</div>
|
||||
<p><span class="glyphicon glyphicon-alert" style="color: #f39c12; margin-right: 10px;"></span> {{data['lan']['PS']}}After the site is successfully established, please<a class="btlink" href="/crontab">[Cron]</a>Add scheduled backup tasks to the page!</p>
|
||||
</div>
|
||||
<div id="bt_site_table"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -47,20 +38,21 @@
|
||||
|
||||
{% block scripts %}
|
||||
<script type="text/javascript" src="/static/laydate/laydate.js?date=20180301"></script>
|
||||
<script type="text/javascript" src="/static/js/bootstrap-select.min.js"></script>
|
||||
<script type="text/javascript" src="/static/js/site.js?version_20200206={{g['version']}}"></script>
|
||||
<script type="text/javascript" src="/static/ace/ace.js?date={{g.version}}"></script>
|
||||
<script type="text/javascript" src="{{g.cdn_url}}/js/site.js?version={{g['version']}}&repair={{data['js_random']}}"></script>
|
||||
<script type="text/javascript" src="{{g.cdn_url}}/ace/ace.js?version={{g['version']}}" defer></script>
|
||||
<!-- 以下文件未来将被剔除 -->
|
||||
<script type="text/javascript" src="{{g.cdn_url}}/js/bootstrap-select.min.js" defer></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
bt.set_cookie('sites_path', "{{session['config']['sites_path']}}");
|
||||
bt.set_cookie('serverType', "{{session['webserver']}}");
|
||||
|
||||
|
||||
{% if not data['isSetup'] %}
|
||||
layer.msg('test', { time: 0, icon: 2 });
|
||||
layer.msg(lan.site.install_web_server_first+'<a href="/soft" style="color:#20a53a; float: right;">'+lan.site.to_install+'</a>', { icon: 7, shade: [0.3, '#000'], time: 0 });
|
||||
$(".layui-layer-shade").css("margin-left", "180px");
|
||||
layer.msg(lan.site.install_web_server_first+'<a href="/soft" style="color:#20a53a; float: right;">'+lan.site.to_install+'</a>', { icon: 7, shade: [0.3, '#000'], time: 0 });
|
||||
$(".layui-layer-shade").css("margin-left", "180px");
|
||||
{% else %}
|
||||
site.get_list();
|
||||
site.plugin_firewall();
|
||||
//site.get_list();
|
||||
site.plugin_firewall();
|
||||
{% endif %}
|
||||
function reverse(array){
|
||||
var reverse_array = [];
|
||||
|
||||
@@ -30,10 +30,10 @@
|
||||
</div>
|
||||
<div class="divtable pd15 relative">
|
||||
<button class="btn btn-default btn-sm" onclick="soft.flush_cache()" title="{{data['lan']['UPDATE_FROM_CLOUD']}}" style="position:absolute;top:-49px;right:15px">{{data['lan']['UPDATE_APP_LIST']}}</button>
|
||||
<div id="updata_pro_info">
|
||||
<div id="updata_pro_info" style="display:none">
|
||||
<div class="alert alert-success" style="margin-bottom:15px"><strong>{{data['lan']['PS']}}</strong><button class="btn btn-success btn-xs va0 updata_pro" onclick="bt.soft.updata_pro()" title="{{data['lan']['UPDATE_PRO_NOW']}}" style="margin-left:8px">"{{data['lan']['UPDATE_NOW']}}"</button></div>
|
||||
</div>
|
||||
<table id="softList" class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0"></table>
|
||||
<table id="softList" class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0" style="margin-top:10px"></table>
|
||||
<div id='softPage' class="dataTables_paginate paging_bootstrap page">
|
||||
|
||||
</div>
|
||||
@@ -51,6 +51,7 @@
|
||||
<script type="text/javascript" src="/static/laydate/laydate.js?date=20180301"></script>
|
||||
<script type="text/javascript" src="/static/ace/ace.js?date={{g.version}}"></script>
|
||||
<script type="text/javascript" src="/static/js/soft.js?version_20200109={{g['version']}}"></script>
|
||||
<script src="https://js.stripe.com/v3/"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
bt.set_cookie('sites_path', "{{session['config']['sites_path']}}");
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
<span class="glyphicon glyphicon-plus" aria-hidden="true" ></span>
|
||||
</span>
|
||||
<span class="tab_tootls">
|
||||
<span class="glyphicon glyphicon-triangle-top" aria-hidden="true"></span>
|
||||
<span class="glyphicon glyphicon-triangle-bottom" aria-hidden="true"></span>
|
||||
<span class="glyphicon glyphicon-resize-full" aria-hidden="true" title="Full Screen"></span><span>Full Screen</span>
|
||||
<!-- <span class="glyphicon glyphicon-triangle-top" aria-hidden="true"></span>
|
||||
<span class="glyphicon glyphicon-triangle-bottom" aria-hidden="true"></span> -->
|
||||
</span>
|
||||
</div>
|
||||
<div class="term_content_tab"></div>
|
||||
@@ -39,7 +40,7 @@
|
||||
<span class="tname">Server IP</span>
|
||||
<div class="info-r">
|
||||
<input type="text" name="host" class="bt-input-text mr5" style="width:240px" value="<% this.form.host %>" placeholder="Enter server IP" val="" autocomplete="off" />
|
||||
<input type="text" name="port" class="bt-input-text mr5" style="width:60px" placeholder="端口" value="<% this.form.port %>" autocomplete="off"/>
|
||||
<input type="text" name="port" class="bt-input-text mr5" style="width:60px" placeholder="Port" value="<% this.form.port %>" autocomplete="off"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
|
||||
@@ -23,7 +23,8 @@ import time
|
||||
import os
|
||||
import sys
|
||||
os.chdir('/www/server/panel')
|
||||
sys.path.append('class/')
|
||||
if not 'class/' in sys.path:
|
||||
sys.path.insert(0,'class/')
|
||||
import http_requests as requests
|
||||
requests.DEFAULT_TYPE = 'curl'
|
||||
import public
|
||||
@@ -87,6 +88,10 @@ class acme_v2:
|
||||
if "type" in result:
|
||||
if result['type'] == 'urn:acme:error:serverInternal':
|
||||
raise Exception(public.getMsg('ACME_MSG_ERR'))
|
||||
if not os.path.exists('/www/server/panel/data/http_type.pl'):
|
||||
public.writeFile('/www/server/panel/data/http_type.pl','python')
|
||||
self.get_apis()
|
||||
return self._apis
|
||||
raise Exception(res.content)
|
||||
s_body = res.json()
|
||||
self._apis = {}
|
||||
@@ -215,10 +220,37 @@ class acme_v2:
|
||||
|
||||
# 取根域名和记录值
|
||||
def extract_zone(self, domain_name):
|
||||
top_domain_list = ['.ac.cn', '.ah.cn', '.bj.cn', '.com.cn', '.cq.cn', '.fj.cn', '.gd.cn',
|
||||
'.gov.cn', '.gs.cn', '.gx.cn', '.gz.cn', '.ha.cn', '.hb.cn', '.he.cn',
|
||||
'.hi.cn', '.hk.cn', '.hl.cn', '.hn.cn', '.jl.cn', '.js.cn', '.jx.cn',
|
||||
'.ln.cn', '.mo.cn', '.net.cn', '.nm.cn', '.nx.cn', '.org.cn','my.id']
|
||||
top_domain_list = ['.ac.cn', '.ah.cn', '.bj.cn', '.com.cn', '.cq.cn', '.fj.cn', '.gd.cn','.gov.cn', '.gs.cn',
|
||||
'.gx.cn', '.gz.cn', '.ha.cn', '.hb.cn', '.he.cn','.hi.cn', '.hk.cn', '.hl.cn', '.hn.cn',
|
||||
'.jl.cn', '.js.cn', '.jx.cn','.ln.cn', '.mo.cn', '.net.cn', '.nm.cn', '.nx.cn', '.org.cn',
|
||||
'.my.id','.com.ac','.com.ad','.com.ae','.com.af','.com.ag','.com.ai','.com.al','.com.am',
|
||||
'.com.an','.com.ao','.com.aq','.com.ar','.com.as','.com.as','.com.at','.com.au','.com.aw',
|
||||
'.com.az','.com.ba','.com.bb','.com.bd','.com.be','.com.bf','.com.bg','.com.bh','.com.bi',
|
||||
'.com.bj','.com.bm','.com.bn','.com.bo','.com.br','.com.bs','.com.bt','.com.bv','.com.bw',
|
||||
'.com.by','.com.bz','.com.ca','.com.ca','.com.cc','.com.cd','.com.cf','.com.cg','.com.ch',
|
||||
'.com.ci','.com.ck','.com.cl','.com.cm','.com.cn','.com.co','.com.cq','.com.cr','.com.cu',
|
||||
'.com.cv','.com.cx','.com.cy','.com.cz','.com.de','.com.dj','.com.dk','.com.dm','.com.do',
|
||||
'.com.dz','.com.ec','.com.ee','.com.eg','.com.eh','.com.es','.com.et','.com.eu','.com.ev',
|
||||
'.com.fi','.com.fj','.com.fk','.com.fm','.com.fo','.com.fr','.com.ga','.com.gb','.com.gd',
|
||||
'.com.ge','.com.gf','.com.gh','.com.gi','.com.gl','.com.gm','.com.gn','.com.gp','.com.gr',
|
||||
'.com.gt','.com.gu','.com.gw','.com.gy','.com.hm','.com.hn','.com.hr','.com.ht','.com.hu',
|
||||
'.com.id','.com.id','.com.ie','.com.il','.com.il','.com.in','.com.io','.com.iq','.com.ir',
|
||||
'.com.is','.com.it','.com.jm','.com.jo','.com.jp','.com.ke','.com.kg','.com.kh','.com.ki',
|
||||
'.com.km','.com.kn','.com.kp','.com.kr','.com.kw','.com.ky','.com.kz','.com.la','.com.lb',
|
||||
'.com.lc','.com.li','.com.lk','.com.lr','.com.ls','.com.lt','.com.lu','.com.lv','.com.ly',
|
||||
'.com.ma','.com.mc','.com.md','.com.me','.com.mg','.com.mh','.com.ml','.com.mm','.com.mn',
|
||||
'.com.mo','.com.mp','.com.mq','.com.mr','.com.ms','.com.mt','.com.mv','.com.mw','.com.mx',
|
||||
'.com.my','.com.mz','.com.na','.com.nc','.com.ne','.com.nf','.com.ng','.com.ni','.com.nl',
|
||||
'.com.no','.com.np','.com.nr','.com.nr','.com.nt','.com.nu','.com.nz','.com.om','.com.pa',
|
||||
'.com.pe','.com.pf','.com.pg','.com.ph','.com.pk','.com.pl','.com.pm','.com.pn','.com.pr',
|
||||
'.com.pt','.com.pw','.com.py','.com.qa','.com.re','.com.ro','.com.rs','.com.ru','.com.rw',
|
||||
'.com.sa','.com.sb','.com.sc','.com.sd','.com.se','.com.sg','.com.sh','.com.si','.com.sj',
|
||||
'.com.sk','.com.sl','.com.sm','.com.sn','.com.so','.com.sr','.com.st','.com.su','.com.sy',
|
||||
'.com.sz','.com.tc','.com.td','.com.tf','.com.tg','.com.th','.com.tj','.com.tk','.com.tl',
|
||||
'.com.tm','.com.tn','.com.to','.com.tp','.com.tr','.com.tt','.com.tv','.com.tw','.com.tz',
|
||||
'.com.ua','.com.ug','.com.uk','.com.uk','.com.us','.com.uy','.com.uz','.com.va','.com.vc',
|
||||
'.com.ve','.com.vg','.com.vn','.com.vu','.com.wf','.com.ws','.com.ye','.com.za','.com.zm',
|
||||
'.com.zw']
|
||||
old_domain_name = domain_name
|
||||
top_domain = "."+".".join(domain_name.rsplit('.')[-2:])
|
||||
new_top_domain = "." + top_domain.replace(".", "")
|
||||
@@ -506,7 +538,7 @@ class acme_v2:
|
||||
number_of_checks = 0
|
||||
while True:
|
||||
if desired_status == ['valid', 'invalid']:
|
||||
write_log(public.getMsg('ACME_QUERY_V_RESULT',(number_of_checks + 1,)))
|
||||
write_log(public.getMsg('ACME_QUERY_V_RESULT',(str(number_of_checks + 1),)))
|
||||
time.sleep(self._wait_time)
|
||||
check_authorization_status_response = self.acme_request(url, "")
|
||||
a_auth = check_authorization_status_response.json()
|
||||
@@ -514,7 +546,7 @@ class acme_v2:
|
||||
number_of_checks += 1
|
||||
if authorization_status in desired_status:
|
||||
if authorization_status == "invalid":
|
||||
write_log("|-verification failed!")
|
||||
write_log("|-"+public.getMsg('VERIFICATION_FAILED'))
|
||||
try:
|
||||
if 'error' in a_auth['challenges'][0]:
|
||||
ret_title = a_auth['challenges'][0]['error']['detail']
|
||||
@@ -538,12 +570,12 @@ class acme_v2:
|
||||
if number_of_checks == self._max_check_num:
|
||||
raise StopIteration(
|
||||
public.getMsg('ACME_V_TIMES',(
|
||||
number_of_checks,
|
||||
self._max_check_num,
|
||||
self._wait_time
|
||||
str(number_of_checks),
|
||||
str(self._max_check_num),
|
||||
str(self._wait_time)
|
||||
)))
|
||||
if desired_status == ['valid', 'invalid']:
|
||||
write_log('ACME_V_SUCCESS')
|
||||
write_log(public.getMsg('ACME_V_SUCCESS'))
|
||||
return check_authorization_status_response
|
||||
|
||||
# 格式化错误输出
|
||||
@@ -559,7 +591,7 @@ class acme_v2:
|
||||
elif error.find('Error getting validation data') != -1:
|
||||
return public.getMsg('ACME_ERR_MSG5')
|
||||
elif "too many certificates already issued for exact set of domains" in error:
|
||||
return public.getMsg('ACME_ERR_MSG6',(re.findall("exact set of domains: (.+):", error),))
|
||||
return public.getMsg('ACME_ERR_MSG6',(str(re.findall("exact set of domains: (.+):", error)),))
|
||||
elif "Error creating new account :: too many registrations for this IP" in error:
|
||||
return public.getMsg('ACME_ERR_MSG7')
|
||||
elif "DNS problem: NXDOMAIN looking up A for" in error:
|
||||
@@ -569,25 +601,25 @@ class acme_v2:
|
||||
elif error.find('TLS Web Server Authentication') != -1:
|
||||
return public.getMsg('ACME_ERR_MSG10')
|
||||
elif error.find('Name does not end in a public suffix') != -1:
|
||||
return public.getMsg('ACME_ERR_MSG11',(re.findall("Cannot issue for \"(.+)\":", error),))
|
||||
return public.getMsg('ACME_ERR_MSG11',(str(re.findall("Cannot issue for \"(.+)\":", error)),))
|
||||
elif error.find('No valid IP addresses found for') != -1:
|
||||
return public.getMsg('ACME_ERR_MSG12',(re.findall("No valid IP addresses found for (.+)", error),))
|
||||
return public.getMsg('ACME_ERR_MSG12',(str(re.findall("No valid IP addresses found for (.+)", error)),))
|
||||
elif error.find('No TXT record found at') != -1:
|
||||
return public.getMsg('ACME_ERR_MSG13',(re.findall("No TXT record found at (.+)", error),))
|
||||
return public.getMsg('ACME_ERR_MSG13',(str(re.findall("No TXT record found at (.+)", error)),))
|
||||
elif error.find('Incorrect TXT record') != -1:
|
||||
return public.getMsg('ACME_ERR_MSG14',(re.findall("found at (.+)", error), re.findall("Incorrect TXT record \"(.+)\"", error)))
|
||||
return public.getMsg('ACME_ERR_MSG14',(str(re.findall("found at (.+)", error)), str(re.findall("Incorrect TXT record \"(.+)\"", error))))
|
||||
elif error.find('Domain not under you or your user') != -1:
|
||||
return public.getMsg('ACME_ERR_MSG15')
|
||||
elif error.find('SERVFAIL looking up TXT for') != -1:
|
||||
return public.getMsg('ACME_ERR_MSG16',re.findall("looking up TXT for (.+)", error))
|
||||
return public.getMsg('ACME_ERR_MSG16',(str(re.findall("looking up TXT for (.+)", error)),))
|
||||
elif error.find('Timeout during connect') != -1:
|
||||
return public.getMsg('ACME_ERR_MSG17')
|
||||
elif error.find("DNS problem: SERVFAIL looking up CAA for") != -1:
|
||||
return public.getMsg('ACME_ERR_MSG18',(re.findall("looking up CAA for (.+)", error),))
|
||||
return public.getMsg('ACME_ERR_MSG18',(str(re.findall("looking up CAA for (.+)", error)),))
|
||||
elif error.find("Read timed out.") != -1:
|
||||
return public.getMsg('ACME_ERR_MSG19')
|
||||
elif error.find('Cannot issue for') != -1:
|
||||
return public.getMsg('ACME_ERR_MSG20',(re.findall(r'for\s+"(.+)"',error),))
|
||||
return public.getMsg('ACME_ERR_MSG20',(str(re.findall(r'for\s+"(.+)"',error)),))
|
||||
elif error.find('too many failed authorizations recently'):
|
||||
return public.getMsg('ACME_ERR_MSG21')
|
||||
elif error.find("Error creating new order") != -1:
|
||||
@@ -642,7 +674,7 @@ class acme_v2:
|
||||
res = self.acme_request(
|
||||
self._config['orders'][index]['certificate_url'], "")
|
||||
if res.status_code not in [200, 201]:
|
||||
raise Exception(public.getMsg('ACME_CERT_DOWNLOAD_ERR',(res.json(),)))
|
||||
raise Exception(public.getMsg('ACME_CERT_DOWNLOAD_ERR',(str(res.json()),)))
|
||||
|
||||
pem_certificate = res.content
|
||||
if type(pem_certificate) == bytes:
|
||||
@@ -874,7 +906,7 @@ fullchain.pem Paste into certificate input box
|
||||
for j in ns.response.answer:
|
||||
for i in j.items:
|
||||
txt_value = i.to_text().replace('"', '').strip()
|
||||
write_log(public.getMsg('ACME_CHECK_DNS1',(n,txt_value)))
|
||||
write_log(public.getMsg('ACME_CHECK_DNS1',(str(n),txt_value)))
|
||||
if txt_value == value:
|
||||
write_log(public.getMsg('ACME_CHECK_DNS2'))
|
||||
return True
|
||||
@@ -1036,7 +1068,7 @@ fullchain.pem Paste into certificate input box
|
||||
res = self.acme_request(url=self._apis['newAccount'], payload=payload)
|
||||
|
||||
if res.status_code not in [201, 200, 409]:
|
||||
raise Exception(public.getMsg('ACME_REGISTERED_ERR',(res.json(),)))
|
||||
raise Exception(public.getMsg('ACME_REGISTERED_ERR',(str(res.json()),)))
|
||||
kid = res.headers["Location"]
|
||||
return kid
|
||||
|
||||
@@ -1212,7 +1244,7 @@ fullchain.pem Paste into certificate input box
|
||||
if not index: # 判断是否只想验证域名
|
||||
write_log(public.getMsg('ACME_CREAT_ORDER'))
|
||||
index = self.create_order(domains, auth_type, auth_to)
|
||||
write_log('ACME_GET_V')
|
||||
write_log(public.getMsg('ACME_GET_V'))
|
||||
self.get_auths(index)
|
||||
if auth_to == 'dns' and len(self._config['orders'][index]['auths']) > 0:
|
||||
return self._config['orders'][index]
|
||||
@@ -1273,14 +1305,19 @@ fullchain.pem Paste into certificate input box
|
||||
args.siteName = public.M('sites').where('id=?',(args.id,)).getField('name')
|
||||
args.sitename = args.siteName
|
||||
data = s.GetRedirectList(args)
|
||||
# 检查重定向是否开启
|
||||
if type(data) == list:
|
||||
for x in data:
|
||||
if x['type']: return public.returnMsg(False, 'SITE_SSL_ERR_301')
|
||||
data = s.GetProxyList(args)
|
||||
# 检查反向代理是否开启
|
||||
if type(data) == list:
|
||||
for x in data:
|
||||
if x['open']: return public.returnMsg(False,'ACME_PROXY_ERR')
|
||||
|
||||
if x['type']: return public.returnMsg(False,'ACME_PROXY_ERR')
|
||||
# 检查旧重定向是否开启
|
||||
data = s.Get301Status(args)
|
||||
if data['status']:
|
||||
return public.returnMsg(False,'SITE_SSL_ERR_3011')
|
||||
#判断是否强制HTTPS
|
||||
if s.IsToHttps(args.siteName):
|
||||
return public.returnMsg(False, 'ACME_FORCE_SSL_ERR')
|
||||
@@ -1307,7 +1344,7 @@ fullchain.pem Paste into certificate input box
|
||||
args_obj = public.dict_obj()
|
||||
if not cron_id:
|
||||
cronPath = public.GetConfigValue('setup_path') + '/cron/' + echo
|
||||
shell = '{} /www/server/panel/class/acme_v2.py --renew=1'.format(sys.executable)
|
||||
shell = '{} -u /www/server/panel/class/acme_v2.py --renew=1'.format(sys.executable)
|
||||
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',("Renew Let's Encrypt Certificate",'day','','0','10',echo,time.strftime('%Y-%m-%d %X',time.localtime()),0,'','localhost','toShell','',shell,''))
|
||||
crontab.crontab().set_cron_status(args_obj)
|
||||
@@ -1321,6 +1358,32 @@ fullchain.pem Paste into certificate input box
|
||||
crontab.crontab().set_cron_status(args_obj)
|
||||
except:pass
|
||||
|
||||
|
||||
# 获取当前正在使用此证书的网站目录
|
||||
def get_ssl_used_site(self,save_path):
|
||||
pkey_file = '{}/privkey.pem'.format(save_path)
|
||||
pkey = public.readFile(pkey_file)
|
||||
if not pkey: return False
|
||||
cert_paths = 'vhost/cert'
|
||||
import panelSite
|
||||
args = public.dict_obj()
|
||||
args.siteName = ''
|
||||
for c_name in os.listdir(cert_paths):
|
||||
skey_file = '{}/{}/privkey.pem'.format(cert_paths,c_name)
|
||||
skey = public.readFile(skey_file)
|
||||
if not skey: continue
|
||||
if skey == pkey:
|
||||
args.siteName = c_name
|
||||
run_path = panelSite.panelSite().GetRunPath(args)
|
||||
if not run_path: continue
|
||||
sitePath = public.M('sites').where('name=?',c_name).getField('path')
|
||||
if not sitePath: continue
|
||||
to_path = "{}/{}".format(sitePath,run_path)
|
||||
return to_path
|
||||
return False
|
||||
|
||||
|
||||
|
||||
# 续签证书
|
||||
def renew_cert(self, index):
|
||||
write_log("", "wb+")
|
||||
@@ -1343,6 +1406,13 @@ fullchain.pem Paste into certificate input box
|
||||
self._config['orders'][i]['cert_timeout'] = int(time.time())
|
||||
if self._config['orders'][i]['cert_timeout'] > s_time or self._config['orders'][i]['auth_to'] == 'dns':
|
||||
continue
|
||||
|
||||
#已删除的网站直接跳过续签
|
||||
if self._config['orders'][i]['auth_to'].find('|') == -1 and self._config['orders'][i]['auth_to'].find('/') != -1:
|
||||
if not os.path.exists(self._config['orders'][i]['auth_to']):
|
||||
auth_to = self.get_ssl_used_site(self._config['orders'][i]['save_path'])
|
||||
if not auth_to: continue
|
||||
self._config['orders'][i]['auth_to'] = auth_to
|
||||
order_index.append(i)
|
||||
|
||||
if not order_index:
|
||||
@@ -1354,7 +1424,7 @@ fullchain.pem Paste into certificate input box
|
||||
cert = None
|
||||
for index in order_index:
|
||||
n += 1
|
||||
write_log(public.getMsg("ACME_RENEWING",(n,self._config['orders'][index]['domains'])))
|
||||
write_log(public.getMsg("ACME_RENEWING",(str(n),self._config['orders'][index]['domains'])))
|
||||
write_log(public.getMsg('ACME_CREAT_ORDER'))
|
||||
try:
|
||||
index = self.create_order(
|
||||
@@ -1477,7 +1547,7 @@ if __name__ == "__main__":
|
||||
write_log(public.getMsg('ACME_USE_TIPS20',(len(cert['auths']),)))
|
||||
for i in range(len(cert['auths'])):
|
||||
write_log('-' * 70)
|
||||
write_log(public.getMsg('ACME_USE_TIPS21',(i+1, cert['auths'][i]['domain'])))
|
||||
write_log(public.getMsg('ACME_USE_TIPS21',(str(i+1), cert['auths'][i]['domain'])))
|
||||
write_log(public.getMsg('ACME_USE_TIPS22',(acme_txt + cert['auths'][i]['domain'].replace('*.', ''), cert['auths'][i]['auth_value'])))
|
||||
write_log(public.getMsg('ACME_USE_TIPS23',(cert['auths'][i]['domain'].replace('*.', ''), acme_caa)))
|
||||
write_log('-' * 70)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
from BTPanel import session,request
|
||||
import public,os,json,time,apache,psutil
|
||||
class ajax:
|
||||
__official_url = 'https://brandnew.aapanel.com'
|
||||
|
||||
def GetApacheStatus(self,get):
|
||||
a = apache.apache()
|
||||
@@ -18,13 +19,13 @@ class ajax:
|
||||
try:
|
||||
pp = psutil.Process(i)
|
||||
if pp.name() not in process_cpu.keys():
|
||||
process_cpu[pp.name()] = float(pp.cpu_percent(interval=0.1))
|
||||
process_cpu[pp.name()] += float(pp.cpu_percent(interval=0.1))
|
||||
process_cpu[pp.name()] = float(pp.cpu_percent(interval=0.01))
|
||||
process_cpu[pp.name()] += float(pp.cpu_percent(interval=0.01))
|
||||
except:
|
||||
pass
|
||||
def GetNginxStatus(self,get):
|
||||
try:
|
||||
if not os.path.exists('/www/server/nginx/sbin/nginx'): return public.returnMsg(False,'nginx is not install')
|
||||
if not os.path.exists('/www/server/nginx/sbin/nginx'): return public.returnMsg(False,'NGINX_NOT_INSTALL')
|
||||
process_cpu = {}
|
||||
worker = int(public.ExecShell("ps aux|grep nginx|grep 'worker process'|wc -l")[0])-1
|
||||
workermen = int(public.ExecShell("ps aux|grep nginx|grep 'worker process'|awk '{memsum+=$6};END {print memsum}'")[0]) / 1024
|
||||
@@ -36,6 +37,9 @@ class ajax:
|
||||
self.CheckStatusConf()
|
||||
result = public.httpGet('http://127.0.0.1/nginx_status')
|
||||
tmp = result.split()
|
||||
if len(tmp) < 15:
|
||||
result = public.ExecShell('curl http://127.0.0.1/nginx_status')[0]
|
||||
tmp = result.split()
|
||||
data = {}
|
||||
if "request_time" in tmp:
|
||||
data['accepts'] = tmp[8]
|
||||
@@ -310,7 +314,7 @@ class ajax:
|
||||
def GetNetWorkIo(self,get):
|
||||
#取指定时间段的网络Io
|
||||
data = public.M('network').dbfile('system').where("addtime>=? AND addtime<=?",(get.start,get.end)).field('id,up,down,total_up,total_down,down_packets,up_packets,addtime').order('id asc').select()
|
||||
return self.ToAddtime(data)
|
||||
return self.ToAddtime(data,None)
|
||||
|
||||
def GetDiskIo(self,get):
|
||||
#取指定时间段的磁盘Io
|
||||
@@ -342,7 +346,10 @@ class ajax:
|
||||
for i in range(length):
|
||||
data[i]['addtime'] = time.strftime('%m/%d %H:%M',time.localtime(float(data[i]['addtime'])))
|
||||
if tomem and data[i]['mem'] > 100: data[i]['mem'] = data[i]['mem'] / mPre
|
||||
|
||||
if tomem in [None]:
|
||||
if type(data[i]['down_packets']) == str:
|
||||
data[i]['down_packets'] = json.loads(data[i]['down_packets'])
|
||||
data[i]['up_packets'] = json.loads(data[i]['up_packets'])
|
||||
return data
|
||||
else:
|
||||
count = 0
|
||||
@@ -353,6 +360,10 @@ class ajax:
|
||||
continue
|
||||
value['addtime'] = time.strftime('%m/%d %H:%M',time.localtime(float(value['addtime'])))
|
||||
if tomem and value['mem'] > 100: value['mem'] = value['mem'] / mPre
|
||||
if tomem in [None]:
|
||||
if type(value['down_packets']) == str:
|
||||
value['down_packets'] = json.loads(value['down_packets'])
|
||||
value['up_packets'] = json.loads(value['up_packets'])
|
||||
tmp.append(value)
|
||||
count = 0
|
||||
return tmp
|
||||
@@ -430,8 +441,8 @@ class ajax:
|
||||
#获取最新的5条测试版更新日志
|
||||
def get_beta_logs(self,get):
|
||||
try:
|
||||
# data = json.loads(public.HttpGet(public.GetConfigValue('home') + '/api/panel/get_beta_logs_en'))
|
||||
data = json.loads(public.HttpGet('https://console.aapanel.com/api/panel/get_beta_logs_en'))
|
||||
# data = json.loads(public.HttpGet('https://console.aapanel.com/api/panel/get_beta_logs_en'))
|
||||
data = json.loads(public.HttpGet('{}/api/panel/getBetaVersionLogs'.format(self.__official_url)))
|
||||
return data
|
||||
except:
|
||||
return public.returnMsg(False,'AJAX_CONN_ERR')
|
||||
@@ -453,7 +464,7 @@ class ajax:
|
||||
import json
|
||||
conf_status = public.M('config').where("id=?",('1',)).field('status').find()
|
||||
if int(session['config']['status']) == 0 and int(conf_status['status']) == 0:
|
||||
public.HttpGet(public.GetConfigValue('home')+'/Api/SetupCount?type=Linux')
|
||||
public.HttpGet('{}/api/setupCount/setupPanel?type=Linux'.format(self.__official_url))
|
||||
public.M('config').where("id=?",('1',)).setField('status',1)
|
||||
|
||||
#取回远程版本信息
|
||||
@@ -484,8 +495,8 @@ class ajax:
|
||||
data['o'] = ''
|
||||
filename = '/www/server/panel/data/o.pl'
|
||||
if os.path.exists(filename): data['o'] = str(public.readFile(filename))
|
||||
# sUrl = public.GetConfigValue('home') + '/api/panel/updateLinuxEn'
|
||||
sUrl = 'https://console.aapanel.com/api/panel/updateLinuxEn'
|
||||
# sUrl = 'https://console.aapanel.com/api/panel/updateLinuxEn'
|
||||
sUrl = '{}/api/panel/updateLinuxEn'.format(self.__official_url)
|
||||
updateInfo = json.loads(public.httpPost(sUrl,data))
|
||||
if not updateInfo: return public.returnMsg(False,"CONNECT_ERR")
|
||||
#updateInfo['msg'] = msg;
|
||||
@@ -665,7 +676,10 @@ class ajax:
|
||||
#清理日志
|
||||
def delClose(self,get):
|
||||
if not 'uid' in session: session['uid'] = 1
|
||||
if session['uid'] != 1: return public.returnMsg(False,'Permission denied!')
|
||||
if session['uid'] != 1: return public.returnMsg(False,'PERMISSION_DENIED')
|
||||
if 'tmp_login_id' in session:
|
||||
return public.returnMsg(False,'PERMISSION_DENIED')
|
||||
|
||||
public.M('logs').where('id>?',(0,)).delete()
|
||||
public.WriteLog('TYPE_CONFIG','LOG_CLOSE')
|
||||
return public.returnMsg(True,'LOG_CLOSE')
|
||||
@@ -865,7 +879,7 @@ class ajax:
|
||||
|
||||
#PHP
|
||||
<FilesMatch \.php$>
|
||||
SetHandler "proxy:unix:/tmp/php-cgi-{}.sock|fcgi://localhost"
|
||||
SetHandler "proxy:{}"
|
||||
</FilesMatch>
|
||||
|
||||
#DENY FILES
|
||||
@@ -883,7 +897,7 @@ class ajax:
|
||||
Require all granted
|
||||
DirectoryIndex index.php index.html index.htm default.php default.html default.htm
|
||||
</Directory>
|
||||
</VirtualHost>'''.format(v["ext"]["phpversion"],auth)
|
||||
</VirtualHost>'''.format(public.get_php_proxy(v["ext"]["phpversion"],'apache'),auth)
|
||||
public.writeFile("/www/server/panel/vhost/apache/phpmyadmin.conf", ssl_conf)
|
||||
else:
|
||||
if os.path.exists("/www/server/panel/vhost/nginx/phpmyadmin.conf"):
|
||||
@@ -947,11 +961,11 @@ class ajax:
|
||||
if public.get_webserver() == 'nginx':
|
||||
filename = public.GetConfigValue('setup_path') + '/nginx/conf/enable-php.conf'
|
||||
conf = public.readFile(filename)
|
||||
rep = r"php-cgi.*\.sock"
|
||||
conf = re.sub(rep,'php-cgi-' + get.phpversion + '.sock',conf,1)
|
||||
rep = r"(unix:/tmp/php-cgi.*\.sock|127.0.0.1:\d+)"
|
||||
conf = re.sub(rep,public.get_php_proxy(get.phpversion,'nginx'),conf,1)
|
||||
elif public.get_webserver() == 'apache':
|
||||
rep = r"php-cgi.*\.sock"
|
||||
conf = re.sub(rep,'php-cgi-' + get.phpversion + '.sock',conf,1)
|
||||
rep = r"(unix:/tmp/php-cgi.*\.sock\|fcgi://localhost|fcgi://127.0.0.1:\d+)"
|
||||
conf = re.sub(rep,public.get_php_proxy(get.phpversion,'apache'),conf,1)
|
||||
else:
|
||||
reg = r'/usr/local/lsws/lsphp\d+/bin/lsphp'
|
||||
conf = re.sub(reg,'/usr/local/lsws/lsphp{}/bin/lsphp'.format(get.phpversion),conf)
|
||||
@@ -983,7 +997,7 @@ class ajax:
|
||||
#return public.returnMsg(False,'ERROR');
|
||||
|
||||
def ToPunycode(self,get):
|
||||
import re;
|
||||
import re
|
||||
get.domain = get.domain.encode('utf8')
|
||||
tmp = get.domain.split('.')
|
||||
newdomain = ''
|
||||
@@ -1148,6 +1162,7 @@ class ajax:
|
||||
|
||||
#检查用户绑定是否正确
|
||||
def check_user_auth(self,get):
|
||||
import requests
|
||||
m_key = 'check_user_auth'
|
||||
if m_key in session: return session[m_key]
|
||||
u_path = 'data/userInfo.json'
|
||||
@@ -1156,16 +1171,15 @@ class ajax:
|
||||
except:
|
||||
if os.path.exists(u_path): os.remove(u_path)
|
||||
return public.returnMsg(False,'AJAX_USER_BE_OVERDUE')
|
||||
pdata = {'access_key':userInfo['access_key'],'secret_key':userInfo['secret_key']}
|
||||
result = public.HttpPost(public.GetConfigValue('home') + '/api/panel/check_auth_key',pdata,3)
|
||||
if result == '0':
|
||||
url_headers = {"authorization":"bt {}".format(userInfo['token'])}
|
||||
resp = requests.post('{}/api/user/verifyToken'.format(self.__official_url),headers=url_headers)
|
||||
resp = resp.json()
|
||||
if not resp['success']:
|
||||
if os.path.exists(u_path): os.remove(u_path)
|
||||
return public.returnMsg(False,'AJAX_USER_BE_OVERDUE')
|
||||
if result == '1':
|
||||
session[m_key] = public.returnMsg(True,'AJAX_USER_IS_VALID!')
|
||||
else:
|
||||
session[m_key] = public.returnMsg(True,'AJAX_USER_IS_VALID')
|
||||
return session[m_key]
|
||||
return public.returnMsg(True,result)
|
||||
|
||||
|
||||
#PHP探针
|
||||
def php_info(self,args):
|
||||
@@ -1178,6 +1192,8 @@ class ajax:
|
||||
if not os.path.exists('/etc/redhat-release'):
|
||||
php_ini = php_path + php_version + '/etc/php/'+args.php_version+'/litespeed/php.ini'
|
||||
tmp = public.ExecShell(php_bin + ' /www/server/panel/class/php_info.php')[0]
|
||||
if tmp.find('Warning: JIT is incompatible') != -1:
|
||||
tmp = tmp.strip().split('\n')[-1]
|
||||
result = json.loads(tmp)
|
||||
result['phpinfo'] = {}
|
||||
result['phpinfo']['php_version'] = result['php_version']
|
||||
|
||||
@@ -11,12 +11,15 @@
|
||||
# Apache管理模块
|
||||
#------------------------------
|
||||
import public,os,re,shutil,math,psutil,time
|
||||
from json import loads
|
||||
os.chdir("/www/server/panel")
|
||||
|
||||
class apache:
|
||||
setupPath = '/www/server'
|
||||
apachedefaultfile = "%s/apache/conf/extra/httpd-default.conf" % (setupPath)
|
||||
apachempmfile = "%s/apache/conf/extra/httpd-mpm.conf" % (setupPath)
|
||||
httpdconf = "%s/apache/conf/httpd.conf" % (setupPath)
|
||||
|
||||
|
||||
def GetProcessCpuPercent(self,i,process_cpu):
|
||||
try:
|
||||
@@ -201,3 +204,143 @@ class apache:
|
||||
'<br>') + '</a>')
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True, 'SET_SUCCESS')
|
||||
|
||||
def add_httpd_access_log_format(self,args):
|
||||
'''
|
||||
@name 添加httpd日志格式
|
||||
@author zhwen<zhw@bt.cn>
|
||||
@param log_format 需要设置的日志格式["$server_name","$remote_addr","-"....]
|
||||
@param log_format_name
|
||||
@param act 操作方式 add/edit
|
||||
'''
|
||||
try:
|
||||
log_format = loads(args.log_format)
|
||||
data = """
|
||||
#LOG_FORMAT_BEGIN_{n}
|
||||
LogFormat '{c}' {n}
|
||||
#LOG_FORMAT_END_{n}
|
||||
""".format(n=args.log_format_name,c=' '.join(log_format))
|
||||
data = data.replace('%{User-agent}i','"%{User-agent}i"')
|
||||
data = data.replace('%{Referer}i', '"%{Referer}i"')
|
||||
if args.act == 'edit':
|
||||
self.del_httpd_access_log_format(args)
|
||||
conf = public.readFile(self.httpdconf)
|
||||
if not conf:
|
||||
return public.returnMsg(False,'CONF_FILE_NOT_EXISTS')
|
||||
reg = '<IfModule log_config_module>'
|
||||
conf = re.sub(reg,'<IfModule log_config_module>'+data,conf)
|
||||
public.writeFile(self.httpdconf,conf)
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True, 'SET_SUCCESS')
|
||||
except:
|
||||
return public.returnMsg(False, str(public.get_error_info()))
|
||||
|
||||
def del_httpd_access_log_format(self,args):
|
||||
'''
|
||||
@name 删除日志格式
|
||||
@author zhwen<zhw@bt.cn>
|
||||
@param log_format_name
|
||||
'''
|
||||
conf = public.readFile(self.httpdconf)
|
||||
if not conf:
|
||||
return public.returnMsg(False, 'CONF_FILE_NOT_EXISTS')
|
||||
reg = '\s*#LOG_FORMAT_BEGIN_{n}(\n|.)+#LOG_FORMAT_END_{n}\n?'.format(n=args.log_format_name)
|
||||
conf = re.sub(reg,'',conf)
|
||||
public.writeFile(self.httpdconf,conf)
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True, 'SET_SUCCESS')
|
||||
|
||||
def get_httpd_access_log_format_parameter(self,args=None):
|
||||
data = {
|
||||
"%h":"Client's IP address",
|
||||
"%r":"Request agreement",
|
||||
"%t":"Request time",
|
||||
"%>s":"http status code",
|
||||
"%b":"Send data size",
|
||||
"%{Referer}i":"http referer",
|
||||
"%{User-agent}i":"http user agent",
|
||||
"%{X-Forwarded-For}i":"The real ip of the client",
|
||||
"%l":"Remote login name",
|
||||
"%u":"Remote user",
|
||||
"-":"-"
|
||||
}
|
||||
if hasattr(args,'log_format_name'):
|
||||
site_list = self._get_format_log_to_website(args.log_format_name)
|
||||
return {'site_list':site_list,'format_log':data}
|
||||
else:
|
||||
return data
|
||||
|
||||
def _process_log_format(self,tmp):
|
||||
log_tips = self.get_httpd_access_log_format_parameter()
|
||||
data = []
|
||||
for t in tmp:
|
||||
t = t.replace('\"','')
|
||||
t = t.replace("'", "")
|
||||
if t not in log_tips:
|
||||
continue
|
||||
data.append({t:log_tips[t]})
|
||||
return data
|
||||
|
||||
def get_httpd_access_log_format(self,args=None):
|
||||
try:
|
||||
reg = "#LOG_FORMAT_BEGIN.*"
|
||||
conf = public.readFile(self.httpdconf)
|
||||
if not conf:
|
||||
return public.returnMsg(False, 'CONF_FILE_NOT_EXISTS')
|
||||
data = re.findall(reg,conf)
|
||||
format_name = [i.split('_')[-1] for i in data]
|
||||
format_log = {}
|
||||
for i in format_name:
|
||||
format_reg = "#LOG_FORMAT_BEGIN_{n}(\n|.)+LogFormat\s+\'(.*)\'\s+{n}".format(n=i)
|
||||
tmp = re.search(format_reg,conf).groups()[1].split()
|
||||
format_log[i] = self._process_log_format(tmp)
|
||||
return format_log
|
||||
except:
|
||||
return public.get_error_info()
|
||||
|
||||
def set_httpd_format_log_to_website(self,args):
|
||||
'''
|
||||
@name 设置网站日志格式
|
||||
@author zhwen<zhw@bt.cn>
|
||||
@param sites aaa.com,bbb.com
|
||||
@param log_format_name
|
||||
'''
|
||||
# sites = args.sites.split(',')
|
||||
sites = loads(args.sites)
|
||||
try:
|
||||
all_site = public.M('sites').field('name').select()
|
||||
reg = 'CustomLog\s+"/www.*{}\s*'.format(args.log_format_name)
|
||||
for site in all_site:
|
||||
website_conf_file = '/www/server/panel/vhost/apache/{}.conf'.format(site['name'])
|
||||
conf = public.readFile(website_conf_file)
|
||||
if not conf:
|
||||
return public.returnMsg(False, 'CONF_FILE_NOT_EXISTS')
|
||||
format_exist_reg = '(CustomLog\s+"/www.*\_log).*'
|
||||
access_log = re.search(format_exist_reg, conf).groups()[0] + '" ' + args.log_format_name
|
||||
if site['name'] not in sites and re.search(format_exist_reg,conf):
|
||||
access_log = ' '.join(access_log.split()[:-1])
|
||||
conf = re.sub(reg, access_log, conf)
|
||||
public.writeFile(website_conf_file,conf)
|
||||
continue
|
||||
conf = re.sub(format_exist_reg,access_log,conf)
|
||||
public.writeFile(website_conf_file,conf)
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True, 'SET_SUCCESS')
|
||||
except:
|
||||
return public.returnMsg(False, str(public.get_error_info()))
|
||||
|
||||
def _get_format_log_to_website(self,log_format_name):
|
||||
tmp = public.M('sites').field('name').select()
|
||||
reg = 'CustomLog.*{}'.format(log_format_name)
|
||||
data = {}
|
||||
for i in tmp:
|
||||
website_conf_file = '/www/server/panel/vhost/apache/{}.conf'.format(i['name'])
|
||||
conf = public.readFile(website_conf_file)
|
||||
if not conf:
|
||||
data[i['name']] = False
|
||||
continue
|
||||
if re.search(reg,conf):
|
||||
data[i['name']] = True
|
||||
else:
|
||||
data[i['name']] = False
|
||||
return data
|
||||
@@ -12,7 +12,8 @@ if sys.version_info[0] == 2:
|
||||
reload(sys)
|
||||
sys.setdefaultencoding('utf-8')
|
||||
os.chdir('/www/server/panel')
|
||||
sys.path.append("class/")
|
||||
if not 'class/' in sys.path:
|
||||
sys.path.insert(0,'class/')
|
||||
import time,hashlib,sys,os,json,requests,re,public,random,string,panelMysql,downloadFile
|
||||
python_bin=public.get_python_bin()
|
||||
class backup_bak:
|
||||
|
||||
@@ -33,36 +33,36 @@ class panelSetup:
|
||||
ua = ua.lower()
|
||||
if ua.find('spider') != -1 or ua.find('bot') != -1:
|
||||
return redirect('https://www.google.com')
|
||||
g.version = '6.8.4'
|
||||
g.version = '6.8.8'
|
||||
g.title = public.GetConfigValue('title')
|
||||
g.uri = request.path
|
||||
g.debug = os.path.exists('data/debug.pl')
|
||||
g.pyversion = sys.version_info[0]
|
||||
if not g.debug:
|
||||
g.cdn_url = public.get_cdn_url()
|
||||
if not g.cdn_url:
|
||||
g.cdn_url = '/static'
|
||||
else:
|
||||
g.cdn_url = '//' + g.cdn_url + '/' + g.version
|
||||
else:
|
||||
g.cdn_url = '/static'
|
||||
|
||||
session['version'] = g.version
|
||||
session['title'] = g.title
|
||||
|
||||
if request.method == 'GET':
|
||||
if not g.debug:
|
||||
g.cdn_url = public.get_cdn_url()
|
||||
if not g.cdn_url:
|
||||
g.cdn_url = '/static'
|
||||
else:
|
||||
g.cdn_url = '//' + g.cdn_url + '/' + g.version
|
||||
else:
|
||||
g.cdn_url = '/static'
|
||||
session['title'] = g.title
|
||||
dirPath = '/www/server/phpmyadmin/pma'
|
||||
if os.path.exists(dirPath):
|
||||
public.ExecShell("rm -rf {}".format(dirPath))
|
||||
|
||||
dirPath = '/www/server/adminer'
|
||||
if os.path.exists(dirPath):
|
||||
public.ExecShell("rm -rf {}".format(dirPath))
|
||||
|
||||
dirPath = '/www/server/panel/adminer'
|
||||
if os.path.exists(dirPath):
|
||||
public.ExecShell("rm -rf {}".format(dirPath))
|
||||
|
||||
g.is_aes = False
|
||||
|
||||
dirPath = '/www/server/phpmyadmin/pma'
|
||||
if os.path.exists(dirPath):
|
||||
public.ExecShell("rm -rf {}".format(dirPath))
|
||||
|
||||
dirPath = '/www/server/adminer'
|
||||
if os.path.exists(dirPath):
|
||||
public.ExecShell("rm -rf {}".format(dirPath))
|
||||
|
||||
dirPath = '/www/server/panel/adminer'
|
||||
if os.path.exists(dirPath):
|
||||
public.ExecShell("rm -rf {}".format(dirPath))
|
||||
|
||||
return None
|
||||
|
||||
|
||||
@@ -91,13 +91,11 @@ class panelAdmin(panelSetup):
|
||||
|
||||
# 设置基础Session
|
||||
def setSession(self):
|
||||
session['menus'] = sorted(json.loads(public.ReadFile(
|
||||
'config/menu.json')), key=lambda x: x['sort'])
|
||||
session['yaer'] = datetime.now().year
|
||||
session['download_url'] = 'http://download.bt.cn'
|
||||
if request.method == 'GET':
|
||||
g.menus = public.get_menus()
|
||||
g.yaer = datetime.now().year
|
||||
session["top_tips"] = public.GetMsg("TOP_TIPS")
|
||||
session["bt_help"] = public.GetMsg("BT_HELP")
|
||||
# session["manual"] = public.GetMsg("MANUAL")
|
||||
session["download"] = public.GetMsg("DOWNLOAD")
|
||||
if not 'brand' in session:
|
||||
session['brand'] = public.GetConfigValue('brand')
|
||||
@@ -113,22 +111,27 @@ class panelAdmin(panelSetup):
|
||||
session['lan'] = public.GetLanguage()
|
||||
if not 'home' in session:
|
||||
session['home'] = 'https://console.aapanel.com'
|
||||
return None
|
||||
return False
|
||||
|
||||
# 检查Web服务器类型
|
||||
|
||||
def checkWebType(self):
|
||||
if os.path.exists('/usr/local/lsws/bin/lswsctrl'):
|
||||
session['webserver'] = 'openlitespeed'
|
||||
elif os.path.exists(self.setupPath + '/apache'):
|
||||
session['webserver'] = 'apache'
|
||||
else:
|
||||
session['webserver'] = 'nginx'
|
||||
if os.path.exists(self.setupPath+'/'+session['webserver']+'/version.pl'):
|
||||
session['webversion'] = public.ReadFile(self.setupPath+'/'+session['webserver']+'/version.pl').strip()
|
||||
filename = self.setupPath+'/data/phpmyadminDirName.pl'
|
||||
if os.path.exists(filename):
|
||||
session['phpmyadminDir'] = public.ReadFile(filename).strip()
|
||||
#if request.method == 'GET':
|
||||
if not 'webserver' in session:
|
||||
if os.path.exists('/usr/local/lsws/bin/lswsctrl'):
|
||||
session['webserver'] = 'openlitespeed'
|
||||
elif os.path.exists(self.setupPath + '/apache/bin/apachectl'):
|
||||
session['webserver'] = 'apache'
|
||||
else:
|
||||
session['webserver'] = 'nginx'
|
||||
if not 'webversion' in session:
|
||||
if os.path.exists(self.setupPath+'/'+session['webserver']+'/version.pl'):
|
||||
session['webversion'] = public.ReadFile(self.setupPath+'/'+session['webserver']+'/version.pl').strip()
|
||||
|
||||
if not 'phpmyadminDir' in session:
|
||||
filename = self.setupPath+'/data/phpmyadminDirName.pl'
|
||||
if os.path.exists(filename):
|
||||
session['phpmyadminDir'] = public.ReadFile(filename).strip()
|
||||
return False
|
||||
|
||||
# 检查面板是否关闭
|
||||
def checkClose(self):
|
||||
@@ -139,15 +142,28 @@ class panelAdmin(panelSetup):
|
||||
def check_login(self):
|
||||
try:
|
||||
api_check = True
|
||||
g.api_request = False
|
||||
if not 'login' in session:
|
||||
api_check = self.get_sk()
|
||||
if api_check:
|
||||
session.clear()
|
||||
return api_check
|
||||
g.api_request = True
|
||||
else:
|
||||
if session['login'] == False:
|
||||
session.clear()
|
||||
return redirect('/login')
|
||||
|
||||
if 'tmp_login_expire' in session:
|
||||
s_file = 'data/session/{}'.format(session['tmp_login_id'])
|
||||
if session['tmp_login_expire'] < time.time():
|
||||
session.clear()
|
||||
if os.path.exists(s_file): os.remove(s_file)
|
||||
return redirect('/login')
|
||||
if not os.path.exists(s_file):
|
||||
session.clear()
|
||||
return redirect('/login')
|
||||
|
||||
if api_check:
|
||||
try:
|
||||
sess_out_path = 'data/session_timeout.pl'
|
||||
@@ -172,14 +188,13 @@ class panelAdmin(panelSetup):
|
||||
if 'login_token' in session:
|
||||
if session['login_token'] != token:
|
||||
session.clear()
|
||||
return redirect('/login?dologin=True')
|
||||
return redirect('/login?dologin=True&go=1')
|
||||
if api_check:
|
||||
filename = 'data/sess_files/' + public.get_sess_key()
|
||||
if not os.path.exists(filename):
|
||||
session.clear()
|
||||
return redirect('/login?dologin=True')
|
||||
return redirect('/login?dologin=True&go=2')
|
||||
except:
|
||||
return public.returnMsg(False,public.get_error_info())
|
||||
session.clear()
|
||||
return redirect('/login')
|
||||
|
||||
@@ -205,7 +220,7 @@ class panelAdmin(panelSetup):
|
||||
|
||||
num_key = client_ip + '_api'
|
||||
if not public.get_error_num(num_key,20):
|
||||
return public.returnMsg(False,'AUTH_FAILED1')
|
||||
return public.returnJson(False,'AUTH_FAILED1')
|
||||
|
||||
|
||||
if not client_ip in api_config['limit_addr']:
|
||||
@@ -214,13 +229,13 @@ class panelAdmin(panelSetup):
|
||||
else:
|
||||
num_key = client_ip + '_app'
|
||||
if not public.get_error_num(num_key,20):
|
||||
return public.returnMsg(False,'AUTH_FAILED1')
|
||||
return public.returnJson(False,'AUTH_FAILED1')
|
||||
a_file = '/dev/shm/' + get.client_bind_token
|
||||
if not os.path.exists(a_file):
|
||||
import panelApi
|
||||
if not panelApi.panelApi().get_app_find(get.client_bind_token):
|
||||
public.set_error_num(num_key)
|
||||
return public.returnMsg(False,'UNBOUND_DEVICE')
|
||||
return public.returnJson(False,'UNBOUND_DEVICE')
|
||||
public.writeFile(a_file,'')
|
||||
|
||||
if not 'key' in api_config:
|
||||
@@ -255,6 +270,7 @@ class panelAdmin(panelSetup):
|
||||
'users').where("id=?", ('1',)).getField('email')
|
||||
if not 'address' in session:
|
||||
session['address'] = public.GetLocalIp()
|
||||
return False
|
||||
|
||||
# 获取操作系统类型
|
||||
def GetOS(self):
|
||||
@@ -271,3 +287,4 @@ class panelAdmin(panelSetup):
|
||||
tmp['x'] = 'Debian'
|
||||
tmp['osname'] = public.ReadFile('/etc/issue').split()[0]
|
||||
session['server_os'] = tmp
|
||||
return False
|
||||
|
||||
@@ -51,65 +51,65 @@ class config:
|
||||
if emial in self.__mail_list:
|
||||
self.__mail_list.remove(emial)
|
||||
public.writeFile(self.__mail_list_data, json.dumps(self.__mail_list))
|
||||
return public.returnMsg(True, 'Successfully deleted')
|
||||
return public.returnMsg(True, 'DEL_SUCCESS')
|
||||
else:
|
||||
return public.returnMsg(True, 'Email does not exist')
|
||||
return public.returnMsg(True, 'EMAIL_NOT_EXISTS')
|
||||
|
||||
#添加接受邮件地址
|
||||
def add_mail_address(self, get):
|
||||
if not hasattr(get, 'email'): return public.returnMsg(False, 'Please input your email')
|
||||
if not hasattr(get, 'email'): return public.returnMsg(False, 'INPUT_EMAIL')
|
||||
emailformat = re.compile(r'[a-zA-Z0-9.-_+%]+@[a-zA-Z0-9]+\.[a-zA-Z0-9]+')
|
||||
if not emailformat.search(get.email): return public.returnMsg(False, 'Please enter your vaild email')
|
||||
if not emailformat.search(get.email): return public.returnMsg(False, 'EMAIL_ERR')
|
||||
# 测试发送邮件
|
||||
if get.email.strip() in self.__mail_list: return public.returnMsg(True, 'Email already exists')
|
||||
if get.email.strip() in self.__mail_list: return public.returnMsg(True, 'EMAIL_EXISTS')
|
||||
self.__mail_list.append(get.email.strip())
|
||||
public.writeFile(self.__mail_list_data, json.dumps(self.__mail_list))
|
||||
return public.returnMsg(True, 'Added successfully')
|
||||
return public.returnMsg(True, 'SET_SUCCESS')
|
||||
|
||||
# 添加自定义邮箱地址
|
||||
def user_mail_send(self, get):
|
||||
if not (hasattr(get, 'email') or hasattr(get, 'stmp_pwd') or hasattr(get, 'hosts') or hasattr(get, 'port')):
|
||||
return public.returnMsg(False, 'Please complete the information')
|
||||
return public.returnMsg(False, 'COMPLETE_INFO')
|
||||
# 自定义邮件
|
||||
self.mail.qq_stmp_insert(get.email.strip(), get.stmp_pwd.strip(), get.hosts.strip(),get.port.strip())
|
||||
# 测试发送
|
||||
if self.mail.qq_smtp_send(get.email.strip(), 'aaPanel Alert Test Email', 'aaPanel Alert Test Email'):
|
||||
if self.mail.qq_smtp_send(get.email.strip(), public.getMsg('TEST_MAIL_TITLE'), public.getMsg('TEST_MAIL_CONTENT')):
|
||||
if not get.email.strip() in self.__mail_list:
|
||||
self.__mail_list.append(get.email.strip())
|
||||
public.writeFile(self.__mail_list_data, json.dumps(self.__mail_list))
|
||||
return public.returnMsg(True, 'Added successfully')
|
||||
return public.returnMsg(True, 'SET_SUCCESS')
|
||||
else:
|
||||
ret = []
|
||||
public.writeFile(self.__mail_config, json.dumps(ret))
|
||||
return public.returnMsg(False, 'Email sending failed, please check if the STMP password is correct or the hosts are correct')
|
||||
return public.returnMsg(False, 'TEST_MAIL_SEND_ERR')
|
||||
|
||||
# 查看自定义邮箱配置
|
||||
def get_user_mail(self, get):
|
||||
qq_mail_info = json.loads(public.ReadFile(self.__mail_config))
|
||||
if len(qq_mail_info) == 0:
|
||||
return public.returnMsg(False, 'No Data')
|
||||
return public.returnMsg(False, 'NO_DATA')
|
||||
if not 'port' in qq_mail_info:qq_mail_info['port']=465
|
||||
return public.returnMsg(True, qq_mail_info)
|
||||
|
||||
|
||||
# 用户自定义邮件发送
|
||||
def user_stmp_mail_send(self, get):
|
||||
if not (hasattr(get, 'email')): return public.returnMsg(False, 'Please fill in the email address')
|
||||
if not (hasattr(get, 'email')): return public.returnMsg(False, 'INPUT_EMAIL')
|
||||
emailformat = re.compile(r'[a-zA-Z0-9.-_+%]+@[a-zA-Z0-9]+\.[a-zA-Z0-9]+')
|
||||
if not emailformat.search(get.email): return public.returnMsg(False, 'Please enter your vaild email')
|
||||
if not emailformat.search(get.email): return public.returnMsg(False, 'EMAIL_ERR')
|
||||
# 测试发送邮件
|
||||
if not get.email.strip() in self.__mail_list: return public.returnMsg(True, 'The mailbox does not exist, please add it to the mailbox list')
|
||||
if not (hasattr(get, 'title')): return public.returnMsg(False, 'Please fill in the message header')
|
||||
if not (hasattr(get, 'body')): return public.returnMsg(False, 'Please enter the message content')
|
||||
if not get.email.strip() in self.__mail_list: return public.returnMsg(True, 'MAILBOX_NOT_EXIST')
|
||||
if not (hasattr(get, 'title')): return public.returnMsg(False, 'EMAIL_TITLE')
|
||||
if not (hasattr(get, 'body')): return public.returnMsg(False, 'EMAIL_CONTENT_ERR')
|
||||
# 先判断是否存在stmp信息
|
||||
qq_mail_info = json.loads(public.ReadFile(self.__mail_config))
|
||||
if len(qq_mail_info) == 0:
|
||||
return public.returnMsg(False, 'STMP information was not found, please re-add custom mail STMP information in the settings')
|
||||
return public.returnMsg(False, 'SMTP_INFO_ERR')
|
||||
if self.mail.qq_smtp_send(get.email.strip(), get.title.strip(), get.body):
|
||||
# 发送成功
|
||||
return public.returnMsg(True, 'Sent successfully')
|
||||
return public.returnMsg(True, 'SEND_SUCCESS')
|
||||
else:
|
||||
return public.returnMsg(False, 'Failed to send')
|
||||
return public.returnMsg(False, 'SEND_FAILED')
|
||||
|
||||
# 查看能使用的告警通道
|
||||
def get_settings(self, get):
|
||||
@@ -130,22 +130,22 @@ class config:
|
||||
# 设置钉钉报警
|
||||
def set_dingding(self, get):
|
||||
if not (hasattr(get, 'url') or hasattr(get, 'atall')):
|
||||
return public.returnMsg(False, 'Please complete the information')
|
||||
return public.returnMsg(False, 'COMPLETE_INFO')
|
||||
if get.atall:
|
||||
get.atall = 'True'
|
||||
else: get.atall = 'False'
|
||||
self.mail.dingding_insert(get.url.strip(), get.atall)
|
||||
if self.mail.dingding_send('aaPanel alarm test'):
|
||||
return public.returnMsg(True, 'Added successfully')
|
||||
if self.mail.dingding_send(public.getMsg('ALARM_TEST')):
|
||||
return public.returnMsg(True, 'SET_SUCCESS')
|
||||
else:
|
||||
ret = []
|
||||
public.writeFile(self.__dingding_config, json.dumps(ret))
|
||||
return public.returnMsg(False, 'Add failed, please check if the URL is correct')
|
||||
return public.returnMsg(False, 'MAIL_ADD_FAILED')
|
||||
# 查看钉钉
|
||||
def get_dingding(self, get):
|
||||
qq_mail_info = json.loads(public.ReadFile(self.__dingding_config))
|
||||
if len(qq_mail_info) == 0:
|
||||
return public.returnMsg(False, 'No Data')
|
||||
return public.returnMsg(False, 'NO_DATA')
|
||||
return public.returnMsg(True, qq_mail_info)
|
||||
|
||||
# 使用钉钉发送消息
|
||||
@@ -155,9 +155,9 @@ class config:
|
||||
return public.returnMsg(False, 'The configuration information of the nails you configured was not found, please add in the settings')
|
||||
if not (hasattr(get, 'content')): return public.returnMsg(False, 'Please enter the data you need to send')
|
||||
if self.mail.dingding_send(get.content):
|
||||
return public.returnMsg(True, 'Sent successfully')
|
||||
return public.returnMsg(True, 'SEND_SUCCESS')
|
||||
else:
|
||||
return public.returnMsg(False, 'Failed to send')
|
||||
return public.returnMsg(False, 'SEND_FAILED')
|
||||
|
||||
|
||||
def getPanelState(self,get):
|
||||
@@ -226,51 +226,51 @@ class config:
|
||||
|
||||
# 创建新用户
|
||||
def create_user(self,args):
|
||||
if session['uid'] != 1: return public.returnMsg(False,'Permission denied!')
|
||||
if len(args.username) < 2: return public.returnMsg(False,'User name must be at least 2 characters')
|
||||
if len(args.password) < 8: return public.returnMsg(False,'Password must be at least 8 characters')
|
||||
if session['uid'] != 1: return public.returnMsg(False,'PERMISSION_DENIED')
|
||||
if len(args.username) < 2: return public.returnMsg(False,'USERNAME_ERR')
|
||||
if len(args.password) < 8: return public.returnMsg(False,'PASSWORD_ERR')
|
||||
pdata = {
|
||||
"username": args.username.strip(),
|
||||
"password": public.password_salt(public.md5(args.password.strip()),username=args.username.strip())
|
||||
}
|
||||
|
||||
if(public.M('users').where('username=?',(pdata['username'],)).count()):
|
||||
return public.returnMsg(False,'The specified username already exists!')
|
||||
return public.returnMsg(False,'USERNAME_EXIST')
|
||||
|
||||
if(public.M('users').insert(pdata)):
|
||||
public.WriteLog('User Management','Create new user {}'.format(pdata['username']))
|
||||
return public.returnMsg(True,'Create new user {} success!'.format(pdata['username']))
|
||||
return public.returnMsg(False,'Create new user failed!')
|
||||
public.WriteLog('USER_MANAGE','CREATE_USER',(pdata['username'],))
|
||||
return public.returnMsg(True,'CREATE_USER_SUCCESS',(pdata['username'],))
|
||||
return public.returnMsg(False,'CREATE_USER_FAILED')
|
||||
|
||||
# 删除用户
|
||||
def remove_user(self,args):
|
||||
if session['uid'] != 1: return public.returnMsg(False,'Permission denied!')
|
||||
if int(args.id) == 1: return public.returnMsg(False,'Cannot delete initial default user!')
|
||||
if session['uid'] != 1: return public.returnMsg(False,'PERMISSION_DENIED')
|
||||
if int(args.id) == 1: return public.returnMsg(False,'DEL_USER_ERR')
|
||||
username = public.M('users').where('id=?',(args.id,)).getField('username')
|
||||
if not username: return public.returnMsg(False,'The specified user does not exist!')
|
||||
if not username: return public.returnMsg(False,'USERNAME_NOT_EXIST')
|
||||
if(public.M('users').where('id=?',(args.id,)).delete()):
|
||||
public.WriteLog('User Management','delete users[{}]'.format(username))
|
||||
return public.returnMsg(True,'Delete user {} success!'.format(username))
|
||||
return public.returnMsg(False,'User deletion failed!')
|
||||
public.WriteLog('USER_MANAGE','DEL_USER',(username))
|
||||
return public.returnMsg(True,'DEL_USER_SUCCESS',(username,))
|
||||
return public.returnMsg(False,'DEL_USER_FAILED')
|
||||
|
||||
# 修改用户
|
||||
def modify_user(self,args):
|
||||
if session['uid'] != 1: return public.returnMsg(False,'Permission denied!')
|
||||
if session['uid'] != 1: return public.returnMsg(False,'PERMISSION_DENIED')
|
||||
username = public.M('users').where('id=?',(args.id,)).getField('username')
|
||||
pdata = {}
|
||||
if 'username' in args:
|
||||
if len(args.username) < 2: return public.returnMsg(False,'User name must be at least 2 characters')
|
||||
if len(args.username) < 2: return public.returnMsg(False,'USERNAME_ERR')
|
||||
pdata['username'] = args.username.strip()
|
||||
|
||||
if 'password' in args:
|
||||
if args.password:
|
||||
if len(args.password) < 8: return public.returnMsg(False,'Password must be at least 8 characters')
|
||||
if len(args.password) < 8: return public.returnMsg(False,'PASSWORD_ERR')
|
||||
pdata['password'] = public.password_salt(public.md5(args.password.strip()),username=username)
|
||||
|
||||
if(public.M('users').where('id=?',(args.id,)).update(pdata)):
|
||||
public.WriteLog('User Management',"Edit user{}".format(username))
|
||||
return public.returnMsg(True,'Successfully modified!')
|
||||
return public.returnMsg(False,'No changes submitted!')
|
||||
public.WriteLog('USER_MANAGE',"EDIT_USER",(username,))
|
||||
return public.returnMsg(True,'EDIT_SUCCESS')
|
||||
return public.returnMsg(False,'NO_CHANGE_SUBMITTED')
|
||||
|
||||
def setPanel(self,get):
|
||||
if not public.IsRestart(): return public.returnMsg(False,'EXEC_ERR_TASK')
|
||||
@@ -522,6 +522,9 @@ class config:
|
||||
rep = r"\s*pm\s*=\s*(\w+)\s*"
|
||||
tmp = re.search(rep, conf).groups()
|
||||
data['pm'] = tmp[0]
|
||||
data['unix'] = 'unix'
|
||||
if not isinstance(public.get_fpm_address(version),str):
|
||||
data['unix'] = 'tcp'
|
||||
|
||||
return data
|
||||
|
||||
@@ -535,7 +538,7 @@ class config:
|
||||
max_spare_servers = get.max_spare_servers
|
||||
pm = get.pm
|
||||
if not pm in ['static','dynamic','ondemand']:
|
||||
return public.returnMsg(False,'Wrong operating mode!')
|
||||
return public.returnMsg(False,'WRONG_MODE')
|
||||
file = public.GetConfigValue('setup_path')+"/php/"+version+"/etc/php-fpm.conf"
|
||||
conf = public.readFile(file)
|
||||
|
||||
@@ -558,8 +561,18 @@ class config:
|
||||
rep = r"\s*listen\.backlog\s*=\s*([0-9-]+)\s*"
|
||||
conf = re.sub(rep, "\nlisten.backlog = 8192\n", conf)
|
||||
|
||||
if get.listen == 'unix':
|
||||
listen = '/tmp/php-cgi-{}.sock'.format(version)
|
||||
else:
|
||||
listen = '127.0.0.1:10{}1'.format(version)
|
||||
|
||||
|
||||
rep = r'\s*listen\s*=\s*.+\s*'
|
||||
conf = re.sub(rep, "\nlisten = "+listen+"\n", conf)
|
||||
|
||||
public.writeFile(file,conf)
|
||||
public.phpReload(version)
|
||||
public.sync_php_address(version)
|
||||
public.WriteLog("TYPE_PHP",'PHP_CHILDREN', (version,max_children,start_servers,min_spare_servers,max_spare_servers))
|
||||
return public.returnMsg(True, 'SET_SUCCESS')
|
||||
|
||||
@@ -686,7 +699,7 @@ class config:
|
||||
#rep_mail = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$"
|
||||
rep_mail = r"[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?"
|
||||
if not re.search(rep_mail,get.email):
|
||||
return public.returnMsg(False,'The E-Mail format is illegal')
|
||||
return public.returnMsg(False,'EMAIL_FORMAT_ERR')
|
||||
import setPanelLets
|
||||
sp = setPanelLets.setPanelLets()
|
||||
sps = sp.set_lets(get)
|
||||
@@ -875,7 +888,7 @@ class config:
|
||||
continue
|
||||
if not os.path.exists(p):
|
||||
continue
|
||||
phpini = public.readFile(filename)
|
||||
phpini = public.readFile(p)
|
||||
for g in gets:
|
||||
try:
|
||||
rep = g + r'\s*=\s*(.+)\r?\n'
|
||||
@@ -946,7 +959,7 @@ class config:
|
||||
return public.returnMsg(False, 'SPECIAL_CHARACTRES', ('" ~ ` / = "'))
|
||||
filename = '/www/server/php/' + get.version + '/etc/php.ini'
|
||||
filename_ols = None
|
||||
if os.path.exists("/usr/local/lsws"):
|
||||
if os.path.exists("/usr/local/lsws/bin/lswsctrl"):
|
||||
filename_ols = '/usr/local/lsws/lsphp{}/etc/php/{}.{}/litespeed/php.ini'.format(get.version, get.version[0],
|
||||
get.version[1])
|
||||
if os.path.exists('/etc/redhat-release'):
|
||||
@@ -958,6 +971,8 @@ class config:
|
||||
if os.path.exists("/etc/redhat-release"):
|
||||
ols_php_os_path = '/usr/local/lsws/lsphp{}/lib64/php/modules/'.format(get.version)
|
||||
ols_so_list = os.listdir(ols_php_os_path)
|
||||
else:
|
||||
ols_so_list = []
|
||||
for f in [filename,filename_ols]:
|
||||
if not f:
|
||||
continue
|
||||
@@ -1075,8 +1090,11 @@ class config:
|
||||
def get_config(self,get):
|
||||
if 'config' in session:
|
||||
session['config']['distribution'] = public.get_linux_distribution()
|
||||
session['webserver'] = public.get_webserver()
|
||||
session['config']['webserver'] = session['webserver']
|
||||
return session['config']
|
||||
data = public.M('config').where("id=?",('1',)).field('webserver,sites_path,backup_path,status,mysql_root').find()
|
||||
data['webserver'] = public.get_webserver()
|
||||
data['distribution'] = public.get_linux_distribution()
|
||||
return data
|
||||
|
||||
@@ -1186,7 +1204,7 @@ class config:
|
||||
import panelSite
|
||||
php_versions = panelSite.panelSite().GetPHPVersion(get)
|
||||
if len(php_versions)==0:
|
||||
return public.returnMsg(False,'Failed to get php version!')
|
||||
return public.returnMsg(False,'GET_PHP_VER_ERR')
|
||||
del(php_versions[0])
|
||||
for v in php_versions:
|
||||
if link_re.find(v['version']) != -1: return {"select":v,"versions":php_versions}
|
||||
@@ -1287,9 +1305,9 @@ class config:
|
||||
else:
|
||||
t_str = 'Open'
|
||||
public.writeFile(debug_path,'True')
|
||||
public.WriteLog('TYPE_PANEL','%s Developer mode(debug)' % t_str)
|
||||
public.WriteLog('TYPE_PANEL','DEVELOPER_MODE',(t_str,))
|
||||
public.restart_panel()
|
||||
return public.returnMsg(True,'Successful setup!')
|
||||
return public.returnMsg(True,'SET_SUCCESS')
|
||||
|
||||
|
||||
#设置离线模式
|
||||
@@ -1301,8 +1319,8 @@ class config:
|
||||
else:
|
||||
t_str = 'Open'
|
||||
public.writeFile(d_path,'True')
|
||||
public.WriteLog('TYPE_PANEL','%s Offline mode' % t_str)
|
||||
return public.returnMsg(True,'Successful setup!')
|
||||
public.WriteLog('TYPE_PANEL','OFFLINE_MODE',(t_str,))
|
||||
return public.returnMsg(True,'SET_SUCCESS')
|
||||
|
||||
# 修改.user.ini文件
|
||||
def _edit_user_ini(self,file,s_conf,act,session_path):
|
||||
@@ -1330,12 +1348,13 @@ class config:
|
||||
:return:
|
||||
'''
|
||||
if public.get_webserver() == 'openlitespeed':
|
||||
return public.returnMsg(False, "This feature does not currently support openlitespeed")
|
||||
return public.returnMsg(False, "NOT_SUPPORT_OLS")
|
||||
import panelSite
|
||||
site_info = public.M('sites').where('id=?', (get.id,)).field('name,path').find()
|
||||
session_path = "/www/php_session/{}".format(site_info["name"])
|
||||
if os.path.exists(session_path):
|
||||
if not os.path.exists(session_path):
|
||||
os.makedirs(session_path)
|
||||
public.ExecShell('chown www.www {}'.format(session_path))
|
||||
run_path = panelSite.panelSite().GetSiteRunPath(get)["runPath"]
|
||||
user_ini_file = "{site_path}{run_path}/.user.ini".format(site_path=site_info["path"], run_path=run_path)
|
||||
conf = "session.save_path={}/\nsession.save_handler = files".format(session_path)
|
||||
@@ -1343,12 +1362,12 @@ class config:
|
||||
if not os.path.exists(user_ini_file):
|
||||
public.writeFile(user_ini_file,conf)
|
||||
public.ExecShell("chattr +i {}".format(user_ini_file))
|
||||
return public.returnMsg(True,"Successful setup")
|
||||
return public.returnMsg(True,"SET_SUCCESS")
|
||||
self._edit_user_ini(user_ini_file,conf,get.act,session_path)
|
||||
return public.returnMsg(True, "Successful setup")
|
||||
return public.returnMsg(True, "SET_SUCCESS")
|
||||
else:
|
||||
self._edit_user_ini(user_ini_file,conf,get.act,session_path)
|
||||
return public.returnMsg(True, "Successful setup")
|
||||
return public.returnMsg(True, "SET_SUCCESS")
|
||||
|
||||
# 获取php_session是否存放到独立文件夹
|
||||
def get_php_session_path(self,get):
|
||||
@@ -1371,9 +1390,9 @@ class config:
|
||||
key = public.readFile(self._key_file)
|
||||
username = public.readFile(self._username_file)
|
||||
if not key:
|
||||
return public.returnMsg(False, "The key does not exist. Please turn on and try again.")
|
||||
return public.returnMsg(False, "KEY_NOT_EXIST")
|
||||
if not username:
|
||||
return public.returnMsg(False, "The username does not exist. Please turn on and try again.")
|
||||
return public.returnMsg(False, "USERNAME_NOT_EXIST1")
|
||||
return {"key":key,"username":username}
|
||||
|
||||
def get_random(self):
|
||||
@@ -1387,7 +1406,7 @@ class config:
|
||||
|
||||
def set_two_step_auth(self,get):
|
||||
if not hasattr(get,"act") or not get.act:
|
||||
return public.returnMsg(False, "Please enter the operation mode")
|
||||
return public.returnMsg(False, "SELECT_MODE")
|
||||
if get.act == "1":
|
||||
if not os.path.exists(self._core_fle_path):
|
||||
os.makedirs(self._core_fle_path)
|
||||
@@ -1402,37 +1421,264 @@ class config:
|
||||
username = public.readFile(self._username_file)
|
||||
local_ip = public.GetLocalIp()
|
||||
if not secret_key:
|
||||
return public.returnMsg(False,"Failed to generate key or username. Please check if the hard disk space is insufficient or the directory cannot be written.[ {} ]".format(self._setup_path+"/data/"))
|
||||
return public.returnMsg(False,"GENERATE_KEY_ERR",(self._setup_path+"/data/",))
|
||||
try:
|
||||
data = pyotp.totp.TOTP(secret_key).provisioning_uri(username, issuer_name=local_ip)
|
||||
try:
|
||||
panel_name = json.loads(public.readFile(self._setup_path+'/config/config.json'))['title']
|
||||
except:
|
||||
panel_name = 'aaPanel'
|
||||
data = pyotp.totp.TOTP(secret_key).provisioning_uri(username, issuer_name='{}--{}'.format(panel_name,local_ip))
|
||||
public.writeFile(self._core_fle_path+'/qrcode.txt',str(data))
|
||||
return public.returnMsg(True, "Open successfully")
|
||||
return public.returnMsg(True, "OPEN_SUCCESSFUL")
|
||||
except Exception as e:
|
||||
return public.returnMsg(False, e)
|
||||
else:
|
||||
if os.path.exists(self._key_file):
|
||||
os.rename(self._key_file,self._bk_key_file)
|
||||
return public.returnMsg(True, "Closed successfully")
|
||||
return public.returnMsg(True, "CLOSE_SUCCESS")
|
||||
|
||||
# 检测是否开启双因素验证
|
||||
def check_two_step(self,get):
|
||||
secret_key = public.readFile(self._key_file)
|
||||
if not secret_key:
|
||||
return public.returnMsg(False, "Did not open Google authentication")
|
||||
return public.returnMsg(True, "Google authentication has been turned on")
|
||||
return public.returnMsg(False, "GOOGLE_AUTH_ERR")
|
||||
return public.returnMsg(True, "TURN_ON_GOOGLE_AUTH")
|
||||
|
||||
# 读取二维码data
|
||||
def get_qrcode_data(self,get):
|
||||
data = public.readFile(self._core_fle_path + '/qrcode.txt')
|
||||
if data:
|
||||
return data
|
||||
return public.returnMsg(True, "No QR code data, please re-open")
|
||||
return public.returnMsg(True, "QR_CODE_ERR")
|
||||
|
||||
# 设置是否云控打开
|
||||
def set_coll_open(self,get):
|
||||
if not 'coll_show' in get: return public.returnMsg(False,'Parameter error!')
|
||||
if not 'coll_show' in get: return public.returnMsg(False,'INIT_ARGS_ERR')
|
||||
if get.coll_show == 'True':
|
||||
session['tmp_login'] = True
|
||||
else:
|
||||
session['tmp_login'] = False
|
||||
return public.returnMsg(True,'Successful setup!')
|
||||
return public.returnMsg(True,'SET_SUCCESS')
|
||||
|
||||
# 获取菜单列表
|
||||
def get_menu_list(self, get):
|
||||
'''
|
||||
@name 获取菜单列表
|
||||
@author hwliang<2020-08-31>
|
||||
@param get<dict_obj>
|
||||
@return list
|
||||
'''
|
||||
menu_file = 'config/menu.json'
|
||||
hide_menu_file = 'config/hide_menu.json'
|
||||
data = json.loads(public.ReadFile(menu_file))
|
||||
if not os.path.exists(hide_menu_file):
|
||||
public.writeFile(hide_menu_file, '[]')
|
||||
hide_menu = public.ReadFile(hide_menu_file)
|
||||
if not hide_menu:
|
||||
hide_menu = []
|
||||
else:
|
||||
hide_menu = json.loads(hide_menu)
|
||||
result = []
|
||||
for d in data:
|
||||
tmp = {}
|
||||
tmp['id'] = d['id']
|
||||
tmp['title'] = d['title']
|
||||
tmp['show'] = not d['id'] in hide_menu
|
||||
tmp['sort'] = d['sort']
|
||||
result.append(tmp)
|
||||
|
||||
menus = sorted(result, key=lambda x: x['sort'])
|
||||
return menus
|
||||
|
||||
# 设置隐藏菜单列表
|
||||
def set_hide_menu_list(self, get):
|
||||
'''
|
||||
@name 设置隐藏菜单列表
|
||||
@author hwliang<2020-08-31>
|
||||
@param get<dict_obj> {
|
||||
hide_list: json<list> 所有不显示的菜单ID
|
||||
}
|
||||
@return dict
|
||||
'''
|
||||
hide_menu_file = 'config/hide_menu.json'
|
||||
not_hide_id = ["dologin", "memuAconfig", "memuAsoft", "memuA"] # 禁止隐藏的菜单
|
||||
|
||||
hide_list = json.loads(get.hide_list)
|
||||
hide_menu = []
|
||||
for h in hide_list:
|
||||
if h in not_hide_id: continue
|
||||
hide_menu.append(h)
|
||||
public.writeFile(hide_menu_file, json.dumps(hide_menu))
|
||||
public.WriteLog('TYPE_CONFIG', 'EDIT_MENU_SUCCESS')
|
||||
return public.returnMsg(True, 'SET_SUCCESS')
|
||||
|
||||
# 获取临时登录列表
|
||||
def get_temp_login(self, args):
|
||||
'''
|
||||
@name 获取临时登录列表
|
||||
@author hwliang<2020-09-2>
|
||||
@return dict
|
||||
'''
|
||||
if 'tmp_login_expire' in session: return public.returnMsg(False, 'PERMISSION_DENIED')
|
||||
public.M('temp_login').where('state=? and expire<?', (0, int(time.time()))).setField('state', -1)
|
||||
callback = ''
|
||||
if 'tojs' in args:
|
||||
callback = args.tojs
|
||||
p = 1
|
||||
if 'p' in args:
|
||||
p = int(args.p)
|
||||
rows = 12
|
||||
if 'rows' in args:
|
||||
rows = int(args.rows)
|
||||
count = public.M('temp_login').count()
|
||||
data = {}
|
||||
page_data = public.get_page(count, p, rows, callback)
|
||||
data['page'] = page_data['page']
|
||||
data['data'] = public.M('temp_login').limit(page_data['shift'] + ',' + page_data['row']).order('id desc').field(
|
||||
'id,addtime,expire,login_time,login_addr,state').select()
|
||||
for i in range(len(data['data'])):
|
||||
data['data'][i]['online_state'] = os.path.exists('data/session/{}'.format(data['data'][i]['id']))
|
||||
return data
|
||||
|
||||
# 设置临时登录
|
||||
def set_temp_login(self, args):
|
||||
'''
|
||||
@name 设置临时登录
|
||||
@author hwliang<2020-09-2>
|
||||
@return dict
|
||||
'''
|
||||
if 'tmp_login_expire' in session: return public.returnMsg(False, 'PERMISSION_DENIED')
|
||||
s_time = int(time.time())
|
||||
public.M('temp_login').where('state=? and expire>?', (0, s_time)).delete()
|
||||
token = public.GetRandomString(48)
|
||||
salt = public.GetRandomString(12)
|
||||
|
||||
pdata = {
|
||||
'token': public.md5(token + salt),
|
||||
'salt': salt,
|
||||
'state': 0,
|
||||
'login_time': 0,
|
||||
'login_addr': '',
|
||||
'expire': s_time + 3600,
|
||||
'addtime': s_time
|
||||
}
|
||||
|
||||
if not public.M('temp_login').count():
|
||||
pdata['id'] = 101
|
||||
|
||||
if public.M('temp_login').insert(pdata):
|
||||
public.WriteLog('TYPE_CONFIG', 'TMP_LOGIN',(public.format_date(times=pdata['expire']),))
|
||||
return {'status': True, 'msg': public.getMsg('TMP_LOGIN1'), 'token': token, 'expire': pdata['expire']}
|
||||
return public.returnMsg(False, 'TMP_LOGIN2')
|
||||
|
||||
# 删除临时登录
|
||||
def remove_temp_login(self, args):
|
||||
'''
|
||||
@name 删除临时登录
|
||||
@author hwliang<2020-09-2>
|
||||
@param args<dict_obj>{
|
||||
id: int<临时登录ID>
|
||||
}
|
||||
@return dict
|
||||
'''
|
||||
if 'tmp_login_expire' in session: return public.returnMsg(False, 'PERMISSION_DENIED')
|
||||
id = int(args.id)
|
||||
if public.M('temp_login').where('id=?', (id,)).delete():
|
||||
public.WriteLog('TYPE_CONFIG', 'TMP_LOGIN3')
|
||||
return public.returnMsg(True, 'DEL_SUCCESS')
|
||||
return public.returnMsg(False, 'DEL_ERROR')
|
||||
|
||||
# 强制弹出指定临时登录
|
||||
def clear_temp_login(self, args):
|
||||
'''
|
||||
@name 强制登出
|
||||
@author hwliang<2020-09-2>
|
||||
@param args<dict_obj>{
|
||||
id: int<临时登录ID>
|
||||
}
|
||||
@return dict
|
||||
'''
|
||||
if 'tmp_login_expire' in session: return public.returnMsg(False, 'PERMISSION_DENIED')
|
||||
id = int(args.id)
|
||||
s_file = 'data/session/{}'.format(id)
|
||||
if os.path.exists(s_file):
|
||||
os.remove(s_file)
|
||||
public.WriteLog('TYPE_CONFIG', 'LOGOUT_TMP_UESR',(str(id),))
|
||||
return public.returnMsg(True, 'LOGOUT_TMP_USER',(str(id),))
|
||||
public.returnMsg(False, 'TMP_USER_NOT_LOGIN')
|
||||
|
||||
# 查看临时授权操作日志
|
||||
def get_temp_login_logs(self, args):
|
||||
'''
|
||||
@name 查看临时授权操作日志
|
||||
@author hwliang<2020-09-2>
|
||||
@param args<dict_obj>{
|
||||
id: int<临时登录ID>
|
||||
}
|
||||
@return dict
|
||||
'''
|
||||
if 'tmp_login_expire' in session: return public.returnMsg(False, 'PERMISSION_DENIED')
|
||||
id = int(args.id)
|
||||
data = public.M('logs').where('uid=?', (id,)).order('id desc').select()
|
||||
return data
|
||||
|
||||
def add_nginx_access_log_format(self,args):
|
||||
n = nginx.nginx()
|
||||
return n.add_nginx_access_log_format(args)
|
||||
|
||||
def del_nginx_access_log_format(self,args):
|
||||
n = nginx.nginx()
|
||||
return n.del_nginx_access_log_format(args)
|
||||
|
||||
def get_nginx_access_log_format(self,args):
|
||||
n = nginx.nginx()
|
||||
return n.get_nginx_access_log_format(args)
|
||||
|
||||
def set_format_log_to_website(self,args):
|
||||
n = nginx.nginx()
|
||||
return n.set_format_log_to_website(args)
|
||||
|
||||
def get_nginx_access_log_format_parameter(self,args):
|
||||
n = nginx.nginx()
|
||||
return n.get_nginx_access_log_format_parameter(args)
|
||||
|
||||
def add_httpd_access_log_format(self,args):
|
||||
a = apache.apache()
|
||||
return a.add_httpd_access_log_format(args)
|
||||
|
||||
def del_httpd_access_log_format(self,args):
|
||||
a = apache.apache()
|
||||
return a.del_httpd_access_log_format(args)
|
||||
|
||||
def get_httpd_access_log_format(self,args):
|
||||
a = apache.apache()
|
||||
return a.get_httpd_access_log_format(args)
|
||||
|
||||
def set_httpd_format_log_to_website(self,args):
|
||||
a = apache.apache()
|
||||
return a.set_httpd_format_log_to_website(args)
|
||||
|
||||
def get_httpd_access_log_format_parameter(self,args):
|
||||
a = apache.apache()
|
||||
return a.get_httpd_access_log_format_parameter(args)
|
||||
|
||||
def get_file_deny(self,args):
|
||||
import file_execute_deny
|
||||
p = file_execute_deny.FileExecuteDeny()
|
||||
return p.get_file_deny(args)
|
||||
|
||||
def set_file_deny(self,args):
|
||||
import file_execute_deny
|
||||
p = file_execute_deny.FileExecuteDeny()
|
||||
return p.set_file_deny(args)
|
||||
|
||||
def del_file_deny(self,args):
|
||||
import file_execute_deny
|
||||
p = file_execute_deny.FileExecuteDeny()
|
||||
return p.del_file_deny(args)
|
||||
|
||||
def get_panel_ssl_status(self,get):
|
||||
import os
|
||||
if os.path.exists('/www/server/panel/data/ssl.pl'):
|
||||
return public.returnMsg(True,'success')
|
||||
return public.returnMsg(False,'false')
|
||||
@@ -27,6 +27,7 @@ class crontab:
|
||||
|
||||
data=[]
|
||||
for i in range(len(cront)):
|
||||
tmp = {}
|
||||
tmp=cront[i]
|
||||
if cront[i]['type']=="day":
|
||||
tmp['type']=public.getMsg('CRONTAB_TODAY')
|
||||
@@ -50,6 +51,10 @@ class crontab:
|
||||
elif cront[i]['type']=="month":
|
||||
tmp['type']=public.getMsg('CRONTAB_MONTH')
|
||||
tmp['cycle']=public.getMsg('CRONTAB_MONTH_CYCLE',(str(cront[i]['where1']),str(cront[i]['where_hour']),str(cront[i]['where_minute'])))
|
||||
|
||||
log_file = '/www/server/cron/{}.log'.format(tmp['echo'])
|
||||
if os.path.exists(log_file):
|
||||
tmp['addtime'] = public.format_date(times=int(os.path.getmtime(log_file)))
|
||||
data.append(tmp)
|
||||
return data
|
||||
|
||||
@@ -196,7 +201,9 @@ class crontab:
|
||||
(get['name'],get['type'],get['where1'],get['hour'],get['minute'],cronName,time.strftime('%Y-%m-%d %X',time.localtime()),1,get['save'],get['backupTo'],get['sType'],get['sName'],get['sBody'],get['urladdress'])
|
||||
)
|
||||
if addData>0:
|
||||
return public.returnMsg(True,'ADD_SUCCESS')
|
||||
result = public.returnMsg(True,'ADD_SUCCESS')
|
||||
result['id'] = addData
|
||||
return result
|
||||
return public.returnMsg(False,'ADD_ERROR')
|
||||
|
||||
#构造周期
|
||||
@@ -316,12 +323,15 @@ class crontab:
|
||||
|
||||
#从crond删除
|
||||
def remove_for_crond(self,echo):
|
||||
u_file = '/var/spool/cron/crontabs/root'
|
||||
file = self.get_cron_file()
|
||||
conf=public.readFile(file)
|
||||
if conf.find(str(echo)) == -1: return True
|
||||
rep = ".+" + str(echo) + ".+\n"
|
||||
conf = re.sub(rep, "", conf)
|
||||
if not public.writeFile(file,conf): return False
|
||||
try:
|
||||
if not public.writeFile(file,conf): return False
|
||||
except:
|
||||
return False
|
||||
self.CrondReload()
|
||||
return True
|
||||
|
||||
@@ -333,8 +343,7 @@ class crontab:
|
||||
shell=param.sFile
|
||||
else :
|
||||
head="#!/bin/bash\nPATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin\nexport PATH\n"
|
||||
|
||||
python_bin = public.get_python_bin()
|
||||
python_bin = "{} -u".format(public.get_python_bin())
|
||||
if public.get_webserver()=='nginx':
|
||||
log='.log'
|
||||
elif public.get_webserver()=='apache':
|
||||
@@ -439,10 +448,11 @@ echo "--------------------------------------------------------------------------
|
||||
cron_path = c_file
|
||||
if not os.path.exists(u_path):
|
||||
cron_path=c_file
|
||||
if os.path.exists('/usr/bin/yum'):
|
||||
cron_path = c_file
|
||||
elif os.path.exists("/usr/bin/apt-get"):
|
||||
|
||||
if os.path.exists("/usr/bin/apt-get"):
|
||||
cron_path = u_file
|
||||
elif os.path.exists('/usr/bin/yum'):
|
||||
cron_path = c_file
|
||||
|
||||
if cron_path == u_file:
|
||||
if not os.path.exists(u_path):
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
import os, json, sys, time
|
||||
|
||||
os.chdir("/www/server/panel")
|
||||
sys.path.append("class/")
|
||||
if not 'class/' in sys.path:
|
||||
sys.path.insert(0,'class/')
|
||||
import public
|
||||
|
||||
sys.path.append(".")
|
||||
|
||||
@@ -7,12 +7,16 @@
|
||||
# | Author: hwliang <hwl@bt.cn>
|
||||
# +-------------------------------------------------------------------
|
||||
import sys,os,re,time
|
||||
sys.path.append("class/")
|
||||
import db,public
|
||||
if not 'class/' in sys.path:
|
||||
sys.path.insert(0,'class/')
|
||||
import db,public,panelMysql
|
||||
import json
|
||||
|
||||
class data:
|
||||
__ERROR_COUNT = 0
|
||||
DB_MySQL = None
|
||||
web_server = None
|
||||
setupPath = '/www/server'
|
||||
'''
|
||||
* 设置备注信息
|
||||
* @param String _GET['tab'] 数据库表名
|
||||
@@ -44,6 +48,55 @@ class data:
|
||||
if temp['local']: result +=2
|
||||
return result
|
||||
|
||||
# 转换时间
|
||||
def strf_date(self, sdate):
|
||||
return time.strftime('%Y-%m-%d', time.strptime(sdate, '%Y%m%d%H%M%S'))
|
||||
|
||||
def get_cert_end(self,pem_file):
|
||||
try:
|
||||
import OpenSSL
|
||||
result = {}
|
||||
x509 = OpenSSL.crypto.load_certificate(
|
||||
OpenSSL.crypto.FILETYPE_PEM, public.readFile(pem_file))
|
||||
# 取产品名称
|
||||
issuer = x509.get_issuer()
|
||||
result['issuer'] = ''
|
||||
if hasattr(issuer, 'CN'):
|
||||
result['issuer'] = issuer.CN
|
||||
if not result['issuer']:
|
||||
is_key = [b'0', '0']
|
||||
issue_comp = issuer.get_components()
|
||||
if len(issue_comp) == 1:
|
||||
is_key = [b'CN', 'CN']
|
||||
for iss in issue_comp:
|
||||
if iss[0] in is_key:
|
||||
result['issuer'] = iss[1].decode()
|
||||
break
|
||||
# 取到期时间
|
||||
result['notAfter'] = self.strf_date(
|
||||
bytes.decode(x509.get_notAfter())[:-1])
|
||||
# 取申请时间
|
||||
result['notBefore'] = self.strf_date(
|
||||
bytes.decode(x509.get_notBefore())[:-1])
|
||||
# 取可选名称
|
||||
result['dns'] = []
|
||||
for i in range(x509.get_extension_count()):
|
||||
s_name = x509.get_extension(i)
|
||||
if s_name.get_short_name() in [b'subjectAltName', 'subjectAltName']:
|
||||
s_dns = str(s_name).split(',')
|
||||
for d in s_dns:
|
||||
result['dns'].append(d.split(':')[1])
|
||||
subject = x509.get_subject().get_components()
|
||||
# 取主要认证名称
|
||||
if len(subject) == 1:
|
||||
result['subject'] = subject[0][1].decode()
|
||||
else:
|
||||
result['subject'] = result['dns'][0]
|
||||
return result
|
||||
except:
|
||||
return public.get_cert_data(pem_file)
|
||||
|
||||
|
||||
def get_site_ssl_info(self,siteName):
|
||||
try:
|
||||
s_file = 'vhost/nginx/{}.conf'.format(siteName)
|
||||
@@ -70,14 +123,51 @@ class data:
|
||||
s_tmp = re.findall(r"ssl_certificate\s+(.+\.pem);",s_conf)
|
||||
if not s_tmp: return -1
|
||||
ssl_file = s_tmp[0]
|
||||
ssl_info = public.get_cert_data(ssl_file)
|
||||
ssl_info = self.get_cert_end(ssl_file)
|
||||
if not ssl_info: return -1
|
||||
ssl_info['endtime'] = int(int(time.mktime(time.strptime(ssl_info['notAfter'], "%Y-%m-%d")) - time.time()) / 86400)
|
||||
return ssl_info
|
||||
except: return -1
|
||||
#return "{}:{}".format(ssl_info['issuer'],ssl_info['notAfter'])
|
||||
|
||||
def get_php_version(self,siteName):
|
||||
try:
|
||||
|
||||
if not self.web_server:
|
||||
self.web_server = public.get_webserver()
|
||||
|
||||
conf = public.readFile(self.setupPath + '/panel/vhost/'+self.web_server+'/'+siteName+'.conf')
|
||||
if self.web_server == 'openlitespeed':
|
||||
conf = public.readFile(
|
||||
self.setupPath + '/panel/vhost/' + self.web_server + '/detail/' + siteName + '.conf')
|
||||
if self.web_server == 'nginx':
|
||||
rep = r"enable-php-([0-9]{2,3})\.conf"
|
||||
elif self.web_server == 'apache':
|
||||
rep = r"php-cgi-([0-9]{2,3})\.sock"
|
||||
else:
|
||||
rep = r"path\s*/usr/local/lsws/lsphp(\d+)/bin/lsphp"
|
||||
tmp = re.search(rep,conf).groups()
|
||||
if tmp[0] == '00':
|
||||
return 'Static'
|
||||
|
||||
return tmp[0][0] + '.' + tmp[0][1]
|
||||
except:
|
||||
return 'Static'
|
||||
|
||||
def map_to_list(self,map_obj):
|
||||
try:
|
||||
if type(map_obj) != list and type(map_obj) != str: map_obj = list(map_obj)
|
||||
return map_obj
|
||||
except: return []
|
||||
|
||||
def get_database_size(self,databaseName):
|
||||
try:
|
||||
if not self.DB_MySQL:self.DB_MySQL = panelMysql.panelMysql()
|
||||
db_size = self.map_to_list(self.DB_MySQL.query("select sum(DATA_LENGTH)+sum(INDEX_LENGTH) from information_schema.tables where table_schema='{}'".format(databaseName)))[0][0]
|
||||
if not db_size: return 0
|
||||
return int(db_size)
|
||||
except:
|
||||
return 0
|
||||
|
||||
|
||||
'''
|
||||
@@ -108,6 +198,7 @@ class data:
|
||||
for i in range(len(data['data'])):
|
||||
data['data'][i]['domain'] = SQL.table('domain').where("pid=?",(data['data'][i]['id'],)).count()
|
||||
data['data'][i]['ssl'] = self.get_site_ssl_info(data['data'][i]['name'])
|
||||
data['data'][i]['php_version'] = self.get_php_version(data['data'][i]['name'])
|
||||
elif table == 'firewall':
|
||||
for i in range(len(data['data'])):
|
||||
if data['data'][i]['port'].find(':') != -1 or data['data'][i]['port'].find('.') != -1 or data['data'][i]['port'].find('-') != -1:
|
||||
|
||||