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

feat: add LibreTranslate, remove ArgosTranslate

ArgosTranslate is offline. Change it to LibreTranslate
This commit is contained in:
eeeXun 2024-08-10 21:45:32 +08:00
parent b3f4135732
commit 8a9f267229
9 changed files with 169 additions and 76 deletions

View File

@ -4,12 +4,12 @@ Google Translate TUI (Originally)
Supported Translator:
[`Apertium`](https://www.apertium.org/),
[`Argos`](https://translate.argosopentech.com/),
[`Bing`](https://www.bing.com/translator),
[`ChatGPT`](https://chat.openai.com/),
[`DeepL`](https://deepl.com/translator)(only free API),
[`DeepLX`](https://github.com/OwO-Network/DeepLX),
[`Google`](https://translate.google.com/)(default),
[`Libre`](https://libretranslate.com/),
[`Reverso`](https://www.reverso.net/text-translation)
## ScreenShot
@ -52,6 +52,22 @@ host:
deeplx: 127.0.0.1:1188 # <- Replace with your server IP address and port
```
## Libre
If you want to use official [LibreTranslate](https://libretranslate.com/), you have to obtain an API Key on their [website](https://portal.libretranslate.com/).
Alternatively, if you want to host it by yourself, you must provide the IP address and port.
Make sure add them to `$XDG_CONFIG_HOME/gtt/server.yaml` or `$HOME/.config/gtt/server.yaml`.
See the example in [server.yaml](example/server.yaml) file.
```yaml
api_key:
libre:
value: LIBRE_API_KEY # <- Replace with your API Key
# file: $HOME/secrets/libre.txt # <- You can also specify the file where to read API Key
host:
libre: 127.0.0.1:5000 # <- Replace with your server IP address and port
```
## Install
### Dependencies
@ -214,12 +230,12 @@ gtt -src "English" -dst "Chinese (Traditional)"
See available languages on:
- [Apertium Translate](https://www.apertium.org/) for `Apertium`
- [argosopentech/argos-translate](https://github.com/argosopentech/argos-translate#supported-languages) for `Argos`
- [Bing language-support](https://learn.microsoft.com/en-us/azure/cognitive-services/translator/language-support#translation) for `Bing`
- `ChatGPT` is same as `Google`. See [Google Language support](https://cloud.google.com/translate/docs/languages)
- [DeepL API docs](https://www.deepl.com/docs-api/translate-text/) for `DeepL`
- `DeepLX` is same as `DeepL`. See [DeepL API docs](https://cloud.google.com/translate/docs/languages)
- [Google Language support](https://cloud.google.com/translate/docs/languages) for `Google`
- [LibreTranslate Languages](https://libretranslate.com/languages) for `Libre`
- [Reverso Translation](https://www.reverso.net/text-translation) for `Reverso`
## Credit

View File

@ -45,8 +45,6 @@ func configInit() {
"destination.border_color": "blue",
"source.language.apertium": "English",
"destination.language.apertium": "English",
"source.language.argos": "English",
"destination.language.argos": "English",
"source.language.bing": "English",
"destination.language.bing": "English",
"source.language.chatgpt": "English",
@ -57,6 +55,8 @@ func configInit() {
"destination.language.deeplx": "English",
"source.language.google": "English",
"destination.language.google": "English",
"source.language.libre": "English",
"destination.language.libre": "English",
"source.language.reverso": "English",
"destination.language.reverso": "English",
"translator": "Google",
@ -162,7 +162,7 @@ func configInit() {
// Import api key and host if file exists
if err := serverConfig.ReadInConfig(); err == nil {
// api key
for _, name := range []string{"ChatGPT", "DeepL", "DeepLX"} {
for _, name := range []string{"ChatGPT", "DeepL", "DeepLX", "Libre"} {
// Read from value first, then read from file
if serverConfig.Get(fmt.Sprintf("api_key.%s.value", name)) != nil {
translators[name].SetAPIKey(serverConfig.GetString(fmt.Sprintf("api_key.%s.value", name)))
@ -174,8 +174,10 @@ func configInit() {
}
}
// host
if serverConfig.Get("host.deeplx") != nil {
translators["DeepLX"].SetHost(serverConfig.GetString("host.deeplx"))
for _, name := range []string{"DeepLX", "Libre"} {
if serverConfig.Get(fmt.Sprintf("host.%s", name)) != nil {
translators[name].SetHost(serverConfig.GetString(fmt.Sprintf("host.%s", name)))
}
}
}
// Set argument language

View File

@ -9,5 +9,9 @@ api_key:
deeplx:
value: DEEPLX_API_KEY
# file: $HOME/secrets/deeplx.txt
libre:
value: LIBRE_API_KEY
# file: $HOME/secrets/libre.txt
host:
deeplx: 127.0.0.1:1188
libre: 127.0.0.1:5000

View File

@ -1,44 +0,0 @@
package argos
var (
lang = []string{
"Arabic",
"Auto",
"Chinese",
"English",
"French",
"German",
"Hindi",
"Indonesian",
"Irish",
"Italian",
"Japanese",
"Korean",
"Polish",
"Portuguese",
"Russian",
"Spanish",
"Turkish",
"Vietnamese",
}
langCode = map[string]string{
"Arabic": "ar",
"Auto": "auto",
"Chinese": "zh",
"English": "en",
"French": "fr",
"German": "de",
"Hindi": "hi",
"Indonesian": "id",
"Irish": "ga",
"Italian": "it",
"Japanese": "ja",
"Korean": "ko",
"Polish": "pl",
"Portuguese": "pt",
"Russian": "ru",
"Spanish": "es",
"Turkish": "tr",
"Vietnamese": "vi",
}
)

View File

@ -141,22 +141,28 @@ func (t *Translator) Translate(message string) (translation *core.Translation, e
}
// Bing will return the request with list when success.
// Otherwises, it would return map. Then the following err would not be nil.
if err = json.Unmarshal(body, &data); err == nil {
poses := make(posSet)
for _, pos := range data[0].(map[string]interface{})["translations"].([]interface{}) {
pos := pos.(map[string]interface{})
var words posWords
words.target = pos["displayTarget"].(string)
for _, backTranslation := range pos["backTranslations"].([]interface{}) {
backTranslation := backTranslation.(map[string]interface{})
words.add(backTranslation["displayText"].(string))
}
poses.add(pos["posTag"].(string), words)
}
translation.POS = poses.format()
if err = json.Unmarshal(body, &data); err != nil {
return nil, err
}
if len(data) <= 0 {
return nil, errors.New("Translation not found")
}
poses := make(posSet)
for _, pos := range data[0].(map[string]interface{})["translations"].([]interface{}) {
pos := pos.(map[string]interface{})
var words posWords
words.target = pos["displayTarget"].(string)
for _, backTranslation := range pos["backTranslations"].([]interface{}) {
backTranslation := backTranslation.(map[string]interface{})
words.add(backTranslation["displayText"].(string))
}
poses.add(pos["posTag"].(string), words)
}
translation.POS = poses.format()
return translation, nil
}

View File

@ -62,7 +62,7 @@ func (t *Translator) Translate(message string) (translation *core.Translation, e
}
if len(data) <= 0 {
return nil, errors.New("translation not found")
return nil, errors.New("Translation not found")
}
if res.StatusCode != 200 {
return nil, errors.New(data["message"].(string))

View File

@ -0,0 +1,98 @@
package libre
var (
lang = []string{
"Albanian",
"Arabic",
"Auto",
"Azerbaijani",
"Bengali",
"Bulgarian",
"Catalan",
"Chinese",
"Chinese (traditional)",
"Czech",
"Danish",
"Dutch",
"English",
"Esperanto",
"Estonian",
"Finnish",
"French",
"German",
"Greek",
"Hebrew",
"Hindi",
"Hungarian",
"Indonesian",
"Irish",
"Italian",
"Japanese",
"Korean",
"Latvian",
"Lithuanian",
"Malay",
"Norwegian",
"Persian",
"Polish",
"Portuguese",
"Romanian",
"Russian",
"Slovak",
"Slovenian",
"Spanish",
"Swedish",
"Tagalog",
"Thai",
"Turkish",
"Ukranian",
"Urdu",
}
langCode = map[string]string{
"Albanian": "sq",
"Arabic": "ar",
"Auto": "auto",
"Azerbaijani": "az",
"Bengali": "bn",
"Bulgarian": "bg",
"Catalan": "ca",
"Chinese": "zh",
"Chinese (traditional)": "zt",
"Czech": "cs",
"Danish": "da",
"Dutch": "nl",
"English": "en",
"Esperanto": "eo",
"Estonian": "et",
"Finnish": "fi",
"French": "fr",
"German": "de",
"Greek": "el",
"Hebrew": "he",
"Hindi": "hi",
"Hungarian": "hu",
"Indonesian": "id",
"Irish": "ga",
"Italian": "it",
"Japanese": "ja",
"Korean": "ko",
"Latvian": "lv",
"Lithuanian": "lt",
"Malay": "ms",
"Norwegian": "nb",
"Persian": "fa",
"Polish": "pl",
"Portuguese": "pt",
"Romanian": "ro",
"Russian": "ru",
"Slovak": "sk",
"Slovenian": "sl",
"Spanish": "es",
"Swedish": "sv",
"Tagalog": "tl",
"Thai": "th",
"Turkish": "tr",
"Ukranian": "uk",
"Urdu": "ur",
}
)

View File

@ -1,4 +1,4 @@
package argos
package libre
import (
"encoding/json"
@ -11,7 +11,7 @@ import (
)
const (
textURL = "https://translate.argosopentech.com/translate"
defaultURL = "https://libretranslate.com/translate"
)
type Translator struct {
@ -26,7 +26,7 @@ func NewTranslator() *Translator {
Server: new(core.Server),
Language: new(core.Language),
TTS: core.NewTTS(),
EngineName: core.NewEngineName("Argos"),
EngineName: core.NewEngineName("Libre"),
}
}
@ -38,11 +38,19 @@ func (t *Translator) Translate(message string) (translation *core.Translation, e
translation = new(core.Translation)
var data map[string]interface{}
var textURL string
if len(t.GetHost()) > 0 {
textURL = "http://"+t.GetHost()+"/translate"
} else {
textURL = defaultURL
}
res, err := http.PostForm(textURL,
url.Values{
"q": {message},
"source": {langCode[t.GetSrcLang()]},
"target": {langCode[t.GetDstLang()]},
"q": {message},
"source": {langCode[t.GetSrcLang()]},
"target": {langCode[t.GetDstLang()]},
"api_key": {t.GetAPIKey()},
})
if err != nil {
return nil, err
@ -58,6 +66,9 @@ func (t *Translator) Translate(message string) (translation *core.Translation, e
if len(data) <= 0 {
return nil, errors.New("Translation not found")
}
if res.StatusCode != 200 {
return nil, errors.New(data["error"].(string))
}
translation.TEXT = data["translatedText"].(string)

View File

@ -2,25 +2,25 @@ package translate
import (
"github.com/eeeXun/gtt/internal/translate/apertium"
"github.com/eeeXun/gtt/internal/translate/argos"
"github.com/eeeXun/gtt/internal/translate/bing"
"github.com/eeeXun/gtt/internal/translate/chatgpt"
"github.com/eeeXun/gtt/internal/translate/core"
"github.com/eeeXun/gtt/internal/translate/deepl"
"github.com/eeeXun/gtt/internal/translate/deeplx"
"github.com/eeeXun/gtt/internal/translate/google"
"github.com/eeeXun/gtt/internal/translate/libre"
"github.com/eeeXun/gtt/internal/translate/reverso"
)
var (
AllTranslator = []string{
"Apertium",
"Argos",
"Bing",
"ChatGPT",
"DeepL",
"DeepLX",
"Google",
"Libre",
"Reverso",
}
)
@ -75,8 +75,6 @@ func NewTranslator(name string) Translator {
switch name {
case "Apertium":
translator = apertium.NewTranslator()
case "Argos":
translator = argos.NewTranslator()
case "Bing":
translator = bing.NewTranslator()
case "ChatGPT":
@ -87,6 +85,8 @@ func NewTranslator(name string) Translator {
translator = deeplx.NewTranslator()
case "Google":
translator = google.NewTranslator()
case "Libre":
translator = libre.NewTranslator()
case "Reverso":
translator = reverso.NewTranslator()
}