Skip to content

Commit

Permalink
feat(translate): 增加华为云NLP翻译;翻译接口增加IsValid判断是否有效(主要根据必需配置是否存在);
Browse files Browse the repository at this point in the history
  • Loading branch information
speauty committed Apr 2, 2023
1 parent 32a49fb commit 6b3532b
Show file tree
Hide file tree
Showing 9 changed files with 281 additions and 15 deletions.
14 changes: 10 additions & 4 deletions domain/translator.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package domain

import (
"fmt"
"sync"
"translator/tst/tt_log"
"translator/tst/tt_translator"
_type "translator/type"
)
Expand Down Expand Up @@ -48,10 +50,14 @@ func (customT *Translators) GetNames() []*_type.StdComboBoxModel {
func (customT *Translators) genNames2ComboBox() {
customT.names = []*_type.StdComboBoxModel{}
customT.list.Range(func(idx, translator any) bool {
customT.names = append(customT.names, &_type.StdComboBoxModel{
Key: translator.(tt_translator.ITranslator).GetId(),
Name: translator.(tt_translator.ITranslator).GetName(),
})
if translator.(tt_translator.ITranslator).IsValid() {
customT.names = append(customT.names, &_type.StdComboBoxModel{
Key: translator.(tt_translator.ITranslator).GetId(),
Name: translator.(tt_translator.ITranslator).GetName(),
})
} else {
tt_log.GetInstance().Warn(fmt.Sprintf("当前翻译引擎无效: %s", translator.(tt_translator.ITranslator).GetName()))
}
return true
})
}
13 changes: 8 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,30 @@ go 1.19

require (
github.com/golang-module/carbon v1.7.3
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.34
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
github.com/lxn/walk v0.0.0-20210112085537-c389da54e794
github.com/lxn/win v0.0.0-20210218163916-a377121e959e
github.com/spf13/viper v1.15.0
github.com/stretchr/testify v1.8.1
github.com/twharmon/gouid v0.5.2
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/gobuffalo/envy v1.7.0 // indirect
github.com/gobuffalo/packd v0.3.0 // indirect
github.com/gobuffalo/packr v1.30.1 // indirect
github.com/joho/godotenv v1.3.0 // indirect
github.com/jonboulle/clockwork v0.3.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/lestrrat-go/strftime v1.0.6 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.6.1 // indirect
go.mongodb.org/mongo-driver v1.11.2 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
golang.org/x/crypto v0.7.0 // indirect
gopkg.in/Knetic/govaluate.v3 v3.0.0 // indirect
)

Expand All @@ -40,8 +43,8 @@ require (
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
go.uber.org/zap v1.24.0
golang.org/x/sys v0.3.0 // indirect
golang.org/x/text v0.5.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/text v0.8.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
58 changes: 54 additions & 4 deletions go.sum

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions tst/tt_translator/huawei_cloud_nlp/cfg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package huawei_cloud_nlp

type Cfg struct {
AKId string `mapstructure:"ak_id"` // Access Key
SkKey string `mapstructure:"sk_key"` // Secret Access Key
Region string `mapstructure:"region"` // 当前接口开发的区域, 目前仅支持华北-北京四终端节点
ProjectId string `mapstructure:"project_id"` // 项目ID
}

func (customC Cfg) DefaultCfg() *Cfg {
return &Cfg{
AKId: "",
SkKey: "",
Region: "cn-north-4",
ProjectId: "",
}
}
175 changes: 175 additions & 0 deletions tst/tt_translator/huawei_cloud_nlp/translator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
package huawei_cloud_nlp

import (
"errors"
"fmt"
"github.com/golang-module/carbon"
"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic"
nlp "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/nlp/v2"
"github.com/huaweicloud/huaweicloud-sdk-go-v3/services/nlp/v2/model"
region "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/nlp/v2/region"
"strings"
"sync"
"translator/tst/tt_log"
"translator/tst/tt_translator"
)

var (
apiTranslator *Translator
onceTranslator sync.Once
)

func GetInstance() *Translator {
onceTranslator.Do(func() {
apiTranslator = New()
})
return apiTranslator
}

func New() *Translator {
return &Translator{
id: "huawei_cloud_nlp",
name: "华为云NLP",
qps: 20,
procMax: 10,
textMaxLen: 2000,
sep: "\n",
langSupported: []tt_translator.LangK{
{"zh", "中文(简体)"},
{"en", "英语"},
{"zh-tw", "中文(繁体)"},
{"ru", "俄语"},
{"fr", "法语"},
{"de", "德语"},
{"ko", "韩语"},
{"ja", "日语"},
{"th", "泰语"},
{"ar", "阿拉伯语"},
{"pt", "葡萄牙语"},
{"tr", "土耳其语"},
{"es", "西班牙语"},
{"vi", "越南语"},
},
}
}

var langTo = map[string]model.TextTranslationReqTo{
"zh": model.GetTextTranslationReqToEnum().ZH,
"en": model.GetTextTranslationReqToEnum().EN,
"zh-tw": model.GetTextTranslationReqToEnum().ZH_TW,
"ru": model.GetTextTranslationReqToEnum().RU,
"fr": model.GetTextTranslationReqToEnum().FR,
"de": model.GetTextTranslationReqToEnum().DE,
"ko": model.GetTextTranslationReqToEnum().KO,
"ja": model.GetTextTranslationReqToEnum().JA,
"th": model.GetTextTranslationReqToEnum().TH,
"ar": model.GetTextTranslationReqToEnum().AR,
"pt": model.GetTextTranslationReqToEnum().PT,
"tr": model.GetTextTranslationReqToEnum().TR,
"es": model.GetTextTranslationReqToEnum().ES,
"vi": model.GetTextTranslationReqToEnum().VI,
}

var langFrom = map[string]model.TextTranslationReqFrom{
"zh": model.GetTextTranslationReqFromEnum().ZH,
"en": model.GetTextTranslationReqFromEnum().EN,
"zh-tw": model.GetTextTranslationReqFromEnum().ZH_TW,
"ru": model.GetTextTranslationReqFromEnum().RU,
"fr": model.GetTextTranslationReqFromEnum().FR,
"de": model.GetTextTranslationReqFromEnum().DE,
"ko": model.GetTextTranslationReqFromEnum().KO,
"ja": model.GetTextTranslationReqFromEnum().JA,
"th": model.GetTextTranslationReqFromEnum().TH,
"ar": model.GetTextTranslationReqFromEnum().AR,
"pt": model.GetTextTranslationReqFromEnum().PT,
"tr": model.GetTextTranslationReqFromEnum().TR,
"es": model.GetTextTranslationReqFromEnum().ES,
"vi": model.GetTextTranslationReqFromEnum().VI,
}

type Translator struct {
id string
name string
cfg *Cfg
qps int
procMax int
textMaxLen int
langSupported []tt_translator.LangK
sep string
}

func (customT *Translator) Init(cfg interface{}) {
customT.cfg = cfg.(*Cfg)
if customT.cfg.Region == "" {
customT.cfg.Region = "cn-north-4"
}
}

func (customT *Translator) GetId() string { return customT.id }
func (customT *Translator) GetName() string { return customT.name }
func (customT *Translator) GetCfg() interface{} { return customT.cfg }
func (customT *Translator) GetQPS() int { return customT.qps }
func (customT *Translator) GetProcMax() int { return customT.procMax }
func (customT *Translator) GetTextMaxLen() int { return customT.textMaxLen }
func (customT *Translator) GetLangSupported() []tt_translator.LangK { return customT.langSupported }
func (customT *Translator) GetSep() string { return customT.sep }

func (customT *Translator) IsValid() bool {
fmt.Println(customT.cfg)
return customT.cfg != nil && customT.cfg.AKId != "" && customT.cfg.SkKey != "" && customT.cfg.ProjectId != ""
}

func (customT *Translator) Translate(args *tt_translator.TranslateArgs) (*tt_translator.TranslateRes, error) {
timeStart := carbon.Now()
ret := new(tt_translator.TranslateRes)

request := &model.RunTextTranslationRequest{}
sceneTextTranslationReq := model.GetTextTranslationReqSceneEnum().COMMON
request.Body = &model.TextTranslationReq{
Scene: &sceneTextTranslationReq,
To: langTo[args.ToLang],
From: langFrom[args.FromLang],
Text: args.TextContent,
}

resp, err := customT.getClient().RunTextTranslation(request)

if err != nil {
tt_log.GetInstance().Error(fmt.Sprintf("调用接口失败, 引擎: %s, 错误: %s", customT.GetName(), err))
return nil, fmt.Errorf("调用接口失败(%s)", err)
}
if resp.ErrorCode != nil && *resp.ErrorCode != "" {
tt_log.GetInstance().Error(fmt.Sprintf("接口响应错误, 引擎: %s, 错误: %s(%s)", customT.GetName(), *resp.ErrorCode, *resp.ErrorMsg))
return nil, fmt.Errorf("响应错误(代码: %s, 错误: %s)", *resp.ErrorCode, *resp.ErrorMsg)
}

srcTexts := strings.Split(*resp.SrcText, customT.GetSep())
translatedTexts := strings.Split(*resp.TranslatedText, customT.GetSep())
if len(srcTexts) != len(translatedTexts) {
tt_log.GetInstance().Error(fmt.Sprintf("响应解析错误, 引擎: %s, 错误: 译文和原文数量匹配失败", customT.GetName()))
return nil, errors.New("译文和原文数量匹配失败")
}
for idx, text := range srcTexts {
ret.Results = append(ret.Results, &tt_translator.TranslateResBlock{
Id: text,
TextTranslated: translatedTexts[idx],
})
}

ret.TimeUsed = int(carbon.Now().DiffAbsInSeconds(timeStart))
return ret, nil

}

func (customT *Translator) getAuth() *basic.Credentials {
return basic.NewCredentialsBuilder().WithAk(customT.cfg.AKId).WithSk(customT.cfg.SkKey).Build()
}

func (customT *Translator) getClient() *nlp.NlpClient {
return nlp.NewNlpClient(
nlp.NlpClientBuilder().
WithRegion(region.ValueOf("cn-north-4")).
WithCredential(customT.getAuth()).
Build(),
)
}
11 changes: 11 additions & 0 deletions tst/tt_translator/ling_va/cfg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package ling_va

type Cfg struct {
DataId string `mapstructure:"data_id"`
}

func (customC Cfg) DefaultCfg() *Cfg {
return &Cfg{
DataId: "3qnDcUVykFKnSC3cdRX2t",
}
}
6 changes: 4 additions & 2 deletions tst/tt_translator/ling_va/translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,15 @@ func New() *Translator {
type Translator struct {
id string
name string
cfg *Cfg
qps int
procMax int
textMaxLen int
langSupported []tt_translator.LangK
sep string
}

func (customT *Translator) Init(_ interface{}) {}
func (customT *Translator) Init(cfg interface{}) { customT.cfg = cfg.(*Cfg) }

func (customT *Translator) GetId() string { return customT.id }
func (customT *Translator) GetName() string { return customT.name }
Expand All @@ -69,11 +70,12 @@ func (customT *Translator) GetProcMax() int { return cus
func (customT *Translator) GetTextMaxLen() int { return customT.textMaxLen }
func (customT *Translator) GetLangSupported() []tt_translator.LangK { return customT.langSupported }
func (customT *Translator) GetSep() string { return customT.sep }
func (customT *Translator) IsValid() bool { return customT.cfg.DataId != "" }

func (customT *Translator) Translate(args *tt_translator.TranslateArgs) (*tt_translator.TranslateRes, error) {
timeStart := carbon.Now()

var api = "https://lingva.ml/_next/data/3qnDcUVykFKnSC3cdRX2t"
var api = fmt.Sprintf("https://lingva.ml/_next/data/%s", customT.cfg.DataId)
queryUrl := fmt.Sprintf(
"%s/%s/%s/%s.json", api,
args.FromLang, args.ToLang, url.PathEscape(args.TextContent),
Expand Down
1 change: 1 addition & 0 deletions tst/tt_translator/translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type ITranslator interface {
GetTextMaxLen() int
GetLangSupported() []LangK
GetSep() string
IsValid() bool
Translate(*TranslateArgs) (*TranslateRes, error)
}

Expand Down
1 change: 1 addition & 0 deletions tst/tt_translator/youdao/translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ func (customT *Translator) GetProcMax() int { return cus
func (customT *Translator) GetTextMaxLen() int { return customT.textMaxLen }
func (customT *Translator) GetLangSupported() []tt_translator.LangK { return customT.langSupported }
func (customT *Translator) GetSep() string { return customT.sep }
func (customT *Translator) IsValid() bool { return true }

func (customT *Translator) Translate(args *tt_translator.TranslateArgs) (*tt_translator.TranslateRes, error) {
timeStart := carbon.Now()
Expand Down

0 comments on commit 6b3532b

Please sign in to comment.