Help modifying script

Hi all,
I am wondering if someone can help modify a script. I’ve realized that there have been some pretty awesome scripts developed by @zverhope on linking and indexing your bookends library into devonthink.

Here is the link to the original post: Autolinking Bookends & DEVONthink records

From my understanding, these scripts were developed before the custom meta data feature was added to DT and as such the metadata in this script is added in the comment pane. I’m wondering if there is a way to amend these to pul the data from bookends and add it to the custom metadata. I’ve seen scripts by @kseggleton and @cgrunenberg , but I cannot for the life of me get the “add custom meta data” part of the script to work in the one below:

tell application "Bookends"
	set theIDs to «event ToySRUID» "Selection"
	repeat with theID in paragraphs of theIDs
		tell front library window
			try
				set myRefs to (publication items whose id is theID)
				set myItem to first item of myRefs
				set thePath to path of attachment items of myItem
				if thePath is not {} then
					set {theKey, theAuthor, theEditor, theTitle} to {citekey, authors, editors, title} of myItem
					if theAuthor = "" then set theAuthor to theEditor
					set theRIS to format myItem using "RIS.fmt"
					set otid to AppleScript's text item delimiters
					set AppleScript's text item delimiters to linefeed
					set thePath to text items of thePath
					repeat with i in thePath
						set thisPath to i as string
						tell application "Finder" to set theName to name of (POSIX file thisPath as alias)
						set AppleScript's text item delimiters to otid
						
						try
							if (characters -4 thru -1 of theName as string) is ".pdf" then do shell script "/usr/local/bin/exiftool -title=" & quoted form of theTitle & " -author=" & quoted form of theAuthor & " -subject=" & theKey & " -overwrite_original " & quoted form of thisPath
						end try
						
						tell application id "DNtp"
							set theDatabase to open database "/aUsers/zhope/DTPO/Research.dtBase2"
							set theLocation to create location "/Library"
							set theRecord to indicate thisPath to theLocation
							set URL of theRecord to ("bookends://sonnysoftware.com/" & theID) as text
							set aliases of theRecord to theKey
							set comment of theRecord to theRIS
							set theLink to reference URL of theRecord
						end tell
						
					end repeat
					
					set user20 of myItem to theLink
					
				end if
				
			on error errorMessage
				
			end try
			
		end tell
	end repeat
end tell

Basically, I’m looking to extract metadata such as Title, Author, etc. similar to the one found in this post by @cgrunenberg: Download bibliographic metadata - #15 by cgrunenberg

If anyone has any ideas on how to get the first script to successfully add custom metadata to devonthink rather than adding it to the comments pane, I’d be most appreciative.

I don’t have bookends, so can’t work through this in practice.

set comment of theRecord to theRIS is adding the variable theRIS to the comment field of the record. If you simply want that data to be added to a custom metadata field instead of the comment field, you would simply change that line to add custom meta data theRIS for "IDOfYourCustomMetadata" to theRecord where IDOfYourCustomMetadata is the identifier of your custom metadata field (see Preferences/Data), enclosed in ".

If you want the data split up into various metadata fields, it would be helpful if you could post more info (such as: what is currently in the comments field, how should it be spilt, into which fields should it be split).

Thanks for the reply!

It would be something similar to this script adaptation by @cgrunenberg:

tell application "Bookends"
	tell front library window
		set theRefs to selected publication items
		repeat with theRef in theRefs
			set theID to id of theRef
			set theDOI to doi of theRef
			set thePMID to pmid of theRef
			set theISBN to isbn of theRef
			set theURL to url of theRef
			set theLanguage to language of theRef
			set theDate to publication date string of theRef
			set theCreationDate to date added of theRef
			set theModificationDate to date modified of theRef
			-- set theType to type of theRef
			
			set theTitle to title of theRef
			set theNotes to notes of theRef
			set theKeywords to keywords of theRef
			set {od, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ASCII character 10}
			set theTags to text items of theKeywords
			set AppleScript's text item delimiters to od
			
			set theAuthors to authors of theRef
			set theEditors to editors of theRef
			set thePublisher to publisher of theRef
			set theJournal to journal of theRef
			set theVolume to volume of theRef
			set thePages to pages of theRef
			set theRating to rating of theRef
			set theCitation to user1 of theRef -- user1 is the Bookends field where BibTex citation is stored
			set theAbstract to abstract of theRef
			set theContent to format theRef using "Summary.fmt" as RTF
			set theFormattedReference to format theRef using "APA 6th Edition Markdown.fmt"
			
			(* repeat with theAttachment in attachments of theRef
				set theFile to the first attachment item of theRef
				set thePath to the path of theFile
				if thePath is not "" then
				end if
			end repeat *)
			
			tell application id "DNtp"
				set theRecord to create record with {name:theTitle, type:rtf, content:theContent, rating:theRating, comment:theNotes, tags:theTags, creation date:theCreationDate, modification date:theModificationDate} in current group
				
				set URL of theRecord to ("bookends://sonnysoftware.com/" & theID) as text
				add custom meta data theDOI for "doi" to theRecord
				add custom meta data thePMID for "pmid" to theRecord
				add custom meta data theISBN for "is?n" to theRecord
				add custom meta data theURL for "link" to theRecord
				add custom meta data theLanguage for "language" to theRecord
				add custom meta data theDate for "date" to theRecord
				-- add custom meta data theType for "type" to theRecord
				
				add custom meta data theAuthors for "authors" to theRecord
				add custom meta data theEditors for "editors" to theRecord
				
				add custom meta data thePublisher for "publisher" to theRecord
				add custom meta data theVolume for "volume" to theRecord
				add custom meta data theJournal for "journal" to theRecord
				add custom meta data thePages for "page" to theRecord
				
				add custom meta data theAbstract for "abstract" to theRecord
				add custom meta data theCitation for "citation" to theRecord
				add custom meta data theFormattedReference for "reference" to theRecord
			end tell
		end repeat
	end tell
