U
    cqe                     @   s   d Z ddlmZ ddlmZmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ ddlmZ dd	lmZ G d
d dZG dd dZdS )z8Objects that implement reading and writing OPC packages.    )RELATIONSHIP_TYPE)PACKAGE_URIPackURI)PartFactory)CorePropertiesPart)PackageReader)PackageWriter)Relationships)lazypropertyc                       s   e Zd ZdZ fddZdd Zedd Zdd	 Zd
d Z	d!ddZ
edd Zdd Zedd Zdd Zedd Zdd Zedd Zdd Zedd  Z  ZS )"
OpcPackagezMain API class for |python-opc|.

    A new instance is constructed by calling the :meth:`open` class method with a path
    to a package file or file-like object containing one.
    c                    s   t t|   d S N)superr   __init__self	__class__ 4/tmp/pip-unpacked-wheel-gx5hpqp3/docx/opc/package.pyr      s    zOpcPackage.__init__c                 C   s   dS )zEntry point for any post-unmarshaling processing.

        May be overridden by subclasses without forwarding call to super.
        Nr   r   r   r   r   after_unmarshal   s    zOpcPackage.after_unmarshalc                 C   s   | j jS )zl|CoreProperties| object providing read/write access to the Dublin Core
        properties for this document.)_core_properties_partcore_propertiesr   r   r   r   r       s    zOpcPackage.core_propertiesc                 #   s&   d fdd	  | D ]
}|V  qdS )zGenerate exactly one reference to each relationship in the package by
        performing a depth-first traversal of the rels graph.Nc                 3   sf   |d krg n|}| j  D ]F}|V  |jr,q|j}||kr<q|| |} ||D ]
}|V  qTqd S r   relsvaluesis_externalZtarget_partappendsourcevisitedrelpartZ
new_source	walk_relsr   r   r#   *   s    
z'OpcPackage.iter_rels.<locals>.walk_rels)Nr   )r   r    r   r"   r   	iter_rels&   s    zOpcPackage.iter_relsc                 #   s(   g f fdd	  | D ]
}|V  qdS )zGenerate exactly one reference to each of the parts in the package by
        performing a depth-first traversal of the rels graph.c                 3   sV   | j  D ]F}|jrq
|j}||kr&q
|| |V  |} ||D ]
}|V  qDq
d S r   r   r   
walk_partsr   r   r&   ?   s    
z)OpcPackage.iter_parts.<locals>.walk_partsNr   )r   r!   r   r%   r   
iter_parts;   s    zOpcPackage.iter_partsFc                 C   s   | j ||||S )a}  Return newly added |_Relationship| instance of `reltype` between this part
        and `target` with key `rId`.

        Target mode is set to ``RTM.EXTERNAL`` if `is_external` is |True|. Intended for
        use during load from a serialized package, where the rId is well known. Other
        methods exist for adding a new relationship to the package during processing.
        )r   Zadd_relationship)r   reltypetargetrIdr   r   r   r   load_relO   s    zOpcPackage.load_relc                 C   s   |  tjS )a  Return a reference to the main document part for this package.

        Examples include a document part for a WordprocessingML package, a presentation
        part for a PresentationML package, or a workbook part for a SpreadsheetML
        package.
        )part_related_byRTZOFFICE_DOCUMENTr   r   r   r   main_document_partY   s    zOpcPackage.main_document_partc                 C   sJ   dd |   D }tdt|d D ] }|| }||kr$t|  S q$dS )a  Return a |PackURI| instance representing partname matching `template`.

        The returned part-name has the next available numeric suffix to distinguish it
        from other parts of its type. `template` is a printf (%)-style template string
        containing a single replacement item, a '%d' to be used to insert the integer
        portion of the partname. Example: "/word/header%d.xml"
        c                 S   s   h | ]
}|j qS r   )partname).0r!   r   r   r   	<setcomp>k   s     z+OpcPackage.next_partname.<locals>.<setcomp>      N)r'   rangelenr   )r   templateZ	partnamesnZcandidate_partnamer   r   r   next_partnamec   s
    zOpcPackage.next_partnamec                 C   s"   t |}|  }t||t |S )zGReturn an |OpcPackage| instance loaded with the contents of `pkg_file`.)r   	from_fileUnmarshaller	unmarshalr   )clspkg_file
