Using Google Translate to automate text translation

Post your working scripts, libraries and tools for AHK v1.1 and older
BoBo
Posts: 6564
Joined: 13 May 2014, 17:15

Re: Using Google Translate to automate text translation

Post by BoBo » 11 Feb 2021, 09:50

That's very good news! Thx :thumbup: Erm, added a feature request to my previous posting (JFTR, was working on that before I got blocked) ... :)

teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Using Google Translate to automate text translation

Post by teadrinker » 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
}

BoBo
Posts: 6564
Joined: 13 May 2014, 17:15

Re: Using Google Translate to automate text translation

Post by BoBo » 11 Feb 2021, 11:46

:clap: :clap: :thumbup: Thx a lot (as always).

teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Using Google Translate to automate text translation

Post by teadrinker » 25 Mar 2021, 18:49

Due to changes in Google, the code in the first post has been updated (thanks @malcev).

sobuj53
Posts: 55
Joined: 19 Mar 2015, 16:08

Re: Using Google Translate to automate text translation

Post by sobuj53 » 11 Apr 2021, 10:12

very helpful

sobuj53
Posts: 55
Joined: 19 Mar 2015, 16:08

Re: Using Google Translate to automate text translation

Post by sobuj53 » 11 Apr 2021, 10:25

@garry I've one request. Please add a option to select source language, sometimes google can't detect what is the source language, eg fast in Deutsch = nearly, but if we select auto then google will fail at detecting the source language.

garry
Posts: 3740
Joined: 22 Dec 2013, 12:50

Re: Using Google Translate to automate text translation

Post by garry » 11 Apr 2021, 14:47

@sobuj53 modified at page-1 , example-4 to select source-language
https://www.autohotkey.com/boards/viewtopic.php?p=273678#p273678
( I should modify examples 1-3 also )

sobuj53
Posts: 55
Joined: 19 Mar 2015, 16:08

Re: Using Google Translate to automate text translation

Post by sobuj53 » 11 Apr 2021, 14:56

@garry
Thank you for your quick response however I'm getting this error,
Image

garry
Posts: 3740
Joined: 22 Dec 2013, 12:50

Re: Using Google Translate to automate text translation

Post by garry » 11 Apr 2021, 15:19

@sobuj53
teadrinkers function should be in folder \Autohotkey\LIB , filename= Googletranslate.ahk ( desactivate msgbox )
see page-1 > https://www.autohotkey.com/boards/viewtopic.php?p=273621#p273621
OR add to script
should update the file in LIB or in your script if the function has changed

Code: Select all

run,%a_programfiles%\Autohotkey\LIB
return

sobuj53
Posts: 55
Joined: 19 Mar 2015, 16:08

Re: Using Google Translate to automate text translation

Post by sobuj53 » 11 Apr 2021, 16:30

@garry
thank you very much. I was actually trying to modify your script but, I confused myself with variable tl1. I thought it was t11 :D .

Anyway here is a modified version that will take source language and To language argument and return translation accordingly.

Code: Select all

;- https://www.autohotkey.com/boards/viewtopic.php?p=273621#p273621  ;- user teadrinker
;- https://www.autohotkey.com/boards/viewtopic.php?p=273678#p273678
;- translator from user teadrinker / with GUI 
;- DropDownList to select 109 languages / save in ini-file / write to logfile
;- mark text then CTRL+c  / or direct input in Edit-2
/*
modified=20210412 added translation from option
modified=20210210  added Edit-2 for direct input 
modified=20200130  translate clipboard again in other language with dropdownlist (ddl1)
modified=20200129  translate when language change (ddl1) 
modified=20191019  ( teadrinker ) edited 1 time in total. 
modified=20190422  EDIT CreateScriptObj() ( teadrinker )
created =20190419  
https://cloud.google.com/translate/docs/languages
*/
;-------------------------------------------------------------------------------
#NoEnv
setworkingdir,%a_scriptdir%
tl1:=""
tl2:=""
transform,s,chr,32
Gui,1:default
Gui,1: +AlwaysOnTop  
Gui,1: -DPIScale
SS_REALSIZECONTROL := 0x40
wa:=a_screenwidth,ha:=a_screenheight,xx:=100
clipboard=
cl=
ex:=""
transform,s,chr,32
gosub,language
F1=%a_scriptdir%\myGoogleTranslate_Logfile.txt
rssini=%a_scriptdir%\translate.ini
ifnotexist,%rssini%    ;- first run
    {
    translateto=en     ;- english predefined
	translatefrom=de
    IniWrite,%translateto%, %rssini% ,Lang1  ,key1
	IniWrite,%translatefrom%, %rssini% ,Lang2  ,key2
    }
Gui,1:Color,Black,Black
Gui, Font,s14 cYellow ,Lucida Console 
IniRead, tl1, %rssini%,Lang1 ,key1
IniRead, tl2, %rssini%,Lang2 ,key2
global tl1,JS,tl2

