Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

How can I add a kMDItemWhereFroms attribute to a file?

I inspected the attribute with a third-party application and now I want to write a URL string as metadata from Terminal.


I tried plutil, xxd and xattr but still couldn't figure out the right form to write the bplist.


Any ideas?

MacBook Air, OS X Mountain Lion (10.8.5)

Posted on Nov 3, 2013 1:05 PM

Reply
31 replies

Dec 5, 2013 6:13 PM in response to iamsudo

NSPropertyListSerialization is what I used to avoid the temporary file - System Events seems to just convert when reading and writing to a file. The readWhereFroms and writeWhereFroms handlers use a couple of methods from the class to get an AppleScript list from and write an AppleScript list to a property list file (XML or binary) - I used that approach so that a regular list can be used. Cocoa methods can't be used in a regular AppleScript, but can be used in a Cocoa-Applet in 10.6 Snow Leopard and later.

Dec 6, 2013 6:21 AM in response to iamsudo

call method was a command from AppleScript Studio (deprecated since Snow Leopard) to allow access to Cocoa methods that didn't have a wrapper written for them. AppleScriptObjC implements a handler syntax to call Cocoa methods directly - see the AppleScriptObjC Release Notes for more information. The AppleScript Language Guide has also been recently updated.

Dec 6, 2013 6:50 PM in response to iamsudo

Hello


Here're some handlers using rubycocoa you may try. However, I don't see any problem in using temp file in your original code and also rpenner_sciforums has already provided a working shell script where plutil handles any necessary escaping, namely for &, < and >.


Hence the following script is merely to demonstrate a way to use Cocoa's NSPropertyListSerialization's method in "plain" applescript by means of rubycocoa via do shell script.


Tested under 10.6.8.


Regards,

H



set f to (path to desktop)'s POSIX path & "test.txt"
set urls to {"http://www.google.com", "https://www.google.com"}

set_metadata_kMDItemWhereFroms(f, urls)
get_metadata_kMDItemWhereFroms(f)

on get_metadata_kMDItemWhereFroms(f)
    (*
        string f : POSIX path of target file or folder
        return list : f's extended attribute of key = com.apple.metadata:kMDItemWhereFroms
    *)
    considering numeric strings
        if (system info)'s system version < "10.9" then
            set ruby to "/usr/bin/ruby"
        else
            set ruby to "/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby"
        end if
    end considering
    do shell script ruby & " <<'EOF' - " & f's quoted form & "
require 'osx/cocoa'
include OSX
raise ArgumentError, \"Usage: #{File.basename($0)} file\" unless ARGV.length == 1
infile = ARGV[0]
x = %x[xattr -p com.apple.metadata:kMDItemWhereFroms \"#{infile}\"]
if x == ''
    puts ''; exit
end
xml = %x[printf '%s' \"#{x}\" | xxd -r -p | plutil -convert xml1 -o - -]
array = xml.to_ns.propertyList
puts array.to_a.join(\"\\n\")
EOF"
    result's paragraphs
end get_metadata_kMDItemWhereFroms

on set_metadata_kMDItemWhereFroms(f, urls)
    (*
        string f : POSIX path of target file or folder
        list urls : list of urls to be written in extended attribute of key = com.apple.metadata:kMDItemWhereFroms
    *)
    set args to ""
    repeat with u in urls
        set args to args & space & u's quoted form
    end repeat
    considering numeric strings
        if (system info)'s system version < "10.9" then
            set ruby to "/usr/bin/ruby"
        else
            set ruby to "/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby"
        end if
    end considering
    do shell script ruby & " <<'EOF' - " & f's quoted form & " " & args & "
require 'osx/cocoa'
include OSX
raise ArgumentError, \"Usage: #{File.basename($0)} file url [url ...]\" unless ARGV.length > 1
outfile, *array = ARGV
plistdata = NSPropertyListSerialization.objc_send(
    :dataWithPropertyList, array.to_ns,
    :format, NSPropertyListBinaryFormat_v1_0,
    :options, 0,
    :error, nil)
x = plistdata.to_s.gsub!(/(^<|>$)/m, '')
%x[xattr -wx com.apple.metadata:kMDItemWhereFroms \"#{x}\" \"#{outfile}\"]
EOF"
end set_metadata_kMDItemWhereFroms

How can I add a kMDItemWhereFroms attribute to a file?

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.