Here is a redesigned version of the code using ASObjC.
use AppleScript version "2.4" # requires at least Yosemite
use scripting additions
use framework "Foundation"
on run
my organize(choose folder)
end run
on open sel
set theMainFolder to item 1 of sel
if (my fileTypeOf:theMainFolder) ≠"folder" then error "Must drop a folder"
my organize(theMainFolder)
end open
on organize(theMainFolder)
local mainURL, |⌘|, fileManager, directoryContents, theRegEx, rootURL, itsName, theResult, isDirectory, theError
local isPackage, theFinds, theRange, |length|, destName, theSourceURL, theDestURL, theFinalURL
set mainURL to my makeURLFromFileOrPath:theMainFolder
set |⌘| to current application
set fileManager to |⌘|'s NSFileManager's defaultManager()
set directoryContents to fileManager's contentsOfDirectoryAtURL:mainURL includingPropertiesForKeys:{} options:0 |error|:(missing value)
# define the regex once
set theRegEx to (|⌘|'s NSRegularExpression's regularExpressionWithPattern:"^[0-9][0-9][0-9][_][^ ]*[_]" options:0 |error|:(missing value))
repeat with rootURL in directoryContents
set itsName to rootURL's |lastPathComponent|()
if (itsName as text) does not start with "." then
set {theResult, isDirectory, theError} to (rootURL's getResourceValue:(reference) forKey:(|⌘|'s NSURLIsDirectoryKey) |error|:(reference))
if not (theResult as boolean) then error (theError's |localizedDescription|() as text)
if isDirectory as boolean then
set {theResult, isPackage, theError} to (rootURL's getResourceValue:(reference) forKey:(|⌘|'s NSURLIsPackageKey) |error|:(reference))
if not (theResult as boolean) then error (theError's |localizedDescription|() as text)
if not (isPackage as boolean) then
# try to extract : 3 digits, an underscore, some characters ≠space, an underline starting from the beginning of the string itsName
set theFinds to (theRegEx's matchesInString:itsName options:0 range:{location:0, |length|:itsName's |length|()})
if (count of theFinds) > 0 then
# the name matches our requirements
set theRange to (item 1 of theFinds)'s range()
set |length| of theRange to (|length| of theRange) - 1 # must drop the ending underscore
set destName to (itsName's substringWithRange:theRange)
set theSourceURL to (mainURL's URLByAppendingPathComponent:itsName)
set theDestURL to (mainURL's URLByAppendingPathComponent:destName)
# creates the folder if it doesn't exist, do nothing if it exists
set {theResult, theError} to (fileManager's createDirectoryAtURL:theDestURL withIntermediateDirectories:true attributes:(missing value) |error|:(reference))
if not (theResult as boolean) then error (theError's |localizedDescription|() as text)
set theFinalURL to (theDestURL's URLByAppendingPathComponent:itsName)
(my moveFromURL:theSourceURL toURL:theFinalURL withReplacing:true)
end if
end if
end if
end if
end repeat
end organize
#=====#=====#=====#=====#=====#=====
# Some ASObjC handlers borrowed to Shane STANLEY
#=====#=====#=====#=====#=====#=====
on fileTypeOf:aFileOrPath # use makeURLFromFileOrPath
local |⌘|, theSourceURL, theResult, isDirectory, theError, isPackage
set |⌘| to current application
set theSourceURL to my makeURLFromFileOrPath:aFileOrPath
set {theResult, isDirectory, theError} to theSourceURL's getResourceValue:(reference) forKey:(|⌘|'s NSURLIsDirectoryKey) |error|:(reference)
if not (theResult as boolean) then error (theError's |localizedDescription|() as text)
if isDirectory as boolean then
set {theResult, isPackage, theError} to theSourceURL's getResourceValue:(reference) forKey:(|⌘|'s NSURLIsPackageKey) |error|:(reference)
if not (theResult as boolean) then error (theError's |localizedDescription|() as text)
if (isPackage as boolean) then
return "package"
else
return "folder"
end if
end if
return "file"
end fileTypeOf:
#=====
-- This handler is called by other handlers, and is not meant to called directly
on makeURLFromFileOrPath:theFileOrPathInput
-- make it into a Cocoa object for easier comparison
set theFileOrPath to item 1 of (current application's NSArray's arrayWithObject:theFileOrPathInput)
if (theFileOrPath's isKindOfClass:(current application's NSString)) as boolean then
if (theFileOrPath's hasPrefix:"/") as boolean then -- full POSIX path
return current application's class "NSURL"'s fileURLWithPath:theFileOrPath
else if (theFileOrPath's hasPrefix:"~") as boolean then -- POSIX path needing ~ expansion
return current application's class "NSURL"'s fileURLWithPath:(theFileOrPath's |stringByExpandingTildeInPath|())
else -- must be HFS path
return current application's class "NSURL"'s fileURLWithPath:(POSIX path of theFileOrPathInput)
end if
else if (theFileOrPath's isKindOfClass:(current application's class "NSURL")) as boolean then -- happens with files and aliases in 10.11
return theFileOrPath
else -- must be a file or alias
return current application's class "NSURL"'s fileURLWithPath:(POSIX path of theFileOrPathInput)
end if
end makeURLFromFileOrPath:
#=====#=====#=====#=====#=====#=====
-- This handler is called by other handlers, and is not meant to called directly
on moveFromURL:sourceURL toURL:destinationURL withReplacing:replaceFlag
set |⌘| to current application
set theFileManager to |⌘|'s NSFileManager's |defaultManager|()
set {theResult, theError} to (theFileManager's moveItemAtURL:sourceURL toURL:destinationURL |error|:(reference))
if not theResult as boolean then
if replaceFlag and (theError's code() = |⌘|'s NSFileWriteFileExistsError) then -- it already exists, so try replacing
-- replace existing file with temp file atomically, then delete temp directory
set {theResult, theError} to theFileManager's replaceItemAtURL:destinationURL withItemAtURL:sourceURL backupItemName:(missing value) options:(|⌘|'s NSFileManagerItemReplacementUsingNewMetadataOnly) resultingItemURL:(missing value) |error|:(reference)
-- if replacement failed, return error
if not theResult as boolean then error (theError's |localizedDescription|() as text)
else -- replaceFlag is false or an error other than file already exists, so return error
error (theError's |localizedDescription|() as text)
end if
end if
end moveFromURL:toURL:withReplacing:
#=====#=====#=====#=====#=====#=====
Yvan KOENIG running Sierra 10.12.3 in French (VALLAURIS, France) jeudi 9 mars 2017 15:40:59