B
    W²ç_	  ã               @   sL   d Z ddlmZmZmZmZ ddlmZ G dd„ deƒZ	G dd„ de
ƒZd	S )
z
Relationship-related objects.
é    )Úabsolute_importÚdivisionÚprint_functionÚunicode_literalsé   )ÚCT_Relationshipsc                   sx   e Zd ZdZ‡ fdd„Zddd„Zdd„ Zd	d
„ Zdd„ Ze	dd„ ƒZ
e	dd„ ƒZddd„Zdd„ Ze	dd„ ƒZ‡  ZS )ÚRelationshipszQ
    Collection object for |_Relationship| instances, having list semantics.
    c                s   t t| ƒ ¡  || _i | _d S )N)Úsuperr   Ú__init__Ú_baseURIÚ_target_parts_by_rId)ÚselfÚbaseURI)Ú	__class__© ú>/var/www/html/venv/lib/python3.7/site-packages/docx/opc/rel.pyr
      s    zRelationships.__init__Fc             C   s,   t |||| j|ƒ}|| |< |s(|| j|< |S )z@
        Return a newly added |_Relationship| instance.
        )Ú_Relationshipr   r   )r   ÚreltypeÚtargetÚrIdÚis_externalÚrelr   r   r   Úadd_relationship   s
    
zRelationships.add_relationshipc             C   s,   |   ||¡}|dkr(| j}|  |||¡}|S )z~
        Return relationship of *reltype* to *target_part*, newly added if not
        already present in collection.
        N)Ú_get_matchingÚ	_next_rIdr   )r   r   Útarget_partr   r   r   r   r   Ú
get_or_add!   s
    zRelationships.get_or_addc             C   s6   | j ||dd}|dkr0| j}| j|||dd}|jS )z
        Return rId of external relationship of *reltype* to *target_ref*,
        newly added if not already present in collection.
        T)r   N)r   r   r   r   )r   r   Ú
target_refr   r   r   r   r   Úget_or_add_ext_rel,   s    z Relationships.get_or_add_ext_relc             C   s   |   |¡}|jS )z¶
        Return target part of rel with matching *reltype*, raising |KeyError|
        if not found and |ValueError| if more than one matching relationship
        is found.
        )Ú_get_rel_of_typer   )r   r   r   r   r   r   Úpart_with_reltype9   s    
zRelationships.part_with_reltypec             C   s   | j S )zq
        dict mapping rIds to target parts for all the internal relationships
        in the collection.
        )r   )r   r   r   r   Úrelated_partsB   s    zRelationships.related_partsc             C   s8   t  ¡ }x(|  ¡ D ]}| |j|j|j|j¡ qW |jS )z
        Serialize this relationship collection into XML suitable for storage
        as a .rels file in an OPC package.
        )	r   ÚnewÚvaluesZadd_relr   r   r   r   Úxml)r   Zrels_elmr   r   r   r   r$   J   s
    zRelationships.xmlc             C   s0   dd„ }x"|   ¡ D ]}|||||ƒr|S qW dS )z‡
        Return relationship of matching *reltype*, *target*, and
        *is_external* from collection, or None if not found.
        c             S   s>   | j |krdS | j|krdS | jr(| jn| j}||kr:dS dS )NFT)r   r   r   r   )r   r   r   r   Z
rel_targetr   r   r   Úmatches\   s    

z,Relationships._get_matching.<locals>.matchesN)r#   )r   r   r   r   r%   r   r   r   r   r   W   s
    
zRelationships._get_matchingc                sV   ‡ fdd„|   ¡ D ƒ}t|ƒdkr2d}t|ˆ  ƒ‚t|ƒdkrNd}t|ˆ  ƒ‚|d S )zà
        Return single relationship of type *reltype* from the collection.
        Raises |KeyError| if no matching relationship is found. Raises
        |ValueError| if more than one matching relationship is found.
        c                s   g | ]}|j ˆ kr|‘qS r   )r   )Ú.0r   )r   r   r   ú
<listcomp>q   s    z2Relationships._get_rel_of_type.<locals>.<listcomp>r   z*no relationship of type '%s' in collectionr   z1multiple relationships of type '%s' in collection)r#   ÚlenÚKeyErrorÚ
ValueError)r   r   ZmatchingÚtmplr   )r   r   r   k   s    zRelationships._get_rel_of_typec             C   s4   x.t dt| ƒd ƒD ]}d| }|| kr|S qW dS )z 
        Next available rId in collection, starting from 'rId1' and making use
        of any gaps in numbering, e.g. 'rId2' for rIds ['rId1', 'rId3'].
        r   é   zrId%dN)Úranger(   )r   ÚnZrId_candidater   r   r   r   z   s    zRelationships._next_rId)F)F)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r
   r   r   r   r    Úpropertyr!   r$   r   r   r   Ú__classcell__r   r   )r   r   r      s   

	
r   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edd„ ƒZ	edd„ ƒZ
‡  ZS )r   z0
    Value object for relationship to part.
    Fc                s4   t t| ƒ ¡  || _|| _|| _|| _t|ƒ| _d S )N)	r	   r   r
   Ú_rIdÚ_reltypeÚ_targetr   ÚboolÚ_is_external)r   r   r   r   r   Zexternal)r   r   r   r
   Š   s    z_Relationship.__init__c             C   s   | j S )N)r9   )r   r   r   r   r   ’   s    z_Relationship.is_externalc             C   s   | j S )N)r6   )r   r   r   r   r   –   s    z_Relationship.reltypec             C   s   | j S )N)r5   )r   r   r   r   r   š   s    z_Relationship.rIdc             C   s   | j rtdƒ‚| jS )NzOtarget_part property on _Relationship is undefined when target mode is External)r9   r*   r7   )r   r   r   r   r   ž   s    z_Relationship.target_partc             C   s    | j r| jS | jj | j¡S d S )N)r9   r7   ZpartnameZrelative_refr   )r   r   r   r   r   ¥   s    z_Relationship.target_ref)F)r/   r0   r1   r2   r
   r3   r   r   r   r   r   r4   r   r   )r   r   r   †   s   r   N)r2   Ú
__future__r   r   r   r   Zoxmlr   Údictr   Úobjectr   r   r   r   r   Ú<module>   s   x