FileManagerLib Features, etc

You’re seeing AppleScript in action. When the if exists... line is called, AppleScript’s result is first set to the NSURL of targetFile in the firstLine of the handler it calls:

on exists object aFileOrPath
	set aURL to my makeURLFromFileOrPath:aFileOrPath
	return (aURL's checkResourceIsReachableAndReturnError:(missing value)) as boolean
end exists object

Because the handler is called as part of an if statement, which do not return results, AppleScript’s result property remains unchanged, despite the actual result of the handler call being a boolean value.

This sort of thing can happen if either the return statement of a handler is followed by code rather than a variable as above, or where the handler has no return statement and its last line is code.

I’d take some convincing that it needs attending to. I could go through every handler and add an extra return line, but I’m not sure there’s any public benefit. I consider exposing quirks as educational :wink:

I now feel more educated. Thanks!

Have we talked about modification date? Would it be possible to get Modification Date and Creation Date added to parse objects command of fileManagerLib??

If not, is there a better (faster) way of getting those than Finder/System Events?

(Changed the name of this topic because we’ve gone way beyond that original post)

They’re easy enough to get via ASObjC:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set thePath to POSIX path of (choose file)
set theURL to current application's |NSURL|'s fileURLWithPath:thePath
set {theResult, theValue} to theURL's getResourceValue:(reference) forKey:(current application's NSURLContentModificationDateKey) |error|:(missing value)
set theDate to theValue as date

The other relevant keys are NSURLContentAccessDateKey and NSURLCreationDateKey.

I’m hesitant about adding them to the lib partly to avoid bloat, and partly because if I add a lot of properties to parse object, I risk slowing it down.

Is there a better (faster) way of doing this? I’m getting all the files in the entire contents of a directory, then filtering by a list of name extensions.

Entire Contents is fast, but going through the list to read the extensions takes forever and causes hangs (there are about 9k files).

I’m thinking I may try just using TIDs to get the extension from the path text, and maybe try to use one of those fancy script objects that Nigel showed us, but first I’m wondering if there’s not a simple solution I’m missing.

on FilterEntireContents(aFolder)
   
   set folderContents to objects of aFolder ¬
      searching subfolders true ¬
      include invisible items false ¬
      include folders false ¬
      include files true ¬
      result type files list
 
   set filteredContents to {}
   repeat with thisFile in folderContents
      set fileInfo to parse object thisFile as item 
      if name_extension of fileInfo is in {"wav", "band", "mp3", "m4p", "m4a"} then
         set the end of filteredContents to thisFile as item
      end if
   end repeat
   return filteredContents
   
end FilterEntireContents

This requires 10.11 or later, but should be pretty quick:

use AppleScript version "2.5" -- requirs 10.11 or later
use framework "Foundation"
use script "FileManagerLib" version "2.2.1"
use scripting additions

FilterEntireContents2("/Users/shane/Desktop")

on FilterEntireContents2(aFolder)
	
	set folderContents to objects of aFolder ¬
		searching subfolders true ¬
		include invisible items false ¬
		include folders false ¬
		include files true ¬
		result type urls array
	
	set thePred to current application's NSPredicate's predicateWithFormat:"pathExtension IN[c] %@" argumentArray:{{"wav", "band", "mp3", "m4p", "m4a"}}
	return (folderContents's filteredArrayUsingPredicate:thePred) as list
end FilterEntireContents2

But you can make it significantly faster by changing include folders to true. Assuming you don’t use extensions for folder names, the result will be the same. But importantly, when both include folders and include files are true, no time is spent separating folders from files and packages — and that’s what takes most of the time because it requires a repeat loop. I’m talking a factor of more than x10.

This script doesn’t work. I want to set the mod date of the files chosen by the users. Am I doing something wrong or is filemanagerlib not working ?


use script "FileManagerLib" version "2.3.2"
use scripting additions
set now to current date
set filesToFix to my chooseFiles()
repeat with thisFile in filesToFix
   modificationdate(thisFile as alias)
   change value for thisFile as alias ¬
      to now ¬
      property name modification property
   modificationdate(thisFile)
end repeat

on modificationdate(anyFile)
   set dateInfo to date info for anyFile
   return modification_date of dateInfo
end modificationdate

on chooseFiles()
   set myfiles to choose file with prompt "Pick files to change modification date" with multiple selections allowed
   return myfiles as list
end chooseFiles

I think you’ll find that it’s working in that the mod date is being changed (see in the Finder). The bug is that the result of date info for is incorrect: the values for modification_date and creation_date are reversed. I’ll get a fix out shortly. Version 2.3.3 is now available for download.

That was quick! Thanks!