diff --git a/README.md b/README.md index 57aef27d..7142046a 100644 --- a/README.md +++ b/README.md @@ -331,6 +331,10 @@ PS: **ARM平台** 请使用全量版 同时 **如果你的机器 RAM < 1G 可能 ## 更新 +### 2023/3/4 + +* 重写翻译,使用百度翻译API + ### 2023/3/2 * 修复config.yaml中把False也当成None的问题 [@pull/1288](https://github.com/HibiKier/zhenxun_bot/pull/1288) @@ -338,7 +342,7 @@ PS: **ARM平台** 请使用全量版 同时 **如果你的机器 RAM < 1G 可能 * 修复词云 * 修复我的签到签到图片 * 更正BuffSkin添加语句 -* 修复词条单 +* 修复词条单图片/表情/at无法添加 ### 2022/3/1 diff --git a/plugins/genshin/query_user/resin_remind/init_task.py b/plugins/genshin/query_user/resin_remind/init_task.py index 63d0b288..a87e9a83 100644 --- a/plugins/genshin/query_user/resin_remind/init_task.py +++ b/plugins/genshin/query_user/resin_remind/init_task.py @@ -101,7 +101,7 @@ async def _(): f"genshin_resin_remind add_job:USER:{u.user_qq} UID:{u.uid}启动原神树脂提醒 " ) else: - u.resin_recovery_time = None + u.resin_recovery_time = None # type: ignore update_list.append(u) add_job(u.user_qq, u.uid) logger.info( diff --git a/plugins/translate/__init__.py b/plugins/translate/__init__.py index 9cf137d5..e6ac9464 100755 --- a/plugins/translate/__init__.py +++ b/plugins/translate/__init__.py @@ -1,25 +1,32 @@ -from nonebot import on_command -from nonebot.params import CommandArg -from services.log import logger -from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent, Message -from nonebot.typing import T_State -from .data_source import translate_msg +from typing import Any, Tuple +from nonebot import on_regex +from nonebot.adapters.onebot.v11 import MessageEvent +from nonebot.params import RegexGroup +from nonebot.typing import T_State + +from services.log import logger +from utils.depends import CheckConfig + +from .data_source import CheckParam, language, translate_msg __zx_plugin_name__ = "翻译" __plugin_usage__ = """ usage: 出国旅游小助手 + Regex: 翻译(form:.*?)?(to:.*?)? (.+) + 一般只需要设置to:,form:按照百度自动检测 指令: - 英翻 [英文] - 翻英 [中文] - 日翻 [日文] - 翻日 [中文] - 韩翻 [韩文] - 翻韩 [中文] + 翻译语种: (查看form与to可用值) + 示例: + 翻译 你好: 将中文翻译为英文 + 翻译 Hello: 将英文翻译为中文 + 翻译to:el 你好: 将"你好"翻译为希腊语 + 翻译to:希腊语 你好: 允许form和to使用中文 + 翻译form:zhto:jp 你好: 指定原语种并将"你好"翻译为日文 """.strip() __plugin_des__ = "出国旅游好助手" -__plugin_cmd__ = ["英翻 [英文]", "翻英 [中文]", "日翻 [日文]", "翻日 [中文]", "韩翻 [韩文]", "翻韩 [中文]"] +__plugin_cmd__ = ["翻译"] __plugin_type__ = ("一些工具",) __plugin_version__ = 0.1 __plugin_author__ = "HibiKier" @@ -29,27 +36,43 @@ __plugin_settings__ = { "limit_superuser": False, "cmd": ["翻译"], } +__plugin_configs__ = { + "APPID": { + "value": None, + "help": "百度翻译APPID", + "type": str, + }, + "SECRET_KEY": { + "value": None, + "help": "百度翻译秘钥", + "type": str, + }, +} + +translate = on_regex("^翻译(form:.*?)?(to:.*?)? (.+)", priority=5, block=True) + +translate_language = on_regex("^翻译语种$", priority=5, block=True) -translate = on_command( - "translate", aliases={"英翻", "翻英", "日翻", "翻日", "韩翻", "翻韩"}, priority=5, block=True +@translate_language.handle() +async def _(event: MessageEvent): + s = "" + for key, value in language.items(): + s += f"{key}: {value}," + await translate_language.send(s[:-1]) + logger.info(f"查看翻译语种", "翻译语种", event.user_id, getattr(event, "group_id", None)) + + +@translate.handle( + parameterless=[ + CheckConfig(config="APPID"), + CheckConfig(config="SECRET_KEY"), + CheckParam(), + ] ) - - -@translate.handle() -async def _(state: T_State, arg: Message = CommandArg()): - msg = arg.extract_plain_text().strip() - if msg: - state["msg"] = msg - - -@translate.got("msg", prompt="你要翻译的消息是啥?") -async def _(event: MessageEvent, state: T_State): - msg = state["msg"] - if len(msg) > 150: - await translate.finish("翻译过长!请不要超过150字", at_sender=True) - await translate.send(await translate_msg(state["_prefix"]["raw_command"], msg)) - logger.info( - f"(USER {event.user_id}, GROUP " - f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 使用翻译:{msg}" - ) +async def _( + event: MessageEvent, state: T_State, reg_group: Tuple[Any, ...] = RegexGroup() +): + _, _, msg = reg_group + await translate.send(await translate_msg(msg, state["form"], state["to"])) + logger.info(f"翻译: {msg}", "翻译", event.user_id, getattr(event, "group_id", None)) diff --git a/plugins/translate/data_source.py b/plugins/translate/data_source.py index a5354b02..517938e2 100755 --- a/plugins/translate/data_source.py +++ b/plugins/translate/data_source.py @@ -1,91 +1,119 @@ -from utils.http_utils import AsyncHttpx import time -import random from hashlib import md5 +from typing import Any, Tuple -# url = f"http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=null" -url = f"https://fanyi-api.baidu.com/api/trans/vip/translate" +from nonebot.internal.matcher import Matcher +from nonebot.internal.params import Depends +from nonebot.params import RegexGroup +from nonebot.typing import T_State + +from configs.config import Config +from utils.http_utils import AsyncHttpx + +URL = "http://api.fanyi.baidu.com/api/trans/vip/translate" -# 获取lts时间戳,salt加密盐,sign加密签名 -def get_lts_salt_sign(word): - lts = str(int(time.time() * 10000)) - salt = lts + str(random.randint(0, 9)) - string = "fanyideskweb" + word + salt + "Ygy_4c=r#e#4EX^NUGUc5" - s = md5() - # md5的加密串必须为字节码 - s.update(string.encode()) - # 16进制加密 - sign = s.hexdigest() - print(lts, salt, sign) - return lts, salt, sign +language = { + "自动": "auto", + "粤语": "yue", + "韩语": "kor", + "泰语": "th", + "葡萄牙语": "pt", + "希腊语": "el", + "保加利亚语": "bul", + "芬兰语": "fin", + "斯洛文尼亚语": "slo", + "繁体中文": "cht", + "中文": "zh", + "文言文": "wyw", + "法语": "fra", + "阿拉伯语": "ara", + "德语": "de", + "荷兰语": "nl", + "爱沙尼亚语": "est", + "捷克语": "cs", + "瑞典语": "swe", + "越南语": "vie", + "英语": "en", + "日语": "jp", + "西班牙语": "spa", + "俄语": "ru", + "意大利语": "it", + "波兰语": "pl", + "丹麦语": "dan", + "罗马尼亚语": "rom", + "匈牙利语": "hu", +} -async def translate_msg(language_type, word): - # data = { - # "type": parse_language(language_type), - # "i": msg, - # "doctype": "json", - # "version": "2.1", - # "keyfrom": "fanyi.web", - # "ue": "UTF-8", - # "action": "FY_BY_CLICKBUTTON", - # "typoResult": "true", - # } - lts, salt, sign = get_lts_salt_sign(word) - data = { - "type": parse_language(language_type), - 'i': word, - 'from': 'AUTO', - 'to': 'AUTO', - 'smartresult': 'dict', - 'client': 'fanyideskweb', - 'salt': salt, - 'sign': sign, - 'lts': lts, - 'bv': 'bdc0570a34c12469d01bfac66273680d', - 'doctype': 'json', - 'version': '2.1', - 'keyfrom': 'fanyi.web', - 'action': 'FY_BY_REALTlME' + +def CheckParam(): + """ + 检查翻译内容是否在language中 + """ + + async def dependency( + matcher: Matcher, + state: T_State, + reg_group: Tuple[Any, ...] = RegexGroup(), + ): + form, to, _ = reg_group + values = language.values() + if form: + form = form.split(":")[-1] + if form not in language and form not in values: + await matcher.finish("FORM选择的语种不存在") + state["form"] = form + else: + state["form"] = "auto" + if to: + to = to.split(":")[-1] + if to not in language and to not in values: + await matcher.finish("TO选择的语种不存在") + state["to"] = to + else: + state["to"] = "auto" + + return Depends(dependency) + + +async def translate_msg(word: str, form: str, to: str) -> str: + """翻译 + + Args: + word (str): 翻译文字 + form (str): 源语言 + to (str): 目标语言 + + Returns: + str: 翻译后的文字 + """ + if form in language: + form = language[form] + if to in language: + to = language[to] + salt = str(time.time()) + app_id = Config.get_config("translate", "APPID") + secret_key = Config.get_config("translate", "SECRET_KEY") + sign = app_id + word + salt + secret_key # type: ignore + md5_ = md5() + md5_.update(sign.encode("utf-8")) + sign = md5_.hexdigest() + params = { + "q": word, + "from": form, + "to": to, + "appid": app_id, + "salt": salt, + "sign": sign, } - data = (await AsyncHttpx.post(url, data=data)).json() - if data["errorCode"] == 0: - return f'原文:{word}\n翻译:{data["translateResult"][0][0]["tgt"]}' - return "翻译惜败.." - - -# ZH_CN2EN 中文 » 英语 -# ZH_CN2JA 中文 » 日语 -# ZH_CN2KR 中文 » 韩语 -# ZH_CN2FR 中文 » 法语 -# ZH_CN2RU 中文 » 俄语 -# ZH_CN2SP 中文 » 西语 -# EN2ZH_CN 英语 » 中文 -# JA2ZH_CN 日语 » 中文 -# KR2ZH_CN 韩语 » 中文 -# FR2ZH_CN 法语 » 中文 -# RU2ZH_CN 俄语 » 中文 -# SP2ZH_CN 西语 » 中文 - - -def parse_language(language_type): - if language_type == "英翻": - return "EN2ZH_CN" - if language_type == "日翻": - return "JA2ZH_CN" - if language_type == "韩翻": - return "KR2ZH_CN" - # if language_type == '法翻': - # return 'FR2ZH_CN' - # if language_type == '俄翻': - # return 'RU2ZH_CN' - if language_type == "翻英": - return "ZH_CN2EN" - if language_type == "翻日": - return "ZH_CN2JA" - if language_type == "翻韩": - return "ZH_CN2KR" - # if language_type == '翻法': - # return 'ZH_CN2FR' - # if language_type == '翻俄': - # return 'ZH_CN2RU' + url = URL + "?" + for key, value in params.items(): + url += f"{key}={value}&" + url = url[:-1] + resp = await AsyncHttpx.get(url) + data = resp.json() + if data.get("error_code"): + return data.get("error_msg") + if trans_result := data.get("trans_result"): + return trans_result[0]["dst"] + return "没有找到翻译捏"