Droplet bug

Had an idea. We use the folder action, drop files on it, get the names of all the files that were dropped. So, we have the names of the files. Then do the undo. Then search all Finder’s windows for files with names in the list of file names. That might work!

Edited: it’s a pseudo droplet! :slight_smile:

A pseudo droplet, yes, but it works (or should work) as expected and above all by simply dragging files on an icon which is basically the droplet ease. :slight_smile:

Hi CMYS,

Started testing with the desktop window with an internet location file on the desktop. It seems to be working, but needs testing. Then expand to all open windows. Also, need to test consistency and time.

on adding folder items to this_folder after receiving these_items
	set item1 to item 1 of these_items
	tell application "System Events" to set item_name to name of item1
	display dialog item_name
	tell application "Finder" to activate
	tell application "System Events"
		keystroke "z" using command down
	end tell
	tell application "Finder"
		activate
		try
			set desk_window to window of desktop
			set item1_ref to (first item of desk_window whose name is item_name) as alias
			display dialog (item1_ref as string)
		on error err_msg
			display dialog err_msg
		end try
	end tell
	beep 1
end adding folder items to

I needed to do some review of desktop window.

Edited: sometimes the folder action doesn’t work if you drop a second file on the folder to soon. Maybe need to update Finder or relaunch System Events. Still testing.

Edited: found that the folder action doesn’t fire if you drop the same we bloc file too soon after the first. But, if you alternate different files, then it seems to be working.

gl,
kel

Got it working with multiple webloc files:

on adding folder items to this_folder after receiving these_items
	set file_names to {}
	repeat with this_item in these_items
		tell application "System Events" to set item_name to name of this_item
		set end of file_names to item_name
	end repeat
	tell application "Finder" to activate
	tell application "System Events"
		keystroke "z" using command down
	end tell
	tell application "Finder"
		activate
		set window_list to every window
		if not (exists window "Desktop") then
			set dtw to window of desktop
			set end of window_list to dtw
		end if
		set the_items to {}
		repeat with this_window in window_list
			set found_items to (every item of this_window whose name is in file_names) as alias list
			set the_items to the_items & found_items
		end repeat
	end tell
	-- test the_items
	set string_items to {}
	repeat with this_item in the_items
		set end of string_items to this_item as string
	end repeat
	activate
	choose from list string_items
	beep 1
end adding folder items to

It slows down with more open windows. Also, try not to drop the same files.

Edited: note that you cannot drag items of sublists when in list view.

Edited: I have a theory on why it doesn’t work when you immediately drop the same file on the folder. Finder seems to think that the file is still there. It has nothing to do with the name of the file though. Somehow, we need to force the Finder to now it’s not there. This happens in the opposite direction also. Rarely, when the file is moved (with undo) to the desktop, Finder thinks that something is there (i.e. under the hard disk) and moves the file to the next space. Tried updating the windows, but it didn’t work. Moving the file makes it work again with a longer delay.

Edited: getting real close. When I drop the same file and another file. The same file doesn’t show up in the choose from list dialog. I don’t think it’s erring. Need to check that out.

Edited: getting closer. The Finder thinks that some operation is not complete. Probably the undo?

Edited: I think System events is not reporting that the job is completed. I think this because, if I just manually move the file on the desktop and redrop it, then it works. Darn, let me try that again.

Edited: what I was thinking is that we might have to skip working with the desktop and just work with the desktop folder if it’s not already open.

gl,
kel

I’ve come to the conclusion again that fodder actions is a lame technology. It’s too slow! That’s why I never used it. It might be ok for simple stuff like displaying a dialog when an item is dropped and hopefully not too often.

But, I did have a new idea to solving this problem.

how about watchpaths? It’s using file system events, it should be a lot faster.

Hi DJ,

I was thinking of using something like a folder watcher instead of folder actions. I’ll look into “watchpaths” whatever that is. Think I’ve read about something like that in one of the developer docs.

