mirror of
https://github.com/eeeXun/GTT.git
synced 2025-05-15 23:30:27 -07:00
feat: add LibreTranslate, remove ArgosTranslate
ArgosTranslate is offline. Change it to LibreTranslate
This commit is contained in:
parent
b3f4135732
commit
8a9f267229
20
README.md
20
README.md
@ -4,12 +4,12 @@ Google Translate TUI (Originally)
|
|||||||
|
|
||||||
Supported Translator:
|
Supported Translator:
|
||||||
[`Apertium`](https://www.apertium.org/),
|
[`Apertium`](https://www.apertium.org/),
|
||||||
[`Argos`](https://translate.argosopentech.com/),
|
|
||||||
[`Bing`](https://www.bing.com/translator),
|
[`Bing`](https://www.bing.com/translator),
|
||||||
[`ChatGPT`](https://chat.openai.com/),
|
[`ChatGPT`](https://chat.openai.com/),
|
||||||
[`DeepL`](https://deepl.com/translator)(only free API),
|
[`DeepL`](https://deepl.com/translator)(only free API),
|
||||||
[`DeepLX`](https://github.com/OwO-Network/DeepLX),
|
[`DeepLX`](https://github.com/OwO-Network/DeepLX),
|
||||||
[`Google`](https://translate.google.com/)(default),
|
[`Google`](https://translate.google.com/)(default),
|
||||||
|
[`Libre`](https://libretranslate.com/),
|
||||||
[`Reverso`](https://www.reverso.net/text-translation)
|
[`Reverso`](https://www.reverso.net/text-translation)
|
||||||
|
|
||||||
## ScreenShot
|
## ScreenShot
|
||||||
@ -52,6 +52,22 @@ host:
|
|||||||
deeplx: 127.0.0.1:1188 # <- Replace with your server IP address and port
|
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
|
## Install
|
||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
@ -214,12 +230,12 @@ gtt -src "English" -dst "Chinese (Traditional)"
|
|||||||
See available languages on:
|
See available languages on:
|
||||||
|
|
||||||
- [Apertium Translate](https://www.apertium.org/) for `Apertium`
|
- [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`
|
- [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)
|
- `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`
|
- [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)
|
- `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`
|
- [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`
|
- [Reverso Translation](https://www.reverso.net/text-translation) for `Reverso`
|
||||||
|
|
||||||
## Credit
|
## Credit
|
||||||
|
12
config.go
12
config.go
@ -45,8 +45,6 @@ func configInit() {
|
|||||||
"destination.border_color": "blue",
|
"destination.border_color": "blue",
|
||||||
"source.language.apertium": "English",
|
"source.language.apertium": "English",
|
||||||
"destination.language.apertium": "English",
|
"destination.language.apertium": "English",
|
||||||
"source.language.argos": "English",
|
|
||||||
"destination.language.argos": "English",
|
|
||||||
"source.language.bing": "English",
|
"source.language.bing": "English",
|
||||||
"destination.language.bing": "English",
|
"destination.language.bing": "English",
|
||||||
"source.language.chatgpt": "English",
|
"source.language.chatgpt": "English",
|
||||||
@ -57,6 +55,8 @@ func configInit() {
|
|||||||
"destination.language.deeplx": "English",
|
"destination.language.deeplx": "English",
|
||||||
"source.language.google": "English",
|
"source.language.google": "English",
|
||||||
"destination.language.google": "English",
|
"destination.language.google": "English",
|
||||||
|
"source.language.libre": "English",
|
||||||
|
"destination.language.libre": "English",
|
||||||
"source.language.reverso": "English",
|
"source.language.reverso": "English",
|
||||||
"destination.language.reverso": "English",
|
"destination.language.reverso": "English",
|
||||||
"translator": "Google",
|
"translator": "Google",
|
||||||
@ -162,7 +162,7 @@ func configInit() {
|
|||||||
// Import api key and host if file exists
|
// Import api key and host if file exists
|
||||||
if err := serverConfig.ReadInConfig(); err == nil {
|
if err := serverConfig.ReadInConfig(); err == nil {
|
||||||
// api key
|
// 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
|
// Read from value first, then read from file
|
||||||
if serverConfig.Get(fmt.Sprintf("api_key.%s.value", name)) != nil {
|
if serverConfig.Get(fmt.Sprintf("api_key.%s.value", name)) != nil {
|
||||||
translators[name].SetAPIKey(serverConfig.GetString(fmt.Sprintf("api_key.%s.value", name)))
|
translators[name].SetAPIKey(serverConfig.GetString(fmt.Sprintf("api_key.%s.value", name)))
|
||||||
@ -174,8 +174,10 @@ func configInit() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// host
|
// host
|
||||||
if serverConfig.Get("host.deeplx") != nil {
|
for _, name := range []string{"DeepLX", "Libre"} {
|
||||||
translators["DeepLX"].SetHost(serverConfig.GetString("host.deeplx"))
|
if serverConfig.Get(fmt.Sprintf("host.%s", name)) != nil {
|
||||||
|
translators[name].SetHost(serverConfig.GetString(fmt.Sprintf("host.%s", name)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Set argument language
|
// Set argument language
|
||||||
|
@ -9,5 +9,9 @@ api_key:
|
|||||||
deeplx:
|
deeplx:
|
||||||
value: DEEPLX_API_KEY
|
value: DEEPLX_API_KEY
|
||||||
# file: $HOME/secrets/deeplx.txt
|
# file: $HOME/secrets/deeplx.txt
|
||||||
|
libre:
|
||||||
|
value: LIBRE_API_KEY
|
||||||
|
# file: $HOME/secrets/libre.txt
|
||||||
host:
|
host:
|
||||||
deeplx: 127.0.0.1:1188
|
deeplx: 127.0.0.1:1188
|
||||||
|
libre: 127.0.0.1:5000
|
||||||
|
@ -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",
|
|
||||||
}
|
|
||||||
)
|
|
@ -141,22 +141,28 @@ func (t *Translator) Translate(message string) (translation *core.Translation, e
|
|||||||
}
|
}
|
||||||
// Bing will return the request with list when success.
|
// Bing will return the request with list when success.
|
||||||
// Otherwises, it would return map. Then the following err would not be nil.
|
// Otherwises, it would return map. Then the following err would not be nil.
|
||||||
if err = json.Unmarshal(body, &data); err == nil {
|
if err = json.Unmarshal(body, &data); err != nil {
|
||||||
poses := make(posSet)
|
return nil, err
|
||||||
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 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
|
return translation, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ func (t *Translator) Translate(message string) (translation *core.Translation, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(data) <= 0 {
|
if len(data) <= 0 {
|
||||||
return nil, errors.New("translation not found")
|
return nil, errors.New("Translation not found")
|
||||||
}
|
}
|
||||||
if res.StatusCode != 200 {
|
if res.StatusCode != 200 {
|
||||||
return nil, errors.New(data["message"].(string))
|
return nil, errors.New(data["message"].(string))
|
||||||
|
98
internal/translate/libre/language.go
Normal file
98
internal/translate/libre/language.go
Normal 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",
|
||||||
|
}
|
||||||
|
)
|
@ -1,4 +1,4 @@
|
|||||||
package argos
|
package libre
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
textURL = "https://translate.argosopentech.com/translate"
|
defaultURL = "https://libretranslate.com/translate"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Translator struct {
|
type Translator struct {
|
||||||
@ -26,7 +26,7 @@ func NewTranslator() *Translator {
|
|||||||
Server: new(core.Server),
|
Server: new(core.Server),
|
||||||
Language: new(core.Language),
|
Language: new(core.Language),
|
||||||
TTS: core.NewTTS(),
|
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)
|
translation = new(core.Translation)
|
||||||
var data map[string]interface{}
|
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,
|
res, err := http.PostForm(textURL,
|
||||||
url.Values{
|
url.Values{
|
||||||
"q": {message},
|
"q": {message},
|
||||||
"source": {langCode[t.GetSrcLang()]},
|
"source": {langCode[t.GetSrcLang()]},
|
||||||
"target": {langCode[t.GetDstLang()]},
|
"target": {langCode[t.GetDstLang()]},
|
||||||
|
"api_key": {t.GetAPIKey()},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -58,6 +66,9 @@ func (t *Translator) Translate(message string) (translation *core.Translation, e
|
|||||||
if len(data) <= 0 {
|
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["error"].(string))
|
||||||
|
}
|
||||||
|
|
||||||
translation.TEXT = data["translatedText"].(string)
|
translation.TEXT = data["translatedText"].(string)
|
||||||
|
|
@ -2,25 +2,25 @@ package translate
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/eeeXun/gtt/internal/translate/apertium"
|
"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/bing"
|
||||||
"github.com/eeeXun/gtt/internal/translate/chatgpt"
|
"github.com/eeeXun/gtt/internal/translate/chatgpt"
|
||||||
"github.com/eeeXun/gtt/internal/translate/core"
|
"github.com/eeeXun/gtt/internal/translate/core"
|
||||||
"github.com/eeeXun/gtt/internal/translate/deepl"
|
"github.com/eeeXun/gtt/internal/translate/deepl"
|
||||||
"github.com/eeeXun/gtt/internal/translate/deeplx"
|
"github.com/eeeXun/gtt/internal/translate/deeplx"
|
||||||
"github.com/eeeXun/gtt/internal/translate/google"
|
"github.com/eeeXun/gtt/internal/translate/google"
|
||||||
|
"github.com/eeeXun/gtt/internal/translate/libre"
|
||||||
"github.com/eeeXun/gtt/internal/translate/reverso"
|
"github.com/eeeXun/gtt/internal/translate/reverso"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
AllTranslator = []string{
|
AllTranslator = []string{
|
||||||
"Apertium",
|
"Apertium",
|
||||||
"Argos",
|
|
||||||
"Bing",
|
"Bing",
|
||||||
"ChatGPT",
|
"ChatGPT",
|
||||||
"DeepL",
|
"DeepL",
|
||||||
"DeepLX",
|
"DeepLX",
|
||||||
"Google",
|
"Google",
|
||||||
|
"Libre",
|
||||||
"Reverso",
|
"Reverso",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -75,8 +75,6 @@ func NewTranslator(name string) Translator {
|
|||||||
switch name {
|
switch name {
|
||||||
case "Apertium":
|
case "Apertium":
|
||||||
translator = apertium.NewTranslator()
|
translator = apertium.NewTranslator()
|
||||||
case "Argos":
|
|
||||||
translator = argos.NewTranslator()
|
|
||||||
case "Bing":
|
case "Bing":
|
||||||
translator = bing.NewTranslator()
|
translator = bing.NewTranslator()
|
||||||
case "ChatGPT":
|
case "ChatGPT":
|
||||||
@ -87,6 +85,8 @@ func NewTranslator(name string) Translator {
|
|||||||
translator = deeplx.NewTranslator()
|
translator = deeplx.NewTranslator()
|
||||||
case "Google":
|
case "Google":
|
||||||
translator = google.NewTranslator()
|
translator = google.NewTranslator()
|
||||||
|
case "Libre":
|
||||||
|
translator = libre.NewTranslator()
|
||||||
case "Reverso":
|
case "Reverso":
|
||||||
translator = reverso.NewTranslator()
|
translator = reverso.NewTranslator()
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user