Files
youtube-dl/lib/framework/init_plugin.py
flaskfarm b4e737a6b2 update
2022-10-06 14:39:43 +09:00

299 lines
14 KiB
Python

import os
import sys
import threading
import traceback
from framework import F
class PluginManager:
plugin_list = {}
plugin_menus = {}
setting_menus = []
@classmethod
def get_plugin_name_list(cls):
#if not app.config['config']['auth_status']:
# return
"""
plugin_path = os.path.join(frame.config['path_app'], 'plugins')
sys.path.insert(0, plugin_path)
from system import SystemModelSetting
plugins = os.listdir(plugin_path)
"""
plugins = []
pass_include = []
except_plugin_list = []
#2019-07-17
if F.config.get('plugin_loading_only_devpath', None) != True:
try:
plugin_path = os.path.join(F.config['path_data'], 'plugins')
if os.path.exists(plugin_path) == True and os.path.isdir(plugin_path) == True:
sys.path.insert(1, plugin_path)
tmps = os.listdir(plugin_path)
add_plugin_list = []
for t in tmps:
if not t.startswith('_') and os.path.isdir(os.path.join(plugin_path, t)):
add_plugin_list.append(t)
plugins = plugins + add_plugin_list
pass_include = pass_include + add_plugin_list
except Exception as exception:
F.logger.error('Exception:%s', exception)
F.logger.error(traceback.format_exc())
# 2018-09-04
try:
plugin_path = F.SystemModelSetting.get('plugin_dev_path')
if plugin_path != '':
if os.path.exists(plugin_path):
sys.path.insert(0, plugin_path)
tmps = os.listdir(plugin_path)
add_plugin_list = []
for t in tmps:
if not t.startswith('_') and os.path.isdir(os.path.join(plugin_path, t)):
add_plugin_list.append(t)
plugins = plugins + add_plugin_list
pass_include = pass_include + add_plugin_list
except Exception as exception:
F.logger.error('Exception:%s', exception)
F.logger.error(traceback.format_exc())
# plugin_loading_list
try:
plugin_loading_list = F.config.get('plugin_loading_list', None)
if plugin_loading_list != None and (type(plugin_loading_list) == type([]) and len(plugin_loading_list)) > 0:
new_plugins = []
for _ in plugins:
if _ in plugin_loading_list:
new_plugins.append(_)
plugins = new_plugins
except Exception as exception:
F.logger.error('Exception:%s', exception)
F.logger.error(traceback.format_exc())
# plugin_except_list
try:
plugin_except_list = F.config.get('plugin_except_list', None)
if plugin_except_list != None and (type(plugin_except_list) == type([]) and len(plugin_except_list)) > 0:
new_plugins = []
for _ in plugins:
if _ not in plugin_except_list:
new_plugins.append(_)
plugins = new_plugins
except Exception as exception:
F.logger.error('Exception:%s', exception)
F.logger.error(traceback.format_exc())
return plugins
# menu, blueprint, plugin_info, plugin_load, plugin_unload
@classmethod
def plugin_init(cls):
try:
plugins = cls.get_plugin_name_list()
plugins = sorted(plugins)
F.logger.debug(plugins)
for plugin_name in plugins:
#logger.debug(len(system.LogicPlugin.current_loading_plugin_list))
#if plugin_name.startswith('_'):
# continue
#if plugin_name == 'terminal' and platform.system() == 'Windows':
# continue
#if plugin_name in except_plugin_list:
# F.logger.debug('Except plugin : %s' % frame.plugin_menu)
# continue
F.logger.debug(f'[+] PLUGIN LOADING Start.. [{plugin_name}]')
entity = {'version':'3'}
try:
mod = __import__('%s' % (plugin_name), fromlist=[])
mod_plugin_info = None
# 2021-12-31
#import system
#if plugin_name not in system.LogicPlugin.current_loading_plugin_list:
# system.LogicPlugin.current_loading_plugin_list[plugin_name] = {'status':'loading'}
try:
mod_plugin_info = getattr(mod, 'plugin_info')
entity['module'] = mod
"""
if 'category' not in mod_plugin_info and 'category_name' in mod_plugin_info:
mod_plugin_info['category'] = mod_plugin_info['category_name']
if 'policy_point' in mod_plugin_info:
if mod_plugin_info['policy_point'] > app.config['config']['point']:
system.LogicPlugin.current_loading_plugin_list[plugin_name]['status'] = 'violation_policy_point'
continue
if 'policy_level' in mod_plugin_info:
if mod_plugin_info['policy_level'] > app.config['config']['level']:
system.LogicPlugin.current_loading_plugin_list[plugin_name]['status'] = 'violation_policy_level'
continue
if 'category' in mod_plugin_info and mod_plugin_info['category'] == 'beta':
if SystemModelSetting.get_bool('use_beta') == False:
system.LogicPlugin.current_loading_plugin_list[plugin_name]['status'] = 'violation_beta'
continue
"""
except Exception as exception:
#logger.error('Exception:%s', exception)
#logger.error(traceback.format_exc())
#mod_plugin_info = getattr(mod, 'setup')
F.logger.warning(f'[!] PLUGIN_INFO not exist : [{plugin_name}]')
if mod_plugin_info == None:
try:
mod = __import__(f'{plugin_name}.setup', fromlist=['setup'])
entity['version'] = '4'
except Exception as e:
F.logger.error(f'Exception:{str(e)}')
F.logger.error(traceback.format_exc())
F.logger.warning(f'[!] NOT normal plugin : [{plugin_name}]')
#entity['version'] = 'not_plugin'
try:
if entity['version'] != '4':
mod_blue_print = getattr(mod, 'blueprint')
else:
entity['setup_mod'] = mod
entity['P'] = getattr(mod, 'P')
mod_blue_print = getattr(entity['P'], 'blueprint')
if mod_blue_print:
#if plugin_name in pass_include or is_include_menu(plugin_name):
F.app.register_blueprint(mod_blue_print)
except Exception as exception:
#logger.error('Exception:%s', exception)
#logger.error(traceback.format_exc())
F.logger.warning(f'[!] BLUEPRINT not exist : [{plugin_name}]')
cls.plugin_list[plugin_name] = entity
#system.LogicPlugin.current_loading_plugin_list[plugin_name]['status'] = 'success'
#system.LogicPlugin.current_loading_plugin_list[plugin_name]['info'] = mod_plugin_info
except Exception as exception:
F.logger.error('Exception:%s', exception)
F.logger.error(traceback.format_exc())
F.logger.debug('no blueprint')
#from tool_base import d
#logger.error(d(system.LogicPlugin.current_loading_plugin_list))
# 2021-07-01 모듈에 있는 DB 테이블 생성이 안되는 문제
# 기존 구조 : db.create_all() => 모듈 plugin_load => celery task 등록 후 리턴
# 변경 구조 : 모듈 plugin_load => db.create_all() => celery인 경우 리턴
# plugin_load 를 해야 하위 로직에 있는 DB가 로딩된다.
# plugin_load 에 db는 사용하는 코드가 있으면 안된다. (테이블도 없을 때 에러발생)
try:
#logger.warning('module plugin_load in celery ')
cls.plugin_list['mod']['module'].plugin_load()
except Exception as exception:
F.logger.debug(f'mod plugin_load error!!')
#logger.error('Exception:%s', exception)
#logger.error(traceback.format_exc())
# import가 끝나면 DB를 만든다.
# 플러그인 로드시 DB 초기화를 할 수 있다.
if not F.config['run_celery']:
try:
F.db.create_all()
except Exception as exception:
F.logger.error('Exception:%s', exception)
F.logger.error(traceback.format_exc())
F.logger.debug('db.create_all error')
if not F.config['run_flask']:
# 2021-06-03
# 모듈의 로직에 있는 celery 함수는 등록해주어야한다.
#try:
# logger.warning('module plugin_load in celery ')
# plugin_instance_list['mod'].plugin_load()
#except Exception as exception:
# logger.error('module plugin_load error')
# logger.error('Exception:%s', exception)
# logger.error(traceback.format_exc())
# 2021-07-01
# db때문에 위에서 로딩함.
return
for key, entity in cls.plugin_list.items():
try:
mod_plugin_load = None
if entity['version'] == '3':
mod_plugin_load = getattr(entity['module'], 'plugin_load')
elif entity['version'] == '4':
mod_plugin_load = getattr(entity['P'], 'plugin_load')
#if mod_plugin_load and (key in pass_include or is_include_menu(key)):
if mod_plugin_load:
def func(mod_plugin_load, key):
try:
F.logger.debug(f'[!] plugin_load threading start : [{key}]')
#mod.plugin_load()
mod_plugin_load()
F.logger.debug(f'[!] plugin_load threading end : [{key}]')
except Exception as exception:
F.logger.error('### plugin_load exception : %s', key)
F.logger.error('Exception:%s', exception)
F.logger.error(traceback.format_exc())
# mod는 위에서 로딩
if key != 'mod':
t = threading.Thread(target=func, args=(mod_plugin_load, key))
t.setDaemon(True)
t.start()
#if key == 'mod':
# t.join()
except Exception as exception:
F.logger.debug(f'[!] PLUGIN_LOAD function not exist : [{key}]')
#logger.error('Exception:%s', exception)
#logger.error(traceback.format_exc())
#logger.debug('no init_scheduler')
try:
mod_menu = None
if entity['version'] == '3':
mod_menu = getattr(entity['module'], 'menu')
elif entity['version'] == '4':
mod_menu = getattr(entity['P'], 'menu')
if mod_menu:# and (key in pass_include or is_include_menu(key)):
cls.plugin_menus[key]= {'menu':mod_menu, 'match':False}
if entity['version'] == '4':
setting_menu = getattr(entity['P'], 'setting_menu')
if setting_menu != None:
cls.setting_menus.append(setting_menu)
except Exception as exception:
F.logger.debug('no menu')
F.logger.debug('### plugin_load threading all start.. : %s ', len(cls.plugin_list))
# 모든 모듈을 로드한 이후에 app 등록, table 생성, start
except Exception as exception:
F.logger.error('Exception:%s', exception)
F.logger.error(traceback.format_exc())
@classmethod
def plugin_unload(cls):
for key, entity in cls.plugin_list.items():
try:
if entity['version'] == '3':
mod_plugin_unload = getattr(entity['module'], 'plugin_unload')
elif entity['version'] == '4':
mod_plugin_unload = getattr(entity['P'], 'plugin_unload')
#if plugin_name == 'rss':
# continue
#mod_plugin_unload = getattr(mod, 'plugin_unload')
if mod_plugin_unload:
mod_plugin_unload()
#mod.plugin_unload()
except Exception as e:
F.logger.error('module:%s', key)
F.logger.error(f'Exception:{str(e)}')
F.logger.error(traceback.format_exc())
try:
from system.setup import P
P.plugin_unload()
except Exception as e:
F.logger.error(f'Exception:{str(e)}')
F.logger.error(traceback.format_exc())