LmeSzinc / AzurLaneAutoScript

Azur Lane bot (CN/EN/JP/TW) 碧蓝航线脚本 | 无缝委托科研,全自动大世界
https://alas.azurlane.cloud
GNU General Public License v3.0
6.9k stars 826 forks source link

Critical errors localization | 关键错误的本地化 #1683

Open LmeSzinc opened 2 years ago

LmeSzinc commented 2 years ago

Is your feature request related to a problem?

因为有一些用户就是不看log中给的提示

Describe the solution you'd like

Python code:

logger.critical(RESOLUTION_NOT_SUPPORTED(width, height))

Expected logs in zh-CN:

CRITICAL | RESOLUTION_NOT_SUPPORTED(1600, 900)
CRITICAL | 不支持分辨率 1600x900
CRITICAL | 请将模拟器分辨率设置为 1280x720

Expected logs in en-US:

CRITICAL | RESOLUTION_NOT_SUPPORTED('1600x900')
CRITICAL | Resolution not supported: 1600x900
CRITICAL | Please set emulator resolution to 1280x720

Should also support logging errors without arguments:

logger.critical(AUTO_SERIES_CANNOT_WORK_ON_MULTIPLE_DEVICES)

Expected logs in zh-CN:

CRITICAL | AUTO_SERIES_CANNOT_WORK_ON_MULTIPLE_DEVICES
CRITICAL | 找到多个设备,自动设备检测无法决定要连接哪个设备,
请复制上面列出的设备之一到 Alas - 模拟器设置 - 模拟器 Serial

Expected logs in en-US:

CRITICAL | AUTO_SERIES_CANNOT_WORK_ON_MULTIPLE_DEVICES
CRITICAL | Multiple devices found, auto device detection cannot decide which to choose, 
please copy one of the available devices listed above to Alas - Emulator Settings - Serial

Additional context

No response

snowly233 commented 1 year ago

exception.zip 只修改了exception,其他CRITICAL的路径没找到,是我要修改alas.py吗

snowly233 commented 1 year ago

alas.zip alas.py也已修改

LmeSzinc commented 1 year ago

这个 issue 已经过去几个月了,需求也产生了一些变化,目前是希望将 warning, error, critical 三个级别的 log 都做本地化,并且有一些更细节的要求:

  1. 尽量保持原代码不变。也就是原代码还是保持英文原文,但是实际打印的时候跟随客户端的语言设置。具体方法简单讨论的结果是正则替换,还没想到更好的办法。
    logger.critical(f'Resolution not supported: {width}x{height}, please set emulator resolution to 1280x720')
  2. 不可以打印全语言的 log。也就是如果用户设置的是英文,不能打印除英文以外的内容,否则可能出现编码问题导致崩溃,这个bug常见于一些日语系统。
  3. 尽量减轻后续维护成本,假如我希望增加一句新的 logger.warning("This is English"),那么我就在代码里写 logger.warning("This is English") 再在翻译文件里写 这是中文这是繁体中文,不需要添加更多内容

这个功能工作量不小的,包括建立整个框架,翻译所有的现有log

Horizon101011 commented 1 year ago

尽量保持原代码不变。也就是原代码还是保持英文原文,但是实际打印的时候跟随客户端的语言设置。具体方法简单讨论的结果是正则替换,还没想到更好的办法。

logger.critical(f'Resolution not supported: {width}x{height}, please set emulator resolution to 1280x720')

结合实现难度和讨论的结果,目前的方案是将f-string分离成占位符format的形式,如上例中的log,将会被修改为

logger.critical(f'Resolution not supported: {0}x{1}, please set emulator resolution to 1280x720', [width, height])

对于不同语言之间的语序问题,可以通过修改编号索引的位置来调整,但是编号索引存在意义不明的弊端 如果改用命名索引,由于log中的f-string并不都是{variable}的形式,存在一小部分的{expr},这些可能需要人工的干预或者一套更好的方案,例如:

logger.warning('History click: {0}', [[str(prev) for prev in self.click_record]])
logger.warning("Wrong Prediction. {0} = '{1}'", [self.grids[loca], grid.str])
logger.warning('Convert radar to local, but current fleet not found. '
'Assuming camera center is current fleet: {0}', [location2node(self.view.center_loca)])
logger.critical('Unexpected item group \'{0}\'; '
'expected one of {1}', [group, SELECT_ITEM_INFO_MAP.keys()])

随后通过引入装饰器来实现格式化,一个简单的示例如下

def translate(func):
def wrapper(msg, format_table=None, *args, **kwargs):
msg = i18n(msg)
if format_table:
return func(msg.format(*format_table), *args, **kwargs)
else:
return func(msg, *args, **kwargs)
return wrapper
logger.critical = translate(logger.critical)

log的修改工作都将交由抽取器来完成 log_extract.zip (目前是编号索引方案) 翻译部分将由msg = i18n(msg)来完成,需要维护翻译表/文件,查找并替换文本 暂定的翻译方案是对msg设计一个哈希函数,通过哈希值去查找翻译表并完成文本的替换 接下来的工作就是如何去维护翻译文件的结构,以及实现、完善包括装饰器和翻译函数在内的具体细节