o
    R
`ê»  ã                   @   s  d Z eZg d¢ZddlZddlmZ ddlZddlZddl	Z	ddl
Z
ddlZddlZzddlmZ W n eyA   ddlmZ Y nw zddlm  mZ W n ey_   ddlm  mZ Y nw ddlmZmZ ddlmZmZ ddlmZ d	Zd
Z dd„ Z!dd„ Z"dd„ Z#G dd„ de$ƒZ%G dd„ de%ƒZ&G dd„ de%ƒZ'G dd„ de(ƒZ)G dd„ dƒZ*G dd„ de)ƒZ+G dd„ de+ƒZ,G dd „ d e)ƒZ-G d!d"„ d"e)e*ƒZ.G d#d$„ d$e*ƒZ/G d%d&„ d&e+e*ƒZ0G d'd(„ d(e)ƒZ1G d)d*„ d*e)ƒZ2G d+d,„ d,e+ƒZ3G d-d.„ d.e)ƒZ4G d/d0„ d0e)ƒZ5dS )1aû  Navigate the resources exposed by a web service.

The wadllib library helps a web client navigate the resources
exposed by a web service. The service defines its resources in a
single WADL file. wadllib parses this file and gives access to the
resources defined inside. The client code can see the capabilities of
a given resource and make the corresponding HTTP requests.

If a request returns a representation of the resource, the client can
bind the string representation to the wadllib Resource object.
)
ÚApplicationÚLinkÚMethodÚNoBoundRepresentationErrorÚ	ParameterÚRepresentationDefinitionÚResponseDefinitionÚResourceÚResourceTypeÚ	WADLErroré    N)Úquote)Ú	urlencode)ÚURIÚmerge)Ú_make_unicodeÚ_string_types)Úiso_strptimez	xmlns:mapz http://www.w3.org/2001/XMLSchemac                 C   s   d|  S )z)Scope a tag name with the WADL namespace.z&{http://research.sun.com/wadl/2006/10}© ©Útag_namer   r   ú5/usr/lib/python3/dist-packages/wadllib/application.pyÚwadl_tagH   s   r   c                 C   s   dt | ƒ S )z#Turn a tag name into an XPath path.z./)r   r   r   r   r   Ú
wadl_xpathM   s   r   c                  G   s$   i }| D ]}|dur|  |¡ q|S )z<Merge any number of dictionaries, some of which may be None.N)Úupdate)ÚdictsÚfinalÚdictr   r   r   Ú_merge_dictsR   s   
€r   c                   @   ó   e Zd ZdZdS )r
   zAAn exception having to do with the state of the WADL application.N©Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r
   [   s    r
   c                   @   r   )r   aA  An unbound resource was used where wadllib expected a bound resource.

    To obtain the value of a resource's parameter, you first must bind
    the resource to a representation. Otherwise the resource has no
    idea what the value is and doesn't even know if you've given it a
    parameter name that makes sense.
    Nr   r   r   r   r   r   `   ó    r   c                   @   r   )ÚUnsupportedMediaTypeErrorz‘A media type was given that's not supported in this context.

    A resource can only be bound to media types it has representations
    of.
    Nr   r   r   r   r   r%   j   r$   r%   c                   @   r   )ÚWADLBasez?A base class for objects that contain WADL-derived information.Nr   r   r   r   r   r&   r   r$   r&   c                   @   s&   e Zd ZdZddd„Z	d	dd„ZdS )
ÚHasParametersMixinzAA mixin class for objects that have associated Parameter objects.Nc                    s\   ˆ du r| j ‰ ˆ du rtdƒ‚| jdu rg S | j tdƒ¡}|du r$g S ‡ ‡fdd„|D ƒS )z6Find subsidiary parameters that have the given styles.Nz&Could not find any particular resourceÚparamc                    s&   g | ]}|j  d ¡ˆv rtˆ |ƒ‘qS )Ústyle)ÚattribÚgetr   )Ú.0Ú	param_tag©ÚresourceÚstylesr   r   Ú
<listcomp>„   s
    þz-HasParametersMixin.params.<locals>.<listcomp>)r/   Ú
ValueErrorÚtagÚfindallr   )Úselfr0   r/   Ú
param_tagsr   r.   r   Úparamsy   s   
ÿzHasParametersMixin.paramsTc           	      K   s
  t ||ƒ}i }|D ]h}|j}|jdur/||v r*|| |jkr*td|| ||jf ƒ‚|j||< dd„ |jD ƒ}t|ƒdkrU||v rU|| |vrUtd|| |d |¡f ƒ‚|rd|jrd||vrdtd| ƒ‚||v rq|| ||< ||= q	t|ƒdkrƒtd	d
 | ¡ ¡ ƒ‚|S )a¼  Make sure the given valueset is valid.

        A valueset might be invalid because it contradicts a fixed
        value or (if enforce_completeness is True) because it lacks a
        required value.

        :param params: A list of Parameter objects.
        :param param_values: A dictionary of parameter values. May include
           paramters whose names are not valid Python identifiers.
        :param enforce_completeness: If True, this method will raise
           an exception when the given value set lacks a value for a
           required parameter.
        :param kw_param_values: A dictionary of parameter values.
        :return: A dictionary of validated parameter values.
        Nz=Value '%s' for parameter '%s' conflicts with fixed value '%s'c                 S   ó   g | ]}|j ‘qS r   )Úvalue)r,   Úoptionr   r   r   r1   ¥   ó    z<HasParametersMixin.validate_param_values.<locals>.<listcomp>r   z=Invalid value '%s' for parameter '%s': valid values are: "%s"z", "z$No value for required parameter '%s'zUnrecognized parameter(s): '%s'z', ')	r   ÚnameÚfixed_valuer2   ÚoptionsÚlenÚjoinÚis_requiredÚkeys)	r5   r7   Úparam_valuesÚenforce_completenessÚkw_param_valuesÚvalidated_valuesr(   r<   r>   r   r   r   Úvalidate_param_valuesˆ   sD   

ÿþ
ÿÿ
ÿ€ÿz(HasParametersMixin.validate_param_values©N)T)r    r!   r"   r#   r7   rG   r   r   r   r   r'   v   s
    
