diff --git a/plugins/simpleping/ico.png b/plugins/simpleping/ico.png
new file mode 100644
index 000000000..348efe3f4
Binary files /dev/null and b/plugins/simpleping/ico.png differ
diff --git a/plugins/simpleping/index.html b/plugins/simpleping/index.html
new file mode 100755
index 000000000..952b4bad7
--- /dev/null
+++ b/plugins/simpleping/index.html
@@ -0,0 +1,31 @@
+
+
+
+
\ No newline at end of file
diff --git a/plugins/simpleping/index.py b/plugins/simpleping/index.py
new file mode 100755
index 000000000..55793fa9b
--- /dev/null
+++ b/plugins/simpleping/index.py
@@ -0,0 +1,338 @@
+# coding:utf-8
+
+import sys
+import io
+import os
+import time
+import re
+
+sys.path.append(os.getcwd() + "/class/core")
+import mw
+
+app_debug = False
+if mw.isAppleSystem():
+ app_debug = True
+
+
+def getHomeDir():
+ if mw.isAppleSystem():
+ user = mw.execShell(
+ "who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
+ return '/Users/' + user
+ else:
+ return '/root'
+
+
+def getRunUser():
+ if mw.isAppleSystem():
+ user = mw.execShell(
+ "who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
+ return user
+ else:
+ return 'root'
+
+__SR = '''#!/bin/bash
+PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
+export PATH
+export USER=%s
+export HOME=%s && ''' % ( getRunUser(), getHomeDir())
+
+def getPluginName():
+ return 'simpleping'
+
+
+def getPluginDir():
+ return mw.getPluginDir() + '/' + getPluginName()
+
+
+def getServerDir():
+ return mw.getServerDir() + '/' + getPluginName()
+
+
+def getInitDFile():
+ current_os = mw.getOs()
+ if current_os == 'darwin':
+ return '/tmp/' + getPluginName()
+
+ if current_os.startswith('freebsd'):
+ return '/etc/rc.d/' + getPluginName()
+ return '/etc/init.d/' + getPluginName()
+
+
+def getConf():
+ path = getServerDir() + "/conf/app.conf"
+ return path
+
+
+def getConfTpl():
+ path = getPluginDir() + "/config/redis.conf"
+ return path
+
+
+def getInitDTpl():
+ path = getPluginDir() + "/init.d/" + getPluginName() + ".tpl"
+ return path
+
+
+def getArgs():
+ args = sys.argv[3:]
+ 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 configTpl():
+ path = getPluginDir() + '/tpl'
+ pathFile = os.listdir(path)
+ tmp = []
+ for one in pathFile:
+ file = path + '/' + one
+ tmp.append(file)
+ return mw.getJson(tmp)
+
+
+def readConfigTpl():
+ args = getArgs()
+ data = checkArgs(args, ['file'])
+ if not data[0]:
+ return data[1]
+
+ content = mw.readFile(args['file'])
+ content = contentReplace(content)
+ return mw.returnJson(True, 'ok', content)
+
+def getPidFile():
+ file = getConf()
+ content = mw.readFile(file)
+ rep = 'pidfile\s*(.*)'
+ tmp = re.search(rep, content)
+ return tmp.groups()[0].strip()
+
+def status():
+ data = mw.execShell(
+ "ps aux|grep simpleping |grep -v grep | grep -v python | grep -v mdserver-web | awk '{print $2}'")
+
+ if data[0] == '':
+ return 'stop'
+ return 'start'
+
+def contentReplace(content):
+ service_path = mw.getServerDir()
+ content = content.replace('{$ROOT_PATH}', mw.getRootDir())
+ content = content.replace('{$SERVER_PATH}', service_path)
+ content = content.replace('{$SERVER_APP}', service_path + '/simpleping')
+ return content
+
+
+
+def initDreplace():
+
+ file_tpl = getInitDTpl()
+ service_path = os.path.dirname(os.getcwd())
+
+ initD_path = getServerDir() + '/init.d'
+ if not os.path.exists(initD_path):
+ os.mkdir(initD_path)
+ file_bin = initD_path + '/' + getPluginName()
+
+ # print(file_bin)
+ # initd replace
+ if not os.path.exists(file_bin):
+ content = mw.readFile(file_tpl)
+ content = content.replace('{$SERVER_PATH}', service_path)
+ mw.writeFile(file_bin, content)
+ mw.execShell('chmod +x ' + file_bin)
+
+ # systemd
+ systemDir = mw.systemdCfgDir()
+ systemService = systemDir + '/' + getPluginName() + '.service'
+ if os.path.exists(systemDir) and not os.path.exists(systemService):
+ systemServiceTpl = getPluginDir() + '/init.d/' + getPluginName() + '.service.tpl'
+ service_path = mw.getServerDir()
+ content = mw.readFile(systemServiceTpl)
+ content = content.replace('{$SERVER_PATH}', service_path)
+ mw.writeFile(systemService, content)
+ mw.execShell('systemctl daemon-reload')
+
+ return file_bin
+
+
+def appOp(method):
+ file = initDreplace()
+
+ current_os = mw.getOs()
+ if current_os == "darwin":
+ data = mw.execShell(__SR + file + ' ' + method)
+ # print(data)
+ return 'ok'
+
+ if current_os.startswith("freebsd"):
+ data = mw.execShell('service ' + getPluginName() + ' ' + method)
+ if data[1] == '':
+ return 'ok'
+ return data[1]
+
+ data = mw.execShell('systemctl ' + method + ' ' + getPluginName())
+ if data[1] == '':
+ return 'ok'
+ return data[1]
+
+
+def start():
+ return appOp('start')
+
+
+def stop():
+ return appOp('stop')
+
+
+def restart():
+ status = appOp('restart')
+ return status
+
+
+def reload():
+ return redisOp('reload')
+
+
+def initdStatus():
+ current_os = mw.getOs()
+ if current_os == 'darwin':
+ return "Apple Computer does not support"
+
+ if current_os.startswith('freebsd'):
+ initd_bin = getInitDFile()
+ if os.path.exists(initd_bin):
+ return 'ok'
+
+ shell_cmd = 'systemctl status ' + \
+ getPluginName() + ' | grep loaded | grep "enabled;"'
+ data = mw.execShell(shell_cmd)
+ if data[0] == '':
+ return 'fail'
+ return 'ok'
+
+
+def initdInstall():
+ current_os = mw.getOs()
+ if current_os == 'darwin':
+ return "Apple Computer does not support"
+
+ # freebsd initd install
+ if current_os.startswith('freebsd'):
+ import shutil
+ source_bin = initDreplace()
+ initd_bin = getInitDFile()
+ shutil.copyfile(source_bin, initd_bin)
+ mw.execShell('chmod +x ' + initd_bin)
+ mw.execShell('sysrc ' + getPluginName() + '_enable="YES"')
+ return 'ok'
+
+ mw.execShell('systemctl enable ' + getPluginName())
+ return 'ok'
+
+
+def initdUinstall():
+ current_os = mw.getOs()
+ if current_os == 'darwin':
+ return "Apple Computer does not support"
+
+ if current_os.startswith('freebsd'):
+ initd_bin = getInitDFile()
+ os.remove(initd_bin)
+ mw.execShell('sysrc ' + getPluginName() + '_enable="NO"')
+ return 'ok'
+
+ mw.execShell('systemctl disable ' + getPluginName())
+ return 'ok'
+
+
+def runLog():
+ return getServerDir() + '/data/log.pl'
+
+
+def getRedisConfInfo():
+ conf = getServerDir() + '/redis.conf'
+
+ gets = [
+ {'name': 'bind', 'type': 2, 'ps': '绑定IP(修改绑定IP可能会存在安全隐患)','must_show':1},
+ {'name': 'port', 'type': 2, 'ps': '绑定端口','must_show':1},
+ {'name': 'timeout', 'type': 2, 'ps': '空闲链接超时时间,0表示不断开','must_show':1},
+ {'name': 'maxclients', 'type': 2, 'ps': '最大连接数','must_show':1},
+ {'name': 'databases', 'type': 2, 'ps': '数据库数量','must_show':1},
+ {'name': 'requirepass', 'type': 2, 'ps': 'redis密码,留空代表没有设置密码','must_show':1},
+ {'name': 'maxmemory', 'type': 2, 'ps': 'MB,最大使用内存,0表示不限制','must_show':1},
+ {'name': 'slaveof', 'type': 2, 'ps': '同步主库地址','must_show':0},
+ {'name': 'masterauth', 'type': 2, 'ps': '同步主库密码', 'must_show':0}
+ ]
+ content = mw.readFile(conf)
+
+ result = []
+ for g in gets:
+ rep = "^(" + g['name'] + ')\s*([.0-9A-Za-z_& ~]+)'
+ tmp = re.search(rep, content, re.M)
+ if not tmp:
+ if g['must_show'] == 0:
+ continue
+
+ g['value'] = ''
+ result.append(g)
+ continue
+ g['value'] = tmp.groups()[1]
+ if g['name'] == 'maxmemory':
+ g['value'] = g['value'].strip("mb")
+ result.append(g)
+
+ return result
+
+
+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 == 'conf':
+ print(getConf())
+ elif func == 'run_log':
+ print(runLog())
+ elif func == 'get_redis_conf':
+ print(getRedisConf())
+ elif func == 'submit_redis_conf':
+ print(submitRedisConf())
+ elif func == 'config_tpl':
+ print(configTpl())
+ elif func == 'read_config_tpl':
+ print(readConfigTpl())
+ else:
+ print('error')
diff --git a/plugins/simpleping/info.json b/plugins/simpleping/info.json
new file mode 100755
index 000000000..ae3d31e55
--- /dev/null
+++ b/plugins/simpleping/info.json
@@ -0,0 +1,17 @@
+{
+ "sort": 999,
+ "ps": "简单Ping服务,检查连通性",
+ "name": "simpleping",
+ "title": "SimplePing",
+ "shell": "install.sh",
+ "versions":["1.0"],
+ "tip": "soft",
+ "checks": "server/simpleping",
+ "path": "server/simpleping",
+ "display": 1,
+ "author": "midoks",
+ "date": "2024-07-10",
+ "home": "https://github.com/midoks/simpleping",
+ "type": 0,
+ "pid": "5"
+}
diff --git a/plugins/simpleping/init.d/simpleping.service.tpl b/plugins/simpleping/init.d/simpleping.service.tpl
new file mode 100644
index 000000000..5610665e7
--- /dev/null
+++ b/plugins/simpleping/init.d/simpleping.service.tpl
@@ -0,0 +1,21 @@
+[Unit]
+Description=SimplePing Server
+After=network.service
+After=syslog.target
+
+[Service]
+User=root
+Group=root
+Type=simple
+WorkingDirectory={$SERVER_PATH}/simpleping
+ExecStart=simpleping service
+ExecReload=/bin/kill -USR2 $MAINPID
+PermissionsStartOnly=true
+LimitNOFILE=5000
+Restart=on-failure
+RestartSec=10
+RestartPreventExitStatus=1
+PrivateTmp=false
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/plugins/simpleping/init.d/simpleping.tpl b/plugins/simpleping/init.d/simpleping.tpl
new file mode 100644
index 000000000..682ae56bc
--- /dev/null
+++ b/plugins/simpleping/init.d/simpleping.tpl
@@ -0,0 +1,46 @@
+#!/bin/sh
+# chkconfig: 2345 55 25
+# description: SimplePing Service
+
+### BEGIN INIT INFO
+# Provides: SimplePing
+# Required-Start: $all
+# Required-Stop: $all
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: starts SimplePing
+# Description: starts the MDW-Web
+### END INIT INFO
+
+# Simple SimplePing init.d script conceived to work on Linux systems
+# as it does use of the /proc filesystem.
+
+app_start(){
+ echo "Starting SimplePing server..."
+ cd {$SERVER_PATH}/simpleping
+ ./simpleping service >> {$SERVER_PATH}/simpleping/logs.pl 2>&1 &
+}
+
+app_stop(){
+ echo "SimplePing stopped"
+ ps -ef| grep simpleping | grep -v grep | grep -v python | grep -v sh | awk '{print $2}'| xargs kill
+}
+
+
+case "$1" in
+ start)
+ app_start
+ ;;
+ stop)
+ app_stop
+ ;;
+ restart|reload)
+ app_stop
+ sleep 0.3
+ app_start
+ ;;
+ *)
+ echo "Please use start or stop as first argument"
+ ;;
+esac
+
diff --git a/plugins/simpleping/install.sh b/plugins/simpleping/install.sh
new file mode 100755
index 000000000..0b75bdb5d
--- /dev/null
+++ b/plugins/simpleping/install.sh
@@ -0,0 +1,78 @@
+#!/bin/bash
+PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
+export PATH
+
+curPath=`pwd`
+rootPath=$(dirname "$curPath")
+rootPath=$(dirname "$rootPath")
+serverPath=$(dirname "$rootPath")
+
+ARCH=`uname -m`
+sysName=`uname`
+VERSION=$2
+
+install_tmp=${rootPath}/tmp/mw_install.pl
+
+Install_App()
+{
+ echo '正在安装脚本文件...' > $install_tmp
+ mkdir -p $serverPath/source
+ mkdir -p $serverPath/source/simpleping
+
+ name=linux
+ if [ "$sysName" == "Darwin" ];then
+ name="darwin"
+ fi
+
+ FILE_TGZ=simpleping_${name}_${ARCH}.tar.gz
+ APP_DIR=$serverPath/source/simpleping
+
+ # https://github.com/midoks/simpleping/releases/download/1.0/simpleping_linux_amd64.tar.gz
+ if [ ! -f $APP_DIR/${FILE_TGZ} ];then
+ wget -O $APP_DIR/${FILE_TGZ} https://github.com/midoks/simpleping/releases/download/1.0/${FILE_TGZ}
+ fi
+
+ mkdir -p $serverPath/simpleping
+ cd $APP_DIR && tar -zxvf ${FILE_TGZ} -C $serverPath/simpleping
+ echo "${VERSION}" > $serverPath/simpleping/version.pl
+
+ cd ${rootPath} && python3 ${rootPath}/plugins/simpleping/index.py start
+ cd ${rootPath} && python3 ${rootPath}/plugins/simpleping/index.py initd_install
+
+ echo '安装SimplePing成功!'
+
+}
+
+Uninstall_App()
+{
+ if [ -f /usr/lib/systemd/system/simpleping.service ];then
+ systemctl stop simpleping
+ systemctl disable simpleping
+ rm -rf /usr/lib/systemd/system/simpleping.service
+ systemctl daemon-reload
+ fi
+
+ if [ -f /lib/systemd/system/simpleping.service ];then
+ systemctl stop simpleping
+ systemctl disable simpleping
+ rm -rf /lib/systemd/system/simpleping.service
+ systemctl daemon-reload
+ fi
+
+ if [ -f $serverPath/simpleping/initd/simpleping ];then
+ $serverPath/simpleping/initd/simpleping stop
+ fi
+
+ if [ -d $serverPath/simpleping ];then
+ rm -rf $serverPath/simpleping
+ fi
+
+ echo "卸载SimplePing成功"
+}
+
+action=$1
+if [ "${1}" == 'install' ];then
+ Install_App
+else
+ Uninstall_App
+fi
diff --git a/plugins/simpleping/js/simpleping.js b/plugins/simpleping/js/simpleping.js
new file mode 100755
index 000000000..2ae8c7b16
--- /dev/null
+++ b/plugins/simpleping/js/simpleping.js
@@ -0,0 +1,72 @@
+function appPost(method, version, args,callback){
+ var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
+
+ var req_data = {};
+ req_data['name'] = 'simpleping';
+ req_data['func'] = method;
+ req_data['version'] = version;
+
+ 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 (!data.status){
+ //错误展示10S
+ layer.msg(data.msg,{icon:0,time:2000,shade: [10, '#000']});
+ return;
+ }
+
+ if(typeof(callback) == 'function'){
+ callback(data);
+ }
+ },'json');
+}
+
+function appPostCallbak(method, version, args,callback){
+ var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
+
+ var req_data = {};
+ req_data['name'] = 'simpleping';
+ req_data['func'] = method;
+ args['version'] = version;
+
+ 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 appReadme(){
+
+ var readme = '';
+ readme += '- 简单说明
';
+ readme += '- 主要是检查内网连通性
';
+ readme += '
';
+ $('.soft-man-con').html(readme);
+}
+
+
+
+function pingDataGraph(){
+ $('.soft-man-con').html('');
+}
+
+