From b6e3448792dd831fc1b2cf82ac059b5147a7f18e Mon Sep 17 00:00:00 2001 From: Apex Liu Date: Mon, 16 Jan 2017 21:28:13 +0800 Subject: [PATCH] tmp. --- .gitignore | 2 + build.bat.in | 5 + build/.gitignore | 1 - build/.idea/build.iml | 2 +- build/build.py | 20 +- build/builder/build-assist.py | 4 +- build/builder/build-server.py | 25 +- build/builder/core/configs.py | 80 ++---- build/builder/core/utils.py | 33 +-- build/config.py.in | 23 -- config.ini.in | 26 ++ .../ssh/{tpssh.sln => tpssh.vs2015.sln} | 2 +- .../{tpssh.vcxproj => tpssh.vs2015.vcxproj} | 1 + ...j.filters => tpssh.vs2015.vcxproj.filters} | 0 server/tp_web/src/main.cpp | 144 +++++++++- .../tp_web/src/tp_web.vs2015.vcxproj.filters | 4 +- server/tp_web/src/ts_env.cpp | 6 +- server/www/teleport/.idea/teleport.iml | 2 +- .../www/teleport/app/eom_app/app/configs.py | 219 ++++++--------- server/www/teleport/app/eom_app/app/core.py | 27 +- .../teleport/app/eom_common/eomcore/logger.py | 264 ++++++++++-------- server/www/teleport/view/log/record.mako | 10 +- 22 files changed, 515 insertions(+), 385 deletions(-) create mode 100644 build.bat.in delete mode 100644 build/.gitignore delete mode 100644 build/config.py.in create mode 100644 config.ini.in rename server/tp_core/protocol/ssh/{tpssh.sln => tpssh.vs2015.sln} (93%) rename server/tp_core/protocol/ssh/{tpssh.vcxproj => tpssh.vs2015.vcxproj} (99%) rename server/tp_core/protocol/ssh/{tpssh.vcxproj.filters => tpssh.vs2015.vcxproj.filters} (100%) diff --git a/.gitignore b/.gitignore index fc743ad..4196b4c 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,7 @@ __pycache__ /external/openssl /external/python +/build/config.py # for dist folder /dist/*.zip @@ -60,3 +61,4 @@ __pycache__ /client/tp_rdp /external/libssh-win-static/lib /server/share/log +/config.ini diff --git a/build.bat.in b/build.bat.in new file mode 100644 index 0000000..7d1ed2f --- /dev/null +++ b/build.bat.in @@ -0,0 +1,5 @@ +@echo off + +SET PYEXEC=C:\Python\Python34-x86\python.exe + +%PYEXEC% -B build/build.py %1 %2 %3 %4 %5 diff --git a/build/.gitignore b/build/.gitignore deleted file mode 100644 index 31efa1c..0000000 --- a/build/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/config.py diff --git a/build/.idea/build.iml b/build/.idea/build.iml index 4462c8b..8182651 100644 --- a/build/.idea/build.iml +++ b/build/.idea/build.iml @@ -2,7 +2,7 @@ - + diff --git a/build/build.py b/build/build.py index 7e53b25..349b81d 100644 --- a/build/build.py +++ b/build/build.py @@ -8,6 +8,7 @@ import platform import sys THIS_PATH = os.path.abspath(os.path.dirname(__file__)) +ROOT_PATH = os.path.abspath(os.path.join(THIS_PATH, '..')) BUILDER_PATH = os.path.join(THIS_PATH, 'builder') sys.path.append(os.path.join(BUILDER_PATH)) @@ -139,16 +140,12 @@ def do_opt(opt): # arg = 'installer' arg = '%s %s installer' % (ctx.dist, opt['bits']) - elif 'installer-ubuntu' == opt['name']: - script = 'build-installer.py' - arg = '%s %s installer' % ('ubuntu', opt['bits']) - elif 'assist-exe' == opt['name']: script = 'build-assist.py' arg = '%s %s exe' % (ctx.target_path, opt['bits']) - elif 'assist-rdp' == opt['name']: - script = 'build-assist.py' - arg = '%s rdp' % (opt['bits']) + # elif 'assist-rdp' == opt['name']: + # script = 'build-assist.py' + # arg = '%s rdp' % (opt['bits']) elif 'assist-installer' == opt['name']: script = 'build-assist.py' arg = '%s %s installer' % (ctx.dist, opt['bits']) @@ -157,9 +154,8 @@ def do_opt(opt): cc.e('unknown option: ', opt['name']) return - cmd = '"%s" -B "%s/%s" %s' % (utils.cfg.py_exec, BUILDER_PATH, script, arg) - cc.i(cmd) - cc.v('') + # cmd = '"%s" -B "%s" %s' % (utils.cfg.py_exec, os.path.join(BUILDER_PATH, script), arg) + cmd = '%s -B %s %s' % (utils.cfg.py_exec, os.path.join(BUILDER_PATH, script), arg) os.system(cmd) @@ -176,13 +172,13 @@ def select_option_by_name(name): return None -def select_option_by_id(id): +def select_option_by_id(_id): global options for o in range(len(options)): if options[o] is None: continue - if options[o]['id'] == id: + if options[o]['id'] == _id: return options[o] return None diff --git a/build/builder/build-assist.py b/build/builder/build-assist.py index 8ed0968..d66bac8 100644 --- a/build/builder/build-assist.py +++ b/build/builder/build-assist.py @@ -31,8 +31,8 @@ class BuilderWin(BuilderBase): def build_exe(self): cc.n('build tp_assist...') - sln_file = os.path.join(ROOT_PATH, 'tp_assist', 'tp_assist.vs2015.sln') - out_file = os.path.join(ROOT_PATH, 'out', 'tp_assist', ctx.bits_path, ctx.target_path, 'tp_assist.exe') + sln_file = os.path.join(ROOT_PATH, 'client', 'tp_assist', 'tp_assist.vs2015.sln') + out_file = os.path.join(ROOT_PATH, 'out', 'client', ctx.bits_path, ctx.target_path, 'tp_assist.exe') if os.path.exists(out_file): utils.remove(out_file) utils.msvc_build(sln_file, 'tp_assist', ctx.target_path, ctx.bits_path, False) diff --git a/build/builder/build-server.py b/build/builder/build-server.py index 780a05e..295bdaf 100644 --- a/build/builder/build-server.py +++ b/build/builder/build-server.py @@ -27,13 +27,30 @@ class BuilderWin(BuilderBase): super().__init__() def build_server(self): - cc.n('build eom_ts...') - sln_file = os.path.join(ROOT_PATH, 'teleport-server', 'src', 'eom_ts.vs2015.sln') - out_file = os.path.join(ROOT_PATH, 'out', 'eom_ts', ctx.bits_path, ctx.target_path, 'eom_ts.exe') + cc.n('build web server ...') + sln_file = os.path.join(ROOT_PATH, 'server', 'tp_web', 'src', 'tp_web.vs2015.sln') + out_file = os.path.join(ROOT_PATH, 'out', 'server', ctx.bits_path, ctx.target_path, 'tp_web.exe') if os.path.exists(out_file): utils.remove(out_file) - utils.msvc_build(sln_file, 'eom_ts', ctx.target_path, ctx.bits_path, False) + utils.msvc_build(sln_file, 'tp_web', ctx.target_path, ctx.bits_path, False) utils.ensure_file_exists(out_file) + + cc.n('build core server ...') + sln_file = os.path.join(ROOT_PATH, 'server', 'tp_core', 'core', 'tp_core.vs2015.sln') + out_file = os.path.join(ROOT_PATH, 'out', 'server', ctx.bits_path, ctx.target_path, 'tp_core.exe') + if os.path.exists(out_file): + utils.remove(out_file) + utils.msvc_build(sln_file, 'tp_core', ctx.target_path, ctx.bits_path, False) + utils.ensure_file_exists(out_file) + + cc.n('build SSH protocol ...') + sln_file = os.path.join(ROOT_PATH, 'server', 'tp_core', 'protocol', 'ssh', 'tpssh.vs2015.sln') + out_file = os.path.join(ROOT_PATH, 'out', 'server', ctx.bits_path, ctx.target_path, 'tpssh.dll') + if os.path.exists(out_file): + utils.remove(out_file) + utils.msvc_build(sln_file, 'tpssh', ctx.target_path, ctx.bits_path, False) + utils.ensure_file_exists(out_file) + # # s = os.path.join(ROOT_PATH, 'out', 'console', ctx.bits_path, ctx.target_path, 'console.exe') # t = os.path.join(ROOT_PATH, 'out', 'eom_agent', ctx.target_path, ctx.dist_path, 'eom_agent.com') diff --git a/build/builder/core/configs.py b/build/builder/core/configs.py index 20e6307..69324a4 100644 --- a/build/builder/core/configs.py +++ b/build/builder/core/configs.py @@ -3,12 +3,13 @@ import os import sys import platform +import configparser from . import colorconsole as cc __all__ = ['cfg'] -class TpDict(dict): +class AttrDict(dict): """ 可以像属性一样访问字典的 Key,var.key 等同于 var['key'] """ @@ -24,17 +25,11 @@ class TpDict(dict): self[name] = val -class ConfigFile(TpDict): +class ConfigFile(AttrDict): def __init__(self, **kwargs): super().__init__(**kwargs) - # self.__file_name = None - # self.__save_indent = 0 - # self.__loaded = False def init(self, cfg_file): - if not self.load(cfg_file, True): - return False - self['ROOT_PATH'] = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..')) self['py_exec'] = sys.executable @@ -55,70 +50,47 @@ class ConfigFile(TpDict): _os = platform.system().lower() + self['is_win'] = False + self['is_linux'] = False + self['is_macos'] = False self['dist'] = '' if _os == 'windows': + self['is_win'] = True self['dist'] = 'windows' elif _os == 'linux': + self['is_linux'] = True self['dist'] = 'linux' elif _os == 'darwin': + self['is_macos'] = True self['dist'] = 'macos' else: cc.e('not support this OS: {}'.format(platform.system())) return False - return True - - def load_str(self, module, code): - m = type(sys)(module) - m.__module_class__ = type(sys) - m.__file__ = module - - try: - exec(compile(code, module, 'exec'), m.__dict__) - except Exception as e: - cc.e('%s\n' % str(e)) - # print(str(e)) - # if eom_dev_conf.debug: - # raise + _cfg = configparser.ConfigParser() + _cfg.read(cfg_file) + if 'external_ver' not in _cfg.sections() or 'toolchain' not in _cfg.sections(): + cc.e('invalid configuration file: need `external_ver` and `toolchain` section.') return False - for y in m.__dict__: - if '__' == y[:2]: - continue - if isinstance(m.__dict__[y], dict): - self[y] = TpDict() - self._assign_dict(m.__dict__[y], self[y]) - else: - self[y] = m.__dict__[y] - - return True - - def load(self, full_path, must_exists=True): - try: - f = open(full_path, encoding='utf8') - code = f.read() - f.close() - self.__loaded = True - except IOError: - if must_exists: - cc.e('Can not load config file: %s\n' % full_path) + _tmp = _cfg['external_ver'] + if 'libuv' not in _tmp or 'mbedtls' not in _tmp or 'sqlite' not in _tmp: + cc.e('invalid configuration file: external version not set.') return False - module = os.path.basename(full_path) - if not self.load_str(module, code): - return False + self['ver'] = AttrDict() + for k in _tmp: + self['ver'][k] = _tmp[k] + + _tmp = _cfg['toolchain'] + if self.is_win: + self['nsis'] = _tmp.get('nsis', None) + self['msbuild'] = None # msbuild always read from register. + else: + self['cmake'] = _tmp.get('cmake', '/usr/bin/cmake') - self.__file_name = full_path return True - def _assign_dict(self, _from, _to): - for y in _from: - if isinstance(_from[y], dict): - _to[y] = TpDict() - self._assign_dict(_from[y], _to[y]) - else: - _to[y] = _from[y] - cfg = ConfigFile() del ConfigFile diff --git a/build/builder/core/utils.py b/build/builder/core/utils.py index b7c9a1b..e78b8cd 100644 --- a/build/builder/core/utils.py +++ b/build/builder/core/utils.py @@ -11,18 +11,15 @@ import time from . import colorconsole as cc from .configs import cfg + try: - CONFIG_FILE = os.path.join(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')), 'config.py') + CONFIG_FILE = os.path.join(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..')), 'config.ini') if not cfg.init(CONFIG_FILE): sys.exit(1) except: cc.e('can not load configuration.\n\nplease copy `config.py.in` into `config.py` and modify it to fit your condition and try again.') sys.exit(1) -# PY_VER = platform.python_version_tuple() -#IS_PY2 = sys.version_info[0] == 2 -#IS_PY3 = sys.version_info[0] == 3 - if cfg.is_py2: import imp elif cfg.is_py3: @@ -222,13 +219,9 @@ def python_exec(): return sys.executable -g_msbuild_path = None - - def msbuild_path(): - global g_msbuild_path - if g_msbuild_path is not None: - return g_msbuild_path + if cfg.msbuild is not None: + return cfg.msbuild # 14.0 = VS2015 # 12.0 = VS2012 @@ -248,21 +241,13 @@ def msbuild_path(): if not os.path.exists(msb): raise RuntimeError('Can not locate MSBuild at {}'.format(msp)) - g_msbuild_path = msb + cfg.msbuild = msb return msb -g_nsis_path = None - - def nsis_path(): - global g_nsis_path - if g_nsis_path is not None: - return g_nsis_path - - if 'nsis' in cfg: - g_nsis_path = cfg['nsis'] - return g_nsis_path + if cfg.nsis is not None: + return cfg.nsis p = winreg_read_wow64_32(r'SOFTWARE\NSIS\Unicode', '') if p is None: @@ -272,7 +257,7 @@ def nsis_path(): if not os.path.exists(p): raise RuntimeError('Can not locate NSIS at {}'.format(p)) - g_nsis_path = p + cfg.nsis = p return p @@ -355,7 +340,7 @@ def nsis_build(nsi_file, _define=''): def cmake(work_path, target, force_rebuild, cmake_define=''): # because cmake v2.8 shipped with Ubuntu 14.04LTS, but we need 3.5. # so we copy a v3.5 cmake from CLion and put to $WORK/eomsoft/toolchain/cmake. - #CMAKE = os.path.abspath(os.path.join(root_path(), 'toolchain', 'cmake', 'bin', 'cmake')) + # CMAKE = os.path.abspath(os.path.join(root_path(), 'toolchain', 'cmake', 'bin', 'cmake')) if 'cmake' not in cfg: raise RuntimeError('please set `cmake` path.') if not os.path.exists(cfg['cmake']): diff --git a/build/config.py.in b/build/config.py.in deleted file mode 100644 index 4c33c98..0000000 --- a/build/config.py.in +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -OPENSSL_VER = '1.0.2h' -LIBUV_VER = '1.9.1' -MBEDTLS_VER = '2.3.0' -SQLITE_VER = '3160200' - - -# ============================================ -# for windows -# ============================================ - -# if not set nsis path, builder will try to get it by read register. -nsis = 'C:\\Program Files (x86)\\NSIS\\Unicode\\makensis.exe' - - -# ============================================ -# for linux -# ============================================ - -cmake = '/opt/cmake/bin/cmake' -# pyexec = os.path.join(ROOT_PATH, 'external', 'linux', 'release', 'bin', 'python3.4') diff --git a/config.ini.in b/config.ini.in new file mode 100644 index 0000000..79c7b1b --- /dev/null +++ b/config.ini.in @@ -0,0 +1,26 @@ +[toolchain] +#============================================ +# for windows +#============================================ + +# if not set nsis path, default to get it by register. +#nsis = "C:\Program Files (x86)\NSIS\Unicode\makensis.exe" + +# if not set msbuild path, default to get it by register. +#msbuild = "C:\Program Files (x86)\MSBuild\14.0\bin\MSBuild.exe" + + +# ============================================ +# for linux +# ============================================ + +# if not set cmake path, default to '/usr/bin/cmake' +cmake = "/opt/cmake/bin/cmake" + + +[external_ver] +# openssl = 1.0.2h +libuv = 1.9.1 +mbedtls = 2.3.0 +sqlite = 3160200 + diff --git a/server/tp_core/protocol/ssh/tpssh.sln b/server/tp_core/protocol/ssh/tpssh.vs2015.sln similarity index 93% rename from server/tp_core/protocol/ssh/tpssh.sln rename to server/tp_core/protocol/ssh/tpssh.vs2015.sln index 753d95d..b4a60e7 100644 --- a/server/tp_core/protocol/ssh/tpssh.sln +++ b/server/tp_core/protocol/ssh/tpssh.vs2015.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 VisualStudioVersion = 14.0.23107.0 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tpssh", "tpssh.vcxproj", "{FDA16D20-09B7-45AF-ADF1-DAF3EF2C0531}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tpssh", "tpssh.vs2015.vcxproj", "{FDA16D20-09B7-45AF-ADF1-DAF3EF2C0531}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/server/tp_core/protocol/ssh/tpssh.vcxproj b/server/tp_core/protocol/ssh/tpssh.vs2015.vcxproj similarity index 99% rename from server/tp_core/protocol/ssh/tpssh.vcxproj rename to server/tp_core/protocol/ssh/tpssh.vs2015.vcxproj index 0fac214..6e6f5cc 100644 --- a/server/tp_core/protocol/ssh/tpssh.vcxproj +++ b/server/tp_core/protocol/ssh/tpssh.vs2015.vcxproj @@ -23,6 +23,7 @@ Win32Proj tpssh 8.1 + tpssh diff --git a/server/tp_core/protocol/ssh/tpssh.vcxproj.filters b/server/tp_core/protocol/ssh/tpssh.vs2015.vcxproj.filters similarity index 100% rename from server/tp_core/protocol/ssh/tpssh.vcxproj.filters rename to server/tp_core/protocol/ssh/tpssh.vs2015.vcxproj.filters diff --git a/server/tp_web/src/main.cpp b/server/tp_web/src/main.cpp index 5050b96..14e591c 100644 --- a/server/tp_web/src/main.cpp +++ b/server/tp_web/src/main.cpp @@ -40,6 +40,10 @@ static ex_u8 g_run_type = RUN_UNKNOWN; static bool _run_daemon(void); +// PythonűʹãҪΪ˼¼־ +// Windowsƽ̨ϣtp_web־ļд֮Pythonűд뷽ʽ򿪴־ļʱʧܡ +PyObject* init_web_builtin_module(void); + #ifdef EX_OS_WIN32 static int service_install() { @@ -227,6 +231,13 @@ static int _main_loop(void) pys_add_arg(pysh, it->c_str()); } + if (!pys_add_builtin_module(pysh, "tpweb", init_web_builtin_module)) + { + EXLOGE("[tpweb] can not add builtin module for python script.\n"); + return 1; + } + + return pys_run(pysh); } @@ -417,9 +428,9 @@ VOID WINAPI service_main(DWORD argc, wchar_t** argv) } } -#else -// not EX_OS_WIN32 -//#include "ts_util.h" +//====================================================== +#else // Linux or MacOS + #include #include #include @@ -500,3 +511,130 @@ static bool _run_daemon(void) } #endif + + + + + +//=============================================================== +// ʾμڽģ鹩ű +//=============================================================== +PyObject* _py_log_output(PyObject* self, PyObject* args) +{ +// UNUSED(self); +// UNUSED(args); + + int level = 0; + const char* msg = NULL; + if (!pylib_PyArg_ParseTuple(args, "is", &level, &msg)) + { + EXLOGE("invalid args for _py_log_output().\n"); + PYLIB_RETURN_FALSE; + } + + ex_wstr tmp; + ex_astr2wstr(msg, tmp, EX_CODEPAGE_UTF8); + + //EXLOGV(msg); + switch (level) + { + case EX_LOG_LEVEL_DEBUG: + ex_printf_d(tmp.c_str()); + break; + case EX_LOG_LEVEL_VERBOSE: + ex_printf_v(tmp.c_str()); + break; + case EX_LOG_LEVEL_INFO: + ex_printf_i(tmp.c_str()); + break; + case EX_LOG_LEVEL_WARN: + ex_printf_w(tmp.c_str()); + break; + case EX_LOG_LEVEL_ERROR: + ex_printf_e(tmp.c_str()); + break; + default: + PYLIB_RETURN_FALSE; + break; + } + + //return pylib_PyLong_FromLong(0x010001); + PYLIB_RETURN_TRUE; +} + +PyObject* _py_log_level(PyObject* self, PyObject* args) +{ + int level = 0; + if (!pylib_PyArg_ParseTuple(args, "i", &level)) + { + EXLOGE("invalid args for _py_log_level().\n"); + PYLIB_RETURN_FALSE; + } + + EXLOG_LEVEL(level); + + PYLIB_RETURN_TRUE; +} + +PyObject* _py_log_console(PyObject* self, PyObject* args) +{ + bool to_console = false; + if (!pylib_PyArg_ParseTuple(args, "p", &to_console)) + { + EXLOGE("invalid args for _py_log_console().\n"); + PYLIB_RETURN_FALSE; + } + + EXLOG_CONSOLE(to_console); + + PYLIB_RETURN_TRUE; +} + +PYS_BUILTIN_FUNC _demo_funcs[] = { + { + "log_output", // űڽűʹ + _py_log_output, // ӦC뺯 + PYS_TRUE, // ĻϢǷҪȵȣ + "write log." // ˵ĵѡǿַ + }, + + { + "log_level", + _py_log_level, + PYS_TRUE, + "set log level." + }, + + { + "log_console", + _py_log_console, + PYS_TRUE, + "set log to console or not." + }, + + // һ飬һԱΪָ룬ʾ + { NULL, NULL, 0, NULL } +}; + +PyObject* init_web_builtin_module(void) +{ + PyObject* mod = NULL; + + mod = pys_create_module("_tpweb", _demo_funcs); + + pys_builtin_const_long(mod, "EX_LOG_LEVEL_DEBUG", EX_LOG_LEVEL_DEBUG); + pys_builtin_const_long(mod, "EX_LOG_LEVEL_VERBOSE", EX_LOG_LEVEL_VERBOSE); + pys_builtin_const_long(mod, "EX_LOG_LEVEL_INFO", EX_LOG_LEVEL_INFO); + pys_builtin_const_long(mod, "EX_LOG_LEVEL_WARN", EX_LOG_LEVEL_WARN); + pys_builtin_const_long(mod, "EX_LOG_LEVEL_ERROR", EX_LOG_LEVEL_ERROR); + +// pys_builtin_const_bool(mod, "DEMO_CONST_2", PYS_TRUE); +// //pys_builtin_const_wcs(mod, "DEMO_CONST_3", L"STRING IJ this is string."); +// pys_builtin_const_wcs(mod, "DEMO_CONST_3", L"STRING this is string."); +// pys_builtin_const_utf8(mod, "DEMO_CONST_4", "this is string."); +// +// ex_u8 test_buf[12] = { 0x01, 0x02, 0x03, 0x04, 0x0a, 0x0b, 0x0c, 0x0d, 0x12, 0x34, 0xab, 0xcd }; +// pys_builtin_const_bin(mod, "DEMO_CONST_5", test_buf, 12); + + return mod; +} diff --git a/server/tp_web/src/tp_web.vs2015.vcxproj.filters b/server/tp_web/src/tp_web.vs2015.vcxproj.filters index 4aff80b..df7b24a 100644 --- a/server/tp_web/src/tp_web.vs2015.vcxproj.filters +++ b/server/tp_web/src/tp_web.vs2015.vcxproj.filters @@ -69,7 +69,6 @@ main app - libex\header @@ -115,6 +114,9 @@ pyshell\header + + Resource Files + diff --git a/server/tp_web/src/ts_env.cpp b/server/tp_web/src/ts_env.cpp index 5be9fdb..f6db09f 100644 --- a/server/tp_web/src/ts_env.cpp +++ b/server/tp_web/src/ts_env.cpp @@ -24,7 +24,7 @@ bool TsEnv::init(void) ex_path_join(base_path, true, L"..", NULL); ex_wstr conf_file = base_path; - ex_path_join(conf_file, false, L"etc", L"web.conf", NULL); + ex_path_join(conf_file, false, L"etc", L"web.ini", NULL); if (ex_is_file_exists(conf_file.c_str())) { @@ -38,7 +38,7 @@ bool TsEnv::init(void) ex_path_join(base_path, true, L"..", L"..", L"..", L"..", L"server", L"share", NULL); conf_file = base_path; - ex_path_join(conf_file, false, L"etc", L"web.conf", NULL); + ex_path_join(conf_file, false, L"etc", L"web.ini", NULL); m_www_path = m_exec_path; ex_path_join(m_www_path, true, L"..", L"..", L"..", L"..", L"server", L"www", NULL); @@ -53,7 +53,7 @@ bool TsEnv::init(void) ExIniFile cfg; if (!cfg.LoadFromFile(conf_file)) { - EXLOGE("[tpweb] can not load web.conf.\n"); + EXLOGE("[tpweb] can not load web.ini.\n"); return false; } diff --git a/server/www/teleport/.idea/teleport.iml b/server/www/teleport/.idea/teleport.iml index a57301b..7de5a86 100644 --- a/server/www/teleport/.idea/teleport.iml +++ b/server/www/teleport/.idea/teleport.iml @@ -11,7 +11,7 @@ - + diff --git a/server/www/teleport/app/eom_app/app/configs.py b/server/www/teleport/app/eom_app/app/configs.py index 1299ccc..28dca7c 100644 --- a/server/www/teleport/app/eom_app/app/configs.py +++ b/server/www/teleport/app/eom_app/app/configs.py @@ -2,13 +2,14 @@ import os import sys +import configparser from eom_common.eomcore.logger import log __all__ = ['app_cfg'] -class SwxDict(dict): +class AttrDict(dict): """ 可以像属性一样访问字典的 Key,var.key 等同于 var['key'] """ @@ -24,154 +25,112 @@ class SwxDict(dict): self[name] = val -def swx_dict(obj): - """ - 将一个对象中的dict转变为EomDict类型 - """ - if isinstance(obj, dict): - ret = SwxDict() - for k in obj: - # ret[k] = obj[k] - if isinstance(obj[k], dict): - ret[k] = swx_dict(obj[k]) - else: - ret[k] = obj[k] - else: - ret = obj - return ret +# def attr_dict(obj): +# """ +# 将一个对象中的dict转变为AttrDict类型 +# """ +# if isinstance(obj, dict): +# ret = AttrDict() +# for k in obj: +# # ret[k] = obj[k] +# if isinstance(obj[k], dict): +# ret[k] = attr_dict(obj[k]) +# else: +# ret[k] = obj[k] +# else: +# ret = obj +# return ret -class ConfigFile(SwxDict): +class ConfigFile(AttrDict): def __init__(self, **kwargs): super().__init__(**kwargs) # self.__file_name = None # self.__save_indent = 0 # self.__loaded = False - def load_str(self, module, code): - m = type(sys)(module) - m.__module_class__ = type(sys) - m.__file__ = module - + def load(self, cfg_file): + if not os.path.exists(cfg_file): + log.e('configuration file does not exists.') + return False try: - exec(compile(code, module, 'exec'), m.__dict__) - except Exception as e: - log.e('%s\n' % str(e)) - # print(str(e)) - # if eom_dev_conf.debug: - # raise + _cfg = configparser.ConfigParser() + _cfg.read(cfg_file) + except: + log.e('can not load configuration file.') return False - for y in m.__dict__: - if '__' == y[:2]: - continue - if isinstance(m.__dict__[y], dict): - self[y] = SwxDict() - self._assign_dict(m.__dict__[y], self[y]) - else: - self[y] = m.__dict__[y] + if 'common' not in _cfg: + log.e('invalid configuration file.') + return False + + _comm = _cfg['common'] + self['server_port'] = _comm.getint('port', 7190) + self['log_file'] = _comm.get('log-file', None) + if self['log_file'] is not None: + self['log_path'] = os.path.dirname(self['log_file']) return True - def load(self, full_path, must_exists=True): - try: - f = open(full_path, encoding='utf8') - code = f.read() - f.close() - self.__loaded = True - except IOError: - if must_exists: - log.e('Can not load config file: %s\n' % full_path) - return False + # def load_str(self, module, code): + # m = type(sys)(module) + # m.__module_class__ = type(sys) + # m.__file__ = module + # + # try: + # exec(compile(code, module, 'exec'), m.__dict__) + # except Exception as e: + # log.e('%s\n' % str(e)) + # # print(str(e)) + # # if eom_dev_conf.debug: + # # raise + # return False + # + # for y in m.__dict__: + # if '__' == y[:2]: + # continue + # if isinstance(m.__dict__[y], dict): + # self[y] = AttrDict() + # self._assign_dict(m.__dict__[y], self[y]) + # else: + # self[y] = m.__dict__[y] + # + # return True + # + # def _load(self, full_path, must_exists=True): + # try: + # f = open(full_path, encoding='utf8') + # code = f.read() + # f.close() + # self.__loaded = True + # except IOError: + # if must_exists: + # log.e('Can not load config file: %s\n' % full_path) + # return False + # + # module = os.path.basename(full_path) + # if not self.load_str(module, code): + # return False + # + # self.__file_name = full_path + # return True + # + # def _assign_dict(self, _from, _to): + # for y in _from: + # if isinstance(_from[y], dict): + # _to[y] = AttrDict() + # self._assign_dict(_from[y], _to[y]) + # else: + # _to[y] = _from[y] + # - module = os.path.basename(full_path) - if not self.load_str(module, code): - return False - - self.__file_name = full_path - return True - - """ - def save(self, filename=None): - if filename is None and not self.__loaded: - # log.w('Can not save config file without file name.\n') - return False - _file_name = filename - if _file_name is None: - _file_name = self.__file_name - if _file_name is None: - log.e('Do not known which file to save to.\n') - return False - - # 排序后保存 - m = [(k, self[k]) for k in sorted(self.keys())] - - self.__save_indent = 0 - s = self._save(m) - - # 尝试加载生成的要保存的配置字符串,如果加载成功,则保存到文件,否则报错 - x = ConfigFile() - if not x.load_str('_eom_tmp_cfg_data_', s): - log.e('Cannot generate config for save.\n') - return False - - f = open(_file_name, 'w') - f.write('# -*- coding: utf-8 -*-\n\n') - f.write(s) - f.close() - return True - - def _save(self, var): - s = '' - for (k, v) in var: - if self.__save_indent == 0 and k.find('_ConfigFile__') == 0: - # 本类的成员变量不用保存 - continue - - if isinstance(v, dict): - if self.__save_indent > 0: - s += "\n%s'%s' : {\n" % ('\t' * self.__save_indent, k) - else: - s += "\n%s%s = {\n" % ('\t' * self.__save_indent, k) - - self.__save_indent += 1 - m = [(x, v[x]) for x in sorted(v.keys())] - s += self._save(m) - self.__save_indent -= 1 - if self.__save_indent > 0: - s += "%s},\n\n" % ('\t' * self.__save_indent) - else: - s += "%s}\n\n" % ('\t' * self.__save_indent) - - else: - if isinstance(v, str): - val = "'%s'" % v.replace("'", "\\'") - else: - val = v - - if self.__save_indent > 0: - s += "%s'%s' : %s,\n" % ('\t' * self.__save_indent, k, val) - else: - s += "%s%s = %s\n" % ('\t' * self.__save_indent, k, val) - return s - """ - - def _assign_dict(self, _from, _to): - for y in _from: - if isinstance(_from[y], dict): - _to[y] = SwxDict() - self._assign_dict(_from[y], _to[y]) - else: - _to[y] = _from[y] - - -_cfg = ConfigFile() +_g_cfg = ConfigFile() del ConfigFile def app_cfg(): - global _cfg - return _cfg + global _g_cfg + return _g_cfg if __name__ == '__main__': diff --git a/server/www/teleport/app/eom_app/app/core.py b/server/www/teleport/app/eom_app/app/core.py index aa320e4..9d44897 100644 --- a/server/www/teleport/app/eom_app/app/core.py +++ b/server/www/teleport/app/eom_app/app/core.py @@ -7,7 +7,6 @@ import tornado.ioloop import tornado.netutil import tornado.process import tornado.web -# from eom_app.controller import controllers # from eom_common.eomcore.eom_mysql import get_mysql_pool from eom_common.eomcore.eom_sqlite import get_sqlite_pool @@ -15,6 +14,7 @@ import eom_common.eomcore.utils as utils from eom_common.eomcore.logger import log from .configs import app_cfg from .session import swx_session + cfg = app_cfg() @@ -28,10 +28,16 @@ class SwxCore: cfg.dev_mode = options['dev_mode'] - if 'log_path' not in options: + if not self._load_config(options): return False - else: - cfg.log_path = options['log_path'] + + if cfg.log_file is None: + if 'log_path' not in options: + return False + else: + cfg.log_path = options['log_path'] + + cfg.log_file = os.path.join(cfg.log_path, 'tpweb.log') if not os.path.exists(cfg.log_path): utils.make_dir(cfg.log_path) @@ -39,14 +45,13 @@ class SwxCore: log.e('Can not create log path.\n') return False + log.set_attribute(filename=cfg.log_file) + if 'app_path' not in options: return False else: cfg.app_path = options['app_path'] - if not self._load_config(options): - return False - if 'static_path' in options: cfg.static_path = options['static_path'] else: @@ -92,7 +97,7 @@ class SwxCore: else: _cfg_path = os.path.join(options['app_path'], 'conf') - _cfg_file = os.path.join(_cfg_path, 'web.conf') + _cfg_file = os.path.join(_cfg_path, 'web.ini') if not cfg.load(_cfg_file): return False @@ -238,9 +243,9 @@ class SwxCore: log.e('Can not listen on port {}, maybe it been used by another application.\n'.format(cfg.server_port)) return 0 - if not cfg.dev_mode: - log_file = os.path.join(cfg.log_path, 'ts-web.log') - log.set_attribute(console=False, filename=log_file) + # if not cfg.dev_mode: + # log_file = os.path.join(cfg.log_path, 'ts-web.log') + # log.set_attribute(console=False, filename=log_file) tornado.ioloop.IOLoop.instance().start() return 0 diff --git a/server/www/teleport/app/eom_common/eomcore/logger.py b/server/www/teleport/app/eom_common/eomcore/logger.py index e4d8555..f7c78f8 100644 --- a/server/www/teleport/app/eom_common/eomcore/logger.py +++ b/server/www/teleport/app/eom_common/eomcore/logger.py @@ -10,11 +10,25 @@ __all__ = ['log', 'CR_DEBUG', 'CR_VERBOSE', 'CR_INFO', 'CR_WARN', 'CR_ERROR', 'LOG_DEBUG', 'LOG_VERBOSE', 'LOG_INFO', 'LOG_WARN', 'LOG_ERROR', 'TRACE_ERROR_NONE', 'TRACE_ERROR_FULL'] -LOG_DEBUG = 1 -LOG_VERBOSE = 10 -LOG_INFO = 20 -LOG_WARN = 30 -LOG_ERROR = 99 +LOG_DEBUG = 0 +LOG_VERBOSE = 1 +LOG_INFO = 2 +LOG_WARN = 3 +LOG_ERROR = 4 + +USE_TPWEB_LOG = True + +try: + import tpweb + + LOG_DEBUG = tpweb.EX_LOG_LEVEL_DEBUG + LOG_VERBOSE = tpweb.EX_LOG_LEVEL_VERBOSE + LOG_INFO = tpweb.EX_LOG_LEVEL_INFO + LOG_WARN = tpweb.EX_LOG_LEVEL_WARN + LOG_ERROR = tpweb.EX_LOG_LEVEL_ERROR +except ImportError: + print('can not import tpweb.') + USE_TPWEB_LOG = False TRACE_ERROR_NONE = 0 TRACE_ERROR_FULL = 999999 @@ -71,9 +85,6 @@ COLORS = { } -# env = eomcore.env.get_env() - - class EomLogger: """ 日志记录模块,支持输出到控制台及文件。 @@ -83,8 +94,13 @@ class EomLogger: """ def __init__(self): + atexit.register(self.finalize) + self._locker = threading.RLock() + # self._sep = ' ' + # self._end = '\n' + self._min_level = LOG_INFO # 大于等于此值的日志信息才会记录 self._trace_error = TRACE_ERROR_NONE # 记录错误信息时,是否追加记录调用栈 self._log_datetime = True # 是否记录日志时间 @@ -93,17 +109,20 @@ class EomLogger: self._win_color = None - self.d = self._func_debug - self.v = self._func_verbose - self.i = self._func_info - self.w = self._func_warn - self.e = self._func_error + if USE_TPWEB_LOG: + self._do_log = self._do_log_tpweb + else: + self._do_log = self._do_log_local + + # self.d = self._log_debug + # self.v = self._log_verbose + # self.i = self._log_info + # self.w = self._log_warn + # self.e = self._log_error self._set_console(True) self._set_level(self._min_level) - atexit.register(self.finalize) - def initialize(self): pass @@ -138,28 +157,28 @@ class EomLogger: return True def _set_level(self, level): - self.d = self._func_debug - self.v = self._func_verbose - self.i = self._func_info - self.w = self._func_warn - # self.e = self._func_error + self.d = self._log_debug + self.v = self._log_verbose + self.i = self._log_info + self.w = self._log_warn + self.e = self._log_error if LOG_DEBUG == level: pass elif LOG_VERBOSE == level: - self.d = self._func_pass + self.d = self._log_pass elif LOG_INFO == level: - self.d = self._func_pass - self.v = self._func_pass + self.d = self._log_pass + self.v = self._log_pass elif LOG_WARN == level: - self.d = self._func_pass - self.v = self._func_pass - self.i = self._func_pass + self.d = self._log_pass + self.v = self._log_pass + self.i = self._log_pass elif LOG_ERROR == level: - self.d = self._func_pass - self.v = self._func_pass - self.i = self._func_pass - self.w = self._func_pass + self.d = self._log_pass + self.v = self._log_pass + self.i = self._log_pass + self.w = self._log_pass pass else: pass @@ -218,33 +237,92 @@ class EomLogger: return True + def _log_pass(self, *args, **kwargs): + pass + + def _log_debug(self, *args, **kwargs): + self._do_log(LOG_DEBUG, *args, **kwargs) + + def _log_verbose(self, *args, **kwargs): + self._do_log(LOG_VERBOSE, *args, **kwargs) + + def _log_info(self, *args, **kwargs): + self._do_log(LOG_INFO, *args, **kwargs) + + def _log_warn(self, *args, **kwargs): + self._do_log(LOG_WARN, *args, **kwargs) + + def _log_error(self, *args, **kwargs): + self._do_log(LOG_ERROR, *args, **kwargs) + + def _do_log_tpweb(self, level, *args, **kwargs): + # sep = kwargs['sep'] if 'sep' in kwargs else self._sep + # end = kwargs['end'] if 'end' in kwargs else self._end + + # first = True + for x in args: + # if not first: + # tpweb.log_output(level, sep) + + first = False + if isinstance(x, str): + tpweb.log_output(level, x) + continue + + else: + tpweb.log_output(level, x.__str__()) + + # tpweb.log_output(level, end) + + def _do_log_local(self, level, *args, **kwargs): + if level < self._min_level: + return + + # sep = kwargs['sep'] if 'sep' in kwargs else self._sep + # end = kwargs['end'] if 'end' in kwargs else self._end + # first = True + for x in args: + # if not first: + # sys.stdout.writelines(sep) + + first = False + if isinstance(x, str): + sys.stdout.writelines(x) + continue + + else: + sys.stdout.writelines(x.__str__()) + + # sys.stdout.writelines(end) + sys.stdout.flush() + def log(self, msg, color=None): """ 自行指定颜色,输出到控制台(不会输出到日志文件),且输出时不含时间信息 """ self._do_log(msg, color=color, show_datetime=False) - def _func_pass(self, msg, color=None): - # do nothing. - pass - - def _func_debug(self, msg): - # 调试输出的数据,在正常运行中不会输出 - self._do_log(msg, CR_DEBUG) - - # 普通的日志数据 - def _func_verbose(self, msg): - # pass - self._do_log(msg, None) - - # 重要信息 - def _func_info(self, msg): - self._do_log(msg, CR_INFO) - - # 警告 - def _func_warn(self, msg): - self._do_log(msg, CR_WARN) + # def _func_pass(self, msg, color=None): + # # do nothing. + # pass + # + # def _func_debug(self, msg): + # # 调试输出的数据,在正常运行中不会输出 + # self._do_log(msg, CR_DEBUG) + # # 普通的日志数据 + # def _func_verbose(self, msg): + # # pass + # self._do_log(msg, None) + # + # # 重要信息 + # def _func_info(self, msg): + # self._do_log(msg, CR_INFO) + # + # # 警告 + # def _func_warn(self, msg): + # self._do_log(msg, CR_WARN) + # def _func_error(self, msg): """错误 """ @@ -315,7 +393,7 @@ class EomLogger: m += '.' m += '\n' - self.log(m, CR_DEBUG) + self._log_debug(m) if loop > 0: x += 1 @@ -342,25 +420,25 @@ class EomLogger: m += '.' m += '\n' - self.log(m, CR_DEBUG) + self._log_debug(m) - def _do_log(self, msg, color=None, show_datetime=True): - with self._locker: - now = time.localtime(time.time()) - _log_time = '[{:04d}-{:02d}-{:02d} {:02d}:{:02d}:{:02d}] '.format(now.tm_year, now.tm_mon, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec) - - try: - if show_datetime and self._log_datetime: - msg = '{}{}'.format(_log_time, msg) - self._log_console(msg, color) - else: - self._log_console(msg, color) - msg = '{}{}'.format(_log_time, msg) - - self._log_file(msg) - - except IOError: - pass + # def _do_log(self, msg, color=None, show_datetime=True): + # with self._locker: + # now = time.localtime(time.time()) + # _log_time = '[{:04d}-{:02d}-{:02d} {:02d}:{:02d}:{:02d}] '.format(now.tm_year, now.tm_mon, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec) + # + # try: + # if show_datetime and self._log_datetime: + # msg = '{}{}'.format(_log_time, msg) + # self._log_console(msg, color) + # else: + # self._log_console(msg, color) + # msg = '{}{}'.format(_log_time, msg) + # + # self._log_file(msg) + # + # except IOError: + # pass def _console_default(self, msg, color=None): """ @@ -482,46 +560,6 @@ class EomLogger: self._set_level(LOG_DEBUG) self._trace_error = TRACE_ERROR_FULL - self.log('###################', CR_NORMAL) - self.log(' CR_NORMAL\n') - self.log('###################', CR_BLACK) - self.log(' CR_BLACK\n') - self.log('###################', CR_LIGHT_GRAY) - self.log(' CR_LIGHT_GRAY\n') - self.log('###################', CR_GRAY) - self.log(' CR_GRAY\n') - self.log('###################', CR_WHITE) - self.log(' CR_WHITE\n') - self.log('###################', CR_RED) - self.log(' CR_RED\n') - self.log('###################', CR_GREEN) - self.log(' CR_GREEN\n') - self.log('###################', CR_YELLOW) - self.log(' CR_YELLOW\n') - self.log('###################', CR_BLUE) - self.log(' CR_BLUE\n') - self.log('###################', CR_MAGENTA) - self.log(' CR_MAGENTA\n') - self.log('###################', CR_CYAN) - self.log(' CR_CYAN\n') - self.log('###################', CR_LIGHT_RED) - self.log(' CR_LIGHT_RED\n') - self.log('###################', CR_LIGHT_GREEN) - self.log(' CR_LIGHT_GREEN\n') - self.log('###################', CR_LIGHT_YELLOW) - self.log(' CR_LIGHT_YELLOW\n') - self.log('###################', CR_LIGHT_BLUE) - self.log(' CR_LIGHT_BLUE\n') - self.log('###################', CR_LIGHT_MAGENTA) - self.log(' CR_LIGHT_MAGENTA\n') - self.log('###################', CR_LIGHT_CYAN) - self.log(' CR_LIGHT_CYAN\n') - data = b'This is a test string and you can see binary format data here.' - self.bin('Binary Data:\n', data) - data = b'' - self.bin('Empty binary\n', data) - self.bin('This is string\n\n', 'data') - self.d('This is DEBUG message.\n') self.v('This is VERBOSE message.\n') self.i('This is INFORMATION message.\n') @@ -530,6 +568,12 @@ class EomLogger: self.v('test auto\nsplited lines.\nYou should see\nmulti-lines.\n') + data = b'This is a test string and you can see binary format data here.' + self.bin('Binary Data:\n', data) + data = b'' + self.bin('Empty binary\n', data) + self.bin('This is string\n\n', 'data') + class Win32DebugView: def __init__(self): @@ -615,6 +659,8 @@ class Win32ColorConsole: log = EomLogger() del EomLogger +log._test() + import builtins builtins.__dict__['print'] = log._log_print diff --git a/server/www/teleport/view/log/record.mako b/server/www/teleport/view/log/record.mako index cb59d2c..146da2e 100644 --- a/server/www/teleport/view/log/record.mako +++ b/server/www/teleport/view/log/record.mako @@ -10,18 +10,18 @@ <%block name="breadcrumb">
- - + + - - 状态:正在获取数据 + + 状态:正在获取数据 总时长:未知