Trying to grab one image from each folder in a tree

Hello -

I’m pretty adept at piecing together bits of code, but still quite a newbie to Applescript. My challenge is that I am trying to take a DVD with many layers of folders and sub-folders, duplicate its structure to a new desitnation and copy one file from each sub-folder that contains files. So, far I have found the following bit of code that will get the most recent file (which is fine, I don’t much care which file it is):

set theFolder to choose folder
tell application "Finder"
	select item -1 of (sort (get files of folder theFolder) by modification date)
end tell

Also, I’ve found a longer script that will copy files of particular file types and move them to a new, duplicate folder structure. I’ll paste it at the end of the post (sorry for not linking, but I can’t find it again and thanks to whomever wrote it). As you can see, I tried to integrate the “most recent file” bit into this longer script, but its erroring out. I would really appreciate any help or guidance anyone could give me in this.

Thanks

Here’s the script:

-- duplicate at destination the source folder's tree structure, omitting 'empty' leaf node folders, and copy all Finale files. 
-- Finale Mac files have file type FIN3. Finale PC created files have name extension MUS. 

property gFileTypes : {"mus"}

tell application "Finder"
	-- (*begin Copy Folder Tree*) 
	set tSourceFolder to choose folder with prompt "Choose a folder structure to duplicate and copy Finale files"
	if tSourceFolder is false then return "User Cancelled"
	set tDestFolder to choose folder
	my copyItems(tSourceFolder, tDestFolder)
	log {"Finished"}
end tell

on copyItems(pSourceFolder, pDestFolder)
	tell application "Finder"
		close windows
		set tSourceFolderName to name of pSourceFolder as string
		make new folder at pDestFolder with properties {name:tSourceFolderName}
		set tNewDestFolder to (folder tSourceFolderName of folder pDestFolder) as alias
		-- copy or move over files of the specified type(s) note parens () of set...to are critical syntax 
		get item -1 of (sort (get files of folder pSourceFolder) by modification date)
		log {"Class", class of tSelectedFiles, "length", length of tSelectedFiles}
		if length of tSelectedFiles is not 0 then
			set inhere to true
			copy tSelectedFiles to folder tNewDestFolder
		else
			set inhere to false
		end if
		log {"inhere", inhere}
		
		-- copy over the folders, calling this handler recursively 
		set insub to false
		set tFolders to (every folder of pSourceFolder)
		repeat with tThisFolder in tFolders
			set rresult to my copyItems(tThisFolder as alias, tNewDestFolder as alias)
			log {"rresult", rresult}
			if rresult then
				-- that folder or some sub folder of it is non empty 
				set insub to true
			else
				-- that folder is empty and it has no non empty subfolder(s) so delete it 
				log {tNewDestFolder, "is empty", tThisFolder}
				set delpath to ((tNewDestFolder as string) & (name of tThisFolder as string)) as alias
				delete delpath
			end if
		end repeat
		log {"inhear", inhere, "insub", insub}
		-- return status of this folder and its sub folders if any 
		if (insub or inhere) then
			return true
		else
			return false
		end if
	end tell
end copyItems

tell application "Finder"
	close windows
	open folder "Work3:XX"
end tell

Model: G4 iBook
Browser: Safari 417.8
Operating System: Mac OS X (10.4)

The script you started with selects (in a new Finder window) the most recent file in the chosen folder.

You’ve changed “select” to “get” in your second script. You can’t get a file, you can only read it or examine its properties. I suspect you want its name or a path to it so you can operate on it - true?

Ah, I see - thank you. Yes, I want to locate the particular file (most recent) in the folder and copy it to the new location (which should have the same name as the old location, just in a different path).

So, I need to get the properties of the file (its name) and then copy it to the new location?

Here’s the gist in a nutshell (as a modification of your original):

set theFolder to choose folder with prompt "Select anything for this example"
tell application "Finder"
	-- get the latest file
	set theFile to (item -1 of (sort (get files of folder theFolder) by modification date))
	-- Convert the finder reference to it to a path
	set thePath to theFile as string
	-- get it's name
	set theName to name of theFile
end tell
display dialog "The complete path: " & return & thePath & return & return & "The Name of the file: " & theName

Thanks Adam, that works perfectly for selecting/getting the most recent file from a folder. Can you give me any advice on embedding that logic in some sort of routine that will search through a folder full of sub-folders and copy the most recent file from each folder into new folders? For example, if I have a CD that has three folders on it, and each of those three folders has 2 folders in it and each of those 2 folders has 10 files in it, I would like the script to create an empty folder structure just like the original but having only one file in each of the lowest level folders.

This is the script I use to duplicate a folder tree (with or withour certain file types). I tried replacing the file type code with most recent file code, but the error says it “can’t get last item of {}”

---------------------------------------------------------------------------------------
-- Copy folder tree
-- by Jeff Fischer <jeff@5fischers.org>
--
-- credit to Dan Decker and Robert Metzker for ideas from their scripts
---------------------------------------------------------------------------------------

-- make gFileTypes an empty set to omit copying/moving any files
property gFileTypes : {"psd", "jpg", "gif", "jpeg"}

