U
    –BÞbº]  ã                   @   s<  d dl mZmZmZ d dlmZmZmZmZm	Z	m
Z
mZmZ ddlmZ ddlmZ ddlmZ ddlmZmZmZ ddlmZ dd	lmZ dd
lmZ ddlmZmZ ddlm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z* ddl+m,Z,m-Z- ddl.m/Z/m0Z0m1Z1m2Z2m3Z3 dZ4G dd„ dƒZ5G dd„ dƒZ6G dd„ de6ƒZ7dS )é    )ÚBytesIOÚFileIOÚIOBase)ÚAnyÚDictÚIterableÚListÚOptionalÚTupleÚUnionÚcasté   )Ú
Encryption)Ú
PageObject)Ú	PdfReader)ÚStrByteTypeÚdeprecate_with_replacementÚstr_)Ú	PdfWriter)ÚGoToActionArguments)ÚPagesAttributes)ÚTypArgumentsÚTypFitArguments)ÚArrayObjectÚBookmarkÚDestinationÚDictionaryObjectÚFloatObjectÚIndirectObjectÚ
NameObjectÚ
NullObjectÚNumberObjectÚTextStringObjectÚ
TreeObject)Ú	PageRangeÚPageRangeSpec)ÚFitTypeÚ
LayoutTypeÚOutlinesTypeÚPagemodeTypeÚZoomArgTypez=close() was called and thus the writer cannot be used anymorec                   @   s$   e Zd ZdZeeeddœdd„ZdS )Ú_MergedPagez@Collect necessary information on each page that is being merged.N)ÚpagedataÚsrcÚidÚreturnc                 C   s   || _ || _d | _|| _d S )N)r-   r,   Úout_pagedatar.   )Úselfr,   r-   r.   © r2   ú2/tmp/pip-unpacked-wheel-weujb6sz/PyPDF2/_merger.pyÚ__init__=   s    z_MergedPage.__init__)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   Úintr4   r2   r2   r2   r3   r+   :   s   r+   c                   @   sò  e Zd ZdZdGeddœdd„ZdHeeee	f e
e e
e eddœd	d
„Zeee	f eeee
e f dœdd„ZdIeee	f e
e edeeeef eeeef f eddœdd„Zeddœdd„Zddœdd„Zeeef ddœdd„Zeeef ddœdd„Zeddœdd„Zeddœdd„Zedd œd!d"„Zedd œd#d$„Ze	eeeeef f eeeef eeeef f e eeef  d%œd&d'„Z!e	e"eeeef eeeef f e"d(œd)d*„Z#ddœd+d,„Z$dJe
e%e&  e
e' dd-œd.d/„Z(ee&e)f e*dd0œd1d2„Z+e e* dd3œd4d5„Z,dKe e* e
e%e&  dd6œd7d8„Z-dLeeef e
e" e
e e  d9œd:d;„Z.dMeeede'e/f e
ee0e0e0f  eee1e2e/d=œ	d>d?„Z3dNeeede'e/f e
ee0e0e0f  eee1e2e/d=œ	d@dA„Z4eeddBœdCdD„Z5eeddBœdEdF„Z6dS )OÚ	PdfMergeraé  
    Initialize a ``PdfMerger`` object.

    ``PdfMerger`` merges multiple PDFs into a single PDF.
    It can concatenate, slice, insert, or any combination of the above.

    See the functions :meth:`merge()<merge>` (or :meth:`append()<append>`)
    and :meth:`write()<write>` for usage information.

    :param bool strict: Determines whether user should be warned of all
            problems and also causes some correctable problems to be fatal.
            Defaults to ``False``.
    FN)Ústrictr/   c                 C   s0   g | _ g | _tƒ | _g | _g | _d| _|| _d S )Nr   )ÚinputsÚpagesr   ÚoutputÚ	bookmarksÚnamed_destsÚid_countr;   )r1   r;   r2   r2   r3   r4   S   s    zPdfMerger.__init__T)ÚpositionÚfileobjÚbookmarkr=   Úimport_bookmarksr/   c                 C   sr  |   |¡\}}}t|| jd�}	| j ||	|f¡ |dk	r>||	_|dkrVdt|	jƒf}n.t|t	ƒrr| 