x:=(wa*.5)/xx,W :=(wa*28)/xx,H :=(ha*10)/xx,y:=(ha*.5)/xx
Gui, Add, Text, x%x% y%y%  w%w% h%h% , From_Language
;-------------------------------------------------------
x:=(wa*.5)/xx,W :=(wa*28)/xx,H :=(ha*10)/xx,y:=(ha*4)/xx
Gui,add,dropdownlist, x%x% y%y% w%w% vDDL3 gddl2 ,%e5x%
;-------------------------------------------------------
x:=(wa*.5)/xx,W :=(wa*28)/xx,H :=(ha*10)/xx,y:=(ha*9)/xx
Gui, Add, Text, x%x% y%y%  w%w% h%h% , To_Language
;-------------------------------------------------------
x:=(wa*.5)/xx,W :=(wa*28)/xx,H :=(ha*10)/xx,y:=(ha*12)/xx
Gui,add,dropdownlist, x%x% y%y% w%w% vDDL1 gddl2 ,%e5x%
;-------------------------------------------------------
W :=(wa*29)/xx , H :=(ha*60)/xx , y:=(ha*18)/xx
Gui,add,Edit,x%x% y%y%  w%w% h%h% vED1  -border -E0x200,
;-------------------------------------------------------
W :=(wa*29)/xx , H :=(ha*8)/xx , y:=(ha*81.6)/xx
Gui,add,Edit,x%x% y%y%  w%w% h%h% vED2 ,
;-------------------------------------------------------

W :=(wa*30)/xx , H :=(ha*92)/xx  , x:=(wa-w),y:=(ha*1)/xx
Gui, Show,x%x% y%y% w%w% h%h% ,TRANSLATE

;-------------------------------------------------------
GuiControl,1:Choose,DDL1,%tl1%
GuiControl,1:Choose,DDL3,%tl2%
GuiControl, Focus,ED2
WinID := WinExist("A")
WinSetTitle, ahk_id %WinID%,, TRANSLATE_to_%tl1%
E0x200 = WS_EX_CLIENTEDGE
gosub,ddl2
RETURN
;--------------------------
esc::exitapp
;--------------------------
Guiclose:
cl=
clipboard=
exitapp
;------------------------------------------------------
~$enter::
Gui,submit,nohide
i++
aa:=GoogleTranslate(ed2,tl2,tl1)
if (i=1)
xc:=tl1x . "`n" . ed2 . "=" . aa
else 
xc:=ed1 . "`n" . ed2 . "=" . aa
GuiControl,1:,ED1,%xc%
fileappend,%ed2%=%aa%`r`n,%f1%,utf-8
aa=
GuiControl,1:,ED2,
GuiControl, Focus,ED2
return
;------------------------------------------------------------
;----- ( Hotkey) CTRL+C Clipboardchange ---------------------
OnClipboardChange:
If (A_EventInfo=1)
 {
 Gui, Show,
 GuiControl, Focus,ED1
 ClipWait,
 if (!ErrorLevel)
  {
  cl:=clipboard
  aa:=GoogleTranslate(cl,tl2,tl1)
  GuiControl,1:,ED1,%aa%
  txnew:= RegExReplace(aa, "([.!?¿:-=] )", "$1`r`n")
  fileappend,------------------`r`n%txnew%`r`n,%f1%,utf-8
  aa=
  GuiControl, Focus,ED2
  }
 }
return
;--------------------------
;--------------------------
ddl2:
Gui,1:submit,nohide
h1:=""
h2:=""

;1st part of 2nd language
x1:=""

StringSplit,h,DDL1,`_

If !InStr(h1, tl1, false)
{

  IniWrite,%h1%, %rssini% ,Lang1  ,key1
  tl1:=h1
  WinSetTitle, ahk_id %WinID%,, TRANSLATE_to_%h2%
  gosub,translateddlchange
  tl1x:=h2

}

StringSplit,x,DDL3,`_

If !InStr(x1, tl2, false)
{
  IniWrite,%x1%, %rssini% ,Lang2  ,key2
  tl2:=x1
  Guicontrolget,ed1
  GuiControl,1:Text,ED1,
}

;find from language code and write to ini


return
;----------------------------------------
;------- translate changed language -----
translateddlchange:
Guicontrolget,ed1
if ed1<>
{
aa:=GoogleTranslate(cl,tl2,tl1)    ;- translate clipboard again in other language
GuiControl,1:Text,ED1,%aa%
aa=
}
return
;---------------------------------------
;;-------- https://www.autohotkey.com/boards/viewtopic.php?p=273621#p273621 ---
; Google Translate script
; Take a string in any language and translate to any other language.
;
; Credited to teadrinker: https://www.autohotkey.com/boards/viewtopic.php?f=5&t=40876#p186877
; Slightly modified by Osprey to allow for determining and using the system language.
; Should be run with the Unicode version of AutoHotkey.
;
; Sample usage
; MsgBox, % GoogleTranslate("今日の天気はとても良いです")			; Translate string from auto-detected language to system language
; MsgBox, % GoogleTranslate("今日の天気はとても良いです", "jp", "en")	; Translate string from Japanese to English

GoogleTranslate(str, from := "auto", to := 0) {
   static JS := GetJScripObject(), _ := JS.( GetJScript() ) := JS.("delete ActiveXObject; delete GetObject;")
   
   if(!to)				; If no "to" parameter was passed
      to := GetISOLanguageCode()	; Assign the system (OS) language to "to"

   if(from = to)			; If the "from" and "to" parameters are the same
      Return str			; Abort translation and return the original string

   json := SendRequest(JS, str, to, from, proxy := "")
   if(!json or InStr(json, "document.getElementById('captcha-form')"))	; If no response (ex. internet down) or spam is detetected
     Return str				; Return the original, untranslated string
   oJSON := JS.("(" . json . ")")

   if !IsObject(oJSON[1])  {
      Loop % oJSON[0].length
         trans .= oJSON[0][A_Index - 1][0]
   }
   else  {
      MainTransText := oJSON[0][0][0]
      Loop % oJSON[1].length  {
         trans .= "`n+"
         obj := oJSON[1][A_Index-1][1]
         Loop % obj.length  {
            txt := obj[A_Index - 1]
            trans .= (MainTransText = txt ? "" : "`n" txt)
         }
      }
   }
   if !IsObject(oJSON[1])
      MainTransText := trans := Trim(trans, ",+`n ")
   else
      trans := MainTransText . "`n+`n" . Trim(trans, ",+`n ")

   from := oJSON[2]
   trans := Trim(trans, ",+`n ")
   Return trans
}

