# -*- 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 # gommi 공용 from framework.logger import get_logger, set_level from framework import ( app, db, scheduler, version, path_app_root, path_data, USERS, ) from framework.util import Util from framework import USERS from framework.user import User from framework import db, scheduler from framework.job import Job # 패키지 from .model import ModelSetting import system # 로그 package_name = __name__.split(".")[0] logger = get_logger(package_name) ######################################################### class SystemLogic(object): point = 0 db_default = { "db_version": "1", "port": "7771", "ddns": "http://localhost:7771", #'url_filebrowser' : 'http://localhost:9998', #'url_celery_monitoring' : 'http://localhost:9997', "id": "sjva", "pw": "sjva", "system_start_time": "", "repeat": "", "auto_restart_hour": "12", #'unique' : '', "theme": "Default", "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": "GOMMI Agent", "my_ip": "", "wavve_guid": "", # 번역 "trans_type": "0", "trans_google_api_key": "", "trans_papago_key": "", # 인증 "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": "# 각 플러그인 설정 설명에 명시되어 있는 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": "", # site "site_daum_interval": "0 4 */3 * *", "site_daum_auto_start": "False", "site_daum_cookie": "TIARA=gaXEIPluo-wWAFlwZN6l8gN3yzhkoo_piP.Kymhuy.6QBt4Q6.cRtxbKDaWpWajcyteRHzrlTVpJRxLjwLoMvyYLVi_7xJ1L", "site_daum_test": "나쁜 녀석들", "site_daum_proxy": "", "site_wavve_id": "", "site_wavve_pw": "", "site_wavve_credential": "", "site_wavve_use_proxy": "False", "site_wavve_proxy_url": "", "site_tving_id": "", "site_tving_pw": "", "site_tving_login_type": "0", "site_tving_token": "", "site_tving_deviceid": "", "site_tving_use_proxy": "False", "site_tving_proxy_url": "", "site_tving_uuid": "", # 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", } db_default2 = { "use_category_vod": "True", "use_category_file_process": "True", "use_category_plex": "True", "use_category_tool": "True", } db_default3 = { "use_plugin_ffmpeg": "False", "use_plugin_ktv": "False", "use_plugin_fileprocess_movie": "False", "use_plugin_plex": "False", "use_plugin_gdrive_scan": "False", "use_plugin_rclone": "False", "use_plugin_daum_tv": "False", } recent_version = None @staticmethod def plugin_load(): try: SystemLogic.db_init() SystemLogic.init() except Exception as exception: logger.error("Exception:%s", exception) logger.error(traceback.format_exc()) @staticmethod def db_init(): try: logger.debug( "setting count : %s", db.session.query(ModelSetting).filter_by().count(), ) is_first = False for key, value in SystemLogic.db_default.items(): if db.session.query(ModelSetting).filter_by(key=key).count() == 0: if key == "port": is_first = True if key == "sjva_id" or key == "auth_apikey": value = "".join( random.choice(string.ascii_uppercase + string.digits) for _ in range(10) ) db.session.add(ModelSetting(key, value)) db.session.commit() # 기존...사람들을 위해 토큰이 있는 사용자면 추가할때 True로 해준다 for key, value in SystemLogic.db_default2.items(): if db.session.query(ModelSetting).filter_by(key=key).count() == 0: tmp = value if is_first is False: tmp = "True" db.session.add(ModelSetting(key, tmp)) db.session.commit() # db.session.commit() for key, value in SystemLogic.db_default3.items(): if db.session.query(ModelSetting).filter_by(key=key).count() == 0: tmp = value if is_first is False: tmp = "True" db.session.add(ModelSetting(key, tmp)) db.session.commit() # for key, value in SystemLogic.db_default_etc.items(): # if db.session.query(ModelSetting).filter_by(key=key).count() == 0: # db.session.add(ModelSetting(key, value)) # db.session.commit() except Exception as exception: logger.error("Exception:%s", exception) logger.error(traceback.format_exc()) @staticmethod def init(): try: if ( app.config["config"]["repeat"] == 0 or SystemLogic.get_setting_value("system_start_time") == "" ): item = ( db.session.query(ModelSetting) .filter_by(key="system_start_time") .with_for_update() .first() ) item.value = datetime.now().strftime("%Y-%m-%d %H:%M:%S") db.session.commit() item = ( db.session.query(ModelSetting) .filter_by(key="repeat") .with_for_update() .first() ) item.value = str(app.config["config"]["repeat"]) db.session.commit() username = db.session.query(ModelSetting).filter_by(key="id").first().value passwd = db.session.query(ModelSetting).filter_by(key="pw").first().value USERS[username] = User(username, passwd_hash=passwd) SystemLogic.set_restart_scheduler() # SystemLogic.set_statistics_scheduler() SystemLogic.set_scheduler_check_scheduler() SystemLogic.get_recent_version() except Exception as exception: logger.error("Exception:%s", exception) logger.error(traceback.format_exc()) @staticmethod def get_recent_version(): try: import requests url = f"{app.config['DEFINE']['MAIN_SERVER_URL']}/version" if ModelSetting.get("ddns") == app.config["DEFINE"]["MAIN_SERVER_URL"]: url = "https://dev.soju6jan.com/version" SystemLogic.recent_version = requests.get(url).text return True except Exception as exception: logger.error("Exception:%s", exception) logger.error(traceback.format_exc()) return False @staticmethod def restart(): import system system.restart() @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"] = "%s. 비동기 작업 : %s" % ( app.config["config"]["running_type"], "사용" if app.config["config"]["use_celery"] else "미사용", ) import system info["auth"] = app.config["config"]["auth_desc"] info["cpu_percent"] = "not supported" info["memory"] = "not supported" info["disk"] = "not supported" if app.config["config"]["running_type"] != "termux": try: import psutil from framework.util import Util print("here") 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"] = "전체 : %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 Exception: 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"] = "전체 : %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"] = "시작 : %s 경과 : %s 재시작 : %s" % ( tmp, str(timedelta).split(".")[0], app.config["config"]["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) 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() 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: USERS[ModelSetting.get("id")] = User( ModelSetting.get("id"), passwd_hash=ModelSetting.get("pw") ) SystemLogic.set_restart_scheduler() 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 set_restart_scheduler(): name = "%s_restart" % (package_name) if scheduler.is_include(name): scheduler.remove_job(name) interval = ModelSetting.get("auto_restart_hour") if interval != "0": if len(interval.split(" ")) == 1: interval = "%s" % (int(interval) * 60) job_instance = Job( package_name, name, interval, SystemLogic.restart, "자동 재시작", True, ) scheduler.add_job_instance(job_instance, run=False) """ @staticmethod def set_statistics_scheduler(): try: name = '%s_statistics' % (package_name) if scheduler.is_include(name): scheduler.remove_job(name) job_instance = Job(package_name, name, 59, SystemLogic.statistics_scheduler_function, u"Update Check", True) scheduler.add_job_instance(job_instance, run=True) except Exception as exception: logger.error('Exception:%s', exception) logger.error(traceback.format_exc()) return False """ @staticmethod def set_scheduler_check_scheduler(): try: name = "scheduler_check" if scheduler.is_include(name): scheduler.remove_job(name) job_instance = Job( package_name, name, 2, scheduler.first_run_check_thread_function, "Scheduler Check", True, ) scheduler.add_job_instance(job_instance, run=False) except Exception as exception: logger.error("Exception:%s", exception) logger.error(traceback.format_exc()) 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 @staticmethod def apply_menu_link(): try: link_data_str = SystemLogic.get_setting_value("link_json") data = json.loads(link_data_str) from framework.menu import get_menu_map menu_map = get_menu_map() for link_category in menu_map: if link_category["type"] == "link": break link_category["list"] = [] for item in data: entity = {} entity["type"] = item["type"] if item["type"] == "link": entity["name"] = item["title"] entity["link"] = item["url"] link_category["list"].append(entity) return True except Exception as exception: logger.error("Exception:%s", exception) logger.error(traceback.format_exc()) return False