This Smart Rule script moves linked images to the record’s new database.
It’s important that you set e.g. /Assets
in preferences, see below. It won’t work if there’s no slash.
What
The script checks
- whether an image is also linked in other records
- whether there’s already an identical image in the new database’s Assets group
(“identical image” means an image that would be a duplicate if both images shared a database)
Depending on these checks different things happen:
-
If only 1 record links to the image
-
If there’s no identical image in the new database’s Assets group:
Move image to new database’s Assets group -
If there’s an identical image in the new database’s Assets group:
Replace link URL with identical image’s reference URL and move unnecessary image to trash
-
-
If more than 1 record links to the image
-
If there’s no identical image in the new database’s Assets group:
Duplicate image and replace link URL with duplicated record’s reference URL -
If there’s an identical image in the new database’s Assets group:
Replace link URL with identical image’s reference URL
-
Setup
Preferences
- Go to preferences
Files > Markdown
- Set a location for
Import images to group…
, e.g./Assets
Note the slash at the start.
Script properties
- Set property
theImageDestinationLocation
to the location that you’ve set in preferences - If you use the “Record History” Smart Rule script click below
Click
Set property theRecordHistory_Name_End
to your Record History records’ name end. If the name is 2022-03-10 My daily record history
then set the property to My daily record history
.
The script uses the linked image’s incoming references
. If you use the “Record History” script and open an image then it’s added to the Record History, which means the Record History record is also added to the image’s incoming references
. Because the Record History and the records this script was written for both are Markdown there’s no way to distinguish between them other than filtering by name.
Smart Rule
Create a Smart Rule:
- Search in: Databases
- Matching:
- All
- Content:
 + 2) thru -1) in thisTextItem) as string
set thisLinkURL to ((characters 1 thru ((offset of ")" in thisTextItem_Part) - 1)) in thisTextItem_Part) as string
if thisLinkURL starts with "x-devonthink-item://" then
set thisImage to (get record with uuid thisLinkURL)
set thisImage_LocationGroup to location group of thisImage
if ("/" & (name of thisImage_LocationGroup)) = theImageDestinationLocation then
set theImageDestinationGroup_OldDatabase to thisImage_LocationGroup
exit repeat
end if
end if
end if
end repeat
if theImageDestinationGroup_OldDatabase ≠ missing value then
if theImageDestinationGroup_NewDatabase ≠ theImageDestinationGroup_OldDatabase then
set thisRecord_Text_new to thisRecord_Text
----------------------------------- Get images in old database's Assets group that link to record ------------------------------------
set theImages to (children of theImageDestinationGroup_OldDatabase whose incoming references contains thisRecord)
repeat with thisImage in theImages
------------------------------ Check whether there's an identical image in new database's Assets group -------------------------------
set theImageDestinationGroup_NewDatabase_Children to (children of theImageDestinationGroup_NewDatabase whose content hash = content hash of thisImage)
if theImageDestinationGroup_NewDatabase_Children = {} then
set theExistingDuplicateImage_ReferenceURL to missing value
else
set theExistingDuplicateImage_ReferenceURL to (reference URL of item 1 of theImageDestinationGroup_NewDatabase_Children) as string
end if
------------------------------------------------ Check how many records link to the image -------------------------------------------------
set thisImage_IncomingReferences to (incoming references of thisImage whose name without extension does not end with theRecordHistory_Name_End)
set thisImage_IncomingReferences_Count to (count of thisImage_IncomingReferences)
if thisImage_IncomingReferences_Count = 1 then
----------------------------------------------- Move image to new database's Assets group ------------------------------------------------
if theExistingDuplicateImage_ReferenceURL = missing value then
set thisImage to move record thisImage to theImageDestinationGroup_NewDatabase
-------------------- Replace link URL with identical image's Reference URL and move unnecessary image to trash ---------------------
else if theExistingDuplicateImage_ReferenceURL ≠ missing value then
set thisRecord_Text_new to my tid(my tid(thisRecord_Text_new, (reference URL of thisImage) as string), theExistingDuplicateImage_ReferenceURL)
move record thisImage to trash group of database of thisImage
end if
else if thisImage_IncomingReferences_Count > 1 then
----------------------------- Duplicate image and replace link URL with duplicated record's Reference URL ------------------------------
if theExistingDuplicateImage_ReferenceURL = missing value then
set thisDuplicatedImage to duplicate record thisImage to theImageDestinationGroup_NewDatabase
set thisRecord_Text_new to my tid(my tid(thisRecord_Text_new, (reference URL of thisImage) as string), (reference URL of thisDuplicatedImage) as string)
----------------------------------------- Replace link URL with identical image's Reference URL ------------------------------------------
else if theExistingDuplicateImage_ReferenceURL ≠ missing value then
set thisRecord_Text_new to my tid(my tid(thisRecord_Text_new, (reference URL of thisImage) as string), theExistingDuplicateImage_ReferenceURL)
end if
end if
end repeat
if thisRecord_Text_new ≠ thisRecord_Text then set plain text of thisRecord to thisRecord_Text_new
end if
else
log message info "Smart Rule: Couldn't find the moved record's old \"Assets\" group" record thisRecord
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 tid(theInput, theDelimiter)
set d to AppleScript's text item delimiters
set AppleScript's text item delimiters to theDelimiter
if class of theInput = text then
set theOutput to text items of theInput
else if class of theInput = list then
set theOutput to theInput as text
end if
set AppleScript's text item delimiters to d
return theOutput
end tid