end tell

The title, authors, date of publication, editors journal, DOI, ISBN, things like that. Does that make sense. Those are the fields that can be populated in bookends. These other scrips are able to hand off the data well, but I can’t seem to integrate it into this script which is much more close to what I am looking for except the part where the metadata goes into the comments vs creating custom metadata fields.

Here is a screenshot of that what goes into the comment pane:

Screenshot 20210830 at 10.52

If I am reading this correctly, the data gets passed through the RIS filter in Bookends and then is pasted into comments section of DT.

The script you’re quoting already contains the code to set custom meta data fields. You could simply copy them, I guess.

I know, i thought that I could just copy and paste parts of one script into the other, but something gets broken along the way. The pdf and file name pass to DT, but the metadata never gets populated…

It would be helpful if you could post the script which you have written and which doesn’t work. It would be clear to me what you are trying to do then.

Or ZIP and post the script.

Really happy that you’ve found the script useful. I have multiple versions of this script floating around, and some of the most recent ones do include a custom metadata component. Here is one version of that script. All you’d need to do here is modify the metadata fields to include the data you’re interested in recording, and then enter the specific variable that you’re taking from Bookends into that field.

There are also three places in this script where you’ll need to enter the name of your BE library, your DT database, and the location within that database. I’ve included comments, so just enter the appropriate information between the quotation marks on those lines.



tell application "Bookends"
	tell (library windows whose name is "Name of your library") -- enter the name of your Bookends library (this is the name at the top of your window - e.g., "Research.bdb")
		set theRefs to selected publication items
		set theIDs to item 1 of theRefs
		set theErrors to "Errors Occurred with the Following Records:" & linefeed
		set isErr to false
		repeat with myItem in theIDs
			try
				set thePath to path of attachment items of myItem
				if thePath is not {} then
					set {theKey, theAuthor, theEditor, theTitle, dtpoLink, theID, theAbstract} to {citekey, authors, editors, title, user20, id, abstract} of myItem
					if dtpoLink is not "" then set dtpoLink to dtpoLink & linefeed
					if theAuthor = "" then set theAuthor to theEditor
					set theBib to format myItem using "BibTeX.fmt"
					set otid to AppleScript's text item delimiters
					set AppleScript's text item delimiters to linefeed
					set thePath to text items of thePath
					set theCount to 1
					repeat with i in thePath
						set thisPath to i as string
						tell application "Finder" to set theName to name of (POSIX file thisPath as alias)
						set AppleScript's text item delimiters to otid
						
						try
							if (characters -4 thru -1 of theName as string) is ".pdf" then do shell script "/usr/local/bin/exiftool -title=" & quoted form of theTitle & " -author=" & quoted form of theAuthor & " -keywords=" & theKey & " -overwrite_original " & quoted form of thisPath
						end try
						
						tell application id "DNtp"
							set theDatabase to open database "Path/to/Database" -- enter path to your database
							set theLocation to create location "/Location" in theDatabase -- enter desired location within your database
						set currentResults to lookup records with path thisPath in theDatabase
							if (count of currentResults) is 0 then
								set theRecord to indicate thisPath to theLocation
								set URL of theRecord to ("bookends://sonnysoftware.com/" & theID) as text
								set srcJSON to do shell script "/usr/local/bin/jq -r --arg arg1 \"" & dtpoLink & "\" --arg arg2 \"" & theTitle & "\" --arg arg3 \"" & theID & "\" --arg arg4 \"" & theKey & "\" --arg arg5 \"" & thisPath & "\" '. | .[\"id\"]=$arg4 | .[\"DEVONthink\"]=$arg1 | .[\"title\"]=$arg2 | .[\"path\"]=$arg5 | .[\"bookends\"]=$arg3' <<<'{}' "
								set bibJSON to do shell script "echo " & quoted form of theBib & " | /usr/local/bin/pandoc -f biblatex -t csljson"
								add custom meta data srcJSON for "srcjson" to theRecord
								add custom meta data bibJSON for "bibjson" to theRecord
								add custom meta data theKey for "citekey" to theRecord
								add custom meta data theBib for "bibtex" to theRecord
								add custom meta data theAbstract for "abstract" to theRecord
								set aliases of theRecord to theKey
								set theLink to reference URL of theRecord
								if theCount is greater than 1 then
									set dtpoLink to dtpoLink & linefeed & theLink
								else
									set dtpoLink to dtpoLink & theLink
								end if
								set theCount to theCount + 1
							end if
						end tell
					end repeat
					tell application "Bookends" to set user20 of myItem to dtpoLink
				end if
			on error errMsg
				set theErrors to theErrors & theKey & " - " & errMsg & linefeed
				set isErr to true
			end try
		end repeat
	end tell
