diff --git a/data/db/menu.yaml b/data/db/menu.yaml
new file mode 100644
index 0000000..a8ac393
--- /dev/null
+++ b/data/db/menu.yaml
@@ -0,0 +1,44 @@
+# 카테고리
+# uri 가 plugin인 경우 name 값은 대체
+
+#- name: "토렌트"
+# list:
+# - uri: "rss"
+
+
+#- name: "기본 기능"
+# list:
+# - uri: "terminal"
+# - uri: "command"
+# - uri: "flaskfilemanager"
+# - uri: "flaskcode"
+# - uri: "number_baseball"
+
+
+#- name: "링크"
+# list:
+# - uri: "https://app.plex.tv"
+# name: "Plex"
+# target: "_self"
+# - uri: "https://www.netflix.com"
+# name: "Netflix"
+
+
+- name: "시스템"
+ list:
+ - uri: "system"
+ name: "설정"
+ - uri: "setting"
+ name: "확장 설정"
+ - uri: "system/plugin"
+ name: "플러그인 관리"
+ - uri: "-"
+ - uri: "system/logout"
+ name: "로그아웃"
+ - uri: "system/restart"
+ name: "재시작(업데이트)"
+ - uri: "system/shutdown"
+ #uri: "javascript:shutdown_confirm();"
+ name: "종료"
+
+
\ No newline at end of file
diff --git a/data/db/system.db b/data/db/system.db
new file mode 100644
index 0000000..c7cd2c5
Binary files /dev/null and b/data/db/system.db differ
diff --git a/lib/framework/init_plugin.py b/lib/framework/init_plugin.py
index 36a69ff..da24fc8 100644
--- a/lib/framework/init_plugin.py
+++ b/lib/framework/init_plugin.py
@@ -43,7 +43,7 @@ class PluginManager:
for t in tmps:
if not t.startswith('_') and os.path.isdir(os.path.join(plugin_path, t)):
add_plugin_list.append(t)
- cls.all_package_list[t] = {'pos':'normal', 'path':os.path.join(plugin_path, t)}
+ cls.all_package_list[t] = {'pos':'normal', 'path':os.path.join(plugin_path, t), 'loading':(F.config.get('plugin_loading_only_devpath', None) != True)}
plugins = plugins + add_plugin_list
except Exception as exception:
@@ -64,7 +64,7 @@ class PluginManager:
for t in tmps:
if not t.startswith('_') and os.path.isdir(os.path.join(plugin_path, t)):
add_plugin_list.append(t)
- cls.all_package_list[t] = {'pos':'dev', 'path':os.path.join(plugin_path, t)}
+ cls.all_package_list[t] = {'pos':'dev', 'path':os.path.join(plugin_path, t), 'loading':True}
plugins = plugins + add_plugin_list
except Exception as exception:
F.logger.error('Exception:%s', exception)
diff --git a/lib/framework/init_route.py b/lib/framework/init_route.py
index a68853e..7acbc18 100644
--- a/lib/framework/init_route.py
+++ b/lib/framework/init_route.py
@@ -34,10 +34,15 @@ def global_ajax(sub):
elif sub == 'is_available_edit':
# globalEditBtn
try:
- import flaskcode
- from flaskcode.setup import P as PP
- ret = {'ret':True, 'target':PP.ModelSetting.get('setting_open_target')}
- return jsonify(ret)
+ if F.PluginManager.all_package_list['flaskcode']['loading']:
+ PP = F.PluginManager.all_package_list['flaskcode']['P']
+ #import flaskcode
+ #from flaskcode.setup import P as PP
+ ret = {'ret':True, 'target':PP.ModelSetting.get('setting_open_target')}
+ return jsonify(ret)
+ else:
+ return jsonify({'ret':False})
+
except:
return jsonify({'ret':False})
elif sub == 'command_modal_hide':
diff --git a/lib/framework/templates/base.html b/lib/framework/templates/base.html
index 6eddcc3..f8e22dd 100644
--- a/lib/framework/templates/base.html
+++ b/lib/framework/templates/base.html
@@ -9,13 +9,6 @@
{% endblock %}
-
-
-
-
diff --git a/lib/support/__init__.py b/lib/support/__init__.py
index bea18d8..1746d13 100644
--- a/lib/support/__init__.py
+++ b/lib/support/__init__.py
@@ -15,7 +15,6 @@ logger = get_logger()
from .base.aes import SupportAES
from .base.discord import SupportDiscord
from .base.file import SupportFile
-from .base.process import SupportProcess
from .base.string import SupportString
from .base.subprocess import SupportSubprocess
from .base.telegram import SupportTelegram
diff --git a/lib/support/base/process.py b/lib/support/base/process.py
deleted file mode 100644
index 5738a4e..0000000
--- a/lib/support/base/process.py
+++ /dev/null
@@ -1,48 +0,0 @@
-import os, sys, traceback, subprocess, json, platform
-from . import logger
-
-
-class SupportProcess(object):
-
- @classmethod
- def execute(cls, command, format=None, shell=False, env=None, timeout=1000):
- logger.debug(command)
- try:
- if platform.system() == 'Windows':
- command = ' '.join(command)
-
- iter_arg = ''
- process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, shell=shell, env=env, encoding='utf8')
- try:
- process_ret = process.wait(timeout=timeout) # wait for the subprocess to exit
- except:
- import psutil
- process = psutil.Process(process.pid)
- for proc in process.children(recursive=True):
- proc.kill()
- process.kill()
- return "timeout"
- ret = []
- with process.stdout:
- for line in iter(process.stdout.readline, iter_arg):
- ret.append(line.strip())
-
- if format is None:
- ret2 = '\n'.join(ret)
- elif format == 'json':
- try:
- index = 0
- for idx, tmp in enumerate(ret):
- #logger.debug(tmp)
- if tmp.startswith('{') or tmp.startswith('['):
- index = idx
- break
- ret2 = json.loads(''.join(ret[index:]))
- except:
- ret2 = None
- return ret2
- except Exception as e:
- logger.error(f'Exception:{str(e)}', )
- logger.error(traceback.format_exc())
- logger.error('command : %s', command)
-
\ No newline at end of file
diff --git a/lib/support/base/subprocess.py b/lib/support/base/subprocess.py
index af40edb..ed351b7 100644
--- a/lib/support/base/subprocess.py
+++ b/lib/support/base/subprocess.py
@@ -132,13 +132,16 @@ class SupportSubprocess(object):
self.start_send_callback()
if self.process is not None:
self.process.wait()
- #logger.info(f"{self.command} 정상 종료")
- if self.stdout_queue != None:
- self.stdout_queue.put('')
+ logger.info(f"{self.command} 정상 종료")
except Exception as e:
logger.error(f'Exception:{str(e)}')
logger.error(traceback.format_exc())
-
+ if self.stdout_callback != None:
+ self.stdout_callback('error', str(e))
+ self.stdout_callback('error', str(traceback.format_exc()))
+ finally:
+ if self.stdout_callback != None:
+ self.stdout_callback('thread_end', None)
def start_communicate(self):
@@ -150,8 +153,6 @@ class SupportSubprocess(object):
def rdr():
while True:
- if self.process == None:
- break
buf = self.process.stdout.read(1)
if buf:
_queue.put( buf )
@@ -178,10 +179,9 @@ class SupportSubprocess(object):
except:
pass
if r is not None:
- if self.stdout_queue != None:
- self.stdout_queue.put(r)
- if self.stdout_queue != None: # 사용자 중지
- self.stdout_queue.put('')
+ #print(f"{r=}")
+ self.stdout_queue.put(r)
+ self.stdout_queue.put('')
for tgt in [rdr, clct]:
th = threading.Thread(target=tgt)
th.setDaemon(True)
@@ -200,10 +200,6 @@ class SupportSubprocess(object):
else:
if self.stdout_callback != None:
self.stdout_callback('log', line)
- self.send_to_ui_thread = None
- self.stdout_queue = None
- self.process = None
-
th = threading.Thread(target=func, args=())
th.setDaemon(True)
th.start()
@@ -222,7 +218,7 @@ class SupportSubprocess(object):
logger.error(traceback.format_exc())
finally:
try:
- self.stdout_queue = None
+ #self.stdout_queue = None
self.process.kill()
except: pass
diff --git a/lib/system/___logic.py b/lib/system/___logic.py
deleted file mode 100644
index e27bdb2..0000000
--- a/lib/system/___logic.py
+++ /dev/null
@@ -1,275 +0,0 @@
-# -*- coding: utf-8 -*-
-#########################################################
-# python
-import os
-import traceback
-import logging
-from datetime import datetime
-import string
-import random
-import json
-
-# third-party
-import requests
-from flask import Blueprint, request, Response, send_file, render_template, redirect, jsonify
-from flask_login import login_user, logout_user, current_user, login_required
-
-
-from framework import F, frame, app, db, scheduler, VERSION, path_app_root, logger, Job, User
-from framework.util import Util
-
-# 패키지
-from .model import ModelSetting
-import system
-
-#########################################################
-
-class SystemLogic(object):
- point = 0
- db_default = {
- 'db_version' : '1',
- 'port' : '9999',
- 'ddns' : 'http://localhost:9999',
- #'url_filebrowser' : 'http://localhost:9998',
- #'url_celery_monitoring' : 'http://localhost:9997',
- 'id' : 'admin',
- 'pw' : '//nCv0/YkVI3U2AAgYwOuJ2hPlQ7cDYIbuaCt4YJupY=',
- 'system_start_time' : '',
- 'repeat' : '',
- 'auto_restart_hour' : '12',
- #'unique' : '',
- 'theme' : 'Cerulean',
- 'log_level' : '10',
- 'use_login' : 'False',
- 'link_json' : '[{"type":"link","title":"위키","url":"https://sjva.me/wiki/public/start"}]',
- 'plugin_dev_path': '',
- 'plugin_tving_level2' : 'False',
- 'web_title' : 'Home',
- 'my_ip' : '',
- 'wavve_guid' : '',
-
- #인증
- 'auth_use_apikey' : 'False',
- 'auth_apikey' : '',
- #'hide_menu' : 'True',
-
- #Selenium
- 'selenium_remote_url' : '',
- 'selenium_remote_default_option' : '--no-sandbox\n--disable-gpu',
- 'selenium_binary_default_option' : '',
-
- # notify
- 'notify_telegram_use' : 'False',
- 'notify_telegram_token' : '',
- 'notify_telegram_chat_id' : '',
- 'notify_telegram_disable_notification' : 'False',
- 'notify_discord_use' : 'False',
- 'notify_discord_webhook' : '',
-
- 'notify_advaned_use' : 'False',
- 'notify_advaned_policy' : u"# 각 플러그인 설정 설명에 명시되어 있는 ID = 형식\n# DEFAULT 부터 주석(#) 제거 후 작성\n\n# DEFAULT = ",
-
- # telegram
- 'telegram_bot_token' : '',
- 'telegram_bot_auto_start' : 'False',
- 'telegram_resend' : 'False',
- 'telegram_resend_chat_id' : '',
-
- # 홈페이지 연동 2020-06-07
- 'sjva_me_user_id' : '',
- 'auth_status' : '',
- 'sjva_id' : '',
-
- # memo
- 'memo' : '',
-
- # tool - decrypt
- 'tool_crypt_use_user_key' : 'False',
- 'tool_crypt_user_key' : '',
- 'tool_crypt_encrypt_word' : '',
- 'tool_crypt_decrypt_word' : '',
-
- 'use_beta' : 'False',
- }
-
-
-
- @staticmethod
- def get_info():
- info = {}
- import platform
- info['platform'] = platform.platform()
- info['processor'] = platform.processor()
-
- import sys
- info['python_version'] = sys.version
- info['version'] = VERSION
- info['recent_version'] = SystemLogic.recent_version
- info['path_app_root'] = path_app_root
- info['running_type'] = u'%s. 비동기 작업 : %s' % (frame.config['running_type'], u"사용" if frame.config['use_celery'] else "미사용")
- import system
-
- info['auth'] = frame.config['member']['auth_desc']
- info['cpu_percent'] = 'not supported'
- info['memory'] = 'not supported'
- info['disk'] = 'not supported'
- if frame.config['running_type'] != 'termux':
- try:
- import psutil
- from framework.util import Util
- info['cpu_percent'] = '%s %%' % psutil.cpu_percent()
- tmp = psutil.virtual_memory()
- #info['memory'] = [Util.sizeof_fmt(tmp[0], suffix='B'), Util.sizeof_fmt(tmp[3]), Util.sizeof_fmt(tmp[1]), tmp[2]]
- info['memory'] = u'전체 : %s 사용량 : %s 남은량 : %s (%s%%)' % (Util.sizeof_fmt(tmp[0], suffix='B'), Util.sizeof_fmt(tmp[3], suffix='B'), Util.sizeof_fmt(tmp[1], suffix='B'), tmp[2])
- except:
- pass
-
- try:
- import platform
- if platform.system() == 'Windows':
- s = os.path.splitdrive(path_app_root)
- root = s[0]
- else:
- root = '/'
- tmp = psutil.disk_usage(root)
- info['disk'] = u'전체 : %s 사용량 : %s 남은량 : %s (%s%%) - 드라이브 (%s)' % (Util.sizeof_fmt(tmp[0], suffix='B'), Util.sizeof_fmt(tmp[1], suffix='B'), Util.sizeof_fmt(tmp[2], suffix='B'), tmp[3], root)
- except Exception as exception:
- pass
- try:
- tmp = SystemLogic.get_setting_value('system_start_time')
- #logger.debug('SYSTEM_START_TIME:%s', tmp)
- tmp_datetime = datetime.strptime(tmp, '%Y-%m-%d %H:%M:%S')
- timedelta = datetime.now() - tmp_datetime
- info['time'] = u'시작 : %s 경과 : %s 재시작 : %s' % (tmp, str(timedelta).split('.')[0], frame.config['arg_repeat'])
- except Exception as exception:
- info['time'] = str(exception)
- return info
-
-
- @staticmethod
- def setting_save_system(req):
- try:
- for key, value in req.form.items():
- logger.debug('Key:%s Value:%s', key, value)
- entity = db.session.query(ModelSetting).filter_by(key=key).with_for_update().first()
- entity.value = value
- #if key == 'theme':
- # SystemLogic.change_theme(value)
- db.session.commit()
- lists = ModelSetting.query.all()
- SystemLogic.setting_list = Util.db_list_to_dict(lists)
- frame.users[db.session.query(ModelSetting).filter_by(key='id').first().value] = User(db.session.query(ModelSetting).filter_by(key='id').first().value, passwd_hash=db.session.query(ModelSetting).filter_by(key='pw').first().value)
- SystemLogic.set_restart_scheduler()
- frame.set_level(int(db.session.query(ModelSetting).filter_by(key='log_level').first().value))
-
- return True
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- return False
-
- @staticmethod
- def setting_save_after():
- try:
- frame.users[ModelSetting.get('id')] = User(ModelSetting.get('id'), passwd_hash=ModelSetting.get('pw'))
- SystemLogic.set_restart_scheduler()
- frame.set_level(int(db.session.query(ModelSetting).filter_by(key='log_level').first().value))
- from .logic_site import SystemLogicSite
- SystemLogicSite.get_daum_cookies(force=True)
- SystemLogicSite.create_tving_instance()
- return True
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- return False
-
- @staticmethod
- def change_theme(theme):
- try:
- source = os.path.join(path_app_root, 'static', 'css', 'theme', '%s_bootstrap.min.css' % theme)
- target = os.path.join(path_app_root, 'static', 'css', 'bootstrap.min.css')
- os.remove(target)
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- return False
-
- @staticmethod
- def get_setting_value(key):
- try:
- #logger.debug('get_setting_value:%s', key)
- entity = db.session.query(ModelSetting).filter_by(key=key).first()
- if entity is None:
- return None
- else:
- return entity.value
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- logger.error('error key : %s', key)
- return False
-
-
-
-
-
-
-
- @staticmethod
- def command_run(command_text):
- try:
- ret = {}
- tmp = command_text.strip().split(' ')
- if not tmp:
- ret['ret'] = 'success'
- ret['log'] = 'Empty..'
- return ret
- if tmp[0] == 'set':
- if len(tmp) == 3:
- if tmp[1] == 'token':
- tmp[1] = 'unique'
- entity = db.session.query(ModelSetting).filter_by(key=tmp[1]).with_for_update().first()
- if entity is None:
- ret['ret'] = 'fail'
- ret['log'] = '%s not exist' % tmp[1]
- return ret
- entity.value = tmp[2] if tmp[2] != 'EMPTY' else ""
- db.session.commit()
- ret['ret'] = 'success'
- ret['log'] = '%s - %s' % (tmp[1], tmp[2])
- return ret
-
- if tmp[0] == 'set2':
- if tmp[1] == 'klive':
- from klive import ModelSetting as KLiveModelSetting
- if KLiveModelSetting.get(tmp[2]) is not None:
- KLiveModelSetting.set(tmp[2], tmp[3])
- ret['ret'] = 'success'
- ret['log'] = f'KLive 설정 값 변경 : {tmp[2]} - {tmp[3]}'
- return ret
-
-
- ret['ret'] = 'fail'
- ret['log'] = 'wrong command'
- return ret
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- ret['ret'] = 'fail'
- ret['log'] = str(exception)
- return ret
-
- @staticmethod
- def link_save(link_data_str):
- try:
- data = json.loads(link_data_str)
- entity = db.session.query(ModelSetting).filter_by(key='link_json').with_for_update().first()
- entity.value = link_data_str
- db.session.commit()
- SystemLogic.apply_menu_link()
- return True
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- return False
-
diff --git a/lib/system/__init__.py b/lib/system/__init__.py
index 82c2912..e69de29 100644
--- a/lib/system/__init__.py
+++ b/lib/system/__init__.py
@@ -1,14 +0,0 @@
-"""
-from .plugin import blueprint, menu, plugin_load, plugin_unload, restart, shutdown
-from .logic import SystemLogic
-from .model import ModelSetting
-from .model import ModelSetting as SystemModelSetting
-
-
-from .logic_plugin import LogicPlugin
-from .logic_selenium import SystemLogicSelenium
-from .logic_command import SystemLogicCommand
-
-from .logic_site import SystemLogicSite
-
-"""
\ No newline at end of file
diff --git a/lib/system/logic_auth.py b/lib/system/logic_auth.py
deleted file mode 100644
index 3411b0a..0000000
--- a/lib/system/logic_auth.py
+++ /dev/null
@@ -1,162 +0,0 @@
-# -*- coding: utf-8 -*-
-#########################################################
-# python
-import codecs
-import json
-import os
-import random
-import string
-import traceback
-
-# third-party
-import requests
-from flask import (Blueprint, Response, jsonify, redirect, render_template,
- request, send_file)
-from framework import app, frame, path_app_root
-from framework.util import Util
-
-from .model import ModelSetting
-# 패키지
-from .plugin import logger, package_name
-
-# sjva 공용
-
-
-
-class SystemLogicAuth(object):
- @staticmethod
- def process_ajax(sub, req):
- logger.debug(sub)
- try:
- if sub == 'apikey_generate':
- ret = SystemLogicAuth.apikey_generate()
- return jsonify(ret)
- elif sub == 'do_auth':
- ret = SystemLogicAuth.do_auth()
- return jsonify(ret)
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
-
- ##########################################################################
-
-
-
- @staticmethod
- def get_auth_status(retry=True):
- try:
- value = ModelSetting.get('auth_status')
- ret = {'ret' : False, 'desc' : '', 'level' : 0, 'point': 0}
- if value == '':
- ret['desc'] = '미인증'
- elif value == 'wrong_id':
- ret['desc'] = '미인증 - 홈페이지 아이디가 없습니다.'
- elif value == 'too_many_sjva':
- ret['desc'] = '미인증 - 너무 많은 SJVA를 사용중입니다.'
- elif value == 'wrong_apikey':
- ret['desc'] = '미인증 - 홈페이지에 등록된 APIKEY와 다릅니다.'
- elif value == 'auth_status':
- ret['desc'] = '인증 실패'
- else:
- status = SystemLogicAuth.check_auth_status(value)
- if status is not None and status['ret']:
- ret['ret'] = status['ret']
- ret['desc'] = '인증되었습니다. (회원등급:%s, 포인트:%s)' % (status['level'], status['point'])
- ret['level'] = status['level']
- ret['point'] = status['point']
- else:
- if retry:
- SystemLogicAuth.do_auth()
- #ModelSetting.set('auth_status', SystemLogicAuth.make_auth_status())
- return SystemLogicAuth.get_auth_status(retry=False)
- else:
- ret['desc'] = '잘못된 값입니다. 다시 인증하세요.'
- return ret
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
- @staticmethod
- def check_auth_status(value=None):
- try:
- from support import SupportAES
- mykey=(codecs.encode(SystemLogicAuth.get_ip().encode(), 'hex').decode() + codecs.encode(ModelSetting.get('auth_apikey').encode(), 'hex').decode()).zfill(32)[:32].encode()
- logger.debug(mykey)
- tmp = SupportAES.decrypt(value, mykey=mykey)
- tmp = tmp.split('_')
- ret = {}
- ret['ret'] = (ModelSetting.get('sjva_id') == tmp[0])
- ret['level'] = int(tmp[1])
- ret['point'] = int(tmp[2])
- return ret
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
- @staticmethod
- def make_auth_status(level, point):
- try:
- from support.base import SupportAES
- mykey=(codecs.encode(SystemLogicAuth.get_ip().encode(), 'hex').decode() + codecs.encode(ModelSetting.get('auth_apikey').encode(), 'hex').decode()).zfill(32)[:32].encode()
- ret = SupportAES.encrypt(str('%s_%s_%s' % (ModelSetting.get('sjva_id'), level, point)), mykey=mykey)
- logger.debug(ret)
- return ret
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
-
- @staticmethod
- def get_ip():
- import socket
- s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- try:
- # doesn't even have to be reachable
- s.connect(('10.255.255.255', 1))
- IP = s.getsockname()[0]
- except Exception:
- IP = '127.0.0.1'
- finally:
- s.close()
- logger.debug('IP:%s', IP)
- return IP
-
- @staticmethod
- def do_auth():
- try:
- ret = {'ret':False, 'msg':'', 'level':0, 'point':0}
- apikey = ModelSetting.get('auth_apikey')
- user_id = ModelSetting.get('sjva_me_user_id')
- if len(apikey) != 10:
- ret['msg'] = 'APIKEY 문자 길이는 10자리여야합니다.'
- return ret
- if user_id == '':
- ret['msg'] = '홈페이지 ID가 없습니다.'
- return ret
-
- data = requests.post(f"{frame.config['DEFINE']['WEB_DIRECT_URL']}/sjva/auth.php", data={'apikey':apikey,'user_id':user_id, 'sjva_id':ModelSetting.get('sjva_id')}).json()
- if data['result'] == 'success':
- ret['ret'] = True
- ret['msg'] = u'총 %s개 등록
회원등급:%s, 포인트:%s' % (data['count'], data['level'], data['point'])
- ret['level'] = int(data['level'])
- ret['point'] = int(data['point'])
- ModelSetting.set('auth_status', SystemLogicAuth.make_auth_status(ret['level'], ret['point']))
- else:
- ModelSetting.set('auth_status', data['result'])
- tmp = SystemLogicAuth.get_auth_status(retry=False)
- ret['ret'] = tmp['ret']
- ret['msg'] = tmp['desc']
- return ret
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- ret['msg'] = '인증 실패'
- ret['level'] = -1
- ret['point'] = -1
- ModelSetting.set('auth_status', 'auth_fail')
-
- return ret
-
-
-
diff --git a/lib/system/logic_command.py b/lib/system/logic_command.py
deleted file mode 100644
index 97c5338..0000000
--- a/lib/system/logic_command.py
+++ /dev/null
@@ -1,246 +0,0 @@
-# -*- coding: utf-8 -*-
-#########################################################
-# python
-import os
-import traceback
-import logging
-import platform
-import subprocess
-import threading
-import sys
-import io
-import time
-import json
-import queue
-# third-party
-
-# sjva 공용
-
-from framework import path_app_root, socketio, app, logger
-
-# 패키지
-
-
-
-class SystemLogicCommand(object):
-
- commands = None
- process = None
- stdout_queue = None
- thread = None
- send_to_ui_thread = None
- return_log = None
- @staticmethod
- def start(title, commands, clear=True, wait=False, show_modal=True):
- try:
- if show_modal:
- if clear:
- socketio.emit("command_modal_clear", None, namespace='/framework', broadcast=True)
- SystemLogicCommand.return_log = []
- SystemLogicCommand.title = title
- SystemLogicCommand.commands = commands
- SystemLogicCommand.thread = threading.Thread(target=SystemLogicCommand.execute_thread_function, args=(show_modal,))
- SystemLogicCommand.thread.setDaemon(True)
- SystemLogicCommand.thread.start()
- if wait:
- time.sleep(1)
- SystemLogicCommand.thread.join()
- return SystemLogicCommand.return_log
-
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
- @staticmethod
- def execute_thread_function(show_modal):
- try:
- #if wait:
- if show_modal:
- socketio.emit("loading_hide", None, namespace='/framework', broadcast=True)
- for command in SystemLogicCommand.commands:
- #logger.debug('Command :%s', command)
- if command[0] == 'msg':
- if show_modal:
- socketio.emit("command_modal_add_text", '%s\n\n' % command[1], namespace='/framework', broadcast=True)
- elif command[0] == 'system':
- if show_modal:
- socketio.emit("command_modal_add_text", '$ %s\n\n' % command[1], namespace='/framework', broadcast=True)
- os.system(command[1])
- else:
- show_command = True
- if command[0] == 'hide':
- show_command = False
- command = command[1:]
- #SystemLogicCommand.process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, bufsize=1)
- SystemLogicCommand.process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, encoding='utf8')
- SystemLogicCommand.start_communicate(command, show_command=show_command)
- SystemLogicCommand.send_queue_start(show_modal)
- if SystemLogicCommand.process is not None:
- SystemLogicCommand.process.wait()
- time.sleep(1)
-
- except Exception as exception:
- #logger.error('Exception:%s', exception)
- #logger.error(traceback.format_exc())
- if show_modal:
- socketio.emit("command_modal_show", SystemLogicCommand.title, namespace='/framework', broadcast=True)
- socketio.emit("command_modal_add_text", str(exception), namespace='/framework', broadcast=True)
- socketio.emit("command_modal_add_text", str(traceback.format_exc()), namespace='/framework', broadcast=True)
-
-
-
- @staticmethod
- def start_communicate(current_command, show_command=True):
- SystemLogicCommand.stdout_queue = queue.Queue()
- if show_command:
- SystemLogicCommand.stdout_queue.put('$ %s\n' % ' '.join(current_command))
- sout = io.open(SystemLogicCommand.process.stdout.fileno(), 'rb', closefd=False)
- #serr = io.open(process.stderr.fileno(), 'rb', closefd=False)
-
- def Pump(stream):
- queue = queue.Queue()
-
- def rdr():
- logger.debug('START RDR')
- while True:
- buf = SystemLogicCommand.process.stdout.read(1)
- if buf:
- queue.put( buf )
- else:
- queue.put( None )
- break
- logger.debug('END RDR')
- queue.put( None )
- time.sleep(1)
-
- #Logic.command_close()
- def clct():
- active = True
- logger.debug('START clct')
- while active:
- r = queue.get()
- if r is None:
- break
- try:
- while True:
- r1 = queue.get(timeout=0.005)
- if r1 is None:
- active = False
- break
- else:
- r += r1
- except:
- pass
- if r is not None:
- try:
- r = r.decode('utf-8')
- except Exception as exception:
- #logger.error('Exception:%s', e)
- #logger.error(traceback.format_exc())
- try:
- r = r.decode('cp949')
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- try:
- r = r.decode('euc-kr')
- except:
- pass
-
- SystemLogicCommand.stdout_queue.put(r)
- #SystemLogicCommand.return_log.append(r)
- SystemLogicCommand.return_log += r.split('\n')
- logger.debug('IN:%s', r)
- SystemLogicCommand.stdout_queue.put('')
- logger.debug('END clct')
- #Logic.command_close()
- for tgt in [rdr, clct]:
- th = threading.Thread(target=tgt)
- th.setDaemon(True)
- th.start()
- Pump(sout)
- #Pump(serr, 'stderr')
-
- @staticmethod
- def send_queue_start(show_modal):
- def send_to_ui_thread_function():
- logger.debug('send_queue_thread_function START')
- if show_modal:
- socketio.emit("command_modal_show", SystemLogicCommand.title, namespace='/framework', broadcast=True)
- while SystemLogicCommand.stdout_queue:
- line = SystemLogicCommand.stdout_queue.get()
- logger.debug('Send to UI :%s', line)
- if line == '':
- if show_modal:
- socketio.emit("command_modal_add_text", "\n", namespace='/framework', broadcast=True)
- break
- else:
- if show_modal:
- socketio.emit("command_modal_add_text", line, namespace='/framework', broadcast=True)
- SystemLogicCommand.send_to_ui_thread = None
- SystemLogicCommand.stdout_queue = None
- SystemLogicCommand.process = None
- logger.debug('send_to_ui_thread_function END')
-
- if SystemLogicCommand.send_to_ui_thread is None:
- SystemLogicCommand.send_to_ui_thread = threading.Thread(target=send_to_ui_thread_function, args=())
- SystemLogicCommand.send_to_ui_thread.start()
-
- @staticmethod
- def plugin_unload():
- try:
- if SystemLogicCommand.process is not None and SystemLogicCommand.process.poll() is None:
- import psutil
- process = psutil.Process(SystemLogicCommand.process.pid)
- for proc in SystemLogicCommand.process.children(recursive=True):
- proc.kill()
- SystemLogicCommand.process.kill()
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
-
- ##################################
- # 외부 호출
- @staticmethod
- def execute_command_return(command, format=None, force_log=False):
- from tool_base import ToolSubprocess
- return ToolSubprocess.execute_command_return(command, format=format, force_log=force_log)
- """
- try:
- logger.debug('execute_command_return : %s', ' '.join(command))
-
- if app.config['config']['running_type'] == 'windows':
- command = ' '.join(command)
-
- process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, encoding='utf8')
- ret = []
- with process.stdout:
- for line in iter(process.stdout.readline, ''):
- ret.append(line.strip())
- if force_log:
- logger.debug(ret[-1])
- process.wait() # wait for the subprocess to exit
-
-
- if format is None:
- ret2 = '\n'.join(ret)
- elif format == 'json':
- try:
- index = 0
- for idx, tmp in enumerate(ret):
- #logger.debug(tmp)
- if tmp.startswith('{') or tmp.startswith('['):
- index = idx
- break
- ret2 = json.loads(''.join(ret[index:]))
- except:
- ret2 = None
-
- return ret2
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- logger.error('command : %s', command)
- """
-
\ No newline at end of file
diff --git a/lib/system/logic_command2.py b/lib/system/logic_command2.py
deleted file mode 100644
index e8033b3..0000000
--- a/lib/system/logic_command2.py
+++ /dev/null
@@ -1,209 +0,0 @@
-# -*- coding: utf-8 -*-
-#########################################################
-# python
-import os
-import traceback
-import logging
-import platform
-import subprocess
-import threading
-import sys
-import io
-import time
-import json
-import queue
-# third-party
-
-# sjva 공용
-
-from framework import path_app_root, socketio, logger, app
-
-# 패키지
-
-# 로그
-package_name = __name__.split('.')[0]
-#logger = get_logger(package_name)
-#########################################################
-
-class SystemLogicCommand2(object):
- instance_list = []
-
- def __init__(self, title, commands, clear=True, wait=False, show_modal=True):
- self.title = title
- self.commands = commands
- self.clear = clear
- self.wait = wait
- self.show_modal = show_modal
-
- self.process = None
- self.stdout_queue = None
- self.thread = None
- self.send_to_ui_thread = None
- self.return_log = []
- SystemLogicCommand2.instance_list.append(self)
-
-
- def start(self):
- try:
- if self.show_modal:
- if self.clear:
- socketio.emit("command_modal_clear", None, namespace='/framework', broadcast=True)
-
- self.thread = threading.Thread(target=self.execute_thread_function, args=())
- self.thread.setDaemon(True)
- self.thread.start()
- if self.wait:
- time.sleep(1)
- self.thread.join()
- return self.return_log
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
-
- def execute_thread_function(self):
- try:
- #if wait:
- if self.show_modal:
- socketio.emit("command_modal_show", self.title, namespace='/framework', broadcast=True)
- socketio.emit("loading_hide", None, namespace='/framework', broadcast=True)
-
- for command in self.commands:
- if command[0] == 'msg':
- if self.show_modal:
- socketio.emit("command_modal_add_text", '%s\n\n' % command[1], namespace='/framework', broadcast=True)
- elif command[0] == 'system':
- if self.show_modal:
- socketio.emit("command_modal_add_text", '$ %s\n\n' % command[1], namespace='/framework', broadcast=True)
- os.system(command[1])
- else:
- show_command = True
- if command[0] == 'hide':
- show_command = False
- command = command[1:]
- #self.process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, bufsize=1)
- self.process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, encoding='utf8')
- self.start_communicate(command, show_command=show_command)
- self.send_queue_start()
- if self.process is not None:
- self.process.wait()
- time.sleep(1)
- except Exception as exception:
- if self.show_modal:
- socketio.emit("command_modal_show", self.title, namespace='/framework', broadcast=True)
- socketio.emit("command_modal_add_text", str(exception), namespace='/framework', broadcast=True)
- socketio.emit("command_modal_add_text", str(traceback.format_exc()), namespace='/framework', broadcast=True)
-
-
- def start_communicate(self, current_command, show_command=True):
- self.stdout_queue = queue.Queue()
- if show_command:
- self.stdout_queue.put('$ %s\n' % ' '.join(current_command))
- sout = io.open(self.process.stdout.fileno(), 'rb', closefd=False)
- #serr = io.open(process.stderr.fileno(), 'rb', closefd=False)
-
- def Pump(stream):
- queue = queue.Queue()
-
- def rdr():
- #logger.debug('START RDR')
- while True:
- buf = self.process.stdout.read(1)
- if buf:
- queue.put( buf )
- else:
- queue.put( None )
- break
- #logger.debug('END RDR')
- queue.put( None )
- time.sleep(1)
-
- #Logic.command_close()
- def clct():
- active = True
- #logger.debug('START clct')
- while active:
- r = queue.get()
- if r is None:
- break
- try:
- while True:
- r1 = queue.get(timeout=0.005)
- if r1 is None:
- active = False
- break
- else:
- r += r1
- except:
- pass
- if r is not None:
- if app.config['config']['is_py2']:
- try:
- r = r.decode('utf-8')
- except Exception as exception:
- #logger.error('Exception:%s', e)
- #logger.error(traceback.format_exc())
- try:
- r = r.decode('cp949')
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- try:
- r = r.decode('euc-kr')
- except:
- pass
-
- self.stdout_queue.put(r)
- self.return_log += r.split('\n')
- #logger.debug('IN:%s', r)
- self.stdout_queue.put('')
- #logger.debug('END clct')
- #Logic.command_close()
- for tgt in [rdr, clct]:
- th = threading.Thread(target=tgt)
- th.setDaemon(True)
- th.start()
- Pump(sout)
- #Pump(serr, 'stderr')
-
- def send_queue_start(self):
- def send_to_ui_thread_function():
- #logger.debug('send_queue_thread_function START')
- if self.show_modal:
- socketio.emit("command_modal_show", self.title, namespace='/framework', broadcast=True)
- while self.stdout_queue:
- line = self.stdout_queue.get()
- #logger.debug('Send to UI :%s', line)
- if line == '':
- if self.show_modal:
- socketio.emit("command_modal_add_text", "\n", namespace='/framework', broadcast=True)
- break
- else:
- if self.show_modal:
- socketio.emit("command_modal_add_text", line, namespace='/framework', broadcast=True)
- self.send_to_ui_thread = None
- self.stdout_queue = None
- self.process = None
- #logger.debug('send_to_ui_thread_function END')
-
- if self.send_to_ui_thread is None:
- self.send_to_ui_thread = threading.Thread(target=send_to_ui_thread_function, args=())
- self.send_to_ui_thread.start()
-
-
- @classmethod
- def plugin_unload(cls):
- for instance in cls.instance_list:
- try:
- if instance.process is not None and instance.process.poll() is None:
- import psutil
- process = psutil.Process(instance.process.pid)
- for proc in instance.process.children(recursive=True):
- proc.kill()
- instance.process.kill()
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- finally:
- try: instance.process.kill()
- except: pass
\ No newline at end of file
diff --git a/lib/system/logic_env.py b/lib/system/logic_env.py
deleted file mode 100644
index 16877a6..0000000
--- a/lib/system/logic_env.py
+++ /dev/null
@@ -1,130 +0,0 @@
-# -*- coding: utf-8 -*-
-#########################################################
-# python
-import logging
-import os
-import platform
-import threading
-import time
-import traceback
-
-# third-party
-from flask import (Blueprint, Response, jsonify, redirect, render_template,
- request, send_file)
-from framework import F, app, celery, path_app_root, path_data
-
-from .model import ModelSetting
-# 패키지
-from .plugin import logger, package_name
-
-# sjva 공용
-
-
-
-class SystemLogicEnv(object):
- @staticmethod
- def load_export():
- try:
- from support import SupportFile
- f = os.path.join(path_app_root, 'export.sh')
- if os.path.exists(f):
- return SupportFile.read_file(f)
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
- @staticmethod
- def process_ajax(sub, req):
- ret = False
- try:
- if sub == 'setting_save':
- data = req.form['export']
- #logger.debug(data)
- data = data.replace("\r\n", "\n" ).replace( "\r", "\n" )
- ret = False
- if platform.system() != 'Windows':
- f = os.path.join(path_app_root, 'export.sh')
- with open(f, 'w') as f:
- f.write(data)
- #os.system("dos2unix export.sh")
- ret = True
- elif sub == 'ps':
- def func():
- import system
- commands = [
- ['msg', u'잠시만 기다려주세요.'],
- ['ps', '-ef'],
- ['top', '-n1']
- ]
- #commands.append(['msg', u'설치가 완료되었습니다.'])
- system.SystemLogicCommand.start('ps', commands)
- t = threading.Thread(target=func, args=())
- t.setDaemon(True)
- t.start()
- elif sub == 'celery_test':
- ret = SystemLogicEnv.celery_test()
- elif sub == 'worker_start':
- os.system('sh worker_start.sh &')
- """
- def func():
- import system
- commands = [
- ['msg', u'잠시만 기다려주세요.'],
- ['sh', 'worker_start.sh'],
- ]
- #commands.append(['msg', u'설치가 완료되었습니다.'])
- system.SystemLogicCommand.start('ps', commands)
- t = threading.Thread(target=func, args=())
- t.setDaemon(True)
- t.start()
- """
- ret = True
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- return jsonify(ret)
-
-
-
- @staticmethod
- def celery_test():
- if F.config['use_celery']:
- from celery import Celery
- from celery.exceptions import NotRegistered, TimeoutError
-
- data = {}
- try:
- result = SystemLogicEnv.celery_test2.apply_async()
- logger.debug(result)
- try:
- tmp = result.get(timeout=5, propagate=True)
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- #result = SystemLogicEnv.celery_test2.delay()
- data['ret'] = 'success'
- data['data'] = tmp
- except TimeoutError:
- data['ret'] = 'timeout'
- data['data'] = u'celery가 동작중이 아니거나 모든 프로세스가 작업중입니다.'
- except NotRegistered:
- data['ret'] = 'not_registered'
- data['data'] = u'Not Registered'
- #logger.debug(data)
- else:
- data['ret'] = 'no_celery'
- data['data'] = u'celery 실행환경이 아닙니다.'
- return data
-
- @staticmethod
- @celery.task
- def celery_test2():
- try:
- logger.debug('!!!! celery_test2222')
- import time
- time.sleep(1)
- data = u'정상입니다. 이 메시지는 celery 에서 반환됩니다. '
- return data
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
diff --git a/lib/system/logic_notify.py b/lib/system/logic_notify.py
deleted file mode 100644
index 23727a0..0000000
--- a/lib/system/logic_notify.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# -*- coding: utf-8 -*-
-#########################################################
-# python
-import os
-import traceback
-import logging
-import platform
-import time
-
-# third-party
-from flask import Blueprint, request, Response, send_file, render_template, redirect, jsonify
-
-
-# sjva 공용
-
-from framework import path_app_root, path_data
-from tool_base import ToolBaseNotify
-# 패키지
-from .plugin import logger, package_name
-from .model import ModelSetting
-
-
-class SystemLogicNotify(object):
- @staticmethod
- def process_ajax(sub, req):
- try:
- if sub == 'telegram_test':
- ret = ToolBaseNotify.send_telegram_message(req.form['text'], bot_token=req.form['bot_token'], chat_id=req.form['chat_id'])
- return jsonify(ret)
- elif sub == 'discord_test':
- ret = ToolBaseNotify.send_discord_message(req.form['text'], webhook_url=req.form['url'])
- return jsonify(ret)
- elif sub == 'advanced_test':
- ret = ToolBaseNotify.send_advanced_message(req.form['text'], policy=req.form['policy'], message_id=req.form['message_id'])
- return jsonify(ret)
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- return jsonify('exception')
-
diff --git a/lib/system/logic_plugin.py b/lib/system/logic_plugin.py
deleted file mode 100644
index d0f1231..0000000
--- a/lib/system/logic_plugin.py
+++ /dev/null
@@ -1,290 +0,0 @@
-# -*- coding: utf-8 -*-
-#########################################################
-# python
-import json
-import logging
-import os
-import platform
-import time
-import traceback
-import zipfile
-
-# third-party
-import requests
-# sjva 공용
-from framework import app, frame, logger, path_data
-from framework.util import Util
-from support import SupportProcess
-
-import system
-
-# 패키지
-from .model import ModelSetting
-
-
-class LogicPlugin(object):
- plugin_loading = False
-
-
-
- current_loading_plugin_list = {}
-
- """
- custom_plugin_list = []
- @staticmethod
- def loading():
- try:
- custom_path = os.path.join(path_data, 'custom')
- plugin_list = os.listdir(custom_path)
- logger.debug(plugin_list)
- for name in plugin_list:
- try:
- p = {}
- p['name'] = name
- p['plugin_name'] = name
- mod = __import__('%s' % (p['plugin_name']), fromlist=[])
- p['local_info'] = getattr(mod, 'plugin_info')
- p['status'] = 'latest'
- LogicPlugin.custom_plugin_list.append(p)
- except Exception as exception:
- logger.error('NO Exception:%s', exception)
- logger.debug('plunin not import : %s', p['plugin_name'])
- p['local_info'] = None
- p['status'] = 'no'
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- """
-
- @staticmethod
- def get_plugin_list():
- return LogicPlugin.current_loading_plugin_list
- """
- try:
- if not LogicPlugin.plugin_loading:
- LogicPlugin.loading()
- LogicPlugin.plugin_loading = True
- return LogicPlugin.custom_plugin_list
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- """
-
-
- @staticmethod
- def get_plugin_info(plugin_name):
- try:
- lists = LogicPlugin.get_plugin_list()
- for key, value in lists.items():
- if key == plugin_name:
- return value['info']
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
-
- """
- @staticmethod
- def plugin_install(plugin_name):
- logger.debug('plugin_name : %s', plugin_name)
- try:
- plugin_info = LogicPlugin.get_plugin_info(plugin_name)
-
- custom_path = os.path.join(path_data, 'custom')
-
- if 'platform' in plugin_info:
- if platform.system() not in plugin_info['platform']:
- return 'not_support_os'
- if 'running_type' in plugin_info:
- if app.config['config']['running_type'] not in plugin_info['running_type']:
- return 'not_support_running_type'
- git_clone_flag = True
- if git_clone_flag:
- # git clone
- command = ['git', '-C', custom_path, 'clone', plugin_info['git'], '--depth', '1']
- ret = Util.execute_command(command)
- return 'success'
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- """
-
- @staticmethod
- def plugin_uninstall(plugin_name):
- logger.debug('plugin_name : %s', plugin_name)
- try:
- mod = __import__('%s' % (plugin_name), fromlist=[])
- mod_plugin_unload = getattr(mod, 'plugin_unload')
- mod_plugin_unload()
- time.sleep(1)
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- try:
- custom_path = os.path.join(path_data, 'custom')
- plugin_path = os.path.join(custom_path, plugin_name)
- if os.path.exists(plugin_path):
- try:
- import framework.common.celery as celery_task
- celery_task.rmtree(plugin_path)
- except Exception as exception:
- try:
- logger.debug('plugin_uninstall')
- os.system('rmdir /S /Q "%s"' % plugin_path)
- except:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- if os.path.exists(plugin_path):
- return 'fail'
- else:
- return 'success'
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
-
- @staticmethod
- def custom_plugin_update():
- try:
- if os.environ.get('UPDATE_STOP') == 'true':
- return
- if os.environ.get('PLUGIN_UPDATE_FROM_PYTHON') == 'false':
- return
- if frame.config['debug'] == True:
- return
- if frame.config.get('plugin_update', True) != True:
- return
-
- custom_path = os.path.join(path_data, 'plugins')
- tmps = os.listdir(custom_path)
- for t in tmps:
- plugin_path = os.path.join(custom_path, t)
- try:
- if t == 'torrent_info':
- os.remove(os.path.join(plugin_path, 'info.json'))
- except:
- pass
- if t.startswith('_'):
- continue
- if os.path.exists(os.path.join(plugin_path, '.git')):
- command = ['git', '-C', plugin_path, 'reset', '--hard', 'HEAD']
- ret = SupportProcess.execute(command)
- command = ['git', '-C', plugin_path, 'pull']
- ret = SupportProcess.execute(command)
- logger.debug("%s\n%s", plugin_path, ret)
- else:
- logger.debug(f"plugin_path is not git repo")
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
-
- @staticmethod
- def plugin_install_by_api(plugin_git, zip_url, zip_filename):
- logger.debug('plugin_git : %s', plugin_git)
- logger.debug('zip_url : %s', zip_url)
- logger.debug('zip_filename : %s', zip_filename)
-
- is_git = True if plugin_git != None and plugin_git != '' else False
- ret = {}
- try:
- if is_git:
- name = plugin_git.split('/')[-1]
- else:
- name = zip_filename.split('.')[0]
-
- custom_path = os.path.join(path_data, 'custom')
- plugin_path = os.path.join(custom_path, name)
- logger.debug(plugin_path)
- plugin_info = None
- if os.path.exists(plugin_path):
- ret['ret'] = 'already_exist'
- ret['log'] = '이미 설치되어 있습니다.'
- else:
- if plugin_git and plugin_git.startswith('http'):
- for tag in ['main', 'master']:
- try:
- info_url = plugin_git.replace('github.com', 'raw.githubusercontent.com') + '/%s/info.json' % tag
- plugin_info = requests.get(info_url).json()
- if plugin_info is not None:
- break
- except:
- pass
- if zip_filename and zip_filename != '':
- import zipfile
-
- from tool_base import ToolBaseFile
- zip_filepath = os.path.join(path_data, 'tmp', zip_filename)
- extract_filepath = os.path.join(path_data, 'tmp', name)
- logger.error(zip_url)
- logger.warning(zip_filepath)
- if ToolBaseFile.download(zip_url, zip_filepath):
- #logger.warning(os.path.exists(zip_filepath))
- with zipfile.ZipFile(zip_filepath, 'r') as zip_ref:
- zip_ref.extractall(extract_filepath)
- plugin_info_filepath = os.path.join(extract_filepath, 'info.json')
- if os.path.exists(plugin_info_filepath):
- plugin_info = ToolBaseFile.read_json(plugin_info_filepath)
- if plugin_info == None:
- plugin_info = {}
- flag = True
- if 'platform' in plugin_info:
- if platform.system() not in plugin_info['platform']:
- ret['ret'] = 'not_support_os'
- ret['log'] = '설치 가능한 OS가 아닙니다.'
- flag = False
- if flag and 'running_type' in plugin_info:
- if app.config['config']['running_type'] not in plugin_info['running_type']:
- ret['ret'] = 'not_support_running_type'
- ret['log'] = '설치 가능한 실행타입이 아닙니다.'
- flag = False
- if flag and 'policy_level' in plugin_info:
- if plugin_info['policy_level'] > app.config['config']['level']:
- ret['ret'] = 'policy_level'
- ret['log'] = '설치 가능 회원등급보다 낮습니다.'
- flag = False
- if flag and 'policy_point' in plugin_info:
- if plugin_info['policy_level'] > app.config['config']['point']:
- ret['ret'] = 'policy_level'
- ret['log'] = '설치 가능 포인트보다 낮습니다.'
- flag = False
-
- if flag:
- if plugin_git and plugin_git.startswith('http'):
- command = ['git', '-C', custom_path, 'clone', plugin_git + '.git', '--depth', '1']
- log = Util.execute_command(command)
- if zip_filename and zip_filename != '':
- import shutil
- if os.path.exists(plugin_path) == False:
- shutil.move(extract_filepath, plugin_path)
- else:
- for tmp in os.listdir(extract_filepath):
- shutil.move(os.path.join(extract_filepath, tmp), plugin_path)
- log = ''
- logger.debug(plugin_info)
- # 2021-12-31
- if 'dependency' in plugin_info:
- for dep in plugin_info['dependency']:
- for key, value in LogicPlugin.get_plugin_list().items():
- if key == dep['name']:
- logger.debug(f"Dependency 설치 - 이미 설치됨 : {dep['name']}")
- break
- else:
- logger.debug(f"Dependency 설치 : {dep['home']}")
- LogicPlugin.plugin_install_by_api(dep['home'], dep.get('zip_url'), dep.get('zip_filename'))
- #command = ['git', '-C', custom_path, 'clone', dep['home'], '--depth', '1']
- #ret = Util.execute_command(command)
- ret['ret'] = 'success'
- ret['log'] = [u'정상적으로 설치하였습니다. 재시작시 적용됩니다.', log]
- ret['log'] = '
'.join(ret['log'])
-
-
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- ret['ret'] = 'exception'
- ret['log'] = str(exception)
-
-
- return ret
-
\ No newline at end of file
diff --git a/lib/system/logic_selenium.py b/lib/system/logic_selenium.py
deleted file mode 100644
index 4472a42..0000000
--- a/lib/system/logic_selenium.py
+++ /dev/null
@@ -1,397 +0,0 @@
-# -*- coding: utf-8 -*-
-#########################################################
-# python
-import os
-import traceback
-import logging
-import platform
-import time
-import base64
-
-# third-party
-from flask import Blueprint, request, Response, send_file, render_template, redirect, jsonify
-
-try:
- from selenium import webdriver
- from selenium.webdriver.support.ui import WebDriverWait
- from PIL import Image
- Image.MAX_IMAGE_PIXELS = None
-except:
- pass
-from io import BytesIO
-
-# sjva 공용
-
-from framework import path_app_root, path_data
-
-# 패키지
-from .plugin import logger, package_name
-from .model import ModelSetting
-
-#########################################################
-#apk --no-cache add --repository http://dl-cdn.alpinelinux.org/alpine/edge/testing firefox
-#https://github.com/mozilla/geckodriver/releases/download/v0.26.0/geckodriver-v0.26.0-linux64.tar.gz
-#curl -s -L "$url" | tar -xz
-
-class SystemLogicSelenium(object):
- chrome_driver = None
- chrome_driver_list = []
-
- @staticmethod
- def process_ajax(sub, req):
- try:
- if sub == 'selenium_test_go':
- driver = SystemLogicSelenium.get_driver()
- driver.get(req.form['url'])
- return jsonify('success')
- elif sub == 'capture':
- driver = SystemLogicSelenium.get_driver()
- img = Image.open(BytesIO((driver.get_screenshot_as_png())))
-
- timestamp = time.time()
- timestamp = str(timestamp).split('.')[0]
- tmp = os.path.join(path_data, 'tmp', '%s.png' % timestamp)
- img.save(tmp)
- from system.model import ModelSetting as SystemModelSetting
- ddns = SystemModelSetting.get('ddns')
- url = '%s/open_file%s' % (ddns, tmp)
- logger.debug(url)
- ret = {}
- ret['ret'] = 'success'
- ret['data'] = url
- return jsonify(ret)
- elif sub == 'full_capture':
- driver = SystemLogicSelenium.get_driver()
- img = SystemLogicSelenium.full_screenshot(driver)
-
- timestamp = time.time()
- timestamp = str(timestamp).split('.')[0]
- tmp = os.path.join(path_data, 'tmp', '%s.png' % timestamp)
- img.save(tmp)
- return send_file(tmp, mimetype='image/png')
- elif sub == 'cookie':
- driver = SystemLogicSelenium.get_driver()
- data = driver.get_cookies()
- return jsonify(data)
- elif sub == 'daum_capcha':
- daum_capcha = req.form['daum_capcha']
- driver = SystemLogicSelenium.get_driver()
- #driver.find_element_by_xpath('//div[@class="secret_viewer"]/p/img').screenshot("captcha.png")
- driver.find_element_by_xpath('//input[@id="answer"]').send_keys(daum_capcha)
- driver.find_element_by_xpath('//input[@value="%s"]' % u'확인').click()
- return jsonify({'ret':'success'})
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- return jsonify('exception')
-
- @staticmethod
- def get_pagesoruce_by_selenium(url, wait_xpath, retry=True):
- try:
- logger.debug('get_pagesoruce_by_selenium:%s %s', url, wait_xpath)
- driver = SystemLogicSelenium.get_driver()
- #logger.debug('driver : %s', driver)
- driver.get(url)
-
- WebDriverWait(driver, 10).until(lambda driver: driver.find_element_by_xpath(wait_xpath))
- #import time
- #driver.save_screenshot('%s.png' % time.time())
- #logger.debug('return page_source')
- return driver.page_source
- except Exception as exception:
- #logger.debug(driver.page_source)
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- SystemLogicSelenium.close_driver()
- #SystemLogicSelenium.chrome_driver = None
- if retry:
- return SystemLogicSelenium.get_pagesoruce_by_selenium(url, wait_xpath, retry=False)
-
- # 1회성
- @staticmethod
- def get_driver(chrome_options=None):
- try:
- if SystemLogicSelenium.chrome_driver is None:
- SystemLogicSelenium.chrome_driver = SystemLogicSelenium.inner_create_driver(chrome_options)
- return SystemLogicSelenium.chrome_driver
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
- # 플러그인이 점유
- @staticmethod
- def create_driver(chrome_options=None):
- try:
- driver = SystemLogicSelenium.inner_create_driver(chrome_options)
- if driver is not None:
- SystemLogicSelenium.chrome_driver_list.append(driver)
- return driver
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
- @staticmethod
- def close_driver():
- try:
- #if SystemLogicSelenium.chrome_driver is not None:
- # SystemLogicSelenium.chrome_driver.quit()
- # SystemLogicSelenium.chrome_driver = None
- if SystemLogicSelenium.chrome_driver is not None:
- try: SystemLogicSelenium.chrome_driver.close()
- except: pass
- time.sleep(2)
- try: SystemLogicSelenium.chrome_driver.quit()
- except: pass
- SystemLogicSelenium.chrome_driver = None
-
-
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
-
- @staticmethod
- def inner_create_driver(chrome_options):
- try:
- driver = None
- remote_url = ModelSetting.get('selenium_remote_url')
- if remote_url.endswith('/wd/hub/'):
- remote_url = remote_url[:-1]
- if remote_url != '':
- if chrome_options is None:
- chrome_options = webdriver.ChromeOptions()
- tmp = ModelSetting.get_list('selenium_remote_default_option')
- for t in tmp:
- chrome_options.add_argument(t)
- driver = webdriver.Remote(command_executor=remote_url, desired_capabilities=chrome_options.to_capabilities())
- driver.set_window_size(1920, 1080)
- logger.debug('Using Remote :%s', driver)
- else:
- path_chrome = os.path.join(path_app_root, 'bin', platform.system(), 'chromedriver')
- if platform.system() == 'Windows':
- path_chrome += '.exe'
- if chrome_options is None:
- chrome_options = webdriver.ChromeOptions()
- tmp = ModelSetting.get_list('selenium_binary_default_option')
- for t in tmp:
- chrome_options.add_argument(t)
- driver = webdriver.Chrome(path_chrome, chrome_options=chrome_options)
- logger.debug('Using local bin :%s', driver)
- if driver is not None:
- return driver
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
-
- @staticmethod
- def plugin_unload():
- try:
- SystemLogicSelenium.close_driver()
- #logger.debug(SystemLogicSelenium.chrome_driver)
- #if SystemLogicSelenium.chrome_driver is not None:
- # SystemLogicSelenium.chrome_driver.quit()
- # logger.debug(SystemLogicSelenium.chrome_driver)
-
- for tmp in SystemLogicSelenium.chrome_driver_list:
- if tmp is not None:
- tmp.quit()
-
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
- @staticmethod
- def get_text_excluding_children(driver, element):
- return driver.execute_script("""
- return jQuery(arguments[0]).contents().filter(function() {
- return this.nodeType == Node.TEXT_NODE;
- }).text();
- """, element)
-
- @staticmethod
- def full_screenshot(driver, low_offset = 0):
- try:
- # initiate value
- #save_path = save_path + '.png' if save_path[-4::] != '.png' else save_path
- img_li = [] # to store image fragment
- offset = 0 # where to start
-
- # js to get height
- height = driver.execute_script('return Math.max('
- 'document.documentElement.clientHeight, window.innerHeight);')
- #height = height - low_offset
- # js to get the maximum scroll height
- # Ref--> https://stackoverflow.com/questions/17688595/finding-the-maximum-scroll-position-of-a-page
- max_window_height = driver.execute_script('return Math.max('
- 'document.body.scrollHeight, '
- 'document.body.offsetHeight, '
- 'document.documentElement.clientHeight, '
- 'document.documentElement.scrollHeight, '
- 'document.documentElement.offsetHeight);')
-
- # looping from top to bottom, append to img list
- # Ref--> https://gist.github.com/fabtho/13e4a2e7cfbfde671b8fa81bbe9359fb
-
- while offset < max_window_height:
-
- # Scroll to height
- driver.execute_script("""
- window.scrollTo(0, arguments[0]);
- """, offset)
- img = Image.open(BytesIO((driver.get_screenshot_as_png())))
-
- if low_offset != 0:
- img = img.crop((0, 0, img.width, img.height-low_offset)) # defines crop points
-
- img_li.append(img)
- offset += height
- logger.debug('offset : %s / %s', offset, max_window_height)
-
- # Stitch image into one
- # Set up the full screen frame
- img_frame_height = sum([img_frag.size[1] for img_frag in img_li])
- img_frame = Image.new('RGB', (img_li[0].size[0], img_frame_height))
- offset = 0
- for img_frag in img_li:
- img_frame.paste(img_frag, (0, offset))
- offset += img_frag.size[1]
- logger.debug('paste offset : %s ', offset)
- #img_frame.save(save_path)
- #return
- return img_frame
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
- @staticmethod
- def remove_element(driver, element):
- driver.execute_script("""
- var element = arguments[0];
- element.parentNode.removeChild(element);
- """, element)
-
-
-
- ######################################################################
- @staticmethod
- def __get_downloaded_files(driver=None):
- if driver is None:
- driver = SystemLogicSelenium.get_driver()
- if not driver.current_url.startswith("chrome://downloads"):
- driver.get("chrome://downloads/")
- #driver.implicitly_wait(4)
- return driver.execute_script( \
- "return downloads.Manager.get().items_ "
- " .filter(e => e.state === 'COMPLETE') "
- " .map(e => e.filePath || e.file_path); " )
-
-
-
- @staticmethod
- def get_file_content(path, driver=None):
- if driver is None:
- driver = SystemLogicSelenium.get_driver()
-
- elem = driver.execute_script( \
- "var input = window.document.createElement('INPUT'); "
- "input.setAttribute('type', 'file'); "
- "input.hidden = true; "
- "input.onchange = function (e) { e.stopPropagation() }; "
- "return window.document.documentElement.appendChild(input); " )
-
- elem._execute('sendKeysToElement', {'value': [ path ], 'text': path})
-
- result = driver.execute_async_script( \
- "var input = arguments[0], callback = arguments[1]; "
- "var reader = new FileReader(); "
- "reader.onload = function (ev) { callback(reader.result) }; "
- "reader.onerror = function (ex) { callback(ex.message) }; "
- "reader.readAsDataURL(input.files[0]); "
- "input.remove(); "
- , elem)
-
- if not result.startswith('data:') :
- raise Exception("Failed to get file content: %s" % result)
-
- return base64.b64decode(result[result.find('base64,') + 7:])
-
-
- @staticmethod
- def get_downloaded_files(driver=None):
- if driver is None:
- driver = SystemLogicSelenium.get_driver()
-
- #files = WebDriverWait(driver, 20, 1).until(SystemLogicSelenium.__get_downloaded_files)
- files = SystemLogicSelenium.__get_downloaded_files()
- return files
-
- @staticmethod
- def waitUntilDownloadCompleted(maxTime=600, driver=None):
- if driver is None:
- driver = SystemLogicSelenium.get_driver()
- driver.execute_script("window.open()")
- # switch to new tab
- driver.switch_to.window(driver.window_handles[-1])
- # navigate to chrome downloads
- driver.get('chrome://downloads')
- # define the endTime
- endTime = time.time() + maxTime
- while True:
- try:
- # get the download percentage
- downloadPercentage = driver.execute_script(
- "return document.querySelector('downloads-manager').shadowRoot.querySelector('#downloadsList downloads-item').shadowRoot.querySelector('#progress').value")
- # check if downloadPercentage is 100 (otherwise the script will keep waiting)
- if downloadPercentage == 100:
- # exit the method once it's completed
- return downloadPercentage
- except:
- pass
- # wait for 1 second before checking the percentage next time
- time.sleep(1)
- # exit method if the download not completed with in MaxTime.
- if time.time() > endTime:
- break
-
-"""
-
-
-driver = webdriver.Chrome(desired_capabilities=capabilities_chrome)
-#driver = webdriver.Remote('http://127.0.0.1:5555/wd/hub', capabilities_chrome)
-
-# download a pdf file
-driver.get("https://www.mozilla.org/en-US/foundation/documents")
-driver.find_element_by_css_selector("[href$='.pdf']").click()
-
-# list all the completed remote files (waits for at least one)
-files = WebDriverWait(driver, 20, 1).until(get_downloaded_files)
-
-# get the content of the first file remotely
-content = get_file_content(driver, files[0])
-
-# save the content in a local file in the working directory
-with open(os.path.basename(files[0]), 'wb') as f:
- f.write(content)
-
-
-capabilities_chrome = { \
- 'browserName': 'chrome',
- # 'proxy': { \
- # 'proxyType': 'manual',
- # 'sslProxy': '50.59.162.78:8088',
- # 'httpProxy': '50.59.162.78:8088'
- # },
- 'goog:chromeOptions': { \
- 'args': [
- ],
- 'prefs': { \
- # 'download.default_directory': "",
- # 'download.directory_upgrade': True,
- 'download.prompt_for_download': False,
- 'plugins.always_open_pdf_externally': True,
- 'safebrowsing_for_trusted_sources_enabled': False
- }
- }
- }
-"""
\ No newline at end of file
diff --git a/lib/system/logic_site.py b/lib/system/logic_site.py
deleted file mode 100644
index bd30b3a..0000000
--- a/lib/system/logic_site.py
+++ /dev/null
@@ -1,233 +0,0 @@
-# -*- coding: utf-8 -*-
-#########################################################
-# python
-import os
-import traceback
-import logging
-import platform
-import time
-
-# third-party
-from flask import Blueprint, request, Response, send_file, render_template, redirect, jsonify
-
-
-
-from framework import F, path_app_root, path_data, socketio, scheduler
-from tool_base import d
-
-
-# 패키지
-from .plugin import logger, package_name
-from .model import ModelSetting
-
-
-class SystemLogicSite(object):
- # 매번 split 하기 머해서
- daum_cookie = None
-
- @staticmethod
- def process_ajax(sub, req):
- try:
- ret = {}
- if sub == 'site_daum_test':
- site_daum_test = req.form['site_daum_test']
- ModelSetting.set('site_daum_test', site_daum_test)
- from framework.common.daum import DaumTV, MovieSearch
- ret['TV'] = DaumTV.get_daum_tv_info(site_daum_test)
- if ret['TV'] is not None and 'episode_list' in ret['TV']:
- del ret['TV']['episode_list']
- ret['MOVIE'] = MovieSearch.search_movie(site_daum_test, -1)
- return jsonify(ret)
- elif sub == 'site_daum_cookie_refresh':
- ret = SystemLogicSite.get_daum_cookie_by_selenium(notify=True)
- return jsonify(ret)
- elif sub == 'scheduler':
- go = req.form['scheduler']
- if go == 'true':
- SystemLogicSite.scheduler_start()
- else:
- SystemLogicSite.scheduler_stop()
- return jsonify(go)
- elif sub == 'tving_login':
- try:
- from support.site.tving import SupportTving
- token = SupportTving().do_login(req.form['tving_id'], req.form['tving_pw'], req.form['tving_login_type'])
- if token is None:
- ret['ret'] = False
- else:
- ret['ret'] = True
- ret['token'] = token
- return jsonify(ret)
- except Exception as e:
- logger.error('Exception:%s', e)
- logger.error(traceback.format_exc())
- elif sub == 'tving_deviceid':
- try:
- from support.site.tving import SupportTving
- device_list = SupportTving(token=req.form['tving_token']).get_device_list()
- if device_list is None:
- ret['ret'] = False
- else:
- ret['ret'] = True
- ret['device_list'] = device_list
- return jsonify(ret)
- except Exception as e:
- logger.error('Exception:%s', e)
- logger.error(traceback.format_exc())
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- ret['ret'] = False
- ret['log'] = str(traceback.format_exc())
- return jsonify(ret)
-
- @staticmethod
- def process_api(sub, req):
- ret = {}
- try:
- if sub == 'daum_cookie':
- return ModelSetting.get('site_daum_cookie')
-
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- ret['ret'] = 'exception'
- ret['data'] = str(exception)
- return jsonify(ret)
- ##########################################################################
-
- @staticmethod
- def plugin_load():
- SystemLogicSite.create_tving_instance()
- return
- SystemLogicSite.get_daum_cookies(force=True)
- if ModelSetting.get_bool('site_daum_auto_start'):
- SystemLogicSite.scheduler_start()
-
- @staticmethod
- def create_tving_instance():
- from support.site.tving import SupportTving
- proxy = None
- if ModelSetting.get_bool('site_tving_use_proxy'):
- proxy = ModelSetting.get('site_tving_proxy_url')
- SupportTving.ins = SupportTving(token=ModelSetting.get('site_tving_token'), proxy=proxy, deviceid=ModelSetting.get('site_tving_deviceid'), uuid=ModelSetting.get('site_tving_uuid'))
-
-
-
- @staticmethod
- def scheduler_start():
- job = Job(package_name, '%s_site' % package_name, ModelSetting.get('site_daum_interval'), SystemLogicSite.scheduler_function, u"Daum cookie refresh", False)
- scheduler.add_job_instance(job)
-
- @staticmethod
- def scheduler_stop():
- scheduler.remove_job('%s_site' % package_name)
-
-
- @staticmethod
- def scheduler_function():
- try:
- data = SystemLogicSite.get_daum_cookie_by_selenium()
- if data['ret']:
- ModelSetting.set('site_daum_cookie', data['data'])
- SystemLogicSite.get_daum_cookies(force=True)
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
-
-
- @staticmethod
- def get_daum_cookie_by_selenium(notify=False):
- try:
- ret = {}
- ret['ret'] = False
- from .logic_selenium import SystemLogicSelenium
- if notify:
- data = {'type':'success', 'msg' : u'사이트 접속중입니다.'}
- socketio.emit("notify", data, namespace='/framework', broadcast=True)
- SystemLogicSelenium.get_pagesoruce_by_selenium('https://www.daum.net', '//*[@id="daumFoot"]/div/a[1]/img')
- if notify:
- data = {'type':'success', 'msg' : u'쿠키 확인'}
- socketio.emit("notify", data, namespace='/framework', broadcast=True)
- driver = SystemLogicSelenium.get_driver()
- cookies = driver.get_cookies()
- for tmp in cookies:
- if tmp['name'] == 'TIARA':
- ret['ret'] = True
- ret['data'] = 'TIARA=%s' % tmp['value']
- return ret
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- return ret
-
-
-
- @staticmethod
- def get_daum_cookies(force=False):
- try:
- if SystemLogicSite.daum_cookie is None or force:
- ret = {}
- tmp = ModelSetting.get('site_daum_cookie')
- tmps = tmp.split(';')
- for t in tmps:
- t2 = t.split('=')
- if len(t2) == 2:
- ret[t2[0]] = t2[1]
- SystemLogicSite.daum_cookie = ret
- return SystemLogicSite.daum_cookie
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- return {'TIARA':'gaXEIPluo-wWAFlwZN6l8gN3yzhkoo_piP.Kymhuy.6QBt4Q6.cRtxbKDaWpWajcyteRHzrlTVpJRxLjwLoMvyYLVi_7xJ1L'}
-
-
- daum_headers = {
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36',
- 'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
- 'Accept-Language' : 'ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7',
- }
-
- @classmethod
- def get_tree_daum(cls, url, post_data=None):
- from lxml import html
- from framework import SystemModelSetting
- text = cls.get_text_daum(url, post_data=post_data)
- if text is None:
- return
- return html.fromstring(text)
-
- @classmethod
- def get_text_daum(cls, url, post_data=None):
- from system.logic_site import SystemLogicSite
- from framework import SystemModelSetting
- res = cls.get_response(url, proxy_url=SystemModelSetting.get('site_daum_proxy'), headers=SystemLogicSite.daum_headers, post_data=post_data, cookies=SystemLogicSite.get_daum_cookies())
- return res.text
-
-
- @classmethod
- def get_response_daum(cls, url, post_data=None):
- from system.logic_site import SystemLogicSite
- from framework import SystemModelSetting
- res = cls.get_response(url, proxy_url=SystemModelSetting.get('site_daum_proxy'), headers=SystemLogicSite.daum_headers, post_data=post_data, cookies=SystemLogicSite.get_daum_cookies())
- return res
-
-
- @classmethod
- def get_response(cls, url, proxy_url=None, headers=None, post_data=None, cookies=None):
- import requests
- proxies = None
- if proxy_url is not None and proxy_url != '':
- proxies = {"http" : proxy_url, "https" : proxy_url}
- if headers is None:
- headers = SystemLogicSite.default_headers
- if post_data is None:
- #logger.warning(d(headers))
- #logger.warning(d(proxies))
- #logger.warning(d(cookies))
-
- res = requests.get(url, headers=headers, proxies=proxies, cookies=cookies)
- else:
- res = requests.post(url, headers=headers, proxies=proxies, data=post_data, cookies=cookies)
- return res
\ No newline at end of file
diff --git a/lib/system/logic_telegram_bot.py b/lib/system/logic_telegram_bot.py
deleted file mode 100644
index bdd4cf9..0000000
--- a/lib/system/logic_telegram_bot.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# -*- coding: utf-8 -*-
-#########################################################
-# python
-import os
-import traceback
-import logging
-import platform
-import time
-
-# third-party
-from flask import Blueprint, request, Response, send_file, render_template, redirect, jsonify
-
-
-
-from framework import F, frame, app, path_app_root, path_data, scheduler
-from tool_base import ToolBaseNotify
-# 패키지
-from .plugin import logger, package_name
-from .model import ModelSetting
-
-
-class SystemLogicTelegramBot(object):
- @staticmethod
- def process_ajax(sub, req):
- try:
- if sub == 'telegram_test':
- ret = ToolBaseNotify.send_telegram_message(req.form['text'], bot_token=req.form['bot_token'], chat_id=req.form['chat_id'])
- return jsonify(ret)
- elif sub == 'discord_test':
- ret = ToolBaseNotify.send_discord_message(req.form['text'], webhook_url=req.form['url'])
- return jsonify(ret)
- elif sub == 'advanced_test':
- ret = ToolBaseNotify.send_advanced_message(req.form['text'], policy=req.form['policy'], message_id=req.form['message_id'])
- return jsonify(ret)
- elif sub == 'scheduler':
- go = request.form['scheduler']
- logger.debug('scheduler :%s', go)
- if go == 'true':
- SystemLogicTelegramBot.scheduler_start()
- else:
- SystemLogicTelegramBot.scheduler_stop()
- return jsonify(go)
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- return jsonify('exception')
-
- @staticmethod
- def plugin_load():
- try:
- if frame.config['run_celery']:
- return
-
- if ModelSetting.get_bool('telegram_bot_auto_start'):
- SystemLogicTelegramBot.scheduler_start()
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
- @staticmethod
- def scheduler_start():
- try:
- interval = 60*24
- job = Job(package_name, '%s_telegram_bot' % (package_name), 9999, SystemLogicTelegramBot.scheduler_function, u"시스템 - 텔레그램 봇", False)
- scheduler.add_job_instance(job)
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
- @staticmethod
- def scheduler_function():
- try:
- bot_token = ModelSetting.get('telegram_bot_token')
- from framework.common.telegram_bot import TelegramBot
- TelegramBot.start(bot_token)
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
\ No newline at end of file
diff --git a/lib/system/logic_terminal.py b/lib/system/logic_terminal.py
deleted file mode 100644
index cdb1127..0000000
--- a/lib/system/logic_terminal.py
+++ /dev/null
@@ -1,62 +0,0 @@
-try:
- import yaml
- a = yaml.FullLoader
-except:
- from framework import app
- import os
- try: os.system(f"{app.config['config']['pip']} install --upgrade pyyaml")
- except: pass
-
-import os, sys, traceback, json
-from framework import path_data
-from flask import request, render_template, redirect, jsonify
-from .plugin import logger
-
-
-class SystemLogicTerminal(object):
- yaml_path = os.path.join(path_data, 'db', 'terminal.yaml')
-
- @classmethod
- def process_ajax(cls, sub, req):
- logger.error(sub)
- logger.error(req)
- try:
- if sub == 'get_info':
- ret = cls.get_info()
- elif sub == 'run':
- data = cls.get_info()
- idx = int(req.form['index'])
- from terminal.logic_terminal import LogicTerminal
- LogicTerminal.wait_input(data['commands'][idx]['command'])
- return jsonify({'ret':'success'})
- return jsonify(ret)
- except Exception as e:
- logger.error(f'Exception: {str(e)}')
- logger.error(traceback.format_exc())
-
- @classmethod
- def get_info(cls):
- if os.path.exists(cls.yaml_path) == False:
- with open(cls.yaml_path, 'w', encoding='utf8') as f:
- f.write(yaml_templete)
- with open(cls.yaml_path, 'r', encoding='utf8') as f:
- info = yaml.load(f, Loader=yaml.FullLoader)
- return info
-
-
-
-
-yaml_templete = '''
-
-commands:
- - title: SJVA 데이터 폴더별 크기 확인
- command: |
- cd ./data
- du -h -d 1
-
- - title: SJVA 도커 재시작
- command: |
- ssh -i MY.pem ubuntu@172.17.0.1
- sudo docker restart sjva
-
-'''
\ No newline at end of file
diff --git a/lib/system/logic_tool_crypt.py b/lib/system/logic_tool_crypt.py
deleted file mode 100644
index dac3b3a..0000000
--- a/lib/system/logic_tool_crypt.py
+++ /dev/null
@@ -1,52 +0,0 @@
-import traceback
-from flask import jsonify
-from framework import app
-
-# 패키지
-from .plugin import package_name, logger
-from .model import ModelSetting
-
-class SystemLogicToolDecrypt(object):
- @staticmethod
- def process_ajax(sub, req):
- try:
- if sub == 'crypt_test':
- ret = SystemLogicToolDecrypt.crypt_test(req)
- return jsonify(ret)
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
- ##########################################################################
-
- @staticmethod
- def crypt_test(req):
- try:
- mode = req.form['mode']
- word = req.form['word']
-
- logger.debug(mode)
- logger.debug(word)
- from tool_base import ToolAESCipher
- mykey = None
- if ModelSetting.get_bool('tool_crypt_use_user_key'):
- mykey = ModelSetting.get('tool_crypt_user_key').lower().zfill(32)
- if app.config['config']['is_py2']:
- mykey = mykey.encode('utf8')
- if len(mykey) > 32:
- mykey = mykey[:32]
- logger.debug(mykey)
-
- if mode == 'encrypt':
- ModelSetting.set('tool_crypt_encrypt_word', u'%s' % word)
- ret = {'ret':'success', 'data':ToolAESCipher.encrypt(word, mykey=mykey)}
- elif mode == 'decrypt':
- ModelSetting.set('tool_crypt_decrypt_word', u'%s' % word)
- ret = {'ret':'success', 'data':ToolAESCipher.decrypt(word, mykey=mykey).decode()}
-
- logger.debug(ret)
- return ret
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- return {'ret':'exception', 'data':str(exception)}
diff --git a/lib/system/mod_setting.py b/lib/system/mod_setting.py
index 979e240..649a171 100644
--- a/lib/system/mod_setting.py
+++ b/lib/system/mod_setting.py
@@ -1,8 +1,10 @@
import random
import string
+import time
-from support import SupportDiscord, SupportFile, SupportTelegram
-from tool.modal_command import ToolModalCommand
+from support import (SupportDiscord, SupportFile, SupportSubprocess,
+ SupportTelegram)
+from tool import ToolModalCommand
from .setup import *
@@ -35,7 +37,7 @@ class ModuleSetting(PluginModuleBase):
'notify.yaml': '', #직접 사용하지 않으나 저장 편의상.
'command_text': '',
'celery_start_by_web': 'False', #웹 실행시 celery 실행
- 'celery_start_command': "celery -A flaskfarm.main.celery worker --loglevel=info --pool=gevent --concurrency=2 --config_filepath={F.config['config_filepath']} --running_type=native",
+ 'celery_start_command': "celery -A flaskfarm.main.celery worker --workdir={F.config['path_working']} --loglevel=info --pool=gevent --concurrency=2 --config_filepath={F.config['config_filepath']} --running_type=native",
}
@@ -65,7 +67,6 @@ class ModuleSetting(PluginModuleBase):
elif page == 'celery':
arg['use_celery'] = F.config['use_celery']
arg['running_type'] = F.config['running_type']
-
return render_template(f'{__package__}_{name}_{page}.html', arg=arg)
except Exception as e:
P.logger.error(f'Exception:{str(e)}')
@@ -122,13 +123,13 @@ class ModuleSetting(PluginModuleBase):
ret['msg'] = arg1
pass
elif command == 'celery_execute':
- tmp = arg1.replace("{F.config['config_filepath']}", F.config['config_filepath']).replace('{F.config["config_filepath"]}', F.config['config_filepath'])
- cmd = [
- ['msg', f'명령 : {tmp}'],
- ['msg', ''],
- tmp.split(' '),
- ]
- ToolModalCommand.start("Celery 실행", cmd)
+ self.celery_execute(arg1, mode='foreground')
+ elif command == 'celery_execute_back':
+ self.celery_execute(arg1, mode='background')
+ ret['msg'] = '실행했습니다.'
+ elif command == 'celery_test':
+ return self.__celery_test()
+
return jsonify(ret)
@@ -136,9 +137,8 @@ class ModuleSetting(PluginModuleBase):
try:
if F.config['run_flask'] == False:
return
- F.logger.info(f"arg_repeat : {F.config['arg_repeat']}")
- F.logger.info(f"arg_repeat : {F.config['arg_repeat']}")
-
+ 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']))
@@ -161,15 +161,17 @@ class ModuleSetting(PluginModuleBase):
from tool import ToolNotify
msg = f"시스템이 시작되었습니다.\n재시작: {F.config['arg_repeat']}"
ToolNotify.send_message(msg, message_id='system_start')
+
+
except Exception as e:
P.logger.error(f'Exception:{str(e)}')
P.logger.error(traceback.format_exc())
def plugin_unload(self):
- ToolModalCommand.process_close()
+ ToolModalCommand.modal_close()
def setting_save_after(self, change_list):
- if 'theme' in change_list:
+ if 'theme' in change_list or 'web_title' in change_list:
F.socketio.emit("refresh", {}, namespace='/framework', broadcast=True)
elif 'notify.yaml' in change_list:
SupportFile.write_file(F.config['notify_yaml_filepath'], SystemModelSetting.get('notify.yaml'))
@@ -196,3 +198,53 @@ class ModuleSetting(PluginModuleBase):
scheduler.add_job_instance(job_instance, run=False)
+ def celery_execute(self, command=None, mode='background'):
+ if command == None:
+ command = SystemModelSetting.get('celery_start_command')
+ command = command.replace("{F.config['config_filepath']}", F.config['config_filepath']).replace('{F.config["config_filepath"]}', F.config['config_filepath']).replace("{F.config['path_working']}", F.config['path_working']).replace('{F.config["path_working"]}', F.config['path_working'])
+ if mode == 'foreground':
+ cmd = [
+ ['msg', f'명령 : {command}'],
+ command.split(' '),
+ ]
+ ToolModalCommand.start("Celery 실행", cmd)
+ elif mode == 'background':
+ SupportSubprocess(command).start(join=False)
+
+
+ def __celery_test(self):
+ if F.config['use_celery']:
+ from celery import Celery
+ from celery.exceptions import NotRegistered, TimeoutError
+ data = {}
+ try:
+ result = self.celery_test.apply_async()
+ try:
+ tmp = result.get(timeout=5, propagate=True)
+ except Exception as e:
+ P.logger.error(f'Exception:{str(e)}')
+ P.logger.error(traceback.format_exc())
+ data['ret'] = 'success'
+ data['msg'] = tmp
+ except TimeoutError:
+ data['ret'] = 'danger'
+ data['msg'] = 'celery가 동작중이 아니거나 모든 Worker가 작업중입니다.'
+ except NotRegistered:
+ data['ret'] = 'danger'
+ data['msg'] = 'Not Registered'
+ else:
+ data['ret'] = 'danger'
+ data['msg'] = 'celery 실행환경이 아닙니다.'
+ P.logger.debug(d(data))
+ return data
+
+ #@staticmethod
+ @celery.task
+ def celery_test():
+ try:
+ time.sleep(1)
+ data = '정상입니다. 이 메시지는 celery 에서 반환됩니다. '
+ return data
+ except Exception as e:
+ P.logger.error(f'Exception:{str(e)}')
+ P.logger.error(traceback.format_exc())
diff --git a/lib/system/model.py b/lib/system/model.py
deleted file mode 100644
index f0805d2..0000000
--- a/lib/system/model.py
+++ /dev/null
@@ -1,8 +0,0 @@
-import traceback
-from framework import db, get_logger
-from framework.util import Util
-
-logger = get_logger(__package__)
-
-from plugin.model_setting import get_model_setting
-ModelSetting = get_model_setting(__package__, logger)
diff --git a/lib/system/plugin.py b/lib/system/plugin.py
deleted file mode 100644
index 5c6db16..0000000
--- a/lib/system/plugin.py
+++ /dev/null
@@ -1,543 +0,0 @@
-# -*- coding: utf-8 -*-
-#########################################################
-# python
-import json
-import logging
-import os
-import platform
-import threading
-import time
-import traceback
-
-# third-party
-import requests
-from flask import (Blueprint, Response, jsonify, redirect, render_template,
- request, send_file, stream_with_context)
-from flask_login import login_required
-# sjva 공용
-from framework import (app, check_api, frame, get_logger, # , celery
- path_app_root, path_data, scheduler, socketio)
-from support import SingletonClass
-
-# 로그
-package_name = __name__.split('.')[0]
-logger = get_logger(__package__)
-
-# 패키지
-from .logic import SystemLogic
-from .logic_auth import SystemLogicAuth
-from .logic_command import SystemLogicCommand
-from .logic_command2 import SystemLogicCommand2
-# celery 때문에 import
-from .logic_env import SystemLogicEnv
-from .logic_notify import SystemLogicNotify
-from .logic_plugin import LogicPlugin
-from .logic_selenium import SystemLogicSelenium
-from .logic_site import SystemLogicSite
-from .logic_telegram_bot import SystemLogicTelegramBot
-from .logic_terminal import SystemLogicTerminal
-from .logic_tool_crypt import SystemLogicToolDecrypt
-from .model import ModelSetting
-
-#########################################################
-
-
-#########################################################
-# 플러그인 공용
-#########################################################
-blueprint = Blueprint(package_name, package_name, url_prefix='/%s' % package_name, template_folder='templates')
-
-menu = {
- 'uri' : package_name,
- 'name': '설정',
- 'list': [
- {
- 'uri': 'setting',
- 'name': '일반설정',
- 'list': [
- {'uri': 'basic', 'name': '기본'},
- {'uri': 'auth', 'name': '인증'},
- {'uri': 'env', 'name': '시스템'},
- {'uri': 'notify', 'name': '알림'},
- {'uri': 'telegram_bot', 'name': '텔레그램 봇'},
- {'uri': 'selenium', 'name': 'Selenium'},
- {'uri': 'site', 'name': 'Site'},
- {'uri': 'memo', 'name': '메모'},
- {'uri': 'terminal', 'name': 'Terminal'},
- ],
- },
- {
- 'uri': 'plugin',
- 'name': '플러그인'
- },
- {
- 'uri': 'tool',
- 'name': 'Tool',
- 'list': [{'uri': 'crypt', 'name': '암호화'}]
- },
- {
- 'uri': 'log',
- 'name': '로그'
- }
- ]
-}
-
-
-
-#if platform.system() == 'Windows':
-# del menu['sub2']['setting'][-1]
-
-
-def plugin_load():
- logger.debug('plugin_load:%s', package_name)
- SystemLogic.plugin_load()
- SystemLogicTelegramBot.plugin_load()
- SystemLogicSite.plugin_load()
-
-def plugin_unload():
- logger.debug('plugin_load:%s', package_name)
- SystemLogicSelenium.plugin_unload()
- SystemLogicCommand.plugin_unload()
- SystemLogicCommand2.plugin_unload()
-
-
-#########################################################
-# WEB Menu
-#########################################################
-@blueprint.route('/')
-def normal():
- return redirect('/%s/setting' % package_name)
-
-@login_required
-def home():
- return render_template('info.html', arg=None)
-
-@blueprint.route('/', methods=['GET', 'POST'])
-@login_required
-def first_menu(sub):
- #logger.debug('System SUB:%s', sub)
- arg = None
- if sub == 'home':
- return render_template('%s_%s.html' % (package_name, sub), arg=None)
- elif sub == 'setting':
- return redirect('/%s/%s/basic' % (package_name, sub))
- elif sub == 'tool':
- return redirect('/%s/%s/crypt' % (package_name, sub))
- elif sub == 'plugin':
- arg = ModelSetting.to_dict()
- arg['install'] = request.args.get('install', '')
- if arg['install'] == 'flaskfilemanager':
- arg['install'] = 'https://github.com/soju6jan/' + arg['install']
- try:
- import flaskfilemanager
- arg['install'] = ''
- except:
- pass
- elif arg['install'] == 'flaskcode':
- arg['install'] = 'https://github.com/soju6jan/' + arg['install']
- try:
- import flaskcode
- arg['install'] = ''
- except:
- pass
-
-
-
- return render_template('system_plugin.html', arg=arg)
- elif sub == 'information':
- return render_template('manual.html', sub=sub, arg='system.json')
- elif sub == 'log':
- log_files=os.listdir(os.path.join(path_data, 'log'))
- log_files.sort()
- log_list = []
- arg = {'package_name' : package_name, 'sub' : sub}
- for x in log_files:
- if x.endswith('.log'):
- log_list.append(x)
- arg['log_list'] = '|'.join(log_list)
- arg['all_list'] = '|'.join(log_files)
- arg['filename'] = ''
- if 'filename' in request.form:
- arg['filename'] = request.form['filename']
- logger.debug(arg)
- return render_template('%s_%s.html' % (package_name, sub), arg=arg)
- elif sub == 'restart':
- restart()
- return render_template('system_restart.html', sub=sub, referer=request.headers.get("Referer"))
- elif sub == 'shutdown':
- shutdown()
- return render_template('system_restart.html', sub=sub, referer=request.headers.get("Referer"))
- elif sub == 'telegram':
- return redirect('/%s/%s/setting' % (package_name, sub))
- return render_template('sample.html', title='%s - %s' % (package_name, sub))
-
-
-@blueprint.route('//')
-@login_required
-def second_menu(sub, sub2):
- try:
- if sub == 'setting':
- arg = ModelSetting.to_dict()
- arg['sub'] = sub2
- if sub2 == 'basic':
- arg['point'] = SystemLogic.point
- return render_template('%s_%s_%s.html' % (package_name, sub, sub2), arg=arg)
- elif sub2 in ['trans', 'selenium', 'notify']:
- return render_template('%s_%s_%s.html' % (package_name, sub, sub2), arg=arg)
- elif sub2 == 'auth':
- arg['auth_result'] = SystemLogicAuth.get_auth_status()
- return render_template('%s_%s_%s.html' % (package_name, sub, sub2), arg=arg)
- elif sub2 == 'telegram_bot':
- arg['scheduler'] = str(scheduler.is_include('%s_%s' % (package_name, sub2)))
- arg['is_running'] = str(scheduler.is_running('%s_%s' % (package_name, sub2)))
- return render_template('%s_%s_%s.html' % (package_name, sub, sub2), arg=arg)
- elif sub2 == 'env':
- arg['export'] = SystemLogicEnv.load_export()
- if arg['export'] is None:
- arg['export'] = u'export.sh 파일이 없습니다.'
- return render_template('%s_%s_%s.html' % (package_name, sub, sub2), arg=arg)
- elif sub2 == 'site':
- arg['scheduler'] = str(scheduler.is_include('%s_%s' % (package_name, sub2)))
- arg['is_running'] = str(scheduler.is_running('%s_%s' % (package_name, sub2)))
- from system.model import ModelSetting as SystemModelSetting
- arg['site_get_daum_cookie_url'] = '{ddns}/{package_name}/api/{sub2}/daum_cookie'.format(ddns=SystemModelSetting.get('ddns'), package_name=package_name, sub2=sub2)
- if SystemModelSetting.get_bool('auth_use_apikey'):
- arg['site_get_daum_cookie_url'] += '?apikey={apikey}'.format(apikey=SystemModelSetting.get('auth_apikey'))
- return render_template('%s_%s_%s.html' % (package_name, sub, sub2), arg=arg)
- elif sub2 == 'memo':
- return render_template('%s_%s_%s.html' % (package_name, sub, sub2), arg=arg)
- elif sub2 == 'terminal':
- arg['yaml_path'] = SystemLogicTerminal.yaml_path.replace(path_app_root, '')
- return render_template('%s_%s_%s.html' % (package_name, sub, sub2), arg=arg)
- elif sub == 'tool':
- arg = ModelSetting.to_dict()
- arg['sub'] = sub2
- if sub2 == 'crypt':
- return render_template('%s_%s_%s.html' % (package_name, sub, sub2), arg=arg)
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
-
-
-
-
-#########################################################
-# For UI
-#########################################################
-@blueprint.route('/ajax//', methods=['GET', 'POST'])
-@login_required
-def second_ajax(sub, sub2):
- logger.debug('System AJAX sub:%s', sub)
- try:
- if sub == 'auth':
- from .logic_auth import SystemLogicAuth
- return SystemLogicAuth.process_ajax(sub2, request)
- elif sub == 'selenium':
- return SystemLogicSelenium.process_ajax(sub2, request)
- elif sub == 'notify':
- return SystemLogicNotify.process_ajax(sub2, request)
- elif sub == 'telegram_bot':
- return SystemLogicTelegramBot.process_ajax(sub2, request)
- elif sub == 'env':
- return SystemLogicEnv.process_ajax(sub2, request)
- elif sub == 'site':
- return SystemLogicSite.process_ajax(sub2, request)
- elif sub == 'crypt':
- return SystemLogicToolDecrypt.process_ajax(sub2, request)
- elif sub == 'terminal':
- return SystemLogicTerminal.process_ajax(sub2, request)
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
-
-
-@blueprint.route('/ajax/', methods=['GET', 'POST'])
-@login_required
-def ajax(sub):
- #logger.debug('System AJAX sub:%s', sub)
- try:
- if sub == 'info':
- try:
- ret = {}
- ret['system'] = SystemLogic.get_info()
- ret['scheduler'] = scheduler.get_job_list_info()
-
- #logger.debug(ret)
- return jsonify(ret)
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- return jsonify()
- elif sub == 'setting_save_system':
- try:
- ret = SystemLogic.setting_save_system(request)
- return jsonify(ret)
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- elif sub == 'setting_save':
- ret = ModelSetting.setting_save(request)
- SystemLogic.setting_save_after()
- return jsonify(ret)
- elif sub == 'ddns_test':
- try:
- url = request.form['ddns'] + '/version'
- res = requests.get(url)
- data = res.text
- #data = res.json()
- #logger.debug(data)
- return jsonify(data)
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- return jsonify('fail')
- elif sub == 'celery_test':
- try:
- #result = add_together.delay(10, 20)
- #print(result.wait())
- #return 'Welcome to my app!'
- try:
- import framework
- framework.exit_code = 1
- socketio.stop()
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- #os.environ['SJVA_REPEAT_TYPE'] = 'update'
-
-
- return jsonify()
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- elif sub == 'command_run':
- try:
- command_text = request.form['command_text']
- ret = SystemLogic.command_run(command_text)
- return jsonify(ret)
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- elif sub == 'get_link_list':
- try:
- link_json = SystemLogic.get_setting_value('link_json')
- j = json.loads(link_json)
- return jsonify(j)
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- elif sub == 'link_save':
- try:
- link_data_str = request.form['link_data']
- #j = json.loads(link_data)
- ret = SystemLogic.link_save(link_data_str)
- return jsonify(ret)
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- elif sub == 'plugin_list':
- try:
- return jsonify(LogicPlugin.get_plugin_list())
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
- elif sub == 'plugin_install':
- try:
- #plugin_name = request.form['plugin_name']
- plugin_git = request.form['plugin_git']
- return jsonify(LogicPlugin.plugin_install_by_api(plugin_git, request.form.get('zip_url'), request.form.get('zip_filename')))
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- elif sub == 'plugin_uninstall':
- try:
- plugin_name = request.form['plugin_name']
- return jsonify(LogicPlugin.plugin_uninstall(plugin_name))
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
- elif sub == 'recent_version':
- ret = SystemLogic.get_recent_version()
- ret = {'ret':ret, 'version':SystemLogic.recent_version}
- return jsonify(ret)
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
-
-
-@socketio.on('connect', namespace='/%s' % package_name)
-def connect():
- try:
- InfoProcess.instance().connect(request.sid)
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
-
-@socketio.on('disconnect', namespace='/%s' % package_name)
-def disconnect():
- try:
- InfoProcess.instance().disconnect(request.sid)
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
-
-@socketio.on('connect', namespace='/system_restart')
-def connect_system_restart():
- try:
- socketio.emit("on_connect", 'restart', namespace='/system_restart', broadcast=True)
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
-
-@socketio.on('disconnect', namespace='/system_restart')
-def disconnect_system_restart():
- try:
- pass
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
-
-
-
-#########################################################
-# API
-#########################################################
-
-@blueprint.route('/api/', methods=['GET', 'POST'])
-@check_api
-def first_api(sub):
- try:
- if sub == 'plugin_add':
- plugin_git = request.form['plugin_git']
- from system.logic_plugin import LogicPlugin
- ret = LogicPlugin.plugin_install_by_api(plugin_git, request.form.get('zip_url'), request.form.get('zip_filename'))
- return jsonify(ret)
- elif sub == 'restart':
- logger.debug('web restart')
- import system
- system.restart()
- return jsonify({'ret':'success'})
- elif sub == 'gds':
- url = f"{app.config['DEFINE']['WEB_DIRECT_URL']}/sjva/gds2.php?type=file&id={request.args.get('id')}&user_id={ModelSetting.get('sjva_me_user_id')}&user_apikey={ModelSetting.get('auth_apikey')}"
- data = requests.get(url).json()['data']
- logger.debug(data)
- req_headers = dict(request.headers)
- headers = {}
-
- if 'Range' not in req_headers or req_headers['Range'].startswith('bytes=0-'):
- headers['Range'] = "bytes=0-1048576"
- else:
- headers['Range'] = req_headers['Range']
- headers['Authorization'] = f"Bearer {data['token']}"
- headers['Connection'] = 'keep-alive'
-
- r = requests.get(data['url'], headers=headers, stream=True)
- rv = Response(r.iter_content(chunk_size=1048576), r.status_code, content_type=r.headers['Content-Type'], direct_passthrough=True)
- rv.headers.add('Content-Range', r.headers.get('Content-Range'))
- return rv
- elif sub == 'gds2':
- url = f"{app.config['DEFINE']['WEB_DIRECT_URL']}/sjva/gds.php?type=file&id={request.args.get('id')}&user_id={ModelSetting.get('sjva_me_user_id')}&user_apikey={ModelSetting.get('auth_apikey')}"
- data = requests.get(url).json()['data']
- logger.debug(data)
- req_headers = dict(request.headers)
- headers = {}
-
- headers['Range'] = f"bytes={request.args.get('range')}"
- headers['Authorization'] = f"Bearer {data['token']}"
- headers['Connection'] = 'keep-alive'
- logger.warning(headers)
- """
- response = redirect(data['url'])
- headers = dict(response.headers)
- headers.update({'Authorization': f"Bearer {data['token']}"})
- response.headers = headers
- return response
-
- response.headers.add('Authorization', headers['Authorization'])
- #response.headers['Location'] = data['url']
- return response
- """
-
- r = requests.get(data['url'], headers=headers, stream=True)
- logger.warning(r.history)
- #rv = Response(r.iter_content(chunk_size=10485760), r.status_code, content_type=r.headers['Content-Type'], direct_passthrough=True)
- #rv.headers.add('Content-Range', r.headers.get('Content-Range'))
-
- rv = Response(r.iter_content(chunk_size=1048576), r.status_code, content_type=r.headers['Content-Type'], direct_passthrough=True)
- rv.headers.add('Content-Range', r.headers.get('Content-Range'))
-
- logger.debug(rv.headers)
- return rv
- elif sub == 'gds_subtitle':
- url = f"{app.config['DEFINE']['WEB_DIRECT_URL']}/sjva/gds2.php?type=file&id={request.args.get('id')}&user_id={ModelSetting.get('sjva_me_user_id')}&user_apikey={ModelSetting.get('auth_apikey')}"
- data = requests.get(url).json()['data']
- logger.debug(data)
- req_headers = dict(request.headers)
- headers = {}
- headers['Range'] = f"bytes={request.args.get('range')}"
- headers['Authorization'] = f"Bearer {data['token']}"
- headers['Connection'] = 'keep-alive'
- logger.warning(headers)
- r = requests.get(data['url'], headers=headers, stream=True)
- logger.warning(r.history)
- if r.encoding != None:
- if r.encoding == 'ISO-8859-1': # 한글자막 인코딩 예외처리
- try:
- text = r.content.decode('utf-8', "strict")
- except Exception as e:
- logger.error('Exception:%s', e)
- logger.error(traceback.format_exc())
- text = r.content.decode('utf-8', "ignore")
- else:
- text = r.content.decode(r.encoding, "ignore")
- else:
- text = r.text
- from framework.common.util import convert_srt_to_vtt as convSrt2Vtt
- vtt = convSrt2Vtt(text)
- r.headers['Content-Type'] = "text/vtt; charset=utf-8"
- rv = Response(vtt, r.status_code, content_type=r.headers['Content-Type'])
- rv.headers.add('Content-Disposition', 'inline; filename="subtitle.vtt"')
- rv.headers.add('Content-Transfer-Encoding', 'binary')
- logger.debug(rv.headers)
- return rv
-
-
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
-
-@blueprint.route('/api//', methods=['GET', 'POST'])
-@check_api
-def second_api(sub, sub2):
- try:
- if sub == 'trans':
- from .logic_trans import SystemLogicTrans
- return SystemLogicTrans.process_api(sub2, request)
- elif sub == 'site':
- from .logic_site import SystemLogicSite
- return SystemLogicSite.process_api(sub2, request)
-
- except Exception as exception:
- logger.error('Exception:%s', exception)
- logger.error(traceback.format_exc())
-
-
-@blueprint.route("/videojs", methods=['GET', 'POST'])
-def videojs():
- data = {}
- data['play_title'] = request.form['play_title']
- data['play_source_src'] = request.form['play_source_src']
- data['play_source_type'] = request.form['play_source_type']
- if 'play_subtitle_src' in request.form:
- data['play_subtitle_src'] = request.form['play_subtitle_src']
- #logger.warning(data)
- return render_template('videojs.html', data=data)
diff --git a/lib/system/setup.py b/lib/system/setup.py
index 08ec564..2fb6ee9 100644
--- a/lib/system/setup.py
+++ b/lib/system/setup.py
@@ -14,7 +14,6 @@ __menu = {
{'uri': 'export', 'name': 'export.sh 파일'},
{'uri': 'celery', 'name': '비동기 작업(celery)'},
{'uri': 'notify', 'name': '알림'},
-
],
},
{
diff --git a/lib/system/templates/system_setting_celery.html b/lib/system/templates/system_setting_celery.html
index 5a1843c..b779ecc 100644
--- a/lib/system/templates/system_setting_celery.html
+++ b/lib/system/templates/system_setting_celery.html
@@ -16,108 +16,45 @@
{{ macros.setting_input_textarea('celery_start_command', 'celery 실행 명령', desc=['',
- '예: celery -A flaskfarm.main.celery worker --loglevel=info --pool=gevent --concurrency=2 --config_filepath="config.yaml파일경로" --running_type=native',
+ '예: celery -A flaskfarm.main.celery worker --workdir={F.config["path_working"]} --loglevel=info --pool=gevent --concurrency=2 --config_filepath={F.config["config_filepath"]} --running_type=native',
+ '',
'패키지로 실행시 : -A flaskfarm.main.celery',
- 'GIT 소스로 실행시 : -A main.celery (현재 작업폴더가 flaskfarm)',
+ 'Git 소스로 실행시 : -A main.celery', '',
'Linux는 사용자에 따라 export C_FORCE_ROOT=true 필요'
],
value=arg['celery_start_command'], row='5') }}
- {{ macros.setting_buttons([['celery_excute_btn', '실행 테스트']]) }}
+ {{ macros.setting_buttons([['celery_excute_btn', '실행 테스트'], ['celery_excute_back_btn', '실행(Background) ']]) }}
{% endblock %}
diff --git a/lib/tool/modal_command.py b/lib/tool/modal_command.py
index d9e3d33..b9aaf77 100644
--- a/lib/tool/modal_command.py
+++ b/lib/tool/modal_command.py
@@ -87,12 +87,15 @@ class ToolModalCommand(object):
@classmethod
def process_callback(cls, mode, text):
+ #F.logger.warning(text)
if cls.__show_modal == False:
return
if mode == 'end':
F.socketio.emit("command_modal_add_text", "\n\n<<프로세스 종료>>", namespace='/framework', broadcast=True)
F.socketio.emit("command_modal_input_disable", "", namespace='/framework', broadcast=True)
-
+ elif mode == 'thread_end':
+ #F.socketio.emit("command_modal_add_text", "\n\n<<프로세스 종료>>", namespace='/framework', broadcast=True)
+ F.socketio.emit("command_modal_input_disable", "", namespace='/framework', broadcast=True)
else:
F.socketio.emit("command_modal_add_text", text, namespace='/framework', broadcast=True)