; Take a 4-digit language code or (if no parameter) the current language code and return the corresponding 2-digit ISO code
GetISOLanguageCode(lang := 0) {
   LanguageCodeArray := { 0436: "af" ; Afrikaans
			, 041c: "sq" ; Albanian
			, 0401: "ar" ; Arabic_Saudi_Arabia
			, 0801: "ar" ; Arabic_Iraq
			, 0c01: "ar" ; Arabic_Egypt
			, 1001: "ar" ; Arabic_Libya
			, 1401: "ar" ; Arabic_Algeria
			, 1801: "ar" ; Arabic_Morocco
			, 1c01: "ar" ; Arabic_Tunisia
			, 2001: "ar" ; Arabic_Oman
			, 2401: "ar" ; Arabic_Yemen
			, 2801: "ar" ; Arabic_Syria
			, 2c01: "ar" ; Arabic_Jordan
			, 3001: "ar" ; Arabic_Lebanon
			, 3401: "ar" ; Arabic_Kuwait
			, 3801: "ar" ; Arabic_UAE
			, 3c01: "ar" ; Arabic_Bahrain
			, 042c: "az" ; Azeri_Latin
			, 082c: "az" ; Azeri_Cyrillic
			, 042d: "eu" ; Basque
			, 0423: "be" ; Belarusian
			, 0402: "bg" ; Bulgarian
			, 0403: "ca" ; Catalan
			, 0404: "zh-CN" ; Chinese_Taiwan
			, 0804: "zh-CN" ; Chinese_PRC
			, 0c04: "zh-CN" ; Chinese_Hong_Kong
			, 1004: "zh-CN" ; Chinese_Singapore
			, 1404: "zh-CN" ; Chinese_Macau
			, 041a: "hr" ; Croatian
			, 0405: "cs" ; Czech
			, 0406: "da" ; Danish
			, 0413: "nl" ; Dutch_Standard
			, 0813: "nl" ; Dutch_Belgian
			, 0409: "en" ; English_United_States
			, 0809: "en" ; English_United_Kingdom
			, 0c09: "en" ; English_Australian
			, 1009: "en" ; English_Canadian
			, 1409: "en" ; English_New_Zealand
			, 1809: "en" ; English_Irish
			, 1c09: "en" ; English_South_Africa
			, 2009: "en" ; English_Jamaica
			, 2409: "en" ; English_Caribbean
			, 2809: "en" ; English_Belize
			, 2c09: "en" ; English_Trinidad
			, 3009: "en" ; English_Zimbabwe
			, 3409: "en" ; English_Philippines
			, 0425: "et" ; Estonian
			, 040b: "fi" ; Finnish
			, 040c: "fr" ; French_Standard
			, 080c: "fr" ; French_Belgian
			, 0c0c: "fr" ; French_Canadian
			, 100c: "fr" ; French_Swiss
			, 140c: "fr" ; French_Luxembourg
			, 180c: "fr" ; French_Monaco
			, 0437: "ka" ; Georgian
			, 0407: "de" ; German_Standard
			, 0807: "de" ; German_Swiss
			, 0c07: "de" ; German_Austrian
			, 1007: "de" ; German_Luxembourg
			, 1407: "de" ; German_Liechtenstein
			, 0408: "el" ; Greek
			, 040d: "iw" ; Hebrew
			, 0439: "hi" ; Hindi
			, 040e: "hu" ; Hungarian
			, 040f: "is" ; Icelandic
			, 0421: "id" ; Indonesian
			, 0410: "it" ; Italian_Standard
			, 0810: "it" ; Italian_Swiss
			, 0411: "ja" ; Japanese
			, 0412: "ko" ; Korean
			, 0426: "lv" ; Latvian
			, 0427: "lt" ; Lithuanian
			, 042f: "mk" ; Macedonian
			, 043e: "ms" ; Malay_Malaysia
			, 083e: "ms" ; Malay_Brunei_Darussalam
			, 0414: "no" ; Norwegian_Bokmal
			, 0814: "no" ; Norwegian_Nynorsk
			, 0415: "pl" ; Polish
			, 0416: "pt" ; Portuguese_Brazilian
			, 0816: "pt" ; Portuguese_Standard
			, 0418: "ro" ; Romanian
			, 0419: "ru" ; Russian
			, 081a: "sr" ; Serbian_Latin
			, 0c1a: "sr" ; Serbian_Cyrillic
			, 041b: "sk" ; Slovak
			, 0424: "sl" ; Slovenian
			, 040a: "es" ; Spanish_Traditional_Sort
			, 080a: "es" ; Spanish_Mexican
			, 0c0a: "es" ; Spanish_Modern_Sort
			, 100a: "es" ; Spanish_Guatemala
			, 140a: "es" ; Spanish_Costa_Rica
			, 180a: "es" ; Spanish_Panama
			, 1c0a: "es" ; Spanish_Dominican_Republic
			, 200a: "es" ; Spanish_Venezuela
			, 240a: "es" ; Spanish_Colombia
			, 280a: "es" ; Spanish_Peru
			, 2c0a: "es" ; Spanish_Argentina
			, 300a: "es" ; Spanish_Ecuador
			, 340a: "es" ; Spanish_Chile
			, 380a: "es" ; Spanish_Uruguay
			, 3c0a: "es" ; Spanish_Paraguay
			, 400a: "es" ; Spanish_Bolivia
			, 440a: "es" ; Spanish_El_Salvador
			, 480a: "es" ; Spanish_Honduras
			, 4c0a: "es" ; Spanish_Nicaragua
			, 500a: "es" ; Spanish_Puerto_Rico
			, 0441: "sw" ; Swahili
			, 041d: "sv" ; Swedish
			, 081d: "sv" ; Swedish_Finland
			, 0449: "ta" ; Tamil
			, 041e: "th" ; Thai
			, 041f: "tr" ; Turkish
			, 0422: "uk" ; Ukrainian
			, 0420: "ur" ; Urdu
			, 042a: "vi"} ; Vietnamese
   If(lang)
     Return LanguageCodeArray[lang]
   Else Return LanguageCodeArray[A_Language]
}

