I've recently seen some interesting videos about using Automator to do more stuff, so I thought I'd give it another try. (See my first post about Automator for some background.)
Turns out that you can pass multiple variables into an action, if you are very, very careful. In general it's easy - if you use two "Get Value of Variable" actions chained together you get an array with the two arguments. Unless you don't. Going back to our example I need to provide two arguments: one is the URL of an image and one is a text string describing the map. The Automator script that I currently use saves the filename into a text file, then asks for the description which it saves into a separate text file. Then it fires off a Ruby script that processes the filename into the URL for the image and makes the necessary changes to the web server. It works, but it's a bit slow and it looks ridiculous.
OK, so you're with me so far right? We have a file that the user selected (via a 'Ask for Finder Items' action), and a description that the user provided (via a 'Ask for Text' action). So let's store each of those in a variable and get them back to back. It works! We have two arguments in the data stream. We can pass that to a 'Run Shell Script' action and $1 will be our filename, and $2 will be the description. I work with that for a bit and it's all great, so I go ahead and start plugging those changes into the "real" script. Except it blows up when I try to retrieve the description variable.
After a lot of messing around I realized the types of the variables is important. The 'Ask for Finder Items' gives you back an file alias. (If you inspect the result it will say 'Alias' in blue and then the filename.) If you manipulate that (say by a 'Rename Finder Items' action) it changes from an alias to the actual file. If you get an alias variable and then a text variable you will be fine. If you get a file then attempt to get a text variable the second get fails. There's a fix for this. You can run a 'Store Disk Item References' action and it will turn the file back into an alias. That seems wonky, but sure whatever.
Next problem. My action *MOVED* the image file from my local drive to the server. So the original file doesn't actually exist by the time you get the variables together. This will also fail, and cause a screwup, even if you have an alias. After some thought I decided to copy the file and then delete the file on my local drive later. Turns out you can delete the "alias" and there's no error, but the original file is there. You have to do the opposite of that 'Store Disk Item References'. Get the variable, run a 'Retrieve Disk Item References', THEN run the 'Move Finder Items to Trash'. Goofy, but I can hang with it.
OK, so now we're set. I've got a script action that is getting the two arguments, I can write the necessary sed mojo (sed is a UNIX command that lets you manipulate text) to convert the filename over to the URL and we're cooking with gas. It all works! Fantastic! Now, there are a couple of actions where Automator seems really slow: both of those Disk Item references take a while and I'm now using Preview to convert the RAW file from my camera to a JPG (which means I don't have to change the filetype on my camera every week.) The convert is instant but Automator takes several seconds before moving to the next step. I wonder if making it into a stand-alone "application" would help? I try that. The application doesn't work. I open the workflow (the one that just worked mind you) and run it. It crashes. After a lot of playing around I confirm what it looked like originally. I can take a running workflow, add a new "Run Shell script" command and paste in the commands I want, and that workflow will run. Save it and run it again and it still runs. Close and reopen Automator and the Run Shell Script action now errors out!
I have no idea what that's about. When I last complained about Automator I felt like I didn't really understand how it worked. Now, after several hours I understand how it's supposed to work, and it just plain doesn't all the times. The distinction between a file and an alias to a file is subtle and it's not documented. The automator documentation calls both of them a Files/Folders object. The 'Rename Finder Items' action claims its input is a 'Files/Folders' and its result is a 'Files/Folders'. Which is true enough, but the change from an alias to a real file changes what you can do with variables later. This second problem with the external script command not working the same on a file load as it does when the command is created is just bullshit.
So, I really need to get rid of Automator. It has a lot of promise, and if I was just automating something simpler it would be OK. But in a way I preferred the way I thought it worked (where it seemed very limited but it worked) to what it actually does (where some things don't work right at all and there are undocumented types that you need to care very much about.)
Turns out that you can pass multiple variables into an action, if you are very, very careful. In general it's easy - if you use two "Get Value of Variable" actions chained together you get an array with the two arguments. Unless you don't. Going back to our example I need to provide two arguments: one is the URL of an image and one is a text string describing the map. The Automator script that I currently use saves the filename into a text file, then asks for the description which it saves into a separate text file. Then it fires off a Ruby script that processes the filename into the URL for the image and makes the necessary changes to the web server. It works, but it's a bit slow and it looks ridiculous.
OK, so you're with me so far right? We have a file that the user selected (via a 'Ask for Finder Items' action), and a description that the user provided (via a 'Ask for Text' action). So let's store each of those in a variable and get them back to back. It works! We have two arguments in the data stream. We can pass that to a 'Run Shell Script' action and $1 will be our filename, and $2 will be the description. I work with that for a bit and it's all great, so I go ahead and start plugging those changes into the "real" script. Except it blows up when I try to retrieve the description variable.
After a lot of messing around I realized the types of the variables is important. The 'Ask for Finder Items' gives you back an file alias. (If you inspect the result it will say 'Alias' in blue and then the filename.) If you manipulate that (say by a 'Rename Finder Items' action) it changes from an alias to the actual file. If you get an alias variable and then a text variable you will be fine. If you get a file then attempt to get a text variable the second get fails. There's a fix for this. You can run a 'Store Disk Item References' action and it will turn the file back into an alias. That seems wonky, but sure whatever.
Next problem. My action *MOVED* the image file from my local drive to the server. So the original file doesn't actually exist by the time you get the variables together. This will also fail, and cause a screwup, even if you have an alias. After some thought I decided to copy the file and then delete the file on my local drive later. Turns out you can delete the "alias" and there's no error, but the original file is there. You have to do the opposite of that 'Store Disk Item References'. Get the variable, run a 'Retrieve Disk Item References', THEN run the 'Move Finder Items to Trash'. Goofy, but I can hang with it.
OK, so now we're set. I've got a script action that is getting the two arguments, I can write the necessary sed mojo (sed is a UNIX command that lets you manipulate text) to convert the filename over to the URL and we're cooking with gas. It all works! Fantastic! Now, there are a couple of actions where Automator seems really slow: both of those Disk Item references take a while and I'm now using Preview to convert the RAW file from my camera to a JPG (which means I don't have to change the filetype on my camera every week.) The convert is instant but Automator takes several seconds before moving to the next step. I wonder if making it into a stand-alone "application" would help? I try that. The application doesn't work. I open the workflow (the one that just worked mind you) and run it. It crashes. After a lot of playing around I confirm what it looked like originally. I can take a running workflow, add a new "Run Shell script" command and paste in the commands I want, and that workflow will run. Save it and run it again and it still runs. Close and reopen Automator and the Run Shell Script action now errors out!
I have no idea what that's about. When I last complained about Automator I felt like I didn't really understand how it worked. Now, after several hours I understand how it's supposed to work, and it just plain doesn't all the times. The distinction between a file and an alias to a file is subtle and it's not documented. The automator documentation calls both of them a Files/Folders object. The 'Rename Finder Items' action claims its input is a 'Files/Folders' and its result is a 'Files/Folders'. Which is true enough, but the change from an alias to a real file changes what you can do with variables later. This second problem with the external script command not working the same on a file load as it does when the command is created is just bullshit.
So, I really need to get rid of Automator. It has a lot of promise, and if I was just automating something simpler it would be OK. But in a way I preferred the way I thought it worked (where it seemed very limited but it worked) to what it actually does (where some things don't work right at all and there are undocumented types that you need to care very much about.)