I use Safari's Reading List to transfer pages from my phone to my computer. But I don't really want to read these in Safari on my desktop. I'd rather read them in Firefox, maybe through Pinboard, which has an API to write items and mark them as "to read". This blog post documents what I learned.
Update: [2014-06-07] Deleting items out of the reading list does not work properly. It's ok to read everything out of there but I haven't figured out how to properly modify it. So I guess I need to delete things manually after I read them out.
Update: [2014-09-18] With iOS 8, I'm switching from Reading List to something else, maybe Pinner, to make this process easier.
I searched the web for some resources, and learned that the reading list, as well as other Safari bookmarks, are stored in ~/Library/Safari/Bookmarks.plist
. I can use plutil
and PlistBuddy
to read and edit that file.
Here's the simplest way for me to get the data in json format (unfortunately plutil
can't directly convert it to json because it won't convert dates to strings):
plutil -convert xml1 ~/Library/Safari/Bookmarks.plist -o - \ | sed -e 's/date>/string>/g' -e 's/data>/string>/g' \ | plutil -convert json -r - -o - >bookmarks.json
Ideally I'd also be able to delete the reading list from Safari when I transfer it elsewhere. To do that, I need to figure out which element(s) to delete.
Looking at the structure of the bookmarks file, Children
is an array of bookmarks, and one of those is the Reading List folder. How do I find the index into the array? If it's a bookmark it will contain URIDictionary
; if it's a folder it will contain Title
. The Title
of the folder will be com.apple.ReadingList
. I needed to figure out how to specify an array element. With PlistBuddy
, the man page tells you what the commands are but not how to access elements. I eventually figured out that I can use Children:3
to access element 3 of the Children
array. Here's a loop to go through the titles (assuming at most 10 bookmarks; you may need to increase this):
bookmarks_file="$HOME/Library/Safari/Bookmarks.plist" i=0 while [ $i -lt 10 ]; do title=$(/usr/libexec/PlistBuddy -c "print Children:$i:Title" $bookmarks_file 2>/dev/null) echo $i $title i=$[$i+1] done
The next step was to delete the folder that contains the Reading List. For some reason I can't remember, I used plutil -remove
instead of PlistBuddy -c delete
to delete the entry. But plutil
wants it written Children.3
instead of Children:3
. Why? I don't know. The same loop as above, except when I find com.apple.ReadingList
I delete it:
bookmarks_file="$HOME/Library/Safari/Bookmarks.plist" i=0 while [ $i -lt 10 ]; do title=$(/usr/libexec/PlistBuddy -c "print Children:$i:Title" $bookmarks_file 2>/dev/null) if [ "$title" = "com.apple.ReadingList" ]; then plutil -remove "Children.$i" $bookmarks_file break fi i=$[$i+1] done
So now I can take the Reading List out of Safari and into JSON format. What to do from there? Pinboard is an obvious choice. I instead write the items out in a text file which I check periodically from Emacs.
How well does an "add" to the list work?
Hi shokk, I haven't tried that. I've put this whole project on hold because it's not been as easy as I had hoped. It's too bad. There could be a nice ecosystem of tools if the reading list were programmable.
The folks on the MACENTERPRISE@LISTS.PSU.EDU list might know more.
Post a Comment