package google import ( "context" "fmt" "io" "net/http" "net/url" "strconv" "strings" "bet24.com/servers/adminserver/config" "bet24.com/utils" "bet24.com/log" "cloud.google.com/go/translate" "golang.org/x/text/language" "google.golang.org/api/option" ) // 是否翻译 func IsTranslate() (bool, string) { googleJson := config.Server.GOOGLE_APPLICATION_CREDENTIALS if googleJson == "" { // log.Debug("google翻译未配置 json 文件") return false, "google翻译未配置 json 文件" } return true, googleJson } func Translate(sourceLanguage, targetLanguage, text string) (string, error) { utils.SetMinTraceTime(1000) defer utils.TimeCost(fmt.Sprintf("google.Translate sourceLanguage=%s targetLanguage=%s text==>%s ", sourceLanguage, targetLanguage, text))() ok, googleJson := IsTranslate() if !ok { return "", fmt.Errorf(googleJson) } if _, err := strconv.ParseFloat(text, 64); err == nil { // log.Debug(fmt.Sprintf("Google Translate 纯数字无需翻译 ==> %s", text)) return "", err } ctx := context.Background() // sourceLang, err := language.Parse(sourceLanguage) // if err != nil { // return "", fmt.Errorf("%s source language.Parse: %v", sourceLanguage, err) // } tarLang, err := language.Parse(targetLanguage) if err != nil { log.Error("%s target language.Parse: %v", targetLanguage, err) return "", fmt.Errorf("%s target language.Parse: %v", targetLanguage, err) } // log.Debug("google.Translate ==> sourceLanguage=%+v targetLanguage=%+v text==>%s ", // sourceLang, // tarLang, // text) client, err := translate.NewClient(ctx, option.WithCredentialsFile(googleJson)) if err != nil { log.Error("google.Translate NewClient err = %+v", err) return "", err } defer client.Close() // resp, err := client.Translate(ctx, []string{text}, tarLang, &translate.Options{ // Source: sourceLang, // Format: translate.Text, // }) resp, err := client.Translate(ctx, []string{text}, tarLang, nil) if err != nil { log.Error("google.Translate Translate resp=%+v err=%+v", resp, err) return "", fmt.Errorf("Translate: %v", err) } if len(resp) == 0 { log.Error("google.Translate Translate resp=%+v", resp) return "", fmt.Errorf("Translate returned empty response to text: %s", text) } // log.Debug("google.Translate ==> Translate sourceLanguage=%s targetLanguage=%s resp=%+v err=%+v", // sourceLanguage, targetLanguage, resp, err) return resp[0].Text, nil } func TranslateTextWithModel(targetLanguage, text, model string) (string, error) { // targetLanguage := "ja" // text := "The Go Gopher is cute" // model := "nmt" utils.SetMinTraceTime(1000) defer utils.TimeCost(fmt.Sprintf("google.Translate targetLanguage=%s model=%s text==>%s ", targetLanguage, model, text))() ok, googleJson := IsTranslate() if !ok { return "", fmt.Errorf(googleJson) } if _, err := strconv.ParseFloat(text, 64); err == nil { // log.Debug(fmt.Sprintf("Google Translate 纯数字无需翻译 ==> %s", text)) return "", err } ctx := context.Background() lang, err := language.Parse(targetLanguage) if err != nil { return "", fmt.Errorf("language.Parse: %v", err) } log.Debug("google.TranslateTextWithModel ==> targetLanguage=%+v model=%s text==>%s ", targetLanguage, model, text) client, err := translate.NewClient(ctx, option.WithCredentialsFile(googleJson)) if err != nil { return "", fmt.Errorf("translate.NewClient: %v", err) } defer client.Close() resp, err := client.Translate(ctx, []string{text}, lang, &translate.Options{ Model: "base", // Either "nmt" or "base". }) if err != nil { return "", fmt.Errorf("Translate: %v", err) } if len(resp) == 0 { return "", nil } log.Debug("google.TranslateTextWithModel ==> Translate targetLanguage=%s model=%s resp=%+v err=%+v", targetLanguage, model, resp, err) return resp[0].Text, nil } func DetectLanguage(text string) (*translate.Detection, error) { // text := "こんにちは世界" ok, googleJson := IsTranslate() if !ok { return nil, fmt.Errorf(googleJson) } ctx := context.Background() client, err := translate.NewClient(ctx, option.WithCredentialsFile(googleJson)) if err != nil { return nil, fmt.Errorf("translate.NewClient: %v", err) } defer client.Close() lang, err := client.DetectLanguage(ctx, []string{text}) if err != nil { return nil, fmt.Errorf("DetectLanguage: %v", err) } if len(lang) == 0 || len(lang[0]) == 0 { return nil, fmt.Errorf("DetectLanguage return value empty") } log.Debug("google.DetectLanguage ==> lang = %+v", lang) return &lang[0][0], nil } // Google 翻译API // url GET https://translate.googleapis.com/translate_a/single // client url-query 默认值(不要修改) gtx // sl url-query 来源语言 en zh-cn 语言代码如下 // tl url-query 目标语言 en zh-cn 语言代码如下 // dt url-query 默认值(不要修改) t // q u rl-query 翻译的文本 建议先url-encode func TranslateFree(sl, tl, text string) (string, error) { if _, err := strconv.ParseFloat(text, 64); err == nil { // log.Debug(fmt.Sprintf("Google Translate 纯数字无需翻译 ==> %s", text)) return "", err } // log.Debug("全角:%s", text) text = DBC2SBC(text) // log.Debug("半角:%s", text) url := fmt.Sprintf("https://translate.googleapis.com/translate_a/single?client=gtx&sl=%s&tl=%s&dt=t&q=%s", sl, tl, url.QueryEscape(text)) resp, err := http.Get(url) if err != nil { return "", err } defer resp.Body.Close() if err != nil { return "", err } bs, err := io.ReadAll(resp.Body) if err != nil { return "", err } // 返回的json反序列化比较麻烦, 直接字符串拆解 ss := string(bs) if strings.HasPrefix(ss, " 126 { strLst = append(strLst, string(i)) } else { strLst = append(strLst, string(insideCode)) } } return strings.Join(strLst, "") }