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

2
.gitignore vendored
View File

@@ -1,6 +1,6 @@
# Byte-compiled / optimized / DLL files # Byte-compiled / optimized / DLL files
__pycache__/ __pycache__/
*.py[cod] *.py[co]
*$py.class *$py.class
# C extensions # C extensions

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

@@ -21,19 +21,8 @@ class PluginManager:
@classmethod @classmethod
def get_plugin_name_list(cls): 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 = [] plugins = []
#2019-07-17 #2019-07-17
try: try:
plugin_path = os.path.join(F.config['path_data'], 'plugins') plugin_path = os.path.join(F.config['path_data'], 'plugins')
if os.path.exists(plugin_path) == True and os.path.isdir(plugin_path) == True: if os.path.exists(plugin_path) == True and os.path.isdir(plugin_path) == True:
@@ -115,51 +104,18 @@ class PluginManager:
F.logger.debug(plugins) F.logger.debug(plugins)
for plugin_name in 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}]') F.logger.debug(f'[+] PLUGIN LOADING Start.. [{plugin_name}]')
entity = cls.all_package_list[plugin_name] entity = cls.all_package_list[plugin_name]
entity['version'] = '3' entity['version'] = '3'
try: try:
mod = __import__('%s' % (plugin_name), fromlist=[]) mod = __import__('%s' % (plugin_name), fromlist=[])
mod_plugin_info = None 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: try:
mod_plugin_info = getattr(mod, 'plugin_info') mod_plugin_info = getattr(mod, 'plugin_info')
entity['module'] = mod 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: 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') F.logger.info(f'[!] PLUGIN_INFO not exist : [{plugin_name}] - is FF')
if mod_plugin_info == None: if mod_plugin_info == None:
try: try:
mod = __import__(f'{plugin_name}.setup', fromlist=['setup']) mod = __import__(f'{plugin_name}.setup', fromlist=['setup'])
@@ -168,13 +124,10 @@ class PluginManager:
F.logger.error(f'Exception:{str(e)}') F.logger.error(f'Exception:{str(e)}')
F.logger.error(traceback.format_exc()) F.logger.error(traceback.format_exc())
F.logger.warning(f'[!] NOT normal plugin : [{plugin_name}]') F.logger.warning(f'[!] NOT normal plugin : [{plugin_name}]')
#entity['version'] = 'not_plugin'
try: try:
if entity['version'] != '4': if entity['version'] != '4':
mod_blue_print = getattr(mod, 'blueprint') mod_blue_print = getattr(mod, 'blueprint')
else: else:
entity['setup_mod'] = mod entity['setup_mod'] = mod
entity['P'] = getattr(mod, 'P') 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]['status'] = 'import fail'
cls.all_package_list[plugin_name]['log'] = traceback.format_exc() 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']: if not F.config['run_celery']:
try: try:
@@ -225,17 +161,6 @@ class PluginManager:
F.logger.debug('db.create_all error') F.logger.debug('db.create_all error')
if not F.config['run_flask']: 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 return
for key, entity in cls.plugin_list.items(): 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]['loading'] = False
cls.all_package_list[key]['status'] = 'plugin_load error' cls.all_package_list[key]['status'] = 'plugin_load error'
cls.all_package_list[key]['log'] = traceback.format_exc() 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는 위에서 로딩 # mod는 위에서 로딩
if key != 'mod': if key != 'mod':
t = threading.Thread(target=func, args=(mod_plugin_load, key)) t = threading.Thread(target=func, args=(mod_plugin_load, key))

View File

@@ -16,34 +16,30 @@ class Logic(object):
self.P = P self.P = P
def plugin_load(self): def plugin_load(self):
try: self.P.logger.debug('%s plugin_load', self.P.package_name)
self.P.logger.debug('%s plugin_load', self.P.package_name) self.db_init()
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: 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: if module.page_list is not None:
for page_instance in module.page_list: 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): def db_init(self):
try: try:

View File

