Converting a recursive-renaming folder script into a droplet

Instead of having the following script prompt the user to choose the folder, I would like for the user to be able to drop the target folder on a droplet to start the conversion.

tell application "Finder" to set the source_folder to choose folder
my handleFolder(source_folder)
to handleFolder(source_folder) -- this handler burrows down the folder heirarchy
	set filelist to source_folder
end handleFolder
to handleFiles(myfilelist) -- this performs the file operations
	repeat with fileToProcess in source_folder
	end repeat
end handleFiles

set the search_parameter to "Both"


set the search_string to "XXX00000"


repeat
	display dialog "Enter the job number:" default answer "" buttons {"Cancel", "OK"} default button 2
	set the replacement_string to the text returned of the result
	if the replacement_string contains ":" then
		beep
		display dialog "A file or folder name cannot contain a colon (:)." buttons {"Cancel", "OK"} default button 2
	else if the replacement_string contains "/" then
		beep
		display dialog "A file or folder name cannot contain a forward slash (/)." buttons {"Cancel", "OK"} default button 2
	else
		exit repeat
	end if
end repeat

set dd to {source_folder} -- # added
repeat until my dd = {} -- # added
	set source_folder to my dd's item 1 -- # added
	set dd to my dd's rest -- # added
	set the item_list to list folder source_folder without invisibles
	set source_folder to source_folder as string
	repeat with i from 1 to number of items in the item_list
		set this_item to item i of the item_list
		set this_item to (source_folder & this_item) as alias
		set this_info to info for this_item
		if folder of this_info then set end of my dd to this_item -- # added
		set the current_name to the name of this_info
		set change_flag to false
		if the current_name contains the search_string then
			if the search_parameter is "Folder Names" and ¬
				folder of this_info is true then
				set the change_flag to true
			else if the search_parameter is "File Names" and ¬
				folder of this_info is false then
				set the change_flag to true
			else if the search_parameter is "Both" then
				set the change_flag to true
			end if
			if the change_flag is true then
				-- replace target string using delimiters
				set AppleScript's text item delimiters to the search_string
				set the text_item_list to every text item of the current_name
				set AppleScript's text item delimiters to the replacement_string
				set the new_item_name to the text_item_list as string
				set AppleScript's text item delimiters to ""
				my set_item_name(this_item, new_item_name)
			end if
		end if
	end repeat
end repeat --# added

beep 2

on set_item_name(this_item, new_item_name)
	tell application "Finder"
		--activate
		set the parent_container_path to (the container of this_item) as text
		if not (exists item (the parent_container_path & new_item_name)) then
			try
				set the name of this_item to new_item_name
			on error the error_message number the error_number
				if the error_number is -59 then
					set the error_message to "This name contains improper characters, such as a colon (:)."
				else --the suggested name is too long
					set the error_message to error_message -- "The name is more than 31 characters long."
				end if
				--beep
				tell me to display dialog the error_message default answer new_item_name buttons {"Cancel", "Skip", "OK"} default button 3
				copy the result as list to {new_item_name, button_pressed}
				if the button_pressed is "Skip" then return 0
				my set_item_name(this_item, new_item_name)
			end try
		else --the name already exists
			--beep
			tell me to display dialog "This name is already taken, please rename." default answer new_item_name buttons {"Cancel", "Skip", "OK"} default button 3
			copy the result as list to {new_item_name, button_pressed}
			if the button_pressed is "Skip" then return 0
			my set_item_name(this_item, new_item_name)
		end if
	end tell
end set_item_name

Browser: Safari 530.19
Operating System: Mac OS X (10.5)

Hi,

easiest way


on open theFolders
	my handleFolder(item 1 of theFolders)
	-- .
	
	
	
	-- .
	beep 2
end open

to handleFolder(source_folder) -- this handler burrows down the folder heirarchy
	set filelist to source_folder
end handleFolder

to handleFiles(myfilelist) -- this performs the file operations
	repeat with fileToProcess in source_folder
	end repeat
end handleFiles

it’s important to keep the handleFolder and handleFiles handlers out of the open handler
and it’s anyway better scripting habit to write the handlers outside the main code.
This makes the script better readable.

