mirror of
https://github.com/midoks/mdserver-web.git
synced 2026-10-10 11:49:26 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d6c6ae5561 | ||
|
|
a6dc15f22d | ||
|
|
360b962bd2 | ||
|
|
37d37e0f1d | ||
|
|
ddc6da9172 | ||
|
|
ceba7ab673 | ||
|
|
384704b8e5 | ||
|
|
232d0c2f74 | ||
|
|
ef8e6f07f5 | ||
|
|
435e565559 | ||
|
|
ec9d7e337d | ||
|
|
b5c7a2a778 | ||
|
|
72d9c9b761 | ||
|
|
30812e1fba | ||
|
|
c95cb07e8d | ||
|
|
f3f2ea8ef0 | ||
|
|
9e5a5192cb | ||
|
|
271b3d448c | ||
|
|
b7424e7195 | ||
|
|
b607527e1f | ||
|
|
3c42a4e450 | ||
|
|
b11fd9508a | ||
|
|
dc0504cf24 | ||
|
|
1d8b82395f | ||
|
|
39ac55760e | ||
|
|
ef6071956d | ||
|
|
bbbe1c84ce | ||
|
|
064252daad | ||
|
|
3cb63c6265 | ||
|
|
b541abad42 | ||
|
|
547027be0d | ||
|
|
d786b2524a | ||
|
|
abac345628 | ||
|
|
d4290cbdd2 | ||
|
|
cfd2d99e24 | ||
|
|
28437ccfb0 | ||
|
|
43bf755609 | ||
|
|
de225fc8b9 | ||
|
|
44f891f7a3 | ||
|
|
64d1387b03 | ||
|
|
51ccbefb04 | ||
|
|
29e3017e51 | ||
|
|
197e2d80c6 | ||
|
|
b8f04043bc | ||
|
|
2ed70b4b96 | ||
|
|
d056c37be5 | ||
|
|
e75abae4b9 | ||
|
|
3e695770d7 | ||
|
|
7301edbc5a | ||
|
|
704b256408 | ||
|
|
e129051a06 | ||
|
|
d38e9f7ad0 | ||
|
|
c696742866 | ||
|
|
046389df99 | ||
|
|
3e244ed227 | ||
|
|
5016aedb0f | ||
|
|
c1cd45a5f3 | ||
|
|
79c9865a5d | ||
|
|
4082f29424 | ||
|
|
d777a29d8c | ||
|
|
04e43e051e | ||
|
|
dffe9a77e7 | ||
|
|
1b1462586e | ||
|
|
f11d2db761 | ||
|
|
842c16540a | ||
|
|
614cc1032f | ||
|
|
ad46b2050e | ||
|
|
8109989927 |
+4
-1
@@ -151,8 +151,10 @@ data/system.db-journal
|
||||
data/hook_*.json
|
||||
data/letsencrypt.json
|
||||
data/basic_auth.json
|
||||
data/notify.json
|
||||
data/api.json
|
||||
data/bind_domain.pl
|
||||
data/unauthorized_status.pl
|
||||
|
||||
plugins/vip_*
|
||||
plugins/own_*
|
||||
@@ -176,4 +178,5 @@ plugins/file_search
|
||||
debug.out
|
||||
|
||||
|
||||
data/unauthorized_status.pl
|
||||
|
||||
|
||||
|
||||
@@ -99,13 +99,15 @@ docker run -itd --name mw-server --privileged=true -p 7200:7200 -p 80:80 -p 443:
|
||||
```
|
||||
|
||||
|
||||
### 版本更新 0.13.1
|
||||
### 版本更新 0.13.2
|
||||
|
||||
* 关闭issue,建立bbs.midoks.me。问题集中处理,发挥群众的力量。
|
||||
* 添加站操作回调钩子site_cb。 网站统计和OP防火墙不再手动重载配置
|
||||
* 修复ubuntu20 pureftp 安装时,端口没有加入安全里
|
||||
* 增加global_static hook关键字,并优化menu的文件加载hook
|
||||
* 各种细节优化。
|
||||
* supervisor添加重启功能。
|
||||
* 加入滚动写入日志 mw.writeFileLog方法。
|
||||
* mysql导出优化优化。
|
||||
* 添加tgbot插件[仅测试]。
|
||||
* TelegramBot机器人通知-加入配置。
|
||||
* mariadb更新版本。
|
||||
* 在线文件编辑优化。
|
||||
|
||||
### JSDelivr安装地址
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ from flask import request
|
||||
|
||||
class config_api:
|
||||
|
||||
__version = '0.13.1'
|
||||
__version = '0.13.2'
|
||||
__api_addr = 'data/api.json'
|
||||
|
||||
def __init__(self):
|
||||
@@ -661,6 +661,60 @@ class config_api:
|
||||
mw.writeLog('面板设置', '将未授权响应状态码设置为:{}'.format(status_code))
|
||||
return mw.returnJson(True, '设置成功!')
|
||||
|
||||
def getNotifyApi(self):
|
||||
# 获取
|
||||
data = mw.getNotifyData(True)
|
||||
return mw.returnData(True, 'ok', data)
|
||||
|
||||
def setNotifyApi(self):
|
||||
tag = request.form.get('tag', '').strip()
|
||||
data = request.form.get('data', '').strip()
|
||||
|
||||
cfg = mw.getNotifyData(False)
|
||||
|
||||
crypt_data = mw.enDoubleCrypt(tag, data)
|
||||
if tag in cfg:
|
||||
cfg[tag]['cfg'] = crypt_data
|
||||
else:
|
||||
t = {'cfg': crypt_data}
|
||||
cfg[tag] = t
|
||||
|
||||
mw.writeNotify(cfg)
|
||||
return mw.returnData(True, '设置成功')
|
||||
|
||||
def setNotifyTestApi(self):
|
||||
# 异步通知验证
|
||||
tag = request.form.get('tag', '').strip()
|
||||
tag_data = request.form.get('data', '').strip()
|
||||
|
||||
if tag == 'tgbot':
|
||||
t = json.loads(tag_data)
|
||||
test_bool = mw.tgbotNotifyTest(t['app_token'], t['chat_id'])
|
||||
if test_bool:
|
||||
return mw.returnData(True, '验证成功')
|
||||
return mw.returnData(False, '验证失败')
|
||||
|
||||
return mw.returnData(False, '暂时未支持该验证')
|
||||
|
||||
def setNotifyEnableApi(self):
|
||||
# 异步通知验证
|
||||
tag = request.form.get('tag', '').strip()
|
||||
tag_enable = request.form.get('enable', '').strip()
|
||||
|
||||
data = mw.getNotifyData(False)
|
||||
op_enable = True
|
||||
op_action = '开启'
|
||||
if tag_enable != 'true':
|
||||
op_enable = False
|
||||
op_action = '关闭'
|
||||
|
||||
if tag in data:
|
||||
data[tag]['enable'] = op_enable
|
||||
|
||||
mw.writeNotify(data)
|
||||
|
||||
return mw.returnData(True, op_action + '成功')
|
||||
|
||||
def getPanelTokenApi(self):
|
||||
api_file = self.__api_addr
|
||||
tmp = mw.readFile(api_file)
|
||||
@@ -853,4 +907,14 @@ class config_api:
|
||||
else:
|
||||
data['hook_global_static'] = []
|
||||
|
||||
# notiy config
|
||||
notify_data = mw.getNotifyData(True)
|
||||
notify_tag_list = ['tgbot', 'email']
|
||||
for tag in notify_tag_list:
|
||||
new_tag = 'notify_' + tag + '_enable'
|
||||
data[new_tag] = ''
|
||||
if tag in notify_data and 'enable' in notify_data[tag]:
|
||||
if notify_data[tag]['enable']:
|
||||
data[new_tag] = 'checked'
|
||||
|
||||
return data
|
||||
|
||||
+184
-6
@@ -22,6 +22,8 @@ import hashlib
|
||||
import shlex
|
||||
import datetime
|
||||
import subprocess
|
||||
import glob
|
||||
|
||||
import re
|
||||
import db
|
||||
from random import Random
|
||||
@@ -80,6 +82,10 @@ def getPanelDataDir():
|
||||
return getRunDir() + '/data'
|
||||
|
||||
|
||||
def getPanelTmp():
|
||||
return getRunDir() + '/tmp'
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return getRootDir() + '/server'
|
||||
|
||||
@@ -536,6 +542,14 @@ def getDate():
|
||||
return time.strftime('%Y-%m-%d %X', time.localtime())
|
||||
|
||||
|
||||
def getDateFromNow(tf_format="%Y-%m-%d %H:%M:%S", time_zone="Asia/Shanghai"):
|
||||
# 取格式时间
|
||||
import time
|
||||
os.environ['TZ'] = time_zone
|
||||
time.tzset()
|
||||
return time.strftime(tf_format, time.localtime())
|
||||
|
||||
|
||||
def getDataFromInt(val):
|
||||
time_format = '%Y-%m-%d %H:%M:%S'
|
||||
time_str = time.localtime(val)
|
||||
@@ -551,10 +565,39 @@ def writeLog(stype, msg, args=()):
|
||||
uid = session['uid']
|
||||
except Exception as e:
|
||||
pass
|
||||
# print(getTracebackInfo())
|
||||
# writeFileLog(getTracebackInfo())
|
||||
return writeDbLog(stype, msg, args, uid)
|
||||
|
||||
|
||||
def writeFileLog(msg, path=None, limit_size=50 * 1024 * 1024, save_limit=3):
|
||||
log_file = getServerDir() + '/mdserver-web/logs/debug.log'
|
||||
if path != None:
|
||||
log_file = path
|
||||
|
||||
if os.path.exists(log_file):
|
||||
size = os.path.getsize(log_file)
|
||||
if size > limit_size:
|
||||
log_file_rename = log_file + "_" + \
|
||||
time.strftime("%Y-%m-%d_%H%M%S") + '.log'
|
||||
os.rename(log_file, log_file_rename)
|
||||
logs = sorted(glob.glob(log_file + "_*"))
|
||||
count = len(logs)
|
||||
save_limit = count - save_limit
|
||||
for i in range(count):
|
||||
if i > save_limit:
|
||||
break
|
||||
os.remove(logs[i])
|
||||
# print('|---多余日志[' + logs[i] + ']已删除!')
|
||||
|
||||
f = open(log_file, 'ab+')
|
||||
msg += "\n"
|
||||
if __name__ == '__main__':
|
||||
print(msg)
|
||||
f.write(msg.encode('utf-8'))
|
||||
f.close()
|
||||
return True
|
||||
|
||||
|
||||
def writeDbLog(stype, msg, args=(), uid=1):
|
||||
try:
|
||||
import time
|
||||
@@ -673,7 +716,7 @@ def enCrypt(key, strings):
|
||||
result = f.encrypt(strings)
|
||||
return result.decode('utf-8')
|
||||
except:
|
||||
print(getTracebackInfo())
|
||||
writeFileLog(getTracebackInfo())
|
||||
return strings
|
||||
|
||||
|
||||
@@ -692,7 +735,7 @@ def deCrypt(key, strings):
|
||||
result = f.decrypt(strings).decode('utf-8')
|
||||
return result
|
||||
except:
|
||||
print(getTracebackInfo())
|
||||
writeFileLog(getTracebackInfo())
|
||||
return strings
|
||||
|
||||
|
||||
@@ -711,7 +754,7 @@ def enDoubleCrypt(key, strings):
|
||||
result = f.encrypt(strings)
|
||||
return result.decode('utf-8')
|
||||
except:
|
||||
print(getTracebackInfo())
|
||||
writeFileLog(getTracebackInfo())
|
||||
return strings
|
||||
|
||||
|
||||
@@ -729,7 +772,7 @@ def deDoubleCrypt(key, strings):
|
||||
result = f.decrypt(strings).decode('utf-8')
|
||||
return result
|
||||
except:
|
||||
print(getTracebackInfo())
|
||||
writeFileLog(getTracebackInfo())
|
||||
return strings
|
||||
|
||||
|
||||
@@ -1533,7 +1576,7 @@ def getCertName(certPath):
|
||||
result['notAfter'], "%Y-%m-%d")) - time.time()) / 86400)
|
||||
return result
|
||||
except Exception as e:
|
||||
# print(getTracebackInfo())
|
||||
writeFileLog(getTracebackInfo())
|
||||
return None
|
||||
|
||||
|
||||
@@ -1631,6 +1674,141 @@ def getMyORMDb():
|
||||
o = ormDb.ORM()
|
||||
return o
|
||||
|
||||
##################### notify start #########################################
|
||||
|
||||
|
||||
def initNotifyConfig():
|
||||
p = getNotifyPath()
|
||||
if not os.path.exists(p):
|
||||
writeFile(p, '{}')
|
||||
return True
|
||||
|
||||
|
||||
def getNotifyPath():
|
||||
path = 'data/notify.json'
|
||||
return path
|
||||
|
||||
|
||||
def getNotifyData(is_parse=False):
|
||||
initNotifyConfig()
|
||||
notify_file = getNotifyPath()
|
||||
notify_data = readFile(notify_file)
|
||||
|
||||
data = json.loads(notify_data)
|
||||
|
||||
if is_parse:
|
||||
tag_list = ['tgbot']
|
||||
for t in tag_list:
|
||||
if t in data and 'cfg' in data[t]:
|
||||
data[t]['data'] = json.loads(deDoubleCrypt(t, data[t]['cfg']))
|
||||
return data
|
||||
|
||||
|
||||
def writeNotify(data):
|
||||
p = getNotifyPath()
|
||||
return writeFile(p, json.dumps(data))
|
||||
|
||||
|
||||
def tgbotNotifyChatID():
|
||||
data = getNotifyData(True)
|
||||
if 'tgbot' in data and 'enable' in data['tgbot']:
|
||||
if data['tgbot']['enable']:
|
||||
t = data['tgbot']['data']
|
||||
return t['chat_id']
|
||||
return ''
|
||||
|
||||
|
||||
def tgbotNotifyObject():
|
||||
data = getNotifyData(True)
|
||||
if 'tgbot' in data and 'enable' in data['tgbot']:
|
||||
if data['tgbot']['enable']:
|
||||
t = data['tgbot']['data']
|
||||
import telebot
|
||||
bot = telebot.TeleBot(app_token)
|
||||
return True, bot
|
||||
return False, None
|
||||
|
||||
|
||||
def tgbotNotifyMessage(app_token, chat_id, msg):
|
||||
import telebot
|
||||
bot = telebot.TeleBot(app_token)
|
||||
try:
|
||||
data = bot.send_message(chat_id, msg)
|
||||
return True
|
||||
except Exception as e:
|
||||
writeFileLog(str(e))
|
||||
return False
|
||||
|
||||
|
||||
def tgbotNotifyHttpPost(app_token, chat_id, msg):
|
||||
try:
|
||||
url = 'https://api.telegram.org/bot' + app_token + '/sendMessage'
|
||||
post_data = {
|
||||
'chat_id': chat_id,
|
||||
'text': msg,
|
||||
}
|
||||
rdata = httpPost(url, post_data)
|
||||
return True
|
||||
except Exception as e:
|
||||
writeFileLog(str(e))
|
||||
return False
|
||||
|
||||
|
||||
def tgbotNotifyTest(app_token, chat_id):
|
||||
msg = 'MW-通知验证测试OK'
|
||||
return tgbotNotifyHttpPost(app_token, chat_id, msg)
|
||||
|
||||
|
||||
def notifyMessageTry(msg, stype='common', trigger_time=300, is_write_log=True):
|
||||
|
||||
lock_file = getPanelTmp() + '/notify_lock.json'
|
||||
if not os.path.exists(lock_file):
|
||||
writeFile(lock_file, '{}')
|
||||
|
||||
lock_data = json.loads(readFile(lock_file))
|
||||
if stype in lock_data:
|
||||
diff_time = time.time() - lock_data[stype]['do_time']
|
||||
if diff_time >= trigger_time:
|
||||
lock_data[stype]['do_time'] = time.time()
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
lock_data[stype] = {'do_time': time.time()}
|
||||
|
||||
writeFile(lock_file, json.dumps(lock_data))
|
||||
|
||||
if is_write_log:
|
||||
writeLog("通知管理[" + stype + "]", msg)
|
||||
|
||||
data = getNotifyData(True)
|
||||
# tag_list = ['tgbot', 'email']
|
||||
# tagbot
|
||||
do_notify = False
|
||||
if 'tgbot' in data and 'enable' in data['tgbot']:
|
||||
if data['tgbot']['enable']:
|
||||
t = data['tgbot']['data']
|
||||
i = sys.version_info
|
||||
|
||||
# telebot 在python小于3.7无法使用
|
||||
if i[0] < 3 or i[1] < 7:
|
||||
do_notify = tgbotNotifyHttpPost(
|
||||
t['app_token'], t['chat_id'], msg)
|
||||
else:
|
||||
do_notify = tgbotNotifyMessage(
|
||||
t['app_token'], t['chat_id'], msg)
|
||||
return do_notify
|
||||
|
||||
|
||||
def notifyMessage(msg, stype='common', trigger_time=300, is_write_log=True):
|
||||
try:
|
||||
return notifyMessageTry(msg, stype, trigger_time, is_write_log)
|
||||
except Exception as e:
|
||||
writeFileLog(getTracebackInfo())
|
||||
return False
|
||||
|
||||
|
||||
##################### notify end #########################################
|
||||
|
||||
|
||||
##################### ssh start #########################################
|
||||
def getSshDir():
|
||||
|
||||
@@ -65,6 +65,9 @@ class ORM:
|
||||
def setCharset(self, charset):
|
||||
self.__DB_CHARSET = charset
|
||||
|
||||
def setHost(self, host):
|
||||
self.__DB_HOST = host
|
||||
|
||||
def setPort(self, port):
|
||||
self.__DB_PORT = port
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"uninstall_pre_inspection":true,
|
||||
"checks": "server/mariadb",
|
||||
"path": "server/mariadb",
|
||||
"versions":["10.6","10.7","10.8","10.9"],
|
||||
"versions":["10.6","10.7","10.8","10.9","10.11","11.0"],
|
||||
"shell":"install.sh",
|
||||
"checks":"server/mariadb",
|
||||
"path":"server/mariadb",
|
||||
|
||||
Executable
+119
@@ -0,0 +1,119 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
#https://dev.mysql.com/downloads/mysql/5.5.html#downloads
|
||||
#https://dev.mysql.com/downloads/file/?id=480541
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
sysName=`uname`
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
mariadbDir=${serverPath}/source/mariadb
|
||||
|
||||
MY_VER=10.11.2
|
||||
|
||||
Install_app()
|
||||
{
|
||||
mkdir -p ${mariadbDir}
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
|
||||
if id mysql &> /dev/null ;then
|
||||
echo "mysql uid is `id -u www`"
|
||||
echo "mysql shell is `grep "^www:" /etc/passwd |cut -d':' -f7 `"
|
||||
else
|
||||
groupadd mysql
|
||||
useradd -g mysql mysql
|
||||
fi
|
||||
|
||||
if [ "$sysName" != "Darwin" ];then
|
||||
mkdir -p /var/log/mariadb
|
||||
touch /var/log/mariadb/mariadb.log
|
||||
fi
|
||||
|
||||
# ----- cpu start ------
|
||||
if [ -z "${cpuCore}" ]; then
|
||||
cpuCore="1"
|
||||
fi
|
||||
|
||||
if [ -f /proc/cpuinfo ];then
|
||||
cpuCore=`cat /proc/cpuinfo | grep "processor" | wc -l`
|
||||
fi
|
||||
|
||||
MEM_INFO=$(free -m|grep Mem|awk '{printf("%.f",($2)/1024)}')
|
||||
if [ "${cpuCore}" != "1" ] && [ "${MEM_INFO}" != "0" ];then
|
||||
if [ "${cpuCore}" -gt "${MEM_INFO}" ];then
|
||||
cpuCore="${MEM_INFO}"
|
||||
fi
|
||||
else
|
||||
cpuCore="1"
|
||||
fi
|
||||
|
||||
if [ "$cpuCore" -gt "2" ];then
|
||||
cpuCore=`echo "$cpuCore" | awk '{printf("%.f",($1)*0.8)}'`
|
||||
else
|
||||
cpuCore="1"
|
||||
fi
|
||||
# ----- cpu end ------
|
||||
|
||||
# if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
|
||||
# wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://mirrors.aliyun.com/mariadb/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
||||
# fi
|
||||
|
||||
# https://downloads.mariadb.org/interstitial/mariadb-10.9.1/source/mariadb-10.9.1.tar.gz
|
||||
if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
|
||||
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://archive.mariadb.org/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
||||
fi
|
||||
|
||||
if [ ! -d ${mariadbDir}/mariadb-${MY_VER} ];then
|
||||
cd ${mariadbDir} && tar -zxvf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
|
||||
fi
|
||||
|
||||
|
||||
if [ ! -d $serverPath/mariadb ];then
|
||||
cd ${mariadbDir}/mariadb-${MY_VER} && cmake \
|
||||
-DCMAKE_INSTALL_PREFIX=$serverPath/mariadb \
|
||||
-DMYSQL_DATADIR=$serverPath/mariadb/data/ \
|
||||
-DMYSQL_USER=mysql \
|
||||
-DMYSQL_UNIX_ADDR=$serverPath/mariadb/mysql.sock \
|
||||
-DWITH_MYISAM_STORAGE_ENGINE=1 \
|
||||
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
|
||||
-DWITH_MEMORY_STORAGE_ENGINE=1 \
|
||||
-DENABLED_LOCAL_INFILE=1 \
|
||||
-DWITH_PARTITION_STORAGE_ENGINE=1 \
|
||||
-DEXTRA_CHARSETS=all \
|
||||
-DDEFAULT_CHARSET=utf8mb4 \
|
||||
-DDEFAULT_COLLATION=utf8mb4_general_ci \
|
||||
-DCMAKE_C_COMPILER=/usr/bin/gcc \
|
||||
-DCMAKE_CXX_COMPILER=/usr/bin/g++
|
||||
make -j${cpuCore} && make install && make clean
|
||||
|
||||
if [ -d $serverPath/mariadb ];then
|
||||
echo '10.11' > $serverPath/mariadb/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
else
|
||||
echo '安装失败' > $install_tmp
|
||||
echo 'install fail'>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
|
||||
}
|
||||
|
||||
Uninstall_app()
|
||||
{
|
||||
rm -rf $serverPath/mariadb
|
||||
echo '卸载完成' > $install_tmp
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_app
|
||||
else
|
||||
Uninstall_app
|
||||
fi
|
||||
@@ -13,7 +13,7 @@ sysName=`uname`
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
mariadbDir=${serverPath}/source/mariadb
|
||||
|
||||
MY_VER=10.6.9
|
||||
MY_VER=10.6.12
|
||||
|
||||
Install_app()
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@ sysName=`uname`
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
mariadbDir=${serverPath}/source/mariadb
|
||||
|
||||
MY_VER=10.7.4
|
||||
MY_VER=10.7.8
|
||||
|
||||
Install_app()
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@ sysName=`uname`
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
mariadbDir=${serverPath}/source/mariadb
|
||||
|
||||
MY_VER=10.8.5
|
||||
MY_VER=10.8.7
|
||||
|
||||
Install_app()
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@ sysName=`uname`
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
mariadbDir=${serverPath}/source/mariadb
|
||||
|
||||
MY_VER=10.9.2
|
||||
MY_VER=10.9.5
|
||||
|
||||
Install_app()
|
||||
{
|
||||
|
||||
Executable
+119
@@ -0,0 +1,119 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
#https://dev.mysql.com/downloads/mysql/5.5.html#downloads
|
||||
#https://dev.mysql.com/downloads/file/?id=480541
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
sysName=`uname`
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
mariadbDir=${serverPath}/source/mariadb
|
||||
|
||||
MY_VER=11.0.1
|
||||
|
||||
Install_app()
|
||||
{
|
||||
mkdir -p ${mariadbDir}
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
|
||||
if id mysql &> /dev/null ;then
|
||||
echo "mysql uid is `id -u www`"
|
||||
echo "mysql shell is `grep "^www:" /etc/passwd |cut -d':' -f7 `"
|
||||
else
|
||||
groupadd mysql
|
||||
useradd -g mysql mysql
|
||||
fi
|
||||
|
||||
if [ "$sysName" != "Darwin" ];then
|
||||
mkdir -p /var/log/mariadb
|
||||
touch /var/log/mariadb/mariadb.log
|
||||
fi
|
||||
|
||||
# ----- cpu start ------
|
||||
if [ -z "${cpuCore}" ]; then
|
||||
cpuCore="1"
|
||||
fi
|
||||
|
||||
if [ -f /proc/cpuinfo ];then
|
||||
cpuCore=`cat /proc/cpuinfo | grep "processor" | wc -l`
|
||||
fi
|
||||
|
||||
MEM_INFO=$(free -m|grep Mem|awk '{printf("%.f",($2)/1024)}')
|
||||
if [ "${cpuCore}" != "1" ] && [ "${MEM_INFO}" != "0" ];then
|
||||
if [ "${cpuCore}" -gt "${MEM_INFO}" ];then
|
||||
cpuCore="${MEM_INFO}"
|
||||
fi
|
||||
else
|
||||
cpuCore="1"
|
||||
fi
|
||||
|
||||
if [ "$cpuCore" -gt "2" ];then
|
||||
cpuCore=`echo "$cpuCore" | awk '{printf("%.f",($1)*0.8)}'`
|
||||
else
|
||||
cpuCore="1"
|
||||
fi
|
||||
# ----- cpu end ------
|
||||
|
||||
# if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
|
||||
# wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://mirrors.aliyun.com/mariadb/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
||||
# fi
|
||||
|
||||
# https://downloads.mariadb.org/interstitial/mariadb-10.9.1/source/mariadb-10.9.1.tar.gz
|
||||
if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
|
||||
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://archive.mariadb.org/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
||||
fi
|
||||
|
||||
if [ ! -d ${mariadbDir}/mariadb-${MY_VER} ];then
|
||||
cd ${mariadbDir} && tar -zxvf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
|
||||
fi
|
||||
|
||||
|
||||
if [ ! -d $serverPath/mariadb ];then
|
||||
cd ${mariadbDir}/mariadb-${MY_VER} && cmake \
|
||||
-DCMAKE_INSTALL_PREFIX=$serverPath/mariadb \
|
||||
-DMYSQL_DATADIR=$serverPath/mariadb/data/ \
|
||||
-DMYSQL_USER=mysql \
|
||||
-DMYSQL_UNIX_ADDR=$serverPath/mariadb/mysql.sock \
|
||||
-DWITH_MYISAM_STORAGE_ENGINE=1 \
|
||||
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
|
||||
-DWITH_MEMORY_STORAGE_ENGINE=1 \
|
||||
-DENABLED_LOCAL_INFILE=1 \
|
||||
-DWITH_PARTITION_STORAGE_ENGINE=1 \
|
||||
-DEXTRA_CHARSETS=all \
|
||||
-DDEFAULT_CHARSET=utf8mb4 \
|
||||
-DDEFAULT_COLLATION=utf8mb4_general_ci \
|
||||
-DCMAKE_C_COMPILER=/usr/bin/gcc \
|
||||
-DCMAKE_CXX_COMPILER=/usr/bin/g++
|
||||
make -j${cpuCore} && make install && make clean
|
||||
|
||||
if [ -d $serverPath/mariadb ];then
|
||||
echo '10.11' > $serverPath/mariadb/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
else
|
||||
echo '安装失败' > $install_tmp
|
||||
echo 'install fail'>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
|
||||
}
|
||||
|
||||
Uninstall_app()
|
||||
{
|
||||
rm -rf $serverPath/mariadb
|
||||
echo '卸载完成' > $install_tmp
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_app
|
||||
else
|
||||
Uninstall_app
|
||||
fi
|
||||
@@ -2474,7 +2474,8 @@ def doFullSyncUser(version=''):
|
||||
|
||||
if not os.path.exists(bak_file):
|
||||
dump_sql_data = getServerDir() + "/bin/mysqldump " + dmp_option + " --force --opt --default-character-set=utf8 --single-transaction -h" + ip + " -P" + \
|
||||
port + " -u" + user + " -p" + apass + " " + sync_db + " > " + bak_file
|
||||
port + " -u" + user + " -p" + apass + \
|
||||
" --ssl-mode=DISABLED " + sync_db + " > " + bak_file
|
||||
mw.execShell(dump_sql_data)
|
||||
|
||||
writeDbSyncStatus({'code': 2, 'msg': '本地导入数据...', 'progress': 40})
|
||||
|
||||
@@ -2434,7 +2434,8 @@ def doFullSyncUser(version=''):
|
||||
|
||||
if not os.path.exists(bak_file):
|
||||
dump_sql_data = getServerDir() + "/bin/mysqldump " + dmp_option + " --force --opt --default-character-set=utf8 --single-transaction -h" + ip + " -P" + \
|
||||
port + " -u" + user + " -p" + apass + " " + sync_db + " > " + bak_file
|
||||
port + " -u" + user + " -p" + apass + \
|
||||
" --ssl-mode=DISABLED " + sync_db + " > " + bak_file
|
||||
mw.execShell(dump_sql_data)
|
||||
|
||||
writeDbSyncStatus({'code': 2, 'msg': '本地导入数据...', 'progress': 40})
|
||||
|
||||
@@ -71,7 +71,7 @@ log_replica_updates = 1
|
||||
# Prevent replication from starting automatically with MySQL
|
||||
#skip_replica_start = 1
|
||||
#replicate-do-db
|
||||
slave_skip_errors=1062
|
||||
replica_skip_errors=1062
|
||||
replicate-ignore-db = information_schema
|
||||
replicate-ignore-db = performance_schema
|
||||
replicate-ignore-db = mysql
|
||||
|
||||
@@ -2665,8 +2665,10 @@ def doFullSyncUser(version=''):
|
||||
writeDbSyncStatus({'code': 1, 'msg': '远程导出数据...', 'progress': 20})
|
||||
|
||||
if not os.path.exists(bak_file):
|
||||
dump_sql_data = getServerDir() + "/bin/mysqldump " + dmp_option + " --force --opt --default-character-set=utf8 --single-transaction -h" + ip + " -P" + \
|
||||
port + " -u" + user + " -p\"" + apass + "\" " + sync_db + " > " + bak_file
|
||||
dump_sql_data = getServerDir() + "/bin/mysqldump " + dmp_option + " --force --opt --default-character-set=utf8 --single-transaction -h" + ip + " -P" + \
|
||||
port + " -u" + user + " -p\"" + apass + \
|
||||
"\" --ssl-mode=DISABLED " + sync_db + " > " + bak_file
|
||||
# print(dump_sql_data)
|
||||
mw.execShell(dump_sql_data)
|
||||
|
||||
writeDbSyncStatus({'code': 2, 'msg': '本地导入数据...', 'progress': 40})
|
||||
|
||||
@@ -344,13 +344,22 @@ local function waf_cc_increase()
|
||||
local make_uri = "/"..make_uri_str
|
||||
|
||||
if params['uri_request_args']['token'] then
|
||||
ngx.header.content_type = "application/json"
|
||||
local args_token = params['uri_request_args']['token']
|
||||
if args_token == make_token then
|
||||
ngx.shared.waf_limit:set(cache_token, 1, config['safe_verify']['time'])
|
||||
ngx.shared.waf_limit:set(cache_token, 1, tonumber(config['safe_verify']['time']))
|
||||
local data = get_return_state(0, "ok")
|
||||
ngx.say(json.encode(data))
|
||||
ngx.exit(200)
|
||||
end
|
||||
|
||||
-- C:D("debug[args]:"..tostring(params['uri_request_args']['debug']))
|
||||
-- if params['uri_request_args']['debug'] == 'ok' then
|
||||
-- ngx.header.content_type = "application/json"
|
||||
-- local data = get_return_state(0, "ok")
|
||||
-- ngx.say(json.encode(data))
|
||||
-- ngx.exit(200)
|
||||
-- end
|
||||
end
|
||||
|
||||
local cc_html = ngx.re.gsub(cc_safe_js_html, "{uri}", make_uri_str)
|
||||
|
||||
@@ -214,7 +214,8 @@ def initdStatus():
|
||||
if mw.isAppleSystem():
|
||||
return "Apple Computer does not support"
|
||||
|
||||
shell_cmd = 'systemctl status redis | grep loaded | grep "enabled;"'
|
||||
shell_cmd = 'systemctl status ' + \
|
||||
getPluginName() + ' | grep loaded | grep "enabled;"'
|
||||
data = mw.execShell(shell_cmd)
|
||||
if data[0] == '':
|
||||
return 'fail'
|
||||
@@ -225,7 +226,7 @@ def initdInstall():
|
||||
if mw.isAppleSystem():
|
||||
return "Apple Computer does not support"
|
||||
|
||||
mw.execShell('systemctl enable redis')
|
||||
mw.execShell('systemctl enable ' + getPluginName())
|
||||
return 'ok'
|
||||
|
||||
|
||||
@@ -233,7 +234,7 @@ def initdUinstall():
|
||||
if mw.isAppleSystem():
|
||||
return "Apple Computer does not support"
|
||||
|
||||
mw.execShell('systemctl disable redis')
|
||||
mw.execShell('systemctl disable ' + getPluginName())
|
||||
return 'ok'
|
||||
|
||||
|
||||
|
||||
@@ -1,14 +1,3 @@
|
||||
|
||||
function str2Obj(str){
|
||||
var data = {};
|
||||
kv = str.split('&');
|
||||
for(i in kv){
|
||||
v = kv[i].split('=');
|
||||
data[v[0]] = v[1];
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
function redisPost(method, version, args,callback){
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
|
||||
@@ -18,7 +7,7 @@ function redisPost(method, version, args,callback){
|
||||
req_data['version'] = version;
|
||||
|
||||
if (typeof(args) == 'string'){
|
||||
req_data['args'] = JSON.stringify(str2Obj(args));
|
||||
req_data['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
@@ -46,7 +35,7 @@ function redisPostCallbak(method, version, args,callback){
|
||||
args['version'] = version;
|
||||
|
||||
if (typeof(args) == 'string'){
|
||||
req_data['args'] = JSON.stringify(str2Obj(args));
|
||||
req_data['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
.code span {display: block;margin-left: 15px;margin-bottom: 0;}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
resetPluginWinWidth(800);
|
||||
resetPluginWinWidth(850);
|
||||
$.getScript( "/plugins/file?name=supervisor&f=js/supervisor.js", function(){
|
||||
pluginService('supervisor');
|
||||
});
|
||||
|
||||
@@ -220,7 +220,8 @@ def getSupList():
|
||||
infos = fr.readlines()
|
||||
for line in infos:
|
||||
if "command=" in line.strip():
|
||||
d["command"] = line.strip().split('=')[1]
|
||||
# d["command"] = line.strip().split('=')[1]
|
||||
d["command"] = "子配置查看"
|
||||
if "user=" in line.strip():
|
||||
d["user"] = line.strip().split('=')[1]
|
||||
if "priority=" in line.strip():
|
||||
@@ -329,6 +330,27 @@ def startJob():
|
||||
return mw.returnJson(True, action + '[' + name + ']成功!')
|
||||
|
||||
|
||||
def restartJob():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['name', 'status'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
supCtl = 'supervisorctl -c ' + getServerDir() + "/supervisor.conf"
|
||||
|
||||
name = args['name']
|
||||
status = args['status']
|
||||
|
||||
cmd = supCtl + " stop " + name
|
||||
data = mw.execShell(cmd)
|
||||
cmd = supCtl + " start " + name
|
||||
data = mw.execShell(cmd)
|
||||
|
||||
if data[1] != '':
|
||||
return mw.returnJson(False, '[' + name + ']重启失败!')
|
||||
return mw.returnJson(True, '[' + name + ']重启成功!')
|
||||
|
||||
|
||||
def delJob():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['name'])
|
||||
@@ -440,8 +462,9 @@ def configTpl():
|
||||
pathFile = os.listdir(path)
|
||||
tmp = []
|
||||
for one in pathFile:
|
||||
file = path + '/' + one
|
||||
tmp.append(file)
|
||||
if one.endswith(".ini"):
|
||||
file = path + '/' + one
|
||||
tmp.append(file)
|
||||
return mw.getJson(tmp)
|
||||
|
||||
|
||||
@@ -567,6 +590,8 @@ if __name__ == "__main__":
|
||||
print(addJob())
|
||||
elif func == 'start_job':
|
||||
print(startJob())
|
||||
elif func == 'restart_job':
|
||||
print(restartJob())
|
||||
elif func == 'del_job':
|
||||
print(delJob())
|
||||
elif func == 'update_job':
|
||||
|
||||
@@ -70,6 +70,7 @@ function supList(page, search){
|
||||
|
||||
list += '<td style="text-align:right">\
|
||||
<a href="javascript:;" class="btlink" onclick="startOrStop(\''+rdata.data[i]['program']+'\',\''+sup_status+'\')" title="启动|停止">'+sup_status_desc+'</a> | ' +
|
||||
'<a href="javascript:;" class="btlink" onclick="restartJob(\''+rdata.data[i]['program']+'\',\''+sup_status+'\')" title="重启">重启</a> | ' +
|
||||
'<a href="javascript:;" class="btlink" onclick="updateJob(\''+rdata.data[i]['program']+'\')">修改</a> | ' +
|
||||
'<a href="javascript:;" class="btlink" onclick="delJob(\''+rdata.data[i]['program']+'\')" title="删除">删除</a>' +
|
||||
'</td>';
|
||||
@@ -128,6 +129,16 @@ function startOrStop(name,status){
|
||||
});
|
||||
}
|
||||
|
||||
function restartJob(name,status){
|
||||
myPost('restart_job',{'name':name,'status':status}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
layer.msg(rdata.msg,{icon:rdata.status?1:2});
|
||||
setTimeout(function(){
|
||||
supList(1,10);
|
||||
},2000);
|
||||
});
|
||||
}
|
||||
|
||||
function updateJob(name){
|
||||
myPost('get_job_info',{'name':name},function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 974 B |
Executable
+25
@@ -0,0 +1,25 @@
|
||||
<div class="bt-form">
|
||||
<div class='plugin_version'></div>
|
||||
<div class="bt-w-main">
|
||||
<div class="bt-w-menu">
|
||||
<p class="bgw" onclick="pluginService('tgbot');">服务</p>
|
||||
<p onclick="pluginInitD('tgbot');">自启动</p>
|
||||
<p onclick="botConf();">Bot配置</p>
|
||||
<p onclick="pluginLogs('tgbot','','run_log');">日志</p>
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="soft-man-con"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
.conf_p span{
|
||||
width: 70px;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
resetPluginWinHeight(300);
|
||||
$.getScript( "/plugins/file?name=tgbot&f=js/tgbot.js", function(){
|
||||
pluginService('tgbot');
|
||||
});
|
||||
</script>
|
||||
Executable
+245
@@ -0,0 +1,245 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import json
|
||||
import base64
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
app_debug = False
|
||||
if mw.isAppleSystem():
|
||||
app_debug = True
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'tgbot'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return mw.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return mw.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getInitDFile():
|
||||
if app_debug:
|
||||
return '/tmp/' + getPluginName()
|
||||
return '/etc/init.d/' + getPluginName()
|
||||
|
||||
|
||||
def getConfigData():
|
||||
cfg_path = getServerDir() + "/data.cfg"
|
||||
if not os.path.exists(cfg_path):
|
||||
mw.writeFile(cfg_path, '{}')
|
||||
t = mw.readFile(cfg_path)
|
||||
return json.loads(t)
|
||||
|
||||
|
||||
def writeConf(data):
|
||||
cfg_path = getServerDir() + "/data.cfg"
|
||||
mw.writeFile(cfg_path, json.dumps(data))
|
||||
return True
|
||||
|
||||
|
||||
def getInitDTpl():
|
||||
path = getPluginDir() + "/init.d/" + getPluginName() + ".tpl"
|
||||
return path
|
||||
|
||||
|
||||
def getArgs():
|
||||
args = sys.argv[2:]
|
||||
tmp = {}
|
||||
args_len = len(args)
|
||||
if args_len == 1:
|
||||
t = args[0].strip('{').strip('}')
|
||||
if t.strip() == '':
|
||||
tmp = []
|
||||
else:
|
||||
t = t.split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
tmp[t[0]] = t[1]
|
||||
elif args_len > 1:
|
||||
for i in range(len(args)):
|
||||
t = args[i].split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
return tmp
|
||||
|
||||
|
||||
def checkArgs(data, ck=[]):
|
||||
for i in range(len(ck)):
|
||||
if not ck[i] in data:
|
||||
return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!'))
|
||||
return (True, mw.returnJson(True, 'ok'))
|
||||
|
||||
|
||||
def status():
|
||||
data = mw.execShell(
|
||||
"ps -ef|grep tgbot |grep -v grep | grep -v mdserver-web | awk '{print $2}'")
|
||||
if data[0] == '':
|
||||
return 'stop'
|
||||
return 'start'
|
||||
|
||||
|
||||
def initDreplace():
|
||||
|
||||
file_tpl = getInitDTpl()
|
||||
service_path = mw.getServerDir()
|
||||
app_path = service_path + '/' + getPluginName()
|
||||
|
||||
initD_path = getServerDir() + '/init.d'
|
||||
if not os.path.exists(initD_path):
|
||||
os.mkdir(initD_path)
|
||||
file_bin = initD_path + '/' + getPluginName()
|
||||
|
||||
# initd replace
|
||||
# if not os.path.exists(file_bin):
|
||||
content = mw.readFile(file_tpl)
|
||||
content = content.replace('{$SERVER_PATH}', service_path + '/mdserver-web')
|
||||
content = content.replace('{$APP_PATH}', app_path)
|
||||
|
||||
mw.writeFile(file_bin, content)
|
||||
mw.execShell('chmod +x ' + file_bin)
|
||||
|
||||
# systemd
|
||||
systemDir = mw.systemdCfgDir()
|
||||
systemService = systemDir + '/tgbot.service'
|
||||
systemServiceTpl = getPluginDir() + '/init.d/tgbot.service.tpl'
|
||||
if os.path.exists(systemDir) and not os.path.exists(systemService):
|
||||
service_path = mw.getServerDir()
|
||||
se_content = mw.readFile(systemServiceTpl)
|
||||
se_content = se_content.replace('{$APP_PATH}', app_path)
|
||||
mw.writeFile(systemService, se_content)
|
||||
mw.execShell('systemctl daemon-reload')
|
||||
|
||||
return file_bin
|
||||
|
||||
|
||||
def tbOp(method):
|
||||
file = initDreplace()
|
||||
|
||||
if not mw.isAppleSystem():
|
||||
data = mw.execShell('systemctl ' + method + ' ' + getPluginName())
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
data = mw.execShell(file + ' ' + method)
|
||||
print(data)
|
||||
# if data[1] == '':
|
||||
# return 'ok'
|
||||
return 'ok'
|
||||
|
||||
|
||||
def start():
|
||||
return tbOp('start')
|
||||
|
||||
|
||||
def stop():
|
||||
return tbOp('stop')
|
||||
|
||||
|
||||
def restart():
|
||||
status = tbOp('restart')
|
||||
return status
|
||||
|
||||
|
||||
def reload():
|
||||
|
||||
tgbot_tpl = getPluginDir() + '/startup/tgbot.py'
|
||||
tgbot_dst = getServerDir() + '/tgbot.py'
|
||||
|
||||
content = mw.readFile(tgbot_tpl)
|
||||
mw.writeFile(tgbot_dst, content)
|
||||
|
||||
return tbOp('reload')
|
||||
|
||||
|
||||
def initdStatus():
|
||||
if mw.isAppleSystem():
|
||||
return "Apple Computer does not support"
|
||||
|
||||
shell_cmd = 'systemctl status ' + \
|
||||
getPluginName() + ' | grep loaded | grep "enabled;"'
|
||||
data = mw.execShell(shell_cmd)
|
||||
if data[0] == '':
|
||||
return 'fail'
|
||||
return 'ok'
|
||||
|
||||
|
||||
def initdInstall():
|
||||
if mw.isAppleSystem():
|
||||
return "Apple Computer does not support"
|
||||
|
||||
mw.execShell('systemctl enable ' + getPluginName())
|
||||
return 'ok'
|
||||
|
||||
|
||||
def initdUinstall():
|
||||
if mw.isAppleSystem():
|
||||
return "Apple Computer does not support"
|
||||
|
||||
mw.execShell('systemctl disable ' + getPluginName())
|
||||
return 'ok'
|
||||
|
||||
|
||||
def getBotConf():
|
||||
data = getConfigData()
|
||||
if 'bot' in data:
|
||||
|
||||
return mw.returnJson(True, 'ok', data['bot'])
|
||||
return mw.returnJson(False, 'ok', {})
|
||||
|
||||
|
||||
def setBotConf():
|
||||
args = getArgs()
|
||||
data_args = checkArgs(args, ['app_token'])
|
||||
if not data_args[0]:
|
||||
return data_args[1]
|
||||
|
||||
data = getConfigData()
|
||||
args['app_token'] = base64.b64decode(args['app_token']).decode('ascii')
|
||||
data['bot'] = args
|
||||
writeConf(data)
|
||||
|
||||
return mw.returnJson(True, '保存成功!', [])
|
||||
|
||||
|
||||
def runLog():
|
||||
p = getServerDir() + '/task.log'
|
||||
return p
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
func = sys.argv[1]
|
||||
if func == 'status':
|
||||
print(status())
|
||||
elif func == 'start':
|
||||
print(start())
|
||||
elif func == 'stop':
|
||||
print(stop())
|
||||
elif func == 'restart':
|
||||
print(restart())
|
||||
elif func == 'reload':
|
||||
print(reload())
|
||||
elif func == 'initd_status':
|
||||
print(initdStatus())
|
||||
elif func == 'initd_install':
|
||||
print(initdInstall())
|
||||
elif func == 'initd_uninstall':
|
||||
print(initdUinstall())
|
||||
elif func == 'get_bot_conf':
|
||||
print(getBotConf())
|
||||
elif func == 'set_bot_conf':
|
||||
print(setBotConf())
|
||||
elif func == 'run_log':
|
||||
print(runLog())
|
||||
|
||||
else:
|
||||
print('error')
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"sort": 7,
|
||||
"ps": "[<b style='color:red;'>DEV</b>]简单Telegram机器人",
|
||||
"name": "tgbot",
|
||||
"title": "tgbot",
|
||||
"shell": "install.sh",
|
||||
"versions":["0.1"],
|
||||
"tip": "soft",
|
||||
"checks": "server/tgbot",
|
||||
"path": "server/tgbot",
|
||||
"display": 1,
|
||||
"author": "Zend",
|
||||
"date": "2023-03-06",
|
||||
"home": "https://core.telegram.org/bots/api",
|
||||
"type": 0,
|
||||
"pid": "5"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Tgbot Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
ExecStart={$APP_PATH}/init.d/tgbot start
|
||||
ExecStop={$APP_PATH}/init.d/tgbot stop
|
||||
ExecReload={$APP_PATH}/init.d/tgbot reload
|
||||
KillMode=process
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,85 @@
|
||||
#!/bin/sh
|
||||
# chkconfig: 2345 55 25
|
||||
# description: Tgbot Service
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: Tgbot
|
||||
# Required-Start: $all
|
||||
# Required-Stop: $all
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: starts Tgbot
|
||||
# Description: starts the MDW-Web
|
||||
### END INIT INFO
|
||||
|
||||
# Simple Tgbot init.d script conceived to work on Linux systems
|
||||
# as it does use of the /proc filesystem.
|
||||
|
||||
PATH=/usr/local/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export LANG=en_US.UTF-8
|
||||
|
||||
|
||||
mw_path={$SERVER_PATH}
|
||||
PATH=$PATH:$mw_path/bin
|
||||
|
||||
if [ -f $mw_path/bin/activate ];then
|
||||
source $mw_path/bin/activate
|
||||
fi
|
||||
|
||||
tg_start(){
|
||||
|
||||
isStart=`ps -ef|grep 'tgbot.py' |grep -v grep | awk '{print $2}'`
|
||||
if [ "$isStart" == '' ];then
|
||||
echo -e "starting tgbot... \c"
|
||||
cd $mw_path
|
||||
python3 {$APP_PATH}/tgbot.py >> {$APP_PATH}/task.log &
|
||||
isStart=""
|
||||
while [[ "$isStart" == "" ]];
|
||||
do
|
||||
echo -e ".\c"
|
||||
sleep 0.5
|
||||
isStart=`ps -ef|grep 'tgbot.py' |grep -v grep | awk '{print $2}'`
|
||||
let n+=1
|
||||
if [ $n -gt 20 ];then
|
||||
break;
|
||||
fi
|
||||
done
|
||||
if [ "$isStart" == '' ];then
|
||||
echo -e "\033[31mfailed\033[0m"
|
||||
echo -e "\033[31mError: tgbot service startup failed.\033[0m"
|
||||
return;
|
||||
fi
|
||||
echo -e "\033[32mdone\033[0m"
|
||||
else
|
||||
echo "starting tgbot...(pid $(echo $isStart)) already running"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
tg_stop(){
|
||||
echo -e "stopping tgbot ... \c";
|
||||
arr=`ps aux|grep 'tgbot.py'|grep -v grep|awk '{print $2}'`
|
||||
for p in ${arr[@]}
|
||||
do
|
||||
kill -9 $p > /dev/null 2>&1
|
||||
done
|
||||
echo -e "\033[32mdone\033[0m"
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
tg_start
|
||||
;;
|
||||
stop)
|
||||
tg_stop
|
||||
;;
|
||||
restart|reload)
|
||||
tg_stop
|
||||
sleep 0.3
|
||||
tg_start
|
||||
;;
|
||||
*)
|
||||
echo "Please use start or stop as first argument"
|
||||
;;
|
||||
esac
|
||||
|
||||
Executable
+59
@@ -0,0 +1,59 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
|
||||
VERSION=$2
|
||||
|
||||
# pip3 install ccxt
|
||||
if [ -f ${rootPath}/bin/activate ];then
|
||||
source ${rootPath}/bin/activate
|
||||
fi
|
||||
|
||||
pip3 install pyTelegramBotAPI
|
||||
pip3 install telebot
|
||||
|
||||
Install_App()
|
||||
{
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
mkdir -p $serverPath/source
|
||||
mkdir -p $serverPath/tgbot
|
||||
echo "${VERSION}" > $serverPath/tgbot/version.pl
|
||||
|
||||
cp -rf ${rootPath}/plugins/tgbot/startup/* $serverPath/tgbot
|
||||
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/tgbot/index.py start
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/tgbot/index.py initd_install
|
||||
echo '安装完成' > $install_tmp
|
||||
}
|
||||
|
||||
Uninstall_App()
|
||||
{
|
||||
if [ -f /usr/lib/systemd/system/tgbot.service ];then
|
||||
systemctl stop tgbot
|
||||
systemctl disable tgbot
|
||||
rm -rf /usr/lib/systemd/system/tgbot.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
if [ -f $serverPath/tgbot/initd/tgbot ];then
|
||||
$serverPath/tgbot/initd/tgbot stop
|
||||
fi
|
||||
|
||||
rm -rf $serverPath/tgbot
|
||||
echo "Uninstall_redis" > $install_tmp
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_App
|
||||
else
|
||||
Uninstall_App
|
||||
fi
|
||||
Executable
+78
@@ -0,0 +1,78 @@
|
||||
function appPost(method, args,callback){
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
|
||||
var req_data = {};
|
||||
req_data['name'] = 'tgbot';
|
||||
req_data['func'] = method;
|
||||
|
||||
if (typeof(args) == 'string'){
|
||||
req_data['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
|
||||
$.post('/plugins/run', req_data, function(data) {
|
||||
layer.close(loadT);
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
function appPostCallbak(method, args,callback){
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
|
||||
var req_data = {};
|
||||
req_data['name'] = 'tgbot';
|
||||
req_data['func'] = method;
|
||||
|
||||
if (typeof(args) == 'string'){
|
||||
req_data['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
|
||||
$.post('/plugins/callback', req_data, function(data) {
|
||||
layer.close(loadT);
|
||||
if (!data.status){
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
function botConf(){
|
||||
appPost('get_bot_conf','',function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
var app_token = 'app_token';
|
||||
if(rdata['status']){
|
||||
db_data = rdata['data'];
|
||||
app_token = db_data['app_token'];
|
||||
|
||||
}
|
||||
|
||||
var mlist = '';
|
||||
mlist += '<p><span>app_token</span><input style="width: 250px;" class="bt-input-text mr5" name="app_token" value="'+app_token+'" type="text"><font>必填写</font></p>'
|
||||
var option = '<style>.conf_p p{margin-bottom: 2px}</style>\
|
||||
<div class="conf_p" style="margin-bottom:0">\
|
||||
' + mlist + '\
|
||||
<div style="margin-top:10px; padding-right:15px" class="text-right">\
|
||||
<button class="btn btn-success btn-sm" onclick="submitBotConf()">保存</button>\
|
||||
</div>\
|
||||
</div>';
|
||||
$(".soft-man-con").html(option);
|
||||
});
|
||||
}
|
||||
|
||||
function submitBotConf(){
|
||||
var pull_data = {};
|
||||
pull_data['app_token'] = base64_encode($('input[name="app_token"]').val());
|
||||
appPost('set_bot_conf',pull_data,function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
layer.msg(rdata['msg'],{icon:rdata['status']?1:2,time:2000,shade: [0.3, '#000']});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import json
|
||||
import base64
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
import telebot
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'tgbot'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return mw.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return mw.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getConfigData():
|
||||
cfg_path = getServerDir() + "/data.cfg"
|
||||
if not os.path.exists(cfg_path):
|
||||
mw.writeFile(cfg_path, '{}')
|
||||
t = mw.readFile(cfg_path)
|
||||
return json.loads(t)
|
||||
|
||||
|
||||
def writeConf(data):
|
||||
cfg_path = getServerDir() + "/data.cfg"
|
||||
mw.writeFile(cfg_path, json.dumps(data))
|
||||
return True
|
||||
|
||||
|
||||
def writeLog(log_str):
|
||||
if __name__ == "__main__":
|
||||
print(log_str)
|
||||
|
||||
log_file = getServerDir() + '/task.log'
|
||||
mw.writeFileLog(log_str, log_file, limit_size=5 * 1024)
|
||||
return True
|
||||
|
||||
# start tgbot
|
||||
cfg = getConfigData()
|
||||
while True:
|
||||
cfg = getConfigData()
|
||||
if 'bot' in cfg and 'app_token' in cfg['bot']:
|
||||
if cfg['bot']['app_token'] != '' and cfg['bot']['app_token'] != 'app_token':
|
||||
break
|
||||
writeLog('等待输入配置,填写app_token')
|
||||
time.sleep(3)
|
||||
|
||||
bot = telebot.TeleBot(cfg['bot']['app_token'])
|
||||
|
||||
|
||||
# from telebot.async_telebot import AsyncTeleBot
|
||||
# import asyncio
|
||||
# bot = AsyncTeleBot(cfg['bot']['app_token'])
|
||||
|
||||
|
||||
@bot.message_handler(commands=['start', 'help'])
|
||||
def hanle_start_help(message):
|
||||
bot.reply_to(message, "hello world")
|
||||
|
||||
|
||||
@bot.message_handler(commands=['chat_id'])
|
||||
def hanle_get_chat_id(message):
|
||||
bot.reply_to(message, message.chat.id)
|
||||
|
||||
writeLog('启动成功')
|
||||
bot.polling()
|
||||
# asyncio.run(bot.polling())
|
||||
@@ -27,6 +27,7 @@
|
||||
"gif",
|
||||
"jpg",
|
||||
"css",
|
||||
"svg",
|
||||
"js",
|
||||
"ico",
|
||||
"woff2"
|
||||
|
||||
@@ -239,6 +239,7 @@ function _M.cronPre(self)
|
||||
local time_key = self:get_store_key()
|
||||
local time_key_next = self:get_store_key_with_time(ngx.time()+3600)
|
||||
|
||||
|
||||
for site_k, site_v in ipairs(sites) do
|
||||
local input_sn = site_v["name"]
|
||||
|
||||
@@ -250,16 +251,24 @@ function _M.cronPre(self)
|
||||
'spider_stat'
|
||||
}
|
||||
|
||||
local v1 = true
|
||||
local v2 = true
|
||||
for _,ws_v in pairs(wc_stat) do
|
||||
self:_update_stat_pre(db, ws_v, time_key)
|
||||
self:_update_stat_pre(db, ws_v, time_key_next)
|
||||
v1 = self:_update_stat_pre(db, ws_v, time_key)
|
||||
v2 = self:_update_stat_pre(db, ws_v, time_key_next)
|
||||
end
|
||||
|
||||
if db and db:isopen() then
|
||||
db:execute([[COMMIT]])
|
||||
db:close()
|
||||
end
|
||||
|
||||
if not v1 or not v2 then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- 后台任务
|
||||
@@ -273,7 +282,12 @@ function _M.cron(self)
|
||||
return true
|
||||
end
|
||||
|
||||
self:cronPre()
|
||||
-- self:D("dedebide:cron task is busy!")
|
||||
local ready_ok = self:cronPre()
|
||||
if not ready_ok then
|
||||
self:D("cron task is busy!")
|
||||
return true
|
||||
end
|
||||
|
||||
ngx.update_time()
|
||||
local begin = ngx.now()
|
||||
@@ -653,9 +667,14 @@ end
|
||||
function _M._update_stat_pre(self, db, stat_table, key)
|
||||
local local_sql = string.format("INSERT INTO %s(time) SELECT :time WHERE NOT EXISTS(SELECT time FROM %s WHERE time=:time);", stat_table, stat_table)
|
||||
local update_stat_stmt = db:prepare(local_sql)
|
||||
update_stat_stmt:bind_names{time=key}
|
||||
update_stat_stmt:step()
|
||||
update_stat_stmt:finalize()
|
||||
|
||||
if update_stat_stmt then
|
||||
update_stat_stmt:bind_names{time=key}
|
||||
update_stat_stmt:step()
|
||||
update_stat_stmt:finalize()
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function _M.update_stat_quick(self, db, stat_table, key,columns)
|
||||
|
||||
@@ -134,6 +134,7 @@ log_by_lua_block {
|
||||
|
||||
local function exclude_url()
|
||||
if not ngx.var.uri then return false end
|
||||
if not ngx.var.request_uri then return false end
|
||||
if not auto_config['exclude_url'] then return false end
|
||||
local the_uri = string.sub(ngx.var.request_uri, 2)
|
||||
local url_conf = auto_config["exclude_url"]
|
||||
|
||||
@@ -29,3 +29,5 @@ flask-caching>=1.10.1
|
||||
bcrypt==3.1.3
|
||||
PyMySQL==1.0.2
|
||||
whitenoise==5.3.0
|
||||
pyTelegramBotAPI
|
||||
telebot
|
||||
|
||||
@@ -354,6 +354,78 @@ function setPanelSSL(){
|
||||
});
|
||||
}
|
||||
|
||||
function setNotifyApi(tag, obj){
|
||||
var enable = $(obj).prop("checked");
|
||||
console.log(tag,obj,enable);
|
||||
$.post('/config/set_notify_enable', {'tag':tag, 'enable':enable},function(rdata){
|
||||
showMsg(rdata.msg, function(){
|
||||
if (rdata.status){}
|
||||
} ,{icon:rdata.status?1:2}, 1000);
|
||||
},'json');
|
||||
}
|
||||
|
||||
function getTgbot(){
|
||||
var loadT = layer.msg('正在获取TgBot信息...',{icon:16,time:0,shade: [0.3, '#000']});
|
||||
$.post('/config/get_notify',{},function(data){
|
||||
layer.close(loadT);
|
||||
|
||||
var app_token = '';
|
||||
var chat_id = '';
|
||||
|
||||
if (data.status){
|
||||
if (typeof(data['data']['tgbot']) !='undefined'){
|
||||
app_token = data['data']['tgbot']['data']['app_token'];
|
||||
chat_id = data['data']['tgbot']['data']['chat_id'];
|
||||
}
|
||||
}
|
||||
|
||||
layer.open({
|
||||
type: 1,
|
||||
area: "500px",
|
||||
title: '配置TgBot配置',
|
||||
closeBtn: 1,
|
||||
shift: 5,
|
||||
btn:["确定","关闭","验证"],
|
||||
shadeClose: false,
|
||||
content: "<div class='bt-form pd20'>\
|
||||
<div class='line'>\
|
||||
<span class='tname'>APP_TOKEN</span>\
|
||||
<div class='info-r'><input class='bt-input-text' type='text' name='app_token' value='"+app_token+"' style='width:100%'/></div>\
|
||||
</div>\
|
||||
<div class='line'>\
|
||||
<span class='tname'>CHAT_ID</span>\
|
||||
<div class='info-r'><input class='bt-input-text' type='text' name='chat_id' value='"+chat_id+"' style='width:100%' /></div>\
|
||||
</div>\
|
||||
</div>",
|
||||
yes:function(index){
|
||||
var pdata = {};
|
||||
pdata['app_token'] = $('input[name="app_token"]').val();
|
||||
pdata['chat_id'] = $('input[name="chat_id"]').val();
|
||||
$.post('/config/set_notify',{'tag':'tgbot', 'data':JSON.stringify(pdata)},function(rdata){
|
||||
showMsg(rdata.msg, function(){
|
||||
if (rdata.status){
|
||||
layer.close(index);
|
||||
}
|
||||
},{icon:rdata.status?1:2},2000);
|
||||
});
|
||||
},
|
||||
|
||||
btn3:function(index){
|
||||
var pdata = {};
|
||||
pdata['app_token'] = $('input[name="app_token"]').val();
|
||||
pdata['chat_id'] = $('input[name="chat_id"]').val();
|
||||
$.post('/config/set_notify_test',{'tag':'tgbot', 'data':JSON.stringify(pdata)},function(rdata){
|
||||
showMsg(rdata.msg, function(){
|
||||
if (rdata.status){
|
||||
layer.close(index);
|
||||
}
|
||||
},{icon:rdata.status?1:2},2000);
|
||||
});
|
||||
return false;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getPanelSSL(){
|
||||
var loadT = layer.msg('正在获取证书信息...',{icon:16,time:0,shade: [0.3, '#000']});
|
||||
|
||||
+227
-74
@@ -515,29 +515,24 @@ function openPath(a) {
|
||||
window.location.href = "/files/"
|
||||
}
|
||||
|
||||
function onlineEditFile(k, f) {
|
||||
function onlineEditFile(k, f, callback) {
|
||||
if(k != 0) {
|
||||
var l = $("#PathPlace input").val();
|
||||
var h = encodeURIComponent($("#textBody").val());
|
||||
var a = $("select[name=encoding]").val();
|
||||
var loadT = layer.msg(lan.bt.save_file, {
|
||||
icon: 16,
|
||||
time: 0
|
||||
});
|
||||
$.post("/files/save_body", "data=" + h + "&path=" + encodeURIComponent(f) + "&encoding=" + a, function(m) {
|
||||
var loadT = layer.msg('正在保存,请稍候...', {icon: 16,time: 0});
|
||||
$.post("/files/save_body", "data=" + h + "&path=" + encodeURIComponent(f) + "&encoding=" + a, function(data) {
|
||||
if(k == 1) {
|
||||
layer.close(loadT);
|
||||
}
|
||||
layer.msg(m.msg, {
|
||||
icon: m.status ? 1 : 2
|
||||
});
|
||||
layer.msg(data.msg, {icon: data.status ? 1 : 2});
|
||||
if (data.status && typeof(callback) == 'function'){
|
||||
callback(k, f);
|
||||
}
|
||||
},'json');
|
||||
return
|
||||
}
|
||||
var e = layer.msg(lan.bt.read_file, {
|
||||
icon: 16,
|
||||
time: 0
|
||||
});
|
||||
var e = layer.msg('正在读取文件,请稍候...', {icon: 16,time: 0});
|
||||
var g = f.split(".");
|
||||
var b = g[g.length - 1];
|
||||
var d;
|
||||
@@ -595,15 +590,12 @@ function onlineEditFile(k, f) {
|
||||
default:
|
||||
var j = {
|
||||
name: "htmlmixed",
|
||||
scriptTypes: [{
|
||||
matches: /\/x-handlebars-template|\/x-mustache/i,
|
||||
mode: null
|
||||
}, {
|
||||
matches: /(text|application)\/(x-)?vb(a|script)/i,
|
||||
mode: "vbscript"
|
||||
}]
|
||||
scriptTypes: [
|
||||
{matches: /\/x-handlebars-template|\/x-mustache/i,mode: null},
|
||||
{matches: /(text|application)\/(x-)?vb(a|script)/i,mode: "vbscript"}
|
||||
]
|
||||
};
|
||||
d = j
|
||||
d = j;
|
||||
}
|
||||
$.post("/files/get_body", "path=" + encodeURIComponent(f), function(s) {
|
||||
if(s.status === false){
|
||||
@@ -619,55 +611,57 @@ function onlineEditFile(k, f) {
|
||||
m = s.data.encoding == u[p] ? "selected" : "";
|
||||
n += '<option value="' + u[p] + '" ' + m + ">" + u[p] + "</option>";
|
||||
}
|
||||
var code_mirror = null;
|
||||
var r = layer.open({
|
||||
type: 1,
|
||||
shift: 5,
|
||||
closeBtn: 1,
|
||||
area: ["90%", "90%"],
|
||||
title: lan.bt.edit_title+"[" + f + "]",
|
||||
content: '<form class="bt-form pd20 pb70">\
|
||||
btn:['保存','关闭'],
|
||||
title: "在线编辑[" + f + "]",
|
||||
content: '<form class="bt-form pd20">\
|
||||
<div class="line">\
|
||||
<p style="color:red;margin-bottom:10px">' + lan.bt.edit_ps + '\
|
||||
<p style="color:red;margin-bottom:10px">提示:Ctrl+F 搜索关键字,Ctrl+G 查找下一个,Ctrl+S 保存,Ctrl+Shift+R 查找替换!\
|
||||
<select class="bt-input-text" name="encoding" style="width: 74px;position: absolute;top: 31px;right: 19px;height: 22px;z-index: 9999;border-radius: 0;">' + n + '</select>\
|
||||
</p>\
|
||||
<textarea class="mCustomScrollbar bt-input-text" id="textBody" style="width:100%;margin:0 auto;line-height: 1.8;position: relative;top: 10px;" value="" />\
|
||||
</div>\
|
||||
<div class="bt-form-submit-btn" style="position:absolute; bottom:0; width:100%">\
|
||||
<button type="button" class="btn btn-danger btn-sm btn-editor-close">'+lan.public.close+'</button>\
|
||||
<button id="OnlineEditFileBtn" type="button" class="btn btn-success btn-sm">'+lan.public.save+'</button>\
|
||||
</div>\
|
||||
</form>'
|
||||
});
|
||||
$("#textBody").text(s.data.data);
|
||||
var q = $(window).height() * 0.9;
|
||||
$("#textBody").height(q - 160);
|
||||
var t = CodeMirror.fromTextArea(document.getElementById("textBody"), {
|
||||
extraKeys: {
|
||||
"Ctrl-F": "findPersistent",
|
||||
"Ctrl-H": "replaceAll",
|
||||
"Ctrl-S": function() {
|
||||
$("#textBody").text(t.getValue());
|
||||
onlineEditFile(2, f)
|
||||
},
|
||||
"Cmd-S":function() {
|
||||
$("#textBody").text(t.getValue());
|
||||
onlineEditFile(2, f)
|
||||
},
|
||||
</form>',
|
||||
success:function(){
|
||||
$("#textBody").text(s.data.data);
|
||||
var q = $(window).height() * 0.9;
|
||||
$("#textBody").height(q - 160);
|
||||
code_mirror = CodeMirror.fromTextArea(document.getElementById("textBody"), {
|
||||
extraKeys: {
|
||||
"Ctrl-F": "findPersistent",
|
||||
"Ctrl-H": "replaceAll",
|
||||
"Ctrl-S": function() {
|
||||
$("#textBody").text(code_mirror.getValue());
|
||||
onlineEditFile(2, f,callback);
|
||||
},
|
||||
"Cmd-S":function() {
|
||||
$("#textBody").text(code_mirror.getValue());
|
||||
onlineEditFile(2, f,callback);
|
||||
},
|
||||
},
|
||||
mode: d,
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
matchtags: true,
|
||||
autoMatchParens: true
|
||||
});
|
||||
code_mirror.focus();
|
||||
code_mirror.setSize("auto", q - 150);
|
||||
|
||||
$(window).resize(function(){
|
||||
var q = $(window).height() * 0.9;
|
||||
code_mirror.setSize("auto", q - 150);
|
||||
});
|
||||
},
|
||||
mode: d,
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
matchtags: true,
|
||||
autoMatchParens: true
|
||||
});
|
||||
t.focus();
|
||||
t.setSize("auto", q - 150);
|
||||
$("#OnlineEditFileBtn").click(function() {
|
||||
$("#textBody").text(t.getValue());
|
||||
onlineEditFile(1, f);
|
||||
});
|
||||
$(".btn-editor-close").click(function() {
|
||||
layer.close(r);
|
||||
yes:function(){
|
||||
$("#textBody").text(code_mirror.getValue());
|
||||
onlineEditFile(1, f,callback);
|
||||
}
|
||||
});
|
||||
},'json');
|
||||
}
|
||||
@@ -1137,18 +1131,21 @@ function bindPanel(a,type,ip,btid,url,user,pw){
|
||||
<li><font style='color:red'>注意,开启广告拦截会导致无法快捷登录。</font></li></ul>\
|
||||
</div>\
|
||||
<div class='bt-form-submit-btn'><button type='button' class='btn btn-danger btn-sm' onclick=\"layer.closeAll()\">关闭</button> "+btn+"</div>\
|
||||
</div>"
|
||||
});
|
||||
$("#btaddress").on("input",function(){
|
||||
var str =$(this).val();
|
||||
var isip = /([\w-]+\.){2,6}\w+/;
|
||||
var iptext = str.match(isip);
|
||||
if(iptext) $("#bttitle").val(iptext[0]);
|
||||
}).blur(function(){
|
||||
var str =$(this).val();
|
||||
var isip = /([\w-]+\.){2,6}\w+/;
|
||||
var iptext = str.match(isip);
|
||||
if(iptext) $("#bttitle").val(iptext[0]);
|
||||
</div>",
|
||||
|
||||
success:function(){
|
||||
$("#btaddress").on("input",function(){
|
||||
var str =$(this).val();
|
||||
var isip = /([\w-]+\.){2,6}\w+/;
|
||||
var iptext = str.match(isip);
|
||||
if(iptext) $("#bttitle").val(iptext[0]);
|
||||
}).blur(function(){
|
||||
var str =$(this).val();
|
||||
var isip = /([\w-]+\.){2,6}\w+/;
|
||||
var iptext = str.match(isip);
|
||||
if(iptext) $("#bttitle").val(iptext[0]);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
//删除快捷登录
|
||||
@@ -1773,6 +1770,159 @@ function entitiesDecode(text) {
|
||||
return text;
|
||||
}
|
||||
|
||||
// base64.js
|
||||
// base64加密
|
||||
function base64_encode(str) {
|
||||
var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
var out, i, len;
|
||||
var c1, c2, c3;
|
||||
|
||||
len = str.length;
|
||||
i = 0;
|
||||
out = "";
|
||||
while(i < len) {
|
||||
c1 = str.charCodeAt(i++) & 0xff;
|
||||
if(i == len)
|
||||
{
|
||||
out += base64EncodeChars.charAt(c1 >> 2);
|
||||
out += base64EncodeChars.charAt((c1 & 0x3) << 4);
|
||||
out += "==";
|
||||
break;
|
||||
}
|
||||
c2 = str.charCodeAt(i++);
|
||||
if(i == len)
|
||||
{
|
||||
out += base64EncodeChars.charAt(c1 >> 2);
|
||||
out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
|
||||
out += base64EncodeChars.charAt((c2 & 0xF) << 2);
|
||||
out += "=";
|
||||
break;
|
||||
}
|
||||
c3 = str.charCodeAt(i++);
|
||||
out += base64EncodeChars.charAt(c1 >> 2);
|
||||
out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
|
||||
out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6));
|
||||
out += base64EncodeChars.charAt(c3 & 0x3F);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
// base64解密
|
||||
function base64_decode(str) {
|
||||
var base64DecodeChars = new Array(
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
|
||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
|
||||
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);
|
||||
var c1, c2, c3, c4;
|
||||
var i, len, out;
|
||||
|
||||
len = str.length;
|
||||
i = 0;
|
||||
out = "";
|
||||
while(i < len) {
|
||||
/* c1 */
|
||||
do {
|
||||
c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
|
||||
} while(i < len && c1 == -1);
|
||||
if(c1 == -1)
|
||||
break;
|
||||
|
||||
/* c2 */
|
||||
do {
|
||||
c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
|
||||
} while(i < len && c2 == -1);
|
||||
if(c2 == -1)
|
||||
break;
|
||||
|
||||
out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));
|
||||
|
||||
/* c3 */
|
||||
do {
|
||||
c3 = str.charCodeAt(i++) & 0xff;
|
||||
if(c3 == 61)
|
||||
return out;
|
||||
c3 = base64DecodeChars[c3];
|
||||
} while(i < len && c3 == -1);
|
||||
if(c3 == -1)
|
||||
break;
|
||||
|
||||
out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));
|
||||
|
||||
/* c4 */
|
||||
do {
|
||||
c4 = str.charCodeAt(i++) & 0xff;
|
||||
if(c4 == 61)
|
||||
return out;
|
||||
c4 = base64DecodeChars[c4];
|
||||
} while(i < len && c4 == -1);
|
||||
if(c4 == -1)
|
||||
break;
|
||||
out += String.fromCharCode(((c3 & 0x03) << 6) | c4);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function utf16to8(str) {
|
||||
var out, i, len, c;
|
||||
|
||||
out = "";
|
||||
len = str.length;
|
||||
for(i = 0; i < len; i++) {
|
||||
c = str.charCodeAt(i);
|
||||
if ((c >= 0x0001) && (c <= 0x007F)) {
|
||||
out += str.charAt(i);
|
||||
} else if (c > 0x07FF) {
|
||||
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
|
||||
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
|
||||
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
|
||||
} else {
|
||||
out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
|
||||
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function utf8to16(str) {
|
||||
var out, i, len, c;
|
||||
var char2, char3;
|
||||
|
||||
out = "";
|
||||
len = str.length;
|
||||
i = 0;
|
||||
while(i < len) {
|
||||
c = str.charCodeAt(i++);
|
||||
switch(c >> 4)
|
||||
{
|
||||
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
|
||||
// 0xxxxxxx
|
||||
out += str.charAt(i-1);
|
||||
break;
|
||||
case 12: case 13:
|
||||
// 110x xxxx 10xx xxxx
|
||||
char2 = str.charCodeAt(i++);
|
||||
out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
|
||||
break;
|
||||
case 14:
|
||||
// 1110 xxxx 10xx xxxx 10xx xxxx
|
||||
char2 = str.charCodeAt(i++);
|
||||
char3 = str.charCodeAt(i++);
|
||||
out += String.fromCharCode(((c & 0x0F) << 12) |
|
||||
((char2 & 0x3F) << 6) |
|
||||
((char3 & 0x3F) << 0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
function pluginService(_name, version){
|
||||
var data = {name:_name, func:'status'}
|
||||
@@ -2124,6 +2274,8 @@ function pluginOpInitD(a, _version, b) {
|
||||
}
|
||||
|
||||
function pluginLogs(_name, version, func, line){
|
||||
|
||||
var _this = this;
|
||||
if ( typeof(version) == 'undefined' ){
|
||||
version = '';
|
||||
}
|
||||
@@ -2164,9 +2316,10 @@ function pluginLogs(_name, version, func, line){
|
||||
if(rdata.data == '') {
|
||||
rdata.data = '当前没有日志!';
|
||||
}
|
||||
var ebody = '<div class="soft-man-con">\
|
||||
<textarea readonly="" style="margin: 0px;width: 100%;height: 520px;background-color: #333;color:#fff; padding:0 5px" id="info_log">'+rdata.data+'</textarea>\
|
||||
</div>';
|
||||
|
||||
|
||||
var h = parseInt($('.bt-w-menu').css('height')) - 40;
|
||||
var ebody = '<textarea readonly="" style="margin: 0px;height: '+h+'px;width: 100%;background-color: #333;color:#fff; padding:0 5px" id="info_log">'+rdata.data+'</textarea>';
|
||||
$(".soft-man-con").html(ebody);
|
||||
var ob = document.getElementById('info_log');
|
||||
ob.scrollTop = ob.scrollHeight;
|
||||
|
||||
@@ -102,7 +102,6 @@
|
||||
</div>
|
||||
|
||||
<div class="title c6 plr15"><h3 class="f16">安全</h3></div>
|
||||
|
||||
<div class="setting-con pd15">
|
||||
|
||||
<p class="mtb15">
|
||||
@@ -148,6 +147,21 @@
|
||||
<span class="set-info c7">为非管理员临时提供面板访问权限</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="title c6 plr15"><h3 class="f16">通知</h3></div>
|
||||
|
||||
<div class="setting-con pd15">
|
||||
|
||||
<p class="mtb15">
|
||||
<span class="set-tit text-right" title="TelegramBot" style="float: left;">TG机器人通知</span>
|
||||
<input id="cfg_tgbot" name="cfg_tgbot" onclick="setNotifyApi('tgbot',this)" class="btswitch btswitch-ios" type="checkbox" {{data['notify_tgbot_enable']}}>
|
||||
<label class="btswitch-btn ml5" for="cfg_tgbot" style="float: left;margin-top:4px;"></label>
|
||||
<button ype="button" class="btn btn-default btn-xs panel_api_btn" style="vertical-align: middle; margin-left: 10px" onclick="getTgbot();">TelegramBot配置</button>
|
||||
<span class="set-info c7">Telegram Bot机器人通知【<b style="color:red;">国内可能无法使用</b>】</span>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -90,8 +90,12 @@
|
||||
|
||||
{% block content %}{% endblock %}
|
||||
<div class="footer bgw">mdserver-web ©2018-∞ Linux面板 (<a class="btlink" target="_blank" href="//github.com/midoks/mdserver-web">源码</a>) <span style="margin-left:5px;">/</span>
|
||||
<a class="btlink" style="margin-left:5px;" href="//github.com/midoks/mdserver-web/wiki" target="_blank">WIKI</a><span style="margin-left:5px;">/</span>
|
||||
<a class="btlink" target="_blank" style="margin-left:5px;" href="//github.com/midoks/mdserver-web/wiki">WIKI</a><span style="margin-left:5px;">/</span>
|
||||
<a class='btlink panel_ad_list_mode' style="margin-left:5px;">AD</a>
|
||||
<span style="margin-left:5px;">/</span>
|
||||
<a class='btlink' target="_blank" href="https://bbs.midoks.me" style="margin-left:5px;">交流论坛</a>
|
||||
<span style="margin-left:5px;">/</span>
|
||||
<a class='btlink' target="_blank" href="https://t.me/mdserver_web" style="margin-left:5px;">TG吹水群</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ CP_CMD=/usr/bin/cp
|
||||
if [ -f /bin/cp ];then
|
||||
CP_CMD=/bin/cp
|
||||
fi
|
||||
$CP_CMD -rf /tmp/mdserver-web-dev/* /www/server/mdserver-web
|
||||
$CP_CMD -rf /tmp/mdserver-web-master/* /www/server/mdserver-web
|
||||
|
||||
rm -rf /tmp/master.zip
|
||||
rm -rf /tmp/mdserver-web-master
|
||||
|
||||
@@ -256,6 +256,13 @@ def systemTask():
|
||||
tmp = {}
|
||||
# 取当前CPU Io
|
||||
tmp['used'] = psutil.cpu_percent(interval=1)
|
||||
if tmp['used'] > 80:
|
||||
panel_title = mw.getConfig('title')
|
||||
ip = mw.getHostAddr()
|
||||
now_time = mw.getDateFromNow()
|
||||
msg = now_time + '|节点[' + panel_title + ':' + ip + \
|
||||
']处于高负载[' + str(tmp['used']) + '],请排查原因!'
|
||||
mw.notifyMessage(msg, '面板监控', 600)
|
||||
|
||||
if not cpuInfo:
|
||||
tmp['mem'] = sm.getMemUsed()
|
||||
|
||||
Reference in New Issue
Block a user