This script creates a JSON file for each selected record.
- property
theCMD_Identifiers
: List of Custom Meta Data identifiers. Add whatever you want.
- property
theOutputFolder_Path
: Path of folder where the JSON files are created.
- property
sortKeys
: Whether the Keys should be sorted. If false
Keys appear in the order they were added.
- There’s a part “Add other key:value pairs here” part where you can add your other values.
Please don’t process all records in one go. You can e.g. set a label or a tag to keep track of what’s already processed. It might be a good idea to create subfolders after each script run because 23.000 files in a single folder might cause problems. Don’t forget to change property theOutputFolder_Path
.
The JSON filenames are build from the record’s name without extension
plus json
. This means if you would create all JSON files into a single folder and not all your records got unique filenames then the script would overwrite previously created JSON files. To prevent this the record’s UUID
is used when necessary.
-- Export Custom Meta Data to JSON files
use AppleScript version "2.4"
use framework "Foundation"
use scripting additions
property theCMD_Identifiers : {"primarycolor", "secondarycolor", "tertiarycolor"} -- Set the Custom Meta Data identifiers
property theOutputFolder_Path : (POSIX path of (path to desktop)) & "Script Output" -- Replace this with a path like "/Users/username/abc/xyz" (or create folder "Script Output" on your desktop)
property sortKeys : false
set theCMD_Titles to my getCustomMetaDataTitles(theCMD_Identifiers)
set theAttributes to {}
repeat with i from 1 to (count of theCMD_Titles)
set thisCMD_Title to item i of theCMD_Titles
set end of theAttributes to {trait_type:thisCMD_Title, value:""}
end repeat
set theDictionary to current application's NSMutableDictionary's new()
set theAttributesArray to current application's NSMutableArray's new()
set theOutputFolder_Path_String to (current application's NSString's stringWithString:theOutputFolder_Path)
tell application id "DNtp"
try
set theRecords to selected records
if theRecords = {} then error "Please select some records."
repeat with thisRecord in theRecords
repeat with i from 1 to (count of theCMD_Identifiers)
set thisCMD_Title to item i of theCMD_Titles
set thisCMD_Identifier to item i of theCMD_Identifiers
set thisCMD_Value to get custom meta data for thisCMD_Identifier from thisRecord
if thisCMD_Value = missing value then set thisCMD_Value to ""
set theAttributesArray to my setValueInAttributesArray(item i of theCMD_Titles, thisCMD_Value, theAttributesArray)
end repeat
-------------------------------------------------------------------------------------------------------------------------------------------------
-- Add other key:value pairs here
set thisKey to "name"
set thisValue to filename of thisRecord
my setValue(thisKey, thisValue, theDictionary)
#set thisKey to "description"
#set thisValue to ""
#my setValue(thisKey, thisValue, theDictionary)
#set thisKey to "image"
#set thisValue to ""
#my setValue(thisKey, thisValue, theDictionary)
#set thisKey to "edition"
#set thisValue to ""
#my setValue(thisKey, thisValue, theDictionary)
-------------------------------------------------------------------------------------------------------------------------------------------------
my setValue("attributes", theAttributesArray, theDictionary)
-------------------------------------------------------------------------------------------------------------------------------------------------
set thisJSONFile_Filename to (name without extension of thisRecord & ".json")
set thisRecord_UUID to uuid of thisRecord
set success to my writeToFile(theDictionary, theOutputFolder_Path_String, thisJSONFile_Filename, thisRecord_UUID)
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
on getCustomMetaDataTitles(theCMD_Identifiers)
try
set theData to current application's NSFileManager's defaultManager()'s contentsAtPath:(POSIX path of (path to application support from user domain) & "DEVONthink 3/CustomMetaData.plist")
set {theCustomMetaDataPlistArray, theError} to (current application's NSPropertyListSerialization's propertyListWithData:theData options:0 format:(current application's NSPropertyListXMLFormat_v1_0) |error|:(reference))
if theError ≠missing value then error (theError's localizedDescription() as string)
set theCMD_Identifiers_withMD to "{\"md" & my tid(theCMD_Identifiers, "\",\"md") & "\"}"
set theCustomMetaDataPlistArray_filtered to (theCustomMetaDataPlistArray's filteredArrayUsingPredicate:(current application's NSPredicate's predicateWithFormat:("self.identifier IN " & theCMD_Identifiers_withMD)))
set theCMD_Titles to (theCustomMetaDataPlistArray_filtered's valueForKey:"title") as list
on error error_message number error_number
activate
if the error_number is not -128 then display alert "Error: Handler \"getCustomMetaDataTitles\"" message error_message as warning
error number -128
end try
end getCustomMetaDataTitles
on setValueInAttributesArray(thisCMD_Title, thisCMD_Value, theAttributesArray)
try
set thisDictionary to (current application's NSMutableDictionary's dictionaryWithDictionary:{trait_type:thisCMD_Title, value:thisCMD_Value})
theAttributesArray's addObject:thisDictionary
return theAttributesArray
on error error_message number error_number
activate
if the error_number is not -128 then display alert "Error: Handler \"setValueInAttributesArray\"" message error_message as warning
error number -128
end try
end setValueInAttributesArray
on setValue(theKey, theValue, theDictionary)
try
theDictionary's setValue:theValue forKey:theKey
return theDictionary
on error error_message number error_number
activate
if the error_number is not -128 then display alert "Error: Handler \"setValue\"" message error_message as warning
error number -128
end try
end setValue
on writeToFile(theDictionary, theOutputFolder_Path_String, theJSONFile_Filename, theUUID)
try
set theJSON_String to my formatJSON(theDictionary, true, sortKeys)
set theJSON_Path to (theOutputFolder_Path_String's stringByAppendingPathComponent:theJSONFile_Filename)
set existsPath to current application's NSFileManager's defaultManager's fileExistsAtPath:theJSON_Path isDirectory:(missing value)
if existsPath then set theJSON_Path to (theOutputFolder_Path_String's stringByAppendingPathComponent:(theUUID & ".json"))
set {success, theError} to (theJSON_String's writeToFile:theJSON_Path atomically:no encoding:(current application's NSUTF8StringEncoding) |error|:(reference))
if success = false then error (theErrorMessage(theError's localizedDescription()) as string)
return success
on error error_message number error_number
activate
if the error_number is not -128 then display alert "Error: Handler \"writeToFile\"" message error_message as warning
error number -128
end try
end writeToFile
on formatJSON(theRecord, usePrettyPrint, useSortKeys)
try
if not (current application's NSJSONSerialization's isValidJSONObject:theRecord) then error "No valid JSON Object"
set theJSONOptions to 0
if usePrettyPrint then set theJSONOptions to theJSONOptions + ((current application's NSJSONWritingPrettyPrinted) as integer)
if useSortKeys then set theJSONOptions to theJSONOptions + ((current application's NSJSONWritingSortedKeys) as integer)
set {theJSONData, theError} to (current application's NSJSONSerialization's dataWithJSONObject:theRecord options:theJSONOptions |error|:(reference))
if theError ≠missing value then error (theError's localizedDescription() as string)
set theJSONString to (current application's NSString's alloc()'s initWithData:theJSONData encoding:(current application's NSUTF8StringEncoding))
return theJSONString
on error error_message number error_number
activate
if the error_number is not -128 then display alert "Error: Handler \"formatJSON\"" message error_message as warning
error number -128
end try
end formatJSON
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
PS the QuickLook Plugin you’re using doesn’t fit into the Dark Mode scheme. You might want to take a look at SourceCodeSyntaxHighlight:
PPS FileMaker is nice but can’t replace DEVONthink. Eagerly waiting for the free version for single users.