PDA

View Full Version : AppleScript Droplets and Large Folders




haravikk
Mar 27, 2012, 09:33 AM
Hi there!

I've written a simple AppleScript droplet for hiding file extensions on multiple items (see below). However, I've got a couple of oddities.

Firstly, if I drop a folder onto the droplet, then the folder is copied, with the new copy having had all the extensions hidden. While the resulting folder is exactly what I wanted, I'm really rather hoping to edit the existing files, as if I did this to, say, a folder full of movies, then it would take a huge amount of time just to hide some file extensions! If it's relevant, I've added the droplet onto the toolbar in the Finder so I can easily drop items onto it.

Secondly, if I drop a very large number of files onto the droplet by selecting the files (rather than the enclosing folder) then the droplet seems to just crash. In a recent example I dropped 500+ images onto it, but it seemed only hide the extension of a single file before becoming completely unresponsive; while I can understand it taking a long time, I can't see why it would fail entirely, but I've left it running for well five minutes with nothing happening. For less than 100 items it just flies through and runs seemingly instantaneously.

Anyway, here's the AppleScript I've written; I've seen more complex ones out there that process the folders into a massive list of files before processing that, but I thought that this was much simpler, and seemed to work just as effectively (the more complex scripts have the same basic problems).

on open (ItemList)
tell application "Finder"
repeat with thisItem in ItemList
if kind of thisItem is "folder" then
set extension hidden of every file of entire contents of (thisItem as alias) to true
else
set extension hidden of thisItem to true
end if
end repeat
end tell
end open

P.S - couldn't find out if there's a way to format code tags for AppleScript?



Mark FX
Mar 28, 2012, 02:54 PM
Firstly you should implement some error checking in your script, this may give
you an idea of what's going wrong, and is also good programming practice.

Try changing to something like this.


on open (ItemList)
tell application "Finder"
repeat with thisItem in ItemList
try
if kind of thisItem is "folder" then
set extension hidden of every file of entire contents of (thisItem as alias) to true
else
set extension hidden of thisItem to true
end if
on error error_message number error_number
display alert error_message & space & error_number message ¬
"An error occured while trying to hide the extension of file" & return & ¬
thisItem & return & "Try increasing the delay time between actions." as warning giving up after 30
exit repeat
end try
delay 0.5
end repeat
end tell
end open


the alert message might give some clues to the problem.

Secondly Applescript is famously slow, especialy when communicating with
other applications, its well known in the Applescript community that you should
allow time in your code, for the scriptable application to react, and carry out
the commands on each file item, before moving on to the next one.
So I have added a delay command to allow the "Finder" time to treat the first
file, before moving on, I've set the delay to half a second, but you may have
to increase that to one second, or more.
The downside of the delay, is that the script will take even longer, but it might
at least work.

If you still have problems with the script, I would recommend you visit the
Macscripter forums, at the link below, there are some real Applescript experts
over there, I'm sure one of them can solve your problems.

http://macscripter.net/

Hope this helps.

Regards Mark

haravikk
Mar 28, 2012, 03:22 PM
Thanks for replying! Unfortunately I've already tried adding some error checks to no avail; as far as I can tell nothing is failing, it just… stops working.

It doesn't even seem like it's just running very slowly, as nothing seems to be happening at all.

I might try Macscripter, it's just a very odd issue though as nothing seems to be wrong.

kryten2
Mar 28, 2012, 06:10 PM
You might want to take a look at the SetFile command. I tried this script on a folder with 500 files with 10 different file extensions. Files were made with the touch command to test . It runs a bit slow on my PowerPC G4 Mac mini but shouldn't be a problem on your Mac Pro.


on open these_items
repeat with i from 1 to the count of these_items
set this_item to item i of these_items
set the item_info to info for this_item
if folder of the item_info is true then
process_folder(this_item)
else
if (folder of the item_info is false) then
process_item(this_item)
end if
end if
end repeat
end open

-- this sub-routine processes folders
on process_folder(this_folder)
set these_items to list folder this_folder without invisibles
repeat with i from 1 to the count of these_items
set this_item to alias ((this_folder as Unicode text) & (item i of these_items))
set the item_info to info for this_item
if folder of the item_info is true then
process_folder(this_item)
else
if (alias of the item_info is false) then
process_item(this_item)
end if
end if
end repeat
end process_folder

-- this sub-routine processes files
on process_item(this_item)
-- NOTE that the variable this_item is a file reference in alias format
-- FILE PROCESSING STATEMENTS GOES HERE
set this_item to POSIX path of this_item
do shell script "SetFile -a E " & this_item
end process_item

Second test with 1500 files runs without a problem. No folder is copied when dropping a folder. Dropping files is a little bit quicker.

haravikk
Mar 29, 2012, 04:51 AM
Thanks kryten2, that works beautifully! It is still a bit slow even on my Mac Pro, but it makes steady progress unless using the Finder command to hide extension.

I only made one minor change, which is to change the second last line to:
do shell script "SetFile -a E \"" & this_item & "\""
As it wasn't handling spaces, but it otherwise works perfectly!

I wonder; would it be faster if more of the work was done in the shell, for example if accumulated files into blocks of 10 or so, and then ran SetFile on them all in one go? I might experiment a little with it.

kryten2
Mar 29, 2012, 02:51 PM
Sorry I forgot about handling spaces. You can solve this by changing this line :
set this_item to POSIX path of this_item
into
set this_item to quoted form of POSIX path of this_item

Applescript always slows things down and the Finder even more so. That's why I left Finder out of the script.
A little shell script takes only a few seconds to complete. Tested with 1500 and 2500 files.
My shell scripting is a bit rusty but try this :

#!/bin/bash
for ext in asf avi gif jpg mkv mp4 pdf png tgz tif
do
SetFile -a E *.$ext
done


Change for your file extensions you want to process.
Save as somefile and chmod +x somefile, put it in the folder where the files are and let it rip.:D

Or a more general script. Copy to /bin or somewhere in your PATH.

#!/bin/bash
NR_ARGS=2

if [ $# -lt "$NR_ARGS" ] # Script invoked with less than 2 command-line args?
then
echo "The script requires at least 2 arguments."
echo "Usage: `basename $0` /some/path/to/folder 1stext 2ndext 3rdext ..."
echo "Example: `basename $0` /Users/test/Documents/TestExtensions jpg pdf ..."
exit # Exit and explain usage.
fi
#echo Name of script is $0
#echo First argument is $1
#echo Number of arguments is $#
#echo All command-line arguments : $@
cd $1
shift
for ext in "$@"
do
SetFile -a E *.$ext
done