Difficult-Rocket/Difficult_Rocket/utils/translate.py

222 lines
8.0 KiB
Python
Raw Normal View History

2021-09-08 23:38:34 +08:00
# -------------------------------
# Difficult Rocket
2023-01-20 14:08:12 +08:00
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
2021-09-08 23:38:34 +08:00
# All rights reserved
# -------------------------------
2021-09-02 22:47:10 +08:00
"""
2022-11-26 21:48:55 +08:00
writen by shenjackyuanjie <3695888@qq.com>
2021-09-02 22:47:10 +08:00
mail: 3695888@qq.com
github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""
2022-07-01 13:59:08 +08:00
import inspect
2023-01-03 16:24:06 +08:00
from dataclasses import dataclass
from typing import Union, Tuple, Any, Type, List, Dict, Hashable, Optional
2022-08-12 21:07:36 +08:00
from Difficult_Rocket import DR_runtime, DR_option
2022-04-26 22:05:58 +08:00
from Difficult_Rocket.utils import tools
2022-07-04 10:36:19 +08:00
from Difficult_Rocket.exception.language import *
2022-11-26 22:45:30 +08:00
2023-01-03 16:24:06 +08:00
@dataclass
class TranslateConfig:
2023-01-16 18:34:17 +08:00
raise_error: bool = False # 引用错误时抛出错误
crack_normal: bool = False # 出现错误引用后 将引用到的正确内容替换为引用路径
insert_crack: bool = True # 加入引用的错误内容
is_final: bool = False # 是否为最终内容
keep_get: bool = True # 引用错误后是否继续引用
always_copy: bool = False # 是否一直新建 Translate (为 True 会降低性能)
2023-01-03 16:24:06 +08:00
def set(self, item: str, value: bool) -> 'TranslateConfig':
assert getattr(self, item, None) is not None, f'Config {item} is not in TranslateConfig'
assert type(value) is bool
setattr(self, item, value)
return self
def __copy__(self) -> 'TranslateConfig':
return TranslateConfig(raise_error=self.raise_error,
crack_normal=self.crack_normal,
insert_crack=self.insert_crack,
is_final=self.is_final,
2023-01-16 18:34:17 +08:00
keep_get=self.keep_get,
always_copy=self.always_copy)
def copy(self) -> 'TranslateConfig':
return self.__copy__()
2023-01-03 16:24:06 +08:00
2023-01-16 18:34:17 +08:00
key_type = Union[str, int, Hashable]
2022-11-26 23:35:49 +08:00
class Translates:
2023-01-06 20:01:34 +08:00
name = 'Translate'
2023-01-19 16:34:06 +08:00
def __init__(self, value: Union[Dict[str, Any], list, tuple, str],
2023-01-03 16:24:06 +08:00
config: Optional[TranslateConfig] = None,
2023-01-19 16:34:06 +08:00
get_list: Optional[List[Tuple[bool, str]]] = None):
""" 一个用于翻译的东西
2022-11-27 13:45:59 +08:00
:param value: 翻译键节点
:param config: 配置
:param get_list: 获取列表
2022-11-27 13:45:59 +08:00
"""
2022-11-26 22:45:30 +08:00
self.value: Union[Dict[str, Any], list, tuple] = value
2023-01-03 16:24:06 +08:00
self.config = config or TranslateConfig()
2022-11-26 22:45:30 +08:00
self.get_list = get_list or []
2023-01-03 16:24:06 +08:00
2023-01-16 18:34:17 +08:00
def set_conf_(self, option: Union[str, TranslateConfig],
value: Optional[Union[bool, List[str]]] = None) -> 'Translates':
2023-01-19 16:34:06 +08:00
assert isinstance(option, (TranslateConfig, str))
2023-01-03 16:24:06 +08:00
if isinstance(option, TranslateConfig):
self.config = option
return self
self.config.set(option, value)
2023-01-16 18:34:17 +08:00
return self
def _raise_no_value(self, e: Exception, item: key_type):
if self.config.raise_error:
raise TranslateKeyNotFound(self.value, [x[1] for x in self.get_list]) from None
2023-01-24 23:59:07 +08:00
elif DR_option.report_translate_not_found:
2023-01-16 18:34:17 +08:00
frame = inspect.currentframe()
if frame is not None:
frame = frame.f_back
if frame.f_back.f_code is not self.__getattr__.__code__:
frame = frame.f_back
frame = f'call at {frame.f_code.co_filename}:{frame.f_lineno}'
else:
frame = 'but No Frame environment'
raise_info = f"{self.name} Cause a error when getting {item} {frame}"
print(raise_info)
2022-11-26 22:45:30 +08:00
2023-01-19 16:34:06 +08:00
def __getitem__(self, item: key_type) -> "Translates":
2022-11-26 22:45:30 +08:00
try:
2023-01-16 18:34:17 +08:00
cache_value = self.value[item]
2023-01-19 16:34:06 +08:00
if isinstance(cache_value, (int, str,)):
self.config.is_final = True
2023-01-16 18:34:17 +08:00
self.get_list.append((True, item))
if self.config.always_copy:
2023-01-19 16:34:06 +08:00
return Translates(value=cache_value, config=self.config, get_list=self.get_list)
self.value = cache_value
return self
2023-01-16 18:34:17 +08:00
except (KeyError, TypeError, AttributeError) as e:
self.get_list.append((False, item))
self._raise_no_value(e, item)
2023-01-19 16:34:06 +08:00
if not self.config.keep_get:
self.config.is_final = True
2023-01-16 18:34:17 +08:00
2023-01-19 16:34:06 +08:00
def copy(self):
return self.__copy__()
2023-01-16 18:34:17 +08:00
def __copy__(self) -> 'Translates':
2023-01-19 16:34:06 +08:00
return Translates(value=self.value, config=self.config, get_list=self.get_lists)
2022-11-26 21:48:55 +08:00
2023-01-19 16:34:06 +08:00
def __getattr__(self, item: key_type) -> "Translates":
2023-01-05 21:36:47 +08:00
# 实际上我这里完全不需要处理正常需求,因为 __getattribute__ 已经帮我处理过了
2022-11-26 21:48:55 +08:00
return self.__getitem__(item)
def __str__(self):
2023-01-19 16:34:06 +08:00
if self.config.crack_normal:
return f'{".".join(f"{gets[1]}({gets[0]})" for gets in self.get_list)}'
elif self.config.insert_crack:
return f'{self.value}.{".".join(gets[1] for gets in self.get_list if not gets[0])}'
return self.value
2022-11-26 21:48:55 +08:00
2021-09-02 22:47:10 +08:00
2022-07-01 13:59:08 +08:00
class Tr:
"""
2023-01-16 18:34:17 +08:00
我不装了我就抄了tr(实际上没啥关系)
2022-08-16 13:25:44 +08:00
GOOD
2022-07-01 13:59:08 +08:00
"""
2023-01-03 16:24:06 +08:00
def __init__(self, language: str = None, config: Optional[TranslateConfig] = None):
2022-12-08 09:53:22 +08:00
"""
诶嘿我抄的MCDR
:param language: Tr 所使用的的语言
:param config: 配置
2022-12-08 09:53:22 +08:00
"""
2022-11-27 13:45:59 +08:00
self.language_name = language or DR_runtime.language
2023-01-19 16:34:06 +08:00
self.translates: Dict[str,] = tools.load_file(f'configs/lang/{self.language_name}.toml')
2022-11-26 21:48:55 +08:00
self.default_translate: Dict = tools.load_file(f'configs/lang/{DR_runtime.default_language}.toml')
self.default_config = config or TranslateConfig()
self.translates_cache = Translates(value=self.translates, config=TranslateConfig().copy())
2023-01-03 16:24:06 +08:00
2023-01-05 21:36:47 +08:00
def __getattr__(self, item) -> Translates:
...
def __getitem__(self, item: Union[str, int]):
return self.__getattr__(item)
2022-07-04 10:36:19 +08:00
2022-07-01 13:59:08 +08:00
2021-09-02 22:47:10 +08:00
class Lang:
"""
用于创建一个对应语言的翻译类
感谢Fallen的MCDR提供idea
https://github.com/Fallen-Breath/MCDReforged
可以用
lang['language'] = 'abc'
lang['lang'] = 'abc'
的方式直接更改并刷新翻译
lang.lang(xxx, xxx)来获取翻译过的值
2021-09-02 22:47:10 +08:00
"""
2021-09-05 00:50:05 +08:00
2022-08-12 21:07:36 +08:00
def __init__(self) -> None:
2022-11-26 21:48:55 +08:00
self.translates = tools.load_file(f'configs/lang/{DR_runtime.language}.toml')
self.default_translates = tools.load_file('configs/lang/zh-CN.toml')
2022-06-14 20:52:03 +08:00
self.直接返回原始数据 = True
2021-09-02 22:47:10 +08:00
def __str__(self) -> str:
2022-08-12 21:07:36 +08:00
return DR_option.language
2021-09-02 22:47:10 +08:00
2021-10-22 06:36:06 +08:00
def __getitem__(self, item) -> Union[int, str, list, dict]:
try:
2022-11-26 21:48:55 +08:00
return self.translates[item]
except KeyError:
try:
2022-11-26 21:48:55 +08:00
return self.default_translates[item]
except KeyError:
2023-01-03 16:24:06 +08:00
raise TranslateKeyNotFound
# raise TranslateKeyNotFound(f'there\'s no key {item} in both {DR_option.language} and zh-CN')
2022-12-08 09:53:22 +08:00
def lang(self, *args) -> Union[int, str, list, dict, tuple]:
2022-07-04 10:36:19 +08:00
# frame = inspect.currentframe()
# # print("调用当前log的文件名:", frame.f_back.f_code.co_filename)
# objprint.objprint(frame.f_back.f_code,
# honor_existing=False,
# depth=2)
try:
2022-11-26 21:48:55 +08:00
result = self.translates
for option in args:
result = result[option]
return result
except KeyError:
try:
2022-11-26 21:48:55 +08:00
result = self.default_translates
for option in args:
result = result[option]
return result
except KeyError as e:
2022-06-14 20:52:03 +08:00
if self.直接返回原始数据:
return args
2023-01-03 16:24:06 +08:00
raise TranslateKeyNotFound from e
# raise TranslateKeyNotFound(f'there\'s no key {args} in both {DR_option.language} and zh-CN') from e
2021-10-22 06:36:06 +08:00
def 翻译(self, *args) -> Union[int, str, list, dict]:
return self.lang(args)
2022-08-12 21:07:36 +08:00
def _update_lang(self) -> str:
"""
用于更新语言(内部调用)
2022-11-26 21:48:55 +08:00
:return: 设置完成后的语言
2022-08-12 21:07:36 +08:00
"""
2022-11-26 21:48:55 +08:00
self.translates = tools.load_file(f'configs/lang/{DR_option.language}.toml')
2022-08-12 21:07:36 +08:00
return DR_option.language
2023-01-19 16:45:40 +08:00
if __name__ == '__main__':
2022-11-27 13:45:59 +08:00
tr_ = Tr()
2023-01-19 16:45:40 +08:00
else:
tr = Lang()