3
NZOA                 @   sv  d Z dZdddddddd	gZd
dlmZmZmZ ddlZddlZddl	Z	yddl
mZ W n  ek
rx   ddl
mZ Y nX d
dlT dZdZed e Zed e d Zejde Zde  Zdd
ddZddddZddddgZi ZxeD ]Zdee< qW dZejeZd d! Zd"d# Zd$d% ZG d&d dZ d-d(dZ!G d)d dZ"G d*d de"Z#G d+d	 d	e"Z$d.d,dZ%dS )/a  
ldif - generate and parse LDIF data (see RFC 2849)
written by Michael Stroeder <michael@stroeder.com>

See http://python-ldap.sourceforge.net for details.

$Id: ldif.py,v 1.3 2008/02/11 16:35:43 dwelch Exp $

Python compability note:
Tested with Python 2.0+, but should work with Python 1.5.2+.

The python-ldap package is distributed under Python-style license.

Standard disclaimer:
   This software is made available by the author(s) to the public for free
   and "as is".  All users of this free software are solely and entirely
   responsible for their own choice and use of this software for their
   own purposes.  By using this software, each user agrees that the
   author(s) shall not be liable for damages of any kind in relation to
   its use or performance. The author(s) do not warrant that this software
   is fit for any purpose.

Note: This file is part of the python-ldap package. For the complete
  python-ldap package, please visit: http://sourceforge.net/projects/python-ldap/
  
  It has been modified for use in HPLIP.

z0.5.5ldif_patternZAttrTypeandValueLDIF
CreateLDIF	ParseLDIF
LDIFWriter
LDIFParserLDIFRecordListLDIFCopy   )urllib2_requesturllib2_parseurllib2_error    N)StringIO)*z[\w;.]+(;[\w_-]+)*z(([^,]|\\,)+|".*?")z	[ ]*=[ ]*z
([ ]*,[ ]*z)*[ ]*z^%s$z>^((dn(:|::) %(dn_pattern)s)|(%(attrtype_pattern)s(:|::) .*)$)+   )adddeletereplacer   r   r   )r   r   r   modifyZmodrdnu"   (^( |
|| |:|<)|[ 
-ÿ]+|[ ]+$)c             C   s,   | dkrdS t j| }|dko*|jd| kS )z%
    returns 1 if s is a LDAP DN
     r   Nr   )dn_regexmatchgroup)sZrm r   /usr/share/hplip/base/ldif.pyis_dnQ   s    
r   c             C   s   t j| dk	S )zK
    returns 1 if s has to be base-64 encoded because of special chars
    N)safe_string_research)r   r   r   r   needs_base64[   s    r   c             C   s   t dd | D S )zR
    return a dictionary with all items of l being the keys of the dictionary
    c             S   s   g | ]}|d fqS )Nr   ).0ir   r   r   
<listcomp>f   s    zlist_dict.<locals>.<listcomp>)dict)lr   r   r   	list_dictb   s    r$   c               @   sB   e Zd ZdZdddZdd Zd	d
 Zdd Zdd Zdd Z	dS )r   z
    Write LDIF entry or change records to file object
    Copy LDIF input to a file output object containing all data retrieved
    via URLs
    NL   
