source: code/trunk/engines/libretranslate.go@ 22

Last change on this file since 22 was 20, checked in by manerakai, 22 months ago

Improved code

File size: 3.9 KB
Line 
1package engines
2
3import (
4 "bytes"
5 "encoding/json"
6 "fmt"
7 "net/http"
8)
9
10// LibreTranslate is an engine that interfaces with any
11// [LibreTranslate](https://github.com/LibreTranslate/LibreTranslate) instance.
12type LibreTranslate struct {
13 // InstanceURL is the URL to a LibreTranslate instance, for example
14 // "https://libretranslate.com".
15 InstanceURL string
16 // APIKey is the API key for the given instance. If empty, then no API
17 // key will be sent along with requests to the instance.
18 //
19 // Some instances issue API keys to users so that they can have a
20 // higher rate limit. See
21 // https://github.com/LibreTranslate/LibreTranslate#manage-api-keys for
22 // more information.
23 APIKey string
24}
25
26func (_ *LibreTranslate) InternalName() string { return "libre" }
27
28func (_ *LibreTranslate) DisplayName() string { return "LibreTranslate" }
29
30func (e *LibreTranslate) getLangs() (Language, error) {
31 response, err := http.Get(e.InstanceURL + "/languages")
32
33 if err != nil {
34 return nil, err
35 }
36
37 defer response.Body.Close()
38
39 if response.StatusCode != 200 {
40 return nil, fmt.Errorf("got status code %d from LibreTranslate API", response.StatusCode)
41 }
42
43 var langsResponse []struct {
44 Name string `json:"name"`
45 Code string `json:"code"`
46 }
47
48 if err := json.NewDecoder(response.Body).Decode(&langsResponse); err != nil {
49 return nil, err
50 }
51
52 langs := Language{}
53
54 for _, lang := range langsResponse {
55 langs[lang.Code] = lang.Name
56 }
57
58 return langs, nil
59
60}
61
62func (e *LibreTranslate) SourceLanguages() (Language, error) { return e.getLangs() }
63
64func (e *LibreTranslate) TargetLanguages() (Language, error) { return e.getLangs() }
65
66func (e *LibreTranslate) Tts(text, lang string) (string, error) { return "", nil }
67
68type libreDetectResponse []struct {
69 Confidence float64 `json:"confidence"`
70 LanguageCode string `json:"language"`
71}
72
73func (e *LibreTranslate) DetectLanguage(text string) (string, error) {
74 formData := map[string]string{"q": text}
75
76 if e.APIKey != "" {
77 formData["api_key"] = e.APIKey
78 }
79
80 formDataJSON, err := json.Marshal(formData)
81
82 if err != nil {
83 return "", err
84 }
85
86 response, err := http.Post(e.InstanceURL+"/detect", "application/json", bytes.NewBuffer(formDataJSON))
87
88 if err != nil {
89 return "", err
90 }
91
92 defer response.Body.Close()
93
94 if response.StatusCode != 200 {
95 return "", fmt.Errorf("got status code %d from LibreTranslate API", response.StatusCode)
96 }
97
98 var langs libreDetectResponse
99
100 if err := json.NewDecoder(response.Body).Decode(&langs); err != nil {
101 return "", err
102 }
103
104 maxConfidenceLang := langs[0]
105
106 for _, lang := range langs[1:] {
107 if lang.Confidence > maxConfidenceLang.Confidence {
108 maxConfidenceLang = lang
109 }
110 }
111
112 engineLangs, err := e.getLangs()
113
114 if err != nil {
115 return "", err
116 }
117
118 for code := range engineLangs {
119 if code == maxConfidenceLang.LanguageCode {
120 return code, nil
121 }
122 }
123
124 return "", fmt.Errorf("language code \"%s\" is not in the instance's language list", maxConfidenceLang.LanguageCode)
125}
126
127type libreTranslateResponse struct {
128 TranslatedText string `json:"translatedText"`
129}
130
131func (e *LibreTranslate) Translate(text string, from, to string) (TranslationResult, error) {
132 formData := map[string]string{
133 "q": text,
134 "source": from,
135 "target": to,
136 }
137
138 if e.APIKey != "" {
139 formData["api_key"] = e.APIKey
140 }
141
142 formDataJSON, err := json.Marshal(formData)
143
144 if err != nil {
145 return TranslationResult{}, err
146 }
147
148 response, err := http.Post(e.InstanceURL+"/translate", "application/json", bytes.NewBuffer(formDataJSON))
149
150 if err != nil {
151 return TranslationResult{}, err
152 }
153
154 defer response.Body.Close()
155
156 if response.StatusCode != 200 {
157 return TranslationResult{}, fmt.Errorf("got status code %d from LibreTranslate API", response.StatusCode)
158 }
159
160 var responseJSON libreTranslateResponse
161
162 if err := json.NewDecoder(response.Body).Decode(&responseJSON); err != nil {
163 return TranslationResult{}, err
164 }
165
166 return TranslationResult{TranslatedText: responseJSON.TranslatedText}, nil
167}
Note: See TracBrowser for help on using the repository browser.