Add translation features

This commit is contained in:
2025-07-06 23:40:14 +08:00
parent a2a332e735
commit 7c2318a13f
19 changed files with 2449 additions and 530 deletions

View File

@@ -26,11 +26,12 @@ var (
// GoogleTranslator Google翻译器结构体统一管理翻译功能
type GoogleTranslator struct {
GoogleHost string // Google服务主机
vm *otto.Otto // JavaScript虚拟机
ttk otto.Value // 翻译token缓存
httpClient *http.Client // HTTP客户端
Timeout time.Duration // 请求超时时间
GoogleHost string // Google服务主机
vm *otto.Otto // JavaScript虚拟机
ttk otto.Value // 翻译token缓存
httpClient *http.Client // HTTP客户端
Timeout time.Duration // 请求超时时间
languages map[string]LanguageInfo // 支持的语言列表
}
// NewGoogleTranslator 创建一个新的Google翻译器实例
@@ -40,6 +41,7 @@ func NewGoogleTranslator() *GoogleTranslator {
vm: otto.New(),
Timeout: defaultTimeout,
httpClient: &http.Client{Timeout: defaultTimeout},
languages: initGoogleLanguages(),
}
// 初始化ttk
@@ -48,6 +50,131 @@ func NewGoogleTranslator() *GoogleTranslator {
return translator
}
// initGoogleLanguages 初始化Google翻译器支持的语言列表
func initGoogleLanguages() map[string]LanguageInfo {
// 创建语言映射表
languages := make(map[string]LanguageInfo)
// 添加所有支持的语言
// 参考: https://cloud.google.com/translate/docs/languages
// 添加自动检测
languages["auto"] = LanguageInfo{Code: "auto", Name: "Auto Detect"}
// 主要语言
languages["en"] = LanguageInfo{Code: "en", Name: "English"}
languages["zh-cn"] = LanguageInfo{Code: "zh-CN", Name: "Chinese (Simplified)"}
languages["zh-tw"] = LanguageInfo{Code: "zh-TW", Name: "Chinese (Traditional)"}
languages["ja"] = LanguageInfo{Code: "ja", Name: "Japanese"}
languages["ko"] = LanguageInfo{Code: "ko", Name: "Korean"}
languages["fr"] = LanguageInfo{Code: "fr", Name: "French"}
languages["de"] = LanguageInfo{Code: "de", Name: "German"}
languages["es"] = LanguageInfo{Code: "es", Name: "Spanish"}
languages["ru"] = LanguageInfo{Code: "ru", Name: "Russian"}
languages["it"] = LanguageInfo{Code: "it", Name: "Italian"}
languages["pt"] = LanguageInfo{Code: "pt", Name: "Portuguese"}
// 其他语言
languages["af"] = LanguageInfo{Code: "af", Name: "Afrikaans"}
languages["sq"] = LanguageInfo{Code: "sq", Name: "Albanian"}
languages["am"] = LanguageInfo{Code: "am", Name: "Amharic"}
languages["ar"] = LanguageInfo{Code: "ar", Name: "Arabic"}
languages["hy"] = LanguageInfo{Code: "hy", Name: "Armenian"}
languages["az"] = LanguageInfo{Code: "az", Name: "Azerbaijani"}
languages["eu"] = LanguageInfo{Code: "eu", Name: "Basque"}
languages["be"] = LanguageInfo{Code: "be", Name: "Belarusian"}
languages["bn"] = LanguageInfo{Code: "bn", Name: "Bengali"}
languages["bs"] = LanguageInfo{Code: "bs", Name: "Bosnian"}
languages["bg"] = LanguageInfo{Code: "bg", Name: "Bulgarian"}
languages["ca"] = LanguageInfo{Code: "ca", Name: "Catalan"}
languages["ceb"] = LanguageInfo{Code: "ceb", Name: "Cebuano"}
languages["zh"] = LanguageInfo{Code: "zh", Name: "Chinese"}
languages["co"] = LanguageInfo{Code: "co", Name: "Corsican"}
languages["hr"] = LanguageInfo{Code: "hr", Name: "Croatian"}
languages["cs"] = LanguageInfo{Code: "cs", Name: "Czech"}
languages["da"] = LanguageInfo{Code: "da", Name: "Danish"}
languages["nl"] = LanguageInfo{Code: "nl", Name: "Dutch"}
languages["eo"] = LanguageInfo{Code: "eo", Name: "Esperanto"}
languages["et"] = LanguageInfo{Code: "et", Name: "Estonian"}
languages["fi"] = LanguageInfo{Code: "fi", Name: "Finnish"}
languages["fy"] = LanguageInfo{Code: "fy", Name: "Frisian"}
languages["gl"] = LanguageInfo{Code: "gl", Name: "Galician"}
languages["ka"] = LanguageInfo{Code: "ka", Name: "Georgian"}
languages["el"] = LanguageInfo{Code: "el", Name: "Greek"}
languages["gu"] = LanguageInfo{Code: "gu", Name: "Gujarati"}
languages["ht"] = LanguageInfo{Code: "ht", Name: "Haitian Creole"}
languages["ha"] = LanguageInfo{Code: "ha", Name: "Hausa"}
languages["haw"] = LanguageInfo{Code: "haw", Name: "Hawaiian"}
languages["he"] = LanguageInfo{Code: "he", Name: "Hebrew"}
languages["hi"] = LanguageInfo{Code: "hi", Name: "Hindi"}
languages["hmn"] = LanguageInfo{Code: "hmn", Name: "Hmong"}
languages["hu"] = LanguageInfo{Code: "hu", Name: "Hungarian"}
languages["is"] = LanguageInfo{Code: "is", Name: "Icelandic"}
languages["ig"] = LanguageInfo{Code: "ig", Name: "Igbo"}
languages["id"] = LanguageInfo{Code: "id", Name: "Indonesian"}
languages["ga"] = LanguageInfo{Code: "ga", Name: "Irish"}
languages["jw"] = LanguageInfo{Code: "jw", Name: "Javanese"}
languages["kn"] = LanguageInfo{Code: "kn", Name: "Kannada"}
languages["kk"] = LanguageInfo{Code: "kk", Name: "Kazakh"}
languages["km"] = LanguageInfo{Code: "km", Name: "Khmer"}
languages["ku"] = LanguageInfo{Code: "ku", Name: "Kurdish"}
languages["ky"] = LanguageInfo{Code: "ky", Name: "Kyrgyz"}
languages["lo"] = LanguageInfo{Code: "lo", Name: "Lao"}
languages["la"] = LanguageInfo{Code: "la", Name: "Latin"}
languages["lv"] = LanguageInfo{Code: "lv", Name: "Latvian"}
languages["lt"] = LanguageInfo{Code: "lt", Name: "Lithuanian"}
languages["lb"] = LanguageInfo{Code: "lb", Name: "Luxembourgish"}
languages["mk"] = LanguageInfo{Code: "mk", Name: "Macedonian"}
languages["mg"] = LanguageInfo{Code: "mg", Name: "Malagasy"}
languages["ms"] = LanguageInfo{Code: "ms", Name: "Malay"}
languages["ml"] = LanguageInfo{Code: "ml", Name: "Malayalam"}
languages["mt"] = LanguageInfo{Code: "mt", Name: "Maltese"}
languages["mi"] = LanguageInfo{Code: "mi", Name: "Maori"}
languages["mr"] = LanguageInfo{Code: "mr", Name: "Marathi"}
languages["mn"] = LanguageInfo{Code: "mn", Name: "Mongolian"}
languages["my"] = LanguageInfo{Code: "my", Name: "Myanmar (Burmese)"}
languages["ne"] = LanguageInfo{Code: "ne", Name: "Nepali"}
languages["no"] = LanguageInfo{Code: "no", Name: "Norwegian"}
languages["ny"] = LanguageInfo{Code: "ny", Name: "Nyanja (Chichewa)"}
languages["ps"] = LanguageInfo{Code: "ps", Name: "Pashto"}
languages["fa"] = LanguageInfo{Code: "fa", Name: "Persian"}
languages["pl"] = LanguageInfo{Code: "pl", Name: "Polish"}
languages["pt-br"] = LanguageInfo{Code: "pt-BR", Name: "Portuguese (Brazil)"}
languages["pt-pt"] = LanguageInfo{Code: "pt-PT", Name: "Portuguese (Portugal)"}
languages["pa"] = LanguageInfo{Code: "pa", Name: "Punjabi"}
languages["ro"] = LanguageInfo{Code: "ro", Name: "Romanian"}
languages["sm"] = LanguageInfo{Code: "sm", Name: "Samoan"}
languages["gd"] = LanguageInfo{Code: "gd", Name: "Scots Gaelic"}
languages["sr"] = LanguageInfo{Code: "sr", Name: "Serbian"}
languages["st"] = LanguageInfo{Code: "st", Name: "Sesotho"}
languages["sn"] = LanguageInfo{Code: "sn", Name: "Shona"}
languages["sd"] = LanguageInfo{Code: "sd", Name: "Sindhi"}
languages["si"] = LanguageInfo{Code: "si", Name: "Sinhala (Sinhalese)"}
languages["sk"] = LanguageInfo{Code: "sk", Name: "Slovak"}
languages["sl"] = LanguageInfo{Code: "sl", Name: "Slovenian"}
languages["so"] = LanguageInfo{Code: "so", Name: "Somali"}
languages["su"] = LanguageInfo{Code: "su", Name: "Sundanese"}
languages["sw"] = LanguageInfo{Code: "sw", Name: "Swahili"}
languages["sv"] = LanguageInfo{Code: "sv", Name: "Swedish"}
languages["tl"] = LanguageInfo{Code: "tl", Name: "Tagalog (Filipino)"}
languages["tg"] = LanguageInfo{Code: "tg", Name: "Tajik"}
languages["ta"] = LanguageInfo{Code: "ta", Name: "Tamil"}
languages["te"] = LanguageInfo{Code: "te", Name: "Telugu"}
languages["th"] = LanguageInfo{Code: "th", Name: "Thai"}
languages["tr"] = LanguageInfo{Code: "tr", Name: "Turkish"}
languages["uk"] = LanguageInfo{Code: "uk", Name: "Ukrainian"}
languages["ur"] = LanguageInfo{Code: "ur", Name: "Urdu"}
languages["uz"] = LanguageInfo{Code: "uz", Name: "Uzbek"}
languages["vi"] = LanguageInfo{Code: "vi", Name: "Vietnamese"}
languages["cy"] = LanguageInfo{Code: "cy", Name: "Welsh"}
languages["xh"] = LanguageInfo{Code: "xh", Name: "Xhosa"}
languages["yi"] = LanguageInfo{Code: "yi", Name: "Yiddish"}
languages["yo"] = LanguageInfo{Code: "yo", Name: "Yoruba"}
languages["zu"] = LanguageInfo{Code: "zu", Name: "Zulu"}
return languages
}
// SetTimeout 设置请求超时时间
func (t *GoogleTranslator) SetTimeout(timeout time.Duration) {
t.Timeout = timeout
@@ -61,25 +188,21 @@ func (t *GoogleTranslator) SetGoogleHost(host string) {
// Translate 使用Go语言提供的标准语言标签进行文本翻译
func (t *GoogleTranslator) Translate(text string, from language.Tag, to language.Tag) (string, error) {
return t.translate(text, from.String(), to.String(), false, defaultNumberOfRetries, 0)
return t.translate(text, from.String(), to.String(), false)
}
// TranslateWithParams 使用简单字符串参数进行文本翻译
func (t *GoogleTranslator) TranslateWithParams(text string, params TranslationParams) (string, error) {
tries := params.Tries
if tries == 0 {
tries = defaultNumberOfRetries
// 设置超时时间(如果有指定)
if params.Timeout > 0 {
t.SetTimeout(params.Timeout)
}
return t.translate(text, params.From, params.To, true, tries, params.Delay)
return t.translate(text, params.From, params.To, true)
}
// translate 执行实际翻译操作
func (t *GoogleTranslator) translate(text, from, to string, withVerification bool, tries int, delay time.Duration) (string, error) {
if tries == 0 {
tries = defaultNumberOfRetries
}
func (t *GoogleTranslator) translate(text, from, to string, withVerification bool) (string, error) {
if withVerification {
if _, err := language.Parse(from); err != nil && from != "auto" {
log.Println("[WARNING], '" + from + "' is a invalid language, switching to 'auto'")
@@ -125,29 +248,21 @@ func (t *GoogleTranslator) translate(text, from, to string, withVerification boo
parameters.Add("tk", token)
u.RawQuery = parameters.Encode()
var r *http.Response
for tries > 0 {
req, err := http.NewRequest("GET", u.String(), nil)
if err != nil {
return "", err
}
req, err := http.NewRequest("GET", u.String(), nil)
if err != nil {
return "", err
}
r, err = t.httpClient.Do(req)
if err != nil {
if errors.Is(err, http.ErrHandlerTimeout) {
return "", ErrBadNetwork
}
return "", err
r, err := t.httpClient.Do(req)
if err != nil {
if errors.Is(err, http.ErrHandlerTimeout) {
return "", ErrBadNetwork
}
return "", err
}
if r.StatusCode == http.StatusOK {
break
}
if r.StatusCode == http.StatusForbidden {
tries--
time.Sleep(delay)
}
if r.StatusCode != http.StatusOK {
return "", fmt.Errorf("API error: status code %d", r.StatusCode)
}
raw, err := io.ReadAll(r.Body)
@@ -309,3 +424,20 @@ func (t *GoogleTranslator) generateToken(a otto.Value, TTK otto.Value) (otto.Val
return result, nil
}
// GetSupportedLanguages 获取翻译器支持的语言列表
func (t *GoogleTranslator) GetSupportedLanguages() map[string]LanguageInfo {
return t.languages
}
// IsLanguageSupported 检查指定的语言代码是否受支持
func (t *GoogleTranslator) IsLanguageSupported(languageCode string) bool {
_, ok := t.languages[strings.ToLower(languageCode)]
return ok
}
// GetStandardLanguageCode 获取标准化的语言代码
func (t *GoogleTranslator) GetStandardLanguageCode(languageCode string) string {
// 简单返回小写版本作为标准代码
return strings.ToLower(languageCode)
}