I can do that. BTW what would be the format for an empty item-link?
It’s my own fault … I missed the fact that custom metadata was global and couldn’t be removed just like tags so I created a bit of a mess in my test database that has polluted far and wide.
If there is away to simply remove all custom metadata, then I would be ok with that since I have a script to generate the custom meta data that I am planning on using moving forward.
Interestingly if I run the script against an RTF formatted custom meta data field, then the text disappears from the custom info panel, but a large chunk of RTF data remains in the custom meta data record.
Alternatively, if I manually delete the RTF text from the info panel then it is removed from the info panel but - more interestingly - also completely removed from the custom meta data record. When I go to check the meta data after removing it in this way from the panel, then I get a missing value.
Not specific to RTF. If I manually remove a link from the info panel by setting it to “No Item” then the custom data changes to << empty >>. In other words manually removing custom meta data from the UI actually removes the key/value pair from the record, it does not just set the value to a 0/null/"" value, the key is gone (for that record).
I think a “remove” custom meta data command would be extremely useful. Perhaps even with the ability to not only specify a single (known) attribute, but all of them in one go. Just while we are dreaming …
Back to your log - I’m curious what you see if you do a
get custom meta data for “Rich Text” from content id …
after setting the meta data to “”
I am also getting a true return value, but there is custom styling info left behind in my case.
For anyone else running into this issue I would note the following temporary workaround for removing this “orphaned” RTF data and the custom meta data field from a record.
manually add any text via the info panel to the RTF custom meta data field
then manually remove that data, again from the info panel
The result (for me) is that the (key/value) pair for this custom meta data field are completely removed from that record.
In my case, I have identified the records that need to be “repaired” via a script and can now do that manually using this method.
I still like the idea of programmatically being able to remove custom meta data @cgrunenberg
With the scripting addition List & Record Tools (from one of the Script Debugger developers) it’s possible to delete items in an AppleScript record. Setting a record’s metadata to this changed AppleScript record works (didn’t test with rich text, but it should work too, I think).
My idea now is to delete unwanted metadata from all records in all databases in order to completely remove it from DEVONthink. Would this be sufficient? Is metadata automatically removed from CustomMetaData.plist if there’s no single record that uses it anymore? I really want to get completely rid of it.
The first is an utility script that copies meta data identifiers from DEVONthink’s plist.
Script: Copy Custom Meta Data Identifiers from plist
-- Copy Custom Meta Data Identifiers from plist
property sortIdentifiers : true
property thePlistPath : POSIX path of (path to application support from user domain) & "DEVONthink 3/CustomMetaData.plist"
tell application "System Events"
try
set theIdentifieres to {}
tell property list file thePlistPath
repeat with thisItem in property list items
set thisItem_Value to value of thisItem
set thisIdentifier to identifier of thisItem_Value
set end of theIdentifieres to thisIdentifier
end repeat
end tell
if sortIdentifiers = true then set theIdentifieres to my sort_list(theIdentifieres)
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
tell application id "DNtp"
try
activate
set chooseFromListItems to theIdentifieres
set theChoice to choose from list chooseFromListItems with prompt "Copy Identifier" default items (item 1 of chooseFromListItems) with title "Custom Meta Data"
if theChoice is false then return
set the clipboard to (item 1 of theChoice) as string
on error error_message number error_number
if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
end try
end tell
on sort_list(theList)
considering numeric strings
set theIndexList to {}
set theSortedList to {}
repeat (length of theList) times
set theLowItem to ""
repeat with a from 1 to (length of theList)
if a is not in theIndexList then
set theCurrentItem to item a of theList as text
if theLowItem is "" then
set theLowItem to theCurrentItem
set theLowItemIndex to a
else if theCurrentItem comes before theLowItem then
set theLowItem to theCurrentItem
set theLowItemIndex to a
end if
end if
end repeat
set end of theSortedList to theLowItem
set end of theIndexList to theLowItemIndex
end repeat
end considering
return theSortedList
end sort_list
The following scripts need the scripting addition List & Record Tools. Put it in /Users/Username/Library/ScriptingAdditions/ (create it if necessary).
The second writes meta data identifiers of selected records to a text file on desktop.
Script: Write Custom Meta Data Identifiers to file
-- Write Custom Meta Data Identifiers to file
use scripting additions
property theFilePath : (POSIX path of (path to desktop) & "Metadata Identifiers.txt") as string
tell application id "DNtp"
try
set theRecords to selection of viewer window 1 as list
if theRecords = {} then error "Select some records"
set writeToFile to my write_To_File(("" & linefeed) as string, theFilePath, true)
show progress indicator "Writing Metadata Identifiers... " steps (count theRecords) as string with cancel button
repeat with thisRecord in theRecords
step progress indicator (name of thisRecord) as string
set thisMetadata to custom meta data of thisRecord
try
set theRecordPropertyNames to my getPropertyNames(thisMetadata)
repeat with thisName in theRecordPropertyNames
set writeToFile to my write_To_File((thisName & linefeed) as string, theFilePath, true)
end repeat
end try
end repeat
hide progress indicator
on error error_message number error_number
hide progress indicator
if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
return
end try
end tell
on getPropertyNames(theMetadata)
set theRecordPropertyNames to get user property names theMetadata
end getPropertyNames
on write_To_File(this_data, target_file, append_data)
try
set the target_file to the target_file as text
set the open_target_file to ¬
open for access POSIX file target_file with write permission
if append_data is false then ¬
set eof of the open_target_file to 0
write this_data as «class utf8» to the open_target_file starting at eof
close access the open_target_file
return true
on error
try
close access POSIX file target_file
end try
return false
end try
end write_To_File
Identifiers are not deduplicated as this can be done in a text editor, e.g. BBEdit Text > Process Duplicate Lines.
Finally the main script that deletes given Custom Meta Data from selected records.
There’s a dialog that should prevent accidents, its default button is set to Cancel. Change this or uncomment the whole dialog if you like.
-- Delete Custom Meta Data
use scripting additions
property deleteMetadataNames : {"mdtest1", "mdtest2"} -- set your Meta Data Identifiers here
tell application id "DNtp"
try
set theRecords to selection of viewer window 1 as list
if theRecords = {} then error "Select some records"
set theButtons to {"Cancel", "Delete"}
set theButton to button returned of (display alert "Delete this Metadata from selected records?" buttons {item 1, item 2} of theButtons default button 1 message my tid(deleteMetadataNames, linefeed) as critical)
if theButton = item 1 of theButtons then return
show progress indicator "Deleting given Metadata... " steps (count theRecords) as string with cancel button
repeat with thisRecord in theRecords
step progress indicator (name of thisRecord) as string
set thisMetadata to custom meta data of thisRecord
try
set newMetadata to thisMetadata
set thePropertyNames to my getPropertyNames(thisMetadata)
repeat with thisPropertyName in thePropertyNames
if (thisPropertyName as string) is in deleteMetadataNames then set newMetadata to my deleteUserProperty(thisPropertyName as string, newMetadata)
end repeat
if newMetadata ≠ thisMetadata then set custom meta data of thisRecord to newMetadata
end try
end repeat
hide progress indicator
on error error_message number error_number
hide progress indicator
if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
end try
end tell
on tid(theList, theDelimiter)
set d to AppleScript's text item delimiters
set AppleScript's text item delimiters to theDelimiter
set theList to theList as text
set AppleScript's text item delimiters to d
return theList
end tid
on getPropertyNames(theMetadata)
set thePropertyNames to get user property names theMetadata
end getPropertyNames
on deleteUserProperty(thePropertyName, theMetadata)
set theMetadata_new to delete user property thePropertyName in theMetadata
end deleteUserProperty
Would these scripts presumably still work with Big Sur? I don’t know code and was wondering if @pete31 (or someone) could perhaps walk me through these steps due to a hangup I’m experiencing. My workflow:
Installed “List and Record Tools” per developer’s instructions
Open a new AppleScript window. So as not to confuse the first script from the second, I named the first one Part-1 before I pasted-in Pete’s first script. Running it gives me this:
Encouraging! So let’s say I now choose/select “mdoclc” (third from bottom in my list) because I know for certain I have roughly 10 records in my entire database in which I assigned, manually, some alphanumeric (single-line) text in this custom metadata field. I then click OK. But now what? (I have been able to ascertain, by clicking OK, I get mdoclc and nothing more/less in my clipboard. Is that all the first script is supposed to do?)
The problem I’m having, is what I’m supposed to do next. i.e. I don’t understand what this means:
Identifiers are not deduplicated as this can be done in a text editor, e.g. BBEdit Text > Process Duplicate Lines.
Perhaps normal behavior; when I paste your second script into a new AppleScript window and click the little hammer icon, I get an error:
My goal is just to see all instances of my custom metadata field called OCLC before I vaporize it once and for all. I presume your second script is supposed to get me there, but I can’t determine what I’m doing wrong. Any guidance would be great. Thanks!
Script 1: Copy Identifier (Copy Custom Meta Data Identifiers from plist)
Script 2: Main script (Delete Custom Meta Data )
Script 3: Verify main script’s result (Write Custom Meta Data Identifiers to file)
The text in brackets is the name of each script as in it’s first line.
This is not the order in which I posted them here.
No idea, still on Mojave.
Yes, it only copies one meta data’s identifier on each run. Paste each meta data you want to delete in the main script’s property deleteMetadataNames.
This is referring to script 3, the one that verifies the main script’s result. It outputs a text file with all meta data identifiers that are used in the selected records.
“Not deduplicated” simply means you’ll get a full list of every selected record’s meta data identifiers - instead of a deduplicated list. I did a lot of testing before I used the scripts and for that it was better to get a full list.
If you want to see whether the meta data was successfully removed you have to deduplicate it somewhere, e.g. in BBEdit. That’s of course not necessary; you could check the full list manually and watch out whether one of the meta data you removed wasn’t removed. After all you could simply forget about script 3 - I wrote it for testing purposes, it’s not necessary at all.
However you could of course use it to get a full list before you use script 2 to see what meta data is currently used.
I can compile it in Script Editor. Please make the whole script visible in Script Editor, try to compile again and post a capture of the window.
Somehow I completely missed the obvious: property deleteMetadataNames : {"mdtest1", "mdtest2"} -- set your Meta Data Identifiers here
I should be good to go but want to ask again about the query question from my OP yesterday. Your comment was of course probing if I wished to permanently delete both the metadata itself and the custom labels (custom metadata) I made, in DT3. Indeed the answer remains yes to both, but I want to first examine all the files in my database in which I actually entered something in a those (single-line text custom metadata) fields I’m planning to delete for good. My intent is to then select-all and replicate those files to a temporary Group that I will name the same as the metadata field (and meta-data) I’m going to vaporize for good. Can this be accomplished first somehow?
Thanks again for being so helpful explaining this to me @pete31! …and for the script!
No problem over here. If you need help just ask. However I would suggest to keep the two threads separated to avoid confusing other users.
I think you’re complicating things a bit, in the end it’s quite simple:
Copy a meta data identifier you want to remove
In the main script: Paste in property deleteMetadataNames
Repeat until everything is set
Run the main script.
That’s it.
You could verify the main script’s result by running script 3 but that’s not necessary. You’re in the lucky position that I wrote, tested and ran the scripts on real data. They should work just fine for you too.