mirror of
https://github.com/xfgryujk/blivechat.git
synced 2024-12-26 21:00:15 +08:00
添加百度翻译官方接口
This commit is contained in:
parent
0b848b1288
commit
df6097a184
@ -109,6 +109,11 @@ class AppConfig:
|
||||
translator_config['secret_id'] = section['secret_id']
|
||||
translator_config['secret_key'] = section['secret_key']
|
||||
translator_config['region'] = section['region']
|
||||
elif type_ == 'BaiduTranslate':
|
||||
translator_config['source_language'] = section['source_language']
|
||||
translator_config['target_language'] = section['target_language']
|
||||
translator_config['app_id'] = section['app_id']
|
||||
translator_config['secret'] = section['secret']
|
||||
else:
|
||||
raise ValueError(f'Invalid translator type: {type_}')
|
||||
|
||||
|
@ -113,3 +113,30 @@ secret_key =
|
||||
# 北京:ap-beijing;上海:ap-shanghai;香港:ap-hongkong;首尔:ap-seoul
|
||||
# 完整地域列表见文档:https://cloud.tencent.com/document/api/551/15615#.E5.9C.B0.E5.9F.9F.E5.88.97.E8.A1.A8
|
||||
region = ap-shanghai
|
||||
|
||||
|
||||
[baidu_translate]
|
||||
# 文档:https://fanyi-api.baidu.com/
|
||||
# 定价:https://fanyi-api.baidu.com/product/112
|
||||
# * 标准版完全免费,不限使用字符量(QPS=1)
|
||||
# * 高级版每月前200万字符免费,超出后仅收取超出部分费用(QPS=10),49元/百万字符
|
||||
# * 尊享版每月前200万字符免费,超出后仅收取超出部分费用(QPS=100),49元/百万字符
|
||||
|
||||
# 类型:百度翻译
|
||||
type = BaiduTranslate
|
||||
|
||||
# 请求间隔时间(秒),等于 1 / QPS
|
||||
query_interval = 1.5
|
||||
# 最大队列长度,注意最长等待时间等于 最大队列长度 * 请求间隔时间
|
||||
max_queue_size = 9
|
||||
|
||||
# 自动:auto;中文:zh;日语:jp;英语:en;韩语:kor
|
||||
# 完整语言列表见文档:https://fanyi-api.baidu.com/doc/21
|
||||
# 源语言
|
||||
source_language = zh
|
||||
# 目标语言
|
||||
target_language = jp
|
||||
|
||||
# 百度翻译开放平台应用ID和密钥
|
||||
app_id =
|
||||
secret =
|
||||
|
@ -7,6 +7,7 @@ import hashlib
|
||||
import hmac
|
||||
import json
|
||||
import logging
|
||||
import random
|
||||
import re
|
||||
from typing import *
|
||||
|
||||
@ -22,7 +23,7 @@ NO_TRANSLATE_TEXTS = {
|
||||
}
|
||||
|
||||
_main_event_loop = asyncio.get_event_loop()
|
||||
_http_session = aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=10))
|
||||
_http_session = None
|
||||
_translate_providers: List['TranslateProvider'] = []
|
||||
# text -> res
|
||||
_translate_cache: Dict[str, str] = {}
|
||||
@ -35,6 +36,9 @@ def init():
|
||||
|
||||
|
||||
async def _do_init():
|
||||
global _http_session
|
||||
_http_session = aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=10))
|
||||
|
||||
cfg = config.get_config()
|
||||
if not cfg.enable_translate:
|
||||
return
|
||||
@ -63,6 +67,11 @@ def create_translate_provider(cfg):
|
||||
cfg['target_language'], cfg['secret_id'], cfg['secret_key'],
|
||||
cfg['region']
|
||||
)
|
||||
elif type_ == 'BaiduTranslate':
|
||||
return BaiduTranslate(
|
||||
cfg['query_interval'], cfg['max_queue_size'], cfg['source_language'],
|
||||
cfg['target_language'], cfg['app_id'], cfg['secret']
|
||||
)
|
||||
return None
|
||||
|
||||
|
||||
@ -464,3 +473,65 @@ class TencentTranslate(FlowControlTranslateProvider):
|
||||
|
||||
def _on_cool_down_timeout(self):
|
||||
self._cool_down_timer_handle = None
|
||||
|
||||
|
||||
class BaiduTranslate(FlowControlTranslateProvider):
|
||||
def __init__(self, query_interval, max_queue_size, source_language, target_language,
|
||||
app_id, secret):
|
||||
super().__init__(query_interval, max_queue_size)
|
||||
self._source_language = source_language
|
||||
self._target_language = target_language
|
||||
self._app_id = app_id
|
||||
self._secret = secret
|
||||
|
||||
self._cool_down_timer_handle = None
|
||||
|
||||
@property
|
||||
def is_available(self):
|
||||
return self._cool_down_timer_handle is None and super().is_available
|
||||
|
||||
async def _do_translate(self, text):
|
||||
try:
|
||||
async with _http_session.post(
|
||||
'https://fanyi-api.baidu.com/api/trans/vip/translate',
|
||||
data=self._add_sign({
|
||||
'q': text,
|
||||
'from': self._source_language,
|
||||
'to': self._target_language,
|
||||
'appid': self._app_id,
|
||||
'salt': random.randint(1, 999999999)
|
||||
})
|
||||
) as r:
|
||||
if r.status != 200:
|
||||
logger.warning('BaiduTranslate request failed: status=%d %s', r.status, r.reason)
|
||||
return None
|
||||
data = await r.json()
|
||||
except (aiohttp.ClientConnectionError, asyncio.TimeoutError):
|
||||
return None
|
||||
error_code = data.get('error_code', None)
|
||||
if error_code is not None:
|
||||
logger.warning('BaiduTranslate failed: %s %s', error_code, data['error_msg'])
|
||||
self._on_fail(error_code)
|
||||
return None
|
||||
return ''.join(result['dst'] for result in data['trans_result'])
|
||||
|
||||
def _add_sign(self, data):
|
||||
str_to_sign = f"{self._app_id}{data['q']}{data['salt']}{self._secret}"
|
||||
sign = hashlib.md5(str_to_sign.encode('utf-8')).hexdigest()
|
||||
return {**data, 'sign': sign}
|
||||
|
||||
def _on_fail(self, code):
|
||||
if self._cool_down_timer_handle is not None:
|
||||
return
|
||||
|
||||
sleep_time = 0
|
||||
if code == '54004':
|
||||
# 账户余额不足,需要手动处理,等5分钟
|
||||
sleep_time = 5 * 60
|
||||
if sleep_time != 0:
|
||||
self._cool_down_timer_handle = asyncio.get_event_loop().call_later(
|
||||
sleep_time, self._on_cool_down_timeout
|
||||
)
|
||||
|
||||
def _on_cool_down_timeout(self):
|
||||
self._cool_down_timer_handle = None
|
||||
|
Loading…
Reference in New Issue
Block a user