Sigh. More Watch Folder issues.

So, my watch folder script worked pretty well, but it breaks apart if you send more than one file at the folder at a time (for example 6 files at once).

My original script looked something like this…




on adding folder items to thisFolder after receiving theItems
	repeat with f in theItems
		-- wait for the item to be all there. Since it can take a few minutes for a file to copy over.
		set Was to 0
		set isNow to 1
		repeat while isNow ≠ Was
			set Was to size of (info for f)
			delay 30 -- longer if getting the item is slow
			set isNow to size of (info for f)
		end repeat
		tell application "Finder"
			open theItems using application file "ProResTo1920X1080.app" of folder "Desktop" of folder "anton" of folder "Users" of startup disk
		end tell
	end repeat -- get next item f in thisFolder
end adding folder items to


The problem with the script is that I’m send theItems to the Compressor droplet on each repetion. But sometimes theItems have multiple items. So, that’s bad.

So my new script for this tries to send only the item of the repetition to the Compressor.



on adding folder items to thisFolder after receiving theItems
	-- this is the standard intro for a folder action
	
	repeat with f in theItems
		set file_name to name of (info for f)
		set fileType to kind of (info for f)
		set theFile to (file f of theItems)
		-- wait for the item to be all there
		set Was to 0
		set isNow to 1
		repeat while isNow ≠ Was
			-- the basic idea is that the script loops until the file size is the same for more than 30 seconds. That means the file has finished copying. 
			set Was to size of (info for f)
			-- this section is getting the file size of the video
			delay 10
			set isNow to size of (info for f)
			-- this section is sampling the file size 30 seconds later
		end repeat
		
		tell application "Finder"
			
			open theFile using application file "ProResSQ.app" of folder "Desktop" of folder "admin" of folder "Users" of startup disk
		end tell
		-- get next item f in thisFolder
		
	end repeat
end adding folder items to



But unfortunately, this doesn’t work.

Sigh.

A

I came up with two different ways of fixing your first script (though I used TextEdit instead of your app(s) in my testing):

  1. change
    open theItems using application file “ProResTo1920X1080.app” of folder “Desktop” of folder “anton” of folder “Users” of startup disk
    to
    open f using application file “ProResTo1920X1080.app” of folder “Desktop” of folder “anton” of folder “Users” of startup disk
    Reason: Changing theItems (the list of all the files) to f (the current file in your loop) means that, after checking each file, your script only tells Finder to open one file at a time instead of trying to open the whole list of files.

  2. move the tell application “Finder” block to after the end of the repeat with f in theItems loop.
    Reason: If you are going to open up all the files at the same time, you probably want to have checked over all of them before you send them to the other program, and you probably do not want to open them all up once for each file. So, move it outside the main loop where it will execute only once.

The second script was not working because set theFile to (file f of theItems) was causing an error. But you can not see the error when the scripts are run as a Folder Action, since they are not running in an editor/debugger. Sometimes I write Folder Action scripts like this:

on adding folder items to thisFolder after receiving theItems
	try
		-- Normal Folder Action code goes here.
	on error m
		display alert m as warning
	end try
end adding folder items to

If there is an error while running the code, a message box with the error message will be displayed.

And if I find that I would like to run the Folder Action code directly in Script Editor (so I can see the Event Log and get better debugging info), I take out the above try block and add something like this

on run
	set thisPath to (path to desktop folder from user domain as string without folder creation) & "Folder Action test folder:"
	set thisFolder to alias thisPath
	set theItems to {alias (thisPath & "newfile.txt"), alias (thisPath & "newfile copy.txt")}
	adding folder items to thisFolder after receiving theItems
end run

to the script on which I am working. Then when I run the script in Script Editor, it will simulate adding “newfile.txt” and “newfile copy.txt” to the “Folder Action test folder” on my Desktop (all these folders and files have to already exist and be in the proper places). You’ll have to adjust the filenames and paths accordingly for each script’s purposes. Also, this is just my attempt at a simulation of the parameters that are passed to the handler when it is triggered as a normal Folder Action, they may not be entirely faithful to what happens when the Folder Action is triggered normally.

There are probably better AppleScript development environments for handling stuff like debugging Folder Action scripts. But, the above methods have served me well enough that I have not yet bothered to seek out better alternatives.

By the way, the error your second script was getting was on set theFile to (file f of theItems) because it was trying to get a file element of a list (as far as I know, lists call all their elements items, never anything more specific: you can ask for item 2 of myList, but not file f of myList). If you wanted to, you could set theFile to f instead (this works out to be the same as my fix #1 above, but using an extra variable).

Script Debugger 4.0 has a nice way of doing folder actions. The run pops up and the choose the on event you want to run. If you do a folder action you can choose files to emulate a dropped file and files. It also remembers what you did last time so easy to repeat the same items.

chrys Script Debugger is a must if you do lot of AppleScripting, worth every cent. And good spotting of the problems. Only thing is theItems are alias class because they can be files and folders.

Have Fun

Thanks guys.

Chrys,

At one point I tried to send f to compressor but it didn’t work at the time (however, it could be another part of the script wasn’t working at the time and I made the wrong assumption as to where the problem was). Indeed, troubleshooting Folder actions is hard, having a way to track errors better will help.

I’ll try it and report back.

So, using the f variable didn’t work. Nothing happened.

Then I changed the script to this:



on adding folder items to thisFolder after receiving theItems
	repeat with f in theItems
		set g to f as alias
		-- wait for the item to be all there. Since it can take a few minutes for a file to copy over.
		set Was to 0
		set isNow to 1
		repeat while isNow ≠ Was
			set Was to size of (info for f)
			delay 30 -- longer if getting the item is slow
			set isNow to size of (info for f)
		end repeat
		tell application "Finder"
			open g using application file "H264forAppleTV.app" of folder "Desktop" of folder "anton" of folder "Users" of startup disk
		end tell
	end repeat -- get next item f in thisFolder
end adding folder items to


This is working. Does that make sense?

Thanks again.

Cheers,

As far as I know, f should be a reference to an alias. If that is true, and my understanding of how references and coercion work together is correct, then doing that coercion would automatically dereference it giving the alias which would then be “coerced” to an alias (no actual change, since it already is an alias), causing g to be the alias itself. I am just learning the ins and outs of references, but it seems to me that a reference to an alias will work just fine in the context in which it is used in your script (open X using …).

I saved your latest script here with the following changes: delay 2 instead of delay 30; changed the target app to TextEdit; deleted the line set g to … line; changed open g using … to open f using …. When I dropped a couple of files into the folder with that modified script attached, the files opened in TextEdit one by one with a couple of seconds between each one. So, using f directly seems to work just fine for me. I also tested with only the delay and app changed and that works for me, too. It could be something about your droplet app, but that does not seem likely.

Sorry, I do not know of a reason you would need g like that (and my testing here works with just f and with g, too). If nothing is happening for you when your script just uses f, it is probably getting an error somewhere. If you have not already, you might try using the try+on error display alert wrapper that I mentioned before:

on adding folder items to thisFolder after receiving theItems
	try
		-- Folder Action code here
	on error m
		display alert m as warning
	end try
end adding folder items to