""" LDIF parsing module """ import base64 def parseLdif(input, field_separator=':', dn_name='dn', key_process=lambda s: s, value_process=str.lstrip, logger=lambda bad_line_number, bad_data: None): """ accepts iterable input with lines printed by ldapsearch returns dict of dicts with parsed data """ temp_dict = {} line_count = 0 line, key, value = '', '', '' comment, b64 = False, False do_work = True state = 0 lines = iter(input) while do_work: if state == 0: # read the line try: line_ = lines.next() line_count += 1 line = line_.rstrip() if line: state = 1 else: state = 5 except StopIteration: line = '' state = 6 elif state == 1: # evaluate the line char = line[0] if char == '#': state = 2 elif char == ' ': state = 3 elif key and value: state = 5 else: state = 4 elif state == 2: # it was the comment comment = True state = 0 elif state == 3: # line continuation if (not comment) and key: value += line[1:] state = 0 elif state == 4: # line seems to be legit - parse it if line: (key_, sep_, value_) = line.partition(field_separator) if sep_: # the line had something good b64 = len(value_) > 2 and value_[0] == ':' key = key_ value = value_[1:].strip() if b64 else value_ elif b64 and key: value += line else: b64 = False logger(line_count, line_) comment = False line = '' state = 0 elif state == 5 or state == 6: # add to temp_dict if key and value: if b64: value = base64.b64decode(value) key = key_process(key) value = value_process(value) if key not in temp_dict: temp_dict[key] = [] temp_dict[key].append(value) key, value = '', '' b64 = False if line: # return to line parsing state = 4 else: if state == 6: # caught exception - no more lines state = 8 else: state = 7 elif state == 7 or state == 8: # yield results if dn_name in temp_dict: yield temp_dict else: # no dn in temp_dict logger(line_count, temp_dict) temp_dict = {} do_work = state != 8 if do_work: state = 0