Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

On Open theItems returns wrong count of items

The On Open block in my applescript is not behaving reliably. I'm dropping up to 8 files on it and sometimes it thinks there are two sets (for example, if I select 8 files and drop on the script application, it thinks there is 1 set of 3 files and one set of 5 files).


It's very frustrating.


I am trying to combine the Finder comments of a small group of files and put the combined set onto a single file. I've written the following script to do that, and it works most of the time. To test it out you have to drag a group of files with Finder comments onto the icon, then after it's done you drag the file you want the combined comments assigned to onto the script app.


The problem is that when you drop 8 files on the script, *sometimes* it runs thru the open block twice with two different sets of files (that combined add up to the dropped set).


This messes up the aggregation of the comments, so when you go to assign the comments to the new file, you only get the second part of the comments.


is that clear? anyway, here's the script. if you see any reason why it would be running the open block more than once when you drop a few files on it, let me know. I'm running Yosemite 10.10.1 on a brand new Mac Mini with a fusion drive. I have seen similar on open problems on my MBA and in Mavericks. Any clues?


-------


property mainComment : ""

property itemList : {}



on open theItems

delay 1


set howMany to count of theItems

-- display dialog howMany


if howMany > 1 then -- when more than 1 file is dropped, combine the Finder comments

set mainComment to ""

set itemList to {}

repeat with theItem in theItems

tell application "Finder"

set myComment to comment of theItem

set wordCount to the number of words in myComment

if wordCount > 1 then

repeat with x from 1 to wordCount

set thisWord to word x of myComment



if itemList does not contain thisWord then

set itemList to itemList & thisWord

end if

end repeat

end if

end tell

end repeat

repeat with myWord in itemList

set mainComment to mainComment & " " & myWord as text

end repeat


else -- when only 1 file is dropped, set the Finder comments

display dialog mainComment

tell application "Finder"

set comment of (item 1 of theItems) to mainComment

end tell


end if

end open

Posted on Dec 31, 2014 12:39 PM

Reply
8 replies

Jan 1, 2015 12:36 PM in response to Paul Adams5

This does seem strange - and I couldn't see any explanation, but it does seem like the open function in the Finder has changed (has a bug?).


In short, the Finder is not doing what you expect. It is not invoking your script and passing in all the files. It's chunking the files and invoking your script multiple times, each with a subset of the files.


In other words, it's nothing to do with your script. You can simplify your script significantly and see the problem:


on open of theFiles



display dialog (counttheFiles)


delay 2

end open


Save this script as an app and then drop any number of files on the app icon - you'll get a dialog showing how many files the script was handed - If I drop 3 files the script gets called twice - once with two files and then again with the remaining one - and that one, of course, triggers your action to set the comments.


Off hand I can't see any way to predict or understand how it's breaking down the files. Without that you're going to have a hard time running the script in this way.


The best (or, at least, first) alternative I can think of is to break your workflow into two separate functions - one that gathers the comments and stores them, and another, separate, script that sets the comment (and clears the store). It's more complex since you're passing data between two scripts, but it will avoid this problem.

Jan 1, 2015 3:16 PM in response to Camelot

I think this is normal (if unfortunate). I'm guessing the system gets notifications of each individual file system change an aggregates them into groups to send to the application according to some internal cutoff value; differences in latency at any given time would give inconsistent outcomes.


I agree with Camelot's suggestion, except that I don't think you need two scripts. Make it a stay-open application script, add in an on idle handler, and combine results until no new files have arrived for a half-second or so:


global itemList, itemCount

on idle

if (count of itemList) > itemCount then

set itemCount to (get count of itemList)

return 0.5

else


-- do whatever you do with the itemList

set itemCount to -1

set itemList to {}


quit

return 1

end if

end idle

that should account for any irregularities, and shouldn't cause any over-aggregations unless you're really quick with the mouse.

Jan 2, 2015 11:09 AM in response to Paul Adams5

Hello


Please file a bug report because droplet should not behave that way. At least under 10.6.8, it does differently.


Since you're observing that, e.g., given 8 items passed on droplet, firstly 3 of them are processed and then the remaining 5 are processed and only the comments of the latter 5 are stored in property at end, it appears that those items are processed in multi-threads without locking shared resource, i.e., the properties in this case. I consider such implementation is simply broken.


