o
    œœ<W‹S  ã                   @   sª   d dl T d dlmZmZ d dlmZmZ d dlmZ ddl	m
Z
 e
dk r-ddlmZ eZndd	lmZ dd
lmZ eZG dd„ deƒZG dd„ deƒZG dd„ deƒZdS )é   )Ú*)ÚisStringÚstr_)ÚPdfFileReaderÚPdfFileWriter)Ú	PageRangeé    )Úversion_info)é   r   )ÚStringIO)ÚBytesIO)ÚFileIOc                   @   s   e Zd ZdZdd„ ZdS )Ú_MergedPagez�
    _MergedPage is used internally by PdfFileMerger to collect necessary
    information on each page that is being merged.
    c                 C   s   || _ || _d | _|| _d S ©N)ÚsrcÚpagedataÚout_pagedataÚid)Úselfr   r   r   © r   ú?/var/www/html/env/lib/python3.10/site-packages/PyPDF2/merger.pyÚ__init__1   s   
z_MergedPage.__init__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r   ,   s    r   c                   @   s¦   e Zd ZdZd&dd„Zd'dd„Zd'dd	„Zd
d„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zd(dd„Zdd„ Zd)dd„Zd)d d!„Zd)d"d#„Zd$d%„ ZdS )*ÚPdfFileMergeraè  
    Initializes a PdfFileMerger object. PdfFileMerger 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 ``True``.
    Tc                 C   s0   g | _ g | _tƒ | _g | _g | _d| _|| _d S )Nr   )ÚinputsÚpagesr   ÚoutputÚ	bookmarksÚnamed_destsÚid_countÚstrict)r   r#   r   r   r   r   F   s   
zPdfFileMerger.__init__Nc                 C   sü  d}d}t |ƒrt|dƒ}d}n>t|tƒr%| d¡ | ¡ }t|ƒ}d}n)t|tƒrN|j ¡ }	|j d¡ t|j ¡ ƒ}|j |	¡ |}t	|dƒrL|j
}d}t|| jd�}
|dur\||
_
|dkrgd|
 ¡ f}nt|tƒrt| |
 ¡ ¡}n	t|tƒs}tdƒ‚g }|rŽtt|ƒt| jƒtd	ƒƒ}g }|r�|
 ¡ }|  |
||¡}|r©|  j||g7  _n|  j|7  _|
j}|  |
||¡}|  j|7  _t|Ž D ]}|
 |¡}| j}|  jd
7  _t||
|ƒ}| |¡ qÅ|   |¡ |  !|¡ || j"||…< | j# ||
|f¡ dS )aß  
        Merges 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 :ref:`Page Range <page-range>` 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``.
        FNÚrbTr   Ú_decryption_key)r#   z0"pages" must be a tuple of (start, stop[, step])z/Fitr   )$r   ÚfileÚ
isinstanceÚseekÚreadÚStreamIOr   ÚstreamÚtellÚhasattrr%   r#   ÚgetNumPagesr   ÚindicesÚtupleÚ	TypeErrorÚBookmarkÚTextStringObjectÚNumberObjectr"   Ú
NameObjectÚgetOutlinesÚ_trim_outliner    ÚnamedDestinationsÚ_trim_destsr!   ÚrangeÚgetPager   ÚappendÚ_associate_dests_to_pagesÚ_associate_bookmarks_to_pagesr   r   )r   ÚpositionÚfileobjÚbookmarkr   Úimport_bookmarksÚmy_fileÚdecryption_keyÚfilecontentÚ	orig_tellÚpdfrÚsrcpagesÚoutlineÚdestsÚiÚpgr   Úmpr   r   r   ÚmergeO   sf   










zPdfFileMerger.mergec                 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 :ref:`Page Range <page-range>` 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)rN   Úlenr   )r   r@   rA   r   rB   r   r   r   r<   ·   s   zPdfFileMerger.appendc                 C   s†   d}t |ƒrt|dƒ}d}| jD ]}| j |j¡ | j | jj ¡ d d  ¡ ¡|_	q|  
¡  |  ¡  | j |¡ |rA| ¡  dS dS )zµ
        Writes 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.
        FÚwbTú/KidséÿÿÿÿN)r   r&   r   r   ÚaddPager   ÚgetReferenceÚ_pagesÚ	getObjectr   Ú_write_destsÚ_write_bookmarksÚwriteÚclose)r   r@   rC   Úpager   r   r   rY   Í   s   

$ÿzPdfFileMerger.writec                 C   s4   g | _ | jD ]\}}}|r| ¡  qg | _d| _dS )zd
        Shuts all file descriptors (input and output) and clears all memory
        usage.
        N)r   r   rZ   r   )r   ÚforG   Úminer   r   r   rZ   ë   s   €
