o
    Fzc2                     @   s  d dl 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
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 dejv ZedZer[eefZnee	jfZG d	d
 d
e
jZ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#Z'G dd de#Z(G dd de#Z)G dd dZ*G dd dZ+dd  Z,d!d" Z-dS )#    N)BytesIO)Path)request)unquote)
httpConfigzgoogle.appengineZ	xhtml2pdfc                   @   s    e Zd Zg Zdd Zdd ZdS )TmpFilesc                 C   s   | j | d S N)filesappendselffile r   /xhtml2pdf/files.pyr
   "   s   zTmpFiles.appendc                 C   s"   | j D ]}|  q| j   d S r   )r	   closeclearr   r   r   r   
cleanFiles%   s   

zTmpFiles.cleanFilesN)__name__
__module____qualname__r	   r
   r   r   r   r   r   r      s    r   c                   @   sV   e Zd ZdZeZdZdefddZdd Zdd	 Zd
d Z	dd Z
dd Zdd ZdS )pisaTempFileaW  
    A temporary file implementation that uses memory unless
    either capacity is breached or fileno is requested, at which
    point a real temporary file will be created and the relevant
    details returned
    If capacity is -1 the second strategy will never be used.
    Inspired by:
    http://code.activestate.com/recipes/496744/
    i (   c                 C   sn   d| _ || _tt|| jk| _z
| j| j  | _W n ty*   | jd  | _Y nw | | | 	d dS )zCreates a TempFile object containing the specified buffer.
        If capacity is specified, we use a real temporary file once the
        file gets larger than that size.  Otherwise, the data is stored
        in memory.
        Nr   )
namecapacityintlenstrategy
STRATEGIES	_delegate
IndexErrorwriteseek)r   bufferr   r   r   r   __init__=   s   
zpisaTempFile.__init__c                 C   s\   | j dkr,z| jd  }||   || _d| _ td| j W dS    d| _Y dS dS )zd
        Switch to next startegy. If an error occured,
        stay with the first strategy
        r      zCreated temporary file %sN)	r   r   r    getvaluer   logwarningr   r   )r   Znew_delegater   r   r   makeTempFileO   s   
zpisaTempFile.makeTempFilec                 C   s   |    | jS )z,
        Get a named temporary file
        N)r)   r   r   r   r   r   getFileName_   s   zpisaTempFile.getFileNamec                 C   s   |    | j S )z
        Forces this buffer to use a temporary file as the underlying.
        object and returns the fileno associated with it.
        N)r)   r   filenor*   r   r   r   r,   g   s   
zpisaTempFile.filenoc                 C   sL   | j dkr
| j S | j  | jd | j }t|ts$|d}|S )zb
        Get value of file. Work around for second strategy.
        Always returns bytes
        r   utf-8N)	r   r   r&   flushr!   read
isinstancebytesencode)r   valuer   r   r   r&   o   s   





zpisaTempFile.getvaluec                 C   sz   | j dkr+| jdkr+t|}|| j krd}n| dd |  | | j k}|r+|   t|ts5|d}| j	
| dS )zV
        If capacity != -1 and length of file > capacity it is time to switch
        r   T   r-   N)r   r   r   r!   tellr)   r0   r1   r2   r   r    )r   r3   Z	len_valueZneeds_new_strategyr   r   r   r    ~   s   


zpisaTempFile.writec                 C   s6   zt | j|W S  ty   d| jj|f }t|w )Nz!object '%s' has no attribute '%s')getattrr   AttributeError	__class__r   )r   r   er   r   r   __getattr__   s   
zpisaTempFile.__getattr__N)r   r   r   __doc__r   ZCAPACITYr#   r)   r+   r,   r&   r    r:   r   r   r   r   r   .   s    
r   c                   @   s4   e Zd Zdd Zdd Zdd Zdd Zd	d
 ZdS )BaseFilec                 C   s"   || _ || _d | _d | _d | _d S r   pathbasepathmimetypesuffixurir   r>   r?   r   r   r   r#      
   
zBaseFile.__init__c                 C      | j S r   )rB   r*   r   r   r   get_uri      zBaseFile.get_uric                 C   rE   r   )r@   r*   r   r   r   get_mimetype   rG   zBaseFile.get_mimetypec                 C   sL   |   }tj| jd}|r|| |  t| | jd u r$|j	| _|S )N)rA   )
get_datatempfileNamedTemporaryFilerA   r    r.   	files_tmpr
   r>   r   )r   datatmp_filer   r   r   get_named_tmp_file   s   


