on datatoposix(x)
set f to (open for access POSIX file ("/tmp/me.lri.datatoposix.dat") with write permission)
repeat with d in x
set eof f to 0
write d to f
set d's contents to POSIX path of (read f from 1 as alias)
end repeat
close access f
x
end datatoposix
tell application "System Events"
tell property list file "~/Library/Preferences/com.apple.recentitems.plist"
set l to property list item "RecentDocuments"'s property list item "CustomListItems"'s property list items's property list item "Bookmark"'s value
end tell
end tell
datatoposix(l)
I’m always getting the error “Can’t get POSIX path ofCan’t get some object.” though. Any fixes or other (shorter) ways to extract the paths?
It seems the data have changed since I wrote those scripts ” at least for Apple-menu Recent Items. A data object data no longer represent an alias but some kind of bookmark object. Analysing this very crudely on a Snow Leopard system reveals that, starting at byte 21, there are data for the names in a POSIX path (without the slashes). The data for each name are:
A byte whose value is the number of bytes representing the name in UTF-8 Unicode text.
Seven more bytes with the values 0, 0, 0, 1, 1, 0, and 0 respectively.
The item’s name as UTF-8 Unicode text.
Padding with zero-value bytes, if necessary, to bring the number of bytes up to a multiple of 4.
The following hack should therefore (hopefully) solve the immediate problem:
on datatoposix(x)
set f to (open for access POSIX file ("/tmp/me.lri.datatoposix.dat") with write permission)
try
repeat with d in x
set eof f to 0
-- Write the data object to the file.
write d's contents to f
-- Reset the file mark to byte 21.
read f from 21 for 0
set POSIXpath to ""
repeat
-- Read the next 8 bytes as a double integer (interpreted as little-endian on Intel machines).
set doubleInt to (read f for 8 as double integer)
-- Finish when the top seven bytes aren't the value for "path item".
if (doubleInt div 256 is not 4.311744512E+9) then exit repeat
-- Get the byte length of the item's name from the lowest-order byte.
set len to doubleInt mod 256 div 1
-- Read that number of bytes as UTF-8 and append the result to the POSIX path.
set POSIXpath to POSIXpath & ("/" & (read f for len as «class utf8»))
-- Advance the file mark past any padding.
read f for (4 - len mod 4) mod 4
end repeat
set d's contents to POSIXpath
end repeat
on error msg
display dialog msg
end try
close access f
x
end datatoposix
tell application "System Events"
tell property list file "~/Library/Preferences/com.apple.recentitems.plist"
set l to property list item "RecentDocuments"'s property list item "CustomListItems"'s property list items's property list item "Bookmark"'s value
end tell
end tell
datatoposix(l)
I couldn’t get that to work either on 10.7.2. It just returns a list of empty strings.
I came up with this though:
[code]#!/bin/sh
plist=$HOME/Library/Preferences/com.apple.recentitems.plist
o0=$(echo $‘\0’); o1=$(echo $‘\1’)
for i in {0…10}; do
/usr/libexec/PlistBuddy -c “Print :RecentDocuments:CustomListItems:$i:Bookmark”
$plist | tr -d ‘\2-\37’ | sed -E “s|$o0$o0$o0$o0$o1$o1$o0$o0|/|g;s|[^/]||"
| tr -d ‘\0’ | sed "s|$o1.||”
done[/code]
Beginning of sed -n ‘l’ for a single entry:
Well that’s exactly the structure the script’s designed to handle, so presumably 'read’s ‘double integer’ interpretation, which is wrong in Snow Leopard, has been either fixed or just changed in Lion. Here’s a variation which reads the eight-byte groups as strings instead and uses the IDs of the characters. Any good on your system?
on datatoposix(x)
set f to (open for access POSIX file ("/tmp/me.lri.datatoposix.dat") with write permission)
try
repeat with d in x
set eof f to 0
-- Write the data object to the file.
write d's contents to f
-- Reset the file mark to byte 21.
read f from 21 for 0
set POSIXpath to ""
repeat
-- Read the next 8 bytes as a string and get the characters' IDs.
set idList to id of (read f for 8 as string)
-- Finish when IDs 2 to 8 aren't the values for "path item".
if (idList does not end with {0, 0, 0, 1, 1, 0, 0}) then exit repeat
-- Get the byte length of the item's name from the first ID.
set len to beginning of idList
-- Read that number of bytes as UTF-8 and append the result to the POSIX path.
set POSIXpath to POSIXpath & ("/" & (read f for len as «class utf8»))
-- Advance the file mark past any padding.
read f for (4 - len mod 4) mod 4
end repeat
set d's contents to POSIXpath
end repeat
on error msg
display dialog msg
end try
close access f
x
end datatoposix
tell application "System Events"
tell property list file "~/Library/Preferences/com.apple.recentitems.plist"
set l to property list item "RecentDocuments"'s property list item "CustomListItems"'s property list items's property list item "Bookmark"'s value
end tell
end tell
datatoposix(l)