t|	jƒ¡}nt|tƒs„tdƒ‚g }
g }|r¤|	j}|  |	||¡}|rØtt|ƒt| jƒttjƒƒ}|  j||g7  _n|  j|7  _|	j}|  |	||¡}|  j|7  _t|Ž D ]:}|	j| }| j}|  jd7  _t||	|ƒ}|
 |¡ �q|  |
¡ |  |
¡ |
| j||…< dS )a  
        Merge the pages from the given file into the output file at the
        specified page number.

        :param int position: The *page number* to insert this file. File will
            be inserted after the given number.

        :param fileobj: A File Object or an object that supports the standard
            read and seek methods similar to a File Object. Could also be a
            string representing a path to a PDF file.

        :param str bookmark: Optionally, you may specify a bookmark to be
            applied at the beginning of the included file by supplying the text
            of the bookmark.

        :param pages: can be a :class:`PageRange<PyPDF2.pagerange.PageRange>`
            or a ``(start, stop[, step])`` tuple
            to merge only the specified range of pages from the source
            document into the output document.

        :param bool import_bookmarks: You may prevent the source document's
            bookmarks from being imported by specifying this as ``False``.
        )r;   Nr   z0"pages" must be a tuple of (start, stop[, step])r   )Ú_create_streamr   r;   r<   ÚappendÚ_encryptionÚlenr=   Ú
isinstancer$   ÚindicesÚtupleÚ	TypeErrorZoutlinesÚ_trim_outliner   r"   r!   rA   r   r   ZFITr?   Znamed_destinationsÚ_trim_destsr@   Úranger+   Ú_associate_dests_to_pagesÚ_associate_bookmarks_to_pages)r1   rB   rC   rD   r=   rE   ÚstreamÚmy_fileÚencryption_objÚreaderZsrcpagesÚoutlineZbookmark_typÚdestsZtrimmed_destsÚiÚpager.   Úmpr2   r2   r3   Úmerge\   sH    

ý


zPdfMerger.merge)rC   r/   c                 C   s°   d}d }t |tƒr"t|dƒ}d}n„t |tƒrn|jr8|j}|j ¡ }|j d¡ t|j 	¡ ƒ}|j |¡ d}n8t
|dƒr¢t
|dƒr¢| d¡ | 	¡ }t|ƒ}d}n|}|||fS )NFÚrbTr   ÚseekÚread)rJ   Ústrr   r   rH   rS   Útellr^   r   r_   Úhasattr)r1   rC   rT   rU   rS   Z	orig_tellZfilecontentr2   r2   r3   rF   ²   s(    




zPdfMerger._create_stream)rC   rD   r=   rE   r/   c                 C   s   |   t| jƒ||||¡ dS )aÑ  
        Identical to the :meth:`merge()<merge>` method, but assumes you want to
        concatenate all pages onto the end of the file instead of specifying a
        position.

        :param fileobj: A File Object or an object that supports the standard
            read and seek methods similar to a File Object. Could also be a
            string representing a path to a PDF file.

        :param str bookmark: Optionally, you may specify a bookmark to be
            applied at the beginning of the included file by supplying the text
            of the bookmark.

        :param pages: can be a :class:`PageRange<PyPDF2.pagerange.PageRange>`
            or a ``(start, stop[, step])`` tuple
            to merge only the specified range of pages from the source
            document into the output document.

        :param bool import_bookmarks: You may prevent the source document's
            bookmarks from being imported by specifying this as ``False``.
        N)r\   rI   r=   )r1   rC   rD   r=   rE   r2   r2   r3   rG   Ø   s    zPdfMerger.appendc                 C   sª   | j dkrttƒ‚d}t|tƒr.t|dƒ}d}| jD ]H}| j  |j¡ t	t
