test
This commit is contained in:
14
lib/plugin/__init__.py
Normal file
14
lib/plugin/__init__.py
Normal file
@@ -0,0 +1,14 @@
|
||||
from framework import logger
|
||||
from .model_setting import get_model_setting
|
||||
from .logic import Logic
|
||||
from .route import default_route, default_route_socketio_module, default_route_socketio_page, default_route_single_module
|
||||
from .logic_module_base import PluginModuleBase, PluginPageBase
|
||||
from .ffmpeg_queue import FfmpegQueueEntity, FfmpegQueue
|
||||
from .model_base import ModelBase
|
||||
from .create_plugin import create_plugin_instance
|
||||
|
||||
|
||||
import os, sys, traceback, re, threading, time
|
||||
from datetime import datetime, timedelta
|
||||
from flask import Blueprint, render_template, jsonify, redirect, request
|
||||
from framework import *
|
||||
7
lib/plugin/common.py
Normal file
7
lib/plugin/common.py
Normal file
@@ -0,0 +1,7 @@
|
||||
"""
|
||||
import os, sys, traceback, re, threading, time
|
||||
from datetime import datetime, timedelta
|
||||
from flask import Blueprint, render_template, jsonify, redirect, request
|
||||
from framework import frame, F, login_required, check_api, Job, SystemModelSetting
|
||||
from plugin import PluginModuleBase, get_model_setting, Logic, default_route, create_plugin_instance
|
||||
"""
|
||||
87
lib/plugin/create_plugin.py
Normal file
87
lib/plugin/create_plugin.py
Normal file
@@ -0,0 +1,87 @@
|
||||
import os, traceback
|
||||
from flask import Blueprint
|
||||
from framework import F
|
||||
from support.base.yaml import SupportYaml
|
||||
from . import get_model_setting, Logic, default_route, default_route_single_module
|
||||
|
||||
class PluginBase(object):
|
||||
package_name = None
|
||||
logger = None
|
||||
blueprint = None
|
||||
menu = None
|
||||
plugin_info = None
|
||||
ModelSetting = None
|
||||
logic = None
|
||||
module_list = None
|
||||
home_module = None
|
||||
|
||||
def __init__(self, setting):
|
||||
try:
|
||||
is_system = ('system' == os.path.basename(os.path.dirname(setting['filepath'])))
|
||||
self.status = ""
|
||||
self.setting = setting
|
||||
|
||||
info_filepath = os.path.join(os.path.dirname(setting['filepath']), 'info.yaml')
|
||||
if os.path.exists(info_filepath) == False and is_system == False:
|
||||
return
|
||||
if is_system:
|
||||
self.package_name = 'system'
|
||||
else:
|
||||
self.plugin_info = SupportYaml.read_yaml(info_filepath)
|
||||
self.package_name = self.plugin_info['package_name']
|
||||
|
||||
self.logger = F.get_logger(self.package_name)
|
||||
self.blueprint = Blueprint(self.package_name, self.package_name, url_prefix=f'/{self.package_name}', template_folder=os.path.join(os.path.dirname(setting['filepath']), 'templates'), static_folder=os.path.join(os.path.dirname(setting['filepath']), 'static'))
|
||||
self.menu = setting['menu']
|
||||
self.setting_menu = setting['setting_menu']
|
||||
|
||||
self.ModelSetting = None
|
||||
if setting.get('use_db', True):
|
||||
db_path = os.path.join(F.config['path_data'], 'db', f'{self.package_name}.db')
|
||||
F.app.config['SQLALCHEMY_BINDS'][self.package_name] = f"sqlite:///{db_path}"
|
||||
if setting.get('use_default_setting', True):
|
||||
self.ModelSetting = get_model_setting(self.package_name, self.logger)
|
||||
|
||||
self.module_list = []
|
||||
self.home_module = setting.get('home_module')
|
||||
self.status = "init_success"
|
||||
self.config = {}
|
||||
except Exception as e:
|
||||
self.logger.error(f'Exception:{str(e)}')
|
||||
self.logger.error(traceback.format_exc())
|
||||
self.status = 'init_fail'
|
||||
|
||||
def set_module_list(self, mod_list):
|
||||
try:
|
||||
for mod in mod_list:
|
||||
mod_ins = mod(self)
|
||||
self.module_list.append(mod_ins)
|
||||
|
||||
except Exception as e:
|
||||
F.logger.error(f'Exception:{str(e)}')
|
||||
F.logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
self.logic = Logic(self)
|
||||
route_mode = self.setting.get('default_route', 'normal')
|
||||
if route_mode == 'normal':
|
||||
default_route(self)
|
||||
elif route_mode == 'single':
|
||||
default_route_single_module(self)
|
||||
|
||||
|
||||
def plugin_load(self):
|
||||
self.logic.plugin_load()
|
||||
|
||||
def plugin_unload(self):
|
||||
self.logic.plugin_unload()
|
||||
|
||||
def get_first_manual_path(self):
|
||||
for __ in self.menu['list']:
|
||||
if __['uri'] == 'manual' and len(__['list']) > 0:
|
||||
return __['list'][0]['uri']
|
||||
|
||||
|
||||
def create_plugin_instance(config):
|
||||
ins = PluginBase(config)
|
||||
return ins
|
||||
300
lib/plugin/ffmpeg_queue.py
Normal file
300
lib/plugin/ffmpeg_queue.py
Normal file
@@ -0,0 +1,300 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#########################################################
|
||||
# python
|
||||
import os, sys, traceback
|
||||
import threading, time
|
||||
from datetime import datetime
|
||||
import abc
|
||||
|
||||
# third-party
|
||||
# sjva 공용
|
||||
#########################################################
|
||||
|
||||
class FfmpegQueueEntity(abc.ABCMeta('ABC', (object,), {'__slots__': ()})):
|
||||
|
||||
def __init__(self, P, module_logic, info):
|
||||
self.P = P
|
||||
self.module_logic = module_logic
|
||||
self.entity_id = -1 #FfmpegQueueEntity.static_index
|
||||
self.info = info
|
||||
self.url = None
|
||||
self.ffmpeg_status = -1
|
||||
self.ffmpeg_status_kor = u'대기중'
|
||||
self.ffmpeg_percent = 0
|
||||
self.ffmpeg_arg = None
|
||||
self.cancel = False
|
||||
self.created_time = datetime.now().strftime('%m-%d %H:%M:%S')
|
||||
self.savepath = None
|
||||
self.filename = None
|
||||
self.filepath = None
|
||||
self.quality = None
|
||||
self.headers = None
|
||||
#FfmpegQueueEntity.static_index += 1
|
||||
#FfmpegQueueEntity.entity_list.append(self)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def get_video_url(self):
|
||||
return self.url
|
||||
|
||||
def get_video_filepath(self):
|
||||
return self.filepath
|
||||
|
||||
@abc.abstractmethod
|
||||
def refresh_status(self):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def info_dict(self, tmp):
|
||||
pass
|
||||
|
||||
def donwload_completed(self):
|
||||
pass
|
||||
|
||||
def as_dict(self):
|
||||
tmp = {}
|
||||
tmp['entity_id'] = self.entity_id
|
||||
tmp['url'] = self.url
|
||||
tmp['ffmpeg_status'] = self.ffmpeg_status
|
||||
tmp['ffmpeg_status_kor'] = self.ffmpeg_status_kor
|
||||
tmp['ffmpeg_percent'] = self.ffmpeg_percent
|
||||
tmp['ffmpeg_arg'] = self.ffmpeg_arg
|
||||
tmp['cancel'] = self.cancel
|
||||
tmp['created_time'] = self.created_time#.strftime('%m-%d %H:%M:%S')
|
||||
tmp['savepath'] = self.savepath
|
||||
tmp['filename'] = self.filename
|
||||
tmp['filepath'] = self.filepath
|
||||
tmp['quality'] = self.quality
|
||||
#tmp['current_speed'] = self.ffmpeg_arg['current_speed'] if self.ffmpeg_arg is not None else ''
|
||||
tmp = self.info_dict(tmp)
|
||||
return tmp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class FfmpegQueue(object):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def __init__(self, P, max_ffmpeg_count):
|
||||
self.P = P
|
||||
self.static_index = 1
|
||||
self.entity_list = []
|
||||
self.current_ffmpeg_count = 0
|
||||
self.download_queue = None
|
||||
self.download_thread = None
|
||||
self.max_ffmpeg_count = max_ffmpeg_count
|
||||
if self.max_ffmpeg_count is None or self.max_ffmpeg_count == '':
|
||||
self.max_ffmpeg_count = 1
|
||||
|
||||
def queue_start(self):
|
||||
try:
|
||||
if self.download_queue is None:
|
||||
self.download_queue = queue.Queue()
|
||||
if self.download_thread is None:
|
||||
self.download_thread = threading.Thread(target=self.download_thread_function, args=())
|
||||
self.download_thread.daemon = True
|
||||
self.download_thread.start()
|
||||
except Exception as exception:
|
||||
self.P.logger.error('Exception:%s', exception)
|
||||
self.P.logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
def download_thread_function(self):
|
||||
while True:
|
||||
try:
|
||||
while True:
|
||||
try:
|
||||
if self.current_ffmpeg_count < self.max_ffmpeg_count:
|
||||
break
|
||||
time.sleep(5)
|
||||
except Exception as exception:
|
||||
self.P.logger.error('Exception:%s', exception)
|
||||
self.P.logger.error(traceback.format_exc())
|
||||
self.P.logger.error('current_ffmpeg_count : %s', self.current_ffmpeg_count)
|
||||
self.P.logger.error('max_ffmpeg_count : %s', self.max_ffmpeg_count)
|
||||
break
|
||||
entity = self.download_queue.get()
|
||||
if entity.cancel:
|
||||
continue
|
||||
|
||||
#from .logic_ani24 import LogicAni24
|
||||
#entity.url = LogicAni24.get_video_url(entity.info['code'])
|
||||
video_url = entity.get_video_url()
|
||||
if video_url is None:
|
||||
entity.ffmpeg_status_kor = 'URL실패'
|
||||
entity.refresh_status()
|
||||
#plugin.socketio_list_refresh()
|
||||
continue
|
||||
|
||||
import ffmpeg
|
||||
#max_pf_count = 0
|
||||
#save_path = ModelSetting.get('download_path')
|
||||
#if ModelSetting.get('auto_make_folder') == 'True':
|
||||
# program_path = os.path.join(save_path, entity.info['filename'].split('.')[0])
|
||||
# save_path = program_path
|
||||
#try:
|
||||
# if not os.path.exists(save_path):
|
||||
# os.makedirs(save_path)
|
||||
#except:
|
||||
# logger.debug('program path make fail!!')
|
||||
# 파일 존재여부 체크
|
||||
filepath = entity.get_video_filepath()
|
||||
if os.path.exists(filepath):
|
||||
entity.ffmpeg_status_kor = '파일 있음'
|
||||
entity.ffmpeg_percent = 100
|
||||
entity.refresh_status()
|
||||
#plugin.socketio_list_refresh()
|
||||
continue
|
||||
dirname = os.path.dirname(filepath)
|
||||
if not os.path.exists(dirname):
|
||||
os.makedirs(dirname)
|
||||
f = ffmpeg.Ffmpeg(video_url, os.path.basename(filepath), plugin_id=entity.entity_id, listener=self.ffmpeg_listener, call_plugin=self.P.package_name, save_path=dirname, headers=entity.headers)
|
||||
f.start()
|
||||
self.current_ffmpeg_count += 1
|
||||
self.download_queue.task_done()
|
||||
except Exception as exception:
|
||||
self.P.logger.error('Exception:%s', exception)
|
||||
self.P.logger.error(traceback.format_exc())
|
||||
|
||||
def ffmpeg_listener(self, **arg):
|
||||
import ffmpeg
|
||||
entity = self.get_entity_by_entity_id(arg['plugin_id'])
|
||||
if entity is None:
|
||||
return
|
||||
if arg['type'] == 'status_change':
|
||||
if arg['status'] == ffmpeg.Status.DOWNLOADING:
|
||||
pass
|
||||
elif arg['status'] == ffmpeg.Status.COMPLETED:
|
||||
entity.donwload_completed()
|
||||
elif arg['status'] == ffmpeg.Status.READY:
|
||||
pass
|
||||
elif arg['type'] == 'last':
|
||||
self.current_ffmpeg_count += -1
|
||||
elif arg['type'] == 'log':
|
||||
pass
|
||||
elif arg['type'] == 'normal':
|
||||
pass
|
||||
|
||||
entity.ffmpeg_arg = arg
|
||||
entity.ffmpeg_status = int(arg['status'])
|
||||
entity.ffmpeg_status_kor = str(arg['status'])
|
||||
entity.ffmpeg_percent = arg['data']['percent']
|
||||
entity.ffmpeg_arg['status'] = str(arg['status'])
|
||||
#self.P.logger.debug(arg)
|
||||
#import plugin
|
||||
#arg['status'] = str(arg['status'])
|
||||
#plugin.socketio_callback('status', arg)
|
||||
entity.refresh_status()
|
||||
|
||||
|
||||
#FfmpegQueueEntity.static_index += 1
|
||||
#FfmpegQueueEntity.entity_list.append(self)
|
||||
|
||||
|
||||
def add_queue(self, entity):
|
||||
try:
|
||||
#entity = QueueEntity.create(info)
|
||||
#if entity is not None:
|
||||
# LogicQueue.download_queue.put(entity)
|
||||
# return True
|
||||
entity.entity_id = self.static_index
|
||||
self.static_index += 1
|
||||
self.entity_list.append(entity)
|
||||
self.download_queue.put(entity)
|
||||
return True
|
||||
except Exception as exception:
|
||||
self.P.logger.error('Exception:%s', exception)
|
||||
self.P.logger.error(traceback.format_exc())
|
||||
return False
|
||||
|
||||
|
||||
def set_max_ffmpeg_count(self, max_ffmpeg_count):
|
||||
self.max_ffmpeg_count = max_ffmpeg_count
|
||||
|
||||
def get_max_ffmpeg_count(self):
|
||||
return self.max_ffmpeg_count
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def command(self, cmd, entity_id):
|
||||
self.P.logger.debug('command :%s %s', cmd, entity_id)
|
||||
ret = {}
|
||||
try:
|
||||
if cmd == 'cancel':
|
||||
self.P.logger.debug('command :%s %s', cmd, entity_id)
|
||||
entity = self.get_entity_by_entity_id(entity_id)
|
||||
if entity is not None:
|
||||
if entity.ffmpeg_status == -1:
|
||||
entity.cancel = True
|
||||
entity.ffmpeg_status_kor = "취소"
|
||||
#entity.refresh_status()
|
||||
ret['ret'] = 'refresh'
|
||||
elif entity.ffmpeg_status != 5:
|
||||
ret['ret'] = 'notify'
|
||||
ret['log'] = '다운로드중 상태가 아닙니다.'
|
||||
else:
|
||||
idx = entity.ffmpeg_arg['data']['idx']
|
||||
import ffmpeg
|
||||
ffmpeg.Ffmpeg.stop_by_idx(idx)
|
||||
entity.refresh_status()
|
||||
ret['ret'] = 'refresh'
|
||||
elif cmd == 'reset':
|
||||
if self.download_queue is not None:
|
||||
with self.download_queue.mutex:
|
||||
self.download_queue.queue.clear()
|
||||
for _ in self.entity_list:
|
||||
if _.ffmpeg_status == 5:
|
||||
import ffmpeg
|
||||
idx = _.ffmpeg_arg['data']['idx']
|
||||
ffmpeg.Ffmpeg.stop_by_idx(idx)
|
||||
self.entity_list = []
|
||||
ret['ret'] = 'refresh'
|
||||
elif cmd == 'delete_completed':
|
||||
new_list = []
|
||||
for _ in self.entity_list:
|
||||
if _.ffmpeg_status_kor in [u'파일 있음', u'취소', u'사용자중지']:
|
||||
continue
|
||||
if _.ffmpeg_status != 7:
|
||||
new_list.append(_)
|
||||
self.entity_list = new_list
|
||||
ret['ret'] = 'refresh'
|
||||
elif cmd == 'remove':
|
||||
new_list = []
|
||||
for _ in self.entity_list:
|
||||
if _.entity_id == entity_id:
|
||||
continue
|
||||
new_list.append(_)
|
||||
self.entity_list = new_list
|
||||
ret['ret'] = 'refresh'
|
||||
return ret
|
||||
except Exception as exception:
|
||||
self.P.logger.error('Exception:%s', exception)
|
||||
self.P.logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
def get_entity_by_entity_id(self, entity_id):
|
||||
for _ in self.entity_list:
|
||||
if _.entity_id == entity_id:
|
||||
return _
|
||||
return None
|
||||
|
||||
|
||||
def get_entity_list(self):
|
||||
ret = []
|
||||
for x in self.entity_list:
|
||||
tmp = x.as_dict()
|
||||
ret.append(tmp)
|
||||
return ret
|
||||
|
||||
|
||||
236
lib/plugin/logic.py
Normal file
236
lib/plugin/logic.py
Normal file
@@ -0,0 +1,236 @@
|
||||
import traceback, time, threading
|
||||
from framework import F, Job
|
||||
|
||||
#########################################################
|
||||
|
||||
|
||||
class Logic(object):
|
||||
db_default = {
|
||||
'recent_menu_plugin' : '',
|
||||
}
|
||||
|
||||
def __init__(self, P):
|
||||
self.P = P
|
||||
|
||||
def plugin_load(self):
|
||||
try:
|
||||
#self.P.logger.debug('%s plugin_load', self.P.package_name)
|
||||
self.db_init()
|
||||
for module in self.P.module_list:
|
||||
module.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:
|
||||
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 exception:
|
||||
self.P.logger.error('Exception:%s', exception)
|
||||
self.P.logger.error(traceback.format_exc())
|
||||
|
||||
def db_init(self):
|
||||
try:
|
||||
if self.P.ModelSetting is None:
|
||||
return
|
||||
|
||||
for key, value in Logic.db_default.items():
|
||||
if F.db.session.query(self.P.ModelSetting).filter_by(key=key).count() == 0:
|
||||
F.db.session.add(self.P.ModelSetting(key, value))
|
||||
|
||||
for module in self.P.module_list:
|
||||
if module.page_list is not None:
|
||||
for page_instance in module.page_list:
|
||||
if page_instance.db_default is not None:
|
||||
for key, value in page_instance.db_default.items():
|
||||
if F.db.session.query(self.P.ModelSetting).filter_by(key=key).count() == 0:
|
||||
F.db.session.add(self.P.ModelSetting(key, value))
|
||||
if module.db_default is not None:
|
||||
for key, value in module.db_default.items():
|
||||
if F.db.session.query(self.P.ModelSetting).filter_by(key=key).count() == 0:
|
||||
F.db.session.add(self.P.ModelSetting(key, value))
|
||||
F.db.session.commit()
|
||||
except Exception as exception:
|
||||
self.P.logger.error('Exception:%s', exception)
|
||||
self.P.logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
def plugin_unload(self):
|
||||
try:
|
||||
self.P.logger.debug('%s plugin_unload', self.P.package_name)
|
||||
for module in self.P.module_list:
|
||||
module.plugin_unload()
|
||||
if module.page_list is not None:
|
||||
for page_instance in module.page_list:
|
||||
page_instance.plugin_unload()
|
||||
except Exception as exception:
|
||||
self.P.logger.error('Exception:%s', exception)
|
||||
self.P.logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
def scheduler_start(self, sub):
|
||||
try:
|
||||
job_id = '%s_%s' % (self.P.package_name, sub)
|
||||
module = self.get_module(sub)
|
||||
job = Job(self.P.package_name, job_id, module.get_scheduler_interval(), self.scheduler_function, module.get_scheduler_desc(), args=sub)
|
||||
F.scheduler.add_job_instance(job)
|
||||
except Exception as exception:
|
||||
self.P.logger.error('Exception:%s', exception)
|
||||
self.P.logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
def scheduler_stop(self, sub):
|
||||
try:
|
||||
job_id = '%s_%s' % (self.P.package_name, sub)
|
||||
F.scheduler.remove_job(job_id)
|
||||
except Exception as exception:
|
||||
self.P.logger.error('Exception:%s', exception)
|
||||
self.P.logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
def scheduler_function(self, sub):
|
||||
try:
|
||||
module = self.get_module(sub)
|
||||
module.scheduler_function()
|
||||
except Exception as exception:
|
||||
self.P.logger.error('Exception:%s', exception)
|
||||
self.P.logger.error(traceback.format_exc())
|
||||
|
||||
def reset_db(self,sub):
|
||||
try:
|
||||
module = self.get_module(sub)
|
||||
return module.reset_db()
|
||||
except Exception as exception:
|
||||
self.P.logger.error('Exception:%s', exception)
|
||||
self.P.logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
def one_execute(self, sub):
|
||||
self.P.logger.debug('one_execute :%s', sub)
|
||||
try:
|
||||
job_id = '%s_%s' % (self.P.package_name, sub)
|
||||
if F.scheduler.is_include(job_id):
|
||||
if F.scheduler.is_running(job_id):
|
||||
ret = 'is_running'
|
||||
else:
|
||||
F.scheduler.execute_job(job_id)
|
||||
ret = 'scheduler'
|
||||
else:
|
||||
def func():
|
||||
time.sleep(2)
|
||||
self.scheduler_function(sub)
|
||||
threading.Thread(target=func, args=()).start()
|
||||
ret = 'thread'
|
||||
except Exception as exception:
|
||||
self.P.logger.error('Exception:%s', exception)
|
||||
self.P.logger.error(traceback.format_exc())
|
||||
ret = 'fail'
|
||||
return ret
|
||||
|
||||
def immediately_execute(self, sub):
|
||||
self.P.logger.debug('immediately_execute :%s', sub)
|
||||
try:
|
||||
def func():
|
||||
time.sleep(1)
|
||||
self.scheduler_function(sub)
|
||||
threading.Thread(target=func, args=()).start()
|
||||
ret = {'ret':'success', 'msg':'실행합니다.'}
|
||||
except Exception as exception:
|
||||
self.P.logger.error('Exception:%s', exception)
|
||||
self.P.logger.error(traceback.format_exc())
|
||||
ret = {'ret' : 'danger', 'msg':str(exception)}
|
||||
return ret
|
||||
|
||||
def get_module(self, sub):
|
||||
try:
|
||||
for module in self.P.module_list:
|
||||
if module.name == sub:
|
||||
return module
|
||||
except Exception as exception:
|
||||
self.P.logger.error('Exception:%s', exception)
|
||||
self.P.logger.error(traceback.format_exc())
|
||||
|
||||
def process_telegram_data(self, data, target=None):
|
||||
try:
|
||||
for module in self.P.module_list:
|
||||
if target is None or target.startswith(module.name):
|
||||
module.process_telegram_data(data, target=target)
|
||||
except Exception as exception:
|
||||
self.P.logger.error('Exception:%s', exception)
|
||||
self.P.logger.error(traceback.format_exc())
|
||||
|
||||
#######################################################
|
||||
# 플러그인 - 모듈 - 페이지 구조하에서 서브 관련 함수
|
||||
|
||||
def scheduler_start_sub(self, module_name, page_name):
|
||||
try:
|
||||
#self.P.logger.warning('scheduler_start_sub')
|
||||
job_id = f'{self.P.package_name}_{module_name}_{page_name}'
|
||||
ins_module = self.get_module(module_name)
|
||||
ins_page = ins_module.get_page(page_name)
|
||||
job = Job(self.P.package_name, job_id, ins_page.get_scheduler_interval(), ins_page.scheduler_function, ins_page.get_scheduler_desc(), args=None)
|
||||
F.scheduler.add_job_instance(job)
|
||||
except Exception as exception:
|
||||
self.P.logger.error('Exception:%s', exception)
|
||||
self.P.logger.error(traceback.format_exc())
|
||||
|
||||
def scheduler_stop_sub(self, module_name, page_name):
|
||||
try:
|
||||
job_id = f'{self.P.package_name}_{module_name}_{page_name}'
|
||||
F.scheduler.remove_job(job_id)
|
||||
except Exception as exception:
|
||||
self.P.logger.error('Exception:%s', exception)
|
||||
self.P.logger.error(traceback.format_exc())
|
||||
|
||||
def scheduler_function_sub(self, module_name, page_name):
|
||||
try:
|
||||
ins_module = self.get_module(module_name)
|
||||
ins_sub = ins_module.get_page(page_name)
|
||||
ins_sub.scheduler_function()
|
||||
except Exception as exception:
|
||||
self.P.logger.error('Exception:%s', exception)
|
||||
self.P.logger.error(traceback.format_exc())
|
||||
|
||||
def one_execute_sub(self, module_name, page_name):
|
||||
try:
|
||||
job_id = f'{self.P.package_name}_{module_name}_{page_name}'
|
||||
if F.scheduler.is_include(job_id):
|
||||
if F.scheduler.is_running(job_id):
|
||||
ret = 'is_running'
|
||||
else:
|
||||
F.scheduler.execute_job(job_id)
|
||||
ret = 'scheduler'
|
||||
else:
|
||||
def func():
|
||||
time.sleep(2)
|
||||
self.scheduler_function_sub(module_name, page_name)
|
||||
threading.Thread(target=func, args=()).start()
|
||||
ret = 'thread'
|
||||
except Exception as exception:
|
||||
self.P.logger.error('Exception:%s', exception)
|
||||
self.P.logger.error(traceback.format_exc())
|
||||
ret = 'fail'
|
||||
return ret
|
||||
|
||||
def immediately_execute_sub(self, module_name, page_name):
|
||||
self.P.logger.debug(f'immediately_execute : {module_name} {page_name}')
|
||||
try:
|
||||
def func():
|
||||
time.sleep(1)
|
||||
self.scheduler_function_sub(module_name, page_name)
|
||||
threading.Thread(target=func, args=()).start()
|
||||
ret = {'ret':'success', 'msg':'실행합니다.'}
|
||||
except Exception as exception:
|
||||
self.P.logger.error('Exception:%s', exception)
|
||||
self.P.logger.error(traceback.format_exc())
|
||||
ret = {'ret' : 'danger', 'msg':str(exception)}
|
||||
return ret
|
||||
171
lib/plugin/logic_module_base.py
Normal file
171
lib/plugin/logic_module_base.py
Normal file
@@ -0,0 +1,171 @@
|
||||
import traceback
|
||||
|
||||
class PluginModuleBase(object):
|
||||
db_default = None
|
||||
|
||||
def __init__(self, P, first_menu=None, name=None, scheduler_desc=None):
|
||||
self.P = P
|
||||
self.scheduler_desc = scheduler_desc
|
||||
self.first_menu = first_menu
|
||||
self.name = name
|
||||
self.socketio_list = None
|
||||
self.page_list = None
|
||||
|
||||
# set_module_list 대응
|
||||
def set_page_list(self, page_list):
|
||||
try:
|
||||
self.page_list = []
|
||||
for mod in page_list:
|
||||
mod_ins = mod(self.P, self)
|
||||
self.page_list.append(mod_ins)
|
||||
|
||||
except Exception as e:
|
||||
self.P.logger.error(f'Exception:{str(e)}')
|
||||
self.P.logger.error(traceback.format_exc())
|
||||
|
||||
def get_page(self, page_name):
|
||||
try:
|
||||
for page in self.page_list:
|
||||
if page_name == page.name:
|
||||
return page
|
||||
except Exception as e:
|
||||
self.P.logger.error(f'Exception:{str(e)}')
|
||||
self.P.logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
def process_menu(self, sub):
|
||||
pass
|
||||
|
||||
def process_ajax(self, sub, req):
|
||||
pass
|
||||
|
||||
def process_command(self, command, arg1, arg2, arg3, req):
|
||||
pass
|
||||
|
||||
def process_api(self, sub, req):
|
||||
pass
|
||||
|
||||
def process_normal(self, sub, req):
|
||||
pass
|
||||
|
||||
def scheduler_function(self):
|
||||
pass
|
||||
|
||||
def reset_db(self):
|
||||
pass
|
||||
|
||||
def plugin_load(self):
|
||||
pass
|
||||
|
||||
def plugin_unload(self):
|
||||
pass
|
||||
|
||||
def setting_save_after(self, change_list):
|
||||
pass
|
||||
|
||||
def process_telegram_data(self, data, target=None):
|
||||
pass
|
||||
|
||||
def migration(self):
|
||||
pass
|
||||
|
||||
#################################################################
|
||||
def get_scheduler_desc(self):
|
||||
return self.scheduler_desc
|
||||
|
||||
def get_scheduler_interval(self):
|
||||
if self.P is not None and self.P.ModelSetting is not None and self.name is not None:
|
||||
return self.P.ModelSetting.get('{module_name}_interval'.format(module_name=self.name))
|
||||
|
||||
def get_first_menu(self):
|
||||
return self.first_menu
|
||||
|
||||
def get_scheduler_name(self):
|
||||
return '%s_%s' % (self.P.package_name, self.name)
|
||||
|
||||
def dump(self, data):
|
||||
if type(data) in [type({}), type([])]:
|
||||
import json
|
||||
return '\n' + json.dumps(data, indent=4, ensure_ascii=False)
|
||||
else:
|
||||
return str(data)
|
||||
|
||||
def socketio_connect(self):
|
||||
pass
|
||||
|
||||
def socketio_disconnect(self):
|
||||
pass
|
||||
|
||||
|
||||
class PluginPageBase(object):
|
||||
db_default = None
|
||||
|
||||
def __init__(self, P, parent, name=None, scheduler_desc=None):
|
||||
self.P = P
|
||||
self.parent = parent
|
||||
self.name = name
|
||||
self.scheduler_desc = scheduler_desc
|
||||
self.socketio_list = None
|
||||
|
||||
|
||||
def process_ajax(self, sub, req):
|
||||
pass
|
||||
|
||||
def scheduler_function(self):
|
||||
pass
|
||||
|
||||
def plugin_load(self):
|
||||
pass
|
||||
|
||||
def plugin_unload(self):
|
||||
pass
|
||||
|
||||
|
||||
def get_scheduler_desc(self):
|
||||
return self.scheduler_desc
|
||||
|
||||
def get_scheduler_interval(self):
|
||||
if self.P is not None and self.P.ModelSetting is not None and self.parent.name is not None and self.name is not None:
|
||||
return self.P.ModelSetting.get(f'{self.parent.name}_{self.name}_interval')
|
||||
|
||||
def get_scheduler_name(self):
|
||||
return f'{self.P.package_name}_{self.parent.name}_{self.name}'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def process_api(self, sub, req):
|
||||
pass
|
||||
|
||||
def process_normal(self, sub, req):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
def reset_db(self):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
def setting_save_after(self, change_list):
|
||||
pass
|
||||
|
||||
def process_telegram_data(self, data, target=None):
|
||||
pass
|
||||
|
||||
def migration(self):
|
||||
pass
|
||||
|
||||
#################################################################
|
||||
|
||||
|
||||
def process_menu(self, sub):
|
||||
pass
|
||||
|
||||
145
lib/plugin/model_base.py
Normal file
145
lib/plugin/model_base.py
Normal file
@@ -0,0 +1,145 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#########################################################
|
||||
# python
|
||||
import traceback
|
||||
from datetime import datetime
|
||||
|
||||
# third-party
|
||||
|
||||
# sjva 공용
|
||||
from framework import db
|
||||
from framework.util import Util
|
||||
|
||||
#########################################################
|
||||
class ModelBase(db.Model):
|
||||
__abstract__ = True
|
||||
__table_args__ = {'mysql_collate': 'utf8_general_ci'}
|
||||
model_setting = None
|
||||
logger = None
|
||||
|
||||
def __repr__(self):
|
||||
return repr(self.as_dict())
|
||||
|
||||
def as_dict(self):
|
||||
return {x.name: getattr(self, x.name).strftime('%m-%d %H:%M:%S') if isinstance(getattr(self, x.name), datetime) else getattr(self, x.name) for x in self.__table__.columns}
|
||||
|
||||
|
||||
def save(self):
|
||||
try:
|
||||
db.session.add(self)
|
||||
db.session.commit()
|
||||
except Exception as e:
|
||||
self.logger.error(f'Exception:{str(e)}')
|
||||
self.logger.error(traceback.format_exc())
|
||||
|
||||
@classmethod
|
||||
def get_paging_info(cls, count, current_page, page_size):
|
||||
try:
|
||||
paging = {}
|
||||
paging['prev_page'] = True
|
||||
paging['next_page'] = True
|
||||
if current_page <= 10:
|
||||
paging['prev_page'] = False
|
||||
|
||||
paging['total_page'] = int(count / page_size) + 1
|
||||
if count % page_size == 0:
|
||||
paging['total_page'] -= 1
|
||||
paging['start_page'] = int((current_page-1)/10) * 10 + 1
|
||||
paging['last_page'] = paging['total_page'] if paging['start_page'] + 9 > paging['total_page'] else paging['start_page'] + 9
|
||||
if paging['last_page'] == paging['total_page']:
|
||||
paging['next_page'] = False
|
||||
paging['current_page'] = current_page
|
||||
paging['count'] = count
|
||||
cls.logger.debug('paging : c:%s %s %s %s %s %s', count, paging['total_page'], paging['prev_page'], paging['next_page'] , paging['start_page'], paging['last_page'])
|
||||
return paging
|
||||
except Exception as e:
|
||||
cls.logger.error(f'Exception:{str(e)}')
|
||||
cls.logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_by_id(cls, id):
|
||||
try:
|
||||
return db.session.query(cls).filter_by(id=id).first()
|
||||
except Exception as e:
|
||||
cls.logger.error(f'Exception:{str(e)}')
|
||||
cls.logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_list(cls, by_dict=False):
|
||||
try:
|
||||
tmp = db.session.query(cls).all()
|
||||
if by_dict:
|
||||
tmp = [x.as_dict() for x in tmp]
|
||||
return tmp
|
||||
except Exception as e:
|
||||
cls.logger.error(f'Exception:{str(e)}')
|
||||
cls.logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
|
||||
@classmethod
|
||||
def delete_by_id(cls, id):
|
||||
try:
|
||||
db.session.query(cls).filter_by(id=id).delete()
|
||||
db.session.commit()
|
||||
return True
|
||||
except Exception as e:
|
||||
cls.logger.error(f'Exception:{str(e)}')
|
||||
cls.logger.error(traceback.format_exc())
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def delete_all(cls):
|
||||
try:
|
||||
db.session.query(cls).delete()
|
||||
db.session.commit()
|
||||
return True
|
||||
except Exception as e:
|
||||
cls.logger.error(f'Exception:{str(e)}')
|
||||
cls.logger.error(traceback.format_exc())
|
||||
return False
|
||||
|
||||
|
||||
@classmethod
|
||||
def web_list(cls, req):
|
||||
try:
|
||||
ret = {}
|
||||
page = 1
|
||||
page_size = 30
|
||||
search = ''
|
||||
if 'page' in req.form:
|
||||
page = int(req.form['page'])
|
||||
if 'keyword' in req.form:
|
||||
search = req.form['keyword']
|
||||
option1 = req.form.get('option1', 'all')
|
||||
option2 = req.form.get('option2', 'all')
|
||||
order = req.form['order'] if 'order' in req.form else 'desc'
|
||||
|
||||
query = cls.make_query(order=order, search=search, option1=option1, option2=option2)
|
||||
count = query.count()
|
||||
query = query.limit(page_size).offset((page-1)*page_size)
|
||||
cls.logger.debug('cls count:%s', count)
|
||||
lists = query.all()
|
||||
ret['list'] = [item.as_dict() for item in lists]
|
||||
ret['paging'] = cls.get_paging_info(count, page, page_size)
|
||||
try:
|
||||
if cls.model_setting is not None and cls.__tablename__ is not None:
|
||||
cls.model_setting.set(f'{cls.__tablename__}_last_list_option', f'{order}|{page}|{search}|{option1}|{option2}')
|
||||
except Exception as e:
|
||||
cls.logger.error('Exception:%s', e)
|
||||
cls.logger.error(traceback.format_exc())
|
||||
cls.logger.error(f'{cls.__tablename__}_last_list_option ERROR!' )
|
||||
return ret
|
||||
except Exception as e:
|
||||
cls.logger.error('Exception:%s', e)
|
||||
cls.logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
# 오버라이딩
|
||||
@classmethod
|
||||
def make_query(cls, order='desc', search='', option1='all', option2='all'):
|
||||
query = db.session.query(cls)
|
||||
return query
|
||||
|
||||
138
lib/plugin/model_setting.py
Normal file
138
lib/plugin/model_setting.py
Normal file
@@ -0,0 +1,138 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#########################################################
|
||||
# python
|
||||
import os, traceback
|
||||
|
||||
# third-party
|
||||
|
||||
# sjva 공용
|
||||
from framework import frame, db
|
||||
from framework.util import Util
|
||||
|
||||
#########################################################
|
||||
def get_model_setting(package_name, logger, table_name=None):
|
||||
|
||||
class ModelSetting(db.Model):
|
||||
__tablename__ = '%s_setting' % package_name if table_name is None else table_name
|
||||
__table_args__ = {'mysql_collate': 'utf8_general_ci'}
|
||||
__bind_key__ = package_name
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
key = db.Column(db.String, unique=True, nullable=False)
|
||||
value = db.Column(db.String, nullable=False)
|
||||
|
||||
def __init__(self, key, value):
|
||||
self.key = key
|
||||
self.value = value
|
||||
|
||||
def __repr__(self):
|
||||
return repr(self.as_dict())
|
||||
|
||||
def as_dict(self):
|
||||
return {x.name: getattr(self, x.name) for x in self.__table__.columns}
|
||||
|
||||
@staticmethod
|
||||
def get(key):
|
||||
try:
|
||||
ret = db.session.query(ModelSetting).filter_by(key=key).first()
|
||||
if ret is not None:
|
||||
return ret.value.strip()
|
||||
return None
|
||||
except Exception as exception:
|
||||
logger.error('Exception:%s %s', exception, key)
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
@staticmethod
|
||||
def has_key(key):
|
||||
return (db.session.query(ModelSetting).filter_by(key=key).first() is not None)
|
||||
|
||||
@staticmethod
|
||||
def get_int(key):
|
||||
try:
|
||||
return int(ModelSetting.get(key))
|
||||
except Exception as exception:
|
||||
logger.error('Exception:%s %s', exception, 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)
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
@staticmethod
|
||||
def set(key, value):
|
||||
try:
|
||||
item = db.session.query(ModelSetting).filter_by(key=key).with_for_update().first()
|
||||
if item is not None:
|
||||
item.value = value.strip() if value is not None else value
|
||||
db.session.commit()
|
||||
else:
|
||||
db.session.add(ModelSetting(key, value.strip()))
|
||||
db.session.commit()
|
||||
except Exception as exception:
|
||||
logger.error('Exception:%s %s', exception, key)
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
@staticmethod
|
||||
def to_dict():
|
||||
try:
|
||||
ret = Util.db_list_to_dict(db.session.query(ModelSetting).all())
|
||||
ret['package_name'] = package_name
|
||||
return ret
|
||||
except Exception as exception:
|
||||
logger.error('Exception:%s', exception)
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
@staticmethod
|
||||
def setting_save(req):
|
||||
try:
|
||||
change_list = []
|
||||
for key, value in req.form.items():
|
||||
if key in ['scheduler', 'is_running']:
|
||||
continue
|
||||
if key.startswith('global_') or key.startswith('tmp_') or key.startswith('_'):
|
||||
continue
|
||||
#logger.debug('Key:%s Value:%s', key, value)
|
||||
if ModelSetting.get(key) != value:
|
||||
change_list.append(key)
|
||||
entity = db.session.query(ModelSetting).filter_by(key=key).with_for_update().first()
|
||||
entity.value = value
|
||||
db.session.commit()
|
||||
return True, change_list
|
||||
except Exception as exception:
|
||||
logger.error('Exception:%s', exception)
|
||||
logger.error(traceback.format_exc())
|
||||
logger.debug('Error Key:%s Value:%s', key, value)
|
||||
return False, []
|
||||
|
||||
@staticmethod
|
||||
def get_list(key, delimeter='\n', comment=' #'):
|
||||
try:
|
||||
value = ModelSetting.get(key).replace('\n', delimeter)
|
||||
if comment is None:
|
||||
values = [x.strip() for x in value.split(delimeter)]
|
||||
else:
|
||||
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)
|
||||
logger.error(traceback.format_exc())
|
||||
logger.error('Error Key:%s Value:%s', key, value)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def get_list_except_empty(source):
|
||||
tmp = []
|
||||
for _ in source:
|
||||
if _.strip().startswith('#'):
|
||||
continue
|
||||
if _.strip() != '':
|
||||
tmp.append(_.strip())
|
||||
return tmp
|
||||
|
||||
return ModelSetting
|
||||
423
lib/plugin/route.py
Normal file
423
lib/plugin/route.py
Normal file
@@ -0,0 +1,423 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# python
|
||||
import traceback, os
|
||||
import json
|
||||
|
||||
# third-party
|
||||
from flask import Blueprint, request, render_template, redirect, jsonify
|
||||
from flask_login import login_required
|
||||
from flask_socketio import SocketIO, emit, send
|
||||
|
||||
# sjva 공용
|
||||
from framework import socketio, check_api
|
||||
from support.base.util import AlchemyEncoder
|
||||
# 패키지
|
||||
|
||||
#########################################################
|
||||
|
||||
|
||||
def default_route(P):
|
||||
@P.blueprint.route('/')
|
||||
def home():
|
||||
if P.ModelSetting is not None:
|
||||
tmp = P.ModelSetting.get('recent_menu_plugin')
|
||||
if tmp is not None and tmp != '':
|
||||
tmps = tmp.split('|')
|
||||
if len(tmps) == 2:
|
||||
return redirect('/{package_name}/{sub}/{sub2}'.format(package_name=P.package_name, sub=tmps[0], sub2=tmps[1]))
|
||||
elif len(tmps) == 1 and not (P.package_name =='system' and tmps[0] == 'logout'):
|
||||
return redirect('/{package_name}/{sub}'.format(package_name=P.package_name, sub=tmps[0]))
|
||||
|
||||
return redirect('/{package_name}/{home_module}'.format(package_name=P.package_name, home_module=P.home_module))
|
||||
|
||||
@P.blueprint.route('/<sub>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def first_menu(sub):
|
||||
try:
|
||||
if P.ModelSetting is not None and (P.package_name == 'system' and sub != 'home'):
|
||||
P.ModelSetting.set('recent_menu_plugin', '{}'.format(sub))
|
||||
for module in P.module_list:
|
||||
if sub == module.name:
|
||||
first_menu = module.get_first_menu()
|
||||
if first_menu:
|
||||
return redirect('/{package_name}/{sub}/{first_menu}'.format(package_name=P.package_name, sub=sub, first_menu=module.get_first_menu()))
|
||||
else:
|
||||
return module.process_menu(None, request)
|
||||
if sub == 'log':
|
||||
return render_template('log.html', package=P.package_name)
|
||||
elif sub == 'manual':
|
||||
#return redirect(f"/{P.package_name}/manual/{P.menu['second']['manual'][0][0]}")
|
||||
try:
|
||||
return redirect(f"/{P.package_name}/manual/{P.menu['sub2']['manual'][0][0]}")
|
||||
except:
|
||||
return redirect(f"/{P.package_name}/manual/{P.get_first_manual_path()}")
|
||||
|
||||
return render_template('sample.html', title='%s - %s' % (P.package_name, sub))
|
||||
except Exception as exception:
|
||||
P.logger.error('Exception:%s', exception)
|
||||
P.logger.error(traceback.format_exc())
|
||||
|
||||
@P.blueprint.route('/manual/<path:path>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def manual(path):
|
||||
try:
|
||||
plugin_root = os.path.dirname(P.blueprint.template_folder)
|
||||
filepath = os.path.join(plugin_root, *path.split('/'))
|
||||
from tool_base import ToolBaseFile
|
||||
data = ToolBaseFile.read(filepath)
|
||||
return render_template('manual.html', data=data)
|
||||
except Exception as exception:
|
||||
P.logger.error('Exception:%s', exception)
|
||||
P.logger.error(traceback.format_exc())
|
||||
|
||||
@P.blueprint.route('/<sub>/<sub2>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def second_menu(sub, sub2):
|
||||
if P.ModelSetting is not None:
|
||||
P.ModelSetting.set('recent_menu_plugin', '{}|{}'.format(sub, sub2))
|
||||
try:
|
||||
for module in P.module_list:
|
||||
if sub == module.name:
|
||||
return module.process_menu(sub2, request)
|
||||
if sub == 'log':
|
||||
return render_template('log.html', package=P.package_name)
|
||||
return render_template('sample.html', title='%s - %s' % (P.package_name, sub))
|
||||
except Exception as exception:
|
||||
P.logger.error('Exception:%s', exception)
|
||||
P.logger.error(traceback.format_exc())
|
||||
|
||||
#########################################################
|
||||
# For UI
|
||||
#########################################################
|
||||
@P.blueprint.route('/ajax/<sub>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def ajax(sub):
|
||||
P.logger.debug('AJAX %s %s', P.package_name, sub)
|
||||
try:
|
||||
# global
|
||||
if sub == 'setting_save':
|
||||
ret, change_list = P.ModelSetting.setting_save(request)
|
||||
for module in P.module_list:
|
||||
module.setting_save_after(change_list)
|
||||
return jsonify(ret)
|
||||
elif sub == 'scheduler':
|
||||
sub = request.form['sub']
|
||||
go = request.form['scheduler']
|
||||
P.logger.debug('scheduler :%s', go)
|
||||
if go == 'true':
|
||||
P.logic.scheduler_start(sub)
|
||||
else:
|
||||
P.logic.scheduler_stop(sub)
|
||||
return jsonify(go)
|
||||
elif sub == 'reset_db':
|
||||
sub = request.form['sub']
|
||||
ret = P.logic.reset_db(sub)
|
||||
return jsonify(ret)
|
||||
elif sub == 'one_execute':
|
||||
sub = request.form['sub']
|
||||
ret = P.logic.one_execute(sub)
|
||||
return jsonify(ret)
|
||||
elif sub == 'immediately_execute':
|
||||
sub = request.form['sub']
|
||||
ret = P.logic.immediately_execute(sub)
|
||||
return jsonify(ret)
|
||||
except Exception as exception:
|
||||
P.logger.error('Exception:%s', exception)
|
||||
P.logger.error(traceback.format_exc())
|
||||
|
||||
@P.blueprint.route('/ajax/<mod>/<cmd>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def second_ajax(mod, cmd):
|
||||
try:
|
||||
for module in P.module_list:
|
||||
if mod == module.name:
|
||||
if cmd == 'command':
|
||||
return module.process_command(request.form['command'], request.form.get('arg1'), request.form.get('arg2'), request.form.get('arg3'), request)
|
||||
else:
|
||||
return module.process_ajax(cmd, request)
|
||||
|
||||
except Exception as exception:
|
||||
P.logger.error('Exception:%s', exception)
|
||||
P.logger.error(traceback.format_exc())
|
||||
|
||||
@P.blueprint.route('/ajax/<module_name>/<page_name>/<command>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def sub_ajax(module_name, page_name, command):
|
||||
try:
|
||||
ins_module = P.get_module(module_name)
|
||||
ins_page = ins_module.get_page(page_name)
|
||||
if ins_page != None:
|
||||
if command == 'scheduler':
|
||||
#sub = page_name
|
||||
go = request.form['scheduler']
|
||||
P.logger.debug('scheduler :%s', go)
|
||||
if go == 'true':
|
||||
P.logic.scheduler_start_sub(module_name, page_name)
|
||||
else:
|
||||
P.logic.scheduler_stop_sub(module_name, page_name)
|
||||
return jsonify(go)
|
||||
#elif command == 'reset_db':
|
||||
# sub = request.form['sub']
|
||||
# ret = P.logic.reset_db(sub)
|
||||
# return jsonify(ret)
|
||||
elif command == 'one_execute':
|
||||
ret = P.logic.one_execute_sub(module_name, page_name)
|
||||
return jsonify(ret)
|
||||
elif command == 'immediately_execute':
|
||||
ret = P.logic.immediately_execute_sub(module_name, page_name)
|
||||
return jsonify(ret)
|
||||
else:
|
||||
return ins_page.process_ajax(command, request)
|
||||
P.logger.error(f"not process ajax : {P.package_name} {module_name} {page_name} {command}")
|
||||
except Exception as exception:
|
||||
P.logger.error('Exception:%s', exception)
|
||||
P.logger.error(traceback.format_exc())
|
||||
|
||||
#########################################################
|
||||
# API - 외부
|
||||
#########################################################
|
||||
# 단일 모듈인 경우 모듈이름을 붙이기 불편하여 추가.
|
||||
@P.blueprint.route('/api/<sub2>', methods=['GET', 'POST'])
|
||||
@check_api
|
||||
def api_first(sub2):
|
||||
try:
|
||||
for module in P.module_list:
|
||||
return module.process_api(sub2, request)
|
||||
except Exception as exception:
|
||||
P.logger.error('Exception:%s', exception)
|
||||
P.logger.error(traceback.format_exc())
|
||||
|
||||
@P.blueprint.route('/api/<sub>/<sub2>', methods=['GET', 'POST'])
|
||||
@check_api
|
||||
def api(sub, sub2):
|
||||
try:
|
||||
for module in P.module_list:
|
||||
if sub == module.name:
|
||||
return module.process_api(sub2, request)
|
||||
except Exception as exception:
|
||||
P.logger.error('Exception:%s', exception)
|
||||
P.logger.error(traceback.format_exc())
|
||||
|
||||
@P.blueprint.route('/normal/<sub>/<sub2>', methods=['GET', 'POST'])
|
||||
def normal(sub, sub2):
|
||||
try:
|
||||
for module in P.module_list:
|
||||
if sub == module.name:
|
||||
return module.process_normal(sub2, request)
|
||||
except Exception as exception:
|
||||
P.logger.error('Exception:%s', exception)
|
||||
P.logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def default_route_single_module(P):
|
||||
@P.blueprint.route('/')
|
||||
def home():
|
||||
return redirect('/{package_name}/{home_module}'.format(package_name=P.package_name, home_module=P.home_module))
|
||||
|
||||
@P.blueprint.route('/<sub>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def first_menu(sub):
|
||||
if sub == 'log':
|
||||
return render_template('log.html', package=P.package_name)
|
||||
return P.module_list[0].process_menu(sub, request)
|
||||
|
||||
@P.blueprint.route('/ajax/<sub>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def ajax(sub):
|
||||
P.logger.debug('AJAX %s %s', P.package_name, sub)
|
||||
try:
|
||||
# global
|
||||
if sub == 'setting_save':
|
||||
ret, change_list = P.ModelSetting.setting_save(request)
|
||||
if ret:
|
||||
P.module_list[0].setting_save_after(change_list)
|
||||
return jsonify(ret)
|
||||
elif sub == 'scheduler':
|
||||
sub = request.form['sub']
|
||||
go = request.form['scheduler']
|
||||
P.logger.debug('scheduler :%s', go)
|
||||
if go == 'true':
|
||||
P.logic.scheduler_start(sub)
|
||||
else:
|
||||
P.logic.scheduler_stop(sub)
|
||||
return jsonify(go)
|
||||
elif sub == 'reset_db':
|
||||
sub = request.form['sub']
|
||||
ret = P.logic.reset_db(sub)
|
||||
return jsonify(ret)
|
||||
elif sub == 'one_execute':
|
||||
sub = request.form['sub']
|
||||
ret = P.logic.one_execute(sub)
|
||||
return jsonify(ret)
|
||||
else:
|
||||
return P.module_list[0].process_ajax(sub, request)
|
||||
except Exception as exception:
|
||||
P.logger.error('Exception:%s', exception)
|
||||
P.logger.error(traceback.format_exc())
|
||||
|
||||
@P.blueprint.route('/api/<sub>', methods=['GET', 'POST'])
|
||||
@check_api
|
||||
def api(sub):
|
||||
try:
|
||||
return P.module_list[0].process_api(sub, request)
|
||||
except Exception as exception:
|
||||
P.logger.error('Exception:%s', exception)
|
||||
P.logger.error(traceback.format_exc())
|
||||
|
||||
@P.blueprint.route('/normal/<sub>', methods=['GET', 'POST'])
|
||||
def normal(sub):
|
||||
try:
|
||||
return P.module_list[0].process_normal(sub, request)
|
||||
except Exception as exception:
|
||||
P.logger.error('Exception:%s', exception)
|
||||
P.logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def default_route_socketio_module(module):
|
||||
P = module.P
|
||||
if module.socketio_list is None:
|
||||
module.socketio_list = []
|
||||
|
||||
@socketio.on('connect', namespace=f'/{P.package_name}/{module.name}')
|
||||
def connect():
|
||||
try:
|
||||
P.logger.debug(f'socket_connect : {P.package_name} - {module.name}')
|
||||
module.socketio_list.append(request.sid)
|
||||
socketio_callback('start', '')
|
||||
module.socketio_connect()
|
||||
except Exception as exception:
|
||||
P.logger.error('Exception:%s', exception)
|
||||
P.logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
@socketio.on('disconnect', namespace='/{package_name}/{sub}'.format(package_name=P.package_name, sub=module.name))
|
||||
def disconnect():
|
||||
try:
|
||||
P.logger.debug('socket_disconnect : %s - %s', P.package_name, module.name)
|
||||
module.socketio_list.remove(request.sid)
|
||||
module.socketio_disconnect()
|
||||
except Exception as exception:
|
||||
P.logger.error('Exception:%s', exception)
|
||||
P.logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
def socketio_callback(cmd, data, encoding=True):
|
||||
if module.socketio_list:
|
||||
if encoding:
|
||||
data = json.dumps(data, cls=AlchemyEncoder)
|
||||
data = json.loads(data)
|
||||
socketio.emit(cmd, data, namespace='/{package_name}/{sub}'.format(package_name=P.package_name, sub=module.name), broadcast=True)
|
||||
|
||||
module.socketio_callback = socketio_callback
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def default_route_socketio_page(page):
|
||||
|
||||
module = page.parent
|
||||
P = page.P
|
||||
if page.socketio_list is None:
|
||||
page.socketio_list = []
|
||||
|
||||
@socketio.on('connect', namespace=f'/{P.package_name}/{module.name}/{page.name}')
|
||||
def connect():
|
||||
try:
|
||||
P.logger.debug(f'socket_connect : {P.package_name}/{module.name}/{page.name}')
|
||||
page.socketio_list.append(request.sid)
|
||||
socketio_callback('start', '')
|
||||
except Exception as exception:
|
||||
P.logger.error(f'Exception:{str(exception)}', exception)
|
||||
P.logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
@socketio.on('disconnect', namespace=f'/{P.package_name}/{module.name}/{page.name}')
|
||||
def disconnect():
|
||||
try:
|
||||
P.logger.debug(f'socket_disconnect : {P.package_name}/{module.name}/{page.name}')
|
||||
page.socketio_list.remove(request.sid)
|
||||
except Exception as exception:
|
||||
P.logger.error(f'Exception:{str(exception)}', exception)
|
||||
P.logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
def socketio_callback(cmd, data, encoding=True):
|
||||
if page.socketio_list:
|
||||
if encoding:
|
||||
data = json.dumps(data, cls=AlchemyEncoder)
|
||||
data = json.loads(data)
|
||||
socketio.emit(cmd, data, namespace=f'/{P.package_name}/{module.name}/{page.name}', broadcast=True)
|
||||
|
||||
page.socketio_callback = socketio_callback
|
||||
Reference in New Issue
Block a user