ÿr'   c                   @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )ÚWADLResolvableDefinitionz=A base class for objects whose definitions may be references.c                 C   s   d| _ || _dS )z§Initialize with a WADL application.

        :param application: A WADLDefinition. Relative links are
            assumed to be relative to this object's URL.
        N)Ú_definitionÚapplication)r5   rK   r   r   r   Ú__init__»   ó   
z!WADLResolvableDefinition.__init__c                 C   s^   | j dur| j S |  ¡ }|du r| | _ | S | j |¡}|  |¡}|du r*td| ƒ‚|| _ |S )aÞ  Return the definition of this object, wherever it is.

        Resource is a good example. A WADL <resource> tag
        may contain a large number of nested tags describing a
        resource, or it may just contain a 'type' attribute that
        references a <resource_type> which contains those same
        tags. Resource.resolve_definition() will return the original
        Resource object in the first case, and a
        ResourceType object in the second case.
        NúNo such XML ID: "%s")rJ   Ú_get_definition_urlrK   Úlookup_xml_idÚ_definition_factoryÚKeyError)r5   Ú
object_urlÚxml_idÚ
definitionr   r   r   Úresolve_definitionÄ   s   

z+WADLResolvableDefinition.resolve_definitionc                 C   ó   t ƒ ‚)zxTransform an XML ID into a wadllib wrapper object.

        Which kind of object it is depends on the subclass.
        ©ÚNotImplementedError©r5   Úidr   r   r   rQ   æ   ó   z,WADLResolvableDefinition._definition_factoryc                 C   rW   )zmFind the URL that identifies an external reference.

        How to do this depends on the subclass.
        rX   ©r5   r   r   r   rO   í   r\   z,WADLResolvableDefinition._get_definition_urlN)r    r!   r"   r#   rL   rV   rQ   rO   r   r   r   r   rI   ¸   s    	"rI   c                       sÎ   e Zd ZdZ			d'‡ fdd„	Zedd„ ƒZedd	„ ƒZed
d„ ƒZ			d(dd„Z	dd„ Z
		d)dd„Zd*dd„Zd*dd„Zedd„ ƒZd*dd„Zdd„ Zdd„ Zdd „ Zd!d"„ Zd*d#d$„Zd%d&„ Z‡  ZS )+r   z/A resource, possibly bound to a representation.NTc                    s®   t t| ƒ |¡ || _t|tƒr| j |¡j| _n|| _d| _	|dur<|dkr6|r2t
 t|ƒ¡| _	n
|| _	ntd| ƒ‚|| _|durU|durL|| _dS |  | j¡| _dS dS )a[  
        :param application: A WADLApplication.
        :param url: The URL to this resource.
        :param resource_type: An ElementTree <resource> or <resource_type> tag.
        :param representation: A string representation.
        :param media_type: The media type of the representation.
        :param representation_needs_processing: Set to False if the
            'representation' parameter should be used as
            is. Otherwise, it will be transformed from a string into
            an appropriate Python data structure, depending on its
            media type.
        :param representation_definition: A RepresentationDefinition
            object describing the structure of this
            representation. Used in cases when the representation
            isn't the result of sending a standard GET to the
            resource.
        Núapplication/jsonz?This resource doesn't define a representation for media type %s)Úsuperr   rL   Ú_urlÚ
isinstancer   rK   Úget_resource_typer3   ÚrepresentationÚjsonÚloadsr   r%   Ú
media_typeÚrepresentation_definitionÚget_representation_definition)r5   rK   ÚurlÚresource_typerc   rf   Úrepresentation_needs_processingrg   ©Ú	__class__r   r   rL   ø   s2   
ÿÿÿ

