1#!/usr/bin/env python3 2# coding=utf-8 3 4# 5# Copyright (c) 2020-2022 Huawei Device Co., Ltd. 6# Licensed under the Apache License, Version 2.0 (the "License"); 7# you may not use this file except in compliance with the License. 8# You may obtain a copy of the License at 9# 10# http://www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, software 13# distributed under the License is distributed on an "AS IS" BASIS, 14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15# See the License for the specific language governing permissions and 16# limitations under the License. 17# 18import types 19from queue import Queue 20 21from _core.error import ErrorMessage 22from _core.interface import IParser 23from _core.logger import platform_logger 24from _core.report.encrypt import check_pub_key_exist 25 26__all__ = ["ShellHandler"] 27 28LOG = platform_logger("ParserLite") 29 30 31class ShellHandler: 32 def __init__(self, parsers): 33 self.parsers = [] 34 self.unfinished_line = "" 35 self.output_queue = Queue() 36 self.process_output_methods = [] 37 for parser in parsers: 38 if isinstance(parser, IParser): 39 self.parsers.append(parser) 40 else: 41 raise TypeError(ErrorMessage.InterfaceImplement.Code_0102007.format(parser)) 42 43 def _process_output(self, output, end_mark="\n"): 44 if self.process_output_methods and \ 45 callable(self.process_output_methods[0]): 46 method = self.process_output_methods[0] 47 return method(self, output, end_mark) 48 else: 49 content = output 50 if self.unfinished_line: 51 content = "".join((self.unfinished_line, content)) 52 self.unfinished_line = "" 53 lines = content.split(end_mark) 54 if content.endswith(end_mark): 55 # get rid of the tail element of this list contains empty str 56 return lines[:-1] 57 else: 58 self.unfinished_line = lines[-1] 59 # not return the tail element of this list contains unfinished 60 # str, so we set position -1 61 return lines 62 63 def add_process_method(self, func): 64 if isinstance(func, types.FunctionType): 65 self.process_output_methods.clear() 66 self.process_output_methods.append(func) 67 68 def __read__(self, output): 69 lines = self._process_output(output) 70 for line in lines: 71 for parser in self.parsers: 72 try: 73 parser.__process__([line]) 74 except (ValueError, TypeError, SyntaxError, AttributeError) \ 75 as error: 76 LOG.debug("Parse %s line error: %s" % (line, error)) 77 78 def __error__(self, message): 79 if message: 80 for parser in self.parsers: 81 parser.__process__([message]) 82 83 def __done__(self, result_code="", message=""): 84 msg_fmt = "" 85 if message: 86 msg_fmt = ", message is {}".format(message) 87 for parser in self.parsers: 88 parser.__process__([message]) 89 if not check_pub_key_exist(): 90 LOG.debug("Result code is: {}{}".format(result_code, msg_fmt)) 91 for parser in self.parsers: 92 parser.__done__() 93