ttf | j j ¡ ƒ}| j  |tj d  ¡ ¡|_q4|  ¡  |  ¡  | j  |¡ |r¦| ¡  dS )z´
        Write all data that has been merged to the given output file.

        :param fileobj: Output file. Can be a filename or any kind of
            file-like object.
        NFÚwbTéÿÿÿÿ)r>   ÚRuntimeErrorÚERR_CLOSED_WRITERrJ   r`   r   r=   Zadd_pager,   r   r   r   Z_pagesÚ
get_objectZget_referenceÚPAZKIDSr0   Ú_write_destsÚ_write_bookmarksÚwriteÚclose)r1   rC   rT   rZ   Z	pages_objr2   r2   r3   rk   ö   s"    



ÿzPdfMerger.write)r/   c                 C   s4   g | _ | jD ]\}}}|r| ¡  qg | _d| _dS )zHShut all file descriptors (input and output) and clear all memory usage.N)r=   r<   rl   r>   )r1   ÚfoÚ_readerZminer2   r2   r3   rl     s    
zPdfMerger.close)Úinfosr/   c                 C   s"   | j dkrttƒ‚| j  |¡ dS )zá
        Add custom metadata to the output.

        :param dict infos: a Python dictionary where each key is a field
            and each value is your new metadata.
            Example: ``{u'/Title': u'My title'}``
        N)r>   re   rf   Úadd_metadata©r1   ro   r2   r2   r3   rp   $  s    
zPdfMerger.add_metadatac                 C   s   t ddƒ |  |¡ dS )zW
        .. deprecated:: 1.28.0

            Use :meth:`add_metadata` instead.
        ÚaddMetadatarp   N)r   rp   rq   r2   r2   r3   rr   0  s    
zPdfMerger.addMetadata)Úlayoutr/   c                 C   s   t ddƒ |  |¡ dS )zZ
        .. deprecated:: 1.28.0

            Use :meth:`set_page_layout` instead.
        ÚsetPageLayoutÚset_page_layoutN)r   ru   ©r1   rs   r2   r2   r3   rt   9  s    
zPdfMerger.setPageLayoutc                 C   s"   | j dkrttƒ‚| j  |¡ dS )a  
        Set the page layout.

        :param str layout: The page layout to be used

        .. list-table:: Valid ``layout`` arguments
           :widths: 50 200

           * - /NoLayout
             - Layout explicitly not specified
           * - /SinglePage
             - Show one page at a time
           * - /OneColumn
             - Show one column at a time
           * - /TwoColumnLeft
             - Show pages in two columns, odd-numbered pages on the left
           * - /TwoColumnRight
             - Show pages in two columns, odd-numbered pages on the right
           * - /TwoPageLeft
             - Show two pages at a time, odd-numbered pages on the left
           * - /TwoPageRight
             - Show two pages at a time, odd-numbered pages on the right
        N)r>   re   rf   Z_set_page_layoutrv   r2   r2   r3   ru   B  s    
zPdfMerger.set_page_layout)Úmoder/   c                 C   s   t ddƒ |  |¡ dS )zX
        .. deprecated:: 1.28.0

            Use :meth:`set_page_mode` instead.
        ÚsetPageModeÚset_page_modeN)r   ry   ©r1   rw   r2   r2   r3   rx   ^  s    
zPdfMerger.setPageModec                 C   s"   | j dkrttƒ‚| j  |¡ dS )aR  
        Set the page mode.

        :param str mode: The page mode to use.

        .. list-table:: Valid ``mode`` arguments
           :widths: 50 200

           * - /UseNone
             - Do not show outlines or thumbnails panels
           * - /UseOutlines
             - Show outlines (aka bookmarks) panel
           * - /UseThumbs
             - Show page thumbnails panel
           * - /FullScreen
             - Fullscreen view
           * - /UseOC
             - Show Optional Content Group (OCG) panel
           * - /UseAttachments
             - Show attachments panel
        N)r>   re   rf   ry   rz   r2   r2   r3   ry   g  s    
zPdfMerger.set_page_mode)ÚpdfrX   r=   r/   c                 C   s|   g }|  ¡ D ]j\}}t|Ž D ]X}|j|  ¡ |d  ¡ kr|d  ¡ |tdƒ< t|ƒt|d ƒksft‚| |¡  qqq|S )zHRemove named destinations that are not a part of the specified page set.ú/Pageú/Title)ÚitemsrP   r=   rg   r   r   ÚAssertionErrorrG   )r1   r{   rX   r=   Z	new_destsÚkeyÚobjÚjr2   r2   r3   rO   �  s    
zPdfMerger._trim_dests)r{   rW   r=   r/   c           
      C   s¼   g }d}t |ƒD ]¦\}}t|tƒrV|  |||¡}|r¶|sJ| ||d  ¡ | |¡ qd}t|Ž D ]R}	|d dkrtqb|j|	  ¡ |d  ¡ krb|d  ¡ |tdƒ< | |¡ d} qqbq|S )zNRemove outline/bookmark entries that are not a part of the specified page set.Tr   Fr|   N)	Ú	enumeraterJ   ÚlistrN   rG   rP   r=   rg   r   )
r1   r{   rW   r=   Znew_outlineZprev_header_addedrY   ÚoÚsubr‚   r2   r2   r3   rN   ’  s&    

zPdfMerger._trim_outlinec                 C   sv   | j d krttƒ‚| jD ]X}d }d|kr\t| jƒD ](\}}|j|d kr2|j|tdƒ<  q\q2|d k	r| j  	|¡ qd S )Nr|   )
r>   re   rf   r@   rƒ   r=   r.   r0   r   Zadd_named_destination_object)r1   Z
named_destÚpagenorZ   r2   r2   r3   ri   ®  s    

zPdfMerger._write_dests)r?   Úparentr/   c                 C   sº   | j d krttƒ‚|d kr | j}|d k	s0tdƒ‚d }|D ]|}t|tƒrT|  ||¡ q8d }d|kr’t| j	ƒD ]&\}}|j
|d krj|  ||¡  q’qj|d k	r8|d= |d= | j  ||¡}q8d S )Núhint for mypyr|   ú/Type)r>   re   rf   r?   r   rJ   r„   rj   rƒ   r=   r.   Ú_write_bookmark_on_pageZadd_bookmark_dict)r1   r?   rˆ   Z
last_addedrD   Zpage_norZ   r2   r2   r3   rj   ¼  s&    

zPdfMerger._write_bookmarks)rD   rZ   r/   c                 C   sô   t t|d ƒ}t|jƒt|ƒg}tjtjftj	tjftj
tjftjtjftjtjtjdftjtjtjtjtjfi}| |tƒ ¡D ]B}||kr®t|| tƒs®| t|| ƒ¡ n| tdƒ¡ ||= q€tttjƒtdƒttjƒt|ƒiƒ|tdƒ< d S )NrŠ   z/Zoomr   z/GoToz/A)r   r`   r!   r.   r   r   ÚFIT_Hr   ZTOPZFIT_BHZFIT_VÚLEFTZFIT_BVZXYZZFIT_RZBOTTOMÚRIGHTÚgetrL   rJ   r    rG   r   r   r   ÚSÚDr   )r1   rD   rZ   Zbm_typeÚargsZfit2arg_keysZarg_keyr2   r2   r3   r‹   ×  s>         üú  þÿz!PdfMerger._write_bookmark_on_page)r=   r/   c                 C   sx   | j D ]l}d }|d }t|tƒr"q|D ]}| ¡ |j ¡ kr&|j}q&|d k	r^t|ƒ|tdƒ< qtd|d › d�ƒ‚qd S )Nr|   zUnresolved named destination 'r}   ú')r@   rJ   r!   rg   r,   r.   r   Ú
ValueError)r1   r=   Zndr‡   ÚnpÚpr2   r2   r3   rQ   ÷  s    

