Is this file copying script efficent?

Hello, I’m very weak at applescript but have painfully cobbled this together.

I have a folder with low resolution files in: FPOfolder, a second folder which contains high resolution versions of all the files in FPOfolder and a great many others. The script gets a list of the files in FPOfolder and then copys the corresponding files from the Hires folder to a third folder: FEB folder

The splendid news for me is that it works but it seems to be very slow, there’s 900 odd files in the Hires folder totally 2GB and 600 files in the FPOfolder.

It trundles along ok but I get the impression there’s a lag between one file and the next, it all looks ok to me but I really wouldn’t know to be honest, I’d be grateful for anyone to suggest a quicker way to tackle or laugh and point out a stupid way to do something, thank-you

That mysterious error can’t be a good thing I imagine?

(there is an outside chance that the server is playing up)

Script is below and some sample Events below that

tell application "Finder"
	set FPOfolder to (choose folder with prompt "Select the FPO folder") as alias
	set FEBfolder to (choose folder with prompt "Select the FEB folder") as alias
	set Hiresfolder to (choose folder with prompt "Select the FLAT folder") as alias
	--set Afolder to "HD:Blah:A:" as alias
	set a_list to every file in FPOfolder
	repeat with i from 1 to number of items in a_list
		set a_file to (item i of a_list)
		set a_filex to a_file as string
		set myArray to my theSplit(a_filex, ":")
		set a_name to last item of myArray
		--say a_name as string
		set a_hires to (Hiresfolder & a_name) as string
		--say a_hires
		set a_hires to a_hires as alias
		copy file a_hires to folder FEBfolder
	end repeat
end tell


on theSplit(theString, theDelimiter)
	-- save delimiters to restore old settings
	set oldDelimiters to AppleScript's text item delimiters
	-- set delimiters to delimiter to be used
	set AppleScript's text item delimiters to theDelimiter
	-- create the array
	set theArray to every text item of theString
	-- restore the old setting
	set AppleScript's text item delimiters to oldDelimiters
	-- return the result
	return theArray
end theSplit

	get document file "Eravikulam Nat Park 2_India.eps" of folder "IG India OLD FPOs" of folder "IG India FEB" of folder "IG India" of folder "IG New Process" of disk "New Process Titles"
		--> "New Process Titles:IG New Process:IG India:IG India FEB:IG India OLD FPOs:Eravikulam Nat Park 2_India.eps"
	copy file (alias "New Process Titles:IG New Process:IG India:IG India SG Files _Old Hires:IG India FLAT:Eravikulam Nat Park 2_India.eps") to folder (alias "New Process Titles:IG New Process:IG India:IG India FEB:")
		--> document file "Eravikulam Nat Park 2_India.eps"
		--> error number 0
	get document file "Guruvayur Temple 3_India.eps" of folder "IG India OLD FPOs" of folder "IG India FEB" of folder "IG India" of folder "IG New Process" of disk "New Process Titles"
		--> "New Process Titles:IG New Process:IG India:IG India FEB:IG India OLD FPOs:Guruvayur Temple 3_India.eps"
	copy file (alias "New Process Titles:IG New Process:IG India:IG India SG Files _Old Hires:IG India FLAT:Guruvayur Temple 3_India.eps") to folder (alias "New Process Titles:IG New Process:IG India:IG India FEB:")
		--> document file "Guruvayur Temple 3_India.eps"
		--> error number 0

Model: MacPro3,1
AppleScript: AppleScript 2.1.2
Browser: Firefox 4.0.1
Operating System: Mac OS X (10.6)

Hi,

I’m wondering that the script works at all.
There are some reference errors and the proper command to copy files with the Finder is duplicate.
the alias coercions while choosing the folder are not needed, the returned references are alias specifiers anyway.
The subroutine is not needed either, you can easily retrieve the file name with the command name

Try this


set FPOfolder to (choose folder with prompt "Select the FPO folder")
set FEBfolder to (choose folder with prompt "Select the FEB folder")
set Hiresfolder to (choose folder with prompt "Select the FLAT folder")
tell application "Finder"
	set a_list to every file in FPOfolder
	repeat with i from 1 to number of items in a_list
		set a_file to (item i of a_list)
		set a_name to name of a_file
		set a_hires to (Hiresfolder as text) & a_name
		duplicate file a_hires to FEBfolder
	end repeat
end tell


tee hee, sorry to have subjected you to that code, I was rather throwing the kitchen sink at it last night I’m afraid

thank-you Stefan, I’ll admit that was the sort of answer I was hoping for, at least i tried, right?

:smiley:

I’ll give you lovely short almost simple code a whirl and report back, I have to now ham fisted put a bit of error type checking stuff in so will report back when I’ve broken it again

:wink:

Well in some Mac OS X version copy did work indeed but no manual or documentation says you can use copy for copying files with the Finder. When the system is updated/upgraded there is a very high chance that script won’t work. Like Stefan says, use duplicate command instead. The reason the copy wont work because copy is a command to duplicate objects in Applescript instead of making a reference to it (set command).

an alternative is (without using the Finder, which I prefer) is simply this:

set FPOfolder to (choose folder with prompt "Select the FPO folder") as string
set FEBfolder to (choose folder with prompt "Select the FEB folder") as string
set Hiresfolder to (choose folder with prompt "Select the FLAT folder") as string
set a_list to list folder FPOfolder without invisibles
repeat with a_name in a_list
	do shell script "ditto " & quoted form of POSIX path of (Hiresfolder & a_name as string) & " " & quoted form of POSIX path of FEBfolder
end repeat

I can only repeat that the original script did work, terrible as it was, I’m running latest OS and a modern Mac

Anyway, onwards (and thank-you)

I’m now getting an applescript timeout on

   set a_list to every file in FPOfolder

which was working fine for hours this morning, so the server is buggering about, it’s been slow at times for week, bleeding IT, so please forgive me if I’m slow in updating this thread with my thrilled news

thanks again for the quick and confident replies gents

Tynan

did you use my script?

also if you want to use alias as an alias (In my example I used the file paths as string).

try
FPOFolder
on error
set FPOFolder to (choose folder with prompt "Select the FPO folder") as alias
end try

if you save your script as an application the next run you don’t have to choose those folder again even if you move the folder(s) to another place on the same file system as long as the alias can be resolved. When you recompile you must choose the folder(s) again.

It worked when I used yours, thank-you, it’s quicker without a shadow of a doubt

I see your line to get all file names is different, it’s also almost instant while mine took a few minutes, nice

every time this script runs the folders will be different and in different places so I think the script is fine as is

Thank-you very much indeed though for the added info

Tynan

the result of choose folder is always an alias :wink:

I hesitate to add any of my guesswork bodges to that elegant script which is humming along so well

I need to add two if type conditionals before it tries to copy

a. skip trying to copy if the file already exists in the destination folder
b. skip trying to copy if the file does not exist in the Hires folder - in that instance I’d like it to put up an alert with a continue button for me to click once I’ve manually resolved the missing file

I won’t be at all offended if such drudgery is beneath you and I should sort that out myself :slight_smile:

After trying every single combination of wording I’ve managed a. although I had to use Finder, if there’s a shell command equivalent I’d love to hear it

set FPOfolder to (choose folder with prompt "Select the FPO folder") as string
set FEBfolder to (choose folder with prompt "Select the FEB folder") as string
set Hiresfolder to (choose folder with prompt "Select the FLAT folder") as string
set a_list to list folder FPOfolder without invisibles
repeat with a_name in a_list
	tell application "Finder"
		
		if (not (exists file (FEBfolder & a_name as string))) then
			--if (not (exists (FEBfolder & a_name))) then
			
			do shell script "ditto " & quoted form of POSIX path of (Hiresfolder & a_name as string) & " " & quoted form of POSIX path of FEBfolder
		end if
	end tell
end repeat

Stafan I know but it’s a copy from tynan’s script because I’ve wrote it in the browser.

yes cheking for existance of a file in the shell you can use test. It doesn’t print out any value but retruns it so this means that there are many different ways of doing this. I prefer to use a separate function for testing it (keeps your code look cleaner).

the function I use mostly is

on fileExists(posixPath) --the argument needs to be a posix path
return not ((do shell script “test -e " & quoted form of posixPath & " ; echo $?” as string) as integer) as boolean
end fileExists

implemented in your code would be something like


set FPOfolder to (choose folder with prompt "Select the FPO folder") as string
set FEBfolder to (choose folder with prompt "Select the FEB folder") as string
set Hiresfolder to (choose folder with prompt "Select the FLAT folder") as string
set a_list to list folder FPOfolder without invisibles
repeat with a_name in a_list
           if not fileExists(posix path of (FEBfolder & a_name as string)) and fileExists(posix path of (Hiresfolder & a_name as string))then
           do shell script "ditto " & quoted form of POSIX path of (Hiresfolder & a_name as string) & " " & quoted form of POSIX path of FEBfolder
       end if
end repeat

on fileExists(posixPath) --the argument needs to be a posix path
	return not ((do shell script "test -e " & quoted form of posixPath & " ; echo $?" as string) as integer) as boolean
end fileExists

It checks if the file not already exists in the FEBFolder and also checks if the source file (file in hires folder) does actually exists before continueing copying the file

p.s. also didn’t test this is in applescript only wrote this in my browser. So it could contain typos

Thank-you, I got a smell of that on google but that shell stuff looks mad to me at the moment

Thank-you very much indeed, greatly appreciated, you;re making the lives of a repro house in Bermondsey much easier

I’ll give it a go tomorrow and feedback

Tynan

Sweet as a nut!

Right, slightly embarrassed by having the whole bloody thing written for me, I’m going to tackle writing to scren at the end the names of all the missing files in the Hires folder myself

But I will post it on here when it works for your amusement and my profit when you replace it with something that uses 10% of the code and works 10 times faster :smiley:

Until then, thanks again very much

Tynan

Well we all started some day and even I let programmers code a lot for me and this is how I can say my thanks to the community.

You’re very welcome and it’s always nice someone appreciates it.

