1 import base64
2
3 from twisted.protocols import basic
4 from twisted.internet import protocol
5
6 from ldaptor import entry
7
9 """Error parsing LDIF."""
10
12 s = self.__doc__
13 if self[:]:
14 s = ': '.join([s]+map(str, self[:]))
15 return s+'.'
16
18 """LDIF line without semicolon seen"""
19 pass
20
22 """LDIF entry starts with a non-DN line"""
23 pass
24
26 """Invalid LDIF value format"""
27 pass
28
30 """Non-numeric LDIF version number"""
31 pass
32
34 """LDIF version not supported"""
35 pass
36
38 """LDIF appears to be truncated"""
39 pass
40
41 HEADER = 'HEADER'
42 WAIT_FOR_DN = 'WAIT_FOR_DN'
43 IN_ENTRY = 'IN_ENTRY'
44
45 -class LDIF(object, basic.LineReceiver):
46 delimiter='\n'
47 mode = HEADER
48
49 dn = None
50 data = None
51 lastLine = None
52
53 version = None
54
56 if line.startswith('#'):
57
58 return
59 getattr(self, 'state_' + self.mode)(line)
60
73
75 if val.startswith(':'):
76 return base64.decodestring(val[1:].lstrip(' '))
77 elif val.startswith('<'):
78 raise NotImplementedError
79 else:
80 return val.lstrip(' ')
81
91
106
108 assert self.dn is None, 'self.dn must not be set when waiting for DN'
109 assert self.data is None, 'self.data must not be set when waiting for DN'
110 if line == '':
111
112 return
113
114 key, val = self._parseLine(line)
115
116 if key.upper() != 'DN':
117 raise LDIFEntryStartsWithNonDNError, line
118
119 self.dn = val
120 self.data = {}
121 self.mode = IN_ENTRY
122
123 - def state_IN_ENTRY(self, line):
124 assert self.dn is not None, 'self.dn must be set when in entry'
125 assert self.data is not None, 'self.data must be set when in entry'
126
127 if line == '':
128
129 self.mode = WAIT_FOR_DN
130 o = entry.BaseLDAPEntry(dn=self.dn,
131 attributes=self.data)
132 self.dn = None
133 self.data = None
134 self.gotEntry(o)
135 return
136
137 key, val = self._parseLine(line)
138
139 if not key in self.data:
140 self.data[key] = []
141
142 self.data[key].append(val)
143
144 - def gotEntry(self, obj):
146
150