z#PdfMerger._associate_dests_to_pages)r=   r?   r/   c                 C   s–   |d kr| j }|d k	stdƒ‚|D ]n}t|tƒr>|  ||¡ q"d }|d }t|tƒrVq"|D ]}| ¡ |j ¡ krZ|j}qZ|d k	r"t|ƒ|t	dƒ< q"d S )Nr‰   r|   )
r?   r   rJ   r„   rR   r!   rg   r,   r.   r   )r1   r=   r?   Úbr‡   Zbpr–   r2   r2   r3   rR     s     

z'PdfMerger._associate_bookmarks_to_pages)rD   Úrootr/   c                 C   sl   |d kr| j }t|ƒD ]P\}}t|tƒrH|  ||¡}|rf|g|   S q||ks\|d |kr|g  S qd S )Nr}   )r?   rƒ   rJ   r„   Úfind_bookmark)r1   rD   r˜   rY   r—   Úresr2   r2   r3   r™      s    
zPdfMerger.find_bookmarkú/Fit)	ÚtitleÚpagenumrˆ   ÚcolorÚboldÚitalicÚfitr’   r/   c           	      G   s&   t ddƒ | j|||||||f|žŽ S )zV
        .. deprecated:: 1.28.0
            Use :meth:`add_bookmark` instead.
        ÚaddBookmarkÚadd_bookmark)r   r£   )	r1   rœ   r�   rˆ   rž   rŸ   r    r¡   r’   r2   r2   r3   r¢   5  s    
      ÿÿzPdfMerger.addBookmarkc           
      G   s2   | j }	|	dkrttƒ‚|	j|||||||f|žŽ S )aG  
        Add a bookmark to this PDF file.

        :param str title: Title to use for this bookmark.
        :param int pagenum: Page number this bookmark will point to.
        :param parent: A reference to a parent bookmark to create nested
            bookmarks.
        :param tuple color: Color of the bookmark as a red, green, blue tuple
            from 0.0 to 1.0
        :param bool bold: Bookmark is bold
        :param bool italic: Bookmark is italic
        :param str fit: The fit of the destination page. See
            :meth:`addLink()<addLink>` for details.
        N)r>   re   rf   r£   )