pkg_readerpackager   r   r   openq   s    
zOpcPackage.openc                 C   s   | j |S )zReturn part to which this package has a relationship of `reltype`.

        Raises |KeyError| if no such relationship is found and |ValueError| if more than
        one such relationship is found.
        )r   Zpart_with_reltype)r   r(   r   r   r   r,   y   s    zOpcPackage.part_related_byc                 C   s   t |  S )zJReturn a list containing a reference to each of the parts in this package.)listr'   r   r   r   r   parts   s    zOpcPackage.partsc                 C   s   | j ||}|jS )zReturn rId key of relationship to `part`, from the existing relationship if
        there is one, otherwise a newly created one.)r   Z
get_or_addr*   )r   r!   r(   r    r   r   r   	relate_to   s    zOpcPackage.relate_toc                 C   s
   t tjS )ztReturn a reference to the |Relationships| instance holding the collection of
        relationships for this package.)r	   r   ZbaseURIr   r   r   r   r      s    zOpcPackage.relsc                 C   s*   | j D ]}|  qt|| j| j  dS )zvSave this package to `pkg_file`, where `file` can be either a path to a file
        (a string) or a file-like object.N)rB   Zbefore_marshalr   writer   )r   r=   r!   r   r   r   save   s    

zOpcPackage.savec                 C   sD   z|  tjW S  tk
r>   t| }| |tj | Y S X dS )z|CorePropertiesPart| object related to this package.

        Creates a default core properties part if one is not present (not common).
        N)r,   r-   ZCORE_PROPERTIESKeyErrorr   defaultrC   )r   Zcore_properties_partr   r   r   r      s    
z OpcPackage._core_properties_part)F)__name__
__module____qualname____doc__r   r   propertyr   r$   r'   r+   r.   r8   classmethodr@   r,   rB   rC   r
   r   rE   r   __classcell__r   r   r   r   r      s,   	



	


r   c                   @   s4   e Zd ZdZedd Zedd Zedd ZdS )	r:   zHHosts static methods for unmarshalling a package from a |PackageReader|.c                 C   s>   t | ||}t | || | D ]}|  q$|  dS )zConstruct graph of parts and realized relationships based on the contents of
        `pkg_reader`, delegating construction of each part to `part_factory`.

        Package relationships are added to `pkg`.
        N)r:   _unmarshal_parts_unmarshal_relationshipsr   r   )r>   r?   part_factoryrB   r!   r   r   r   r;      s
    
zUnmarshaller.unmarshalc                 C   s2   i }|   D ] \}}}}||||||||< q|S )zReturn a dictionary of |Part| instances unmarshalled from `pkg_reader`, keyed
        by partname.

        Side-effect is that each part in `pkg_reader` is constructed using
        `part_factory`.
        )Ziter_sparts)r>   r?   rQ   rB   r/   content_typer(   Zblobr   r   r   rO      s        
zUnmarshaller._unmarshal_partsc                 C   sV   |   D ]H\}}|dkr|n|| }|jr0|jn||j }||j||j|j qdS )zAdd a relationship to the source object corresponding to each of the
        relationships in `pkg_reader` with its target_part set to the actual target part
        in `parts`./N)Z
iter_srelsr   Z
target_refZtarget_partnamer+   r(   r*   )r>   r?   rB   Z
source_uriZsrelr   r)   r   r   r   rP      s
    z%Unmarshaller._unmarshal_relationshipsN)rH   rI   rJ   rK   staticmethodr;   rO   rP   r   r   r   r   r:      s   

r:   N)rK   Zdocx.opc.constantsr   r-   Zdocx.opc.packurir   r   Zdocx.opc.partr   Zdocx.opc.parts.corepropsr   Zdocx.opc.pkgreaderr   Zdocx.opc.pkgwriterr   Zdocx.opc.relr	   Zdocx.opc.sharedr
   r   r:   r   r   r   r   <module>   s    