v/GTT
1
0
mirror of https://github.com/eeeXun/GTT.git synced 2025-05-27 21:11:11 -07:00
2023-04-15 01:35:09 +08:00

127 lines
3.0 KiB
Go

package bingtranslate
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"regexp"
"strings"
"github.com/eeeXun/gtt/internal/translate/core"
)
const (
setUpURL = "https://www.bing.com/translator"
textURL = "https://www.bing.com/ttranslatev3?IG=%s&IID=%s"
)
type BingTranslate struct {
*core.Language
*core.TTSLock
core.EngineName
}
type setUpData struct {
ig string
iid string
key string
token string
}
func NewBingTranslate() *BingTranslate {
return &BingTranslate{
Language: core.NewLanguage(),
TTSLock: core.NewTTSLock(),
EngineName: core.NewEngineName("BingTranslate"),
}
}
func (t *BingTranslate) GetAllLang() []string {
return lang
}
func (t *BingTranslate) setUp() (*setUpData, error) {
var data setUpData
res, err := http.Get(setUpURL)
if err != nil {
return nil, err
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
bodyStr := string(body)
igData := regexp.MustCompile(`IG:"([^"]+)"`).FindStringSubmatch(bodyStr)
if len(igData) < 2 {
return nil, errors.New(t.GetEngineName() + " IG not found")
}
data.ig = igData[1]
iidData := regexp.MustCompile(`data-iid="([^"]+)`).FindStringSubmatch(bodyStr)
if len(iidData) < 2 {
return nil, errors.New(t.GetEngineName() + " IID not found")
}
data.iid = iidData[1]
params := regexp.MustCompile(`params_AbusePreventionHelper = ([^;]+);`).FindStringSubmatch(bodyStr)
if len(params) < 2 {
return nil, errors.New(t.GetEngineName() + " Key and Token not found")
}
paramsStr := strings.Split(params[1][1:len(params[1])-1], ",")
data.key = paramsStr[0]
data.token = paramsStr[1][1 : len(paramsStr[1])-1]
return &data, nil
}
func (t *BingTranslate) Translate(message string) (translation, definition, partOfSpeech string, err error) {
var data []interface{}
initData, err := t.setUp()
if err != nil {
return "", "", "", err
}
userData := url.Values{
"fromLang": {langCode[t.GetSrcLang()]},
"to": {langCode[t.GetDstLang()]},
"text": {message},
"key": {initData.key},
"token": {initData.token},
}
req, err := http.NewRequest("POST",
fmt.Sprintf(textURL, initData.ig, initData.iid),
strings.NewReader(userData.Encode()),
)
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
req.Header.Add("User-Agent", core.UserAgent)
res, err := http.DefaultClient.Do(req)
if err != nil {
return "", "", "", err
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return "", "", "", err
}
if err = json.Unmarshal(body, &data); err != nil {
return "", "", "", err
}
if len(data) <= 0 {
return "", "", "", errors.New("Translation not found")
}
// translation
translation = fmt.Sprintf("%v",
data[0].(map[string]interface{})["translations"].([]interface{})[0].(map[string]interface{})["text"])
return translation, definition, partOfSpeech, nil
}
func (t *BingTranslate) PlayTTS(lang, message string) error {
defer t.ReleaseLock()
return errors.New(t.GetEngineName() + " does not support text to speech")
}