ÿüzResource.__init__c                 C   s   | j S )z Return the URL to this resource.)r`   r]   r   r   r   ri   ,  s   zResource.urlc                 C   sb   | j du rdS | j j d¡}|dur|S | j j d¡}|dur/t| jjƒ ¡ }t|ƒd | S dS )z@Return the URL to the type definition for this resource, if any.NÚtyper[   ú#)r3   r*   r+   r   rK   Ú
markup_urlÚensureSlashÚstr)r5   ri   Útype_idÚbaser   r   r   Útype_url1  s   
zResource.type_urlc                 C   s   | j jd S )zReturn the ID of this resource.r[   )r3   r*   r]   r   r   r   r[   C  ó   zResource.idr^   c                 C   s   t | j| j| j||||ƒS )a—  Bind the resource to a representation of that resource.

        :param representation: A string representation
        :param media_type: The media type of the representation.
        :param representation_needs_processing: Set to False if the
            'representation' parameter should be used as
            is.
        :param representation_definition: A RepresentationDefinition
            object describing the structure of this
            representation. Used in cases when the representation
            isn't the result of sending a standard GET to the
            resource.
        :return: A Resource bound to a particular representation.
        )r   rK   ri   r3   )r5   rc   rf   rk   rg   r   r   r   ÚbindH  s
   ýzResource.bindc                 C   sD   |   d¡j}|D ]}| ¡ j}|j d¡|kr|  S qtd| ƒ‚)z<Get a description of one of this resource's representations.ÚGETÚ	mediaTypez4No definition for representation with media type %s.)Ú
get_methodÚresponserV   r3   r*   r+   r%   )r5   rf   Údefault_get_responserc   Úrepresentation_tagr   r   r   rh   ^  s   
ÿÿz&Resource.get_representation_definitionc                 C   sX   |   ¡ D ]%}|j dd¡ ¡ }|du s|| ¡ kr)t| |ƒ}| |||¡r)|  S qdS )a   Look up one of this resource's methods by HTTP method.

        :param http_method: The HTTP method used to invoke the desired
                            method. Case-insensitive and optional.

        :param media_type: The media type of the representation
                           accepted by the method. Optional.

        :param query_params: The names and values of any fixed query
                             parameters used to distinguish between
                             two methods that use the same HTTP
                             method. Optional.

        :param representation_params: The names and values of any
                             fixed representation parameters used to
                             distinguish between two methods that use
                             the same HTTP method and have the same
                             media type. Optional.

        :return: A MethodDefinition, or None if there's no definition
                  that fits the given constraints.
        r<   Ú N)Ú_method_tag_iterr*   r+   Úlowerr   Úis_described_by)r5   Úhttp_methodrf   Úquery_paramsÚrepresentation_paramsÚ
method_tagr<   Úmethodr   r   r   rz   h  s   
ÿ€zResource.get_methodc                 C   ó   |   |¡ | ¡S )a~  A list of this resource's parameters.

        :param media_type: Media type of the representation definition
            whose parameters are being named. Must be present unless
            this resource is bound to a representation.

        :raise NoBoundRepresentationError: If this resource is not
            bound to a representation and media_type was not provided.
        )Ú_find_representation_definitionr7   ©r5   rf   r   r   r   Ú
parameters‰  ó
   
ÿÿzResource.parametersc                 C   r‡   )a‚  A list naming this resource's parameters.

        :param media_type: Media type of the representation definition
            whose parameters are being named. Must be present unless
            this resource is bound to a representation.

        :raise NoBoundRepresentationError: If this resource is not
            bound to a representation and media_type was not provided.
        )rˆ   Úparameter_namesr‰   r   r   r   rŒ   –  r‹   zResource.parameter_namesc                 c   s    � |   ¡ D ]}t| |ƒV  qdS )z6An iterator over the methods defined on this resource.N)r   r   )r5   r…   r   r   r   Úmethod_iter£  s   €ÿzResource.method_iterc                 C   sF   |   |¡}|j}| tdƒ¡D ]}|j d¡|kr t| |ƒ  S qdS )aÈ  Find a parameter within a representation definition.

        :param param_name: Name of the parameter to find.

        :param media_type: Media type of the representation definition
            whose parameters are being named. Must be present unless
            this resource is bound to a representation.

        :raise NoBoundRepresentationError: If this resource is not
            bound to a representation and media_type was not provided.
        r(   r<   N)rˆ   r3   r4   r   r*   r+   r   )r5   Ú
param_namerf   rU   r}   r-   r   r   r   Úget_parameter©  s   
ÿzResource.get_parameterc                 C   sÖ   | j du r	tdƒ‚| jdkrd|jdkrtd|j ƒ‚| j |j }|durb|  |j|j¡\}}|t	krb|dv rbzt
|ƒ}W |S  tya   ztjt |d¡dd	… Ž }W Y |S  ty`   t|ƒ‚w w |S td
| j ƒ‚)z¨Find the value of a parameter, given the Parameter object.

        :raise ValueError: If the parameter value can't be converted into
        its defined type.
        Nz,Resource is not bound to any representation.r^   Úplainú8Don't know how to find value for a parameter of type %s.)ÚdateTimeÚdatez%Y-%m-%dr   é   zEPath traversal not implemented for a representation of media type %s.)rc   r   rf   r)   rY   r<   Ú_dereference_namespacer3   rn   ÚXML_SCHEMA_NS_URIr   r2   ÚdatetimeÚtimeÚstrptime)r5   Ú	parameterr9   Únamespace_urlÚ	data_typer   r   r   Úget_parameter_value¼  sF   
ÿ

ÿÿÿ
öÿûüû
þzResource.get_parameter_valuec                 C   sD   |durd|v r|  dd¡\}}nd}| t¡}| |d¡}||fS )z�Splits a value into namespace URI and value.

        :param tag: A tag to use as context when mapping namespace
        names to URIs.
        Nú:é   r~   )Úsplitr+   ÚNS_MAP)r5   r3   r9   Ú	namespaceÚns_mapr›   r   r   r   r•   ì  s   
