1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3# Copyright (c) 2024 Huawei Device Co., Ltd.
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16import sys
17import typing
18import os
19import glob
20import re
21from pathlib import Path
22from typing import Text, Callable, Any, Iterator
23
24
25def unit_adaptive(size: int) -> str:
26    unit_list = ["Byte", "KB", "MB", "GB"]
27    index = 0
28    while index < len(unit_list) and size >= 1024:
29        size /= 1024
30        index += 1
31    if index == len(unit_list):
32        index = len(unit_list) - 1
33        size *= 1024
34    return str(round(size, 2)) + unit_list[index]
35
36
37class BasicTool:
38    @classmethod
39    def match_paragraph(cls, content: str, start_pattern: str = r"\w+\(\".*?\"\) *{", end_pattern: str = "\}") -> \
40            Iterator[re.Match]:
41        """
42        匹配代码段,支持单行
43        注意:ptrn中已经包含前面的空格,所以start_pattern中可以省略
44        :param content: 被匹配的字符串
45        :param start_pattern: 模式的开头
46        :param end_pattern: 模式的结尾
47        :return: 匹配到的段落的迭代器
48        """
49        ptrn = r'^( *){s}(?#匹配开头).*?(?#中间非贪婪)\1(?#如果开头前面有空格,则结尾的前面应该有相同数量的空格)?{e}$(?#匹配结尾)'.format(
50            s=start_pattern, e=end_pattern)
51        ptrn = re.compile(ptrn, re.M | re.S)
52        result = re.finditer(ptrn, content)
53        return result
54
55    @classmethod
56    def find_all_files(cls, folder: str, real_path: bool = True, apply_abs: bool = True, de_duplicate: bool = True,
57                       p_filter: typing.Callable = lambda x: True) -> list:
58        filepath_list = set()
59        for root, _, file_names in os.walk(folder):
60            filepath_list.update(
61                [os.path.abspath(os.path.realpath(
62                    os.path.join(root, f) if real_path else os.path.join(root, f))) if apply_abs else os.path.relpath(
63                    os.path.realpath(os.path.join(root, f) if real_path else os.path.join(root, f))) for f in file_names
64                 if p_filter(os.path.join(root, f))])
65        if de_duplicate:
66            filepath_list = set(filepath_list)
67        filepath_list = sorted(filepath_list, key=str.lower)
68        return filepath_list
69
70    @classmethod
71    def get_abs_path(cls, path: str) -> str:
72        return os.path.abspath(os.path.expanduser(path))
73
74    @classmethod
75    def re_group_1(cls, content: str, pattern: str, **kwargs) -> str:
76        """
77        匹配正则表达式,如果有匹配到内容,返回group(1)的内容
78        :param content: 要被匹配的内容
79        :param pattern: 进行匹配的模式
80        :return: 匹配到的结果(group(1))
81        TODO 对()的检查应该更严格
82        """
83        if not (r'(' in pattern and r')' in pattern):
84            raise ValueError("parentheses'()' must in the pattern")
85        result = re.search(pattern, content, **kwargs)
86        if result:
87            return result.group(1)
88        return str()
89
90    @classmethod
91    def execute(cls, cmd: str, post_processor: Callable[[Text], Text] = lambda x: x) -> Any:
92        """
93        封装popen,返回标准输出的列表
94        :param post_processor: 对执行结果进行处理
95        :param cmd: 待执行的命令
96        :return: 经处理过后的字符串列表
97
98        """
99        output = os.popen(cmd).read()
100        output = post_processor(output)
101        return output
102
103
104if __name__ == '__main__':
105    for i in BasicTool.find_all_files(".", apply_abs=False):
106        print(i)
107