Also, was thinking about the original idea of getting the Safari windows (or whatever is the default), get the urls, and finding the files in Finder’s open windows.

Edited: found it. It’s used in a launch agent.

Thanks a lot,
kel

Reading up on the various types of jobs, this looks like it might work also:

Yeah, after several hours off and on, finally got the launch agent to work. I think it was because I was using:

instead of:

which now works. Now I can call an AppleScript script. Probably, need to work on it tomorrow.

Btw, I think the QueueDirectories might work better, because the agent won’t run if the folder is not empty.

Thanks DJ! Forgot about Launch Agents.

Oops! Didn’t see your last posts earlier.
Just one thing: if you set item1 to item 1 of these_items you’ll never catch the other ones. Was it on purpose?

Hi CMYS,

Yes, I was just testing. :slight_smile: Sorry about not mentioning that.

As I was driving this morning, i remembered that an alias (path) reference follows the items where they are moved. So, it is not actually needed to check all Finder windows. So basically, all that needs to be done is get an alias list and undo the drag and drop. We then have a list of items wherever they came from! I must be getting old. :slight_smile:

Just started working on the whole thing.

Later,
kel

I see why now. The directory is never empty because of invisible files. So we need to use WatchPaths .

Hi Dj,

If you’re not too busy, I’ve noticed that when the files are removed from the drop folder, then the launch agent fires again. Should I unload the agent before removing the added items with:

then, remove the items from the drop folder. Or, is there a better way to not make it fire again? I couldn’t find anything in the man page for launched.plist for not having it fire again.

Btw, the speed of execution is great!

Thanks,
kel

Darn, one missing colon in the folder path caused another 2 hours of debugging! Think I’ve got it now!

Hi,

Think I’ve found the secret. You need to unload and load at the end of the AppleScript. Otherwise, your program will act funny. :slight_smile:

This is a great puzzle man!

Darn, no you need to reload it somewhere else. This is so frustrating, but I love it!

You probably don’t know what I’m talking about, so here’s all the players.

Here’s the launch agent:

The Label can be anything, but it should be unique. Also, you might need to restart or maybe just restart Finder. Here’s the bash script it calls:

Remember to make it executable. In Terminal "chmod +x /path/to/the/script’. Here’s the AppleScript compiled script:

property drop_folder_path : "Macintosh HD:Users:kelhome:Desktop:DropFolder:"

-- call this script from shell script
on run -- p -- parameters if needed
	set drop_folder_ref to drop_folder_path as alias
	tell application "Finder"
		set dropped_items to every item of drop_folder_ref as alias list
		activate
	end tell
	-- move the added items back to original location
	-- but first, turn off launch agent for one-shot
	-- remember to re-load at end
	--do shell script "launchctl unload /Users/kelhome/Library/LaunchAgents/com.apple.launchagent.plist"
	tell application "System Events" to keystroke "z" using command down
	-- dropped_items are now in original loacation and references should reflect that
	-- testing: look at original locations
	set string_list to {}
	repeat with this_item in dropped_items
		set end of string_list to this_item as string
	end repeat
	activate
	choose from list string_list
	-- one shot
	do shell script "launchctl unload /Users/kelhome/Library/LaunchAgents/com.apple.launchagent.plist"
end run

The question is where to re-load the launch agent. Here’s the load and unload Terminal scripts:

It’s pretty quick, but where to re-load the launch agent. I need to step back and think. Getting to one track minded.

Edited: oops, forgot to add the .2 sec. delay:

property drop_folder_path : "Macintosh HD:Users:kelhome:Desktop:DropFolder:"

