I don't want a folder action to check file sizes

I want to check a folder to see if files are done copying. All the scripts I find are made to be folder actions, which I don’t find always reliable. I’m trying to convert this one I found to check a folder I specify, but this isn’t working.

Original:

property item_check_delay_time : 2
property folder_check_delay_time : 3
--property special_label_index : 7

on adding folder items to this_folder after receiving added_items
	--try
	
	
	-- CHECK THE FILES TO MAKE SURE THEY"RE COMPLETELY AVAILABLE
	set the added_items to my check_added_items(the added_items)
	if the added_items is {} then return "no vaild items"
	
	repeat with i from 1 to number of items in added_items
		set this_item to item i of added_items as alias
		
		--YOUR SCRIPT HERE
		
		
	end repeat

	--end try
end adding folder items to


on check_added_items(the added_items)
	-- check the transfer status of every added file to determine
	-- if each file has completed being moved into the attached folder
	set the notbusy_items to {}
	repeat with i from 1 to the number of items in the added_items
		set this_item to (item i of the added_items)
		if my check_busy_status(this_item) is false then
			set the end of the notbusy_items to this_item
		end if
	end repeat
	return the notbusy_items
end check_added_items

on check_busy_status(this_item)
	-- a folder can contain items partially transfered
	-- this routine will wait for all the folder contents to transfer
	if the last character of (this_item as text) is ":" then
		set the check_flag to false
		repeat
			-- look for any files within the folder that are still transferring
			tell application "Finder"
				try
					set the busy_items to the name of every file of the entire contents of this_item ¬
						whose file type begins with "bzy"
				on error
					set the busy_items to {}
				end try
			end tell
			if the check_flag is true and the busy_items is {} then return false
			-- pause for the indicated time
			delay the folder_check_delay_time
			-- set the flag and check again
			set the check_flag to true
		end repeat
	else -- the passed item is a single file, suitcase, clipping, etc.
		
(*
		-- check the label of the item. If it is the marked label, then it's already been processed so ignore.
		tell application "Finder"
			if (the label index of this_item) as integer is the special_label_index then
				return "ignore"
			end if
		end tell
*)
		set the check_flag to false
		repeat
			tell application "Finder"
				set the item_file_type to the file type of this_item
			end tell
			if the check_flag is true and ¬
				the item_file_type does not start with "bzy" then
				
(*
tell application "Finder"
					set the label index of this_item to the special_label_index
				end tell
*)
				-- allow the Finder time to change the label
				delay the item_check_delay_time
				return false
			else if the item_file_type does not start with "bzy" then
				-- set the flag and check again
				set the check_flag to true
			end if
			-- pause for the indicated time
			delay the item_check_delay_time
		end repeat
	end if
end check_busy_status


I want it to check the following folder:


((path to desktop folder as text) & “foldername”)

My Script:

property item_check_delay_time : 2
property folder_check_delay_time : 3
--property special_label_index : 7
set myFolder to ((path to desktop folder as text) & "foldername")

on adding folder items to myFolder after receiving added_items
	--try
	
	
	-- CHECK THE FILES TO MAKE SURE THEY"RE COMPLETELY AVAILABLE
	set the added_items to my check_added_items(the added_items)
	if the added_items is {} then return "no vaild items"
	
	repeat with i from 1 to number of items in added_items
		set this_item to item i of added_items as alias
		
		--YOUR SCRIPT HERE
		
		
	end repeat

	--end try
end adding folder items to


on check_added_items(the added_items)
	-- check the transfer status of every added file to determine
	-- if each file has completed being moved into the attached folder
	set the notbusy_items to {}
	repeat with i from 1 to the number of items in the added_items
		set this_item to (item i of the added_items)
		if my check_busy_status(this_item) is false then
			set the end of the notbusy_items to this_item
		end if
	end repeat
	return the notbusy_items
end check_added_items