zBaseFile.get_named_tmp_filec                 C   s   |   }|r
t|S d S r   )rI   r   )r   rM   r   r   r   get_BytesIO   s   zBaseFile.get_BytesION)r   r   r   r#   rF   rH   rO   rP   r   r   r   r   r<      s    r<   c                   @   s0   e Zd ZedejejB Zdd Zdd Z	dS )B64InlineURIz2^data:(?P<mime>[a-z]+/[a-z]+);base64,(?P<data>.*)$c              
   C   <   z|   W S  ty } ztd W Y d }~d S d }~ww )NzExtract data form data: in tagextract_data	Exceptionr'   errorr   r9   r   r   r   rI         
zB64InlineURI.get_datac                 C   s~   | j | j}|d| _t|d}|dd }t	dd|}t	dd|}|dd	t
|d	  d	  7 }t|S )
NmimerM   zb''s   \n    s   [^A-Za-z0-9\+\/]+   =   )_rx_dataurimatchr>   groupr@   urllib_unquotestripr2   resubr   base64	b64decode)r   mZb64r   r   r   rT      s   
zB64InlineURI.extract_dataN)
r   r   r   rc   compileMDOTALLr^   rI   rT   r   r   r   r   rQ      s    rQ   c                   @   s   e Zd Zdd Zdd ZdS )LocalProtocolURIc              
   C   rR   )Nz.Extract data form local file based on protocolrS   rW   r   r   r   rI      rX   zLocalProtocolURI.get_datac                 C   s`   | j r,| jdr.t| j | jdd  }t|}| dd	dd | _
| S d S d S )N/r$   Content-Typer   ;r   )r?   r>   
startswithurlparseurljoinr   Zurlopeninfogetsplitr@   r/   )r   rB   ZurlResponser   r   r   rT      s   
zLocalProtocolURI.extract_dataN)r   r   r   rI   rT   r   r   r   r   rk      s    rk   c                       s4   e Zd Z fddZdd Zdd Zdd Z  ZS )	NetworkFileUric                    s   t  || d| _d| _d S )N   r   )superr#   attemptsactual_attemptsrC   r8   r   r   r#      s   
zNetworkFileUri.__init__c              
   C   s   d }| j | jkr>|d u r>|  jd7  _z|  }W n ty3 } ztd| j  W Y d }~nd }~ww | j | jkr>|d u s|S )Nr$   zExtract data remote trying %d)rx   ry   rT   rU   r'   rV   )r   rM   r9   r   r   r   rI      s   zNetworkFileUri.get_datac           	      C   s   t d| d d\}}t|}|d }|d }||d r%d|d  nd7 }|d	r7tj|fi t}nt|}|	d
| |
 }|j|jfdkrk|dddd | _| }|ddkrgd}||fS t d|j d|j  ||fS )NzSending request for z with httplib)NFr$   r4   rv   ?r   zhttps://ZGET)   ZOKrm   rn   r   zcontent-encodinggzipTzReceived non-200 status:  )r'   debugrp   urlsplitro   httplibZHTTPSConnectionr   ZHTTPConnectionr   Zgetresponsestatusreason	getheaderrt   r@   r/   )	r   rB   rM   is_gzipZurl_splittedserverr>   ZconnZr1r   r   r   get_httplib   s.   


zNetworkFileUri.get_httplibc                 C   sh   | j r| jdst| j | j}n| j}|| _| |\}}|r*tjdt	|d}t
d| |S )Nhttprb)modefileobjzUri parsed: {})r?   r>   ro   rp   rq   rB   r   r}   ZGzipFiler   r'   r   format)r   rB   rM   r   r   r   r   rT     s   zNetworkFileUri.extract_data)r   r   r   r#   rI   r   rT   __classcell__r   r   rz   r   ru      s
    ru   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )LocalFileURIc              
   C   rR   )NzExtract data form local filerS   rW   r   r   r   rI   "  rX   zLocalFileURI.get_datac                 C   s:   t t|d }|durt t|d dd }|S )z Guess the mime type r   Nrn   )	mimetypesZ
guess_typestrrt   )r   r   r@   r   r   r   guess_mimetype(  s   zLocalFileURI.guess_mimetypec                 C   s   d }t d t| j}d }| jd urt| j| }ntd| }| r+| s+|}| r{|| _|j| _| 	|| _
| j
ra| j
drat|d}| }W d    |S 1 sZw   Y  |S t|d}| }W d    |S 1 svw   Y  |S )Nz-Unrecognized scheme, assuming local file path.textrr   )r'   r   r   r>   r?   existsis_filerB   rA   r   r@   ro   openr/   )r   rM   r>   rB   Zfile_handlerr   r   r   rT   /  s4   






zLocalFileURI.extract_dataN)r   r   r   rI   r   rT   r   r   r   r   r   !  s    r   c                   @   s   e Zd Zdd ZdS )BytesFileUric                 C   rE   r   )r>   r*   r   r   r   rI   J  rG   zBytesFileUri.get_dataN)r   r   r   rI   r   r   r   r   r   I  s    r   c                       s,   e Zd Zdd Z fddZdd Z  ZS )LocalTmpFilec                 C   s"   || _ d | _|| _d | _d | _d S r   r=   rC   r   r   r   r#   P  rD   zLocalTmpFile.__init__c                    s    t   }| jd u r|j| _|S r   )rw   rO   r>   r   )r   rN   rz   r   r   rO   W  s   

zLocalTmpFile.get_named_tmp_filec                 C   sF   | j d u rd S t| j d}| W  d    S 1 sw   Y  d S )Nr   )r>   r   r/   )r   archr   r   r   rI   ]  s
   
$zLocalTmpFile.get_data)r   r   r   r#   rO   rI   r   r   r   rz   r   r   N  s    r   c                   @   s   e Zd ZedddZdS )FileNetworkManagerNc                 C   s   | d u rt | |}|S t| trt| |}|S | dr#t| |}|S |r1t| js1t|}nt| }t	d
||jf |jdkrMt| |}|S |jdv rYt| |}|S t| |}|S )Nzdata:zURLParts: {}r   )r   https)r   r0   r1   r   ro   rQ   rp   schemer'   r   r   rk   ru   r   )rB   r?   instanceZurlPartsr   r   r   get_managere  s*   










zFileNetworkManager.get_managerr   )r   r   r   staticmethodr   r   r   r   r   r   d  s    r   c                   @   sV   e Z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S )pisaFileObjectNc                 C   sZ   || _ d }|d ur|||}|d urd | _|}n|| _td|| tj|| jd| _d S )NzFileObject %r, Basepath: %r)r?   )rB   r?   r'   r   r   r   r   )r   rB   r?   callbackZbasepathretr   r   r   r#     s   
zpisaFileObject.__init__c                 C   
   | j  S r   r   rI   r*   r   r   r   getFileContent     
zpisaFileObject.getFileContentc                 C   s   | j  }|r
|jS d S r   )r   rO   r   )r   fr   r   r   getNamedFile  s   
zpisaFileObject.getNamedFilec                 C   r   r   r   r*   r   r   r   getData  r   zpisaFileObject.getDatac                 C   s   t r| j S | j S r   )GAEr   rP   rO   r*   r   r   r   getFile  s   

zpisaFileObject.getFilec                 C   r   r   )r   rH   r*   r   r   r   getMimeType  r   zpisaFileObject.getMimeTypec                 C   s   |   d u S r   )r   r*   r   r   r   notFound     zpisaFileObject.notFoundc                 C   r   r   )r   rF   r*   r   r   r   
getAbsPath  r   zpisaFileObject.getAbsPathc                 C   r   r   )r   rP   r*   r   r   r   
getBytesIO  r   zpisaFileObject.getBytesIO)NN)r   r   r   r#   r   r   r   r   r   r   r   r   r   r   r   r   r   ~  s    
r   c                  O   s   t | i |S r   )r   )akwr   r   r   r     s   r   c                   C   s   t   d S r   )rL   r   r   r   r   r   r     r   r   ).re   r}   Zhttp.clientZclientr   loggingr   rc   sysrJ   	threadingurllib.parseparserp   ior   pathlibr   urllibr   r   ra   Zxhtml2pdf.config.httpconfigr   modulesr   	getLoggerr'   r   rK   localr   rL   objectr   r<   rQ   rk   ru   r   r   r   r   r   r   r   r   r   r   r   <module>   sL    

o 7(/