mirror of
https://github.com/eeeXun/GTT.git
synced 2025-05-17 00:00:16 -07:00
feat(translator): add ChatGPT (#18)
* feat(translator): add ChatGPT * feat: check chatgpt error * refactor: change chatgpt apiKey not set text * refactor: change language to google * docs: yaml indent with 4 * refactor: APIKey in struct
This commit is contained in:
parent
2d2834c6da
commit
aa957d195c
12
README.md
12
README.md
@ -6,9 +6,20 @@ Supported Translator:
|
|||||||
[`Apertium`](https://www.apertium.org/),
|
[`Apertium`](https://www.apertium.org/),
|
||||||
[`Argos`](https://translate.argosopentech.com/),
|
[`Argos`](https://translate.argosopentech.com/),
|
||||||
[`Bing`](https://www.bing.com/translator),
|
[`Bing`](https://www.bing.com/translator),
|
||||||
|
[`ChatGPT`](https://chat.openai.com/),
|
||||||
[`Google`](https://translate.google.com/)(default),
|
[`Google`](https://translate.google.com/)(default),
|
||||||
[`Reverso`](https://www.reverso.net/text-translation)
|
[`Reverso`](https://www.reverso.net/text-translation)
|
||||||
|
|
||||||
|
## ⚠️ Note for ChatGPT
|
||||||
|
|
||||||
|
You need to apply a API key on [ChatGPT](https://platform.openai.com/account/api-keys).
|
||||||
|
And write it to `$XDG_CONFIG_HOME/gtt/gtt.yaml` or `$HOME/.config/gtt/gtt.yaml`.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
api_key:
|
||||||
|
chatgpt: YOUR_API_KEY # <- Replace with your API Key
|
||||||
|
```
|
||||||
|
|
||||||
## ScreenShot
|
## ScreenShot
|
||||||
|
|
||||||

|

|
||||||
@ -50,6 +61,7 @@ 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`
|
- [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)
|
||||||
- [Google Language support](https://cloud.google.com/translate/docs/languages) for `Google`
|
- [Google Language support](https://cloud.google.com/translate/docs/languages) for `Google`
|
||||||
- [Reverso Translation](https://www.reverso.net/text-translation) for `Reverso`
|
- [Reverso Translation](https://www.reverso.net/text-translation) for `Reverso`
|
||||||
|
|
||||||
|
10
config.go
10
config.go
@ -25,6 +25,8 @@ func configInit() {
|
|||||||
"destination.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",
|
||||||
|
"destination.language.chatgpt": "English",
|
||||||
"source.language.google": "English",
|
"source.language.google": "English",
|
||||||
"destination.language.google": "English",
|
"destination.language.google": "English",
|
||||||
"source.language.reverso": "English",
|
"source.language.reverso": "English",
|
||||||
@ -76,7 +78,7 @@ func configInit() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup
|
// Setup
|
||||||
for _, name := range translate.AllTranslator {
|
for _, name := range translate.AllTranslator {
|
||||||
translators[name] = translate.NewTranslator(name)
|
translators[name] = translate.NewTranslator(name)
|
||||||
translators[name].SetSrcLang(
|
translators[name].SetSrcLang(
|
||||||
@ -90,7 +92,11 @@ func configInit() {
|
|||||||
uiStyle.Transparent = config.GetBool("transparent")
|
uiStyle.Transparent = config.GetBool("transparent")
|
||||||
uiStyle.SetSrcBorderColor(config.GetString("source.border_color")).
|
uiStyle.SetSrcBorderColor(config.GetString("source.border_color")).
|
||||||
SetDstBorderColor(config.GetString("destination.border_color"))
|
SetDstBorderColor(config.GetString("destination.border_color"))
|
||||||
// set argument language
|
// Set API Key
|
||||||
|
if config.Get("api_key.chatgpt") != nil {
|
||||||
|
translators["ChatGPT"].SetAPIKey(config.GetString("api_key.chatgpt"))
|
||||||
|
}
|
||||||
|
// Set argument language
|
||||||
if len(*srcLangArg) > 0 {
|
if len(*srcLangArg) > 0 {
|
||||||
translator.SetSrcLang(*srcLangArg)
|
translator.SetSrcLang(*srcLangArg)
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Translator struct {
|
type Translator struct {
|
||||||
|
*core.APIKey
|
||||||
*core.Language
|
*core.Language
|
||||||
*core.TTSLock
|
*core.TTSLock
|
||||||
core.EngineName
|
core.EngineName
|
||||||
@ -23,6 +24,7 @@ type Translator struct {
|
|||||||
|
|
||||||
func NewTranslator() *Translator {
|
func NewTranslator() *Translator {
|
||||||
return &Translator{
|
return &Translator{
|
||||||
|
APIKey: new(core.APIKey),
|
||||||
Language: new(core.Language),
|
Language: new(core.Language),
|
||||||
TTSLock: core.NewTTSLock(),
|
TTSLock: core.NewTTSLock(),
|
||||||
EngineName: core.NewEngineName("Apertium"),
|
EngineName: core.NewEngineName("Apertium"),
|
||||||
|
@ -16,6 +16,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Translator struct {
|
type Translator struct {
|
||||||
|
*core.APIKey
|
||||||
*core.Language
|
*core.Language
|
||||||
*core.TTSLock
|
*core.TTSLock
|
||||||
core.EngineName
|
core.EngineName
|
||||||
@ -23,6 +24,7 @@ type Translator struct {
|
|||||||
|
|
||||||
func NewTranslator() *Translator {
|
func NewTranslator() *Translator {
|
||||||
return &Translator{
|
return &Translator{
|
||||||
|
APIKey: new(core.APIKey),
|
||||||
Language: new(core.Language),
|
Language: new(core.Language),
|
||||||
TTSLock: core.NewTTSLock(),
|
TTSLock: core.NewTTSLock(),
|
||||||
EngineName: core.NewEngineName("Argos"),
|
EngineName: core.NewEngineName("Argos"),
|
||||||
|
@ -25,6 +25,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Translator struct {
|
type Translator struct {
|
||||||
|
*core.APIKey
|
||||||
*core.Language
|
*core.Language
|
||||||
*core.TTSLock
|
*core.TTSLock
|
||||||
core.EngineName
|
core.EngineName
|
||||||
@ -39,6 +40,7 @@ type setUpData struct {
|
|||||||
|
|
||||||
func NewTranslator() *Translator {
|
func NewTranslator() *Translator {
|
||||||
return &Translator{
|
return &Translator{
|
||||||
|
APIKey: new(core.APIKey),
|
||||||
Language: new(core.Language),
|
Language: new(core.Language),
|
||||||
TTSLock: core.NewTTSLock(),
|
TTSLock: core.NewTTSLock(),
|
||||||
EngineName: core.NewEngineName("Bing"),
|
EngineName: core.NewEngineName("Bing"),
|
||||||
|
142
internal/translate/chatgpt/language.go
Normal file
142
internal/translate/chatgpt/language.go
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
package chatgpt
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Generated from Google
|
||||||
|
lang = []string{
|
||||||
|
"Afrikaans",
|
||||||
|
"Albanian",
|
||||||
|
"Amharic",
|
||||||
|
"Arabic",
|
||||||
|
"Armenian",
|
||||||
|
"Auto",
|
||||||
|
"Assamese",
|
||||||
|
"Aymara",
|
||||||
|
"Azerbaijani",
|
||||||
|
"Bambara",
|
||||||
|
"Basque",
|
||||||
|
"Belarusian",
|
||||||
|
"Bengali",
|
||||||
|
"Bhojpuri",
|
||||||
|
"Bosnian",
|
||||||
|
"Bulgarian",
|
||||||
|
"Catalan",
|
||||||
|
"Cebuano",
|
||||||
|
"Chinese (Simplified)",
|
||||||
|
"Chinese (Traditional)",
|
||||||
|
"Corsican",
|
||||||
|
"Croatian",
|
||||||
|
"Czech",
|
||||||
|
"Danish",
|
||||||
|
"Dhivehi",
|
||||||
|
"Dogri",
|
||||||
|
"Dutch",
|
||||||
|
"English",
|
||||||
|
"Esperanto",
|
||||||
|
"Estonian",
|
||||||
|
"Ewe",
|
||||||
|
"Filipino (Tagalog)",
|
||||||
|
"Finnish",
|
||||||
|
"French",
|
||||||
|
"Frisian",
|
||||||
|
"Galician",
|
||||||
|
"Georgian",
|
||||||
|
"German",
|
||||||
|
"Greek",
|
||||||
|
"Guarani",
|
||||||
|
"Gujarati",
|
||||||
|
"Haitian Creole",
|
||||||
|
"Hausa",
|
||||||
|
"Hawaiian",
|
||||||
|
"Hebrew",
|
||||||
|
"Hindi",
|
||||||
|
"Hmong",
|
||||||
|
"Hungarian",
|
||||||
|
"Icelandic",
|
||||||
|
"Igbo",
|
||||||
|
"Ilocano",
|
||||||
|
"Indonesian",
|
||||||
|
"Irish",
|
||||||
|
"Italian",
|
||||||
|
"Japanese",
|
||||||
|
"Javanese",
|
||||||
|
"Kannada",
|
||||||
|
"Kazakh",
|
||||||
|
"Khmer",
|
||||||
|
"Kinyarwanda",
|
||||||
|
"Konkani",
|
||||||
|
"Korean",
|
||||||
|
"Krio",
|
||||||
|
"Kurdish",
|
||||||
|
"Kurdish (Sorani)",
|
||||||
|
"Kyrgyz",
|
||||||
|
"Lao",
|
||||||
|
"Latin",
|
||||||
|
"Latvian",
|
||||||
|
"Lingala",
|
||||||
|
"Lithuanian",
|
||||||
|
"Luganda",
|
||||||
|
"Luxembourgish",
|
||||||
|
"Macedonian",
|
||||||
|
"Maithili",
|
||||||
|
"Malagasy",
|
||||||
|
"Malay",
|
||||||
|
"Malayalam",
|
||||||
|
"Maltese",
|
||||||
|
"Maori",
|
||||||
|
"Marathi",
|
||||||
|
"Meiteilon (Manipuri)",
|
||||||
|
"Mizo",
|
||||||
|
"Mongolian",
|
||||||
|
"Myanmar (Burmese)",
|
||||||
|
"Nepali",
|
||||||
|
"Norwegian",
|
||||||
|
"Nyanja (Chichewa)",
|
||||||
|
"Odia (Oriya)",
|
||||||
|
"Oromo",
|
||||||
|
"Pashto",
|
||||||
|
"Persian",
|
||||||
|
"Polish",
|
||||||
|
"Portuguese (Portugal, Brazil)",
|
||||||
|
"Punjabi",
|
||||||
|
"Quechua",
|
||||||
|
"Romanian",
|
||||||
|
"Russian",
|
||||||
|
"Samoan",
|
||||||
|
"Sanskrit",
|
||||||
|
"Scots Gaelic",
|
||||||
|
"Sepedi",
|
||||||
|
"Serbian",
|
||||||
|
"Sesotho",
|
||||||
|
"Shona",
|
||||||
|
"Sindhi",
|
||||||
|
"Sinhala (Sinhalese)",
|
||||||
|
"Slovak",
|
||||||
|
"Slovenian",
|
||||||
|
"Somali",
|
||||||
|
"Spanish",
|
||||||
|
"Sundanese",
|
||||||
|
"Swahili",
|
||||||
|
"Swedish",
|
||||||
|
"Tagalog (Filipino)",
|
||||||
|
"Tajik",
|
||||||
|
"Tamil",
|
||||||
|
"Tatar",
|
||||||
|
"Telugu",
|
||||||
|
"Thai",
|
||||||
|
"Tigrinya",
|
||||||
|
"Tsonga",
|
||||||
|
"Turkish",
|
||||||
|
"Turkmen",
|
||||||
|
"Twi (Akan)",
|
||||||
|
"Ukrainian",
|
||||||
|
"Urdu",
|
||||||
|
"Uyghur",
|
||||||
|
"Uzbek",
|
||||||
|
"Vietnamese",
|
||||||
|
"Welsh",
|
||||||
|
"Xhosa",
|
||||||
|
"Yiddish",
|
||||||
|
"Yoruba",
|
||||||
|
"Zulu",
|
||||||
|
}
|
||||||
|
)
|
94
internal/translate/chatgpt/translator.go
Normal file
94
internal/translate/chatgpt/translator.go
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
package chatgpt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/eeeXun/gtt/internal/translate/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
textURL = "https://api.openai.com/v1/chat/completions"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Translator struct {
|
||||||
|
*core.APIKey
|
||||||
|
*core.Language
|
||||||
|
*core.TTSLock
|
||||||
|
core.EngineName
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTranslator() *Translator {
|
||||||
|
return &Translator{
|
||||||
|
APIKey: new(core.APIKey),
|
||||||
|
Language: new(core.Language),
|
||||||
|
TTSLock: core.NewTTSLock(),
|
||||||
|
EngineName: core.NewEngineName("ChatGPT"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Translator) GetAllLang() []string {
|
||||||
|
return lang
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Translator) Translate(message string) (translation *core.Translation, err error) {
|
||||||
|
translation = new(core.Translation)
|
||||||
|
var data map[string]interface{}
|
||||||
|
|
||||||
|
if len(t.GetAPIKey()) <= 0 {
|
||||||
|
return nil, errors.New("Please write your API Key in config file for " + t.GetEngineName())
|
||||||
|
}
|
||||||
|
|
||||||
|
userData, _ := json.Marshal(map[string]interface{}{
|
||||||
|
"model": "gpt-3.5-turbo",
|
||||||
|
"messages": []map[string]string{{
|
||||||
|
"role": "user",
|
||||||
|
"content": fmt.Sprintf(
|
||||||
|
"Translate following text from %s to %s\n%s",
|
||||||
|
t.GetSrcLang(),
|
||||||
|
t.GetDstLang(),
|
||||||
|
message,
|
||||||
|
),
|
||||||
|
}},
|
||||||
|
"temperature": 0.7,
|
||||||
|
})
|
||||||
|
req, _ := http.NewRequest("POST",
|
||||||
|
textURL,
|
||||||
|
bytes.NewBuffer(userData),
|
||||||
|
)
|
||||||
|
req.Header.Add("Content-Type", "application/json")
|
||||||
|
req.Header.Add("Authorization", "Bearer "+t.GetAPIKey())
|
||||||
|
res, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
body, err := ioutil.ReadAll(res.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err = json.Unmarshal(body, &data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(data) <= 0 {
|
||||||
|
return nil, errors.New("Translation not found")
|
||||||
|
}
|
||||||
|
if data["error"] != nil {
|
||||||
|
return nil, errors.New(data["error"].(map[string]interface{})["message"].(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
translation.TEXT =
|
||||||
|
data["choices"].([]interface{})[0].(map[string]interface{})["message"].(map[string]interface{})["content"].(string)
|
||||||
|
|
||||||
|
return translation, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Translator) PlayTTS(lang, message string) error {
|
||||||
|
defer t.ReleaseLock()
|
||||||
|
|
||||||
|
return errors.New(t.GetEngineName() + " does not support text to speech")
|
||||||
|
}
|
13
internal/translate/core/apikey.go
Normal file
13
internal/translate/core/apikey.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
type APIKey struct {
|
||||||
|
key string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k *APIKey) SetAPIKey(key string) {
|
||||||
|
k.key = key
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k *APIKey) GetAPIKey() string {
|
||||||
|
return k.key
|
||||||
|
}
|
@ -20,6 +20,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Translator struct {
|
type Translator struct {
|
||||||
|
*core.APIKey
|
||||||
*core.Language
|
*core.Language
|
||||||
*core.TTSLock
|
*core.TTSLock
|
||||||
core.EngineName
|
core.EngineName
|
||||||
@ -27,6 +28,7 @@ type Translator struct {
|
|||||||
|
|
||||||
func NewTranslator() *Translator {
|
func NewTranslator() *Translator {
|
||||||
return &Translator{
|
return &Translator{
|
||||||
|
APIKey: new(core.APIKey),
|
||||||
Language: new(core.Language),
|
Language: new(core.Language),
|
||||||
TTSLock: core.NewTTSLock(),
|
TTSLock: core.NewTTSLock(),
|
||||||
EngineName: core.NewEngineName("Google"),
|
EngineName: core.NewEngineName("Google"),
|
||||||
|
@ -22,6 +22,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Translator struct {
|
type Translator struct {
|
||||||
|
*core.APIKey
|
||||||
*core.Language
|
*core.Language
|
||||||
*core.TTSLock
|
*core.TTSLock
|
||||||
core.EngineName
|
core.EngineName
|
||||||
@ -29,6 +30,7 @@ type Translator struct {
|
|||||||
|
|
||||||
func NewTranslator() *Translator {
|
func NewTranslator() *Translator {
|
||||||
return &Translator{
|
return &Translator{
|
||||||
|
APIKey: new(core.APIKey),
|
||||||
Language: new(core.Language),
|
Language: new(core.Language),
|
||||||
TTSLock: core.NewTTSLock(),
|
TTSLock: core.NewTTSLock(),
|
||||||
EngineName: core.NewEngineName("Reverso"),
|
EngineName: core.NewEngineName("Reverso"),
|
||||||
|
@ -4,6 +4,7 @@ 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/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/core"
|
"github.com/eeeXun/gtt/internal/translate/core"
|
||||||
"github.com/eeeXun/gtt/internal/translate/google"
|
"github.com/eeeXun/gtt/internal/translate/google"
|
||||||
"github.com/eeeXun/gtt/internal/translate/reverso"
|
"github.com/eeeXun/gtt/internal/translate/reverso"
|
||||||
@ -14,6 +15,7 @@ var (
|
|||||||
"Apertium",
|
"Apertium",
|
||||||
"Argos",
|
"Argos",
|
||||||
"Bing",
|
"Bing",
|
||||||
|
"ChatGPT",
|
||||||
"Google",
|
"Google",
|
||||||
"Reverso",
|
"Reverso",
|
||||||
}
|
}
|
||||||
@ -41,6 +43,9 @@ type Translator interface {
|
|||||||
// Swap source and destination language of the translator
|
// Swap source and destination language of the translator
|
||||||
SwapLang()
|
SwapLang()
|
||||||
|
|
||||||
|
// Set API Key
|
||||||
|
SetAPIKey(key string)
|
||||||
|
|
||||||
// Check if lock is available
|
// Check if lock is available
|
||||||
LockAvailable() bool
|
LockAvailable() bool
|
||||||
|
|
||||||
@ -67,6 +72,8 @@ func NewTranslator(name string) Translator {
|
|||||||
translator = argos.NewTranslator()
|
translator = argos.NewTranslator()
|
||||||
case "Bing":
|
case "Bing":
|
||||||
translator = bing.NewTranslator()
|
translator = bing.NewTranslator()
|
||||||
|
case "ChatGPT":
|
||||||
|
translator = chatgpt.NewTranslator()
|
||||||
case "Google":
|
case "Google":
|
||||||
translator = google.NewTranslator()
|
translator = google.NewTranslator()
|
||||||
case "Reverso":
|
case "Reverso":
|
||||||
|
Loading…
x
Reference in New Issue
Block a user