on check_busy_status(this_item)
	-- a folder can contain items partially transfered
	-- this routine will wait for all the folder contents to transfer
	if the last character of (this_item as text) is ":" then
		set the check_flag to false
		repeat
			-- look for any files within the folder that are still transferring
			tell application "Finder"
				try
					set the busy_items to the name of every file of the entire contents of this_item ¬
						whose file type begins with "bzy"
				on error
					set the busy_items to {}
				end try
			end tell
			if the check_flag is true and the busy_items is {} then return false
			-- pause for the indicated time
			delay the folder_check_delay_time
			-- set the flag and check again
			set the check_flag to true
		end repeat
	else -- the passed item is a single file, suitcase, clipping, etc.
		
(*
		-- check the label of the item. If it is the marked label, then it's already been processed so ignore.
		tell application "Finder"
			if (the label index of this_item) as integer is the special_label_index then
				return "ignore"
			end if
		end tell
*)
		set the check_flag to false
		repeat
			tell application "Finder"
				set the item_file_type to the file type of this_item
			end tell
			if the check_flag is true and ¬
				the item_file_type does not start with "bzy" then
				
(*
tell application "Finder"
					set the label index of this_item to the special_label_index
				end tell
*)
				-- allow the Finder time to change the label
				delay the item_check_delay_time
				return false
			else if the item_file_type does not start with "bzy" then
				-- set the flag and check again
				set the check_flag to true
			end if
			-- pause for the indicated time
			delay the item_check_delay_time
		end repeat
	end if
end check_busy_status

as far as I can see the scripts are identical except the set myFolder line,
To convert a folder action script to a script with a run handler you have to “hard-code” the event variables and remove the event handler.
added_items is a list of files of class alias
myFolder is actually not needed in your script, there is no reference to it


property item_check_delay_time : 2
property folder_check_delay_time : 3
--property special_label_index : 7
set myFolder to ((path to desktop folder as text) & "foldername:") -- don't forget the colon!
set added_items to choose file with multiple selections allowed
-- on adding folder items to myFolder after receiving added_items
--try


-- CHECK THE FILES TO MAKE SURE THEY"RE COMPLETELY AVAILABLE
set the added_items to my check_added_items(the added_items)
if the added_items is {} then return "no vaild items"

repeat with i from 1 to number of items in added_items
	set this_item to item i of added_items as alias
	
	--YOUR SCRIPT HERE
	
	
end repeat

--end try
-- end adding folder items to

.


Won’t the script need the “myFolder” variable though, so it knows what folder I want the script to check? When this script is run by the user, the folder it is checking will already have files copying to it. I don’t want the user to be prompted at all to choose where the folder is located because I already know where the folder is, and it will always be constant. Does this sound right, or am I missing something from the script you posted above?

ok, if you want to parse the files of myFolder, use this


set myFolder to ((path to desktop folder as text) & "foldername:")
tell application "Finder" to set added_items to files of folder myFolder as alias list

Okay, I made the changes and added back the rest of the script. I told it to activate “safari” after all files are done copying just as a reference to see if it was actually waiting for the files to copy before performing the next command. I started copying a file around 10 gb as an extreme to the folder. Once it started copying, I ran the script. It waited the 3 seconds that was set for the property delay, and then Safari activated. SO while I didn’t get any errors, it still wasn’t performing correctly. Am I missing a line or a step? I’m looking down the script and it keeps referring to file types that start with “bzy”. Does that stand for something or was it written in reference to specific files that were being added by the user of the original script? I want the script to wait for any file copying, regardless of the file type.

property item_check_delay_time : 2
property folder_check_delay_time : 3
--property special_label_index : 7

set myFolder to ((path to desktop folder as text) & "foldername:")
tell application "Finder" to set added_items to files of folder myFolder as alias list
-- on adding folder items to myFolder after receiving added_items
--try


-- CHECK THE FILES TO MAKE SURE THEY"RE COMPLETELY AVAILABLE
set the added_items to my check_added_items(the added_items)
if the added_items is {} then return "no vaild items"

repeat with i from 1 to number of items in added_items
	set this_item to item i of added_items as alias
	
	tell application "Safari" to activate
	
	
