AppleScript process to copy files from a folder and its subfolders to

Hi all.

I am trying to create an applescript process that will copy all my photos from a folder and all sub-folders to a new single folder and add append the fileCreateDate to the end of the filename. Adding the FileCreateDate will help where I have different photos with the same name. I want all the original photo meta data to remain with the photo.

I have been working with a number of sample routines on from the web but cannot get this to work …

Prompt for SourceFileFolder Prompt for TargetFileFolder

Then copy all files from SourceFileFolder and subfolders to the TargetFileFolder renaming the file from filename.fileextention to filename-“createdate”.fileextension

Any help would be appreciated.

Note that there may be duplicates when running this where the new filename file name exists on the TargetFileFolder … if this is the case it should be a valid duplicate and either not copy or replace …

Please help …

Thanks in advance.

Here is an example script that executes this. It collects files like PNG and JPG, but can also collect files with other extensions. It is enough to indicate the desired extension.

WARNING: since I did not quite understand in what form the OP wants to add a date to the photo names, ALWAYS MAKE A BACKUP OF THE SOURCE FOLDER before running the script.


global targetFolder

set sourceFolder to choose folder with prompt "CHOOSE SOURCE FOLDER, PLEASE"
set targetFolder to choose folder with prompt "CHOOSE TARGET FOLDER, PLEASE"

get_All_Files_of_Folder(sourceFolder)

on get_All_Files_of_Folder(the_folder)
	tell application "System Events"
		--Check each of the files in this disk/folder
		set files_list to (every file of the_folder) whose (name extension is "png") or (name extension is "jpg")
		repeat with aPhoto in files_list
			set aPhoto to contents of aPhoto
			set fileCreatedDate to (creation date of aPhoto) as text
			set aName to name of aPhoto
			set anExtension to name extension of aPhoto
			set aBaseName to text 1 thru -5 of aName
			set newPhoto to move aPhoto to targetFolder
			set name of newPhoto to aBaseName & "  __" & fileCreatedDate & "__ ." & anExtension
		end repeat
		set sub_folders_list to folders of the_folder
		repeat with the_sub_folder_ref in sub_folders_list
			my get_All_Files_of_Folder(the_sub_folder_ref)
		end repeat
	end tell
end get_All_Files_of_Folder

Just a point, the OP wrote:
I am trying to create an applescript process that will copy all my photos from a folder and all sub-folders to a new single folder.
He didn’t wanted to move them.
Alas, at least with High Sierra and older systems, System Events fails to duplicate files.
The problem of possible duplicates is not treated too.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) lundi 27 janvier 2020 18:49:52

Here is a script doing the asked job.

----------------------------------------------------------------
use AppleScript version "2.5"
use framework "Foundation"
use scripting additions
----------------------------------------------------------------

property |⌘| : a reference to current application

-- use the format which fits your needs
property dateFormat : "yyyy-MM-dd 'at' HH'h'mm"
--property dateFormat : "yyyy-MM-dd"

my germaine()