r1   rœ   r�   rˆ   rž   rŸ   r    r¡   r’   Úwriterr2   r2   r3   r£   I  s          ÿÿzPdfMerger.add_bookmark)rœ   r�   r/   c                 C   s   t ddƒ |  ||¡S )z_
        .. deprecated:: 1.28.0
            Use :meth:`add_named_destination` instead.
        ÚaddNamedDestinationÚadd_named_destination)r   r¦   )r1   rœ   r�   r2   r2   r3   r¥   i  s    
zPdfMerger.addNamedDestinationc                 C   s0   t t|ƒt|ƒttjƒtdƒƒ}| j |¡ dS )zž
        Add a destination to the output.

        :param str title: Title to use
        :param int pagenum: Page number this destination points at.
        i:  N)r   r"   r!   r   r   rŒ   r@   rG   )r1   rœ   r�   Údestr2   r2   r3   r¦   q  s    üzPdfMerger.add_named_destination)F)NNT)NNT)NN)N)N)NNFFr›   )NNFFr›   )7r5   r6   r7   r8   Úboolr4   r9   r   r   r   r	   r`   r%   r\   r
   r   r   rF   r$   rG   rk   rl   r   r   rp   rr   r'   rt   ru   r)   rx   ry   r   rO   r(   rN   ri   r   r   r#   rj   r   r+   r‹   rQ   rR   r™   r   Úfloatr&   r*   r¢   r£   r¥   r¦   r2   r2   r2   r3   r:   D   sÎ      ú
ùW
þ)   û
 ú$
			ûû  ý
ü
 þ  ÿ 
þ ý

ü     øö     øö r:   c                       s&   e Zd Zeeddœ‡ fdd„Z‡  ZS )ÚPdfFileMergerN)r’   Úkwargsr/   c                    s8   t ddƒ d|kr&t|ƒdk r&d|d< tƒ j||Ž d S )Nrª   ZPdfMerger;   r   T)r   rI   Úsuperr4   )r1   r’   r«   ©Ú	__class__r2   r3   r4   ‚  s    
zPdfFileMerger.__init__)r5   r6   r7   r   r4   Ú__classcell__r2   r2   r­   r3   rª   �  s   rª   N)8Úior   r   r   Útypingr   r   r   r   r	   r
   r   r   rH   r   Z_pager   rn   r   Ú_utilsr   r   r   Z_writerr   Ú	constantsr   r   rh   r   r   Zgenericr   r   r   r   r   r   r   r    r!   r"   r#   Z	pageranger$   r%   Útypesr&   r'   r(   r)   r*   rf   r+   r:   rª   r2   r2   r2   r3   Ú<module>   s(   (4
    A