end repeat

on check_added_items(the added_items)
	-- check the transfer status of every added file to determine
	-- if each file has completed being moved into the attached folder
	set the notbusy_items to {}
	repeat with i from 1 to the number of items in the added_items
		set this_item to (item i of the added_items)
		if my check_busy_status(this_item) is false then
			set the end of the notbusy_items to this_item
		end if
	end repeat
	return the notbusy_items
end check_added_items

on check_busy_status(this_item)
	-- a folder can contain items partially transfered
	-- this routine will wait for all the folder contents to transfer
	if the last character of (this_item as text) is ":" then
		set the check_flag to false
		repeat
			-- look for any files within the folder that are still transferring
			tell application "Finder"
				try
					set the busy_items to the name of every file of the entire contents of this_item ¬
						whose file type begins with "bzy"
				on error
					set the busy_items to {}
				end try
			end tell
			if the check_flag is true and the busy_items is {} then return false
			-- pause for the indicated time
			delay the folder_check_delay_time
			-- set the flag and check again
			set the check_flag to true
		end repeat
	else -- the passed item is a single file, suitcase, clipping, etc.
		
		(*
       -- check the label of the item. If it is the marked label, then it's already been processed so ignore.
       tell application "Finder"
           if (the label index of this_item) as integer is the special_label_index then
               return "ignore"
           end if
       end tell
*)
		set the check_flag to false
		repeat
			tell application "Finder"
				set the item_file_type to the file type of this_item
			end tell
			if the check_flag is true and ¬
				the item_file_type does not start with "bzy" then
				
				(*
tell application "Finder"
                   set the label index of this_item to the special_label_index
               end tell
*)
				-- allow the Finder time to change the label
				delay the item_check_delay_time
				return false
			else if the item_file_type does not start with "bzy" then
				-- set the flag and check again
				set the check_flag to true
			end if
			-- pause for the indicated time
			delay the item_check_delay_time
		end repeat
	end if
end check_busy_status

I found and slightly adjusted a post that accomplishes this a little more simply:

set myFolder to ((path to desktop folder as text) & "myfolder:") as alias
set firstSize to size of (info for myFolder) --get initial size
delay 3 --wait 3 seconds
set newSize to size of (info for myFolder) --get a newer size, bigger
repeat while newSize ≠ firstSize --if they don't equal, loop until they do
	set firstSize to newSize --new base size
	delay 3 --wait three seconds
	set newSize to size of (info for myFolder) --get a newer size
end repeat --once the sizes match, the transfer is complete
tell application "Safari" to activate

why not easiily


set myFolder to ((path to desktop folder as text) & "myFolder:")
tell application "Finder" to set theFiles to files of folder myFolder
repeat with oneFile in theFiles
	checkStableSize(oneFile)
end repeat
say "done"

on checkStableSize(myFile)
	set f to quoted form of POSIX path of (myFile as alias)
	set sizeThen to first word of (do shell script "du -d 0 " & f)
	delay 2 -- seconds (set to longer if needed)
	set sizeNow to first word of (do shell script "du -d 0 " & f) as integer --coercing to integer fixes the quote problem
	return (sizeNow - sizeThen = 0)
end checkStableSize

As always, I like your approach more. Thanks again Stefan.

sorry there’s repeat loop missing


set myFolder to ((path to desktop folder as text) & "myFolder:")
tell application "Finder" to set theFiles to files of folder myFolder
repeat with oneFile in theFiles
	repeat until checkStableSize(oneFile)
	end repeat
end repeat
say "done"

on checkStableSize(myFile)
	set f to quoted form of POSIX path of (myFile as alias)
	set sizeThen to first word of (do shell script "du -d 0 " & f)
	delay 2 -- seconds (set to longer if needed)
	set sizeNow to first word of (do shell script "du -d 0 " & f) as integer --coercing to integer fixes the quote problem
	return (sizeNow - sizeThen = 0)
end checkStableSize