zResource._dereference_namespacec                 C   ó   | j j |¡S )z-Given an ID, find a ResourceType for that ID.)rK   Úresource_typesr+   rZ   r   r   r   rQ   ú  ó   zResource._definition_factoryc                 C   ó   | j j d¡S )zýReturn the URL that shows where a resource is 'really' defined.

        If a resource's capabilities are defined by reference, the
        <resource> tag's 'type' attribute will contain the URL to the
        <resource_type> that defines them.
        rn   ©r3   r*   r+   r]   r   r   r   rO   þ  ó   zResource._get_definition_urlc                 C   s>   | j dur| j ¡ }| ¡ S |dur|  |¡}| ¡ S tdƒ‚)a3  Get the most appropriate representation definition.

        If media_type is provided, the most appropriate definition is
        the definition of the representation of that media type.

        If this resource is bound to a representation, the most
        appropriate definition is the definition of that
        representation. Otherwise, the most appropriate definition is
        the definition of the representation served in response to a
        standard GET.

        :param media_type: Media type of the definition to find. Must
            be present unless the resource is bound to a
            representation.

        :raise NoBoundRepresentationError: If this resource is not
            bound to a representation and media_type was not provided.

        :return: A RepresentationDefinition
        NzSResource is not bound to any representation, and no media media type was specified.)rc   rg   rV   rh   r   )r5   rf   rU   r   r   r   rˆ     s   

ú
ýÿz(Resource._find_representation_definitionc                 c   s*   � |   ¡ j}| tdƒ¡D ]}|V  qdS )z+Iterate over this resource's <method> tags.r†   N)rV   r3   r4   r   )r5   rU   r…   r   r   r   r   *  s
   €
ÿzResource._method_tag_iter)NNTN)r^   TN)NNNNrH   )r    r!   r"   r#   rL   Úpropertyri   ru   r[   rw   rh   rz   rŠ   rŒ   r�   r�   r�   r•   rQ   rO   rˆ   r   Ú__classcell__r   r   rl   r   r   õ   s>    ý4



þ

ÿ
!


0
	#r   c                   @   sn   e Zd ZdZdd„ Zedd„ ƒZedd„ ƒZedd	„ ƒZed
d„ ƒZ	ddd„Z
		ddd„Z		ddd„ZdS )r   z*A wrapper around an XML <method> tag.
    c                 C   s   || _ | j j| _|| _dS )zaInitialize with a <method> tag.

        :param method_tag: An ElementTree <method> tag.
        N)r/   rK   r3   )r5   r/   r…   r   r   r   rL   4  s   

zMethod.__init__c                 C   s   t | | j tdƒ¡ƒS )z@Return the definition of a request that invokes the WADL method.Úrequest)ÚRequestDefinitionr3   Úfindr   r]   r   r   r   r¬   =  s   zMethod.requestc                 C   s   t | j| j tdƒ¡ƒS )z9Return the definition of the response to the WADL method.r{   )r   r/   r3   r®   r   r]   r   r   r   r{   B  s   ÿzMethod.responsec                 C   r§   )z)The XML ID of the WADL method definition.r[   r¨   r]   r   r   r   r[   H  ó   z	Method.idc                 C   s   | j j d¡ ¡ S )z«The name of the WADL method definition.

        This is also the name of the HTTP method (GET, POST, etc.)
        that should be used to invoke the WADL method.
        r<   ©r3   r*   r+   r€   r]   r   r   r   r<   M  s   zMethod.nameNc                 K   s   | j j|fi |¤ŽS )ú4Return the request URL to use to invoke this method.)r¬   Ú	build_url)r5   rC   rE   r   r   r   Úbuild_request_urlV  ó   zMethod.build_request_urlc                 K   s   | j j||fi |¤ŽS )z‚Build a representation to be sent when invoking this method.

        :return: A 2-tuple of (media_type, representation).
        )r¬   rc   )r5   rf   rC   rE   r   r   r   Úbuild_representationZ  s
   ÿÿzMethod.build_representationc              	   C   sà   d}|dur| j  |¡}|du rdS |dur:t|ƒdkr:| j }|du r%dS z
| |j|d¡ W n
 ty9   Y dS w |du sDt|ƒdkrFdS |durO| |¡S | j jD ]}z| | | j	¡|d¡ W  dS  tym   Y qSw dS )a  Returns true if this method fits the given constraints.

        :param media_type: The method must accept this media type as a
                           representation.

        :param query_values: These key-value pairs must be acceptable
                           as values for this method's query
                           parameters. This need not be a complete set
                           of parameters acceptable to the method.

        :param representation_values: These key-value pairs must be
                           acceptable as values for this method's
                           representation parameters. Again, this need
                           not be a complete set of parameters
                           acceptable to the method.
        NFr   T)
r¬   rh   r?   rG   rƒ   r2   r�   Úrepresentationsr7   r/   )r5   rf   Úquery_valuesÚrepresentation_valuesrc   r¬   r   r   r   r�   c  sH   ÿÿÿÿ
þÿzMethod.is_described_byrH   ©NN)NNN)r    r!   r"   r#   rL   rª   r¬   r{   r[   r<   r³   rµ   r�   r   r   r   r   r   1  s$    	





