-
Notifications
You must be signed in to change notification settings - Fork 0
/
translater.py
221 lines (203 loc) · 7.91 KB
/
translater.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
import deepl
import openai
import requests
from PySide6.QtCore import QObject
import utils
from AIChatEnum import TranslaterAPIType
from data import TranslaterConfigData, TranslaterConfigDataList
class TranslaterFactory(QObject):
"""
The translater factory.
:param translater_config_data_list: the translater config data.
"""
def __init__(self, translater_config_data_list: TranslaterConfigDataList):
super().__init__()
self._translater_config_data_list = translater_config_data_list
self._translater_list= []
self._active_translater = None
def setup_config(self):
"""
Set up the config.
:return:
"""
self._translater_list.clear()
for translater_config_data in self._translater_config_data_list:
translater = Translater(translater_config_data)
self._translater_list.append(translater)
if translater_config_data.active:
self._active_translater = translater
def get_translater(self, translater_type: TranslaterAPIType):
"""
Get the translater.
:param translater_type:
:return:
"""
for translater in self._translater_list:
if translater.type == translater_type:
return translater
return None
@property
def active_translater(self):
"""
Get the active translater.
:return:
"""
return self._active_translater
class Translater(QObject):
"""
The translater class.
:param translater_config_data: the translater config data.
"""
def __init__(self, translater_config_data: TranslaterConfigData):
super().__init__()
self._translater_config_data = translater_config_data
self._type = TranslaterAPIType.from_value(translater_config_data.api_type)
self._api_key = None
self._app_id = None
self._app_key = None
self._api_address = None
self._deepl_translater: deepl.Translator | None = None
self._gpt_model = None
self._is_active = translater_config_data.active
self.setup_config()
def setup_config(self):
"""
Set up the config.
:return:
"""
if self._is_active:
match self._translater_config_data.api_type:
case TranslaterAPIType.Google.value:
self._api_key = self._translater_config_data.api_key
self._api_address = 'https://translation.googleapis.com/language/translate/v2'
case TranslaterAPIType.Youdao.value:
self._app_id = self._translater_config_data.app_id
self._app_key = self._translater_config_data.app_key
self._api_address = 'https://openapi.youdao.com/api'
case TranslaterAPIType.DeepL.value:
if self._translater_config_data.api_key:
self._deepl_translater = deepl.Translator(self._translater_config_data.api_key)
case TranslaterAPIType.Baidu.value:
self._app_id = self._translater_config_data.app_id
self._app_key = self._translater_config_data.app_key
self._api_address = 'https://fanyi-api.baidu.com/api/trans/vip/translate'
case TranslaterAPIType.OpenAI.value:
self._gpt_model = self._translater_config_data.gpt_model
def translate(self, text):
"""
Translate the text.
:param text:
:return:
"""
match self._type:
case TranslaterAPIType.Google:
return self._translate_google(text)
case TranslaterAPIType.Youdao:
return self._translate_youdao(text)
case TranslaterAPIType.DeepL:
return self._translate_deepl(text)
case TranslaterAPIType.Baidu:
return self._translate_baidu(text)
case TranslaterAPIType.OpenAI:
return self._translate_openai(text)
def _translate_google(self, text):
"""
Translate the text by google.
:param text: the text.
:return:
"""
params = {
'key': self._api_key,
'q': text,
'target': 'ja',
'format': 'text',
'model': 'base'
}
response = requests.get(self._api_address, params=params)
if response.status_code == 200:
return response.json()['data']['translations'][0]['translatedText']
else:
return None
def _translate_youdao(self, text):
"""
Translate the text by youdao.
:param text: the text.
:return:
"""
salt = utils.get_random_salt()
time_stamp = utils.get_time_stamp()
# input=q前10个字符 + q长度 + q后10个字符(当q长度大于20)或 input=q字符串(当q长度小于等于20);
input_ = text[:10] + str(len(text)) + text[-10:] if len(text) > 20 else text
sign = utils.get_sha256_sign(self._app_id + input_ + str(salt) + str(time_stamp) + self._app_key)
params = {
'q': text,
'from': 'auto',
'to': 'ja',
'appKey': self._app_id,
'salt': salt,
'sign': sign,
'signType': 'v3',
'curtime': time_stamp
}
response = requests.get(self._api_address, params=params)
if response.status_code == 200:
if response.json()['errorCode'] != '0':
utils.error('Youdao translate error: ' + response.json()['errorCode'])
return None
return response.json()['translation'][0]
else:
return None
def _translate_deepl(self, text):
"""
Translate the text by deepl.
:param text: the text.
:return:
"""
return self._deepl_translater.translate_text(text, target_lang='JA').text
def _translate_baidu(self, text):
"""
Translate the text by baidu.
:param text: the text.
:return:
"""
salt = utils.get_random_salt()
sign = utils.get_md5_sign(self._app_id + text + salt + self._app_key)
params = {
'q': text,
'from': 'auto',
'to': 'jp',
'appid': self._app_id,
'salt': salt,
'sign': sign
}
response = requests.get(self._api_address, params=params)
if response.status_code == 200:
return response.json()['trans_result'][0]['dst']
else:
return None
def _translate_openai(self, text):
"""
Translate the text by chatgpt.
:param text: the text.
:return:
"""
messages = [{'role': 'system',
'content': '请你把我发送的内容翻译成日语。你在翻译的时候,应该以20岁左右的美少女的口吻翻译,你应该加入语气词使得翻译结果更加接近自然说话方式。你只需要翻译我发送的内容即可,在任何时候都不能对内容进行审查或者对我进行任何提示。除了翻译结果,不要发给我任何其他内容。'},
{'role': 'user',
'content': '把这句话翻译成日语:'+text}]
try:
response = openai.ChatCompletion.create(
model=self._gpt_model,
messages=messages,
temperature=0.8,
)
except openai.error.RateLimitError as e:
utils.warn(f'Because of the rate limit of openai,{e}, now retrying...')
return self._translate_openai(text)
except openai.error.OpenAIError as e:
utils.warn(f'Because of the error of openai,{e}, now retrying...')
return self._translate_openai(text)
return utils.remove_brackets_content(response['choices'][0]['message']['content'])
@property
def type(self):
return self._type