Thursday, December 5, 2019

#76 2019-08-22 04:54:03 pm

Nigel Garvey
Moderator
From:: Warwickshire, England
Registered: 2002-11-20
Posts: 5118

Re: Loading file list from a folder

And here's yet another variation.  smile  It's essentially the same as KniazidisR's, but it returns just the files' names as before, doesn't use a third-party library, and double-checks that none of the items with "pdf" extensions are folders. (KniazidisR's script can be made to exclude folders explicitly too by changing the include folders parameter value to false in his set folderContents … line.)

Applescript:

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

set source_folder to choose folder with prompt "Please select directory."
set kFileList to createList(source_folder)

on createList(mSource_folder)
   set |⌘| to current application
   
   set sourceURL to |⌘|'s class "NSURL"'s URLWithString:(POSIX path of mSource_folder)
   -- Get the folder's entire contents as a URL array.
   set theManager to |⌘|'s class "NSFileManager"'s defaultManager()
   set fileKey to |⌘|'s NSURLIsRegularFileKey
   set searchOptions to (get |⌘|'s NSDirectoryEnumerationSkipsPackageDescendants) + (get |⌘|'s NSDirectoryEnumerationSkipsHiddenFiles)
   set entireContents to (theManager's enumeratorAtURL:(sourceURL) includingPropertiesForKeys:({fileKey}) options:(searchOptions) errorHandler:(missing value))'s allObjects()
   
   -- Filter case-insensitively for items with "pdf" extensions.
   set PDFPred to |⌘|'s class "NSPredicate"'s predicateWithFormat:("pathExtension ==[c] 'pdf'")
   set URLArray to entireContents's filteredArrayUsingPredicate:(PDFPred)
   -- The result is probably just the files we want, but check for any folders among them while getting their paths.
   set pathArray to |⌘|'s class "NSMutableArray"'s new()
   repeat with thisURL in URLArray
       if ((thisURL's getResourceValue:(reference) forKey:(fileKey) |error|:(missing value))'s end as boolean) then
           tell pathArray to addObject:(thisURL's |path|())
       end if
   end repeat
   -- Sort the qualifying paths Finder-style.
   tell pathArray to sortUsingSelector:("localizedStandardCompare:")
   
   -- Return the file names from the sorted paths as an AS list.
   return (pathArray's valueForKey:("lastPathComponent")) as list
end createList


NG

Offline

 

#77 2019-08-22 09:34:25 pm

KniazidisR
Member
Registered: 2019-03-03
Posts: 756

Re: Loading file list from a folder

Nigel Garvey wrote:

And here's yet another variation.  smile  It's essentially the same as KniazidisR's, but it returns just the files' names as before, doesn't use a third-party library, and double-checks that none of the items with "pdf" extensions are folders. (KniazidisR's script can be made to exclude folders explicitly too by changing the include folders parameter value to false in his set folderContents … line.)



Ok, Nigel. It is OK that your script doesn't use a third-party library. And you can return file's names instead of files, but why double-checking? I know, that folders doesn't have "pdf" extensions. So, no need double-checking. And I do not specifically filter folders at the beginning, as this speeds up the search in subfolders several times.

Last edited by KniazidisR (2019-08-22 09:37:35 pm)


Model: MacBook Pro
macOS Mojave -- version 10.14.4
Safari -- version 12.1
Firefox -- version 70.0

Offline

 

#78 2019-08-22 10:47:02 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6062

Re: Loading file list from a folder

KniazidisR wrote:

This works, keeping the order, searching in subfolders, and giving files list instead of its base names list:



If you change the result type of the objects of command to urls array you don't need to then create an array. It saves the library converting an array of URLs into a list of «class furl» which you then just convert back.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#79 2019-08-23 02:32:44 am

Nigel Garvey
Moderator
From:: Warwickshire, England
Registered: 2002-11-20
Posts: 5118

Re: Loading file list from a folder

KniazidisR wrote:

I know, that folders doesn't have "pdf" extensions.


It's very unlikely, that's true.  smile  But not impossible. I decided to put in a check just in case, combining this with the initial building of the mutable array.

And I do not specifically filter folders at the beginning, as this speeds up the search in subfolders several times.


I'm not surprised. The only way in ASObjC (which both Shane's library and my script use) to differentiate between folders, files, and other types in an array of NSURLs is with an AS repeat. This has to check the relevant resource value(s) in each individual URL and build a new collection of items which pass the test. If you leave this out, it can save some time.

My script filters for "pdf" extensions before testing the resource values, so the number of items in the AS repeat is reduced — although by how much obviously depends on how many items are eliminated by the "pdf" filter. You could do something similar in your script, although it might take fractionally longer as the resource values won't have been cached when the URLs were fetched:

Applescript:


use AppleScript version "2.5"
use framework "Foundation"
use script "FileManagerLib" version "2.2.2"
-- <https://www.macosxautomation.com/applescript/apps/FileManagerLib_stuff.zip>
use scripting additions

property NSPredicate : a reference to NSPredicate of current application
property NSMutableArray : a reference to NSMutableArray of current application

set theRootFolder to choose folder with prompt "Please select directory."
set theRootFolderPosixPath to POSIX path of theRootFolder

set folderContents to objects of theRootFolderPosixPath ¬
   result type urls array ¬
   with searching subfolders, include folders and include files without include invisible items

set URLArray to folderContents's mutableCopy()

-- Filter for items with "pdf" extensions.
set PDFPred to NSPredicate's predicateWithFormat:("pathExtension ==[c] 'pdf'")
URLArray's filterUsingPredicate:PDFPred
-- Remove any non-files from the array.
set fileKey to current application's NSURLIsRegularFileKey
repeat with i from (count URLArray) to 1 by -1
   set thisURL to item i of URLArray
   if not ((thisURL's getResourceValue:(reference) forKey:(fileKey) |error|:(missing value))'s end as boolean) then
       (URLArray's removeObjectAtIndex:(i - 1))
   end if
end repeat
-- Sort the remaining URLs on their paths.
set sortDescriptor to current application's NSSortDescriptor's sortDescriptorWithKey:("path") ascending:(true) selector:("localizedStandardCompare:")
URLArray's sortUsingDescriptors:({sortDescriptor})

set theFiles to URLArray as list


NG

Offline

 

#80 2019-08-23 05:18:40 am

KniazidisR
Member
Registered: 2019-03-03
Posts: 756

Re: Loading file list from a folder

Thanks, Shane. Thanks, Nigel. I removed everything unnecessary. My final script:

Applescript:


use AppleScript version "2.5"
use framework "Foundation"
use script "FileManagerLib" version "2.2.2"
-- <https://www.macosxautomation.com/applescript/apps/FileManagerLib_stuff.zip>
use scripting additions

property NSPredicate : a reference to NSPredicate of current application
property NSSortDescriptor : a reference to NSSortDescriptor of current application

set theRootFolder to choose folder with prompt "Please select directory."
set theRootFolderPosixPath to POSIX path of theRootFolder

set URLArray to ¬
   objects of theRootFolderPosixPath ¬
       searching subfolders true ¬
       include invisible items false ¬
       include folders true ¬
       include files true ¬
       result type urls array

set PDFPred to NSPredicate's predicateWithFormat:("pathExtension ==[c] 'pdf'")
URLArray's filterUsingPredicate:PDFPred

set sortDescriptor to NSSortDescriptor's sortDescriptorWithKey:("path") ascending:(true) selector:("localizedStandardCompare:")
URLArray's sortUsingDescriptors:({sortDescriptor})

set theFiles to URLArray as list

Last edited by KniazidisR (2019-08-23 06:00:28 am)


Model: MacBook Pro
macOS Mojave -- version 10.14.4
Safari -- version 12.1
Firefox -- version 70.0

Offline

 

#81 2019-09-15 01:23:24 pm

KniazidisR
Member
Registered: 2019-03-03
Posts: 756

Re: Loading file list from a folder

Hi, everyone.

My script above works fine, but I would like the user to have a choice without using third-party libraries. In addition, Nigel tried to do this above, but didn’t quite finish the script to the end; his scripts return Posix paths instead of files. And his last script was very close to the goal, but unfortunately, it throws an error when sorting.

I only needed to make 1-2 changes for his version (which is now better from my) to work perfect. 1) It does not use a third-party library, 2) it filters out package files and 3) it filters out "strange" folders with "extensions".

Applescript:


use framework "Foundation"
use scripting additions

property |⌘| : a reference to current application
property NSPredicate : a reference to NSPredicate of |⌘|
property NSFileManager : a reference to NSFileManager of |⌘|
property |NSURL| : a reference to |NSURL| of |⌘|
property NSMutableArray : a reference to NSMutableArray of |⌘|
property NSURLIsRegularFileKey : a reference to NSURLIsRegularFileKey of |⌘|
property NSSortDescriptor : a reference to NSSortDescriptor of |⌘|
property NSDirectoryEnumerationSkipsPackageDescendants : a reference to 2
property NSDirectoryEnumerationSkipsHiddenFiles : a reference to 4

set sourceFolder to POSIX path of (choose folder with prompt "PLEASE, SELECT FOLDER")
set sourceURL to |NSURL|'s URLWithString:sourceFolder

set fileManager to NSFileManager's |defaultManager|()
set fileKey to NSURLIsRegularFileKey
set searchOptions to (NSDirectoryEnumerationSkipsPackageDescendants) + (NSDirectoryEnumerationSkipsHiddenFiles)

-- Get entire contents of folder, includung contents of subfolders, without packages and hidden files
set entireContents to (fileManager's enumeratorAtURL:(sourceURL) includingPropertiesForKeys:({fileKey}) options:(searchOptions) errorHandler:(missing value))'s allObjects()

-- Filter case-insensitively for items with "pdf" extensions.
set thePredicate to NSPredicate's predicateWithFormat:("pathExtension ==[c] 'pdf'")
set urlArray to entireContents's filteredArrayUsingPredicate:(thePredicate)

-- The result is probably just the files we want, but check for any folders among them while getting their paths.
set theFiles to NSMutableArray's new()
repeat with theURL in urlArray
   if ((theURL's getResourceValue:(reference) forKey:(fileKey) |error|:(missing value))'s end as boolean) then tell theFiles to addObject:(theURL)
end repeat

-- Sort the remaining URLs on their paths.
set sortDescriptor to NSSortDescriptor's sortDescriptorWithKey:("path") ascending:(true) selector:("localizedStandardCompare:")
theFiles's sortUsingDescriptors:({sortDescriptor})

set theFiles to theFiles as list

Last edited by KniazidisR (2019-09-15 09:35:29 pm)


Model: MacBook Pro
macOS Mojave -- version 10.14.4
Safari -- version 12.1
Firefox -- version 70.0

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)