replicate selected items to named folder

I have revised this script and thought I’d share.

It allows you to replicate the selected items to a group whose (partial) name you type in a dialogue box. Very handy for using devonthink pro 2 to file items without mousing around. I save it with the filename replicate_to_folder___ctrl_r for quick single key filing. It also leaves the selection intact so you can hit delete after the script is done and the record has been moved. Saves on the carpal tunnel for me. I hope it is useful.

You do need to install growl to make this work…
-erico


----replicate to named group 
--by Eric Oberle v 1.1
--This script assumes you have selected a group of records. 
---It then will replicate those records to a folder of your choosing.
----It will attempt to locate this folder based on a string search of all folders in all currently open databases.  
---It searches all open databases, and if the chosen destination is in another database, the script will export it from the current database and reimport it to the new one. 

--this script requires Mac Growl to be installed for notifications.

tell application "DEVONthink Pro"
	
	log name of current database
	set safe_sel to {selection}
	if safe_sel is not application then
		set cur_sel to selection
		set first_item to first item of cur_sel
		set rec_name to name of first_item
	else
		display dialog "please select an item"
	end if
	
	---prompt user for records to search
	set the_filter to "*"
	set the_filter to display dialog "Please enter a portion of the destination to which you would like to replicate the selected records:  " & rec_name default answer "*"
	set the_filter to text returned of the_filter
	set combined_record_list to my records_matching_name(the_filter)
	
	--build list of hierarchical names
	set combined_name_list to my build_hierarchical_list(combined_record_list)
	
	
	if (count of combined_name_list) is greater than 0 then
		set destination_list to my choose_record_from_name_list(combined_name_list, combined_record_list)
		
		repeat with the_destination in destination_list
			--		set the_destination to item (this_target) of record_list
			log "about to replicate" & name of the_destination
			
			repeat with the_rec in cur_sel
				--duplicate record the_rec to the_destination
				set the_rep to replicate record the_rec to the_destination
				
				
				log the_rep
				if the_rep is missing value then
					---duplicate the record if replicating fails
					---(It probably failed because the destination is in a different database than the target, so export the record.) 
					log "detected missing value"
					log (duplicate record the_rec to the_destination)
					set the_export to export record the_rec to "/tmp/"
					import the_export to the_destination
					my growlNotification("DEVONthink Pro", "duplicated " & name of the_rec & " to ", name of the_destination)
					
					log (do shell script ("rm -r " & quoted form of the_export))
					
				else
					my growlNotification("DEVONthink Pro", "replicated " & name of the_rep, name of the_destination)
					
				end if
			end repeat
		end repeat
		
	else
		---if we didn't find the destination, allow user to create it.
		beep
		set new_folder to display dialog "Destination not found. To create a new group please ennter it here or cancel to exit:  " & rec_name default answer the_filter
		set new_folder to text returned of new_folder
		---prompt user for records to search
		
		set the_filter to display dialog "We are now going to search for the destination of the new group " & new_folder & ". Please enter a partial name." default answer "*"
		set the_filter to text returned of the_filter
		
		set combined_record_list to my records_matching_name(the_filter)
		
		--build list of hierarchical names
		set combined_name_list to my build_hierarchical_list(combined_record_list)
		
		
		if (count of combined_name_list) is greater than 0 then
			set destination_list to my choose_record_from_name_list(combined_name_list, combined_record_list)
			repeat with this_destination in destination_list
				set new_record to create record with {type:group, name:new_folder} in this_destination
				repeat with the_rec in cur_sel
					set the_rep to replicate record the_rec to new_record
				end repeat
			end repeat
		end if
		
	end if
	
	
end tell



on choose_record_from_name_list(name_list, record_list)
	---given two lists--a list of names and a list of records that are equal in length and
	--corresponding to each other, this subroutine asks the user to pick from the name list
	---and returns the corresponding record(s)
	set destination_records to {}
	set destination_numbers to {}
	tell application "DEVONthink Pro"
		set user_choice to choose from list name_list with multiple selections allowed
		log user_choice
		
		if user_choice is {} then
			return {}
			
		else
			
			---choose item returns the string they actually chose....
			---so recurse through list again to figure out which item that was
			set the_choices to every item of user_choice
			log the_choices
			log item 1 of the_choices
			repeat with this_choice in the_choices
				set the_counter to 0
				repeat with this_record in name_list
					set the_counter to the_counter + 1
					log "comparing " & this_choice & " to " & this_record & return
					if this_record contains this_choice or this_record is equal to this_choice then
						set destination_numbers to destination_numbers & {the_counter}
						set the_dest to item (the_counter) of record_list
						
						set destination_records to destination_records & {the_dest}
						--		set the_destination to item (this_target) of record_list
						log "found match"
					end if
				end repeat
			end repeat
			return destination_records
		end if
	end tell
end choose_record_from_name_list


on records_matching_name(the_string)
	tell application "DEVONthink Pro"
		set record_list to {}
		set the_dbs to get databases
		repeat with this_db in the_dbs
			set record_list to record_list & (every parent of this_db whose name contains the_string)
		end repeat
		return record_list
	end tell
end records_matching_name


on build_hierarchical_list(the_records)
	set name_list to {}
	if the_records is not {} then
		repeat with this_rec in the_records
			set hier_name to my name_hierarchy(this_rec, "", true)
			set name_list to name_list & hier_name
		end repeat
	end if
	return name_list
end build_hierarchical_list


on name_hierarchy(the_record, previous_parent, even_time_in)
	---uses recursion to create a string describing the "path" of the record....
	----this seems to be the only way to figure out the internal database path of a given record.
	---I can at least see no other method that works to discover the database to which a record belongs. 
	
	tell application "DEVONthink Pro"
		set the_string to ""
		set the_name to ""
		log name of the_record
		log kind of the_record
		log (count of parents of the_record)
		
		
		log {first parent of the_record}
		
		if (count of parents of the_record) is greater than 0 then
			set parent_name to name of first parent of the_record
			
			log "recursing " & name of the_record & " ** " & the_name
			if even_time_in is true then
				set the_name to "==>" & name of the_record
				set the_name to my name_hierarchy(first parent of the_record, parent_name, false) & the_name
				
			else
				
				set the_name to my name_hierarchy(first parent of the_record, parent_name, true) & " -> " & previous_parent & the_name
				
			end if
			
		else
			log "about to return " & the_name
			return previous_parent & the_name
		end if
		return the_name
	end tell
	
end name_hierarchy


on growlNotification(growlIcon, growlTitle, growlDescrip)
	
	if application "GrowlHelperApp" is running then
		set appName to "ericsdtnotify"
		set notifs to {growlTitle}
		
		tell application "GrowlHelperApp"
			register as application ¬
				appName all notifications notifs ¬
				default notifications notifs ¬
				icon of application growlIcon
			notify with name growlTitle title growlTitle description growlDescrip application name appName
		end tell
	end if
	return ""
end growlNotification