forked from nmcspadden/SalProfileGenerator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFoundationPlist.py
executable file
·137 lines (112 loc) · 4.88 KB
/
FoundationPlist.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/python
# encoding: utf-8
#
# Copyright 2009-2014 Greg Neagle.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""FoundationPlist.py -- a tool to generate and parse MacOSX .plist files.
This is intended as a drop-in replacement for Python's included plistlib,
with a few caveats:
- readPlist() and writePlist() operate only on a filepath,
not a file object.
- there is no support for the deprecated functions:
readPlistFromResource()
writePlistToResource()
- there is no support for the deprecated Plist class.
The Property List (.plist) file format is a simple XML pickle supporting
basic object types, like dictionaries, lists, numbers and strings.
Usually the top level object is a dictionary.
To write out a plist file, use the writePlist(rootObject, filepath)
function. 'rootObject' is the top level object, 'filepath' is a
filename.
To parse a plist from a file, use the readPlist(filepath) function,
with a file name. It returns the top level object (again, usually a
dictionary).
To work with plist data in strings, you can use readPlistFromString()
and writePlistToString().
"""
import os
from Foundation import NSData, \
NSPropertyListSerialization, \
NSPropertyListMutableContainersAndLeaves, \
NSPropertyListXMLFormat_v1_0
class FoundationPlistException(Exception):
'''Base error for this module'''
pass
class NSPropertyListSerializationException(FoundationPlistException):
'''Read error for this module'''
pass
class NSPropertyListWriteException(FoundationPlistException):
'''Write error for this module'''
pass
# private functions
def _dataToPlist(data):
'''low-level function that parses a data object into a propertyList object'''
darwin_vers = int(os.uname()[2].split('.')[0])
if darwin_vers > 10:
(plistObject, plistFormat, error) = (
NSPropertyListSerialization.propertyListWithData_options_format_error_(
data, NSPropertyListMutableContainersAndLeaves, None, None))
else:
# 10.5 doesn't support propertyListWithData:options:format:error:
# 10.6's PyObjC wrapper for propertyListWithData:options:format:error:
# is broken
# so use the older NSPropertyListSerialization function
(plistObject, plistFormat, error) = (
NSPropertyListSerialization.propertyListFromData_mutabilityOption_format_errorDescription_(
data, NSPropertyListMutableContainersAndLeaves, None, None))
if error:
raise NSPropertyListSerializationException(error)
else:
return plistObject
def _plistToData(plistObject):
'''low-level function that creates NSData from a plist object'''
darwin_vers = int(os.uname()[2].split('.')[0])
if darwin_vers > 10:
(data, error) = (
NSPropertyListSerialization.dataWithPropertyList_format_options_error_(
plistObject, NSPropertyListXMLFormat_v1_0, 0, None))
else:
# use the older NSPropertyListSerialization function on 10.6 and 10.5
(data, error) = (
NSPropertyListSerialization.dataFromPropertyList_format_errorDescription_(
plistObject, NSPropertyListXMLFormat_v1_0, None))
if error:
raise NSPropertyListSerializationException(error)
return data
# public functions
def readPlist(filepath):
'''Read a .plist file from filepath. Return the unpacked root object
(which is usually a dictionary).'''
try:
data = NSData.dataWithContentsOfFile_(filepath)
except NSPropertyListSerializationException, error:
# insert filepath info into error message
errmsg = (u'%s in %s' % (error, filepath))
raise NSPropertyListSerializationException(errmsg)
return _dataToPlist(data)
def readPlistFromString(aString):
'''Read a plist data from a string. Return the root object.'''
data = buffer(aString)
return _dataToPlist(data)
def writePlist(plistObject, filepath):
'''Write 'plistObject' as a plist to filepath.'''
plistData = _plistToData(plistObject)
if plistData.writeToFile_atomically_(filepath, True):
return
else:
raise NSPropertyListWriteException(
u"Failed to write plist data to %s" % filepath)
def writePlistToString(plistObject):
'''Create a plist-formatted string from plistObject.'''
return str(_plistToData(plistObject))