
    3vjF                     8   d 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Zddl	m
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mZmZmZ d	d
lmZ d	dlmZ  ej:                  d      Z ej:                  d      Z ej@                         Z!de dddZ" G d de      Z#d Z$d Z%d Z&d'dZ'd Z(d Z)d Z*d Z+	 	 d(dZ,ejZ                  	 	 d)d       Z. G d de/      Z0 G d  d!e1      Z2 G d" d#ejf                        Z4 G d$ d%      Z5ejZ                  d&        Z6y)*z9Various utility functions and classes for URL management.    N)EmailMessage)GzipFile)BytesIOStringIO)Path)request)quoteunquoteurljoinurlsplit   )__version__)LOGGERz^([a-zA-Z][a-zA-Z0-9.+-]+):s   ^([a-zA-Z][a-zA-Z0-9.+-]+):zWeasyPrint z*/*zgzip, deflate)z
User-AgentAcceptzAccept-Encodingc                       e Zd Zd Zd Zd Zy)StreamingGzipFilec                 @    t        j                  | |       || _        y )Nfileobj)r   __init__fileobj_to_close)selfr   s     B/root/.hermes/venv/lib/python3.12/site-packages/weasyprint/urls.pyr   zStreamingGzipFile.__init__$   s    $0 '    c                 b    t        j                  |        | j                  j                          y N)r   closer   r   s    r   r   zStreamingGzipFile.close(   s     t##%r   c                      y)NF r   s    r   seekablezStreamingGzipFile.seekable,   s    r   N)__name__
__module____qualname__r   r   r!   r    r   r   r   r   #   s    (&r   r   c                     | j                  d      r| S | j                  | j                  d      rt        nd      } t        | d      S )zDTurn a Unicode IRI into an ASCII-only URI that conforms to RFC 3986.zdata:file:utf-8s   /:?#[]@!$&'()*+,;=~%)safe)
startswithencodeFILESYSTEM_ENCODINGr	   urls    r   
iri_to_urir.   0   s?    
~~g

**CNN7,C(
QC 233r   c                 (   t        | t              rt        |       } n%t        | t              r| j	                  t
              } | j                  t        j                  j                  df      }t        j                  j                  |       } |st        j                  j                  |       r| t        j                  j                  z  } d}t        j                  |       } |r| j                  d      s| dz  } | j                  d      rd|  S d|  S )zVReturn file URL of `path`.

    Accepts 'str', 'bytes' or 'Path', returns 'str'.

    /Tz///r&   zfile://)
isinstancer   strbytesdecoder+   endswithospathsepabspathisdirr   pathname2urlr)   )r7   wants_trailing_slashs     r   path2urlr=   @   s     $4y	D%	 {{./=="''++s);<77??4 Drww}}T2 	#%DDMM#$6u tf~r   c                 n    t        | t              rt        nt        }t	        |j                  |             S )z4Return whether an URL (bytes or string) is absolute.)r1   r2   UNICODE_SCHEME_REBYTES_SCHEME_REboolmatch)r-   schemes     r   url_is_absoluterD   _   s'    ",S#"6OFS!""r   c           	          | j                  |d      j                         }|r t        |xs d||d| j                  ||f      S y)a'  Get the URI corresponding to the ``attr_name`` attribute.

    Return ``None`` if:

    * the attribute is empty or missing or,
    * the value is a relative URI but the document has no base URI and
      ``allow_relative`` is ``False``.

    Otherwise return an URI, absolute if possible.

     z<%s %s="%s">N)getstripurl_jointag)element	attr_namebase_urlallow_relativevalues        r   get_url_attributerP   e   sM     KK	2&,,.ENE>>[[)U+- 	- r   c                     | j                  d      rdt        | dd       fS t        |       rdt        |       fS |rdt        t	        ||             fS y)z.Get tuple describing internal or external URI.#internalr   Nexternal)r)   r
   rD   r.   r   )r-   rM   s     r   get_url_tuplerU   x   sZ    
~~cGCG,--		JsO,,	Jwx'=>?? 
r   c                     t        |      rt        |      S | rt        t        | |            S |rt        |      S t        j                  d| g|  y)zBLike urllib.urljoin, but warn if base_url is required but missing.z+Relative URI reference without a base URI: N)rD   r.   r   r   error)rM   r-   rN   contextcontext_argss        r   rI   rI      sY    s#	'(C011	#9'C		 r   c                    | j                  |d      j                         }|j                  d      r t        |      dkD  rddt	        |dd       ffS t        | ||d      }|rP|rH	 t        |      }	 t        |      }|j                  r$|dd	 |dd	 k(  rddt	        |j                        ffS dd|ffS y# t        $ r t        j                  d
|       Y (w xY w# t        $ r t        j                  d|       Y Mw xY w)zGet the URL value of an element attribute.

    Return ``('external', absolute_uri)``, or ``('internal',
    unquoted_fragment_id)``, or ``None``.

    rF   rR   r   r-   rS   NT)rN   zMalformed base URL: %szMalformed URL: %srT   )rG   rH   r)   lenr
   rP   r   fragment
