v/GTT
1
0
mirror of https://github.com/eeeXun/GTT.git synced 2025-05-16 15:50:52 -07:00

feat(translator): add BingTranslate

This commit is contained in:
eeeXun 2023-04-15 01:35:09 +08:00
parent 42b01a8cb2
commit 2e41fa800c
7 changed files with 403 additions and 4 deletions

View File

@ -5,6 +5,7 @@ Google Translate TUI (Originally)
Supported Translator: Supported Translator:
[`ApertiumTranslate`](https://www.apertium.org/), [`ApertiumTranslate`](https://www.apertium.org/),
[`ArgosTranslate`](https://translate.argosopentech.com/), [`ArgosTranslate`](https://translate.argosopentech.com/),
[`BingTranslate`](https://www.bing.com/translator),
[`GoogleTranslate`](https://translate.google.com/), [`GoogleTranslate`](https://translate.google.com/),
[`ReversoTranslate`](https://www.reverso.net/text-translation) [`ReversoTranslate`](https://www.reverso.net/text-translation)
@ -48,6 +49,7 @@ See language on:
- [Apertium Translate](https://www.apertium.org/) for `ApertiumTranslate` - [Apertium Translate](https://www.apertium.org/) for `ApertiumTranslate`
- [argosopentech/argos-translate](https://github.com/argosopentech/argos-translate#supported-languages) for `ArgosTranslate` - [argosopentech/argos-translate](https://github.com/argosopentech/argos-translate#supported-languages) for `ArgosTranslate`
- [Bing Translate](https://www.bing.com/translator) for `BingTranslate`
- [Google Language support](https://cloud.google.com/translate/docs/languages) for `GoogleTranslate` - [Google Language support](https://cloud.google.com/translate/docs/languages) for `GoogleTranslate`
- [Reverso Translation](https://www.reverso.net/text-translation) for `ReversoTranslate` - [Reverso Translation](https://www.reverso.net/text-translation) for `ReversoTranslate`

View File

@ -22,6 +22,8 @@ func configInit() {
"destination.language.apertiumtranslate": "English", "destination.language.apertiumtranslate": "English",
"source.language.argostranslate": "English", "source.language.argostranslate": "English",
"destination.language.argostranslate": "English", "destination.language.argostranslate": "English",
"source.language.bingtranslate": "English",
"destination.language.bingtranslate": "English",
"source.language.googletranslate": "English", "source.language.googletranslate": "English",
"destination.language.googletranslate": "English", "destination.language.googletranslate": "English",
"source.language.reversotranslate": "English", "source.language.reversotranslate": "English",

View File

@ -0,0 +1,256 @@
package bingtranslate
var (
lang = []string{
"Afrikaans",
"Albanian",
"Amharic",
"Auto",
"Arabic",
"Armenian",
"Assamese",
"Azerbaijani",
"Bangla",
"Bashkir",
"Basque",
"Bosnian",
"Bulgarian",
"Cantonese (Traditional)",
"Catalan",
"Chinese (Literary)",
"Chinese Simplified",
"Chinese Traditional",
"Croatian",
"Czech",
"Danish",
"Dari",
"Divehi",
"Dutch",
"English",
"Estonian",
"Faroese",
"Fijian",
"Filipino",
"Finnish",
"French",
"French (Canada)",
"Galician",
"Ganda",
"Georgian",
"German",
"Greek",
"Gujarati",
"Haitian Creole",
"Hausa",
"Hebrew",
"Hindi",
"Hmong Daw",
"Hungarian",
"Icelandic",
"Igbo",
"Indonesian",
"Inuinnaqtun",
"Inuktitut",
"Inuktitut (Latin)",
"Irish",
"Italian",
"Japanese",
"Kannada",
"Kazakh",
"Khmer",
"Kinyarwanda",
"Klingon (Latin)",
"Korean",
"Kurdish (Central)",
"Kurdish (Northern)",
"Kyrgyz",
"Lao",
"Latvian",
"Lingala",
"Lithuanian",
"Lower Sorbian",
"Macedonian",
"Malagasy",
"Malay",
"Malayalam",
"Maltese",
"Marathi",
"Mongolian (Cyrillic)",
"Mongolian (Traditional)",
"Myanmar (Burmese)",
"Māori",
"Nepali",
"Norwegian",
"Nyanja",
"Odia",
"Pashto",
"Persian",
"Polish",
"Portuguese (Brazil)",
"Portuguese (Portugal)",
"Punjabi",
"Querétaro Otomi",
"Romanian",
"Rundi",
"Russian",
"Samoan",
"Serbian (Cyrillic)",
"Serbian (Latin)",
"Sesotho",
"Sesotho sa Leboa",
"Setswana",
"Shona",
"Slovak",
"Slovenian",
"Somali",
"Spanish",
"Swahili",
"Swedish",
"Tahitian",
"Tamil",
"Tatar",
"Telugu",
"Thai",
"Tibetan",
"Tigrinya",
"Tongan",
"Turkish",
"Turkmen",
"Ukrainian",
"Urdu",
"Uyghur",
"Uzbek (Latin)",
"Vietnamese",
"Welsh",
"Xhosa",
"Yoruba",
"Yucatec Maya",
"Zulu",
}
langCode = map[string]string{
"Afrikaans": "af",
"Albanian": "sq",
"Amharic": "am",
"Auto": "auto-detect",
"Arabic": "ar",
"Armenian": "hy",
"Assamese": "as",
"Azerbaijani": "az",
"Bangla": "bn",
"Bashkir": "ba",
"Basque": "eu",
"Bosnian": "bs",
"Bulgarian": "bg",
"Cantonese (Traditional)": "yue",
"Catalan": "ca",
"Chinese (Literary)": "lzh",
"Chinese Simplified": "zh-Hans",
"Chinese Traditional": "zh-Hant",
"Croatian": "hr",
"Czech": "cs",
"Danish": "da",
"Dari": "prs",
"Divehi": "dv",
"Dutch": "nl",
"English": "en",
"Estonian": "et",
"Faroese": "fo",
"Fijian": "fj",
"Filipino": "fil",
"Finnish": "fi",
"French": "fr",
"French (Canada)": "fr-CA",
"Galician": "gl",
"Ganda": "lug",
"Georgian": "ka",
"German": "de",
"Greek": "el",
"Gujarati": "gu",
"Haitian Creole": "ht",
"Hausa": "ha",
"Hebrew": "he",
"Hindi": "hi",
"Hmong Daw": "mww",
"Hungarian": "hu",
"Icelandic": "is",
"Igbo": "ig",
"Indonesian": "id",
"Inuinnaqtun": "ikt",
"Inuktitut": "iu",
"Inuktitut (Latin)": "iu-Latn",
"Irish": "ga",
"Italian": "it",
"Japanese": "ja",
"Kannada": "kn",
"Kazakh": "kk",
"Khmer": "km",
"Kinyarwanda": "rw",
"Klingon (Latin)": "tlh-Latn",
"Korean": "ko",
"Kurdish (Central)": "ku",
"Kurdish (Northern)": "kmr",
"Kyrgyz": "ky",
"Lao": "lo",
"Latvian": "lv",
"Lingala": "ln",
"Lithuanian": "lt",
"Lower Sorbian": "dsb",
"Macedonian": "mk",
"Malagasy": "mg",
"Malay": "ms",
"Malayalam": "ml",
"Maltese": "mt",
"Marathi": "mr",
"Mongolian (Cyrillic)": "mn-Cyrl",
"Mongolian (Traditional)": "mn-Mong",
"Myanmar (Burmese)": "my",
"Māori": "mi",
"Nepali": "ne",
"Norwegian": "nb",
"Nyanja": "nya",
"Odia": "or",
"Pashto": "ps",
"Persian": "fa",
"Polish": "pl",
"Portuguese (Brazil)": "pt",
"Portuguese (Portugal)": "pt-PT",
"Punjabi": "pa",
"Querétaro Otomi": "otq",
"Romanian": "ro",
"Rundi": "run",
"Russian": "ru",
"Samoan": "sm",
"Serbian (Cyrillic)": "sr-Cyrl",
"Serbian (Latin)": "sr-Latn",
"Sesotho": "st",
"Sesotho sa Leboa": "nso",
"Setswana": "tn",
"Shona": "sn",
"Slovak": "sk",
"Slovenian": "sl",
"Somali": "so",
"Spanish": "es",
"Swahili": "sw",
"Swedish": "sv",
"Tahitian": "ty",
"Tamil": "ta",
"Tatar": "tt",
"Telugu": "te",
"Thai": "th",
"Tibetan": "bo",
"Tigrinya": "ti",
"Tongan": "to",
"Turkish": "tr",
"Turkmen": "tk",
"Ukrainian": "uk",
"Urdu": "ur",
"Uyghur": "ug",
"Uzbek (Latin)": "uz",
"Vietnamese": "vi",
"Welsh": "cy",
"Xhosa": "xh",
"Yoruba": "yo",
"Yucatec Maya": "yua",
"Zulu": "zu",
}
)

View File

@ -0,0 +1,126 @@
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")
}

View File

@ -0,0 +1,5 @@
package core
const (
UserAgent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"
)

View File

@ -19,7 +19,6 @@ import (
const ( const (
textURL = "https://api.reverso.net/translate/v1/translation" textURL = "https://api.reverso.net/translate/v1/translation"
ttsURL = "https://voice.reverso.net/RestPronunciation.svc/v1/output=json/GetVoiceStream/voiceName=%s?voiceSpeed=80&inputText=%s" ttsURL = "https://voice.reverso.net/RestPronunciation.svc/v1/output=json/GetVoiceStream/voiceName=%s?voiceSpeed=80&inputText=%s"
userAgent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36"
) )
type ReversoTranslate struct { type ReversoTranslate struct {
@ -65,7 +64,7 @@ func (t *ReversoTranslate) Translate(message string) (translation, definition, p
textURL, textURL,
bytes.NewBuffer([]byte(userData))) bytes.NewBuffer([]byte(userData)))
req.Header.Add("Content-Type", "application/json") req.Header.Add("Content-Type", "application/json")
req.Header.Add("User-Agent", userAgent) req.Header.Add("User-Agent", core.UserAgent)
res, err := http.DefaultClient.Do(req) res, err := http.DefaultClient.Do(req)
if err != nil { if err != nil {
return "", "", "", err return "", "", "", err
@ -124,7 +123,7 @@ func (t *ReversoTranslate) PlayTTS(lang, message string) error {
base64.StdEncoding.EncodeToString([]byte(message)), base64.StdEncoding.EncodeToString([]byte(message)),
) )
req, _ := http.NewRequest("GET", urlStr, nil) req, _ := http.NewRequest("GET", urlStr, nil)
req.Header.Add("User-Agent", userAgent) req.Header.Add("User-Agent", core.UserAgent)
res, err := http.DefaultClient.Do(req) res, err := http.DefaultClient.Do(req)
if err != nil { if err != nil {
return err return err

View File

@ -3,12 +3,19 @@ package translate
import ( import (
"github.com/eeeXun/gtt/internal/translate/apertiumtranslate" "github.com/eeeXun/gtt/internal/translate/apertiumtranslate"
"github.com/eeeXun/gtt/internal/translate/argostranslate" "github.com/eeeXun/gtt/internal/translate/argostranslate"
"github.com/eeeXun/gtt/internal/translate/bingtranslate"
"github.com/eeeXun/gtt/internal/translate/googletranslate" "github.com/eeeXun/gtt/internal/translate/googletranslate"
"github.com/eeeXun/gtt/internal/translate/reversotranslate" "github.com/eeeXun/gtt/internal/translate/reversotranslate"
) )
var ( var (
AllTranslator = []string{"ApertiumTranslate", "ArgosTranslate", "GoogleTranslate", "ReversoTranslate"} AllTranslator = []string{
"ApertiumTranslate",
"BingTranslate",
"ArgosTranslate",
"GoogleTranslate",
"ReversoTranslate",
}
) )
type Translator interface { type Translator interface {
@ -57,6 +64,8 @@ func NewTranslator(name string) Translator {
translator = apertiumtranslate.NewApertiumTranslate() translator = apertiumtranslate.NewApertiumTranslate()
case "ArgosTranslate": case "ArgosTranslate":
translator = argostranslate.NewArgosTranslate() translator = argostranslate.NewArgosTranslate()
case "BingTranslate":
translator = bingtranslate.NewBingTranslate()
case "GoogleTranslate": case "GoogleTranslate":
translator = googletranslate.NewGoogleTranslate() translator = googletranslate.NewGoogleTranslate()
case "ReversoTranslate": case "ReversoTranslate":