mirror of
https://github.com/flucont/btcloud.git
synced 2025-10-15 15:20:24 +00:00
Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
53a878def3 | ||
![]() |
b6350dbed8 | ||
![]() |
2c9f84c121 | ||
![]() |
ab81af3b94 |
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
Linux_Version="7.9.5"
|
||||
Windows_Version="7.7.0"
|
||||
Linux_Version="7.9.7"
|
||||
Windows_Version="7.8.0"
|
||||
|
||||
FILES=(
|
||||
public/install/src/panel6.zip
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -12,12 +12,12 @@ INSERT INTO `cloud_config` (`key`, `value`) VALUES
|
||||
('bt_key', ''),
|
||||
('whitelist', '0'),
|
||||
('download_page', '1'),
|
||||
('new_version', '7.9.5'),
|
||||
('new_version', '7.9.7'),
|
||||
('update_msg', '暂无更新日志'),
|
||||
('update_date', '2022-11-02'),
|
||||
('new_version_win', '7.7.0'),
|
||||
('update_date', '2022-12-21'),
|
||||
('new_version_win', '7.8.0'),
|
||||
('update_msg_win', '暂无更新日志'),
|
||||
('update_date_win', '2022-09-09'),
|
||||
('update_date_win', '2022-12-08'),
|
||||
('updateall_type', '0'),
|
||||
('syskey', 'UqP94LtI8eWAIgCP');
|
||||
|
||||
|
@@ -54,6 +54,27 @@ GetSysInfo(){
|
||||
echo -e ${SYS_VERSION}
|
||||
echo -e Bit:${SYS_BIT} Mem:${MEM_TOTAL}M Core:${CPU_INFO}
|
||||
echo -e ${SYS_INFO}
|
||||
|
||||
if [ -z "${os_version}" ];then
|
||||
echo -e "============================================"
|
||||
echo -e "检测到为非常用系统安装,建议更换至Centos-7或Debian-10+或Ubuntu-20+系统安装宝塔面板"
|
||||
echo -e "详情请查看系统兼容表:https://docs.qq.com/sheet/DUm54VUtyTVNlc21H?tab=BB08J2"
|
||||
echo -e "特殊情况可通过以下联系方式寻求安装协助情况"
|
||||
fi
|
||||
|
||||
is64bit=$(getconf LONG_BIT)
|
||||
if [ "${is64bit}" == '32' ];then
|
||||
echo -e "宝塔面板不支持32位系统进行安装,请使用64位系统/服务器架构进行安装宝塔"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
S390X_CHECK=$(uname -a|grep s390x)
|
||||
if [ "${S390X_CHECK}" ];then
|
||||
echo -e "宝塔面板不支持s390x架构进行安装,请使用64位系统/服务器架构进行安装宝塔"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "============================================"
|
||||
echo -e "请截图以上报错信息发帖至论坛www.bt.cn/bbs求助"
|
||||
}
|
||||
Red_Error(){
|
||||
@@ -97,6 +118,33 @@ System_Check(){
|
||||
Install_Check
|
||||
fi
|
||||
}
|
||||
Set_Ssl(){
|
||||
echo -e ""
|
||||
echo -e "----------------------------------------------------------------------"
|
||||
echo -e "为了您的面板使用安全,建议您开启面板SSL,开启后请使用https访问宝塔面板"
|
||||
echo -e "输入y回车即开启面板SSL并进行下一步安装"
|
||||
echo -e "输入n回车跳过面板SSL配置,直接进行安装"
|
||||
echo -e "10秒后将跳过SSL配置,直接进行面板安装"
|
||||
echo -e "----------------------------------------------------------------------"
|
||||
echo -e ""
|
||||
read -t 10 -p "是否确定开启面板SSL ? (y/n): " yes
|
||||
|
||||
if [ $? != 0 ];then
|
||||
SET_SSL=false
|
||||
else
|
||||
case "$yes" in
|
||||
y)
|
||||
SET_SSL=true
|
||||
;;
|
||||
n)
|
||||
SET_SSL=false
|
||||
rm -f /www/server/panel/data/ssl.pl
|
||||
;;
|
||||
*)
|
||||
Set_Ssl
|
||||
esac
|
||||
fi
|
||||
}
|
||||
Get_Pack_Manager(){
|
||||
if [ -f "/usr/bin/yum" ] && [ -d "/etc/yum.repos.d" ]; then
|
||||
PM="yum"
|
||||
@@ -183,7 +231,7 @@ get_node_url(){
|
||||
|
||||
echo '---------------------------------------------';
|
||||
echo "Selected download node...";
|
||||
nodes=(http://dg2.bt.cn http://dg1.bt.cn http://125.90.93.52:5880 http://36.133.1.8:5880 http://123.129.198.197 http://38.34.185.130 http://116.213.43.206:5880 http://128.1.164.196);
|
||||
nodes=(https://dg2.bt.cn https://dg1.bt.cn https://download.bt.cn);
|
||||
|
||||
if [ "$1" ];then
|
||||
nodes=($(echo ${nodes[*]}|sed "s#${1}##"))
|
||||
@@ -225,7 +273,7 @@ get_node_url(){
|
||||
if [ -z "$NODE_URL" ];then
|
||||
NODE_URL=$(cat $tmp_file2|sort -g -t " " -k 1|head -n 1|awk '{print $2}')
|
||||
if [ -z "$NODE_URL" ];then
|
||||
NODE_URL='http://download.bt.cn';
|
||||
NODE_URL='https://download.bt.cn';
|
||||
fi
|
||||
fi
|
||||
rm -f $tmp_file1
|
||||
@@ -426,7 +474,7 @@ Install_Python_Lib(){
|
||||
if [ "$is_package" = "" ];then
|
||||
wget -O $pyenv_path/pyenv/pip.txt $download_Url/install/pyenv/pip.txt -T 5
|
||||
$pyenv_path/pyenv/bin/pip install -U pip
|
||||
$pyenv_path/pyenv/bin/pip install -U setuptools
|
||||
$pyenv_path/pyenv/bin/pip install -U setuptools==65.5.0
|
||||
$pyenv_path/pyenv/bin/pip install -r $pyenv_path/pyenv/pip.txt
|
||||
fi
|
||||
source $pyenv_path/pyenv/bin/activate
|
||||
@@ -560,7 +608,7 @@ Install_Python_Lib(){
|
||||
ln -sf $pyenv_path/pyenv/bin/python3.7 /usr/bin/btpython
|
||||
chmod -R 700 $pyenv_path/pyenv/bin
|
||||
$pyenv_path/pyenv/bin/pip install -U pip
|
||||
$pyenv_path/pyenv/bin/pip install -U setuptools
|
||||
$pyenv_path/pyenv/bin/pip install -U setuptools==65.5.0
|
||||
$pyenv_path/pyenv/bin/pip install -U wheel==0.34.2
|
||||
$pyenv_path/pyenv/bin/pip install -r $pyenv_path/pyenv/pip.txt
|
||||
source $pyenv_path/pyenv/bin/activate
|
||||
@@ -576,10 +624,7 @@ Install_Bt(){
|
||||
if [ -f ${setup_path}/server/panel/data/port.pl ];then
|
||||
panelPort=$(cat ${setup_path}/server/panel/data/port.pl)
|
||||
else
|
||||
RE_NUM=$(expr $RANDOM % 3)
|
||||
if [ "${RE_NUM}" == "1" ];then
|
||||
panelPort=$(expr $RANDOM % 55535 + 10000)
|
||||
fi
|
||||
panelPort=$(expr $RANDOM % 55535 + 10000)
|
||||
fi
|
||||
mkdir -p ${setup_path}/server/panel/logs
|
||||
mkdir -p ${setup_path}/server/panel/vhost/apache
|
||||
@@ -680,6 +725,8 @@ Set_Bt_Panel(){
|
||||
auth_path=$(cat /dev/urandom | head -n 16 | md5sum | head -c 8)
|
||||
echo "/${auth_path}" > ${admin_auth}
|
||||
fi
|
||||
auth_path=$(cat /dev/urandom | head -n 16 | md5sum | head -c 8)
|
||||
echo "/${auth_path}" > ${admin_auth}
|
||||
chmod -R 700 $pyenv_path/pyenv/bin
|
||||
/www/server/panel/pyenv/bin/pip3 install pymongo
|
||||
/www/server/panel/pyenv/bin/pip3 install psycopg2-binary
|
||||
@@ -687,6 +734,10 @@ Set_Bt_Panel(){
|
||||
/www/server/panel/pyenv/bin/pip3 install flask-sock
|
||||
auth_path=$(cat ${admin_auth})
|
||||
cd ${setup_path}/server/panel/
|
||||
if [ "$SET_SSL" == true ]; then
|
||||
btpip install -I pyOpenSSl
|
||||
btpython /www/server/panel/tools.py ssl
|
||||
fi
|
||||
/etc/init.d/bt start
|
||||
$python_bin -m py_compile tools.py
|
||||
$python_bin tools.py username
|
||||
@@ -698,7 +749,7 @@ Set_Bt_Panel(){
|
||||
/etc/init.d/bt restart
|
||||
sleep 3
|
||||
isStart=$(ps aux |grep 'BT-Panel'|grep -v grep|awk '{print $2}')
|
||||
LOCAL_CURL=$(curl 127.0.0.1:8888/login 2>&1 |grep -i html)
|
||||
LOCAL_CURL=$(curl 127.0.0.1:${panelPort}/login 2>&1 |grep -i html)
|
||||
if [ -z "${isStart}" ] && [ -z "${LOCAL_CURL}" ];then
|
||||
/etc/init.d/bt 22
|
||||
cd /www/server/panel/pyenv/bin
|
||||
@@ -776,7 +827,6 @@ Get_Ip_Address(){
|
||||
isHosts=$(cat /etc/hosts|grep 'www.bt.cn')
|
||||
if [ -z "${isHosts}" ];then
|
||||
echo "" >> /etc/hosts
|
||||
echo "116.213.43.206 www.bt.cn" >> /etc/hosts
|
||||
getIpAddress=$(curl -sS --connect-timeout 10 -m 60 https://www.bt.cn/Api/getIpAddress)
|
||||
if [ -z "${getIpAddress}" ];then
|
||||
sed -i "/bt.cn/d" /etc/hosts
|
||||
@@ -812,6 +862,7 @@ Setup_Count(){
|
||||
echo /www > /var/bt_setupPath.conf
|
||||
}
|
||||
Install_Main(){
|
||||
#Set_Ssl
|
||||
startTime=`date +%s`
|
||||
Lock_Clear
|
||||
System_Check
|
||||
@@ -869,17 +920,28 @@ fi
|
||||
|
||||
Install_Main
|
||||
|
||||
PANEL_SSL=$(cat /www/server/panel/data/ssl.pl 2> /dev/null)
|
||||
if [ "${PANEL_SSL}" == "True" ];then
|
||||
HTTP_S="https"
|
||||
else
|
||||
HTTP_S="http"
|
||||
fi
|
||||
|
||||
echo > /www/server/panel/data/bind.pl
|
||||
echo -e "=================================================================="
|
||||
echo -e "\033[32mCongratulations! Installed successfully!\033[0m"
|
||||
echo -e "=================================================================="
|
||||
echo "外网面板地址: http://${getIpAddress}:${panelPort}${auth_path}"
|
||||
echo "内网面板地址: http://${LOCAL_IP}:${panelPort}${auth_path}"
|
||||
echo "外网面板地址: ${HTTP_S}://${getIpAddress}:${panelPort}${auth_path}"
|
||||
echo "内网面板地址: ${HTTP_S}://${LOCAL_IP}:${panelPort}${auth_path}"
|
||||
echo -e "username: $username"
|
||||
echo -e "password: $password"
|
||||
echo -e "\033[33mIf you cannot access the panel,\033[0m"
|
||||
echo -e "\033[33mrelease the following panel port [${panelPort}] in the security group\033[0m"
|
||||
echo -e "\033[33m若无法访问面板,请检查防火墙/安全组是否有放行面板[${panelPort}]端口\033[0m"
|
||||
if [ "${HTTP_S}" == "https" ];then
|
||||
echo -e "\033[33m因已开启面板自签证书,访问面板会提示不匹配证书,请参考以下链接配置证书\033[0m"
|
||||
echo -e "\033[33mhttps://www.bt.cn/bbs/thread-105443-1-1.html\033[0m"
|
||||
fi
|
||||
echo -e "=================================================================="
|
||||
|
||||
endTime=`date +%s`
|
||||
|
@@ -10,7 +10,7 @@ export LANG=en_US.UTF-8
|
||||
export LANGUAGE=en_US:en
|
||||
|
||||
get_node_url(){
|
||||
nodes=(http://dg2.bt.cn http://dg1.bt.cn http://36.133.1.8:5880 http://123.129.198.197 http://38.34.185.130 http://116.213.43.206:5880 http://128.1.164.196);
|
||||
nodes=(https://dg2.bt.cn https://dg1.bt.cn https://download.bt.cn https://hk1-node.bt.cn https://na1-node.bt.cn https://jp1-node.bt.cn);
|
||||
|
||||
if [ "$1" ];then
|
||||
nodes=($(echo ${nodes[*]}|sed "s#${1}##"))
|
||||
@@ -52,7 +52,7 @@ get_node_url(){
|
||||
if [ -z "$NODE_URL" ];then
|
||||
NODE_URL=$(cat $tmp_file2|sort -g -t " " -k 1|head -n 1|awk '{print $2}')
|
||||
if [ -z "$NODE_URL" ];then
|
||||
NODE_URL='http://download.bt.cn';
|
||||
NODE_URL='https://download.bt.cn';
|
||||
fi
|
||||
fi
|
||||
rm -f $tmp_file1
|
||||
@@ -108,7 +108,7 @@ send_check(){
|
||||
chmod +x /etc/init.d/bt
|
||||
p_path2=/www/server/panel/class/common.py
|
||||
p_version=$(cat $p_path2|grep "version = "|awk '{print $3}'|tr -cd [0-9.])
|
||||
curl -sS --connect-timeout 3 -m 60 http://www.bt.cn/api/panel/notpro?version=$p_version
|
||||
curl -sS --connect-timeout 3 -m 60 https://www.bt.cn/api/panel/notpro?version=$p_version
|
||||
NODE_URL=""
|
||||
exit 0;
|
||||
}
|
||||
@@ -147,3 +147,4 @@ if [ ! $NODE_URL ];then
|
||||
get_node_url
|
||||
fi
|
||||
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
@@ -42,7 +42,7 @@ download_Url=$NODE_URL
|
||||
setup_path=/www
|
||||
version=$(curl -Ss --connect-timeout 5 -m 2 $Btapi_Url/api/panel/get_version)
|
||||
if [ "$version" = '' ];then
|
||||
version='7.9.5'
|
||||
version='7.9.7'
|
||||
fi
|
||||
armCheck=$(uname -m|grep arm)
|
||||
if [ "${armCheck}" ];then
|
||||
|
@@ -70,7 +70,7 @@ select_node(){
|
||||
get_version(){
|
||||
version=$(curl -Ss --connect-timeout 5 -m 2 $Btapi_Url/api/panel/get_version)
|
||||
if [ "$version" = '' ];then
|
||||
version='7.9.5'
|
||||
version='7.9.7'
|
||||
fi
|
||||
}
|
||||
|
||||
|
@@ -22,7 +22,7 @@ def readReg(path,key):
|
||||
return False
|
||||
|
||||
panelPath = readReg(r'SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\宝塔面板','PanelPath')
|
||||
if not panelPath:
|
||||
if not panelPath:
|
||||
panelPath = os.getenv('BT_PANEL')
|
||||
if not panelPath: exit();
|
||||
|
||||
@@ -44,11 +44,11 @@ class Sql():
|
||||
__OPT_FIELD = "*" # field条件
|
||||
__OPT_PARAM = () # where值
|
||||
__LOCK = panelPath + '/data/sqlite_lock.pl'
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.__DB_FILE = panelPath + '/data/default.db'
|
||||
|
||||
def __GetConn(self):
|
||||
|
||||
def __GetConn(self):
|
||||
#取数据库对象
|
||||
try:
|
||||
if self.__DB_CONN == None:
|
||||
@@ -62,8 +62,8 @@ class Sql():
|
||||
#设置表名
|
||||
self.__DB_TABLE = table
|
||||
return self
|
||||
|
||||
|
||||
|
||||
|
||||
def where(self,where,param):
|
||||
#WHERE条件
|
||||
if where:
|
||||
@@ -73,7 +73,7 @@ class Sql():
|
||||
|
||||
def __to_tuple(self,param):
|
||||
#将参数转换为tuple
|
||||
if type(param) != tuple:
|
||||
if type(param) != tuple:
|
||||
if type(param) == list:
|
||||
param = tuple(param)
|
||||
else:
|
||||
@@ -85,7 +85,7 @@ class Sql():
|
||||
if not pdata: return False
|
||||
keys,param = self.__format_pdata(pdata)
|
||||
return self.save(keys,param)
|
||||
|
||||
|
||||
#构造数据
|
||||
def __format_pdata(self,pdata):
|
||||
keys = pdata.keys()
|
||||
@@ -98,17 +98,17 @@ class Sql():
|
||||
#FIELD条件
|
||||
if len(field):
|
||||
self.__OPT_FIELD = field
|
||||
return self
|
||||
return self
|
||||
|
||||
def getField(self,keyName):
|
||||
#取回指定字段
|
||||
|
||||
|
||||
result = self.field(keyName).select()
|
||||
print(result)
|
||||
if len(result) != 0:
|
||||
return result[0][keyName]
|
||||
return result
|
||||
|
||||
|
||||
def __format_field(self,field):
|
||||
import re
|
||||
fields = []
|
||||
@@ -159,16 +159,16 @@ class Sql():
|
||||
return data
|
||||
except Exception as ex:
|
||||
return "error: " + str(ex)
|
||||
|
||||
|
||||
def setField(self,keyName,keyValue):
|
||||
#更新指定字段
|
||||
return self.save(keyName,(keyValue,))
|
||||
return self.save(keyName,(keyValue,))
|
||||
|
||||
def commit(self):
|
||||
self.__close()
|
||||
self.__DB_CONN.commit()
|
||||
|
||||
|
||||
|
||||
|
||||
def save(self,keys,param):
|
||||
#更新数据
|
||||
self.write_lock()
|
||||
@@ -180,7 +180,7 @@ class Sql():
|
||||
opt += key + "=?,"
|
||||
opt = opt[0:len(opt)-1]
|
||||
sql = "UPDATE " + self.__DB_TABLE + " SET " + opt+self.__OPT_WHERE
|
||||
|
||||
|
||||
#处理拼接WHERE与UPDATE参数
|
||||
tmp = list(self.__to_tuple(param))
|
||||
for arg in self.__OPT_PARAM:
|
||||
@@ -193,8 +193,8 @@ class Sql():
|
||||
return result.rowcount
|
||||
except Exception as ex:
|
||||
return "error: " + str(ex)
|
||||
|
||||
|
||||
|
||||
|
||||
def execute(self,sql,param = ()):
|
||||
#执行SQL语句返回受影响行
|
||||
self.write_lock()
|
||||
@@ -225,7 +225,7 @@ class Sql():
|
||||
def rm_lock(self):
|
||||
if os.path.exists(self.__LOCK):
|
||||
os.remove(self.__LOCK)
|
||||
|
||||
|
||||
def query(self,sql,param = ()):
|
||||
#执行SQL语句返回数据集
|
||||
self.__GetConn()
|
||||
@@ -236,7 +236,7 @@ class Sql():
|
||||
return data
|
||||
except Exception as ex:
|
||||
return "error: " + str(ex)
|
||||
|
||||
|
||||
def __close(self):
|
||||
#清理条件属性
|
||||
self.__OPT_WHERE = ""
|
||||
@@ -244,8 +244,8 @@ class Sql():
|
||||
self.__OPT_ORDER = ""
|
||||
self.__OPT_LIMIT = ""
|
||||
self.__OPT_PARAM = ()
|
||||
|
||||
|
||||
|
||||
|
||||
def close(self):
|
||||
#释放资源
|
||||
try:
|
||||
@@ -254,7 +254,7 @@ class Sql():
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
def GetLocalIp():
|
||||
"""
|
||||
取本地外网IP
|
||||
@@ -264,17 +264,16 @@ def GetLocalIp():
|
||||
filename = panelPath + '/data/iplist.txt'
|
||||
ipaddress = readFile(filename)
|
||||
if not ipaddress:
|
||||
|
||||
url = 'http://pv.sohu.com/cityjson?ie=utf-8'
|
||||
|
||||
url = 'http://www.example.com/api/getIpAddress';
|
||||
str = httpGet(url)
|
||||
ipaddress = re.search('\d+.\d+.\d+.\d+',str).group(0)
|
||||
writeFile(filename,ipaddress)
|
||||
|
||||
|
||||
ipaddress = re.search('\d+.\d+.\d+.\d+',ipaddress).group(0);
|
||||
return ipaddress
|
||||
except:
|
||||
try:
|
||||
url = 'http://www.example.com/api/getIpAddress';
|
||||
url = 'https://www.bt.cn/Api/getIpAddress';
|
||||
str = httpGet(url)
|
||||
writeFile(filename,ipaddress)
|
||||
return str
|
||||
@@ -302,12 +301,12 @@ def start_service(name):
|
||||
while get_server_status(name) == 0:
|
||||
try:
|
||||
win32serviceutil.StartService(name)
|
||||
time.sleep(1);
|
||||
except : time.sleep(1);
|
||||
time.sleep(1);
|
||||
except : time.sleep(1);
|
||||
timeout += 1
|
||||
if timeout > 10:break
|
||||
|
||||
if get_server_status(name) != 0:
|
||||
if get_server_status(name) != 0:
|
||||
return True,None
|
||||
return False,'操作失败,10秒内未完成启动服务【{}】'.format(name)
|
||||
except :
|
||||
@@ -319,12 +318,12 @@ def stop_service(name):
|
||||
while get_server_status(name) == 1:
|
||||
try:
|
||||
win32serviceutil.StopService(name)
|
||||
time.sleep(1);
|
||||
except : time.sleep(1);
|
||||
time.sleep(1);
|
||||
except : time.sleep(1);
|
||||
timeout += 1
|
||||
if timeout > 10:break
|
||||
|
||||
if get_server_status(name) != 1:
|
||||
if get_server_status(name) != 1:
|
||||
return True,None
|
||||
return False,'操作失败,10秒内未完成启动服务【{}】'.format(name)
|
||||
except :
|
||||
@@ -364,15 +363,15 @@ def downloadFileByWget(url,filename):
|
||||
if os.path.exists(logPath): os.remove(logPath)
|
||||
except : pass
|
||||
loacl_path = '{}/script/wget.exe'.format(panelPath)
|
||||
if not os.path.exists(loacl_path): downloadFile(get_url()+'/win/panel/data/wget.exe',loacl_path)
|
||||
if not os.path.exists(loacl_path): downloadFile(get_url()+'/win/panel/data/wget.exe',loacl_path)
|
||||
|
||||
if os.path.getsize(loacl_path) < 10:
|
||||
os.remove(loacl_path)
|
||||
downloadFile(url,filename)
|
||||
else:
|
||||
shell = "{} {} -O {} -t 5 -T 60 --no-check-certificate --auth-no-challenge --force-directorie > {} 2>&1".format(loacl_path,url,filename,logPath)
|
||||
shell = "{} {} -O {} -t 5 -T 60 --no-check-certificate --auth-no-challenge --force-directorie > {} 2>&1".format(loacl_path,url,filename,logPath)
|
||||
os.system(shell)
|
||||
|
||||
|
||||
num = 0
|
||||
re_size = 0
|
||||
while num <= 5:
|
||||
@@ -382,17 +381,17 @@ def downloadFileByWget(url,filename):
|
||||
break;
|
||||
else:
|
||||
re_size = cr_size
|
||||
time.sleep(0.5)
|
||||
time.sleep(0.5)
|
||||
num += 1
|
||||
|
||||
if os.path.exists(filename):
|
||||
if os.path.exists(filename):
|
||||
if os.path.getsize(filename) < 1:
|
||||
os.remove(filename)
|
||||
downloadFile(url,filename)
|
||||
else:
|
||||
downloadFile(url,filename)
|
||||
|
||||
def writeFile(filename,s_body,mode='w+',encoding = 'utf-8'):
|
||||
def writeFile(filename,s_body,mode='w+',encoding = 'utf-8'):
|
||||
try:
|
||||
fp = open(filename, mode,encoding = encoding);
|
||||
fp.write(s_body)
|
||||
@@ -402,7 +401,7 @@ def writeFile(filename,s_body,mode='w+',encoding = 'utf-8'):
|
||||
return False
|
||||
|
||||
def readFile(filename,mode = 'r'):
|
||||
|
||||
|
||||
import os,chardet
|
||||
if not os.path.exists(filename): return False
|
||||
if not os.path.isfile(filename): return False
|
||||
@@ -425,15 +424,15 @@ def readFile(filename,mode = 'r'):
|
||||
encoding = 'ansi'
|
||||
fp = open(filename, mode,encoding = encoding)
|
||||
f_body = fp.read()
|
||||
|
||||
|
||||
try:
|
||||
if f_body[0] == '\ufeff':
|
||||
if f_body[0] == '\ufeff':
|
||||
#处理带bom格式
|
||||
new_code = chardet.detect(f_body.encode(encoding))["encoding"]
|
||||
f_body = f_body.encode(encoding).decode(new_code);
|
||||
except : pass
|
||||
|
||||
fp.close()
|
||||
except : pass
|
||||
|
||||
fp.close()
|
||||
return f_body
|
||||
|
||||
def httpGet(url,timeout = 60,headers = {}):
|
||||
@@ -445,11 +444,11 @@ def httpGet(url,timeout = 60,headers = {}):
|
||||
req = urllib.request.Request(url,headers = headers)
|
||||
response = urllib.request.urlopen(req,timeout = timeout)
|
||||
result = response.read()
|
||||
if type(result) == bytes:
|
||||
if type(result) == bytes:
|
||||
try:
|
||||
result = result.decode('utf-8')
|
||||
except :
|
||||
result = result.decode('gb2312')
|
||||
result = result.decode('gb2312')
|
||||
return result
|
||||
except Exception as ex:
|
||||
if headers: return False
|
||||
@@ -470,9 +469,9 @@ def httpPost(url, data, timeout=60, headers={}):
|
||||
|
||||
return result
|
||||
except Exception as ex:
|
||||
|
||||
|
||||
return str(ex);
|
||||
|
||||
|
||||
|
||||
def get_timeout(url,timeout=3):
|
||||
|
||||
@@ -484,10 +483,10 @@ def get_timeout(url,timeout=3):
|
||||
|
||||
def get_url(timeout = 0.5):
|
||||
import json
|
||||
try:
|
||||
try:
|
||||
#
|
||||
node_list = [{"protocol":"http://","address":"dg1.bt.cn","port":"80","ping":500},{"protocol":"http://","address":"dg2.bt.cn","port":"80","ping":500},{"protocol":"http://","address":"node.aapanel.com","port":"80","ping":500},{"protocol":"http://","address":"download.bt.cn","port":"80","ping":500}]
|
||||
|
||||
node_list = [{"protocol":"http://","address":"dg2.bt.cn","port":"80","ping":500},{"protocol":"http://","address":"dg1.bt.cn","port":"80","ping":500},{"protocol":"http://","address":"download.bt.cn","port":"80","ping":500},{"protocol":"http://","address":"hk1-node.bt.cn","port":"80","ping":500},{"protocol":"http://","address":"na1-node.bt.cn","port":"80","ping":500},{"protocol":"http://","address":"jp1-node.bt.cn","port":"80","ping":500}]
|
||||
|
||||
mnode1 = []
|
||||
mnode2 = []
|
||||
mnode3 = []
|
||||
@@ -510,12 +509,12 @@ def get_url(timeout = 0.5):
|
||||
mnode = sorted(mnode3,key= lambda x:x['net'],reverse=True)
|
||||
else: #终选中等延迟,中等带宽
|
||||
mnode = sorted(mnode2,key= lambda x:x['ping'],reverse=False)
|
||||
|
||||
if not mnode: return 'http://download.bt.cn'
|
||||
|
||||
if not mnode: return 'https://download.bt.cn'
|
||||
#return mnode[0]['protocol'] + mnode[0]['address'] + ':' + mnode[0]['port']
|
||||
return "https://" + mnode[0]['address']
|
||||
except:
|
||||
return 'http://download.bt.cn'
|
||||
return 'https://download.bt.cn'
|
||||
|
||||
|
||||
|
||||
@@ -529,12 +528,12 @@ def del_file_access(filename,user):
|
||||
sd = win32security.GetFileSecurity(filename, win32security.DACL_SECURITY_INFORMATION)
|
||||
dacl = sd.GetSecurityDescriptorDacl()
|
||||
ace_count = dacl.GetAceCount()
|
||||
|
||||
for i in range(ace_count ,0 ,-1):
|
||||
|
||||
for i in range(ace_count ,0 ,-1):
|
||||
try:
|
||||
data = {}
|
||||
data['rev'], data['access'], usersid = dacl.GetAce(i-1)
|
||||
data['user'],data['group'], data['type'] = win32security.LookupAccountSid('', usersid)
|
||||
data['user'],data['group'], data['type'] = win32security.LookupAccountSid('', usersid)
|
||||
if data['user'].lower() == user.lower(): dacl.DeleteAce(i-1) #删除旧的dacl
|
||||
if data['user'].lower() == 'users': dacl.DeleteAce(i-1) #删除旧的dacl
|
||||
|
||||
@@ -542,35 +541,35 @@ def del_file_access(filename,user):
|
||||
try:
|
||||
#处理拒绝访问
|
||||
dacl.DeleteAce(i-1)
|
||||
except : pass
|
||||
except : pass
|
||||
sd.SetSecurityDescriptorDacl(1, dacl, 0)
|
||||
win32security.SetFileSecurity(filename, win32security.DACL_SECURITY_INFORMATION, sd)
|
||||
except :
|
||||
pass
|
||||
return True
|
||||
|
||||
def set_file_access(filename,user,access):
|
||||
def set_file_access(filename,user,access):
|
||||
try:
|
||||
sd = win32security.GetFileSecurity(filename, win32security.DACL_SECURITY_INFORMATION)
|
||||
dacl = sd.GetSecurityDescriptorDacl()
|
||||
ace_count = dacl.GetAceCount()
|
||||
|
||||
for i in range(ace_count, 0,-1):
|
||||
for i in range(ace_count, 0,-1):
|
||||
try:
|
||||
data = {}
|
||||
data['rev'], data['access'], usersid = dacl.GetAce(i-1)
|
||||
data['user'],data['group'], data['type'] = win32security.LookupAccountSid('', usersid)
|
||||
data['user'],data['group'], data['type'] = win32security.LookupAccountSid('', usersid)
|
||||
if data['user'].lower() == user.lower(): dacl.DeleteAce(i-1) #删除旧的dacl
|
||||
if data['user'].lower() == 'users': dacl.DeleteAce(i-1) #删除旧的dacl
|
||||
|
||||
|
||||
except :
|
||||
pass
|
||||
try:
|
||||
userx, domain, type = win32security.LookupAccountName("", user)
|
||||
except :
|
||||
userx, domain, type = win32security.LookupAccountName("", 'IIS APPPOOL\\' + user)
|
||||
userx, domain, type = win32security.LookupAccountName("", 'IIS APPPOOL\\' + user)
|
||||
if access > 0: dacl.AddAccessAllowedAceEx(win32security.ACL_REVISION, 3, access, userx)
|
||||
|
||||
|
||||
sd.SetSecurityDescriptorDacl(1, dacl, 0)
|
||||
win32security.SetFileSecurity(filename, win32security.DACL_SECURITY_INFORMATION, sd)
|
||||
return True,None
|
||||
@@ -582,24 +581,24 @@ def ExecShell(cmdstring, cwd=None, timeout=None, shell=True):
|
||||
cmdstring_list = cmdstring
|
||||
else:
|
||||
cmdstring_list = shlex.split(cmdstring)
|
||||
|
||||
|
||||
if timeout:
|
||||
end_time = datetime.datetime.now() + datetime.timedelta(seconds=timeout)
|
||||
|
||||
sub = subprocess.Popen(cmdstring_list, cwd=cwd, stdin=subprocess.PIPE,shell=shell,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
|
||||
|
||||
sub = subprocess.Popen(cmdstring_list, cwd=cwd, stdin=subprocess.PIPE,shell=shell,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
|
||||
while sub.poll() is None:
|
||||
time.sleep(0.1)
|
||||
if timeout:
|
||||
if end_time <= datetime.datetime.now():
|
||||
raise Exception("Timeout:%s"%cmdstring)
|
||||
a,e = sub.communicate()
|
||||
if type(a) == bytes:
|
||||
if type(a) == bytes:
|
||||
try:
|
||||
a = a.decode('utf-8')
|
||||
except :
|
||||
except :
|
||||
a = a.decode('gb2312','ignore')
|
||||
|
||||
if type(e) == bytes:
|
||||
if type(e) == bytes:
|
||||
try:
|
||||
e = e.decode('utf-8')
|
||||
except :
|
||||
@@ -626,7 +625,7 @@ def GetRandomString1(length):
|
||||
strings += chars[random.randint(0, chrlen)]
|
||||
return strings
|
||||
|
||||
def GetRandomString2(length):
|
||||
def GetRandomString2(length):
|
||||
from random import Random
|
||||
strings = ''
|
||||
chars = '!@#$%^&*()_+.,?[]-='
|
||||
@@ -637,7 +636,7 @@ def GetRandomString2(length):
|
||||
return strings
|
||||
|
||||
def chdck_salt():
|
||||
|
||||
|
||||
sql = Sql()
|
||||
sql.table('users').execute("ALTER TABLE 'users' ADD 'salt' TEXT",())
|
||||
|
||||
@@ -657,7 +656,7 @@ def md5(strings):
|
||||
"""
|
||||
import hashlib
|
||||
m = hashlib.md5()
|
||||
|
||||
|
||||
m.update(strings.encode('utf-8'))
|
||||
return m.hexdigest()
|
||||
|
||||
@@ -673,18 +672,18 @@ def password_salt(password,username=None,uid=None):
|
||||
salt = sql.table('users').where('id=?',(uid,)).getField('salt')
|
||||
return md5(md5(password+'_bt.cn')+salt)
|
||||
|
||||
def check_user(username):
|
||||
def check_user(username):
|
||||
resume = 0
|
||||
while True:
|
||||
data, total, resume = win32net.NetUserEnum(None, 3, win32netcon.FILTER_NORMAL_ACCOUNT, resume)
|
||||
for user in data:
|
||||
if user['name'] == username: return True
|
||||
if not resume: break
|
||||
return False
|
||||
return False
|
||||
|
||||
def add_user(username,password,ps):
|
||||
try:
|
||||
if not check_user(username):
|
||||
if not check_user(username):
|
||||
d = {}
|
||||
d['name'] = username
|
||||
d['password'] = password
|
||||
@@ -692,7 +691,7 @@ def add_user(username,password,ps):
|
||||
d['flags'] = win32netcon.UF_NORMAL_ACCOUNT | win32netcon.UF_SCRIPT
|
||||
d['priv'] = win32netcon.USER_PRIV_USER
|
||||
win32net.NetUserAdd(None, 1, d)
|
||||
|
||||
|
||||
#设置用户允许登录服务
|
||||
handle = win32security.LsaOpenPolicy(None, win32security.POLICY_ALL_ACCESS)
|
||||
sid_obj, domain, tmp = win32security.LookupAccountName(None, username)
|
||||
@@ -713,25 +712,25 @@ def add_user_bywww():
|
||||
|
||||
pwd = GetRandomString(64) + GetRandomString1(32) + GetRandomString2(32)
|
||||
status,error = add_user('www',pwd,'用于启动宝塔安装的程序,删除后会导致部分软件无法启动,请勿删除')
|
||||
if not status:
|
||||
if not status:
|
||||
writeFile(error_path,error)
|
||||
return False
|
||||
return True
|
||||
|
||||
def add_user_bymysql():
|
||||
|
||||
|
||||
pwd = GetRandomString(64) + GetRandomString1(32) + GetRandomString2(32)
|
||||
status,error = add_user('mysql',pwd,'用于启动宝塔安装的程序,删除后会导致部分软件无法启动,请勿删除')
|
||||
if not status:
|
||||
if not status:
|
||||
writeFile(error_path,error)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def getIP(url):
|
||||
import socket,re
|
||||
|
||||
tmp = re.search('http://(.+)\:\d*',url)
|
||||
if tmp:
|
||||
if tmp:
|
||||
domain = tmp.groups()[0]
|
||||
myaddr = socket.getaddrinfo(domain, 'http')
|
||||
return myaddr[0][4][0]
|
||||
@@ -756,14 +755,14 @@ def add_panel_dir():
|
||||
]
|
||||
|
||||
is_break = False
|
||||
for sobj in slist:
|
||||
for sobj in slist:
|
||||
if not os.path.exists(sobj[0]):
|
||||
os.makedirs(sobj[0])
|
||||
os.makedirs(sobj[0])
|
||||
n = 0
|
||||
while n < 5:
|
||||
if os.path.exists(sobj[0]): break
|
||||
|
||||
os.makedirs(sobj[0])
|
||||
os.makedirs(sobj[0])
|
||||
time.sleep(0.5)
|
||||
n += 1
|
||||
|
||||
@@ -773,17 +772,17 @@ def add_panel_dir():
|
||||
|
||||
del_file_access(sobj[0],'users')
|
||||
|
||||
for user in sobj[1]:
|
||||
for user in sobj[1]:
|
||||
n = 0
|
||||
while n < 3:
|
||||
while n < 3:
|
||||
status,error = set_file_access(sobj[0],user,2032127)
|
||||
if status: break
|
||||
if status: break
|
||||
time.sleep(0.5)
|
||||
|
||||
if not status:
|
||||
writeFile(error_path,"目录{}设置{}权限设置错误 -> {}".format(sobj[0],user,error))
|
||||
break
|
||||
|
||||
|
||||
del_file_access(setupPath,'users')
|
||||
url = get_url()
|
||||
|
||||
@@ -793,18 +792,18 @@ def add_panel_dir():
|
||||
download_url = '{}/win/panel/data/{}'.format(url,f_name)
|
||||
|
||||
n = 0
|
||||
while n < 10:
|
||||
while n < 10:
|
||||
n += 1;
|
||||
|
||||
try:
|
||||
if os.path.exists(local_path) and os.path.getsize(local_path) < 10: os.remove(local_path)
|
||||
if not os.path.exists(local_path): downloadFileByWget(download_url,local_path)
|
||||
if os.path.getsize(local_path) and os.path.getsize(local_path) > 10: break;
|
||||
if os.path.exists(local_path) and os.path.getsize(local_path) < 10: os.remove(local_path)
|
||||
if not os.path.exists(local_path): downloadFileByWget(download_url,local_path)
|
||||
if os.path.getsize(local_path) and os.path.getsize(local_path) > 10: break;
|
||||
|
||||
writeFile(error_path,'download {} error ->> {} \r\n {}'.format(f_name,download_url,""))
|
||||
writeFile(error_path,'download {} error ->> {} \r\n {}'.format(f_name,download_url,""))
|
||||
except :
|
||||
ip = getIP(url)
|
||||
writeFile(error_path,'download {} error ->> {} \r\n connect {} \r\n {}'.format(ip,f_name,download_url,get_error_info()))
|
||||
writeFile(error_path,'download {} error ->> {} \r\n connect {} \r\n {}'.format(ip,f_name,download_url,get_error_info()))
|
||||
|
||||
if n > 5: return False
|
||||
time.sleep(0.2)
|
||||
@@ -816,9 +815,9 @@ def add_panel_dir():
|
||||
|
||||
def unzip(src_path,dst_path):
|
||||
import zipfile
|
||||
zip_file = zipfile.ZipFile(src_path)
|
||||
for names in zip_file.namelist():
|
||||
zip_file.extract(names,dst_path)
|
||||
zip_file = zipfile.ZipFile(src_path)
|
||||
for names in zip_file.namelist():
|
||||
zip_file.extract(names,dst_path)
|
||||
zip_file.close()
|
||||
return True
|
||||
|
||||
@@ -834,44 +833,44 @@ def download_panel(file_list = []):
|
||||
#下载面板
|
||||
loacl_path = setupPath + '/panel.zip'
|
||||
tmpPath = "{}/temp/panel".format(setupPath)
|
||||
if os.path.exists(loacl_path): os.remove(loacl_path)
|
||||
if os.path.exists(loacl_path): os.remove(loacl_path)
|
||||
if os.path.exists(tmpPath): shutil.rmtree(tmpPath,True)
|
||||
if not os.path.exists(tmpPath): os.makedirs(tmpPath)
|
||||
|
||||
|
||||
p_ver = sys.argv[2]
|
||||
downUrl = url + '/win/panel/panel_' + p_ver + '.zip';
|
||||
downloadFileByWget(downUrl,loacl_path);
|
||||
unzip(loacl_path,tmpPath)
|
||||
|
||||
downloadFileByWget(downUrl,loacl_path);
|
||||
unzip(loacl_path,tmpPath)
|
||||
|
||||
for ff_path in file_list:
|
||||
if os.path.exists(tmpPath + '/' + ff_path): os.remove(tmpPath + '/' + ff_path)
|
||||
if os.path.exists(tmpPath + '/' + ff_path): os.remove(tmpPath + '/' + ff_path)
|
||||
|
||||
tcPath = '{}\class'.format(tmpPath)
|
||||
for name in os.listdir(tcPath):
|
||||
try:
|
||||
for name in os.listdir(tcPath):
|
||||
try:
|
||||
if name.find('win_amd64.pyd') >=0:
|
||||
oldName = os.path.join(tcPath,name);
|
||||
lName = name.split('.')[0] + '.pyd'
|
||||
newName = os.path.join(tcPath,lName)
|
||||
lName = name.split('.')[0] + '.pyd'
|
||||
newName = os.path.join(tcPath,lName)
|
||||
if not os.path.exists(newName):os.rename(oldName,newName)
|
||||
except :pass
|
||||
|
||||
cPath = '{}/panel/class'.format(setupPath)
|
||||
|
||||
if os.path.exists(cPath):
|
||||
if os.path.exists(cPath):
|
||||
os.system("del /s {}\*.pyc".format(to_path(cPath)))
|
||||
os.system("del /s {}\*.pyt".format(to_path(cPath)))
|
||||
for name in os.listdir(cPath):
|
||||
try:
|
||||
if name.find('.pyd') >=0:
|
||||
if name.find('.pyd') >=0:
|
||||
oldName = os.path.join(cPath,name)
|
||||
newName = os.path.join(cPath,GetRandomString(8) + '.pyt')
|
||||
os.rename(oldName,newName)
|
||||
newName = os.path.join(cPath,GetRandomString(8) + '.pyt')
|
||||
os.rename(oldName,newName)
|
||||
except : pass
|
||||
os.system("del /s {}\*.pyc".format(to_path(cPath)))
|
||||
os.system("del /s {}\*.pyt".format(to_path(cPath)))
|
||||
|
||||
os.system("xcopy /s /c /e /y /r {} {}".format(to_path(tmpPath),to_path(panelPath)))
|
||||
os.system("xcopy /s /c /e /y /r {} {}".format(to_path(tmpPath),to_path(panelPath)))
|
||||
try:
|
||||
os.remove(loacl_path)
|
||||
except : pass
|
||||
@@ -880,7 +879,7 @@ def download_panel(file_list = []):
|
||||
shutil.rmtree(tmpPath,True)
|
||||
except : pass
|
||||
|
||||
s_ver = platform.platform()
|
||||
s_ver = platform.platform()
|
||||
net_v = '45'
|
||||
if s_ver.find('2008') >= 0: net_v = '20'
|
||||
writeFile('{}/data/net'.format(setupPath),net_v)
|
||||
@@ -910,7 +909,7 @@ def download_panel(file_list = []):
|
||||
try:
|
||||
from gevent import monkey
|
||||
except :
|
||||
os.system('"C:\Program Files\python\python.exe" -m pip install gevent')
|
||||
os.system('"C:\Program Files\python\python.exe" -m pip install gevent')
|
||||
except :
|
||||
writeFile(error_path,get_error_info())
|
||||
|
||||
@@ -918,7 +917,7 @@ def update_panel():
|
||||
|
||||
file_list = ['config/config.json','config/index.json','data/libList.conf','data/plugin.json']
|
||||
download_panel(file_list)
|
||||
|
||||
|
||||
py_path = 'C:/Program Files/python/python.exe'
|
||||
|
||||
ExecShell("\"{}\" {}/panel/runserver.py --startup auto install".format(py_path,setupPath))
|
||||
@@ -929,7 +928,7 @@ def update_panel():
|
||||
def init_panel_data():
|
||||
try:
|
||||
sql = Sql()
|
||||
username = sql.table('users').where('id=?',(1,)).getField('username')
|
||||
username = sql.table('users').where('id=?',(1,)).getField('username')
|
||||
if username == 'admin':
|
||||
username = GetRandomString(8)
|
||||
password = GetRandomString(8)
|
||||
@@ -937,12 +936,12 @@ def init_panel_data():
|
||||
|
||||
sql.table('users').where('id=?',(1,)).setField('username',username)
|
||||
pwd = password_salt(md5(password),uid=1)
|
||||
|
||||
|
||||
result = sql.table('users').where('id=?',(1,)).setField('password',pwd)
|
||||
|
||||
backup_path = panelPath[:2] + '/backup'
|
||||
www_path = panelPath[:2] + '/wwwroot'
|
||||
|
||||
|
||||
if not os.path.exists(backup_path): os.makedirs(backup_path)
|
||||
if not os.path.exists(www_path): os.makedirs(www_path)
|
||||
|
||||
@@ -953,11 +952,11 @@ def init_panel_data():
|
||||
if not os.path.exists(bind_path): writeFile(bind_path,'True')
|
||||
|
||||
admin_path = panelPath+ '/data/admin_path.pl'
|
||||
if not os.path.exists(admin_path): writeFile(admin_path,"/" + GetRandomString(8))
|
||||
if not os.path.exists(admin_path): writeFile(admin_path,"/" + GetRandomString(8))
|
||||
|
||||
port_path = panelPath+ '/data/port.pl'
|
||||
if not os.path.exists(port_path): writeFile(port_path,'8888')
|
||||
|
||||
|
||||
recycle_bin_db = panelPath+ '/data/recycle_bin_db.pl'
|
||||
if not os.path.exists(recycle_bin_db): writeFile(recycle_bin_db,'True')
|
||||
|
||||
@@ -975,26 +974,26 @@ def init_panel_data():
|
||||
except :
|
||||
writeFile(error_path,get_error_info())
|
||||
return False
|
||||
|
||||
|
||||
def add_panel_services(num = 0):
|
||||
try:
|
||||
py_path = 'C:/Program Files/python/python.exe'
|
||||
|
||||
delete_server('btPanel')
|
||||
delete_server('btPanel')
|
||||
ret = ExecShell("\"{}\" {}/panel/runserver.py --startup auto install".format(py_path,setupPath))
|
||||
|
||||
|
||||
delete_server('btTask')
|
||||
ExecShell("\"{}\" {}/panel/task.py --startup auto install".format(py_path,setupPath))
|
||||
|
||||
if get_server_status('btPanel') < 0 or get_server_status('btTask') < 0:
|
||||
ret1 = ExecShell("\"{}\" {}/panel/task.py --startup auto install".format(py_path,setupPath))
|
||||
|
||||
if get_server_status('btPanel') < 0 or get_server_status('btTask') < 0:
|
||||
if num <= 0 :
|
||||
localPath = setupPath + "/temp/Time_Zones.reg";
|
||||
downloadFileByWget(get_url() + '/win/panel/data/Time_Zones.reg',localPath)
|
||||
ExecShell("regedit /s " + localPath)
|
||||
|
||||
add_panel_services(1)
|
||||
add_panel_services(1)
|
||||
else:
|
||||
writeFile(error_path,ret[0] + ret[1])
|
||||
writeFile(error_path,ret[0] + ret[1] + ret1[0] + ret1[1])
|
||||
else:
|
||||
os.system('sc failure btPanel reset=1800 actions=restart/60000/restart/120000/restart/30000')
|
||||
os.system('sc failure btTask reset=1800 actions=restart/60000/restart/120000/restart/30000')
|
||||
@@ -1005,9 +1004,9 @@ def add_panel_services(num = 0):
|
||||
|
||||
|
||||
def add_firewall_byport():
|
||||
|
||||
|
||||
conf = ExecShell('netsh advfirewall firewall show rule "宝塔面板"')[0]
|
||||
if conf.lower().find('tcp') == -1:
|
||||
if conf.lower().find('tcp') == -1:
|
||||
ExecShell("netsh advfirewall firewall add rule name=宝塔面板 dir=in action=allow protocol=tcp localport=8888");
|
||||
ExecShell("netsh advfirewall firewall add rule name=网站访问端口 dir=in action=allow protocol=tcp localport=80");
|
||||
ExecShell("netsh advfirewall firewall add rule name=远程桌面 dir=in action=allow protocol=tcp localport=3389");
|
||||
@@ -1029,8 +1028,8 @@ def get_error_log():
|
||||
return error
|
||||
|
||||
if __name__ == "__main__":
|
||||
stype = sys.argv[1];
|
||||
if not stype in ['get_error_log']:
|
||||
stype = sys.argv[1];
|
||||
if not stype in ['get_error_log']:
|
||||
if os.path.exists(error_path): os.remove(error_path)
|
||||
result = eval('{}()'.format(stype))
|
||||
print(result)
|
||||
|
Binary file not shown.
@@ -163,6 +163,19 @@ if("undefined" != typeof database && database.hasOwnProperty("del_database")){
|
||||
}
|
||||
],
|
||||
success: function () {
|
||||
$('#check_layer_content').find('.glyphicon-info-sign').click(function (e) {
|
||||
var msg = $(this).parent().prop('title')
|
||||
msg = msg.replace('数据库:','<br>数据库:')
|
||||
layer.tips(msg, $(this).parent(), { tips: [1, 'red'], time: 3000 })
|
||||
$(document).click(function (ev) {
|
||||
layer.closeAll('tips');
|
||||
$(this).unbind('click');
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
});
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
});
|
||||
if ($('.remote_database').length) {
|
||||
$('.remote_database').each(function (index, el) {
|
||||
var id = $(el).parent().parent().parent().index()
|
||||
|
@@ -43,66 +43,128 @@ if("undefined" != typeof bt && bt.hasOwnProperty("prompt_confirm")){
|
||||
}
|
||||
if("undefined" != typeof database && database.hasOwnProperty("del_database")){
|
||||
database.del_database = function (wid, dbname,obj, callback) {
|
||||
var tips = '是否确认【删除数据库】,删除后可能会影响业务使用!';
|
||||
if(obj && obj.db_type > 0) tips = '远程数据库不支持数据库回收站,删除后将无法恢复,请谨慎操作';
|
||||
var title = typeof dbname === "function" ?'批量删除数据库':'删除数据库 [ '+ dbname +' ]';
|
||||
layer.open({
|
||||
type:1,
|
||||
title:title,
|
||||
icon:0,
|
||||
skin:'delete_site_layer',
|
||||
area: "530px",
|
||||
closeBtn: 2,
|
||||
shadeClose: true,
|
||||
content:"<div class=\'bt-form webDelete pd30\' id=\'site_delete_form\'>" +
|
||||
"<i class=\'layui-layer-ico layui-layer-ico0\'></i>" +
|
||||
"<div class=\'f13 check_title\' style=\'margin-bottom: 20px;\'>"+tips+"</div>" +
|
||||
"<div style=\'color:red;margin:18px 0 18px 18px;font-size:14px;font-weight: bold;\'>注意:数据无价,请谨慎操作!!!"+(!recycle_bin_db_open?'<br>风险操作:当前数据库回收站未开启,删除数据库将永久消失!':'')+"</div>" +
|
||||
"</div>",
|
||||
btn:[lan.public.ok,lan.public.cancel],
|
||||
yes:function(indexs){
|
||||
var data = {id: wid,name: dbname};
|
||||
if(typeof dbname === "function"){
|
||||
delete data.id;
|
||||
delete data.name;
|
||||
}
|
||||
layer.close(indexs)
|
||||
if(typeof dbname === "function"){
|
||||
dbname(data)
|
||||
}else{
|
||||
bt.database.del_database(data, function (rdata) {
|
||||
layer.closeAll()
|
||||
if (rdata.status) database_table.$refresh_table_list(true);
|
||||
if (callback) callback(rdata);
|
||||
bt.msg(rdata);
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
var title = '',
|
||||
tips = '是否确认【删除数据库】,删除后可能会影响业务使用!';
|
||||
if(obj && obj.db_type > 0) tips = '远程数据库不支持数据库回收站,删除后将无法恢复,请谨慎操作';
|
||||
title = typeof dbname === "function" ?'批量删除数据库':'删除数据库 [ '+ dbname +' ]';
|
||||
layer.open({
|
||||
type:1,
|
||||
title:title,
|
||||
icon:0,
|
||||
skin:'delete_site_layer',
|
||||
area: "530px",
|
||||
closeBtn: 2,
|
||||
shadeClose: true,
|
||||
content:"<div class=\'bt-form webDelete pd30\' id=\'site_delete_form\'>" +
|
||||
"<i class=\'layui-layer-ico layui-layer-ico0\'></i>" +
|
||||
"<div class=\'f13 check_title\' style=\'margin-bottom: 20px;\'>"+tips+"</div>" +
|
||||
"<div style=\'color:red;margin:18px 0 18px 18px;font-size:14px;font-weight: bold;\'>注意:数据无价,请谨慎操作!!!"+(!recycle_bin_db_open?'<br>风险操作:当前数据库回收站未开启,删除数据库将永久消失!':'')+"</div>" +
|
||||
"</div>",
|
||||
btn:[lan.public.ok,lan.public.cancel],
|
||||
yes:function(indexs){
|
||||
var data = {id: wid,name: dbname};
|
||||
if(typeof dbname === "function"){
|
||||
delete data.id;
|
||||
delete data.name;
|
||||
}
|
||||
layer.close(indexs)
|
||||
var arrs = wid instanceof Array ? wid : [wid]
|
||||
var ids = JSON.stringify(arrs), countDown = 9;
|
||||
if (arrs.length == 1) countDown = 4
|
||||
title = typeof dbname === "function" ?'二次验证信息,批量删除数据库':'二次验证信息,删除数据库 [ ' + dbname + ' ]';
|
||||
var loadT = bt.load('正在检测数据库数据信息,请稍后...')
|
||||
|
||||
bt_tools.send({url:'database/'+bt.data.db_tab_name+'/check_del_data',data:{data:JSON.stringify({ids: ids})}},function(res){
|
||||
loadT.close()
|
||||
layer.open({
|
||||
type:1,
|
||||
title:title,
|
||||
closeBtn: 2,
|
||||
skin: 'verify_site_layer_info',
|
||||
area: '740px',
|
||||
content: '<div class="check_delete_site_main pd30">' +
|
||||
'<i class="layui-layer-ico layui-layer-ico0"></i>' +
|
||||
'<div class="check_layer_title">堡塔温馨提示您,请冷静几秒钟,确认是否要删除以下数据。</div>' +
|
||||
'<div class="check_layer_content">' +
|
||||
'<div class="check_layer_item">' +
|
||||
'<div class="check_layer_site"></div>' +
|
||||
'<div class="check_layer_database"></div>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<div class="check_layer_error ' + (recycle_bin_db_open ? 'hide' : '') + '"><span class="glyphicon glyphicon-info-sign"></span>风险事项:当前未开启数据库回收站功能,删除数据库后,数据库将永久消失!</div>' +
|
||||
'<div class="check_layer_message"><span style="color:red">注意:请仔细阅读以上要删除信息,防止数据库被误删</span></div>' +
|
||||
'</div>',
|
||||
btn: ['确认删除', '取消删除'],
|
||||
success: function (layers) {
|
||||
var html = '', rdata = res.data;
|
||||
var filterData = rdata.filter(function(el){
|
||||
return ids.indexOf(el.id) != -1
|
||||
})
|
||||
for (var i = 0; i < filterData.length; i++) {
|
||||
var item = filterData[i], newTime = parseInt(new Date().getTime() / 1000),
|
||||
t_icon = '<span class="glyphicon glyphicon-info-sign" style="color: red;width:15px;height: 15px;;vertical-align: middle;"></span>';
|
||||
|
||||
database_html = (function(item){
|
||||
var is_time_rule = (newTime - item.st_time) > (86400 * 30) && (item.total > 1024 * 10),
|
||||
is_database_rule = res.db_size <= item.total,
|
||||
database_time = bt.format_data(item.st_time, 'yyyy-MM-dd'),
|
||||
database_size = bt.format_size(item.total);
|
||||
|
||||
var f_size = '<i ' + (is_database_rule ? 'class="warning"' : '') + ' style = "vertical-align: middle;" > ' + database_size + '</i> ' + (is_database_rule ? t_icon : '');
|
||||
var t_size = '注意:此数据库较大,可能为重要数据,请谨慎操作.\n数据库:' + database_size;
|
||||
|
||||
return '<div class="check_layer_database">' +
|
||||
'<span title="数据库:' + item.name + '">数据库:' + item.name + '</span>' +
|
||||
'<span title="' + t_size+'">大小:' + f_size +'</span>' +
|
||||
'<span title="' + (is_time_rule && item.total != 0 ? '重要:此数据库创建时间较早,可能为重要数据,请谨慎操作.' : '') + '时间:' + database_time+'">创建时间:<i ' + (is_time_rule && item.total != 0 ? 'class="warning"' : '') + '>' + database_time + '</i></span>' +
|
||||
'</div>'
|
||||
}(item))
|
||||
if(database_html !== '') html += '<div class="check_layer_item">' + database_html +'</div>';
|
||||
}
|
||||
if(html === '') html = '<div style="text-align: center;width: 100%;height: 100%;line-height: 300px;font-size: 15px;">无数据</div>'
|
||||
$('.check_layer_content').html(html)
|
||||
},
|
||||
yes:function(indes,layers){
|
||||
if(typeof dbname === "function"){
|
||||
dbname(data)
|
||||
}else{
|
||||
bt.database.del_database(data, function (rdata) {
|
||||
layer.closeAll()
|
||||
if (rdata.status) database_table.$refresh_table_list(true);
|
||||
if (callback) callback(rdata);
|
||||
bt.msg(rdata);
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
if("undefined" != typeof site && site.hasOwnProperty("del_site")){
|
||||
site.del_site = function(wid, wname, callback) {
|
||||
var title = typeof wname === "function" ?'批量删除站点':'删除站点 [ '+ wname +' ]';
|
||||
var title = typeof wname === "function" ? '批量删除站点' : '删除站点 [ ' + wname + ' ]';
|
||||
recycle_bin_open = bt.get_cookie("is_recycle") || bt.get_cookie("is_recycle") == null ? true : false
|
||||
layer.open({
|
||||
type:1,
|
||||
title:title,
|
||||
icon:0,
|
||||
skin:'delete_site_layer',
|
||||
type: 1,
|
||||
title: title,
|
||||
icon: 0,
|
||||
skin: 'delete_site_layer',
|
||||
area: "440px",
|
||||
closeBtn: 2,
|
||||
shadeClose: true,
|
||||
content:"<div class=\'bt-form webDelete pd30\' id=\'site_delete_form\'>" +
|
||||
content: "<div class=\'bt-form webDelete pd30\' id=\'site_delete_form\'>" +
|
||||
'<i class="layui-layer-ico layui-layer-ico0"></i>' +
|
||||
"<div class=\'f13 check_title\'>是否要删除关联的FTP、数据库、站点目录!</div>" +
|
||||
"<div class=\"check_type_group\">" +
|
||||
"<label><input type=\"checkbox\" name=\"ftp\"><span>FTP</span></label>" +
|
||||
"<label><input type=\"checkbox\" name=\"database\"><span>数据库</span>"+ (!recycle_bin_db_open?'<span class="glyphicon glyphicon-info-sign" style="color: red"></span>':'') +"</label>" +
|
||||
"<label><input type=\"checkbox\" name=\"path\"><span>站点目录</span>"+ (!recycle_bin_open?'<span class="glyphicon glyphicon-info-sign" style="color: red"></span>':'') +"</label>" +
|
||||
"</div>"+
|
||||
"<label><input type=\"checkbox\" name=\"database\"><span>数据库</span>" + (!recycle_bin_db_open ? '<span class="glyphicon glyphicon-info-sign" style="color: red"></span>' : '') + "</label>" +
|
||||
"<label><input type=\"checkbox\" name=\"path\"><span>站点目录</span>" + (!recycle_bin_open ? '<span class="glyphicon glyphicon-info-sign" style="color: red"></span>' : '') + "</label>" +
|
||||
"</div>" +
|
||||
"</div>",
|
||||
btn:[lan.public.ok,lan.public.cancel],
|
||||
success:function(layers,indexs){
|
||||
btn: [lan.public.ok, lan.public.cancel],
|
||||
success: function (layers, indexs) {
|
||||
$(layers).find('.check_type_group label').hover(function () {
|
||||
var name = $(this).find('input').attr('name');
|
||||
if (name === 'data' && !recycle_bin_db_open) {
|
||||
@@ -114,14 +176,14 @@ if("undefined" != typeof site && site.hasOwnProperty("del_site")){
|
||||
layer.closeAll('tips');
|
||||
})
|
||||
},
|
||||
yes:function(indexs){
|
||||
var data = {id: wid,webname: wname};
|
||||
yes: function (indexs) {
|
||||
var data = { id: wid, webname: wname };
|
||||
$('#site_delete_form input[type=checkbox]').each(function (index, item) {
|
||||
if($(item).is(':checked')) data[$(item).attr('name')] = 1
|
||||
if ($(item).is(':checked')) data[$(item).attr('name')] = 1
|
||||
})
|
||||
var is_database = data.hasOwnProperty('database'),is_path = data.hasOwnProperty('path'),is_ftp = data.hasOwnProperty('ftp');
|
||||
if((!is_database && !is_path) && (!is_ftp || is_ftp)){
|
||||
if(typeof wname === "function"){
|
||||
var is_database = data.hasOwnProperty('database'), is_path = data.hasOwnProperty('path'), is_ftp = data.hasOwnProperty('ftp');
|
||||
if ((!is_database && !is_path) && (!is_ftp || is_ftp)) {
|
||||
if (typeof wname === "function") {
|
||||
wname(data)
|
||||
return false;
|
||||
}
|
||||
@@ -132,24 +194,104 @@ if("undefined" != typeof site && site.hasOwnProperty("del_site")){
|
||||
})
|
||||
return false
|
||||
}
|
||||
if(typeof wname === "function"){
|
||||
if (typeof wname === "function") {
|
||||
delete data.id;
|
||||
delete data.webname;
|
||||
}
|
||||
layer.close(indexs)
|
||||
if(typeof wname === "function"){
|
||||
console.log(data)
|
||||
wname(data)
|
||||
}else{
|
||||
bt.site.del_site(data, function (rdata) {
|
||||
layer.closeAll()
|
||||
if (rdata.status) site.get_list();
|
||||
if (callback) callback(rdata);
|
||||
bt.msg(rdata);
|
||||
var arrs = wid instanceof Array ? wid : [wid]
|
||||
var ids = JSON.stringify(arrs), countDown = 9;
|
||||
if (arrs.length == 1) countDown = 4
|
||||
title = typeof wname === "function" ? '二次验证信息,批量删除站点' : '二次验证信息,删除站点 [ ' + wname + ' ]';
|
||||
var loadT = bt.load('正在检测站点数据信息,请稍后...')
|
||||
bt.send('check_del_data', 'site/check_del_data', { ids: ids }, function (res) {
|
||||
loadT.close()
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: title,
|
||||
closeBtn: 2,
|
||||
skin: 'verify_site_layer_info',
|
||||
area: '740px',
|
||||
content: '<div class="check_delete_site_main pd30">' +
|
||||
'<i class="layui-layer-ico layui-layer-ico0"></i>' +
|
||||
'<div class="check_layer_title">堡塔温馨提示您,请冷静几秒钟,确认以下要删除的数据。</div>' +
|
||||
'<div class="check_layer_content">' +
|
||||
'<div class="check_layer_item">' +
|
||||
'<div class="check_layer_site"></div>' +
|
||||
'<div class="check_layer_database"></div>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<div class="check_layer_error ' + (data.database && recycle_bin_db_open ? 'hide' : '') + '"><span class="glyphicon glyphicon-info-sign"></span>风险事项:当前未开启数据库回收站功能,删除数据库后,数据库将永久消失!</div>' +
|
||||
'<div class="check_layer_error ' + (data.path && recycle_bin_open ? 'hide' : '') + '"><span class="glyphicon glyphicon-info-sign"></span>风险事项:当前未开启文件回收站功能,删除站点目录后,站点目录将永久消失!</div>' +
|
||||
'<div class="check_layer_message"><span style="color:red">注意:请仔细阅读以上要删除信息,防止网站数据被误删</span></div>' +
|
||||
'</div>',
|
||||
// recycle_bin_db_open &&
|
||||
// recycle_bin_open &&
|
||||
btn: ['确认删除', '取消删除'],
|
||||
success: function (layers) {
|
||||
var html = '', rdata = res.data;
|
||||
for (var i = 0; i < rdata.length; i++) {
|
||||
var item = rdata[i], newTime = parseInt(new Date().getTime() / 1000),
|
||||
t_icon = '<span class="glyphicon glyphicon-info-sign" style="color: red;width:15px;height: 15px;;vertical-align: middle;"></span>';
|
||||
|
||||
site_html = (function (item) {
|
||||
if (!is_path) return ''
|
||||
var is_time_rule = (newTime - item.st_time) > (86400 * 30) && (item.total > 1024 * 10),
|
||||
is_path_rule = res.file_size <= item.total,
|
||||
dir_time = bt.format_data(item.st_time, 'yyyy-MM-dd'),
|
||||
dir_size = bt.format_size(item.total);
|
||||
|
||||
var f_html = '<i ' + (is_path_rule ? 'class="warning"' : '') + ' style = "vertical-align: middle;" > ' + dir_size + '</i> ' + (is_path_rule ? t_icon : '');
|
||||
var f_title = (is_path_rule ? '注意:此目录较大,可能为重要数据,请谨慎操作.\n' : '') + '目录:' + item.path + '(' + (item.limit ? '大于' : '') + dir_size + ')';
|
||||
|
||||
return '<div class="check_layer_site">' +
|
||||
'<span title="站点:' + item.name + '">站点名:' + item.name + '</span>' +
|
||||
'<span title="' + f_title + '" >目录:<span style="vertical-align: middle;max-width: 160px;width: auto;">' + item.path + '</span> (' + f_html + ')</span>' +
|
||||
'<span title="' + (is_time_rule ? '注意:此站点创建时间较早,可能为重要数据,请谨慎操作.\n' : '') + '时间:' + dir_time + '">创建时间:<i ' + (is_time_rule ? 'class="warning"' : '') + '>' + dir_time + '</i></span>' +
|
||||
'</div>'
|
||||
}(item)),
|
||||
database_html = (function (item) {
|
||||
if (!is_database || !item.database) return '';
|
||||
var is_time_rule = (newTime - item.st_time) > (86400 * 30) && (item.total > 1024 * 10),
|
||||
is_database_rule = res.db_size <= item.database.total,
|
||||
database_time = bt.format_data(item.database.st_time, 'yyyy-MM-dd'),
|
||||
database_size = bt.format_size(item.database.total);
|
||||
|
||||
var f_size = '<i ' + (is_database_rule ? 'class="warning"' : '') + ' style = "vertical-align: middle;" > ' + database_size + '</i> ' + (is_database_rule ? t_icon : '');
|
||||
var t_size = '注意:此数据库较大,可能为重要数据,请谨慎操作.\n数据库:' + database_size;
|
||||
|
||||
return '<div class="check_layer_database">' +
|
||||
'<span title="数据库:' + item.database.name + '">数据库:' + item.database.name + '</span>' +
|
||||
'<span title="' + t_size + '">大小:' + f_size + '</span>' +
|
||||
'<span title="' + (is_time_rule && item.database.total != 0 ? '重要:此数据库创建时间较早,可能为重要数据,请谨慎操作.' : '') + '时间:' + database_time + '">创建时间:<i ' + (is_time_rule && item.database.total != 0 ? 'class="warning"' : '') + '>' + database_time + '</i></span>' +
|
||||
'</div>'
|
||||
}(item))
|
||||
if ((site_html + database_html) !== '') html += '<div class="check_layer_item">' + site_html + database_html + '</div>';
|
||||
}
|
||||
if (html === '') html = '<div style="text-align: center;width: 100%;height: 100%;line-height: 300px;font-size: 15px;">无数据</div>'
|
||||
$('.check_layer_content').html(html)
|
||||
},
|
||||
yes: function (indes, layers) {
|
||||
if (typeof wname === "function") {
|
||||
wname(data)
|
||||
} else {
|
||||
bt.site.del_site(data, function (rdata) {
|
||||
layer.closeAll()
|
||||
if (rdata.status) site.get_list();
|
||||
if (callback) callback(rdata);
|
||||
bt.msg(rdata);
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
if(bt.get_cookie("is_recycle") || bt.get_cookie("is_recycle")==null){
|
||||
$('[name="path"]').attr('checked',true)
|
||||
}else{
|
||||
$('[name="path"]').removeProp('checked');
|
||||
}
|
||||
}
|
||||
}
|
||||
if("undefined" != typeof bt && bt.hasOwnProperty("firewall") && bt.firewall.hasOwnProperty("add_accept_port")){
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
- 全局搜索替换 https://www.bt.cn/api/ => http://www.example.com/api/(需排除clearModel.py、scanningModel.py、ipsModel.py)
|
||||
|
||||
- 全局搜索替换 http://download.bt.cn/install/update6.sh => http://www.example.com/install/update6.sh
|
||||
- 全局搜索替换 https://download.bt.cn/install/update6.sh => http://www.example.com/install/update6.sh
|
||||
|
||||
- class/ajax.py 文件 \#是否执行升级程序 下面的 public.get_url() 改成 public.GetConfigValue('home')
|
||||
|
||||
@@ -42,22 +42,26 @@
|
||||
|
||||
在 def get_improvement(): 这一行下面加上 return False
|
||||
|
||||
在free_login_area方法内get_free_ips_area替换成get_ips_area
|
||||
|
||||
- class/panelPlugin.py 文件,download_icon方法内替换 public.GetConfigValue('home') => 'https://www.bt.cn'
|
||||
|
||||
- class/panelPlugin.py 文件,删除public.total_keyword(get.query)这一行
|
||||
删除public.total_keyword(get.query)这一行
|
||||
|
||||
- class/panelPlugin.py 文件,set_pyenv方法内,temp_file = public.readFile(filename)这行代码下面加上
|
||||
set_pyenv方法内,temp_file = public.readFile(filename)这行代码下面加上
|
||||
|
||||
```python
|
||||
temp_file = temp_file.replace('wget -O Tpublic.sh', '#wget -O Tpublic.sh')
|
||||
temp_file = temp_file.replace('\cp -rpa Tpublic.sh', '#\cp -rpa Tpublic.sh')
|
||||
temp_file = temp_file.replace('http://download.bt.cn/install/public.sh', 'http://www.example.com/install/public.sh')
|
||||
temp_file = temp_file.replace('https://download.bt.cn/install/public.sh', 'http://www.example.com/install/public.sh')
|
||||
```
|
||||
|
||||
|
||||
- install/install_soft.sh 在bash执行之前加入以下代码
|
||||
|
||||
```shell
|
||||
sed -i "s/http:\/\/download.bt.cn\/install\/public.sh/http:\/\/www.example.com\/install\/public.sh/" lib.sh
|
||||
sed -i "s/https:\/\/download.bt.cn\/install\/public.sh/http:\/\/www.example.com\/install\/public.sh/" lib.sh
|
||||
sed -i "/wget -O Tpublic.sh/d" $name.sh
|
||||
```
|
||||
|
||||
|
@@ -52,10 +52,12 @@ Windows版宝塔由于加密文件太多,无法全部解密,因此无法做
|
||||
|
||||
- 删除最下面 logs_analysis() 这1行
|
||||
|
||||
- 去除首页广告:BTPanel/static/js/index.js 文件删除最下面index.recommend_paid_version()这一行
|
||||
- 去除首页广告:BTPanel/static/js/index.js 文件删除最下面index.recommend_paid_version()这一行以及index.consultancy_services()这一行
|
||||
|
||||
- 去除首页自动检测更新,避免频繁请求云端:BTPanel/static/js/index.js 文件注释掉bt.system.check_update这一段代码外的setTimeout
|
||||
|
||||
- 去除内页广告:BTPanel/templates/default/layout.html 删除getPaymentStatus();这一行
|
||||
|
||||
- [可选]去除各种计算题:复制win/bt.js到 BTPanel/static/ ,在 BTPanel/templates/default/layout.html 的尾部加入
|
||||
|
||||
```javascript
|
||||
|
Reference in New Issue
Block a user