441 lines
14 KiB
Python
441 lines
14 KiB
Python
# 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()
|