ValueErrorr   warning)rK   rL   rM   
attr_valueuriparsedparsed_bases          r   get_link_attributerd      s    Y+113JS!c*o&9
GJqrN$;<==
GY
NC
O!#O"*8"4K
 6#2;+cr:J+J %
GFOO4L'MNN
C())  " GNN#;XFG  92C89s$   &C 2B4 4CCC;:C;c                 2    t        |       r| S t        |       S )zGet a ``scheme://path`` URL from ``string``.

    If ``string`` looks like an URL, return it unchanged. Otherwise assume a
    filename and convert it to a ``file://`` URL.

    )rD   r=   )strings    r   
ensure_urlrg      s     %V,6B(62BBr   c                 z    t        j                  dt               t        ||||d      }|j	                  |       S )z~Fetch an external resource such as an image or stylesheet.

    This function is deprecated, use ``URLFetcher`` instead.

    a-  default_url_fetcher is deprecated and will be removed in WeasyPrint 69.0, please use URLFetcher instead. For security reasons, HTTP redirects are not supported anymore with default_url_fetcher, but are with URLFetcher.

See https://doc.courtbouillon.org/weasyprint/stable/first_steps.html#url-fetcherscategoryF)allow_redirects)warningswarnDeprecationWarning
URLFetcherfetch)r-   timeoutssl_contexthttp_headersallowed_protocolsfetchers         r   default_url_fetcherrv      sC     MM	X $% l,=uVG==r   c              #   8  K   |t        |      }|
t               }| ||||fD cg c]  }|| }	}t        |	      dk7  r#dj                  |	      xs d}
t	        d|
       | _|||d}t        | d      r| |d<   n,t        | t              r| |d	<   nt        |       r| |d
<   n| |d	<   t        di |}|5 }| ddd       y|+|t        |      }t        |d      5 }||ddf ddd       y|t        ||      5 }|rP|j                  dk7  rAt        j                  d|j                   d|j                           t#        d      |ddf n*||j                   }|||j$                  |j                  f ddd       y|6|+t'        |dd      }|r|j)                  d      st        |      }||ddf yt        |t*              rt#        |      |ddf yt-        |      |ddf yc c}w # 1 sw Y   yxY w# 1 sw Y   yxY w# 1 sw Y   yxY ww)zIf only one input is given, return it.

    Yield a file object, the base url, the protocol encoding and the protocol mime-type.

    Nr   z, nothingz!Expected exactly one source, got )rM   url_fetchercheck_css_mime_typereadfile_objfilenamer-   rbztext/csszUnsupported stylesheet type z for rF   name<r    )rg   ro   r\   join	TypeErrorhasattrr1   r   rD   select_sourcer=   openrp   content_typer   rW   r-   r   charsetgetattrr)   r2   r   )guessr}   r-   r|   rf   rM   ry   rz   paramselected_paramssourcekwargsresultresponser   s                  r   r   r      s     h' l "8S(FC 	O  ?q ?+8y;F8DEE		 &#6

 5&!!&F:t$!&F:U#!F5M!&F:(( 	vL	 			)H(D! 	1XHdD00	1 	1	;$ 		R"x'<'<
