Zotero to DT script (WIP) - ways to improve?

Hi,

I’ve been working on a script to take Zotero items (from a BetterBibTeX JSON export) and create a set of DT groups and items, much like the earlier Bookends script. Because I can’t put info back in Zotero, I’m trying to use a plist file to store the citekey/DT uuid pairs so taht if e.g. the title of the Zotero item changes I will update the DT item. It works but is pretty slow. Any ideas for how to construct, modify, and then serialise/deserialise a dictionary of citekey/uuid pairs?

Script below, but health warning that it’s pretty untested, is unfinished, and doesn’t work properly yet.

use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

-- all the settings should be here
set bibJSONFile to "/Users/lyndon/repo/workflow/zot-export-bbt-short.json"
set thePListFile to "/Users/lyndon/repo/workflow/zotero-to-devonthink.plist"
set theTemplateFile to "/Users/lyndon/Library/Application Support/DEVONthink 3/Templates.noindex/Education/Reference LD.md"
set theDTDBFile to "/Users/lyndon/DevonThink/Research.dtBase2"
set theDTLocation to "/Library"

-- 
property NSJSONSerialization : a reference to current application's NSJSONSerialization
property NSData : a reference to current application's NSData
set theJSONData to NSData's dataWithContentsOfFile:(bibJSONFile)
set theJSON to NSJSONSerialization's JSONObjectWithData:theJSONData options:0 |error|:(missing value)

set bibjson to theJSON as record
set therefs to |items| of bibjson

tell application "System Events"
	if exists property list file thePListFile then
		set thePList to property list file thePListFile
	else
		set thePList to make new property list file with properties {name:thePListFile}
	end if
end tell

tell application id "DNtp"
	set theDatabase to open database theDTDBFile
	set theLocation to create location theDTLocation
	
	repeat with theRef in therefs
		set {theKey, theTitle, theURI, theZoteroID} to {citationKey, title, uri, itemID} of theRef
		
		try
			set theTitle to |shortTitle| of theRef
		end try
		
		set theGroupFile to theKey & " " & theTitle
		set theUUID to ""
		try
			tell application "System Events"
				tell property list file thePListFile
					set theUUID to value of property list item theKey
				end tell
			end tell
		end try
		
		if theUUID = "" then
			set theGroup to create location theDTLocation & "/" & theGroupFile
			set theUUID to uuid of theGroup
			tell application "System Events"
				tell property list file thePListFile
					try
						set value of property list item theKey to theUUID
					on error
						tell property list items
							make new property list item at end with properties {kind:string, name:theKey, value:theUUID}
						end tell
					end try
				end tell
			end tell
		else
			set theGroup to get record with uuid theUUID
			if theGroup is missing value then
				set theGroup to create location theDTLocation & "/" & theGroupFile
			end if
			set theUUID to uuid of theGroup
			tell application "System Events"
				tell property list file thePListFile
					try
						set value of property list item theKey to theUUID
					on error
						tell property list items
							make new property list item at end with properties {kind:string, name:theKey, value:theUUID}
						end tell
					end try
				end tell
			end tell
		end if
		
		set theDOI to ""
		try
			set theDOI to DOI of theRef
		end try
		
		set theAbstract to ""
		try
			set theAbstract to abstractNote of theRef
		end try
		
		set theDate to ""
		try
			set theDate to date of theRef
		end try
		
		set theURL to ""
		try
			set theURL to URL of theRef
		end try
		
		set theAttachmentPath to ""
		try
			repeat with theAttachment in |attachments| of theRef
				try
					if (title of theAttachment) ≠ "Snapshot" then
						try
							set theAttachmentPath to |path| of theAttachment
							set theAttachmentURI to uri of theAttachment
							tell theGroup
								set theAttachmentRecord to lookup records with path theAttachmentPath
								if theAttachmentReord is missing value or (count of theAttachmentRecord) is less than 1 then
									set theAttachmentRecord to indicate theAttachmentPath to theGroup
								else
									set theAttachmentRecord to item 1 of the AttachmentRecord
								end if
								set custom meta data of the AttachmentRecord to {|date|:theDate, DOI:theDOI, abstract:theAbstract, citekey:theKey, zoteroid:theZoteroID}
							end tell
						end try
					end if
				end try
			end repeat
		end try
		
		set theCreators to ""
		set multipleCreators to ""
		try
			repeat with theCreator in creators of theRef
				try
					set theCreators to theCreators & multipleCreators & |firstName| of theCreator & " " & |lastName| of theCreator & "(" & |creatorType| of theCreator & ")"
					set multipleCreators to " and "
				end try
			end repeat
		end try
	end repeat
end tell

Have you seen this approach to importing Zotero to DT? I use it regularly. Are there some features in the import that you are seeking that it does not do?

Yes, I have seen it, but I want a structure that the other script doesn’t give - I want a group as a container for e.g. markdown annotations from Highlights, other notes I add manually, bookmarks, and so forth. I also want to tell DT to index the PDFs which I’ve linked in Zotero (which get renamed and moved to a standard location by Zotfile), again within the group for that item