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

Last change on this file since 67 was 60, checked in by yakumo.izuru, 17 months ago

GET HTTP リクエストが機能しない問題を修正し、iCIBA および LibreTranslate エンジンを再追加し、マニュアル ページを作成し、Docker に関連するものを削除しました。

Signed-off-by: Izuru Yakumo <yakumo.izuru@…>

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