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

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

Improved code

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