SendRequest(JS, str, tl, sl, proxy) {
   ComObjError(false)
   http := ComObjCreate("WinHttp.WinHttpRequest.5.1")
   ( proxy && http.SetProxy(2, proxy) )
   http.open( "POST", "https://translate.google.com/translate_a/single?client=t&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=1&ssel=3&tsel=3&pc=1&kc=2"
      . "&tk=" . JS.("tk").(str), 1 )

   http.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
   http.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0")
   http.send("q=" . URIEncode(str))
   http.WaitForResponse(-1)
   Return http.responsetext
}

URIEncode(str, encoding := "UTF-8")  {
   VarSetCapacity(var, StrPut(str, encoding))
   StrPut(str, &var, encoding)

   While code := NumGet(Var, A_Index - 1, "UChar")  {
      bool := (code > 0x7F || code < 0x30 || code = 0x3D)
      UrlStr .= bool ? "%" . Format("{:02X}", code) : Chr(code)
   }
   Return UrlStr
}

GetJScript()
{
   script =
   (
      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)
      }
   )
   Return script
}

GetJScripObject()  {
   static doc
   doc := ComObjCreate("htmlfile")
   doc.write("<meta http-equiv='X-UA-Compatible' content='IE=9'>")
   Return ObjBindMethod(doc.parentWindow, "eval")
}
;-----------------------------------------------------------------
;-- some examples to select 
;-https://cloud.google.com/translate/docs/languages
language:
e5x:=""
e5x=
(Ltrim join|
af_Afrikaans
sq_Albania
am_Amharisch
ar_Arab
hy_Armenia
az_Aserbaijan
eu_Baskisch
be_Belarus
bn_Bengal
bs_Bosnia
bg_Bulgaria
ca_Catalan
ceb_Cebuano (ISO-639-2)
zh-CN_China or zh (BCP-47)
zh-TW_China trad (BCP-47)
co_Corsica
hr_Croatia
cs_Cesko
da_Danmark
nl_Nederland
en_English
eo_Esperanto
et_Estonia
fi_Finland Suomi
fr_France
fy_Fryslan
gl_Galicia
ka_Georgia
de_German
el_Greece Elliniki
gu_Gujarati
ht_Creol Haiti
ha_Haussa
haw_Hawaii(ISO-639-2)
he_Hebräisch
iw_Hebräisch
hi_Hindi
hmn_Hmong (ISO-639-2)
hu_Hungarian Magyar
is_Iceland
ig_Igbo
id_Indonesia
ga_Irland Eire
it_Italia
ja_Japan Nippon
jv_Java
kn_Kannada
kk_Kasach
km_Khmer
rw_Kinyarwanda
ko_Korea
ku_Kurdistan
ky_Kirgisian
lo_Lao
la_Latin
lv_Lettland Latvija
lt_Litvanija Lietuva
lb_Luxemburg
mk_Mazedonia
mg_Madagascar
ms_Malaia
ml_Malayalam
mt_Malta
mi_Maori
mr_Marathi
mn_Mongolia
my_Myanmar
ne_Nepal
no_Norge
ny_Nyanja (Chichewa)
or_Odia (Oriya)
ps_Pashtun
fa_Persia
pl_Poland
pt_Portugal Brasilia
pa_Pandschabi
ro_Romania
ru_Rossija
sm_Samoa
gd_Scotia gael
sr_Serbia
st_Sesotho
sn_Shona
sd_Sindhi
si_Singhal
sk_Slovakia
sl_Slovenia
so_Somalia
es_Espana
su_Sundanesisch
sw_Swahili
sv_Sverige
tl_Tagalog (Philippines)
tg_Tadschikistan
ta_Tamil
tt_Tatar
te_Telugu
th_Thai
tr_Turkiye
tk_Turkmenistan
uk_Ukraina
ur_Urdu
ug_Uigur
uz_Uzbekistan
vi_Vietnam
cy_Wales GB
xh_Xhosa
yi_Jiddisch
yo_Yoruba
zu_Zulu
%s%
%s%
)
return
;====================== END SCRIPT ==================================================

