Page 10 of 12

Re: Using Google Translate to automate text translation

Posted: 17 Aug 2022, 09:13
by kunkel321
EM3R50N wrote:
17 Aug 2022, 05:58
My apologies on a noob question but I primarily just use AHK for snippet stuff - by typing keywords to get the full string, etc.
How do you guys trigger/use this script? Can I select text in notepad (for example) and trigger this script somehow?
I'm not an expert, but I'll try to answer... The first post of this thread has Teadrinker's original function, which does all the work. Throughout the thread, several people have posted their own GUIs (graphical user interfaces). The gui calls the function. You can probably just take the gui you like best and use it as is. Many of them probably have a hotkey built in. If they do, then you would run the script, and it would sit in RAM. Then when you press the hotkey combo, the gui will appear.

My own application of Teadrinker's function (a couple of replies above this reply) doesn't have a hotkey, because it gets activated from my masterscript that I always have running in the background.

EDIT: Welcome to the forum, by the way! :- }

Re: Using Google Translate to automate text translation

Posted: 17 Aug 2022, 12:25
by garry
at first page , GUI example second with audio : mark text and copy with ctrl+c
see result and also can use audio-button ( selected language is saved in a ini-file )
viewtopic.php?p=273678#p273678

Re: Using Google Translate to automate text translation

Posted: 18 Aug 2022, 19:57
by sfrerku
teadrinker wrote:
19 Oct 2019, 16:59
I fixed the obsolete parameters in the http request, the script is edited.
Hello teadrinker, awesome work. I have 2 questions tho:
1) The only way I have managed to activate it is by executing it. Can't you bind it to a hotkey without having to create another script to execute it?
2) Is there anyway I can get the result directly and automatically copied to my clipboard instead of opening a message box?

Re: Using Google Translate to automate text translation

Posted: 18 Aug 2022, 21:27
by sfrerku
@teadrinker Hi, thanks for your work!

I would like to know if there's a chance to bind this script to be executed by a hotkey, make it cut the selected text, translate it and paste it back.

I found a script that successfully replaces your current clipboard temporarily by another text (in this case the translation), then pastes it and then restores again the clipboard with whatever there was there before. I modified it to what I think would actually first save temporarily your clipboard, then cut the text you selected, then activate your script to translate the text, then replace the clipboard with the translated text, then paste it, and finally restore the clipboard to whatever it was before pressing the hotkey [ALT + T].

Code: Select all

!t::
 {
   temp := clipboardall
   sendinput, ^x
   "EXECUTE YOUR SCRIPT HERE, TRANSLATING THE CONTENTS OF THE CLIPBOARD, BUT WITHOUT DISPLAYING THE MSG BOX AT THE END WITH THE TRANSLATION"
   clipboard := "Translated text should be here"
   sendinput, ^v
   clipboard := temp
 }
return
[Mod edit: [code][/code] tags added.]

Is this possible?

Thanks in advance

Re: Using Google Translate to automate text translation

Posted: 19 Aug 2022, 11:55
by rommmcek
Try:
Spoiler

Re: Using Google Translate to automate text translation

Posted: 23 Aug 2022, 10:52
by sfrerku
rommmcek wrote:
19 Aug 2022, 11:55
Try:
Spoiler
Ok, but where exactly should I add this code on the original teadrinker Script? and what should I delete on the original Script to avoid the pop up window with the translation? I'm a complete beginner in scripting sorry. Thank you so much in advance.

Re: Using Google Translate to automate text translation

Posted: 24 Aug 2022, 06:18
by rommmcek
Just paste the function underneath the code I posted.
P.s.: Replacing only one marked word this way will yield often unexpected result, so avoid it or use my version of the function like: GoogleTranslate(Clipboard, "en", "ru").1.

Re: Using Google Translate to automate text translation

Posted: 11 Oct 2022, 10:00
by Gh0sTG0
Hi. I find some really strange bug.
I'm trying to do some translator for my own use.

I just copypasted code from 1st post. My command is:

Code: Select all

F2::
{
	Clipboard := GoogleTranslate(Clipboard)
	Return
}

On testing I find some number of things that were translated good and this:
うずまきすすふえん| 卯月総集編

When I press F2 I have in my clipboard this:
Uzumaki Sufuen |
As you can see there's no part that is on right from "|".


I tried to remove "|", and I get this:
Uzumaki Sufuen Uzuki Highlights

