first commit
This commit is contained in:
346
lib/system/logic_plugin.py
Normal file
346
lib/system/logic_plugin.py
Normal file
@@ -0,0 +1,346 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#########################################################
|
||||
# python
|
||||
import os
|
||||
import traceback
|
||||
import logging
|
||||
import json
|
||||
import zipfile
|
||||
import time
|
||||
import platform
|
||||
|
||||
# third-party
|
||||
import requests
|
||||
from flask import (
|
||||
Blueprint,
|
||||
request,
|
||||
Response,
|
||||
send_file,
|
||||
render_template,
|
||||
redirect,
|
||||
jsonify,
|
||||
)
|
||||
from flask_login import login_user, logout_user, current_user, login_required
|
||||
|
||||
# gommi 공용
|
||||
from framework.logger import get_logger, set_level
|
||||
from framework import (
|
||||
app,
|
||||
db,
|
||||
scheduler,
|
||||
version,
|
||||
path_app_root,
|
||||
path_data,
|
||||
USERS,
|
||||
)
|
||||
from framework.util import Util
|
||||
|
||||
# 패키지
|
||||
from .model import ModelSetting
|
||||
import system
|
||||
|
||||
# 로그
|
||||
package_name = __name__.split(".")[0]
|
||||
logger = get_logger(package_name)
|
||||
#########################################################
|
||||
|
||||
|
||||
class LogicPlugin(object):
|
||||
plugin_loading = False
|
||||
|
||||
current_loading_plugin_list = {}
|
||||
|
||||
"""
|
||||
custom_plugin_list = []
|
||||
@staticmethod
|
||||
def loading():
|
||||
try:
|
||||
custom_path = os.path.join(path_data, 'custom')
|
||||
plugin_list = os.listdir(custom_path)
|
||||
logger.debug(plugin_list)
|
||||
for name in plugin_list:
|
||||
try:
|
||||
p = {}
|
||||
p['name'] = name
|
||||
p['plugin_name'] = name
|
||||
mod = __import__('%s' % (p['plugin_name']), fromlist=[])
|
||||
p['local_info'] = getattr(mod, 'plugin_info')
|
||||
p['status'] = 'latest'
|
||||
LogicPlugin.custom_plugin_list.append(p)
|
||||
except Exception as exception:
|
||||
logger.error('NO Exception:%s', exception)
|
||||
logger.debug('plunin not import : %s', p['plugin_name'])
|
||||
p['local_info'] = None
|
||||
p['status'] = 'no'
|
||||
except Exception as exception:
|
||||
logger.error('Exception:%s', exception)
|
||||
logger.error(traceback.format_exc())
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def get_plugin_list():
|
||||
return LogicPlugin.current_loading_plugin_list
|
||||
"""
|
||||
try:
|
||||
if not LogicPlugin.plugin_loading:
|
||||
LogicPlugin.loading()
|
||||
LogicPlugin.plugin_loading = True
|
||||
return LogicPlugin.custom_plugin_list
|
||||
except Exception as exception:
|
||||
logger.error('Exception:%s', exception)
|
||||
logger.error(traceback.format_exc())
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def get_plugin_info(plugin_name):
|
||||
try:
|
||||
lists = LogicPlugin.get_plugin_list()
|
||||
for key, value in lists.items():
|
||||
if key == plugin_name:
|
||||
return value["info"]
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
"""
|
||||
@staticmethod
|
||||
def plugin_install(plugin_name):
|
||||
logger.debug('plugin_name : %s', plugin_name)
|
||||
try:
|
||||
plugin_info = LogicPlugin.get_plugin_info(plugin_name)
|
||||
|
||||
custom_path = os.path.join(path_data, 'custom')
|
||||
|
||||
if 'platform' in plugin_info:
|
||||
if platform.system() not in plugin_info['platform']:
|
||||
return 'not_support_os'
|
||||
if 'running_type' in plugin_info:
|
||||
if app.config['config']['running_type'] not in plugin_info['running_type']:
|
||||
return 'not_support_running_type'
|
||||
git_clone_flag = True
|
||||
if git_clone_flag:
|
||||
# git clone
|
||||
command = ['git', '-C', custom_path, 'clone', plugin_info['git'], '--depth', '1']
|
||||
ret = Util.execute_command(command)
|
||||
return 'success'
|
||||
except Exception as exception:
|
||||
logger.error('Exception:%s', exception)
|
||||
logger.error(traceback.format_exc())
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def plugin_uninstall(plugin_name):
|
||||
logger.debug("plugin_name : %s", plugin_name)
|
||||
try:
|
||||
mod = __import__("%s" % (plugin_name), fromlist=[])
|
||||
mod_plugin_unload = getattr(mod, "plugin_unload")
|
||||
mod_plugin_unload()
|
||||
time.sleep(1)
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
try:
|
||||
custom_path = os.path.join(path_data, "custom")
|
||||
plugin_path = os.path.join(custom_path, plugin_name)
|
||||
if os.path.exists(plugin_path):
|
||||
try:
|
||||
import framework.common.celery as celery_task
|
||||
|
||||
celery_task.rmtree(plugin_path)
|
||||
except Exception as exception:
|
||||
try:
|
||||
logger.debug("plugin_uninstall")
|
||||
os.system('rmdir /S /Q "%s"' % plugin_path)
|
||||
except Exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
if os.path.exists(plugin_path):
|
||||
return "fail"
|
||||
else:
|
||||
return "success"
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
@staticmethod
|
||||
def custom_plugin_update():
|
||||
try:
|
||||
if os.environ.get("UPDATE_STOP") == "true":
|
||||
return
|
||||
if os.environ.get("PLUGIN_UPDATE_FROM_PYTHON") == "false":
|
||||
return
|
||||
custom_path = os.path.join(path_data, "custom")
|
||||
tmps = os.listdir(custom_path)
|
||||
for t in tmps:
|
||||
plugin_path = os.path.join(custom_path, t)
|
||||
try:
|
||||
if t == "torrent_info":
|
||||
os.remove(os.path.join(plugin_path, "info.json"))
|
||||
except Exception:
|
||||
pass
|
||||
if t.startswith("_"):
|
||||
continue
|
||||
if os.path.exists(os.path.join(plugin_path, ".git")):
|
||||
command = [
|
||||
"git",
|
||||
"-C",
|
||||
plugin_path,
|
||||
"reset",
|
||||
"--hard",
|
||||
"HEAD",
|
||||
]
|
||||
ret = Util.execute_command(command)
|
||||
command = ["git", "-C", plugin_path, "pull"]
|
||||
ret = Util.execute_command(command)
|
||||
logger.debug("%s\n%s", plugin_path, ret)
|
||||
else:
|
||||
logger.debug(f"{plugin_path} is not git repo")
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
@staticmethod
|
||||
def plugin_install_by_api(plugin_git, zip_url, zip_filename):
|
||||
logger.debug("plugin_git : %s", plugin_git)
|
||||
logger.debug("zip_url : %s", zip_url)
|
||||
logger.debug("zip_filename : %s", zip_filename)
|
||||
|
||||
is_git = True if plugin_git != None and plugin_git != "" else False
|
||||
ret = {}
|
||||
try:
|
||||
if is_git:
|
||||
name = plugin_git.split("/")[-1]
|
||||
else:
|
||||
name = zip_filename.split(".")[0]
|
||||
|
||||
custom_path = os.path.join(path_data, "custom")
|
||||
plugin_path = os.path.join(custom_path, name)
|
||||
logger.debug(plugin_path)
|
||||
plugin_info = None
|
||||
if os.path.exists(plugin_path):
|
||||
ret["ret"] = "already_exist"
|
||||
ret["log"] = "이미 설치되어 있습니다."
|
||||
else:
|
||||
if plugin_git and plugin_git.startswith("http"):
|
||||
for tag in ["main", "master"]:
|
||||
try:
|
||||
info_url = (
|
||||
plugin_git.replace(
|
||||
"github.com", "raw.githubusercontent.com"
|
||||
)
|
||||
+ "/%s/info.json" % tag
|
||||
)
|
||||
plugin_info = requests.get(info_url).json()
|
||||
if plugin_info is not None:
|
||||
break
|
||||
except:
|
||||
pass
|
||||
if zip_filename and zip_filename != "":
|
||||
import zipfile
|
||||
from tool_base import ToolBaseFile
|
||||
|
||||
zip_filepath = os.path.join(path_data, "tmp", zip_filename)
|
||||
extract_filepath = os.path.join(path_data, "tmp", name)
|
||||
logger.error(zip_url)
|
||||
logger.warning(zip_filepath)
|
||||
if ToolBaseFile.download(zip_url, zip_filepath):
|
||||
# logger.warning(os.path.exists(zip_filepath))
|
||||
with zipfile.ZipFile(zip_filepath, "r") as zip_ref:
|
||||
zip_ref.extractall(extract_filepath)
|
||||
plugin_info_filepath = os.path.join(
|
||||
extract_filepath, "info.json"
|
||||
)
|
||||
if os.path.exists(plugin_info_filepath):
|
||||
plugin_info = ToolBaseFile.read_json(
|
||||
plugin_info_filepath
|
||||
)
|
||||
if plugin_info == None:
|
||||
plugin_info = {}
|
||||
flag = True
|
||||
if "platform" in plugin_info:
|
||||
if platform.system() not in plugin_info["platform"]:
|
||||
ret["ret"] = "not_support_os"
|
||||
ret["log"] = "설치 가능한 OS가 아닙니다."
|
||||
flag = False
|
||||
if flag and "running_type" in plugin_info:
|
||||
if (
|
||||
app.config["config"]["running_type"]
|
||||
not in plugin_info["running_type"]
|
||||
):
|
||||
ret["ret"] = "not_support_running_type"
|
||||
ret["log"] = "설치 가능한 실행타입이 아닙니다."
|
||||
flag = False
|
||||
if flag and "policy_level" in plugin_info:
|
||||
if (
|
||||
plugin_info["policy_level"]
|
||||
> app.config["config"]["level"]
|
||||
):
|
||||
ret["ret"] = "policy_level"
|
||||
ret["log"] = "설치 가능 회원등급보다 낮습니다."
|
||||
flag = False
|
||||
if flag and "policy_point" in plugin_info:
|
||||
if (
|
||||
plugin_info["policy_level"]
|
||||
> app.config["config"]["point"]
|
||||
):
|
||||
ret["ret"] = "policy_level"
|
||||
ret["log"] = "설치 가능 포인트보다 낮습니다."
|
||||
flag = False
|
||||
|
||||
if flag:
|
||||
if plugin_git and plugin_git.startswith("http"):
|
||||
command = [
|
||||
"git",
|
||||
"-C",
|
||||
custom_path,
|
||||
"clone",
|
||||
plugin_git + ".git",
|
||||
"--depth",
|
||||
"1",
|
||||
]
|
||||
log = Util.execute_command(command)
|
||||
if zip_filename and zip_filename != "":
|
||||
import shutil
|
||||
|
||||
if os.path.exists(plugin_path) == False:
|
||||
shutil.move(extract_filepath, plugin_path)
|
||||
else:
|
||||
for tmp in os.listdir(extract_filepath):
|
||||
shutil.move(
|
||||
os.path.join(extract_filepath, tmp),
|
||||
plugin_path,
|
||||
)
|
||||
log = ""
|
||||
logger.debug(plugin_info)
|
||||
# 2021-12-31
|
||||
if "dependency" in plugin_info:
|
||||
for dep in plugin_info["dependency"]:
|
||||
for (
|
||||
key,
|
||||
value,
|
||||
) in LogicPlugin.get_plugin_list().items():
|
||||
if key == dep["name"]:
|
||||
logger.debug(
|
||||
f"Dependency 설치 - 이미 설치됨 : {dep['name']}"
|
||||
)
|
||||
break
|
||||
else:
|
||||
logger.debug(f"Dependency 설치 : {dep['home']}")
|
||||
LogicPlugin.plugin_install_by_api(
|
||||
dep["home"],
|
||||
dep.get("zip_url"),
|
||||
dep.get("zip_filename"),
|
||||
)
|
||||
# command = ['git', '-C', custom_path, 'clone', dep['home'], '--depth', '1']
|
||||
# ret = Util.execute_command(command)
|
||||
ret["ret"] = "success"
|
||||
ret["log"] = ["정상적으로 설치하였습니다. 재시작시 적용됩니다.", log]
|
||||
ret["log"] = "<br>".join(ret["log"])
|
||||
|
||||
except Exception as exception:
|
||||
logger.error("Exception:%s", exception)
|
||||
logger.error(traceback.format_exc())
|
||||
ret["ret"] = "exception"
|
||||
ret["log"] = str(exception)
|
||||
|
||||
return ret
|
||||
Reference in New Issue
Block a user