jodjod
Posts: 7
Joined: 23 May 2021, 06:59

Re: Using Google Translate to automate text translation

Post by jodjod » 12 Jul 2021, 07:58

i`m sorry if my question out of topic, can I use this google translate.ahk only for detecting the text file in a file example:
if there is mix korean and english text like 이리에 now... in a file, the result will be the text file is in kr_en_file
like in the https://cloud.google.com/translate/docs/basic/detecting-language#detecting_the_language_of_a_single_string

teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Using Google Translate to automate text translation

Post by teadrinker » 12 Jul 2021, 11:24

@jodjod
I think RegexMatch() is more suitable for this purpose.

jodjod
Posts: 7
Joined: 23 May 2021, 06:59

Re: Using Google Translate to automate text translation

Post by jodjod » 12 Jul 2021, 21:23

@teadrinker
wow, yes I agree with you, we can use regex, but because I'm newbie in script so I'm using IfInString and FileCopy to rename the file for the semi solution, thank you for the idea and reply

Sieceres
Posts: 12
Joined: 06 Sep 2018, 05:16

Re: Using Google Translate to automate text translation

Post by Sieceres » 28 Nov 2021, 05:41

Osprey wrote:
23 Apr 2019, 03:48
By my estimation, it took sending hundreds or even thousands of translation requests in the span of just a few minutes for me to trigger the block, so more reasonable usage in scripts may be perfectly safe.
I don't know if Google have updated T&C but for me it gets blocked pretty quickly. Is it possible to use any other provider such as Bing?

way1000
Posts: 90
Joined: 20 Jun 2016, 02:19

Re: Using Google Translate to automate text translation

Post by way1000 » 23 Dec 2021, 12:53

how to make this script use google document translate and translate a entire folder with .txt files, then it downloads from google with http as .txt
file

it uses "https://translate.googleusercontent.com/translate_f" web service


Screenshot 2021-12-23 105501.png
Screenshot 2021-12-23 105501.png (36.51 KiB) Viewed 4666 times
Screenshot 2021-12-23 105626.png
Screenshot 2021-12-23 105626.png (63.81 KiB) Viewed 4666 times
Capture2.PNG
Capture2.PNG (10.13 KiB) Viewed 4664 times

teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Using Google Translate to automate text translation

Post by teadrinker » 23 Dec 2021, 13:32

way1000 wrote: how to make this script use google document translate and translate a entire folder with .txt files, then it downloads from google with http as .txt
file
My script can only translate the text from the variable.

CyberKlabauter
Posts: 44
Joined: 26 Jan 2017, 17:59

Re: Using Google Translate to automate text translation

Post by CyberKlabauter » 28 Jan 2022, 18:36

Here an update of with my version; Show popup menu, auto replace highlighted textwith selection or read aloud. I did not incooperate the newest update of teadrickers version.

Code: Select all

; Name: Google Translate
; GitHub:       -
; Forum:        https://www.autohotkey.com/boards/viewtopic.php?f=6&t=63835
; Authors:      teadrinker, garry 
; Modifications by CyberKlabauter


#NoEnv ; For security
#SingleInstance force
SendMode Input
SetBatchLines, -1
SetWorkingDir %A_ScriptDir%

#Include, %a_scriptDir%\..\AHKScripts\Lib\BasicScriptConfiguration.ahk
	
global tl1,JS,txt22,h1
rssini=%a_scriptdir%\translate.ini

IfNotExist, %rssini%   ;- first run
		{
		translateto=de     ;- german
		IniWrite,%translateto%, %rssini%, Language01, NativeLanguage
		IniWrite,en, %rssini%, Language01, SecondLanguage
		IniWrite,Shift, %rssini%, Hotkeys, CopyModifierKey
		}
IniRead, NativeLanguage, %rssini%, Language01, NativeLanguage
IniRead, SecondLanguage, %rssini%, Language01, SecondLanguage
IniRead, ModifierKey, %rssini%,Lang1, CopyModifierKey
tl1 := NativeLanguage

; GroupAdd, AppId,%AppTitle%
return

^+ü::TranslateMenu(NativeLanguage, SecondLanguage)


#IfWinActive, ahk_group AppId
	Esc::
		Menu, TranslationMenu, UseErrorLevel
		Menu, TranslationMenu, Rename, Read translation, Read translation
		if (ErrorLevel)
			Menu, TranslationMenu, DeleteAll
		return
#IfWinActive

return  ; end autoexecution

; --------------------------------------------------------------------------------------
; --------------------------------------------------------------------------------------
; --------------------         Google Audio Translate GUI          ---------------------
; --------------------------------------------------------------------------------------
; --------------------------------------------------------------------------------------

TranslationAndAudioGui:
   ; tl1:=""
   Gui,1:default
   Gui,1: +AlwaysOnTop  
   Gui,1: -DPIScale
   SS_REALSIZECONTROL := 0x40
   wa:=a_screenwidth,ha:=a_screenheight,xx:=100
;   clipboard=
;   cl=
   transform,s,chr,32
   gosub,language

   Gui,1:Color,f5fff9,f5fff9 ; Background color: White Gui
   ; Gui,1:Color,Black,Black ; Background color
   Gui,1:Font,s14 c242424 ,Calibri Light ; Font color
   ; Gui,1:Font,s14 cFFFFFF ,Calibri Light ; Font color
;   IniRead, tl1, %rssini%,Lang1 ,key1
;   global tl1,JS,txt22,h1
   x:=(wa*.5)/xx,W :=(wa*18)/xx,H :=(ha*10)/xx,y:=(ha*.5)/xx
   Gui,add,dropdownlist, x%x% y%y% w%w% vDDL1 gddl2 ,%e5x%
   x:=(wa*20)/xx,W :=(wa*8)/xx,H :=(ha*2.4)/xx,y:=(ha*.5)/xx
   Gui,add,button,x%x% y%y%  w%w% h%h% gAudio, Read aloud
   x:=(wa*.5)/xx,W :=(wa*29)/xx , H :=(ha*88)/xx , y:=(ha*3.5)/xx
   Gui,add,edit,x%x% y%y%  w%w% h%h% vED1  -border -E0x200,
   W :=(wa*30)/xx , H :=(ha*91)/xx  , x:=(wa-w),y:=(ha*2)/xx
   ;Gui, Show,x%x% y%y% w%w% h%h% ,TRANSLATE
   Gui, Show,x%x% y0 w%w% h%h% ,TRANSLATE
   ;GuiControl,1:Choose,ddl1,%tl1% , 
   GuiControl, ChooseString, ddl1, %tl1%  ; select translate to language
   GuiControl, Focus,ED1
   WinID := WinExist("A")
   WinSetTitle, ahk_id %WinID%,, TRANSLATE_to_%tl1%
   E0x200 = WS_EX_CLIENTEDGE
   gosub ShowAudioGui
   RETURN
   
Guiclose:
;	cl=
;	clipboard=
	Gui, destroy
	return
	
;-----  CTRL+C Clipboardchange ---------------------
ShowAudioGui:
;	If (A_EventInfo=1)  {
	Gui, Show,
	GuiControl, Focus,ED1
;	ClipWait,
;	if (!ErrorLevel)  {
;		cl:=clipboard
;		aa:=GoogleTranslate()
		aa:=GoogleTranslate(Translation, "auto", tl1)
;		aa:= 
		ControlSetText,edit1,%aa%, ahk_class AutoHotkeyGUI
		txt22:=aa
		aa=
		GuiControl, Focus,ED1
;		}
;	}
	gosub, AUDIO
	return
	
;--------------------------
;--------------------------
ddl2:
	Gui,1:submit,nohide
	h1:=""
	h2:=""
	; tl1 := Ddl2  ; CK
	if (DDL1 <> "")  {
		StringSplit,h,ddl1,`_
		if (h1 <> "")  {
		  IniWrite,%h1%, %rssini% ,Lang1, key1
		  tl1 := h1
		  WinSetTitle, ahk_id %WinID%,, TRANSLATE_to_%h2%
		  gosub,translateddlchange
		  gosub,Audio ; CB
		  }
	}
	return
	