c             C   s4   || _ tdd tpg D | _|| _|| _d| _dS )aI  
        output_file
            file object for output
        base64_attrs
            list of attribute types to be base64-encoded in any case
        cols
            Specifies how many columns a line may have before it's
            folded into many lines.
        line_sep
            String used as line separator
        c             S   s   g | ]}|j  qS r   )lower)r   ar   r   r   r!   }   s    z'LDIFWriter.__init__.<locals>.<listcomp>r   N)_output_filer$   Zbases64_attrs_base64_attrs_cols	_line_seprecords_written)selfoutput_filebase64_attrscolsline_sepr   r   r   __init__p   s
    zLDIFWriter.__init__c             C   s   t |}|| jkr.| jj| | jj| j n| j}| jj|dt|| j  | jj| j xX||k r| jjd | jj||t||| j d   | jj| j || j d }q`W dS )z?
        Write string line as one or more folded lines
        r    r   N)lenr+   r)   writer,   min)r.   lineZline_lenposr   r   r   _unfoldLDIFLine   s    

$zLDIFWriter._unfoldLDIFLinec             C   sR   |j  | jkst|r:| jdj|tj|jddg n| jdj||g dS )z
        Write a single attribute type/value pair

        attr_type
              attribute type
        attr_value
              attribute value
        z:: r&   r   z: N)r'   r*   r   r:   joinbase64Zencodestringr   )r.   	attr_type
attr_valuer   r   r   _unparseAttrTypeandValue   s
    	$z#LDIFWriter._unparseAttrTypeandValuec             C   sL   t |j dd }|j  x*|D ]"}x|| D ]}| j|| q0W q"W dS )z?
        entry
            dictionary holding an entry
        N)listkeyssortr?   )r.   entryZ
attr_typesr=   r>   r   r   r   _unparseEntryRecord   s
    
zLDIFWriter._unparseEntryRecordc       	      C   s   t |d }|dkrd}n|dkr(d}ntd| jd| x|D ]z}|dkrX|\}}n,|dkr||\}}}| jt| | ntd|rx|D ]}| j|| qW |dkrB| jjd	| j  qBW d
S )z\
        modlist
            list of additions (2-tuple) or modifications (3-tuple)
        r   r   r      r   zmodlist item of wrong length
changetypez'Subsequent modlist item of wrong length-N)r5   
ValueErrorr?   
MOD_OP_STRr)   r6   r,   )	r.   ZmodlistZmod_lenrF   modmod_typeZmod_valsZmod_opZmod_valr   r   r   _unparseChangeRecord   s&    



zLDIFWriter._unparseChangeRecordc             C   sf   |sdS | j d| t|tr*| j| nt|tr@| j| ntd| jj| j	 | j
d | _
dS )z
        dn
              string-representation of distinguished name
        record
              Either a dictionary holding the LDAP entry {attrtype:record}
              or a list with a modify list like for LDAPObject.modify().
        Ndnz*Argument record must be dictionary or listr   )r?   
isinstancer"   rD   r@   rL   rH   r)   r6   r,   r-   )r.   rM   recordr   r   r   unparse   s    

zLDIFWriter.unparse)Nr%   r&   )
__name__
__module____qualname____doc__r3   r:   r?   rD   rL   rP   r   r   r   r   r   i   s   
r%   c             C   s4   t  }t|||d}|j| | |j }|j  |S )a  
    Create LDIF single formatted record including trailing empty line.
    This is a compability function. Use is deprecated!

    dn
          string-representation of distinguished name
    record
          Either a dictionary holding the LDAP entry {attrtype:record}
          or a list with a modify list like for LDAPObject.modify().
    base64_attrs
          list of attribute types to be base64-encoded in any case
    cols
          Specifies how many columns a line may have before it's
          folded into many lines.
    r&   )r   r   rP   getvalueclose)rM   rO   r0   r1   fZldif_writerr   r   r   r   r      s    c               @   sB   e Zd ZdZdd ZdddZd	d
 Zdd Zdd Zdd Z	dS )r   z
    Base class for a LDIF parser. Applications should sub-class this
    class and override method handle() to implement something meaningful.

    Public class attributes:
    records_read
          Counter for records processed so far
    c             C   s   |j dj dS )zQ
        Strip trailing line separators from s, but no other whitespaces
        r&   )strip)r.   r   r   r   r   _stripLineSep  s    zLDIFParser._stripLineSepNr   r&   c             C   sL   || _ || _tdd |pg D | _tdd |p2g D | _|| _d| _dS )aK  
        Parameters:
        input_file
            File-object to read the LDIF input from
        ignored_attr_types
            Attributes with these attribute type names will be ignored.
        max_entries
            If non-zero specifies the maximum number of entries to be
            read from f.
        process_url_schemes
            List containing strings with URLs schemes to process with urllib.
            An empty list turns off all URL processing and the attribute
            is ignored completely.
        line_sep
            String used as line separator
        c             S   s   g | ]}|j  qS r   )r'   )r   r   r   r   r   r!   ,  s    z'LDIFParser.__init__.<locals>.<listcomp>c             S   s   g | ]}|j  qS r   )r'   )r   r(   r   r   r   r!   -  s    r   N)_input_file_max_entriesr$   _process_url_schemes_ignored_attr_typesr,   records_read)r.   
input_fileignored_attr_typesmax_entriesprocess_url_schemesr2   r   r   r   r3     s    zLDIFParser.__init__c             C   s   dS )z
        Process a single content LDIF record. This method should be
        implemented by applications using LDIFParser.
        Nr   )r.   rM   rC   r   r   r   handle1  s    zLDIFParser.handlec             C   sd   | j | jg}| jj | _x>| jrX| jd dkrX|j| j | jdd  | jj | _qW dj|S )zO
        Unfold several folded lines with trailing space into one line
        r   r4   r   Nr   )rZ   _liner[   readlineappendr;   )r.   Zunfolded_linesr   r   r   r:   7  s    zLDIFParser._unfoldLDIFLinec             C   s8  | j  }x|r$|d dkr$| j  }q
W | s<|dks<|dkr@dS y|jd}W n" tk
rp   tjd|  dS X |d| }|||d	  }|d
krtj||d	 d }n|dkr||d	 d j }d}| jr0t	j
|}|d | jkr0tj|j }n.|dks|dkrd}n||d	 d j }||fS )zj
        Parse a single attribute type and value pair from one or
        more lines of LDIF data
        r   #r&   z
N:zMalformed line: %sr   r   z::z:<z:
)NN)r   r   )r:   indexrH   logerrorr<   ZdecodestringrY   r]   r
   Zurlparser	   Zurlopenreadlstrip)r.   Zunfolded_lineZ	colon_posr=   Z
value_specr>   Zurlur   r   r   _parseAttrTypeandValueD  s2    

z!LDIFParser._parseAttrTypeandValuec             C   s  | j j | _x| jo(| j s,| j| jk rd}d}d}d}i }| j \}}x6|dk	o^|dk	r|j }tjdt	|t	|f  | s| r| j \}}qP|dkr|dk	rt
dt|st
dt	| |}n|dkr|dkrd}n|dkr8|dkrt
d	|dk	rt
d
|tkr2t
dt	| |}n>|dk	rv|j | jkrv||krl|| j| n
|g||< | j \}}qPW |r| j|| |  jd7  _qW dS )z9
        Continously read and parse LDIF records
        Nz
%s ---> %srM   z*Two lines starting with dn: in one record.z8No valid string-representation of distinguished name %s.versionr   rF   z/Read changetype: before getting valid dn: line.z2Two lines starting with changetype: in one record.zchangetype value %s is invalid.)r[   rf   re   r\   r_   rp   r'   rk   debugreprrH   r   valid_changetype_dictr^   rg   rd   )r.   rq   rM   rF   ZmodoprC   r=   r>   r   r   r   parseu  sR    







zLDIFParser.parse)Nr   Nr&   )
rQ   rR   rS   rT   rZ   r3   rd   r:   rp   ru   r   r   r   r   r     s    
1c               @   s"   e Zd ZdZdddZdd ZdS )	r   zt
    Collect all records of LDIF input into a single list.
    of 2-tuples (dn, entry). It can be a memory hog!
    Nr   c             C   s   t j| |||| g | _dS )z
        See LDIFParser.__init__()

        Additional Parameters:
        all_records
            List instance for storing parsed records
        N)r   r3   all_records)r.   r`   ra   rb   rc   r   r   r   r3     s    	zLDIFRecordList.__init__c             C   s   | j j||f dS )zD
        Append single record to dictionary of all records.
        N)rv   rg   )r.   rM   rC   r   r   r   rd     s    zLDIFRecordList.handle)Nr   N)rQ   rR   rS   rT   r3   rd   r   r   r   r   r     s    