ÿ	ÿr   c                   @   sN   e Zd ZdZdd„ Zedd„ ƒZedd„ ƒZdd	d
„Zddd„Z	ddd„Z
dS )r­   zBA wrapper around the description of the request invoking a method.c                 C   s$   || _ | j j| _| jj| _|| _dS )z­Initialize with a <request> tag.

        :param resource: The resource to which this request can be sent.
        :param request_tag: An ElementTree <request> tag.
        N)r†   r/   rK   r3   )r5   r†   Úrequest_tagr   r   r   rL   �  s   


zRequestDefinition.__init__c                 C   s   |   dg¡S )z,Return the query parameters for this method.Úquery©r7   r]   r   r   r   rƒ   ¨  rv   zRequestDefinition.query_paramsc                 c   s.   � | j  tdƒ¡D ]}t| j| j|ƒV  q	d S )Nrc   )r3   r4   r   r   rK   r/   )r5   rU   r   r   r   r¶   ­  s   €
ÿÿz!RequestDefinition.representationsNc                 C   s*   | j D ]}|du s|j|kr|  S qdS )z1Return the appropriate representation definition.N)r¶   rf   ©r5   rf   rc   r   r   r   rh   ³  s
   
ÿz/RequestDefinition.get_representation_definitionc                 K   s0   |   |¡}|du rtd| ƒ‚|j|fi |¤ŽS )z€Build a representation to be sent along with this request.

        :return: A 2-tuple of (media_type, representation).
        Nz,Cannot build representation of media type %s)rh   Ú	TypeErrorrw   )r5   rf   rC   rE   rU   r   r   r   rc   º  s   
ÿz RequestDefinition.representationc                 K   sX   | j | j|fi |¤Ž}| jj}t|ƒdkr*d|v rd}nd}||tt| ¡ ƒƒ 7 }|S )r±   r   ú?ú&)rG   rƒ   r/   ri   r?   r   ÚsortedÚitems)r5   rC   rE   rF   ri   Úappendr   r   r   r²   Æ  s   ÿÿzRequestDefinition.build_urlrH   r¹   )r    r!   r"   r#   rL   rª   rƒ   r¶   rh   rc   r²   r   r   r   r   r­   ›  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;A wrapper around the description of a response to a method.Nc                 C   s   |j | _ || _|| _|| _dS )zgInitialize with a <response> tag.

        :param response_tag: An ElementTree <response> tag.
        N)rK   r/   r3   Úheaders)r5   r/   Úresponse_tagrÄ   r   r   r   rL   Ü  s   
zResponseDefinition.__init__c                 c   s4   � t dƒ}| j |¡D ]}t| jj| j|ƒV  qdS )z¢Get an iterator over the representation definitions.

        These are the representations returned in response to an
        invocation of this method.
        rc   N)r   r3   r4   r   r/   rK   )r5   Úpathr}   r   r   r   Ú__iter__æ  s   €ÿÿzResponseDefinition.__iter__c                 C   s   t | j| j|ƒS )z�Bind the response to a set of HTTP headers.

        A WADL response can have associated header parameters, but no
        other kind.
        )r   r/   r3   )r5   rÄ   r   r   r   rw   ñ  s   zResponseDefinition.bindc                 C   sH   | j  tdƒ¡D ]}|j d¡|kr!|j d¡dkr!t| |ƒ  S qdS )z,Find a header parameter within the response.r(   r<   r)   ÚheaderN)r3   r4   r   r*   r+   r   )r5   rŽ   r-   r   r   r   r�   ù  s   €z ResponseDefinition.get_parameterc                 C   s8   | j du r	tdƒ‚|jdkrtd|j ƒ‚| j  |j¡S )z:Find the value of a parameter, given the Parameter object.Nz,Response object is not bound to any headers.rÈ   r‘   )rÄ   r   r)   rY   r+   r<   )r5   rš   r   r   r   r�     s   
ÿ
ÿÿz&ResponseDefinition.get_parameter_valuec                 C   s.   | j du rdS | D ]}|j|kr|  S q	dS )z8Get one of the possible representations of the response.N)r3   rf   r½   r   r   r   rh     s   

ÿz0ResponseDefinition.get_representation_definitionrH   )
r    r!   r"   r#   rL   rÇ   rw   r�   r�   rh   r   r   r   r   r   Ô  s    