tell application "Finder"
	set tSourceFolder to choose folder with prompt "Choose a folder structure to duplicate"
	if tSourceFolder is false then return "User Cancelled"
	set tDestFolder to choose folder with prompt "Choose the location for the duplicate structure"
	if tDestFolder is false then return "User Cancelled"
	
	my copyItems(tSourceFolder, tDestFolder)
end tell

on copyItems(pSourceFolder, pDestFolder)
	tell application "Finder"
		set tSourceFolderName to name of pSourceFolder as string
		make new folder at pDestFolder with properties {name:tSourceFolderName}
		set tNewDestFolder to (folder tSourceFolderName of folder pDestFolder) as alias
		
		-- copy or move over files of the specified type(s)
		set tSelectedFiles to (every file of folder pSourceFolder whose name extension is in gFileTypes)
		if tSelectedFiles ≠ {} then
			select (every file of folder pSourceFolder whose name extension is in gFileTypes)
			try
				-- uncomment the action you want, either copy or move
				-- copy the selection to folder tNewDestFolder
				move the selection to folder tNewDestFolder
				close window (name of folder pSourceFolder as string)
			end try
		end if
		
		-- copy over the folders, calling this handler recursively
		set tFolders to (every folder of pSourceFolder)
		repeat with tThisFolder in tFolders
			my copyItems(tThisFolder as alias, tNewDestFolder as alias)
		end repeat
	end tell
end copyItems

Hello again -

I’m sorry to repost but I haven’t been able to make more progress on this task and it would be a huge help to me if someone could point me in the right direction. What I am trying to do is take a CD full of images buried in several levels of folders, duplicate the empty folder structure, and copy just one representative file (the most recent) from each folder into its corresponding duplicated folder. This script (thanks Adam) gets the most recent file from a chosen folder:

set theFolder to choose folder with prompt "Select anything for this example"
tell application "Finder"
	-- get the latest file
	set theFile to (item -1 of (sort (get files of folder theFolder) by modification date))
	-- Convert the finder reference to it to a path
	set thePath to theFile as string
	-- get it's name
	set theName to name of theFile
end tell
display dialog "The complete path: " & return & thePath & return & return & "The Name of the file: " & theName

And I also have a script that successfully duplicates a folder structure with or without certain file types (see below), but I haven’t yet been able to integrate the two scripts. Can anyone help me out, or tell me if there is an easier solution?

Thanks,

John

Here is the folder duplication script:

---------------------------------------------------------------------------------------
-- Copy folder tree
-- by Jeff Fischer <jeff@5fischers.org>
--
-- credit to Dan Decker and Robert Metzker for ideas from their scripts
---------------------------------------------------------------------------------------

-- make gFileTypes an empty set to omit copying/moving any files
property gFileTypes : {}

tell application "Finder"
	set tSourceFolder to choose folder with prompt "Choose a folder structure to duplicate"
	if tSourceFolder is false then return "User Cancelled"
	set tDestFolder to choose folder with prompt "Choose the location for the duplicate structure"
	if tDestFolder is false then return "User Cancelled"
	
	my copyItems(tSourceFolder, tDestFolder)
end tell

on copyItems(pSourceFolder, pDestFolder)
	tell application "Finder"
		set tSourceFolderName to name of pSourceFolder as string
		make new folder at pDestFolder with properties {name:tSourceFolderName}
		set tNewDestFolder to (folder tSourceFolderName of folder pDestFolder) as alias
		
		-- copy or move over files of the specified type(s)
		set tSelectedFiles to (every file of folder pSourceFolder whose name extension is in gFileTypes)
		if tSelectedFiles ≠ {} then
			select (every file of folder pSourceFolder whose name extension is in gFileTypes)
			try
				-- uncomment the action you want, either copy or move
				-- copy the selection to folder tNewDestFolder
				move the selection to folder tNewDestFolder
				close window (name of folder pSourceFolder as string)
			end try
		end if
		
		-- copy over the folders, calling this handler recursively
		set tFolders to (every folder of pSourceFolder)
		repeat with tThisFolder in tFolders
			my copyItems(tThisFolder as alias, tNewDestFolder as alias)
		end repeat
	end tell
end copyItems

Sorry to say that in 20 minutes of trying, jb, that I couldn’t find the magic coercion either, so though I can get partway there I end up with a bunch of empty folders.

In a nutshell for the experts, the problem is to take a CD filled with a nested folder structure containing files and create a copy of the complete structure with only the newest file copied in each folder.

Thank you Adam, thank you jacques for your help on this. I’ve just tried Jacques’ first posted script and it seems to work perfectly (and quickly!) for image files. The second one, however, runs into an error saying that the variable ALL_subfolders is not defined.

Thank you again - this is a big help.

Jaques - my hat is off to you - that is some great work, this particular problem was bugging me all day saturday…I gave up on it a few times. I think the hard part was that there are just so many ways to go about solving this problem - I was having trouble committing to one. I was thinking - would it be easier to duplicate the whole structure then delete everything except the most recent file…or…

Overall, the problem is considerably more difficult than it first seems…

Anyway - again, great work.

Jaques; Let me join ChrisAdmin here - I too spent a lot of time trying (I posted after 20 minutes that I couldn’t do it because I had tried all I could think of by then, but I came back to it several times). Great stuff!