From 0b826f2255f10db1c4ee437dc6edcee7a18112f3 Mon Sep 17 00:00:00 2001 From: manerakai Date: Thu, 31 Aug 2023 12:23:39 +0000 Subject: [PATCH] Implemented Definitions and Translations for google git-svn-id: file:///srv/svn/repo/mai/trunk@21 e410bdd4-646f-c54f-a7ce-fffcc4f439ae --- engines/engine.go | 6 +- engines/google.go | 156 +++++++++++++++++++++++++++++++++++++++++++++ web/static/LICENSE | 4 +- 3 files changed, 162 insertions(+), 4 deletions(-) diff --git a/engines/engine.go b/engines/engine.go index 774be15..29e0b69 100644 --- a/engines/engine.go +++ b/engines/engine.go @@ -1,8 +1,10 @@ package engines type TranslationResult struct { - SourceLanguage string `json:"source_language"` - TranslatedText string `json:"translated_text"` + SourceLanguage string `json:"source_language"` + Definitions interface{} `json:"definitions"` + Translations interface{} `json:"translations"` + TranslatedText string `json:"translated_text"` } type Engine interface { diff --git a/engines/google.go b/engines/google.go index a54de5f..d398c81 100644 --- a/engines/google.go +++ b/engines/google.go @@ -1,10 +1,15 @@ package engines import ( + "bytes" "fmt" + "io/ioutil" "net/http" "net/url" + "encoding/json" + "regexp" + "github.com/PuerkitoBio/goquery" ) @@ -119,8 +124,159 @@ func (_ *GoogleTranslate) Translate(text string, from, to string) (TranslationRe return TranslationResult{}, err } + url_ := "https://translate.google.com/_/TranslateWebserverUi/data/batchexecute?rpcids=MkEWBc&rt=c" + + reqJSON := []interface{}{ + []interface{}{text, from, to, true}, + []interface{}{nil}, + } + reqJSONString, err := json.Marshal(reqJSON) + if err != nil { + fmt.Println("Error:", err) + return TranslationResult{}, nil + } + + req := []interface{}{[]interface{}{[]interface{}{"MkEWBc", string(reqJSONString), nil, "generic"}}} + + JSONString, _ := json.Marshal(req) + + body := "f.req=" + url.QueryEscape(string(JSONString)) + + resp, err := http.Post(url_, "application/x-www-form-urlencoded;charset=utf-8", bytes.NewBuffer([]byte(body))) + if err != nil { + fmt.Println("Error:", err) + return TranslationResult{}, nil + } + defer resp.Body.Close() + + bodyBytes, err := ioutil.ReadAll(resp.Body) + if err != nil { + fmt.Println("Error:", err) + return TranslationResult{}, nil + } + responseText := string(bodyBytes) + + responseText = regexp.MustCompile(`\n\d+\n(.*)\n\d+\n`).FindStringSubmatch(responseText)[1] + + var raw []interface{} + err = json.Unmarshal([]byte(responseText), &raw) + if err != nil { + fmt.Println("Error:", err) + return TranslationResult{}, nil + } + + data := raw[0].([]interface{})[2].(string) + + var json_ []interface{} + err = json.Unmarshal([]byte(data), &json_) + + definitions := make(map[string][]map[string]interface{}) + + if len(json_) > 3 && json_[3] != nil && + len(json_[3].([]interface{})) > 1 && json_[3].([]interface{})[1] != nil && + len(json_[3].([]interface{})[1].([]interface{})) > 0 && json_[3].([]interface{})[1].([]interface{})[0] != nil { + for x := 0; x < len(json_[3].([]interface{})[1].([]interface{})[0].([]interface{})); x++ { + if len(json_[3].([]interface{})[1].([]interface{})[0].([]interface{})[x].([]interface{})) > 0 { + definitionType := json_[3].([]interface{})[1].([]interface{})[0].([]interface{})[x].([]interface{})[0] + if definitionType == nil { + definitionType = "unknown" + } + + definitions[definitionType.(string)] = []map[string]interface{}{} + + for i := 0; i < len(json_[3].([]interface{})[1].([]interface{})[0].([]interface{})[x].([]interface{})[1].([]interface{})); i++ { + definitionBox := json_[3].([]interface{})[1].([]interface{})[0].([]interface{})[x].([]interface{})[1].([]interface{})[i].([]interface{}) + definitions[definitionType.(string)] = append(definitions[definitionType.(string)], map[string]interface{}{}) + + if len(definitionBox) > 4 && definitionBox[4] != nil && + len(definitionBox[4].([]interface{})) > 0 && definitionBox[4].([]interface{})[0] != nil && + len(definitionBox[4].([]interface{})[0].([]interface{})) > 0 && definitionBox[4].([]interface{})[0].([]interface{})[0] != nil { + definitions[definitionType.(string)][i]["dictionary"] = definitionBox[4].([]interface{})[0].([]interface{})[0] + } + + if len(definitionBox) > 0 && definitionBox[0] != nil { + definitions[definitionType.(string)][i]["definition"] = definitionBox[0] + } + + if len(definitionBox) > 1 && definitionBox[1] != nil { + definitions[definitionType.(string)][i]["use-in-sentence"] = definitionBox[1] + } + + if len(definitionBox) > 5 && definitionBox[5] != nil { + definitions[definitionType.(string)][i]["synonyms"] = map[string][]string{} + synonyms := definitionBox[5].([]interface{}) + synonymsMap := make(map[string][]string) + + for _, synonymBox := range synonyms { + synonymType := "" + if len(synonymBox.([]interface{})) > 1 && synonymBox.([]interface{})[1] != nil && + len(synonymBox.([]interface{})[1].([]interface{})) > 0 && synonymBox.([]interface{})[1].([]interface{})[0] != nil { + synonymType = synonymBox.([]interface{})[1].([]interface{})[0].([]interface{})[0].(string) + } + + if len(synonymBox.([]interface{})) > 0 && synonymBox.([]interface{})[0] != nil { + synonymList := synonymBox.([]interface{})[0].([]interface{}) + synonymsMap[synonymType] = []string{} + for _, synonymTypeWord := range synonymList { + synonymsMap[synonymType] = append(synonymsMap[synonymType], synonymTypeWord.([]interface{})[0].(string)) + } + } + } + + definitions[definitionType.(string)][i]["synonyms"] = synonymsMap + } + } + } + } + } + + translations := make(map[string]map[string]map[string]interface{}) + if len(json_) > 3 && json_[3] != nil && + len(json_[3].([]interface{})) > 5 && json_[3].([]interface{})[5] != nil && + len(json_[3].([]interface{})[5].([]interface{})) > 0 && json_[3].([]interface{})[5].([]interface{})[0] != nil { + translationBox := json_[3].([]interface{})[5].([]interface{})[0].([]interface{}) + for x := 0; x < len(translationBox); x++ { + if len(translationBox[x].([]interface{})) > 0 { + translationType := translationBox[x].([]interface{})[0] + if translationType == nil { + translationType = "unknown" + } + translations[translationType.(string)] = make(map[string]map[string]interface{}) + + if len(translationBox[x].([]interface{})) > 1 && translationBox[x].([]interface{})[1] != nil { + translationNamesBox := translationBox[x].([]interface{})[1].([]interface{}) + for i := 0; i < len(translationNamesBox); i++ { + if len(translationNamesBox[i].([]interface{})) > 0 && translationNamesBox[i].([]interface{})[0] != nil { + translationName := translationNamesBox[i].([]interface{})[0].(string) + translations[translationType.(string)][translationName] = make(map[string]interface{}) + if len(translationNamesBox[i].([]interface{})) > 3 && translationNamesBox[i].([]interface{})[3] != nil { + frequency := fmt.Sprintf("%d", int(translationNamesBox[i].([]interface{})[3].(float64))) + if frequency == "3" { + frequency = "1" + } else if frequency == "1" { + frequency = "3" + } + translations[translationType.(string)][translationName]["frequency"] = frequency + "/3" + + translations[translationType.(string)][translationName]["words"] = []string{} + if len(translationNamesBox[i].([]interface{})) > 2 && translationNamesBox[i].([]interface{})[2] != nil { + for z := 0; z < len(translationNamesBox[i].([]interface{})[2].([]interface{})); z++ { + word := translationNamesBox[i].([]interface{})[2].([]interface{})[z].(string) + translations[translationType.(string)][translationName]["words"] = append(translations[translationType.(string)][translationName]["words"].([]string), word) + } + } + } + } + } + } + } + } + } + return TranslationResult{ SourceLanguage: from, + Definitions: definitions, + Translations: translations, TranslatedText: doc.Find(".result-container").Text(), }, nil } diff --git a/web/static/LICENSE b/web/static/LICENSE index 690ed1a..d4bcb5a 100644 --- a/web/static/LICENSE +++ b/web/static/LICENSE @@ -1,3 +1,3 @@ favicon.ico, favicon.svg, favicon128x128.png - Created by "joelchrono12" (https://https://joelchrono12.ml/) - Creative Commons Attribution 4.0 International License (CC BY 4.0) +Created by "joelchrono12" (https://joelchrono12.ml/) +Creative Commons Attribution 4.0 International License (CC BY 4.0)