r   c                       sz   e Zd ZdZ‡ fdd„Z‡ fdd„Zdd„ Zedd	„ ƒZd
d„ Z	dd„ Z
ddd„Zdd„ Zdd„ Zdd„ Zdd„ Z‡  ZS )r   z2A definition of the structure of a representation.c                    s    t t| ƒ |¡ || _|| _d S rH   )r_   r   rL   r/   r3   )r5   rK   r/   r}   rl   r   r   rL     s   
z!RepresentationDefinition.__init__c                    s   t t| ƒ ddg|¡S )Nr»   r�   )r_   r   r7   ©r5   r/   rl   r   r   r7     s   
ÿzRepresentationDefinition.paramsc                 C   s   dd„ |   |¡D ƒS )z#Return the names of all parameters.c                 S   r8   r   )r<   )r,   r(   r   r   r   r1   $  r;   z<RepresentationDefinition.parameter_names.<locals>.<listcomp>r¼   rÉ   r   r   r   rŒ   "  r´   z(RepresentationDefinition.parameter_namesc                 C   s   |   ¡ jjd S )z4The media type of the representation described here.ry   )rV   r3   r*   r]   r   r   r   rf   &  s   z#RepresentationDefinition.media_typec           	      C   s–   t ttjd ƒƒ}d| }t tj¡}d||  d }|du r!|S |}d}	 dt |¡ d	  d
¡}tj	||tj
d�s>	 |S |d t|ƒ }|d7 }q&)z;Make a random boundary that does not appear in `all_parts`.rŸ   z%%0%ddz===============z==Nr   Tz^--z(--)?$Úascii)ÚflagsÚ.)r?   ÚreprÚsysÚmaxsizeÚrandomÚ	randrangeÚreÚescapeÚencodeÚsearchÚ	MULTILINErr   )	r5   Ú	all_partsÚ_widthÚ_fmtÚtokenÚboundaryÚbÚcounterÚpatternr   r   r   Ú_make_boundary+  s    þûz'RepresentationDefinition._make_boundaryc                 C   sP   |D ]\}}|  | d¡¡ |  d¡ |  | d¡¡ |  d¡ q|  d¡ dS )z$Write MIME headers to a file object.úUTF-8s   : ó   
N©ÚwriterÔ   )r5   ÚbufrÄ   Úkeyr9   r   r   r   Ú_write_headers=  s   
z'RepresentationDefinition._write_headersFc                 C   s6   |  d¡ |  | d¡¡ |r|  d¡ |  d¡ dS )z,Write a multipart boundary to a file object.s   --rà   rá   Nrâ   )r5   rä   rÛ   Úclosingr   r   r   Ú_write_boundaryF  s
   

z(RepresentationDefinition._write_boundaryc                 C   s€  g }|D ]|\}}}t  ¡ }|rd}dt|ƒt|ƒf }nd}dt|ƒ }|  |dd|fd|fg¡ |rFt|tƒs@tdt|ƒ ƒ‚| |¡ n3t|t	ƒsStd	t|ƒ ƒ‚t
 d
|¡}	|	dd… D ]}
| |
 d¡¡ | d¡ q_| |	d  d¡¡ | | ¡ ¡ q|  d |¡¡}t  ¡ }dt|ƒ }|  |dd|fg¡ |D ]}|  ||¡ | |¡ | d¡ qŸ| j||dd� || ¡ fS )aV  Generate a multipart/form-data message.

        This is very loosely based on the email module in the Python standard
        library.  However, that module doesn't really support directly embedding
        binary data in a form: various versions of Python have mangled line
        separators in different ways, and none of them get it quite right.
        Since we only need a tiny subset of MIME here, it's easier to implement
        it ourselves.

        :return: a tuple of two elements: the Content-Type of the message, and
            the entire encoded message as a byte string.
        zapplication/octet-streamz#form-data; name="%s"; filename="%s"ztext/plain; charset="utf-8"zform-data; name="%s")zMIME-Versionz1.0zContent-TypezContent-Dispositionzbytes payload expected: %szstring payload expected: %sz
\r\n|\r|\nNéÿÿÿÿrà   rá   z"multipart/form-data; boundary="%s"T)rç   )ÚioÚBytesIOr   ræ   ra   Úbytesr¾   rn   rã   r   rÒ   r    rÔ   rÃ   Úgetvaluerß   r@   rè   )r5   ÚpartsÚencoded_partsÚ	is_binaryr<   r9   rä   ÚctypeÚcdispÚlinesÚlinerÛ   Úencoded_partr   r   r   Ú_generate_multipart_formN  sT   ÿý


ÿþ
z1RepresentationDefinition._generate_multipart_formc                 K   sÔ   |   ¡ }| | j¡}| j||fi |¤Ž}| j}|dkr'tt| ¡ ƒƒ}||fS |dkrWg }tƒ }	|D ]}
| 	|
j
|	¡}||	urK| |
jdk|
j
|f¡ q2|  |¡\}}||fS |dkrdt |¡}||fS td| ƒ‚)zzBind the definition to parameter values, creating a document.

        :return: A 2-tuple (media_type, document).
        z!application/x-www-form-urlencodedzmultipart/form-dataÚbinaryr^   zUnsupported media type: '%s')rV   r7   r/   rG   rf   r   rÁ   rÂ   Úobjectr+   r<   rÃ   rn   rö   rd   Údumpsr2   )r5   rC   rE   rU   r7   rF   rf   Údocrî   Úmissingr(   r9   r   r   r   rw   �  s2   ÿÿô€ü
ÿzRepresentationDefinition.bindc                 C   r¤   )z9Turn a representation ID into a RepresentationDefinition.)rK   Úrepresentation_definitionsr+   rZ   r   r   r   rQ   ©  r¦   z,RepresentationDefinition._definition_factoryc                 C   r§   )a  Find the URL containing the representation's 'real' definition.

        If a representation's structure is defined by reference, the
        <representation> tag's 'href' attribute will contain the URL
        to the <representation> that defines the structure.
        Úhrefr¨   r]   r   r   r   rO   ­  r©   z,RepresentationDefinition._get_definition_url)F)r    r!   r"   r#   rL   r7   rŒ   rª   rf   rß   ræ   rè   rö   rw   rQ   rO   r«   r   r   rl   r   r     s    

	Ar   c                   @   s€   e Zd ZdZdd„ Zedd„ ƒZedd„ ƒZedd	„ ƒZed
