This commit is contained in:
flaskfarm
2022-10-17 13:28:55 +09:00
parent fefdbada91
commit 259daa8ad8
13 changed files with 243 additions and 139 deletions

46
lib/cli/code_encode.py Normal file
View File

@@ -0,0 +1,46 @@
import argparse
import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(__file__)))
from support import SupportFile, SupportSC, logger
class CodeEncode:
def start_folder(self, folderpath):
for name in os.listdir(folderpath):
filepath = os.path.join(folderpath, name)
if os.path.isfile(filepath) and name not in ['setup.py', '__init__.py'] and name.endswith('.py'):
self.encode_file(filepath)
def encode_file(self, filepath):
if filepath.endswith(".py") == False:
logger.info("is not .py file")
return
text = SupportFile.read_file(filepath)
data = SupportSC.encode(text, 1)
SupportFile.write_file(filepath + 'f', data)
logger.info(f"Create {os.path.basename(filepath + 'f')}")
def process_args(self):
parser = argparse.ArgumentParser()
parser.add_argument('--mode', default='encode')
parser.add_argument('--source', required=True, help=u'absolute path. folder or file')
args = parser.parse_args()
if SupportSC.LIBRARY_LOADING == False:
logger.error("sc import fail")
return
if os.path.exists(args.source):
if os.path.isdir(args.source):
self.start_folder(args.source)
elif os.path.isfile(args.source):
self.encode_file(args.source)
if __name__== "__main__":
CodeEncode().process_args()
# python C:\work\FlaskFarm\flaskfarm\lib\cli\code_encode.py --source=C:\work\FlaskFarm\data\LOADING\klive_plus\source_spotv.py

View File

@@ -204,7 +204,7 @@ class Framework:
from .init_web import jinja_initialize
jinja_initialize(self.app)
from .init_plugin import PluginManager
self.PluginManager = PluginManager
PluginManager.plugin_update()

View File

