o
    /hn                     @   s  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m	Z	 d dl
mZmZm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mZ g d	ZG d
d deZG dd deZG dd deZdd Zdd Z e d(ddZ!e dd Z"dd Z#e$dZ%e$dej&Z'e$dej(ej)B Z*e$dZ+e$dej,Z-g d Z.G d!d" d"e/Z0d)d$d%Z1e2d&krd'Ze0eZ3e4e31  dS dS )*    N)OrderedDict)escapeunescape)urljoinurlparseunquote)etreeCSSSelector)function_cache)csstext_to_pairsmerge_styles)PremailerError	Premailer	transformc                   @      e Zd ZdS )r   N__name__
__module____qualname__ r   r   G/var/www/html/myenv/lib/python3.10/site-packages/premailer/premailer.pyr          r   c                   @   r   )ExternalNotFoundErrorNr   r   r   r   r   r      r   r   c                   @   r   )ExternalFileLoadingErrorNr   r   r   r   r   r      r   r   c                 C   s   d dd | dD S )z,makes every property in a string !important.;c                 s   s&    | ]}| d sd| n|V  qdS )
!importantz%s !importantN)endswith).0pr   r   r   	<genexpr>$   s
    
z!make_important.<locals>.<genexpr>)joinsplit)bulkr   r   r   make_important"   s   
r$   c                 C   sF   t d| }|std}t d| d }| d| |S |d S )z=Ensures that `root` contains a <head> element and returns it.headbodyr   )_create_cssselectorr   Element	getparentinsert)rootr%   r&   r   r   r   get_or_create_head*   s   
r,   Tc                 C   s   t j| |dS )a  
    This function will cache the result from cssutils
    It is a big gain when number of rules is big
    Maximum cache entries are 1000. This is mainly for
    protecting memory leak in case something gone wild.
    Be aware that you can turn the cache off in Premailer

    Args:
        css_body(str): css rules in string format
        validate(bool): if cssutils should validate

    Returns:
        cssutils.css.cssstylesheet.CSSStyleSheet

    validate)cssutilsparseString)css_bodyr.   r   r   r   _cache_parse_css_string6   s   r2   c                 C   s   t | S Nr	   )selectorr   r   r   r'   J   s   r'   c                 C   s   dd }t || S )z.Capitalize float and margin CSS property namesc                 S   s$   d | d | d| dS )Nz
{0}:{1}{2}propertyvalue
terminator)formatgroup
capitalizematchr   r   r   _capitalize_propertyR   s
   z5capitalize_float_margin.<locals>._capitalize_property)_lowercase_margin_float_rulesub)r1   r=   r   r   r   capitalize_float_marginO   s   r@   z(^|\s)\wz\<\!\[CDATA\[(.*?)\]\]\>zr(?P<property>margin(-(top|bottom|left|right))?|float)
        :
        (?P<value>.*?)
        (?P<terminator>$|;)z\s*!importantz!^#([0-9a-f])([0-9a-f])([0-9a-f])$)z:last-childz:first-child
:nth-childc                   @   s   e Zd ZdZ																												dddZddd	Zd
d ZdddZdd Zdd Z	e
dd ZdddZdd Zdd ZdS )r   zdata-premailerNFThtmlc                 C   s   || _ || _|| _|| _|| _|| _|| _|| _|
| _|| _	|	| _
t|tr)|g}|| _t|tr4|g}|| _|| _|| _|| _|d u rFg }|| _|| _|| _|| _|| _|| _|| _|| _|| _|pdt| _|rntj| |rxtj | d S d S r3   )!rB   base_urldisable_link_rewritespreserve_internal_linkspreserve_inline_attachmentspreserve_handlebar_syntaxexclude_pseudoclasseskeep_style_tagsremove_classesr@   include_star_selectors
isinstancestrexternal_stylescss_textstrip_importantmethod	base_pathdisable_basic_attributesdisable_validationcache_css_parsingdisable_leftover_cssalign_floating_imagesremove_unset_propertiesallow_networkallow_insecure_sslallow_loading_external_filesrequestssessionr/   log
addHandlersetLevel)selfrB   rC   rD   rE   rF   rG   rH   rI   rK   rJ   r@   rP   rN   rO   rQ   rR   rS   rT   rU   cssutils_logging_handlercssutils_logging_levelrV   rW   rX   rY   rZ   r[   r]   r   r   r   __init__r   sJ   


