diff --git a/README.md b/README.md index dc7e93e..1dfea72 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ Support: [`ApertiumTranslate`](https://www.apertium.org/), [`ArgosTranslate`](https://translate.argosopentech.com/), [`GoogleTranslate`](https://translate.google.com/) +[`ReversoTranslate`](https://www.reverso.net/text-translation) ## ScreenShot @@ -43,10 +44,12 @@ You can pass `-src` and `-dst` in argument to set source and destination languag gtt -src "English" -dst "Chinese (Traditional)" ``` -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`. +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` +- [Reverso Translation](https://www.reverso.net/text-translation) for `ReversoTranslate` ## Key Map @@ -105,7 +108,10 @@ Switch pop out window. ## Credit -[soimort/translate-shell](https://github.com/soimort/translate-shell) For translation URL. +[soimort/translate-shell](https://github.com/soimort/translate-shell), +[SimplyTranslate-Engines](https://codeberg.org/SimpleWeb/SimplyTranslate-Engines), +[s0ftik3/reverso-api](https://github.com/s0ftik3/reverso-api) +For translation URL. [snsd0805/GoogleTranslate-TUI](https://github.com/snsd0805/GoogleTranslate-TUI) For inspiration. diff --git a/config.go b/config.go index 5fef13f..192446b 100644 --- a/config.go +++ b/config.go @@ -30,6 +30,8 @@ func configInit() { "destination.language.argostranslate": "English", "source.language.googletranslate": "English", "destination.language.googletranslate": "English", + "source.language.reversotranslate": "English", + "destination.language.reversotranslate": "English", "hide_below": false, "translator": "ArgosTranslate", } diff --git a/internal/translate/reversotranslate/language.go b/internal/translate/reversotranslate/language.go new file mode 100644 index 0000000..de9a9c2 --- /dev/null +++ b/internal/translate/reversotranslate/language.go @@ -0,0 +1,60 @@ +package reversotranslate + +var ( + lang = []string{ + "Arabic", + "Chinese (Simplified)", + "Czech", + "Danish", + "Dutch", + "English", + "French", + "German", + "Greek", + "Hebrew", + "Hindi", + "Hungarian", + "Italian", + "Japanese", + "Korean", + "Persian", + "Polish", + "Portuguese", + "Romanian", + "Russian", + "Slovak", + "Spanish", + "Swedish", + "Thai", + "Turkish", + "Ukrainian", + } + langCode = map[string]string{ + "Arabic": "ara", + "Chinese (Simplified)": "chi", + "Czech": "cze", + "Danish": "dan", + "Dutch": "dut", + "English": "eng", + "French": "fra", + "German": "ger", + "Greek": "gre", + "Hebrew": "heb", + "Hindi": "hin", + "Hungarian": "hun", + "Italian": "ita", + "Japanese": "jpn", + "Korean": "kor", + "Persian": "per", + "Polish": "pol", + "Portuguese": "por", + "Romanian": "rum", + "Russian": "rus", + "Slovak": "slo", + "Spanish": "spa", + "Swedish": "swe", + "Thai": "tha", + "Turkish": "tur", + "Ukrainian": "ukr", + } +) diff --git a/internal/translate/reversotranslate/translator.go b/internal/translate/reversotranslate/translator.go new file mode 100644 index 0000000..9e3c82f --- /dev/null +++ b/internal/translate/reversotranslate/translator.go @@ -0,0 +1,91 @@ +package reversotranslate + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net/http" + + "github.com/eeeXun/gtt/internal/lock" +) + +const ( + textURL = "https://api.reverso.net/translate/v1/translation" +) + +type ReversoTranslate struct { + srcLang string + dstLang string + EngineName string + SoundLock *lock.Lock +} + +func (t *ReversoTranslate) GetEngineName() string { + return t.EngineName +} + +func (t *ReversoTranslate) GetAllLang() []string { + return lang +} + +func (t *ReversoTranslate) GetSrcLang() string { + return t.srcLang +} + +func (t *ReversoTranslate) GetDstLang() string { + return t.dstLang +} + +func (t *ReversoTranslate) SetSrcLang(srcLang string) { + t.srcLang = srcLang +} + +func (t *ReversoTranslate) SetDstLang(dstLang string) { + t.dstLang = dstLang +} + +func (t *ReversoTranslate) SwapLang() { + t.srcLang, t.dstLang = t.dstLang, t.srcLang +} + +func (t *ReversoTranslate) Translate(message string) (translation, definition, partOfSpeech string, err error) { + var data map[string]interface{} + + userData, _ := json.Marshal(map[string]interface{}{ + "format": "text", + "from": langCode[t.srcLang], + "to": langCode[t.dstLang], + "input": message, + "options": map[string]string{ + "sentenceSplitter": "true", + "origin": "translation.web", + "contextResults": "true", + "languageDetection": "true", + }, + }) + req, _ := http.NewRequest("POST", + textURL, + bytes.NewBuffer([]byte(userData))) + req.Header.Add("Content-Type", "application/json") + req.Header.Add("User-Agent", "") + 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 { + translation += fmt.Sprintf("%v", data) + + return translation, definition, partOfSpeech, nil + } + return "", "", "", errors.New("Translation not found") +} diff --git a/internal/translate/reversotranslate/tts.go b/internal/translate/reversotranslate/tts.go new file mode 100644 index 0000000..0c15bfd --- /dev/null +++ b/internal/translate/reversotranslate/tts.go @@ -0,0 +1,62 @@ +// echo 'nice' | base64 +// curl -A "Mozilla/4.0" \ +// "https://voice.reverso.net/RestPronunciation.svc/v1/output=json/GetVoiceStream/voiceName=Heather22k?voiceSpeed=80&inputText=bmljZQ==" \ +// --output a.mp +package reversotranslate + +const ( + ttsURL = "https://translate.google.com.vn/translate_tts?ie=UTF-8&q=%s&tl=%s&client=tw-ob" +) + +func (t *ReversoTranslate) LockAvailable() bool { + return t.SoundLock.Available() +} + +func (t *ReversoTranslate) LockAcquire() { + t.SoundLock.Acquire() +} + +func (t *ReversoTranslate) StopTTS() { + t.SoundLock.Stop = true +} + +func (t *ReversoTranslate) PlayTTS(lang, message string) error { + // urlStr := fmt.Sprintf( + // ttsURL, + // url.QueryEscape(message), + // langCode[lang], + // ) + // res, err := http.Get(urlStr) + // if err != nil { + // t.SoundLock.Release() + // return err + // } + // decoder, err := mp3.NewDecoder(res.Body) + // if err != nil { + // t.SoundLock.Release() + // return err + // } + // otoCtx, readyChan, err := oto.NewContext(decoder.SampleRate(), 2, 2) + // if err != nil { + // t.SoundLock.Release() + // return err + // } + // <-readyChan + // player := otoCtx.NewPlayer(decoder) + // player.Play() + // for player.IsPlaying() { + // if t.SoundLock.Stop { + // t.SoundLock.Release() + // return nil + // } else { + // time.Sleep(time.Millisecond) + // } + // } + // if err = player.Close(); err != nil { + // t.SoundLock.Release() + // return err + // } + // + t.SoundLock.Release() + return nil +} diff --git a/internal/translate/translator.go b/internal/translate/translator.go index 2f4541e..37c8917 100644 --- a/internal/translate/translator.go +++ b/internal/translate/translator.go @@ -5,10 +5,11 @@ import ( "github.com/eeeXun/gtt/internal/translate/apertiumtranslate" "github.com/eeeXun/gtt/internal/translate/argostranslate" "github.com/eeeXun/gtt/internal/translate/googletranslate" + "github.com/eeeXun/gtt/internal/translate/reversotranslate" ) var ( - AllTranslator = []string{"ApertiumTranslate", "ArgosTranslate", "GoogleTranslate"} + AllTranslator = []string{"ApertiumTranslate", "ArgosTranslate", "GoogleTranslate", "ReversoTranslate"} ) type Translator interface { @@ -48,6 +49,11 @@ func NewTranslator(name string) Translator { EngineName: "GoogleTranslate", SoundLock: lock.NewLock(), } + case "ReversoTranslate": + translator = &reversotranslate.ReversoTranslate{ + EngineName: "ReversoTranslate", + SoundLock: lock.NewLock(), + } } return translator