"""
dsml.py - Various routines for handling DSML data
(c) by Michael Stroeder <michael@stroeder.com>

This module is distributed under the terms of the
GPL (GNU GENERAL PUBLIC LICENSE) Version 2
(see http://www.gnu.org/copyleft/gpl.html)
"""

__version__ = '0.2.0'

import sys,string,StringIO,re,base64

dn_pattern   = r'([\w;.]+[\s]*=[^,]+)(,[ ]*[\w;.]+[\s]*=[^,]+)*'
dn_regex   = re.compile(dn_pattern)


def CreateDSML(
  outfile,		# File object for output
  dn,			# string-representation of distinguished name
  entry={},		# dictionary holding the LDAP entry {attr:data}
  binary_attrs=[],	# Attribute types to be base64-encoded
  indent=2,             # Number of spaces for indentiation
):
  """Write a single DSML formatted LDAP entry to outfile"""

  # Write line dn: first
  outfile.write('%s<dsml:entry dn="%s">\n' % (' '*indent*1,dn))

  objectclasses = entry.get('objectclass',entry.get('objectClass',[]))

  outfile.write('%s<dsml:objectclass>\n' % (' '*indent*2))
  for oc in objectclasses:
    outfile.write('%s<dsml:oc-value>%s</dsml:oc-value>\n' % (' '*indent*3,oc))
  outfile.write('%s</dsml:objectclass>\n' % (' '*indent*2))

  attrs = entry.keys()[:]
  try:
    attrs.remove('objectclass')
    attrs.remove('objectClass')
  except ValueError:
    pass
  attrs.sort()
  for attr in attrs:
    outfile.write('%s<dsml:attr name="%s">\n' % (' '*indent*2,attr))
    for data in entry[attr]:
      if attr in binary_attrs:
  	outfile.write('%s<dsml:value encoding="base64">\n%s</dsml:value>\n' % (
            ' '*indent*3,
            base64.encodestring(data)
          )
        )
      else:
  	outfile.write('%s<dsml:value>\n%s%s\n%s</dsml:value>\n' % (
            ' '*indent*3,
            ' '*indent*4,
            data,
            ' '*indent*3,
          )
        )
    outfile.write('%s</dsml:attr>\n' % (' '*indent*2))
  outfile.write('%s</dsml:entry>\n' % (' '*indent*1))
  return