;----------------------------------------
;------- translate changed language -----
translateddlchange:
	Guicontrolget,ed1
	ControlGet, Language, Choice, , , ahk_class AutoHotkeyGUI
	Language := SubStr(Language, 1, 2)
	ControlGetText,aa, edit1, ahk_class AutoHotkeyGUI
	if (ed1 <> "") {
		aa:=GoogleTranslate(aa, "auto", Language)      ;- translate clipboard again in other language
		ControlSetText,edit1,%aa%, 
		txt22:=aa
		aa=
		}
	return




; --------------------------------------------------------------------------------------
; --------------------------------------------------------------------------------------
; ---------------------        Google Translate Functions         ----------------------
; --------------------------------------------------------------------------------------
; --------------------------------------------------------------------------------------
TranslateMenu(NativeLanguage:="de", SecondLanguage:="en")  {
	global Translation
	Gui, destroy
	SavedClipboard := ClipboardAll
	Clipboard := ""
    Send, ^c
    ClipWait, 0
	ClipboardContent := Clipboard
	Clipboard := SavedClipboard
	Translation := GoogleTranslate(ClipboardContent, "auto", NativeLanguage)
	tl1 := NativeLanguage
	; Check: If terms is in native language use second language to translate to 
	; Ideas for improvements are welcome. This is not the best approach. Some word get auto corrected by google. In this case this the native language is not detected. 
	If (SubStr(ClipboardContent, 1, 30) = SubStr(Translation, 1, StrLen(SubStr(ClipboardContent, 1, 30)))) {
        Translation := GoogleTranslate(ClipboardContent, NativeLanguage, SecondLanguage) 
		tl1 := SecondLanguage
		}
	AlternativeTranslations := ""
	if ((PositionAlternativeTranslations:=InStr(Translation,"`n")) > 0)  {
		if (SubStr(Translation, PositionAlternativeTranslations, 3) = "`n+`n")  {
			AlternativeTranslations := SubStr(Translation, PositionAlternativeTranslations + 3)
			Translation := SubStr(Translation, 1, PositionAlternativeTranslations - 1)
			}	
		}
	If (StrLen(Translation) > 30)
        TranslationTeaser := SubStr(Translation, 1, 30) "…" 
    Else 
        TranslationTeaser := Translation
	
	menu, TranslationMenu, add, % TranslationTeaser, ShowPasteMenu
	menu, TranslationMenu, Default, % TranslationTeaser
	menu, TranslationMenu, Add
	if (AlternativeTranslations != "") {	; Loop through all + alternatives and create their own menu entry
		Loop, Parse, AlternativeTranslations, `n, `r
			{
			menu, TranslationMenu, add, % A_LoopField, ShowPasteMenu			
			}
		menu, TranslationMenu, Add
		}
	menu, TranslationMenu, add, Copy to Clipboard , CopyToClipboard
	menu, TranslationMenu, add, Read translation , TranslationAndAudioGui
	menu, TranslationMenu, useErrorLevel
	menu, TranslationMenu, show
	menu, TranslationMenu, deleteAll
	return
	
	ShowPasteMenu:
		if (GetKeyState(ModifierKey, "P"))  {
			if (AlternativeTranslations != "")	
				Clipboard := A_ThisMenuItem
			else
				Clipboard := Translation
			}
		else {
			SavedClipboard := ClipboardAll
			Clipboard := ""
			if (AlternativeTranslations != "")	
				Clipboard := A_ThisMenuItem
			else
				Clipboard := Translation
			ClipWait, 0
			Send, ^v
			Sleep, 3000
			Clipboard := SavedClipboard
			}
		return
		
	CopyToClipboard: 
		Clipboard := Translation "`n" AlternativeTranslations
		return
	}


