first commit

This commit is contained in:
2022-04-21 19:23:01 +09:00
commit cfd562fd13
152 changed files with 54937 additions and 0 deletions

346
lib/system/logic_plugin.py Normal file
View 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