Thanks for your reply. Is the following the way you meant? When I compile this, I get an error (Expected “end” but found “on”.) on line 58, (on set_item_name(this_item, new_item_name)). I then removed lines 58-85 and when I tested, I received the error that “The variable source_folder is not defined.”

on open theFolders
	my handleFolder(item 1 of theFolders)
	-- .
	set the search_parameter to "Both"
	
	set the search_string to "XXX00000"
	
	repeat
		display dialog "Enter the job number:" default answer "" buttons {"Cancel", "OK"} default button 2
		set the replacement_string to the text returned of the result
		if the replacement_string contains ":" then
			beep
			display dialog "A file or folder name cannot contain a colon (:)." buttons {"Cancel", "OK"} default button 2
		else if the replacement_string contains "/" then
			beep
			display dialog "A file or folder name cannot contain a forward slash (/)." buttons {"Cancel", "OK"} default button 2
		else
			exit repeat
		end if
	end repeat
	
	set dd to {source_folder} -- # added
	repeat until my dd = {} -- # added
		set source_folder to my dd's item 1 -- # added
		set dd to my dd's rest -- # added
		set the item_list to list folder source_folder without invisibles
		set source_folder to source_folder as string
		repeat with i from 1 to number of items in the item_list
			set this_item to item i of the item_list
			set this_item to (source_folder & this_item) as alias
			set this_info to info for this_item
			if folder of this_info then set end of my dd to this_item -- # added
			set the current_name to the name of this_info
			set change_flag to false
			if the current_name contains the search_string then
				if the search_parameter is "Folder Names" and ¬
					folder of this_info is true then
					set the change_flag to true
				else if the search_parameter is "File Names" and ¬
					folder of this_info is false then
					set the change_flag to true
				else if the search_parameter is "Both" then
					set the change_flag to true
				end if
				if the change_flag is true then
					-- replace target string using delimiters
					set AppleScript's text item delimiters to the search_string
					set the text_item_list to every text item of the current_name
					set AppleScript's text item delimiters to the replacement_string
					set the new_item_name to the text_item_list as string
					set AppleScript's text item delimiters to ""
					my set_item_name(this_item, new_item_name)
				end if
			end if
		end repeat
	end repeat --# added
	
	on set_item_name(this_item, new_item_name)
   tell application "Finder"
       --activate
       set the parent_container_path to (the container of this_item) as text
       if not (exists item (the parent_container_path & new_item_name)) then
           try
               set the name of this_item to new_item_name
           on error the error_message number the error_number
               if the error_number is -59 then
                   set the error_message to "This name contains improper characters, such as a colon (:)."
               else --the suggested name is too long
                   set the error_message to error_message -- "The name is more than 31 characters long."
               end if
               --beep
               tell me to display dialog the error_message default answer new_item_name buttons {"Cancel", "Skip", "OK"} default button 3
               copy the result as list to {new_item_name, button_pressed}
               if the button_pressed is "Skip" then return 0
               my set_item_name(this_item, new_item_name)
           end try
       else --the name already exists
           --beep
           tell me to display dialog "This name is already taken, please rename." default answer new_item_name buttons {"Cancel", "Skip", "OK"} default button 3
           copy the result as list to {new_item_name, button_pressed}
           if the button_pressed is "Skip" then return 0
           my set_item_name(this_item, new_item_name)
       end if
   end tell
end set_item_name
	-- .
	beep 2
end open

to handleFolder(source_folder) -- this handler burrows down the folder heirarchy
	set filelist to source_folder
end handleFolder

to handleFiles(myfilelist) -- this performs the file operations
	repeat with fileToProcess in source_folder
	end repeat
end handleFiles

basically yes. In AppleScript nested handlers are not allowed. You must keep all handlers out of the on open handler, including on set_item_name().

How could I rewrite the [on set_item_name(this_item, new_item_name)] part so it fits in? It also appears that I have to replace the [tell application “Finder” to set the source_folder to choose folder] in the original post so that the source_folder gets set. Thanks.

just delete or comment out the line


tell application "Finder" to set the source_folder to choose folder

and move the complete code from


on set_item_name(this_item, new_item_name)

to


end set_item_name

out of the on open handler to the top level of the script