c               @   s"   e Zd ZdZd
ddZdd	 ZdS )r   zS
    Copy LDIF input to LDIF output containing all data retrieved
    via URLs
    Nr   r%   r&   c	       	      C   s&   t j| |||| t||||| _dS )zE
        See LDIFParser.__init__() and LDIFWriter.__init__()
        N)r   r3   r   _output_ldif)	r.   r`   r/   ra   rb   rc   r0   r1   r2   r   r   r   r3     s    zLDIFCopy.__init__c             C   s   | j j|| dS )z:
        Write single LDIF record to output file.
        N)rw   rP   )r.   rM   rC   r   r   r   rd     s    zLDIFCopy.handle)Nr   NNr%   r&   )rQ   rR   rS   rT   r3   rd   r   r   r   r   r     s
     
c             C   s   t | ||dd}|j  |jS )zc
    Parse LDIF records read from file.
    This is a compability function. Use is deprecated!
    r   )ra   rb   rc   )r   ru   rv   )rW   Zignore_attrsZ
maxentriesZldif_parserr   r   r   r     s    
)Nr%   )Nr   )&rT   __version____all__Zsixext.movesr	   r
   r   r<   retypesior   ImportErrorgZattrtype_patternZattrvalue_patternZrdn_patternZ
dn_patterncompiler   varsr   ZMOD_OP_INTEGERrI   ZCHANGE_TYPESrt   cZSAFE_STRING_PATTERNr   r   r   r$   r   r   r   r   r   r   r   r   r   r   <module>   sR   



 
 =