Google Translator as Tooltip - Script not working any more

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
fid75
Posts: 8
Joined: 15 Apr 2015, 07:56

Google Translator as Tooltip - Script not working any more

16 Apr 2015, 09:32

Hello friends,

For a longer time period I have used the script "google translation as tooltip" - from the old script forums:

http://www.autohotkey.com/board/topic/4 ... ill-works/

Code: Select all

;--------------------------------------------------
; Translate text using translate.google.com 
; after Google Translate API deprecation
;
; Ctrl+C, Ctrl+C
; Author: Mikhail Kuropyatnikov ([email protected]), 
;       Volgograd, Russia
;--------------------------------------------------
#NoEnv

~^C:: DoublePress()

DoublePress()
{
   static pressed1 = 0
   if pressed1 and A_TimeSincePriorHotkey <= 200
   {
      pressed1 = 0
	  ; Translate from any language to Russian and from Russian to English if source was in Russian
      Translate("ru","en") 
   }
   else
      pressed1 = 1
   
}

; translate to "to" language,
; if source language is "to" 
; translate to "anti" language

Translate(To,Anti)
{
   UseAnti = 0
   TranslateTo := To
   if Clipboard = 
       return

   UriCli := UriEncode(Clipboard)

anti_translate:
   Url := "http://translate.google.com/translate_a/t?client=x&text="
            . UriCli . "&tl=" . TranslateTo

   ; Simulate Google Chrome
   JsonTrans := UrlDownloadToVar(Url,"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/18.6.872.0 Safari/535.2")

   ; thanks to Grey (http://forum.script-coding.com/profile.php?id=25792)
   StringReplace, JsonTrans, JsonTrans, \r\n,`r`n, All
   StringReplace, JsonTrans, JsonTrans, \", ", All
   FromLang:=JSON(JsonTrans, "src")
   ElapsedTime:=JSON(JsonTrans, "server_time")

   if (FromLang == To and TranslateTo <> Anti)
   {
      TranslateTo := Anti
      ;MsgBox % FromLang . " " . To . " " TranslateTo . " " . Anti
      goto anti_translate
   }

   Loop
   {
     Sentence:=JSON(JsonTrans, "sentences["(A_Index-1)"].trans")
     If Sentence
       TransText.=Sentence
     Else
       Break
   }
   
   ; Convert To UTF-8
   BaseFileEnc := A_FileEncoding
   FileEncoding
   FileDelete, %A_ScriptDir%\Convert.html 
   FileAppend, %TransText%, %A_ScriptDir%\Convert.html 
   FileEncoding, UTF-8
   FileRead TransText, %A_ScriptDir%\Convert.html 
   FileEncoding, %BaseFileEnc%
   
   ; split long line to smaller lines about 40-50 symbols length
   t := RegExReplace(transText,".{40,50}(\s)","$0`n")
   
   ToolTip %FromLang%: %t%
   ; copy result to clipboard
   clipboard := t
   
}



~LButton::
ToolTip
return



UrlDownloadToVar(URL, UserAgent = "", Proxy = "", ProxyBypass = "") {
    ; Requires Windows Vista, Windows XP, Windows 2000 Professional, Windows NT Workstation 4.0,
    ; Windows Me, Windows 98, or Windows 95.
    ; Requires Internet Explorer 3.0 or later.
    pFix:=a_isunicode ? "W" : "A"
    hModule := DllCall("LoadLibrary", "Str", "wininet.dll")

    AccessType := Proxy != "" ? 3 : 1
    ;INTERNET_OPEN_TYPE_PRECONFIG                    0   // use registry configuration
    ;INTERNET_OPEN_TYPE_DIRECT                       1   // direct to net
    ;INTERNET_OPEN_TYPE_PROXY                        3   // via named proxy
    ;INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY  4   // prevent using java/script/INS

    io := DllCall("wininet\InternetOpen" . pFix
    , "Str", UserAgent ;lpszAgent
    , "UInt", AccessType
    , "Str", Proxy
    , "Str", ProxyBypass
    , "UInt", 0) ;dwFlags

    iou := DllCall("wininet\InternetOpenUrl" . pFix
    , "UInt", io
    , "Str", url
    , "Str", "" ;lpszHeaders
    , "UInt", 0 ;dwHeadersLength
    , "UInt", 0x80000000 ;dwFlags: INTERNET_FLAG_RELOAD = 0x80000000 // retrieve the original item
    , "UInt", 0) ;dwContext

    If (ErrorLevel != 0 or iou = 0) {
        DllCall("FreeLibrary", "UInt", hModule)
        return 0
    }

    VarSetCapacity(buffer, 10240, 0)
    VarSetCapacity(BytesRead, 4, 0)

    Loop
    {
        ;http://msdn.microsoft.com/library/en-us/wininet/wininet/internetreadfile.asp
        irf := DllCall("wininet\InternetReadFile", "UInt", iou, "UInt", &buffer, "UInt", 10240, "UInt", &BytesRead)
        VarSetCapacity(buffer, -1) ;to update the variable's internally-stored length

        BytesRead_ = 0 ; reset
        Loop, 4  ; Build the integer by adding up its bytes. (From ExtractInteger-function)
            BytesRead_ += *(&BytesRead + A_Index-1) << 8*(A_Index-1) ;Bytes read in this very DllCall

        ; To ensure all data is retrieved, an application must continue to call the
        ; InternetReadFile function until the function returns TRUE and the lpdwNumberOfBytesRead parameter equals zero.
        If (irf = 1 and BytesRead_ = 0)
            break
        Else ; append the buffer's contents
        {
            a_isunicode ? buffer:=StrGet(&buffer, "CP0")
            Result .= SubStr(buffer, 1, BytesRead_ * (a_isunicode ? 2 : 1))
        }

        /* optional: retrieve only a part of the file
        BytesReadTotal += BytesRead_
        If (BytesReadTotal >= 30000) ; only read the first x bytes
        break                      ; (will be a multiple of the buffer size, if the file is not smaller; trim if neccessary)
        */
    }

    DllCall("wininet\InternetCloseHandle",  "UInt", iou)
    DllCall("wininet\InternetCloseHandle",  "UInt", io)
    DllCall("FreeLibrary", "UInt", hModule)
   Return Result
}

JSON(ByRef js, s, v = "") {
   j = %js%
   Loop, Parse, s, .
   {
      p = 2
      RegExMatch(A_LoopField, "([+\-]?)([^[]+)((?:\[\d+\])*)", q)
      Loop {
         If (!p := RegExMatch(j, "(?<!\\)(""|')([^\1]+?)(?<!\\)(?-1)\s*:\s*((\{(?:[^{}]++|(?-1))*\})|(\[(?:[^[\]]++|(?-1))*\])|"
            . "(?<!\\)(""|')[^\7]*?(?<!\\)(?-1)|[+\-]?\d+(?:\.\d*)?|true|false|null?)\s*(?:,|$|\})", x, p))
            Return
         Else If (x2 == q2 or q2 == "*") {
            j = %x3%
            z += p + StrLen(x2) - 2
            If (q3 != "" and InStr(j, "[") == 1) {
               StringTrimRight, q3, q3, 1
               Loop, Parse, q3, ], [
               {
                  z += 1 + RegExMatch(SubStr(j, 2, -1), "^(?:\s*((\[(?:[^[\]]++|(?-1))*\])|(\{(?:[^{\}]++|(?-1))*\})|[^,]*?)\s*(?:,|$)){" . SubStr(A_LoopField, 1) + 1 . "}", x)
                  j = %x1%
               }
            }
            Break
         }
         Else p += StrLen(x)
      }
   }
   If v !=
   {
      vs = "
      If (RegExMatch(v, "^\s*(?:""|')*\s*([+\-]?\d+(?:\.\d*)?|true|false|null?)\s*(?:""|')*\s*$", vx)
         and (vx1 + 0 or vx1 == 0 or vx1 == "true" or vx1 == "false" or vx1 == "null" or vx1 == "nul"))
         vs := "", v := vx1
      StringReplace, v, v, ", \", All
      js := SubStr(js, 1, z := RegExMatch(js, ":\s*", zx, z) + StrLen(zx) - 1) . vs . v . vs . SubStr(js, z + StrLen(x3) + 1)
   }
   Return, j == "false" ? 0 : j == "true" ? 1 : j == "null" or j == "nul"
      ? "" : SubStr(j, 1, 1) == """" ? SubStr(j, 2, -1) : j
}

;-------------------------------------------------
; HTML encode/decode
;------------------------------------------------

StrPutVar(string, ByRef var, encoding)
{
    ; Ensure capacity.
    SizeInBytes := VarSetCapacity( var, StrPut(string, encoding)
        ; StrPut returns char count, but VarSetCapacity needs bytes.
        * ((encoding="utf-16"||encoding="cp1200") ? 2 : 1) )
    ; Copy or convert the string.
    StrPut(string, &var, encoding)
   Return SizeInBytes 
}

UriEncode(str) 
{ 
   b_Format := A_FormatInteger 
   data := "" 
   SetFormat,Integer,H 
   SizeInBytes := StrPutVar(str,var,"utf-8")
   Loop, %SizeInBytes%
   {
   ch := NumGet(var,A_Index-1,"UChar")
   If (ch=0)
      Break
   if ((ch>0x7f) || (ch<0x30) || (ch=0x3d))
      s .= "%" . ((StrLen(c:=SubStr(ch,3))<2) ? "0" . c : c)
   Else
      s .= Chr(ch)
   }   
   SetFormat,Integer,%b_format% 
   return s 
} 
It seems the script stopped working and I am wondering why.
Does anyone here know of a solution or can help to fix this?
Or perhaps it could be possible to use Microsoft Bing instead, if the issue is showing as a result of some Google changes?

Thank you in advance for your help or any workaround in this case.

Regards,
fid
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: Google Translator as Tooltip - Script not working any mo

16 Apr 2015, 11:14

Try this:

Code: Select all

~^C::
	If isDoublePress() {
		ToolTip, Translating...
		ToolTip, % gTranslate(Clipboard, "ru")
		KeyWait, LButton, Down
		ToolTip
	}
Return

gTranslate(string, tl = "", sl = "") {
	static whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
	url := "https://translate.google.com/translate_a/single?client=t&sl=" sl "&tl=" tl
	     . "&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&dt=at&ie=UTF-8&oe=UTF-8&otf=2&srcrom=0&ssel=0&tsel=3&q=" string
	whr.Open("GET", url, true)
	whr.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko)")
	whr.Send()
	whr.WaitForResponse()
	Return RegExReplace(whr.ResponseText, "^.*?""(.*?)"".*$", "$1")
}

isDoublePress(ms = 300) {
	Return (A_ThisHotKey = A_PriorHotKey) && (A_TimeSincePriorHotkey <= ms)
}
fid75
Posts: 8
Joined: 15 Apr 2015, 07:56

Re: Google Translator as Tooltip - Script not working any mo

16 Apr 2015, 16:37

Thanks tmplinshi,
this seems to work.

Just 2 things I am missing now from original code:

1) copy result to clipboard
2) Translate from any language to Russian and from Russian to English if source was in Russian

What I tried, was to merge your code snippet to the original one, but failed to do so, perhaps missing some sleep after many hours of work. :(
I like the simplicity of your code and perhaps you (or anyone) can help out with the 2 missing parts above too?

Thanks for your time and efforts.
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: Google Translator as Tooltip - Script not working any mo

17 Apr 2015, 05:21

Code: Select all

~^C::
	If isDoublePress() {
		ToolTip, Translating...
		ToolTip, % Clipboard := gTranslate(Clipboard, "ru", "en")
		KeyWait, LButton, Down
		ToolTip
	}
Return

gTranslate(str, tl = "", switchLang = "") {
	static whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")

	url := "https://translate.google.com/translate_a/single?client=t&sl=&tl=" tl
	     . "&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&dt=at&ie=UTF-8&oe=UTF-8&otf=2&srcrom=0&ssel=0&tsel=3&q=" str
	whr.Open("GET", url, true)
	whr.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko)")
	whr.Send()
	whr.WaitForResponse()

	If RegExMatch(whr.ResponseText, ",[\d.]+,,\[\[""\K[\w-]+", sl) && (sl = tl && switchLang)
		Return A_ThisFunc.(str, switchLang)

	Return RegExReplace(whr.ResponseText, "^.*?""(.*?)"".*$", "$1")
}

isDoublePress(ms = 300) {
	Return (A_ThisHotKey = A_PriorHotKey) && (A_TimeSincePriorHotkey <= ms)
}
I found that it won't works correctly on multiple lines or sentences. Needs some UriEncode/Loop/Json parse to fix it..

Edit: Removed 'sl' parameter in the url.
Last edited by tmplinshi on 17 Apr 2015, 06:14, edited 1 time in total.
toralf
Posts: 868
Joined: 27 Apr 2014, 21:08
Location: Germany

Re: Google Translator as Tooltip - Script not working any mo

17 Apr 2015, 05:49

In the code above is sl and switchlang. I assume they should be identical.
ciao
toralf
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: Google Translator as Tooltip - Script not working any mo

17 Apr 2015, 06:11

toralf wrote:In the code above is sl and switchlang. I assume they should be identical.
Thanks. I forgot to remove the sl parameter in the url.

I'm not sure what you mean, but 'sl' here is short for 'Source Language'. And 'switchlang' is used as the second 'to language', when source language is same as 'to language'.
toralf
Posts: 868
Joined: 27 Apr 2014, 21:08
Location: Germany

Re: Google Translator as Tooltip - Script not working any mo

17 Apr 2015, 06:35

I didn't know the meaning of the abbreviations, that's why I wrote 'I assume'. You showed that I was wrong. Thanks for the code I will give this to coworkers that have trouble with German. :)
ciao
toralf
fid75
Posts: 8
Joined: 15 Apr 2015, 07:56

Re: Google Translator as Tooltip - Script not working any mo

17 Apr 2015, 06:42

The script is getting better and better, thank you guys, you are awesome!

With the multiple lines you are right, sometimes, but not always, it doesn't handle them correctly. Until now I can live with it, but feel free to modify.
One more thing to better visualize multiple translated text/lines results, would be some option like in origin code, I just don't know where to implement this in a clean way:

Code: Select all

   ; split long line to smaller lines about 40-50 symbols length
   t := RegExReplace(transText,".{40,50}(\s)","$0`n")
Some help would be nice. ;)

Thanks too, for clarifiying the abbreviation, I didn't know this either. This helps to better understand the code.
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: Google Translator as Tooltip - Script not working any mo

17 Apr 2015, 06:58

The should works with multiple lines and sentences:

Code: Select all

~^C::
	If isDoublePress() {
		ToolTip, Translating...
		ToolTip, % Clipboard := gTranslate(Clipboard, "ru", "en")
		KeyWait, LButton, Down
		ToolTip
	}
Return

gTranslate(str, tolang = "", switchLang = "") {
	static whr := ComObjCreate("WinHttp.WinHttpRequest.5.1"), _ := ComObjError(0)

	str := StrReplace(str, "`r", "%0D")
	str := StrReplace(str, "`n", "%0A")

	url := "https://translate.google.com/translate_a/single?client=t&sl=&tl=" tolang
		 . "&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&dt=at&ie=UTF-8"
		 . "&oe=UTF-8&otf=2&srcrom=0&ssel=0&tsel=3&q=" str
	whr.Open("GET", url, true)
	whr.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko)")

	Loop {
		whr.Send()
		If !retCode := whr.WaitForResponse(5) ; Wait up to 5 seconds
			Sleep, 1000
	} Until (retCode = -1) ; Success = -1, Timeout = 0, No response = Empty String

	If RegExMatch(whr.ResponseText, ",[\d.]+,,\[\[""\K[\w-]+", sl) && (sl = tolang && switchLang)
		Return A_ThisFunc.(str, switchLang)

	For i, arr in ParseJson(whr.ResponseText).1
		result .= StrReplace(arr.1, "\n", "`n")
	Return result
}

isDoublePress(ms = 300) {
	Return (A_ThisHotKey = A_PriorHotKey) && (A_TimeSincePriorHotkey <= ms)
}

/****************************************************************************************
	Function: ParseJson(jsonStr)
		Converts a JSON string into an AutoHotkey object

	Parameters:
		jsonstr - the JSON string to convert

	Remarks:
		Originally by Getfree,
		http://www.autohotkey.com/board/topic/93300-what-format-to-store-settings-in/#entry588268

	Returns:
		The AutoHotkey object.
*/
ParseJson(jsonStr)
{
	SC := ComObjCreate("ScriptControl") 
	SC.Language := "JScript"
	ComObjError(false)
	jsCode =
	(
	function arrangeForAhkTraversing(obj){
		if(obj instanceof Array){
			for(var i=0 ; i<obj.length ; ++i)
			    obj[i] = arrangeForAhkTraversing(obj[i]) ;
			return ['array',obj] ;
		}else if(obj instanceof Object){
			var keys = [], values = [] ;
			for(var key in obj){
				keys.push(key) ;
				values.push(arrangeForAhkTraversing(obj[key])) ;
			}
			return ['object',[keys,values]] ;
		}else
			return [typeof obj,obj] ;
	}
	)
	SC.ExecuteStatement(jsCode "; obj=" jsonStr)
	return convertJScriptObjToAhks( SC.Eval("arrangeForAhkTraversing(obj)") )
}

/*!
	Function: convertJScriptObjToAhks(jsObj)
		Used by ParseJson()
*/
convertJScriptObjToAhks(jsObj)
{
	if(jsObj[0]="object"){
		obj := {}, keys := jsObj[1][0], values := jsObj[1][1]
		loop % keys.length
			obj[keys[A_INDEX-1]] := convertJScriptObjToAhks( values[A_INDEX-1] )
		return obj
	}else if(jsObj[0]="array"){
		array := []
		loop % jsObj[1].length
			array.insert(convertJScriptObjToAhks( jsObj[1][A_INDEX-1] ))
		return array
	}else
		return jsObj[1]
}
Edit: Fixed 'Missing close-quote'.
Last edited by tmplinshi on 17 Apr 2015, 09:11, edited 3 times in total.
fid75
Posts: 8
Joined: 15 Apr 2015, 07:56

Re: Google Translator as Tooltip - Script not working any mo

17 Apr 2015, 08:30

Unfortunately last code gives me an error at line 16

Line Text: " str
Error: Missing close-quote.

The URL seems to be truncated to 3 lines now, instead of 2 as before?
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: Google Translator as Tooltip - Script not working any mo

17 Apr 2015, 09:07

fid75 wrote:Unfortunately last code gives me an error at line 16

Line Text: " str
Error: Missing close-quote.

The URL seems to be truncated to 3 lines now, instead of 2 as before?
fixed! 2 lines still looks too long, so I split to 3 lines :)
fid75
Posts: 8
Joined: 15 Apr 2015, 07:56

Re: Google Translator as Tooltip - Script not working any mo

17 Apr 2015, 10:50

uhh, wanted to try now the new code, but new error pops up:

Call to nonexistent function.
Specifically: StrReplace(str, "....

Do I miss some external libraries here?

Edit: Or should I upgrade my Autohotkey? Didn't do it for some time now...
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: Google Translator as Tooltip - Script not working any mo

17 Apr 2015, 11:09

Yes, StrReplace is quite new. Requires version v1.1.21+. Or you can use StringReplace instead.
list
Posts: 222
Joined: 26 Mar 2014, 14:03
Contact:

Re: Google Translator as Tooltip - Script not working any mo

19 Apr 2015, 07:11

When I tried it it didn't work at first, but then I remembered Microsoft's ScriptControl is not available to 64-bit programs and you need ActiveScript by lexikos - so for 64-bit users you can try this version (you need to download ActiveScript.ahk) - took only three or so minor changes to tmplinshi's script so :thumbup: for tmplinshi ;)

Code: Select all

; for 64bit you need ActiveScript - Host VBScript and JScript in-process
; Forum : http://ahkscript.org/boards/viewtopic.php?f=6&t=4555
; Source: https://github.com/Lexikos/ActiveScript.ahk
#Include ActiveScript.ahk

; Google Translator as Tooltip
; update by tmplinshi
; http://ahkscript.org/boards/viewtopic.php?p=43151#p43151

~^c::
    If isDoublePress() {
        ToolTip, Translating...
        ToolTip, % Clipboard := gTranslate(Clipboard)
        KeyWait, LButton, Down
        ToolTip
    }
Return

; 'sl' here is short for 'Source Language'. 
; 'switchlang' is used as the second 'to language',
; when source language is same as 'to language'.
gTranslate(str, tolang = "", switchLang = "") {
    static whr := ComObjCreate("WinHttp.WinHttpRequest.5.1"), _ := ComObjError(0)

    str := StrReplace(str, "`r", "%0D")
    str := StrReplace(str, "`n", "%0A")

    url := "https://translate.google.com/translate_a/single?client=t&sl=&tl=" tolang
         . "&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&dt=at&ie=UTF-8"
         . "&oe=UTF-8&otf=2&srcrom=0&ssel=0&tsel=3&q=" str
    whr.Open("GET", url, true)
    whr.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko)")

    Loop {
        whr.Send()
        If !retCode := whr.WaitForResponse(5) ; Wait up to 5 seconds
            Sleep, 1000
    } Until (retCode = -1) ; Success = -1, Timeout = 0, No response = Empty String

    If RegExMatch(whr.ResponseText, ",[\d.]+,,\[\[""\K[\w-]+", sl) && (sl = tolang && switchLang)
        Return A_ThisFunc.(str, switchLang)

    For i, arr in ParseJson(whr.ResponseText).1
        result .= StrReplace(arr.1, "\n", "`n")
    Return result
}

isDoublePress(ms = 300) {
    Return (A_ThisHotKey = A_PriorHotKey) && (A_TimeSincePriorHotkey <= ms)
}

/****************************************************************************************
    Function: ParseJson(jsonStr)
        Converts a JSON string into an AutoHotkey object

    Parameters:
        jsonstr - the JSON string to convert

    Remarks:
        Originally by Getfree,
        http://www.autohotkey.com/board/topic/93300-what-format-to-store-settings-in/#entry588268

    Returns:
        The AutoHotkey object.
*/
ParseJson(jsonStr)
{
	sc := new ActiveScript("JScript")

    ComObjError(false)
    jsCode =
    (
    function arrangeForAhkTraversing(obj){
        if(obj instanceof Array){
            for(var i=0 ; i<obj.length ; ++i)
                obj[i] = arrangeForAhkTraversing(obj[i]) ;
            return ['array',obj] ;
        }else if(obj instanceof Object){
            var keys = [], values = [] ;
            for(var key in obj){
                keys.push(key) ;
                values.push(arrangeForAhkTraversing(obj[key])) ;
            }
            return ['object',[keys,values]] ;
        }else
            return [typeof obj,obj] ;
    }
    )
    SC.Exec(jsCode "; obj=" jsonStr)
    return convertJScriptObjToAhks( SC.Eval("arrangeForAhkTraversing(obj)") )
}

/*!
    Function: convertJScriptObjToAhks(jsObj)
        Used by ParseJson()
*/
convertJScriptObjToAhks(jsObj)
{
    if(jsObj[0]="object"){
        obj := {}, keys := jsObj[1][0], values := jsObj[1][1]
        loop % keys.length
            obj[keys[A_INDEX-1]] := convertJScriptObjToAhks( values[A_INDEX-1] )
        return obj
    }else if(jsObj[0]="array"){
        array := []
        loop % jsObj[1].length
            array.insert(convertJScriptObjToAhks( jsObj[1][A_INDEX-1] ))
        return array
    }else
        return jsObj[1]
}
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: Google Translator as Tooltip - Script not working any mo

19 Apr 2015, 07:48

Thanks list! I also worried about 64-bit problems when I choose the ParseJson() function, but it works on my win7 x64 OS, then I know it just won't work for 64-bit exe, not 64-bit OS :D. I forgot the ActiveScript.ahk, thanks for mentioned it.
fid75
Posts: 8
Joined: 15 Apr 2015, 07:56

Re: Google Translator as Tooltip - Script not working any mo

20 Apr 2015, 04:27

Thanks list and tmplinshi for your help!

The only thing that sould be added in latest provided code from list, are the chosen languages.
Here the complete code, which is working for me now.

Prerequisites:
- use at least Autohotkey Version v1.1.21+
- include ActiveScript.ahk if using 64bit exe file (source link can be found in code)

Code: Select all

; for 64bit you need ActiveScript - Host VBScript and JScript in-process
; Forum : http://ahkscript.org/boards/viewtopic.php?f=6&t=4555
; Source: https://github.com/Lexikos/ActiveScript.ahk
#Include %A_ScriptDir%\Scripts\ActiveScript.ahk ;choose your folder which contains the .ahk file

; Google Translator as Tooltip
; update by tmplinshi
; edited by list
; http://ahkscript.org/boards/viewtopic.php?p=43151#p43151

~^c::
    If isDoublePress() {
        ToolTip, Translating...
        ToolTip, % Clipboard := gTranslate(Clipboard, "de", "en") ;edit here your "source-" and "translate to-" language abbreviations
        KeyWait, LButton, Down
        ToolTip
    }
Return

; 'sl' here is short for 'Source Language'. 
; 'switchlang' is used as the second 'to language',
; when source language is same as 'to language'.
gTranslate(str, tolang = "", switchLang = "") {
    static whr := ComObjCreate("WinHttp.WinHttpRequest.5.1"), _ := ComObjError(0)

    str := StrReplace(str, "`r", "%0D")
    str := StrReplace(str, "`n", "%0A")

    url := "https://translate.google.com/translate_a/single?client=t&sl=&tl=" tolang
         . "&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&dt=at&ie=UTF-8"
         . "&oe=UTF-8&otf=2&srcrom=0&ssel=0&tsel=3&q=" str
    whr.Open("GET", url, true)
    whr.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko)")

    Loop {
        whr.Send()
        If !retCode := whr.WaitForResponse(5) ; Wait up to 5 seconds
            Sleep, 1000
    } Until (retCode = -1) ; Success = -1, Timeout = 0, No response = Empty String

    If RegExMatch(whr.ResponseText, ",[\d.]+,,\[\[""\K[\w-]+", sl) && (sl = tolang && switchLang)
        Return A_ThisFunc.(str, switchLang)

    For i, arr in ParseJson(whr.ResponseText).1
        result .= StrReplace(arr.1, "\n", "`n")
    Return result
}

isDoublePress(ms = 300) {
    Return (A_ThisHotKey = A_PriorHotKey) && (A_TimeSincePriorHotkey <= ms)
}

/****************************************************************************************
    Function: ParseJson(jsonStr)
        Converts a JSON string into an AutoHotkey object

    Parameters:
        jsonstr - the JSON string to convert

    Remarks:
        Originally by Getfree,
        http://www.autohotkey.com/board/topic/93300-what-format-to-store-settings-in/#entry588268

    Returns:
        The AutoHotkey object.
*/
ParseJson(jsonStr)
{
   sc := new ActiveScript("JScript")

    ComObjError(false)
    jsCode =
    (
    function arrangeForAhkTraversing(obj){
        if(obj instanceof Array){
            for(var i=0 ; i<obj.length ; ++i)
                obj[i] = arrangeForAhkTraversing(obj[i]) ;
            return ['array',obj] ;
        }else if(obj instanceof Object){
            var keys = [], values = [] ;
            for(var key in obj){
                keys.push(key) ;
                values.push(arrangeForAhkTraversing(obj[key])) ;
            }
            return ['object',[keys,values]] ;
        }else
            return [typeof obj,obj] ;
    }
    )
    SC.Exec(jsCode "; obj=" jsonStr)
    return convertJScriptObjToAhks( SC.Eval("arrangeForAhkTraversing(obj)") )
}

/*!
    Function: convertJScriptObjToAhks(jsObj)
        Used by ParseJson()
*/
convertJScriptObjToAhks(jsObj)
{
    if(jsObj[0]="object"){
        obj := {}, keys := jsObj[1][0], values := jsObj[1][1]
        loop % keys.length
            obj[keys[A_INDEX-1]] := convertJScriptObjToAhks( values[A_INDEX-1] )
        return obj
    }else if(jsObj[0]="array"){
        array := []
        loop % jsObj[1].length
            array.insert(convertJScriptObjToAhks( jsObj[1][A_INDEX-1] ))
        return array
    }else
        return jsObj[1]
}
User avatar
fump2000
Posts: 313
Joined: 04 Oct 2013, 17:31

Re: Google Translator as Tooltip - Script not working any more

07 Oct 2015, 09:22

It does not work anymore. An idea why?
translate

Re: Google Translator as Tooltip - Script not working any more

07 Oct 2015, 09:40

I have the same issue. It worked one minute stopped the next. When I check the contents of the whr.ResponseText variable which is returned it reads:
Our systems have detected unusual traffic from your computer network.
Please try your request again later.

Why did this happen?
This page appears when Google automatically detects requests coming from your computer network which appear to be in violation of the Terms of Service. The block will expire shortly after those requests stop.This traffic may have been sent by malicious software, a browser plug-in, or a script that sends automated requests. If you share your network connection, ask your administrator for help - a different computer using the same IP address may be responsible.

Learn more

Sometimes you may see this page if you are using advanced terms that robots are known to use, or sending requests very quickly.
so perhaps it will work again later today or tomorrow. I hope so.
geek
Posts: 1052
Joined: 02 Oct 2013, 22:13
Location: GeekDude
Contact:

Re: Google Translator as Tooltip - Script not working any more

07 Oct 2015, 09:42

This kind of script is very against Google's ToS. If you want to have script based translate through Google, you will need to pay for a developer license from them (which as I understand it is not cheap).

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: ArkuS, Chunjee, Frogrammer and 376 guests