end tell
2 Likes

Thanks so much for the reply. For some reason, this script does not do anything except create the location folder in my DT database. No file is moved into DT. I added the appropriate information where you’ve noted:

tell application "Bookends"
	tell (library windows whose name is "Research.bdb") -- enter the name of your Bookends library (this is the name at the top of your window - e.g., "Research.bdb")
		set theRefs to selected publication items
		set theIDs to item 1 of theRefs
		set theErrors to "Errors Occurred with the Following Records:" & linefeed
		set isErr to false
		repeat with myItem in theIDs
			try
				set thePath to path of attachment items of myItem
				if thePath is not {} then
					set {theKey, theAuthor, theEditor, theTitle, dtpoLink, theID, theAbstract} to {citekey, authors, editors, title, user20, id, abstract} of myItem
					if dtpoLink is not "" then set dtpoLink to dtpoLink & linefeed
					if theAuthor = "" then set theAuthor to theEditor
					set theBib to format myItem using "BibTeX.fmt"
					set otid to AppleScript's text item delimiters
					set AppleScript's text item delimiters to linefeed
					set thePath to text items of thePath
					set theCount to 1
					repeat with i in thePath
						set thisPath to i as string
						tell application "Finder" to set theName to name of (POSIX file thisPath as alias)
						set AppleScript's text item delimiters to otid
						
						try
							if (characters -4 thru -1 of theName as string) is ".pdf" then do shell script "/usr/local/bin/exiftool -title=" & quoted form of theTitle & " -author=" & quoted form of theAuthor & " -keywords=" & theKey & " -overwrite_original " & quoted form of thisPath
						end try
						
						tell application id "DNtp"
							set theDatabase to open database "/Users/marsgrover/Databases/Literature.dtBase2" -- enter path to your database
							set theLocation to create location "/My Library" in theDatabase -- enter desired location within your database
							set currentResults to lookup records with path thisPath in theDatabase
							if (count of currentResults) is 0 then
								set theRecord to indicate thisPath to theLocation
								set URL of theRecord to ("bookends://sonnysoftware.com/" & theID) as text
								set srcJSON to do shell script "/usr/local/bin/jq -r --arg arg1 \"" & dtpoLink & "\" --arg arg2 \"" & theTitle & "\" --arg arg3 \"" & theID & "\" --arg arg4 \"" & theKey & "\" --arg arg5 \"" & thisPath & "\" '. | .[\"id\"]=$arg4 | .[\"DEVONthink\"]=$arg1 | .[\"title\"]=$arg2 | .[\"path\"]=$arg5 | .[\"bookends\"]=$arg3' <<<'{}' "
								set bibJSON to do shell script "echo " & quoted form of theBib & " | /usr/local/bin/pandoc -f biblatex -t csljson"
								add custom meta data srcJSON for "srcjson" to theRecord
								add custom meta data bibJSON for "bibjson" to theRecord
								add custom meta data theKey for "citekey" to theRecord
								add custom meta data theBib for "bibtex" to theRecord
								add custom meta data theAbstract for "abstract" to theRecord
								set aliases of theRecord to theKey
								set theLink to reference URL of theRecord
								if theCount is greater than 1 then
									set dtpoLink to dtpoLink & linefeed & theLink
								else
									set dtpoLink to dtpoLink & theLink
								end if
								set theCount to theCount + 1
							end if
						end tell
					end repeat
					tell application "Bookends" to set user20 of myItem to dtpoLink
				end if
			on error errMsg
				set theErrors to theErrors & theKey & " - " & errMsg & linefeed
				set isErr to true
			end try
		end repeat
	end tell