on germaine()
	set sourceFolder to choose folder with prompt "Choose source folder, please." --> an alias
	set destFolder to choose folder with prompt "Choose target folder, please." --> an alias
	
	-- no need to convert sourceFolder
	-- but, at least under High Sierra, destFolder MUST be explicitly converted into a NSURL item.
	set destFolder to (|⌘|'s NSArray's arrayWithObject:destFolder)'s firstObject()
	set theFileManager to |⌘|'s NSFileManager's |defaultManager|()
	set keysToRequest to {|⌘|'s NSURLTypeIdentifierKey, |⌘|'s NSURLCreationDateKey}
	set theOptions to (|⌘|'s NSDirectoryEnumerationSkipsPackageDescendants as integer) + (|⌘|'s NSDirectoryEnumerationSkipsHiddenFiles as integer)
	set theEnumerator to theFileManager's enumeratorAtURL:sourceFolder includingPropertiesForKeys:keysToRequest options:theOptions errorHandler:(missing value)
	set theURLs to (theEnumerator's allObjects())
	if theURLs is {} then error "The folder “" & sourceFolder & "” is empty."
	set UTIArray to (|⌘|'s NSArray's arrayWithArray:{"public.jpeg", "public.png", "public.tiff", "public.image", "com.microsoft.bmp"})
	repeat with aURL in theURLs
		set {theResult, theUTI} to (aURL's getResourceValue:(reference) forKey:(|⌘|'s NSURLTypeIdentifierKey) |error|:(missing value))
		if (UTIArray's containsObject:theUTI) as boolean then
			set theDestURL to (my copyURL:aURL uniquelyToFolderURL:destFolder)
		end if
	end repeat
end germaine

#=====

-- adapted from a handler of "FileManagerLib"
on copyURL:theSourceURL uniquelyToFolderURL:theDestFolderURL
	set itsExtension to theSourceURL's pathExtension()
	set {theResult, theDate} to (theSourceURL's getResourceValue:(reference) forKey:(|⌘|'s NSURLCreationDateKey) |error|:(missing value))
	set destNameLessExt to ((theSourceURL's lastPathComponent())'s |stringByDeletingPathExtension|()'s stringByAppendingString:("_" & (my formatDate:theDate usingFormat:dateFormat)))
	set theDestURL to theDestFolderURL's URLByAppendingPathComponent:(destNameLessExt's stringByAppendingPathExtension:itsExtension)
	set theFileManager to |⌘|'s NSFileManager's |defaultManager|()
	set i to 1
	repeat
		if (theDestURL's checkResourceIsReachableAndReturnError:(missing value)) as boolean is false then
			set {theResult, theError} to (theFileManager's copyItemAtURL:theSourceURL toURL:theDestURL |error|:(reference))
			if theResult as boolean is false then error (theError's |localizedDescription|() as text) number (theError's code() as integer)
			exit repeat
		else
			set proposedName to (destNameLessExt's stringByAppendingString:(" #" & i))'s stringByAppendingPathExtension:itsExtension
			set theDestURL to theDestFolderURL's URLByAppendingPathComponent:proposedName
			set i to i + 1
		end if
	end repeat
	return theDestURL as «class furl» as text
end copyURL:uniquelyToFolderURL:

#=====

on formatDate:theDate usingFormat:formatString
	set theFormatter to |⌘|'s NSDateFormatter's new()
	theFormatter's setDateFormat:formatString
	return (theFormatter's stringFromDate:theDate) as text
end formatDate:usingFormat:

#=====

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) lundi 27 janvier 2020 21:23:28

Made changes upon way picture files are filtered.

I could suggest other way to do this…

FIRST COPY YOUR FILES TO YOUR NEW LOCATION

BUT BEFORE TEST WITH TEST FILES TO YOUR LIKE.

If you do not have Transnomino it’s free, download it at
https://transnomino.bastiaanverreijt.com

  1. Open Transnomino, make a recipe that rename your file to include create date.

There it say ‘Replace’ you change to ‘Set’ next and click the 3 dots on right…

When you have created what you want. save the recipe to desktop.

Then you could run this Script when you select the Folder Name of your files…

Change the YOUR_NAME.RECIPE in the AppleScript to what you call it.

The Script will import your files to the Application, load the recipe.

Before you do anything check the transformed file is of your like, then press rename.

Ps. when you know how Transnomino work, you could have many custom recipe for anything
you like to do in the future. The application has many feature… one of my favourite application.

on run
	tell application "Finder" to set selected_path ¬
		to POSIX path of ((get selection) as alias)
	
	-- path to recipe
	set settings to POSIX path of ((path to desktop) as alias) & "YOUR_NAME.RECIPE"
	return do shell script "open -a Transnomino " & selected_path & space & "--args " & settings
end run