linkkf 로직수정중
This commit is contained in:
277
lib/system/files/all_plugin.yaml
Normal file
277
lib/system/files/all_plugin.yaml
Normal file
@@ -0,0 +1,277 @@
|
||||
- name: "기본"
|
||||
list:
|
||||
- title: "파일 매니저"
|
||||
package_name: "flaskfilemanager"
|
||||
developer: "stevelittlefish"
|
||||
home: "https://github.com/flaskfarm/flaskfilemanager"
|
||||
description: "RichFilemanager를 Flask에서 동작하도록 한 FlaskFileManager 포크"
|
||||
- title: "터미널"
|
||||
package_name: "terminal"
|
||||
developer: "joyful"
|
||||
home: "https://github.com/flaskfarm/terminal"
|
||||
description: "리눅스 전용 심플 터미널. xterm.js client"
|
||||
- title: "편집기"
|
||||
package_name: "flaskcode"
|
||||
developer: "sujeetkv"
|
||||
home: "https://github.com/flaskfarm/flaskcode"
|
||||
description: "flaskcode를 fork한 문서 편집기"
|
||||
- name: "보조 & 라이브러리"
|
||||
list:
|
||||
- title: "번역"
|
||||
package_name: "trans"
|
||||
developer: "FlaskFarm"
|
||||
home: "https://github.com/flaskfarm/trans"
|
||||
description: "번역 관련 설정 및 API 제공"
|
||||
- title: "support_site"
|
||||
package_name: "support_site"
|
||||
developer: "flaskfarm"
|
||||
home: "https://github.com/flaskfarm/support_site"
|
||||
description: "사이트 크롤링 라이브러리"
|
||||
- title: "Gdrive 라이브러리 for FlaskFarm"
|
||||
package_name: "libgdrive"
|
||||
developer: "orial"
|
||||
home: "https://github.com/byorial/libgdrive"
|
||||
description: "구글드라이브 API 라이브러리"
|
||||
- name: "외부 연결"
|
||||
list:
|
||||
- title: "Rclone"
|
||||
package_name: "rclone"
|
||||
developer: "flaskfarm"
|
||||
home: "https://github.com/flaskfarm/rclone"
|
||||
description: "Rclone을 좀 더 쉽게 사용하기 위한 플러그인"
|
||||
- title: "PLEX MATE"
|
||||
package_name: "plex_mate"
|
||||
developer: "flaskfarm"
|
||||
home: "https://github.com/flaskfarm/plex_mate"
|
||||
description: "PLEX와 동일 기기에서 동작하는 툴"
|
||||
- title: "vnStat"
|
||||
package_name: "vnStat"
|
||||
developer: "by275"
|
||||
home: "https://github.com/by275/vnStat"
|
||||
description: "vnStat 정보를 보여주는 플러그인"
|
||||
- title: "115 TOOL"
|
||||
package_name: "tool_115"
|
||||
developer: "soju6jan"
|
||||
home: "https://github.com/soju6jan/tool_115"
|
||||
description: "115 TOOL"
|
||||
- name: "도구"
|
||||
list:
|
||||
- title: "디스코드 봇"
|
||||
package_name: "discord_bot"
|
||||
developer: "flaskfarm"
|
||||
home: "https://github.com/flaskfarm/discord_bot"
|
||||
description: "디스코드 봇"
|
||||
- title: "정적 호스트"
|
||||
package_name: "static_host"
|
||||
developer: "by275"
|
||||
description: "정적 웹을 호스팅 하는 플러그인"
|
||||
home: "https://github.com/by275/static_host"
|
||||
- title: 'Flaskfarmaider'
|
||||
package_name: 'flaskfarmaider'
|
||||
developer: 'halfaider'
|
||||
description: 'Flaskfarm 보조 플러그인'
|
||||
home: 'https://github.com/halfaider/flaskfarmaider'
|
||||
- title: "메타데이터"
|
||||
package_name: "metadata"
|
||||
developer: "flaskfarm"
|
||||
home: "https://github.com/flaskfarm/metadata"
|
||||
description: "VIDEO 메타데이터 제공"
|
||||
- title: "lotto"
|
||||
package_name: "lotto"
|
||||
developer: "honeypig5"
|
||||
home: "https://github.com/hudulgi/lotto"
|
||||
description: "로또 구매"
|
||||
- title: "핫딜 알람"
|
||||
package_name: "hotdeal_alarm"
|
||||
developer: "dbswnschl"
|
||||
home: "https://github.com/dbswnschl/hotdeal_alarm"
|
||||
description: "핫딜 알리미"
|
||||
- name: "파일처리"
|
||||
list:
|
||||
- title: "국내TV 파일처리"
|
||||
package_name: "fp_ktv"
|
||||
developer: "flaskfarm"
|
||||
home: "https://github.com/flaskfarm/fp_ktv"
|
||||
description: "국내TV 영상 파일 전용 파일처리"
|
||||
- title: "영화 파일처리"
|
||||
package_name: "fp_movie"
|
||||
developer: "flaskfarm"
|
||||
home: "https://github.com/flaskfarm/fp_movie"
|
||||
description: "영화 파일처리"
|
||||
- title: "musicProc2"
|
||||
package_name: "musicProc2"
|
||||
developer: "dyllislev"
|
||||
home: "https://github.com/dyllisLev/musicProc2"
|
||||
description: "음악정리"
|
||||
- title: "해외TV 파일처리"
|
||||
package_name: "fp_ftv"
|
||||
developer: "kihyyo"
|
||||
home: "https://github.com/kihyyo/fp_ftv"
|
||||
description: "해외TV 영상 파일 전용 파일처리"
|
||||
- title: "자막 툴"
|
||||
package_name: "subtitle_tool"
|
||||
developer: "flaskfarm"
|
||||
home: "https://github.com/flaskfarm/subtitle_tool"
|
||||
description: "자막 관련 툴"
|
||||
- name: "토렌트 & RSS"
|
||||
list:
|
||||
- title: "토렌트 정보"
|
||||
package_name: "torrent_info"
|
||||
developer: "by275"
|
||||
home: "https://github.com/by275/torrent_info"
|
||||
description: "토렌트 마그넷/파일 정보를 보여주는 플러그인"
|
||||
- title: "티프리카"
|
||||
package_name: "tfreeca"
|
||||
developer: "by275"
|
||||
home: "https://github.com/by275/tfreeca"
|
||||
description: "티프리카 게시판 뷰어"
|
||||
- name: "OTT"
|
||||
list:
|
||||
- title: "티빙 검색"
|
||||
package_name: "tving_search"
|
||||
developer: "by275"
|
||||
home: "https://github.com/by275/tving_search"
|
||||
description: "티빙 검색 플러그인"
|
||||
- title: "FFMPEG"
|
||||
package_name: "ffmpeg"
|
||||
developer: "FlaskFarm"
|
||||
home: "https://github.com/flaskfarm/ffmpeg"
|
||||
description: "m3u8 다운로드 & 비디오파일 분석"
|
||||
- title: "웨이브"
|
||||
package_name: "wavve"
|
||||
developer: "halfaider"
|
||||
home: "https://github.com/halfaider/wavve"
|
||||
description: "웨이브 VOD 다운로더"
|
||||
- title: "티빙"
|
||||
package_name: "tving"
|
||||
developer: "kihyyo"
|
||||
home: "https://github.com/kihyyo/tving"
|
||||
description: "티빙 VOD 다운로더"
|
||||
- title: "쿠팡플레이"
|
||||
package_name: "cppl"
|
||||
developer: "soju6jan"
|
||||
home: "https://github.com/soju6jan/cppl"
|
||||
description: "쿠팡플레이 VOD 다운로더"
|
||||
- title: "DRM 다운로드"
|
||||
package_name: "wv_tool"
|
||||
developer: "soju6jan"
|
||||
home: "https://github.com/soju6jan/wv_tool"
|
||||
description: "DRM 영상 다운로드"
|
||||
- title: "make_yaml"
|
||||
package_name: "make_yaml"
|
||||
developer: "kihyyo"
|
||||
home: "https://github.com/kihyyo/make_yaml"
|
||||
description: "OTT 정보로 직접 yaml로 만드는 플러그인"
|
||||
- title: "RE_tool"
|
||||
package_name: "RE_tool"
|
||||
developer: "kihyyo"
|
||||
home: "https://github.com/kihyyo/RE_tool"
|
||||
description: "M3U8_RE 다운로드"
|
||||
- name: "라이브"
|
||||
list:
|
||||
- title: "ALive"
|
||||
package_name: "alive"
|
||||
developer: "by275"
|
||||
home: "https://github.com/by275/alive"
|
||||
description: "라이브 방송 플러그인"
|
||||
- title: "EPG"
|
||||
package_name: "epg"
|
||||
developer: "flaskfarm"
|
||||
home: "https://github.com/flaskfarm/epg"
|
||||
description: "EPG 생성"
|
||||
- title: "MY EPG"
|
||||
package_name: "myepg"
|
||||
developer: "include"
|
||||
home: "https://github.com/myepg/myepg"
|
||||
description: "EPG API 플러그인"
|
||||
- title: "HDHomerun"
|
||||
package_name: "hdhomerun"
|
||||
developer: "flaskfarm"
|
||||
home: "https://github.com/flaskfarm/hdhomerun"
|
||||
description: "HDHomerun 도구"
|
||||
- title: "스포TV"
|
||||
package_name: "ff_spotv"
|
||||
developer: "ssagajikorea"
|
||||
home: "https://github.com/ssagajikorea/ff_spotv"
|
||||
description: "스포TV 방송 FF플러그인"
|
||||
- title: "삼성TV플러스"
|
||||
package_name: "ff_sstvplus"
|
||||
developer: "ssagajikorea"
|
||||
home: "https://github.com/ssagajikorea/ff_sstvplus"
|
||||
description: "삼성TV플러스 방송 FF플러그인"
|
||||
- title: "네이버스포츠"
|
||||
package_name: "ff_nsports"
|
||||
developer: "ssagajikorea"
|
||||
home: "https://github.com/ssagajikorea/ff_nsports"
|
||||
description: "네이버스포츠 방송 FF플러그인"
|
||||
- title: "쿠팡플레이"
|
||||
package_name: "ff_cpp"
|
||||
developer: "ssagajikorea"
|
||||
home: "https://github.com/ssagajikorea/ff_cpp"
|
||||
description: "쿠팡플레이 방송 FF플러그인"
|
||||
- title: "아프리카TV"
|
||||
package_name: "ff_afrtv"
|
||||
developer: "ssagajikorea"
|
||||
home: "https://github.com/ssagajikorea/ff_afrtv"
|
||||
description: "아프리카TV 방송 FF플러그인"
|
||||
- title: "REYSTREAM"
|
||||
package_name: "ff_reystream"
|
||||
developer: "ssagajikorea"
|
||||
description: "REYSTREAM 방송 FF플러그인"
|
||||
home: "https://github.com/ssagajikorea/ff_reystream"
|
||||
- title: "팝콘TV"
|
||||
package_name: "ff_pktv"
|
||||
developer: "ssagajikorea"
|
||||
home: "https://github.com/ssagajikorea/ff_pktv"
|
||||
description: "팝콘TV 방송 FF플러그인"
|
||||
- title: "팬더TV"
|
||||
package_name: "ff_pdtv"
|
||||
developer: "ssagajikorea"
|
||||
home: "https://github.com/ssagajikorea/ff_pdtv"
|
||||
description: "팬더TV 방송 FF플러그인"
|
||||
- title: "NEXTCAST"
|
||||
package_name: "ff_nextcast"
|
||||
developer: "ssagajikorea"
|
||||
home: "https://github.com/ssagajikorea/ff_nextcast"
|
||||
description: "NEXTCAST 방송 FF플러그인"
|
||||
- title: "LIFETV365"
|
||||
package_name: "ff_lifetv365"
|
||||
developer: "ssagajikorea"
|
||||
home: "https://github.com/ssagajikorea/ff_lifetv365"
|
||||
description: "LIFETV365 방송 FF플러그인"
|
||||
- title: "KLive+"
|
||||
package_name: "klive_plus"
|
||||
developer: "soju6jan"
|
||||
home: "https://github.com/soju6jan/klive_plus"
|
||||
description: "KLive+"
|
||||
- name: "SJVA"
|
||||
list:
|
||||
- title: "SJVA"
|
||||
package_name: "sjva"
|
||||
developer: "soju6jan"
|
||||
home: "https://github.com/soju6jan/sjva"
|
||||
description: "SJVA 인증 & 사이트 연동"
|
||||
- title: "구드공 툴"
|
||||
package_name: "gds_tool"
|
||||
developer: "soju6jan"
|
||||
home: "https://github.com/soju6jan/gds_tool"
|
||||
description: "복사요청, 제공, GDS 변경사항"
|
||||
- title: "봇 다운로더"
|
||||
package_name: "bot_downloader"
|
||||
developer: "flaskfarm"
|
||||
home: "https://github.com/soju6jan/bot_downloader"
|
||||
description: "봇 다운로더"
|
||||
# name: "기타"
|
||||
# list:
|
||||
# - title: "숫자 야구"
|
||||
# package_name: "number_baseball"
|
||||
# developer: "FlaskFarm"
|
||||
# home: "https://github.com/flaskfarm/number_baseball"
|
||||
# description: "숫자 야구 - 샘플 플러그인"
|
||||
# - title: "샘플 플러그인"
|
||||
# package_name: "sample"
|
||||
# developer: "FlaskFarm"
|
||||
# home: "https://github.com/flaskfarm/sample"
|
||||
# description: "샘플 플러그인"
|
||||
|
||||
|
||||
9
lib/system/files/매뉴얼_설정.md
Normal file
9
lib/system/files/매뉴얼_설정.md
Normal file
@@ -0,0 +1,9 @@
|
||||
### 알림
|
||||
|
||||
##### 텔레그램
|
||||
|
||||
* @BotFather 에게서 Bot 생성
|
||||
* https://api.telegram.org/bot봇토큰/getUpdates 접속
|
||||
* 본인의 봇과 대화
|
||||
* https://api.telegram.org/bot봇토큰/getUpdates 접속
|
||||
"from":{"id":879500000, 숫자가 본인의 Chat ID
|
||||
@@ -31,7 +31,7 @@ class ModuleHome(PluginModuleBase):
|
||||
for key, value in F.app.config.items():
|
||||
if key not in ['SECRET_KEY']:
|
||||
data[key] = str(value)
|
||||
ret = {'json':{'Framework':F.config, 'Flask':data}}
|
||||
ret = {'json':{'Framework':F.config, 'Flask':data}, 'title':'config'}
|
||||
return jsonify(ret)
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ class ModuleHome(PluginModuleBase):
|
||||
ret = {}
|
||||
ret['system'] = self.get_info()
|
||||
ret['scheduler'] = scheduler.get_job_list_info()
|
||||
F.socketio.emit("status", ret, namespace=f'/{P.package_name}/{name}', broadcast=True)
|
||||
F.socketio.emit("status", ret, namespace=f'/{P.package_name}/{name}')
|
||||
|
||||
|
||||
def get_info(self, mode=''):
|
||||
|
||||
@@ -22,14 +22,11 @@ class ModuleLog(PluginModuleBase):
|
||||
log_list.append(x)
|
||||
arg['log_list'] = '|'.join(log_list)
|
||||
arg['all_list'] = '|'.join(log_files)
|
||||
arg['filename'] = 'framework.log'
|
||||
print(request.form)
|
||||
print(request.form)
|
||||
print(request.form)
|
||||
print(request.form)
|
||||
|
||||
arg['filename'] = 'all.log'
|
||||
|
||||
if 'filename' in request.form:
|
||||
arg['filename'] = request.form['filename']
|
||||
arg['filename'] = req.args.get('filename', arg['filename'])
|
||||
return render_template(f'{__package__}_{name}.html', arg=arg)
|
||||
except Exception as e:
|
||||
P.logger.error(f'Exception:{str(e)}')
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
import shutil
|
||||
|
||||
from support import SupportFile
|
||||
from support import SupportFile, SupportYaml
|
||||
|
||||
from .setup import *
|
||||
|
||||
name = 'plugin'
|
||||
|
||||
class ModulePlugin(PluginModuleBase):
|
||||
|
||||
def __init__(self, P):
|
||||
super(ModulePlugin, self).__init__(P, name=name, first_menu='list')
|
||||
self.all_plugin_list = None
|
||||
|
||||
|
||||
def process_menu(self, page, req):
|
||||
@@ -36,14 +38,16 @@ class ModulePlugin(PluginModuleBase):
|
||||
"""
|
||||
for name, entity in F.PluginManager.all_package_list.items():
|
||||
try:
|
||||
if entity.get('version') == '3':
|
||||
#data.append(entity)
|
||||
data.append({'package_name':name})
|
||||
else:
|
||||
if 'P' in entity:
|
||||
data.append(entity['P'].plugin_info)
|
||||
data[-1]['loading'] = entity.get('loading')
|
||||
data[-1]['status'] = entity.get('status')
|
||||
data[-1]['log'] = entity.get('log')
|
||||
else:
|
||||
data.append({'package_name':name})
|
||||
data[-1]['loading'] = entity.get('loading')
|
||||
data[-1]['status'] = entity.get('status')
|
||||
data[-1]['log'] = entity.get('log')
|
||||
except Exception as e:
|
||||
data.append({'package_name':name})
|
||||
P.logger.error(f'Exception:{str(e)}')
|
||||
@@ -64,6 +68,36 @@ class ModulePlugin(PluginModuleBase):
|
||||
else:
|
||||
ret['msg'] = info['path'] + "<br>폴더가 없습니다."
|
||||
ret['ret'] = 'danger'
|
||||
elif command == 'get_plugin_list_all':
|
||||
if self.all_plugin_list == None:
|
||||
filepath = os.path.join(os.path.dirname(__file__), 'files', 'all_plugin.yaml')
|
||||
self.all_plugin_list = SupportYaml.read_yaml(filepath)
|
||||
|
||||
def get_plugin(_name):
|
||||
for _cate in self.all_plugin_list:
|
||||
for _plugin in _cate['list']:
|
||||
if _plugin['package_name'] == _name:
|
||||
P.logger.info(_name)
|
||||
if _name == 'ff_reystream':
|
||||
P.logger.info(_name)
|
||||
return _plugin
|
||||
|
||||
|
||||
for name, entity in F.PluginManager.all_package_list.items():
|
||||
try:
|
||||
_plugin = get_plugin(name)
|
||||
if _plugin != None:
|
||||
_plugin['loading'] = entity.get('loading')
|
||||
_plugin['status'] = entity.get('status')
|
||||
_plugin['log'] = entity.get('log')
|
||||
|
||||
_plugin['version'] = entity['P'].plugin_info['version']
|
||||
|
||||
except Exception as e:
|
||||
data.append({'package_name':name})
|
||||
P.logger.error(f'Exception:{str(e)}')
|
||||
P.logger.error(traceback.format_exc())
|
||||
ret['data'] = self.all_plugin_list
|
||||
return jsonify(ret)
|
||||
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ class ModuleRoute(PluginModuleBase):
|
||||
|
||||
@F.socketio.on('connect', namespace=f'/{P.package_name}/restart')
|
||||
def restart_socket_connect():
|
||||
F.socketio.emit('connect', {}, namespace='/{P.package_name}/restart', broadcast=True)
|
||||
F.socketio.emit('connect', {}, namespace='/{P.package_name}/restart')
|
||||
|
||||
|
||||
def process_menu(self, page, req):
|
||||
|
||||
@@ -2,8 +2,8 @@ import random
|
||||
import string
|
||||
import time
|
||||
|
||||
from support import (SupportDiscord, SupportFile, SupportSubprocess,
|
||||
SupportTelegram)
|
||||
from support import (SupportDiscord, SupportFile, SupportSlack,
|
||||
SupportSubprocess, SupportTelegram, SupportYaml)
|
||||
from tool import ToolModalCommand
|
||||
|
||||
from .setup import *
|
||||
@@ -12,7 +12,7 @@ name = 'setting'
|
||||
|
||||
class ModuleSetting(PluginModuleBase):
|
||||
db_default = {
|
||||
'db_version' : '1',
|
||||
'db_version' : '1.1',
|
||||
'port' : '9999',
|
||||
'ddns' : 'http://localhost:9999',
|
||||
'use_login' : 'False',
|
||||
@@ -34,6 +34,8 @@ class ModuleSetting(PluginModuleBase):
|
||||
'notify_telegram_disable_notification' : 'False',
|
||||
'notify_discord_use' : 'False',
|
||||
'notify_discord_webhook' : '',
|
||||
'notify_slack_use' : 'False',
|
||||
'notify_slack_webhook' : '',
|
||||
'notify_advaned_use' : 'False',
|
||||
'notify.yaml': '', #직접 사용하지 않으나 저장 편의상.
|
||||
'command_text': '',
|
||||
@@ -91,10 +93,15 @@ class ModuleSetting(PluginModuleBase):
|
||||
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)
|
||||
try:
|
||||
SupportYaml.read_yaml(F.config['menu_yaml_filepath'])
|
||||
ret['msg'] = '저장하였습니다.'
|
||||
from framework.init_menu import MenuManager
|
||||
MenuManager.init_menu()
|
||||
F.socketio.emit("refresh", {}, namespace='/framework')
|
||||
except:
|
||||
ret['ret'] = "danger"
|
||||
ret['msg'] = "yaml 형식에 맞지 않습니다"
|
||||
elif command == 'notify_test':
|
||||
if arg1 == 'telegram':
|
||||
token, chatid, sound, text = arg2.split('||')
|
||||
@@ -104,6 +111,9 @@ class ModuleSetting(PluginModuleBase):
|
||||
elif arg1 == 'discord':
|
||||
SupportDiscord.send_discord_message(arg3, webhook_url=arg2)
|
||||
ret['msg'] = '메시지를 전송했습니다.'
|
||||
elif arg1 == 'slack':
|
||||
SupportSlack.send_slack_message(arg3, webhook_url=arg2)
|
||||
ret['msg'] = '메시지를 전송했습니다.'
|
||||
elif arg1 == 'advanced':
|
||||
from tool import ToolNotify
|
||||
ToolNotify.send_advanced_message(arg3, message_id=arg2)
|
||||
@@ -122,7 +132,31 @@ class ModuleSetting(PluginModuleBase):
|
||||
ret['type'] = 'warning'
|
||||
elif command == 'command_run':
|
||||
ret['msg'] = arg1
|
||||
pass
|
||||
SystemModelSetting.set('command_text', arg1)
|
||||
# db이름 set/get key value
|
||||
try:
|
||||
tmp = arg1.strip().split(' ')
|
||||
if tmp[0].startswith('setting'):
|
||||
plugin = F.PluginManager.get_plugin_instance(tmp[1])
|
||||
if len(tmp) == 2 or tmp[2] == 'all':
|
||||
ret['json'] = plugin.ModelSetting.to_dict()
|
||||
ret['ret'] = 'success'
|
||||
elif tmp[2] == 'get':
|
||||
ret['msg'] = plugin.ModelSetting.get(tmp[3])
|
||||
ret['ret'] = 'success'
|
||||
elif tmp[2] == 'set':
|
||||
value = ""
|
||||
if len(tmp) == 5:
|
||||
value = tmp[4]
|
||||
plugin.ModelSetting.set(tmp[3], value)
|
||||
ret['msg'] = f"{tmp[1]} DB에 {tmp[3]}={value} 저장"
|
||||
|
||||
except Exception as e:
|
||||
P.logger.error(f'Exception:{str(e)}')
|
||||
P.logger.error(traceback.format_exc())
|
||||
ret['msg'] = f"실행 실패: {str(e)}"
|
||||
ret['type'] = 'danger'
|
||||
|
||||
elif command == 'celery_execute':
|
||||
self.celery_execute(arg1, mode='foreground')
|
||||
elif command == 'celery_execute_back':
|
||||
@@ -138,8 +172,7 @@ class ModuleSetting(PluginModuleBase):
|
||||
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']))
|
||||
@@ -162,7 +195,11 @@ class ModuleSetting(PluginModuleBase):
|
||||
from tool import ToolNotify
|
||||
msg = f"시스템이 시작되었습니다.\n재시작: {F.config['arg_repeat']}"
|
||||
ToolNotify.send_message(msg, message_id='system_start')
|
||||
|
||||
if SystemModelSetting.get_bool('celery_start_by_web'):
|
||||
# 2022-11-14 DB는 flask가 만드는데 만들기전 celery를 실행해버림
|
||||
from threading import Timer
|
||||
Timer(10, self.celery_execute).start()
|
||||
#self.celery_execute()
|
||||
|
||||
except Exception as e:
|
||||
P.logger.error(f'Exception:{str(e)}')
|
||||
@@ -173,9 +210,14 @@ class ModuleSetting(PluginModuleBase):
|
||||
|
||||
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)
|
||||
F.socketio.emit("refresh", {}, namespace='/framework')
|
||||
elif 'notify.yaml' in change_list:
|
||||
SupportFile.write_file(F.config['notify_yaml_filepath'], SystemModelSetting.get('notify.yaml'))
|
||||
try:
|
||||
SupportFile.write_file(F.config['notify_yaml_filepath'], SystemModelSetting.get('notify.yaml'))
|
||||
SupportYaml.read_yaml(F.config['notify_yaml_filepath'])
|
||||
except:
|
||||
data = {'type':'danger', 'msg' : "알림 정책이 yaml 형식에 맞지 않습니다."}
|
||||
F.socketio.emit("notify", data, namespace='/framework')
|
||||
elif 'web_pw' in change_list:
|
||||
import hashlib
|
||||
enc = hashlib.md5()
|
||||
@@ -185,6 +227,9 @@ class ModuleSetting(PluginModuleBase):
|
||||
if SystemModelSetting.get('restart_interval') == '':
|
||||
SystemModelSetting.set('restart_interval', '0')
|
||||
self.__set_restart_scheduler()
|
||||
elif 'log_level' in change_list:
|
||||
F.set_level(SystemModelSetting.get_int('log_level'))
|
||||
|
||||
|
||||
|
||||
def __set_restart_scheduler(self):
|
||||
@@ -258,6 +303,7 @@ class ModuleSetting(PluginModuleBase):
|
||||
try:
|
||||
time.sleep(1)
|
||||
data = '정상입니다. 이 메시지는 celery 에서 반환됩니다. '
|
||||
P.logger.info(data)
|
||||
return data
|
||||
except Exception as e:
|
||||
P.logger.error(f'Exception:{str(e)}')
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import queue
|
||||
import shlex
|
||||
|
||||
from support import SupportSubprocess
|
||||
from tool import ToolModalCommand
|
||||
@@ -25,7 +26,7 @@ class PageCommand(PluginPageBase):
|
||||
ret = {'ret':'success'}
|
||||
if command == 'foreground_command':
|
||||
P.ModelSetting.set(f'{self.parent.name}_{self.name}_recent', arg1)
|
||||
self.__foreground_execute(arg1, arg1.split(' '))
|
||||
self.__foreground_execute(arg1, shlex.split(arg1))
|
||||
|
||||
return jsonify('')
|
||||
elif command == 'job_new':
|
||||
@@ -54,7 +55,7 @@ class PageCommand(PluginPageBase):
|
||||
elif command == 'job_fore_execute':
|
||||
db_item = ModelCommand.get_by_id(arg1)
|
||||
cmd = (db_item.command + ' ' + db_item.args).strip()
|
||||
self.__foreground_execute(f"Command ID: {db_item.id}", cmd.split(' '), db_item.id)
|
||||
self.__foreground_execute(f"Command ID: {db_item.id}", shlex.split(cmd), db_item.id)
|
||||
elif command == 'job_back_execute':
|
||||
self.execute_thread_start(arg1)
|
||||
ret['msg'] = "실행 요청을 하였습니다.<br>로그를 확인하세요."
|
||||
@@ -64,8 +65,8 @@ class PageCommand(PluginPageBase):
|
||||
ret['ret'] = 'danger'
|
||||
ret['msg'] = "로그 파일이 없습니다."
|
||||
elif command == 'task_sched':
|
||||
job_id = req.form['arg1']
|
||||
flag = (req.form['arg2'] == 'true')
|
||||
job_id = arg1
|
||||
flag = (arg2 == 'true')
|
||||
scheduler_id = f'command_{job_id}'
|
||||
if flag and F.scheduler.is_include(scheduler_id):
|
||||
ret['msg'] = '이미 스케쥴러에 등록되어 있습니다.'
|
||||
@@ -92,7 +93,7 @@ class PageCommand(PluginPageBase):
|
||||
if command[0] != 'LOAD':
|
||||
ToolModalCommand.start(title, [command])
|
||||
else:
|
||||
F.socketio.emit("command_modal_show", title, namespace='/framework', broadcast=True)
|
||||
F.socketio.emit("command_modal_show", title, namespace='/framework')
|
||||
def start_communicate_load(load_log_list):
|
||||
def func():
|
||||
while True:
|
||||
@@ -100,7 +101,7 @@ class PageCommand(PluginPageBase):
|
||||
load_log_list.truncate(0)
|
||||
if logs:
|
||||
P.logger.error(logs)
|
||||
F.socketio.emit("command_modal_add_text", logs.strip() + '\n', namespace='/framework', broadcast=True)
|
||||
F.socketio.emit("command_modal_add_text", logs.strip() + '\n', namespace='/framework')
|
||||
if logs == '<<END>>':
|
||||
break
|
||||
time.sleep(0.3)
|
||||
@@ -154,11 +155,12 @@ class PageCommand(PluginPageBase):
|
||||
th = threading.Thread(target=self.execute_thread_function_by_job_id, args=(job_id,))
|
||||
th.setDaemon(True)
|
||||
th.start()
|
||||
return th
|
||||
|
||||
|
||||
def execute_thread_function_by_job_id(self, *args, **kwargs):
|
||||
P.logger.error(d(args))
|
||||
P.logger.error(d(kwargs))
|
||||
#P.logger.error(d(args))
|
||||
#P.logger.error(d(kwargs))
|
||||
db_item = ModelCommand.get_by_id(args[0])
|
||||
kwargs['id'] = args[0]
|
||||
self.execute_thread_function((db_item.command + ' ' + db_item.args).strip(), **kwargs)
|
||||
@@ -166,7 +168,7 @@ class PageCommand(PluginPageBase):
|
||||
|
||||
def execute_thread_function(self, command, **kwargs):
|
||||
try:
|
||||
cmd = command.split(' ')
|
||||
cmd = shlex.split(command)
|
||||
|
||||
if cmd[0] == 'LOAD':
|
||||
command_logger = F.get_logger(f"command_{kwargs['id']}")
|
||||
@@ -177,8 +179,8 @@ class PageCommand(PluginPageBase):
|
||||
def __init__(self, logger):
|
||||
self.logger = logger
|
||||
|
||||
def stdout_callback(self, mode, text):
|
||||
if mode == 'log':
|
||||
def stdout_callback(self, call_id, mode, text):
|
||||
if mode == 'LOG':
|
||||
self.logger.debug(text)
|
||||
else:
|
||||
self.logger.debug(mode)
|
||||
@@ -194,14 +196,17 @@ class PageCommand(PluginPageBase):
|
||||
def plugin_load(self):
|
||||
def plugin_load_thread():
|
||||
try:
|
||||
while F.config['loading_completed'] == False:
|
||||
time.sleep(1)
|
||||
|
||||
db_items = ModelCommand.get_list()
|
||||
for db_item in db_items:
|
||||
if db_item.schedule_mode == 'startup':
|
||||
self.execute_thread_start(db_item.id)
|
||||
elif db_item.schedule_mode == 'scheduler' and db_item.schedule_auto_start:
|
||||
self.__sched_add(db_item.id, db_item=db_item)
|
||||
except Exception as exception:
|
||||
logger.error('Exception:%s', exception)
|
||||
except Exception as e:
|
||||
logger.error(f"Exception:{str(e)}")
|
||||
logger.error(traceback.format_exc())
|
||||
try:
|
||||
th = threading.Thread(target=plugin_load_thread)
|
||||
@@ -219,7 +224,7 @@ class PageCommand(PluginPageBase):
|
||||
job_id = f"command_{db_item.id}"
|
||||
if scheduler.is_include(job_id):
|
||||
return
|
||||
job = Job(self.P.package_name, job_id, db_item.schedule_interval, self.execute_thread_function_by_job_id, db_item.description, args=db_item.id)
|
||||
job = Job(self.P.package_name, job_id, db_item.schedule_interval, self.execute_thread_function_by_job_id, db_item.description, args=(db_item.id,))
|
||||
scheduler.add_job_instance(job)
|
||||
return True
|
||||
except Exception as e:
|
||||
@@ -286,6 +291,6 @@ class ModelCommand(ModelBase):
|
||||
item['process'] = (SupportSubprocess.get_instance_by_call_id(f"command_{item['id']}") != None)
|
||||
|
||||
return data
|
||||
except Exception as exception:
|
||||
logger.error('Exception:%s', exception)
|
||||
except Exception as e:
|
||||
logger.error(f"Exception:{str(e)}")
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
@@ -14,6 +14,7 @@ __menu = {
|
||||
{'uri': 'export', 'name': 'export.sh 파일'},
|
||||
{'uri': 'celery', 'name': '비동기 작업(celery)'},
|
||||
{'uri': 'notify', 'name': '알림'},
|
||||
{'uri': 'manual/files/매뉴얼_설정.md', 'name': '매뉴얼'},
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -22,7 +23,7 @@ __menu = {
|
||||
'list': [
|
||||
#{'uri': 'setting', 'name': '설정'},
|
||||
{'uri': 'list', 'name': '로딩 플러그인'},
|
||||
#{'uri': 'all', 'name': '플러그인 목록'},
|
||||
{'uri': 'all', 'name': '전체 플러그인 목록'},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,33 +1,9 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
|
||||
</style>
|
||||
<div>
|
||||
{{ macros.setting_select_empty('log_select1', '로그 파일 선택 (.log)') }}
|
||||
<!--{{ macros.setting_select_empty('log_select2', '로그 파일 선택 (.logX)') }}-->
|
||||
<nav>
|
||||
{{ macros.m_tab_head_start() }}
|
||||
{{ macros.m_tab_head('old', '이전', true) }}
|
||||
{{ macros.m_tab_head('new', '실시간', false) }}
|
||||
{{ macros.m_tab_head_end() }}
|
||||
</nav>
|
||||
<div class="tab-content" id="nav-tabContent">
|
||||
{{ macros.m_tab_content_start('old', true) }}
|
||||
<div>
|
||||
<textarea id="log" class="col-md-12" rows="30" charswidth="23" disabled style="background-color:#ffffff;visibility:hidden"></textarea>
|
||||
</div>
|
||||
{{ macros.m_tab_content_end() }}
|
||||
{{ macros.m_tab_content_start('new', false) }}
|
||||
<div>
|
||||
<textarea id="add" class="col-md-12" rows="30" charswidth="23" disabled style="background-color:#ffffff;visibility:visible"></textarea>
|
||||
</div>
|
||||
<div class="form-inline">
|
||||
<label class="form-check-label" for="auto_scroll">자동 스크롤</label>
|
||||
<input id="auto_scroll" name="auto_scroll" class="form-control form-control-sm" type="checkbox" data-toggle="toggle" checked>
|
||||
<span class='text-left' style="padding-left:25px; padding-top:0px">
|
||||
<button id="clear" class="btn btn-sm btn-outline-success">리셋</button>
|
||||
</span>
|
||||
</div>
|
||||
{{ macros.m_tab_content_end() }}
|
||||
<div id="log_div" class="bg-dark" style="overflow:auto; border-color: blue; border: solid 1px;">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -56,14 +32,6 @@ function make_form() {
|
||||
str += '<option value="' + data[i] + '">' + data[i] + '</option>';
|
||||
}
|
||||
$("#log_select1_div").html(str);
|
||||
/*
|
||||
str = '<select id="log_select" name="log_select" class="form-control form-control-sm">';
|
||||
data = all_list.split('|')
|
||||
for(var i in data) {
|
||||
str += '<option value="' + data[i] + '">' + data[i] + '</option>';
|
||||
}
|
||||
$("#log_select2_div").html(str);
|
||||
*/
|
||||
}
|
||||
|
||||
$("body").on('change', '#log_select', function(e){
|
||||
@@ -75,11 +43,9 @@ $("body").on('change', '#log_select', function(e){
|
||||
socket.emit("start", {'filename':filename} );
|
||||
});
|
||||
|
||||
|
||||
function ResizeTextAreaAllLog() {
|
||||
ClientHeight = window.innerHeight
|
||||
$("#log").height(ClientHeight-300);
|
||||
$("#add").height(ClientHeight-320);
|
||||
$("#log_div").height(ClientHeight-180);
|
||||
}
|
||||
|
||||
$(window).resize(function() {
|
||||
@@ -88,17 +54,20 @@ $(window).resize(function() {
|
||||
|
||||
|
||||
socket.on('on_start', function(data){
|
||||
document.getElementById("log").innerHTML += data.data;
|
||||
document.getElementById("log").scrollTop = document.getElementById("log").scrollHeight;
|
||||
document.getElementById("log").style.visibility = 'visible';
|
||||
lines = splitLines(data.data);
|
||||
var html = '';
|
||||
for (i in lines) {
|
||||
html += logline(lines[i]);
|
||||
}
|
||||
$('#log_div').html(html)
|
||||
document.getElementById("log_div").scrollTop = document.getElementById("log_div").scrollHeight;
|
||||
$('#loading').hide();
|
||||
});
|
||||
|
||||
socket.on('add', function(data){
|
||||
if (data.filename == current_filename) {
|
||||
var chk = $('#auto_scroll').is(":checked");
|
||||
document.getElementById("add").innerHTML += data.data;
|
||||
if (chk) document.getElementById("add").scrollTop = document.getElementById("add").scrollHeight;
|
||||
$('#log_div').append(logline(data.data.trim()));
|
||||
document.getElementById("log_div").scrollTop = document.getElementById("log_div").scrollHeight;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
|
||||
<canvas id="mycanvas" height="100vh"></canvas>
|
||||
<h3>시스템</h3>
|
||||
<hr>
|
||||
{{ macros.info_text_and_buttons('python_version', 'Python', [['globalLinkBtn', '패키지 관리', [('url','/system/tool/python')]]], info['python_version']) }}
|
||||
@@ -45,21 +45,102 @@
|
||||
|
||||
<h3>스케쥴</h3>
|
||||
<div id="scheduler_list_div"></div>
|
||||
</div> <!--전체-->
|
||||
</div>
|
||||
<!--전체-->
|
||||
<script src="{{ url_for('static', filename='js/chartjs-utils.js') }}"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1/dist/chart.min.js"></script>
|
||||
<script>
|
||||
const Utils = ChartUtils.init()
|
||||
</script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/luxon@3.0.4"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon@1.2.0"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-streaming@2.0.0"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
var socket = io.connect(window.location.href);
|
||||
Chart.defaults.set("plugins.streaming", {
|
||||
duration: 20000,
|
||||
})
|
||||
|
||||
socket.on('start', function(data){
|
||||
});
|
||||
// used for example purposes
|
||||
function getRandomIntInclusive(min, max) {
|
||||
min = Math.ceil(min)
|
||||
max = Math.floor(max)
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min
|
||||
}
|
||||
|
||||
socket.on('status', function(data) {
|
||||
make_system(data.system);
|
||||
make_scheduler_list(data.scheduler);
|
||||
});
|
||||
});
|
||||
$(document).ready(function () {
|
||||
var socket = io.connect(window.location.href)
|
||||
var postId = 1
|
||||
socket.on("start", function (data) {})
|
||||
|
||||
socket.on("status", function (data) {
|
||||
console.log(data.system.cpu_percent)
|
||||
const now = Date.now()
|
||||
//myChart.data.labels.push("T " + postId++)
|
||||
/* */
|
||||
myChart.data.datasets[0].data.push({ x: now, y: data.system.cpu_percent.replace(/.%/g, "") })
|
||||
/* */
|
||||
myChart.update()
|
||||
make_system(data.system)
|
||||
make_scheduler_list(data.scheduler)
|
||||
})
|
||||
|
||||
/* const onRefresh = (chart) => {
|
||||
const now = Date.now()
|
||||
chart.data.datasets.forEach((dataset) => {
|
||||
dataset.data.push({
|
||||
x: now,
|
||||
y: Utils.rand(0, 100),
|
||||
})
|
||||
})
|
||||
}
|
||||
*/
|
||||
|
||||
var ctx_live = document.getElementById("mycanvas")
|
||||
var myChart = new Chart(ctx_live, {
|
||||
type: "line",
|
||||
data: {
|
||||
labels: [],
|
||||
datasets: [
|
||||
{
|
||||
label: "CPU",
|
||||
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
|
||||
borderColor: Utils.CHART_COLORS.blue,
|
||||
cubicInterpolationMode: "monotone",
|
||||
data: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
plugins: {
|
||||
// Change options for ALL axes of THIS CHART
|
||||
streaming: {
|
||||
duration: 20000,
|
||||
},
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
type: "realtime",
|
||||
realtime: {
|
||||
duration: 60000,
|
||||
refresh: 1000,
|
||||
delay: 1000,
|
||||
//onRefresh: onRefresh,
|
||||
},
|
||||
},
|
||||
y: {
|
||||
title: {
|
||||
display: true,
|
||||
//text: "Value",
|
||||
},
|
||||
},
|
||||
},
|
||||
interaction: {
|
||||
intersect: false,
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
$("body").on('click', '#recent_version_btn', function(e){
|
||||
e.preventDefault();
|
||||
@@ -70,7 +151,7 @@ $("body").on('click', '#recent_version_btn', function(e){
|
||||
|
||||
$("body").on('click', '#config_show_btn', function(e){
|
||||
e.preventDefault();
|
||||
globalSendCommand('get_config', null, null, null, 'Config');
|
||||
globalSendCommand('get_config');
|
||||
});
|
||||
|
||||
|
||||
@@ -184,4 +265,4 @@ function make_scheduler_list(data) {
|
||||
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -45,7 +45,6 @@ $("body").on('click', '#login_btn', function(e){
|
||||
$('#username').val(),
|
||||
$('#password').val(),
|
||||
$("#remember").is(":checked"),
|
||||
'',
|
||||
function(data) {
|
||||
if (data == 'redirect') {
|
||||
next = document.getElementById("next").value;
|
||||
@@ -53,7 +52,6 @@ $("body").on('click', '#login_btn', function(e){
|
||||
if (next == '' || next == 'None' || next == '/system/restart' || '/system/shutdown') {
|
||||
next = '/'
|
||||
}
|
||||
//console.log(next)
|
||||
window.location.href = next;
|
||||
} else if (data == 'no_id') {
|
||||
$.notify('<strong>ID가 없습니다.</strong>', {
|
||||
|
||||
153
lib/system/templates/system_plugin_all.html
Normal file
153
lib/system/templates/system_plugin_all.html
Normal file
@@ -0,0 +1,153 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div>
|
||||
<div id="plugin_list_div"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
$(document).ready(function(){
|
||||
globalSendCommand('get_plugin_list_all', null, null, null, function(data){
|
||||
make_plugin_list(data.data);
|
||||
});
|
||||
});
|
||||
|
||||
$("body").on('click', '#plugin_install_btn', function(e){
|
||||
e.preventDefault();
|
||||
globalSendCommand('plugin_install', $('#_plugin_git').val());
|
||||
});
|
||||
|
||||
function make_plugin_list(data) {
|
||||
current_data = data;
|
||||
str = ''
|
||||
count = 0;
|
||||
for (i in data) {
|
||||
console.log(data[i])
|
||||
str += j_row_start();
|
||||
str += j_col(12, '<b><span style="font-size:150%; font-style:italic; margin=0px;">' + data[i].name + '</span></b>', 'left');
|
||||
//str += '<hr style="width: 100%; margin:0px; margin-bottom:10px; margin-top:2px; margin-left:15px; margin-right:15px; background-color:black; height:2px" />'
|
||||
//str += '<div class="d-inline-block"></div><hr style="width: 100%; margin:0px; margin-left:15px; margin-right:15px;background-color:#808080;">';
|
||||
|
||||
str += j_row_end();
|
||||
//str += j_hr_black(0);
|
||||
|
||||
str += head();
|
||||
for (j in data[i].list) {
|
||||
console.log(data[i].list[j]);
|
||||
str += j_row_start();
|
||||
count += 1
|
||||
str += j_col_wide(1, (parseInt(count)), 'center')
|
||||
tmp = text_color_bootstrap(data[i].list[j].title, 'text-info');
|
||||
str += j_col_wide(2, tmp);
|
||||
tmp = data[i].list[j].package_name;
|
||||
str += j_col_wide(2, tmp);
|
||||
str += j_col_wide(1, data[i].list[j].developer);
|
||||
if (data[i].list[j].version == null) {
|
||||
str += j_col_wide(1, "미설치");
|
||||
} else {
|
||||
str += j_col_wide(1, text_color_bootstrap(data[i].list[j].version, 'text-danger'));
|
||||
}
|
||||
if (data[i].list[j].loading == false) {
|
||||
tmp = data[i].list[j].description + '<br>' + text_color('[로딩 실패] ') + data[i].list[j].status;
|
||||
str += j_col_wide(3, tmp);
|
||||
|
||||
} else {
|
||||
str += j_col_wide(3, data[i].list[j].description);
|
||||
}
|
||||
tmp = ''
|
||||
tmp += j_button_small('globalOpenBtn', '홈페이지', {'url':data[i].list[j].home}, 'primary', false, true);
|
||||
if (data[i].list[j].version == null) {
|
||||
tmp += j_button_small('install_btn', '설치', {'package_name':data[i].list[j].package_name, 'title':data[i].list[j].title, 'home':data[i].list[j].home}, 'info', false, true);
|
||||
} else {
|
||||
tmp += j_button_small('uninstall_btn', '삭제', {'package_name':data[i].list[j].package_name, 'title':data[i].list[j].title}, 'danger', false, true);
|
||||
}
|
||||
tmp = j_button_group(tmp)
|
||||
str += j_col_wide(2, tmp, 'right')
|
||||
str += j_row_end();
|
||||
if (i != current_data.length -1) str += j_hr(0);
|
||||
}
|
||||
str += j_row_start();
|
||||
str += j_row_end();
|
||||
}
|
||||
$("#plugin_list_div").html(str);
|
||||
}
|
||||
|
||||
$("body").on('click', '#json_btn', function(e){
|
||||
e.preventDefault();
|
||||
item_id = $(this).data('idx');
|
||||
showModal(current_data[item_id]);
|
||||
});
|
||||
|
||||
$("body").on('click', '#install_btn', function(e){
|
||||
e.preventDefault();
|
||||
$("#confirm_title").html("설치 확인");
|
||||
$("#confirm_body").html($(this).data('title') + " 플러그인을 설치 하시겠습니까?");
|
||||
home = $(this).data('home');
|
||||
$('#confirm_button').attr('onclick', "javascript:install(home);");
|
||||
$("#confirm_modal").modal();
|
||||
});
|
||||
|
||||
function install(git) {
|
||||
globalSendCommand('plugin_install', git);
|
||||
}
|
||||
|
||||
|
||||
|
||||
$("body").on('click', '#uninstall_btn', function(e){
|
||||
e.preventDefault();
|
||||
$("#confirm_title").html("삭제 확인");
|
||||
$("#confirm_body").html($(this).data('title') + " 플러그인을 삭제 하시겠습니까?");
|
||||
package_name = $(this).data('package_name');
|
||||
$('#confirm_button').attr('onclick', "javascript:uninstall(package_name);");
|
||||
$("#confirm_modal").modal();
|
||||
});
|
||||
|
||||
|
||||
function uninstall(package_name) {
|
||||
globalSendCommand('uninstall', package_name, null, null, function(ret) {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$("body").on('click', '#plugin_uninstall_btn', function(e){
|
||||
e.preventDefault();
|
||||
plugin_name = $(this).data('plugin_name')
|
||||
$.ajax({
|
||||
url: '/' + package_name + '/ajax/plugin_uninstall',
|
||||
type: "POST",
|
||||
cache: false,
|
||||
data:{plugin_name:plugin_name},
|
||||
success: function (data) {
|
||||
if (data == 'success') {
|
||||
$.notify('<strong>재시작시 적용됩니다.</strong>', {
|
||||
type: 'success'
|
||||
});
|
||||
} else {
|
||||
$.notify('<strong>실패하였습니다.</strong>', {
|
||||
type: 'warning'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function head(str) {
|
||||
|
||||
tmp = '<hr style="width: 100%; margin:0px; background-color:#808080;"> \
|
||||
<div class="row chover" style="padding:0px; align-items:center;"> \
|
||||
<div class="col-sm-1" style="padding:0px; margin:0px; text-align:center; word-break:break-all;"><strong>Idx</strong></div> \
|
||||
<div class="col-sm-2" style="padding:0px; margin:0px; text-align:left; word-break:break-all;"><strong>Title</strong></div> \
|
||||
<div class="col-sm-2" style="padding:0px; margin:0px; text-align:left; word-break:break-all;"><strong>Package Name</strong></div> \
|
||||
<div class="col-sm-1" style="padding:0px; margin:0px; text-align:left; word-break:break-all;"><strong>Dev.</strong></div> \
|
||||
<div class="col-sm-1" style="padding:0px; margin:0px; text-align:left; word-break:break-all;"><strong>Version</strong></div> \
|
||||
<div class="col-sm-5" style="padding:0px; margin:0px; text-align:left; word-break:break-all;"><strong>Description</strong></div> \
|
||||
</div> \
|
||||
<hr style="width: 100%; margin:0px; margin-bottom:10px; margin-top:2px; background-color:#808080; height:2px" />';
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -19,7 +19,7 @@
|
||||
<script type="text/javascript">
|
||||
|
||||
$(document).ready(function(){
|
||||
globalSendCommand('get_plugin_list', null, null, null, null, function(data){
|
||||
globalSendCommand('get_plugin_list', null, null, null, function(data){
|
||||
make_plugin_list(data.data);
|
||||
});
|
||||
});
|
||||
@@ -31,7 +31,6 @@ $("body").on('click', '#plugin_install_btn', function(e){
|
||||
|
||||
function make_plugin_list(data) {
|
||||
current_data = data;
|
||||
console.log(data);
|
||||
str = ''
|
||||
console.log(data)
|
||||
for (i in data) {
|
||||
@@ -41,7 +40,7 @@ function make_plugin_list(data) {
|
||||
if (data[i].title == null) {
|
||||
str += j_col_wide(2, '');
|
||||
str += j_col_wide(2, data[i].package_name);
|
||||
str += j_col_wide(5, '');
|
||||
str += j_col_wide(5, data[i].status, 'center');
|
||||
tmp = j_button('uninstall_btn', '삭제', {'package_name':data[i].package_name}, 'danger', false, true);
|
||||
} else {
|
||||
str += j_col_wide(2, data[i].title);
|
||||
@@ -74,7 +73,7 @@ function make_plugin_list(data) {
|
||||
$("body").on('click', '#json_btn', function(e){
|
||||
e.preventDefault();
|
||||
item_id = $(this).data('idx');
|
||||
m_modal(current_data[item_id]);
|
||||
showModal(current_data[item_id]);
|
||||
});
|
||||
|
||||
|
||||
@@ -89,7 +88,7 @@ $("body").on('click', '#uninstall_btn', function(e){
|
||||
|
||||
|
||||
function uninstall(package_name) {
|
||||
globalSendCommand('uninstall', package_name, null, null, null, function(ret) {
|
||||
globalSendCommand('uninstall', package_name, null, null, function(ret) {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ $(document).ready(function() {
|
||||
var restartSocket = io.connect(window.location.href);
|
||||
|
||||
restartSocket.on('connect', function(data){
|
||||
console.log('접속 받음')
|
||||
window.location.href = referer;
|
||||
});
|
||||
}, 3000);
|
||||
|
||||
@@ -33,7 +33,7 @@ $('#use_login').change(function() {
|
||||
|
||||
$("body").on('click', '#apikey_generate_btn', function(e) {
|
||||
e.preventDefault();
|
||||
globalSendCommand('apikey_generate', null, null, null, null, function(ret){
|
||||
globalSendCommand('apikey_generate', null, null, null, function(ret){
|
||||
$("#apikey").val(ret);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,22 +1,20 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
|
||||
<div>
|
||||
{{ macros.m_button_group([['globalSettingSaveBtn', '설정 저장']])}}
|
||||
{{ macros.m_row_start('5') }}
|
||||
{{ macros.m_row_end() }}
|
||||
{{ macros.m_hr() }}
|
||||
{{ macros.m_button_group([['globalSettingSaveBtn', '설정 저장']])}}
|
||||
{{ macros.m_row_start('5') }}
|
||||
{{ macros.m_row_end() }}
|
||||
{{ macros.m_hr() }}
|
||||
|
||||
<form id='setting' name='setting'>
|
||||
{{ macros.setting_input_int('port', 'Port', value=arg['port'], min='1', placeholder='Port', desc=['포트 번호입니다.', '네이티브 설치 혹은 도커 네트워크 타입이 호스트일 경우 반영됩니다.', '도커 브릿지 모드인 경우는 docker run -p 옵션에서 변경하시기 바랍니다.', '경고 : -p 브릿지 모드로 사용중 일 경우 9999번을 변경하지 마세요.']) }}
|
||||
{{ macros.setting_input_text_and_buttons('ddns', 'DDNS', [['ddns_test_btn', '테스트']], value=arg['ddns'], desc=['외부에서 접근시 사용할 DDNS. http:// 나 https:// 로 시작해야합니다.', 'URL생성시 사용합니다.', '테스트 버튼 클릭 후 버전을 확인 할 수 있어야 합니다.']) }}
|
||||
{{ macros.setting_input_text('restart_interval', '자동 재시작 시간', value=arg['restart_interval'], col='3', desc=['자동 재시작 간격(시간단위)이나 Cron 설정을 입력합니다.', '0이면 재시작 안함.']) }}
|
||||
{{ macros.setting_checkbox('restart_notify', '시작시 알림', value=arg['restart_notify'], desc=['메시지 ID: system_start']) }}
|
||||
{{ macros.setting_select('log_level', '로그 레벨', [['10', 'DEBUG'],['20', 'INFO'],['30', 'WARNING'],['40', 'ERROR'], ['50', 'CRITICAL'] ], value=arg['log_level'], col='3') }}
|
||||
{{ macros.m_hr() }}
|
||||
{{ macros.setting_input_text_and_buttons('command_text', 'Command', [['command_run_btn', 'Run']], value='', desc='') }}
|
||||
</form>
|
||||
</div><!--전체-->
|
||||
<form id='setting' name='setting'>
|
||||
{{ macros.setting_input_int('port', 'Port', value=arg['port'], min='1', placeholder='Port', desc=['포트 번호입니다.', '네이티브 설치 혹은 도커 네트워크 타입이 호스트일 경우 반영됩니다.', '도커 브릿지 모드인 경우는 docker run -p 옵션에서 변경하시기 바랍니다.', '경고 : -p 브릿지 모드로 사용중 일 경우 9999번을 변경하지 마세요.']) }}
|
||||
{{ macros.setting_input_text_and_buttons('ddns', 'DDNS', [['ddns_test_btn', '테스트']], value=arg['ddns'], desc=['외부에서 접근시 사용할 DDNS. http:// 나 https:// 로 시작해야합니다.', 'URL생성시 사용합니다.', '테스트 버튼 클릭 후 버전을 확인 할 수 있어야 합니다.']) }}
|
||||
{{ macros.setting_input_text('restart_interval', '자동 재시작 시간', value=arg['restart_interval'], col='3', desc=['자동 재시작 간격(시간단위)이나 Cron 설정을 입력합니다.', '0이면 재시작 안함.']) }}
|
||||
{{ macros.setting_checkbox('restart_notify', '시작시 알림', value=arg['restart_notify'], desc=['메시지 ID: system_start']) }}
|
||||
{{ macros.setting_select('log_level', '로그 레벨', [['10', 'DEBUG'],['20', 'INFO'],['30', 'WARNING'],['40', 'ERROR'], ['50', 'CRITICAL'] ], value=arg['log_level'], col='3') }}
|
||||
{{ macros.m_hr() }}
|
||||
{{ macros.setting_input_text_and_buttons('command_text', 'Command', [['command_run_btn', 'Run']], value=arg['command_text'], desc='') }}
|
||||
</form>
|
||||
|
||||
<script type="text/javascript">
|
||||
$("body").on('click', '#ddns_test_btn', function(e){
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<div class="tab-content" id="nav-tabContent">
|
||||
{{ macros.info_text('use_celery', 'use_celery 값', arg['use_celery']) }}
|
||||
{{ macros.info_text('running_type', 'running_type 값', arg['running_type']) }}
|
||||
{{ macros.info_text('_tmp', '설명', "Docker는 celery가 서비스로 동작하기 때문에 설정이 불필요하며 '테스트' 버튼으로 작동 여부 확인만 가능합니다.", desc=['','native로 동작하는 경우 celery 실행을 따로 하지 않고 한번에 실행하기 위한 설정', 'Redis는 설정된 Port로 동작중인 상태여야 함.']) }}
|
||||
{{ macros.info_text('_tmp', '설명', "보통 시작시 celery 실행 On 상태로 동작하며 개발시에만 Off로 설정.", desc=None) }}
|
||||
{{ macros.m_hr() }}
|
||||
<form id='setting' name='setting'>
|
||||
{{ macros.setting_checkbox('celery_start_by_web', '시작시 celery 실행', value=arg['celery_start_by_web']) }}
|
||||
|
||||
@@ -29,6 +29,14 @@
|
||||
{{ macros.setting_input_text('notify_discord_webhook', '웹훅', value=arg['notify_discord_webhook']) }}
|
||||
{{ macros.setting_input_text_and_buttons('tmp_text_discord', 'Test', [['tmp_discord_test_btn', '전송']], value='테스트 메시지입니다.', col='9') }}
|
||||
</div>
|
||||
|
||||
{{ macros.m_hr() }}
|
||||
|
||||
{{ macros.setting_checkbox('notify_slack_use', '슬랙 사용', value=arg['notify_slack_use']) }}
|
||||
<div id="notify_slack_use_div" class="collapse">
|
||||
{{ macros.setting_input_text('notify_slack_webhook', '웹훅', value=arg['notify_slack_webhook']) }}
|
||||
{{ macros.setting_input_text_and_buttons('tmp_text_slack', 'Test', [['tmp_slack_test_btn', '전송']], value='테스트 메시지입니다.', col='9') }}
|
||||
</div>
|
||||
{{ macros.m_tab_content_end() }}
|
||||
|
||||
{{ macros.m_tab_content_start('advanced', false) }}
|
||||
@@ -53,6 +61,7 @@
|
||||
$(document).ready(function(){
|
||||
use_collapse("notify_telegram_use");
|
||||
use_collapse("notify_discord_use");
|
||||
use_collapse("notify_slack_use");
|
||||
use_collapse("notify_advaned_use");
|
||||
});
|
||||
|
||||
@@ -64,6 +73,10 @@ $('#notify_discord_use').change(function() {
|
||||
use_collapse('notify_discord_use');
|
||||
});
|
||||
|
||||
$('#notify_slack_use').change(function() {
|
||||
use_collapse('notify_slack_use');
|
||||
});
|
||||
|
||||
$('#notify_advaned_use').change(function() {
|
||||
use_collapse('notify_advaned_use');
|
||||
});
|
||||
@@ -80,6 +93,11 @@ $("body").on('click', '#tmp_discord_test_btn', function(e){
|
||||
globalSendCommand('notify_test', 'discord', $('#notify_discord_webhook').val(), $('#tmp_text_discord').val());
|
||||
});
|
||||
|
||||
$("body").on('click', '#tmp_slack_test_btn', function(e){
|
||||
e.preventDefault();
|
||||
globalSendCommand('notify_test', 'slack', $('#notify_slack_webhook').val(), $('#tmp_text_slack').val());
|
||||
});
|
||||
|
||||
$("body").on('click', '#tmp_advanced_test_btn', function(e){
|
||||
e.preventDefault();
|
||||
globalSendCommand('notify_test', 'advanced', $('#tmp_message_id').val(), $('#tmp_text_advanced').val());
|
||||
|
||||
@@ -63,7 +63,7 @@ $("body").on('click', '#foreground_command_btn', function(e){
|
||||
|
||||
$("body").on('click', '#job_new_btn', function(e){
|
||||
e.preventDefault();
|
||||
globalSendCommandPage('job_new', $('#command').val(), null, null, null, function(ret){
|
||||
globalSendCommandPage('job_new', $('#command').val(), null, null, function(ret){
|
||||
request_list();
|
||||
});
|
||||
});
|
||||
@@ -79,7 +79,7 @@ $("body").on('click', '#select_file_btn', function(e){
|
||||
|
||||
|
||||
function request_list() {
|
||||
globalSendCommandPage('job_list', null, null, null, null, function(ret){
|
||||
globalSendCommandPage('job_list', null, null, null, function(ret){
|
||||
make_list(ret.data);
|
||||
});
|
||||
}
|
||||
@@ -92,18 +92,16 @@ function make_list(data) {
|
||||
<th style="width:60%; text-align:center;">Command & arg & Desc</th> \
|
||||
<th style="width:5%; text-align:center;">자동</th> \
|
||||
<th colspan="2" style="width:20%; text-align:center;">스케쥴 상태</th> \
|
||||
<th style="width:10%; text-align:center;">스케쥴</th> \
|
||||
<th style="width:10%; text-align:center;">스케쥴주기</th> \
|
||||
</tr></thead><tbody id="list">';
|
||||
|
||||
if (data.length == 0) str += '<tr><td colspan="6"><h4>작업이 없습니다.</h4></td></tr>';
|
||||
|
||||
for(i in data) {
|
||||
console.log(data[i]);
|
||||
//console.log(data[i]);
|
||||
str += '<tr class="chover" style="cursor: pointer;" data-toggle="collapse" data-target="#collapse_' + i + '" aria-expanded="true" >';
|
||||
|
||||
str += '<td rowspan="2" scope="col" style="width:5%; text-align:center;">'+ (data[i].id) + '</td>';
|
||||
|
||||
|
||||
// command
|
||||
tmp = '';
|
||||
tmp += text_color(data[i].command, 'blue') + '<br>';
|
||||
@@ -123,7 +121,7 @@ function make_list(data) {
|
||||
tmp1 = "시작시 한번 실행";
|
||||
} else if (data[i].schedule_mode == 'scheduler') {
|
||||
tmp1 = "스케쥴링";
|
||||
tmp2 = '<input id="use_checkbox|'+data[i].id+'" type="checkbox" data-id='+data[i].id+' data-toggle="toggle" data-on="On" data-off="Off" data-onstyle="info" data-offstyle="danger" data-size="small" ' + ((data[i].scheduler_is_include) ? 'checked' : '') + '>';
|
||||
tmp2 = '<input id="use_checkbox|'+data[i].id+'" type="checkbox" data-id='+data[i].id+' data-toggle="toggle" data-on="On" data-off="Off" data-onstyle="danger" data-offstyle="info" data-size="small" ' + ((data[i].scheduler_is_include) ? 'checked' : '') + '>';
|
||||
if (data[i].scheduler_is_include) {
|
||||
tmp2 += (data[i].scheduler_is_running) ? "<br>실행중" : "<br>대기중";
|
||||
}
|
||||
@@ -197,7 +195,7 @@ $("body").on('click', '#job_save_btn', function(e){
|
||||
}
|
||||
|
||||
var formData = getFormdata('#item_setting');
|
||||
globalSendCommandPage('job_save', formData, null, null, null, function(ret){
|
||||
globalSendCommandPage('job_save', formData, null, null, function(ret){
|
||||
if (ret.ret == 'success') {
|
||||
$('#job_modal').modal('hide');
|
||||
request_list();
|
||||
@@ -216,7 +214,7 @@ $("body").on('click', '#job_remove_btn', function(e){
|
||||
});
|
||||
|
||||
function remove_job(job_id) {
|
||||
globalSendCommandPage('job_remove', job_id, null, null, null, function(ret){
|
||||
globalSendCommandPage('job_remove', job_id, null, null, function(ret){
|
||||
if (ret.ret == 'success') {
|
||||
$('#job_modal').modal('hide');
|
||||
request_list();
|
||||
@@ -267,14 +265,14 @@ $("body").on('click', '#job_fore_execute_btn', function(e){
|
||||
|
||||
$("body").on('click', '#job_back_execute_btn', function(e){
|
||||
e.preventDefault();
|
||||
globalSendCommandPage('job_back_execute', $(this).data('id'), null, null, null, function(e) {
|
||||
globalSendCommandPage('job_back_execute', $(this).data('id'), null, null, function(e) {
|
||||
request_list();
|
||||
});
|
||||
});
|
||||
|
||||
$("body").on('click', '#job_log_btn', function(e){
|
||||
e.preventDefault();
|
||||
globalSendCommandPage('job_log', $(this).data('id'), null, null, null, function(data){
|
||||
globalSendCommandPage('job_log', $(this).data('id'), null, null, function(data){
|
||||
if (data.ret == 'success') {
|
||||
redirect = '/system/all_log/list';
|
||||
$.redirectPost(redirect, {filename: data.filename});
|
||||
@@ -293,14 +291,14 @@ $("body").on('click', '#job_cmd_input_btn', function(e){
|
||||
|
||||
$("body").on('change', 'input[id^="use_checkbox|"]', function(e){
|
||||
e.preventDefault();
|
||||
globalSendCommandPage('task_sched', $(this).data('id'), $(this).prop('checked'), null, null, function(e) {
|
||||
globalSendCommandPage('task_sched', $(this).data('id'), $(this).prop('checked'), null, function(e) {
|
||||
request_list();
|
||||
});
|
||||
});
|
||||
|
||||
$("body").on('click', '#job_process_stop_btn', function(e){
|
||||
e.preventDefault();
|
||||
globalSendCommandPage('job_process_stop', $(this).data('id'), null, null, null, function(e) {
|
||||
globalSendCommandPage('job_process_stop', $(this).data('id'), null, null, function(e) {
|
||||
request_list();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -16,7 +16,7 @@ $(document).ready(function(){
|
||||
});
|
||||
|
||||
function refresh() {
|
||||
globalSendCommandPage('get_freeze', null, null, null, null, function(ret){
|
||||
globalSendCommandPage('get_freeze', null, null, null, function(ret){
|
||||
make_list(ret.data);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user