GoogleTranslate(str, from := "auto", to := "en")  {
	static JS := CreateScriptObj(), _ := JS.( GetJScript() ) := JS.("delete ActiveXObject; delete GetObject;")
   
	json := SendRequest(JS, str, to, from, proxy := "")
	oJSON := JS.("(" . json . ")")

	if !IsObject(oJSON[1])  {
		Loop % oJSON[0].length
			trans .= oJSON[0][A_Index - 1][0]
			}
   else  {
      MainTransText := oJSON[0][0][0]
      Loop % oJSON[1].length  {
        trans .= "`n+"
        obj := oJSON[1][A_Index-1][1]
        Loop % obj.length  {
            txt := obj[A_Index - 1]
            trans .= (MainTransText = txt ? "" : "`n" txt)
			}
		}
	}
	if !IsObject(oJSON[1])
		MainTransText := trans := Trim(trans, ",+`n ")
	else
		trans := MainTransText . "`n+`n" . Trim(trans, ",+`n ")

	from := oJSON[2]
	trans := Trim(trans, ",+`n ")
	Return trans
	}

SendRequest(JS, str, tl, sl, proxy) {
	static http
	ComObjError(false)
	if !http
		{
		http := ComObjCreate("WinHttp.WinHttpRequest.5.1")
		( proxy && http.SetProxy(2, proxy) )
		http.open( "get", "https://translate.google.com", 1 )
		http.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0")
		http.send()
		http.WaitForResponse(-1)
		}
	http.open( "POST", "https://translate.google.com/translate_a/single?client=webapp&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), 1 )

	http.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
	http.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0")
	http.send("q=" . URIEncode(str))
	http.WaitForResponse(-1)
	Return http.responsetext
	}

URIEncode(str, encoding := "UTF-8")  {
   VarSetCapacity(var, StrPut(str, encoding))
   StrPut(str, &var, encoding)

   While code := NumGet(Var, A_Index - 1, "UChar")  {
      bool := (code > 0x7F || code < 0x30 || code = 0x3D)
      UrlStr .= bool ? "%" . Format("{:02X}", code) : Chr(code)
   }
   Return UrlStr
	}

GetJScript()  {
   script =
   (
      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)
      }
   )
   Return script
}

CreateScriptObj() {
   static doc
   doc := ComObjCreate("htmlfile")
   doc.write("<meta http-equiv='X-UA-Compatible' content='IE=9'>")
   Return ObjBindMethod(doc.parentWindow, "eval")
	}





; --------------------------------------------------------------------------------------
; --------------------------------------------------------------------------------------
; -------------------     	Audio / Text to speach Functions        --------------------
; --------------------------------------------------------------------------------------
; --------------------------------------------------------------------------------------

