Ok, (photo) keywords to tags work - ... but how about tags to keywords?

@lerone I should have mentioned that this was just for testing on your side and not ready for use as smart rule, sorry for the trouble.

Speaking of smart rules there’s something else to mention: If you use an external script and change the value of a property (the ones at the top) it’s necessary to restart DEVONthink. Without restarting the script uses the old value because DEVONthink caches scripts. Embedded scripts don’t need a restart.

To test smart rule scripts in Script Editor you can add this line: tell application id "DNtp" to my PerformSmartRule(selection as list). A very nice tip found here (but @cgrunenberg might want to fix “on” from “my onPerformSmartRule(selection as list)”, it’s a bit confusing :slight_smile: )

The smart rule below has an option to sort keywords which makes it easier (for me) to compare tags and keywords.

-- Add DEVONthink tags to image keywords [Smart Rule]
-- Test this with duplicates!

property overwriteKeywordsWithTags : false -- set to true if you want to mirror DEVONthink tags
property sortKeywords : false

on PerformSmartRule(theRecords)
	tell application id "DNtp"
		try
			repeat with thisRecord in theRecords
				set thePath to path of thisRecord
				
				try
					set theMetaData to meta data of thisRecord
					set existingKeywords to my textItemDelimiters(KMDItemKeywords of theMetaData, "," & linefeed)
				on error
					set existingKeywords to {}
				end try
				
				set theTags to tags of thisRecord
				
				if my sort_list(theTags) ≠ my sort_list(existingKeywords) then
					if overwriteKeywordsWithTags = true then
						if sortKeywords = true then
							set overwriteAndSort to my overwriteKeywords((my string_From_List(my sort_list(theTags), ", ")), thePath)
						else
							set overwrite to my overwriteKeywords(my string_From_List(theTags, ", "), thePath)
						end if
						
					else if overwriteKeywordsWithTags = false then
						set tagsToAdd_list to {}
						repeat with thisTag in theTags
							if existingKeywords does not contain thisTag then set end of tagsToAdd_list to thisTag as string
						end repeat
						if sortKeywords = true then
							set addAndSort to my overwriteKeywords((my string_From_List(my sort_list(existingKeywords & tagsToAdd_list), ", ")), thePath)
						else
							set theTags_string to my string_From_List(theTags, ", ")
							set addTagsToKeywords to do shell script "/usr/local/bin/exiftool -sep ', ' -iptc:Keywords-=\"" & theTags_string & "\" -iptc:Keywords+=\"" & theTags_string & "\" -overwrite_original_in_place " & quoted form of thePath
						end if
					end if
				end if
			end repeat
			
		on error error_message number error_number
			if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
			return
		end try
	end tell
end PerformSmartRule

on overwriteKeywords(theString, thePath)
	do shell script "/usr/local/bin/exiftool -sep ', ' -iptc:Keywords=\"" & theString & "\" -overwrite_original_in_place " & quoted form of thePath
end overwriteKeywords

on textItemDelimiters(theText, theDelimiter)
	set d to AppleScript's text item delimiters
	set AppleScript's text item delimiters to theDelimiter
	set TextItems to text items of theText
	set AppleScript's text item delimiters to d
	return TextItems
end textItemDelimiters

on string_From_List(theList, theDelimiter)
	set theString to ""
	set theCount to 0
	repeat with thisItem in theList
		set theCount to theCount + 1
		set thisItem to thisItem as string
		if theCount ≠ (count of theList) then
			set theString to theString & thisItem & theDelimiter
		else
			set theString to theString & thisItem
		end if
	end repeat
	return theString
end string_From_List

on sort_list(theList)
	set old_delims to AppleScript's text item delimiters
	set AppleScript's text item delimiters to {ASCII character 10} -- always a linefeed
	set list_string to (theList as string)
	set new_string to do shell script "echo " & quoted form of list_string & " | sort -f"
	set new_list to (paragraphs of new_string)
	set AppleScript's text item delimiters to old_delims
	return new_list
end sort_list

@lerone regarding MetaImage.app, maybe you can get a refund?


Offtopic: Hi @BLUEFROG I’m working on a script that creates and sets custom thumbnails respecting the different record types (record, group etc.). It works fine in Script Debugger, but in DEVONthink it doesn’t work reliably. It sets a thumbail for record type “record” where it should set a thumbnail for e.g. type “group”. I’m going nuts on this, any ideas why it behaves different in Script Debugger and DEVONthink?

1 Like