update
This commit is contained in:
parent
1826adf50e
commit
d4cfd90ccd
|
|
@ -40,8 +40,7 @@ class crontab_api:
|
|||
startPage = (int(p) - 1) * psize
|
||||
pageInfo = str(startPage) + ',' + str(psize)
|
||||
|
||||
_list = mw.M('crontab').where('', ()).field(
|
||||
self.field).limit(pageInfo).order('id desc').select()
|
||||
_list = mw.M('crontab').where('', ()).field(self.field).limit(pageInfo).order('id desc').select()
|
||||
|
||||
data = []
|
||||
for i in range(len(_list)):
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
30
|
||||
|
|
@ -1 +0,0 @@
|
|||
88rr2g7e
|
||||
|
|
@ -1 +0,0 @@
|
|||
True
|
||||
|
|
@ -33,8 +33,9 @@ CREATE TABLE IF NOT EXISTS `crontab` (
|
|||
`sname` TEXT,
|
||||
`sbody` TEXT,
|
||||
'stype' TEXT,
|
||||
`urladdress` TEXT
|
||||
`add_time` TEXT
|
||||
`url_address` TEXT,
|
||||
`add_time` TEXT,
|
||||
`update_time` TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `firewall` (
|
||||
|
|
@ -60,7 +61,6 @@ CREATE TABLE IF NOT EXISTS `logs` (
|
|||
`uid` INTEGER DEFAULT '1',
|
||||
`add_time` TEXT
|
||||
);
|
||||
ALTER TABLE `logs` ADD COLUMN `uid` INTEGER DEFAULT '1';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `sites` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
|
|
@ -73,12 +73,10 @@ CREATE TABLE IF NOT EXISTS `sites` (
|
|||
`edate` TEXT,
|
||||
`ssl_effective_date` TEXT,
|
||||
`ssl_expiration_date` TEXT,
|
||||
`add_time` TEXT
|
||||
`add_time` TEXT,
|
||||
`update_time` TEXT
|
||||
);
|
||||
|
||||
ALTER TABLE `sites` ADD COLUMN `ssl_effective_date` TEXT DEFAULT '';
|
||||
ALTER TABLE `sites` ADD COLUMN `ssl_expiration_date` TEXT DEFAULT '';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `site_types` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`name` TEXT
|
||||
|
|
@ -94,18 +92,16 @@ CREATE TABLE IF NOT EXISTS `domain` (
|
|||
|
||||
CREATE TABLE IF NOT EXISTS `users` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`username` TEXT,
|
||||
`name` TEXT,
|
||||
`password` TEXT,
|
||||
`login_ip` TEXT,
|
||||
`login_time` TEXT,
|
||||
`phone` TEXT,
|
||||
`email` TEXT
|
||||
`email` TEXT,
|
||||
`add_time` INTEGER,
|
||||
`update_time` INTEGER
|
||||
);
|
||||
|
||||
INSERT INTO `users` (`id`, `username`, `password`, `login_ip`, `login_time`, `phone`, `email`) VALUES
|
||||
(1, 'admin', '21232f297a57a5a743894a0e4a801fc3', '192.168.0.10', '2022-02-02 00:00:00', 0, 'midoks@163.com');
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `tasks` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`name` TEXT,
|
||||
|
|
@ -145,3 +141,5 @@ CREATE TABLE IF NOT EXISTS `option` (
|
|||
`type` TEXT,
|
||||
`value` TEXT
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX name_idx ON option(name);
|
||||
|
|
|
|||
|
|
@ -64,7 +64,6 @@ mw_start_debug(){
|
|||
}
|
||||
|
||||
mw_start_panel(){
|
||||
python3 panel_task.py >> $DIR/logs/panel_task.log 2>&1 &
|
||||
cd ${DIR}/web && gunicorn -b :7200 -w 1 app:app
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,26 +41,12 @@ def execShell(cmdstring, cwd=None, timeout=None, shell=True):
|
|||
cmd = cmdstring + ' > ' + g_log_file + ' 2>&1'
|
||||
return mw.execShell(cmd)
|
||||
|
||||
def service_cmd(method):
|
||||
cmd = '/etc/init.d/mw'
|
||||
if os.path.exists(cmd):
|
||||
execShell(cmd + ' ' + method)
|
||||
return
|
||||
|
||||
cmd = mw.getPanelDir() + '/scripts/init.d/mw'
|
||||
if os.path.exists(cmd):
|
||||
print(cmd + ' ' + method)
|
||||
data = execShell(cmd + ' ' + method)
|
||||
print(data)
|
||||
return
|
||||
|
||||
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)
|
||||
|
|
@ -68,7 +54,6 @@ def restartMw():
|
|||
mw.execShell(cmd)
|
||||
|
||||
|
||||
|
||||
def downloadFile(url, filename):
|
||||
# 下载文件
|
||||
try:
|
||||
|
|
@ -115,23 +100,23 @@ def writeLogs(data):
|
|||
|
||||
def runPanelTask():
|
||||
try:
|
||||
bash_list = model.getTaskList(status=-1)
|
||||
bash_list = thisdb.getTaskList(status=-1)
|
||||
for task in bash_list:
|
||||
model.setTaskStatus(task['id'], 0)
|
||||
thisdb.setTaskStatus(task['id'], 0)
|
||||
|
||||
run_list = model.getTaskList(status=0)
|
||||
run_list = thisdb.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)
|
||||
thisdb.setTaskData(run_task['id'], start=start)
|
||||
thisdb.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)
|
||||
thisdb.setTaskData(run_task['id'], end=end)
|
||||
thisdb.setTaskStatus(run_task['id'], 1)
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
|
||||
|
|
@ -371,6 +356,5 @@ def run():
|
|||
startPanelTask()
|
||||
|
||||
if __name__ == "__main__":
|
||||
with app.app_context():
|
||||
run()
|
||||
run()
|
||||
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ def mwcli(mw_input=0):
|
|||
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显示成功!")
|
||||
mw.echoInfo("执行PHP52显示成功!")
|
||||
elif mw_input == 101:
|
||||
php_conf = 'plugins/php/info.json'
|
||||
if os.path.exists(php_conf):
|
||||
|
|
@ -198,7 +198,7 @@ def mwcli(mw_input=0):
|
|||
cont = re.sub("\"52\",", "", cont)
|
||||
cont = re.sub("\"5.2.17\",", cont)
|
||||
mw.writeFile(php_conf, cont)
|
||||
print("|-执行PHP52隐藏成功!")
|
||||
mw.echoInfo("执行PHP52隐藏成功!")
|
||||
elif mw_input == 200:
|
||||
os.system(INIT_CMD + " mirror")
|
||||
elif mw_input == 201:
|
||||
|
|
|
|||
|
|
@ -31,8 +31,9 @@ from flask_migrate import Migrate
|
|||
from flask_caching import Cache
|
||||
from werkzeug.local import LocalProxy
|
||||
|
||||
from admin import model
|
||||
# from admin import model
|
||||
from admin import setup
|
||||
import thisdb
|
||||
|
||||
from admin.model import db as sys_db
|
||||
|
||||
|
|
@ -68,12 +69,13 @@ 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_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)
|
||||
# sys_db.init_app(app)
|
||||
# Migrate(app, sys_db)
|
||||
|
||||
|
||||
# 检查数据库是否存在。如果没有就创建它。
|
||||
|
|
@ -84,15 +86,15 @@ if not os.path.isfile(config.SQLITE_PATH):
|
|||
# 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:
|
||||
# sys_db.create_all()
|
||||
|
||||
# 初始化用户信息
|
||||
with app.app_context():
|
||||
if setup_db_required:
|
||||
setup.init_admin_user()
|
||||
setup.init_option()
|
||||
if setup_db_required:
|
||||
# 初始化用户信息
|
||||
thisdb.initPanelData()
|
||||
setup.init_admin_user()
|
||||
setup.init_option()
|
||||
setup.init_cmd()
|
||||
setup.init_db_system()
|
||||
|
||||
|
|
|
|||
|
|
@ -10,13 +10,14 @@
|
|||
|
||||
import time
|
||||
|
||||
from admin import model
|
||||
# from admin import model
|
||||
from admin import session
|
||||
import thisdb
|
||||
|
||||
def isLogined():
|
||||
if 'login' in session and session['login'] == True and 'username' in session:
|
||||
username = session['username']
|
||||
info = model.getUserByName(username)
|
||||
info = thisdb.getUserByName(username)
|
||||
if info is None:
|
||||
return False
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,10 @@ from flask import Blueprint, render_template
|
|||
from flask import request
|
||||
|
||||
from admin.user_login_check import panel_login_required
|
||||
from admin.model import Crontab
|
||||
|
||||
from utils.crontab import crontab as MwCrontab
|
||||
import core.mw as mw
|
||||
import thisdb
|
||||
|
||||
blueprint = Blueprint('crontab', __name__, url_prefix='/crontab', template_folder='../../templates/default')
|
||||
@blueprint.route('/index', endpoint='index')
|
||||
|
|
@ -24,26 +27,51 @@ def index():
|
|||
@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)
|
||||
page = request.args.get('p', '1').strip()
|
||||
limit = request.args.get('limit', '10').strip()
|
||||
return MwCrontab.instance().getCrontabList(page=int(page),size=int(limit))
|
||||
|
||||
return []
|
||||
# 插件列表
|
||||
@blueprint.route('/logs', endpoint='logs', methods=['GET','POST'])
|
||||
def logs(self):
|
||||
sid = request.form.get('id', '')
|
||||
echo = mw.M('crontab').where("id=?", (sid,)).field('echo').find()
|
||||
logFile = mw.getServerDir() + '/cron/' + echo['echo'] + '.log'
|
||||
if not os.path.exists(logFile):
|
||||
return mw.returnData(False, '当前日志为空!')
|
||||
log = mw.getLastLine(logFile, 500)
|
||||
return mw.returnData(True, log)
|
||||
|
||||
# 获取计划任务
|
||||
@blueprint.route('/del', endpoint='del', methods=['GET','POST'])
|
||||
def crontab_del():
|
||||
task_id = request.form.get('id', '')
|
||||
return MwCrontab.instance().delete(task_id)
|
||||
|
||||
# 获取计划任务
|
||||
@blueprint.route('/get_crond_find', endpoint='get_crond_find', methods=['GET','POST'])
|
||||
def get_crond_find():
|
||||
sid = request.form.get('id', '')
|
||||
data = MwCrontab.instance().getCrondFind(sid)
|
||||
return data
|
||||
|
||||
# 添加计划任务
|
||||
@blueprint.route('/add', endpoint='add', methods=['GET','POST'])
|
||||
@panel_login_required
|
||||
def add():
|
||||
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 []
|
||||
request_data = {}
|
||||
request_data['name'] = request.form.get('name', '')
|
||||
request_data['type'] = request.form.get('type', '')
|
||||
request_data['week'] = request.form.get('week', '')
|
||||
request_data['where1'] = request.form.get('where1', '')
|
||||
request_data['hour'] = request.form.get('hour', '')
|
||||
request_data['minute'] = request.form.get('minute', '')
|
||||
request_data['save'] = request.form.get('save', '')
|
||||
request_data['backup_to'] = request.form.get('backupTo', '')
|
||||
request_data['stype'] = request.form.get('sType', '')
|
||||
request_data['sname'] = request.form.get('sName', '')
|
||||
request_data['sbody'] = request.form.get('sBody', '')
|
||||
request_data['url_address'] = request.form.get('urladdress', '')
|
||||
return MwCrontab.instance().add(request_data)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -8,236 +8,6 @@
|
|||
# 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')
|
||||
|
||||
# 安全路径
|
||||
@blueprint.route('/<path>',endpoint='admin_safe_path',methods=['GET'])
|
||||
def admin_safe_path(path):
|
||||
db_path = model.getOption('admin_path')
|
||||
|
||||
if isLogined():
|
||||
return redirect('/')
|
||||
|
||||
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))
|
||||
|
||||
# 仅针对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.returnData(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)
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# 定义登录入口相关方法
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
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, '登录成功,正在跳转...')
|
||||
from .dashboard import *
|
||||
from .login import *
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
# 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
|
||||
import thisdb
|
||||
|
||||
|
||||
blueprint = Blueprint('dashboard', __name__, url_prefix='/', template_folder='../../templates')
|
||||
@blueprint.route('/')
|
||||
@panel_login_required
|
||||
def index():
|
||||
return render_template('default/index.html')
|
||||
|
||||
# 安全路径
|
||||
@blueprint.route('/<path>',endpoint='admin_safe_path',methods=['GET'])
|
||||
def admin_safe_path(path):
|
||||
db_path = thisdb.getOption('admin_path')
|
||||
if isLogined():
|
||||
return redirect('/')
|
||||
|
||||
print(db_path,path)
|
||||
if db_path == path:
|
||||
return render_template('default/login.html')
|
||||
|
||||
unauthorized_status = thisdb.getOption('unauthorized_status')
|
||||
if unauthorized_status == '0':
|
||||
return render_template('default/path.html')
|
||||
return Response(status=int(unauthorized_status))
|
||||
|
||||
# 仅针对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.returnData(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)
|
||||
|
|
@ -0,0 +1,189 @@
|
|||
# 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
|
||||
import thisdb
|
||||
|
||||
from .dashboard import blueprint
|
||||
|
||||
|
||||
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 = thisdb.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 = thisdb.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, '登录成功,正在跳转...')
|
||||
|
|
@ -14,11 +14,9 @@ from flask import request
|
|||
|
||||
from admin.user_login_check import panel_login_required
|
||||
|
||||
from admin import model
|
||||
from admin.model import db, Logs
|
||||
|
||||
import core.mw as mw
|
||||
import utils.adult_log as adult_log
|
||||
import thisdb
|
||||
|
||||
# 日志页面
|
||||
blueprint = Blueprint('logs', __name__, url_prefix='/logs', template_folder='../../templates')
|
||||
|
|
@ -36,33 +34,18 @@ def get_log_list():
|
|||
size = request.form.get('limit', '10').strip()
|
||||
search = request.form.get('search', '').strip()
|
||||
|
||||
count = Logs.query.filter_by().count()
|
||||
if search != '':
|
||||
pagination = Logs.query.filter_by(Logs.type.like(search) or Logs.log.like(search)).paginate(page=int(p), per_page=int(size))
|
||||
else:
|
||||
pagination = Logs.query.filter_by().order_by(Logs.id.desc()).paginate(page=int(p), per_page=int(size))
|
||||
|
||||
rows = []
|
||||
for item in pagination.items:
|
||||
t = {}
|
||||
t['id'] = item.id
|
||||
t['type'] = item.type
|
||||
t['log'] = item.log
|
||||
t['uid'] = item.uid
|
||||
t['add_time'] = item.add_time
|
||||
rows.append(t)
|
||||
info = thisdb.getLogsList(page=int(p),size=int(size), search=search)
|
||||
|
||||
data = {}
|
||||
data['data'] = rows
|
||||
data['page'] = mw.getPage({'count':count,'tojs':'getLogs','p':p})
|
||||
data['data'] = info['list']
|
||||
data['page'] = mw.getPage({'count':info['count'],'tojs':'getLogs','p':p,'row':size})
|
||||
return data
|
||||
|
||||
# 日志清空
|
||||
@blueprint.route('/del_panel_logs', endpoint='del_panel_logs', methods=['POST'])
|
||||
@panel_login_required
|
||||
def del_panel_logs():
|
||||
model.clearLog()
|
||||
# mw.M('logs').dbPos(mw.getPanelDataDir(),'panel').where('id>?', (0,)).delete()
|
||||
thisdb.clearLog()
|
||||
mw.writeLog('面板设置', '面板操作日志已清空!')
|
||||
return mw.returnData(True, '面板操作日志已清空!')
|
||||
|
||||
|
|
|
|||
|
|
@ -16,10 +16,12 @@ 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 thisdb
|
||||
import utils.config as utils_config
|
||||
|
||||
|
||||
|
|
@ -41,9 +43,9 @@ def get_panel_list():
|
|||
@panel_login_required
|
||||
def set_webname():
|
||||
webname = request.form.get('webname', '')
|
||||
src_webname = model.getOption('title')
|
||||
src_webname = thisdb.getOption('title')
|
||||
if webname != src_webname:
|
||||
model.setOption('title', webname)
|
||||
thisdb.setOption('title', webname)
|
||||
return mw.returnData(True, '面板别名保存成功!')
|
||||
|
||||
# 设置服务器IP
|
||||
|
|
@ -51,9 +53,9 @@ def set_webname():
|
|||
@panel_login_required
|
||||
def set_ip():
|
||||
host_ip = request.form.get('host_ip', '')
|
||||
src_host_ip = model.getOption('server_ip')
|
||||
src_host_ip = thisdb.getOption('server_ip')
|
||||
if host_ip != src_host_ip:
|
||||
model.setOption('server_ip', host_ip)
|
||||
thisdb.setOption('server_ip', host_ip)
|
||||
return mw.returnData(True, 'IP保存成功!')
|
||||
|
||||
# 默认备份目录
|
||||
|
|
@ -61,9 +63,9 @@ def set_ip():
|
|||
@panel_login_required
|
||||
def set_backup_dir():
|
||||
backup_path = request.form.get('backup_path', '')
|
||||
src_backup_path = model.getOption('backup_path')
|
||||
src_backup_path = thisdb.getOption('backup_path')
|
||||
if backup_path != src_backup_path:
|
||||
model.setOption('backup_path', backup_path)
|
||||
thisdb.setOption('backup_path', backup_path)
|
||||
return mw.returnData(True, '修改默认备份目录成功!')
|
||||
|
||||
# 默认站点目录
|
||||
|
|
@ -71,9 +73,9 @@ def set_backup_dir():
|
|||
@panel_login_required
|
||||
def set_www_dir():
|
||||
sites_path = request.form.get('sites_path', '')
|
||||
src_sites_path = model.getOption('sites_path')
|
||||
src_sites_path = thisdb.getOption('sites_path')
|
||||
if sites_path != src_sites_path:
|
||||
model.setOption('sites_path', sites_path)
|
||||
thisdb.setOption('sites_path', sites_path)
|
||||
return mw.returnData(True, '修改默认建站目录成功!')
|
||||
|
||||
|
||||
|
|
@ -102,9 +104,9 @@ def set_admin_path():
|
|||
if not re.match(r"^/[\w]+$", admin_path):
|
||||
return mw.returnData(False, '入口地址格式不正确,示例: /mw_rand')
|
||||
|
||||
src_admin_path = model.getOption('admin_path')
|
||||
src_admin_path = thisdb.getOption('admin_path')
|
||||
if admin_path != src_admin_path:
|
||||
model.setOption('admin_path', admin_path[1:])
|
||||
thisdb.setOption('admin_path', admin_path[1:])
|
||||
return mw.returnData(True, '修改成功!')
|
||||
|
||||
|
||||
|
|
@ -125,7 +127,7 @@ def set_basic_auth():
|
|||
is_open = False
|
||||
|
||||
if basic_open == 'false':
|
||||
model.setOption('basic_auth', json.dumps({'open':False}))
|
||||
thisdb.setOption('basic_auth', json.dumps({'open':False}))
|
||||
mw.writeLog('面板设置', '设置BasicAuth状态为: %s' % is_open)
|
||||
return mw.returnData(True, '删除BasicAuth成功!')
|
||||
|
||||
|
|
@ -139,7 +141,7 @@ def set_basic_auth():
|
|||
data['basic_pwd'] = mw.md5(basic_pwd + salt)
|
||||
data['open'] = is_open
|
||||
|
||||
model.setOption('basic_auth', json.dumps(data))
|
||||
thisdb.setOption('basic_auth', json.dumps(data))
|
||||
mw.writeLog('面板设置', '设置BasicAuth状态为: %s' % is_open)
|
||||
return mw.returnData(True, '设置成功!')
|
||||
|
||||
|
|
@ -158,7 +160,7 @@ def set_status_code():
|
|||
return mw.returnData(False, '状态码范围错误!')
|
||||
|
||||
info = utils_config.getUnauthStatus(code=str(status_code))
|
||||
model.setOption('unauthorized_status', str(status_code))
|
||||
thisdb.setOption('unauthorized_status', str(status_code))
|
||||
mw.writeLog('面板设置', '将未授权响应状态码设置为:{0}:{1}'.format(status_code,info['text']))
|
||||
return mw.returnData(True, '设置成功!')
|
||||
|
||||
|
|
@ -166,11 +168,11 @@ def set_status_code():
|
|||
@blueprint.route('/open_debug', endpoint='open_debug', methods=['POST'])
|
||||
@panel_login_required
|
||||
def open_debug():
|
||||
debug = model.getOption('debug',default='close')
|
||||
debug = thisdb.getOption('debug',default='close')
|
||||
if debug == 'open':
|
||||
model.setOption('debug','close')
|
||||
thisdb.setOption('debug','close')
|
||||
return mw.returnData(True, '开发模式关闭!')
|
||||
model.setOption('debug','open')
|
||||
thisdb.setOption('debug','open')
|
||||
return mw.returnData(True, '开发模式开启!')
|
||||
|
||||
|
||||
|
|
@ -178,11 +180,11 @@ def open_debug():
|
|||
@blueprint.route('/close_panel', endpoint='close_panel', methods=['POST'])
|
||||
@panel_login_required
|
||||
def close_panel():
|
||||
admin_close = model.getOption('admin_close',default='no')
|
||||
admin_close = thisdb.getOption('admin_close',default='no')
|
||||
if admin_close == 'no':
|
||||
model.setOption('admin_close','yes')
|
||||
thisdb.setOption('admin_close','yes')
|
||||
return mw.returnData(True, '开启面板成功!')
|
||||
model.setOption('admin_close','no')
|
||||
thisdb.setOption('admin_close','no')
|
||||
return mw.returnData(True, '关闭面板成功!')
|
||||
|
||||
# 设置IPV6状态
|
||||
|
|
|
|||
|
|
@ -12,50 +12,47 @@ import json
|
|||
|
||||
from flask import request
|
||||
|
||||
from admin import model
|
||||
from admin.model import db, Users
|
||||
|
||||
import core.mw as mw
|
||||
import thisdb
|
||||
|
||||
def init_option():
|
||||
model.setOption('title', '后羿面板')
|
||||
model.setOption('recycle_bin', 'open')
|
||||
model.setOption('template', 'default')
|
||||
thisdb.setOption('title', '后羿面板')
|
||||
thisdb.setOption('recycle_bin', 'open')
|
||||
thisdb.setOption('template', 'default')
|
||||
|
||||
# 后台面板是否关闭
|
||||
model.setOption('admin_close', 'no')
|
||||
thisdb.setOption('admin_close', 'no')
|
||||
|
||||
# 未认证状态码
|
||||
model.setOption('unauthorized_status', '0')
|
||||
thisdb.setOption('unauthorized_status', '0')
|
||||
|
||||
# 调式模式,默认关闭
|
||||
model.setOption('debug', 'close')
|
||||
thisdb.setOption('debug', 'close')
|
||||
|
||||
# basic auth 配置
|
||||
model.setOption('basic_auth', json.dumps({'open':False}))
|
||||
thisdb.setOption('basic_auth', json.dumps({'open':False}))
|
||||
|
||||
# 开启后台任务
|
||||
# model.setOption('run_bg_task', 'close')
|
||||
|
||||
# 首页展示初始化
|
||||
model.setOption('display_index', '[]')
|
||||
thisdb.setOption('display_index', '[]')
|
||||
|
||||
# 监控默认配置
|
||||
model.setOption('monitor_status', 'open', type='monitor')
|
||||
model.setOption('monitor_day', '30', type='monitor')
|
||||
model.setOption('monitor_only_netio', 'open', type='monitor')
|
||||
thisdb.setOption('monitor_status', 'open', type='monitor')
|
||||
thisdb.setOption('monitor_day', '30', type='monitor')
|
||||
thisdb.setOption('monitor_only_netio', 'open', type='monitor')
|
||||
|
||||
# 初始化安全路径
|
||||
model.setOption('admin_path', mw.getRandomString(8))
|
||||
thisdb.setOption('admin_path', mw.getRandomString(8))
|
||||
|
||||
|
||||
ip = mw.getLocalIp()
|
||||
model.setOption('server_ip', ip)
|
||||
thisdb.setOption('server_ip', ip)
|
||||
|
||||
# 默认备份目录
|
||||
model.setOption('backup_path', mw.getFatherDir()+'/backup')
|
||||
thisdb.setOption('backup_path', mw.getFatherDir()+'/backup')
|
||||
# 默认站点目录
|
||||
model.setOption('site_path', mw.getFatherDir()+'/wwwroot')
|
||||
thisdb.setOption('site_path', mw.getFatherDir()+'/wwwroot')
|
||||
|
||||
|
||||
return True
|
||||
|
|
@ -14,28 +14,10 @@ from admin import model
|
|||
from admin.model import db, Users
|
||||
|
||||
import core.mw as mw
|
||||
import thisdb
|
||||
|
||||
# 初始化用户信息
|
||||
def init_admin_user():
|
||||
data = Users.query.filter_by(id=1).first()
|
||||
if not data:
|
||||
name = mw.getRandomString(8).lower()
|
||||
password = mw.getRandomString(8).lower()
|
||||
file_pass_pl = mw.getPanelDataDir() + '/default.pl'
|
||||
mw.writeFile(file_pass_pl, password)
|
||||
insert_time = mw.formatDate()
|
||||
login_ip = '127.0.0.1'
|
||||
add_user = Users(
|
||||
name=name,
|
||||
password=mw.md5(password),
|
||||
login_ip=login_ip,
|
||||
login_time=insert_time,
|
||||
phone='',
|
||||
email='',
|
||||
add_time=insert_time,
|
||||
update_time=insert_time)
|
||||
db.session.add(add_user)
|
||||
db.session.commit()
|
||||
db.session.close()
|
||||
thisdb.initAdminUser()
|
||||
return True
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ from admin.user_login_check import panel_login_required
|
|||
from utils.plugin import plugin as MwPlugin
|
||||
import utils.site as site
|
||||
import core.mw as mw
|
||||
import thisdb
|
||||
|
||||
blueprint = Blueprint('site', __name__, url_prefix='/site', template_folder='../../templates/default')
|
||||
@blueprint.route('/index', endpoint='index')
|
||||
|
|
@ -34,28 +35,11 @@ def list():
|
|||
type_id = request.form.get('type_id', '0').strip()
|
||||
search = request.form.get('search', '').strip()
|
||||
|
||||
count = Sites.query.count()
|
||||
pagination = Sites.query.paginate(page=int(p), per_page=int(limit))
|
||||
|
||||
site_list = []
|
||||
for item in pagination.items:
|
||||
t = {}
|
||||
t['id'] = item.id
|
||||
t['name'] = item.name
|
||||
t['path'] = item.path
|
||||
t['index'] = item.index
|
||||
t['ps'] = item.ps
|
||||
t['edate'] = item.edate
|
||||
t['type_id'] = item.type_id
|
||||
t['status'] = item.status
|
||||
t['add_time'] = item.add_time
|
||||
t['update_time'] = item.update_time
|
||||
site_list.append(t)
|
||||
info = thisdb.getSitesList(page=int(p),size=int(limit),type_id=int(type_id), search=search)
|
||||
|
||||
data = {}
|
||||
data['data'] = site_list
|
||||
data['page'] = mw.getPage({'count':count,'tojs':'getWeb','p':p, 'row':limit})
|
||||
|
||||
data['data'] = info['list']
|
||||
data['page'] = mw.getPage({'count':info['count'],'tojs':'getWeb','p':p, 'row':limit})
|
||||
return data
|
||||
|
||||
@blueprint.route('/get_site_types', endpoint='get_site_types',methods=['POST'])
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@ from flask import request
|
|||
from admin.user_login_check import panel_login_required
|
||||
from utils.system import monitor
|
||||
|
||||
import admin.model.option as option
|
||||
import core.mw as mw
|
||||
import utils.system as sys
|
||||
import thisdb
|
||||
|
||||
|
||||
|
||||
|
|
@ -112,19 +112,19 @@ def set_control():
|
|||
day = request.form.get('day', '')
|
||||
|
||||
if stype == '0':
|
||||
option.setOption('monitor_status', 'close', type='monitor')
|
||||
thisdb.setOption('monitor_status', 'close', type='monitor')
|
||||
return mw.returnData(True, "设置成功!")
|
||||
elif stype == '1':
|
||||
_day = int(day)
|
||||
if _day < 1:
|
||||
return mw.returnData(False, "设置失败!")
|
||||
option.setOption('monitor_day', day, type='monitor')
|
||||
thisdb.setOption('monitor_day', day, type='monitor')
|
||||
return mw.returnData(True, "设置成功!")
|
||||
elif stype == '2':
|
||||
option.setOption('monitor_only_netio', 'close', type='monitor')
|
||||
thisdb.setOption('monitor_only_netio', 'close', type='monitor')
|
||||
return mw.returnData(True, "设置成功!")
|
||||
elif stype == '3':
|
||||
option.setOption('monitor_only_netio', 'open', type='monitor')
|
||||
thisdb.setOption('monitor_only_netio', 'open', type='monitor')
|
||||
return mw.returnData(True, "设置成功!")
|
||||
elif stype == 'del':
|
||||
if not mw.isRestart():
|
||||
|
|
@ -132,9 +132,9 @@ def set_control():
|
|||
monitor.instance().clearDbFile()
|
||||
return mw.returnData(True, "清空监控记录成功!")
|
||||
else:
|
||||
monitor_status = option.getOption('monitor_status', default='open', type='monitor')
|
||||
monitor_day = option.getOption('monitor_day', default='30', type='monitor')
|
||||
monitor_only_netio = option.getOption('monitor_only_netio', default='open', type='monitor')
|
||||
monitor_status = thisdb.getOption('monitor_status', default='open', type='monitor')
|
||||
monitor_day = thisdb.getOption('monitor_day', default='30', type='monitor')
|
||||
monitor_only_netio = thisdb.getOption('monitor_only_netio', default='open', type='monitor')
|
||||
data = {}
|
||||
data['day'] = monitor_day
|
||||
if monitor_status == 'open':
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ from admin.user_login_check import panel_login_required
|
|||
|
||||
import core.mw as mw
|
||||
import utils.task as MwTasks
|
||||
import thisdb
|
||||
|
||||
blueprint = Blueprint('task', __name__, url_prefix='/task', template_folder='../../templates/default')
|
||||
|
||||
|
|
@ -25,7 +26,7 @@ blueprint = Blueprint('task', __name__, url_prefix='/task', template_folder='../
|
|||
@blueprint.route('/count', endpoint='task_count')
|
||||
@panel_login_required
|
||||
def task_count():
|
||||
return str(model.getTaskUnexecutedCount())
|
||||
return str(thisdb.getTaskUnexecutedCount())
|
||||
|
||||
|
||||
@blueprint.route('/list', endpoint='list', methods=['POST'])
|
||||
|
|
|
|||
|
|
@ -14,17 +14,17 @@ from flask import Response
|
|||
|
||||
from functools import wraps
|
||||
|
||||
from admin import model
|
||||
from admin import session
|
||||
from admin.common import isLogined
|
||||
|
||||
import thisdb
|
||||
|
||||
def panel_login_required(func):
|
||||
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
if not isLogined():
|
||||
unauthorized_status = model.getOption('unauthorized_status')
|
||||
unauthorized_status = thisdb.getOption('unauthorized_status')
|
||||
if unauthorized_status == '0':
|
||||
return render_template('default/path.html')
|
||||
return Response(status=int(unauthorized_status))
|
||||
|
|
|
|||
|
|
@ -120,6 +120,21 @@ class Sql():
|
|||
self.__OPT_FIELD = field
|
||||
return self
|
||||
|
||||
def getDbField(self,name):
|
||||
sql = "PRAGMA table_info(%s)" % name
|
||||
result = self.__DB_CONN.execute(sql)
|
||||
data = result.fetchall()
|
||||
|
||||
fields = []
|
||||
for i in data:
|
||||
fields.append(i[1])
|
||||
return fields
|
||||
|
||||
def getDbFieldString(self,name):
|
||||
fields = self.getDbField(name)
|
||||
return ','.join(fields)
|
||||
|
||||
|
||||
def select(self):
|
||||
# 查询数据集
|
||||
self.__getConn()
|
||||
|
|
@ -130,25 +145,40 @@ class Sql():
|
|||
# print(self.__OPT_PARAM)
|
||||
result = self.__DB_CONN.execute(sql, self.__OPT_PARAM)
|
||||
data = result.fetchall()
|
||||
if len(data) == 0:
|
||||
return data
|
||||
|
||||
# 构造字曲系列
|
||||
if self.__OPT_FIELD != "*":
|
||||
field = self.__OPT_FIELD.split(',')
|
||||
tmp = []
|
||||
for row in data:
|
||||
i = 0
|
||||
tmp1 = {}
|
||||
t = {}
|
||||
for key in field:
|
||||
tmp1[key] = row[i]
|
||||
t[key] = row[i]
|
||||
i += 1
|
||||
tmp.append(tmp1)
|
||||
del(tmp1)
|
||||
tmp.append(t)
|
||||
del(t)
|
||||
data = tmp
|
||||
del(tmp)
|
||||
else:
|
||||
# 将元组转换成列表
|
||||
tmp = map(list, data)
|
||||
field = self.getDbField(self.__DB_TABLE)
|
||||
tmp = []
|
||||
for row in data:
|
||||
i = 0
|
||||
t = {}
|
||||
for key in field:
|
||||
t[key] = row[i]
|
||||
i += 1
|
||||
tmp.append(t)
|
||||
del(t)
|
||||
data = tmp
|
||||
del(tmp)
|
||||
# 将元组转换成列表
|
||||
# tmp = map(list, data)
|
||||
# data = tmp
|
||||
# del(tmp)
|
||||
self.__close()
|
||||
return data
|
||||
except Exception as ex:
|
||||
|
|
@ -162,7 +192,8 @@ class Sql():
|
|||
sql = "SELECT " + self.__OPT_FIELD + " FROM " + self.__DB_TABLE + \
|
||||
self.__OPT_WHERE + self.__OPT_GROUP + self.__OPT_ORDER + self.__OPT_LIMIT
|
||||
|
||||
if os.path.exists('data/debug.pl'):
|
||||
debug = getPanelDir()+'/data/debug.pl'
|
||||
if os.path.exists(debug):
|
||||
print(sql, self.__OPT_PARAM)
|
||||
result = self.__DB_CONN.execute(sql, self.__OPT_PARAM)
|
||||
data = result.fetchall()
|
||||
|
|
@ -199,7 +230,7 @@ class Sql():
|
|||
result = self.field(keyName).select()
|
||||
if len(result) == 1:
|
||||
return result[0][keyName]
|
||||
return result
|
||||
return None
|
||||
|
||||
def setField(self, keyName, keyValue):
|
||||
# 更新指定字段
|
||||
|
|
@ -210,7 +241,7 @@ class Sql():
|
|||
result = self.limit("1").select()
|
||||
if len(result) == 1:
|
||||
return result[0]
|
||||
return result
|
||||
return None
|
||||
|
||||
def count(self):
|
||||
# 取行数
|
||||
|
|
@ -237,7 +268,8 @@ class Sql():
|
|||
self.__DB_CONN.commit()
|
||||
return last_id
|
||||
except Exception as ex:
|
||||
return "error: " + str(ex)
|
||||
print(str(ex))
|
||||
return 0
|
||||
|
||||
# 插入数据
|
||||
def insert(self, pdata):
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ function getBackupName(hook_data, name){
|
|||
function getCronData(page){
|
||||
var load = layer.msg(lan.public.the,{icon:16,time:0,shade: [0.3, '#000']});
|
||||
$.post("/crontab/list?p="+page,'', function(rdata){
|
||||
console.log(rdata);
|
||||
layer.close(load);
|
||||
var cbody = "";
|
||||
if(rdata == ""){
|
||||
|
|
@ -115,7 +116,7 @@ function getCronData(page){
|
|||
<td>"+rdata.data[i].cycle+"</td>\
|
||||
<td>"+cron_save +"</td>\
|
||||
<td>"+cron_backupto+"</td>\
|
||||
<td>"+rdata.data[i].addtime+"</td>\
|
||||
<td>"+rdata.data[i].add_time+"</td>\
|
||||
<td>\
|
||||
<a href=\"javascript:startTask("+rdata.data[i].id+");\" class='btlink'>执行</a> | \
|
||||
<a href=\"javascript:editTaskInfo('"+rdata.data[i].id+"');\" class='btlink'>编辑</a> | \
|
||||
|
|
@ -341,7 +342,7 @@ function planAdd(){
|
|||
|
||||
$("#cronConfig input[name='sName']").val(sName);
|
||||
layer.msg('正在添加,请稍候...!',{icon:16,time:0,shade: [0.3, '#000']});
|
||||
var data = $("#cronConfig").serialize() + '&sBody='+sBody + '&urladdress=' + urladdress;
|
||||
var data = $("#cronConfig").serialize() + '&sBody='+sBody;
|
||||
// console.log(data);
|
||||
$.post('/crontab/add',data,function(rdata){
|
||||
if(!rdata.status) {
|
||||
|
|
|
|||
|
|
@ -14,3 +14,4 @@ from .user import *
|
|||
from .sites import *
|
||||
from .tasks import *
|
||||
from .logs import *
|
||||
from .crontab import *
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
# 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 core.mw as mw
|
||||
|
||||
__field = 'id,name,type,where1,where_hour,where_minute,echo,status,save,backup_to,stype,sname,sbody,url_address,add_time,update_time'
|
||||
|
||||
def addCrontab(data):
|
||||
now_time = mw.formatDate()
|
||||
data['add_time'] = now_time
|
||||
data['update_time'] = now_time
|
||||
return mw.M('crontab').insert(data)
|
||||
|
||||
def getCrond(id):
|
||||
return mw.M('crontab').where('id=?', (id,)).field(__field).find()
|
||||
|
||||
def deleteCronById(id):
|
||||
mw.M('crontab').where("id=?", (id,)).delete()
|
||||
return True
|
||||
|
||||
def getCrontabList(
|
||||
page:int | None = 1,
|
||||
size:int | None = 10,
|
||||
):
|
||||
start = (int(page) - 1) * size
|
||||
limit = str(start) + ',' + str(size)
|
||||
|
||||
cron_list = mw.M('crontab').field(__field).limit(limit).order('id desc').select()
|
||||
count = mw.M('crontab').count()
|
||||
|
||||
data = {}
|
||||
data['count'] = count
|
||||
data['list'] = cron_list
|
||||
return data
|
||||
|
|
@ -8,6 +8,20 @@
|
|||
# Author: midoks <midoks@163.com>
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
import os
|
||||
|
||||
import core.mw as mw
|
||||
|
||||
|
||||
def initPanelData():
|
||||
pass
|
||||
_dbfile = mw.getPanelDataDir() + '/panel.db'
|
||||
if os.path.exists(_dbfile):
|
||||
return True
|
||||
sql_file = mw.getPanelDataDir() + '/sql/default.sql'
|
||||
sql = mw.M().dbPos(mw.getPanelDataDir(),'panel')
|
||||
csql = mw.readFile(sql_file)
|
||||
csql_list = csql.split(';')
|
||||
for index in range(len(csql_list)):
|
||||
print(index)
|
||||
sql.execute(csql_list[index], ())
|
||||
return True
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
# Author: midoks <midoks@163.com>
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
import json
|
||||
|
||||
|
||||
import core.mw as mw
|
||||
|
|
@ -32,4 +33,30 @@ def addLog(type, log,
|
|||
'add_time':add_time,
|
||||
}
|
||||
mw.M('logs').insert(insert_data)
|
||||
return True
|
||||
return True
|
||||
|
||||
def getLogsList(
|
||||
page:int | None = 1,
|
||||
size:int | None = 10,
|
||||
search: str | None = ''
|
||||
):
|
||||
sql_where = ''
|
||||
if search != '' :
|
||||
sql_where = " type like '%" + search + "%' or log like '%" + search + "%' "
|
||||
|
||||
field = 'id,type,log,uid,add_time'
|
||||
dbM = dbC = mw.M('logs').field(field)
|
||||
|
||||
if sql_where != '':
|
||||
count = mw.M('logs').field(field).where(sql_where).count()
|
||||
else:
|
||||
count = mw.M('logs').field(field).count()
|
||||
|
||||
start = (int(page) - 1) * (int(size))
|
||||
limit = str(start) + ',' +str(size)
|
||||
logs_list = mw.M('logs').field(field).limit(limit).order('id desc').select()
|
||||
|
||||
data = {}
|
||||
data['list'] = logs_list
|
||||
data['count'] = count
|
||||
return data
|
||||
|
|
@ -23,8 +23,7 @@ def getOption(name,
|
|||
:default -> str 默认值 (可选)
|
||||
'''
|
||||
data = mw.M('option').field('name').where('name=? and type=?',(name, type,)).getField('value')
|
||||
|
||||
if len(data) == 0:
|
||||
if data is None:
|
||||
return default
|
||||
return data
|
||||
|
||||
|
|
@ -40,7 +39,7 @@ def getOptionByJson(name,
|
|||
:default -> str 默认值 (可选)
|
||||
'''
|
||||
data = mw.M('option').field('name').where('name=? and type=?',(name, type,)).getField('value')
|
||||
if len(data) == 0:
|
||||
if data is None:
|
||||
return default
|
||||
if data is not None:
|
||||
return json.loads(data)
|
||||
|
|
@ -54,5 +53,15 @@ def setOption(name, value,
|
|||
:value -> object值 (必填)
|
||||
:type -> str 类型 (可选|默认common)
|
||||
'''
|
||||
mw.M('option').field('name').where('name=? and type=?',(name, type,)).setField('value', value)
|
||||
|
||||
data = mw.M('option').field('name,type,value').where('name=? and type=?',(name, type,)).find()
|
||||
if data is not None:
|
||||
mw.M('option').field('name').where('name=? and type=?',(name, type,)).setField('value', value)
|
||||
return True
|
||||
add_option = {
|
||||
'name':name,
|
||||
'type':type,
|
||||
'value':value
|
||||
}
|
||||
mw.M('option').insert(add_option)
|
||||
return True
|
||||
|
|
@ -11,5 +11,38 @@
|
|||
import core.mw as mw
|
||||
|
||||
def getSitesCount():
|
||||
return mw.M('sites').count()
|
||||
return mw.M('sites').count()
|
||||
|
||||
|
||||
def getSitesList(
|
||||
page:int | None = 1,
|
||||
size:int | None = 10,
|
||||
type_id:int | None = 0,
|
||||
search: str | None = ''
|
||||
):
|
||||
sql_where = ''
|
||||
if search != '' :
|
||||
sql_where = " name like '%" + search + "%' or ps like '%" + search + "%' "
|
||||
if type_id != '' and int(type_id) >= 0 and search != '' :
|
||||
sql_where = sql_where + " and type_id=" + str(type_id) + ""
|
||||
if type_id != '' and int(type_id) >= 0:
|
||||
sql_where = " type_id=" + str(type_id)
|
||||
|
||||
|
||||
dbM = dbC = mw.M('sites').field('id,name,path,status,ps,edate,type_id,add_time,update_time')
|
||||
|
||||
if sql_where != '':
|
||||
count = dbC.where(sql_where).count()
|
||||
else:
|
||||
count = dbC.count()
|
||||
|
||||
start = (int(page) - 1) * (int(size))
|
||||
limit = str(start) + ',' +str(size)
|
||||
site_list = dbM.limit(limit).order('id desc').select()
|
||||
|
||||
|
||||
data = {}
|
||||
data['list'] = site_list
|
||||
data['count'] = count
|
||||
return data
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@
|
|||
|
||||
import core.mw as mw
|
||||
|
||||
# 未执行任务总数
|
||||
def getTaskUnexecutedCount() -> int:
|
||||
return mw.M('tasks').where('status!=?',(1,)).count()
|
||||
|
||||
def addTask(
|
||||
name: str | None = '常用任务',
|
||||
cmd: str | None = None,
|
||||
|
|
@ -36,4 +40,35 @@ def addTask(
|
|||
'add_time':add_time,
|
||||
}
|
||||
mw.M('tasks').insert(insert_data)
|
||||
return True
|
||||
|
||||
|
||||
def getTaskList(
|
||||
status: int | None = 1,
|
||||
page: int | None = 1,
|
||||
size: int | None = 10,
|
||||
):
|
||||
start = (page - 1) * size
|
||||
limit = str(start) + ',' + str(size)
|
||||
|
||||
field = 'id,name,type,start,end,status,add_time'
|
||||
data = mw.M('tasks').where('', ()).field(field).limit(limit).order('id asc').select()
|
||||
return data
|
||||
|
||||
|
||||
|
||||
def setTaskStatus(id,
|
||||
status: int | None = 0
|
||||
):
|
||||
mw.M('tasks').where('id=?',(id,)).update({'status':status})
|
||||
return True
|
||||
|
||||
def setTaskData(id,
|
||||
start: int | None = None,
|
||||
end: int | None = None,
|
||||
):
|
||||
if start is not None:
|
||||
mw.M('tasks').where('id=?',(id,)).update({'start':start})
|
||||
if end is not None:
|
||||
mw.M('tasks').where('id=?',(id,)).update({'end':end})
|
||||
return True
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
# 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.model import db, TempLogin
|
||||
|
||||
import core.mw as mw
|
||||
|
||||
def getTempLoginByToken(token,
|
||||
) -> None:
|
||||
'''
|
||||
获取用户信息通过用户名
|
||||
'''
|
||||
field = 'id,addtime,expire,login_time,login_addr,state,add_time'
|
||||
data = mw.M('temp_login').where('token=?', (token,)).field(field).order('id asc').select()
|
||||
return data
|
||||
|
||||
def clearTempLogin()->bool:
|
||||
'''
|
||||
清空过期数据
|
||||
'''
|
||||
|
||||
now_time = int(time.time())
|
||||
mw.M('temp_login').where('expire<?', (now_time)).delete()
|
||||
return True
|
||||
|
|
@ -10,25 +10,49 @@
|
|||
|
||||
import core.mw as mw
|
||||
|
||||
# 初始化用户信息
|
||||
def initAdminUser():
|
||||
data = mw.M('users').field('id').where('id=?', (1,)).find()
|
||||
if data is None:
|
||||
name = mw.getRandomString(8).lower()
|
||||
password = mw.getRandomString(8).lower()
|
||||
insert_time = mw.formatDate()
|
||||
login_ip = '127.0.0.1'
|
||||
add_user = {
|
||||
'name':name,
|
||||
'password':mw.md5(password),
|
||||
'login_ip':login_ip,
|
||||
'login_time':insert_time,
|
||||
'phone':'',
|
||||
'email':'',
|
||||
'add_time':insert_time,
|
||||
'update_time':insert_time
|
||||
}
|
||||
file_pass_pl = mw.getPanelDataDir() + '/default.pl'
|
||||
mw.writeFile(file_pass_pl, password)
|
||||
mw.M('users').insert(add_user)
|
||||
return True
|
||||
|
||||
|
||||
def getUserByName(name,
|
||||
) -> None:
|
||||
'''
|
||||
获取用户信息通过用户名
|
||||
'''
|
||||
users_field = 'id,name,password,login_ip,login_time,phone,email,add_time,update_time'
|
||||
item = mw.M('users').field(users_field).where('name=?', (name,)).select()
|
||||
if len(item) == 0:
|
||||
data = mw.M('users').field(users_field).where('name=?', (name,)).find()
|
||||
if data is None:
|
||||
return None
|
||||
row = {}
|
||||
row['id'] = item[0]['id']
|
||||
row['name'] = item[0]['name']
|
||||
row['password'] = item[0]['password']
|
||||
row['login_ip'] = item[0]['login_ip']
|
||||
row['login_time'] = item[0]['login_time']
|
||||
row['phone'] = item[0]['phone']
|
||||
row['email'] = item[0]['email']
|
||||
row['add_time'] = item[0]['add_time']
|
||||
row['update_time'] = item[0]['update_time']
|
||||
row['id'] = data['id']
|
||||
row['name'] = data['name']
|
||||
row['password'] = data['password']
|
||||
row['login_ip'] = data['login_ip']
|
||||
row['login_time'] = data['login_time']
|
||||
row['phone'] = data['phone']
|
||||
row['email'] = data['email']
|
||||
row['add_time'] = data['add_time']
|
||||
row['update_time'] = data['update_time']
|
||||
return row
|
||||
|
||||
def getUserById(id,
|
||||
|
|
@ -37,19 +61,19 @@ def getUserById(id,
|
|||
获取用户信息通过用户名
|
||||
'''
|
||||
users_field = 'id,name,password,login_ip,login_time,phone,email,add_time,update_time'
|
||||
item = mw.M('users').field(users_field).where('id=?', (1,)).select()
|
||||
if len(item) == 0:
|
||||
data = mw.M('users').field(users_field).where('id=?', (1,)).find()
|
||||
if data is None:
|
||||
return None
|
||||
row = {}
|
||||
row['id'] = item[0]['id']
|
||||
row['name'] = item[0]['name']
|
||||
row['password'] = item[0]['password']
|
||||
row['login_ip'] = item[0]['login_ip']
|
||||
row['login_time'] = item[0]['login_time']
|
||||
row['phone'] = item[0]['phone']
|
||||
row['email'] = item[0]['email']
|
||||
row['add_time'] = item[0]['add_time']
|
||||
row['update_time'] = item[0]['update_time']
|
||||
row['id'] = data['id']
|
||||
row['name'] = data['name']
|
||||
row['password'] = data['password']
|
||||
row['login_ip'] = data['login_ip']
|
||||
row['login_time'] = data['login_time']
|
||||
row['phone'] = data['phone']
|
||||
row['email'] = data['email']
|
||||
row['add_time'] = data['add_time']
|
||||
row['update_time'] = data['update_time']
|
||||
return row
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -8,4 +8,423 @@
|
|||
# Author: midoks <midoks@163.com>
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import json
|
||||
import threading
|
||||
import multiprocessing
|
||||
|
||||
from admin import model
|
||||
|
||||
import core.mw as mw
|
||||
import thisdb
|
||||
|
||||
class crontab(object):
|
||||
# lock
|
||||
_instance_lock = threading.Lock()
|
||||
|
||||
@classmethod
|
||||
def instance(cls, *args, **kwargs):
|
||||
if not hasattr(crontab, "_instance"):
|
||||
with crontab._instance_lock:
|
||||
if not hasattr(crontab, "_instance"):
|
||||
crontab._instance = crontab(*args, **kwargs)
|
||||
return crontab._instance
|
||||
|
||||
# 获取指定任务数据
|
||||
def getCrondFind(self, cron_id):
|
||||
return thisdb.getCrond(cron_id)
|
||||
|
||||
def add(self, data):
|
||||
if len(data['name']) < 1:
|
||||
return mw.returnData(False, '任务名称不能为空!')
|
||||
|
||||
is_check_pass, msg = self.cronCheck(data)
|
||||
if not is_check_pass:
|
||||
return mw.returnData(is_check_pass, msg)
|
||||
|
||||
cmd, title = self.getCrondCycle(data)
|
||||
cron_path = mw.getServerDir() + '/cron'
|
||||
cron_name = self.getShell(data)
|
||||
|
||||
cmd += ' ' + cron_path + '/' + cron_name + ' >> ' + cron_path + '/' + cron_name + '.log 2>&1'
|
||||
|
||||
if not mw.isAppleSystem():
|
||||
data = self.writeShell(cmd)
|
||||
if not data['status']:
|
||||
return data
|
||||
self.crondReload()
|
||||
|
||||
add_dbdata = {}
|
||||
add_dbdata['name'] = data['name']
|
||||
add_dbdata['type'] = data['type']
|
||||
add_dbdata['where1'] = data['where1']
|
||||
add_dbdata['where_hour'] = data['hour']
|
||||
add_dbdata['where_minute'] = data['minute']
|
||||
add_dbdata['save'] = data['save']
|
||||
add_dbdata['backup_to'] = data['backup_to']
|
||||
add_dbdata['sname'] = data['sname']
|
||||
add_dbdata['sbody'] = data['sbody']
|
||||
add_dbdata['stype'] = data['stype']
|
||||
add_dbdata['echo'] = cron_name
|
||||
add_dbdata['url_address'] = data['url_address']
|
||||
|
||||
tid = thisdb.addCrontab(add_dbdata)
|
||||
if tid > 0:
|
||||
return mw.returnData(True, '添加成功')
|
||||
return mw.returnData(False, '添加失败')
|
||||
|
||||
def delete(self, tid):
|
||||
data = thisdb.getCrond(tid)
|
||||
if not self.removeForCrond(data['echo']):
|
||||
return mw.returnData(False, '无法写入文件,请检查是否开启了系统加固功能!')
|
||||
|
||||
cron_path = mw.getServerDir() + '/cron'
|
||||
cron_file = cron_path + '/' + data['echo']
|
||||
|
||||
if os.path.exists(cron_file):
|
||||
os.remove(cron_file)
|
||||
cron_file = cron_path + '/' + data['echo'] + '.log'
|
||||
if os.path.exists(cron_file):
|
||||
os.remove(cron_file)
|
||||
|
||||
thisdb.deleteCronById(tid)
|
||||
msg = mw.getInfo('删除计划任务[{1}]成功!', (data['name'],))
|
||||
mw.writeLog('计划任务', msg)
|
||||
return mw.returnData(True, msg)
|
||||
|
||||
def getCrontabHuman(self, data):
|
||||
rdata = []
|
||||
for i in range(len(data)):
|
||||
t = data[i]
|
||||
if t['type'] == "day":
|
||||
t['type'] = '每天'
|
||||
t['cycle'] = mw.getInfo('每天, {1}点{2}分 执行', (str(t['where_hour']), str(t['where_minute'])))
|
||||
elif t['type'] == "day-n":
|
||||
t['type'] = mw.getInfo('每{1}天', (str(t['where1']),))
|
||||
t['cycle'] = mw.getInfo('每隔{1}天, {2}点{3}分 执行', (str(t['where1']), str(t['where_hour']), str(t['where_minute'])))
|
||||
elif t['type'] == "hour":
|
||||
t['type'] = '每小时'
|
||||
t['cycle'] = mw.getInfo('每小时, 第{1}分钟 执行', (str(t['where_minute']),))
|
||||
elif t['type'] == "hour-n":
|
||||
t['type'] = mw.getInfo('每{1}小时', (str(t['where1']),))
|
||||
t['cycle'] = mw.getInfo('每{1}小时, 第{2}分钟 执行', (str(t['where1']), str(t['where_minute'])))
|
||||
elif t['type'] == "minute-n":
|
||||
t['type'] = mw.getInfo('每{1}分钟', (str(t['where1']),))
|
||||
t['cycle'] = mw.getInfo('每隔{1}分钟执行', (str(t['where1']),))
|
||||
elif t['type'] == "week":
|
||||
t['type'] = '每周'
|
||||
if not t['where1']:
|
||||
t['where1'] = '0'
|
||||
t['cycle'] = mw.getInfo('每周{1}, {2}点{3}分执行', (self.toWeek(int(t['where1'])), str(t['where_hour']), str(t['where_minute'])))
|
||||
elif t['type'] == "month":
|
||||
t['type'] = '每月'
|
||||
t['cycle'] = mw.getInfo('每月, {1}日 {2}点{3}分执行', (str(t['where1']), str(t['where_hour']), str(t['where_minute'])))
|
||||
rdata.append(t)
|
||||
return rdata
|
||||
|
||||
# 从crond删除
|
||||
def removeForCrond(self, echo):
|
||||
if mw.isAppleSystem():
|
||||
return True
|
||||
|
||||
u_file = '/var/spool/cron/crontabs/root'
|
||||
if not os.path.exists(u_file):
|
||||
file = '/var/spool/cron/root'
|
||||
if not os.path.exists(file):
|
||||
return False
|
||||
else:
|
||||
file = u_file
|
||||
|
||||
conf = mw.readFile(file)
|
||||
rep = ".+" + str(echo) + ".+\n"
|
||||
conf = re.sub(rep, "", conf)
|
||||
if not mw.writeFile(file, conf):
|
||||
return False
|
||||
self.crondReload()
|
||||
return True
|
||||
|
||||
def getCrontabList(self,
|
||||
page:int | None = 1,
|
||||
size:int | None = 10
|
||||
):
|
||||
info = thisdb.getCrontabList(page=int(page),size=int(size))
|
||||
|
||||
rdata = {}
|
||||
rdata['data'] = self.getCrontabHuman(info['list'])
|
||||
rdata['page'] = mw.getPage({'count':info['count'],'tojs':'getCronData','p':page,'row':size})
|
||||
return rdata
|
||||
|
||||
def getCrondCycle(self, params):
|
||||
cron_cmd = ''
|
||||
title = ''
|
||||
if params['type'] == "day":
|
||||
cron_cmd = self.getDay(params)
|
||||
title = '每天'
|
||||
elif params['type'] == "day-n":
|
||||
cron_cmd = self.getDay_N(params)
|
||||
title = mw.getInfo('每{1}天', (params['where1'],))
|
||||
elif params['type'] == "hour":
|
||||
cron_cmd = self.getHour(params)
|
||||
title = '每小时'
|
||||
elif params['type'] == "hour-n":
|
||||
cron_cmd = self.getHour_N(params)
|
||||
title = '每小时'
|
||||
elif params['type'] == "minute-n":
|
||||
cron_cmd = self.minute_N(params)
|
||||
elif params['type'] == "week":
|
||||
params['where1'] = params['week']
|
||||
cron_cmd = self.week(params)
|
||||
elif params['type'] == "month":
|
||||
cron_cmd = self.month(params)
|
||||
return cron_cmd, title
|
||||
|
||||
# 转换大写星期
|
||||
def toWeek(self, num):
|
||||
wheres = {
|
||||
0: '日',
|
||||
1: '一',
|
||||
2: '二',
|
||||
3: '三',
|
||||
4: '四',
|
||||
5: '五',
|
||||
6: '六'
|
||||
}
|
||||
try:
|
||||
return wheres[num]
|
||||
except:
|
||||
return ''
|
||||
|
||||
# 取任务构造Day
|
||||
def getDay(self, param):
|
||||
cmd = "{0} {1} * * * ".format(param['minute'], param['hour'])
|
||||
return cmd
|
||||
|
||||
# 取任务构造Day_n
|
||||
def getDay_N(self, param):
|
||||
cmd = "{0} {1} */{2} * * ".format(param['minute'], param['hour'], param['where1'])
|
||||
return cmd
|
||||
|
||||
# 取任务构造Hour
|
||||
def getHour(self, param):
|
||||
cmd = "{0} * * * * ".format(param['minute'])
|
||||
return cmd
|
||||
|
||||
# 取任务构造Hour-N
|
||||
def getHour_N(self, param):
|
||||
cmd = "{0} */{1} * * * ".format(param['minute'], param['where1'])
|
||||
return cmd
|
||||
|
||||
# 取任务构造Minute-N
|
||||
def minute_N(self, param):
|
||||
cmd = "*/{0} * * * * ".format(param['where1'])
|
||||
return cmd
|
||||
|
||||
# 取任务构造week
|
||||
def week(self, param):
|
||||
cmd = "{0} {1} * * {2}".format(param['minute'], param['hour'], param['week'])
|
||||
return cmd
|
||||
|
||||
# 取任务构造Month
|
||||
def month(self, param):
|
||||
cmd = "{0} {1} {2} * * ".format(param['minute'], param['hour'], param['where1'])
|
||||
return cmd
|
||||
|
||||
# 参数校验
|
||||
def cronCheck(self, params):
|
||||
if params['stype'] == 'site' or params['stype'] == 'database' or params['stype'].find('database_') > -1 or params['stype'] == 'logs' or params['stype'] == 'path':
|
||||
if params['save'] == '':
|
||||
return False, '保留份数不能为空!'
|
||||
|
||||
if params['type'] == 'day':
|
||||
if params['hour'] == '':
|
||||
return False, '小时不能为空!'
|
||||
if params['minute'] == '':
|
||||
return False, '分钟不能为空!'
|
||||
|
||||
if params['type'] == 'day-n':
|
||||
if params['where1'] == '':
|
||||
return False, '天不能为空!'
|
||||
if params['hour'] == '':
|
||||
return False, '小时不能为空!'
|
||||
if params['minute'] == '':
|
||||
return False, '分钟不能为空!'
|
||||
if params['type'] == 'hour':
|
||||
if params['minute'] == '':
|
||||
return False, '分钟不能为空!'
|
||||
|
||||
if params['type'] == 'hour-n':
|
||||
if params['where1'] == '':
|
||||
return False, '小时不能为空!'
|
||||
if params['minute'] == '':
|
||||
return False, '分钟不能为空!'
|
||||
|
||||
if params['type'] == 'minute-n':
|
||||
if params['where1'] == '':
|
||||
return False, '分钟不能为空!'
|
||||
|
||||
if params['type'] == 'week':
|
||||
if params['hour'] == '':
|
||||
return False, '小时不能为空!'
|
||||
if params['minute'] == '':
|
||||
return False, '分钟不能为空!'
|
||||
|
||||
if params['type'] == 'month':
|
||||
if params['where1'] == '':
|
||||
return False, '日不能为空!'
|
||||
if params['hour'] == '':
|
||||
return False, '小时不能为空!'
|
||||
if params['minute'] == '':
|
||||
return False, '分钟不能为空!'
|
||||
return True, 'OK'
|
||||
|
||||
|
||||
# 取执行脚本
|
||||
def getShell(self, param):
|
||||
# try:
|
||||
stype = param['stype']
|
||||
if stype == 'toFile':
|
||||
shell = param.sFile
|
||||
else:
|
||||
head = "#!/bin/bash\nPATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin\nexport PATH\n"
|
||||
|
||||
start_head = '''
|
||||
SCRIPT_RUN_TIME="0s"
|
||||
MW_ToSeconds()
|
||||
{
|
||||
SEC=$1
|
||||
if [ $SEC -lt 60 ]; then
|
||||
SCRIPT_RUN_TIME="${SEC}s"
|
||||
elif [ $SEC -ge 60 ] && [ $SEC -lt 3600 ];then
|
||||
SCRIPT_RUN_TIME="$(( SEC / 60 ))m$(( SEC % 60 ))s"
|
||||
elif [ $SEC -ge 3600 ]; then
|
||||
SCRIPT_RUN_TIME="$(( SEC / 3600 ))h$(( (SEC % 3600) / 60 ))m$(( (SEC % 3600) % 60 ))s"
|
||||
fi
|
||||
}
|
||||
START_MW_SHELL_TIME=`date +%s`
|
||||
'''
|
||||
|
||||
source_bin_activate = '''
|
||||
export LANG=en_US.UTF-8
|
||||
MW_PATH=%s/bin/activate
|
||||
if [ -f $MW_PATH ];then
|
||||
source $MW_PATH
|
||||
fi''' % (mw.getPanelDir(),)
|
||||
|
||||
head = head + start_head + source_bin_activate + "\n"
|
||||
log = '.log'
|
||||
|
||||
#所有
|
||||
if param['sname'] == 'ALL':
|
||||
log = ''
|
||||
|
||||
script_dir = mw.getPanelDir() + "/scripts"
|
||||
source_stype = 'database'
|
||||
if stype.find('database_') > -1:
|
||||
plugin_name = stype.replace('database_', '')
|
||||
script_dir = mw.getPanelDir() + "/plugins/" + plugin_name + "/scripts"
|
||||
|
||||
source_stype = stype
|
||||
stype = 'database'
|
||||
|
||||
wheres = {
|
||||
'path': head + "python3 " + script_dir + "/backup.py path " + param['sname'] + " " + str(param['save']),
|
||||
'site': head + "python3 " + script_dir + "/backup.py site " + param['sname'] + " " + str(param['save']),
|
||||
'database': head + "python3 " + script_dir + "/backup.py database " + param['sname'] + " " + str(param['save']),
|
||||
'logs': head + "python3 " + script_dir + "/logs_backup.py " + param['sname'] + log + " " + str(param['save']),
|
||||
'rememory': head + "/bin/bash " + script_dir + '/rememory.sh'
|
||||
}
|
||||
if param['backup_to'] != 'localhost':
|
||||
cfile = mw.getPluginDir() + "/" + \
|
||||
param['backup_to'] + "/index.py"
|
||||
|
||||
wheres['path'] = head + "python3 " + cfile + \
|
||||
" path " + param['sname'] + " " + str(param['save'])
|
||||
wheres['site'] = head + "python3 " + cfile + \
|
||||
" site " + param['sname'] + " " + str(param['save'])
|
||||
wheres['database'] = head + "python3 " + cfile + " " + \
|
||||
source_stype + " " + \
|
||||
param['sname'] + " " + str(param['save'])
|
||||
try:
|
||||
shell = wheres[stype]
|
||||
except:
|
||||
if stype == 'toUrl':
|
||||
shell = head + "curl -sS --connect-timeout 10 -m 60 '" + \
|
||||
param['urladdress'] + "'"
|
||||
else:
|
||||
shell = head + param['sbody'].replace("\r\n", "\n")
|
||||
|
||||
shell += '''
|
||||
echo "----------------------------------------------------------------------------"
|
||||
endDate=`date +"%Y-%m-%d %H:%M:%S"`
|
||||
END_MW_SHELL_TIME=`date +"%s"`
|
||||
((SHELL_COS_TIME=($END_MW_SHELL_TIME-$START_MW_SHELL_TIME)))
|
||||
MW_ToSeconds $SHELL_COS_TIME
|
||||
echo "★[$endDate] Successful | Script Run [$SCRIPT_RUN_TIME] "
|
||||
echo "----------------------------------------------------------------------------"
|
||||
'''
|
||||
cron_path = mw.getServerDir() + '/cron'
|
||||
if not os.path.exists(cron_path):
|
||||
mw.execShell('mkdir -p ' + cron_path)
|
||||
|
||||
if not 'echo' in param:
|
||||
cron_name = mw.md5(mw.md5(str(time.time()) + '_mw'))
|
||||
else:
|
||||
cron_name = param['echo']
|
||||
file = cron_path + '/' + cron_name
|
||||
mw.writeFile(file, self.checkScript(shell))
|
||||
mw.execShell('chmod 750 ' + file)
|
||||
return cron_name
|
||||
|
||||
# 检查脚本
|
||||
def checkScript(self, shell):
|
||||
keys = ['shutdown', 'init 0', 'mkfs', 'passwd',
|
||||
'chpasswd', '--stdin', 'mkfs.ext', 'mke2fs']
|
||||
for key in keys:
|
||||
shell = shell.replace(key, '[***]')
|
||||
return shell
|
||||
|
||||
|
||||
|
||||
# 将Shell脚本写到文件
|
||||
def writeShell(self, config):
|
||||
file = '/var/spool/cron/crontabs/root'
|
||||
current_os = mw.getOs()
|
||||
if current_os == 'darwin':
|
||||
file = '/etc/crontab'
|
||||
elif current_os.startswith("freebsd"):
|
||||
file = '/var/cron/tabs/root'
|
||||
|
||||
if not os.path.exists(file):
|
||||
file = '/var/spool/cron/root'
|
||||
|
||||
if not os.path.exists(file):
|
||||
mw.writeFile(file, '')
|
||||
conf = mw.readFile(file)
|
||||
conf += str(config) + "\n"
|
||||
if mw.writeFile(file, conf):
|
||||
if not os.path.exists(file):
|
||||
mw.execShell("chmod 600 '" + file +"' && chown root.root " + file)
|
||||
else:
|
||||
mw.execShell("chmod 600 '" + file +"' && chown root.crontab " + file)
|
||||
return mw.returnData(True, 'ok')
|
||||
return mw.returnData(False, '文件写入失败,请检查是否开启系统加固功能!')
|
||||
|
||||
# 重载配置
|
||||
def crondReload(self):
|
||||
if mw.isAppleSystem():
|
||||
if os.path.exists('/etc/crontab'):
|
||||
pass
|
||||
else:
|
||||
if os.path.exists('/etc/init.d/crond'):
|
||||
mw.execShell('/etc/init.d/crond reload')
|
||||
elif os.path.exists('/etc/init.d/cron'):
|
||||
mw.execShell('service cron restart')
|
||||
else:
|
||||
mw.execShell("systemctl reload crond")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ import multiprocessing
|
|||
from admin import model
|
||||
|
||||
import core.mw as mw
|
||||
import admin.model.option as option
|
||||
import thisdb
|
||||
|
||||
class pg_thread(threading.Thread):
|
||||
|
|
@ -108,7 +107,7 @@ class plugin(object):
|
|||
self.__index_data = json.loads(mw.readFile(self.__index))
|
||||
|
||||
def getIndexList(self):
|
||||
indexList = option.getOptionByJson('display_index')
|
||||
indexList = thisdb.getOptionByJson('display_index')
|
||||
plist = []
|
||||
for i in indexList:
|
||||
tmp = i.split('-')
|
||||
|
|
@ -152,30 +151,30 @@ class plugin(object):
|
|||
|
||||
def addIndex(self, name, version):
|
||||
vname = name + '-' + version
|
||||
indexList = option.getOptionByJson('display_index')
|
||||
indexList = thisdb.getOptionByJson('display_index',default=[])
|
||||
|
||||
if vname in indexList:
|
||||
return mw.returnData(False, '请不要重复添加!')
|
||||
if len(indexList) > 12:
|
||||
return mw.returnData(False, '首页最多只能显示12个软件!')
|
||||
|
||||
indexList.append(vname)
|
||||
option.setOption('display_index', json.dumps(indexList))
|
||||
|
||||
thisdb.setOption('display_index', json.dumps(indexList))
|
||||
return mw.returnData(True, '添加成功!')
|
||||
|
||||
def removeIndex(self, name, version):
|
||||
vname = name + '-' + version
|
||||
indexList = option.getOptionByJson('display_index')
|
||||
indexList = thisdb.getOptionByJson('display_index')
|
||||
if not vname in indexList:
|
||||
return mw.returnData(True, '删除成功!!')
|
||||
indexList.remove(vname)
|
||||
|
||||
print(indexList)
|
||||
option.setOption('display_index', json.dumps(indexList))
|
||||
thisdb.setOption('display_index', json.dumps(indexList))
|
||||
return mw.returnData(True, '删除成功!')
|
||||
|
||||
def hookInstallOption(self, hook_name, info):
|
||||
hn_name = 'hook_'+hook_name
|
||||
src_data = option.getOptionByJson(hn_name,type='hook',default=[])
|
||||
src_data = thisdb.getOptionByJson(hn_name,type='hook',default=[])
|
||||
isNeedAdd = True
|
||||
for x in range(len(src_data)):
|
||||
if src_data[x]['title'] == info['title'] and src_data[x]['name'] == info['name']:
|
||||
|
|
@ -184,17 +183,17 @@ class plugin(object):
|
|||
if isNeedAdd:
|
||||
src_data.append(info)
|
||||
|
||||
option.setOption(hn_name, json.dumps(src_data), type='hook')
|
||||
thisdb.setOption(hn_name, json.dumps(src_data), type='hook')
|
||||
return True
|
||||
|
||||
def hookUninstallOption(self, hook_name, info):
|
||||
hn_name = 'hook_'+hook_name
|
||||
src_data = option.getOptionByJson(hn_name,type='hook',default=[])
|
||||
src_data = thisdb.getOptionByJson(hn_name,type='hook',default=[])
|
||||
for idx in range(len(src_data)):
|
||||
if src_data[idx]['name'] == info['name']:
|
||||
src_data.remove(src_data[idx])
|
||||
break
|
||||
option.setOption(hn_name, json.dumps(src_data), type='hook')
|
||||
thisdb.setOption(hn_name, json.dumps(src_data), type='hook')
|
||||
return True
|
||||
|
||||
def hookInstall(self, info):
|
||||
|
|
@ -316,7 +315,7 @@ class plugin(object):
|
|||
return ''
|
||||
|
||||
def checkIndexList(self, name, version):
|
||||
indexList = option.getOptionByJson('display_index')
|
||||
indexList = thisdb.getOptionByJson('display_index',default=[])
|
||||
for i in indexList:
|
||||
t = i.split('-')
|
||||
if t[0] == name:
|
||||
|
|
@ -426,15 +425,28 @@ class plugin(object):
|
|||
return pInfo
|
||||
|
||||
def makeCoexistData(self, data):
|
||||
plugins_t = []
|
||||
plugins = []
|
||||
if type(data['versions']) == list and 'coexist' in data and data['coexist']:
|
||||
data_t = self.makeCoexist(data)
|
||||
for index in range(len(data_t)):
|
||||
plugins_t.append(data_t[index])
|
||||
plugins.append(data_t[index])
|
||||
else:
|
||||
pg = self.getPluginInfo(data)
|
||||
plugins_t.append(pg)
|
||||
return plugins_t
|
||||
plugins.append(pg)
|
||||
return plugins
|
||||
|
||||
def makeCoexistDataInstalled(self, data):
|
||||
plugins = []
|
||||
if type(data['versions']) == list and 'coexist' in data and data['coexist']:
|
||||
data_t = self.makeCoexist(data)
|
||||
for index in range(len(data_t)):
|
||||
if data_t[index]['setup']:
|
||||
plugins.append(data_t[index])
|
||||
else:
|
||||
pg = self.getPluginInfo(data)
|
||||
if pg['setup']:
|
||||
plugins.append(pg)
|
||||
return plugins
|
||||
|
||||
# 对多版本共存进行处理
|
||||
def makeCoexistList(self, data,
|
||||
|
|
@ -449,12 +461,11 @@ class plugin(object):
|
|||
if plugin_type == None or plugin_type == '0':
|
||||
return self.makeCoexistData(data)
|
||||
# 已经安装
|
||||
if plugin_type == '-1':
|
||||
return self.makeCoexistData(data)
|
||||
if str(plugin_type) == '-1':
|
||||
return self.makeCoexistDataInstalled(data)
|
||||
return plugins_t
|
||||
|
||||
|
||||
|
||||
def getPluginList(self, name,
|
||||
keyword: str | None = None,
|
||||
type: str | None = None,
|
||||
|
|
|
|||
Loading…
Reference in New Issue