Hi scripters,
Is there a way to make a script wait for an action to finish in order to avoid jamming up the automation?
What I want to accomplish:
I downloaded a bunch of images from NASA’s image server http://img.pds.nasa.gov/ to experiment with making animations out of them.
The files come in the ˜Planetary Data System’ file format and need to be converted to JPG’s to be able to work with them.
Some batch converting applications like the beautiful XnConvert exist, but they have trouble opening all the files (I guess 20% of the images get skipped).
The small application NASAView gets almost every file opened and converted, but it doesn’t provide batch functionality.
Applescript to the rescue. I collected snippets of code and made a script that does the job. It works by calling System Events to click menu items and press keys in order to achieve an automation sequence. I’m planning to convert about 300.000 files. It’s not fast, but I can let the script run day and night on a dedicated machine that won’t be touched.
The Problem:
The script jams from time to time. After increasing the delays in between the commands, the script runs longer: in about a day and a half it converts around 8000 files, but eventually it gets stuck too. The error message I get is:
error "System Events got an error: Can't get menu bar 1 of process \"NASAView\". Invalid index." number -1719 from menu bar 1 of process "NASAView"
In the Applescript log window I can see that the commands are logged faster than I see them executed.
For example: four return presses are immediately logged (and probably executed), but the process of actually seeing the different pop up windows appear and disappear takes longer.
I’m assuming that some kind of buffer runs out of memory eventually, resulting in Finder, or NASAView not being able to keep up with the script.
The solution?
Instead of using delays, it would make more sense to wait for the actions like key presses, or menu clicks to finish before continuing the script.
So. not only sending a keypress to a certain application, but also waiting until the action of the result of the keypress is finished, so that the application is ready to receive new commands again
The code:
The script currently looks like this:
(*
NASAVIEW batch
01: open NASAView
02: in the finder: select a data folder, and show only .IMG files by searching for the file extention .IMG
03: do one (or a few) images manually in NASAView, until the desired output folder is remembered in NASAView save dialog box as a default location
04: start the script
05: come back after a few days to check on the result
*)
set finished to 0
set i to 1
repeat while finished = 0
-- GET SELECTED FILE IN THE FINDER
tell application "Finder"
set selectedFile to the selection -- Get selected Finder item (path described in Applescript language)
set filePathAsText to selectedFile as text -- path as text with colons
set filePathAsPOSIX to POSIX path of filePathAsText -- path as text with slashes
set the clipboard to filePathAsPOSIX
set currentFileName to do shell script "basename '" & filePathAsPOSIX & "'" -- get the file name (from a POSIX path)
set fileExtention to name extension of (selectedFile as alias) -- file extention ( from the Applescript variable)
end tell
-- CHECK IF THE FILE IS GOOD TO WORK WITH
if fileExtention is not equal to "IMG" then
tell application "System Events" to key code 125 -- 125 = arrow down
log currentFileName & " is a wrong file, selecting the file below this one and trying again"
delay 0.3
end if
tell application "NASAView" to activate
tell application "System Events"
tell process "NASAView"
-- OPEN FILE
tell menu bar 1 to click menu item "Open Object" of menu "File" -- open file
delay 0.4
tell application "System Events" to key code 5 using {shift down, command down} -- 5 = g -- open "go to" dialog box
delay 0.4
tell application "System Events" to key code 9 using command down -- 9 = v -- paste the file path
delay 0.4
tell application "System Events" to key code 36 -- 36 = return -- enter the file path
delay 1
repeat 4 times
tell application "System Events" to key code 36 -- 36 = return -- press enter to open the file, and press enter 3 more times to accept various dialog boxes in NASAView
delay 0.3
end repeat
delay 1
-- SAVE FILE AS JPEG
tell menu bar 1 to click menu item "Save JPEG AS" of menu "File"
delay 1
tell application "System Events" to key code 36 -- 36 = return
delay 0.8
-- CLOSE FILE
tell menu bar 1 to click menu item "Close" of menu "File"
end tell
end tell
log "ok: " & i & " - " & currentFileName -- log, just for log's sake
set i to i + 1
-- GO TO NEXT FILE
tell application "Finder"
activate
delay 0.2
tell application "System Events" to key code 125 -- 125 = arrow down -- select the file below the current one in the list
delay 0.2
-- DID WE REACH THE END OF THE FOLDER?
tell application "Finder" -- get selected item in the finder
set newFilepath to the selection as text
set newFilepathPOSIX to POSIX path of newFilepath
set newFileName to do shell script "basename '" & newFilepathPOSIX & "'" -- get the file name (from a POSIX path)
end tell
if (currentFileName is equal to newFileName) then -- if the new file has the same name as the previous one, we're at the last file in the folder
display dialog "twice the same filename: we're done!"
set finished to 1
end if
end tell
end repeat
Thanks,
Elias