zPremailer.__init__c                 C   s    | j r	t||dS tj||dS )Nr-   )rU   r2   r/   r0   )ra   r1   r.   r   r   r   _parse_css_string   s   zPremailer._parse_css_stringc              
      s  fdd  fdd}g }g }|s||fS j |j d}|D ]}|j|jkr/|| q!|j|jkr6q!dd |j D }dd |j D }	||}
||	}|||	 }d	d
 |j	dD }|D ]^}d|v rj
rd|	ddd  tvr|||f qed|v rjsqe|drqe|d}|d}tt|}d|fd|
ffD ]\}}|sq|||||t|f}||||f qqeq!||fS )aA  Returns a list of rules to apply to this doc and a list of rules
        that won't be used because e.g. they are pseudoclasses. Rules
        look like: (specificity, selector, bulk)
        for example: ((0, 1, 0, 0, 0), u'.makeblue', u'color:blue').
        The bulk of the rule should not end in a semicolon.
        c                    s0    j s| jdkrd| j| jS d| j| jS )N	importantz{0}:{1}z{0}:{1} !important)rP   priorityr8   namer6   )prop)ra   r   r   format_css_property   s   z9Premailer._parse_style_rules.<locals>.format_css_propertyc                    s   d  fdd| D S )zAccepts a list of cssutils Property objects and returns
            a semicolon delimitted string like 'color: red; font-size: 12px'
            r   c                 3   s    | ]} |V  qd S r3   r   r   ri   rj   r   r   r       s    zLPremailer._parse_style_rules.<locals>.join_css_properties.<locals>.<genexpr>)r!   )
propertiesrl   r   r   join_css_properties   s   z9Premailer._parse_style_rules.<locals>.join_css_propertiesr-   c                 S   s   g | ]	}|j d kr|qS rf   rg   rk   r   r   r   
<listcomp>   
    
z0Premailer._parse_style_rules.<locals>.<listcomp>c                 S   s   g | ]	}|j d kr|qS ro   rp   rk   r   r   r   rq      rr   c                 s   s.    | ]}|  r|  d s|  V  qdS )@N)strip
startswithr   xr   r   r   r       s    
z/Premailer._parse_style_rules.<locals>.<genexpr>,:   *#.r   )re   rT   type
MEDIA_RULEappend
STYLE_RULEstylegetPropertiesselectorTextr"   rH   FILTER_PSEUDOSELECTORSrK   ru   countlen_element_selector_regexfindall)ra   r1   ruleset_indexrn   leftoverrulessheetrulenormal_propertiesimportant_propertiesbulk_normalbulk_importantbulk_all	selectorsr4   id_countclass_countelement_countis_importantr#   specificityr   )rj   ra   r   _parse_style_rules   sj   




%zPremailer._parse_style_rulesc           )      K   sP  |dur| j durtd|du r| j du rtd|du r!| j }t|dr/| }|}|}n8| jdkr<tjddd}nt }| }| j	rPt
dd	d
 |}t|| }| }||jjre|n|}|dusmJ | jrsd}	nt|}	g }
d}dg}| jr|d td||D ]}|jd}|r|dvrq|j| j}|r|dkr|j| j= qtd| j|f  |jdk}|r|j}n|jd}| |}| ||\}}|d7 }|
 | |! }|s| j"r0|r|}n
