Thursday, April 24, 2014

#1 2011-10-17 06:37:26 am

Trash Man
Sanitation Department
Registered: 2005-10-20
Posts: 5336

Get POSIX paths from «data» in com.apple.recentitems.plist

I tried modifying the scripts posted by Nigel Garvey at these threads:

- Sort OSX Recent Items by Date..?
- Plist files and the NSRecentDocumentRecords entries

And came up with something like:

Applescript:

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?

Last edited by l-ri (2011-10-17 04:03:53 pm)


One mans trash is another mans treasure

Offline

 

#2 2011-10-17 01:23:42 pm

Nigel Garvey
Moderator
From: Warwickshire, England
Registered: 2002-11-19
Posts: 3454

Re: Get POSIX paths from «data» in com.apple.recentitems.plist

Hi, l-ri.

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:

Applescript:

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)


NG

Offline

 

#3 2011-10-17 03:59:59 pm

Trash Man
Sanitation Department
Registered: 2005-10-20
Posts: 5336

Re: Get POSIX paths from «data» in com.apple.recentitems.plist

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

Beginning of sed -n 'l' for a single entry:

Code:

book\350\002\000\000\000\000\001\020\020\000\000\000\034\
\002\000\000\005\000\000\000\001\001\000\000Users\000\000\
\000\005\000\000\000\001\001\000\000lauri\000\000\000\a\000\
\000\000\001\001\000\000Desktop\000\020\000\000\000\001\001\
\000\000datatoposix.scpt\020\000\000\000\001\006\000\000\
\004\000\000\000\024\000\000\000$\000\000\0004\000\000\000\
\b\000\000\000\004\003\000\0001\277\000\000\000\000\000\000\
\b\000\000\000\004\003\000\0003\001\005\000\000\000\000\000\
\b\000\000\000\004\003\000\000\321\001\005\000\000\000\000\


One mans trash is another mans treasure

Offline

 

#4 2011-10-17 04:42:49 pm

Nigel Garvey
Moderator
From: Warwickshire, England
Registered: 2002-11-19
Posts: 3454

Re: Get POSIX paths from «data» in com.apple.recentitems.plist

l-ri wrote:

Beginning of sed -n 'l' for a single entry:

Code:

book\350\002\000\000\000\000\001\020\020\000\000\000\034\
\002\000\000\005\000\000\000\001\001\000\000Users\000\000\
\000\005\000\000\000\001\001\000\000lauri\000\000\000\a\000\
\000\000\001\001\000\000Desktop\000\020\000\000\000\001\001\
\000\000datatoposix.scpt\020\000\000\000\001\006\000\000\
\004\000\000\000\024\000\000\000$\000\000\0004\000\000\000\
\b\000\000\000\004\003\000\0001\277\000\000\000\000\000\000\
\b\000\000\000\004\003\000\0003\001\005\000\000\000\000\000\
\b\000\000\000\004\003\000\000\321\001\005\000\000\000\000\

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?

Applescript:

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)


NG

Offline

 

#5 2011-10-17 05:18:50 pm

Trash Man
Sanitation Department
Registered: 2005-10-20
Posts: 5336

Re: Get POSIX paths from «data» in com.apple.recentitems.plist

Yeah, that version does work properly on Lion.


One mans trash is another mans treasure

Offline

 

Board footer

Powered by FluxBB

[ Generated in 0.061 seconds, 10 queries executed ]

RSS (new topics) RSS (active topics)