255 lines
11 KiB
Python
255 lines
11 KiB
Python
import random
|
|
import string
|
|
import time
|
|
|
|
from support import (SupportDiscord, SupportFile, SupportSubprocess,
|
|
SupportTelegram)
|
|
from tool import ToolModalCommand
|
|
|
|
from .setup import *
|
|
|
|
name = 'setting'
|
|
|
|
class ModuleSetting(PluginModuleBase):
|
|
db_default = {
|
|
'db_version' : '1',
|
|
'port' : '9999',
|
|
'ddns' : 'http://localhost:9999',
|
|
'use_login' : 'False',
|
|
'web_id': 'admin',
|
|
'web_pw': 'Vm51JgZqhpwXc/UPc9CAN1lhj4s65+4ikv7GzNmvN6c=',
|
|
'web_title': 'Home',
|
|
'use_apikey': 'False',
|
|
'apikey': ''.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',
|
|
'log_level' : '20',
|
|
'system_start_time': '',
|
|
# notify
|
|
'notify_telegram_use' : 'False',
|
|
'notify_telegram_token' : '',
|
|
'notify_telegram_chat_id' : '',
|
|
'notify_telegram_disable_notification' : 'False',
|
|
'notify_discord_use' : 'False',
|
|
'notify_discord_webhook' : '',
|
|
'notify_advaned_use' : 'False',
|
|
'notify.yaml': '', #직접 사용하지 않으나 저장 편의상.
|
|
'command_text': '',
|
|
'celery_start_by_web': 'False', #웹 실행시 celery 실행
|
|
'celery_start_command': "celery -A flaskfarm.main.celery worker --loglevel=info --pool=gevent --concurrency=2 --config_filepath={F.config['config_filepath']} --running_type=native",
|
|
|
|
|
|
}
|
|
|
|
def __init__(self, P):
|
|
super(ModuleSetting, self).__init__(P, name=name, first_menu='basic')
|
|
|
|
|
|
def process_menu(self, page, req):
|
|
arg = P.ModelSetting.to_dict()
|
|
try:
|
|
if page == 'config':
|
|
arg['config.yaml'] = SupportFile.read_file(F.config['config_filepath'])
|
|
arg['config_filepath'] = F.config['config_filepath']
|
|
elif page == 'export':
|
|
arg['export_filepath'] = F.config['export_filepath']
|
|
if F.config['exist_export']:
|
|
arg['export.sh'] = SupportFile.read_file(export)
|
|
else:
|
|
arg['export.sh'] = "export.sh 파일이 없습니다."
|
|
elif page == 'menu':
|
|
arg['menu_yaml_filepath'] = F.config['menu_yaml_filepath']
|
|
arg['menu.yaml'] = SupportFile.read_file(arg['menu_yaml_filepath'])
|
|
elif page == 'notify':
|
|
arg['notify_yaml_filepath'] = F.config['notify_yaml_filepath']
|
|
arg['notify.yaml'] = SupportFile.read_file(arg['notify_yaml_filepath'])
|
|
elif page == 'celery':
|
|
arg['use_celery'] = F.config['use_celery']
|
|
arg['running_type'] = F.config['running_type']
|
|
return render_template(f'{__package__}_{name}_{page}.html', arg=arg)
|
|
except Exception as e:
|
|
P.logger.error(f'Exception:{str(e)}')
|
|
P.logger.error(traceback.format_exc())
|
|
return render_template('sample.html', title=f"{__package__}/{name}/{page}")
|
|
|
|
|
|
def process_command(self, command, arg1, arg2, arg3, req):
|
|
ret = {'ret':'success'}
|
|
if command == 'apikey_generate':
|
|
return jsonify(''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10)))
|
|
elif command == 'config_save':
|
|
SupportFile.write_file(F.config['config_filepath'], arg1 )
|
|
ret['msg'] = '저장하였습니다.'
|
|
elif command == 'export_save':
|
|
if F.config['exist_export']:
|
|
SupportFile.write_file(F.config['export_filepath'], arg1 )
|
|
ret['msg'] = '저장하였습니다.'
|
|
else:
|
|
ret['ret'] = 'warning'
|
|
ret['msg'] = 'export.sh 파일이 없습니다.'
|
|
elif command == 'menu_save':
|
|
SupportFile.write_file(F.config['menu_yaml_filepath'], arg1 )
|
|
ret['msg'] = '저장하였습니다.'
|
|
from framework.init_menu import MenuManager
|
|
MenuManager.init_menu()
|
|
F.socketio.emit("refresh", {}, namespace='/framework', broadcast=True)
|
|
elif command == 'notify_test':
|
|
if arg1 == 'telegram':
|
|
token, chatid, sound, text = arg2.split('||')
|
|
sound = True if sound == 'true' else False
|
|
SupportTelegram.send_telegram_message(text, image_url=None, bot_token=token, chat_id=chatid, disable_notification=sound)
|
|
ret['msg'] = '메시지를 전송했습니다.'
|
|
elif arg1 == 'discord':
|
|
SupportDiscord.send_discord_message(arg3, webhook_url=arg2)
|
|
ret['msg'] = '메시지를 전송했습니다.'
|
|
elif arg1 == 'advanced':
|
|
from tool import ToolNotify
|
|
ToolNotify.send_advanced_message(arg3, message_id=arg2)
|
|
ret['msg'] = '메시지를 전송했습니다.'
|
|
elif command == 'ddns_test':
|
|
try:
|
|
import requests
|
|
url = arg1 + '/version'
|
|
res = requests.get(url)
|
|
data = res.text
|
|
ret['msg'] = f"버전: {data}"
|
|
except Exception as e:
|
|
P.logger.error(f'Exception:{str(e)}')
|
|
P.logger.error(traceback.format_exc())
|
|
ret['msg'] = str(e)
|
|
ret['type'] = 'warning'
|
|
elif command == 'command_run':
|
|
ret['msg'] = arg1
|
|
pass
|
|
elif command == 'celery_execute':
|
|
self.celery_execute(arg1, mode='foreground')
|
|
elif command == 'celery_execute_back':
|
|
self.celery_execute(arg1, mode='background')
|
|
ret['msg'] = '실행했습니다.'
|
|
elif command == 'celery_test':
|
|
return self.__celery_test()
|
|
|
|
return jsonify(ret)
|
|
|
|
|
|
def plugin_load(self):
|
|
try:
|
|
if F.config['run_flask'] == False:
|
|
return
|
|
if SystemModelSetting.get_bool('celery_start_by_web'):
|
|
self.celery_execute()
|
|
if F.config['arg_repeat'] == 0 or SystemModelSetting.get('system_start_time') == '':
|
|
SystemModelSetting.set('system_start_time', datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
|
|
SystemModelSetting.set('repeat', str(F.config['arg_repeat']))
|
|
username = SystemModelSetting.get('web_id')
|
|
passwd = SystemModelSetting.get('web_pw')
|
|
F.users[username] = User(username, passwd_hash=passwd)
|
|
|
|
self.__set_restart_scheduler()
|
|
self.__set_scheduler_check_scheduler()
|
|
F.get_recent_version()
|
|
|
|
notify_yaml_filepath = os.path.join(F.config['path_data'], 'db', 'notify.yaml')
|
|
if os.path.exists(notify_yaml_filepath) == False:
|
|
import shutil
|
|
shutil.copy(
|
|
os.path.join(F.config['path_app'], 'files', 'notify.yaml.template'),
|
|
notify_yaml_filepath
|
|
)
|
|
if SystemModelSetting.get_bool('restart_notify'):
|
|
from tool import ToolNotify
|
|
msg = f"시스템이 시작되었습니다.\n재시작: {F.config['arg_repeat']}"
|
|
ToolNotify.send_message(msg, message_id='system_start')
|
|
|
|
|
|
except Exception as e:
|
|
P.logger.error(f'Exception:{str(e)}')
|
|
P.logger.error(traceback.format_exc())
|
|
|
|
def plugin_unload(self):
|
|
ToolModalCommand.modal_close()
|
|
|
|
def setting_save_after(self, change_list):
|
|
if 'theme' in change_list or 'web_title' in change_list:
|
|
F.socketio.emit("refresh", {}, namespace='/framework', broadcast=True)
|
|
elif 'notify.yaml' in change_list:
|
|
SupportFile.write_file(F.config['notify_yaml_filepath'], SystemModelSetting.get('notify.yaml'))
|
|
|
|
|
|
def __set_restart_scheduler(self):
|
|
name = f'{__package__}_restart'
|
|
if F.scheduler.is_include(name):
|
|
F.scheduler.remove_job(name)
|
|
interval = SystemModelSetting.get('restart_interval')
|
|
if interval != '0':
|
|
if len(interval.split(' ')) == 1:
|
|
interval = '%s' % (int(interval) * 60)
|
|
job_instance = Job(__package__, name, interval, F.restart, "자동 재시작")
|
|
F.scheduler.add_job_instance(job_instance, run=False)
|
|
|
|
|
|
def __set_scheduler_check_scheduler(self):
|
|
name = 'scheduler_check'
|
|
if F.scheduler.is_include(name):
|
|
F.scheduler.remove_job(name)
|
|
|
|
job_instance = Job(__package__, name, 2, F.scheduler.first_run_check_thread_function, "Scheduler Check")
|
|
scheduler.add_job_instance(job_instance, run=False)
|
|
|
|
|
|
def celery_execute(self, command=None, mode='background'):
|
|
if command == None:
|
|
command = SystemModelSetting.get('celery_start_command')
|
|
command = command.replace("{F.config['config_filepath']}", F.config['config_filepath']).replace('{F.config["config_filepath"]}', F.config['config_filepath']).replace("{F.config['path_working']}", F.config['path_working']).replace('{F.config["path_working"]}', F.config['path_working'])
|
|
command = command.split(' ')
|
|
if mode == 'foreground':
|
|
cmd = [
|
|
['msg', f'명령 : {' '.join(command)}'],
|
|
command,
|
|
]
|
|
ToolModalCommand.start("Celery 실행", cmd)
|
|
elif mode == 'background':
|
|
SupportSubprocess(command).start(join=False)
|
|
|
|
|
|
def __celery_test(self):
|
|
if F.config['use_celery']:
|
|
from celery import Celery
|
|
from celery.exceptions import NotRegistered, TimeoutError
|
|
data = {}
|
|
try:
|
|
result = self.celery_test.apply_async()
|
|
try:
|
|
tmp = result.get(timeout=5, propagate=True)
|
|
except Exception as e:
|
|
P.logger.error(f'Exception:{str(e)}')
|
|
P.logger.error(traceback.format_exc())
|
|
data['ret'] = 'success'
|
|
data['msg'] = tmp
|
|
except TimeoutError:
|
|
data['ret'] = 'danger'
|
|
data['msg'] = 'celery가 동작중이 아니거나 모든 Worker가 작업중입니다.'
|
|
except NotRegistered:
|
|
data['ret'] = 'danger'
|
|
data['msg'] = 'Not Registered'
|
|
except:
|
|
data['ret'] = 'danger'
|
|
data['msg'] = '실패'
|
|
else:
|
|
data['ret'] = 'danger'
|
|
data['msg'] = 'celery 실행환경이 아닙니다.'
|
|
P.logger.debug(d(data))
|
|
return data
|
|
|
|
#@staticmethod
|
|
@celery.task
|
|
def celery_test():
|
|
try:
|
|
time.sleep(1)
|
|
data = '정상입니다. 이 메시지는 celery 에서 반환됩니다. '
|
|
return data
|
|
except Exception as e:
|
|
P.logger.error(f'Exception:{str(e)}')
|
|
P.logger.error(traceback.format_exc())
|