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.
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
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).
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:
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.
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.
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
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
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.
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.