I’m quite good at php and some other stuff, promise

Got the Alert working ‘already’ and very pleasing it is

The last bit to really put a cherry on top is to make it search for the Hires through subfolders, off to google i go

Will post finished script then on the off chance that some other numpty wants to do this and you and Stefan and everyone else competent is on hols

Tynan

hmm

I can see this is something to do with ‘entire contents’ but this looks like fiddly, relatively to the glorious simplicity so far

The script is going to have to capture the path for each file so it knows where that file is when it’s told to copy that file I assume?

So a list which holds the entire path for each file, and then retrieve the relevant path that contains the wanted filename and then use it?

I’ll tackle this on my ownsome and let you get on with your life but I’d appreciate the outline of a better method if there is one

Thanks again
Tynan

You can use find and mdfind for looking for files instead of recursively walking through it.

I prefer find because network volumes, system directories removable media is no problem for find while mdfind does not always find the files. Mdfind will lookup in a database and not look in the file hierarchy of your file systems this is teh most reason why mdls can’t find some files while find does. I know find is slower than mdfind but I prefer find’s reliability above mdfind’s speed.

this is a function I also use a lot

on findFileInFolder(theFile, posixPath)
	set AppleScript's text item delimiters to return
	set theFiles to every text item of (do shell script "find " & quoted form of posixPath & " -iname " & quoted form of theFile)
	set AppleScript's text item delimiters to ""
	return theFiles
end findFileInFolder

the script returns a list of paths of where the files are located. The check to see if a file exists in the highres folder can now be terminated because when the file can’t be found it also means it doesn’t exists.

set FPOfolder to (choose folder with prompt "Select the FPO folder") as string
set FEBfolder to (choose folder with prompt "Select the FEB folder") as string
set Hiresfolder to (choose folder with prompt "Select the FLAT folder") as string
set a_list to list folder FPOfolder without invisibles
repeat with a_name in a_list
if not fileExists(posix path of (FEBfolder & a_name as string)) then
set theFiles to findFileInFolder(a_name, posix path of Hiresfolder)
if length of theFiles = 1 then
do shell script "ditto " & quoted form of item 1 of theFiles & " " & quoted form of POSIX path of FEBfolder
end if
end if
end repeat

on fileExists(posixPath) --the argument needs to be a posix path
   return not ((do shell script "test -e " & quoted form of posixPath & " ; echo $?" as string) as integer) as boolean
end fileExists

on findFileInFolder(theFile, posixPath)
	set AppleScript's text item delimiters to return
	set theFiles to every text item of (do shell script "find " & quoted form of posixPath & " -iname " & quoted form of theFile)
	set AppleScript's text item delimiters to ""
	return theFiles
end findFileInFolder

Bless you

giving that a whirl

(if you saw an earlier post grumbling about it not working, some silly arse wasn’t choosing the right Hires folder, the one with the subfolders rather than the flattened one they’d chosen a thousand times in the last two days …:rolleyes:

Brilliant, I was expecting it to be slower but very little in it if anything

works like a dream

Anyhow, 1001 sincere and appreciative thanks from me to you

Tynan

Here’s my essentially final version for completeness and hopefully someone else’s delight, all I’ve added is a summary alert box at the end

set FPOfolder to (choose folder with prompt "Select the FPO folder") as string
set FEBfolder to (choose folder with prompt "Select the Recorrection Hires folder") as string
set Hiresfolder to (choose folder with prompt "Select the Master Hires folder") as string
set theStart to (current date) as date
set a_list to list folder FPOfolder without invisibles
set NoFPOs to count of a_list
set FPOsDone to 0
set NoHires to ""
repeat with a_name in a_list
	if not fileExists(POSIX path of (FEBfolder & a_name as string)) then
		set theFiles to findFileInFolder(a_name, POSIX path of Hiresfolder)
		
		if length of theFiles = 1 then
			do shell script "ditto " & quoted form of item 1 of theFiles & " " & quoted form of POSIX path of FEBfolder
		else
			set NoHires to NoHires & return & a_name
		end if
	end if
	set FPOsDone to (FPOsDone + 1)
end repeat
set theEnd to (current date) as date
set theTime to (theEnd - theStart)
--display results
display dialog "No. FPOs: " & NoFPOs & " | FPOs processed: " & FPOsDone & return & "Time taken: " & theTime & " seconds" & return & "Missing Hires: " & NoHires & return buttons {"OK"} default button "OK"

on fileExists(posixPath) --the argument needs to be a posix path
	return not ((do shell script "test -e " & quoted form of posixPath & " ; echo $?" as string) as integer) as boolean
end fileExists

on findFileInFolder(theFile, posixPath)
	set AppleScript's text item delimiters to return
	set theFiles to every text item of (do shell script "find " & quoted form of posixPath & " -iname " & quoted form of theFile)
	set AppleScript's text item delimiters to ""
	return theFiles
end findFileInFolder

-- written by Tynan Dean on 05.05.11 but actually almost entirely done by DJ Bazzie Wazzie and StefanK from http://macscripter.net/viewtopic.php?pid=139899#p139899