From 5fcb72cbb2e878c932fc0018540e24d90c3ea234 Mon Sep 17 00:00:00 2001 From: Xun <58657914+eeeXun@users.noreply.github.com> Date: Mon, 13 Feb 2023 15:22:04 +0800 Subject: [PATCH] feat(translator): add ApertiumTranslate (#13) --- README.md | 6 +- config.go | 22 +++-- .../translate/apertiumtranslate/language.go | 98 +++++++++++++++++++ .../translate/apertiumtranslate/translator.go | 92 +++++++++++++++++ internal/translate/apertiumtranslate/tts.go | 22 +++++ internal/translate/translator.go | 8 +- 6 files changed, 236 insertions(+), 12 deletions(-) create mode 100644 internal/translate/apertiumtranslate/language.go create mode 100644 internal/translate/apertiumtranslate/translator.go create mode 100644 internal/translate/apertiumtranslate/tts.go diff --git a/README.md b/README.md index 305d4fb..dc7e93e 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ Google Translate TUI (Originally) Support: +[`ApertiumTranslate`](https://www.apertium.org/), [`ArgosTranslate`](https://translate.argosopentech.com/), [`GoogleTranslate`](https://translate.google.com/) @@ -42,7 +43,10 @@ You can pass `-src` and `-dst` in argument to set source and destination languag gtt -src "English" -dst "Chinese (Traditional)" ``` -See language on [argosopentech/argos-translate](https://github.com/argosopentech/argos-translate#supported-languages) for `ArgosTranslate`, [Google Language support](https://cloud.google.com/translate/docs/languages) for `GoogleTranslate` +See language on +[Apertium Translate](https://www.apertium.org/) for `ApertiumTranslate`, +[argosopentech/argos-translate](https://github.com/argosopentech/argos-translate#supported-languages) for `ArgosTranslate`, +[Google Language support](https://cloud.google.com/translate/docs/languages) for `GoogleTranslate`. ## Key Map diff --git a/config.go b/config.go index a00b65e..5fef13f 100644 --- a/config.go +++ b/config.go @@ -20,16 +20,18 @@ func configInit() { var ( defaultConfigPath string defaultConfig = map[string]interface{}{ - "transparent": false, - "theme": "Gruvbox", - "source.borderColor": "red", - "destination.borderColor": "blue", - "source.language.argostranslate": "English", - "destination.language.argostranslate": "English", - "source.language.googletranslate": "English", - "destination.language.googletranslate": "English", - "hide_below": false, - "translator": "ArgosTranslate", + "transparent": false, + "theme": "Gruvbox", + "source.borderColor": "red", + "destination.borderColor": "blue", + "source.language.apertiumtranslate": "English", + "destination.language.apertiumtranslate": "English", + "source.language.argostranslate": "English", + "destination.language.argostranslate": "English", + "source.language.googletranslate": "English", + "destination.language.googletranslate": "English", + "hide_below": false, + "translator": "ArgosTranslate", } ) diff --git a/internal/translate/apertiumtranslate/language.go b/internal/translate/apertiumtranslate/language.go new file mode 100644 index 0000000..09c611f --- /dev/null +++ b/internal/translate/apertiumtranslate/language.go @@ -0,0 +1,98 @@ +package apertiumtranslate + +var ( + lang = []string{ + "Afrikaans", + "Arabic", + "Aranese", + "Aragonese", + "Arpitan", + "Basque", + "Belarusian", + "Breton", + "Bulgarian", + "Catalan", + "Crimean Tatar", + "Danish", + "Dutch", + "East Norwegian, vi→vi", + "English", + "Esperanto", + "French", + "Galician", + "Gascon", + "Hindi", + "Icelandic", + "Indonesian", + "Italian", + "Kazakh", + "Macedonian", + "Malay", + "Maltese", + "Northern Sami", + "Norwegian Bokmål", + "Norwegian Nynorsk", + "Occitan", + "Polish", + "Portuguese", + "Romanian", + "Russian", + "Serbo-Croatian", + "Silesian", + "Slovenian", + "Spanish", + "Swedish", + "Tatar", + "Turkish", + "Ukrainian", + "Urdu", + "Welsh", + } + langCode = map[string]string{ + "Afrikaans": "afr", + "Arabic": "ara", + "Aranese": "oci_aran", + "Aragonese": "arg", + "Arpitan": "frp", + "Basque": "eus", + "Belarusian": "bel", + "Breton": "bre", + "Bulgarian": "bul", + "Catalan": "cat", + "Crimean Tatar": "crh", + "Danish": "dan", + "Dutch": "nld", + "East Norwegian, vi→vi": "nno_e", + "English": "eng", + "Esperanto": "epo", + "French": "fra", + "Galician": "glg", + "Gascon": "oci_gascon", + "Hindi": "hin", + "Icelandic": "isl", + "Indonesian": "ind", + "Italian": "ita", + "Kazakh": "kaz", + "Macedonian": "mkd", + "Malay": "zlm", + "Maltese": "mlt", + "Northern Sami": "sme", + "Norwegian Bokmål": "nob", + "Norwegian Nynorsk": "nno", + "Occitan": "oci", + "Polish": "pol", + "Portuguese": "por", + "Romanian": "ron", + "Russian": "rus", + "Serbo-Croatian": "hbs", + "Silesian": "szl", + "Slovenian": "slv", + "Spanish": "spa", + "Swedish": "swe", + "Tatar": "tat", + "Turkish": "tur", + "Ukrainian": "ukr", + "Urdu": "urd", + "Welsh": "cym", + } +) diff --git a/internal/translate/apertiumtranslate/translator.go b/internal/translate/apertiumtranslate/translator.go new file mode 100644 index 0000000..cc8b464 --- /dev/null +++ b/internal/translate/apertiumtranslate/translator.go @@ -0,0 +1,92 @@ +package apertiumtranslate + +import ( + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net/http" + "net/url" + + "github.com/eeeXun/gtt/internal/lock" +) + +const ( + textURL = "https://www.apertium.org/apy/translate?langpair=%s|%s&q=%s" +) + +type ApertiumTranslate struct { + srcLang string + dstLang string + EngineName string + SoundLock *lock.Lock +} + +func (t *ApertiumTranslate) GetEngineName() string { + return t.EngineName +} + +func (t *ApertiumTranslate) GetAllLang() []string { + return lang +} + +func (t *ApertiumTranslate) GetSrcLang() string { + return t.srcLang +} + +func (t *ApertiumTranslate) GetDstLang() string { + return t.dstLang +} + +func (t *ApertiumTranslate) SetSrcLang(srcLang string) { + t.srcLang = srcLang +} + +func (t *ApertiumTranslate) SetDstLang(dstLang string) { + t.dstLang = dstLang +} + +func (t *ApertiumTranslate) SwapLang() { + t.srcLang, t.dstLang = t.dstLang, t.srcLang +} + +func (t *ApertiumTranslate) Translate(message string) (translation, definition, partOfSpeech string, err error) { + var data interface{} + + urlStr := fmt.Sprintf( + textURL, + langCode[t.srcLang], + langCode[t.dstLang], + url.QueryEscape(message), + ) + res, err := http.Get(urlStr) + 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 { + switch res.StatusCode { + case 200: + translation += fmt.Sprintf("%v", + data.(map[string]interface{})["responseData"].(map[string]interface{})["translatedText"]) + default: + return "", "", "", errors.New( + fmt.Sprintf("%s does not support translate from %s to %s.\nSee available pair on %s", + t.EngineName, + t.srcLang, + t.dstLang, + "https://www.apertium.org/", + )) + } + + return translation, definition, partOfSpeech, nil + } + return "", "", "", errors.New("Translation not found") +} diff --git a/internal/translate/apertiumtranslate/tts.go b/internal/translate/apertiumtranslate/tts.go new file mode 100644 index 0000000..206a08d --- /dev/null +++ b/internal/translate/apertiumtranslate/tts.go @@ -0,0 +1,22 @@ +package apertiumtranslate + +import ( + "errors" +) + +func (t *ApertiumTranslate) LockAvailable() bool { + return t.SoundLock.Available() +} + +func (t *ApertiumTranslate) LockAcquire() { + t.SoundLock.Acquire() +} + +func (t *ApertiumTranslate) StopTTS() { + t.SoundLock.Stop = true +} + +func (t *ApertiumTranslate) PlayTTS(lang, message string) error { + t.SoundLock.Release() + return errors.New(t.EngineName + " does not support text to speech") +} diff --git a/internal/translate/translator.go b/internal/translate/translator.go index fcdf4f9..2f4541e 100644 --- a/internal/translate/translator.go +++ b/internal/translate/translator.go @@ -2,12 +2,13 @@ package translate import ( "github.com/eeeXun/gtt/internal/lock" + "github.com/eeeXun/gtt/internal/translate/apertiumtranslate" "github.com/eeeXun/gtt/internal/translate/argostranslate" "github.com/eeeXun/gtt/internal/translate/googletranslate" ) var ( - AllTranslator = []string{"ArgosTranslate", "GoogleTranslate"} + AllTranslator = []string{"ApertiumTranslate", "ArgosTranslate", "GoogleTranslate"} ) type Translator interface { @@ -32,6 +33,11 @@ func NewTranslator(name string) Translator { var translator Translator switch name { + case "ApertiumTranslate": + translator = &apertiumtranslate.ApertiumTranslate{ + EngineName: "ApertiumTranslate", + SoundLock: lock.NewLock(), + } case "ArgosTranslate": translator = &argostranslate.ArgosTranslate{ EngineName: "ArgosTranslate",