@@ -1,4 +1,5 @@
import traceback import traceback
from datetime import datetime
from framework import F from framework import F
@@ -32,8 +33,8 @@ def get_model_setting(package_name, logger, table_name=None):
if ret is not None: if ret is not None:
return ret.value.strip() return ret.value.strip()
return None return None
except Exception as exception: except Exception as e:
logger.error('Exception:%s %s', exception, key) logger.error(f"Exception:{str(e)} [{key}]")
logger.error(traceback.format_exc()) logger.error(traceback.format_exc())
@staticmethod @staticmethod
@@ -45,16 +46,24 @@ def get_model_setting(package_name, logger, table_name=None):
def get_int(key): def get_int(key):
try: try:
return int(ModelSetting.get(key)) return int(ModelSetting.get(key))
except Exception as exception: except Exception as e:
logger.error('Exception:%s %s', exception, key) logger.error(f"Exception:{str(e)} [{key}]")
logger.error(traceback.format_exc()) logger.error(traceback.format_exc())
@staticmethod @staticmethod
def get_bool(key): def get_bool(key):
try: try:
return (ModelSetting.get(key) == 'True') return (ModelSetting.get(key) == 'True')
except Exception as exception: except Exception as e:
logger.error('Exception:%s %s', exception, key) 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()) logger.error(traceback.format_exc())
@staticmethod @staticmethod
@@ -68,8 +77,8 @@ def get_model_setting(package_name, logger, table_name=None):
else: else:
F.db.session.add(ModelSetting(key, value.strip())) F.db.session.add(ModelSetting(key, value.strip()))
F.db.session.commit() F.db.session.commit()
except Exception as exception: except Exception as e:
logger.error('Exception:%s %s', exception, key) logger.error(f"Exception:{str(e)} [{key}]")
logger.error(traceback.format_exc()) logger.error(traceback.format_exc())
@staticmethod @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 = ModelSetting.db_list_to_dict(F.db.session.query(ModelSetting).all())
ret['package_name'] = package_name ret['package_name'] = package_name
return ret return ret
except Exception as exception: except Exception as e:
logger.error('Exception:%s', exception) logger.error(f"Exception:{str(e)}")
logger.error(traceback.format_exc()) logger.error(traceback.format_exc())
@@ -99,8 +108,8 @@ def get_model_setting(package_name, logger, table_name=None):
entity.value = value entity.value = value
F.db.session.commit() F.db.session.commit()
return True, change_list return True, change_list
except Exception as exception: except Exception as e:
logger.error('Exception:%s', exception) logger.error(f"Exception:{str(e)}")
logger.error(traceback.format_exc()) logger.error(traceback.format_exc())
logger.debug('Error Key:%s Value:%s', key, value) logger.debug('Error Key:%s Value:%s', key, value)
return False, [] 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 = [x.split(comment)[0].strip() for x in value.split(delimeter)]
values = ModelSetting.get_list_except_empty(values) values = ModelSetting.get_list_except_empty(values)
return values return values
except Exception as exception: except Exception as e:
logger.error('Exception:%s', exception) logger.error(f"Exception:{str(e)}")
logger.error(traceback.format_exc()) logger.error(traceback.format_exc())
logger.error('Error Key:%s Value:%s', key, value) 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.aes import SupportAES
from .base.discord import SupportDiscord from .base.discord import SupportDiscord
from .base.file import SupportFile from .base.file import SupportFile
from .base.sc import SupportSC
from .base.string import SupportString from .base.string import SupportString
from .base.subprocess import SupportSubprocess from .base.sub_process import SupportSubprocess
from .base.telegram import SupportTelegram from .base.telegram import SupportTelegram
from .base.util import (AlchemyEncoder, SingletonClass, SupportUtil, from .base.util import (AlchemyEncoder, SingletonClass, SupportUtil,
default_headers, pt) default_headers, pt)

View File

@@ -1,10 +1,16 @@
import os, base64, traceback import base64
from Crypto.Cipher import AES import os
import traceback
from Crypto import Random from Crypto import Random
from Crypto.Cipher import AES
from . import logger from . import logger
BS = 16 BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS) 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[0:-s[-1]]
unpad = lambda s : s[:-ord(s[len(s)-1:])]
key = b'140b41b22a29beb4061bda66b6747e14' key = b'140b41b22a29beb4061bda66b6747e14'
class SupportAES(object): class SupportAES(object):
@@ -39,5 +45,56 @@ class SupportAES(object):
iv = enc[:16] iv = enc[:16]
if len(iv) != 16: if len(iv) != 16:
iv = os.urandom(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 ) cipher = AES.new(key if mykey is None else mykey, AES.MODE_CBC, iv )
return unpad(cipher.decrypt( enc[16:] )).decode() 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 @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', 'web_title': 'Home',
'use_apikey': 'False', 'use_apikey': 'False',
'apikey': ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10)), '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)} * * *', f'restart_interval': f'{random.randint(0,59)} {random.randint(1,23)} * * *',
'restart_notify': 'False', 'restart_notify': 'False',
'theme' : 'Cerulean', 'theme' : 'Cerulean',