Hi, I’m working on a script (using Script Debugger, of course) to create DEVONThink items from Zotero items. It’s sort of working. One bit I’d love help with is that I’m trying to maintain a persistent mapping for key/value pairs, the key being the Zotero citekey, and the value being the DEVONthink uuid. I’m using a plist to do this but that seems pretty slow and my code for doing it is a bit clunky. The script (work-in-progress, doesn’t work properly yet, etc.) is below. Any suggestions on how to do this better?

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

You can use an NSMutableDictionary that you can read/write as a property list very simply.

I don’t have the apps you’re dealing with, but this should get you started:

set theUUID to missing value
set mainDict to current application's NSMutableDictionary's dictionaryWithContentsOfFile:thePListFile
if mainDict is not missing value then set theUUID to mainDict's objectForKey:theKey
if theUUID is missing value then
tell application id "DNtp"
set theGroup to create location theDTLocation & "/" & theGroupFile
set theUUID to uuid of theGroup
end tell
else
set theUUI to the UUID as text
tell application id "DNtp"
set theGroup to get record with uuid theUUID
if theGroup is missing value then set theGroup to create location theDTLocation & "/" & theGroupFile
set theUUID to uuid of theGroup
end tell
mainDict's setObject:theUUID forKey:theKey
mainDict's writeToFile:thPlistfile atomically:true
end if

One other thing: you should try to restrict code in application tell blocks to code relevant to the app, and not nest tell blocks if possible.

@lyndondrake, there’s a lot of “stuff” going on in your script, so I might not have a clear picture, but it looks like you’re reading a JSON file and basically putting all the values from that into a property list file.

Since it’s possible (and very straightforward) to convert a JSON file to a property list file, would doing that meet the same objective as the one you’re trying to achieve here?

Can you demo how to convert a JSON file to a property list file? I’m actually wanting to take the data from the JSON file and add records to DEVONthink - the property list file is just to keep track of the mapping between IDs in the JSON file and the DEVONthink records.

I’ve got a project that will provide spec files to handle tag translations between two proprietary systems.
We were going to do this in xml, but the developer would prefer JSON.
I have the data in AppleScript records, is there a good solution to go from AppleScript records to JSON (and back again)?