3.10
This commit is contained in:
@@ -1,8 +1,16 @@
|
|||||||
|
path_data: "."
|
||||||
|
#path_plugins_dev:
|
||||||
|
|
||||||
|
|
||||||
# 데이터 폴더 루트 경로
|
# 데이터 폴더 루트 경로
|
||||||
# 윈도우의 경우 폴더 구분 기호 \ 를 두개 사용
|
# 윈도우의 경우 폴더 구분 기호 \ 를 두개 사용
|
||||||
# 예) data_folder: "C:\\work\\data"
|
# 예) data_folder: "C:\\work\\data"
|
||||||
# 현재 폴더인 경우 .
|
# 현재 폴더인 경우 .
|
||||||
path_data: "."
|
#path_data: "."
|
||||||
|
#path_data: "/mnt/c/work/FlaskFarm/working"
|
||||||
|
|
||||||
|
# 개발용 플러그인 경로
|
||||||
|
#path_plugins_dev:
|
||||||
#path_data: "/mnt/c/work/FlaskFarm/working"
|
#path_data: "/mnt/c/work/FlaskFarm/working"
|
||||||
|
|
||||||
# gevent 사용여부
|
# gevent 사용여부
|
||||||
@@ -10,7 +18,6 @@ path_data: "."
|
|||||||
# 실행환경에 gevent 관련 패키지가 설치되어 있지 않는다면 값과 상관 없이 false로 동작.
|
# 실행환경에 gevent 관련 패키지가 설치되어 있지 않는다면 값과 상관 없이 false로 동작.
|
||||||
#use_gevent: true
|
#use_gevent: true
|
||||||
|
|
||||||
|
|
||||||
# celery 사용 여부
|
# celery 사용 여부
|
||||||
#use_celery: true
|
#use_celery: true
|
||||||
|
|
||||||
@@ -33,21 +40,18 @@ path_data: "."
|
|||||||
# - debug 값이 true인 경우에는 항상 false
|
# - debug 값이 true인 경우에는 항상 false
|
||||||
#plugin_update: true
|
#plugin_update: true
|
||||||
|
|
||||||
|
|
||||||
# running_type
|
# running_type
|
||||||
# termux, entware 인 경우 입력 함.
|
# termux, entware 인 경우 입력 함.
|
||||||
#running_type: "native"
|
#running_type: "native"
|
||||||
|
|
||||||
|
|
||||||
# 개발용 폴더만 로딩할 경우 사용
|
# 개발용 폴더만 로딩할 경우 사용
|
||||||
#plugin_loading_only_devpath: true
|
#plugin_loading_only_devpath: true
|
||||||
|
|
||||||
|
|
||||||
# 로딩할 플러그인 package 명
|
# 로딩할 플러그인 package 명
|
||||||
# 타 플러그인과 연동되는 플러그인 개발시 사용.
|
# 타 플러그인과 연동되는 플러그인 개발시 사용.
|
||||||
# import 로 런타임에 로딩할 수 있지만 타 패키지 메뉴 등은 표시되지 않음.
|
# import 로 런타임에 로딩할 수 있지만 타 패키지 메뉴 등은 표시되지 않음.
|
||||||
#plugin_loading_list: ['command', 'flaskcode']
|
#plugin_loading_list: ['command', 'flaskcode']
|
||||||
|
|
||||||
|
|
||||||
# 로딩 제외할 플러그인 package 명
|
# 로딩 제외할 플러그인 package 명
|
||||||
#plugin_except_list: ['terminal', 'membership']
|
#plugin_except_list: ['terminal', 'membership']
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#flask
|
#flask
|
||||||
Flask==1.1.1
|
Flask==1.1.1
|
||||||
Flask-SQLAlchemy
|
Flask-SQLAlchemy==2.5.1
|
||||||
Flask-Login==0.4.1
|
Flask-Login==0.4.1
|
||||||
Flask-Cors==3.0.8
|
Flask-Cors==3.0.8
|
||||||
Flask-Markdown
|
Flask-Markdown
|
||||||
|
|||||||
@@ -67,7 +67,8 @@ class Framework:
|
|||||||
self.app = Flask(__name__)
|
self.app = Flask(__name__)
|
||||||
self.__config_initialize('flask')
|
self.__config_initialize('flask')
|
||||||
|
|
||||||
self.db = SQLAlchemy(self.app, session_options={"autoflush": False})
|
self.__init_db()
|
||||||
|
|
||||||
|
|
||||||
if True or self.config['run_flask']:
|
if True or self.config['run_flask']:
|
||||||
from .scheduler import Job, Scheduler
|
from .scheduler import Job, Scheduler
|
||||||
@@ -96,7 +97,29 @@ class Framework:
|
|||||||
#DROPZONE_ALLOWED_FILE_TYPE = 'default, image, audio, video, text, app, *.*',
|
#DROPZONE_ALLOWED_FILE_TYPE = 'default, image, audio, video, text, app, *.*',
|
||||||
)
|
)
|
||||||
self.dropzone = Dropzone(self.app)
|
self.dropzone = Dropzone(self.app)
|
||||||
|
|
||||||
|
|
||||||
|
def __init_db(self):
|
||||||
|
# https://flask-sqlalchemy.palletsprojects.com/en/3.0.x/config/#flask_sqlalchemy.config.SQLALCHEMY_BINDS
|
||||||
|
# 어떤 편법도 불가. db를 사용하지 않아도 파일이 생김.
|
||||||
|
db_path = os.path.join(self.config['path_data'], 'db', 'system.db')
|
||||||
|
self.app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{db_path}' # 3.0에서 필수
|
||||||
|
self.app.config['SQLALCHEMY_BINDS'] = {'system':f'sqlite:///{db_path}'}
|
||||||
|
self.app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
||||||
|
|
||||||
|
_ = os.path.join(self.config['path_data'], 'plugins')
|
||||||
|
plugins = []
|
||||||
|
if os.path.exists(_):
|
||||||
|
plugins = os.listdir(_)
|
||||||
|
|
||||||
|
if self.config['path_plugins_dev'] != None and os.path.exists(self.config['path_plugins_dev']):
|
||||||
|
plugins += os.listdir(self.config['path_plugins_dev'])
|
||||||
|
|
||||||
|
for package_name in plugins:
|
||||||
|
db_path = os.path.join(self.config['path_data'], 'db', f'{package_name}.db')
|
||||||
|
self.app.config['SQLALCHEMY_BINDS'][package_name] = f'sqlite:///{db_path}'
|
||||||
|
self.db = SQLAlchemy(self.app, session_options={"autoflush": False})
|
||||||
|
|
||||||
|
|
||||||
def __init_celery(self):
|
def __init_celery(self):
|
||||||
try:
|
try:
|
||||||
@@ -158,7 +181,8 @@ class Framework:
|
|||||||
from system.setup import P
|
from system.setup import P
|
||||||
SystemInstance = P
|
SystemInstance = P
|
||||||
try:
|
try:
|
||||||
self.db.create_all()
|
with self.app.app_context():
|
||||||
|
self.db.create_all()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error('CRITICAL db.create_all()!!!')
|
self.logger.error('CRITICAL db.create_all()!!!')
|
||||||
self.logger.error(f'Exception:{str(e)}')
|
self.logger.error(f'Exception:{str(e)}')
|
||||||
@@ -200,7 +224,6 @@ class Framework:
|
|||||||
self.logger.info(f"### PORT: {self.config.get('port')}")
|
self.logger.info(f"### PORT: {self.config.get('port')}")
|
||||||
self.logger.info('### Now you can access App by webbrowser!!')
|
self.logger.info('### Now you can access App by webbrowser!!')
|
||||||
|
|
||||||
|
|
||||||
def __prepare_starting(self):
|
def __prepare_starting(self):
|
||||||
# 여기서 monkey.patch시 너무 늦다고 문제 발생
|
# 여기서 monkey.patch시 너무 늦다고 문제 발생
|
||||||
pass
|
pass
|
||||||
@@ -233,10 +256,6 @@ class Framework:
|
|||||||
self.config['notify_yaml_filepath'] = os.path.join(self.config['path_data'], 'db', 'notify.yaml')
|
self.config['notify_yaml_filepath'] = os.path.join(self.config['path_data'], 'db', 'notify.yaml')
|
||||||
elif mode == "flask":
|
elif mode == "flask":
|
||||||
self.app.secret_key = os.urandom(24)
|
self.app.secret_key = os.urandom(24)
|
||||||
#db_path = os.path.join(self.config['path_data'], 'db', 'system.db')
|
|
||||||
#self.app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{db_path}check_same_thread=False'
|
|
||||||
self.app.config['SQLALCHEMY_BINDS'] = {}
|
|
||||||
self.app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
|
||||||
self.app.config['TEMPLATES_AUTO_RELOAD'] = True
|
self.app.config['TEMPLATES_AUTO_RELOAD'] = True
|
||||||
self.app.config['JSON_AS_ASCII'] = False
|
self.app.config['JSON_AS_ASCII'] = False
|
||||||
elif mode == 'system_loading_after':
|
elif mode == 'system_loading_after':
|
||||||
@@ -327,7 +346,8 @@ class Framework:
|
|||||||
self.config['plugin_loading_list'] = []
|
self.config['plugin_loading_list'] = []
|
||||||
if self.config.get('plugin_except_list') == None:
|
if self.config.get('plugin_except_list') == None:
|
||||||
self.config['plugin_except_list'] = []
|
self.config['plugin_except_list'] = []
|
||||||
|
if self.config.get('path_plugins_dev') == None:
|
||||||
|
self.config['path_plugins_dev'] = None
|
||||||
|
|
||||||
|
|
||||||
def __make_default_dir(self):
|
def __make_default_dir(self):
|
||||||
|
|||||||
@@ -213,9 +213,11 @@ class PluginManager:
|
|||||||
|
|
||||||
# import가 끝나면 DB를 만든다.
|
# import가 끝나면 DB를 만든다.
|
||||||
# 플러그인 로드시 DB 초기화를 할 수 있다.
|
# 플러그인 로드시 DB 초기화를 할 수 있다.
|
||||||
|
|
||||||
if not F.config['run_celery']:
|
if not F.config['run_celery']:
|
||||||
try:
|
try:
|
||||||
F.db.create_all()
|
with F.app.app_context():
|
||||||
|
F.db.create_all()
|
||||||
except Exception as exception:
|
except Exception as exception:
|
||||||
F.logger.error('Exception:%s', exception)
|
F.logger.error('Exception:%s', exception)
|
||||||
F.logger.error(traceback.format_exc())
|
F.logger.error(traceback.format_exc())
|
||||||
|
|||||||
@@ -29,7 +29,8 @@
|
|||||||
<script src="{{ url_for('static', filename='js/ff_ui1.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/ff_ui1.js') }}"></script>
|
||||||
|
|
||||||
|
|
||||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.6/socket.io.js"></script>
|
<!--<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.6/socket.io.js"></script>-->
|
||||||
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.5.0/socket.io.js"></script>
|
||||||
<!-- 토글 -->
|
<!-- 토글 -->
|
||||||
<link href="https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.4.0/css/bootstrap4-toggle.min.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.4.0/css/bootstrap4-toggle.min.css" rel="stylesheet">
|
||||||
<script src="https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.4.0/js/bootstrap4-toggle.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.4.0/js/bootstrap4-toggle.min.js"></script>
|
||||||
|
|||||||
@@ -47,21 +47,20 @@ class Logic(object):
|
|||||||
return
|
return
|
||||||
|
|
||||||
for key, value in Logic.db_default.items():
|
for key, value in Logic.db_default.items():
|
||||||
if F.db.session.query(self.P.ModelSetting).filter_by(key=key).count() == 0:
|
if self.P.ModelSetting.get(key) == None:
|
||||||
F.db.session.add(self.P.ModelSetting(key, value))
|
self.P.ModelSetting.set(key, value)
|
||||||
|
|
||||||
for module in self.P.module_list:
|
for module in self.P.module_list:
|
||||||
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:
|
||||||
if page_instance.db_default is not None:
|
if page_instance.db_default is not None:
|
||||||
for key, value in page_instance.db_default.items():
|
for key, value in page_instance.db_default.items():
|
||||||
if F.db.session.query(self.P.ModelSetting).filter_by(key=key).count() == 0:
|
if self.P.ModelSetting.get(key) == None:
|
||||||
F.db.session.add(self.P.ModelSetting(key, value))
|
self.P.ModelSetting.set(key, value)
|
||||||
if module.db_default is not None:
|
if module.db_default is not None:
|
||||||
for key, value in module.db_default.items():
|
for key, value in module.db_default.items():
|
||||||
if F.db.session.query(self.P.ModelSetting).filter_by(key=key).count() == 0:
|
if self.P.ModelSetting.get(key) == None:
|
||||||
F.db.session.add(self.P.ModelSetting(key, value))
|
self.P.ModelSetting.set(key, value)
|
||||||
F.db.session.commit()
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.P.logger.error(f'Exception:{str(e)}')
|
self.P.logger.error(f'Exception:{str(e)}')
|
||||||
self.P.logger.error(traceback.format_exc())
|
self.P.logger.error(traceback.format_exc())
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from framework import F
|
|||||||
|
|
||||||
|
|
||||||
def get_model_setting(package_name, logger, table_name=None):
|
def get_model_setting(package_name, logger, table_name=None):
|
||||||
|
|
||||||
class ModelSetting(F.db.Model):
|
class ModelSetting(F.db.Model):
|
||||||
__tablename__ = '%s_setting' % package_name if table_name is None else table_name
|
__tablename__ = '%s_setting' % package_name if table_name is None else table_name
|
||||||
__table_args__ = {'mysql_collate': 'utf8_general_ci'}
|
__table_args__ = {'mysql_collate': 'utf8_general_ci'}
|
||||||
@@ -27,17 +27,19 @@ def get_model_setting(package_name, logger, table_name=None):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def get(key):
|
def get(key):
|
||||||
try:
|
try:
|
||||||
ret = F.db.session.query(ModelSetting).filter_by(key=key).first()
|
with F.app.app_context():
|
||||||
if ret is not None:
|
ret = F.db.session.query(ModelSetting).filter_by(key=key).first()
|
||||||
return ret.value.strip()
|
if ret is not None:
|
||||||
return None
|
return ret.value.strip()
|
||||||
|
return None
|
||||||
except Exception as exception:
|
except Exception as exception:
|
||||||
logger.error('Exception:%s %s', exception, key)
|
logger.error('Exception:%s %s', exception, key)
|
||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def has_key(key):
|
def has_key(key):
|
||||||
return (F.db.session.query(ModelSetting).filter_by(key=key).first() is not None)
|
with F.app.app_context():
|
||||||
|
return (F.db.session.query(ModelSetting).filter_by(key=key).first() is not None)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_int(key):
|
def get_int(key):
|
||||||
@@ -58,13 +60,14 @@ def get_model_setting(package_name, logger, table_name=None):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def set(key, value):
|
def set(key, value):
|
||||||
try:
|
try:
|
||||||
item = F.db.session.query(ModelSetting).filter_by(key=key).with_for_update().first()
|
with F.app.app_context():
|
||||||
if item is not None:
|
item = F.db.session.query(ModelSetting).filter_by(key=key).with_for_update().first()
|
||||||
item.value = value.strip() if value is not None else value
|
if item is not None:
|
||||||
F.db.session.commit()
|
item.value = value.strip() if value is not None else value
|
||||||
else:
|
F.db.session.commit()
|
||||||
F.db.session.add(ModelSetting(key, value.strip()))
|
else:
|
||||||
F.db.session.commit()
|
F.db.session.add(ModelSetting(key, value.strip()))
|
||||||
|
F.db.session.commit()
|
||||||
except Exception as exception:
|
except Exception as exception:
|
||||||
logger.error('Exception:%s %s', exception, key)
|
logger.error('Exception:%s %s', exception, key)
|
||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
|
|||||||
Reference in New Issue
Block a user