On 26 Nov 2013, at 10:07 AM, Shane Stanley <email@hidden> wrote:
The Finder's sort command sorts from lowest to highest
And, as usual with the Finder, does it at a leisurely pace. Fortunately it's another thing Mavericks users no longer have to rely on the Finder for, courtesy of ASObjC-based libraries.
This handler is a bit more complicated, but most of the effort is in copying, pasting and saving in a library. It could do with someone defining some terminology to make it a bit easier to use, but it's not exactly rocket science to use as-is.
The handler requires a POSIX path for the folder, and boolean values for whether you want to include folders as well as files, whether to also search subfolders, and whether to sort in ascending order. And it takes a key to sort on, which is where it's a little more complicated. So:
use framework "Foundation"
on sortFolder:folderPosixPath byKey:theKey includeFolders:includeFolders entireContents:entireContents ascendingOrder:ascendingOrder set keysToRequest to {current application's NSURLPathKey, current application's NSURLIsDirectoryKey, theKey} -- keys for values we want from each item set theInfo to current application's NSMutableArray's array() -- array to store new values in set theURL to current application's NSURL's fileURLWithPath:folderPosixPath -- make URL for folder because that's what's needed set fileManager to current application's NSFileManager's defaultManager() -- get file manager set theOptions to ((current application's NSDirectoryEnumerationSkipsPackageDescendants) as integer) + ((current application's NSDirectoryEnumerationSkipsHiddenFiles) as integer) -- options to use when enumerating directory if not entireContents then -- extra option to skip deep search set theOptions to theOptions + ((current application's NSDirectoryEnumerationSkipsSubdirectoryDescendants) as integer) end if -- enumerate the folder set theEnumerator to fileManager's enumeratorAtURL:theURL includingPropertiesForKeys:keysToRequest options:theOptions errorHandler:(missing value) repeat set aURL to theEnumerator's nextObject() -- nextObject() returns the next URL held by the enumerator if aURL is missing value then exit repeat -- missing value means there are no more, so exit theInfo's addObject:(aURL's resourceValuesForKeys:keysToRequest |error|:(missing value)) -- get values and add to array end repeat if not includeFolders then -- filter out folders set thePred to current application's NSPredicate's predicateWithFormat_("%K != YES", current application's NSURLIsDirectoryKey) theInfo's filterUsingPredicate:thePred end if set theDescriptor to current application's NSSortDescriptor's sortDescriptorWithKey:theKey ascending:ascendingOrder -- describes the sort theInfo's sortUsingDescriptors:{theDescriptor} -- do the sort return (theInfo's valueForKey:(current application's NSURLPathKey)) as list -- extract paths and convert to list end sortFolder:byKey:includeFolders:entireContents:ascendingOrder:
And you'd call it like this:
use theLib : script "<lib name>" use scripting additions set theFiles to theLib's sortFolder:(POSIX path of (path to desktop)) byKey:(current application's NSURLContentModificationDateKey) includeFolders:false entireContents:false ascendingOrder:true
If you wanted files instead of POSIX paths, you could add:
repeat with i from 1 to count of theFiles set item i of theFiles to POSIX file (item i of theFiles) end repeat
The tricky bit is knowing the key to use. The main ones are: NSURLAttributeModificationDateKey, NSURLContentAccessDateKey, NSURLContentModificationDateKey, NSURLCreationDateKey, NSURLLabelColorKey, NSURLLabelNumberKey, NSURLLocalizedLabelKey, NSURLLocalizedTypeDescriptionKey, NSURLNameKey, NSURLTypeIdentifierKey, NSURLFileSizeKey, NSURLFileAllocatedSizeKey, NSURLTotalFileAllocatedSizeKey, and NSURLTotalFileSizeKey.
Why bother? On my Mac, with about 400-odd items on my desktop, the difference in times is about 1.3 seconds vs 0.08 seconds. If I instead set entireContents to true and do the equivalent for the Finder, the ASObjC method blows out to about 0.2 seconds, while the Finder spends two minutes thinking and then times out.
For a hoot, I tried this:
set theFiles to theLib's sortFolder:(POSIX path of (path to home folder)) byKey:(current application's NSURLContentModificationDateKey) includeFolders:false entireContents:true ascendingOrder:true
It took a bit over a minute, although returning the list of more than 90,000 items took quite a bit longer. I wouldn't want to try it with Finder... |