From d1d0d4367250f2b2279623d8faca6281fa8d1f4f Mon Sep 17 00:00:00 2001 From: dnomd343 Date: Tue, 2 Aug 2022 13:48:09 +0800 Subject: [PATCH] style: optimize code and log output --- Basis/Check.py | 6 +++--- Basis/Compile.py | 2 +- Basis/Functions.py | 12 +++++------ Basis/Logger.py | 4 ++-- Basis/Process.py | 26 +++++++++++------------ Builder/Brook.py | 2 +- Builder/Hysteria.py | 34 +++++++++++++++++------------- Builder/Shadowsocks.py | 11 ++++------ Builder/ShadowsocksR.py | 2 +- Builder/Trojan.py | 7 ++++--- Builder/TrojanGo.py | 46 ++++++++++++++++++++++------------------- Builder/VLESS.py | 9 ++++---- Builder/VMess.py | 2 +- Builder/Xray.py | 4 ++-- Tester/VMess.py | 7 +++---- main.py | 1 - 16 files changed, 91 insertions(+), 84 deletions(-) diff --git a/Basis/Check.py b/Basis/Check.py index 57b6ec9..6fff046 100644 --- a/Basis/Check.py +++ b/Basis/Check.py @@ -23,14 +23,14 @@ def Check(taskId: str, taskInfo: dict) -> dict: except Exception as reason: logging.error('[%s] Client build error -> %s' % (taskId, reason)) raise RuntimeError('Client build error') - logging.info('[%s] Client loaded successfully') + logging.info('[%s] Client loaded successfully' % taskId) # TODO: wait port occupied (client.socksPort) time.sleep(1) if not client.status(): # client unexpected exit - logging.warning('[%s] Client unexpected exit') + logging.warning('[%s] Client unexpected exit' % taskId) client.destroy() # remove file and kill sub process - logging.debug('[%s] Client output\n%s', client.output) + logging.debug('[%s] Client output\n%s', (taskId, client.output)) raise RuntimeError('Client unexpected exit') checkResult = Checker(taskId, taskInfo['check'], { diff --git a/Basis/Compile.py b/Basis/Compile.py index e084edf..22aea3d 100644 --- a/Basis/Compile.py +++ b/Basis/Compile.py @@ -7,5 +7,5 @@ from Basis.Logger import logging def startCompile(dirRange: str = '/') -> None: for optimize in [-1, 1, 2]: - logging.warning('python optimize compile -> %s (level = %i)' % (dirRange, optimize)) + logging.warning('Python optimize compile -> %s (level = %i)' % (dirRange, optimize)) compileall.compile_dir(dirRange, quiet = 1, maxlevels = 256, optimize = optimize) diff --git a/Basis/Functions.py b/Basis/Functions.py index 437fbfd..ffb0565 100644 --- a/Basis/Functions.py +++ b/Basis/Functions.py @@ -32,7 +32,7 @@ def genFlag(length: int = 12) -> str: # generate random task flag flag += chr(tmp + 87) # a ~ f else: flag += str(tmp) # 0 ~ 9 - logging.debug('generate new flag -> ' + flag) + logging.debug('Generate new flag -> ' + flag) return flag @@ -44,21 +44,21 @@ def genUUID() -> str: # generate uuid v5 def getAvailablePort(rangeStart: int = 1024, rangeEnd: int = 65535, waitTime: int = 10) -> int: # get available port if rangeStart > rangeEnd or rangeStart < 1 or rangeEnd > 65535: - raise RuntimeError('invalid port range') + raise RuntimeError('Invalid port range') while True: port = random.randint(rangeStart, rangeEnd) # choose randomly if checkPortStatus(port): - logging.debug('get new port -> %i' % port) + logging.debug('Get new port -> %i' % port) return port time.sleep(waitTime / 1000) # ms -> s (default 10ms) def checkPortStatus(port: int) -> bool: # check if the port is occupied - logging.debug('check status of port %i -> available' % port) for connection in networkStatus(): # scan every connections if connection['local']['port'] == port: # port occupied (whatever ipv4-tcp / ipv4-udp / ipv6-tcp / ipv6-udp) - logging.debug('check status of port %i -> occupied' % port) + logging.debug('Check port %i -> occupied' % port) return False + logging.debug('Check port %i -> available' % port) return True @@ -84,5 +84,5 @@ def networkStatus() -> list: # get all network connections 'status': connection.status, 'pid': connection.pid, # process id }) - logging.debug('get network status -> found %i connections' % len(result)) + logging.debug('Network status -> found %i connections' % len(result)) return result diff --git a/Basis/Logger.py b/Basis/Logger.py index 383cee2..764bf9e 100644 --- a/Basis/Logger.py +++ b/Basis/Logger.py @@ -6,8 +6,8 @@ import logging from colorlog import ColoredFormatter logFile = 'runtime.log' -logLevel = logging.DEBUG -# logLevel = logging.WARNING +# logLevel = logging.DEBUG +logLevel = logging.WARNING dateFormat = '%Y-%m-%d %H:%M:%S' logFormat = '[%(asctime)s] [%(levelname)s] %(message)s (%(module)s.%(funcName)s)' logging.basicConfig( diff --git a/Basis/Process.py b/Basis/Process.py index 2df40d3..c2f134a 100644 --- a/Basis/Process.py +++ b/Basis/Process.py @@ -73,13 +73,13 @@ class Process(object): logging.error('[%s] %s already exist but not folder' % (self.id, self.workDir)) else: logging.error('[%s] Unable to create new folder -> %s' % (self.id, self.workDir)) - raise RuntimeError('working directory error') # fatal error + raise RuntimeError('Working directory error') # fatal error def __killProcess(self, killSignal: int) -> None: try: pgid = os.getpgid(self.__process.pid) # progress group id os.killpg(pgid, killSignal) # kill sub process group - logging.debug('[%s] Send kill signal to PGID %i' % (self.id, pgid)) + logging.debug('[%s] Send signal %i to PGID %i' % (self.id, killSignal, pgid)) except: logging.warning('[%s] Failed to get PGID of sub process (PID = %i)' % (self.id, self.__process.pid)) @@ -129,15 +129,15 @@ class Process(object): def start(self, isCapture: bool = True) -> None: self.__capture = isCapture - logging.debug('[%s] Process ready to start (%s)' % (self.id, ( - 'with output capture' if self.__capture else 'without output capture' - ))) + logging.debug('[%s] Process ready to start (%s)' % ( + self.id, ('with' if self.__capture else 'without') + ' output capture' + )) if self.cmd is None: # ERROR CASE logging.error('[%s] Process miss start command' % self.id) - raise RuntimeError('miss start command') + raise RuntimeError('Miss start command') if self.__process is not None and self.__process.poll() is None: # ERROR CASE - logging.error('[%s] Sub process is still running' % self.id) - raise RuntimeError('sub process is still running') + logging.error('[%s] Process is still running' % self.id) + raise RuntimeError('Process is still running') if self.env is not None and 'PATH' not in self.env and '/' not in self.cmd[0]: # WARNING CASE logging.warning('[%s] Executable file in relative path but miss PATH in environ' % self.id) if self.file is not None: # create and write file contents @@ -147,7 +147,7 @@ class Process(object): logging.debug('[%s] File %s -> %s' % (self.id, file['path'], file['content'])) if self.__capture: # with output capture self.__logfile = os.path.join(self.workDir, self.id + '.log') - logging.debug('[%s] Output capture file -> %s' % (self.id, self.__logfile)) + logging.debug('[%s] Process output capture -> %s' % (self.id, self.__logfile)) stdout = open(self.__logfile, 'w', encoding = 'utf-8') stderr = STDOUT # combine the stderr with stdout else: # discard all the output of sub process @@ -170,20 +170,20 @@ class Process(object): def status(self) -> bool: # check if the sub process is still running status = self.__process.poll() is None - logging.debug('[%s] Check status -> %s' % (self.id, 'running' if status else 'exit')) + logging.debug('[%s] Process check status -> %s' % (self.id, 'running' if status else 'exit')) return status def wait(self, timeout: int or None = None) -> None: # blocking wait sub process logging.info('[%s] Process wait -> timeout = %s' % (self.id, str(timeout))) try: self.__process.wait(timeout = timeout) - logging.info('[%s] Process wait timeout -> sub process exit' % self.id) + logging.info('[%s] Process wait timeout -> exit' % self.id) except: - logging.info('[%s] Process wait timeout -> sub process still running' % self.id) + logging.info('[%s] Process wait timeout -> running' % self.id) def quit(self, isForce: bool = False, waitTime: int = 50) -> None: # wait 50ms in default killSignal = signal.SIGKILL if isForce else signal.SIGTERM # 9 -> force kill / 15 -> terminate signal - logging.debug('[%s] Kill signal = %i (%s)' % (self.id, killSignal, signal.Signals(killSignal).name)) + logging.debug('[%s] Kill signal -> %i (%s)' % (self.id, killSignal, signal.Signals(killSignal).name)) self.__killProcess(killSignal) time.sleep(waitTime / 1000) # sleep (ms -> s) while self.__process.poll() is None: # confirm sub process exit diff --git a/Builder/Brook.py b/Builder/Brook.py index 2154d65..ab2940b 100644 --- a/Builder/Brook.py +++ b/Builder/Brook.py @@ -35,4 +35,4 @@ def load(proxyInfo: dict, socksInfo: dict, configFile: str) -> tuple[list, str, }[proxyInfo['stream']['type']](proxyInfo) + [ '--socks5', '%s:%i' % (hostFormat(socksInfo['addr'], v6Bracket = True), socksInfo['port']) ] - return brookCommand, 'Config file %s no need' % configFile, {} + return brookCommand, 'Config file %s no need' % configFile, {} # command, fileContent, envVar diff --git a/Builder/Hysteria.py b/Builder/Hysteria.py index 2840a0b..4f4be18 100644 --- a/Builder/Hysteria.py +++ b/Builder/Hysteria.py @@ -6,7 +6,7 @@ from Basis.Functions import hostFormat def load(proxyInfo: dict, socksInfo: dict, configFile: str) -> tuple[list, str, dict]: - hysteriaConfig = {**{ + hysteriaConfig = { 'server': '%s:%i' % (hostFormat(proxyInfo['server'], v6Bracket = True), proxyInfo['port']), 'protocol': proxyInfo['protocol'], 'up_mbps': proxyInfo['up'], @@ -15,16 +15,22 @@ def load(proxyInfo: dict, socksInfo: dict, configFile: str) -> tuple[list, str, 'retry': 3, 'socks5': { 'listen': '%s:%i' % (hostFormat(socksInfo['addr'], v6Bracket = True), socksInfo['port']) - } - }, **({} if proxyInfo['obfs'] is None else { - 'obfs': proxyInfo['obfs'] - }), **({} if proxyInfo['passwd'] is None else { - 'auth_str': proxyInfo['passwd'] - }), **({} if proxyInfo['sni'] == '' else { - 'server_name': proxyInfo['sni'] - }), **({} if proxyInfo['alpn'] is None else { - 'alpn': proxyInfo['alpn'] - }), **({} if proxyInfo['verify'] else { - 'insecure': True - })} - return ['hysteria', '-c', configFile, 'client'], json.dumps(hysteriaConfig), {'LOGGING_LEVEL': 'trace'} + }, + **({} if proxyInfo['obfs'] is None else { + 'obfs': proxyInfo['obfs'] + }), + **({} if proxyInfo['passwd'] is None else { + 'auth_str': proxyInfo['passwd'] + }), + **({} if proxyInfo['sni'] == '' else { + 'server_name': proxyInfo['sni'] + }), + **({} if proxyInfo['alpn'] is None else { + 'alpn': proxyInfo['alpn'] + }), + **({} if proxyInfo['verify'] else { + 'insecure': True + }) + } + return ['hysteria', '-c', configFile, 'client'], \ + json.dumps(hysteriaConfig), {'LOGGING_LEVEL': 'trace'} # command, fileContent, envVar diff --git a/Builder/Shadowsocks.py b/Builder/Shadowsocks.py index aa71a50..c985a60 100644 --- a/Builder/Shadowsocks.py +++ b/Builder/Shadowsocks.py @@ -72,12 +72,9 @@ def ssPythonLegacy(proxyInfo: dict, socksInfo: dict, isUdp: bool) -> tuple[dict, def load(proxyInfo: dict, socksInfo: dict, configFile: str) -> tuple[list, str, dict]: - if proxyInfo['plugin'] is None: # UDP is enabled when server without plugin - isUdp = True - else: - isUdp = not pluginUdp( # check the UDP conflict status of plugins - proxyInfo['plugin']['type'], proxyInfo['plugin']['param'] - ) + isUdp = True if proxyInfo['plugin'] is None else ( # UDP enabled when server without plugin + not pluginUdp(proxyInfo['plugin']['type'], proxyInfo['plugin']['param']) # UDP conflict status of plugins + ) if proxyInfo['method'] not in ssAllMethods: # unknown shadowsocks method raise RuntimeError('Unknown shadowsocks method') for client in ssMethods: # traverse all shadowsocks client @@ -89,4 +86,4 @@ def load(proxyInfo: dict, socksInfo: dict, configFile: str) -> tuple[list, str, 'ss-python': ssPython, 'ss-python-legacy': ssPythonLegacy }[client](proxyInfo, socksInfo, isUdp) # generate config file - return ssClient + ['-c', configFile], json.dumps(ssConfig), {} # tuple[command, fileContent, envVar] + return ssClient + ['-c', configFile], json.dumps(ssConfig), {} # command, fileContent, envVar diff --git a/Builder/ShadowsocksR.py b/Builder/ShadowsocksR.py index 170cf27..8155da6 100644 --- a/Builder/ShadowsocksR.py +++ b/Builder/ShadowsocksR.py @@ -24,4 +24,4 @@ def load(proxyInfo: dict, socksInfo: dict, configFile: str) -> tuple[list, str, 'obfs': proxyInfo['obfs'], 'obfs_param': proxyInfo['obfsParam'] } - return ['ssr-local', '-vv', '-c', configFile], json.dumps(ssrConfig), {} # tuple[command, fileContent, envVar] + return ['ssr-local', '-vv', '-c', configFile], json.dumps(ssrConfig), {} # command, fileContent, envVar diff --git a/Builder/Trojan.py b/Builder/Trojan.py index e9078fe..b6aaa5e 100644 --- a/Builder/Trojan.py +++ b/Builder/Trojan.py @@ -9,13 +9,14 @@ def load(proxyInfo: dict, socksInfo: dict, configFile: str) -> tuple[list, str, outboundConfig = { 'protocol': 'trojan', 'settings': { - 'servers': [{**{ + 'servers': [{ 'address': proxyInfo['server'], 'port': proxyInfo['port'], 'password': proxyInfo['passwd'], - }, **Xray.xtlsFlow(proxyInfo['stream'])}] + **Xray.xtlsFlow(proxyInfo['stream']) + }] }, 'streamSettings': Xray.loadStream(proxyInfo['stream']) } trojanConfig = Xray.loadConfig(socksInfo, outboundConfig) # load config file for xray-core - return ['xray', '-c', configFile], json.dumps(trojanConfig), {} + return ['xray', '-c', configFile], json.dumps(trojanConfig), {} # command, fileContent, envVar diff --git a/Builder/TrojanGo.py b/Builder/TrojanGo.py index ed6eeb8..0ba1f4a 100644 --- a/Builder/TrojanGo.py +++ b/Builder/TrojanGo.py @@ -5,13 +5,15 @@ import json def sslConfig(proxyInfo: dict) -> dict: - return {**{ - 'verify': proxyInfo['verify'] - }, **({} if proxyInfo['sni'] == '' else { - 'sni': proxyInfo['sni'] - }), **({} if proxyInfo['alpn'] is None else { - 'alpn': proxyInfo['alpn'].split(',') - })} + return { + 'verify': proxyInfo['verify'], + **({} if proxyInfo['sni'] == '' else { + 'sni': proxyInfo['sni'] + }), + **({} if proxyInfo['alpn'] is None else { + 'alpn': proxyInfo['alpn'].split(',') + }), + } def wsConfig(proxyInfo: dict) -> dict: @@ -27,22 +29,24 @@ def wsConfig(proxyInfo: dict) -> dict: def ssConfig(proxyInfo: dict) -> dict: - return {**{ - 'enabled': False if proxyInfo['ss'] is None else True - }, **({} if proxyInfo['ss'] is None else { - 'method': proxyInfo['ss']['method'], - 'password': proxyInfo['ss']['passwd'], - })} + return { + 'enabled': False if proxyInfo['ss'] is None else True, + **({} if proxyInfo['ss'] is None else { + 'method': proxyInfo['ss']['method'], + 'password': proxyInfo['ss']['passwd'], + }) + } def pluginConfig(proxyInfo: dict) -> dict: - return {**{ - 'enabled': False if proxyInfo['plugin'] is None else True - }, **({} if proxyInfo['plugin'] is None else { - 'type': 'shadowsocks', - 'command': proxyInfo['plugin']['type'], - 'option': proxyInfo['plugin']['param'], - })} + return { + 'enabled': False if proxyInfo['plugin'] is None else True, + **({} if proxyInfo['plugin'] is None else { + 'type': 'shadowsocks', + 'command': proxyInfo['plugin']['type'], + 'option': proxyInfo['plugin']['param'], + }) + } def load(proxyInfo: dict, socksInfo: dict, configFile: str) -> tuple[list, str, dict]: @@ -61,4 +65,4 @@ def load(proxyInfo: dict, socksInfo: dict, configFile: str) -> tuple[list, str, 'shadowsocks': ssConfig(proxyInfo), 'transport_plugin': pluginConfig(proxyInfo), } - return ['trojan-go', '-config', configFile], json.dumps(trojanGoConfig), {} + return ['trojan-go', '-config', configFile], json.dumps(trojanGoConfig), {} # command, fileContent, envVar diff --git a/Builder/VLESS.py b/Builder/VLESS.py index e91522f..3180801 100644 --- a/Builder/VLESS.py +++ b/Builder/VLESS.py @@ -12,13 +12,14 @@ def load(proxyInfo: dict, socksInfo: dict, configFile: str) -> tuple[list, str, 'vnext': [{ 'address': proxyInfo['server'], 'port': proxyInfo['port'], - 'users': [{**{ + 'users': [{ 'id': proxyInfo['id'], - 'encryption': proxyInfo['method'] - }, **Xray.xtlsFlow(proxyInfo['stream'])}] + 'encryption': proxyInfo['method'], + **Xray.xtlsFlow(proxyInfo['stream']) + }] }] }, 'streamSettings': Xray.loadStream(proxyInfo['stream']) } vlessConfig = Xray.loadConfig(socksInfo, outboundConfig) # load config file for xray-core - return ['xray', '-c', configFile], json.dumps(vlessConfig), {} + return ['xray', '-c', configFile], json.dumps(vlessConfig), {} # command, fileContent, envVar diff --git a/Builder/VMess.py b/Builder/VMess.py index 230fca7..76076ad 100644 --- a/Builder/VMess.py +++ b/Builder/VMess.py @@ -25,4 +25,4 @@ def load(proxyInfo: dict, socksInfo: dict, configFile: str) -> tuple[list, str, 'streamSettings': V2ray.loadStream(proxyInfo['stream']) } vmessConfig = V2ray.loadConfig(socksInfo, outboundConfig) # load config file for v2ray-core - return ['v2ray', '-c', configFile], json.dumps(vmessConfig), {} + return ['v2ray', '-c', configFile], json.dumps(vmessConfig), {} # command, fileContent, envVar diff --git a/Builder/Xray.py b/Builder/Xray.py index 9f3a538..bde216c 100644 --- a/Builder/Xray.py +++ b/Builder/Xray.py @@ -34,9 +34,9 @@ def wsStream(streamInfo: dict) -> dict: # WebSocket stream config (different ed wsObject['headers']['Host'] = streamInfo['host'] if streamInfo['ed'] is not None: # ed value into uri path -> /...?ed=xxx if wsObject['path'].find('?') == -1: # no params in raw path - wsObject['path'] += '?ed=' + str(streamInfo['ed']) + wsObject['path'] += '?ed=%i' % streamInfo['ed'] else: - wsObject['path'] += '&ed=' + str(streamInfo['ed']) + wsObject['path'] += '&ed=%i' % streamInfo['ed'] return { 'network': 'ws', 'wsSettings': wsObject diff --git a/Tester/VMess.py b/Tester/VMess.py index 52d1b95..daffe63 100644 --- a/Tester/VMess.py +++ b/Tester/VMess.py @@ -6,11 +6,10 @@ import json import itertools from Tester import V2ray from Builder import VMess -from Builder import pathEnv from Basis.Logger import logging from Basis.Process import Process from Tester.Settings import Settings -from Basis.Constant import vmessMethods +from Basis.Constant import PathEnv, vmessMethods from Basis.Functions import md5Sum, genUUID, getAvailablePort @@ -31,8 +30,8 @@ def loadServer(configFile: str, proxyInfo: dict, streamConfig: dict) -> Process: return Process(Settings['workDir'], cmd = ['v2ray', '-c', serverFile], file = { 'path': serverFile, 'content': json.dumps(vmessConfig) - }, env= { - 'PATH': pathEnv, + }, env = { + 'PATH': PathEnv, 'v2ray.vmess.aead.forced': 'false' # enable non-aead test (aid not 0) }, isStart = False) diff --git a/main.py b/main.py index 21d00f5..d9bcbe0 100755 --- a/main.py +++ b/main.py @@ -50,7 +50,6 @@ def loopCheck() -> None: try: taskId, taskInfo = Manager.popTask() except: - logging.debug('no more task') continue logging.info('new task %s -> %s' % (taskId, taskInfo)) ret = Check(taskId, taskInfo)