t#d}d|jd< | j"r||_n| $||_| j%rt&d|j|_| jdkr"t'|j|_|s/|(| |)| q| j"r7|s<|)| q| j*r]| jr]| j*D ]}| |}| +|||
|	 |d7 }qH| j,rt| j,D ]}| +|||
|	 |d7 }qd|
j-t./dd i }|
D ]o\}}}|}d}d|v rt
0d|d\}}d| }|t1v s|drd}n|}|sJ t|}||}t2|rt3|| j4 d}|D ]&} t5| }!|!|vr| g g d||!< ||! d | ||! d | qȐq|6 D ]-\}}t7|d jdd|d |d | j8d }"|"r|"|d jd< | j9|d |"d!d" q| j:r8|;d#D ]} | ! }#|#jd$= q,| j<rP|;d%D ]} t<| }$|$| ! jd< qA| j=r}|;d&D ]#} t>?| jd }%|%j@d'krpd'| jd(< qY|%j@d)kr{d)| jd(< qY| jAr| jBstC| jAjDstEd*d+D ]O}&|;d,|& D ]D} | ! }#|#j|& }'|&dkr| jFr|'d-rq|&d.kr| jGr|'d/rȐq|&dkr|'d0rՐqtH| jA|'|#j|&< qqt|dr|S |Id1| j |Id2| |Id3d4 tjJ|fi |K|d3 }(| jdkrtLd5d
 |(}(| j	r&t
d6d7d
 |(}(|(S )8zUchange the html and return it with CSS turned into style
        attributes.
        NzCan't pass html argument twicez must pass html as first argumentgetroottreexmlF)ns_cleanresolve_entitiesz="{{(.*?)}}"c                 S   s   dt |  d  d S Nz="{{r   z}}")r   groupsr;   r   r   r   <lambda>]  s    z%Premailer.transform.<locals>.<lambda>r   r   zlink[rel~=stylesheet]rx   media)allscreenignorezUnrecognized %s attribute (%r)hrefrz   text/cssr~    )keyry   z:%srA   r-   )itemclassesr   r   r   )rX   T)forcez//@classclassz//@stylez//img[@style]rightalignleftzBase URL must have a scheme)r   srcz//@%sr|   r   zcid:ztel:rQ   pretty_printencodingutf-8c                 S   s   d|  d S )Nz/*<![CDATA[*/%s/*]]>*/rz   )r9   )mr   r   r   r   0  s    z="%7B%7B(.+?)%7D%7D"c                 S   s   dt t|  d  d S r   )r   r   r   r;   r   r   r   r   7  s    )MrB   	TypeErrorhasattrr   rQ   r   	XMLParser
HTMLParserrt   rG   rer?   
fromstringgetrootru   docinfodoctyperV   r,   rY   r   r'   r!   attribgetattribute_namewarningswarntagtext_load_externalr   extendr)   rI   r(   _css_rules_to_stringrP   _importantsCDATAaddpreviousremoverN   _process_css_textrO   sortoperator
itemgetterr"   r   r   r   rT   iditemsr   rX   _style_to_basic_html_attributesrJ   xpathr@   rW   r/   
parseStylefloatrC   rD   r   scheme
ValueErrorrE   rF   r   
setdefaulttostringdecode_cdata_regex))ra   rB   r   kwargsr+   pagetreeparserstrippedr%   r   indexcssselectorelementr   data_attributeis_styler1   r   these_rulesthese_leftoverparent_of_elementr   	stylefileelements_r4   new_selectorclass_selr   processed_styler   item_idfinal_styleparentmangled	image_cssattrurloutr   r   r   r   +  s`  
























zPremailer.transformc                 C   s"   | j j|| j d}|  |jS )N)verify)r]   r   rZ   raise_for_statusr   )ra   r   responser   r   r   _load_external_url<  s   zPremailer._load_external_urlc                 C   s  | dr| jrd| jv rd| }nd| }| ds | dr'| |}|S | js1td||}tj| j	p;tj
}tj|sNtjtj||}tj|rrtj|dd}| }W d	   |S 1 skw   Y  |S | jrt| j|}| |S t|)
z<loads an external stylesheet from a remote url or local pathz//zhttps://zhttps:zhttp:zhttp://zEUnable to load external file {!r} because it's explicitly not allowedr   )r   N)ru   rC   r   r[   r   r8   ospathabspathrR   curdirisabsr!   existscodecsopenreadr   r   r   )ra   r   r1   r   rR   fr   r   r   r   A  s6   





zPremailer._load_externalc                 C   s   t d| }|S )zFix background colors for Lotus Notes

        Notes which fails to handle three character ``bgcolor`` codes well.
        see <https://github.com/peterbe/premailer/issues/114>z#\1\1\2\2\3\3)_short_color_codesr?   )color_valueretvalr   r   r   	six_colora  s   zPremailer.six_colorc                 C   s$  | dr| d| dkr|dd dd }t }dd |dD D ]M\}}| }|d	kr:| |d
< q'|dkrE| |d< q'|dkrYd| vrY| | |d< q'|dksa|dkrt| }|drp|dd }|||< q'| D ]\}}||jv r|r|| j	v rqy||j|< qydS )a0  given an element and styles like
        'background-color:red; font-family:Arial' turn some of that into HTML
        attributes. like 'bgcolor', etc.

        Note, the style_content can contain pseudoclasses like:
        '{color:red; border:1px solid green} :visited{border:1px solid green}'
        }{r   rz   Nc                 S   s(   g | ]}t |d dkr|d qS )ry      )r   r"   rv   r   r   r   rq   z  s    "z=Premailer._style_to_basic_html_attributes.<locals>.<listcomp>r   z
text-alignr   zvertical-alignvalignzbackground-colortransparentbgcolorwidthheightpx)
r   r"   r   rt   lowerr
  r   r   r   rS   )ra   r   style_contentr   
attributesr   r6   r   r   r   r   l  s:   


z)Premailer._style_to_basic_html_attributesc                 C   s   g }|D ]E}t |tr|\}}|d|t|f  q|jD ]$}t |tjjjtjj	j
fr.q|j D ]}|j|ddf|j|< q3q||j qd|S )z.given a list of css rules returns a css stringz%s {%s}Fr   
)rL   tupler   r$   cssRulesr/   css
csscomment
CSSCommentcssunknownruleCSSUnknownRuler   keysgetPropertyValuecssTextr!   )ra   r   linesr   kvr   r   r   r   r   r     s(   


zPremailer._css_rules_to_stringc                 C   sp   |  ||\}}|| |dur4|s| jr6td}d|jd< | jr'||_n| ||_|| dS dS dS )zprocesses the given css_text by adding rules that can be
        in-lined to the given rules list and adding any that cannot
        be in-lined to the given `<head>` element.
        Nr   r   r~   )	r   r   rI   r   r(   r   r   r   r   )ra   rO   r   r   r%   r   r   r   r   r   r   r     s   


zPremailer._process_css_text)NNFFTFTFFFFTNNrB   NNFTNNFTTTFFNT)NTF)r   r   r   r   rd   re   r   r   r   r   staticmethodr
  r   r   r   r   r   r   r   r   n   sV    

R
a   


-r   Fc                 K   s   t di |j| |dS )N)r   r   )r   r   )rB   r   r   r   r   r   r     s   r   __main__a  <html>
        <head>
        <title>Test</title>
        <style>
        h1, h2 { color:red; }
        strong {
          text-decoration:none
          }
        p { font-size:2px }
        p.footer { font-size: 1px}
        </style>
        </head>
        <body>
        <h1>Hi!</h1>
        <p><strong>Yes!</strong></p>
        <p class="footer" style="color:red">Feetnuts</p>
        </body>
        </html>r&  r'  )5r  r   r   r   r   collectionsr   rB   r   r   urllib.parser   r   r   r/   r\   lxmlr   lxml.cssselectr
   premailer.cacher   premailer.merge_styler   r   __all__	Exceptionr   r   r   r   r$   r,   r2   r'   r@   compiler   DOTALLr   
IGNORECASEVERBOSEr>   r   Ir  r   objectr   r   r   r   printr   r   r   r   <module>   sZ    



    
Z