@@ -21,19 +21,8 @@ class PluginManager:
@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 = []
#2019-07-17
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:
@@ -115,51 +104,18 @@ class PluginManager:
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 = cls.all_package_list[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.info(f'[!] PLUGIN_INFO not exist : [{plugin_name}] - is FF')
if mod_plugin_info == None:
try:
mod = __import__(f'{plugin_name}.setup', fromlist=['setup'])
@@ -168,13 +124,10 @@ class PluginManager:
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')
@@ -196,24 +149,7 @@ class PluginManager:
cls.all_package_list[plugin_name]['status'] = 'import fail'
cls.all_package_list[plugin_name]['log'] = traceback.format_exc()
#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:
@@ -225,17 +161,6 @@ class PluginManager:
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():
@@ -259,6 +184,13 @@ class PluginManager:
cls.all_package_list[key]['loading'] = False
cls.all_package_list[key]['status'] = 'plugin_load error'
cls.all_package_list[key]['log'] = traceback.format_exc()
if key in cls.plugin_menus:
del cls.plugin_menus[key]
from framework.init_menu import MenuManager
MenuManager.init_menu()
# mod는 위에서 로딩
if key != 'mod':
t = threading.Thread(target=func, args=(mod_plugin_load, key))

View File

@@ -16,34 +16,30 @@ class Logic(object):
self.P = P
def plugin_load(self):
try:
self.P.logger.debug('%s plugin_load', self.P.package_name)
self.db_init()
self.P.logger.debug('%s plugin_load', self.P.package_name)
self.db_init()
for module in self.P.module_list:
module.migration()
if module.page_list is not None:
for page_instance in module.page_list:
page_instance.migration()
for module in self.P.module_list:
module.plugin_load()
if module.page_list is not None:
for page_instance in module.page_list:
page_instance.plugin_load()
if self.P.ModelSetting is not None:
for module in self.P.module_list:
module.migration()
key = f'{module.name}_auto_start'
if self.P.ModelSetting.has_key(key) and self.P.ModelSetting.get_bool(key):
self.scheduler_start(module.name)
if module.page_list is not None:
for page_instance in module.page_list:
page_instance.migration()
key = f'{module.name}_{page_instance.name}_auto_start'
if self.P.ModelSetting.has_key(key) and self.P.ModelSetting.get_bool(key):
self.scheduler_start_sub(module.name, page_instance.name)
for module in self.P.module_list:
module.plugin_load()
if module.page_list is not None:
for page_instance in module.page_list:
page_instance.plugin_load()
if self.P.ModelSetting is not None:
for module in self.P.module_list:
key = f'{module.name}_auto_start'
if self.P.ModelSetting.has_key(key) and self.P.ModelSetting.get_bool(key):
self.scheduler_start(module.name)
if module.page_list is not None:
for page_instance in module.page_list:
key = f'{module.name}_{page_instance.name}_auto_start'
if self.P.ModelSetting.has_key(key) and self.P.ModelSetting.get_bool(key):
self.scheduler_start_sub(module.name, page_instance.name)
except Exception as e:
self.P.logger.error(f'Exception:{str(e)}')
self.P.logger.error(traceback.format_exc())
def db_init(self):
try:

View File

@@ -1,4 +1,5 @@
import traceback
from datetime import datetime
from framework import F
@@ -32,8 +33,8 @@ def get_model_setting(package_name, logger, table_name=None):
if ret is not None:
return ret.value.strip()
return None
except Exception as exception:
logger.error('Exception:%s %s', exception, key)
except Exception as e:
logger.error(f"Exception:{str(e)} [{key}]")
logger.error(traceback.format_exc())
@staticmethod
@@ -45,16 +46,24 @@ def get_model_setting(package_name, logger, table_name=None):
def get_int(key):
try:
return int(ModelSetting.get(key))
except Exception as exception:
logger.error('Exception:%s %s', exception, key)
except Exception as e:
logger.error(f"Exception:{str(e)} [{key}]")
logger.error(traceback.format_exc())
@staticmethod
def get_bool(key):
try:
return (ModelSetting.get(key) == 'True')
except Exception as exception:
logger.error('Exception:%s %s', exception, key)
except Exception as e:
logger.error(f"Exception:{str(e)} [{key}]")
logger.error(traceback.format_exc())
@staticmethod
def get_datetime(key):
try:
return datetime.strptime(ModelSetting.get(key), '%Y-%m-%d %H:%M:%S.%f')
except Exception as e:
logger.error(f"Exception:{str(e)} [{key}]")
logger.error(traceback.format_exc())
@staticmethod
@@ -68,8 +77,8 @@ def get_model_setting(package_name, logger, table_name=None):
else:
F.db.session.add(ModelSetting(key, value.strip()))
F.db.session.commit()
except Exception as exception:
logger.error('Exception:%s %s', exception, key)
except Exception as e:
logger.error(f"Exception:{str(e)} [{key}]")
logger.error(traceback.format_exc())
@staticmethod
@@ -78,8 +87,8 @@ def get_model_setting(package_name, logger, table_name=None):
ret = ModelSetting.db_list_to_dict(F.db.session.query(ModelSetting).all())
ret['package_name'] = package_name
return ret
except Exception as exception:
logger.error('Exception:%s', exception)
except Exception as e:
logger.error(f"Exception:{str(e)}")
logger.error(traceback.format_exc())
@@ -99,8 +108,8 @@ def get_model_setting(package_name, logger, table_name=None):
entity.value = value
F.db.session.commit()
return True, change_list
except Exception as exception:
logger.error('Exception:%s', exception)
except Exception as e:
logger.error(f"Exception:{str(e)}")
logger.error(traceback.format_exc())
logger.debug('Error Key:%s Value:%s', key, value)
return False, []
@@ -115,8 +124,8 @@ def get_model_setting(package_name, logger, table_name=None):
values = [x.split(comment)[0].strip() for x in value.split(delimeter)]
values = ModelSetting.get_list_except_empty(values)
return values
except Exception as exception:
logger.error('Exception:%s', exception)
except Exception as e:
logger.error(f"Exception:{str(e)}")
logger.error(traceback.format_exc())
logger.error('Error Key:%s Value:%s', key, value)

View File

@@ -15,8 +15,9 @@ logger = get_logger()
from .base.aes import SupportAES
from .base.discord import SupportDiscord
from .base.file import SupportFile
from .base.sc import SupportSC
from .base.string import SupportString
from .base.subprocess import SupportSubprocess
from .base.sub_process import SupportSubprocess
from .base.telegram import SupportTelegram
from .base.util import (AlchemyEncoder, SingletonClass, SupportUtil,
default_headers, pt)

View File

@@ -1,10 +1,16 @@
import os, base64, traceback
from Crypto.Cipher import AES
import base64
import os
import traceback
from Crypto import Random
from Crypto.Cipher import AES
from . import logger
BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
unpad = lambda s : s[0:-s[-1]]
pad = lambda s: s + (BS - len(s.encode('utf-8')) % BS) * chr(BS - len(s.encode('utf-8')) % BS)
#unpad = lambda s : s[0:-s[-1]]
unpad = lambda s : s[:-ord(s[len(s)-1:])]
key = b'140b41b22a29beb4061bda66b6747e14'
class SupportAES(object):
@@ -39,5 +45,56 @@ class SupportAES(object):
iv = enc[:16]
if len(iv) != 16:
iv = os.urandom(16)
if mykey is not None and type(mykey) == type(''):
mykey = mykey.encode()
cipher = AES.new(key if mykey is None else mykey, AES.MODE_CBC, iv )
return unpad(cipher.decrypt( enc[16:] )).decode()
@classmethod
def md5(cls, text):
import hashlib
enc = hashlib.md5()
enc.update(text.encode())
return enc.hexdigest()
@classmethod
def encrypt_(cls, raw, mykey=None, iv=None):
try:
Random.atfork()
except Exception as exception:
logger.error('Exception:%s', exception)
logger.error(traceback.format_exc())
raw = pad(raw)
if type(raw) == type(''):
raw = raw.encode()
if mykey is not None and type(mykey) == type(''):
mykey = mykey.encode()
if iv == None:
iv = Random.new().read( AES.block_size )
elif iv is not None and type(iv) == type(''):
iv = iv.encode()
cipher = AES.new(key if mykey is None else mykey, AES.MODE_CBC, iv )
try:
tmp = cipher.encrypt( raw )
except Exception as exception:
logger.error('Exception:%s', exception)
logger.error(traceback.format_exc())
tmp = cipher.encrypt( raw.encode() )
ret = base64.b64encode( tmp )
ret = ret.decode()
return ret
@classmethod
def decrypt_(cls, enc, mykey=None, iv=None):
enc = base64.b64decode(enc)
if iv == None:
iv = os.urandom(16)
elif iv is not None and type(iv) == type(''):
iv = iv.encode()
if mykey is not None and type(mykey) == type(''):
mykey = mykey.encode()
cipher = AES.new(key if mykey is None else mykey, AES.MODE_CBC, iv )
return unpad(cipher.decrypt( enc )).decode()

View File

@@ -94,23 +94,6 @@ class SupportFile(object):
@classmethod
def write(cls, data, filepath, mode='w'):
try:
import codecs
ofp = codecs.open(filepath, mode, encoding='utf8')
if isinstance(data, bytes) and mode == 'w':
data = data.decode('utf-8')
ofp.write(data)
ofp.close()
return True
except Exception as exception:
logger.debug('Exception:%s', exception)
logger.debug(traceback.format_exc())
return False
@classmethod

79
lib/support/base/sc.py Normal file
View File

@@ -0,0 +1,79 @@
import argparse
import os
import platform
import re
import sys
import traceback
from . import logger
class SupportSC:
LIBRARY_LOADING = False
try:
if platform.system() == 'Linux':
if (platform.platform().find('86') == -1 and platform.platform().find('64') == -1) or platform.platform().find('arch') != -1 or platform.platform().find('arm') != -1:
sys.path.insert(2, os.path.join(os.path.dirname(os.path.abspath(__file__)), 'lib', 'sc', 'LinuxArm'))
else:
sys.path.insert(2, os.path.join(os.path.dirname(os.path.abspath(__file__)), 'lib', 'sc', 'Linux'))
if platform.system() == 'Windows':
sys.path.append(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'sc', 'Windows'))
import sc
LIBRARY_LOADING = True
except:
pass
@classmethod
def encode(cls, text, mode=0):
try:
import sc
return sc.encode(text, mode)
except Exception as e:
logger.error(f'Exception:{str(e)}')
logger.error(traceback.format_exc())
return None
@classmethod
def decode(cls, text):
try:
import sc
return sc.decode(text)
except:
return None
@classmethod
def load_module(cls, module_name, module_code):
try:
import sc
mod = sc.load_module(module_name, module_code)
sys.modules[mod] = mod
logger.warning(f"C-LOADING : {module_name}")
return mod
except Exception as e:
logger.error(f'Exception:{str(e)}')
logger.error(traceback.format_exc())
@classmethod
def load_module_P(cls, plugin_ins, filename):
return cls.load_module_f(plugin_ins.setting['filepath'], filename)
@classmethod
def load_module_f(cls, package_filepath, filename):
dirname = os.path.dirname(package_filepath)
filepath = os.path.join(dirname, filename + '.pyf')
if os.path.exists(filepath) and os.path.exists(filepath):
from support import SupportFile
code = SupportFile.read_file(filepath)
return cls.load_module(f"{os.path.basename(dirname)}.{filename}", code)
@classmethod
def td(self, mediacode, ts, url):
try:
import sc
ret = sc.td1(mediacode, str(ts), url).strip()
ret = re.sub('[^ -~]+', '', ret).strip()
return ret
except:
return None

Binary file not shown.

View File

@@ -21,6 +21,7 @@ class ModuleSetting(PluginModuleBase):
'web_title': 'Home',
'use_apikey': 'False',
'apikey': ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10)),
'app_id': ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10)),
f'restart_interval': f'{random.randint(0,59)} {random.randint(1,23)} * * *',
'restart_notify': 'False',
'theme' : 'Cerulean',