'J283H3H2I J#<<.*+ rlHdD88#'||H(*:*:H<Q<QQQ		R 		R 
	8VT2DDOOC0%d+$,,fc"6"HdD88&/8T477g*	 	
	1 	1		R 		RsZ   #HG1BH6G6;$H	H(H?A=H<A:H6G?;HHHHHc                       e Zd ZdZy)URLFetchingErrorz)Some error happened when fetching an URL.Nr"   r#   r$   __doc__r    r   r   r   r     s    3r   r   c                       e Zd ZdZy)FatalURLFetchingErrorzESome error happened when fetching an URL and must stop the rendering.Nr   r    r   r   r   r     s    Or   r   c                   B     e Zd ZdZ	 	 d fd	Zd fd	ZddZd Z xZS )	ro   a`  Fetcher of external resources such as images or stylesheets.

    :param int timeout: The number of seconds before HTTP requests are dropped.
    :param ssl.SSLContext ssl_context: An SSL context used for HTTPS requests.
    :param dict http_headers: Additional HTTP headers used for HTTP requests.
    :type allowed_protocols: :term:`sequence`
    :param allowed_protocols: A set of authorized protocols, :obj:`None` means all.
    :param bool allow_redirects: Whether HTTP redirects must be followed.
    :param bool fail_on_errors: Whether HTTP errors should stop the rendering.

    Another class inheriting from this class, with a ``fetch`` method that has a
    compatible signature, can be given as the ``url_fetcher`` argument to
    :class:`weasyprint.HTML` or :class:`weasyprint.CSS`.

    See :ref:`URL Fetchers` for more information and examples.

    c                 X   t         
|           t        j                         t        j                         t        j
                         t        j                         t        j                         t        j                         t        j                         t        j                         t        j                  |      g	}|r#|j                  t        j                                |D ]  }	| j                  |	        || _        i t         |xs i | _        || _        || _        d | _        y )N)rX   )superr   r   ProxyHandlerUnknownHandlerHTTPHandlerHTTPDefaultErrorHandler
FTPHandlerFileHandlerHTTPErrorProcessorDataHandlerHTTPSHandlerappendHTTPRedirectHandleradd_handler_timeoutHTTP_HEADERS_http_headers_allowed_protocols_fail_on_errors_request)r   rq   rr   rs   rt   rk   fail_on_errorsr   handlershandler	__class__s             r   r   zURLFetcher.__init__)  s     	  "G$:$:$<g>Q>Q>S++-w/A/A/C!7#=#=#?ATATAV  5	7
 OOG779: 	&GW%	&  EE1CE"3-r   c                 J   t         j                  |      x}st        d|       |d   j                         }| j                  || j                  vrt        d|       |dk(  r|j                  d      d   }t        |      }i | j                  |xs i }| j                  xs t        j                  ||      }d| _        t        
| 1  || j                  	      }|}d
|j                  v rY|j                  d
   }|j                  d
= |dk(  rt        |      }n+|dk(  r&|j!                         }		 t#        j$                  |	      }t)        |j*                  ||j                  |j,                        S # t"        j&                  $ r t#        j$                  |	d      }Y Ww xY w)aE  Fetch a given URL.

        :returns: A :obj:`URLFetcherResponse` instance.
        :raises: An exception indicating failure, e.g. :obj:`ValueError` on
            syntactically invalid URL. All exceptions are catched internally by
            WeasyPrint, except when they inherit from :obj:`FatalURLFetchingError`.

        zNot an absolute URI: r   NzURI uses disallowed protocol: file?r   headers)rq   zContent-Encodinggzipr   deflatei)r?   rB   r^   lowerr   splitr.   r   r   r   Requestr   r   r   r   r   r{   zlib
decompressrW   URLFetcherResponser-   status)r   r-   r   rB   rC   http_requestr   bodycontent_encodingdatar   s             r   rp   zURLFetcher.fetch=  s    +005554SE:;;q! "".T444 #A#!GHH V))C.#C o <T'';GMr;}}MW(M7<dmm<D !1!11'//0BC  !346)(:!Y.}}6??40D
 "(,,h6F6FXX	 zz 6??45D6s   5E6 6)F"!F"c                     t        |t        j                        r-|| _        | j	                  |j
                  |j                        S | j	                  |      S r   )r1   r   r   r   rp   full_urlr   )r   r-   r   rq   s       r   r   zURLFetcher.openo  s>    c7??+DM::cllCKK88zz#r   c                 $    | j                  |      S r   )rp   )r   r-   s     r   __call__zURLFetcher.__call__u  s    zz#r   )
   NNNTFr   )NN)	r"   r#   r$   r   r   rp   r   r   __classcell__)r   s   @r   ro   ro     s(    $ CGNS(0Ydr   ro   c                   v    e Zd ZdZddZd Zd Zed        Zed        Z	ed        Z
d	 Zd
 Zed        Zd Zy)r   u  The HTTP response of an URL fetcher.

    :param str url: The URL of the HTTP response.
    :type body: :class:`str`, :class:`bytes` or :term:`file object`
    :param body: The body of the HTTP response.
    :type headers: dict or email.message.EmailMessage
    :param headers: The headers of the HTTP response.
    :param int status: The status of the HTTP response.

    Has the same interface as :class:`urllib.response.addinfourl`.

    If a :term:`file object` is given for the body, it is the caller’s responsibility to
    call ``close()`` on it. The default function used internally to fetch data in
    WeasyPrint tries to close the file object after retreiving; but if this URL fetcher
    is used elsewhere, the file object has to be closed manually.

    Nc                    || _         || _        t        |t              r|| _        n;t               | _        |xs i j                         D ]  \  }}	 || j                  |<    t        |d      r|| _        y t        |t              r<| j                  j                  dd       t        |j                  d            | _        y t        |      | _        y # t        $ r Y w xY w)Nr{   r   r'   )r-   r   r1   r   r   itemsr^   r   	_file_objr2   	set_paramr   r*   )r   r-   r   r   r   r   keyrO   s           r   r   zURLFetcherResponse.__init__  s    g|,"DL'>DL&}"335 