;============================================================================
;=================================   AUDIO ==================================
	AUDIO:
	Gui,submit,nohide
	global aa2,TL1,text
	F1 := A_Temp . "\TextToRead.mp3"
	tl1=%tl1%
	;TL1:="de"
	;text:="Good evening , how are you ?"
	text:=txt22
	;msgbox, 262208, ,LNG=`n%lng%`n---------------------`nTEXT=`n%text%
	;return
	aa2:= GetAudioFromGoogle(text, TL1, F1)
	if (aa2<>1)	  {
	  msgbox, 262208, ,AA2=%aa2%`nLanguage = "%Tl1%"
	  return
	  }
	soundplay,%f1%
	filedelete,%f1%
	return
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
GetAudioFromGoogle(text,TL1, mp3filePath)  {
   url := CreateUrl(text,TL1)
   data := sendrequest2(url)
   if SubStr(data, 1, 6) = "Error!"
      Return data
   
   Return SaveDataToFile(data, mp3filePath)
	}
	
CreateUrl(text, TL1)  {
   JS := CreateScriptObj2(), JS.( GetJscript2() )
   url := "https://translate.google.ru/translate_tts?ie=UTF-8&tl="
         . TL1 . "&total=1&idx=0&client=t&prev=input&textlen="
         . StrLen(text) . "&tk=" . JS.("tk").(text) . "&q=" . uriencode2(text)
   Return url
	}
	
sendrequest2(url) {
   whr := ComObjCreate("Msxml2.XMLHTTP.6.0")
   whr.Open("GET", url, false)
   whr.Send()
   
   if (whr.Status != 200)
      Return "Error! Status: " . whr.Status . "`n`n" . whr.responseBody
   Return whr.responseBody
	}
	
SaveDataToFile(data, filePath) {
   stream := ComObjCreate("ADODB.Stream")
   stream.type := 1  ; Binary data
   stream.Open
   stream.Write(data)
   stream.SaveToFile(filePath, 2)
   stream.Close
   Return true
	}
	
;=====================================================================================
GetJscript2()  {
   script = 
   (
      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)
		}
	)
	Return script
	}

UriEncode2(str, encoding := "UTF-8")  {
	urlstr:=""
	VarSetCapacity(var, StrPut(str, encoding))
	StrPut(str, &var, encoding)
	While code := NumGet(Var, A_Index - 1, "UChar")  {
		bool := (code > 0x7F || code < 0x30 || code = 0x3D)
		UrlStr .= bool ? "%" . Format("{:02X}", code) : Chr(code)
	}
	Return UrlStr
	}
	
CreateScriptObj2() {
   static doc
   doc := ComObjCreate("htmlfile")
   doc.write("<meta http-equiv='X-UA-Compatible' content='IE=9'>")
   Return ObjBindMethod(doc.parentWindow, "eval")
	}





;-----------------------------------------------------------------
;-- some examples to select 
language:
	e5x:=""
	e5x=
	(Ltrim join|
	de_Deutsch
	en_English
	fr_Français
	it_Italia
	el_Greek
	tr_Turkiye
	nl_Nederlands
	da_Dansk
	sv_Sverige
	no_Norge
	pt_Portugues
	es_Español
	ru_Rossija
	zh-CN_Chinese
	ja_Nippon
	ro_Romania
	ta_Tamil
	%s%
	%s%
	)
	return

/*
;-----------------------------------------------------------------
;-- some examples to select 
language:
	e5x:=""
	e5x=
	(Ltrim join|
	nl_Nederlands
	af_Suid-Afrika
	fy_Fryslân
	eu_Basque
	ca_Catalan
	de_Deutsch
	da_Dansk
	sv_Sverige
	no_Norge
	is_Iceland
	fi_Suomen
	en_English
	pt_Portugues
	es_Español
	it_Italia
	fr_Français
	ru_Rossija
	zh-CN_Chinese
	ja_Nippon
	ko_Korea
	ro_Romania
	bg_Bulgaria
	mk_Macedonia
	el_Greek
	tr_Turkiye
	sq_Albania
	hr_Croatia
	sr_Serbia
	sl_Slovenia
	hu_Hungary
	cs_Czech
	sk_Slovakia
	pl_Poland
	be_Belarus
	uk_Ukraina
	et_Estonia
	lv_Latvija
	lt_Lituania
	az_Azerbaijan 
	ka_Georgian
	ar_Arabic
	iw_Hebrew
	hi_Hindi
	id_Indonesia
	ms_Malaysia
	vi_Vietnam
	th_Thai
	ta_Tamil
	ur_Urdu
	sw_Swahili
	bn_Bengal
	%s%
	%s%
	)
	return
*/
;====================== END SCRIPT ==================================================

User avatar
kunkel321
Posts: 976
Joined: 30 Nov 2015, 21:19

Re: Using Google Translate to automate text translation

Post by kunkel321 » 30 Jan 2022, 17:04

I guess I'll share my version too...

It gets called from another script, so no hotkey in this script. If a person wanted to run this as a "standalone" app that stays in memory, they would probably just add a hotkey near the top, then, replace the two "ExitApp" lines with "Exit."

The script uses an INI file. This allows it to remember that last-used language. Since it gets called from another script (that is in the parent folder), I can't just have the name of the INI file when reading/writing to it. Change lines 21, 22, and 52 accordingly.

When run, it shows the dialog on the left. Pressing "More" opens the INI. Pressing "OK" translates the selected text and puts it in the MsgBox seen on the right. It translates it, then translates it back to English so I can see how much of the message was lost in translation. I use this at work sometimes.

AHK script and INI content in spoiler.

Image
Spoiler
ste(phen|ve) kunkel

UnReALiTyy
Posts: 223
Joined: 06 Jun 2017, 11:38

Re: Using Google Translate to automate text translation

Post by UnReALiTyy » 15 Feb 2022, 09:40

kunkel321 wrote:
30 Jan 2022, 17:04
I guess I'll share my version too...

It gets called from another script, so no hotkey in this script. If a person wanted to run this as a "standalone" app that stays in memory, they would probably just add a hotkey near the top, then, replace the two "ExitApp" lines with "Exit."

The script uses an INI file. This allows it to remember that last-used language. Since it gets called from another script (that is in the parent folder), I can't just have the name of the INI file when reading/writing to it. Change lines 21, 22, and 52 accordingly.

When run, it shows the dialog on the left. Pressing "More" opens the INI. Pressing "OK" translates the selected text and puts it in the MsgBox seen on the right. It translates it, then translates it back to English so I can see how much of the message was lost in translation. I use this at work sometimes.

AHK script and INI content in spoiler.
Really good, I have also updated my GUI to the latest version.

viewtopic.php?f=10&t=73329&p=445727#p316703

EM3R50N
Posts: 1
Joined: 17 Aug 2022, 05:55

Re: Using Google Translate to automate text translation

Post by EM3R50N » 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?

Post Reply

Return to “Scripts and Functions (v1)”