zPdfFileMerger.closec                 C   ó   | 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   ÚaddMetadata)r   Úinfosr   r   r   r_   ø   s   zPdfFileMerger.addMetadatac                 C   r^   )a„  
        Set the page layout

        :param str layout: The page layout to be used

        Valid layouts are:
             /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   ÚsetPageLayout)r   Úlayoutr   r   r   ra     s   zPdfFileMerger.setPageLayoutc                 C   r^   )aÔ  
        Set the page mode.

        :param str mode: The page mode to use.

        Valid modes are:
            /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   ÚsetPageMode)r   Úmoder   r   r   rc     s   zPdfFileMerger.setPageModec           	      C   s„   g }d}t | ¡ ƒD ]5\}}t|Ž D ],}| |¡ ¡ |d  ¡ kr>|d  ¡ |tdƒ< t|ƒt|d ƒks7J ‚| |¡  nqq
|S )zg
        Removes any named destinations that are not a part of the specified
        page set.
        Tú/Pageú/Title)ÚlistÚitemsr:   r;   rV   r5   r   r<   )	r   ÚpdfrJ   r   Ú	new_destsÚprev_header_addedÚkÚoÚjr   r   r   r9   #  s   
ü€zPdfFileMerger._trim_destsc           
      C   s®   g }d}t |ƒD ]L\}}t|tƒr+|  |||¡}|r*|s%| ||d  ¡ | |¡ qd}t|Ž D ]"}	| |	¡ ¡ |d  ¡ krS|d  ¡ |tdƒ< | |¡ d} nq1q|S )zm
        Removes any outline/bookmark entries that are not a part of the
        specified page set.
        Tr   Fre   )	Ú	enumerater'   rg   r7   r<   r:   r;   rV   r5   )
r   ri   rI   r   Únew_outlinerk   rK   rm   Úsubrn   r   r   r   r7   3  s(   

€
ü€zPdfFileMerger._trim_outlinec                 C   sv   | j }|D ]3}d }d }d|v r.t| jƒD ]\}}|j|d kr-|j|tdƒ< |}|j} nq|d kr8| j |¡ qd S )Nre   )	r!   ro   r   r   r   r5   r   r   ÚaddNamedDestinationObject)r   rJ   ÚvÚpagenori   rK   Úpr   r   r   rW   K  s    ü€õzPdfFileMerger._write_destsc           
      C   sr  |d kr| j }d }|D �]ª}t|tƒr|  ||¡ qd }d }d|v �r¤t| jƒD �]z\}}|j|d k�r£t|jƒt|d ƒg}	|d dksL|d dkrmd|v rat|d t	ƒsa|	 
t|d ƒ¡ n|	 
tdƒ¡ |d= �n|d dksy|d dkr™d	|v rŽt|d	 t	ƒsŽ|	 
t|d	 ƒ¡ n|	 
tdƒ¡ |d	= nï|d d
krýd	|v r´t|d	 t	ƒs´|	 
t|d	 ƒ¡ n|	 
tdƒ¡ d|v rÐt|d t	ƒsÐ|	 
t|d ƒ¡ n|	 
tdƒ¡ d|v rìt|d t	ƒsì|	 
t|d ƒ¡ n|	 
tdƒ¡ |d= |d= |d	= n‹|d dk�rˆd	|v �rt|d	 t	ƒ�s|	 
t|d	 ƒ¡ n|	 
tdƒ¡ d|v �r9t|d t	ƒ�s9|	 
t|d ƒ¡ n|	 
tdƒ¡ d|v �rWt|d t	ƒ�sW|	 
t|d ƒ¡ n|	 
tdƒ¡ d|v �rut|d t	ƒ�su|	 
t|d ƒ¡ n|	 
tdƒ¡ |d	= |d= |d= |d= ttdƒtdƒtdƒt|	ƒiƒ|tdƒ< |}|j} nq(|d k�r¶|d= |d= | j ||¡}qd S )Nre   z/Typeú/FitHz/FitBHz/Topr   z/FitVz/FitBVz/Leftz/XYZz/Zoomz/FitRz/Bottomz/Rightú/Sú/GoToú/Dú/A)r    r'   rg   rX   ro   r   r   r4   r5   Ú
NullObjectr<   ÚFloatObjectÚDictionaryObjectÚArrayObjectr   r   ÚaddBookmarkDict)
r   r    ÚparentÚ
last_addedÚbrt   ri   rK   ru   Úargsr   r   r   rX   [  st   



(Ê
7€¾zPdfFileMerger._write_bookmarksc                 C   st   | j D ]4}d }|d }t|tƒrq|D ]}| ¡ |j ¡ kr!|j}q|d kr/t|ƒ|tdƒ< qtd|d f ƒ‚d S )Nre   z!Unresolved named destination '%s'rf   )r!   r'   r4   rV   r   r   r5   Ú
ValueError)r   r   Úndrt   Únpru   r   r   r   r=   ¥  s   