U(-DLL% 4 !DNc"LL""9g6$T[[%9:DN$T]DN " s   C	CCc                 :     | j                   j                  |i |S r   )r   r{   )r   argsr   s      r   r{   zURLFetcherResponse.read  s    "t~~""D3F33r   c                     	 | j                   j                          y # t        $ r6 t        j                  d| j
                  t        j                                Y y w xY w)Nz$Error when closing stream for %s:
%s)r   r   	Exceptionr   r_   r-   	traceback
format_excr   s    r   r   zURLFetcherResponse.close  sI    	2NN  " 	2 NN7)..02	2s    <AAc                     | j                   j                  d      r@t        j                  | j                   j	                  d      d   j                  d            S y )Nr&   r   r   )r-   r)   r   url2pathnamer   removeprefixr   s    r   r7   zURLFetcherResponse.path  sG    88w'''s(;A(>(K(KG(TUU (r   c                 6    | j                   j                         S r   )r   get_content_typer   s    r   r   zURLFetcherResponse.content_type  s    ||,,..r   c                 8    | j                   j                  d      S )Nr   )r   	get_paramr   s    r   r   zURLFetcherResponse.charset  s    ||%%i00r   c                     | j                   S r   r,   r   s    r   geturlzURLFetcherResponse.geturl  s    xxr   c                     | j                   S r   r   r   s    r   infozURLFetcherResponse.info  s    ||r   c                     | j                   S r   r   r   s    r   codezURLFetcherResponse.code  s    {{r   c                     | j                   S r   r   r   s    r   getcodezURLFetcherResponse.getcode  s    {{r   )NN   )r"   r#   r$   r   r   r{   r   propertyr7   r   r   r   r   r   r   r    r   r   r   r   y  sw    "+,42 V V / / 1 1  r   r   c              #     K   	  | |      }t        |t              rt        j                  dt               d	|vr|j                  d
|      |d	<   |j                  d|j                  d            |d<   |j                  dd      }|j                  d      x}r|d| z  }d|i|d<   t        di |}t        |t              sJ d       	 | |j                          y# t         $ rE}t        | dd      rt        d| d      |t        t	        |      j
                   d|       d}~ww xY w# |j                          w xY ww)aD  Fetch an ``url`` with ```url_fetcher``, fill in optional data, and clean up.

    Fatal errors must raise a ``FatalURLFetchingError`` that stops the rendering. All
    other exceptions are catched and raise an ``URLFetchingError``, that is usually
    catched by the code that fetches the resource and emits a warning.

    r   FzError fetching ""z: NzReturning dicts in URL fetchers is deprecated and will be removed in WeasyPrint 69.0, please return URLFetcherResponse instead.ri   r-   redirected_urlr|   rf   r   	mime_typezapplication/octet-streamencodingz
; charset=zContent-Typer   zFURL fetcher must return either a dict or a URLFetcherResponse instancer    )r   r   r   r   typer"   r1   dictrl   rm   rn   rG   r   r   )ry   r-   resource	exceptionr   r   s         r   rp   rp     s\    Ks# (D!L'	)  &ll+;SAHUO#<<
HLL4JK||K1KLll:..7.j	22L-|<%11h 23 RPR33  K; 159'*:3%q(AB	Q$y/":":!;2i[IJJK2 	sA   EC  B>ED1 E 	D.)A D))D..E1EE)F)r   NNN)NNNNNNNF)7r   
contextlibos.pathr6   resysr   rl   r   email.messager   r   r   ior   r   pathlibr   urllibr   urllib.parser	   r
   r   r   rF   r   loggerr   compiler?   r@   getfilesystemencodingr+   r   r   r.   r=   rD   rP   rU   rI   rd   rg   rv   contextmanagerr   IOErrorr   BaseExceptionr   OpenerDirectorro   r   rp   r    r   r   <module>r      sC   ?   	 
    &      : :  
 BJJ<= "**;</c//1   }-&
 
4  >#-&@*<C IM*.$ MQGL?8 ?8D4w 4PM P`'' `FM M` # #r   