Any ideas about why "|" is breaking translation?


I know, that I can just:

Code: Select all

Clipboard := StrReplace(Clipboard, "|", A_Space)
But... Is "|" the only one symbol that is breaking translation? Or I should catch them all manually? Or... what?

Re: Using Google Translate to automate text translation

Posted: 11 Oct 2022, 10:48
by teadrinker
@Gh0sTG0
Perhaps some Japanese language related issue. Try translating from any other language.

Re: Using Google Translate to automate text translation

Posted: 11 Oct 2022, 11:05
by Gh0sTG0
teadrinker wrote:
11 Oct 2022, 10:48
@Gh0sTG0
Try translating from any other language.
Already tried, it's working ok.
And... I find that it's not script's failure =_= it's some google translate problems, it translates like that in browser window =(.

Re: Using Google Translate to automate text translation

Posted: 18 Oct 2022, 01:51
by Rikk03
How can I just write the slit text back to the clipboard, each new piece on a new line?
teadrinker wrote:
11 Feb 2021, 10:08
BoBo wrote: split input in (to be specified) chunks allowing to pass Googles' 5K-char per session limit.

Code: Select all

text =
(
@teadrinker - I've used your script a minute ago (and now it looks that I've got blocked :shh:) so, time to ask ...
Has your updated script taken the before mentioned condition already into account? I thought about to translate the transcription of YouTube videos so people from abroad will have a chance to better follow its (German) speaker. Higher translation quality would shrink the time of necessarry corrections.
)
arr := SplitText(text, 200)
for k, v in arr
   MsgBox, % v

SplitText(text, max := 5000) {
   chunks := [], text .= ".", pos := 1
   Loop {
      for k, v in ["\.", "!", "\?", ";", ",", ":", "\(", "\)", " ", "$"]
         RegExMatch(SubStr(text, pos, max), "sO).+" . v . "+", m)
      until m.Len
      chunks.Push(m[0])
      pos += m.Len
   } until pos > StrLen(text)
   last := chunks.Pop()
   chunks.Push( SubStr(last, 1, -1) )
   Return chunks
}

Re: Using Google Translate to automate text translation

Posted: 18 Oct 2022, 04:44
by Rikk03
Never mind I figured it out

Code: Select all

vid .= Ltrim(v) "`n`n"

Re: Using Google Translate to automate text translation

Posted: 17 Feb 2023, 14:14
by mryoussef79
Is there an update for it with Autohotkey V2

Re: Using Google Translate to automate text translation

Posted: 17 Feb 2023, 16:02
by MrDoge
@mryoussef79 not a direct translation but it's v2 : viewtopic.php?p=505855 [v2] GoogleTranslate /_/TranslateWebserverUi

Re: Using Google Translate to automate text translation

Posted: 17 Feb 2023, 17:37
by teadrinker
I added code for AHK v2, please report any bugs you find.
MrDoge wrote: viewtopic.php?f=6&t=63835 incorrectly detects 門 as Chinese Simplified
Looks like the last versoin correctly works with 門.

Re: Using Google Translate to automate text translation

Posted: 17 Feb 2023, 18:26
by MrDoge
teadrinker wrote:
17 Feb 2023, 17:37
I added code for AHK v2, please report any bugs you find.
MrDoge wrote: viewtopic.php?f=6&t=63835 incorrectly detects 門 as Chinese Simplified
Looks like the last versoin correctly works with 門.
it's not a "bug", it has to do with google's api route

[[["Door","門",null,null,10],[null,null,null,"Mén"]],[["noun",["door","field of endeavor","gate","gateway","ostium","phylum","subkingdom"],[["door",["大門","戶","門"]],["field of endeavor",["門"]],["gate",["出入口","大門","登機口","門","門口","閘板"]],["gateway",["出入口","門"]],["ostium",["門"]],["phylum",["門"]],["subkingdom",["門"]]],"門",1]],"zh-CN",null,null,[["門",null,[["Door",1000,true,false,[10,8]],["Gate",1000,true,false,[10]],["the door",0,true,false,[3],null,[[3]]]],[[0,1]],"門",0,0]],0.8984375,[],[["zh-CN"],null,[0.8984375],["zh-TW"]]]

(get fromLanguage)

Code: Select all

#SingleInstance force
ListLines 0
KeyHistory 0
SendMode "Input" ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir A_ScriptDir ; Ensures a consistent starting directory.

