v/GTT
1
0
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:
Xun 2023-05-12 13:53:23 +08:00 committed by GitHub
parent 2d2834c6da
commit aa957d195c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 286 additions and 2 deletions

View File

@ -6,9 +6,20 @@ Supported Translator:
[`Apertium`](https://www.apertium.org/),
[`Argos`](https://translate.argosopentech.com/),
[`Bing`](https://www.bing.com/translator),
[`ChatGPT`](https://chat.openai.com/),
[`Google`](https://translate.google.com/)(default),
[`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](https://user-images.githubusercontent.com/58657914/213123592-5d8bccfb-ff80-4ad6-aaca-03b31c4c2c59.gif)
@ -50,6 +61,7 @@ See available languages on:
- [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`
- `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`
- [Reverso Translation](https://www.reverso.net/text-translation) for `Reverso`

View File

@ -25,6 +25,8 @@ func configInit() {
"destination.language.argos": "English",
"source.language.bing": "English",
"destination.language.bing": "English",
"source.language.chatgpt": "English",
"destination.language.chatgpt": "English",
"source.language.google": "English",
"destination.language.google": "English",
"source.language.reverso": "English",
@ -76,7 +78,7 @@ func configInit() {
}
}
// setup
// Setup
for _, name := range translate.AllTranslator {
translators[name] = translate.NewTranslator(name)
translators[name].SetSrcLang(
@ -90,7 +92,11 @@ func configInit() {
uiStyle.Transparent = config.GetBool("transparent")
uiStyle.SetSrcBorderColor(config.GetString("source.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 {
translator.SetSrcLang(*srcLangArg)
}

View File

@ -16,6 +16,7 @@ const (
)
type Translator struct {
*core.APIKey
*core.Language
*core.TTSLock
core.EngineName
@ -23,6 +24,7 @@ type Translator struct {
func NewTranslator() *Translator {
return &Translator{
APIKey: new(core.APIKey),
Language: new(core.Language),
TTSLock: core.NewTTSLock(),
EngineName: core.NewEngineName("Apertium"),

View File

@ -16,6 +16,7 @@ const (
)
type Translator struct {
*core.APIKey
*core.Language
*core.TTSLock
core.EngineName
@ -23,6 +24,7 @@ type Translator struct {
func NewTranslator() *Translator {
return &Translator{
APIKey: new(core.APIKey),
Language: new(core.Language),
TTSLock: core.NewTTSLock(),
EngineName: core.NewEngineName("Argos"),

View File

@ -25,6 +25,7 @@ const (
)
type Translator struct {
*core.APIKey
*core.Language
*core.TTSLock
core.EngineName
@ -39,6 +40,7 @@ type setUpData struct {
func NewTranslator() *Translator {
return &Translator{
APIKey: new(core.APIKey),
Language: new(core.Language),
TTSLock: core.NewTTSLock(),
EngineName: core.NewEngineName("Bing"),

View 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",
}
)

View 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")
}

View 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
}

View File

@ -20,6 +20,7 @@ const (
)
type Translator struct {
*core.APIKey
*core.Language
*core.TTSLock
core.EngineName
@ -27,6 +28,7 @@ type Translator struct {
func NewTranslator() *Translator {
return &Translator{
APIKey: new(core.APIKey),
Language: new(core.Language),
TTSLock: core.NewTTSLock(),
EngineName: core.NewEngineName("Google"),

View File

@ -22,6 +22,7 @@ const (
)
type Translator struct {
*core.APIKey
*core.Language
*core.TTSLock
core.EngineName
@ -29,6 +30,7 @@ type Translator struct {
func NewTranslator() *Translator {
return &Translator{
APIKey: new(core.APIKey),
Language: new(core.Language),
TTSLock: core.NewTTSLock(),
EngineName: core.NewEngineName("Reverso"),

View File

@ -4,6 +4,7 @@ import (
"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/chatgpt"
"github.com/eeeXun/gtt/internal/translate/core"
"github.com/eeeXun/gtt/internal/translate/google"
"github.com/eeeXun/gtt/internal/translate/reverso"
@ -14,6 +15,7 @@ var (
"Apertium",
"Argos",
"Bing",
"ChatGPT",
"Google",
"Reverso",
}
@ -41,6 +43,9 @@ type Translator interface {
// Swap source and destination language of the translator
SwapLang()
// Set API Key
SetAPIKey(key string)
// Check if lock is available
LockAvailable() bool
@ -67,6 +72,8 @@ func NewTranslator(name string) Translator {
translator = argos.NewTranslator()
case "Bing":
translator = bing.NewTranslator()
case "ChatGPT":
translator = chatgpt.NewTranslator()
case "Google":
translator = google.NewTranslator()
case "Reverso":