I’m trying to automate a time consuming process that I’ve been doing by hand. Essentially I need to be able to drop a folder on a script and have it find a move files that are created from a panorama stitching program called PtGui.
PTGui is great right up until you want to automate the naming and placement of your created files.
I would like to have a droplet that finds these files and if they’re in the wrong folder (something)_Hdri_Raw: I would like to take take the .hdr .pts and .mov file and move them into a new folder within the parent folder called (Parent Folder)_Stitched. I would also like to rename the three files (Parent Folder)_Stitched
Assuming you drag-and-drop the _HDRI folder, something like this:
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
on open {theFolder}
set posixPath to POSIX path of theFolder
set folderURL to current application's |NSURL|'s fileURLWithPath:posixPath
-- create _Stitched folder if necessary
set folderName to folderURL's lastPathComponent()
set stitchedFolderURL to (folderURL's URLByAppendingPathComponent:(folderName's stringByAppendingString:"_Stitched"))
(fileManager's createDirectoryAtURL:stitchedFolderURL withIntermediateDirectories:true attributes:(missing value) |error|:(missing value))
-- make file manager
set fileManager to current application's NSFileManager's new()
-- get contents of _Raw folder
set rawFolderURL to (folderURL's URLByAppendingPathComponent:(folderName's stringByAppendingString:"_Raw"))
set theURLs to fileManager's contentsOfDirectoryAtURL:rawFolderURL includingPropertiesForKeys:{} options:(current application's NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)
-- filter files you want to move
set thePred to current application's NSPredicate's predicateWithFormat_("pathExtension IN %@", {"pts", "mov", "hdr", "exr"})
set theURLs to (theURLs's filteredArrayUsingPredicate:thePred)
-- move them
repeat with aURL in theURLs
set newName to aURL's lastPathComponent()
(fileManager's moveItemAtURL:aURL toURL:(stitchedFolderURL's URLByAppendingPathComponent:newName) |error|:(missing value))
end repeat
end open
Your sample suggests you might also want the file names changed, in which case the last repeat in the above would instead probably need to be something like:
repeat with aURL in theURLs
set newName to ((folderName's stringByAppendingString:"_Raw_Stitched")'s stringByAppendingPathExtension:(aURL's pathExtension()))
(fileManager's moveItemAtURL:aURL toURL:(stitchedFolderURL's URLByAppendingPathComponent:newName) |error|:(missing value))
end repeat
Thanks for this! Is there a way this script could be modified to be able to drop a higher level folder than just the _hdri folder–have it repeat for each subfolder by looking for folders ending with “_Hdri_Raw” ?
That way it could quickly run through dozens or even hundreds of folders with minimal interaction?
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
on open {theFile}
set posixPath to POSIX path of theFile
set theNSURL to current application's |NSURL|'s fileURLWithPath:posixPath
my checkFolderURL:theNSURL
set theNSURL to missing value
display dialog "Finished." buttons {"OK"} default button 1
end open
on checkFolderURL:folderURL
-- make file manager
set fileManager to current application's NSFileManager's new()
-- get contents of folder
set theURLs to fileManager's contentsOfDirectoryAtURL:folderURL includingPropertiesForKeys:{current application's NSURLIsDirectoryKey, current application's NSURLIsPackageKey} options:(current application's NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)
repeat with aURL in theURLs
-- is it a directory?
set {theResult, isDirectory} to (aURL's getResourceValue:(reference) forKey:(current application's NSURLIsDirectoryKey) |error|:(missing value))
if isDirectory as boolean then -- check it's not a package
set {theResult, isPackage} to (aURL's getResourceValue:(reference) forKey:(current application's NSURLIsPackageKey) |error|:(missing value))
-- is it not a package?
if not isPackage as boolean then
set theRange to (aURL's |path|()'s rangeOfString:"_hdri$|_hdri_0\\d$" options:((current application's NSRegularExpressionSearch) + (get current application's NSCaseInsensitiveSearch)))
if |length| of theRange > 0 then
-- check for enclosed _Raw folder
set rawFolderPath to (aURL's |path|()'s stringByAppendingPathComponent:(aURL's lastPathComponent()'s stringByAppendingString:"_Raw"))
if (fileManager's fileExistsAtPath:rawFolderPath) as boolean then
(my processFolderURL:aURL)
else
(my checkFolderURL:aURL)
end if
else
(my checkFolderURL:aURL)
end if
end if
end if
end repeat
end checkFolderURL:
on processFolderURL:folderURL
-- make file manager
set fileManager to current application's NSFileManager's new()
-- create _Stitched folder if necessary
set folderName to folderURL's lastPathComponent()
set stitchedFolderName to folderName's stringByAppendingString:"_Stitched"
set stitchedFolderURL to (folderURL's URLByAppendingPathComponent:stitchedFolderName)
(fileManager's createDirectoryAtURL:stitchedFolderURL withIntermediateDirectories:true attributes:(missing value) |error|:(missing value))
-- get contents of _Raw folder
set rawFolderURL to (folderURL's URLByAppendingPathComponent:(folderName's stringByAppendingString:"_Raw"))
set theURLs to fileManager's contentsOfDirectoryAtURL:rawFolderURL includingPropertiesForKeys:{} options:(current application's NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)
-- filter files you want to move
set thePred to current application's NSPredicate's predicateWithFormat_("pathExtension IN %@", {"pts", "mov", "hdr", "exr"})
set theURLs to (theURLs's filteredArrayUsingPredicate:thePred)
-- move them
repeat with aURL in theURLs
set newName to (stitchedFolderName's stringByAppendingPathExtension:(aURL's pathExtension()))
(fileManager's moveItemAtURL:aURL toURL:(stitchedFolderURL's URLByAppendingPathComponent:newName) |error|:(missing value))
end repeat
end processFolderURL:
Fixed typos listed below Modified for moved goalposts
Two questions:
Question one: I noticed that the folders named _Hdri_01 and _Hdri_02 don’t get fixed because it doesn’t have the suffix “hdri”
I was able to work around that by doing a bit of sloppy coding here:
if not isPackage as boolean then
if aURL's its (lastPathComponent()'s lowercaseString()'s hasSuffix:"_hdri") then
(my processFolderURL:aURL)
else if aURL's its (lastPathComponent()'s lowercaseString()'s hasSuffix:"_hdri_01") then
(my processFolderURL:aURL)
else if aURL's its (lastPathComponent()'s lowercaseString()'s hasSuffix:"_hdri_02") then
(my processFolderURL:aURL)
else if aURL's its (lastPathComponent()'s lowercaseString()'s hasSuffix:"_hdri_03") then
(my processFolderURL:aURL)
else
(my checkFolderURL:aURL)
end if
end if
I’m wondering if there’s a more elegant solution to this?
Question 2:
Based on my testing, it looks like I have to be the exact number of directories away for the script to work because the first directory will never contain “_hdri”. And as you can see from the above, occasionally there will be a directory called “XXXX_hdri” which contains folders “XXXX_Hdri_01”, “XXXX_Hdri_02”, etc. Which also break the script. Is there any way to fix this?
I know this is getting a bit more complicated than you probably wanted when you first replied, but if you help me get this up and running I will be forever grateful. Thank you so much for your effort and knowledge.