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 19 20from queue import Queue 21from _core.interface import IParser 22from _core.report.encrypt import check_pub_key_exist 23from _core.logger import platform_logger 24 25__all__ = ["ShellHandler"] 26 27LOG = platform_logger("ParserLite") 28 29 30class ShellHandler: 31 def __init__(self, parsers): 32 self.parsers = [] 33 self.unfinished_line = "" 34 self.output_queue = Queue() 35 self.process_output_methods = [] 36 for parser in parsers: 37 if isinstance(parser, IParser): 38 self.parsers.append(parser) 39 else: 40 raise TypeError( 41 "Parser {} must implement IOutputParser interface.".format( 42 parser, )) 43 44 def _process_output(self, output, end_mark="\n"): 45 if self.process_output_methods: 46 method = self.process_output_methods[0] 47 if callable(method): 48 return method(self, output, end_mark) 49 else: 50 content = output 51 if self.unfinished_line: 52 content = "".join((self.unfinished_line, content)) 53 self.unfinished_line = "" 54 lines = content.split(end_mark) 55 if content.endswith(end_mark): 56 # get rid of the tail element of this list contains empty str 57 return lines[:-1] 58 else: 59 self.unfinished_line = lines[-1] 60 # not return the tail element of this list contains unfinished str, 61 # so we set position -1 62 return lines 63 64 def add_process_method(self, func): 65 if isinstance(func, types.FunctionType): 66 self.process_output_methods.clear() 67 self.process_output_methods.append(func) 68 69 def __read__(self, output): 70 lines = self._process_output(output) 71 for line in lines: 72 for parser in self.parsers: 73 try: 74 parser.__process__([line]) 75 except (ValueError, TypeError, SyntaxError, AttributeError) \ 76 as error: 77 LOG.debug("Parse %s line error: %s" % (line, error)) 78 79 def __error__(self, message): 80 if message: 81 for parser in self.parsers: 82 parser.__process__([message]) 83 84 def __done__(self, result_code="", message=""): 85 msg_fmt = "" 86 if message: 87 msg_fmt = ", message is {}".format(message) 88 for parser in self.parsers: 89 parser.__process__([message]) 90 if not check_pub_key_exist(): 91 LOG.debug("Result code is: {}{}".format(result_code, msg_fmt)) 92 for parser in self.parsers: 93 parser.__done__() 94