-- call this script from shell script
on run -- p -- parameters if needed
	set drop_folder_ref to drop_folder_path as alias
	tell application "Finder"
		set dropped_items to every item of drop_folder_ref as alias list
		activate
	end tell
	-- move the added items back to original location
	-- but first, turn off launch agent for one-shot
	-- remember to re-load at end
	--do shell script "launchctl unload /Users/kelhome/Library/LaunchAgents/com.apple.launchagent.plist"
	tell application "System Events" to keystroke "z" using command down
	-- dropped_items are now in original loacation and references should reflect that
	-- testing: look at original locations
	delay 0.2 -- added this
	set string_list to {}
	repeat with this_item in dropped_items
		set end of string_list to this_item as string
	end repeat
	activate
	choose from list string_list
	-- one shot
	do shell script "launchctl unload /Users/kelhome/Library/LaunchAgents/com.apple.launchagent.plist"
end run

See the comment.

gl,
kel

Cleaned up the script and modified things. Here’s the launch agent:

Here’s the shell script:

Here’s the AppleScript:

property drop_folder_path : "Macintosh HD:Users:kelhome:Desktop:DropFolder:"

-- call this script from shell script
on run -- p -- parameters if needed
	set drop_folder_ref to drop_folder_path as alias
	-- get alias list of dropped items
	tell application "Finder"
		set dropped_items to every item of drop_folder_ref as alias list
		activate
	end tell
	-- move the added items back to original location and wait for update
	tell application "System Events" to keystroke "z" using command down
	delay 0.5 -- added this
	-- dropped_items are now in original loacation and references should reflect that
	my DoSomething(dropped_items)
	return
end run

on DoSomething(item_list)
	-- testing: look at original locations
	set string_list to {}
	repeat with this_item in item_list
		set end of string_list to this_item as string
	end repeat
	activate
	choose from list string_list
	return
end DoSomething

Here’s the Terminal scripts for loading and unloading in Terminal:

Still trying to figure out where and how to load besides doing it manually.

Edited: think I’ve found a way by using a helper app! :slight_smile:

Edited: it works! :smiley: Still testing, but here’s the helper AppleScript app:

repeat
	try
		do shell script "launchctl load /Users/kelhome/Library/LaunchAgents/com.apple.launchagent.plist"
		exit repeat
	on error
		-- continue repeat
		delay 2
	end try
end repeat
say "launch agent reloaded"

Save as non-stay open app. Here’s the modified DropletAppleScript:

property drop_folder_path : "Macintosh HD:Users:kelhome:Desktop:DropFolder:"

-- call this script from shell script
on run -- p -- parameters if needed
	set drop_folder_ref to drop_folder_path as alias
	-- get alias list of dropped items
	tell application "Finder"
		set dropped_items to every item of drop_folder_ref as alias list
		activate
	end tell
	-- move the added items back to original location and wait for update
	tell application "System Events" to keystroke "z" using command down
	delay 0.5 -- added this
	-- dropped_items are now in original loacation and references should reflect that
	my DoSomething(dropped_items)
	-- run helper app to reload
	ignoring application responses
		tell application "DropletHelper"
			launch
			run
		end tell
	end ignoring
	return
end run

on DoSomething(item_list)
	-- testing: look at original locations
	set string_list to {}
	repeat with this_item in item_list
		set end of string_list to this_item as string
	end repeat
	activate
	choose from list string_list
	return
end DoSomething

I think that should do it!!! :smiley: Thanks for all the help.

Edited: btw, everything needed is in this last post.

Edited: darn, there’s a bug. Now I have to debug this thing. :slight_smile: I think the delay after the undo is too low. changing the delay to 0.5 secs.

Edited: oops, already did that. Increasing to 1 sec.

Edited: added quick fix:

property drop_folder_path : "Macintosh HD:Users:kelhome:Desktop:DropFolder:"

