🚧 Optimize
This commit is contained in:
210
internal/common/translator/tartunlp_translator.go
Normal file
210
internal/common/translator/tartunlp_translator.go
Normal file
@@ -0,0 +1,210 @@
|
||||
// Package translator 提供文本翻译功能
|
||||
package translator
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
// TartuNLPTranslator TartuNLP翻译器结构体
|
||||
type TartuNLPTranslator struct {
|
||||
httpClient *http.Client // HTTP客户端
|
||||
Timeout time.Duration // 请求超时时间
|
||||
languages map[string]LanguageInfo // 支持的语言列表
|
||||
}
|
||||
|
||||
// 常量定义
|
||||
const (
|
||||
tartuNLPDefaultTimeout = 300 * time.Second // 默认超时时间300秒
|
||||
tartuNLPAPIURL = "https://api.tartunlp.ai/translation/v2" // TartuNLP API地址
|
||||
tartuNLPLengthLimit = 5000 // 长度限制5000字符
|
||||
)
|
||||
|
||||
// 错误定义
|
||||
var (
|
||||
ErrTartuNLPNetworkError = errors.New("tartunlp translator network error")
|
||||
ErrTartuNLPUnsupportedLang = errors.New("tartunlp translator unsupported language")
|
||||
ErrTartuNLPResponseError = errors.New("tartunlp translator response error")
|
||||
ErrTartuNLPLengthExceeded = errors.New("tartunlp translator text length exceeded")
|
||||
)
|
||||
|
||||
// TartuNLPRequest TartuNLP请求结构体
|
||||
type TartuNLPRequest struct {
|
||||
Text []string `json:"text"` // 要翻译的文本数组
|
||||
Src string `json:"src"` // 源语言
|
||||
Tgt string `json:"tgt"` // 目标语言
|
||||
}
|
||||
|
||||
// TartuNLPResponse TartuNLP响应结构体
|
||||
type TartuNLPResponse struct {
|
||||
Result []string `json:"result"` // 翻译结果数组
|
||||
}
|
||||
|
||||
// NewTartuNLPTranslator 创建一个新的TartuNLP翻译器实例
|
||||
func NewTartuNLPTranslator() *TartuNLPTranslator {
|
||||
translator := &TartuNLPTranslator{
|
||||
httpClient: &http.Client{
|
||||
Timeout: tartuNLPDefaultTimeout,
|
||||
},
|
||||
Timeout: tartuNLPDefaultTimeout,
|
||||
languages: initTartuNLPLanguages(),
|
||||
}
|
||||
|
||||
return translator
|
||||
}
|
||||
|
||||
// initTartuNLPLanguages 初始化TartuNLP翻译器支持的语言列表
|
||||
func initTartuNLPLanguages() map[string]LanguageInfo {
|
||||
// 创建语言映射表
|
||||
languages := make(map[string]LanguageInfo)
|
||||
|
||||
// 添加支持的语言
|
||||
// 基于 TartuNLP API 支持的语言列表
|
||||
languages["en"] = LanguageInfo{Code: "en", Name: "English"}
|
||||
languages["et"] = LanguageInfo{Code: "et", Name: "Estonian"}
|
||||
languages["de"] = LanguageInfo{Code: "de", Name: "German"}
|
||||
languages["lt"] = LanguageInfo{Code: "lt", Name: "Lithuanian"}
|
||||
languages["lv"] = LanguageInfo{Code: "lv", Name: "Latvian"}
|
||||
languages["fi"] = LanguageInfo{Code: "fi", Name: "Finnish"}
|
||||
languages["ru"] = LanguageInfo{Code: "ru", Name: "Russian"}
|
||||
languages["no"] = LanguageInfo{Code: "no", Name: "Norwegian"}
|
||||
languages["hu"] = LanguageInfo{Code: "hu", Name: "Hungarian"}
|
||||
languages["se"] = LanguageInfo{Code: "se", Name: "Swedish"}
|
||||
|
||||
return languages
|
||||
}
|
||||
|
||||
// SetTimeout 设置请求超时时间
|
||||
func (t *TartuNLPTranslator) SetTimeout(timeout time.Duration) {
|
||||
t.Timeout = timeout
|
||||
t.httpClient.Timeout = timeout
|
||||
}
|
||||
|
||||
// Translate 使用标准语言标签进行文本翻译
|
||||
func (t *TartuNLPTranslator) Translate(text string, from language.Tag, to language.Tag) (string, error) {
|
||||
return t.translate(text, from.String(), to.String())
|
||||
}
|
||||
|
||||
// TranslateWithParams 使用简单字符串参数进行文本翻译
|
||||
func (t *TartuNLPTranslator) TranslateWithParams(text string, params TranslationParams) (string, error) {
|
||||
// 设置超时时间(如果有指定)
|
||||
if params.Timeout > 0 {
|
||||
t.SetTimeout(params.Timeout)
|
||||
}
|
||||
|
||||
return t.translate(text, params.From, params.To)
|
||||
}
|
||||
|
||||
// checkLengthLimit 检查文本长度是否超出限制
|
||||
func (t *TartuNLPTranslator) checkLengthLimit(text string) error {
|
||||
if len(text) > tartuNLPLengthLimit {
|
||||
return fmt.Errorf("%w: text length %d exceeds limit %d", ErrTartuNLPLengthExceeded, len(text), tartuNLPLengthLimit)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// translate 执行实际翻译操作
|
||||
func (t *TartuNLPTranslator) translate(text, from, to string) (string, error) {
|
||||
if text == "" {
|
||||
return "", fmt.Errorf("text cannot be empty")
|
||||
}
|
||||
|
||||
// 检查文本长度限制
|
||||
if err := t.checkLengthLimit(text); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 转换语言代码为TartuNLP格式
|
||||
fromLower := strings.ToLower(from)
|
||||
toLower := strings.ToLower(to)
|
||||
|
||||
// 验证源语言支持
|
||||
if _, ok := t.languages[fromLower]; !ok {
|
||||
return "", fmt.Errorf("%w: source language '%s' not supported by TartuNLP", ErrTartuNLPUnsupportedLang, from)
|
||||
}
|
||||
|
||||
// 验证目标语言支持
|
||||
if _, ok := t.languages[toLower]; !ok {
|
||||
return "", fmt.Errorf("%w: target language '%s' not supported by TartuNLP", ErrTartuNLPUnsupportedLang, to)
|
||||
}
|
||||
|
||||
// 创建带超时的context
|
||||
ctx, cancel := context.WithTimeout(context.Background(), t.Timeout)
|
||||
defer cancel()
|
||||
|
||||
// 构建请求体
|
||||
request := TartuNLPRequest{
|
||||
Text: []string{text},
|
||||
Src: fromLower,
|
||||
Tgt: toLower,
|
||||
}
|
||||
|
||||
// 序列化请求
|
||||
jsonData, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to marshal request: %w", err)
|
||||
}
|
||||
|
||||
// 创建HTTP请求
|
||||
req, err := http.NewRequestWithContext(ctx, "POST", tartuNLPAPIURL, bytes.NewBuffer(jsonData))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to create request: %w", err)
|
||||
}
|
||||
|
||||
// 设置请求头
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Accept", "application/json")
|
||||
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
|
||||
|
||||
// 发送请求
|
||||
resp, err := t.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("%w: %v", ErrTartuNLPNetworkError, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// 检查HTTP状态码
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
return "", fmt.Errorf("%w: HTTP %d - %s", ErrTartuNLPResponseError, resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
// 读取响应体
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to read response body: %w", err)
|
||||
}
|
||||
|
||||
// 解析响应
|
||||
var response TartuNLPResponse
|
||||
if err := json.Unmarshal(body, &response); err != nil {
|
||||
return "", fmt.Errorf("%w: failed to parse response: %v", ErrTartuNLPResponseError, err)
|
||||
}
|
||||
|
||||
// 检查响应结果
|
||||
if len(response.Result) == 0 {
|
||||
return "", fmt.Errorf("%w: empty translation result", ErrTartuNLPResponseError)
|
||||
}
|
||||
|
||||
return response.Result[0], nil
|
||||
}
|
||||
|
||||
// GetSupportedLanguages 获取翻译器支持的语言列表
|
||||
func (t *TartuNLPTranslator) GetSupportedLanguages() map[string]LanguageInfo {
|
||||
return t.languages
|
||||
}
|
||||
|
||||
// IsLanguageSupported 检查指定的语言代码是否受支持
|
||||
func (t *TartuNLPTranslator) IsLanguageSupported(languageCode string) bool {
|
||||
_, exists := t.languages[strings.ToLower(languageCode)]
|
||||
return exists
|
||||
}
|
||||
Reference in New Issue
Block a user