d„ ƒZ	edd„ ƒZ
dd„ Zedd„ ƒZedd„ ƒZedd„ ƒZdS )r   z5One of the parameters of a representation definition.c                 C   s   |j | _ || _|| _dS )aÏ  Initialize with respect to a value container.

        :param value_container: Usually the resource whose representation
            has this parameter. If the resource is bound to a representation,
            you'll be able to find the value of this parameter in the
            representation. This may also be a server response whose headers
            define a value for this parameter.
        :tag: The ElementTree <param> tag for this parameter.
        N)rK   Úvalue_containerr3   )r5   rþ   r3   r   r   r   rL   º  s   

zParameter.__init__c                 C   r§   )zThe name of this parameter.r<   r¨   r]   r   r   r   r<   È  r¯   zParameter.namec                 C   r§   )zThe style of this parameter.r)   r¨   r]   r   r   r   r)   Í  r¯   zParameter.stylec                 C   r§   )zThe XSD type of this parameter.rn   r¨   r]   r   r   r   rn   Ò  r¯   zParameter.typec                 C   r§   )a9  The value to which this parameter is fixed, if any.

        A fixed parameter must be present in invocations of a WADL
        method, and it must have a particular value. This is commonly
        used to designate one parameter as containing the name of the
        server-side operation to be invoked.
        Úfixedr¨   r]   r   r   r   r=   ×  s   	zParameter.fixed_valuec                 C   s   | j j dd¡ ¡ dv S )z6Whether or not a value for this parameter is required.ÚrequiredÚfalse)Ú1Útruer°   r]   r   r   r   rA   â  s   ÿzParameter.is_requiredc                 C   s   | j  | ¡S )zíThe value of this parameter in the bound representation/headers.

        :raise NoBoundRepresentationError: If this parameter's value
               container is not bound to a representation or a set of
               headers.
        )rþ   r�   r]   r   r   r   Ú	get_valueè  s   zParameter.get_valuec                    s   ‡ fdd„ˆ j  tdƒ¡D ƒS )z7Return the set of acceptable values for this parameter.c                    s   g | ]}t ˆ |ƒ‘qS r   )ÚOption)r,   Ú
option_tagr]   r   r   r1   ô  s    ÿz%Parameter.options.<locals>.<listcomp>r:   )r3   r4   r   r]   r   r]   r   r>   ñ  s   
ÿzParameter.optionsc                 C   s&   | j  tdƒ¡}|du rdS t| |ƒS )zÃGet the link to another resource.

        The link may be examined and, if its type is of a known WADL
        description, it may be followed.

        :return: A Link object, or None.
        ÚlinkN)r3   r®   r   r   )r5   Úlink_tagr   r   r   r  ÷  s   	
zParameter.linkc                 C   s   | j }|du rtdƒ‚|jS )a  Follow a link from this parameter to a new resource.

        This only works for parameters whose WADL definition includes a
        <link> tag that points to a known WADL description.

        :return: A Resource object for the resource at the other end
        of the link.
        Nz(This parameter isn't a link to anything.)r  r2   Úfollow)r5   r  r   r   r   Úlinked_resource  s   
zParameter.linked_resourceN)r    r!   r"   r#   rL   rª   r<   r)   rn   r=   rA   r  r>   r  r
  r   r   r   r   r   ·  s(    





	

r   c                   @   s$   e Zd ZdZdd„ Zedd„ ƒZdS )r  z0One of a set of possible values for a parameter.c                 C   s   || _ || _dS )z}Initialize the option.

        :param parameter: A Parameter.
        :param link_tag: An ElementTree <option> tag.
        N)rš   r3   )r5   rš   r  r   r   r   rL     rM   zOption.__init__c                 C   r§   )Nr9   r¨   r]   r   r   r   r9      r¦   zOption.valueN)r    r!   r"   r#   rL   rª   r9   r   r   r   r   r    s
    	r  c                       sH   e Zd ZdZ‡ fdd„Zedd„ ƒZedd„ ƒZdd	„ Zd
d„ Z	‡  Z
S )r   zµA link from one resource to another.

    Calling resolve_definition() on a Link will give you a Resource for the
    type of resource linked to. An alias for this is 'follow'.
    c                    s"   t t| ƒ |j¡ || _|| _dS )zyInitialize the link.

        :param parameter: A Parameter.
        :param link_tag: An ElementTree <link> tag.
        N)r_   r   rL   rK   rš   r3   )r5   rš   r  rl   r   r   rL   ,  s   
zLink.__init__c                 C   s   | j stdƒ‚|  ¡ S )z$Follow the link to another Resource.zfCannot follow a link when the target has no WADL description. Try using a general HTTP client instead.)Ú
can_followr
   rV   r]   r   r   r   r	  6  s   zLink.followc                 C   s$   z|   ¡ }W dS  ty   Y dS w )z”Can this link be followed within wadllib?

        wadllib can follow a link if it points to a resource that has
        a WADL definition.
        FT)rO   r
   )r5   Údefinition_urlr   r   r   r  ?  s   
