plistlib – Manipulate OS X property list files
| Purpose: | Read and write OS X property list files |
|---|---|
| Python Version: | 2.6 |
plistlib provides an interface for working with property list files
used under OS X. plist files are typically XML, sometimes compressed.
They are used by the operating system and applications to store
preferences or other configuration settings. The contents are usually
structured as a dictionary containing key value pairs of basic
built-in types (unicode strings, integers, dates, etc.). Values can
also be nested data structures such as other dictionaries or lists.
Binary data, or strings with control characters, can be encoded using
the data type.
Reading plist Files
OS X applications such as iCal use plist files to store meta-data
about objects they manage. For example, iCal stores the definitions
of all of your calendars as a series of plist files in the Library
directory.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AlarmFilter</key>
<true/>
<key>AlarmsDisabled</key>
<false/>
<key>AttachmentFilter</key>
<true/>
<key>AutoRefresh</key>
<true/>
<key>Checked</key>
<integer>1</integer>
<key>Color</key>
<string>#808000FF</string>
<key>Enabled</key>
<true/>
<key>Key</key>
<string>4221BCE5-1017-4EE4-B7FF-311A846C600D</string>
<key>NeedsForcedUpdate</key>
<false/>
<key>NeedsRefresh</key>
<true/>
<key>Order</key>
<integer>25</integer>
<key>RefreshDate</key>
<date>2009-11-29T16:31:53Z</date>
<key>RefreshInterval</key>
<integer>3600</integer>
<key>SubscriptionTitle</key>
<string>Athens, GA Weather - By Weather Underground</string>
<key>SubscriptionURL</key>
<string>http://ical.wunderground.com/auto/ical/GA/Athens.ics?units=both</string>
<key>TaskFilter</key>
<true/>
<key>Title</key>
<string>Athens, GA Weather - By Weather Underground</string>
<key>Type</key>
<string>Subscription</string>
</dict>
</plist>
This sample script finds the calendar defintions, reads
them, and prints the titles of any calendars being displayed by iCal
(having the property Checked set to a true value).
import plistlib
import os
import glob
calendar_root = os.path.expanduser('~/Library/Calendars')
calendar_directories = (
glob.glob(os.path.join(calendar_root, '*.caldav', '*.calendar')) +
glob.glob(os.path.join(calendar_root, '*.calendar'))
)
for dirname in calendar_directories:
info_filename = os.path.join(dirname, 'Info.plist')
if os.path.isfile(info_filename):
info = plistlib.readPlist(info_filename)
if info.get('Checked'):
print info['Title']
The type of the Checked property is defined by the plist file, so
our script does not need to convert the string to an integer.
$ python plistlib_checked_calendars.py
Doug Hellmann
Tasks
Vacation Schedule
EarthSeasons
US Holidays
Athens, GA Weather - By Weather Underground
Birthdays
Georgia Bulldogs Calendar (NCAA Football)
Home
Meetup: Django
Meetup: PythonWriting plist Files
If you want to use plist files to save your own settings, use
writePlist() to serialize the data and write it to the filesystem.
import plistlib
import datetime
import tempfile
d = { 'an_int':2,
'a_bool':False,
'the_float':5.9,
'simple_string':'This string has no special characters.',
'xml_string':'<element attr="value">This string includes XML markup </element>',
'nested_list':['a', 'b', 'c'],
'nested_dict':{ 'key':'value' },
'timestamp':datetime.datetime.now(),
}
output_file = tempfile.NamedTemporaryFile()
try:
plistlib.writePlist(d, output_file)
output_file.seek(0)
print output_file.read()
finally:
output_file.close()
The first argument is the data structure to write out, and the second
is an open file handle or the name of a file.
$ python plistlib_write_plist.py
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>a_bool</key>
<false/>
<key>an_int</key>
<integer>2</integer>
<key>nested_dict</key>
<dict>
<key>key</key>
<string>value</string>
</dict>
<key>nested_list</key>
<array>
<string>a</string>
<string>b</string>
<string>c</string>
</array>
<key>simple_string</key>
<string>This string has no special characters.</string>
<key>the_float</key>
<real>5.9000000000000004</real>
<key>timestamp</key>
<date>2009-11-29T12:09:35Z</date>
<key>xml_string</key>
<string><element attr="value">This string includes XML markup &nbsp;</element></string>
</dict>
</plist>Binary Property Data
Serializing binary data or strings that may include control characters
using a plist is not immune to the typical challenges for an XML
format. To work around the issues, plist files can store binary data
in base64 format if the object is wrapped with a Datainstance.
import plistlib
d = { 'binary_data':plistlib.Data('This data has an embedded null. \0'),
}
print plistlib.writePlistToString(d)
This example uses the ToString version of the write function to create
an in-memory string instead of writing to a file.
$ python plistlib_binary_write.py
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>binary_data</key>
<data>
VGhpcyBkYXRhIGhhcyBhbiBlbWJlZGRlZCBudWxsLiAA
</data>
</dict>
</plist>Binary data is automatically converted to a Data instance when
read.
import plistlib
import pprint
DATA = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>binary_data</key>
<data>
VGhpcyBkYXRhIGhhcyBhbiBlbWJlZGRlZCBudWxsLiAA
</data>
</dict>
</plist>
"""
d = plistlib.readPlistFromString(DATA)
print repr(d['binary_data'].data)
The data attribute of the object contains the decoded data.
$ python plistlib_binary_read.py
'This data has an embedded null. \x00'See also
- plistlib
- The standard library documentation for this module.
- plist manual page
- Documentation of the plist file format.
- Weather Underground
- Free weather information, including ICS and RSS feeds.
- Convert plist between XML and Binary formats
- Some plist files are stored in a binary format instead of XML
because the binary format is faster to parse using Apple’s
libraries. Python’s plistlib module does not handle the
binary format, so you may need to convert binary files to XML
using plutil before reading them.
The canonical version of this article
