google.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. package google
  2. import (
  3. "context"
  4. "fmt"
  5. "io"
  6. "net/http"
  7. "net/url"
  8. "strconv"
  9. "strings"
  10. "bet24.com/servers/adminserver/config"
  11. "bet24.com/utils"
  12. "bet24.com/log"
  13. "cloud.google.com/go/translate"
  14. "golang.org/x/text/language"
  15. "google.golang.org/api/option"
  16. )
  17. // 是否翻译
  18. func IsTranslate() (bool, string) {
  19. googleJson := config.Server.GOOGLE_APPLICATION_CREDENTIALS
  20. if googleJson == "" {
  21. // log.Debug("google翻译未配置 json 文件")
  22. return false, "google翻译未配置 json 文件"
  23. }
  24. return true, googleJson
  25. }
  26. func Translate(sourceLanguage, targetLanguage, text string) (string, error) {
  27. utils.SetMinTraceTime(1000)
  28. defer utils.TimeCost(fmt.Sprintf("google.Translate sourceLanguage=%s targetLanguage=%s text==>%s ",
  29. sourceLanguage,
  30. targetLanguage,
  31. text))()
  32. ok, googleJson := IsTranslate()
  33. if !ok {
  34. return "", fmt.Errorf(googleJson)
  35. }
  36. if _, err := strconv.ParseFloat(text, 64); err == nil {
  37. // log.Debug(fmt.Sprintf("Google Translate 纯数字无需翻译 ==> %s", text))
  38. return "", err
  39. }
  40. ctx := context.Background()
  41. // sourceLang, err := language.Parse(sourceLanguage)
  42. // if err != nil {
  43. // return "", fmt.Errorf("%s source language.Parse: %v", sourceLanguage, err)
  44. // }
  45. tarLang, err := language.Parse(targetLanguage)
  46. if err != nil {
  47. log.Error("%s target language.Parse: %v", targetLanguage, err)
  48. return "", fmt.Errorf("%s target language.Parse: %v", targetLanguage, err)
  49. }
  50. // log.Debug("google.Translate ==> sourceLanguage=%+v targetLanguage=%+v text==>%s ",
  51. // sourceLang,
  52. // tarLang,
  53. // text)
  54. client, err := translate.NewClient(ctx, option.WithCredentialsFile(googleJson))
  55. if err != nil {
  56. log.Error("google.Translate NewClient err = %+v", err)
  57. return "", err
  58. }
  59. defer client.Close()
  60. // resp, err := client.Translate(ctx, []string{text}, tarLang, &translate.Options{
  61. // Source: sourceLang,
  62. // Format: translate.Text,
  63. // })
  64. resp, err := client.Translate(ctx, []string{text}, tarLang, nil)
  65. if err != nil {
  66. log.Error("google.Translate Translate resp=%+v err=%+v", resp, err)
  67. return "", fmt.Errorf("Translate: %v", err)
  68. }
  69. if len(resp) == 0 {
  70. log.Error("google.Translate Translate resp=%+v", resp)
  71. return "", fmt.Errorf("Translate returned empty response to text: %s", text)
  72. }
  73. // log.Debug("google.Translate ==> Translate sourceLanguage=%s targetLanguage=%s resp=%+v err=%+v",
  74. // sourceLanguage, targetLanguage, resp, err)
  75. return resp[0].Text, nil
  76. }
  77. func TranslateTextWithModel(targetLanguage, text, model string) (string, error) {
  78. // targetLanguage := "ja"
  79. // text := "The Go Gopher is cute"
  80. // model := "nmt"
  81. utils.SetMinTraceTime(1000)
  82. defer utils.TimeCost(fmt.Sprintf("google.Translate targetLanguage=%s model=%s text==>%s ",
  83. targetLanguage,
  84. model,
  85. text))()
  86. ok, googleJson := IsTranslate()
  87. if !ok {
  88. return "", fmt.Errorf(googleJson)
  89. }
  90. if _, err := strconv.ParseFloat(text, 64); err == nil {
  91. // log.Debug(fmt.Sprintf("Google Translate 纯数字无需翻译 ==> %s", text))
  92. return "", err
  93. }
  94. ctx := context.Background()
  95. lang, err := language.Parse(targetLanguage)
  96. if err != nil {
  97. return "", fmt.Errorf("language.Parse: %v", err)
  98. }
  99. log.Debug("google.TranslateTextWithModel ==> targetLanguage=%+v model=%s text==>%s ",
  100. targetLanguage,
  101. model,
  102. text)
  103. client, err := translate.NewClient(ctx, option.WithCredentialsFile(googleJson))
  104. if err != nil {
  105. return "", fmt.Errorf("translate.NewClient: %v", err)
  106. }
  107. defer client.Close()
  108. resp, err := client.Translate(ctx, []string{text}, lang, &translate.Options{
  109. Model: "base", // Either "nmt" or "base".
  110. })
  111. if err != nil {
  112. return "", fmt.Errorf("Translate: %v", err)
  113. }
  114. if len(resp) == 0 {
  115. return "", nil
  116. }
  117. log.Debug("google.TranslateTextWithModel ==> Translate targetLanguage=%s model=%s resp=%+v err=%+v",
  118. targetLanguage, model, resp, err)
  119. return resp[0].Text, nil
  120. }
  121. func DetectLanguage(text string) (*translate.Detection, error) {
  122. // text := "こんにちは世界"
  123. ok, googleJson := IsTranslate()
  124. if !ok {
  125. return nil, fmt.Errorf(googleJson)
  126. }
  127. ctx := context.Background()
  128. client, err := translate.NewClient(ctx, option.WithCredentialsFile(googleJson))
  129. if err != nil {
  130. return nil, fmt.Errorf("translate.NewClient: %v", err)
  131. }
  132. defer client.Close()
  133. lang, err := client.DetectLanguage(ctx, []string{text})
  134. if err != nil {
  135. return nil, fmt.Errorf("DetectLanguage: %v", err)
  136. }
  137. if len(lang) == 0 || len(lang[0]) == 0 {
  138. return nil, fmt.Errorf("DetectLanguage return value empty")
  139. }
  140. log.Debug("google.DetectLanguage ==> lang = %+v", lang)
  141. return &lang[0][0], nil
  142. }
  143. // Google 翻译API
  144. // url GET https://translate.googleapis.com/translate_a/single
  145. // client url-query 默认值(不要修改) gtx
  146. // sl url-query 来源语言 en zh-cn 语言代码如下
  147. // tl url-query 目标语言 en zh-cn 语言代码如下
  148. // dt url-query 默认值(不要修改) t
  149. // q u rl-query 翻译的文本 建议先url-encode
  150. func TranslateFree(sl, tl, text string) (string, error) {
  151. if _, err := strconv.ParseFloat(text, 64); err == nil {
  152. // log.Debug(fmt.Sprintf("Google Translate 纯数字无需翻译 ==> %s", text))
  153. return "", err
  154. }
  155. // log.Debug("全角:%s", text)
  156. text = DBC2SBC(text)
  157. // log.Debug("半角:%s", text)
  158. url := fmt.Sprintf("https://translate.googleapis.com/translate_a/single?client=gtx&sl=%s&tl=%s&dt=t&q=%s",
  159. sl, tl, url.QueryEscape(text))
  160. resp, err := http.Get(url)
  161. if err != nil {
  162. return "", err
  163. }
  164. defer resp.Body.Close()
  165. if err != nil {
  166. return "", err
  167. }
  168. bs, err := io.ReadAll(resp.Body)
  169. if err != nil {
  170. return "", err
  171. }
  172. // 返回的json反序列化比较麻烦, 直接字符串拆解
  173. ss := string(bs)
  174. if strings.HasPrefix(ss, "<!DOCTYPE") {
  175. return "", err
  176. }
  177. ss = strings.ReplaceAll(ss, "[", "")
  178. ss = strings.ReplaceAll(ss, "]", "")
  179. ss = strings.ReplaceAll(ss, "null,", "")
  180. ss = strings.Trim(ss, `"`)
  181. ps := strings.Split(ss, `","`)
  182. log.Debug("google.Translate 原文:%s 译文:%s", text, ps[0])
  183. return ps[0], nil
  184. }
  185. // 全角转半角
  186. func DBC2SBC(s string) string {
  187. var strLst []string
  188. for _, i := range s {
  189. insideCode := i
  190. if insideCode == 12288 {
  191. insideCode = 32
  192. } else {
  193. insideCode -= 65248
  194. }
  195. if insideCode < 32 || insideCode > 126 {
  196. strLst = append(strLst, string(i))
  197. } else {
  198. strLst = append(strLst, string(insideCode))
  199. }
  200. }
  201. return strings.Join(strLst, "")
  202. }