This Python module provides a very simple interface to read the contents of your Safari Reading List. Here is a simple usage example:
from readinglistlib import ReadingListReader rlr = ReadingListReader() rl = rlr.read()
The output of
rlr.read() is a list of articles. Each article is a dictionary with the following keys:
date (creation date of bookmark),
added (sync date; may be undefined),
viewed (read date; undefined for unread articles),
If you provide a path as an argument to the
ReadingListReader constructor, an attempt will be made to load the Reading List from that file. By default, your Reading List is read from
read() method has a few optional arguments that can be used to control its output:
showcan be set to
'read'to return only unread or read items, respectively. Any other value (such as
None) will cause all items to be returned. Defaults to
sortfieldcan be set to any of the keys listed above. The default is
ascendingcontrols sort order of the returned list. The default is
True; set to
Falsefor descending sort.
dateformatcontrols the formatting of the
viewedfields. Defaults to
None, in which case datetime objects are returned instead of strings. Understands strftime format directives.
Your Reading List is read once by the
ReadingListReader constructor. Subsequent calls to the
read() method do not reload the Reading List, but can be called with different options to return different subsets of the same list.
These scripts are developed for Mac OS X 10.7 ("Lion"). It relies on libraries introduced with Python 2.7, which is not included with "Snow Leopard" or earlier versions of Mac OS X.
Two Python scripts based on
readinglistlib are provided as examples.
readinglistreader.py dumps your Reading List in tabular or "bookmarks" format.
readinglist2instapaper.py adds your unread Reading List items to your Instapaper queue.
readinglist2html.py dumps your Reading List to a simple HTML list. Details below.
An AppleScript bundle called Send Reading List to Instapaper is also available. It provides a somewhat more user-friendly interface to
Safari Reading List "lets you save web pages to read or browse later." This script reads your Reading List and lists the articles bookmarked therein. It is offered as a proof of concept rather than a finished tool. Safari's bookmarks file format is undocumented so reading it directly is totally unsupported and quite likely to fail in a variety of cases. That said, this script does not edit or modify your Safari bookmarks file in any way. No changes are made to the status of your Reading List.
This script is derived from Safari-Reading-List-Recipe. It's intended to facilitate experimental integration of Reading List with services like Instapaper or Pinboard. For example, you can import the output of
readinglistreader.py --bookmarks to add your unread articles to Pinboard.
usage: readinglistreader.py [-h] [--separator SEP] [--quote QUOTE] [--forcequotes] [--fields FIELD [FIELD ...]] [--header] [--timestamp FORMAT] [--bookmarks] [--show FILTER] [--sortfield FIELD] [--sortorder ORDER] [--output OUTPUT] [--input INPUT] This script outputs the contents of your Safari Reading List, a queue of temporary bookmarks representing articles you intend to read. By default, it prints the title and url of unread articles in chronological order, beginning with the oldest bookmark. Default output is compliant with CSV conventions. optional arguments: -h, --help show this help message and exit --separator SEP Separates field values. Specify 'tab' to use an actual tab character. Defaults to ','. --quote QUOTE Specify '' to suppress quoting. Defaults to '"'. --forcequotes Quote all field values. By default, only quote empty fields or values containing SEP, QUOTE, or newlines. --fields FIELD [FIELD ...] Controls format of output record. Acceptable fields are title, url, preview, date, added, viewed, uuid, synckey, and syncserverid. Defaults to title and url. (Date is date article was originally bookmarked. If defined, added is date bookmark was synced via iCloud. If defined, viewed is date article was read.) --header Output a header record containing field labels. --timestamp FORMAT Controls format of date, added, and viewed fields. Understands strftime directives. Defaults to '%a %b %d %H:%M:%S %Y' (eg, 'Mon Feb 13 22:50:40 2012'). --bookmarks Output items in Netscape bookmarks file format. Overrides preceding tabular output options. --show FILTER Control which items to output. Acceptable FILTER values are unread, read, or all. Defaults to unread. --sortfield FIELD Controls how output is sorted. Defaults to date. --sortorder ORDER May be ascending or descending. Defaults to ascending. --output OUTPUT Output file path. Defaults to stdout. --input INPUT Input file path. Assumed to be a Safari bookmarks file formatted as a binary property list. Defaults to ~/Library/Safari/Bookmarks.plist
Make it executable with
chown +x readinglistreader.py and put it in your
/usr/local/bin if you want. Make sure you have installed
readinglistlib somewhere in your sys.path.
With no options, a list of your unread bookmarks is displayed in
--fields option to specify the "schema" of your output table:
readinglistreader.py --fields title preview date url
By default, output is sorted by
date, starting with the oldest bookmark. To sort alphabetically by article
readinglistreader.py --sortfield title
As an alternative to outputting a table, you can save a bookmarks file:
readinglistreader.py --bookmarks --output bookmarks.html
--bookmarks mode ignores tabular output options such as
--fields. However, your
--sortorder settings are reflected in the bookmarks output.
This script uses
readinglistreader.py and Daniel Schauenberg's InstapaperLibrary to add your unread Reading List articles to your Instapaper account. Specify your Instapaper account with the
--password arguments, or create a file named
~/.instapaperrc containing a line with your credentials formatted as
username:password. Articles are not removed from your Reading List as they are added to Instapaper. This script is provided as example.
(InstapaperLibrary is not included with this script; install it via any of the methods advised at its GitHub page, or simply put the
instapaperlib package folder in the same folder as
This is a very simply script that posts your Reading List items to your Pinboard account as bookmarks marked 'to read'. Insert your Pinboard API token in the script before running.
This script outputs HTML for a very plain web page which displays your Reading List. Add some styles and some HTTP headers and maybe you could run it on your Mac's web server.
Uses Pocket Oauth2 library to gain access token to Pocket. Afterwards, loops through unread reading list entries and bulk adds them to Pocket library.
To begin, please find copy the
consumer_key in the Pocket developer portal: https://getpocket.com/developer/apps.
redirect_uri usage. See Wishlist.
- Allow deletion and/or mark-as-read of Reading List items. Naïvely overwriting
~/Library/Safari/Bookmarks.plistwith a modified plist accomplishes this, albeit without propagating changes to synced browsers/devices. Alternatively, use GUI scripting to remove items auto-manually (more compatible, but likely more visually distracting).
- Currently the solution implemented for readinglist2pocket.py is hacky. The
redirect_urifield is not used, because there is no URI to return to. This could lead to potential phishing vulnerabilities. In an ideal solution, we would have a separate server/socket set up to serve as the
redirect_uriand validate the OAuth request.
ReadingListReader is freely distributed under an open source MIT License:
Copyright (c) 2012 Jim DeVona
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.