end tell

Odd…

Do you get any error message? I’m wondering if the calls to do shell script might be breaking the script for you. Perhaps just try extracting the custom meta data portions of the script above, place them in the older script that’s working for you, and see if that suffices?

I think I did it. It seems to work well now and imports much of the metadata I needed. I modified the script that runs on a named group as well.

I have a question about how to effectively sync this automatically. For example, do you have a group in bookends that you run this on every time? This script doesn’t work with bookends’ built in groups, so do you have a workflow that would automatically update a folder from bookends to DT by running this script?

It seems that the other script you’ve posted can be executed without the library window open, correct?


tell application "Bookends"
	tell front library window
		set theIDs to get id of publication items of group item "Data Policing"
		repeat with theID in theIDs
			try
				set myRefs to (publication items whose id is theID)
				set myItem to first item of myRefs
				set thePath to path of attachment items of myItem
				if thePath is not {} then set {theKey, theAuthor, theEditor, theTitle, theJournal, thePublisher, theVolume, thePages} to {citekey, authors, editors, title, journal, publisher, volume, pages} of myItem
				if theAuthor = "" then set theAuthor to theEditor
				set otid to AppleScript's text item delimiters
				set AppleScript's text item delimiters to linefeed
				set thePath to text items of thePath
				repeat with i in thePath
					set thisPath to i as string
					tell application "Finder" to set theName to name of (POSIX file thisPath as alias)
					set AppleScript's text item delimiters to otid
					
					try
						if (characters -4 thru -1 of theName as string) is ".pdf" then do shell script "/usr/local/bin/exiftool -title=" & quoted form of theTitle & " -author=" & quoted form of theAuthor & " -subject=" & theKey & " -overwrite_original " & quoted form of thisPath
					end try
					
					tell application id "DNtp"
						set theDatabase to open database "/Users/marsgrover/Databases/Literature.dtBase2"
						set theLocation to create location "/Test Library"
						set theRecord to indicate thisPath to theLocation
						set URL of theRecord to ("bookends://sonnysoftware.com/" & theID) as text
						set aliases of theRecord to theKey
						set theLink to reference URL of theRecord
						add custom meta data theAuthor for "authors" to theRecord
						add custom meta data theTitle for "title" to theRecord
						add custom meta data theEditor for "editors" to theRecord
						add custom meta data theJournal for "journal" to theRecord
						add custom meta data thePublisher for "publisher" to theRecord
						add custom meta data theVolume for "volume" to theRecord
						add custom meta data thePages for "pages" to theRecord
						
					end tell
					
				end repeat
				
				set user20 of myItem to theLink
				
			on error errorMessage
				
			end try
		end repeat
	end tell
end tell

Yeah, if you look at the gist here you’ll see a version of the script that works on a Bookends group called “Unlinked Attachments”. This group shows every record that includes an attachment but has no entry in the user20 field. If you wanted to automate it, you could create a Keyboard Maestro or Automator macro to do so, but I typically do it manually once a week, or whenever I need a recently added document in my DEVONthink database.

The SQL I use for the group in Bookends is:

(attachments IS NOT NULL) AND (user20 IS NULL) AND (thedate IS NOT NULL) AND (attachments REGEX '^\S*\d{4}[a-z]?-\S*?(?=\.).(pdf|epub|mobi|md|webarchive|djvu|txt|md)') OR ((attachments REGEX '\n') AND (user20 REGEX '^.*$'))

Great, thank you. My only issue now is that the script will create a new location in whatever database I have open and active in my DT window. I ran the script and realized that I had a different database active and the PDFs imported there.
Is there a way to prevent this from happening. In the script I have identified the specific filepath of the desired database, yet it only imports to the active database.

Any ideas?

Did you read the description of create location?

createLocation method : Create a hierarchy of groups if necessary.

create location [Text]: The hierarchy as a POSIX path (/ in names has to be replaced with \/, see location property).
[in: [Database] : The database. Uses current database if not specified.
→ [Record]

you call create location without using in database. It is of course not sufficient to just set a database somewhere, you have to use this setting, too.

Thank you! I think I got it now!

Thanks everyone! I really like this community. :smiley:

2 Likes

I was just about to come write this. Glad to hear it’s all working, @MarsGrover