update
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -143,6 +143,7 @@ false
|
|||||||
*copy.py
|
*copy.py
|
||||||
*.sh
|
*.sh
|
||||||
data/
|
data/
|
||||||
|
tmp/
|
||||||
lib/support/site/tving.py
|
lib/support/site/tving.py
|
||||||
lib/support/site/wavve.py
|
lib/support/site/wavve.py
|
||||||
|
|
||||||
|
|||||||
@@ -104,8 +104,8 @@ class Framework:
|
|||||||
# https://flask-sqlalchemy.palletsprojects.com/en/3.0.x/config/#flask_sqlalchemy.config.SQLALCHEMY_BINDS
|
# https://flask-sqlalchemy.palletsprojects.com/en/3.0.x/config/#flask_sqlalchemy.config.SQLALCHEMY_BINDS
|
||||||
# 어떤 편법도 불가. db를 사용하지 않아도 파일이 생김.
|
# 어떤 편법도 불가. db를 사용하지 않아도 파일이 생김.
|
||||||
db_path = os.path.join(self.config['path_data'], 'db', 'system.db')
|
db_path = os.path.join(self.config['path_data'], 'db', 'system.db')
|
||||||
self.app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{db_path}' # 3.0에서 필수
|
self.app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{db_path}?check_same_thread=False' # 3.0에서 필수
|
||||||
self.app.config['SQLALCHEMY_BINDS'] = {'system':f'sqlite:///{db_path}'}
|
self.app.config['SQLALCHEMY_BINDS'] = {'system':f'sqlite:///{db_path}?check_same_thread=False'}
|
||||||
self.app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
self.app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
||||||
|
|
||||||
_ = os.path.join(self.config['path_data'], 'plugins')
|
_ = os.path.join(self.config['path_data'], 'plugins')
|
||||||
@@ -124,7 +124,7 @@ class Framework:
|
|||||||
|
|
||||||
for package_name in plugins:
|
for package_name in plugins:
|
||||||
db_path = os.path.join(self.config['path_data'], 'db', f'{package_name}.db')
|
db_path = os.path.join(self.config['path_data'], 'db', f'{package_name}.db')
|
||||||
self.app.config['SQLALCHEMY_BINDS'][package_name] = f'sqlite:///{db_path}'
|
self.app.config['SQLALCHEMY_BINDS'][package_name] = f'sqlite:///{db_path}?check_same_thread=False'
|
||||||
self.db = SQLAlchemy(self.app, session_options={"autoflush": False, "expire_on_commit": False})
|
self.db = SQLAlchemy(self.app, session_options={"autoflush": False, "expire_on_commit": False})
|
||||||
#with self.app.app_context():
|
#with self.app.app_context():
|
||||||
# self.db.session.expunge_all()
|
# self.db.session.expunge_all()
|
||||||
|
|||||||
@@ -130,6 +130,175 @@ $("body").on('click', '#globalCliboardBtn', function(e) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// 사용 on / off
|
||||||
|
$("body").on('change', '#globalSchedulerSwitchBtn', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var ret = $(this).prop('checked');
|
||||||
|
$.ajax({
|
||||||
|
url: '/'+PACKAGE_NAME+'/ajax/' + MODULE_NAME + '/scheduler',
|
||||||
|
type: "POST",
|
||||||
|
cache: false,
|
||||||
|
data: {scheduler : ret},
|
||||||
|
dataType: "json",
|
||||||
|
success: function () {}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("body").on('change', '#globalSchedulerSwitchPageBtn', function(e) {
|
||||||
|
var ret = $(this).prop('checked');
|
||||||
|
$.ajax({
|
||||||
|
url: '/'+PACKAGE_NAME+'/ajax/' + MODULE_NAME + '/' + PAGE_NAME + '/scheduler',
|
||||||
|
type: "POST",
|
||||||
|
cache: false,
|
||||||
|
data: {scheduler : ret},
|
||||||
|
dataType: "json",
|
||||||
|
success: function () {}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("body").on('click', '#globalOneExecuteBtn', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
$.ajax({
|
||||||
|
url: '/'+PACKAGE_NAME+'/ajax/' + MODULE_NAME + '/one_execute',
|
||||||
|
type: "POST",
|
||||||
|
cache: false,
|
||||||
|
data: {},
|
||||||
|
dataType: "json",
|
||||||
|
success: function (ret) {
|
||||||
|
if (ret=='scheduler' || ret=='thread') {
|
||||||
|
$.notify('<strong>작업을 시작하였습니다. ('+ret+')</strong>', {
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
} else if (ret == 'is_running') {
|
||||||
|
$.notify('<strong>작업중입니다.</strong>', {
|
||||||
|
type: 'warning'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$.notify('<strong>작업 시작에 실패하였습니다.</strong>', {
|
||||||
|
type: 'warning'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("body").on('click', '#globalOneExecutePageBtn', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
$.ajax({
|
||||||
|
url: '/'+PACKAGE_NAME+'/ajax/' + MODULE_NAME + '/' + PAGE_NAME + '/one_execute',
|
||||||
|
type: "POST",
|
||||||
|
cache: false,
|
||||||
|
data: {sub:sub},
|
||||||
|
dataType: "json",
|
||||||
|
success: function (ret) {
|
||||||
|
if (ret=='scheduler' || ret=='thread') {
|
||||||
|
$.notify('<strong>작업을 시작하였습니다. ('+ret+')</strong>', {
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
} else if (ret == 'is_running') {
|
||||||
|
$.notify('<strong>작업중입니다.</strong>', {
|
||||||
|
type: 'warning'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$.notify('<strong>작업 시작에 실패하였습니다.</strong>', {
|
||||||
|
type: 'warning'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("body").on('click', '#globalImmediatelyExecuteBtn', function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
$.ajax({
|
||||||
|
url: '/'+PACKAGE_NAME+'/ajax/' + MODULE_NAME + '/immediately_execute',
|
||||||
|
type: "POST",
|
||||||
|
cache: false,
|
||||||
|
data: {},
|
||||||
|
dataType: "json",
|
||||||
|
success: function (ret) {
|
||||||
|
if (ret.msg != null) notify(ret.msg, ret.ret);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("body").on('click', '#globalImmediatelyExecutePageBtn', function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
$.ajax({
|
||||||
|
url: '/'+PACKAGE_NAME+'/ajax/' + MODULE_NAME + '/' + PAGE_NAME + '/immediately_execute',
|
||||||
|
type: "POST",
|
||||||
|
cache: false,
|
||||||
|
data: {},
|
||||||
|
dataType: "json",
|
||||||
|
success: function (ret) {
|
||||||
|
if (ret.msg != null) notify(ret.msg, ret.ret);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$("body").on('click', '#globalDbDeleteBtn', function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
document.getElementById("confirm_title").innerHTML = "DB 삭제";
|
||||||
|
document.getElementById("confirm_body").innerHTML = "전체 목록을 삭제 하시겠습니까?";
|
||||||
|
$('#confirm_button').attr('onclick', "globalDbDelete();");
|
||||||
|
$("#confirm_modal").modal();
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
|
||||||
|
function globalDbDelete() {
|
||||||
|
$.ajax({
|
||||||
|
url: '/'+PACKAGE_NAME+'/ajax/' + MODULE_NAME + '/reset_db',
|
||||||
|
type: "POST",
|
||||||
|
cache: false,
|
||||||
|
data: {},
|
||||||
|
dataType: "json",
|
||||||
|
success: function (data) {
|
||||||
|
if (data) {
|
||||||
|
$.notify('<strong>삭제하였습니다.</strong>', {
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$.notify('<strong>삭제에 실패하였습니다.</strong>',{
|
||||||
|
type: 'warning'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$("body").on('click', '#globalDbDeletePageBtn', function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
document.getElementById("confirm_title").innerHTML = "DB 삭제";
|
||||||
|
document.getElementById("confirm_body").innerHTML = "전체 목록을 삭제 하시겠습니까?";
|
||||||
|
$('#confirm_button').attr('onclick', "globalDbDeletePage();");
|
||||||
|
$("#confirm_modal").modal();
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
|
||||||
|
function globalDbDeletePage() {
|
||||||
|
$.ajax({
|
||||||
|
url: '/'+PACKAGE_NAME+'/ajax/' + MODULE_NAME + '/' + PAGE_NAME + '/reset_db',
|
||||||
|
type: "POST",
|
||||||
|
cache: false,
|
||||||
|
data: {sub:sub},
|
||||||
|
dataType: "json",
|
||||||
|
success: function (data) {
|
||||||
|
if (data) {
|
||||||
|
$.notify('<strong>삭제하였습니다.</strong>', {
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$.notify('<strong>삭제에 실패하였습니다.</strong>',{
|
||||||
|
type: 'warning'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// Global - 함수
|
// Global - 함수
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
@@ -180,6 +349,88 @@ function shutdown_confirm() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
// 리스트 화면 기본
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
function globalRequestSearch(page, move_top=true) {
|
||||||
|
var formData = getFormdata('#form_search')
|
||||||
|
formData += '&page=' + page;
|
||||||
|
$.ajax({
|
||||||
|
url: '/' + PACKAGE_NAME + '/ajax/' + MODULE_NAME + '/web_list',
|
||||||
|
type: "POST",
|
||||||
|
cache: false,
|
||||||
|
data: formData,
|
||||||
|
dataType: "json",
|
||||||
|
success: function (data) {
|
||||||
|
current_data = data;
|
||||||
|
if (move_top)
|
||||||
|
window.scrollTo(0,0);
|
||||||
|
make_list(data.list)
|
||||||
|
make_page_html(data.paging)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function make_page_html(data) {
|
||||||
|
str = ' \
|
||||||
|
<div class="d-inline-block"></div> \
|
||||||
|
<div class="row mb-3"> \
|
||||||
|
<div class="col-sm-12"> \
|
||||||
|
<div class="btn-toolbar" style="justify-content: center;" role="toolbar" aria-label="Toolbar with button groups" > \
|
||||||
|
<div class="btn-group btn-group-sm mr-2" role="group" aria-label="First group">'
|
||||||
|
if (data.prev_page) {
|
||||||
|
str += '<button id="gloablSearchPageBtn" data-page="' + (data.start_page-1) + '" type="button" class="btn btn-secondary">«</button>'
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = data.start_page ; i <= data.last_page ; i++) {
|
||||||
|
str += '<button id="gloablSearchPageBtn" data-page="' + i +'" type="button" class="btn btn-secondary" ';
|
||||||
|
if (i == data.current_page) {
|
||||||
|
str += 'disabled';
|
||||||
|
}
|
||||||
|
str += '>'+i+'</button>';
|
||||||
|
}
|
||||||
|
if (data.next_page) {
|
||||||
|
str += '<button id="gloablSearchPageBtn" data-page="' + (data.last_page+1) + '" type="button" class="btn btn-secondary">»</button>'
|
||||||
|
}
|
||||||
|
|
||||||
|
str += '</div> \
|
||||||
|
</div> \
|
||||||
|
</div> \
|
||||||
|
</div> \
|
||||||
|
'
|
||||||
|
document.getElementById("page1").innerHTML = str;
|
||||||
|
document.getElementById("page2").innerHTML = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$("body").on('click', '#gloablSearchPageBtn', function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
globalRequestSearch($(this).data('page'), false);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("body").on('click', '#globalSearchSearchBtn', function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
globalRequestSearch(1, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("body").on('click', '#globalSearchResetBtn', function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
$("#order").val('desc');
|
||||||
|
$("#option1").val('all');
|
||||||
|
$("#option2").val('all');
|
||||||
|
$("#keyword").val('');
|
||||||
|
globalRequestSearch(1, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// 파일 선택 모달
|
// 파일 선택 모달
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
|||||||
@@ -84,6 +84,14 @@ function j_row_info(left, right, l=2, r=8) {
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function j_progress(id, width, label) {
|
||||||
|
var str = '';
|
||||||
|
str += '<div class="progress" style="height: 25px;">'
|
||||||
|
str += '<div id="'+id+'" class="progress-bar" style="background-color:yellow;width:'+width+'%"></div>';
|
||||||
|
str += '<div id="'+id+'_label" class="justify-content-center d-flex w-100 position-absolute" style="margin-top:2px">'+label+'</div>';
|
||||||
|
str += '</div>'
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -110,6 +118,19 @@ function j_row_info(left, right, l=2, r=8) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function make_log(key, value, left=2, right=10) {
|
||||||
|
row = m_col(left, key, aligh='right');
|
||||||
|
row += m_col(right, value, aligh='left');
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -118,17 +139,107 @@ function text_color(text, color='red') {
|
|||||||
return '<span style="color:'+color+'; font-weight:bold">' + text + '</span>';
|
return '<span style="color:'+color+'; font-weight:bold">' + text + '</span>';
|
||||||
}
|
}
|
||||||
|
|
||||||
function m_table(id, heads) {
|
|
||||||
str += '<table id="result_table" class="table table-sm tableRowHover " ><thead class="thead-dark"><tr> \
|
|
||||||
<th style="width:10%;text-align:center;">NO</th> \
|
|
||||||
<th style="width:15%;text-align:center;">물어본 숫자</th> \
|
///////////////////////////////////////
|
||||||
<th style="width:10%;text-align:center;">스트라이크</th> \
|
// UI - 확장설정 - dropdown
|
||||||
<th style="width:10%;text-align:center;">볼</th> \
|
///////////////////////////////////////
|
||||||
<th style="width:15%;text-align:center;">가능한 숫자 수</th> \
|
|
||||||
<th style="width:40%;text-align:center;">Action</th> \
|
document.addEventListener("DOMContentLoaded", function(){
|
||||||
</tr></thead><tbody id="list">';
|
/////// Prevent closing from click inside dropdown
|
||||||
|
document.querySelectorAll('.dropdown-menu').forEach(function(element){
|
||||||
|
element.addEventListener('click', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
// make it as accordion for smaller screens
|
||||||
|
if (window.innerWidth < 992) {
|
||||||
|
// close all inner dropdowns when parent is closed
|
||||||
|
document.querySelectorAll('.navbar .dropdown').forEach(function(everydropdown){
|
||||||
|
everydropdown.addEventListener('hidden.bs.dropdown', function () {
|
||||||
|
// after dropdown is hidden, then find all submenus
|
||||||
|
this.querySelectorAll('.submenu').forEach(function(everysubmenu){
|
||||||
|
// hide every submenu as well
|
||||||
|
everysubmenu.style.display = 'none';
|
||||||
|
});
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
document.querySelectorAll('.dropdown-menu a').forEach(function(element){
|
||||||
|
element.addEventListener('click', function (e) {
|
||||||
|
|
||||||
|
let nextEl = this.nextElementSibling;
|
||||||
|
if(nextEl && nextEl.classList.contains('submenu')) {
|
||||||
|
// prevent opening link if link needs to open dropdown
|
||||||
|
e.preventDefault();
|
||||||
|
console.log(nextEl);
|
||||||
|
if(nextEl.style.display == 'block'){
|
||||||
|
nextEl.style.display = 'none';
|
||||||
|
} else {
|
||||||
|
nextEl.style.display = 'block';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// end if innerWidth
|
||||||
|
});
|
||||||
|
// DOMContentLoaded end
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -218,14 +329,7 @@ function m_tab_content(name, content, active) {
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
function m_progress(id, width, label) {
|
|
||||||
var str = '';
|
|
||||||
str += '<div class="progress" style="height: 25px;">'
|
|
||||||
str += '<div id="'+id+'" class="progress-bar" style="background-color:yellow;width:'+width+'%"></div>';
|
|
||||||
str += '<div id="'+id+'_label" class="justify-content-center d-flex w-100 position-absolute" style="margin-top:2px">'+label+'</div>';
|
|
||||||
str += '</div>'
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function m_progress2(id, width, label) {
|
function m_progress2(id, width, label) {
|
||||||
@@ -239,94 +343,12 @@ function m_progress2(id, width, label) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
function make_page_html(data) {
|
|
||||||
str = ' \
|
|
||||||
<div class="d-inline-block"></div> \
|
|
||||||
<div class="row mb-3"> \
|
|
||||||
<div class="col-sm-12"> \
|
|
||||||
<div class="btn-toolbar" style="justify-content: center;" role="toolbar" aria-label="Toolbar with button groups" > \
|
|
||||||
<div class="btn-group btn-group-sm mr-2" role="group" aria-label="First group">'
|
|
||||||
if (data.prev_page) {
|
|
||||||
str += '<button id="page" data-page="' + (data.start_page-1) + '" type="button" class="btn btn-secondary">«</button>'
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = data.start_page ; i <= data.last_page ; i++) {
|
|
||||||
str += '<button id="page" data-page="' + i +'" type="button" class="btn btn-secondary" ';
|
|
||||||
if (i == data.current_page) {
|
|
||||||
str += 'disabled';
|
|
||||||
}
|
|
||||||
str += '>'+i+'</button>';
|
|
||||||
}
|
|
||||||
if (data.next_page) {
|
|
||||||
str += '<button id="page" data-page="' + (data.last_page+1) + '" type="button" class="btn btn-secondary">»</button>'
|
|
||||||
}
|
|
||||||
|
|
||||||
str += '</div> \
|
|
||||||
</div> \
|
|
||||||
</div> \
|
|
||||||
</div> \
|
|
||||||
'
|
|
||||||
document.getElementById("page1").innerHTML = str;
|
|
||||||
document.getElementById("page2").innerHTML = str;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function make_log(key, value, left=2, right=10) {
|
|
||||||
row = m_col(left, key, aligh='right');
|
|
||||||
row += m_col(right, value, aligh='left');
|
|
||||||
return row;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
// UI - 확장설정 - dropdown
|
|
||||||
///////////////////////////////////////
|
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", function(){
|
|
||||||
/////// Prevent closing from click inside dropdown
|
|
||||||
document.querySelectorAll('.dropdown-menu').forEach(function(element){
|
|
||||||
element.addEventListener('click', function (e) {
|
|
||||||
e.stopPropagation();
|
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
// make it as accordion for smaller screens
|
|
||||||
if (window.innerWidth < 992) {
|
|
||||||
// close all inner dropdowns when parent is closed
|
|
||||||
document.querySelectorAll('.navbar .dropdown').forEach(function(everydropdown){
|
|
||||||
everydropdown.addEventListener('hidden.bs.dropdown', function () {
|
|
||||||
// after dropdown is hidden, then find all submenus
|
|
||||||
this.querySelectorAll('.submenu').forEach(function(everysubmenu){
|
|
||||||
// hide every submenu as well
|
|
||||||
everysubmenu.style.display = 'none';
|
|
||||||
});
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
document.querySelectorAll('.dropdown-menu a').forEach(function(element){
|
|
||||||
element.addEventListener('click', function (e) {
|
|
||||||
|
|
||||||
let nextEl = this.nextElementSibling;
|
|
||||||
if(nextEl && nextEl.classList.contains('submenu')) {
|
|
||||||
// prevent opening link if link needs to open dropdown
|
|
||||||
e.preventDefault();
|
|
||||||
console.log(nextEl);
|
|
||||||
if(nextEl.style.display == 'block'){
|
|
||||||
nextEl.style.display = 'none';
|
|
||||||
} else {
|
|
||||||
nextEl.style.display = 'block';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// end if innerWidth
|
|
||||||
});
|
|
||||||
// DOMContentLoaded end
|
|
||||||
///////////////////////////////////////
|
|
||||||
@@ -193,202 +193,14 @@ function streaming_kill(command, data={}) {
|
|||||||
// Global.. JS 파일로 뺄것
|
// Global.. JS 파일로 뺄것
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// 사용 on / off
|
|
||||||
$('#global_scheduler').change(function() {
|
|
||||||
var ret = $(this).prop('checked');
|
|
||||||
$.ajax({
|
|
||||||
url: '/'+package_name+'/ajax/scheduler',
|
|
||||||
type: "POST",
|
|
||||||
cache: false,
|
|
||||||
data: {scheduler : ret},
|
|
||||||
dataType: "json",
|
|
||||||
success: function (list) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#global_scheduler_sub').change(function() {
|
|
||||||
var ret = $(this).prop('checked');
|
|
||||||
$.ajax({
|
|
||||||
url: '/'+package_name+'/ajax/scheduler',
|
|
||||||
type: "POST",
|
|
||||||
cache: false,
|
|
||||||
data: {scheduler : ret, sub:sub},
|
|
||||||
dataType: "json",
|
|
||||||
success: function (list) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
function global_setting_save_function() {
|
|
||||||
var formData = getFormdata('#setting');
|
|
||||||
$.ajax({
|
|
||||||
url: '/'+package_name+'/ajax/setting_save',
|
|
||||||
type: "POST",
|
|
||||||
cache: false,
|
|
||||||
data: formData,
|
|
||||||
dataType: "json",
|
|
||||||
success: function (ret) {
|
|
||||||
if (ret) {
|
|
||||||
$.notify('<strong>설정을 저장하였습니다.</strong>', {
|
|
||||||
type: 'success'
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$.notify('<strong>설정 저장에 실패하였습니다.</strong>', {
|
|
||||||
type: 'warning'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#global_one_execute_btn").click(function(e) {
|
|
||||||
//$("body").on('click', '#one_execute_btn', function(e){
|
|
||||||
e.preventDefault();
|
|
||||||
$.ajax({
|
|
||||||
url: '/' + package_name + '/ajax/one_execute',
|
|
||||||
type: "POST",
|
|
||||||
cache: false,
|
|
||||||
data: {},
|
|
||||||
dataType: "json",
|
|
||||||
success: function (ret) {
|
|
||||||
if (ret=='scheduler' || ret=='thread') {
|
|
||||||
$.notify('<strong>작업을 시작하였습니다. ('+ret+')</strong>', {
|
|
||||||
type: 'success'
|
|
||||||
});
|
|
||||||
} else if (ret == 'is_running') {
|
|
||||||
$.notify('<strong>작업중입니다.</strong>', {
|
|
||||||
type: 'warning'
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$.notify('<strong>작업 시작에 실패하였습니다.</strong>', {
|
|
||||||
type: 'warning'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#global_one_execute_sub_btn").click(function(e) {
|
|
||||||
//$("body").on('click', '#one_execute_btn', function(e){
|
|
||||||
e.preventDefault();
|
|
||||||
$.ajax({
|
|
||||||
url: '/' + package_name + '/ajax/one_execute',
|
|
||||||
type: "POST",
|
|
||||||
cache: false,
|
|
||||||
data: {sub:sub},
|
|
||||||
dataType: "json",
|
|
||||||
success: function (ret) {
|
|
||||||
if (ret=='scheduler' || ret=='thread') {
|
|
||||||
$.notify('<strong>작업을 시작하였습니다. ('+ret+')</strong>', {
|
|
||||||
type: 'success'
|
|
||||||
});
|
|
||||||
} else if (ret == 'is_running') {
|
|
||||||
$.notify('<strong>작업중입니다.</strong>', {
|
|
||||||
type: 'warning'
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$.notify('<strong>작업 시작에 실패하였습니다.</strong>', {
|
|
||||||
type: 'warning'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$("body").on('click', '#global_immediately_execute_sub_btn', function(e){
|
|
||||||
e.preventDefault();
|
|
||||||
$.ajax({
|
|
||||||
url: '/' + package_name + '/ajax/immediately_execute',
|
|
||||||
type: "POST",
|
|
||||||
cache: false,
|
|
||||||
data: {sub:sub},
|
|
||||||
dataType: "json",
|
|
||||||
success: function (ret) {
|
|
||||||
if (ret.msg != null) notify(ret.msg, ret.ret);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$("body").on('click', '#global_reset_db_btn', function(e){
|
|
||||||
e.preventDefault();
|
|
||||||
document.getElementById("confirm_title").innerHTML = "DB 삭제";
|
|
||||||
document.getElementById("confirm_body").innerHTML = "전체 목록을 삭제 하시겠습니까?";
|
|
||||||
$('#confirm_button').attr('onclick', "global_db_delete();");
|
|
||||||
$("#confirm_modal").modal();
|
|
||||||
return;
|
|
||||||
});
|
|
||||||
|
|
||||||
function global_db_delete() {
|
|
||||||
$.ajax({
|
|
||||||
url: '/' + package_name + '/ajax/reset_db',
|
|
||||||
type: "POST",
|
|
||||||
cache: false,
|
|
||||||
data: {},
|
|
||||||
dataType: "json",
|
|
||||||
success: function (data) {
|
|
||||||
if (data) {
|
|
||||||
$.notify('<strong>삭제하였습니다.</strong>', {
|
|
||||||
type: 'success'
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$.notify('<strong>삭제에 실패하였습니다.</strong>',{
|
|
||||||
type: 'warning'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$("body").on('click', '#global_reset_db_sub_btn', function(e){
|
|
||||||
e.preventDefault();
|
|
||||||
document.getElementById("confirm_title").innerHTML = "DB 삭제";
|
|
||||||
document.getElementById("confirm_body").innerHTML = "전체 목록을 삭제 하시겠습니까?";
|
|
||||||
$('#confirm_button').attr('onclick', "global_db_delete_sub();");
|
|
||||||
$("#confirm_modal").modal();
|
|
||||||
return;
|
|
||||||
});
|
|
||||||
|
|
||||||
function global_db_delete_sub() {
|
|
||||||
$.ajax({
|
|
||||||
url: '/' + package_name + '/ajax/reset_db',
|
|
||||||
type: "POST",
|
|
||||||
cache: false,
|
|
||||||
data: {sub:sub},
|
|
||||||
dataType: "json",
|
|
||||||
success: function (data) {
|
|
||||||
if (data) {
|
|
||||||
$.notify('<strong>삭제하였습니다.</strong>', {
|
|
||||||
type: 'success'
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$.notify('<strong>삭제에 실패하였습니다.</strong>',{
|
|
||||||
type: 'warning'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function global_sub_request_search(page, move_top=true) {
|
|
||||||
var formData = getFormdata('#form_search')
|
|
||||||
formData += '&page=' + page;
|
|
||||||
$.ajax({
|
|
||||||
url: '/' + package_name + '/ajax/' + sub + '/web_list',
|
|
||||||
type: "POST",
|
|
||||||
cache: false,
|
|
||||||
data: formData,
|
|
||||||
dataType: "json",
|
|
||||||
success: function (data) {
|
|
||||||
current_data = data;
|
|
||||||
if (move_top)
|
|
||||||
window.scrollTo(0,0);
|
|
||||||
make_list(data.list)
|
|
||||||
make_page_html(data.paging)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$("body").on('click', '#global_json_btn', function(e){
|
$("body").on('click', '#global_json_btn', function(e){
|
||||||
@@ -438,79 +250,11 @@ $("body").on('click', '#global_remove_btn', function(e) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//#######################################################
|
|
||||||
//플러그인 - 모듈 - 서브 구조하에서 서브 관련 함수
|
|
||||||
|
|
||||||
function global_send_command_sub(command, arg1, arg2, arg3, modal_title, callback) {
|
|
||||||
$.ajax({
|
|
||||||
url: '/' + package_name + '/ajax/' + sub + '/' + sub2 + '/command',
|
|
||||||
type: "POST",
|
|
||||||
cache: false,
|
|
||||||
data:{command:command, arg1:arg1, arg2:arg2, arg3},
|
|
||||||
dataType: "json",
|
|
||||||
success: function (ret) {
|
|
||||||
console.log(ret);
|
|
||||||
if (ret.msg != null) notify(ret.msg, ret.ret);
|
|
||||||
if (ret.modal != null) m_modal(ret.modal, modal_title, false);
|
|
||||||
if (ret.json != null) m_modal(ret.json, modal_title, true);
|
|
||||||
if (callback != null) callback(ret);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$("body").on('click', '#global_one_execute_sublogic_btn', function(e){
|
|
||||||
e.preventDefault();
|
|
||||||
$.ajax({
|
|
||||||
url: '/' + package_name + '/ajax/' + sub + '/' + sub2 + '/one_execute',
|
|
||||||
type: "POST",
|
|
||||||
cache: false,
|
|
||||||
data: {},
|
|
||||||
dataType: "json",
|
|
||||||
success: function (ret) {
|
|
||||||
if (ret=='scheduler' || ret=='thread') {
|
|
||||||
$.notify('<strong>작업을 시작하였습니다. ('+ret+')</strong>', {
|
|
||||||
type: 'success'
|
|
||||||
});
|
|
||||||
} else if (ret == 'is_running') {
|
|
||||||
$.notify('<strong>작업중입니다.</strong>', {
|
|
||||||
type: 'warning'
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$.notify('<strong>작업 시작에 실패하였습니다.</strong>', {
|
|
||||||
type: 'warning'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$("body").on('click', '#global_immediately_execute_sublogic_btn', function(e){
|
|
||||||
e.preventDefault();
|
|
||||||
$.ajax({
|
|
||||||
url: '/' + package_name + '/ajax/' + sub + '/' + sub2 + '/immediately_execute',
|
|
||||||
type: "POST",
|
|
||||||
cache: false,
|
|
||||||
data: {},
|
|
||||||
dataType: "json",
|
|
||||||
success: function (ret) {
|
|
||||||
if (ret.msg != null) notify(ret.msg, ret.ret);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#global_scheduler_sublogic').change(function() {
|
|
||||||
var ret = $(this).prop('checked');
|
|
||||||
$.ajax({
|
|
||||||
url: '/'+package_name+'/ajax/' + sub + '/' + sub2 + '/scheduler',
|
|
||||||
type: "POST",
|
|
||||||
cache: false,
|
|
||||||
data: {scheduler : ret},
|
|
||||||
dataType: "json",
|
|
||||||
success: function (list) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -615,50 +359,3 @@ $('#global_scheduler_sublogic').change(function() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 이동한 함수
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function global_send_command(command, data={}) {
|
|
||||||
data['command'] = command;
|
|
||||||
$.ajax({
|
|
||||||
url: '/' + package_name + '/ajax/' + sub + '/command',
|
|
||||||
type: "POST",
|
|
||||||
cache: false,
|
|
||||||
data:data,
|
|
||||||
dataType: "json",
|
|
||||||
success: function (data) {
|
|
||||||
notify(data['msg'], data['ret']);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function global_send_command2(command, arg1, arg2, arg3, modal_title, callback) {
|
|
||||||
$.ajax({
|
|
||||||
url: '/' + package_name + '/ajax/' + sub + '/command',
|
|
||||||
type: "POST",
|
|
||||||
cache: false,
|
|
||||||
data:{command:command, arg1:arg1, arg2:arg2, arg3},
|
|
||||||
dataType: "json",
|
|
||||||
success: function (ret) {
|
|
||||||
if (ret.msg != null) notify(ret.msg, ret.ret);
|
|
||||||
if (ret.modal != null) m_modal(ret.modal, modal_title, false);
|
|
||||||
if (ret.json != null) m_modal(ret.json, modal_title, true);
|
|
||||||
if (callback != null) callback(ret);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -97,58 +97,8 @@ function m_tab_content(name, content, active) {
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
function m_progress(id, width, label) {
|
|
||||||
var str = '';
|
|
||||||
str += '<div class="progress" style="height: 25px;">'
|
|
||||||
str += '<div id="'+id+'" class="progress-bar" style="background-color:yellow;width:'+width+'%"></div>';
|
|
||||||
str += '<div id="'+id+'_label" class="justify-content-center d-flex w-100 position-absolute" style="margin-top:2px">'+label+'</div>';
|
|
||||||
str += '</div>'
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function m_progress2(id, width, label) {
|
|
||||||
var str = '';
|
|
||||||
str += '<div class="progress" style="height: 25px;">'
|
|
||||||
str += '<div id="'+id+'" class="progress-bar" style="background-color:yellow;width:'+width+'%"></div>';
|
|
||||||
str += '<div id="'+id+'_label" class="justify-content-center d-flex w-100 position-absolute" style="margin:0px; margin-top:2px">'+label+'</div>';
|
|
||||||
str += '</div>'
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function make_page_html(data) {
|
|
||||||
str = ' \
|
|
||||||
<div class="d-inline-block"></div> \
|
|
||||||
<div class="row mb-3"> \
|
|
||||||
<div class="col-sm-12"> \
|
|
||||||
<div class="btn-toolbar" style="justify-content: center;" role="toolbar" aria-label="Toolbar with button groups" > \
|
|
||||||
<div class="btn-group btn-group-sm mr-2" role="group" aria-label="First group">'
|
|
||||||
if (data.prev_page) {
|
|
||||||
str += '<button id="page" data-page="' + (data.start_page-1) + '" type="button" class="btn btn-secondary">«</button>'
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = data.start_page ; i <= data.last_page ; i++) {
|
|
||||||
str += '<button id="page" data-page="' + i +'" type="button" class="btn btn-secondary" ';
|
|
||||||
if (i == data.current_page) {
|
|
||||||
str += 'disabled';
|
|
||||||
}
|
|
||||||
str += '>'+i+'</button>';
|
|
||||||
}
|
|
||||||
if (data.next_page) {
|
|
||||||
str += '<button id="page" data-page="' + (data.last_page+1) + '" type="button" class="btn btn-secondary">»</button>'
|
|
||||||
}
|
|
||||||
|
|
||||||
str += '</div> \
|
|
||||||
</div> \
|
|
||||||
</div> \
|
|
||||||
</div> \
|
|
||||||
'
|
|
||||||
document.getElementById("page1").innerHTML = str;
|
|
||||||
document.getElementById("page2").innerHTML = str;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -246,7 +246,25 @@
|
|||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 스케쥴링 작동 버튼-->
|
||||||
|
{% macro setting_global_scheduler_button(is_include, is_running, id='scheduler', left='스케쥴링 작동', desc=['On : 스케쥴링 시작','Off : 스케쥴링 중지']) %}
|
||||||
|
{{ setting_top(left) }}
|
||||||
|
<div class="input-group col-sm-3">
|
||||||
|
{% if is_include == 'True' %}
|
||||||
|
<input id="globalSchedulerSwitchBtn" name="globalSchedulerSwitchBtn" class="form-control form-control-sm" type="checkbox" data-toggle="toggle" checked>
|
||||||
|
{% else %}
|
||||||
|
<input id="globalSchedulerSwitchBtn" name="globalSchedulerSwitchBtn" class="form-control form-control-sm" type="checkbox" data-toggle="toggle">
|
||||||
|
{% endif %}
|
||||||
|
{% if is_running == 'True' %}
|
||||||
|
<span style="padding-left:10px; padding-top: 8px;">동작중</span>
|
||||||
|
{% else %}
|
||||||
|
{% if is_include == 'True' %}
|
||||||
|
<span style="padding-left:10px; padding-top: 8px;">대기중</span>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{{ setting_bottom(desc) }}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -728,25 +746,7 @@ macros.setting_button_with_info([['toggle_btn', 'Toggle', [{'key':'category', 'v
|
|||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
|
||||||
<!-- 스케쥴링 작동 버튼-->
|
|
||||||
{% macro setting_global_scheduler_button(is_include, is_running, id='scheduler', left='스케쥴링 작동', desc=['On : 스케쥴링 시작','Off : 스케쥴링 중지']) %}
|
|
||||||
{{ setting_top(left) }}
|
|
||||||
<div class="input-group col-sm-3">
|
|
||||||
{% if is_include == 'True' %}
|
|
||||||
<input id="global_scheduler" name="global_scheduler" class="form-control form-control-sm" type="checkbox" data-toggle="toggle" checked>
|
|
||||||
{% else %}
|
|
||||||
<input id="global_scheduler" name="global_scheduler" class="form-control form-control-sm" type="checkbox" data-toggle="toggle">
|
|
||||||
{% endif %}
|
|
||||||
{% if is_running == 'True' %}
|
|
||||||
<span style="padding-left:10px; padding-top: 8px;">동작중</span>
|
|
||||||
{% else %}
|
|
||||||
{% if is_include == 'True' %}
|
|
||||||
<span style="padding-left:10px; padding-top: 8px;">대기중</span>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{{ setting_bottom(desc) }}
|
|
||||||
{% endmacro %}
|
|
||||||
|
|
||||||
{% macro setting_global_scheduler_sub_button(is_include, is_running, id='scheduler', left='스케쥴링 작동', desc=['On : 스케쥴링 시작','Off : 스케쥴링 중지']) %}
|
{% macro setting_global_scheduler_sub_button(is_include, is_running, id='scheduler', left='스케쥴링 작동', desc=['On : 스케쥴링 시작','Off : 스케쥴링 중지']) %}
|
||||||
{{ setting_top(left) }}
|
{{ setting_top(left) }}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
VERSION="4.0.30"
|
VERSION="4.0.32"
|
||||||
@@ -44,7 +44,7 @@ class PluginBase(object):
|
|||||||
self.ModelSetting = None
|
self.ModelSetting = None
|
||||||
if setting.get('use_db', True):
|
if setting.get('use_db', True):
|
||||||
db_path = os.path.join(F.config['path_data'], 'db', f'{self.package_name}.db')
|
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}"
|
F.app.config['SQLALCHEMY_BINDS'][self.package_name] = f"sqlite:///{db_path}?check_same_thread=False"
|
||||||
if setting.get('use_default_setting', True):
|
if setting.get('use_default_setting', True):
|
||||||
self.ModelSetting = get_model_setting(self.package_name, self.logger)
|
self.ModelSetting = get_model_setting(self.package_name, self.logger)
|
||||||
|
|
||||||
|
|||||||
@@ -84,47 +84,47 @@ class Logic(object):
|
|||||||
self.P.logger.error(traceback.format_exc())
|
self.P.logger.error(traceback.format_exc())
|
||||||
|
|
||||||
|
|
||||||
def scheduler_start(self, sub):
|
def scheduler_start(self, module_name):
|
||||||
try:
|
try:
|
||||||
job_id = '%s_%s' % (self.P.package_name, sub)
|
job_id = '%s_%s' % (self.P.package_name, module_name)
|
||||||
module = self.get_module(sub)
|
module = self.get_module(module_name)
|
||||||
job = Job(self.P.package_name, job_id, module.get_scheduler_interval(), self.scheduler_function, module.get_scheduler_desc(), args=sub)
|
job = Job(self.P.package_name, job_id, module.get_scheduler_interval(), self.scheduler_function, module.get_scheduler_desc(), args=module_name)
|
||||||
F.scheduler.add_job_instance(job)
|
F.scheduler.add_job_instance(job)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.P.logger.error(f'Exception:{str(e)}')
|
self.P.logger.error(f'Exception:{str(e)}')
|
||||||
self.P.logger.error(traceback.format_exc())
|
self.P.logger.error(traceback.format_exc())
|
||||||
|
|
||||||
|
|
||||||
def scheduler_stop(self, sub):
|
def scheduler_stop(self, module_name):
|
||||||
try:
|
try:
|
||||||
job_id = '%s_%s' % (self.P.package_name, sub)
|
job_id = '%s_%s' % (self.P.package_name, module_name)
|
||||||
F.scheduler.remove_job(job_id)
|
F.scheduler.remove_job(job_id)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.P.logger.error(f'Exception:{str(e)}')
|
self.P.logger.error(f'Exception:{str(e)}')
|
||||||
self.P.logger.error(traceback.format_exc())
|
self.P.logger.error(traceback.format_exc())
|
||||||
|
|
||||||
|
|
||||||
def scheduler_function(self, sub):
|
def scheduler_function(self, module_name):
|
||||||
try:
|
try:
|
||||||
module = self.get_module(sub)
|
module = self.get_module(module_name)
|
||||||
module.scheduler_function()
|
module.scheduler_function()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.P.logger.error(f'Exception:{str(e)}')
|
self.P.logger.error(f'Exception:{str(e)}')
|
||||||
self.P.logger.error(traceback.format_exc())
|
self.P.logger.error(traceback.format_exc())
|
||||||
|
|
||||||
def reset_db(self,sub):
|
def reset_db(self, module_name):
|
||||||
try:
|
try:
|
||||||
module = self.get_module(sub)
|
module = self.get_module(module_name)
|
||||||
return module.reset_db()
|
return module.reset_db()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.P.logger.error(f'Exception:{str(e)}')
|
self.P.logger.error(f'Exception:{str(e)}')
|
||||||
self.P.logger.error(traceback.format_exc())
|
self.P.logger.error(traceback.format_exc())
|
||||||
|
|
||||||
|
|
||||||
def one_execute(self, sub):
|
def one_execute(self, module_name):
|
||||||
self.P.logger.debug('one_execute :%s', sub)
|
self.P.logger.debug('one_execute :%s', module_name)
|
||||||
try:
|
try:
|
||||||
job_id = '%s_%s' % (self.P.package_name, sub)
|
job_id = '%s_%s' % (self.P.package_name, module_name)
|
||||||
if F.scheduler.is_include(job_id):
|
if F.scheduler.is_include(job_id):
|
||||||
if F.scheduler.is_running(job_id):
|
if F.scheduler.is_running(job_id):
|
||||||
ret = 'is_running'
|
ret = 'is_running'
|
||||||
@@ -134,7 +134,7 @@ class Logic(object):
|
|||||||
else:
|
else:
|
||||||
def func():
|
def func():
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
self.scheduler_function(sub)
|
self.scheduler_function(module_name)
|
||||||
threading.Thread(target=func, args=()).start()
|
threading.Thread(target=func, args=()).start()
|
||||||
ret = 'thread'
|
ret = 'thread'
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -143,12 +143,12 @@ class Logic(object):
|
|||||||
ret = 'fail'
|
ret = 'fail'
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def immediately_execute(self, sub):
|
def immediately_execute(self, module_name):
|
||||||
self.P.logger.debug('immediately_execute :%s', sub)
|
self.P.logger.debug('immediately_execute :%s', module_name)
|
||||||
try:
|
try:
|
||||||
def func():
|
def func():
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
self.scheduler_function(sub)
|
self.scheduler_function(module_name)
|
||||||
threading.Thread(target=func, args=()).start()
|
threading.Thread(target=func, args=()).start()
|
||||||
ret = {'ret':'success', 'msg':'실행합니다.'}
|
ret = {'ret':'success', 'msg':'실행합니다.'}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -175,6 +175,65 @@ class Logic(object):
|
|||||||
self.P.logger.error(f'Exception:{str(e)}')
|
self.P.logger.error(f'Exception:{str(e)}')
|
||||||
self.P.logger.error(traceback.format_exc())
|
self.P.logger.error(traceback.format_exc())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#######################################################
|
#######################################################
|
||||||
# 플러그인 - 모듈 - 페이지 구조하에서 서브 관련 함수
|
# 플러그인 - 모듈 - 페이지 구조하에서 서브 관련 함수
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,16 @@ class PluginModuleBase(object):
|
|||||||
self.socketio_list = None
|
self.socketio_list = None
|
||||||
self.page_list = None
|
self.page_list = None
|
||||||
|
|
||||||
|
def get_module(self, module_name):
|
||||||
|
try:
|
||||||
|
for module in self.P.module_list:
|
||||||
|
if module.name == module_name:
|
||||||
|
return module
|
||||||
|
except Exception as e:
|
||||||
|
self.P.logger.error(f'Exception:{str(e)}')
|
||||||
|
self.P.logger.error(traceback.format_exc())
|
||||||
|
|
||||||
|
|
||||||
# set_module_list 대응
|
# set_module_list 대응
|
||||||
def set_page_list(self, page_list):
|
def set_page_list(self, page_list):
|
||||||
try:
|
try:
|
||||||
@@ -87,7 +97,7 @@ class PluginModuleBase(object):
|
|||||||
def get_first_menu(self):
|
def get_first_menu(self):
|
||||||
return self.first_menu
|
return self.first_menu
|
||||||
|
|
||||||
def get_scheduler_name(self):
|
def get_scheduler_id(self):
|
||||||
return '%s_%s' % (self.P.package_name, self.name)
|
return '%s_%s' % (self.P.package_name, self.name)
|
||||||
|
|
||||||
def dump(self, data):
|
def dump(self, data):
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import traceback
|
import traceback
|
||||||
from datetime import datetime
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
from framework import F
|
from framework import F
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@ class ModelBase(F.db.Model):
|
|||||||
__abstract__ = True
|
__abstract__ = True
|
||||||
__table_args__ = {'mysql_collate': 'utf8_general_ci'}
|
__table_args__ = {'mysql_collate': 'utf8_general_ci'}
|
||||||
model_setting = None
|
model_setting = None
|
||||||
logger = None
|
P = None
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return repr(self.as_dict())
|
return repr(self.as_dict())
|
||||||
@@ -24,8 +24,8 @@ class ModelBase(F.db.Model):
|
|||||||
F.db.session.commit()
|
F.db.session.commit()
|
||||||
return self
|
return self
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(f'Exception:{str(e)}')
|
self.P.logger.error(f'Exception:{str(e)}')
|
||||||
self.logger.error(traceback.format_exc())
|
self.P.logger.error(traceback.format_exc())
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_paging_info(cls, count, current_page, page_size):
|
def get_paging_info(cls, count, current_page, page_size):
|
||||||
@@ -48,8 +48,8 @@ class ModelBase(F.db.Model):
|
|||||||
F.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'])
|
F.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
|
return paging
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
F.logger.error(f'Exception:{str(e)}')
|
cls.P.logger.error(f'Exception:{str(e)}')
|
||||||
F.logger.error(traceback.format_exc())
|
cls.P.logger.error(traceback.format_exc())
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -58,8 +58,8 @@ class ModelBase(F.db.Model):
|
|||||||
with F.app.app_context():
|
with F.app.app_context():
|
||||||
return F.db.session.query(cls).filter_by(id=int(id)).first()
|
return F.db.session.query(cls).filter_by(id=int(id)).first()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
F.logger.error(f'Exception:{str(e)}')
|
cls.P.logger.error(f'Exception:{str(e)}')
|
||||||
F.logger.error(traceback.format_exc())
|
cls.P.logger.error(traceback.format_exc())
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -71,8 +71,8 @@ class ModelBase(F.db.Model):
|
|||||||
tmp = [x.as_dict() for x in tmp]
|
tmp = [x.as_dict() for x in tmp]
|
||||||
return tmp
|
return tmp
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
F.logger.error(f'Exception:{str(e)}')
|
cls.P.logger.error(f'Exception:{str(e)}')
|
||||||
F.logger.error(traceback.format_exc())
|
cls.P.logger.error(traceback.format_exc())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -84,20 +84,32 @@ class ModelBase(F.db.Model):
|
|||||||
F.db.session.commit()
|
F.db.session.commit()
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
F.logger.error(f'Exception:{str(e)}')
|
cls.P.logger.error(f'Exception:{str(e)}')
|
||||||
F.logger.error(traceback.format_exc())
|
cls.P.logger.error(traceback.format_exc())
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def delete_all(cls):
|
def delete_all(cls, days=None):
|
||||||
try:
|
try:
|
||||||
with F.app.app_context():
|
with F.app.app_context():
|
||||||
|
if days == None:
|
||||||
F.db.session.query(cls).delete()
|
F.db.session.query(cls).delete()
|
||||||
F.db.session.commit()
|
F.db.session.commit()
|
||||||
|
else:
|
||||||
|
now = datetime.datetime.now()
|
||||||
|
ago = now - datetime.timedelta(days=days)
|
||||||
|
|
||||||
|
ret = F.db.session.query(cls).filter(cls.created_time > ago).delete()
|
||||||
|
cls.P.debug(ret)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
F.logger.error(f'Exception:{str(e)}')
|
cls.P.logger.error(f'Exception:{str(e)}')
|
||||||
F.logger.error(traceback.format_exc())
|
cls.P.logger.error(traceback.format_exc())
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
@@ -111,12 +123,12 @@ class ModelBase(F.db.Model):
|
|||||||
if 'page' in req.form:
|
if 'page' in req.form:
|
||||||
page = int(req.form['page'])
|
page = int(req.form['page'])
|
||||||
if 'keyword' in req.form:
|
if 'keyword' in req.form:
|
||||||
search = req.form['keyword']
|
search = req.form['keyword'].strip()
|
||||||
option1 = req.form.get('option1', 'all')
|
option1 = req.form.get('option1', 'all')
|
||||||
option2 = req.form.get('option2', 'all')
|
option2 = req.form.get('option2', 'all')
|
||||||
order = req.form['order'] if 'order' in req.form else 'desc'
|
order = req.form['order'] if 'order' in req.form else 'desc'
|
||||||
|
|
||||||
query = cls.make_query(order=order, search=search, option1=option1, option2=option2)
|
query = cls.make_query(req, order=order, search=search, option1=option1, option2=option2)
|
||||||
count = query.count()
|
count = query.count()
|
||||||
query = query.limit(page_size).offset((page-1)*page_size)
|
query = query.limit(page_size).offset((page-1)*page_size)
|
||||||
F.logger.debug('cls count:%s', count)
|
F.logger.debug('cls count:%s', count)
|
||||||
@@ -124,21 +136,21 @@ class ModelBase(F.db.Model):
|
|||||||
ret['list'] = [item.as_dict() for item in lists]
|
ret['list'] = [item.as_dict() for item in lists]
|
||||||
ret['paging'] = cls.get_paging_info(count, page, page_size)
|
ret['paging'] = cls.get_paging_info(count, page, page_size)
|
||||||
try:
|
try:
|
||||||
if cls.model_setting is not None and cls.__tablename__ is not None:
|
if cls.P.ModelSetting 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}')
|
cls.P.ModelSetting.set(f'{cls.__tablename__}_last_list_option', f'{order}|{page}|{search}|{option1}|{option2}')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
F.logger.error('Exception:%s', e)
|
F.logger.error('Exception:%s', e)
|
||||||
F.logger.error(traceback.format_exc())
|
F.logger.error(traceback.format_exc())
|
||||||
F.logger.error(f'{cls.__tablename__}_last_list_option ERROR!' )
|
F.logger.error(f'{cls.__tablename__}_last_list_option ERROR!' )
|
||||||
return ret
|
return ret
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
F.logger.error('Exception:%s', e)
|
cls.P.logger.error('Exception:%s', e)
|
||||||
F.logger.error(traceback.format_exc())
|
cls.P.logger.error(traceback.format_exc())
|
||||||
|
|
||||||
|
|
||||||
# 오버라이딩
|
# 오버라이딩
|
||||||
@classmethod
|
@classmethod
|
||||||
def make_query(cls, order='desc', search='', option1='all', option2='all'):
|
def make_query(cls, req, order='desc', search='', option1='all', option2='all'):
|
||||||
with F.app.app_context():
|
with F.app.app_context():
|
||||||
query = F.db.session.query(cls)
|
query = F.db.session.query(cls)
|
||||||
return query
|
return query
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ def get_model_setting(package_name, logger, table_name=None):
|
|||||||
for key, value in req.form.items():
|
for key, value in req.form.items():
|
||||||
if key in ['scheduler', 'is_running']:
|
if key in ['scheduler', 'is_running']:
|
||||||
continue
|
continue
|
||||||
if key.startswith('global_') or key.startswith('tmp_') or key.startswith('_'):
|
if key.startswith('global') or key.startswith('tmp_') or key.startswith('_'):
|
||||||
continue
|
continue
|
||||||
#logger.debug('Key:%s Value:%s', key, value)
|
#logger.debug('Key:%s Value:%s', key, value)
|
||||||
if ModelSetting.get(key) != value:
|
if ModelSetting.get(key) != value:
|
||||||
|
|||||||
@@ -92,42 +92,37 @@ def default_route(P):
|
|||||||
for module in P.module_list:
|
for module in P.module_list:
|
||||||
module.setting_save_after(change_list)
|
module.setting_save_after(change_list)
|
||||||
return jsonify(ret)
|
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:
|
except Exception as exception:
|
||||||
P.logger.error('Exception:%s', exception)
|
P.logger.error('Exception:%s', exception)
|
||||||
P.logger.error(traceback.format_exc())
|
P.logger.error(traceback.format_exc())
|
||||||
|
|
||||||
@P.blueprint.route('/ajax/<mod>/<cmd>', methods=['GET', 'POST'])
|
@P.blueprint.route('/ajax/<module_name>/<cmd>', methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def second_ajax(mod, cmd):
|
def second_ajax(module_name, cmd):
|
||||||
try:
|
try:
|
||||||
for module in P.module_list:
|
for module in P.module_list:
|
||||||
if mod == module.name:
|
if module_name == module.name:
|
||||||
if cmd == 'command':
|
if cmd == 'command':
|
||||||
return module.process_command(request.form['command'], request.form.get('arg1'), request.form.get('arg2'), request.form.get('arg3'), request)
|
return module.process_command(request.form['command'], request.form.get('arg1'), request.form.get('arg2'), request.form.get('arg3'), request)
|
||||||
else:
|
else:
|
||||||
return module.process_ajax(cmd, request)
|
return module.process_ajax(cmd, request)
|
||||||
|
elif cmd == 'scheduler':
|
||||||
|
go = request.form['scheduler']
|
||||||
|
if go == 'true':
|
||||||
|
P.logic.scheduler_start(module_name)
|
||||||
|
else:
|
||||||
|
P.logic.scheduler_stop(module_name)
|
||||||
|
return jsonify(go)
|
||||||
|
elif cmd == 'reset_db':
|
||||||
|
ret = P.logic.reset_db(module_name)
|
||||||
|
return jsonify(ret)
|
||||||
|
elif cmd == 'one_execute':
|
||||||
|
ret = P.logic.one_execute(module_name)
|
||||||
|
return jsonify(ret)
|
||||||
|
elif cmd == 'immediately_execute':
|
||||||
|
ret = P.logic.immediately_execute(module_name)
|
||||||
|
return jsonify(ret)
|
||||||
except Exception as exception:
|
except Exception as exception:
|
||||||
P.logger.error('Exception:%s', exception)
|
P.logger.error('Exception:%s', exception)
|
||||||
P.logger.error(traceback.format_exc())
|
P.logger.error(traceback.format_exc())
|
||||||
|
|||||||
Reference in New Issue
Block a user