þÿzLink.can_followc                 C   s    t | j| j ¡ | jj |¡jƒS )z,Turn a resource type ID into a ResourceType.)r   rK   rš   r  r¥   r+   r3   rZ   r   r   r   rQ   L  s   þzLink._definition_factoryc                 C   s"   | j j d¡}|du rtdƒ‚|S )z(Find the URL containing the definition .rj   NzIParameter is a link, but not to a resource with a known WADL description.)r3   r*   r+   r
   )r5   rn   r   r   r   rO   R  s   zLink._get_definition_url)r    r!   r"   r#   rL   rª   r	  r  rQ   rO   r«   r   r   rl   r   r   %  s    


r   c                   @   s   e Zd ZdZdd„ ZdS )r	   z,A wrapper around an XML <resource_type> tag.c                 C   s
   || _ dS )zvInitialize with a <resource_type> tag.

        :param resource_type_tag: An ElementTree <resource_type> tag.
        N)r3   )r5   Úresource_type_tagr   r   r   rL   ^  s   
zResourceType.__init__N)r    r!   r"   r#   rL   r   r   r   r   r	   [  s    r	   c                   @   s@   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dS )r   z1A WADL document made programmatically accessible.c                 C   sÊ   || _ t|dƒr|  |¡| _n|  |¡| _| j tdƒ¡| _| jj 	d¡| _
i | _i | _| j tdƒ¡D ]}|j 	d¡}|durKt| d|ƒ}|| j|< q4| j tdƒ¡D ]}|jd }t|ƒ| j|< qTdS )zÝParse WADL and find the most important parts of the document.

        :param markup_url: The URL from which this document was obtained.
        :param markup: The WADL markup itself, or an open filehandle to it.
        ÚreadÚ	resourcesrt   rc   r[   Nrj   )rp   ÚhasattrÚ_from_streamrú   Ú_from_stringr®   r   r  r*   r+   Úresource_baserü   r¥   r4   r   r	   )r5   rp   Úmarkuprc   r[   rU   rj   r   r   r   rL   i  s(   
ÿ
€
þzApplication.__init__c                 C   sv   d}d}g }t  ||¡D ])\}}|dkr| |¡ q|dkr#| ¡  q|dkr5|du r-|}| tt|ƒ¡ qt  |¡S )zrTurns markup into a document.

        Just a wrapper around ElementTree which keeps track of namespaces.
        )Ústartústart-nsúend-nsNr  r  r  )ÚETÚ	iterparserÃ   ÚpopÚsetr¡   r   ÚElementTree)r5   ÚstreamÚeventsÚrootr£   ÚeventÚelemr   r   r   r  ‚  s   
€
zApplication._from_streamc                 C   s$   t |tƒs
| d¡}|  t |¡¡S )zTurns markup into a document.rà   )ra   rì   rÔ   r  rê   rë   )r5   r  r   r   r   r  –  s   

zApplication._from_stringc                 C   s.   |   |¡}| j |¡}|du rtd| ƒ‚|S )z7Retrieve a resource type by the URL of its description.NrN   )rP   r¥   r+   rR   )r5   Úresource_type_urlrT   rj   r   r   r   rb   œ  s
   
zApplication.get_resource_typec                 C   sZ   t | jƒ ¡ }d|_| d¡rt |ƒ ¡ }n| |¡}|j}d|_||kr'|S td| ƒ‚)zÖA helper method for locating a part of a WADL document.

        :param url: The URL (with anchor) of the desired part of the
        WADL document.
        :return: The XML ID corresponding to the anchor.
        NÚhttpz,Can't look up definition in another url (%s))r   rp   ÚensureNoSlashÚfragmentÚ
startswithÚresolverY   )r5   ri   Ú
markup_uriÚthis_uriÚpossible_xml_idr   r   r   rP   ¤  s   

ÿzApplication.lookup_xml_idc                    sV   ‡ fdd„| j D ƒ}t|ƒdk rdS t|ƒdkrtdˆ  ƒ‚t| t| jˆ dƒ|d ƒS )zpLocate one of the resources described by this document.

        :param path: The path to the resource.
        c                    s   g | ]}|j d  ˆ kr|‘qS ©rÆ   )r*   )r,   r/   r+  r   r   r1   Ì  s    ÿz4Application.get_resource_by_path.<locals>.<listcomp>rŸ   Nz+More than one resource defined with path %sTr   )r  r?   r
   r   r   r  )r5   rÆ   Úmatchingr   r+  r   Úget_resource_by_pathÄ  s   ÿÿz Application.get_resource_by_pathN)
r    r!   r"   r#   rL   r  r  rb   rP   r-  r   r   r   r   r   f  s     r   )6r#   rn   Ú__metaclass__Ú__all__r—   Úemail.utilsr   rê   rd   rÐ   rÒ   rÎ   r˜   Úurllib.parser   ÚImportErrorÚurllibÚxml.etree.cElementTreeÚetreeÚcElementTreer  Úxml.etree.ElementTreer  Úlazr.urir   r   Úwadllibr   r   Úwadllib.iso_strptimer   r¡   r–   r   r   r   Ú	Exceptionr
   r   r%   rø   r&   r'   rI   r   r   r­   r   r   r   r  r   r	   r   r   r   r   r   Ú<module>   s`   ÿÿ	
B=  >j9B "]6