[v2] GoogleTranslate /_/TranslateWebserverUi
Posted: 05 Feb 2023, 17:59
motivation:
viewtopic.php?f=6&t=63835 incorrectly detects 門 as Chinese Simplified, it uses url path: /translate_a/single
there's another url path of translate.google.com which detects this correctly: /_/TranslateWebserverUi
it is the same url path that the website https://translate.google.com/ uses, which also detects it correctly: Chinese (Traditional)
edit: added autocorrect, use it to correct dia to día for example
fromText is the autocorrected
viewtopic.php?f=6&t=63835 incorrectly detects 門 as Chinese Simplified, it uses url path: /translate_a/single
there's another url path of translate.google.com which detects this correctly: /_/TranslateWebserverUi
it is the same url path that the website https://translate.google.com/ uses, which also detects it correctly: Chinese (Traditional)
Code: Select all
MsgBox JSON_stringify(GoogleTranslate("hello world", "zh-CH")) ;{"fromLanguage": "en","text": "你好世界"}
MsgBox JSON_stringify(GoogleTranslate("门", "zh-TW")) ;{"fromLanguage": "zh-CN","text": "門"}
; good luck finding out what 门 means
GoogleTranslate(text, languageTo:="en", languageFrom:="auto") {
if (!GoogleTranslate.HasOwnProp("extracted")) {
hObject:=ComObject("WinHttp.WinHttpRequest.5.1")
hObject.Open("GET","https://translate.google.com")
hObject.SetRequestHeader("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)")
hObject.Send()
lol:=hObject.ResponseText
pos_FdrFJe := InStr(lol, "FdrFJe", true)
pos_quote_FdrFJe := InStr(lol, "`"", true, pos_FdrFJe + 9)
value_FdrFJe := SubStr(lol, pos_FdrFJe + 9, pos_quote_FdrFJe - (pos_FdrFJe + 9))
pos_cfb2h := InStr(lol, "cfb2h", true)
pos_quote_cfb2h := InStr(lol, "`"", true, pos_cfb2h + 8)
value_cfb2h := SubStr(lol, pos_cfb2h + 8, pos_quote_cfb2h - (pos_cfb2h + 8))
GoogleTranslate.extracted:={ FdrFJe: value_FdrFJe, cfb2h: value_cfb2h }
}
hObject:=ComObject("WinHttp.WinHttpRequest.5.1")
hObject.Open("POST","https://translate.google.com/_/TranslateWebserverUi/data/batchexecute?rpcids=MkEWBc&source-path=%2F&f.sid=" GoogleTranslate.extracted.FdrFJe "&bl=" GoogleTranslate.extracted.cfb2h "&hl=en-US&soc-app=1&soc-platform=1&soc-device=1&_reqid=" Random(1000,9999) "&rt=c")
hObject.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8")
hObject.Send("f.req=" encodeURIComponent(JSON_stringify([[["MkEWBc",JSON_stringify([[text, languageFrom, languageTo, {Base:{__Class:"JSON_false"}}], [{Base:{__Class:"JSON_null"}}]]), {Base:{__Class:"JSON_null"}}, 'generic']]])))
lol:=hObject.ResponseText
pos_newline := InStr(lol,"`n",true,8)
fwef:=SubStr(lol,7,pos_newline - 7)
size := Integer(SubStr(lol,7,pos_newline - 7)) - 2
jsonTemp := JSON_parse(SubStr(lol,pos_newline+1,size))
json := JSON_parse(jsonTemp[1][3])
if (type(json[1][2])=="JSON_null" || type(json[1][2][1])=="JSON_null") {
fromText:=false
} else {
fromText:=json[1][2][1][5]
}
;fromText is the autocorrected
return {text:json[2][1][1][6][1][1],fromLanguage:json[3],fromText:fromText}
}
JSON_parse(str) {
c_:=1
return JSON_value()
JSON_value() {
char_:=SubStr(str, c_, 1)
Switch char_ {
case "{":
obj_:=Map()
;object
c_++
loop {
skip_s()
if (SubStr(str, c_, 1) == "}") {
c_++
return obj_
}
; key_:=JSON_objKey()
; a or "a"
if (SubStr(str, c_, 1) == "`"") {
RegExMatch(str, "(?:\\.|.)*?(?=`")", &OutputVar, c_ + 1)
key_:=StrReplace(StrReplace(StrReplace(StrReplace(StrReplace(StrReplace(StrReplace(OutputVar.0, "\`"", "`"", true), "\f", "`f", true), "\r", "`r", true), "\n", "`n", true), "\b", "`b", true), "\t", "`t", true), "\\", "\", true)
c_+=OutputVar.Len
} else {
RegExMatch(str, ".*?(?=[\s:])", &OutputVar, c_)
key_:=OutputVar.0
c_+=OutputVar.Len
}
c_:=InStr(str, ":", true, c_) + 1
skip_s()
value_:=JSON_value()
obj_[key_]:=value_
obj_.DefineProp(key_, {Value: value_})
skip_s()
if (SubStr(str, c_, 1) == ",") {
c_++, skip_s()
}
}
case "[":
arr_:=[]
;array
c_++
loop {
skip_s()
if (SubStr(str, c_, 1) == "]") {
c_++
return arr_
}
value_:=JSON_value()
arr_.Push(value_)
skip_s()
char_:=SubStr(str, c_, 1)
if (char_ == ",") {
c_++, skip_s()
}
}
case "`"":
RegExMatch(str, "(?:\\.|.)*?(?=`")", &OutputVar, c_ + 1)
unquoted:=StrReplace(StrReplace(StrReplace(StrReplace(StrReplace(StrReplace(StrReplace(OutputVar.0, "\`"", "`"", true), "\f", "`f", true), "\r", "`r", true), "\n", "`n", true), "\b", "`b", true), "\t", "`t", true), "\\", "\", true)
c_+=OutputVar.Len + 2
return unquoted
case "-", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9":
; -100
; 100.0
; 1.0E+2
; 1E-2
RegExMatch(str, "[0-9.eE\-+]*", &OutputVar, c_)
c_+=OutputVar.Len
return Number(OutputVar.0)
case "t":
;"true"
c_+=4
return {Base:{__Class:"JSON_true"}}
case "f":
;"false"
c_+=5
return {Base:{__Class:"JSON_false"}}
case "n":
;"null"
c_+=4
return {Base:{__Class:"JSON_null"}}
}
}
skip_s() {
RegExMatch(str, "\s*", &OutputVar, c_)
c_+=OutputVar.Len
}
}
JSON_stringify(obj, maxDepth := 5) {
stringified := ""
escape(str) {
str:=StrReplace(str, "\", "\\", true)
str:=StrReplace(str, "`t", "\t", true)
str:=StrReplace(str, "`b", "\b", true)
str:=StrReplace(str, "`n", "\n", true)
str:=StrReplace(str, "`r", "\r", true)
str:=StrReplace(str, "`f", "\f", true)
str:=StrReplace(str, "`"", "\`"", true)
return str
}
ok(obj, depth) {
switch (Type(obj)) {
case 'Map':
if (depth > maxDepth) {
stringified.="`"[DEEP ...Map]`""
} else {
stringified.="{"
for k, v in obj {
(A_Index > 1 && stringified.=",")
stringified.="`"" escape(k) "`": "
ok(v, depth+1)
}
stringified.="}"
}
case 'Object':
if (depth > maxDepth) {
stringified.="`"[DEEP ...Object]`""
} else {
stringified.="{"
for k, v in obj.OwnProps() {
(A_Index > 1 && stringified.=",")
stringified.="`"" escape(k) "`": "
ok(v, depth+1)
}
stringified.="}"
}
case 'Array':
if (depth > maxDepth) {
stringified.="`"[DEEP ...Array]`""
} else {
stringified.="["
for v in obj {
(A_Index > 1 && stringified.=",")
ok(v, depth+1)
}
stringified.="]"
}
case 'String':
stringified.="`"" escape(obj) "`"" ;in order to escape \n and etc
case "Integer", "Float":
stringified.=obj
case "JSON_true":
stringified.="true"
case "JSON_false":
stringified.="false"
case "JSON_null":
stringified.="null"
}
}
ok(obj, 0)
return stringified
}
encodeURIComponent(str) {
static arr:=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"!",0,0,0,0,0,"'","(",")","*",0,0,"-",".",0,"0","1","2","3","4","5","6","7","8","9",0,0,0,0,0,0,0,"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",0,0,0,0,"_",0,"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z",0,0,0,"~",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,]
size:=StrPut(str, "UTF-8")
buf := Buffer(size)
StrPut(str, buf, "UTF-8")
i_ := 0
sizeMinusOne := size - 1
finalStr:=""
while (i_ < sizeMinusOne) {
uChar:=NumGet(buf, i_, "UChar")
if (type(arr[uChar + 1])=="String") { ;I REALLY don't know how to get : "0"!==0 -> to give me false
finalStr.=arr[uChar + 1]
} else {
finalStr.="%" Format("{:02X}",uChar)
}
++i_
}
return finalStr
}
Exitapp
f3::Exitapp
fromText is the autocorrected