Since it is currently broken beyond repair, you'd need some workaround. For instance, storing collected comments in a file in droplet bundle may help. But you'd need to be very carefull in collecting distinct words because, if multiple instances of the script are to be run asynchronously, instance 2 might read the shared file before instance 1 writes collected words to the file and thus instance 2 may collect the duplicate words that instance 1 has aleardy collected.


Here's an example workround droplet code which has two operation modes – one is triggered by dropping items onto the droplet and to collect words in comment of dropped items regardless of the duplicates; and other is triggered by double clicking the droplet and to collect distinct words in the stored words and set the comment of the file/folder chosen by choose file or choose folder commands.


Collected words are stored in Contents/Resources/comments.txt in droplet bundle.



property |STORE_NAME| : "comments.txt" on open aa collect_comments(aa) end open on run set_comment() end run on collect_comments(aa) script o property cf : (path to me)'s POSIX path & "Contents/Resources/" & |STORE_NAME| property pp : (do shell script "f=" & cf's quoted form & ";touch \"$f\"; cat \"$f\"")'s words property qq : {} -- collect words in comments regardless of duplicates repeat with a in aa tell application "Finder" to set qq to (get a's comment)'s words repeat with q in my qq set my pp's end to q's contents end repeat end repeat set c to "" repeat with p in pp set c to c & p & space end repeat do shell script "printf '%s' " & c's quoted form & " >> " & cf's quoted form end script tell o to run end collect_comments on set_comment() script o property cf : (path to me)'s POSIX path & "Contents/Resources/" & |STORE_NAME| property pp : (do shell script "f=" & cf's quoted form & ";touch \"$f\"; cat \"$f\"")'s words property qq : {} property btts : {"Cancel", "Clear", "Set"} property opts : {"Folder", "File"} -- reduce stored words (remove duplicates) repeat with p in my pp set p to p's contents if p is not in my qq then set my qq's end to p end repeat set c to "" repeat with q in qq set c to c & q & space end repeat do shell script "printf '%s' " & c's quoted form & " > " & cf's quoted form display dialog c with title "Stored words" buttons btts default button 3 set b to result's button returned if b = btts's item 1 then -- user cancel error number -128 else if b = btts's item 2 then -- clear stored words do shell script ": > " & cf's quoted form else -- set comment to stored words set r to choose from list opts default items {opts's item 2} with prompt "Set comment of" if r = false then error number -128 -- user cancel set r to r's item 1 if r = opts's item 1 then set f to choose folder else set f to choose file end if tell application "Finder" to set f's comment to c end if end script tell o to run end set_comment



Only tested under OS X 10.6.8.


Good luck,

H



EDIT: fixed code

Nov 12, 2015 6:30 PM in response to Hiroto

I am experiencing something similar in my 'on open' handler in a droplet. It's for processing a collection of URL files.

onopenweblocs

display alert (countofweblocs)

endopen

I've made a the simplest possible example and it often does run multiple times when dropping more than one file on it. It was driving me batty trying to understand why it would throw up two debugging alert boxes when the code only had one display alert. After some time I noticed that the icon animations when dropping the files on the droplet looked like two clusters of files animating

Here is what I have observed. These are observations, maybe not facts.

Dropping files of the same type will trigger it to run only once--even with many (13) files.


Dropping files of two different types will cause it to run twice. Each time the handler reports the correct count of files of each type. So if I drop 4 .webloc files and 3 .jpg files I get two alert boxes showing '4' and '3'. This seems very repeatable when testing with varying numbers of .webloc and .jpg files.


Some combinations of different file types will only trigger the handler once. In my testing, .png and .pdf seem to be ok together.


One last thing. The handler apparently will not run more than twice. If too many types of files are dropped on the droplet, the sum of the numbers reported in the alert box does not equal the number of files dropped.

Nov 12, 2015 7:30 PM in response to Camelot

This is misbehaving on El Capitan 10.11.1. Dropped 5 documents, got two display dialogs of 2, and no display dialog count for the fifth document.


However, if you set up the script to request multiple file selections on a double-click of the application, and then pass that list of files on to the on open handler, then you get correct file counts. I have tested this with varying numbers of selected files and the count is always accurate.


property default_loc : (path to desktop)


on run

set theObjects to (choose filedefault locationdefault_loc with multiple selections allowed without showing package contents)

opentheObjects

return

end run


on opentheObjects

display dialog (count of theObjects) as text

return

end open

On Open theItems returns wrong count of items

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.