first commit
This commit is contained in:
440
lib/system/plugin.py
Normal file
440
lib/system/plugin.py
Normal file
@@ -0,0 +1,440 @@
|
||||
# third-party
|
||||
import requests
|
||||
import traceback
|
||||
import logging
|
||||
import threading
|
||||
import time
|
||||
import json
|
||||
import os
|
||||
|
||||
from flask import (
|
||||
Blueprint,
|
||||
request,
|
||||
Response,
|
||||
send_file,
|
||||
render_template,
|
||||
redirect,
|
||||
jsonify,
|
||||
stream_with_context,
|
||||
)
|
||||
|
||||
# gommi 공용
|
||||
from framework.logger import get_logger
|
||||
from framework import (
|
||||
app,
|
||||
db,
|
||||
scheduler,
|
||||
socketio,
|
||||
check_api,
|
||||
path_app_root,
|
||||
path_data,
|
||||
) # , celery
|
||||
from flask_login import login_user, logout_user, current_user, login_required
|
||||
from framework.util import Util, SingletonClass
|
||||
|
||||
# 로그
|
||||
package_name = __name__.split(".")[0]
|
||||
logger = get_logger(package_name)
|
||||
|
||||
# package
|
||||
from .logic import SystemLogic
|
||||
from .model import ModelSetting
|
||||
from .logic_plugin import LogicPlugin
|
||||
from .logic_selenium import SystemLogicSelenium
|
||||
from .logic_command import SystemLogicCommand
|
||||
from .logic_command2 import SystemLogicCommand2
|
||||
from .logic_auth import SystemLogicAuth
|
||||
|
||||
# celery 때문에 import
|
||||
from .logic_site import SystemLogicSite
|
||||
|
||||
|
||||
# ========================================================================
|
||||
# plugin public
|
||||
# ========================================================================
|
||||
blueprint = Blueprint(
|
||||
package_name,
|
||||
package_name,
|
||||
url_prefix="/%s" % package_name,
|
||||
template_folder="templates",
|
||||
)
|
||||
menu = {
|
||||
"main": [package_name, "설정"],
|
||||
"sub": [
|
||||
["setting", "일반설정"],
|
||||
["plugin", "플러그인"],
|
||||
["tool", "Tool"],
|
||||
["log", "로그"],
|
||||
],
|
||||
"sub2": {
|
||||
"setting": [
|
||||
["basic", "기본"],
|
||||
["auth", "인증"],
|
||||
["env", "시스템"],
|
||||
["notify", "알림"],
|
||||
["telegram_bot", "텔레그램 봇"],
|
||||
["selenium", "Selenium"],
|
||||
["trans", "번역"],
|
||||
["site", "Site"],
|
||||
["memo", "메모"],
|
||||
["terminal", "Terminal"],
|
||||
],
|
||||
"rss": [["setting", "설정"], ["job", "작업"], ["list", "목록"]],
|
||||
"cache": [["setting", "설정"], ["list", "목록"]],
|
||||
"tool": [["crypt", "암호화"]],
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def plugin_load():
|
||||
logger.debug("plugin_load:%s", package_name)
|
||||
SystemLogic.plugin_load()
|
||||
# SystemLogicTelegramBot.plugin_load()
|
||||
SystemLogicSite.plugin_load()
|
||||
|
||||
|
||||
def plugin_unload():
|
||||
logger.debug("plugin_load:%s", package_name)
|
||||
SystemLogicSelenium.plugin_unload()
|
||||
SystemLogicCommand.plugin_unload()
|
||||
SystemLogicCommand2.plugin_unload()
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Web menu
|
||||
# ============================================================
|
||||
@blueprint.route("/")
|
||||
def normal():
|
||||
return redirect("/%s/setting" % package_name)
|
||||
|
||||
|
||||
@login_required
|
||||
def home():
|
||||
return render_template("info.html", arg=None)
|
||||
|
||||
|
||||
@blueprint.route("/<sub>", methods=["GET", "POST"])
|
||||
@login_required
|
||||
def first_menu(sub):
|
||||
logger.debug("System SUB:%s", sub)
|
||||
arg = None
|
||||
if sub == "home":
|
||||
return render_template("%s_%s.html" % (package_name, sub), arg=None)
|
||||
elif sub == "setting":
|
||||
return redirect("/%s/%s/basic" % (package_name, sub))
|
||||
elif sub == "restart":
|
||||
restart()
|
||||
return render_template(
|
||||
"system_restart.html",
|
||||
sub=sub,
|
||||
referer=request.headers.get("Referer"),
|
||||
)
|
||||
elif sub == "plugin":
|
||||
arg = ModelSetting.to_dict()
|
||||
logger.debug = f"arg:: {arg}"
|
||||
arg["install"] = request.args.get("install", "")
|
||||
|
||||
return render_template("system_plugin.html", arg=arg)
|
||||
|
||||
return render_template("sample.html", title="%s - %s" % (package_name, sub))
|
||||
|
||||
|
||||
@blueprint.route("/<sub>/<sub2>")
|
||||
@login_required
|
||||
def second_menu(sub, sub2):
|
||||
try:
|
||||
if sub == "setting":
|
||||
arg = ModelSetting.to_dict()
|
||||
arg["sub"] = sub2
|
||||
if sub2 == "basic":
|
||||
arg["point"] = SystemLogic.point
|
||||
return render_template(
|
||||
"%s_%s_%s.html" % (package_name, sub, sub2), arg=arg
|
||||
)
|
||||
elif sub2 == "auth":
|
||||
arg["auth_result"] = SystemLogicAuth.get_auth_status()
|
||||
return render_template(
|
||||
"%s_%s_%s.html" % (package_name, sub, sub2), arg=arg
|
||||
)
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
#########################################################
|
||||
# For UI
|
||||
#########################################################
|
||||
@blueprint.route("/ajax/<sub>/<sub2>", methods=["GET", "POST"])
|
||||
@login_required
|
||||
def second_ajax(sub, sub2):
|
||||
logger.debug("System AJAX sub:%s", sub)
|
||||
try:
|
||||
if sub == "trans":
|
||||
from .logic_trans import SystemLogicTrans
|
||||
|
||||
return SystemLogicTrans.process_ajax(sub2, request)
|
||||
elif sub == "auth":
|
||||
from .logic_auth import SystemLogicAuth
|
||||
|
||||
return SystemLogicAuth.process_ajax(sub2, request)
|
||||
elif sub == "selenium":
|
||||
return SystemLogicSelenium.process_ajax(sub2, request)
|
||||
elif sub == "notify":
|
||||
return SystemLogicNotify.process_ajax(sub2, request)
|
||||
elif sub == "telegram_bot":
|
||||
return SystemLogicTelegramBot.process_ajax(sub2, request)
|
||||
elif sub == "env":
|
||||
return SystemLogicEnv.process_ajax(sub2, request)
|
||||
elif sub == "site":
|
||||
return SystemLogicSite.process_ajax(sub2, request)
|
||||
elif sub == "crypt":
|
||||
return SystemLogicToolDecrypt.process_ajax(sub2, request)
|
||||
elif sub == "terminal":
|
||||
return SystemLogicTerminal.process_ajax(sub2, request)
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
@blueprint.route("/ajax/<sub>", methods=["GET", "POST"])
|
||||
@login_required
|
||||
def ajax(sub):
|
||||
# logger.debug('System AJAX sub:%s', sub)
|
||||
try:
|
||||
if sub == "info":
|
||||
try:
|
||||
ret = {}
|
||||
ret["system"] = SystemLogic.get_info()
|
||||
ret["scheduler"] = scheduler.get_job_list_info()
|
||||
|
||||
# logger.debug(ret)
|
||||
return jsonify(ret)
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
return jsonify()
|
||||
elif sub == "setting_save_system":
|
||||
try:
|
||||
ret = SystemLogic.setting_save_system(request)
|
||||
return jsonify(ret)
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
elif sub == "setting_save":
|
||||
ret = ModelSetting.setting_save(request)
|
||||
SystemLogic.setting_save_after()
|
||||
return jsonify(ret)
|
||||
elif sub == "ddns_test":
|
||||
try:
|
||||
url = request.form["ddns"] + "/version"
|
||||
res = requests.get(url)
|
||||
data = res.text
|
||||
# data = res.json()
|
||||
# logger.debug(data)
|
||||
return jsonify(data)
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
return jsonify("fail")
|
||||
elif sub == "celery_test":
|
||||
try:
|
||||
# result = add_together.delay(10, 20)
|
||||
# print(result.wait())
|
||||
# return 'Welcome to my app!'
|
||||
try:
|
||||
import framework
|
||||
|
||||
framework.exit_code = 1
|
||||
socketio.stop()
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
# os.environ['SJVA_REPEAT_TYPE'] = 'update'
|
||||
|
||||
return jsonify()
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
elif sub == "command_run":
|
||||
try:
|
||||
command_text = request.form["command_text"]
|
||||
ret = SystemLogic.command_run(command_text)
|
||||
return jsonify(ret)
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
elif sub == "get_link_list":
|
||||
try:
|
||||
link_json = SystemLogic.get_setting_value("link_json")
|
||||
j = json.loads(link_json)
|
||||
return jsonify(j)
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
elif sub == "link_save":
|
||||
try:
|
||||
link_data_str = request.form["link_data"]
|
||||
# j = json.loads(link_data)
|
||||
ret = SystemLogic.link_save(link_data_str)
|
||||
return jsonify(ret)
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
elif sub == "plugin_list":
|
||||
try:
|
||||
return jsonify(LogicPlugin.get_plugin_list())
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
elif sub == "plugin_install":
|
||||
try:
|
||||
# plugin_name = request.form['plugin_name']
|
||||
plugin_git = request.form["plugin_git"]
|
||||
return jsonify(
|
||||
LogicPlugin.plugin_install_by_api(
|
||||
plugin_git,
|
||||
request.form.get("zip_url"),
|
||||
request.form.get("zip_filename"),
|
||||
)
|
||||
)
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
elif sub == "plugin_uninstall":
|
||||
try:
|
||||
plugin_name = request.form["plugin_name"]
|
||||
return jsonify(LogicPlugin.plugin_uninstall(plugin_name))
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
elif sub == "recent_version":
|
||||
ret = SystemLogic.get_recent_version()
|
||||
ret = {"ret": ret, "version": SystemLogic.recent_version}
|
||||
return jsonify(ret)
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
def restart():
|
||||
try:
|
||||
try:
|
||||
import framework
|
||||
|
||||
framework.exit_code = 1
|
||||
app_close()
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
def shutdown():
|
||||
try:
|
||||
try:
|
||||
nginx_kill = "/app/data/custom/nginx/files/kill.sh"
|
||||
if os.path.exists(nginx_kill):
|
||||
SystemLogicCommand.execute_command_return([nginx_kill])
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
import framework
|
||||
|
||||
framework.exit_code = 0
|
||||
app_close()
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
def app_close():
|
||||
try:
|
||||
from framework.init_plugin import plugin_unload
|
||||
|
||||
plugin_unload()
|
||||
socketio.stop()
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
@socketio.on("connect", namespace="/%s" % package_name)
|
||||
def connect():
|
||||
try:
|
||||
InfoProcess.instance().connect(request.sid)
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
@socketio.on("disconnect", namespace="/%s" % package_name)
|
||||
def disconnect():
|
||||
try:
|
||||
InfoProcess.instance().disconnect(request.sid)
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
@socketio.on("connect", namespace="/system_restart")
|
||||
def connect_system_restart():
|
||||
try:
|
||||
socketio.emit(
|
||||
"on_connect", "restart", namespace="/system_restart", broadcast=True
|
||||
)
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
@socketio.on("disconnect", namespace="/system_restart")
|
||||
def disconnect_system_restart():
|
||||
try:
|
||||
pass
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
class InfoThread(threading.Thread):
|
||||
def __init__(self):
|
||||
super(InfoThread, self).__init__()
|
||||
self.stop_flag = False
|
||||
self.daemon = True
|
||||
|
||||
def stop(self):
|
||||
self.stop_flag = True
|
||||
|
||||
def run(self) -> None:
|
||||
while not self.stop_flag:
|
||||
ret = {}
|
||||
ret["system"] = SystemLogic.get_info()
|
||||
ret["scheduler"] = scheduler.get_job_list_info()
|
||||
socketio.emit(
|
||||
"status", ret, namespace="/system", broadcast=True
|
||||
)
|
||||
# logger.debug('InfoThread')
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
class InfoProcess(SingletonClass):
|
||||
sid_list = []
|
||||
thread = None
|
||||
|
||||
@classmethod
|
||||
def connect(cls, sid):
|
||||
logger.debug("Info connect:%s", InfoProcess.sid_list)
|
||||
if not InfoProcess.sid_list:
|
||||
InfoProcess.thread = InfoThread()
|
||||
InfoProcess.thread.start()
|
||||
InfoProcess.sid_list.append(sid)
|
||||
|
||||
@classmethod
|
||||
def disconnect(cls, sid):
|
||||
logger.debug("Info disconnect:%s", InfoProcess.sid_list)
|
||||
InfoProcess.sid_list.remove(sid)
|
||||
if not InfoProcess.sid_list:
|
||||
InfoProcess.thread.stop()
|
||||
Reference in New Issue
Block a user