-- call this script from shell script
on run -- p -- parameters if needed
	set drop_folder_ref to drop_folder_path as alias
	-- get alias list of dropped items
	tell application "Finder"
		set dropped_items to every item of drop_folder_ref as alias list
		activate
	end tell
	if dropped_items is not {} then -- ADDED THIS FOR BUG
		-- move the added items back to original location and wait for update
		tell application "System Events" to keystroke "z" using command down
		delay 1 -- added this
		-- dropped_items are now in original loacation and references should reflect that
		my DoSomething(dropped_items)
	end if
	-- run helper app to reload
	ignoring application responses
		tell application "DropletHelper"
			launch
			run
		end tell
	end ignoring
	return
end run

on DoSomething(item_list)
	-- testing: look at original locations
	set string_list to {}
	repeat with this_item in item_list
		set end of string_list to this_item as string
	end repeat
	activate
	choose from list string_list
	return
end DoSomething

See comments.

Edited: it is working well now. Also fairly quick. What was happening is that sometimes the scripts would run when nothing was added. So the items would jump back into the drop folder. If anyone finds a bug can you post it? Thanks. Also thinking about changing the helper to unload if the user wants to do that instead of using Terminal to unload. Also, forgot to check cpu usage, but the last time I checked it was very good.

Edited: note that there are many ways to rewrite this and a lot that is not necessary. For instance, you don’t really need the helper app. In fact, everything can be done with just the shell script I think.

gl,
kel

Update. Sorry about the short explanations, but everyone is sick with this new terrible cold virus. Still need to cook the chicken soup for everybody. :slight_smile: Also, donating recyclable items. Waiting for the picker uppers.

Don’t need the helper, but might add a toggled app to turn on/off the loading and unloading of the agent.

Here’s the AppleScript:

property drop_folder_path : "Macintosh HD:Users:kelhome:Desktop:DropFolder:"

-- call this script from shell script
on run -- p -- parameters if needed
	set drop_folder_ref to drop_folder_path as alias
	-- get alias list of dropped items
	tell application "Finder"
		set dropped_items to every item of drop_folder_ref as alias list
		activate
	end tell
	if dropped_items is not {} then
		-- move the added items back to original location and wait for update
		tell application "System Events" to keystroke "z" using command down
		delay 0.2
		-- dropped_items are now in original loacation and references should reflect that
		my DoSomething(dropped_items)
	end if
	return
end run

on DoSomething(item_list)
	-- testing: look at original locations
	set string_list to {}
	repeat with this_item in item_list
		set end of string_list to this_item as string
	end repeat
	activate
	choose from list string_list
	return
end DoSomething

Here’s the bash script:

You don’t need to load and unload until you want to do that.

Also, the agent doesn’t need the last key, because it is default. Wasn’t sure about that because of the changing in systems. Apple updated its docs. Think that was all, but if I have anything else, then will update post. Also, think I can crunch the setup more.

Edited: Also, trying to combine everything into one package. Doing some reading up on that.

Edited: also, trying to make the keystroke"z" invisible to users.

Edited: forgot about the third big job I had to do until I got the phone call to pick up materials. :confused: Done. Now just need to make the chicken soup and finish this. While I was driving it occurred to me that Python lists is more compatible with other forms of unix lists. If you return a python list to AppleScript, then it can easily be coerced to AppleScript list. The only difference is the square brackets as opposed to AppleScript curly brackets. So It is easy to pas lists between the two languages. Maybe there is something there. In fact, AppleScript will automatically coerce the square brackets. Something to think about.

Edited: I hope nobody gets what I wrote wrong. You can not pas list from unix to Applescript. The list is in string form. When you get the string in AppleScript, you need to ‘run script’ to change it for AppleScript to use as list.

Edited: e.g.

set t to "[1,2,3]"
set AppleScript_list to run script t

gl,
kel

Yeah, it is working great!

Now I can just drag my desktop items and put them into categories!

Thanks DJ for the great idea! My desktop was getting too full too quickly! Love it man. :smiley:

All I need to do is integrate the application into one place so I don’t accidentally trash a needed part of it. Reading up on bundles and packages.

Edited: oh and did I mention that I learned a lot!!! :smiley:

Later,
kel