On 12/03/2013, at 12:20 PM, Brian Christmas <email@hidden> wrote:
Any thoughts on how to fix it anyone?
So it looks like our old friend the Finder.
But first, this line:
get folders of folder mailmanagerdesktopfolder whose label index ≠ 0 # this takes 37 seconds
is just, well, lazy. You have just looped through mailmanagerdesktopfolder setting the label indexes of its subfolders, so you could have made a list of all those you set to other than 0 as you went, avoiding the need to talk to the Finder again.
But the real solution is probably to give up on the Finder. You don't need it any more: use NSFileManager and NSURL.
Start with labelling. The NSURL class lets you get and set the label index easily enough, and you can make an NSURL from a POSIX path. So here are two potential handlers:
on useLabel_forPath_(labelNum, posixPath) set theURL to current application's NSURL's fileURLWithPath_(posixPath) tell theURL to setResourceValue_forKey_error_(labelNum, current application's NSURLLabelNumberKey, missing value) end useLabel_forPath_
on findLabelForPath_(posixPath) set theURL to current application's NSURL's fileURLWithPath_(posixPath) set {theFlag, theValue} to theURL's getResourceValue_forKey_error_(reference, current application's NSURLLabelNumberKey, missing value) return theValue as integer end findLabelForPath_
The other thing you're using the Finder for is getting the contents of folders, and for that you use NSFileManager. You get an instance of it via the class method defaultManager(), and use the result.
There are a couple of methods of getting the contents. The simplest is contentsOfDirectoryAtPath_error_, which gives you the names of the files in the folder. But it will probably be more efficient to use contentsOfDirectoryAtURL_includingPropertiesForKeys_options_error_. It sounds more daunting, but (a) it returns URLs, which means you can avoid making them in the handlers earlier, and (b) includingPropertiesForKeys_ can tell it to pre-fetch the label numbers at the same time, so they are cached for when we want them. The options_ also lets you specify the depth (in this case exclude the contents of subfolders), and whether to ignore invisible files.
So here are two methods, depending on whether you are dealing with a POSIX path or a URL:
on urlsInFolder_(posixPath) set theURL to current application's NSURL's fileURLWithPath_(posixPath) return urlsInURL_(theURL) end urlsInFolder_
on urlsInURL_(theURL) set fileManager to current application's NSFileManager's defaultManager() set theOptions to ((current application's NSDirectoryEnumerationSkipsHiddenFiles) as integer) + ((current application's NSDirectoryEnumerationSkipsSubdirectoryDescendants) as integer) + ((current application's NSDirectoryEnumerationSkipsPackageDescendants) as integer) set theURLs to fileManager's contentsOfDirectoryAtURL_includingPropertiesForKeys_options_error_(theURL, {current application's NSURLLabelNumberKey}, theOptions, missing value) return theURLs as list end urlsInURL_
You should then rework the first two handlers that can deal directly with URLs too, so:
on useLabel_forPath_(labelNum, posixPath) set theURL to current application's NSURL's fileURLWithPath_(posixPath) useLabel_forURL_(labelNum, theURL) end useLabel_forPath_
on useLabel_forURL_(labelNum, theURL) tell theURL to setResourceValue_forKey_error_(labelNum, current application's NSURLLabelNumberKey, missing value) end useLabel_forURL_
on findLabelForPath_(posixPath) set theURL to current application's NSURL's fileURLWithPath_(posixPath) return findLabelForURL_(theURL) end findLabelForPath_
on findLabelForURL_(theURL) set {theFlag, theValue} to theURL's getResourceValue_forKey_error_(reference, current application's NSURLLabelNumberKey, missing value) return theValue as integer end findLabelForURL_
Now get rid of the Finder, use POSIX paths, and call the relevant handlers.
|