€òz'PdfFileMerger._associate_dests_to_pagesc                 C   s˜   |d kr| j }|D ]@}t|tƒr|  ||¡ q	d }|d }t|tƒr#q	|D ]}| ¡ |j ¡ kr3|j}q%|d krAt|ƒ|tdƒ< q	t	d|d f ƒ‚d S )Nre   zUnresolved bookmark '%s'rf   )
r    r'   rg   r>   r4   rV   r   r   r5   r„   )r   r   r    r‚   rt   Úbpru   r   r   r   r>   ¶  s$   

€îz+PdfFileMerger._associate_bookmarks_to_pagesc                 C   sl   |d kr| j }t|ƒD ](\}}t|tƒr$|  ||¡}|r#|g|   S q||ks.|d |kr3|g  S qd S )Nrf   )r    ro   r'   rg   ÚfindBookmark)r   rA   ÚrootrK   r‚   Úresr   r   r   rˆ   Î  s   
ÿ
ÿzPdfFileMerger.findBookmarkc           	      C   sÔ   |dkrt | jƒd g}nt|tƒr|}n|  |¡}tt|ƒt|ƒtdƒtdƒƒ}|dkr5| j 	|¡ |S | j}|dd… D ]}|| }q>|d d }|t |ƒk rat|| tƒra||  	|¡ |S | 
||g¡ |S )a  
        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.
        Nr   rv   é:  rR   )rO   r    r'   rg   rˆ   r2   r3   r4   r5   r<   Úinsert)	r   ÚtitleÚpagenumr€   ÚilocÚdestÚbmparentrK   Únposr   r   r   ÚaddBookmarkÜ  s$   	


ø
ÿzPdfFileMerger.addBookmarkc                 C   s.   t t|ƒt|ƒtdƒ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.
        rv   r‹   N)ÚDestinationr3   r4   r5   r!   r<   )r   r�   rŽ   r�   r   r   r   ÚaddNamedDestinationû  s   z!PdfFileMerger.addNamedDestination)T)NNT)NNr   )r   r   r   r   r   rN   r<   rY   rZ   r_   ra   rc   r9   r7   rW   rX   r=   r>   rˆ   r“   r•   r   r   r   r   r   8   s&    

	
h

J


r   c                   @   s.   e Zd Zd
dd„Zdd„ Zdd„ Zdd	„ ZdS )ÚOutlinesObjectNc                 C   s    t  | ¡ || _|| _|| _d S r   )rg   r   Útreeri   r€   )r   ri   r—   r€   r   r   r   r     s   

zOutlinesObject.__init__c                 C   s   | | }| |= | j  |¡ d S r   )r—   ÚremoveChild)r   ÚindexÚobjr   r   r   Úremove  s   zOutlinesObject.removec                 C   sš   | j  | j j¡d | }tƒ }| tdƒt|tdƒtdƒgƒtdƒtdƒi¡ | j  |¡}t	ƒ }| tdƒ|tdƒt
|ƒi¡ | j  |¡ | j |¡ d S )	NrQ   ry   rv   r‹   rw   rx   rz   rf   )ri   rV   rU   r}   Úupdater5   r~   r4   Ú
_addObjectÚ
TreeObjectÚcreateStringObjectr—   ÚaddChild)r   r�   rŽ   ÚpageRefÚactionÚ	actionRefrA   r   r   r   Úadd  s   þþzOutlinesObject.addc                 C   s2   dd„ | j  ¡ D ƒD ]}| j  |¡ |  ¡  q
d S )Nc                 S   s   g | ]}|‘qS r   r   )Ú.0Úxr   r   r   Ú
<listcomp>'  s    z,OutlinesObject.removeAll.<locals>.<listcomp>)r—   Úchildrenr˜   Úpop)r   Úchildr   r   r   Ú	removeAll&  s   
þzOutlinesObject.removeAllr   )r   r   r   r   r›   r¤   r«   r   r   r   r   r–     s
    
r–   N)ÚgenericÚutilsr   r   ri   r   r   Ú	pageranger   Úsysr	   Ú	cStringIOr   r*   Úior   r   r&   Úobjectr   r   rg   r–   r   r   r   r   Ú<module>   s"      R