Remove | DR same with lib-not-dr
This commit is contained in:
parent
3cc59ca8c3
commit
9e9c7d5e16
@ -4,18 +4,64 @@
|
||||
# All rights reserved
|
||||
# -------------------------------
|
||||
|
||||
from Difficult_Rocket.utils.options import (Options,
|
||||
FontData,
|
||||
Fonts,
|
||||
OptionsError,
|
||||
OptionNameNotDefined,
|
||||
OptionNotFound,
|
||||
get_type_hints_)
|
||||
from typing import Dict, Union
|
||||
from dataclasses import dataclass
|
||||
|
||||
from libs.lib_not_dr.types.options import (Options,
|
||||
OptionsError,
|
||||
OptionNameNotDefined,
|
||||
OptionNotFound,
|
||||
get_type_hints_)
|
||||
from libs.MCDR.version import (Version,
|
||||
VersionRequirement,
|
||||
VersionParsingError)
|
||||
|
||||
|
||||
class Fonts(Options):
|
||||
# font's value
|
||||
|
||||
HOS: str = 'HarmonyOS Sans'
|
||||
HOS_S: str = 'HarmonyOS Sans SC'
|
||||
HOS_T: str = 'HarmonyOS Sans TC'
|
||||
HOS_C: str = 'HarmonyOS Sans Condensed'
|
||||
|
||||
鸿蒙字体: str = HOS
|
||||
鸿蒙简体: str = HOS_S
|
||||
鸿蒙繁体: str = HOS_T
|
||||
鸿蒙窄体: str = HOS_C
|
||||
|
||||
CC: str = 'Cascadia Code'
|
||||
CM: str = 'Cascadia Mono'
|
||||
CCPL: str = 'Cascadia Code PL'
|
||||
CMPL: str = 'Cascadia Mono PL'
|
||||
|
||||
微软等宽: str = CC
|
||||
微软等宽无线: str = CM
|
||||
微软等宽带电线: str = CCPL
|
||||
微软等宽带电线无线: str = CMPL
|
||||
|
||||
得意黑: str = '得意黑'
|
||||
# SS = smiley-sans
|
||||
SS: str = 得意黑
|
||||
|
||||
|
||||
@dataclass
|
||||
class FontData:
|
||||
""" 用于保存字体的信息 """
|
||||
font_name: str = Fonts.鸿蒙简体
|
||||
font_size: int = 13
|
||||
bold: bool = False
|
||||
italic: bool = False
|
||||
stretch: bool = False
|
||||
|
||||
def dict(self) -> Dict[str, Union[str, int, bool]]:
|
||||
return dict(font_name=self.font_name,
|
||||
font_size=self.font_size,
|
||||
bold=self.bold,
|
||||
italic=self.italic,
|
||||
stretch=self.stretch)
|
||||
|
||||
|
||||
__all__ = [
|
||||
# main class
|
||||
'Options',
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
__all__ = [
|
||||
'camera',
|
||||
'options',
|
||||
'thread',
|
||||
'tools',
|
||||
'translate'
|
||||
|
@ -1,320 +0,0 @@
|
||||
# -------------------------------
|
||||
# Difficult Rocket
|
||||
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
||||
# All rights reserved
|
||||
# -------------------------------
|
||||
|
||||
import shutil
|
||||
import traceback
|
||||
from io import StringIO
|
||||
from dataclasses import dataclass
|
||||
from typing import get_type_hints, Type, List, Union, Dict, Any, Callable, Tuple, Optional, TYPE_CHECKING, Iterable
|
||||
|
||||
__all__ = [
|
||||
'get_type_hints_',
|
||||
'Options',
|
||||
'OptionsError',
|
||||
'OptionNotFound',
|
||||
'OptionNameNotDefined',
|
||||
'Fonts',
|
||||
'FontData'
|
||||
]
|
||||
|
||||
|
||||
def get_type_hints_(cls: Type):
|
||||
try:
|
||||
return get_type_hints(cls)
|
||||
except ValueError:
|
||||
return get_type_hints(cls, globalns={})
|
||||
|
||||
|
||||
def to_str_value_(value: Any) -> Any:
|
||||
"""递归的将输入值的每一个非 builtin type 转换成 str"""
|
||||
if isinstance(value, (str, bytes, bytearray, int, float, bool, type(None))):
|
||||
return value
|
||||
elif isinstance(value, dict):
|
||||
return {k: to_str_value_(v) for k, v in value.items()}
|
||||
elif isinstance(value, (list, Iterable)):
|
||||
return [to_str_value_(v) for v in value]
|
||||
else:
|
||||
return str(value)
|
||||
|
||||
|
||||
class OptionsError(Exception):
|
||||
""" option 的错误基类"""
|
||||
|
||||
|
||||
class OptionNameNotDefined(OptionsError):
|
||||
""" 向初始化的 option 里添加了一个不存在于选项里的选项 """
|
||||
|
||||
|
||||
class OptionNotFound(OptionsError):
|
||||
""" 某个选项没有找到 """
|
||||
|
||||
|
||||
class Options:
|
||||
"""
|
||||
一个用于存储选项 / 提供 API 定义 的类
|
||||
用法:
|
||||
存储配置: 继承 Options 类
|
||||
在类里定义 option: typing
|
||||
(可选 定义 name: str = 'Option Base' 用于在打印的时候显示名字)
|
||||
提供 API 接口: 继承 Options 类
|
||||
在类里定义 option: typing
|
||||
定义 一些需要的方法
|
||||
子类: 继承 新的 Options 类
|
||||
实现定义的方法
|
||||
"""
|
||||
name = 'Option Base'
|
||||
cached_options: Dict[str, Union[str, Any]] = {}
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
"""
|
||||
创建一个新的 Options 的时候的配置
|
||||
如果存在 init 方法 会在设置完 kwargs 之后运行子类的 init 方法
|
||||
:param kwargs: 需要设置的选项
|
||||
"""
|
||||
if TYPE_CHECKING:
|
||||
self._options: Dict[str, Union[Callable, object]] = {}
|
||||
self.flush_option()
|
||||
for option, value in kwargs.items():
|
||||
if option not in self.cached_options:
|
||||
raise OptionNameNotDefined(f"option: {option} with value: {value} is not defined")
|
||||
setattr(self, option, value)
|
||||
run_load_file = True
|
||||
if hasattr(self, 'init'):
|
||||
run_load_file = self.init(**kwargs) # 默认 False/None
|
||||
run_load_file = not run_load_file
|
||||
if hasattr(self, 'load_file') and run_load_file:
|
||||
try:
|
||||
self.load_file()
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
self.flush_option()
|
||||
|
||||
def __str__(self):
|
||||
return f"<{self.__class__.__name__} {self.name}>" if self.name else f"<{self.__class__.__name__}>"
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
if TYPE_CHECKING:
|
||||
_options: Dict[str, Union[Callable, object]] = {}
|
||||
|
||||
def init(self, **kwargs) -> bool:
|
||||
""" 如果子类定义了这个函数,则会在 __init__ 之后调用这个函数
|
||||
返回值为 True 则不会调用 load_file 函数
|
||||
"""
|
||||
#
|
||||
|
||||
def load_file(self) -> bool:
|
||||
"""如果子类定义了这个函数,则会在 __init__ 和 init 之后再调用这个函数
|
||||
|
||||
请注意,这个函数请尽量使用 try 包裹住可能出现错误的部分
|
||||
否则会在控制台输出你的报错"""
|
||||
return True
|
||||
|
||||
def option(self) -> Dict[str, Any]:
|
||||
"""
|
||||
获取配置类的所有配置
|
||||
:return: 自己的所有配置
|
||||
"""
|
||||
values = {}
|
||||
for ann in self.__annotations__: # 获取类型注释
|
||||
values[ann] = getattr(self, ann, None)
|
||||
if values[ann] is None:
|
||||
values[ann] = self.__annotations__[ann]
|
||||
|
||||
if not hasattr(self, '_options'):
|
||||
self._options: Dict[str, Union[Callable, object]] = {}
|
||||
for option, a_fun in self._options.items(): # 获取额外内容
|
||||
values[option] = a_fun
|
||||
|
||||
for option, a_fun in values.items(): # 检查是否为 property
|
||||
if a_fun is bool and getattr(self, option, None) is not None:
|
||||
values[option] = False
|
||||
if isinstance(a_fun, property):
|
||||
try:
|
||||
values[option] = getattr(self, option)
|
||||
except AttributeError:
|
||||
raise OptionNotFound(f'Option {option} is not found in {self.name}') from None
|
||||
return values
|
||||
|
||||
def str_option(self, shrink_to_long: Optional[int] = None) -> Dict[str, Union[str, Any]]:
|
||||
"""
|
||||
获取配置类的所有配置 并将所有非 BuiltIn 类型的值转换为 str
|
||||
:return:
|
||||
"""
|
||||
raw_option = self.option()
|
||||
str_option = to_str_value_(raw_option)
|
||||
if shrink_to_long is None:
|
||||
return str_option
|
||||
if not isinstance(shrink_to_long, int) or shrink_to_long <= 0:
|
||||
return str_option
|
||||
for option, value in str_option.items():
|
||||
if value is not None:
|
||||
if len(str(value)) > shrink_to_long:
|
||||
str_option[option] = str(value)[:shrink_to_long] + '...'
|
||||
return str_option
|
||||
|
||||
def format(self, text: str) -> str:
|
||||
"""
|
||||
使用自己的选项给输入的字符串替换内容
|
||||
:param text: 想替换的内容
|
||||
:return: 替换之后的内容
|
||||
"""
|
||||
cache_option = self.flush_option()
|
||||
for option, value in cache_option.items():
|
||||
text = text.replace(f'{{{option}}}', str(value))
|
||||
return text
|
||||
|
||||
def flush_option(self) -> Dict[str, Any]:
|
||||
"""
|
||||
刷新缓存 options 的内容
|
||||
:return: 刷新过的 options
|
||||
"""
|
||||
self.cached_options = self.option()
|
||||
return self.cached_options
|
||||
|
||||
def option_with_len(self) -> Tuple[List[Tuple[str, Any, Type]], int, int, int]:
|
||||
"""
|
||||
返回一个可以用于打印的 option 列表
|
||||
:return:
|
||||
"""
|
||||
options = self.flush_option()
|
||||
max_len_key = 1
|
||||
max_len_value = 1
|
||||
max_len_value_t = 1
|
||||
option_list = []
|
||||
for key, value in options.items():
|
||||
value_t = type(value) if isinstance(value, type(value)) else type(value) # 判定这个类型 是不是 基本类型
|
||||
max_len_key = max(max_len_key, len(key))
|
||||
max_len_value = max(max_len_value, len(str(value)))
|
||||
max_len_value_t = max(max_len_value_t, len(str(value_t)))
|
||||
option_list.append([key, value, value_t])
|
||||
return [option_list, max_len_key, max_len_value, max_len_value_t] # noqa
|
||||
|
||||
def as_markdown(self, longest: Optional[int] = None) -> str:
|
||||
"""
|
||||
返回一个 markdown 格式的 option 字符串
|
||||
:param longest: 最长的输出长度
|
||||
:return: markdown 格式的 option 字符串
|
||||
"""
|
||||
value = self.option_with_len()
|
||||
cache = StringIO()
|
||||
option_len = max(value[1], len('Option'))
|
||||
value_len = max(value[2], len('Value'))
|
||||
value_type_len = max(value[3], len('Value Type'))
|
||||
|
||||
# | Option | Value | Value Type |
|
||||
shortest = len('Option | Value | Value Type')
|
||||
|
||||
if longest is not None:
|
||||
console_width = max(longest, shortest)
|
||||
else:
|
||||
console_width = shutil.get_terminal_size(fallback=(100, 80)).columns
|
||||
console_width = max(console_width, shortest)
|
||||
|
||||
# 为每一栏 预分配 1/3 或者 需要的宽度 (如果不需要 1/3)
|
||||
option_len = min(option_len, console_width // 3)
|
||||
value_len = min(value_len, console_width // 3)
|
||||
value_type_len = min(value_type_len, console_width // 3)
|
||||
|
||||
# 先指定每一个列的输出最窄宽度, 然后去尝试增加宽度
|
||||
# 循环分配新空间之前 首先检查是否已经不需要多分配 (and 后面)
|
||||
while option_len + value_len + value_type_len + 16 < console_width\
|
||||
and (option_len < value[1]
|
||||
or value_len < value[2]
|
||||
or value_type_len < value[3]):
|
||||
# 每一个部分的逻辑都是
|
||||
# 如果现在的输出长度小于原始长度
|
||||
# 并且长度 + 1 之后的总长度依然在允许范围内
|
||||
# 那么就 + 1
|
||||
if option_len < value[1] and option_len + value_len + value_type_len + 16 < console_width:
|
||||
option_len += 1
|
||||
if value_len < value[2] and option_len + value_len + value_type_len + 16 < console_width:
|
||||
value_len += 1
|
||||
if value_type_len < value[3] and option_len + value_len + value_type_len + 16 < console_width:
|
||||
value_type_len += 1
|
||||
# 实际上 对于列表(可变对象) for 出来的这个值是一个引用
|
||||
# 所以可以直接修改 string
|
||||
for v in value[0]:
|
||||
if len(str(v[0])) > option_len:
|
||||
v[0] = f'{str(v[0])[:value_len - 3]}...'
|
||||
if len(str(v[1])) > value_len:
|
||||
v[1] = f'{str(v[1])[:value_len - 3]}...'
|
||||
if len(str(v[2])) > value_type_len:
|
||||
v[2] = f'{str(v[2])[:value_len - 3]}..'
|
||||
|
||||
cache.write(
|
||||
f"| Option{' ' * (option_len - 3)}| Value{' ' * (value_len - 2)}| Value Type{' ' * (value_type_len - 7)}|\n")
|
||||
cache.write(f'|:{"-" * (option_len + 3)}|:{"-" * (value_len + 3)}|:{"-" * (value_type_len + 3)}|\n')
|
||||
for option, value, value_t in value[0]:
|
||||
cache.write(f"| `{option}`{' ' * (option_len - len(option))} "
|
||||
f"| `{value}`{' ' * (value_len - len(str(value)))} "
|
||||
f"| `{value_t}`{' ' * (value_type_len - len(str(value_t)))} |\n")
|
||||
result = cache.getvalue()
|
||||
cache.close()
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def add_option(cls, name: str, value: Union[Callable, object]) -> Dict:
|
||||
"""
|
||||
向配置类中添加一个额外的配置
|
||||
:param name: 配置的名字
|
||||
:param value: 用于获取配置的函数或者类
|
||||
:return: 配置类的所有配置
|
||||
"""
|
||||
if not hasattr(cls, '_options'):
|
||||
cls._options: Dict[str, Union[Callable, object]] = {}
|
||||
cls._options[name] = value
|
||||
return cls._options
|
||||
|
||||
@staticmethod
|
||||
def init_option(options_class: Type['Options'], init_value: Optional[dict] = None) -> 'Options':
|
||||
return options_class(**init_value if init_value is not None else {})
|
||||
|
||||
|
||||
class Fonts(Options):
|
||||
# font's value
|
||||
|
||||
HOS: str = 'HarmonyOS Sans'
|
||||
HOS_S: str = 'HarmonyOS Sans SC'
|
||||
HOS_T: str = 'HarmonyOS Sans TC'
|
||||
HOS_C: str = 'HarmonyOS Sans Condensed'
|
||||
|
||||
鸿蒙字体: str = HOS
|
||||
鸿蒙简体: str = HOS_S
|
||||
鸿蒙繁体: str = HOS_T
|
||||
鸿蒙窄体: str = HOS_C
|
||||
|
||||
CC: str = 'Cascadia Code'
|
||||
CM: str = 'Cascadia Mono'
|
||||
CCPL: str = 'Cascadia Code PL'
|
||||
CMPL: str = 'Cascadia Mono PL'
|
||||
|
||||
微软等宽: str = CC
|
||||
微软等宽无线: str = CM
|
||||
微软等宽带电线: str = CCPL
|
||||
微软等宽带电线无线: str = CMPL
|
||||
|
||||
得意黑: str = '得意黑'
|
||||
# SS = smiley-sans
|
||||
SS: str = 得意黑
|
||||
|
||||
|
||||
@dataclass
|
||||
class FontData:
|
||||
""" 用于保存字体的信息 """
|
||||
font_name: str = Fonts.鸿蒙简体
|
||||
font_size: int = 13
|
||||
bold: bool = False
|
||||
italic: bool = False
|
||||
stretch: bool = False
|
||||
|
||||
def dict(self) -> Dict[str, Union[str, int, bool]]:
|
||||
return dict(font_name=self.font_name,
|
||||
font_size=self.font_size,
|
||||
bold=self.bold,
|
||||
italic=self.italic,
|
||||
stretch=self.stretch)
|
12
libs/utils/logger/structer.md
Normal file
12
libs/utils/logger/structer.md
Normal file
@ -0,0 +1,12 @@
|
||||
# Logger
|
||||
|
||||
```
|
||||
[App -> Logger +-> Handler(Formatter)] -> Queue(string io) -> [File Output] ?
|
||||
|-> Handler(Formatter) -> Console Output]
|
||||
```
|
||||
|
||||
```
|
||||
[App -> Logger] -> Queue(raw log) -> [Facade +-> Handler(Formatter) -> File Output ] ?
|
||||
[ |-> Handler(Formatter) -> Console Output]
|
||||
```
|
||||
|
@ -29,5 +29,3 @@ class LogMessage(Options):
|
||||
stack_trace: Optional[FrameType] = None
|
||||
|
||||
|
||||
# [App -> Logger +-> Handler(Formatter)] -> Queue(log) -> [(File, Socket) Output] ?
|
||||
# |-> Handler(Formatter) -> Console Output
|
||||
|
@ -12,7 +12,7 @@ from dataclasses import dataclass
|
||||
from pyglet.image import load, AbstractImage
|
||||
|
||||
# Difficult Rocket
|
||||
from Difficult_Rocket.utils.options import Options
|
||||
from Difficult_Rocket.api.types import Options
|
||||
|
||||
|
||||
class SR1Textures(Options):
|
||||
|
Loading…
Reference in New Issue
Block a user