mirror of
https://github.com/midoks/mdserver-web.git
synced 2026-10-10 16:49:26 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2438717c79 | ||
|
|
f952f88d9a | ||
|
|
019594cee7 | ||
|
|
d7980147d6 | ||
|
|
2e45194b34 | ||
|
|
8d21448edb | ||
|
|
1d986a2b16 | ||
|
|
c291cc57e7 | ||
|
|
0c9fe565e4 | ||
|
|
c04e52d3df | ||
|
|
966506bb8d | ||
|
|
11f42d5d2c | ||
|
|
ebf474aefb | ||
|
|
1ab3718fe5 | ||
|
|
aad35bb73b | ||
|
|
1c72e5b664 | ||
|
|
028307d1fc | ||
|
|
d0fc6a4c08 | ||
|
|
7507de7ed2 | ||
|
|
eb3f78ef4a | ||
|
|
a015c32e42 | ||
|
|
e5e106e3bc | ||
|
|
bc85a6003b | ||
|
|
e7bf5ef8b9 | ||
|
|
2337ea901b | ||
|
|
3a17126ac0 | ||
|
|
164bfa780c | ||
|
|
cb0375d9f7 | ||
|
|
1d15747753 | ||
|
|
af7c38a8c2 | ||
|
|
57bbf07432 | ||
|
|
fe1bc268d5 | ||
|
|
ea2cf0b691 | ||
|
|
a593e2b8e0 | ||
|
|
5394dd329a | ||
|
|
b121d08503 | ||
|
|
97800e3424 | ||
|
|
bb1068a03c | ||
|
|
f2443d9473 | ||
|
|
f7c9e6636a | ||
|
|
feb3e0220e | ||
|
|
c9951f870d | ||
|
|
c876c59e4f | ||
|
|
0e75844fd3 | ||
|
|
515a8c4272 | ||
|
|
d026385370 | ||
|
|
95ff8c66f6 | ||
|
|
6d90935784 | ||
|
|
94d45b1b07 | ||
|
|
dc1458fb2a | ||
|
|
ae74121229 | ||
|
|
f5b0ce7788 | ||
|
|
5757627a12 | ||
|
|
28f8f8945d | ||
|
|
e5386ab01c | ||
|
|
8ad9153012 | ||
|
|
2790a3890b | ||
|
|
a978c494c4 | ||
|
|
e1dd781b73 | ||
|
|
13a7c20764 | ||
|
|
7812c4983f | ||
|
|
a35ae6df9e | ||
|
|
32eefbba10 | ||
|
|
81de116417 | ||
|
|
37ace1226b | ||
|
|
7c780b32b8 | ||
|
|
eba923aa5f | ||
|
|
d97e265035 | ||
|
|
86014afedb | ||
|
|
b3626022bf | ||
|
|
e5bf49bca4 | ||
|
|
d988ce55b1 | ||
|
|
2804d0ed24 | ||
|
|
730797dcde | ||
|
|
476a4e9d88 | ||
|
|
665710f912 | ||
|
|
890a1ee864 | ||
|
|
5d7872200d | ||
|
|
ccdfde3186 | ||
|
|
f74c1ab784 | ||
|
|
82efc1a3e5 | ||
|
|
b6f87e16ac | ||
|
|
e1014a72bd | ||
|
|
218991d8d0 | ||
|
|
7937747a05 | ||
|
|
649ea30cb4 | ||
|
|
b92cfdeade | ||
|
|
76199a20a4 | ||
|
|
c42b92bb95 | ||
|
|
ce2affb119 | ||
|
|
d3e228bcd6 | ||
|
|
baac8e84ec | ||
|
|
3d0a55a383 | ||
|
|
d8c822de9d | ||
|
|
ee8a928357 | ||
|
|
785fb9698b | ||
|
|
14c3ccbfa5 | ||
|
|
41edac3e3a | ||
|
|
36173cdd0a | ||
|
|
ee59bd31e6 | ||
|
|
63004db963 | ||
|
|
93b3c5ba3c | ||
|
|
613063ce24 | ||
|
|
2e7a147fd3 | ||
|
|
894c0bff1f | ||
|
|
3ad999db00 | ||
|
|
1e5e1afeeb | ||
|
|
463d5c1b23 | ||
|
|
a24b98cbea | ||
|
|
94034125f7 | ||
|
|
17d446161b | ||
|
|
fb8c1d124e | ||
|
|
5033692886 | ||
|
|
e5ba11ae79 | ||
|
|
0be032041a | ||
|
|
3bf3e83442 | ||
|
|
bd7aefb6cc | ||
|
|
7009dfc3c4 | ||
|
|
21c30c6e99 | ||
|
|
63a0d2205d | ||
|
|
2e2e48e440 | ||
|
|
2f125383bf | ||
|
|
71877f7403 | ||
|
|
3d9d528694 | ||
|
|
39e8b98287 | ||
|
|
fe960a32ee | ||
|
|
645450f886 | ||
|
|
77b4917d3a | ||
|
|
893797b5e4 | ||
|
|
019543b790 | ||
|
|
c85fb94bc2 | ||
|
|
60f3dbf6fc | ||
|
|
b1846342d7 | ||
|
|
2f583d2e97 | ||
|
|
551bb1c3f7 | ||
|
|
36cf6c87cc | ||
|
|
66bea6a943 | ||
|
|
212d3e4ee8 | ||
|
|
422060b929 | ||
|
|
2b4f755244 | ||
|
|
67c477af14 | ||
|
|
a8502e30b3 | ||
|
|
82db6d14e0 | ||
|
|
c529d18ad8 | ||
|
|
cf54ee1736 | ||
|
|
8e8c4c47ec | ||
|
|
a6c981355c | ||
|
|
69755363ca | ||
|
|
eaa5a4d4ed | ||
|
|
4dcae9f877 | ||
|
|
424830729f | ||
|
|
a678d28a12 | ||
|
|
b9b5ecbac9 | ||
|
|
199716e1fd | ||
|
|
c95efcdd04 | ||
|
|
02f14b29ee | ||
|
|
97789d0796 | ||
|
|
ea5af1ac5b | ||
|
|
6e279a67e2 | ||
|
|
9758becc46 |
@@ -183,3 +183,6 @@ plugins/tidb
|
||||
plugins/goedge-admin
|
||||
plugins/goedge-node
|
||||
plugins/goedge-happy
|
||||
plugins/dztasks
|
||||
|
||||
data/default_new.pl
|
||||
|
||||
@@ -182,6 +182,11 @@ curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev
|
||||
|
||||
curl --insecure -fsSL https://code.midoks.icu/midoks/mdserver-web/raw/branch/dev/scripts/install_dev.sh | bash
|
||||
curl --insecure -fsSL https://code.midoks.icu/midoks/mdserver-web/raw/branch/dev/scripts/update_dev.sh | bash
|
||||
|
||||
|
||||
|
||||
curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/install_new.sh | bash
|
||||
curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/install_new.sh | bash
|
||||
```
|
||||
|
||||
### 捐赠地址 USDT(TRC20)
|
||||
|
||||
+22
-1
@@ -1383,6 +1383,17 @@ fullchain.pem 粘贴到证书输入框
|
||||
writeLog("-" * 70)
|
||||
return cert
|
||||
|
||||
def checkDomainIsExsits(self, domain):
|
||||
if mw.M('domain').where("name=?", (domain,)).count() > 0:
|
||||
return True
|
||||
|
||||
if mw.M('sites').where("name=?", (domain,)).count() > 0:
|
||||
return True
|
||||
|
||||
if mw.M('binding').where("name=?", (domain,)).count() > 0:
|
||||
return True
|
||||
return False
|
||||
|
||||
def renewCert(self, index):
|
||||
writeLog("", "wb+")
|
||||
# self.D('renew_cert', index)
|
||||
@@ -1429,6 +1440,8 @@ fullchain.pem 粘贴到证书输入框
|
||||
for domain in self.__config['orders'][i]['domains']:
|
||||
if domain.find('*') != -1:
|
||||
break
|
||||
|
||||
|
||||
if not mw.M('domain').where("name=?", (domain,)).count() and not mw.M('binding').where("domain=?", domain).count():
|
||||
auth_to = None
|
||||
msg = "|-跳过被删除的域名: {}".format(
|
||||
@@ -1439,6 +1452,14 @@ fullchain.pem 粘贴到证书输入框
|
||||
|
||||
self.__config['orders'][i]['auth_to'] = auth_to
|
||||
|
||||
auth_to = True
|
||||
for domain in self.__config['orders'][i]['domains']:
|
||||
if not self.checkDomainIsExsits(domain):
|
||||
auth_to = False
|
||||
msg = "|-跳过被删除的域名: {}!".format(self.__config['orders'][i]['domains'])
|
||||
writeLog(msg)
|
||||
if not auth_to:
|
||||
continue
|
||||
# 是否到了允许重试的时间
|
||||
if 'next_retry_time' in self.__config['orders'][i]:
|
||||
timeout = self.__config['orders'][i][
|
||||
@@ -1452,7 +1473,7 @@ fullchain.pem 粘贴到证书输入框
|
||||
# 是否到了最大重试次数
|
||||
if 'retry_count' in self.__config['orders'][i]:
|
||||
if self.__config['orders'][i]['retry_count'] >= 100:
|
||||
msg = '|-本次跳过域名:{},因连续10次续签失败,不再续签此证书(可尝试手动续签此证书,成功后错误次数将被重置)'.format(
|
||||
msg = '|-本次跳过域名:{},因连续100次续签失败,不再续签此证书(可尝试手动续签此证书,成功后错误次数将被重置)'.format(
|
||||
self.__config['orders'][i]['domains'])
|
||||
writeLog(msg)
|
||||
continue
|
||||
|
||||
@@ -28,7 +28,7 @@ from flask import request
|
||||
|
||||
class config_api:
|
||||
|
||||
__version = '0.17.3'
|
||||
__version = '0.17.4'
|
||||
__api_addr = 'data/api.json'
|
||||
|
||||
# 统一默认配置文件
|
||||
@@ -42,7 +42,7 @@ class config_api:
|
||||
'bind_domain' : 'data/bind_domain.pl', # 面板域名绑定
|
||||
'unauth_status' : 'data/unauthorized_status.pl', # URL路径未成功显示状态
|
||||
'auth_secret': 'data/auth_secret.pl', # 二次验证密钥
|
||||
'ssl':'ssl/choose.pl', # ssl设置
|
||||
'ssl':'ssl/choose.pl', # ssl设置
|
||||
'hook_database' : 'data/hook_database.json', # 数据库钩子
|
||||
'hook_menu' : 'data/hook_menu.json', # 菜单钩子
|
||||
'hook_global_static' : 'data/hook_global_static.json', # 静态文件钩子
|
||||
|
||||
@@ -1074,9 +1074,9 @@ class files_api:
|
||||
|
||||
order_arr = order.split(' ')
|
||||
if len(order_arr) < 2:
|
||||
plist = mw.sortFileList(path, order_arr[0],'')
|
||||
plist = mw.sortFileList(path, order_arr[0], '')
|
||||
else:
|
||||
plist = mw.sortFileList(path, order_arr[0],order_arr[1])
|
||||
plist = mw.sortFileList(path, order_arr[0], order_arr[1])
|
||||
|
||||
for filename in plist:
|
||||
if search:
|
||||
|
||||
@@ -173,14 +173,12 @@ class logs_api:
|
||||
|
||||
def __to_date2(self, date_str):
|
||||
tmp = date_str.split()
|
||||
s_date = str(tmp[-1]) + '-' + self.__months.get(tmp[1],
|
||||
tmp[1]) + '-' + tmp[2] + ' ' + tmp[3]
|
||||
s_date = str(tmp[-1]) + '-' + self.__months.get(tmp[1], tmp[1]) + '-' + tmp[2] + ' ' + tmp[3]
|
||||
return s_date
|
||||
|
||||
def __to_date3(self, date_str):
|
||||
tmp = date_str.split()
|
||||
s_date = str(datetime.now().year) + '-' + \
|
||||
self.__months.get(tmp[1], tmp[1]) + '-' + tmp[2] + ' ' + tmp[3]
|
||||
s_date = str(datetime.now().year) + '-' + self.__months.get(tmp[1], tmp[1]) + '-' + tmp[2] + ' ' + tmp[3]
|
||||
return s_date
|
||||
|
||||
def __to_date4(self, date_str):
|
||||
|
||||
+7
-7
@@ -593,8 +593,11 @@ def writeLog(stype, msg, args=()):
|
||||
if 'uid' in session:
|
||||
uid = session['uid']
|
||||
except Exception as e:
|
||||
pass
|
||||
print('writeL:',e)
|
||||
# pass
|
||||
# writeFileLog(getTracebackInfo())
|
||||
|
||||
print(stype, msg)
|
||||
return writeDbLog(stype, msg, args, uid)
|
||||
|
||||
|
||||
@@ -716,11 +719,9 @@ def enPunycode(domain):
|
||||
newdomain += dkey + '.'
|
||||
else:
|
||||
if sys.version_info[0] == 2:
|
||||
newdomain += 'xn--' + \
|
||||
dkey.decode('utf-8').encode('punycode') + '.'
|
||||
newdomain += 'xn--' + dkey.decode('utf-8').encode('punycode') + '.'
|
||||
else:
|
||||
newdomain += 'xn--' + \
|
||||
dkey.encode('punycode').decode('utf-8') + '.'
|
||||
newdomain += 'xn--' + dkey.encode('punycode').decode('utf-8') + '.'
|
||||
if tmp[0] == '*':
|
||||
newdomain = "*." + newdomain
|
||||
return newdomain[0:-1]
|
||||
@@ -732,8 +733,7 @@ def dePunycode(domain):
|
||||
newdomain = ''
|
||||
for dkey in tmp:
|
||||
if dkey.find('xn--') >= 0:
|
||||
newdomain += dkey.replace('xn--',
|
||||
'').encode('utf-8').decode('punycode') + '.'
|
||||
newdomain += dkey.replace('xn--','').encode('utf-8').decode('punycode') + '.'
|
||||
else:
|
||||
newdomain += dkey + '.'
|
||||
return newdomain[0:-1]
|
||||
|
||||
@@ -663,7 +663,7 @@ class plugins_api:
|
||||
return mw.readFile(version_f).strip()
|
||||
return ''
|
||||
|
||||
# 构造本地插件信息
|
||||
# 构造本地插件信息
|
||||
def getPluginInfo(self, info):
|
||||
checks = ''
|
||||
path = ''
|
||||
|
||||
+60
-60
@@ -727,43 +727,43 @@ class site_api:
|
||||
conf = mw.readFile(file)
|
||||
|
||||
if conf:
|
||||
rep = "\n\s*#HTTP_TO_HTTPS_START(.|\n){1,300}#HTTP_TO_HTTPS_END"
|
||||
rep = "\n\\s*#HTTP_TO_HTTPS_START(.|\n){1,300}#HTTP_TO_HTTPS_END"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+ssl_certificate\s+.+;\s+ssl_certificate_key\s+.+;"
|
||||
rep = "\\s+ssl_certificate\\s+.+;\\s+ssl_certificate_key\\s+.+;"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+ssl_protocols\s+.+;\n"
|
||||
rep = "\\s+ssl_protocols\\s+.+;\n"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+ssl_ciphers\s+.+;\n"
|
||||
rep = "\\s+ssl_ciphers\\s+.+;\n"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+ssl_prefer_server_ciphers\s+.+;\n"
|
||||
rep = "\\s+ssl_prefer_server_ciphers\\s+.+;\n"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+ssl_session_cache\s+.+;\n"
|
||||
rep = "\\s+ssl_session_cache\\s+.+;\n"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+ssl_session_timeout\s+.+;\n"
|
||||
rep = r"\s+ssl_session_timeout\s+.+;\n"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+ssl_ecdh_curve\s+.+;\n"
|
||||
rep = r"\s+ssl_ecdh_curve\s+.+;\n"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+ssl_session_tickets\s+.+;\n"
|
||||
rep = r"\s+ssl_session_tickets\s+.+;\n"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+ssl_stapling\s+.+;\n"
|
||||
rep = r"\s+ssl_stapling\s+.+;\n"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+ssl_stapling_verify\s+.+;\n"
|
||||
rep = r"\s+ssl_stapling_verify\s+.+;\n"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+add_header\s+.+;\n"
|
||||
rep = r"\s+add_header\s+.+;\n"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+add_header\s+.+;\n"
|
||||
rep = r"\s+add_header\s+.+;\n"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+ssl\s+on;"
|
||||
rep = r"\s+ssl\s+on;"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+error_page\s497.+;"
|
||||
rep = r"\s+error_page\s497.+;"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+if.+server_port.+\n.+\n\s+\s*}"
|
||||
rep = r"\s+if.+server_port.+\n.+\n\s+\s*}"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+listen\s+443.*;"
|
||||
rep = r"\s+listen\s+443.*;"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+listen\s+\[\:\:\]\:443.*;"
|
||||
rep = r"\s+listen\s+\[\:\:\]\:443.*;"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+http2\s+on;"
|
||||
rep = r"\s+http2\s+on;"
|
||||
conf = re.sub(rep, '', conf)
|
||||
mw.writeFile(file, conf)
|
||||
|
||||
@@ -888,7 +888,7 @@ class site_api:
|
||||
# fix binddir domain ssl apply question
|
||||
mw.backFile(host_conf_file)
|
||||
auth_to = self.getSitePath(siteName)
|
||||
rep = "\s*root\s*(.+);"
|
||||
rep = r"\s*root\s*(.+);"
|
||||
replace_root = "\n\troot " + auth_to + ";"
|
||||
siteConf = re.sub(rep, replace_root, siteConf)
|
||||
mw.writeFile(host_conf_file, siteConf)
|
||||
@@ -1043,7 +1043,7 @@ class site_api:
|
||||
src_path = mw.getAcmeDomainDir(domains[0])
|
||||
src_cert = src_path + '/fullchain.cer'
|
||||
src_key = src_path + '/' + domains[0] + '.key'
|
||||
src_cert.replace("\*", "*")
|
||||
src_cert.replace("\\*", "*")
|
||||
|
||||
msg = '签发失败,您尝试申请证书的失败次数已达上限!<p>1、检查域名是否绑定到对应站点</p>\
|
||||
<p>2、检查域名是否正确解析到本服务器,或解析还未完全生效</p>\
|
||||
@@ -1115,9 +1115,9 @@ class site_api:
|
||||
file = self.getHostConf(site_name)
|
||||
conf = mw.readFile(file)
|
||||
if conf:
|
||||
rep = "\n\s*#HTTP_TO_HTTPS_START(.|\n){1,300}#HTTP_TO_HTTPS_END"
|
||||
rep = r"\n\s*#HTTP_TO_HTTPS_START(.|\n){1,300}#HTTP_TO_HTTPS_END"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+if.+server_port.+\n.+\n\s+\s*}"
|
||||
rep = r"\s+if.+server_port.+\n.+\n\s+\s*}"
|
||||
conf = re.sub(rep, '', conf)
|
||||
mw.writeFile(file, conf)
|
||||
|
||||
@@ -1282,7 +1282,7 @@ class site_api:
|
||||
domain_name = self.toPunycode(domain[0])
|
||||
domain_port = '80'
|
||||
|
||||
reg = "^([\w\-\*]{1,100}\.){1,4}([\w\-]{1,24}|[\w\-]{1,24}\.[\w\-]{1,24})$"
|
||||
reg = r"^([\w\-\*]{1,100}\.){1,4}([\w\-]{1,24}|[\w\-]{1,24}\.[\w\-]{1,24})$"
|
||||
if not re.match(reg, domain_name):
|
||||
return mw.returnJson(False, '域名格式不正确!')
|
||||
|
||||
@@ -1339,7 +1339,7 @@ class site_api:
|
||||
if dirName == '':
|
||||
mw.returnJson(False, '目录不能为空!')
|
||||
|
||||
reg = "^([\w\-\*]{1,100}\.){1,4}(\w{1,10}|\w{1,10}\.\w{1,10})$"
|
||||
reg = r"^([\w\-\*]{1,100}\.){1,4}(\w{1,10}|\w{1,10}\.\w{1,10})$"
|
||||
if not re.match(reg, domain):
|
||||
return mw.returnJson(False, '主域名格式不正确!')
|
||||
|
||||
@@ -1355,7 +1355,7 @@ class site_api:
|
||||
filename = self.getHostConf(siteInfo['name'])
|
||||
conf = mw.readFile(filename)
|
||||
if conf:
|
||||
rep = "enable-php-([0-9]{2,3})\.conf"
|
||||
rep = r"enable-php-([0-9]{2,3})\.conf"
|
||||
tmp = re.search(rep, conf).groups()
|
||||
version = tmp[0]
|
||||
|
||||
@@ -1507,7 +1507,7 @@ class site_api:
|
||||
filename = self.getHostConf(siteName)
|
||||
if os.path.exists(filename):
|
||||
conf = mw.readFile(filename)
|
||||
rep = '\s*root\s*(.+);'
|
||||
rep = r'\s*root\s*(.+);'
|
||||
path = re.search(rep, conf).groups()[0]
|
||||
conf = conf.replace(path, newPath)
|
||||
mw.writeFile(filename, conf)
|
||||
@@ -1578,7 +1578,7 @@ class site_api:
|
||||
|
||||
if os.path.exists(configFile):
|
||||
conf = mw.readFile(configFile)
|
||||
rep = "\n\s*#AUTH_START(.|\n){1,200}#AUTH_END"
|
||||
rep = r"\n\s*#AUTH_START(.|\n){1,200}#AUTH_END"
|
||||
conf = re.sub(rep, '', conf)
|
||||
mw.writeFile(configFile, conf)
|
||||
|
||||
@@ -1604,19 +1604,19 @@ class site_api:
|
||||
conf = mw.readFile(file)
|
||||
if conf:
|
||||
# 删除域名
|
||||
rep = "server_name\s+(.+);"
|
||||
rep = r"server_name\s+(.+);"
|
||||
tmp = re.search(rep, conf).group()
|
||||
newServerName = tmp.replace(' ' + domain + ';', ';')
|
||||
newServerName = newServerName.replace(' ' + domain + ' ', ' ')
|
||||
conf = conf.replace(tmp, newServerName)
|
||||
|
||||
# 删除端口
|
||||
rep = "listen\s+([0-9]+);"
|
||||
rep = r"listen\s+([0-9]+);"
|
||||
tmp = re.findall(rep, conf)
|
||||
port_count = mw.M('domain').where(
|
||||
'pid=? AND port=?', (pid, port)).count()
|
||||
if mw.inArray(tmp, port) == True and port_count < 2:
|
||||
rep = "\n*\s+listen\s+" + port + ";"
|
||||
rep = r"\n*\s+listen\s+" + port + ";"
|
||||
conf = re.sub(rep, '', conf)
|
||||
# 保存配置
|
||||
mw.writeFile(file, conf)
|
||||
@@ -1778,7 +1778,7 @@ class site_api:
|
||||
if item["r_from"] == _from:
|
||||
return mw.returnJson(False, "重复的规则!")
|
||||
|
||||
rep = "http(s)?\:\/\/([a-zA-Z0-9][-a-zA-Z0-9]{0,62}\.)+([a-zA-Z0-9][a-zA-Z0-9]{0,62})+.?"
|
||||
rep = r"http(s)?\:\/\/([a-zA-Z0-9][-a-zA-Z0-9]{0,62}\.)+([a-zA-Z0-9][a-zA-Z0-9]{0,62})+.?"
|
||||
if not re.match(rep, _to):
|
||||
return mw.returnJson(False, "错误的目标地址")
|
||||
|
||||
@@ -1942,7 +1942,7 @@ class site_api:
|
||||
if _name == "" or _siteName == "" or _from == "" or _to == "" or _host == "":
|
||||
return mw.returnJson(False, "必填项不能为空")
|
||||
|
||||
rep = "http(s)?\:\/\/([a-zA-Z0-9][-a-zA-Z0-9]{0,62}\.)+([a-zA-Z0-9][a-zA-Z0-9]{0,62})+.?"
|
||||
rep = r"http(s)?\:\/\/([a-zA-Z0-9][-a-zA-Z0-9]{0,62}\.)+([a-zA-Z0-9][a-zA-Z0-9]{0,62})+.?"
|
||||
if not re.match(rep, _to):
|
||||
return mw.returnJson(False, "错误的目标地址!")
|
||||
|
||||
@@ -1990,7 +1990,7 @@ location ^~ {from} {\n\
|
||||
}\n\
|
||||
# PROXY-END"
|
||||
|
||||
tpl_proxy_cache = "\n\
|
||||
tpl_proxy_cache = r"\n\
|
||||
if ( $uri ~* \"\.(gif|png|jpg|css|js|woff|woff2)$\" )\n\
|
||||
{\n\
|
||||
expires {cache_time}m;\n\
|
||||
@@ -2001,7 +2001,7 @@ location ^~ {from} {\n\
|
||||
proxy_cache_valid 200 304 301 302 {cache_time}m;\n\
|
||||
"
|
||||
|
||||
tpl_proxy_nocache = "\n\
|
||||
tpl_proxy_nocache = r"\n\
|
||||
set $static_files_app 0; \n\
|
||||
if ( $uri ~* \"\.(gif|png|jpg|css|js|woff|woff2)$\" )\n\
|
||||
{\n\
|
||||
@@ -2219,7 +2219,7 @@ location ^~ {from} {\n\
|
||||
file = self.getHostConf(siteName)
|
||||
if os.path.exists(file):
|
||||
conf = mw.readFile(file)
|
||||
rep = '\s*root\s*(.+);'
|
||||
rep = r'\s*root\s*(.+);'
|
||||
find_cnf = re.search(rep, conf)
|
||||
if not find_cnf:
|
||||
return ''
|
||||
@@ -2236,7 +2236,7 @@ location ^~ {from} {\n\
|
||||
filename = self.getHostConf(siteName)
|
||||
if os.path.exists(filename):
|
||||
conf = mw.readFile(filename)
|
||||
rep = '\s*root\s*(.+);'
|
||||
rep = r'\s*root\s*(.+);'
|
||||
path = re.search(rep, conf).groups()[0]
|
||||
|
||||
data = {}
|
||||
@@ -2321,7 +2321,7 @@ location ^~ {from} {\n\
|
||||
|
||||
def getSitePhpVersion(self, siteName):
|
||||
conf = mw.readFile(self.getHostConf(siteName))
|
||||
rep = "enable-php-(.*)\.conf"
|
||||
rep = r"enable-php-(.*)\.conf"
|
||||
find_php_cnf = re.search(rep, conf)
|
||||
|
||||
def_pver = '00'
|
||||
@@ -2337,7 +2337,7 @@ location ^~ {from} {\n\
|
||||
siteName = mw.M('sites').where("id=?", (sid,)).getField('name')
|
||||
file = self.getHostConf(siteName)
|
||||
conf = mw.readFile(file)
|
||||
rep = "\s+index\s+(.+);"
|
||||
rep = r"\s+index\s+(.+);"
|
||||
tmp = re.search(rep, conf).groups()
|
||||
return tmp[0].replace(' ', ',')
|
||||
|
||||
@@ -2356,7 +2356,7 @@ location ^~ {from} {\n\
|
||||
file = self.getHostConf(siteName)
|
||||
conf = mw.readFile(file)
|
||||
if conf:
|
||||
rep = "\s+index\s+.+;"
|
||||
rep = r"\s+index\s+.+;"
|
||||
conf = re.sub(rep, "\n\tindex " + index_l + ";", conf)
|
||||
mw.writeFile(file, conf)
|
||||
|
||||
@@ -2370,17 +2370,17 @@ location ^~ {from} {\n\
|
||||
data = {}
|
||||
conf = mw.readFile(filename)
|
||||
try:
|
||||
rep = "\s+limit_conn\s+perserver\s+([0-9]+);"
|
||||
rep = r"\s+limit_conn\s+perserver\s+([0-9]+);"
|
||||
tmp = re.search(rep, conf).groups()
|
||||
data['perserver'] = int(tmp[0])
|
||||
|
||||
# IP并发限制
|
||||
rep = "\s+limit_conn\s+perip\s+([0-9]+);"
|
||||
rep = r"\s+limit_conn\s+perip\s+([0-9]+);"
|
||||
tmp = re.search(rep, conf).groups()
|
||||
data['perip'] = int(tmp[0])
|
||||
|
||||
# 请求并发限制
|
||||
rep = "\s+limit_rate\s+([0-9]+)\w+;"
|
||||
rep = r"\s+limit_rate\s+([0-9]+)\w+;"
|
||||
tmp = re.search(rep, conf).groups()
|
||||
data['limit_rate'] = int(tmp[0])
|
||||
except:
|
||||
@@ -2410,15 +2410,15 @@ location ^~ {from} {\n\
|
||||
conf = mw.readFile(filename)
|
||||
if(conf.find('limit_conn perserver') != -1):
|
||||
# 替换总并发
|
||||
rep = "limit_conn\s+perserver\s+([0-9]+);"
|
||||
rep = r"limit_conn\s+perserver\s+([0-9]+);"
|
||||
conf = re.sub(rep, str_perserver, conf)
|
||||
|
||||
# 替换IP并发限制
|
||||
rep = "limit_conn\s+perip\s+([0-9]+);"
|
||||
rep = r"limit_conn\s+perip\s+([0-9]+);"
|
||||
conf = re.sub(rep, str_perip, conf)
|
||||
|
||||
# 替换请求流量限制
|
||||
rep = "limit_rate\s+([0-9]+)\w+;"
|
||||
rep = r"limit_rate\s+([0-9]+)\w+;"
|
||||
conf = re.sub(rep, str_limit_rate, conf)
|
||||
else:
|
||||
conf = conf.replace('#error_page 404/404.html;', "#error_page 404/404.html;\n " +
|
||||
@@ -2434,15 +2434,15 @@ location ^~ {from} {\n\
|
||||
filename = self.getHostConf(siteName)
|
||||
conf = mw.readFile(filename)
|
||||
# 清理总并发
|
||||
rep = "\s+limit_conn\s+perserver\s+([0-9]+);"
|
||||
rep = r"\s+limit_conn\s+perserver\s+([0-9]+);"
|
||||
conf = re.sub(rep, '', conf)
|
||||
|
||||
# 清理IP并发限制
|
||||
rep = "\s+limit_conn\s+perip\s+([0-9]+);"
|
||||
rep = r"\s+limit_conn\s+perip\s+([0-9]+);"
|
||||
conf = re.sub(rep, '', conf)
|
||||
|
||||
# 清理请求流量限制
|
||||
rep = "\s+limit_rate\s+([0-9]+)\w+;"
|
||||
rep = r"\s+limit_rate\s+([0-9]+)\w+;"
|
||||
conf = re.sub(rep, '', conf)
|
||||
mw.writeFile(filename, conf)
|
||||
mw.restartWeb()
|
||||
@@ -2458,15 +2458,15 @@ location ^~ {from} {\n\
|
||||
rep = "#SECURITY-START(\n|.){1,500}#SECURITY-END"
|
||||
tmp = re.search(rep, conf).group()
|
||||
data['fix'] = re.search(
|
||||
"\(.+\)\$", tmp).group().replace('(', '').replace(')$', '').replace('|', ',')
|
||||
r"\(.+\)\$", tmp).group().replace('(', '').replace(')$', '').replace('|', ',')
|
||||
|
||||
data['status'] = False
|
||||
data['none'] = False
|
||||
|
||||
valid_referers = re.search(
|
||||
"valid_referers\s+(.+);\n", tmp)
|
||||
r"valid_referers\s+(.+);\n", tmp)
|
||||
valid_referers_none = re.search(
|
||||
"valid_referers\s+none\s+blocked\s+(.+);\n", tmp)
|
||||
r"valid_referers\s+none\s+blocked\s+(.+);\n", tmp)
|
||||
|
||||
if valid_referers or valid_referers_none:
|
||||
data['status'] = True
|
||||
@@ -2500,11 +2500,11 @@ location ^~ {from} {\n\
|
||||
if os.path.exists(file):
|
||||
conf = mw.readFile(file)
|
||||
if status == 'false':
|
||||
rep = "\s{0,4}#SECURITY-START(\n|.){1,500}#SECURITY-END\n?"
|
||||
rep = r"\s{0,4}#SECURITY-START(\n|.){1,500}#SECURITY-END\n?"
|
||||
conf = re.sub(rep, '', conf)
|
||||
mw.writeLog('网站管理', '站点[' + name + ']已关闭防盗链设置!')
|
||||
else:
|
||||
rep = "\s{0,4}#SECURITY-START(\n|.){1,500}#SECURITY-END\n?"
|
||||
rep = r"\s{0,4}#SECURITY-START(\n|.){1,500}#SECURITY-END\n?"
|
||||
conf = re.sub(rep, '', conf)
|
||||
|
||||
valid_referers = domains.strip().replace(',', ' ')
|
||||
@@ -2512,8 +2512,8 @@ location ^~ {from} {\n\
|
||||
valid_referers = 'none blocked ' + valid_referers
|
||||
|
||||
pre_path = self.setupPath + "/php/conf"
|
||||
re_path = "include\s+" + pre_path + "/enable-php-"
|
||||
rconf = '''#SECURITY-START 防盗链配置
|
||||
re_path = r"include\s+" + pre_path + "/enable-php-"
|
||||
rconf = r'''#SECURITY-START 防盗链配置
|
||||
location ~ .*\.(%s)$
|
||||
{
|
||||
expires 30d;
|
||||
@@ -2555,7 +2555,7 @@ location ^~ {from} {\n\
|
||||
conf_dir = mw.getServerDir() + "/web_conf/php/conf"
|
||||
conf_list = os.listdir(conf_dir)
|
||||
l = len(conf_list)
|
||||
rep = "enable-php-(.*?)\.conf"
|
||||
rep = r"enable-php-(.*?)\.conf"
|
||||
for name in conf_list:
|
||||
tmp = {}
|
||||
try:
|
||||
@@ -2611,7 +2611,7 @@ location ^~ {from} {\n\
|
||||
return
|
||||
|
||||
# 添加域名
|
||||
rep = "server_name\s*(.*);"
|
||||
rep = r"server_name\s*(.*);"
|
||||
tmp = re.search(rep, conf).group()
|
||||
domains = tmp.split(' ')
|
||||
if not mw.inArray(domains, domain):
|
||||
@@ -2619,7 +2619,7 @@ location ^~ {from} {\n\
|
||||
conf = conf.replace(tmp, newServerName)
|
||||
|
||||
# 添加端口
|
||||
rep = "listen\s+([0-9]+)\s*[default_server]*\s*;"
|
||||
rep = r"listen\s+([0-9]+)\s*[default_server]*\s*;"
|
||||
tmp = re.findall(rep, conf)
|
||||
if not mw.inArray(tmp, port):
|
||||
listen = re.search(rep, conf).group()
|
||||
@@ -2820,7 +2820,7 @@ location ^~ {from} {\n\
|
||||
|
||||
conf = conf.replace('#error_page 404/404.html;', sslStr)
|
||||
|
||||
rep = "listen\s+([0-9]+)\s*[default_server|reuseport]*;"
|
||||
rep = r"listen\s+([0-9]+)\s*[default_server|reuseport]*;"
|
||||
tmp = re.findall(rep, conf)
|
||||
if not mw.inArray(tmp, '443'):
|
||||
listen = re.search(rep, conf).group()
|
||||
|
||||
@@ -717,7 +717,6 @@ class system_api:
|
||||
|
||||
self.cache[iokey] = {'info':diskio_group,'time':mtime}
|
||||
except Exception as e:
|
||||
# print(mw.getTracebackInfo())
|
||||
pass
|
||||
|
||||
return diskInfo
|
||||
@@ -866,6 +865,7 @@ class system_api:
|
||||
return {}
|
||||
|
||||
def updateServer(self, stype, version=''):
|
||||
return mw.returnJson(False, '与后续版本差异太大,不再提供更新')
|
||||
# 更新服务
|
||||
try:
|
||||
if not mw.isRestart():
|
||||
|
||||
@@ -3,5 +3,6 @@ PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/usr/loc
|
||||
|
||||
|
||||
|
||||
find . -name .DS_Store -print0 | xargs -0 git rm -f --ignore-unmatch
|
||||
find . -name .DS_Store | xargs rm -rf
|
||||
find . -type d -name "*.pyc" | xargs rm -rf
|
||||
+1
-1
@@ -40,7 +40,7 @@ server
|
||||
allow all;
|
||||
}
|
||||
|
||||
location ~ .*\\.(gif|jpg|jpeg|png|bmp|swf|js|css)$
|
||||
location ~ .*\\.(gif|jpg|jpeg|png|bmp|swf|js|css|ttf|woff2)$
|
||||
{
|
||||
expires 30d;
|
||||
error_log /dev/null;
|
||||
|
||||
Executable
+113
@@ -0,0 +1,113 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
DIR=$(cd "$(dirname "$0")"; pwd)
|
||||
MDIR=$(dirname "$DIR")
|
||||
|
||||
# echo $DIR
|
||||
|
||||
PATH=$PATH:$DIR/bin
|
||||
if [ -f ${DIR}/bin/activate ];then
|
||||
source ${DIR}/bin/activate
|
||||
|
||||
if [ "$?" != "0" ];then
|
||||
echo "load local python env fail!"
|
||||
fi
|
||||
fi
|
||||
|
||||
export LC_ALL="en_US.UTF-8"
|
||||
|
||||
|
||||
mw_start_task()
|
||||
{
|
||||
isStart=$(ps aux |grep 'panel_task.py'|grep -v grep|awk '{print $2}')
|
||||
if [ "$isStart" == '' ];then
|
||||
echo -e "starting mw-tasks... \c"
|
||||
cd $DIR && python3 panel_task.py >> ${DIR}/logs/panel_task.log 2>&1 &
|
||||
sleep 0.3
|
||||
isStart=$(ps aux |grep 'panel_task.py'|grep -v grep|awk '{print $2}')
|
||||
if [ "$isStart" == '' ];then
|
||||
echo -e "\033[31mfailed\033[0m"
|
||||
echo '------------------------------------------------------'
|
||||
tail -n 20 $DIR/logs/panel_task.log
|
||||
echo '------------------------------------------------------'
|
||||
echo -e "\033[31mError: mw-tasks service startup failed.\033[0m"
|
||||
return;
|
||||
fi
|
||||
echo -e "\033[32mdone\033[0m"
|
||||
else
|
||||
echo "starting mw-tasks... mw-tasks (pid $(echo $isStart)) already running"
|
||||
fi
|
||||
}
|
||||
|
||||
mw_start(){
|
||||
cd web && gunicorn -c setting.py app:app
|
||||
#安全启动
|
||||
mw_start_task
|
||||
}
|
||||
|
||||
|
||||
mw_start_debug(){
|
||||
if [ ! -f $DIR/logs/panel_task.log ];then
|
||||
echo '' > $DIR/logs/panel_task.log
|
||||
fi
|
||||
|
||||
python3 panel_task.py >> $DIR/logs/panel_task.log 2>&1 &
|
||||
port=7200
|
||||
if [ -f /www/server/mdserver-web/data/port.pl ];then
|
||||
port=$(cat /www/server/mdserver-web/data/port.pl)
|
||||
fi
|
||||
|
||||
if [ -f ${DIR}/data/port.pl ];then
|
||||
port=$(cat ${DIR}/data/port.pl)
|
||||
fi
|
||||
# gunicorn -b :${port} -k gevent -w 1 app:app
|
||||
cd web && gunicorn -b :${port} -w 1 app:app
|
||||
}
|
||||
|
||||
mw_start_debug2(){
|
||||
python3 panel_task.py >> $DIR/logs/panel_task.log 2>&1 &
|
||||
gunicorn -b :7200 -w 1 app:app
|
||||
}
|
||||
|
||||
mw_start_debug3(){
|
||||
gunicorn -c setting.py app:app
|
||||
python3 panel_task.py
|
||||
}
|
||||
|
||||
|
||||
mw_stop()
|
||||
{
|
||||
PLIST=`ps -ef|grep app:app |grep -v grep|awk '{print $2}'`
|
||||
for i in $PLIST
|
||||
do
|
||||
kill -9 $i > /dev/null 2>&1
|
||||
done
|
||||
|
||||
pids=`ps -ef|grep panel_task.py | grep -v grep |awk '{print $2}'`
|
||||
arr=($pids)
|
||||
for p in ${arr[@]}
|
||||
do
|
||||
kill -9 $p > /dev/null 2>&1
|
||||
done
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
'start') mw_start;;
|
||||
'stop') mw_stop;;
|
||||
'restart')
|
||||
mw_stop
|
||||
mw_start
|
||||
;;
|
||||
'debug')
|
||||
mw_stop
|
||||
mw_start_debug
|
||||
;;
|
||||
'debug2')
|
||||
mw_stop
|
||||
mw_start_debug2
|
||||
;;
|
||||
'debug3')
|
||||
mw_stop
|
||||
mw_start_debug3
|
||||
;;
|
||||
esac
|
||||
Executable
+626
@@ -0,0 +1,626 @@
|
||||
# coding: utf-8
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# MW-Linux面板
|
||||
# ---------------------------------------------------------------------------------
|
||||
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
|
||||
# ---------------------------------------------------------------------------------
|
||||
# Author: midoks <midoks@163.com>
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# 计划任务
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
import time
|
||||
import threading
|
||||
import psutil
|
||||
|
||||
|
||||
web_dir = os.getcwd() + "/web"
|
||||
os.chdir(web_dir)
|
||||
sys.path.append(web_dir)
|
||||
|
||||
from admin import app
|
||||
from admin import model
|
||||
|
||||
import core.mw as mw
|
||||
import core.db as db
|
||||
|
||||
|
||||
# print(mw.getPanelDir())
|
||||
|
||||
# print sys.path
|
||||
|
||||
# cmd = 'ls /usr/local/lib/ | grep python | cut -d \\ -f 1 | awk \'END {print}\''
|
||||
# info = mw.execShell(cmd)
|
||||
# p = "/usr/local/lib/" + info[0].strip() + "/site-packages"
|
||||
# sys.path.append(p)
|
||||
|
||||
|
||||
global pre, timeoutCount, logPath, isTask, oldEdate, isCheck
|
||||
pre = 0
|
||||
timeoutCount = 0
|
||||
isCheck = 0
|
||||
oldEdate = None
|
||||
|
||||
g_log_file = mw.getPanelTaskLog()
|
||||
isTask = mw.getMWLogs() + '/panelTask.pl'
|
||||
|
||||
if not os.path.exists(g_log_file):
|
||||
os.system("touch " + g_log_file)
|
||||
|
||||
def execShell(cmdstring, cwd=None, timeout=None, shell=True):
|
||||
try:
|
||||
global g_log_file
|
||||
import shlex
|
||||
import datetime
|
||||
import subprocess
|
||||
|
||||
if timeout:
|
||||
end_time = datetime.datetime.now() + datetime.timedelta(seconds=timeout)
|
||||
|
||||
cmd = cmdstring + ' > ' + g_log_file + ' 2>&1'
|
||||
sub = subprocess.Popen(cmd, cwd=cwd, stdin=subprocess.PIPE, shell=shell, bufsize=4096)
|
||||
while sub.poll() is None:
|
||||
time.sleep(0.1)
|
||||
|
||||
data = sub.communicate()
|
||||
# python3 fix 返回byte数据
|
||||
if isinstance(data[0], bytes):
|
||||
t1 = str(data[0], encoding='utf-8')
|
||||
|
||||
if isinstance(data[1], bytes):
|
||||
t2 = str(data[1], encoding='utf-8')
|
||||
return (t1, t2)
|
||||
except Exception as e:
|
||||
return (None, None)
|
||||
|
||||
def service_cmd(method):
|
||||
cmd = '/etc/init.d/mw'
|
||||
if os.path.exists(cmd):
|
||||
execShell(cmd + ' ' + method)
|
||||
return
|
||||
|
||||
cmd = mw.getRunDir() + '/scripts/init.d/mw'
|
||||
if os.path.exists(cmd):
|
||||
execShell(cmd + ' ' + method)
|
||||
return
|
||||
|
||||
|
||||
def openresty_cmd(method = 'reload'):
|
||||
# 检查是否安装
|
||||
odir = mw.getServerDir() + '/openresty'
|
||||
if not os.path.exists(odir):
|
||||
return False
|
||||
|
||||
# systemd
|
||||
systemd = mw.systemdCfgDir()+'/openresty.service'
|
||||
if os.path.exists(systemd):
|
||||
execShell('systemctl ' + method + ' openresty')
|
||||
return True
|
||||
|
||||
sys_initd = '/etc/init.d/openresty'
|
||||
if os.path.exists(sys_initd):
|
||||
os.system(sys_initd + ' ' + method)
|
||||
return True
|
||||
|
||||
install_initd = mw.getServerDir()+'/openresty/init.d/openresty'
|
||||
if os.path.exists(install_initd):
|
||||
os.system(install_initd + ' ' + method)
|
||||
return True
|
||||
return False
|
||||
|
||||
def mw_async(f):
|
||||
def wrapper(*args, **kwargs):
|
||||
thr = threading.Thread(target=f, args=args, kwargs=kwargs)
|
||||
thr.start()
|
||||
return wrapper
|
||||
|
||||
|
||||
@mw_async
|
||||
def restartMw():
|
||||
time.sleep(1)
|
||||
cmd = mw.getRunDir() + '/scripts/init.d/mw reload &'
|
||||
mw.execShell(cmd)
|
||||
|
||||
|
||||
|
||||
def downloadFile(url, filename):
|
||||
# 下载文件
|
||||
try:
|
||||
import urllib
|
||||
import socket
|
||||
socket.setdefaulttimeout(300)
|
||||
|
||||
headers = ('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36')
|
||||
opener = urllib.request.build_opener()
|
||||
opener.addheaders = [headers]
|
||||
urllib.request.install_opener(opener)
|
||||
|
||||
urllib.request.urlretrieve(url, filename=filename, reporthook=downloadHook)
|
||||
|
||||
if not mw.isAppleSystem():
|
||||
os.system('chown www.www ' + filename)
|
||||
|
||||
writeLogs('done')
|
||||
except Exception as e:
|
||||
writeLogs(str(e))
|
||||
return True
|
||||
|
||||
|
||||
def downloadHook(count, blockSize, totalSize):
|
||||
# 下载文件进度回调
|
||||
global pre
|
||||
used = count * blockSize
|
||||
pre1 = int((100.0 * used / totalSize))
|
||||
if pre == (100 - pre1):
|
||||
return
|
||||
speed = {'total': totalSize, 'used': used, 'pre': pre1}
|
||||
writeLogs(json.dumps(speed))
|
||||
|
||||
|
||||
def writeLogs(data):
|
||||
# 写输出日志
|
||||
try:
|
||||
fp = open(g_log_file, 'w+')
|
||||
fp.write(data)
|
||||
fp.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def runPanelTask():
|
||||
try:
|
||||
bash_list = model.getTaskList(status=-1)
|
||||
for task in bash_list:
|
||||
model.setTaskStatus(task['id'], 0)
|
||||
|
||||
run_list = model.getTaskList(status=0)
|
||||
for run_task in run_list:
|
||||
start = int(time.time())
|
||||
model.setTaskData(run_task['id'], start=start)
|
||||
model.setTaskStatus(run_task['id'], -1)
|
||||
if run_task['type'] == 'download':
|
||||
argv = run_task['cmd'].split('|mw|')
|
||||
downloadFile(argv[0], argv[1])
|
||||
elif run_task['type'] == 'execshell':
|
||||
execShell(run_task['cmd'])
|
||||
end = int(time.time())
|
||||
model.setTaskData(run_task['id'], end=end)
|
||||
model.setTaskStatus(run_task['id'], 1)
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
|
||||
# 站点过期检查
|
||||
# siteEdate()
|
||||
|
||||
# 任务队列
|
||||
def startPanelTask():
|
||||
try:
|
||||
while True:
|
||||
runPanelTask()
|
||||
time.sleep(1)
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
time.sleep(10)
|
||||
startPanelTask()
|
||||
|
||||
# 网站到期处理
|
||||
def siteEdate():
|
||||
global oldEdate
|
||||
try:
|
||||
if not oldEdate:
|
||||
oldEdate = mw.readFile('data/edate.pl')
|
||||
if not oldEdate:
|
||||
oldEdate = '0000-00-00'
|
||||
mEdate = time.strftime('%Y-%m-%d', time.localtime())
|
||||
if oldEdate == mEdate:
|
||||
return False
|
||||
edateSites = mw.M('sites').where('edate>? AND edate<? AND (status=? OR status=?)',
|
||||
('0000-00-00', mEdate, 1, '正在运行')).field('id,name').select()
|
||||
import site_api
|
||||
for site in edateSites:
|
||||
site_api.site_api().stop(site['id'], site['name'])
|
||||
oldEdate = mEdate
|
||||
mw.writeFile('data/edate.pl', mEdate)
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
|
||||
|
||||
def systemTask():
|
||||
# 系统监控任务
|
||||
try:
|
||||
import system_api
|
||||
import psutil
|
||||
sm = system_api.system_api()
|
||||
filename = 'data/control.conf'
|
||||
|
||||
sql = db.Sql().dbfile('system')
|
||||
csql = mw.readFile('data/sql/system.sql')
|
||||
csql_list = csql.split(';')
|
||||
for index in range(len(csql_list)):
|
||||
sql.execute(csql_list[index], ())
|
||||
|
||||
cpuIo = cpu = {}
|
||||
cpuCount = psutil.cpu_count()
|
||||
used = count = 0
|
||||
reloadNum = 0
|
||||
network_up = network_down = diskio_1 = diskio_2 = networkInfo = cpuInfo = diskInfo = None
|
||||
while True:
|
||||
if not os.path.exists(filename):
|
||||
time.sleep(10)
|
||||
continue
|
||||
|
||||
day = 30
|
||||
try:
|
||||
day = int(mw.readFile(filename))
|
||||
if day < 1:
|
||||
time.sleep(10)
|
||||
continue
|
||||
except:
|
||||
day = 30
|
||||
|
||||
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()
|
||||
cpuInfo = tmp
|
||||
|
||||
if cpuInfo['used'] < tmp['used']:
|
||||
tmp['mem'] = sm.getMemUsed()
|
||||
cpuInfo = tmp
|
||||
|
||||
# 取当前网络Io
|
||||
networkIo = sm.psutilNetIoCounters()
|
||||
if not network_up:
|
||||
network_up = networkIo[0]
|
||||
network_down = networkIo[1]
|
||||
tmp = {}
|
||||
tmp['upTotal'] = networkIo[0]
|
||||
tmp['downTotal'] = networkIo[1]
|
||||
tmp['up'] = round(float((networkIo[0] - network_up) / 1024), 2)
|
||||
tmp['down'] = round(float((networkIo[1] - network_down) / 1024), 2)
|
||||
tmp['downPackets'] = networkIo[3]
|
||||
tmp['upPackets'] = networkIo[2]
|
||||
|
||||
network_up = networkIo[0]
|
||||
network_down = networkIo[1]
|
||||
|
||||
if not networkInfo:
|
||||
networkInfo = tmp
|
||||
if (tmp['up'] + tmp['down']) > (networkInfo['up'] + networkInfo['down']):
|
||||
networkInfo = tmp
|
||||
# 取磁盘Io
|
||||
# if os.path.exists('/proc/diskstats'):
|
||||
diskio_2 = psutil.disk_io_counters()
|
||||
if not diskio_1:
|
||||
diskio_1 = diskio_2
|
||||
tmp = {}
|
||||
tmp['read_count'] = diskio_2.read_count - diskio_1.read_count
|
||||
tmp['write_count'] = diskio_2.write_count - diskio_1.write_count
|
||||
tmp['read_bytes'] = diskio_2.read_bytes - diskio_1.read_bytes
|
||||
tmp['write_bytes'] = diskio_2.write_bytes - diskio_1.write_bytes
|
||||
tmp['read_time'] = diskio_2.read_time - diskio_1.read_time
|
||||
tmp['write_time'] = diskio_2.write_time - diskio_1.write_time
|
||||
|
||||
if not diskInfo:
|
||||
diskInfo = tmp
|
||||
else:
|
||||
diskInfo['read_count'] += tmp['read_count']
|
||||
diskInfo['write_count'] += tmp['write_count']
|
||||
diskInfo['read_bytes'] += tmp['read_bytes']
|
||||
diskInfo['write_bytes'] += tmp['write_bytes']
|
||||
diskInfo['read_time'] += tmp['read_time']
|
||||
diskInfo['write_time'] += tmp['write_time']
|
||||
diskio_1 = diskio_2
|
||||
|
||||
# print diskInfo
|
||||
if count >= 12:
|
||||
try:
|
||||
addtime = int(time.time())
|
||||
deltime = addtime - (day * 86400)
|
||||
|
||||
data = (cpuInfo['used'], cpuInfo['mem'], addtime)
|
||||
sql.table('cpuio').add('pro,mem,addtime', data)
|
||||
sql.table('cpuio').where("addtime<?", (deltime,)).delete()
|
||||
|
||||
data = (networkInfo['up'] / 5, networkInfo['down'] / 5, networkInfo['upTotal'], networkInfo[
|
||||
'downTotal'], networkInfo['downPackets'], networkInfo['upPackets'], addtime)
|
||||
sql.table('network').add(
|
||||
'up,down,total_up,total_down,down_packets,up_packets,addtime', data)
|
||||
sql.table('network').where(
|
||||
"addtime<?", (deltime,)).delete()
|
||||
# if os.path.exists('/proc/diskstats'):
|
||||
data = (diskInfo['read_count'], diskInfo['write_count'], diskInfo['read_bytes'], diskInfo[
|
||||
'write_bytes'], diskInfo['read_time'], diskInfo['write_time'], addtime)
|
||||
sql.table('diskio').add(
|
||||
'read_count,write_count,read_bytes,write_bytes,read_time,write_time,addtime', data)
|
||||
sql.table('diskio').where(
|
||||
"addtime<?", (deltime,)).delete()
|
||||
|
||||
# LoadAverage
|
||||
load_average = sm.getLoadAverage()
|
||||
lpro = round(
|
||||
(load_average['one'] / load_average['max']) * 100, 2)
|
||||
if lpro > 100:
|
||||
lpro = 100
|
||||
sql.table('load_average').add('pro,one,five,fifteen,addtime', (lpro, load_average[
|
||||
'one'], load_average['five'], load_average['fifteen'], addtime))
|
||||
|
||||
lpro = None
|
||||
load_average = None
|
||||
cpuInfo = None
|
||||
networkInfo = None
|
||||
diskInfo = None
|
||||
count = 0
|
||||
reloadNum += 1
|
||||
if reloadNum > 1440:
|
||||
reloadNum = 0
|
||||
mw.writeFile('logs/sys_interrupt.pl',
|
||||
"reload num:" + str(reloadNum))
|
||||
restartMw()
|
||||
except Exception as ex:
|
||||
print(str(ex))
|
||||
mw.writeFile('logs/sys_interrupt.pl', str(ex))
|
||||
|
||||
del(tmp)
|
||||
time.sleep(5)
|
||||
count += 1
|
||||
except Exception as ex:
|
||||
print(str(ex))
|
||||
mw.writeFile('logs/sys_interrupt.pl', str(ex))
|
||||
|
||||
restartMw()
|
||||
|
||||
time.sleep(30)
|
||||
systemTask()
|
||||
|
||||
|
||||
# -------------------------------------- PHP监控 start --------------------------------------------- #
|
||||
# 502错误检查线程
|
||||
def check502Task():
|
||||
try:
|
||||
while True:
|
||||
if os.path.exists(mw.getPanelDir() + '/data/502Task.pl'):
|
||||
check502()
|
||||
time.sleep(30)
|
||||
except:
|
||||
time.sleep(30)
|
||||
check502Task()
|
||||
|
||||
|
||||
def check502():
|
||||
try:
|
||||
verlist = [
|
||||
'52', '53', '54', '55', '56', '70',
|
||||
'71', '72', '73', '74', '80', '81',
|
||||
'82', '83', '84'
|
||||
]
|
||||
for ver in verlist:
|
||||
sdir = mw.getServerDir()
|
||||
php_path = sdir + '/php/' + ver + '/sbin/php-fpm'
|
||||
if not os.path.exists(php_path):
|
||||
continue
|
||||
if checkPHPVersion(ver):
|
||||
continue
|
||||
if startPHPVersion(ver):
|
||||
print('检测到PHP-' + ver + '处理异常,已自动修复!')
|
||||
mw.writeLog('PHP守护程序', '检测到PHP-' + ver + '处理异常,已自动修复!')
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
|
||||
|
||||
# 处理指定PHP版本
|
||||
def startPHPVersion(version):
|
||||
sdir = mw.getServerDir()
|
||||
try:
|
||||
# system
|
||||
phpService = mw.systemdCfgDir() + '/php' + version + '.service'
|
||||
if os.path.exists(phpService):
|
||||
mw.execShell("systemctl restart php" + version)
|
||||
if checkPHPVersion(version):
|
||||
return True
|
||||
|
||||
# initd
|
||||
fpm = sdir + '/php/init.d/php' + version
|
||||
php_path = sdir + '/php/' + version + '/sbin/php-fpm'
|
||||
if not os.path.exists(php_path):
|
||||
if os.path.exists(fpm):
|
||||
os.remove(fpm)
|
||||
return False
|
||||
|
||||
if not os.path.exists(fpm):
|
||||
return False
|
||||
|
||||
# 尝试重载服务
|
||||
os.system(fpm + ' reload')
|
||||
if checkPHPVersion(version):
|
||||
return True
|
||||
|
||||
# 尝试重启服务
|
||||
cgi = '/tmp/php-cgi-' + version + '.sock'
|
||||
pid = sdir + '/php/' + version + '/var/run/php-fpm.pid'
|
||||
data = mw.execShell("ps -ef | grep php/" + version +" | grep -v grep|grep -v python |awk '{print $2}'")
|
||||
if data[0] != '':
|
||||
os.system("ps -ef | grep php/" + version + " | grep -v grep|grep -v python |awk '{print $2}' | xargs kill ")
|
||||
time.sleep(0.5)
|
||||
if not os.path.exists(cgi):
|
||||
os.system('rm -f ' + cgi)
|
||||
if not os.path.exists(pid):
|
||||
os.system('rm -f ' + pid)
|
||||
os.system(fpm + ' start')
|
||||
if checkPHPVersion(version):
|
||||
return True
|
||||
|
||||
# 检查是否正确启动
|
||||
if os.path.exists(cgi):
|
||||
return True
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
return True
|
||||
|
||||
|
||||
def getFpmConfFile(version):
|
||||
return mw.getServerDir() + '/php/' + version + '/etc/php-fpm.d/www.conf'
|
||||
|
||||
|
||||
def getFpmAddress(version):
|
||||
fpm_address = '/tmp/php-cgi-{}.sock'.format(version)
|
||||
php_fpm_file = getFpmConfFile(version)
|
||||
try:
|
||||
content = readFile(php_fpm_file)
|
||||
tmp = re.findall(r"listen\s*=\s*(.+)", content)
|
||||
if not tmp:
|
||||
return fpm_address
|
||||
if tmp[0].find('sock') != -1:
|
||||
return fpm_address
|
||||
if tmp[0].find(':') != -1:
|
||||
listen_tmp = tmp[0].split(':')
|
||||
if bind:
|
||||
fpm_address = (listen_tmp[0], int(listen_tmp[1]))
|
||||
else:
|
||||
fpm_address = ('127.0.0.1', int(listen_tmp[1]))
|
||||
else:
|
||||
fpm_address = ('127.0.0.1', int(tmp[0]))
|
||||
return fpm_address
|
||||
except:
|
||||
return fpm_address
|
||||
|
||||
|
||||
def checkPHPVersion(version):
|
||||
# 检查指定PHP版本
|
||||
try:
|
||||
sock = getFpmAddress(version)
|
||||
data = mw.requestFcgiPHP(sock, '/phpfpm_status_' + version + '?json')
|
||||
result = str(data, encoding='utf-8')
|
||||
except Exception as e:
|
||||
result = 'Bad Gateway'
|
||||
|
||||
# print(version,result)
|
||||
# 检查openresty
|
||||
if result.find('Bad Gateway') != -1:
|
||||
return False
|
||||
if result.find('HTTP Error 404: Not Found') != -1:
|
||||
return False
|
||||
|
||||
# 检查Web服务是否启动
|
||||
if result.find('Connection refused') != -1:
|
||||
return False
|
||||
# global isTask
|
||||
# if os.path.exists(isTask):
|
||||
# isStatus = mw.readFile(isTask)
|
||||
# if isStatus == 'True':
|
||||
# return True
|
||||
|
||||
# # systemd
|
||||
# systemd = mw.systemdCfgDir() + '/openresty.service'
|
||||
# if os.path.exists(systemd):
|
||||
# execShell('systemctl reload openresty')
|
||||
# return True
|
||||
# # initd
|
||||
# initd = '/etc/init.d/openresty'
|
||||
# if os.path.exists(initd):
|
||||
# os.system(initd + ' reload')
|
||||
return True
|
||||
|
||||
# --------------------------------------PHP监控 end--------------------------------------------- #
|
||||
|
||||
|
||||
# --------------------------------------OpenResty Auto Restart Start --------------------------------------------- #
|
||||
# 解决acme.sh续签后,未起效。
|
||||
def openrestyAutoRestart():
|
||||
try:
|
||||
while True:
|
||||
# 检查是否安装
|
||||
odir = mw.getServerDir() + '/openresty'
|
||||
if not os.path.exists(odir):
|
||||
time.sleep(86400)
|
||||
continue
|
||||
|
||||
openresty_cmd('reload')
|
||||
time.sleep(86400)
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
time.sleep(86400)
|
||||
|
||||
# --------------------------------------OpenResty Auto Restart End --------------------------------------------- #
|
||||
|
||||
# ------------------------------------ OpenResty Restart At Once Start ------------------------------------------ #
|
||||
|
||||
|
||||
def openrestyRestartAtOnce():
|
||||
restart_nginx_tip = 'data/restart_nginx.pl'
|
||||
while True:
|
||||
if os.path.exists(restart_nginx_tip):
|
||||
os.remove(restart_nginx_tip)
|
||||
openresty_cmd('reload')
|
||||
time.sleep(1)
|
||||
# ----------------------------------- OpenResty Restart At Once End ------------------------------------------ #
|
||||
|
||||
|
||||
# --------------------------------------Panel Restart Start --------------------------------------------- #
|
||||
def restartPanelService():
|
||||
restartTip = 'data/restart.pl'
|
||||
while True:
|
||||
if os.path.exists(restartTip):
|
||||
os.remove(restartTip)
|
||||
service_cmd('restart_panel')
|
||||
time.sleep(1)
|
||||
# --------------------------------------Panel Restart End --------------------------------------------- #
|
||||
|
||||
|
||||
def setDaemon(t):
|
||||
if sys.version_info.major == 3 and sys.version_info.minor >= 10:
|
||||
t.daemon = True
|
||||
else:
|
||||
t.setDaemon(True)
|
||||
return t
|
||||
|
||||
def run():
|
||||
# # 系统监控
|
||||
# sysTask = threading.Thread(target=systemTask)
|
||||
# sysTask = setDaemon(sysTask)
|
||||
# sysTask.start()
|
||||
|
||||
# # PHP 502错误检查线程
|
||||
# php502 = threading.Thread(target=check502Task)
|
||||
# php502 = setDaemon(php502)
|
||||
# php502.start()
|
||||
|
||||
# # OpenResty Restart At Once Start
|
||||
# oraos = threading.Thread(target=openrestyRestartAtOnce)
|
||||
# oraos = setDaemon(oraos)
|
||||
# oraos.start()
|
||||
|
||||
|
||||
# # OpenResty Auto Restart Start
|
||||
# oar = threading.Thread(target=openrestyAutoRestart)
|
||||
# oar = setDaemon(oar)
|
||||
# oar.start()
|
||||
|
||||
|
||||
# # Panel Restart Start
|
||||
# rps = threading.Thread(target=restartPanelService)
|
||||
# rps = setDaemon(rps)
|
||||
# rps.start()
|
||||
|
||||
# 面板后台任务
|
||||
startPanelTask()
|
||||
|
||||
if __name__ == "__main__":
|
||||
with app.app_context():
|
||||
run()
|
||||
|
||||
Executable
+306
@@ -0,0 +1,306 @@
|
||||
# coding=utf-8
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# MW-Linux面板
|
||||
# ---------------------------------------------------------------------------------
|
||||
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
|
||||
# ---------------------------------------------------------------------------------
|
||||
# Author: midoks <midoks@163.com>
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# 工具箱
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
import time
|
||||
import re
|
||||
|
||||
web_dir = os.getcwd() + "/web"
|
||||
os.chdir(web_dir)
|
||||
sys.path.append(web_dir)
|
||||
|
||||
import core.mw as mw
|
||||
import core.db as db
|
||||
|
||||
# cmd = 'ls /usr/local/lib/ | grep python | cut -d \\ -f 1 | awk \'END {print}\''
|
||||
# info = mw.execShell(cmd)
|
||||
# p = "/usr/local/lib/" + info[0].strip() + "/site-packages"
|
||||
# sys.path.append(p)
|
||||
|
||||
INIT_DIR = "/etc/rc.d/init.d"
|
||||
if mw.isAppleSystem():
|
||||
INIT_DIR = mw.getPanelDir() + "/scripts/init.d"
|
||||
|
||||
INIT_CMD = INIT_DIR + "/mw"
|
||||
|
||||
|
||||
def mw_input_cmd(msg):
|
||||
if sys.version_info[0] == 2:
|
||||
in_val = raw_input(msg)
|
||||
else:
|
||||
in_val = input(msg)
|
||||
return in_val
|
||||
|
||||
|
||||
def mwcli(mw_input=0):
|
||||
raw_tip = "======================================================"
|
||||
if not mw_input:
|
||||
print("===============mdserver-web cli tools=================")
|
||||
print("(1) 重启面板服务")
|
||||
print("(2) 停止面板服务")
|
||||
print("(3) 启动面板服务")
|
||||
print("(4) 重载面板服务")
|
||||
print("(5) 修改面板端口")
|
||||
print("(10) 查看面板默认信息")
|
||||
print("(11) 修改面板密码")
|
||||
print("(12) 修改面板用户名")
|
||||
print("(13) 显示面板错误日志")
|
||||
print("(20) 关闭BasicAuth认证")
|
||||
print("(21) 解除域名绑定")
|
||||
print("(22) 解除面板SSL绑定")
|
||||
print("(23) 开启IPV6支持")
|
||||
print("(24) 关闭IPV6支持")
|
||||
print("(25) 开启防火墙SSH端口")
|
||||
print("(26) 关闭二次验证")
|
||||
print("(27) 查看防火墙信息")
|
||||
print("(100) 开启PHP52显示")
|
||||
print("(101) 关闭PHP52显示")
|
||||
print("(200) 切换Linux系统软件源")
|
||||
print("(201) 简单速度测试")
|
||||
print("(0) 取消")
|
||||
print(raw_tip)
|
||||
try:
|
||||
mw_input = input("请输入命令编号:")
|
||||
if sys.version_info[0] == 3:
|
||||
mw_input = int(mw_input)
|
||||
except:
|
||||
mw_input = 0
|
||||
|
||||
nums = [
|
||||
1, 2, 3, 4, 5, 10, 11, 12, 13,
|
||||
20, 21, 22, 23, 24, 25, 26, 27,
|
||||
100, 101,
|
||||
200, 201
|
||||
]
|
||||
if not mw_input in nums:
|
||||
print(raw_tip)
|
||||
print("已取消!")
|
||||
exit()
|
||||
|
||||
if mw_input == 1:
|
||||
os.system(INIT_CMD + " restart")
|
||||
elif mw_input == 2:
|
||||
os.system(INIT_CMD + " stop")
|
||||
elif mw_input == 3:
|
||||
os.system(INIT_CMD + " start")
|
||||
elif mw_input == 4:
|
||||
os.system(INIT_CMD + " reload")
|
||||
elif mw_input == 5:
|
||||
in_port = mw_input_cmd("请输入新的面板端口:")
|
||||
in_port_int = int(in_port.strip())
|
||||
if in_port_int < 65536 and in_port_int > 0:
|
||||
import firewall_api
|
||||
firewall_api.firewall_api().addAcceptPortArgs(
|
||||
in_port, 'WEB面板[TOOLS修改]', 'port')
|
||||
mw.writeFile('data/port.pl', in_port)
|
||||
os.system(INIT_CMD + " restart_panel")
|
||||
os.system(INIT_CMD + " default")
|
||||
else:
|
||||
print("|-端口范围在0-65536之间")
|
||||
return
|
||||
elif mw_input == 10:
|
||||
os.system(INIT_CMD + " default")
|
||||
elif mw_input == 11:
|
||||
input_pwd = mw_input_cmd("请输入新的面板密码:")
|
||||
if len(input_pwd.strip()) < 5:
|
||||
print("|-错误,密码长度不能小于5位")
|
||||
return
|
||||
set_panel_pwd(input_pwd.strip(), True)
|
||||
elif mw_input == 12:
|
||||
input_user = mw_input_cmd("请输入新的面板用户名(>=5位):")
|
||||
set_panel_username(input_user.strip())
|
||||
elif mw_input == 13:
|
||||
os.system('tail -100 ' + mw.getPanelDir() + '/logs/error.log')
|
||||
elif mw_input == 20:
|
||||
basic_auth = 'data/basic_auth.json'
|
||||
if os.path.exists(basic_auth):
|
||||
os.remove(basic_auth)
|
||||
os.system(INIT_CMD + " restart")
|
||||
print("|-关闭basic_auth成功")
|
||||
elif mw_input == 21:
|
||||
bind_domain = 'data/bind_domain.pl'
|
||||
if os.path.exists(bind_domain):
|
||||
os.remove(bind_domain)
|
||||
os.system(INIT_CMD + " unbind_domain")
|
||||
print("|-解除域名绑定成功")
|
||||
elif mw_input == 22:
|
||||
ssl_choose = 'ssl/choose.pl'
|
||||
if os.path.exists(ssl_choose):
|
||||
os.remove(ssl_choose)
|
||||
os.system(INIT_CMD + " unbind_ssl")
|
||||
print("|-解除面板SSL绑定成功")
|
||||
elif mw_input == 23:
|
||||
listen_ipv6 = 'data/ipv6.pl'
|
||||
if not os.path.exists(listen_ipv6):
|
||||
mw.writeFile(listen_ipv6,'True')
|
||||
os.system(INIT_CMD + " restart")
|
||||
print("|-开启IPv6支持了")
|
||||
else:
|
||||
print("|-已开启IPv6支持!")
|
||||
elif mw_input == 24:
|
||||
listen_ipv6 = 'data/ipv6.pl'
|
||||
if not os.path.exists(listen_ipv6):
|
||||
print("|-已关闭IPv6支持!")
|
||||
else:
|
||||
os.remove(listen_ipv6)
|
||||
os.system(INIT_CMD + " restart")
|
||||
print("|-关闭IPv6支持了")
|
||||
elif mw_input == 25:
|
||||
open_ssh_port()
|
||||
print("|-已开启!")
|
||||
elif mw_input == 26:
|
||||
auth_secret = 'data/auth_secret.pl'
|
||||
if os.path.exists(auth_secret):
|
||||
os.remove(auth_secret)
|
||||
print("|-关闭二次验证成功!")
|
||||
else:
|
||||
print("|-二次验证已关闭!")
|
||||
elif mw_input == 27:
|
||||
cmd = 'which ufw'
|
||||
run_cmd = False
|
||||
find_cmd = mw.execShell(cmd)
|
||||
if find_cmd[0].strip() != '':
|
||||
run_cmd = True
|
||||
os.system('ufw status')
|
||||
|
||||
cmd = 'which firewall-cmd'
|
||||
find_cmd = mw.execShell(cmd)
|
||||
if find_cmd[0].strip() != '':
|
||||
run_cmd = True
|
||||
os.system('firewall-cmd --list-all')
|
||||
if not run_cmd:
|
||||
mw.echoInfo("未检测到防火墙!")
|
||||
elif mw_input == 100:
|
||||
php_conf = 'plugins/php/info.json'
|
||||
if os.path.exists(php_conf):
|
||||
cont = mw.readFile(php_conf)
|
||||
cont = re.sub("\"53\"", "\"52\",\"53\"", cont)
|
||||
cont = re.sub("\"5.3.29\"", "\"5.2.17\",\"5.3.29\"", cont)
|
||||
mw.writeFile(php_conf, cont)
|
||||
print("|-执行PHP52显示成功!")
|
||||
elif mw_input == 101:
|
||||
php_conf = 'plugins/php/info.json'
|
||||
if os.path.exists(php_conf):
|
||||
cont = mw.readFile(php_conf)
|
||||
cont = re.sub("\"52\",", "", cont)
|
||||
cont = re.sub("\"5.2.17\",", cont)
|
||||
mw.writeFile(php_conf, cont)
|
||||
print("|-执行PHP52隐藏成功!")
|
||||
elif mw_input == 200:
|
||||
os.system(INIT_CMD + " mirror")
|
||||
elif mw_input == 201:
|
||||
os.system('curl -Lso- bench.sh | bash')
|
||||
|
||||
|
||||
def open_ssh_port():
|
||||
import firewall_api
|
||||
find_ssh_port_cmd = "cat /etc/ssh/sshd_config | grep '^Port \\d*' | tail -1"
|
||||
cmd_data = mw.execShell(find_ssh_port_cmd)
|
||||
ssh_port = cmd_data[0].replace("Port ", '').strip()
|
||||
if ssh_port == '':
|
||||
ssh_port = '22'
|
||||
|
||||
print("|-SSH端口: "+ str(ssh_port))
|
||||
firewall_api.firewall_api().addAcceptPortArgs(ssh_port, 'SSH远程管理服务', 'port')
|
||||
return True
|
||||
|
||||
|
||||
def set_panel_pwd(password, ncli=False):
|
||||
# 设置面板密码
|
||||
import db
|
||||
sql = db.Sql()
|
||||
result = sql.table('users').where('id=?', (1,)).setField(
|
||||
'password', mw.md5(password))
|
||||
username = sql.table('users').where('id=?', (1,)).getField('username')
|
||||
if ncli:
|
||||
print("|-用户名: " + username)
|
||||
print("|-新密码: " + password)
|
||||
else:
|
||||
print(username)
|
||||
|
||||
|
||||
def show_panel_pwd():
|
||||
# 设置面板密码
|
||||
import db
|
||||
sql = db.Sql()
|
||||
password = sql.table('users').where('id=?', (1,)).getField('password')
|
||||
|
||||
file_pwd = ''
|
||||
if os.path.exists('data/default.pl'):
|
||||
file_pwd = mw.readFile('data/default.pl').strip()
|
||||
|
||||
if mw.md5(file_pwd) == password:
|
||||
print('password: ' + file_pwd)
|
||||
return
|
||||
print("password has been changed!")
|
||||
|
||||
|
||||
def set_panel_username(username=None):
|
||||
# 随机面板用户名
|
||||
import db
|
||||
sql = db.Sql()
|
||||
if username:
|
||||
if len(username) < 5:
|
||||
print("|-错误,用户名长度不能少于5位")
|
||||
return
|
||||
if username in ['admin', 'root']:
|
||||
print("|-错误,不能使用过于简单的用户名")
|
||||
return
|
||||
|
||||
sql.table('users').where('id=?', (1,)).setField('username', username)
|
||||
print("|-新用户名: %s" % username)
|
||||
return
|
||||
|
||||
username = sql.table('users').where('id=?', (1,)).getField('username')
|
||||
if username == 'admin':
|
||||
username = mw.getRandomString(8).lower()
|
||||
sql.table('users').where('id=?', (1,)).setField('username', username)
|
||||
print('username: ' + username)
|
||||
|
||||
|
||||
def getServerIp():
|
||||
version = sys.argv[2]
|
||||
# ip = mw.execShell(
|
||||
# "curl --insecure -{} -sS --connect-timeout 5 -m 60 https://v6r.ipip.net/?format=text".format(version))
|
||||
ip = mw.execShell(
|
||||
"curl --insecure -{} -sS --connect-timeout 5 -m 60 https://ip.cachecha.com/?format=text".format(version))
|
||||
print(ip[0])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
method = sys.argv[1]
|
||||
if method == 'panel':
|
||||
set_panel_pwd(sys.argv[2])
|
||||
elif method == 'username':
|
||||
if len(sys.argv) > 2:
|
||||
set_panel_username(sys.argv[2])
|
||||
else:
|
||||
set_panel_username()
|
||||
elif method == 'password':
|
||||
show_panel_pwd()
|
||||
elif method == 'getServerIp':
|
||||
getServerIp()
|
||||
elif method == "cli":
|
||||
clinum = 0
|
||||
try:
|
||||
if len(sys.argv) > 2:
|
||||
clinum = int(sys.argv[2]) if sys.argv[2][:6] else sys.argv[2]
|
||||
except:
|
||||
clinum = sys.argv[2]
|
||||
mwcli(clinum)
|
||||
else:
|
||||
print('ERROR: Parameter error')
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
Executable
+31
@@ -0,0 +1,31 @@
|
||||
<style>
|
||||
.overflow_hide {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="bt-form">
|
||||
<div class='plugin_version'></div>
|
||||
<div class="bt-w-main">
|
||||
<div class="bt-w-menu">
|
||||
<p class="bgw" onclick="pluginService('alist');">服务</p>
|
||||
<p onclick="pluginInitD('alist');">自启动</p>
|
||||
<p onclick="alistCommonFunc();">常用功能</p>
|
||||
<p onclick="pluginConfigTpl('alist',$('.plugin_version').attr('version'));">配置修改</p>
|
||||
<p onclick="pluginLogs('alist','','run_log');">运行日志</p>
|
||||
<p onclick="alistReadme();">相关说明</p>
|
||||
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="soft-man-con" style="height: 520px; overflow: auto;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$.getScript( "/plugins/file?name=alist&f=js/alist.js", function(){
|
||||
pluginService('alist', $('.plugin_version').attr('version'));
|
||||
});
|
||||
</script>
|
||||
Executable
+292
@@ -0,0 +1,292 @@
|
||||
# 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 getPluginName():
|
||||
return 'alist'
|
||||
|
||||
|
||||
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 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 getConf():
|
||||
path = getServerDir() + "/data/config.json"
|
||||
return path
|
||||
|
||||
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 status():
|
||||
data = mw.execShell(
|
||||
"ps aux|grep alist |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 + '/'+getPluginName())
|
||||
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()
|
||||
|
||||
# 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()
|
||||
se_content = mw.readFile(systemServiceTpl)
|
||||
se_content = se_content.replace('{$SERVER_PATH}', service_path)
|
||||
mw.writeFile(systemService, se_content)
|
||||
mw.execShell('systemctl daemon-reload')
|
||||
|
||||
return file_bin
|
||||
|
||||
|
||||
def alistOp(method):
|
||||
file = initDreplace()
|
||||
|
||||
current_os = mw.getOs()
|
||||
if current_os == "darwin":
|
||||
data = mw.execShell(file + ' ' + method)
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
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 alistOp('start')
|
||||
|
||||
|
||||
def stop():
|
||||
return alistOp('stop')
|
||||
|
||||
|
||||
def restart():
|
||||
status = alistOp('restart')
|
||||
return status
|
||||
|
||||
|
||||
def reload():
|
||||
return alistOp('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/log.log'
|
||||
|
||||
def pSqliteDb(dbname='databases'):
|
||||
pos_file = getServerDir() + '/data/'
|
||||
file = pos_file + '/data.db'
|
||||
name = 'data'
|
||||
conn = mw.M(dbname).dbPos(pos_file, name)
|
||||
return conn
|
||||
|
||||
def clearCopyTask():
|
||||
conn = pSqliteDb('x_task_items')
|
||||
conn.where('key=?', ('copy',)).setField('persist_data','[]')
|
||||
restart()
|
||||
return mw.returnJson(True, '清空成功并重启服务!')
|
||||
|
||||
def homePage():
|
||||
import json
|
||||
content = mw.readFile(getConf())
|
||||
data = json.loads(content)
|
||||
http_port = data['scheme']['http_port']
|
||||
ip = mw.getLocalIp()
|
||||
if mw.isAppleSystem():
|
||||
ip = '127.0.0.1'
|
||||
url = 'http://'+ip+":"+str(http_port)
|
||||
# print(url)
|
||||
return mw.returnJson(True, 'ok!', url)
|
||||
|
||||
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 == 'config_tpl':
|
||||
print(configTpl())
|
||||
elif func == 'read_config_tpl':
|
||||
print(readConfigTpl())
|
||||
elif func == 'clear_copy_task':
|
||||
print(clearCopyTask())
|
||||
elif func == 'home_page':
|
||||
print(homePage())
|
||||
else:
|
||||
print('error')
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"sort": 7,
|
||||
"ps": "一个支持多种存储的文件列表程序",
|
||||
"name": "alist",
|
||||
"title": "Alist",
|
||||
"shell": "install.sh",
|
||||
"versions":["3.37.4","3.38.0"],
|
||||
"tip": "soft",
|
||||
"checks": "server/alist",
|
||||
"path": "server/alist",
|
||||
"display": 1,
|
||||
"author": "alist",
|
||||
"date": "2022-10-09",
|
||||
"home": "https://alist.nn.ci",
|
||||
"type": 0,
|
||||
"pid": "5"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=A file list program that supports multiple storage
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory={$SERVER_PATH}/alist
|
||||
ExecStart={$SERVER_PATH}/alist/alist server
|
||||
ExecReload=/bin/kill -USR2 $MAINPID
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,46 @@
|
||||
#!/bin/sh
|
||||
# chkconfig: 2345 55 25
|
||||
# description: alist Service
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: alist
|
||||
# Required-Start: $all
|
||||
# Required-Stop: $all
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: starts alist
|
||||
# Description: starts the MDW-Web
|
||||
### END INIT INFO
|
||||
|
||||
# Simple alist init.d script conceived to work on Linux systems
|
||||
# as it does use of the /proc filesystem.
|
||||
|
||||
app_start(){
|
||||
echo "Starting alist server..."
|
||||
cd {$SERVER_PATH}/alist
|
||||
./alist server >> {$SERVER_PATH}/alist/logs.pl 2>&1 &
|
||||
}
|
||||
|
||||
app_stop(){
|
||||
echo "dztasks stopped"
|
||||
ps -ef| grep alist | 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
|
||||
|
||||
Executable
+94
@@ -0,0 +1,94 @@
|
||||
#!/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")
|
||||
|
||||
# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/alist && bash install.sh install 3.37.4
|
||||
# cd /www/server/mdserver-web/plugins/alist && bash install.sh install 3.37.4
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=$2
|
||||
|
||||
sysArch=`arch`
|
||||
sysName=`uname`
|
||||
|
||||
ALIST_ARCH_NAME=amd64
|
||||
if [ "$sysArch" == "arm64" ];then
|
||||
ALIST_ARCH_NAME=arm64
|
||||
elif [ "$sysArch" == "x86_64" ]; then
|
||||
ALIST_ARCH_NAME=amd64
|
||||
elif [ "$sysArch" == "aarch64" ]; then
|
||||
ALIST_ARCH_NAME=arm64
|
||||
fi
|
||||
|
||||
ALIST_NAME=linux
|
||||
if [ "$sysName" == "Darwin" ];then
|
||||
ALIST_NAME=darwin
|
||||
fi
|
||||
|
||||
Install_App()
|
||||
{
|
||||
echo '正在安装脚本文件...'
|
||||
|
||||
mkdir -p $serverPath/source
|
||||
mkdir -p $serverPath/source/alist
|
||||
|
||||
FILE_TGZ=alist-${ALIST_NAME}-${ALIST_ARCH_NAME}.tar.gz
|
||||
|
||||
ALIST_DIR=$serverPath/source/alist
|
||||
|
||||
if [ ! -f $ALIST_DIR/${FILE_TGZ} ];then
|
||||
wget -O $ALIST_DIR/${FILE_TGZ} https://github.com/alist-org/alist/releases/download/v${VERSION}/${FILE_TGZ}
|
||||
fi
|
||||
|
||||
mkdir -p $serverPath/alist
|
||||
|
||||
cd $ALIST_DIR && tar -zxvf ${FILE_TGZ} -C $serverPath/alist
|
||||
echo "${VERSION}" > $serverPath/alist/version.pl
|
||||
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/alist/index.py start
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/alist/index.py initd_install
|
||||
|
||||
cd $serverPath/alist && ./alist admin set admin
|
||||
# cd /www/server/alist && ./alist admin set admin
|
||||
|
||||
echo '安装完成'
|
||||
}
|
||||
|
||||
Uninstall_App()
|
||||
{
|
||||
if [ -f /usr/lib/systemd/system/alist.service ];then
|
||||
systemctl stop alist
|
||||
systemctl disable alist
|
||||
rm -rf /usr/lib/systemd/system/alist.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
if [ -f /lib/systemd/system/alist.service ];then
|
||||
systemctl stop alist
|
||||
systemctl disable alist
|
||||
rm -rf /lib/systemd/system/alist.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
if [ -f $serverPath/alist/initd/alist ];then
|
||||
$serverPath/alist/initd/alist stop
|
||||
fi
|
||||
|
||||
if [ -d $serverPath/alist ];then
|
||||
rm -rf $serverPath/alist
|
||||
fi
|
||||
|
||||
echo "卸载alist成功"
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_App
|
||||
else
|
||||
Uninstall_App
|
||||
fi
|
||||
Executable
+92
@@ -0,0 +1,92 @@
|
||||
function alistPost(method, version, args,callback){
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
|
||||
var req_data = {};
|
||||
req_data['name'] = 'alist';
|
||||
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 alistPostCallbak(method, version, args,callback){
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
|
||||
var req_data = {};
|
||||
req_data['name'] = 'alist';
|
||||
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 clearTaskCopy(){
|
||||
layer.confirm('您真的要清空复制任务吗?', { icon: 3, closeBtn: 2 }, function() {
|
||||
alistPost('clear_copy_task', '', {}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg, function(){},{ icon: rdata.status ? 1 : 2 });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function commonHomePage(){
|
||||
alistPost('home_page', '', {}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
window.open(rdata.data);
|
||||
});
|
||||
}
|
||||
|
||||
function alistCommonFunc(){
|
||||
var con = '';
|
||||
con += '<hr/><p class="conf_p" style="text-align:center;">\
|
||||
<button class="btn btn-default btn-sm" onclick="commonHomePage()">主页</button>\
|
||||
<button class="btn btn-default btn-sm" onclick="clearTaskCopy()">清空复制任务</button>\
|
||||
</p>';
|
||||
|
||||
$(".soft-man-con").html(con);
|
||||
}
|
||||
|
||||
function alistReadme(){
|
||||
|
||||
|
||||
var readme = '<ul class="help-info-text c7">';
|
||||
readme += '<li>默认admin:admin</li>';
|
||||
readme += '<li>手动改密码: cd /www/server/alist && ./alist admin set NEW_PASSWORD</li>';
|
||||
readme += '</ul>';
|
||||
|
||||
$('.soft-man-con').html(readme);
|
||||
}
|
||||
|
||||
@@ -113,6 +113,9 @@ def initConf():
|
||||
|
||||
"/tmp/yum_save_*",
|
||||
"/tmp/tmp.*",
|
||||
|
||||
"/www/server/dztasks/logs/dztasks.*.log",
|
||||
"/www/server/dztasks/logs/dztasks_*",
|
||||
]
|
||||
for i in clog:
|
||||
content += i + "\n"
|
||||
@@ -147,6 +150,8 @@ def initConf():
|
||||
"/www/server/openresty/nginx/logs",
|
||||
"/www/server/phpmyadmin",
|
||||
"/www/server/redis/data",
|
||||
"/www/server/alist/data/log",
|
||||
"/www/server/dztasks/logs",
|
||||
"/www/server/cron",
|
||||
]
|
||||
for i in clogcom:
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
Executable
+31
@@ -0,0 +1,31 @@
|
||||
<style>
|
||||
.overflow_hide {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="bt-form">
|
||||
<div class='plugin_version'></div>
|
||||
<div class="bt-w-main">
|
||||
<div class="bt-w-menu">
|
||||
<p class="bgw" onclick="pluginService('cloudreve');">服务</p>
|
||||
<p onclick="pluginInitD('cloudreve');">自启动</p>
|
||||
<p onclick="alistCommonFunc();">常用功能</p>
|
||||
<p onclick="pluginConfigTpl('cloudreve',$('.plugin_version').attr('version'));">配置修改</p>
|
||||
<p onclick="pluginLogs('cloudreve','','run_log');">运行日志</p>
|
||||
<p onclick="alistReadme();">相关说明</p>
|
||||
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="soft-man-con" style="height: 520px; overflow: auto;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$.getScript( "/plugins/file?name=cloudreve&f=js/cloudreve.js", function(){
|
||||
pluginService('cloudreve', $('.plugin_version').attr('version'));
|
||||
});
|
||||
</script>
|
||||
Executable
+288
@@ -0,0 +1,288 @@
|
||||
# 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 getPluginName():
|
||||
return 'cloudreve'
|
||||
|
||||
|
||||
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 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 getConf():
|
||||
path = getServerDir() + "/conf.ini"
|
||||
return path
|
||||
|
||||
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 status():
|
||||
data = mw.execShell(
|
||||
"ps aux|grep cloudreve |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 + '/'+getPluginName())
|
||||
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()
|
||||
|
||||
# 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()
|
||||
se_content = mw.readFile(systemServiceTpl)
|
||||
se_content = se_content.replace('{$SERVER_PATH}', service_path)
|
||||
mw.writeFile(systemService, se_content)
|
||||
mw.execShell('systemctl daemon-reload')
|
||||
|
||||
return file_bin
|
||||
|
||||
|
||||
def alistOp(method):
|
||||
file = initDreplace()
|
||||
|
||||
current_os = mw.getOs()
|
||||
if current_os == "darwin":
|
||||
data = mw.execShell(file + ' ' + method)
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
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 alistOp('start')
|
||||
|
||||
|
||||
def stop():
|
||||
return alistOp('stop')
|
||||
|
||||
|
||||
def restart():
|
||||
status = alistOp('restart')
|
||||
return status
|
||||
|
||||
|
||||
def reload():
|
||||
return alistOp('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() + '/logs.pl'
|
||||
|
||||
def pSqliteDb(dbname='databases'):
|
||||
pos_file = getServerDir() + '/data/'
|
||||
file = pos_file + '/data.db'
|
||||
name = 'data'
|
||||
conn = mw.M(dbname).dbPos(pos_file, name)
|
||||
return conn
|
||||
|
||||
def getCloudrevePort():
|
||||
file = getConf()
|
||||
content = mw.readFile(file)
|
||||
rep = r'Listen\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
def homePage():
|
||||
http_port = getCloudrevePort()
|
||||
ip = mw.getLocalIp()
|
||||
if mw.isAppleSystem():
|
||||
ip = '127.0.0.1'
|
||||
url = 'http://'+ip+""+str(http_port)
|
||||
# print(url)
|
||||
return mw.returnJson(True, 'ok!', url)
|
||||
|
||||
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 == 'config_tpl':
|
||||
print(configTpl())
|
||||
elif func == 'read_config_tpl':
|
||||
print(readConfigTpl())
|
||||
elif func == 'home_page':
|
||||
print(homePage())
|
||||
else:
|
||||
print('error')
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"sort": 7,
|
||||
"ps": "一个支持多种存储的文件列表程序",
|
||||
"name": "cloudreve",
|
||||
"title": "cloudreve",
|
||||
"shell": "install.sh",
|
||||
"versions":["3.8.3"],
|
||||
"tip": "soft",
|
||||
"checks": "server/cloudreve",
|
||||
"path": "server/cloudreve",
|
||||
"display": 1,
|
||||
"author": "cloudreve",
|
||||
"date": "2024-10-14",
|
||||
"home": "https://cloudreve.org/",
|
||||
"type": 0,
|
||||
"pid": "5"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=A file list program that supports multiple storage
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory={$SERVER_PATH}/cloudreve
|
||||
ExecStart={$SERVER_PATH}/cloudreve/cloudreve
|
||||
ExecReload=/bin/kill -USR2 $MAINPID
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,46 @@
|
||||
#!/bin/sh
|
||||
# chkconfig: 2345 55 25
|
||||
# description: cloudreve Service
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: cloudreve
|
||||
# Required-Start: $all
|
||||
# Required-Stop: $all
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: starts cloudreve
|
||||
# Description: starts the MDW-Web
|
||||
### END INIT INFO
|
||||
|
||||
# Simple cloudreve init.d script conceived to work on Linux systems
|
||||
# as it does use of the /proc filesystem.
|
||||
|
||||
app_start(){
|
||||
echo "Starting cloudreve server..."
|
||||
cd {$SERVER_PATH}/cloudreve
|
||||
./cloudreve >> {$SERVER_PATH}/cloudreve/logs.pl 2>&1 &
|
||||
}
|
||||
|
||||
app_stop(){
|
||||
echo "dztasks stopped"
|
||||
ps -ef| grep cloudreve | 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
|
||||
|
||||
Executable
+91
@@ -0,0 +1,91 @@
|
||||
#!/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")
|
||||
|
||||
# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/cloudreve && bash install.sh install 3.8.3
|
||||
# cd /www/server/mdserver-web/plugins/cloudreve && bash install.sh install 3.8.3
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=$2
|
||||
|
||||
sysArch=`arch`
|
||||
sysName=`uname`
|
||||
|
||||
ALIST_ARCH_NAME=amd64
|
||||
if [ "$sysArch" == "arm64" ];then
|
||||
ALIST_ARCH_NAME=arm64
|
||||
elif [ "$sysArch" == "x86_64" ]; then
|
||||
ALIST_ARCH_NAME=amd64
|
||||
elif [ "$sysArch" == "aarch64" ]; then
|
||||
ALIST_ARCH_NAME=aarch64
|
||||
fi
|
||||
|
||||
ALIST_NAME=linux
|
||||
if [ "$sysName" == "Darwin" ];then
|
||||
ALIST_NAME=darwin
|
||||
fi
|
||||
|
||||
Install_App()
|
||||
{
|
||||
echo '正在安装脚本文件...'
|
||||
|
||||
mkdir -p $serverPath/source
|
||||
mkdir -p $serverPath/source/cloudreve
|
||||
|
||||
FILE_TGZ=cloudreve_${VERSION}_${ALIST_NAME}_${ALIST_ARCH_NAME}.tar.gz
|
||||
CLOUDREVE_DIR=$serverPath/source/cloudreve
|
||||
|
||||
if [ ! -f $CLOUDREVE_DIR/${FILE_TGZ} ];then
|
||||
wget -O $CLOUDREVE_DIR/${FILE_TGZ} https://github.com/cloudreve/Cloudreve/releases/download/${VERSION}/${FILE_TGZ}
|
||||
fi
|
||||
|
||||
mkdir -p $serverPath/cloudreve
|
||||
|
||||
cd $CLOUDREVE_DIR && tar -zxvf ${FILE_TGZ} -C $serverPath/cloudreve
|
||||
echo "${VERSION}" > $serverPath/cloudreve/version.pl
|
||||
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/cloudreve/index.py start
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/cloudreve/index.py initd_install
|
||||
|
||||
# cd $serverPath/cloudreve && ./alist admin set admin
|
||||
echo '安装cloudreve完成'
|
||||
}
|
||||
|
||||
Uninstall_App()
|
||||
{
|
||||
if [ -f /usr/lib/systemd/system/cloudreve.service ];then
|
||||
systemctl stop cloudreve
|
||||
systemctl disable cloudreve
|
||||
rm -rf /usr/lib/systemd/system/cloudreve.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
if [ -f /lib/systemd/system/cloudreve.service ];then
|
||||
systemctl stop cloudreve
|
||||
systemctl disable cloudreve
|
||||
rm -rf /lib/systemd/system/cloudreve.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
if [ -f $serverPath/cloudreve/initd/cloudreve ];then
|
||||
$serverPath/cloudreve/initd/cloudreve stop
|
||||
fi
|
||||
|
||||
if [ -d $serverPath/cloudreve ];then
|
||||
rm -rf $serverPath/cloudreve
|
||||
fi
|
||||
|
||||
echo "卸载cloudreve成功"
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_App
|
||||
else
|
||||
Uninstall_App
|
||||
fi
|
||||
Executable
+82
@@ -0,0 +1,82 @@
|
||||
function alistPost(method, version, args,callback){
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
|
||||
var req_data = {};
|
||||
req_data['name'] = 'cloudreve';
|
||||
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 alistPostCallbak(method, version, args,callback){
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
|
||||
var req_data = {};
|
||||
req_data['name'] = 'cloudreve';
|
||||
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 commonHomePage(){
|
||||
alistPost('home_page', '', {}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
window.open(rdata.data);
|
||||
});
|
||||
}
|
||||
|
||||
function alistCommonFunc(){
|
||||
var con = '';
|
||||
con += '<hr/><p class="conf_p" style="text-align:center;">\
|
||||
<button class="btn btn-default btn-sm" onclick="commonHomePage()">主页</button>\
|
||||
</p>';
|
||||
|
||||
$(".soft-man-con").html(con);
|
||||
}
|
||||
|
||||
function alistReadme(){
|
||||
|
||||
|
||||
var readme = '<ul class="help-info-text c7">';
|
||||
readme += '<li>记住安装时生成的用户+密码</li>';
|
||||
readme += '</ul>';
|
||||
|
||||
$('.soft-man-con').html(readme);
|
||||
}
|
||||
|
||||
@@ -11,8 +11,12 @@ import re
|
||||
import json
|
||||
import pymemcache
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
try:
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
except Exception as e:
|
||||
import core.mw as mw
|
||||
|
||||
|
||||
def singleton(cls):
|
||||
_instance = {}
|
||||
|
||||
@@ -12,8 +12,11 @@ import yaml
|
||||
from bson.objectid import ObjectId
|
||||
from bson.json_util import dumps
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
try:
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
except Exception as e:
|
||||
import core.mw as mw
|
||||
|
||||
def singleton(cls):
|
||||
_instance = {}
|
||||
|
||||
@@ -7,8 +7,13 @@ import time
|
||||
import re
|
||||
import redis
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
try:
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
except Exception as e:
|
||||
import core.mw as mw
|
||||
|
||||
|
||||
# def getPluginName():
|
||||
# return 'data_query'
|
||||
|
||||
@@ -8,9 +8,11 @@ import re
|
||||
import pymongo
|
||||
import json
|
||||
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
try:
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
except Exception as e:
|
||||
import core.mw as mw
|
||||
|
||||
def singleton(cls):
|
||||
_instance = {}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<div class="bgw mtb15 pd15 tab-view-box firewall-tab-view safe" style="overflow: hidden;">
|
||||
|
||||
<div class="mask_layer" style="display:none;">
|
||||
<div class="prompt_description">当前未安装本地服务器,<a class="btlink install_server" href="/soft">点击安装</a></div>
|
||||
<div class="prompt_description">当前未安装本地服务器,<a class="btlink install_server" href="/soft/index">点击安装</a></div>
|
||||
</div>
|
||||
|
||||
<!-- mysql start -->
|
||||
|
||||
@@ -10,7 +10,11 @@ import json
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
import docker
|
||||
try:
|
||||
import docker
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
app_debug = False
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<p class="bgw" onclick="pluginService('fail2ban');">服务</p>
|
||||
<p onclick="pluginInitD('fail2ban');">自启动</p>
|
||||
<p onclick="pluginConfigTpl('fail2ban',$('.plugin_version').attr('version'));">配置修改</p>
|
||||
<!-- <p onclick="getRedisConfig($('.plugin_version').attr('version'));">性能调整</p> -->
|
||||
<p onclick="f2bBanIp();">IP黑名单</p>
|
||||
<!-- <p onclick="redisStatus($('.plugin_version').attr('version'));">负载状态</p> -->
|
||||
<p onclick="pluginLogs('fail2ban','','run_log');">运行日志</p>
|
||||
</div>
|
||||
@@ -24,6 +24,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
resetPluginWinWidth(1000);
|
||||
// resetPluginWinHeight(500);
|
||||
$.getScript( "/plugins/file?name=fail2ban&f=js/fail2ban.js", function(){
|
||||
pluginService('fail2ban', $('.plugin_version').attr('version'));
|
||||
});
|
||||
|
||||
+113
-13
@@ -5,6 +5,7 @@ import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import json
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
@@ -18,10 +19,10 @@ def getPluginName():
|
||||
return 'fail2ban'
|
||||
|
||||
def f2bDir():
|
||||
return '/run/fail2ban'
|
||||
return '/run/'+getPluginName()
|
||||
|
||||
def f2bEtcDir():
|
||||
return '/etc/fail2ban'
|
||||
return '/etc/'+getPluginName()
|
||||
|
||||
def getPluginDir():
|
||||
return mw.getPluginDir() + '/' + getPluginName()
|
||||
@@ -48,7 +49,7 @@ def getConf():
|
||||
|
||||
|
||||
def getConfTpl():
|
||||
path = getPluginDir() + "/config/redis.conf"
|
||||
path = getPluginDir() + "/tpl/fail2ban.conf"
|
||||
return path
|
||||
|
||||
|
||||
@@ -89,7 +90,7 @@ def configTpl():
|
||||
for one in pathFile:
|
||||
if one.endswith("conf"):
|
||||
file = path + '/' + one
|
||||
tmp.append(file)
|
||||
tmp.append(file)
|
||||
return mw.getJson(tmp)
|
||||
|
||||
|
||||
@@ -123,6 +124,21 @@ def contentReplace(content):
|
||||
return content
|
||||
|
||||
|
||||
def initFail2BanD():
|
||||
dst_conf = f2bEtcDir() + '/fail2ban.d/default.conf'
|
||||
dst_conf_tpl = getPluginDir() + '/tpl/fail2ban.d/default.conf'
|
||||
if not os.path.exists(dst_conf):
|
||||
content = mw.readFile(dst_conf_tpl)
|
||||
content = contentReplace(content)
|
||||
mw.writeFile(dst_conf, content)
|
||||
|
||||
def initJailD():
|
||||
dst_conf = f2bEtcDir() + '/jail.d/default.conf'
|
||||
dst_conf_tpl = getPluginDir() + '/tpl/jail.d/default.conf'
|
||||
if not os.path.exists(dst_conf):
|
||||
content = mw.readFile(dst_conf_tpl)
|
||||
content = contentReplace(content)
|
||||
mw.writeFile(dst_conf, content)
|
||||
|
||||
def initDreplace():
|
||||
|
||||
@@ -134,12 +150,17 @@ def initDreplace():
|
||||
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)
|
||||
# mw.writeFile(file_bin, content)
|
||||
# mw.execShell('chmod +x ' + file_bin)
|
||||
# config replace
|
||||
# dst_conf = getConf()
|
||||
# dst_conf_init = getServerDir() + '/init.pl'
|
||||
# if not os.path.exists(dst_conf_init):
|
||||
# content = mw.readFile(getConfTpl())
|
||||
# content = contentReplace(content)
|
||||
# mw.writeFile(dst_conf, content)
|
||||
# mw.writeFile(dst_conf_init, 'ok')
|
||||
|
||||
initFail2BanD()
|
||||
initJailD()
|
||||
|
||||
# systemd
|
||||
systemDir = mw.systemdCfgDir()
|
||||
@@ -147,9 +168,9 @@ def initDreplace():
|
||||
if os.path.exists(systemDir) and not os.path.exists(systemService):
|
||||
systemServiceTpl = getPluginDir() + '/init.d/' + getPluginName() + '.service.tpl'
|
||||
service_path = mw.getServerDir()
|
||||
se_content = mw.readFile(systemServiceTpl)
|
||||
se_content = se_content.replace('{$SERVER_PATH}', service_path)
|
||||
mw.writeFile(systemService, se_content)
|
||||
content = mw.readFile(systemServiceTpl)
|
||||
content = content.replace('{$SERVER_PATH}', service_path)
|
||||
mw.writeFile(systemService, content)
|
||||
mw.execShell('systemctl daemon-reload')
|
||||
|
||||
return file_bin
|
||||
@@ -249,8 +270,83 @@ def initdUinstall():
|
||||
return 'ok'
|
||||
|
||||
|
||||
# 读取配置
|
||||
def _read_conf(path, l=None):
|
||||
conf = mw.readFile(path)
|
||||
if not conf:
|
||||
if not l:
|
||||
conf = {}
|
||||
else:
|
||||
conf = []
|
||||
mw.writeFile(path, json.dumps(conf))
|
||||
return conf
|
||||
return json.loads(conf)
|
||||
|
||||
def getBlackFile():
|
||||
return getServerDir() + "/black_list.json"
|
||||
|
||||
|
||||
def getConfigFile():
|
||||
return getServerDir() + "/config.json"
|
||||
|
||||
|
||||
def getBlackListArr():
|
||||
_black_list = getBlackFile()
|
||||
conf = _read_conf(_black_list, l=1)
|
||||
if not conf:
|
||||
conf = []
|
||||
return conf
|
||||
|
||||
|
||||
def getBlackList():
|
||||
conf = getBlackListArr()
|
||||
content = "\n".join(conf)
|
||||
return mw.returnJson(True, 'ok', content)
|
||||
|
||||
def setBlackIp():
|
||||
ip_list = getBlackListArr()
|
||||
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['black_ip'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
new_ip_list = args['black_ip']
|
||||
add_ip_list = [new_ip for new_ip in new_ip_list if new_ip not in ip_list]
|
||||
del_ip_list = [del_ip for del_ip in ip_list if del_ip not in new_ip_list]
|
||||
rep_ip = "^(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}($|[\\/\\d]+$)"
|
||||
rep_ipv6 = "^\\s*((([0-9A-Fa-f]{1,4}:){7}(([0-9A-Fa-f]{1,4})|:))|(([0-9A-Fa-f]{1,4}:){6}(:|((25[0-5]|2[0-4]\\d|[01]?\\d{1,2})(\\.(25[0-5]|2[0-4]\\d|[01]?\\d{1,2})){3})|(:[0-9A-Fa-f]{1,4})))|(([0-9A-Fa-f]{1,4}:){5}((:((25[0-5]|2[0-4]\\d|[01]?\\d{1,2})(\\.(25[0-5]|2[0-4]\\d|[01]?\\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){4}(:[0-9A-Fa-f]{1,4}){0,1}((:((25[0-5]|2[0-4]\\d|[01]?\\d{1,2})(\\.(25[0-5]|2[0-4]\\d|[01]?\\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){3}(:[0-9A-Fa-f]{1,4}){0,2}((:((25[0-5]|2[0-4]\\d|[01]?\\d{1,2})(\\.(25[0-5]|2[0-4]\\d|[01]?\\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){2}(:[0-9A-Fa-f]{1,4}){0,3}((:((25[0-5]|2[0-4]\\d|[01]?\\d{1,2})(\\.(25[0-5]|2[0-4]\\d|[01]?\\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:)(:[0-9A-Fa-f]{1,4}){0,4}((:((25[0-5]|2[0-4]\\d|[01]?\\d{1,2})(\\.(25[0-5]|2[0-4]\\d|[01]?\\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(:(:[0-9A-Fa-f]{1,4}){0,5}((:((25[0-5]|2[0-4]\\d|[01]?\\d{1,2})(\\.(25[0-5]|2[0-4]\\d|[01]?\\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(((25[0-5]|2[0-4]\\d|[01]?\\d{1,2})(\\.(25[0-5]|2[0-4]\\d|[01]?\\d{1,2})){3})))(%.+)?\\s*$"
|
||||
|
||||
data = _read_conf(getConfigFile())
|
||||
|
||||
if new_ip_list == '':
|
||||
for d in data:
|
||||
for ip in ip_list:
|
||||
mw.execShell('fail2ban-client -vvv set {jail} unbanip {ip}'.format(jail=d, ip=ip))
|
||||
|
||||
mw.writeFile(getBlackFile(), json.dumps([]))
|
||||
return nw.returnJson(True, "禁止IP成功")
|
||||
|
||||
# 检查IP格式
|
||||
for ip in add_ip_list:
|
||||
if not re.search(rep_ip, ip) and not re.search(rep_ipv6, ip):
|
||||
return mw.returnJson(False, "IP格式错误 {}".format(ip))
|
||||
|
||||
# 添加新域名到黑名单
|
||||
for d in data:
|
||||
for ip in add_ip_list:
|
||||
mw.execShell('fail2ban-client -vvv set {jail} banip {ip}'.format(jail=d, ip=ip))
|
||||
|
||||
# 检查是否有清理掉的IP
|
||||
for d in data:
|
||||
for ip in del_ip_list:
|
||||
mw.execShell('fail2ban-client -vvv set {jail} unbanip {ip}'.format(jail=d, ip=ip))
|
||||
|
||||
for ip in add_ip_list:
|
||||
ip_list.append(ip)
|
||||
|
||||
mw.writeFile(getBlackFile(), json.dumps(ip_list))
|
||||
return mw.returnJson(True, "添加黑名单成功")
|
||||
|
||||
if __name__ == "__main__":
|
||||
func = sys.argv[1]
|
||||
@@ -280,5 +376,9 @@ if __name__ == "__main__":
|
||||
print(configTpl())
|
||||
elif func == 'read_config_tpl':
|
||||
print(readConfigTpl())
|
||||
elif func == 'get_black_list':
|
||||
print(getBlackList())
|
||||
elif func == 'set_black_ip':
|
||||
print(setBlackIp())
|
||||
else:
|
||||
print('error')
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"path": "server/fail2ban",
|
||||
"display": 1,
|
||||
"author": "fail2ban",
|
||||
"date": "2025-07-28",
|
||||
"date": "2024-07-28",
|
||||
"home": "https://www.fail2ban.org",
|
||||
"type": 0,
|
||||
"pid": "4"
|
||||
|
||||
@@ -12,6 +12,7 @@ install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=$2
|
||||
|
||||
# cd /www/server/mdserver-web/plugins/fail2ban && bash install.sh install 1.1.0
|
||||
# cd /www/server/mdserver-web && python3 plugins/fail2ban/index.py config_tpl
|
||||
|
||||
Install_App()
|
||||
{
|
||||
@@ -31,7 +32,7 @@ Install_App()
|
||||
Uninstall_App()
|
||||
{
|
||||
apt remove -y fail2ban
|
||||
|
||||
apt purge -y fail2ban
|
||||
|
||||
if [ -f /usr/lib/systemd/system/fail2ban.service ];then
|
||||
systemctl stop fail2ban
|
||||
@@ -54,6 +55,10 @@ Uninstall_App()
|
||||
if [ -d $serverPath/fail2ban ];then
|
||||
rm -rf $serverPath/fail2ban
|
||||
fi
|
||||
|
||||
if [ -d /etc/fail2ban ];then
|
||||
rm -rf /etc/fail2ban
|
||||
fi
|
||||
|
||||
echo "卸载fail2ban成功"
|
||||
}
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
function getVersion(){
|
||||
return $('.plugin_version').attr('version');
|
||||
}
|
||||
|
||||
function f2bPost(method, version, args,callback){
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
|
||||
@@ -26,7 +30,7 @@ function f2bPost(method, version, args,callback){
|
||||
},'json');
|
||||
}
|
||||
|
||||
function f2bPostCallbak(method, version, args,callback){
|
||||
function f2bPostCallbak(method, version, args, callback){
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
|
||||
var req_data = {};
|
||||
@@ -52,3 +56,55 @@ function f2bPostCallbak(method, version, args,callback){
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
function f2bBanIpSave(black_ip){
|
||||
var ver = getVersion();
|
||||
f2bPost('set_black_ip', ver, {'black_ip':black_ip}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
|
||||
});
|
||||
}
|
||||
|
||||
function f2bBanIp(){
|
||||
var con = '<p style="color: #666; margin-bottom: 7px">提示:Ctrl+F 搜索关键字,Ctrl+G 查找下一个,Ctrl+S 保存,Ctrl+Shift+R 查找替换!</p>\
|
||||
<textarea class="bt-input-text" style="height: 320px; line-height:18px;" id="textBody"></textarea>\
|
||||
<button id="onlineEditFileBtn" class="btn btn-success btn-sm" style="margin-top:10px;">保存</button>\
|
||||
<ul class="help-info-text c7 ptb15">\
|
||||
<li>如有多个请以换行隔开例:<br/>\
|
||||
192.168.1.1<br/>\
|
||||
192.168.1.0/24\
|
||||
</li>\
|
||||
</ul>';
|
||||
|
||||
$(".soft-man-con").html(con);
|
||||
$("#textBody").empty();
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("textBody"), {
|
||||
extraKeys: {
|
||||
"Ctrl-Space": "autocomplete",
|
||||
"Ctrl-F": "findPersistent",
|
||||
"Ctrl-H": "replaceAll",
|
||||
"Ctrl-S": function() {
|
||||
$("#textBody").text(editor.getValue());
|
||||
f2bPost('set_black_list', '', {'black_ip':editor.getValue()}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
|
||||
});
|
||||
|
||||
f2bBanIpSave(editor.getValue());
|
||||
}
|
||||
},
|
||||
lineNumbers: true,
|
||||
matchBrackets:true,
|
||||
});
|
||||
editor.focus();
|
||||
|
||||
f2bPost('get_black_list', '', {}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
$("#textBody").text(rdata.data);
|
||||
});
|
||||
|
||||
$("#onlineEditFileBtn").click(function(){
|
||||
f2bBanIpSave(editor.getValue());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
[DEFAULT]
|
||||
allowipv6 = auto
|
||||
|
||||
action_ = %(banaction)s[port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
|
||||
|
||||
action_mw = %(action_)s
|
||||
%(mta)s-whois[sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]
|
||||
|
||||
action_mwl = %(action_)s
|
||||
%(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
|
||||
|
||||
action_xarf = %(action_)s
|
||||
xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath="%(logpath)s", port="%(port)s"]
|
||||
|
||||
action_cf_mwl = cloudflare[cfuser="%(cfemail)s", cftoken="%(cfapikey)s"]
|
||||
%(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
|
||||
|
||||
action_blocklist_de = blocklist_de[email="%(sender)s", service="%(__name__)s", apikey="%(blocklist_de_apikey)s", agent="%(fail2ban_agent)s"]
|
||||
|
||||
action_badips = badips.py[category="%(__name__)s", banaction="%(banaction)s", agent="%(fail2ban_agent)s"]
|
||||
action_badips_report = badips[category="%(__name__)s", agent="%(fail2ban_agent)s"]
|
||||
|
||||
action_abuseipdb = abuseipdb
|
||||
|
||||
action = %(action_)s
|
||||
@@ -0,0 +1,2 @@
|
||||
[DEFAULT]
|
||||
backend = systemd
|
||||
@@ -0,0 +1,11 @@
|
||||
#sshd-START
|
||||
[sshd]
|
||||
enabled = true
|
||||
filter = sshd
|
||||
port = 2022,no
|
||||
maxretry = 5
|
||||
findtime = 300
|
||||
bantime = 86400
|
||||
action = %(action_mwl)s
|
||||
logpath = /var/log/auth.log
|
||||
#sshd-END
|
||||
@@ -220,7 +220,7 @@ def getDbConfValue():
|
||||
rep_scope = r"\[database\](.*?)\["
|
||||
tmp = re.findall(rep_scope, content, re.S)
|
||||
|
||||
rep = '(\w*)\s*=\s*(.*)'
|
||||
rep = '(\\w*)\\s*=\\s*(.*)'
|
||||
tmp = re.findall(rep, tmp[0])
|
||||
r = {}
|
||||
for x in range(len(tmp)):
|
||||
@@ -418,7 +418,7 @@ def getGogsConf():
|
||||
result = []
|
||||
|
||||
for g in gets:
|
||||
rep = g['name'] + '\s*=\s*(.*)'
|
||||
rep = g['name'] + '\\s*=\\s*(.*)'
|
||||
tmp = re.search(rep, conf)
|
||||
if not tmp:
|
||||
continue
|
||||
@@ -447,7 +447,7 @@ def submitGogsConf():
|
||||
conf = mw.readFile(filename)
|
||||
for g in gets:
|
||||
if g in args:
|
||||
rep = g + '\s*=\s*(.*)'
|
||||
rep = g + '\\s*=\\s*(.*)'
|
||||
val = g + ' = ' + args[g]
|
||||
conf = re.sub(rep, val, conf)
|
||||
mw.writeFile(filename, conf)
|
||||
|
||||
@@ -173,12 +173,12 @@ def initDreplace():
|
||||
|
||||
def getRootUrl():
|
||||
content = mw.readFile(getConf())
|
||||
rep = r'ROOT_URL\s*=\s*(.*)'
|
||||
rep = r'ROOT_URL\\s*=\\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
if tmp:
|
||||
return tmp.groups()[0]
|
||||
|
||||
rep = r'EXTERNAL_URL\s*=\s*(.*)'
|
||||
rep = r'EXTERNAL_URL\\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
if tmp:
|
||||
return tmp.groups()[0]
|
||||
@@ -187,7 +187,7 @@ def getRootUrl():
|
||||
|
||||
def getSshPort():
|
||||
content = mw.readFile(getConf())
|
||||
rep = r'SSH_PORT\s*=\s*(.*)'
|
||||
rep = r'SSH_PORT\\s*=\\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
if not tmp:
|
||||
return ''
|
||||
@@ -196,7 +196,7 @@ def getSshPort():
|
||||
|
||||
def getHttpPort():
|
||||
content = mw.readFile(getConf())
|
||||
rep = r'HTTP_PORT\s*=\s*(.*)'
|
||||
rep = r'HTTP_PORT\\s*=\\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
if not tmp:
|
||||
return ''
|
||||
@@ -205,7 +205,7 @@ def getHttpPort():
|
||||
|
||||
def getRootPath():
|
||||
content = mw.readFile(getConf())
|
||||
rep = r'ROOT\s*=\s*(.*)'
|
||||
rep = r'ROOT\\s*=\\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
if not tmp:
|
||||
return ''
|
||||
@@ -218,10 +218,10 @@ def getDbConfValue():
|
||||
return {}
|
||||
|
||||
content = mw.readFile(conf)
|
||||
rep_scope = r"\[database\](.*?)\["
|
||||
rep_scope = r"\\[database\\](.*?)\\["
|
||||
tmp = re.findall(rep_scope, content, re.S)
|
||||
|
||||
rep = r'(\w*)\s*=\s*(.*)'
|
||||
rep = r'(\\w*)\\s*=\\s*(.*)'
|
||||
tmp = re.findall(rep, tmp[0])
|
||||
r = {}
|
||||
for x in range(len(tmp)):
|
||||
@@ -419,7 +419,7 @@ def getGogsConf():
|
||||
result = []
|
||||
|
||||
for g in gets:
|
||||
rep = g['name'] + '\s*=\s*(.*)'
|
||||
rep = g['name'] + '\\s*=\\s*(.*)'
|
||||
tmp = re.search(rep, conf)
|
||||
if not tmp:
|
||||
continue
|
||||
@@ -448,7 +448,7 @@ def submitGogsConf():
|
||||
conf = mw.readFile(filename)
|
||||
for g in gets:
|
||||
if g in args:
|
||||
rep = g + '\s*=\s*(.*)'
|
||||
rep = g + '\\s*=\\s*(.*)'
|
||||
val = g + ' = ' + args[g]
|
||||
conf = re.sub(rep, val, conf)
|
||||
mw.writeFile(filename, conf)
|
||||
|
||||
@@ -238,7 +238,7 @@ def getPort():
|
||||
conf = getServerDir() + '/gorse.conf'
|
||||
content = mw.readFile(conf)
|
||||
|
||||
rep = "^(" + 'port' + ')\s*([.0-9A-Za-z_& ~]+)'
|
||||
rep = "^(" + 'port' + ')\\s*([.0-9A-Za-z_& ~]+)'
|
||||
tmp = re.search(rep, content, re.M)
|
||||
if tmp:
|
||||
return tmp.groups()[1]
|
||||
|
||||
@@ -209,10 +209,10 @@ def runInfo():
|
||||
|
||||
conf = mw.readFile(getServerDir() + '/memcached.env')
|
||||
result['bind'] = re.search('IP=(.+)', conf).groups()[0]
|
||||
result['port'] = int(re.search('PORT=(\d+)', conf).groups()[0])
|
||||
result['maxconn'] = int(re.search('MAXCONN=(\d+)', conf).groups()[0])
|
||||
result['port'] = int(re.search('PORT=(\\d+)', conf).groups()[0])
|
||||
result['maxconn'] = int(re.search('MAXCONN=(\\d+)', conf).groups()[0])
|
||||
result['cachesize'] = int(
|
||||
re.search('CACHESIZE=(\d+)', conf).groups()[0])
|
||||
re.search('CACHESIZE=(\\d+)', conf).groups()[0])
|
||||
return mw.getJson(result)
|
||||
except Exception as e:
|
||||
return mw.getJson({})
|
||||
|
||||
@@ -172,7 +172,7 @@ class backupTools:
|
||||
if auth != 'disabled':
|
||||
uoption =' --authenticationDatabase admin -u root -p '+mg_root
|
||||
|
||||
cmd = db_path + "/bin/mongodump "+uoption+" --port "+str(port)+" -d test -o "+backup_path
|
||||
cmd = db_path + "/bin/mongodump "+uoption+" --port "+str(port)+" -d "+name+" -o "+backup_path
|
||||
# print(cmd)
|
||||
mw.execShell(cmd)
|
||||
cmd_gz = "cd "+backup_path+"/"+name+" && tar -zcvf "+filename + " ./"
|
||||
|
||||
@@ -9,7 +9,7 @@ rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=5.0.20
|
||||
VERSION=5.0.29
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
|
||||
@@ -9,7 +9,7 @@ rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=5.0.20
|
||||
VERSION=5.0.29
|
||||
SYS_ARCH=`arch`
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
SYS_NAME=${SYS_VERSION_ID/./}
|
||||
|
||||
@@ -9,7 +9,7 @@ rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=5.0.20
|
||||
VERSION=5.0.29
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
@@ -9,7 +9,7 @@ rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=5.0.20
|
||||
VERSION=5.0.29
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}' | awk -F . '{print $1}'`
|
||||
|
||||
@@ -9,7 +9,7 @@ rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=5.0.20
|
||||
VERSION=5.0.29
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
|
||||
@@ -9,7 +9,7 @@ rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=6.0.9
|
||||
VERSION=6.0.18
|
||||
SYS_ARCH=`arch`
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
SYS_NAME=${SYS_VERSION_ID/./}
|
||||
|
||||
@@ -9,7 +9,7 @@ rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=6.0.9
|
||||
VERSION=6.0.18
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
@@ -9,7 +9,7 @@ rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=6.0.9
|
||||
VERSION=6.0.18
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}' | awk -F . '{print $1}'`
|
||||
|
||||
@@ -9,7 +9,7 @@ rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=6.0.9
|
||||
VERSION=6.0.18
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
|
||||
@@ -9,7 +9,7 @@ rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=7.0.9
|
||||
VERSION=7.0.14
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
|
||||
@@ -9,11 +9,12 @@ rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=7.0.9
|
||||
VERSION=7.0.14
|
||||
SYS_ARCH=`arch`
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
SYS_NAME=${SYS_VERSION_ID/./}
|
||||
|
||||
|
||||
if [ "$SYS_NAME" -gt "11" ];then
|
||||
SYS_NAME="11"
|
||||
fi
|
||||
@@ -22,6 +23,10 @@ if [ "$SYS_NAME" -lt "11" ];then
|
||||
SYS_NAME="11"
|
||||
fi
|
||||
|
||||
if [ "$SYS_NAME" == "" ];then
|
||||
SYS_NAME="11"
|
||||
fi
|
||||
|
||||
FILE_NAME=mongodb-linux-${SYS_ARCH}-debian${SYS_NAME}-${VERSION}
|
||||
FILE_NAME_TGZ=${FILE_NAME}.tgz
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=7.0.9
|
||||
VERSION=7.0.14
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
|
||||
@@ -10,7 +10,7 @@ serverPath=$(dirname "$rootPath")
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=7.0.9
|
||||
VERSION=7.0.14
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
@@ -9,7 +9,7 @@ rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=7.0.9
|
||||
VERSION=7.0.14
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}' | awk -F . '{print $1}'`
|
||||
|
||||
@@ -9,7 +9,7 @@ rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=7.0.9
|
||||
VERSION=7.0.14
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
|
||||
@@ -10,6 +10,8 @@ serverPath=$(dirname "$rootPath")
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=$2
|
||||
|
||||
# cd /www/server/mdserver-web/plugins/msonedrive && bash install.sh install 1.0
|
||||
|
||||
if [ -f ${rootPath}/bin/activate ];then
|
||||
source ${rootPath}/bin/activate
|
||||
fi
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# coding:utf-8
|
||||
# coding=utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# coding:utf-8
|
||||
#!/usr/bin/env python
|
||||
# coding=utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
@@ -2241,7 +2242,7 @@ def getMasterStatus(version=''):
|
||||
|
||||
return mw.returnJson(master_status, '设置成功', data)
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, "数据库密码错误,在管理列表-点击【修复】,"+str(e), 'pwd')
|
||||
return mw.returnJson(False, "数据库密码错误,在管理列表-点击【修复】,"+str(mw.getTracebackInfo()), 'pwd')
|
||||
|
||||
|
||||
def setMasterStatus(version=''):
|
||||
|
||||
@@ -259,6 +259,8 @@ function myPerfOpt() {
|
||||
<option value="3">4-8GB</option>\
|
||||
<option value="4">8-16GB</option>\
|
||||
<option value="5">16-32GB</option>\
|
||||
<option value="6">32-64GB</option>\
|
||||
<option value="7">64-128GB</option>\
|
||||
</select>\
|
||||
<span>' + lan.soft.mysql_set_maxmem + ': </span><input style="width:70px;background-color:#eee;" class="bt-input-text mr5" name="memSize" type="text" value="' + memSize.toFixed(2) + '" readonly>MB\
|
||||
</div>\
|
||||
@@ -439,6 +441,36 @@ function mySQLMemOpt(opt) {
|
||||
$("input[name='table_open_cache']").val(2048);
|
||||
$("input[name='max_connections']").val(500);
|
||||
break;
|
||||
case '6':
|
||||
$("input[name='key_buffer_size']").val(2048);
|
||||
if (query_size) $("input[name='query_cache_size']").val(384);
|
||||
$("input[name='tmp_table_size']").val(4096);
|
||||
$("input[name='innodb_buffer_pool_size']").val(8192);
|
||||
$("input[name='sort_buffer_size']").val(8192);
|
||||
$("input[name='read_buffer_size']").val(8192);
|
||||
$("input[name='read_rnd_buffer_size']").val(4096);
|
||||
$("input[name='join_buffer_size']").val(16384);
|
||||
$("input[name='thread_stack']").val(1024);
|
||||
$("input[name='binlog_cache_size']").val(512);
|
||||
$("input[name='thread_cache_size']").val(512);
|
||||
$("input[name='table_open_cache']").val(4096);
|
||||
$("input[name='max_connections']").val(1000);
|
||||
break;
|
||||
case '7':
|
||||
$("input[name='key_buffer_size']").val(4096);
|
||||
if (query_size) $("input[name='query_cache_size']").val(384);
|
||||
$("input[name='tmp_table_size']").val(8192);
|
||||
$("input[name='innodb_buffer_pool_size']").val(16384);
|
||||
$("input[name='sort_buffer_size']").val(16384);
|
||||
$("input[name='read_buffer_size']").val(16384);
|
||||
$("input[name='read_rnd_buffer_size']").val(8192);
|
||||
$("input[name='join_buffer_size']").val(16384);
|
||||
$("input[name='thread_stack']").val(2048);
|
||||
$("input[name='binlog_cache_size']").val(1024);
|
||||
$("input[name='thread_cache_size']").val(1024);
|
||||
$("input[name='table_open_cache']").val(8192);
|
||||
$("input[name='max_connections']").val(2000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@ Description=pgadmin service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
ExecStart=gunicorn --bind unix:/tmp/pgadmin4.sock --workers=1 --threads=25 --chdir {$SERVER_PATH}/pgadmin/run/lib/{$PY_VER}/site-packages/pgadmin4 pgAdmin4:app
|
||||
|
||||
ExecStart={$SERVER_PATH}/pgadmin/run/bin/gunicorn --bind unix:/tmp/pgadmin4.sock --workers=1 --threads=25 --chdir {$SERVER_PATH}/pgadmin/run/lib/{$PY_VER}/site-packages/pgadmin4 pgAdmin4:app
|
||||
ExecReload=/bin/kill -USR2 $MAINPID
|
||||
PrivateTmp=false
|
||||
|
||||
|
||||
@@ -79,10 +79,10 @@ Install_pgadmin()
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [ -f ${PG_DIR}/bin/activate ];then
|
||||
source ${PG_DIR}/bin/activate
|
||||
fi
|
||||
pip install gunicorn
|
||||
|
||||
# pip install https://ftp.postgresql.org/pub/pgadmin/pgadmin4/v8.10/pip/pgadmin4-8.10-py3-none-any.whl
|
||||
pip install https://ftp.postgresql.org/pub/pgadmin/pgadmin4/v8.12/pip/pgadmin4-8.12-py3-none-any.whl
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
"name": "php",
|
||||
"title": "PHP",
|
||||
"coexist": true,
|
||||
"versions": ["53","54","55","56","70","71","72","73","74","80","81","82","83"],
|
||||
"updates": ["5.3.29","5.4.45","5.6.36","7.0.30","7.1.33","7.2.32","7.3.20","7.4.30","8.0.30","8.1.24","8.2.11","8.3.0"],
|
||||
"versions": ["53","54","55","56","70","71","72","73","74","80","81","82","83","84"],
|
||||
"updates": ["5.3.29","5.4.45","5.6.36","7.0.30","7.1.33","7.2.32","7.3.20","7.4.30","8.0.30","8.1.29","8.2.24","8.3.12","8.4.0"],
|
||||
"tip": "soft",
|
||||
"install_pre_inspection":true,
|
||||
"checks": "server/php/VERSION/bin/php",
|
||||
|
||||
@@ -16,7 +16,7 @@ function version_lt() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)"
|
||||
function version_ge() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" == "$1"; }
|
||||
|
||||
|
||||
version=8.1.29
|
||||
version=8.1.30
|
||||
PHP_VER=81
|
||||
Install_php()
|
||||
{
|
||||
@@ -56,7 +56,7 @@ if [ ! -d $sourcePath/php/php${PHP_VER} ];then
|
||||
fi
|
||||
|
||||
#检测文件是否损坏.
|
||||
md5_file_ok=288884af60581d4284baba2ace9ca6d646f72facbd3e3c2dd2acc7fe6f903536
|
||||
md5_file_ok=f24a6007f0b25a53cb7fbaee69c85017e0345b62089c2425a0afb7e177192ed1
|
||||
if [ -f $sourcePath/php/php-${version}.tar.xz ];then
|
||||
md5_file=`sha256sum $sourcePath/php/php-${version}.tar.xz | awk '{print $1}'`
|
||||
if [ "${md5_file}" != "${md5_file_ok}" ]; then
|
||||
|
||||
@@ -15,7 +15,7 @@ function version_le() { test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)"
|
||||
function version_lt() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" != "$1"; }
|
||||
function version_ge() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" == "$1"; }
|
||||
|
||||
version=8.4
|
||||
version=8.4.0RC2
|
||||
PHP_VER=84
|
||||
Install_php()
|
||||
{
|
||||
@@ -37,18 +37,19 @@ if [ ! -d $sourcePath/php/php${PHP_VER} ];then
|
||||
|
||||
|
||||
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
|
||||
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://www.php.net/distributions/php-${version}.tar.xz
|
||||
# wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://www.php.net/distributions/php-${version}.tar.xz
|
||||
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://downloads.php.net/~calvinb/php-${version}.tar.xz
|
||||
fi
|
||||
|
||||
#检测文件是否损坏.
|
||||
md5_file_ok=xxx
|
||||
if [ -f $sourcePath/php/php-${version}.tar.xz ];then
|
||||
md5_file=`sha256sum $sourcePath/php/php-${version}.tar.xz | awk '{print $1}'`
|
||||
if [ "${md5_file}" != "${md5_file_ok}" ]; then
|
||||
echo "PHP${version} 下载文件不完整,重新安装"
|
||||
rm -rf $sourcePath/php/php-${version}.tar.xz
|
||||
fi
|
||||
fi
|
||||
# md5_file_ok=xxx
|
||||
# if [ -f $sourcePath/php/php-${version}.tar.xz ];then
|
||||
# md5_file=`sha256sum $sourcePath/php/php-${version}.tar.xz | awk '{print $1}'`
|
||||
# if [ "${md5_file}" != "${md5_file_ok}" ]; then
|
||||
# echo "PHP${version} 下载文件不完整,重新安装"
|
||||
# rm -rf $sourcePath/php/php-${version}.tar.xz
|
||||
# fi
|
||||
# fi
|
||||
|
||||
cd $sourcePath/php && tar -Jxf $sourcePath/php/php-${version}.tar.xz
|
||||
mv $sourcePath/php/php-${version} $sourcePath/php/php${PHP_VER}
|
||||
|
||||
@@ -21,6 +21,11 @@ if [ "$version" -lt "72" ];then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$version" == "84" ];then
|
||||
LIBV=1.0.7
|
||||
fi
|
||||
|
||||
|
||||
LIB_PATH_NAME=lib/php
|
||||
if [ -d $serverPath/php/${version}/lib64 ];then
|
||||
LIB_PATH_NAME=lib64
|
||||
|
||||
@@ -12,7 +12,7 @@ serverPath=$(dirname "$rootPath")
|
||||
sourcePath=${serverPath}/source/php
|
||||
SYS_ARCH=`arch`
|
||||
LIBNAME=redis
|
||||
LIBV=5.3.7
|
||||
LIBV=6.1.0
|
||||
sysName=`uname`
|
||||
actionType=$1
|
||||
version=$2
|
||||
@@ -21,8 +21,10 @@ if [ "$version" == "52" ];then
|
||||
LIBV=2.2.7
|
||||
elif [ "$version" -lt "70" ];then
|
||||
LIBV=4.2.0
|
||||
elif [ "$version" -gt "74" ];then
|
||||
elif [ "$version" -lt "80" ];then
|
||||
LIBV=5.3.7
|
||||
elif [ "$version" -gt "80" ];then
|
||||
LIBV=6.1.0
|
||||
else
|
||||
echo 'ok'
|
||||
fi
|
||||
|
||||
@@ -58,7 +58,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "脚本解密",
|
||||
"msg": "用于解密ionCube Encoder加密脚本!",
|
||||
@@ -76,7 +77,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "加密库",
|
||||
"msg": "Sodium加密库的包装器",
|
||||
@@ -94,7 +96,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "运算库",
|
||||
"msg": "一个开源的数学运算库",
|
||||
@@ -116,7 +119,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "缓存器",
|
||||
"msg": "用于加速PHP脚本!",
|
||||
@@ -138,7 +142,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "SSL!",
|
||||
@@ -155,7 +160,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "加密软件!",
|
||||
@@ -177,7 +183,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "高精度计算!",
|
||||
@@ -200,7 +207,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "缓存器",
|
||||
"msg": "用于信号控制!",
|
||||
@@ -223,7 +231,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "编码转换!",
|
||||
@@ -244,7 +253,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "用于FILE!",
|
||||
@@ -264,7 +274,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "提供到libevent库的接口",
|
||||
@@ -285,7 +296,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "用于图像文件格式!",
|
||||
@@ -303,7 +315,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "序列化扩展!",
|
||||
@@ -326,7 +339,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "国际化与本地化!",
|
||||
@@ -349,7 +363,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "通用GD库!",
|
||||
@@ -372,7 +387,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "提供国际化支持",
|
||||
@@ -417,7 +433,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "缓存器",
|
||||
"msg": "强大的内容缓存器,支持集群",
|
||||
@@ -440,7 +457,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "缓存器",
|
||||
"msg": "更强大的内容缓存器,支持集群",
|
||||
@@ -488,7 +506,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "比GD更强大的图形库",
|
||||
@@ -510,7 +529,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "调试器",
|
||||
"msg": "不多说,不了解的不要安装",
|
||||
@@ -533,7 +553,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "性能分析",
|
||||
"msg": "不多说,不了解的不要安装!",
|
||||
@@ -555,7 +576,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "异步、并行、高性能网络通信引擎",
|
||||
@@ -601,7 +623,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "框架",
|
||||
"msg": "Yaf是一个C语言编写的PHP框架",
|
||||
@@ -618,7 +641,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "YAML-1.1解析器和发射器",
|
||||
@@ -651,7 +675,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "Mongodb数据库连接驱动",
|
||||
@@ -669,7 +694,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "缓存器",
|
||||
"msg": "高性能无锁共享内存Cache",
|
||||
@@ -691,7 +717,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "大数据",
|
||||
"msg": "SOLR全文搜索服务",
|
||||
@@ -713,7 +740,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "日志",
|
||||
"msg": "SeasLog高性能日志记录",
|
||||
@@ -738,7 +766,8 @@
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
"83",
|
||||
"84"
|
||||
],
|
||||
"type": "压缩",
|
||||
"msg": "压缩组件",
|
||||
|
||||
@@ -120,7 +120,7 @@ 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 + '/redis')
|
||||
content = content.replace('{$SERVER_APP}', service_path + '/'+getPluginName())
|
||||
content = content.replace('{$REDIS_PASS}', mw.getRandomString(10))
|
||||
return content
|
||||
|
||||
|
||||
@@ -331,7 +331,7 @@ def getRecListData():
|
||||
path = appConf()
|
||||
content = mw.readFile(path)
|
||||
|
||||
flist = re.findall("\[(.*)\]", content)
|
||||
flist = re.findall("\\[(.*)\\]", content)
|
||||
|
||||
flist_len = len(flist)
|
||||
ret_list = []
|
||||
@@ -341,15 +341,15 @@ def getRecListData():
|
||||
n = i + 1
|
||||
reg = ''
|
||||
if n == flist_len:
|
||||
reg = '\[' + flist[i] + '\](.*)\[?'
|
||||
reg = '\\[' + flist[i] + '\\](.*)\\[?'
|
||||
else:
|
||||
reg = '\[' + flist[i] + '\](.*)\[' + flist[n] + '\]'
|
||||
reg = '\\[' + flist[i] + '\\](.*)\\[' + flist[n] + '\\]'
|
||||
|
||||
t1 = re.search(reg, content, re.S)
|
||||
if t1:
|
||||
args = t1.groups()[0]
|
||||
# print('args start', args, 'args_end')
|
||||
t2 = re.findall('\s*(.*)\s*\=\s*?(.*)?', args, re.M | re.I)
|
||||
t2 = re.findall('\\s*(.*)\\s*\\=\\s*?(.*)?', args, re.M | re.I)
|
||||
for i in range(len(t2)):
|
||||
tmp[t2[i][0].strip()] = t2[i][1].strip()
|
||||
ret_list.append(tmp)
|
||||
@@ -456,9 +456,9 @@ def delRecBy(name):
|
||||
next_name = reclist[x + 1]['name']
|
||||
reg = ''
|
||||
if is_end:
|
||||
reg = '\[' + name + '\]\s*(.*)'
|
||||
reg = '\\[' + name + '\\]\\s*(.*)'
|
||||
else:
|
||||
reg = '\[' + name + '\]\s*(.*)\s*\[' + next_name + '\]'
|
||||
reg = '\\[' + name + '\\]\\s*(.*)\\s*\\[' + next_name + '\\]'
|
||||
|
||||
conre = re.search(reg, content, re.S)
|
||||
content = content.replace(
|
||||
|
||||
@@ -268,7 +268,7 @@ def runLog():
|
||||
def ipList():
|
||||
config = getServerDir() + '/conf/app.conf'
|
||||
content = mw.readFile(config)
|
||||
rep = 'ip\s*=\s*(.*)'
|
||||
rep = r'ip\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
if not tmp:
|
||||
return ''
|
||||
|
||||
@@ -26,6 +26,7 @@ def getServerDir():
|
||||
return mw.getServerDir() + '/' + getPluginName()
|
||||
|
||||
def pingData(args = ()):
|
||||
# print(args)
|
||||
conn = mw.M('sp_ping').dbPos(getServerDir()+'/data', 'simpleping', 'db3')
|
||||
field = 'id,speed,created_unix'
|
||||
conn = conn.field(field)
|
||||
@@ -36,16 +37,21 @@ def pingData(args = ()):
|
||||
ip = 'all'
|
||||
else:
|
||||
ip = args['ip']
|
||||
if ip != 'all':
|
||||
conn = conn.where('ip=?',(ip,))
|
||||
|
||||
if atype == 'pos':
|
||||
pos = args['pos']
|
||||
data = conn.where('created_unix>?',(pos,)).limit("3000").select()
|
||||
if 'pos' in args:
|
||||
pos = args['pos']
|
||||
conn.where('created_unix>?',(pos,)).limit("3000")
|
||||
if ip != 'all':
|
||||
conn.andWhere('ip=?',(ip,))
|
||||
elif atype == 'range':
|
||||
start = args['start']
|
||||
end = args['end']
|
||||
data = conn.where('created_unix>=? and created_unix<=?',(start,end)).limit("1000").select()
|
||||
conn.where('created_unix>=? and created_unix<=?',(start,end,)).limit("1000")
|
||||
if ip != 'all':
|
||||
conn.andWhere('ip=?',(ip,))
|
||||
|
||||
data = conn.select()
|
||||
return data
|
||||
|
||||
|
||||
|
||||
@@ -11,8 +11,12 @@ import json
|
||||
|
||||
from typing import List, Dict
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
try:
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
except Exception as e:
|
||||
import core.mw as mw
|
||||
|
||||
|
||||
app_debug = False
|
||||
if mw.isAppleSystem():
|
||||
|
||||
@@ -52,7 +52,7 @@ def send_msg(bot, tag='ad', trigger_time=300):
|
||||
|
||||
# https://t.me/gjgzs2022 | 22/m | @GJ_gzs
|
||||
# https://zhaoziyuan1.cc | web | 15/m | 2m | next,12/15 | @baleite
|
||||
# 综合包网/NG接口开户 | 28/m | 6m | next,10/28 | @aabbcx888
|
||||
# 综合包网/NG接口开户 | 28/m | 6m | next,4/28 | x
|
||||
# 实名认证/过人脸🕵️♀️各种账号处理✅ | 30/m| next,12/30 | @nngzs
|
||||
# 桃花资源采集| 13/m| next,1/13 | @xiaolizi1122
|
||||
keyboard = [
|
||||
|
||||
@@ -7,8 +7,12 @@ import time
|
||||
import json
|
||||
import re
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
try:
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
except Exception as e:
|
||||
import core.mw as mw
|
||||
|
||||
|
||||
app_debug = False
|
||||
|
||||
+5
-1
@@ -14,7 +14,11 @@ gevent>=22.10.2
|
||||
gevent-websocket==0.10.1
|
||||
psutil==5.9.1
|
||||
chardet==3.0.4
|
||||
flask-sqlalchemy==2.3.2
|
||||
SQLAlchemy==2.*
|
||||
Flask-SQLAlchemy==3.1.*
|
||||
Flask-Migrate==4.*
|
||||
#Flask-Security-Too==5.5.*; python_version >= '3.10'
|
||||
#Flask-Security-Too==5.4.*; python_version <= '3.9'
|
||||
pyOpenSSL==23.2.0
|
||||
cryptography>=40.0.2
|
||||
configparser==5.2.0
|
||||
|
||||
@@ -6,7 +6,7 @@ After=network.target
|
||||
Type=simple
|
||||
WorkingDirectory={$SERVER_PATH}
|
||||
EnvironmentFile={$SERVER_PATH}/scripts/init.d/service.sh
|
||||
ExecStart=python3 task.py
|
||||
ExecStart=python3 panel_task.py
|
||||
ExecStop=kill -HUP $MAINID
|
||||
ExecReload=kill -HUP $MAINID
|
||||
KillMode=process
|
||||
|
||||
@@ -231,6 +231,11 @@ error_logs()
|
||||
|
||||
mw_update()
|
||||
{
|
||||
if [ -f $mw_path/task.py ];then
|
||||
echo "与后续版本差异太大,不再提供更新"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
LOCAL_ADDR=common
|
||||
cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"")
|
||||
if [ ! -z "$cn" ] || [ "$?" == "0" ] ;then
|
||||
@@ -246,6 +251,11 @@ mw_update()
|
||||
|
||||
mw_update_dev()
|
||||
{
|
||||
if [ -f $mw_path/task.py ];then
|
||||
echo "与后续版本差异太大,不再提供更新"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
LOCAL_ADDR=common
|
||||
cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"")
|
||||
if [ ! -z "$cn" ] || [ "$?" == "0" ] ;then
|
||||
|
||||
@@ -4,6 +4,13 @@ export PATH
|
||||
# LANG=en_US.UTF-8
|
||||
is64bit=`getconf LONG_BIT`
|
||||
|
||||
if [ -f /www/server/mdserver-web/tools.py ];then
|
||||
echo -e "存在旧版代码,不能安装!,已知风险的情况下"
|
||||
echo -e "rm -rf /www/server/mdserver-web"
|
||||
echo -e "可安装!"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
LOG_FILE=/var/log/mw-install.log
|
||||
|
||||
{
|
||||
|
||||
@@ -4,6 +4,14 @@ export PATH
|
||||
# LANG=en_US.UTF-8
|
||||
is64bit=`getconf LONG_BIT`
|
||||
|
||||
if [ -f /www/server/mdserver-web/tools.py ];then
|
||||
echo -e "存在旧版代码,不能安装!,已知风险的情况下"
|
||||
echo -e "rm -rf /www/server/mdserver-web"
|
||||
echo -e "可安装!"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
echo -e "您正在安装的是\033[31mmdserver-web测试版\033[0m,非开发测试用途请使用正式版 install.sh !"
|
||||
echo -e "You are installing\033[31m mdserver-web dev version\033[0m, normally use install.sh for production.\n"
|
||||
sleep 1
|
||||
|
||||
Executable
+182
@@ -0,0 +1,182 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
# LANG=en_US.UTF-8
|
||||
is64bit=`getconf LONG_BIT`
|
||||
|
||||
echo -e "您正在安装的是\033[31mmdserver-web测试版\033[0m,非开发测试用途请使用正式版 install.sh !"
|
||||
echo -e "You are installing\033[31m mdserver-web dev version\033[0m, normally use install.sh for production.\n"
|
||||
sleep 1
|
||||
|
||||
LOG_FILE=/var/log/mw-install.log
|
||||
|
||||
{
|
||||
|
||||
if [ -f /etc/motd ];then
|
||||
echo "welcome to mdserver-web panel" > /etc/motd
|
||||
fi
|
||||
|
||||
startTime=`date +%s`
|
||||
|
||||
_os=`uname`
|
||||
echo "use system: ${_os}"
|
||||
|
||||
|
||||
if [ ${_os} == "Darwin" ]; then
|
||||
OSNAME='macos'
|
||||
elif grep -Eq "openSUSE" /etc/*-release; then
|
||||
OSNAME='opensuse'
|
||||
zypper refresh
|
||||
zypper install -y wget curl zip unzip unrar rar
|
||||
elif grep -Eq "FreeBSD" /etc/*-release; then
|
||||
OSNAME='freebsd'
|
||||
pkg install -y wget curl zip unzip unrar rar
|
||||
elif grep -Eqi "EulerOS" /etc/*-release || grep -Eqi "openEuler" /etc/*-release; then
|
||||
OSNAME='euler'
|
||||
yum install -y wget curl zip unzip tar crontabs
|
||||
elif grep -Eqi "CentOS" /etc/issue || grep -Eqi "CentOS" /etc/*-release; then
|
||||
OSNAME='rhel'
|
||||
yum install -y wget zip unzip tar
|
||||
elif grep -Eqi "Fedora" /etc/issue || grep -Eqi "Fedora" /etc/*-release; then
|
||||
OSNAME='rhel'
|
||||
yum install -y wget zip unzip tar
|
||||
elif grep -Eqi "Rocky" /etc/issue || grep -Eqi "Rocky" /etc/*-release; then
|
||||
OSNAME='rhel'
|
||||
yum install -y wget zip unzip
|
||||
elif grep -Eqi "AlmaLinux" /etc/issue || grep -Eqi "AlmaLinux" /etc/*-release; then
|
||||
OSNAME='rhel'
|
||||
yum install -y wget zip unzip tar
|
||||
elif grep -Eqi "Amazon Linux" /etc/issue || grep -Eqi "Amazon Linux" /etc/*-release; then
|
||||
OSNAME='amazon'
|
||||
yum install -y wget zip unzip tar
|
||||
elif grep -Eqi "Ubuntu" /etc/issue || grep -Eqi "Ubuntu" /etc/*-release; then
|
||||
OSNAME='ubuntu'
|
||||
apt install -y wget zip unzip tar
|
||||
elif grep -Eqi "Debian" /etc/issue || grep -Eqi "Debian" /etc/*-release; then
|
||||
OSNAME='debian'
|
||||
apt update -y
|
||||
apt install -y devscripts
|
||||
apt install -y wget zip unzip tar
|
||||
else
|
||||
OSNAME='unknow'
|
||||
fi
|
||||
|
||||
if [ "$EUID" -ne 0 ] && [ "$OSNAME" != "macos" ];then
|
||||
echo "Please run as root!"
|
||||
exit
|
||||
fi
|
||||
|
||||
# HTTP_PREFIX="https://"
|
||||
# LOCAL_ADDR=common
|
||||
# ping -c 1 github.com > /dev/null 2>&1
|
||||
# if [ "$?" != "0" ];then
|
||||
# LOCAL_ADDR=cn
|
||||
# HTTP_PREFIX="https://mirror.ghproxy.com/"
|
||||
# fi
|
||||
|
||||
HTTP_PREFIX="https://"
|
||||
LOCAL_ADDR=common
|
||||
cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"")
|
||||
if [ ! -z "$cn" ] || [ "$?" == "0" ] ;then
|
||||
LOCAL_ADDR=cn
|
||||
HTTP_PREFIX="https://mirror.ghproxy.com/"
|
||||
fi
|
||||
|
||||
echo "local:${LOCAL_ADDR}"
|
||||
echo "OSNAME:${OSNAME}"
|
||||
|
||||
if [ $OSNAME != "macos" ];then
|
||||
|
||||
if id www &> /dev/null ;then
|
||||
echo ""
|
||||
else
|
||||
groupadd www
|
||||
useradd -g www -s /usr/sbin/nologin www
|
||||
fi
|
||||
|
||||
mkdir -p /www/server
|
||||
mkdir -p /www/wwwroot
|
||||
mkdir -p /www/wwwlogs
|
||||
mkdir -p /www/backup/database
|
||||
mkdir -p /www/backup/site
|
||||
|
||||
if [ ! -d /www/server/mdserver-web ];then
|
||||
|
||||
if [ "$LOCAL_ADDR" == "common" ];then
|
||||
curl --insecure -sSLo /tmp/dev.zip ${HTTP_PREFIX}github.com/midoks/mdserver-web/archive/refs/heads/dev.zip
|
||||
cd /tmp && unzip /tmp/dev.zip
|
||||
mv -f /tmp/mdserver-web-dev /www/server/mdserver-web
|
||||
rm -rf /tmp/dev.zip
|
||||
rm -rf /tmp/mdserver-web-dev
|
||||
else
|
||||
# curl --insecure -sSLo /tmp/dev.zip https://code.midoks.icu/midoks/mdserver-web/archive/dev.zip
|
||||
wget --no-check-certificate -O /tmp/dev.zip https://code.midoks.icu/midoks/mdserver-web/archive/dev.zip
|
||||
cd /tmp && unzip /tmp/dev.zip
|
||||
mv -f /tmp/mdserver-web /www/server/mdserver-web
|
||||
rm -rf /tmp/dev.zip
|
||||
rm -rf /tmp/mdserver-web
|
||||
fi
|
||||
fi
|
||||
|
||||
# install acme.sh
|
||||
if [ ! -d /root/.acme.sh ];then
|
||||
if [ "$LOCAL_ADDR" != "common" ];then
|
||||
# curl -sSL -o /tmp/acme.tar.gz ${HTTP_PREFIX}github.com/acmesh-official/acme.sh/archive/master.tar.gz
|
||||
curl --insecure -sSLo /tmp/acme.tar.gz https://gitee.com/neilpang/acme.sh/repository/archive/master.tar.gz
|
||||
tar xvzf /tmp/acme.tar.gz -C /tmp
|
||||
cd /tmp/acme.sh-master
|
||||
bash acme.sh install
|
||||
fi
|
||||
|
||||
if [ ! -d /root/.acme.sh ];then
|
||||
curl https://get.acme.sh | sh
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "use system version: ${OSNAME}"
|
||||
|
||||
if [ "${OSNAME}" == "macos" ];then
|
||||
curl --insecure -fsSL https://code.midoks.icu/midoks/mdserver-web/raw/branch/master/scripts/install/macos.sh | bash
|
||||
else
|
||||
cd /www/server/mdserver-web && bash scripts/install/${OSNAME}.sh
|
||||
fi
|
||||
|
||||
if [ "${OSNAME}" == "macos" ];then
|
||||
echo "macos end"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
cd /www/server/mdserver-web && bash cli_new.sh start
|
||||
isStart=`ps -ef|grep 'gunicorn -c setting.py app:app' |grep -v grep|awk '{print $2}'`
|
||||
n=0
|
||||
while [ ! -f /etc/rc.d/init.d/mw ];
|
||||
do
|
||||
echo -e ".\c"
|
||||
sleep 1
|
||||
let n+=1
|
||||
if [ $n -gt 20 ];then
|
||||
echo -e "start mw fail"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
cd /www/server/mdserver-web && bash /etc/rc.d/init.d/mw stop
|
||||
cd /www/server/mdserver-web && bash /etc/rc.d/init.d/mw start
|
||||
cd /www/server/mdserver-web && bash /etc/rc.d/init.d/mw default
|
||||
|
||||
sleep 2
|
||||
if [ ! -e /usr/bin/mw ]; then
|
||||
if [ -f /etc/rc.d/init.d/mw ];then
|
||||
ln -s /etc/rc.d/init.d/mw /usr/bin/mw
|
||||
fi
|
||||
fi
|
||||
|
||||
endTime=`date +%s`
|
||||
((outTime=(${endTime}-${startTime})/60))
|
||||
echo -e "Time consumed:\033[32m $outTime \033[0mMinute!"
|
||||
|
||||
} 1> >(tee $LOG_FILE) 2>&1
|
||||
|
||||
echo -e "\nInstall completed. If error occurs, please contact us with the log file mw-install.log ."
|
||||
echo "安装完毕,如果出现错误,请带上同目录下的安装日志 mw-install.log 联系我们反馈."
|
||||
@@ -19,7 +19,7 @@ fi
|
||||
|
||||
# openresty
|
||||
if [ ! -d /www/server/openresty ];then
|
||||
cd /www/server/mdserver-web/plugins/openresty && bash install.sh install 1.21.4.1
|
||||
cd /www/server/mdserver-web/plugins/openresty && bash install.sh install 1.25.3
|
||||
else
|
||||
echo "openresty alreay exist!"
|
||||
fi
|
||||
@@ -50,7 +50,7 @@ fi
|
||||
|
||||
# mysql
|
||||
if [ ! -d /www/server/mysql ];then
|
||||
cd /www/server/mdserver-web/plugins/mysql && bash install.sh install 5.6
|
||||
cd /www/server/mdserver-web/plugins/mysql && bash install.sh install 5.7
|
||||
else
|
||||
echo "mysql alreay exist!"
|
||||
fi
|
||||
|
||||
@@ -6,6 +6,14 @@ is64bit=`getconf LONG_BIT`
|
||||
|
||||
startTime=`date +%s`
|
||||
|
||||
if [ -f /www/server/mdserver-web/tools.py ];then
|
||||
echo -e "存在旧版代码,不能安装!,已知风险的情况下"
|
||||
echo -e "rm -rf /www/server/mdserver-web"
|
||||
echo -e "可安装!"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
_os=`uname`
|
||||
echo "use system: ${_os}"
|
||||
|
||||
|
||||
@@ -6,6 +6,13 @@ is64bit=`getconf LONG_BIT`
|
||||
|
||||
startTime=`date +%s`
|
||||
|
||||
if [ -f /www/server/mdserver-web/tools.py ];then
|
||||
echo -e "存在旧版代码,不能安装!,已知风险的情况下"
|
||||
echo -e "rm -rf /www/server/mdserver-web"
|
||||
echo -e "可安装!"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
_os=`uname`
|
||||
echo "use system: ${_os}"
|
||||
|
||||
|
||||
+3
-1
@@ -1,4 +1,6 @@
|
||||
urllib3==1.21.1
|
||||
gevent==22.10.2
|
||||
gunicorn==21.2.0
|
||||
pyyaml
|
||||
sqlalchemy==1.4.47
|
||||
flask-sqlalchemy==2.5.1
|
||||
pyyaml
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
# coding:utf-8
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# MW-Linux面板
|
||||
# ---------------------------------------------------------------------------------
|
||||
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
|
||||
# ---------------------------------------------------------------------------------
|
||||
# Author: midoks <midoks@163.com>
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import time
|
||||
import uuid
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
|
||||
from flask import Flask
|
||||
|
||||
from flask_socketio import SocketIO, emit, send
|
||||
from flask import Flask, abort, current_app, session, url_for
|
||||
from flask import Blueprint, render_template
|
||||
from flask import render_template_string
|
||||
|
||||
from flask import request
|
||||
from flask import Response
|
||||
|
||||
|
||||
from flask_migrate import Migrate
|
||||
from flask_caching import Cache
|
||||
from werkzeug.local import LocalProxy
|
||||
|
||||
from admin import model
|
||||
from admin import setup
|
||||
|
||||
from admin.model import db as sys_db
|
||||
|
||||
|
||||
import core.mw as mw
|
||||
import config
|
||||
import utils.config as utils_config
|
||||
|
||||
root_dir = mw.getRunDir()
|
||||
|
||||
socketio = SocketIO(manage_session=False, async_mode='threading',
|
||||
logger=False, engineio_logger=False, debug=False,
|
||||
ping_interval=25, ping_timeout=120)
|
||||
|
||||
|
||||
app = Flask(__name__, template_folder='templates/default')
|
||||
|
||||
# 缓存配置
|
||||
cache = Cache(config={'CACHE_TYPE': 'simple'})
|
||||
cache.init_app(app, config={'CACHE_TYPE': 'simple'})
|
||||
|
||||
# 静态文件配置
|
||||
from whitenoise import WhiteNoise
|
||||
app.wsgi_app = WhiteNoise(app.wsgi_app, root="../web/static/", prefix="static/", max_age=604800)
|
||||
|
||||
# session配置
|
||||
app.secret_key = uuid.UUID(int=uuid.getnode()).hex[-12:]
|
||||
# app.config['sessions'] = dict()
|
||||
app.config['SESSION_PERMANENT'] = True
|
||||
app.config['SESSION_USE_SIGNER'] = True
|
||||
app.config['SESSION_KEY_PREFIX'] = 'MW_:'
|
||||
app.config['SESSION_COOKIE_NAME'] = "MW_VER_1"
|
||||
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=31)
|
||||
|
||||
# db的配置
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = mw.getSqitePrefix()+config.SQLITE_PATH+"?timeout=20" # 使用 SQLite 数据库
|
||||
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
|
||||
|
||||
# 初始化db
|
||||
sys_db.init_app(app)
|
||||
Migrate(app, sys_db)
|
||||
|
||||
|
||||
# 检查数据库是否存在。如果没有就创建它。
|
||||
setup_db_required = False
|
||||
if not os.path.isfile(config.SQLITE_PATH):
|
||||
setup_db_required = True
|
||||
|
||||
# with app.app_context():
|
||||
# sys_db.create_all()
|
||||
|
||||
with app.app_context():
|
||||
if setup_db_required:
|
||||
sys_db.create_all()
|
||||
|
||||
# 初始化用户信息
|
||||
with app.app_context():
|
||||
if setup_db_required:
|
||||
setup.init_admin_user()
|
||||
setup.init_option()
|
||||
|
||||
app.config['BASIC_AUTH_OPEN'] = False
|
||||
with app.app_context():
|
||||
basic_auth = model.getOptionByJson('basic_auth', default={'open':False})
|
||||
if basic_auth['open']:
|
||||
app.config['BASIC_AUTH_OPEN'] = True
|
||||
|
||||
|
||||
# 加载模块
|
||||
from .submodules import get_submodules
|
||||
for module in get_submodules():
|
||||
app.logger.info('Registering blueprint module: %s' % module)
|
||||
if app.blueprints.get(module.name) is None:
|
||||
app.register_blueprint(module)
|
||||
|
||||
def sendAuthenticated():
|
||||
# 发送http认证信息
|
||||
request_host = mw.getHostAddr()
|
||||
result = Response('', 401, {'WWW-Authenticate': 'Basic realm="%s"' % request_host.strip()})
|
||||
if not 'login' in session and not 'admin_auth' in session:
|
||||
session.clear()
|
||||
return result
|
||||
|
||||
@app.before_request
|
||||
def requestCheck():
|
||||
# 自定义basic auth认证
|
||||
if app.config['BASIC_AUTH_OPEN']:
|
||||
basic_auth = model.getOptionByJson('basic_auth', default={'open':False})
|
||||
if not basic_auth['open']:
|
||||
return
|
||||
|
||||
auth = request.authorization
|
||||
if request.path in ['/download', '/hook', '/down']:
|
||||
return
|
||||
if not auth:
|
||||
return sendAuthenticated()
|
||||
|
||||
# print(auth.username.strip(),auth.password.strip())
|
||||
salt = basic_auth['salt']
|
||||
basic_user = mw.md5(auth.username.strip() + salt)
|
||||
basic_pwd = mw.md5(auth.password.strip() + salt)
|
||||
if basic_user != basic_auth['basic_user'] or basic_pwd != basic_auth['basic_pwd']:
|
||||
return sendAuthenticated()
|
||||
|
||||
|
||||
|
||||
@app.after_request
|
||||
def requestAfter(response):
|
||||
response.headers['soft'] = config.APP_NAME
|
||||
response.headers['mw-version'] = config.APP_VERSION
|
||||
return response
|
||||
|
||||
|
||||
@app.errorhandler(404)
|
||||
def page_unauthorized(error):
|
||||
return render_template_string('404 not found', error_info=error), 404
|
||||
|
||||
|
||||
# 设置模板全局变量
|
||||
@app.context_processor
|
||||
def inject_global_variables():
|
||||
ver = config.APP_VERSION;
|
||||
if mw.isDebugMode():
|
||||
ver = ver + str(time.time())
|
||||
|
||||
data = utils_config.getGlobalVar()
|
||||
g_config = {
|
||||
'version': ver,
|
||||
'title' : 'MW面板',
|
||||
'ip' : '127.0.0.1'
|
||||
}
|
||||
return dict(config=g_config, data=data)
|
||||
|
||||
|
||||
# from flasgger import Swagger
|
||||
# api = Api(app, version='1.0', title='API', description='API 文档')
|
||||
# Swagger(app)
|
||||
|
||||
# @app.route('/colors/<palette>/')
|
||||
# def colors(palette):
|
||||
# """
|
||||
# 根据调色板名称返回颜色列表
|
||||
# ---
|
||||
# parameters:
|
||||
# - name: palette
|
||||
# in: path
|
||||
# type: string
|
||||
# enum: ['all', 'rgb', 'cmyk']
|
||||
# required: true
|
||||
# default: all
|
||||
# definitions:
|
||||
# Palette:
|
||||
# type: object
|
||||
# properties:
|
||||
# palette_name:
|
||||
# type: array
|
||||
# items:
|
||||
# $ref: '#/definitions/Color'
|
||||
# Color:
|
||||
# type: string
|
||||
# responses:
|
||||
# 200:
|
||||
# description: 返回的颜色列表,可按调色板过滤
|
||||
# schema:
|
||||
# $ref: '#/definitions/Palette'
|
||||
# examples:
|
||||
# rgb: ['red', 'green', 'blue']
|
||||
# """
|
||||
# all_colors = {
|
||||
# 'cmyk': ['cyan', 'magenta', 'yellow', 'black'],
|
||||
# 'rgb': ['red', 'green', 'blue']
|
||||
# }
|
||||
# if palette == 'all':
|
||||
# result = all_colorselse
|
||||
# result = {palette: all_colors.get(palette)}
|
||||
# return jsonify(result)
|
||||
|
||||
|
||||
|
||||
|
||||
# Log the startup
|
||||
app.logger.info('########################################################')
|
||||
app.logger.info('Starting %s v%s...', config.APP_NAME, config.APP_VERSION)
|
||||
app.logger.info('########################################################')
|
||||
app.logger.debug("Python syspath: %s", sys.path)
|
||||
|
||||
|
||||
|
||||
# OK
|
||||
socketio.init_app(app, cors_allowed_origins="*")
|
||||
|
||||
# def create_app(app_name = None):
|
||||
#
|
||||
# if not app_name:
|
||||
# app_name = config.APP_NAME
|
||||
|
||||
# # Check if app is created for CLI operations or Web
|
||||
# cli_mode = False
|
||||
# if app_name.endswith('-cli'):
|
||||
# cli_mode = True
|
||||
# return app
|
||||
@@ -0,0 +1,37 @@
|
||||
# coding:utf-8
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# MW-Linux面板
|
||||
# ---------------------------------------------------------------------------------
|
||||
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
|
||||
# ---------------------------------------------------------------------------------
|
||||
# Author: midoks <midoks@163.com>
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
import time
|
||||
|
||||
from admin import model
|
||||
from admin import session
|
||||
|
||||
def isLogined():
|
||||
if 'login' in session and session['login'] == True and 'username' in session:
|
||||
username = session['username']
|
||||
info = model.getUserByName(username)
|
||||
if info is None:
|
||||
return False
|
||||
|
||||
# print(userInfo)
|
||||
if info['name'] != session['username']:
|
||||
return False
|
||||
|
||||
now_time = int(time.time())
|
||||
|
||||
if 'overdue' in session and now_time > session['overdue']:
|
||||
# 自动续期
|
||||
session['overdue'] = int(time.time()) + 7 * 24 * 60 * 60
|
||||
return False
|
||||
|
||||
if 'tmp_login_expire' in session and now_time > int(session['tmp_login_expire']):
|
||||
session.clear()
|
||||
return False
|
||||
return True
|
||||
@@ -0,0 +1,34 @@
|
||||
# coding:utf-8
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# MW-Linux面板
|
||||
# ---------------------------------------------------------------------------------
|
||||
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
|
||||
# ---------------------------------------------------------------------------------
|
||||
# Author: midoks <midoks@163.com>
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
|
||||
from flask import Blueprint, render_template
|
||||
from flask import request
|
||||
|
||||
from admin.user_login_check import panel_login_required
|
||||
from admin.model import Crontab
|
||||
|
||||
blueprint = Blueprint('crontab', __name__, url_prefix='/crontab', template_folder='../../templates/default')
|
||||
@blueprint.route('/index', endpoint='index')
|
||||
def index():
|
||||
return render_template('crontab.html')
|
||||
|
||||
# 插件列表
|
||||
@blueprint.route('/list', endpoint='list', methods=['GET','POST'])
|
||||
@panel_login_required
|
||||
def list():
|
||||
page = request.args.get('p', 1)
|
||||
size = 10
|
||||
count = Crontab.query.count()
|
||||
print(count)
|
||||
clist = Crontab.query.paginate(page=int(page), per_page=size)
|
||||
print(clist)
|
||||
|
||||
return []
|
||||
@@ -0,0 +1,240 @@
|
||||
# coding:utf-8
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# MW-Linux面板
|
||||
# ---------------------------------------------------------------------------------
|
||||
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
|
||||
# ---------------------------------------------------------------------------------
|
||||
# Author: midoks <midoks@163.com>
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
import io
|
||||
import time
|
||||
|
||||
from flask import Blueprint, render_template
|
||||
from flask import make_response
|
||||
from flask import redirect
|
||||
from flask import Response
|
||||
from flask import request,g
|
||||
|
||||
from admin.common import isLogined
|
||||
from admin.user_login_check import panel_login_required
|
||||
from admin import cache,session
|
||||
from admin import model
|
||||
from admin.model import db,TempLogin,Users
|
||||
|
||||
import core.mw as mw
|
||||
|
||||
|
||||
blueprint = Blueprint('dashboard', __name__, url_prefix='/', template_folder='../../templates')
|
||||
@blueprint.route('/')
|
||||
@panel_login_required
|
||||
def index():
|
||||
return render_template('default/index.html')
|
||||
|
||||
# 仅针对webhook插件
|
||||
@blueprint.route("/hook", methods=['POST', 'GET'])
|
||||
def webhook():
|
||||
# 兼容获取关键数据
|
||||
access_key = request.args.get('access_key', '').strip()
|
||||
if access_key == '':
|
||||
access_key = request.form.get('access_key', '').strip()
|
||||
|
||||
params = request.args.get('params', '').strip()
|
||||
if params == '':
|
||||
params = request.form.get('params', '').strip()
|
||||
|
||||
input_args = {
|
||||
'access_key': access_key,
|
||||
'params': params,
|
||||
}
|
||||
|
||||
wh_install_path = mw.getServerDir() + '/webhook'
|
||||
if not os.path.exists(wh_install_path):
|
||||
return mw.returnJson(False, '请先安装WebHook插件!')
|
||||
|
||||
package = mw.getPanelDir() + "/plugins/webhook"
|
||||
if not package in sys.path:
|
||||
sys.path.append(package)
|
||||
|
||||
try:
|
||||
import webhook_index
|
||||
return webhook_index.runShellArgs(input_args)
|
||||
except Exception as e:
|
||||
return str(e)
|
||||
|
||||
# 安全路径
|
||||
@blueprint.route('/<path>',endpoint='admin_safe_path',methods=['GET'])
|
||||
def admin_safe_path(path):
|
||||
db_path = model.getOption('admin_path')
|
||||
if db_path == path:
|
||||
return render_template('default/login.html')
|
||||
|
||||
unauthorized_status = model.getOption('unauthorized_status')
|
||||
if unauthorized_status == '0':
|
||||
return render_template('default/path.html')
|
||||
return Response(status=int(unauthorized_status))
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# 定义登录入口相关方法
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
def getErrorNum(key, limit=None):
|
||||
key = mw.md5(key)
|
||||
num = cache.get(key)
|
||||
if not num:
|
||||
num = 0
|
||||
if not limit:
|
||||
return num
|
||||
if limit > num:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def setErrorNum(key, empty=False, expire=3600):
|
||||
key = mw.md5(key)
|
||||
num = cache.get(key)
|
||||
if not num:
|
||||
num = 0
|
||||
else:
|
||||
if empty:
|
||||
cache.delete(key)
|
||||
return True
|
||||
cache.set(key, num + 1, expire)
|
||||
return True
|
||||
|
||||
def login_temp_user(token):
|
||||
if len(token) != 32:
|
||||
return '错误的参数!'
|
||||
|
||||
skey = mw.getClientIp() + '_temp_login'
|
||||
if not getErrorNum(skey, 10):
|
||||
return '连续10次验证失败,禁止1小时'
|
||||
|
||||
stime = int(time.time())
|
||||
|
||||
tmp_data = model.getTempLoginByToken(token)
|
||||
if not tmp_data:
|
||||
setErrorNum(skey)
|
||||
return '验证失败!'
|
||||
|
||||
if stime > int(tmp_data['expire']):
|
||||
setErrorNum(skey)
|
||||
return "过期"
|
||||
|
||||
user_data = model.getUserById(1)
|
||||
|
||||
login_addr = mw.getClientIp() + ":" + str(request.environ.get('REMOTE_PORT'))
|
||||
mw.writeLog('用户临时登录', "登录成功,帐号:{1},登录IP:{2}",(user_data['name'], login_addr))
|
||||
|
||||
TempLogin.query.filter(TempLogin.id==tmp_data['id']).update({"login_time": stime, 'state': 1, 'login_addr': login_addr})
|
||||
db.session.commit()
|
||||
|
||||
session['login'] = True
|
||||
session['username'] = user_data['name']
|
||||
session['tmp_login'] = True
|
||||
session['tmp_login_id'] = str(tmp_data['id'])
|
||||
session['tmp_login_expire'] = int(tmp_data['expire'])
|
||||
session['uid'] = user_data['id']
|
||||
|
||||
return redirect('/')
|
||||
|
||||
# 登录页: 当设置了安全路径,本页失效。
|
||||
@blueprint.route('/login')
|
||||
def login():
|
||||
|
||||
# 临时登录功能
|
||||
token = request.args.get('tmp_token', '').strip()
|
||||
if token != '':
|
||||
return login_temp_user(token)
|
||||
|
||||
# 注销登录
|
||||
signout = request.args.get('signout', '')
|
||||
if signout == 'True':
|
||||
session.clear()
|
||||
session['login'] = False
|
||||
session['overdue'] = 0
|
||||
|
||||
db_path = model.getOption('admin_path')
|
||||
if db_path == '':
|
||||
return render_template('default/login.html')
|
||||
else:
|
||||
unauthorized_status = model.getOption('unauthorized_status')
|
||||
if unauthorized_status == '0':
|
||||
return render_template('default/path.html')
|
||||
return Response(status=int(unauthorized_status))
|
||||
|
||||
# 验证码
|
||||
@blueprint.route('/code')
|
||||
def code():
|
||||
import utils.vilidate as vilidate
|
||||
vie = vilidate.vieCode()
|
||||
codeImage = vie.GetCodeImage(80, 4)
|
||||
out = io.BytesIO()
|
||||
codeImage[0].save(out, "png")
|
||||
session['code'] = mw.md5(''.join(codeImage[1]).lower())
|
||||
|
||||
img = Response(out.getvalue(), headers={'Content-Type': 'image/png'})
|
||||
return make_response(img)
|
||||
|
||||
# 检查是否登录
|
||||
@blueprint.route('/check_login',methods=['GET','POST'])
|
||||
def check_login():
|
||||
if isLogined():
|
||||
return mw.returnData(True,'已登录')
|
||||
return mw.returnData(False,'未登录')
|
||||
|
||||
# 执行登录操作
|
||||
@blueprint.route('/do_login', endpoint='do_login', methods=['POST'])
|
||||
def do_login():
|
||||
username = request.form.get('username', '').strip()
|
||||
password = request.form.get('password', '').strip()
|
||||
code = request.form.get('code', '').strip()
|
||||
|
||||
login_cache_count = 5
|
||||
login_cache_limit = cache.get('login_cache_limit')
|
||||
|
||||
if 'code' in session:
|
||||
if session['code'] != mw.md5(code):
|
||||
if login_cache_limit == None:
|
||||
login_cache_limit = 1
|
||||
else:
|
||||
login_cache_limit = int(login_cache_limit) + 1
|
||||
|
||||
if login_cache_limit >= login_cache_count:
|
||||
model.setOption('admin_close', 'yes')
|
||||
return mw.returnJson(False, '面板已经关闭!')
|
||||
|
||||
cache.set('login_cache_limit', login_cache_limit, timeout=10000)
|
||||
login_cache_limit = cache.get('login_cache_limit')
|
||||
login_err_msg = mw.getInfo("验证码错误,您还可以尝试[{1}]次!", (str(login_cache_count - login_cache_limit)))
|
||||
mw.writeLog('用户登录', login_err_msg)
|
||||
return mw.returnData(False, login_err_msg)
|
||||
|
||||
info = model.getUserByName(username)
|
||||
password = mw.md5(password)
|
||||
|
||||
if info['name'] != username or info['password'] != password:
|
||||
msg = "<a style='color: red'>密码错误</a>,帐号:{1},密码:{2},登录IP:{3}", (('****', '******', request.remote_addr))
|
||||
|
||||
if login_cache_limit == None:
|
||||
login_cache_limit = 1
|
||||
else:
|
||||
login_cache_limit = int(login_cache_limit) + 1
|
||||
|
||||
if login_cache_limit >= login_cache_count:
|
||||
model.setOption('admin_close', 'yes')
|
||||
return mw.returnData(False, '面板已经关闭!')
|
||||
|
||||
cache.set('login_cache_limit', login_cache_limit, timeout=10000)
|
||||
login_cache_limit = cache.get('login_cache_limit')
|
||||
mw.writeLog('用户登录', mw.getInfo(msg))
|
||||
return mw.returnData(-1, mw.getInfo("用户名或密码错误,您还可以尝试[{1}]次!", (str(login_cache_count - login_cache_limit))))
|
||||
|
||||
|
||||
session['login'] = True
|
||||
session['username'] = info['name']
|
||||
session['overdue'] = int(time.time()) + 7 * 24 * 60 * 60
|
||||
|
||||
return mw.returnJson(1, '登录成功,正在跳转...')
|
||||
@@ -0,0 +1,156 @@
|
||||
# coding:utf-8
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# MW-Linux面板
|
||||
# ---------------------------------------------------------------------------------
|
||||
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
|
||||
# ---------------------------------------------------------------------------------
|
||||
# Author: midoks <midoks@163.com>
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
import os
|
||||
|
||||
from flask import Blueprint, render_template
|
||||
from flask import request
|
||||
|
||||
|
||||
from admin import model
|
||||
from admin.user_login_check import panel_login_required
|
||||
import core.mw as mw
|
||||
import utils.file as file
|
||||
|
||||
blueprint = Blueprint('files', __name__, url_prefix='/files', template_folder='../../templates/default')
|
||||
@blueprint.route('/index', endpoint='index')
|
||||
@panel_login_required
|
||||
def index():
|
||||
return render_template('files.html')
|
||||
|
||||
# 获取文件内容
|
||||
@blueprint.route('/get_body', endpoint='get_file_body', methods=['POST'])
|
||||
@panel_login_required
|
||||
def get_file_body():
|
||||
path = request.form.get('path', '')
|
||||
return file.getFileBody(path)
|
||||
|
||||
# 获取文件内容
|
||||
@blueprint.route('/save_body', endpoint='save_body', methods=['POST'])
|
||||
@panel_login_required
|
||||
def save_body():
|
||||
path = request.form.get('path', '')
|
||||
data = request.form.get('data', '')
|
||||
encoding = request.form.get('encoding', '')
|
||||
if not os.path.exists(path):
|
||||
return mw.returnData(False, '文件不存在')
|
||||
try:
|
||||
if encoding == 'ascii':
|
||||
encoding = 'utf-8'
|
||||
|
||||
data = data.encode(encoding, errors='ignore').decode(encoding)
|
||||
fp = open(path, 'w+', encoding=encoding)
|
||||
fp.write(data)
|
||||
fp.close()
|
||||
|
||||
if path.find("web_conf") > 0:
|
||||
mw.restartWeb()
|
||||
mw.writeLog('文件管理', '文件[{1}]保存成功', (path,))
|
||||
return mw.returnData(True, '文件保存成功')
|
||||
except Exception as ex:
|
||||
return mw.returnData(False, '文件保存错误:' + str(ex))
|
||||
|
||||
# 获取文件内容(最新行数)
|
||||
@blueprint.route('/get_last_body', endpoint='get_file_last_body', methods=['POST'])
|
||||
@panel_login_required
|
||||
def get_file_last_body():
|
||||
path = request.form.get('path', '')
|
||||
line = request.form.get('line', '100')
|
||||
|
||||
if not os.path.exists(path):
|
||||
return mw.returnData(False, '文件不存在', (path,))
|
||||
|
||||
try:
|
||||
data = mw.getLastLine(path, int(line))
|
||||
return mw.returnData(True, 'OK', data)
|
||||
except Exception as ex:
|
||||
return mw.returnData(False, '无法正确读取文件!' + str(ex))
|
||||
|
||||
|
||||
# 获取文件列表
|
||||
@blueprint.route('/get_dir', endpoint='get_dir', methods=['POST'])
|
||||
@panel_login_required
|
||||
def get_dir():
|
||||
path = request.form.get('path', '')
|
||||
if not os.path.exists(path):
|
||||
path = mw.getFatherDir() + '/wwwroot'
|
||||
search = request.args.get('search', '').strip().lower()
|
||||
search_all = request.args.get('all', '').strip().lower()
|
||||
page = request.args.get('p', '1').strip().lower()
|
||||
row = request.args.get('row', '10')
|
||||
order = request.form.get('order', '')
|
||||
|
||||
if search_all == 'yes' and search != '':
|
||||
dir_list = file.getAllDirList(path, int(page), int(row),order, search)
|
||||
else:
|
||||
dir_list = file.getDirList(path, int(page), int(row),order, search)
|
||||
|
||||
dir_list['page'] = mw.getPage({'p':page, 'row': row, 'tojs':'getFiles', 'count': dir_list['count']}, '1,2,3,4,5,6,7,8')
|
||||
return dir_list
|
||||
|
||||
# 获取站点日志目录
|
||||
@blueprint.route('/get_dir_size', endpoint='get_dir_size', methods=['POST'])
|
||||
@panel_login_required
|
||||
def get_dir_size():
|
||||
path = request.form.get('path', '')
|
||||
size = file.getDirSize(path)
|
||||
return mw.returnData(True, mw.toSize(size))
|
||||
|
||||
|
||||
# 删除文件
|
||||
@blueprint.route('/delete', endpoint='delete', methods=['POST'])
|
||||
@panel_login_required
|
||||
def delete():
|
||||
path = request.form.get('path', '')
|
||||
return file.fileDelete(path)
|
||||
|
||||
|
||||
# 删除文件
|
||||
@blueprint.route('/delete_dir', endpoint='delete_dir', methods=['POST'])
|
||||
@panel_login_required
|
||||
def delete_dir():
|
||||
path = request.form.get('path', '')
|
||||
return file.dirDelete(path)
|
||||
|
||||
|
||||
# 回收站文件
|
||||
@blueprint.route('/get_recycle_bin', endpoint='get_recycle_bin', methods=['POST'])
|
||||
@panel_login_required
|
||||
def get_recycle_bin():
|
||||
return file.getRecycleBin()
|
||||
|
||||
# 回收站文件恢复
|
||||
@blueprint.route('/re_recycle_bin', endpoint='re_recycle_bin', methods=['POST'])
|
||||
@panel_login_required
|
||||
def re_recycle_bin():
|
||||
path = request.form.get('path', '')
|
||||
return file.reRecycleBin(path)
|
||||
|
||||
# 回收站文件
|
||||
@blueprint.route('/recycle_bin', endpoint='recycle_bin', methods=['POST'])
|
||||
@panel_login_required
|
||||
def recycle_bin():
|
||||
return file.toggleRecycleBin()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user