Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 05/11/2024 in all areas

  1. The current version actually has a higher date in the comment. But this is also wrong 😉 - I obviously overlooked the date and didn't always adjust it. The current version can always be found in the github repository: https://github.com/Sylvan86/autoit-json-udf The last change there was on 21 February 2024.
    2 points
  2. Here is the final reworked script taking care of UTF-8 encoding, so cyrillic characters shouldn't be a problem anymore. Now that all original text is always converted to UTF-8 (no matter they were Ascii characters, Ansi, Unicode, mix) then my initial issue with end of lines has disappeared as EOL's will be restored correctly at their right place, when the translation is done (no more workaround !) I notice the script needs the last version of AutoIt (because of Maps in Json.au3) Though some translations will work with older versions of AutoIt (because Maps aren't always used during translation, depending on the original text), it's better to use last version of AutoIt (3.3.16.1) to cover all cases. @AspirinJunkie I would like to know : this is what is found in your version of Json.au3 I found on the net : ; Title .........: JSON-UDF ; Version .......: 0.9 ; AutoIt Version : 3.3.16.1 ... ; Author(s) .....: AspirinJunkie ; Last changed ..: 2023-01-16 In case there is a newer version, could you please indicate where it can be downloaded ? Thanks to everybody involved in this script #include "Json.au3" ; (by @AspirinJunkie) #include <StringConstants.au3> ;======================== Local $sLangFROM = "auto" Local $sLangTO = "en" ; <===== change this line for the language of the translated text ;======================== Local $sInput, $sClipGet = StringToBinary(ClipGet(), $SB_UTF8) ; for example л (russian) becomes 0xD0BB For $i = 3 To StringLen($sClipGet) Step 2 ; start at 3 to bypass "0x" $sInput &= "%" & StringMid($sClipGet, $i, 2) Next Local $sTranslated = _GoogleAPITranslate($sInput, $sLangFROM, $sLangTO) ; If (Not @compiled) And ProcessExists("scite.exe") Then ; not 100% proof to bypass the 3 following ConsoleWrite, but better than nothing. If Not @compiled Then ; probably a bit faster than preceding line. It will be enough when script run from .a3x shortcut placed on Desktop. ConsoleWrite("ORIGINAL: " & BinaryToString($sClipGet, $SB_ANSI) & @crlf) ; in case of accented characters in Scite console. ConsoleWrite("----------------------------------------------------------------------------------------------------------------" & @crlf) ConsoleWrite(BinaryToString(StringToBinary($sTranslated, $SB_UTF8), $SB_ANSI) & @crlf) EndIf MsgBox(262144, "Translated From " & $sLangFROM & " To " & $sLangTO, $sTranslated) ; $MB_TOPMOST = 262144 ;============================================== Func _GoogleAPITranslate($sMytext, $sFrom, $sTo) Local $sUrl, $oHTTP, $sResponse, $JSONData, $sOutput = "", $aData $sUrl = "https://translate.googleapis.com/translate_a/single?client=gtx&sl=" & $sFrom & "&tl=" & $sTo & "&dt=t&q=" & $sMytext $oHTTP = ObjCreate("Microsoft.XMLHTTP") $oHTTP.Open("POST", $sUrl, False) $oHTTP.Send() $sResponse = $oHTTP.ResponseText $JSONData = _JSON_Parse($sResponse) If VarGetType($JSONData) = 'Array' Then $aData = $JSONData[0] If VarGetType($aData) = 'Array' Then For $i = 0 To UBound($aData) -1 $sOutput &= ($aData[$i])[0] Next EndIf EndIf Return $sOutput EndFunc ;==>_GoogleAPITranslate * Update May 11, 2024 : Added a test on @compiled to bypass (or not) all ConsoleWrite lines and the functions included in them. Though it's not 100% proof, it's better than nothing. Other ways to detect more precisely how the script was launched can be found on the Forum, for example by using _WinAPI_GetParentProcess and _WinAPI_GetProcessName, but do we really need all this just to bypass 3 ConsoleWrite lines ? Let's test on @compiled for the moment, we'll see...
    2 points
  3. In fact it's not that hard to translate from russian to english with the script. You just need to prepare a UTF-8 input string that the google api translator will recognize, for example with these few lines of script : #include <StringConstants.au3> Local $sInput, $sClipGet = StringToBinary(ClipGet(), $SB_UTF8) ; л (russian) becomes 0xD0BB For $i = 3 To StringLen($sClipGet) Step 2 ; forget "0x" at beginning $sInput &= "%" & StringMid($sClipGet, $i, 2) Next ConsoleWrite("ClipGet() = " & BinaryToString($sClipGet, $SB_ANSI) & @crlf & @crlf) ConsoleWrite("$sClipGet = " & $sClipGet & @crlf & @crlf) ConsoleWrite("$sInput = " & $sInput & @crlf) AutoIt console : ClipGet() = а если подумать в 99,9999999999% случаев $sClipGet = 0xD0B020D0B5D181D0BBD0B820D0BFD0BED0B4D183D0BCD0B0D182D18C2020D0B22039392C393939393939393939392520D181D0BBD183D187D0B0D0B5D0B2 $sInput = %D0%B0%20%D0%B5%D1%81%D0%BB%D0%B8%20%D0%BF%D0%BE%D0%B4%D1%83%D0%BC%D0%B0%D1%82%D1%8C%20%20%D0%B2%20%39%39%2C%39%39%39%39%39%39%39%39%39%39%25%20%D1%81%D0%BB%D1%83%D1%87%D0%B0%D0%B5%D0%B2 Then you use the variable $sInput for the google api translator, it will translate correctly : Same result as translating with the Browser, yes ! I'll have to rework a bit the original script to integrate in it these new lines of script.
    2 points
  4. Accept Multiple Files UDF is inspired by this topic and this topic. Introduction if your app (compiled script) is launched from Windows Explorer context menu, then you've probably noticed that when multiple files are selected, only one file is passed to your app, so Windows starts multiple instances of your app, one for each file selected. few simple ways to overcome this issue are: 1) put a shortcut to your app on your "Send To..." context menu. this passes all the selected files as individual parameters to a single instance of your app. 2) put a shortcut to your app somewhere accessible, and drag the selected files to that shortcut. that will give you the same effect. (an accessible location might not include the task bar, unfortunately. but the Start menu for example is ok). 3) use an intermediate launcher, like this one (not tested by me). if none of these apply to you, then this UDF allows your app to handle this issue internally. Usage - yes, it is a one-liner: Global $aFiles = _AcceptMultipleFiles() Example Script - with comprehensive comments inside: #AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #include <Array.au3> ; this is needed only For the _ArrayDisplay later In this example script. #include 'AMF.au3' ; include the "Accept Multiple Files" UDF. #NoTrayIcon ; disable this interactive feature. Global $hTimer = TimerInit() ; for testing purposes Global $aFiles = _AcceptMultipleFiles() Global $fDiff = Round(TimerDiff($hTimer)) / 1000 ; determine how long the process took #cs calling _AcceptMultipleFiles makes the calling script accept all files passed as parameters to multiple instances of the calling script, typically invoked by Windows Explorer context menu. list of files is returned as an array. this is best performed as early as possible in your script, and definitely before any user interaction. it will either make this instance the 'master', that will accept multiple files to process (and continue running), or submit its file to the master instance if one is already active (and exit). *NOTE: if there are files to process, and if this is NOT the 'master' instance, then this line will never be reached. *NOTE: if only one file is selected - thus only one instance is invoked - then that instance becomes the 'master' and the files array contains only the one file. if your code made it this far, there are two possible scenarios: 1) there are files to process, and they are stored in the array. element zero and @extended both store the number of files. 2) your app was called with no parameters, or too many, or one that is not a file. in this case element zero = 0 and @extended = 0. hence, you can use element zero to decide on your next action. something like this: #ce If $aFiles[0] > 0 Then ; <<<<<<<<<< do your stuff with the files listed in $aFiles >>>>>>>>>> _ArrayDisplay($aFiles, 'AMF Example (' & $fDiff & ' sec)') Else ; <<<<<<<<<< do your stuff when no parameters were specified, or too many parameters, or a single parameter which is not a valid file >>>>>>>>>> MsgBox(0, 'AMF Example (' & $fDiff & ' sec)', 'This was the command line:' & @CRLF & $CmdLineRaw) EndIf UDF: #include-Once ; #INDEX# ======================================================================================================================= ; Title .........: Accept Multiple Files ; AutoIt Version : 3.3.16.1 ; UDF Version ...: 2.0 ; Status ........: Production ; Language ......: English ; Description ...: Allows a script to accept multiple files from Windows Explorer context menu, which invokes multiple instances. ; One instance becomes the 'master'. All other instanes submit their files to the master and exit, so only the ; 'master' instance remains active and can process all files. ; Author(s) .....: orbs ; =============================================================================================================================== ; #VARIABLES# =================================================================================================================== Global $__g_AMF_bDebug = False ; =============================================================================================================================== ; #CURRENT# ===================================================================================================================== ; _AcceptMultipleFiles ; =============================================================================================================================== ; #FUNCTION# ==================================================================================================================== ; Name ..........: _AcceptMultipleFiles ; Description ...: Accepts multiple files given as parameters to multiple instances of the calling script. ; Syntax ........: _AcceptMultipleFiles([$iAttempts = 10[, $iInterval = 10[, $bDebug = False]]]) ; Parameters ....: $iAttempts - [optional] number of attempts of searching for submitted files. Default (and minimum) is 10. ; $iInterval - [optional] number of milliseconds between attempts. Default (and minimum) is 10. ; $bDebug - [optional] default is False. if True, log files are created in the temporary folder. ; Return values .: a 1-based array of all files submitted by all instances. @extended is set to file count. ; Author ........: orbs ; Modified ......: ; Remarks .......: - if no parameters were specified, or too many parameters, or a single parameter which is not a valid file, ; then the function returns an array with element [0]=0, and @extended is set to 0. ; - to improve reliability, the calling script may increase $iAttempts and/or $iInterval. ; Related .......: ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _AcceptMultipleFiles($iAttempts = 10, $iInterval = 10, $bDebug = False) ; process parameters If ($iAttempts = Default) Or ($iAttempts < 10) Then $iAttempts = 10 If ($iInterval = Default) Or ($iInterval < 10) Then $iInterval = 10 If $bDebug = Default Then $bDebug = False $__g_AMF_bDebug = $bDebug __AMF_Log('enter _AcceptMultipleFiles') __AMF_Log('attempts: ' & $iAttempts) __AMF_Log('interval: ' & $iInterval) ; initialize return data Local $aFiles[1] = [0] ; validate parameter If Not ($CmdLine[0] = 1 And FileExists($CmdLine[1])) Then Return SetExtended(__AMF_Log('invalid param => return empty array'), $aFiles) ; prepare variables and parent (root) folder Local Const $sAMF_Root = @LocalAppDataDir & '\AMF' __AMF_Log('AMF root: ' & $sAMF_Root) __AMF_Log('root DirCreate = ' & DirCreate($sAMF_Root)) Local Const $sAMF_Path = @LocalAppDataDir & '\AMF\' & __AMF_CreateGUID(StringRight(@ScriptFullPath, 16)) Local Const $sAMF_MasterFile = $sAMF_Path & '\master' __AMF_Log('AMF path: ' & $sAMF_Path) __AMF_Log('master file: ' & $sAMF_MasterFile) Local $iIteration = 0 Local $bFound Local $hSearch Local $sAMF_File Local $sFile ; determine if master While Not __AMF_TakeOver($sAMF_Path, $sAMF_MasterFile) ; see if this should become the master process. If __AMF_MasterIsActive($sAMF_MasterFile, $iAttempts, $iInterval) Then ;; if not, then check if there is already an active master process. __AMF_SubmitFile($sAMF_Path, $CmdLine[1]) ;;; if so, then submit the file to the master and exit. __AMF_Log('file submitted => exit') Exit Else __AMF_Cleanup($sAMF_Path) ;; if there is no active master, assume the past master has crashed. cleanup and repeat trying to take over. EndIf WEnd __AMF_Log('this instance is master') ; start with first file, submitted by the master ReDim $aFiles[UBound($aFiles) + 1] $aFiles[0] += 1 $aFiles[UBound($aFiles) - 1] = $CmdLine[1] ; process submitted files __AMF_Log('searching for submitted files') Do $iIteration += 1 $bFound = False __AMF_Log('start iteration #' & $iIteration) For $i = 1 To $iAttempts __AMF_Log('attempt #' & $i) FileClose($hSearch) $hSearch = FileFindFirstFile($sAMF_Path & '\PID_*') If @error Then __AMF_Log('FileFindFirstFile @error=' & @error & ' => next attempt') FileClose($hSearch) Sleep($iInterval) ContinueLoop EndIf $sAMF_File = FileFindNextFile($hSearch) If @error Then __AMF_Log('FileFindNextFile @error=' & @error & ' => next attempt') Sleep($iInterval) ContinueLoop EndIf $bFound = True __AMF_Log('$sAMF_File = ' & $sAMF_File) $sAMF_File = $sAMF_Path & '\' & $sAMF_File __AMF_Log('prefix full path = ' & $sAMF_File) __AMF_Log('FileGetAttrib = ' & FileGetAttrib($sAMF_File)) If StringInStr(FileGetAttrib($sAMF_File), 'R') Then __AMF_Log('Attrib R found') $sFile = FileReadLine($sAMF_File) __AMF_Log('FileReadLine = ' & $sFile) If $sFile = '' Then __AMF_Log('result is empty => repeat attempt') Sleep($iInterval) $i -= 1 ContinueLoop Else __AMF_Log('FileSetAttrib -R = ' & FileSetAttrib($sAMF_File, '-R')) __AMF_Log('FileDelete = ' & FileDelete($sAMF_File)) EndIf Else __AMF_Log('Attrib R not found => repeat attempt') Sleep($iInterval) $i -= 1 ContinueLoop EndIf ReDim $aFiles[UBound($aFiles) + 1] $aFiles[0] += 1 $aFiles[UBound($aFiles) - 1] = $sFile __AMF_Log('added to array => repeat attempt on next file') $i -= 1 Next __AMF_Log('iteration ended. files found = ' & $bFound) Until Not $bFound FileClose($hSearch) __AMF_Log('search for submitted files ended') __AMF_Cleanup($sAMF_Path) Return SetExtended(__AMF_Log('end _AcceptMultipleFiles => return array with @extended=' & $aFiles[0], $aFiles[0]), $aFiles) EndFunc ;==>_AcceptMultipleFiles ; #INTERNAL_USE_ONLY# =========================================================================================================== ; __AMF_CreateGUID ; __AMF_TakeOver ; __AMF_MasterIsActive ; __AMF_SubmitFile ; __AMF_Cleanup ; __AMF_Log ; =============================================================================================================================== Func __AMF_CreateGUID($sString) ; ref: https://www.autoitscript.com/forum/topic/147995-createguidfromstring-convert-a-string-to-a-valid-guid/ Return StringRegExpReplace(StringToBinary($sString) & "0000000000000000000000000000000000", "..(.{8})(.{4})(.{4})(.{4})(.{12}).*", "\{$1-$2-$3-$4-$5\}") EndFunc ;==>__AMF_CreateGUID Func __AMF_TakeOver($sAMF_Path, $sAMF_MasterFile) __AMF_Log('enter __AMF_TakeOver') Local $aResult = DllCall('kernel32.dll', 'bool', 'CreateDirectoryW', 'wstr', $sAMF_Path, 'struct*', 0) If @error Or ($aResult[0] = 0) Then Return __AMF_Log('cannot create folder => this instance is not the master. return 0') Else __AMF_Log('FileWriteLine = ' & FileWriteLine($sAMF_MasterFile, @AutoItPID)) __AMF_Log('FileSetAttrib +R = ' & FileSetAttrib($sAMF_MasterFile, '+R')) Return __AMF_Log('master file created => return 1', 1) EndIf EndFunc ;==>__AMF_TakeOver Func __AMF_MasterIsActive($sAMF_MasterFile, $iAttempts, $iInterval) __AMF_Log('enter __AMF_MasterIsActive') Local $iPID For $i = 1 To $iAttempts If StringInStr(FileGetAttrib($sAMF_MasterFile), 'R') Then $iPID = Number(FileReadLine($sAMF_MasterFile)) ExitLoop Else Sleep($iInterval) EndIf Next __AMF_Log('read PID = ' & $iPID) If $iPID = 0 Then Return __AMF_Log('PID=0 => return 0') If ProcessExists($iPID) Then Return __AMF_Log('process exists => return 1', 1) Return __AMF_Log('end __AMF_MasterIsActive => return 0') EndFunc ;==>__AMF_MasterIsActive Func __AMF_SubmitFile($sAMF_Path, $sFile) __AMF_Log('enter __AMF_SubmitFile') Local $sAMF_File = $sAMF_Path & '\PID_' & @AutoItPID __AMF_Log('FileDelete = ' & FileDelete($sAMF_File)) __AMF_Log('file to submit: ' & $sFile) __AMF_Log('FileWriteLine = ' & FileWriteLine($sAMF_File, $sFile)) __AMF_Log('FileSetAttrib +R = ' & FileSetAttrib($sAMF_File, 'R')) __AMF_Log('end __AMF_SubmitFile') EndFunc ;==>__AMF_SubmitFile Func __AMF_Cleanup($sAMF_Path) __AMF_Log('enter __AMF_Cleanup') __AMF_Log('dir to remove: ' & $sAMF_Path) __AMF_Log('FileSetAttrib -R = ' & FileSetAttrib($sAMF_Path, '-R', 1)) __AMF_Log('DirRemove = ' & DirRemove($sAMF_Path, 1)) __AMF_Log('end __AMF_Cleanup') EndFunc ;==>__AMF_Cleanup Func __AMF_Log($sString, $xRet = 0) If $__g_AMF_bDebug Then FileWriteLine(@TempDir & '\AMF_log_' & @AutoItPID & '.txt', @HOUR & ':' & @MIN & ':' & @SEC & '.' & @MSEC & ' (' & @AutoItPID & ') ' & $sString) Return $xRet EndFunc ;==>__AMF_Log Testing Instructions: 1) save the UDF as file "AMF.au3". 2) save the example script as file "AMF_Example.au3". 3) compile the example script as "AMF_Example.exe". 4) place the executable in the root of drive D (or anywhere else ,but adapt the following registry entry accordingly) 5) save this text as registry file "AMF_Example.reg" and import it: Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\*\shell\AMF Example] "MultiSelectModel"="Player" [HKEY_CLASSES_ROOT\*\shell\AMF Example\command] @="D:\\AMF_Example.exe \"%1\"" 6) open Windows Explorer, select multiple files, right click one of them and choose "AMF Example" from the context menu. 7) enjoy!
    1 point
  5. Ok, i didn't know this about the API. Thanks for the information. The powershell may have been shortened by a colleague who may have deleted some neccessary parts. I will investigate this. Maybe then it is better trying the webdriver. I will be back here when i have my first webdriver code done or when i fail with this task 🙂
    1 point
×
×
  • Create New...