From 0faaa757e3edcad517a077eaba295e9ea3896dc8 Mon Sep 17 00:00:00 2001 From: eeeXun Date: Thu, 26 Jan 2023 23:45:59 +0800 Subject: [PATCH] feat: add libretranslate --- config.go | 66 +++++++++------- .../translate/googletranslate/translator.go | 1 - internal/translate/libretranslate/language.go | 42 ++++++++++ .../translate/libretranslate/translator.go | 78 +++++++++++++++++++ internal/translate/libretranslate/tts.go | 26 +++++++ internal/translate/translator.go | 11 +++ main.go | 7 +- 7 files changed, 198 insertions(+), 33 deletions(-) create mode 100644 internal/translate/libretranslate/language.go create mode 100644 internal/translate/libretranslate/translator.go create mode 100644 internal/translate/libretranslate/tts.go diff --git a/config.go b/config.go index d79026a..6b3a841 100644 --- a/config.go +++ b/config.go @@ -1,6 +1,7 @@ package main import ( + "fmt" "gtt/internal/color" "os" @@ -19,14 +20,16 @@ func configInit() { var ( defaultConfigPath string defaultConfig = map[string]interface{}{ - "transparent": false, - "theme": "Gruvbox", - "source.borderColor": "red", - "destination.borderColor": "blue", - "source.google.language": "English", - "destination.google.language": "Chinese (Traditional)", - "hide_below": false, - "translator": "google", + "transparent": false, + "theme": "Gruvbox", + "source.borderColor": "red", + "destination.borderColor": "blue", + "source.googletranslate.language": "English", + "destination.googletranslate.language": "Chinese (Traditional)", + "source.libretranslate.language": "English", + "destination.libretranslate.language": "Chinese", + "hide_below": false, + "translator": "LibreTranslate", } ) @@ -64,25 +67,23 @@ func configInit() { } // setup - switch config.GetString("translator") { - case "google": - translator = googleTranslate - if len(*srcLangArg) > 0 { - translator.SetSrcLang(*srcLangArg) - } else { - translator.SetSrcLang(config.GetString("source.google.language")) - } - if len(*dstLangArg) > 0 { - translator.SetDstLang(*dstLangArg) - } else { - translator.SetDstLang(config.GetString("destination.google.language")) - } + for t_str, t := range translators { + t.SetSrcLang(config.GetString(fmt.Sprintf("source.%s.language", t_str))) + t.SetDstLang(config.GetString(fmt.Sprintf("destination.%s.language", t_str))) } + translator = translators[config.GetString("translator")] hideBelow = config.GetBool("hide_below") style.Theme = config.GetString("theme") style.Transparent = config.GetBool("transparent") style.SetSrcBorderColor(config.GetString("source.borderColor")). SetDstBorderColor(config.GetString("destination.borderColor")) + // set argument language + if len(*srcLangArg) > 0 { + translator.SetSrcLang(*srcLangArg) + } + if len(*dstLangArg) > 0 { + translator.SetDstLang(*dstLangArg) + } } // Check if need to modify config file when quit program @@ -90,16 +91,21 @@ func updateConfig() { changed := false // Source language is not passed in argument - if len(*srcLangArg) == 0 && - config.GetString("source.google.language") != googleTranslate.GetSrcLang() { - changed = true - config.Set("source.google.language", googleTranslate.GetSrcLang()) + if len(*srcLangArg) == 0 { + for t_str, t := range translators { + if config.GetString(fmt.Sprintf("source.%s.language", t_str)) != t.GetSrcLang() { + changed = true + config.Set(fmt.Sprintf("source.%s.language", t_str), t.GetSrcLang()) + } + } } - // Destination language is not passed in argument - if len(*dstLangArg) == 0 && - config.GetString("destination.google.language") != googleTranslate.GetDstLang() { - changed = true - config.Set("destination.google.language", googleTranslate.GetDstLang()) + if len(*dstLangArg) == 0 { + for t_str, t := range translators { + if config.GetString(fmt.Sprintf("destination.%s.language", t_str)) != t.GetDstLang() { + changed = true + config.Set(fmt.Sprintf("destination.%s.language", t_str), t.GetDstLang()) + } + } } if config.GetBool("hide_below") != hideBelow { changed = true diff --git a/internal/translate/googletranslate/translator.go b/internal/translate/googletranslate/translator.go index f9661f5..666a728 100644 --- a/internal/translate/googletranslate/translator.go +++ b/internal/translate/googletranslate/translator.go @@ -65,7 +65,6 @@ func (t *GoogleTranslate) Translate(message string) ( if err != nil { return "", "", "", err } - if err = json.Unmarshal(body, &data); err != nil { return "", "", "", err } diff --git a/internal/translate/libretranslate/language.go b/internal/translate/libretranslate/language.go new file mode 100644 index 0000000..191834e --- /dev/null +++ b/internal/translate/libretranslate/language.go @@ -0,0 +1,42 @@ +package libretranslate + +var ( + lang = []string{ + "Arabic", + "Chinese", + "English", + "French", + "German", + "Hindi", + "Indonesian", + "Irish", + "Italian", + "Japanese", + "Korean", + "Polish", + "Portuguese", + "Russian", + "Spanish", + "Turkish", + "Vietnamese", + } + langCode = map[string]string{ + "Arabic": "ar", + "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", + } +) diff --git a/internal/translate/libretranslate/translator.go b/internal/translate/libretranslate/translator.go new file mode 100644 index 0000000..c94b099 --- /dev/null +++ b/internal/translate/libretranslate/translator.go @@ -0,0 +1,78 @@ +package libretranslate + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "gtt/internal/lock" + "io/ioutil" + "net/http" +) + +const ( + textURL = "https://translate.argosopentech.com/translate" +) + +type LibreTranslate struct { + srcLang string + dstLang string + SoundLock *lock.Lock +} + +func (t *LibreTranslate) GetAllLang() []string { + return lang +} + +func (t *LibreTranslate) GetSrcLang() string { + return t.srcLang +} + +func (t *LibreTranslate) GetDstLang() string { + return t.dstLang +} + +func (t *LibreTranslate) SetSrcLang(srcLang string) { + t.srcLang = srcLang +} + +func (t *LibreTranslate) SetDstLang(dstLang string) { + t.dstLang = dstLang +} + +func (t *LibreTranslate) SwapLang() { + t.srcLang, t.dstLang = t.dstLang, t.srcLang +} + +func (t *LibreTranslate) Translate(message string) ( + translation string, + definition string, + partOfSpeech string, + err error) { + var data interface{} + + res, err := http.Post(textURL, + "application/json", + bytes.NewBuffer([]byte(fmt.Sprintf(`{ + "q": "%s", + "source": "%s", + "target": "%s" }`, message, langCode[t.srcLang], langCode[t.dstLang])))) + 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.(map[string]interface{})) > 0 { + translation += fmt.Sprintf("%v", + data.(map[string]interface{})["translatedText"]) + + return translation, definition, partOfSpeech, nil + } + return "", "", "", errors.New("Translation not found") +} diff --git a/internal/translate/libretranslate/tts.go b/internal/translate/libretranslate/tts.go new file mode 100644 index 0000000..cb7d53f --- /dev/null +++ b/internal/translate/libretranslate/tts.go @@ -0,0 +1,26 @@ +package libretranslate + +import ( + "errors" +) + +const ( + ttsURL = "https://translate.google.com.vn/translate_tts?ie=UTF-8&q=%s&tl=%s&client=tw-ob" +) + +func (t *LibreTranslate) LockAvailable() bool { + return t.SoundLock.Available() +} + +func (t *LibreTranslate) LockAcquire() { + t.SoundLock.Acquire() +} + +func (t *LibreTranslate) StopTTS() { + t.SoundLock.Stop = true +} + +func (t *LibreTranslate) PlayTTS(lang string, message string) error { + t.SoundLock.Release() + return errors.New("LibreTranslate does not support text to speech") +} diff --git a/internal/translate/translator.go b/internal/translate/translator.go index b80193a..a703ebb 100644 --- a/internal/translate/translator.go +++ b/internal/translate/translator.go @@ -3,6 +3,11 @@ package translate import ( "gtt/internal/lock" "gtt/internal/translate/googletranslate" + "gtt/internal/translate/libretranslate" +) + +var ( + AllTranslator = []string{"LibreTranslate", "GoogleTranslate"} ) type Translator interface { @@ -30,3 +35,9 @@ func NewGoogleTranslate() *googletranslate.GoogleTranslate { SoundLock: lock.NewLock(), } } + +func NewLibreTranslate() *libretranslate.LibreTranslate { + return &libretranslate.LibreTranslate{ + SoundLock: lock.NewLock(), + } +} diff --git a/main.go b/main.go index 45e7347..b58eaa5 100644 --- a/main.go +++ b/main.go @@ -15,8 +15,11 @@ var ( srcLangArg *string = flag.String("src", "", "Set source language") dstLangArg *string = flag.String("dst", "", "Set destination language") // Translate - translator translate.Translator - googleTranslate = translate.NewGoogleTranslate() + translator translate.Translator + translators = map[string]translate.Translator{ + "LibreTranslate": translate.NewLibreTranslate(), + "GoogleTranslate": translate.NewGoogleTranslate(), + } // UI app = tview.NewApplication() srcInput = tview.NewTextArea()