Changeset 15 in code
- Timestamp:
- Aug 30, 2023, 11:57:46 AM (22 months ago)
- Location:
- trunk
- Files:
-
- 1 deleted
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/engines/engine.go
r12 r15 2 2 3 3 type TranslationResult struct { 4 SourceLanguage Language5 TranslatedText string 4 SourceLanguage string `json:"source_language"` 5 TranslatedText string `json:"translated_text"` 6 6 } 7 7 … … 9 9 InternalName() string 10 10 DisplayName() string 11 SourceLanguages() ([]Language, error) 12 TargetLanguages() ([]Language, error) 13 Translate(text string, from, to Language) (TranslationResult, error) 14 SupportsAutodetect() bool 15 DetectLanguage(text string) (Language, error) 11 SourceLanguages() (Language, error) 12 TargetLanguages() (Language, error) 13 Translate(text string, from, to string) (TranslationResult, error) 14 DetectLanguage(text string) (string, error) 16 15 } 16 17 type Language map[string]string 18 19 var Engines = map[string]Engine{ 20 "google": &GoogleTranslate{}, 21 "icibia": &ICIBA{}, 22 "libre": &LibreTranslate{}, 23 "reverseo": &Reverso{}, 24 } -
trunk/engines/google.go
r12 r15 15 15 func (_ *GoogleTranslate) DisplayName() string { return "Google" } 16 16 17 func (_ *GoogleTranslate) getLangs(type_ string) ( []Language, error) {17 func (_ *GoogleTranslate) getLangs(type_ string) (Language, error) { 18 18 var langsType string 19 19 switch type_ { … … 28 28 } 29 29 30 requestURL, err := url.Parse("https://translate.google.com/m") 31 32 if err != nil { 33 // The URL is constant, so it should never fail. 34 panic(err) 35 } 30 requestURL, _ := url.Parse("https://translate.google.com/m") 36 31 37 32 query := url.Values{} … … 54 49 } 55 50 56 var langs []Language51 var langs Language 57 52 58 53 doc.Find(".language-item").Each(func(_ int, s *goquery.Selection) { … … 78 73 } 79 74 80 langs = append(langs, Language{Name: a.Text(), Code: langCode})75 langs[langCode] = a.Text() 81 76 }) 82 77 … … 84 79 } 85 80 86 func (e *GoogleTranslate) SourceLanguages() ( []Language, error) {81 func (e *GoogleTranslate) SourceLanguages() (Language, error) { 87 82 return e.getLangs("source") 88 83 } 89 84 90 func (e *GoogleTranslate) TargetLanguages() ( []Language, error) {85 func (e *GoogleTranslate) TargetLanguages() (Language, error) { 91 86 return e.getLangs("target") 92 87 } 93 88 94 func (_ *GoogleTranslate) SupportsAutodetect() bool { return true}89 func (_ *GoogleTranslate) DetectLanguage(text string) (string, error) { return "", nil } 95 90 96 func (_ *GoogleTranslate) DetectLanguage(text string) (Language, error) { return Language{}, nil } 91 func (_ *GoogleTranslate) Translate(text string, from, to string) (TranslationResult, error) { 92 requestURL, _ := url.Parse("https://translate.google.com/m") 97 93 98 func (_ *GoogleTranslate) Translate(text string, from, to Language) (TranslationResult, error) { 99 requestURL, err := url.Parse("https://translate.google.com/m") 100 101 if err != nil { 102 // The URL is constant, so it should never fail. 103 panic(err) 94 if from == "" { 95 from = "auto" 104 96 } 105 97 106 98 query := url.Values{} 107 query.Add("sl", from .Code)108 query.Add("tl", to .Code)109 query.Add("hl", to .Code)99 query.Add("sl", from) 100 query.Add("tl", to) 101 query.Add("hl", to) 110 102 query.Add("q", text) 111 103 requestURL.RawQuery = query.Encode() -
trunk/engines/iciba.go
r12 r15 17 17 func (_ *ICIBA) DisplayName() string { return "iCIBA" } 18 18 19 var icibaLanguages = []Language{19 var icibaLanguages = Language{ 20 20 // ICIBA does have an API, but they return Chinese names. 21 21 // For languages already present in Google translate, the English … … 26 26 // due to conflict between ISO-639 table and Chinese label 27 27 // one "//" means on iciba but not on google 28 {Name: "Achinese", Code: "ace"}, //29 {Name: "Achuar-Shiwiar", Code: "acu"}, //30 {Name: "Afrikaans", Code: "af"},31 {Name: "Aguaruna", Code: "agr"}, //32 {Name: "Akawaio", Code: "ake"}, //33 {Name: "Albanian", Code: "sq"},34 {Name: "Amharic", Code: "am"},35 {Name: "Arabic", Code: "ar"},36 {Name: "Armenian", Code: "hy"},37 {Name: "Azerbaijani", Code: "az"},38 {Name: "Barasana-Eduria", Code: "bsn"}, //39 {Name: "Bashkir", Code: "ba"},//40 {Name: "Basque", Code: "eu"},41 {Name: "Belarusian", Code: "be"},42 {Name: "Bemba", Code: "bem"}, //43 {Name: "Bengali", Code: "bn"},44 {Name: "Berber", Code: "ber"},//45 {Name: "Bislama", Code: "bi"}, //46 {Name: "Bosnian", Code: "bs"},47 {Name: "Breton", Code: "br"}, //48 {Name: "Bulgarian", Code: "bg"},49 {Name: "Cabécar", Code: "cjp"}, //50 {Name: "Cantonese", Code: "yue"},51 {Name: "Catalan", Code: "ca"},52 {Name: "Cebuano", Code: "ceb"},53 {Name: "Chamorro", Code: "cha"}, //54 {Name: "Cherokee", Code: "chr"}, //55 {Name: "Chichewa", Code: "ny"},56 {Name: "Chinese (Simplified)", Code: "zh"},// "zh-cn" on Google57 {Name: "Chinese (Traditional)", Code: "cht"}, // "zh-tw" on Google58 {Name: "Chuvash", Code: "cv"},59 {Name: "Coptic", Code: "cop"}, //60 {Name: "Corsican", Code: "co"},61 {Name: "Croatian", Code: "hr"},62 {Name: "Czech", Code: "cs"},63 {Name: "Danish", Code: "da"},64 {Name: "Dhivehi", Code: "dv"}, //65 {Name: "Dinka", Code: "dik"},//66 {Name: "Dutch", Code: "nl"},67 {Name: "Dzongkha", Code: "dz"}, //68 {Name: "English", Code: "en"},69 {Name: "Esperanto", Code: "eo"},70 {Name: "Estonian", Code: "et"},71 {Name: "Ewe", Code: "ee"},//72 {Name: "Faroese", Code: "fo"},//73 {Name: "Fijian", Code: "fj"},//74 {Name: "Filipino", Code: "fil"}, // "tl" on Google75 {Name: "Finnish", Code: "fi"},76 {Name: "French", Code: "fr"},77 {Name: "Frisian", Code: "fy"},78 {Name: "Galela", Code: "gbi"}, //79 {Name: "Galician", Code: "gl"},80 {Name: "Ganda", Code: "lg"}, //81 {Name: "Georgian", Code: "jy"}, // "ka" on Google82 {Name: "German", Code: "de"},83 {Name: "Greek", Code: "el"},84 {Name: "Guerrero Amuzgo", Code: "amu"}, //85 {Name: "Gujarati", Code: "gu"},86 {Name: "Haitian Creole", Code: "ht"},87 {Name: "Hausa", Code: "ha"},88 {Name: "Hawaiian", Code: "haw"},89 {Name: "Hebrew", Code: "he"}, // "iw" on Google90 {Name: "Hindi", Code: "hi"},91 {Name: "Hmong Daw", Code: "mww"}, //92 {Name: "Hmong", Code: "hmn"}, // not in iciba93 {Name: "Hungarian", Code: "hu"},94 {Name: "Icelandic", Code: "is"},95 {Name: "Igbo", Code: "ig"},96 {Name: "Indonesian", Code: "id"},97 {Name: "Irish", Code: "ga"},98 {Name: "Italian", Code: "it"},99 {Name: "Jacalteco", Code: "jac"}, //100 {Name: "Japanese", Code: "ja"},101 {Name: "Javanese", Code: "jv"}, // "jw" on Google102 {Name: "Kabyle", Code: "kab"},//103 {Name: "Kannada", Code: "kn"},104 {Name: "Kaqchikel", Code: "cak"},//105 {Name: "Kazakh", Code: "ka"}, // Google only has "kk"106 {Name: "Kazakh (Cyrillic)", Code: "kk"}, // Google has it as just "Kazakh"107 {Name: "Kekchí", Code: "kek"},//108 {Name: "Khmer", Code: "km"},109 {Name: "Kinyarwanda", Code: "rw"},110 {Name: "Kongo", Code: "kg"}, //111 {Name: "Korean", Code: "ko"},112 {Name: "Kurdish (Kurmanji)", Code: "ku"},113 {Name: "Kyrgyz", Code: "ky"},114 {Name: "Lao", Code: "lo"},115 {Name: "Latin", Code: "la"},116 {Name: "Latvian", Code: "lv"},117 {Name: "Lingala", Code: "ln"}, //118 {Name: "Lithuanian", Code: "lt"},119 {Name: "Lukpa", Code: "dop"}, //120 {Name: "Luxembourgish", Code: "lb"},121 {Name: "Macedonian", Code: "mk"},122 {Name: "Malagasy", Code: "mg"},123 {Name: "Malay", Code: "ms"},124 {Name: "Malayalam", Code: "ml"},125 {Name: "Maltese", Code: "mt"},126 {Name: "Mam", Code: "mam"},//127 {Name: "Manx", Code: "gv"}, //128 {Name: "Maori", Code: "mi"},129 {Name: "Marathi", Code: "mr"},130 {Name: "Mari (Eastern)", Code: "mhr"}, //131 {Name: "Mari (Western)", Code: "mrj"}, //132 {Name: "Mongolian", Code: "mn"},133 {Name: "Montenegrin", Code: "me"}, //134 {Name: "Myanmar (Burmese)", Code: "my"},135 {Name: "Nahuatl", Code: "nhg"}, //136 {Name: "Ndyuka", Code: "djk"}, //137 {Name: "Nepali", Code: "ne"},138 {Name: "Norwegian", Code: "no"},139 {Name: "Odia (Oriya)", Code: "or"},140 {Name: "Ojibwa", Code: "ojb"},141 {Name: "Oromo", Code: "om"},//142 {Name: "Ossetian", Code: "os"},//143 {Name: "Paite", Code: "pck"}, //144 {Name: "Papiamento", Code: "pap"}, //145 {Name: "Pashto", Code: "ps"},146 {Name: "Persian", Code: "fa"},147 {Name: "Polish", Code: "pl"},148 {Name: "Portuguese", Code: "pt"},149 {Name: "Potawatomi", Code: "pot"}, //150 {Name: "Punjabi", Code: "pa"},151 {Name: "Querétaro Otomi", Code: "otq"}, //152 {Name: "Quiché", Code: "quc"}, //153 {Name: "Quichua", Code: "quw"}, //154 {Name: "Quiotepec Chinantec", Code: "chq"}, //155 {Name: "Romani", Code: "rmn"}, //156 {Name: "Romanian", Code: "ro"},157 {Name: "Rundi", Code: "rn"}, //158 {Name: "Russian", Code: "ru"},159 {Name: "Samoan", Code: "sm"},160 {Name: "Sango", Code: "sg"}, //161 {Name: "Scots Gaelic", Code: "gd"},162 {Name: "Serbian", Code: "sr"},163 {Name: "Seselwa Creole French", Code: "crs"}, //164 {Name: "Sesotho", Code: "st"},165 {Name: "Shona", Code: "sn"},166 {Name: "Shuar", Code: "jiv"}, //167 {Name: "Sindhi", Code: "sd"},168 {Name: "Sinhala", Code: "si"},169 {Name: "Slovak", Code: "sk"},170 {Name: "Slovenian", Code: "sl"},171 {Name: "Somali", Code: "so"},172 {Name: "Spanish", Code: "es"},173 {Name: "Sundanese", Code: "su"},174 {Name: "Swahili", Code: "sw"},175 {Name: "Swedish", Code: "sv"},176 {Name: "Syriac", Code: "syc"}, // considered "extinct" but is somehow supported177 {Name: "Tachelhit", Code: "shi"}, //178 {Name: "Tahitian", Code: "ty"},//179 {Name: "Tajik", Code: "tg"},180 {Name: "Tamil", Code: "ta"},181 {Name: "Tatar", Code: "tt"},182 {Name: "Telugu", Code: "te"},183 {Name: "Tetum", Code: "tet"}, //184 {Name: "Thai", Code: "th"},185 {Name: "Tigre", Code: "ti"},//186 {Name: "Tiwi", Code: "tw"},//187 {Name: "Tok Pisin", Code: "tpi"}, //188 {Name: "Tonga", Code: "to"},//189 {Name: "Tsonga", Code: "ts"},190 {Name: "Tswana", Code: "tn"}, //191 {Name: "Turkish", Code: "tr"},192 {Name: "Turkmen", Code: "tk"},193 {Name: "Udmurt", Code: "udm"}, //194 {Name: "Ukrainian", Code: "uk"},195 {Name: "Uma", Code: "ppk"}, //196 {Name: "Urdu", Code: "ur"},197 {Name: "Uspanteco", Code: "usp"}, //198 {Name: "Uyghur", Code: "uy"},// "ug" on Google199 {Name: "Uzbek", Code: "uz"},200 {Name: "Venda", Code: "ve"}, //201 {Name: "Vietnamese", Code: "vi"},202 {Name: "Waray", Code: "war"}, //203 {Name: "Welsh", Code: "cy"},204 {Name: "Wolaitta", Code: "wal"}, //205 {Name: "Wolof", Code: "wol"},206 {Name: "Xhosa", Code: "xh"},207 {Name: "Yiddish", Code: "yi"},208 {Name: "Yoruba", Code: "yo"},209 {Name: "Yucatán Maya", Code: "yua"}, //210 {Name: "Zarma", Code: "dje"}, //211 {Name: "Zulu", Code: "zu"},28 "ace": "Achinese", // 29 "acu": "Achuar-Shiwiar", // 30 "af": "Afrikaans", 31 "agr": "Aguaruna", // 32 "ake": "Akawaio", // 33 "sq": "Albanian", 34 "am": "Amharic", 35 "ar": "Arabic", 36 "hy": "Armenian", 37 "az": "Azerbaijani", 38 "bsn": "Barasana-Eduria", // 39 "ba": "Bashkir", // 40 "eu": "Basque", 41 "be": "Belarusian", 42 "bem": "Bemba", // 43 "bn": "Bengali", 44 "ber": "Berber", // 45 "bi": "Bislama", // 46 "bs": "Bosnian", 47 "br": "Breton", // 48 "bg": "Bulgarian", 49 "cjp": "Cabécar", // 50 "yue": "Cantonese", 51 "ca": "Catalan", 52 "ceb": "Cebuano", 53 "cha": "Chamorro", // 54 "chr": "Cherokee", // 55 "ny": "Chichewa", 56 "zh": "Chinese (Simplified)", // "zh-cn" on Google 57 "cht": "Chinese (Traditional)", // "zh-tw" on Google 58 "cv": "Chuvash", 59 "cop": "Coptic", // 60 "co": "Corsican", 61 "hr": "Croatian", 62 "cs": "Czech", 63 "da": "Danish", 64 "dv": "Dhivehi", // 65 "dik": "Dinka", // 66 "nl": "Dutch", 67 "dz": "Dzongkha", // 68 "en": "English", 69 "eo": "Esperanto", 70 "et": "Estonian", 71 "ee": "Ewe", // 72 "fo": "Faroese", // 73 "fj": "Fijian", // 74 "fil": "Filipino", // "tl" on Google 75 "fi": "Finnish", 76 "fr": "French", 77 "fy": "Frisian", 78 "gbi": "Galela", // 79 "gl": "Galician", 80 "lg": "Ganda", // 81 "jy": "Georgian", // "ka" on Google 82 "de": "German", 83 "el": "Greek", 84 "amu": "Guerrero Amuzgo", // 85 "gu": "Gujarati", 86 "ht": "Haitian Creole", 87 "ha": "Hausa", 88 "haw": "Hawaiian", 89 "he": "Hebrew", // "iw" on Google 90 "hi": "Hindi", 91 "mww": "Hmong Daw", // 92 "hmn": "Hmong", // not in iciba 93 "hu": "Hungarian", 94 "is": "Icelandic", 95 "ig": "Igbo", 96 "id": "Indonesian", 97 "ga": "Irish", 98 "it": "Italian", 99 "jac": "Jacalteco", // 100 "ja": "Japanese", 101 "jv": "Javanese", // "jw" on Google 102 "kab": "Kabyle", // 103 "kn": "Kannada", 104 "cak": "Kaqchikel", // 105 "ka": "Kazakh", // Google only has "kk" 106 "kk": "Kazakh (Cyrillic)", // Google has it as just "Kazakh" 107 "kek": "Kekchí", // 108 "km": "Khmer", 109 "rw": "Kinyarwanda", 110 "kg": "Kongo", // 111 "ko": "Korean", 112 "ku": "Kurdish (Kurmanji)", 113 "ky": "Kyrgyz", 114 "lo": "Lao", 115 "la": "Latin", 116 "lv": "Latvian", 117 "ln": "Lingala", // 118 "lt": "Lithuanian", 119 "dop": "Lukpa", // 120 "lb": "Luxembourgish", 121 "mk": "Macedonian", 122 "mg": "Malagasy", 123 "ms": "Malay", 124 "ml": "Malayalam", 125 "mt": "Maltese", 126 "mam": "Mam", // 127 "gv": "Manx", // 128 "mi": "Maori", 129 "mr": "Marathi", 130 "mhr": "Mari (Eastern)", // 131 "mrj": "Mari (Western)", // 132 "mn": "Mongolian", 133 "me": "Montenegrin", // 134 "my": "Myanmar (Burmese)", 135 "nhg": "Nahuatl", // 136 "djk": "Ndyuka", // 137 "ne": "Nepali", 138 "no": "Norwegian", 139 "or": "Odia (Oriya)", 140 "ojb": "Ojibwa", 141 "om": "Oromo", // 142 "os": "Ossetian", // 143 "pck": "Paite", // 144 "pap": "Papiamento", // 145 "ps": "Pashto", 146 "fa": "Persian", 147 "pl": "Polish", 148 "pt": "Portuguese", 149 "pot": "Potawatomi", // 150 "pa": "Punjabi", 151 "otq": "Querétaro Otomi", // 152 "quc": "Quiché", // 153 "quw": "Quichua", // 154 "chq": "Quiotepec Chinantec", // 155 "rmn": "Romani", // 156 "ro": "Romanian", 157 "rn": "Rundi", // 158 "ru": "Russian", 159 "sm": "Samoan", 160 "sg": "Sango", // 161 "gd": "Scots Gaelic", 162 "sr": "Serbian", 163 "crs": "Seselwa Creole French", // 164 "st": "Sesotho", 165 "sn": "Shona", 166 "jiv": "Shuar", // 167 "sd": "Sindhi", 168 "si": "Sinhala", 169 "sk": "Slovak", 170 "sl": "Slovenian", 171 "so": "Somali", 172 "es": "Spanish", 173 "su": "Sundanese", 174 "sw": "Swahili", 175 "sv": "Swedish", 176 "syc": "Syriac", // considered "extinct" but is somehow supported 177 "shi": "Tachelhit", // 178 "ty": "Tahitian", // 179 "tg": "Tajik", 180 "ta": "Tamil", 181 "tt": "Tatar", 182 "te": "Telugu", 183 "tet": "Tetum", // 184 "th": "Thai", 185 "ti": "Tigre", // 186 "tw": "Tiwi", // 187 "tpi": "Tok Pisin", // 188 "to": "Tonga", // 189 "ts": "Tsonga", 190 "tn": "Tswana", // 191 "tr": "Turkish", 192 "tk": "Turkmen", 193 "udm": "Udmurt", // 194 "uk": "Ukrainian", 195 "ppk": "Uma", // 196 "ur": "Urdu", 197 "usp": "Uspanteco", // 198 "uy": "Uyghur", // "ug" on Google 199 "uz": "Uzbek", 200 "ve": "Venda", // 201 "vi": "Vietnamese", 202 "war": "Waray", // 203 "cy": "Welsh", 204 "wal": "Wolaitta", // 205 "wol": "Wolof", 206 "xh": "Xhosa", 207 "yi": "Yiddish", 208 "yo": "Yoruba", 209 "yua": "Yucatán Maya", // 210 "dje": "Zarma", // 211 "zu": "Zulu", 212 212 } 213 213 214 func (_ *ICIBA) SourceLanguages() ([]Language, error) { return icibaLanguages, nil } 215 216 func (_ *ICIBA) TargetLanguages() ([]Language, error) { return icibaLanguages, nil } 217 218 func (_ *ICIBA) SupportsAutodetect() bool { return true } 219 220 func (_ *ICIBA) DetectLanguage(text string) (Language, error) { return Language{}, nil } 214 func (_ *ICIBA) SourceLanguages() (Language, error) { return icibaLanguages, nil } 215 216 func (_ *ICIBA) TargetLanguages() (Language, error) { return icibaLanguages, nil } 217 218 func (_ *ICIBA) DetectLanguage(text string) (string, error) { return "", nil } 221 219 222 220 type icibaTranslateResponse struct { … … 227 225 } 228 226 229 func (_ *ICIBA) Translate(text string, from, to Language) (TranslationResult, error) {227 func (_ *ICIBA) Translate(text string, from, to string) (TranslationResult, error) { 230 228 requestURL, err := url.Parse("https://ifanyi.iciba.com/index.php") 231 229 … … 248 246 249 247 formData := url.Values{} 250 formData.Add("from", from .Code)251 formData.Add("to", to .Code)248 formData.Add("from", from) 249 formData.Add("to", to) 252 250 formData.Add("q", text) 253 251 … … 270 268 } 271 269 272 var sourceLanguage Language273 274 for _, lang:= range icibaLanguages {275 if lang.Code == responseJSON.Content.From {276 sourceLanguage = lang270 var sourceLanguage string 271 272 for code := range icibaLanguages { 273 if code == responseJSON.Content.From { 274 sourceLanguage = code 277 275 break 278 276 } 279 277 } 280 278 281 if sourceLanguage == (Language{}){282 return TranslationResult{ SourceLanguage: from,TranslatedText: responseJSON.Content.Out},279 if sourceLanguage == "" { 280 return TranslationResult{TranslatedText: responseJSON.Content.Out}, 283 281 fmt.Errorf("language code \"%s\" is not in iCIBA's language list", responseJSON.Content.From) 284 282 } -
trunk/engines/libretranslate.go
r12 r15 28 28 func (_ *LibreTranslate) DisplayName() string { return "LibreTranslate" } 29 29 30 type libreLanguagesResponse []struct { 31 Name string `json:"name"` 32 Code string `json:"code"` 33 } 34 35 func (e *LibreTranslate) getLangs() ([]Language, error) { 30 func (e *LibreTranslate) getLangs() (Language, error) { 36 31 response, err := http.Get(e.InstanceURL + "/languages") 37 32 … … 46 41 } 47 42 48 var langsResponse libreLanguagesResponse 43 var langsResponse []struct { 44 Name string `json:"name"` 45 Code string `json:"code"` 46 } 49 47 50 48 if err := json.NewDecoder(response.Body).Decode(&langsResponse); err != nil { … … 52 50 } 53 51 54 langs := make([]Language, len(langsResponse))52 langs := Language{} 55 53 56 for i, lang := range langsResponse {57 langs[ i] = Language{Name: lang.Name, Code: lang.Code}54 for _, lang := range langsResponse { 55 langs[lang.Code] = lang.Name 58 56 } 59 57 … … 62 60 } 63 61 64 func (e *LibreTranslate) SourceLanguages() ( []Language, error) { return e.getLangs() }62 func (e *LibreTranslate) SourceLanguages() (Language, error) { return e.getLangs() } 65 63 66 func (e *LibreTranslate) TargetLanguages() ([]Language, error) { return e.getLangs() } 67 68 func (_ *LibreTranslate) SupportsAutodetect() bool { return true } 64 func (e *LibreTranslate) TargetLanguages() (Language, error) { return e.getLangs() } 69 65 70 66 type libreDetectResponse []struct { … … 73 69 } 74 70 75 func (e *LibreTranslate) DetectLanguage(text string) ( Language, error) {71 func (e *LibreTranslate) DetectLanguage(text string) (string, error) { 76 72 formData := map[string]string{"q": text} 77 73 … … 83 79 84 80 if err != nil { 85 return Language{}, err81 return "", err 86 82 } 87 83 … … 89 85 90 86 if err != nil { 91 return Language{}, err87 return "", err 92 88 } 93 89 … … 95 91 96 92 if response.StatusCode != 200 { 97 return Language{}, fmt.Errorf("got status code %d from LibreTranslate API", response.StatusCode)93 return "", fmt.Errorf("got status code %d from LibreTranslate API", response.StatusCode) 98 94 } 99 95 … … 101 97 102 98 if err := json.NewDecoder(response.Body).Decode(&langs); err != nil { 103 return Language{}, err99 return "", err 104 100 } 105 101 … … 115 111 116 112 if err != nil { 117 return Language{}, err113 return "", err 118 114 } 119 115 120 for _, lang:= range engineLangs {121 if lang.Code == maxConfidenceLang.LanguageCode {122 return lang, nil116 for code := range engineLangs { 117 if code == maxConfidenceLang.LanguageCode { 118 return code, nil 123 119 } 124 120 } 125 121 126 return Language{}, fmt.Errorf("language code \"%s\" is not in the instance's language list", maxConfidenceLang.LanguageCode)122 return "", fmt.Errorf("language code \"%s\" is not in the instance's language list", maxConfidenceLang.LanguageCode) 127 123 } 128 124 … … 131 127 } 132 128 133 func (e *LibreTranslate) Translate(text string, from, to Language) (TranslationResult, error) {129 func (e *LibreTranslate) Translate(text string, from, to string) (TranslationResult, error) { 134 130 formData := map[string]string{ 135 131 "q": text, 136 "source": from .Code,137 "target": to .Code,132 "source": from, 133 "target": to, 138 134 } 139 135 … … 166 162 } 167 163 168 return TranslationResult{ SourceLanguage: from,TranslatedText: responseJSON.TranslatedText}, nil164 return TranslationResult{TranslatedText: responseJSON.TranslatedText}, nil 169 165 } -
trunk/engines/reverso.go
r13 r15 15 15 func (_ *Reverso) DisplayName() string { return "Reverso" } 16 16 17 var reversoLangs = []Language{18 {Name: "Arabic", Code: "ara"},19 {Name: "Chinese (Simplified)", Code: "chi"}, // marketed as just "Chinese"20 {Name: "Czech", Code: "cze"},21 {Name: "Danish", Code: "dan"},22 {Name: "Dutch", Code: "dut"},23 {Name: "English", Code: "eng"},24 {Name: "French", Code: "fra"},25 {Name: "German", Code: "ger"},26 {Name: "Hebrew", Code: "heb"},27 {Name: "Hindi", Code: "hin"},28 {Name: "Hungarian", Code: "hun"},29 {Name: "Italian", Code: "ita"},30 {Name: "Japanese", Code: "jpn"},31 {Name: "Korean", Code: "kor"},32 {Name: "Persian", Code: "per"},33 {Name: "Polish", Code: "pol"},34 {Name: "Portuguese", Code: "por"},35 {Name: "Romanian", Code: "rum"},36 {Name: "Russian", Code: "rus"},37 {Name: "Slovak", Code: "slo"},38 {Name: "Spanish", Code: "spa"},39 {Name: "Swedish", Code: "swe"},40 {Name: "Thai", Code: "tha"},41 {Name: "Turkish", Code: "tur"},42 {Name: "Ukrainian", Code: "ukr"},17 var reversoLangs = Language{ 18 "ara": "Arabic", 19 "chi": "Chinese (Simplified)", // marketed as just "Chinese" 20 "cze": "Czech", 21 "dan": "Danish", 22 "dut": "Dutch", 23 "eng": "English", 24 "fra": "French", 25 "ger": "German", 26 "heb": "Hebrew", 27 "hin": "Hindi", 28 "hun": "Hungarian", 29 "ita": "Italian", 30 "jpn": "Japanese", 31 "kor": "Korean", 32 "per": "Persian", 33 "pol": "Polish", 34 "por": "Portuguese", 35 "rum": "Romanian", 36 "rus": "Russian", 37 "slo": "Slovak", 38 "spa": "Spanish", 39 "swe": "Swedish", 40 "tha": "Thai", 41 "tur": "Turkish", 42 "ukr": "Ukrainian", 43 43 } 44 44 45 func (_ *Reverso) SourceLanguages() ( []Language, error) { return reversoLangs, nil }45 func (_ *Reverso) SourceLanguages() (Language, error) { return reversoLangs, nil } 46 46 47 func (_ *Reverso) TargetLanguages() ([]Language, error) { return reversoLangs, nil } 48 49 func (_ *Reverso) SupportsAutodetect() bool { return true } 47 func (_ *Reverso) TargetLanguages() (Language, error) { return reversoLangs, nil } 50 48 51 49 type reversoAPIResponse struct { … … 56 54 } 57 55 58 func (e *Reverso) callAPI(text string, from, to Language) (reversoAPIResponse, error) {56 func (e *Reverso) callAPI(text string, from, to string) (reversoAPIResponse, error) { 59 57 // `contextResults` must be false for language detection 60 58 formData := map[string]interface{}{ 61 59 "format": "text", 62 "from": from .Code,63 "to": to .Code,60 "from": from, 61 "to": to, 64 62 "input": text, 65 63 "options": map[string]interface{}{ … … 110 108 } 111 109 112 func (e *Reverso) DetectLanguage(text string) ( Language, error) {110 func (e *Reverso) DetectLanguage(text string) (string, error) { 113 111 // Any language pair works here, does not affect result 114 r, err := e.callAPI(text, reversoLangs[0], reversoLangs[1])112 r, err := e.callAPI(text, "ara", "chi") 115 113 116 114 if err != nil { 117 return Language{}, err115 return "", err 118 116 } 119 117 120 118 langCode := r.LanguageDetection.DetectedLanguage 121 119 122 for _, lang:= range reversoLangs {123 if lang.Code == langCode {124 return lang, nil120 for code := range reversoLangs { 121 if code == langCode { 122 return code, nil 125 123 } 126 124 } 127 125 128 return Language{}, fmt.Errorf("language code \"%s\" is not in Reverso's language list", langCode)126 return "", fmt.Errorf("language code \"%s\" is not in Reverso's language list", langCode) 129 127 } 130 128 131 func (e *Reverso) Translate(text string, from, to Language) (TranslationResult, error) {132 if from .Code== "auto" {129 func (e *Reverso) Translate(text string, from, to string) (TranslationResult, error) { 130 if from == "auto" { 133 131 from_, err := e.DetectLanguage(text) 134 132 … … 155 153 156 154 return TranslationResult{ 157 SourceLanguage: from,158 155 TranslatedText: translation, 159 156 }, nil -
trunk/web/go.mod
r9 r15 3 3 go 1.16 4 4 5 require codeberg.org/SimpleWeb/SimplyTranslate/engines v0.0.0 5 require ( 6 codeberg.org/SimpleWeb/SimplyTranslate/engines v0.0.0 7 github.com/gofiber/fiber/v2 v2.49.0 // indirect 8 ) 6 9 7 10 replace codeberg.org/SimpleWeb/SimplyTranslate/engines v0.0.0 => ../engines -
trunk/web/go.sum
r14 r15 1 1 github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM= 2 2 github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ= 3 github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= 4 github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= 3 5 github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c= 4 6 github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA= 7 github.com/gofiber/fiber/v2 v2.49.0 h1:xBVG2c66GDcWfww56xHvMn52Q0XX7UrSvjj6MD8/5EE= 8 github.com/gofiber/fiber/v2 v2.49.0/go.mod h1:oxpt7wQaEYgdDmq7nMxCGhilYicBLFnZ+jQSJcQDlSE= 9 github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= 10 github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 11 github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= 12 github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= 13 github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= 14 github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 15 github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= 16 github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 17 github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= 18 github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 19 github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= 20 github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= 21 github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0= 22 github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= 23 github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= 24 github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw= 25 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= 26 github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= 27 github.com/valyala/fasthttp v1.48.0 h1:oJWvHb9BIZToTQS3MuQ2R3bJZiNSa2KiNdeI8A+79Tc= 28 github.com/valyala/fasthttp v1.48.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA= 29 github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= 30 github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= 5 31 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 6 32 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 7 33 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 34 golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= 8 35 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= 36 golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 9 37 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 10 38 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= … … 12 40 golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 13 41 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 42 golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= 14 43 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= 15 44 golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= … … 25 54 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 26 55 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 56 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 57 golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 27 58 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 28 59 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 60 golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= 61 golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 29 62 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 30 63 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 64 golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= 31 65 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= 32 66 golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= … … 35 69 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 36 70 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 71 golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 37 72 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 38 73 golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= … … 40 75 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 41 76 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 77 golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= 42 78 golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= 43 79 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -
trunk/web/main.go
r10 r15 3 3 import ( 4 4 "codeberg.org/SimpleWeb/SimplyTranslate/engines" 5 "github.com/gofiber/fiber/v2" 5 6 ) 6 7 7 // TODO: port web frontend to Go. 8 func main() { 9 app := fiber.New() 8 10 9 func main() { 10 engine := &engines.GoogleTranslate{} 11 print(engine.DisplayName()) 11 app.All("/api/translate", func(c *fiber.Ctx) error { 12 from := "" 13 to := "" 14 engine := "" 15 text := "" 16 if c.Method() == "GET" { 17 engine = c.Query("engine") 18 text = c.Query("text") 19 from = c.Query("from") 20 to = c.Query("to") 21 } else if c.Method() == "POST" { 22 engine = c.FormValue("engine") 23 text = c.FormValue("text") 24 from = c.FormValue("from") 25 to = c.FormValue("to") 26 } else { 27 return c.SendStatus(400) 28 } 29 if engine == "" { 30 engine = "google" 31 } 32 if to == "" { 33 return c.SendStatus(400) 34 } 35 if result, err := engines.Engines[engine].Translate(text, from, to); err != nil { 36 return c.SendStatus(500) 37 } else { 38 return c.JSON(result) 39 } 40 }) 41 42 app.Listen(":3000") 12 43 }
Note:
See TracChangeset
for help on using the changeset viewer.