json:="
(
[[["Door","門",null,null,10],[null,null,null,"Mén"]],[["noun",["door","field of endeavor","gate","gateway","ostium","phylum","subkingdom"],[["door",["大門","戶","門"]],["field of endeavor",["門"]],["gate",["出入口","大門","登機口","門","門口","閘板"]],["gateway",["出入口","門"]],["ostium",["門"]],["phylum",["門"]],["subkingdom",["門"]]],"門",1]],"zh-CN",null,null,[["門",null,[["Door",1000,true,false,[10,8]],["Gate",1000,true,false,[10]],["the door",0,true,false,[3],null,[[3]]]],[[0,1]],"門",0,0]],0.8984375,[],[["zh-CN"],null,[0.8984375],["zh-TW"]]]
)"

JS := ObjBindMethod(GetJS(), 'eval')
JsonObj := JS('(' . json . ')')

; the way to get the `fromLanguage` from that json is to take the 3rd element in the array
; if you know any other way (because zh-TW IS indeed found in the json, but it's inconsistent/ambiguous), please help
MsgBox fromLanguage:=JsonObj.%2% ;zh-CH stands for Chinese Simplified, it should be zh-TW

return

GetJS() {
    static document := '', JS
    if !document {
        document := ComObject('HTMLFILE')
        document.write('<meta http-equiv="X-UA-Compatible" content="IE=9">')
        JS := document.parentWindow
        (document.documentMode < 9 && JS.execScript())
    }
    return JS
}

f3::Exitapp
(get response json)

Code: Select all

MsgBox A_Clipboard:=GoogleTranslateGetJSON('門', from := 'auto')

GoogleTranslateGetJSON(str, from := 'auto', to := 'en', &variants := '') {
    static JS := ObjBindMethod(GetJS(), 'eval'), _ := JS(GetJScript())

    json := SendRequest(str, Type(from) = 'VarRef' ? %from% : from, to)
    return json

    SendRequest(str, sl, tl) {
        static WR := ''
             , headers := Map('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8',
                              'User-Agent'  , 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0')
        if !WR {
            WR := WebRequest()
            WR.Fetch('https://translate.google.com',, headers)
        }
        url := 'https://translate.googleapis.com/translate_a/single?client=gtx'
             . '&sl=' . sl . '&tl=' . tl . '&hl=' . tl
             . '&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&ie=UTF-8&oe=UTF-8&otf=0&ssel=0&tsel=0&pc=1&kc=1'
             . '&tk=' . JS('tk')(str)
        return WR.Fetch(url, 'POST', headers, 'q=' . JS('encodeURIComponent')(str))
    }

    GetJScript()
    {
        return '
        (
            var TKK = ((function() {
                var a = 561666268;
                var b = 1526272306;
                return 406398 + '.' + (a + b);
            })());

            function b(a, b) {
                for (var d = 0; d < b.length - 2; d += 3) {
                    var c = b.charAt(d + 2),
                        c = 'a' <= c ? c.charCodeAt(0) - 87 : Number(c),
                        c = '+' == b.charAt(d + 1) ? a >>> c : a << c;
                    a = '+' == b.charAt(d) ? a + c & 4294967295 : a ^ c
                }
                return a
            }

            function tk(a) {
                for (var e = TKK.split('.'), h = Number(e[0]) || 0, g = [], d = 0, f = 0; f < a.length; f++) {
                    var c = a.charCodeAt(f);
                    128 > c ? g[d++] = c : (2048 > c ? g[d++] = c >> 6 | 192 : (55296 == (c & 64512) && f + 1 < a.length && 56320 == (a.charCodeAt(f + 1) & 64512) ?
                    (c = 65536 + ((c & 1023) << 10) + (a.charCodeAt(++f) & 1023), g[d++] = c >> 18 | 240,
                    g[d++] = c >> 12 & 63 | 128) : g[d++] = c >> 12 | 224, g[d++] = c >> 6 & 63 | 128), g[d++] = c & 63 | 128)
                }
                a = h;
                for (d = 0; d < g.length; d++) a += g[d], a = b(a, '+-a^+6');
                a = b(a, '+-3^+b+-f');
                a ^= Number(e[1]) || 0;
                0 > a && (a = (a & 2147483647) + 2147483648);
                a `%= 1E6;
                return a.toString() + '.' + (a ^ h)
            }
        )'
    }

    GetJS() {
        static document := '', JS
        if !document {
            document := ComObject('HTMLFILE')
            document.write('<meta http-equiv="X-UA-Compatible" content="IE=9">')
            JS := document.parentWindow
            (document.documentMode < 9 && JS.execScript())
        }
        return JS
    }
}


class WebRequest
{
    __New() {
        this.whr := ComObject('WinHttp.WinHttpRequest.5.1')
    }

    __Delete() {
        this.whr := ''
    }

    Fetch(url, method := 'GET', HeadersArray := '', body := '', getRawData := false) {
        this.whr.Open(method, url, true)
        for name, value in HeadersArray
            this.whr.SetRequestHeader(name, value)
        this.error := ''
        this.whr.Send(body)
        this.whr.WaitForResponse()
        status := this.whr.status
        if (status != 200)
            this.error := 'HttpRequest error, status: ' . status . ' — ' . this.whr.StatusText
        Arr := this.whr.responseBody
        pData := NumGet(ComObjValue(arr) + 8 + A_PtrSize, 'Ptr')
        length := Arr.MaxIndex() + 1
        if !getRawData
            res := StrGet(pData, length, 'UTF-8')
        else {
            outData := Buffer(length, 0)
            DllCall('RtlMoveMemory', 'Ptr', outData, 'Ptr', pData, 'Ptr', length)
            res := outData
        }
        return res
    }
}

f3::ExitApp

Re: Using Google Translate to automate text translation

Posted: 17 Feb 2023, 18:33
by MrDoge
compare it with the json here, (also 3rd element in the array), here it's : "zh-TW"

[["Mén",null,"zh-TW",[[[0,[[[null,1]],[true]]]],1],[["門",null,null,1]],null,["門","auto","en"]],[[[null,null,null,null,null,[["Door",null,null,null,[["Door",[4,5],[]],["Gate",[4],[]],["Doors",[11],[]]]]]]],"en",1,"zh-TW",["門","auto","en"]],"zh-TW",["門",null,null,null,null,[[["noun",[["door",null,["大門","戶","門"],3,true],["field of endeavor",null,["門"],3,true],["gate",null,["出入口","大門","登機口","門","門口","閘板"],3,true],["gateway",null,["出入口","門"],3,true],["ostium",null,["門"],3,true],["phylum",null,["門"],3,true],["subkingdom",null,["門"],3,true]],"en","zh-TW"]],7],"Mén",null,"zh-TW",1]]

Code: Select all

MsgBox A_Clipboard:=GoogleTranslate("門")

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))
    return jsonTemp[1][3]
}

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

Re: Using Google Translate to automate text translation

Posted: 17 Feb 2023, 18:56
by teadrinker
@MrDoge
Try this one:

Code: Select all

#Requires AutoHotkey v2

text := GoogleTranslate('門', &from := 'auto')
MsgBox 'from: ' . from . '`ntranslate: ' . text, 'from auto to English'

GoogleTranslate(str, from := 'auto', to := 'en', &variants := '') {
    static JS := ObjBindMethod(GetJS(), 'eval'), _ := JS(GetJScript())
    
    json := SendRequest(str, Type(from) = 'VarRef' ? %from% : from, to)
    JsonObj := JS('(' . json . ')')
    variants := ''
    if !IsObject(JsonObj.1) {
        Loop JsonObj.0.length {
            variants .= JsonObj.0.%A_Index - 1%.0
        }
    } else {
        mainTrans := JsonObj.0.0.0
        Loop JsonObj.1.length {
            variants .= '`n+'
            obj := JsonObj.1.%A_Index - 1%.1
            Loop obj.length {
                txt := obj.%A_Index - 1%
                variants .= (mainTrans = txt ? '' : '`n' . txt)
            }
        }
    }
    if !IsObject(JsonObj.1)
        mainTrans := variants := Trim(variants, ',+`n ')
    else
        variants := mainTrans . '`n+`n' . Trim(variants, ',+`n ')

    (Type(from) = 'VarRef' && %from% := JsonObj.8.3.0)
    return mainTrans

    SendRequest(str, sl, tl) {
        static WR := ''
             , headers := Map('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8',
                              'User-Agent'  , 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0')
        if !WR {
            WR := WebRequest()
            WR.Fetch('https://translate.google.com',, headers)
        }
        url := 'https://translate.googleapis.com/translate_a/single?client=gtx'
             . '&sl=' . sl . '&tl=' . tl . '&hl=' . tl
             . '&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&ie=UTF-8&oe=UTF-8&otf=0&ssel=0&tsel=0&pc=1&kc=1'
             . '&tk=' . JS('tk')(str)
        return WR.Fetch(url, 'POST', headers, 'q=' . JS('encodeURIComponent')(str))
    }

    GetJScript()
    {
        return '
        (
            var TKK = ((function() {
                var a = 561666268;
                var b = 1526272306;
                return 406398 + '.' + (a + b);
            })());

            function b(a, b) {
                for (var d = 0; d < b.length - 2; d += 3) {
                    var c = b.charAt(d + 2),
                        c = 'a' <= c ? c.charCodeAt(0) - 87 : Number(c),
                        c = '+' == b.charAt(d + 1) ? a >>> c : a << c;
                    a = '+' == b.charAt(d) ? a + c & 4294967295 : a ^ c
                }
                return a
            }

            function tk(a) {
                for (var e = TKK.split('.'), h = Number(e[0]) || 0, g = [], d = 0, f = 0; f < a.length; f++) {
                    var c = a.charCodeAt(f);
                    128 > c ? g[d++] = c : (2048 > c ? g[d++] = c >> 6 | 192 : (55296 == (c & 64512) && f + 1 < a.length && 56320 == (a.charCodeAt(f + 1) & 64512) ?
                    (c = 65536 + ((c & 1023) << 10) + (a.charCodeAt(++f) & 1023), g[d++] = c >> 18 | 240,
                    g[d++] = c >> 12 & 63 | 128) : g[d++] = c >> 12 | 224, g[d++] = c >> 6 & 63 | 128), g[d++] = c & 63 | 128)
                }
                a = h;
                for (d = 0; d < g.length; d++) a += g[d], a = b(a, '+-a^+6');
                a = b(a, '+-3^+b+-f');
                a ^= Number(e[1]) || 0;
                0 > a && (a = (a & 2147483647) + 2147483648);
                a `%= 1E6;
                return a.toString() + '.' + (a ^ h)
            }
        )'
    }

    GetJS() {
        static document := '', JS
        if !document {
            document := ComObject('HTMLFILE')
            document.write('<meta http-equiv="X-UA-Compatible" content="IE=9">')
            JS := document.parentWindow
            (document.documentMode < 9 && JS.execScript())
        }
        return JS
    }
}


class WebRequest
{
    __New() {
        this.whr := ComObject('WinHttp.WinHttpRequest.5.1')
    }

    __Delete() {
        this.whr := ''
    }

    Fetch(url, method := 'GET', HeadersArray := '', body := '', getRawData := false) {
        this.whr.Open(method, url, true)
        for name, value in HeadersArray
            this.whr.SetRequestHeader(name, value)
        this.error := ''
        this.whr.Send(body)
        this.whr.WaitForResponse()
        status := this.whr.status
        if (status != 200)
            this.error := 'HttpRequest error, status: ' . status . ' — ' . this.whr.StatusText
        Arr := this.whr.responseBody
        pData := NumGet(ComObjValue(arr) + 8 + A_PtrSize, 'Ptr')
        length := Arr.MaxIndex() + 1
        if !getRawData
            res := StrGet(pData, length, 'UTF-8')
        else {
            outData := Buffer(length, 0)
            DllCall('RtlMoveMemory', 'Ptr', outData, 'Ptr', pData, 'Ptr', length)
            res := outData
        }
        return res
    }
}
Do you think, it is more correct?

Re: Using Google Translate to automate text translation

Posted: 17 Feb 2023, 19:08
by MrDoge
@teadrinker
%from% := JsonObj.8.3.0
the json "path" [8][3][0] works perfectly for 門, I'm getting "zh-TW" (that's good), but it works for 門 only, it fails for
text := GoogleTranslate('día', &from := 'auto')
in which I get "pt"

EDIT: I was too fast to reply, "pt" stands for Portuguese (and not some random thing like Point or px), which is correct

EDIT 2: as perfect as it gets, unless I think of something else and come back to edit

Re: Using Google Translate to automate text translation

Posted: 17 Feb 2023, 19:21
by teadrinker
Thanks for testing, I'll change the code, until someone reports about another issue.