• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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