Skip to content

Commit

Permalink
feat: 新增微软翻译(microsoft-edge);
Browse files Browse the repository at this point in the history
  • Loading branch information
speauty committed Apr 23, 2024
1 parent 5ae43ab commit 4f9f1bf
Show file tree
Hide file tree
Showing 7 changed files with 230 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
tidy:
go mod tidy

BinName=anto-v3.6.2-windows.exe
BinName=anto-v3.6.3-windows.exe

deploy: rs build

Expand Down
4 changes: 3 additions & 1 deletion bootstrap/boot.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"anto/domain/service/translator/g_deepl_x"
"anto/domain/service/translator/google_cloud"
"anto/domain/service/translator/huawei_cloud_nlp"
"anto/domain/service/translator/microsoft_edge"
"anto/domain/service/translator/niutrans"
"anto/domain/service/translator/openai"
"anto/domain/service/translator/openai_sweet"
Expand Down Expand Up @@ -51,13 +52,14 @@ func Boot(_ context.Context) {
deepl.API().Init(cfg.Singleton().DeepL)
deepl_pro.API().Init(cfg.Singleton().DeepLPro)
ai_baidu.API().Init(cfg.Singleton().AiBaidu)
microsoft_edge.API().Init(cfg.Singleton().MicrosoftEdge)

repository.GetTranslators().Register(
huawei_cloud_nlp.API(), baidu.API(),
tencent_cloud_mt.API(), openapi_youdao.API(),
ali_cloud_mt.API(), caiyunai.API(), niutrans.API(),
volcengine.API(), g_deepl_x.API(),
google_cloud.API(), openai.API(), deepl.API(), deepl_pro.API(),
openai_sweet.API(), ai_baidu.API(),
openai_sweet.API(), ai_baidu.API(), microsoft_edge.API(),
)
}
3 changes: 3 additions & 0 deletions cfg/cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"anto/domain/service/translator/google_cloud"
"anto/domain/service/translator/huawei_cloud_nlp"
"anto/domain/service/translator/ling_va"
"anto/domain/service/translator/microsoft_edge"
"anto/domain/service/translator/niutrans"
"anto/domain/service/translator/openai"
"anto/domain/service/translator/openai_sweet"
Expand Down Expand Up @@ -50,6 +51,7 @@ func Singleton() *Cfg {
apiSingleton.DeepL = new(deepl.Config).Default().(*deepl.Config)
apiSingleton.DeepLPro = new(deepl_pro.Config).Default().(*deepl_pro.Config)
apiSingleton.AiBaidu = new(ai_baidu.Config).Default().(*ai_baidu.Config)
apiSingleton.MicrosoftEdge = new(microsoft_edge.Config).Default().(*microsoft_edge.Config)
})
return apiSingleton
}
Expand All @@ -74,6 +76,7 @@ type Cfg struct {
DeepL *deepl.Config `mapstructure:"deepl"`
DeepLPro *deepl_pro.Config `mapstructure:"deepl_pro"`
AiBaidu *ai_baidu.Config `mapstructure:"ai_baidu"`
MicrosoftEdge *microsoft_edge.Config `mapstructure:"microsoft_edge"`

currentViper *viper.Viper `mapstructure:"-"`
}
Expand Down
2 changes: 1 addition & 1 deletion common/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package common
const (
AppName = "anto"
Author = "speauty"
Version = "v3.6.2"
Version = "v3.6.3"
DownloadLatestVersionUrl = "http://kodo.app.speauty.cn/anto-latest-windows.exe"

GoUidLen = 8
Expand Down
56 changes: 56 additions & 0 deletions domain/service/translator/microsoft_edge/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package microsoft_edge

import (
"anto/domain/service/translator"
"github.com/spf13/viper"
)

type Config struct {
*translator.DefaultConfig
QPS int `mapstructure:"qps"`
MaxCharNum int `mapstructure:"max_single_text_length"`
MaxCoroutineNum int `mapstructure:"max_coroutine_num"`
}

func (config *Config) Default() translator.ImplConfig {
return &Config{
MaxCharNum: 1000, QPS: 10, MaxCoroutineNum: 5,
}
}

func (config *Config) SyncDisk(currentViper *viper.Viper) error {
tagAndVal := config.JoinAllTagAndValue(API(), config, "mapstructure")

for tag, val := range tagAndVal {
currentViper.Set(tag, val)
}
return nil
}

func (config *Config) GetQPS() int { return config.QPS }
func (config *Config) GetMaxCharNum() int { return config.MaxCharNum }
func (config *Config) GetMaxCoroutineNum() int { return config.MaxCoroutineNum }

func (config *Config) SetQPS(num int) error {
if err := config.ValidatorNum(num); err != nil {
return err
}
config.QPS = num
return nil
}

func (config *Config) SetMaxCharNum(num int) error {
if err := config.ValidatorNum(num); err != nil {
return err
}
config.MaxCharNum = num
return nil
}

func (config *Config) SetMaxCoroutineNum(num int) error {
if err := config.ValidatorNum(num); err != nil {
return err
}
config.MaxCoroutineNum = num
return nil
}
20 changes: 20 additions & 0 deletions domain/service/translator/microsoft_edge/lang.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package microsoft_edge

import (
"anto/domain/service/translator"
)

var langSupported = []translator.LangPair{
{"zh-cn", "中文"},
{"en", "英语"},
{"ja", "日语"},
{"ru", "俄语"},
{"fr", "法语"},
{"ko", "韩语"},
{"de", "德语"},
{"da", "丹麦语"},
{"nl", "荷兰语"},
{"it", "意大利语"},
{"ar", "阿拉伯语"},
{"be", "白俄罗斯语"},
}
146 changes: 146 additions & 0 deletions domain/service/translator/microsoft_edge/translator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package microsoft_edge

import (
"anto/domain/service/translator"
"anto/lib/log"
"context"
"encoding/json"
"fmt"
"github.com/golang-module/carbon"
"strings"
"sync"
)

var (
apiTranslator *Translator
onceTranslator sync.Once
)

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

func New() *Translator {
return &Translator{
id: "edge",
name: "微软翻译",
sep: "\n",
langSupported: langSupported,
}
}

// Translator LingVA翻译已崩溃, 当前处于不可用状态, 所以直接禁用
type Translator struct {
id string
name string
cfg translator.ImplConfig
langSupported []translator.LangPair
sep string
token string
}

func (customT *Translator) Init(cfg translator.ImplConfig) { customT.cfg = cfg }

func (customT *Translator) GetId() string { return customT.id }
func (customT *Translator) GetShortId() string { return "me" }
func (customT *Translator) GetName() string { return customT.name }
func (customT *Translator) GetCfg() translator.ImplConfig { return customT.cfg }
func (customT *Translator) GetLangSupported() []translator.LangPair { return customT.langSupported }
func (customT *Translator) GetSep() string { return customT.sep }
func (customT *Translator) IsValid() bool { return true }

func (customT *Translator) Translate(ctx context.Context, args *translator.TranslateArgs) (*translator.TranslateRes, error) {
timeStart := carbon.Now()
token, err := customT.getToken(ctx)
if err != nil {
return nil, err
}

var queryUrl = fmt.Sprintf(
"https://api-edge.cognitive.microsofttranslator.com/translate?from=%s&to=%s&api-version=3.0&includeSentenceLength=true",
args.FromLang, args.ToLang,
)
req := []microsoftEdgeReq{}
textReq := strings.Split(args.TextContent, customT.sep)
for _, text := range textReq {
req = append(req, microsoftEdgeReq{Text: text})
}
respBytes, err := translator.RequestSimpleHttp(ctx, customT, queryUrl, true, req, map[string]string{
"Authorization": fmt.Sprintf("Bearer Bearer %s", token),
})
if err != nil {
return nil, err
}
resp := []microsoftEdgeResp{}
if err := json.Unmarshal(respBytes, &resp); err != nil {
log.Singleton().ErrorF("解析报文异常, 引擎: %s, 错误: %s", customT.GetName(), err)
return nil, fmt.Errorf("解析报文出现异常, 错误: %s", err.Error())
}
textResp := []string{}
for _, edgeResp := range resp {
if edgeResp.Error.Code != 0 {
// The request is not authorized because credentials are missing or invalid.
if edgeResp.Error.Code == 401001 {
customT.token = ""
}
return nil, fmt.Errorf("翻译异常: %s", edgeResp.Error.Message)
}
for _, translation := range edgeResp.Translations {
textResp = append(textResp, translation.Text)
}
}
if len(textReq) != len(textResp) {
return nil, translator.ErrSrcAndTgtNotMatched
}

ret := new(translator.TranslateRes)
for textIdx, textSource := range textReq {
ret.Results = append(ret.Results, &translator.TranslateResBlock{
Id: textSource,
TextTranslated: textResp[textIdx],
})
}

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

}

func (customT *Translator) getToken(ctx context.Context) (token string, err error) {
if customT.token == "" {
tokenBytes := []byte{}
tokenBytes, err = translator.RequestSimpleHttp(ctx, customT, "https://edge.microsoft.com/translate/auth", false, nil, nil)
if err != nil {
return
}
customT.token = string(tokenBytes)
}
token = customT.token
return
}

type microsoftEdgeReq struct {
Text string `json:"text"`
}

type microsoftEdgeResp struct {
Error struct {
Code int `json:"code"`
Message string `json:"message"`
} `json:"error"`
DetectedLanguage struct {
Language string `json:"language"`
Score float64 `json:"score"`
} `json:"detectedLanguage"`
Translations []struct {
Text string `json:"text"`
To string `json:"to"`
SentLen struct {
SrcSentLen []int `json:"srcSentLen"`
TransSentLen []int `json:"transSentLen"`
} `json:"sentLen"`
} `json:"translations"`
}

0 comments on commit 4f9f1bf

Please sign in to comment.