a
    }0b:                     @   s  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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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%m&Z& d dl'm(Z(m)Z)m*Z*m+Z+ dZ,dZ-z8e.e,Z/e 0e/Z1W d   n1 s00    Y  W n e2yT   i Z1Y n0 z8e.e-Z3e 0e3Z4W d   n1 s0    Y  W n e2y   i Z4Y n0 dd Z5dd Z6e%e%e7dddZ8ee9dddZ:ed edddZ;e;de%e&d d!d"Z<e;d#e%e=d d$d%Z>eee7e9f d&d'd(Z?e9e9d d)d*Z@eeee9eAf   e%d+d,d-ZBe9e7d.d/d0ZCe9ee7 d.d1d2ZDe%edd3d4ZEd?e9e9dd6d7d8ZFd@e9e9e9e=e9d:d;d<ZGG d=d> d>ZHdS )A    Nwraps)blake2b)getsize)Path)runPIPE)TupleListCallableIterableUnionLiteralAnyOptional)ElementTree)Workbook)get_column_letter)post	HTTPErrorConnectionError)InsecureRequestWarning)PathLikeHtmlValidationResult)HTML_VALIDATOR_URLCSS_VALIDATOR_URLMAX_TRYCACHE_FOLDERz(/home/manager/cache_html_validation.jsonz'/home/manager/cache_css_validation.jsonc                    s   t  d fdd	}|S )Nc                    s^    j }z|| jv r| j| W S W n ty8   i | _Y n0  | g|R i |}|| j|< |S N)__name___cacheAttributeError)selfargskwkeyresultf Q/home/manager/.local/lib/python3.9/site-packages/websites_test_framework/tools.pycached_f?   s    

zcached.<locals>.cached_f)Nr   r(   r+   r)   r'   r*   cached>   s    r-   c                 C   s   t t| S r   )propertyr-   r'   r)   r)   r*   cached_propertyN   s    r/   )pathrootreturnc                 C   sB   t |  } t | }z| | W dS  ty<   Y dS 0 dS )zUFunction similar to Path.is_relative_to(), which is only available for python >= 3.9.TFN)r   resolverelative_to
ValueError)r0   r1   r)   r)   r*   is_relative_toR   s    
r6   )r0   r2   c                 C   sB   t | d$}t| dd W  d    S 1 s40    Y  d S )Nrb    )Zdigest_size)openr   readZ	hexdigest)r0   filer)   r)   r*   	hash_fileb   s    r<   )htmlcss)html_or_cssr2   c                    s    t tgtf d fdd}|S )Nr'   c                    s    t  td fdd}|S )N)filenamec                    sn   t | } t t t|  d }| r>t|jdd}n, | }|jjddd |j	t
|dd |S )Nz.jsonutf8)encodingT)parentsexist_ok)as_pathr   r<   is_filejsonloads	read_textparentmkdir
write_textdumps)r@   
cache_pathr&   )r(   r?   r)   r*   r+   i   s    z>cache_result_as_json_file.<locals>.decorator.<locals>.cached_f)r   r   r,   r?   r'   r*   	decoratorh   s    z,cache_result_as_json_file.<locals>.decorator)r   r   r   )r?   rP   r)   rO   r*   cache_result_as_json_fileg   s    rQ   r=   )r@   r2   c              	   C   s  t tD ]}zbtd t| d,}tjtddidd|fid}W d   n1 sT0    Y  |  W  qW q t	y   t
d	| d
 Y q0 q| d }dd |D }dd |D }t|tsJ tdd |D sJ t|tsJ |tdd |D s
J ||dS )ua   Renvoie la liste des erreurs et celle des avertissements émis
    par le validateur HTML du W3C.   r7   outrG   r;   z	file.html)datafilesNErreur de validation de . Nouvel essai...messagesc                 S   s    g | ]}|d  dkr|d qS )typeerrormessager)   .0msgr)   r)   r*   
<listcomp>       z!validate_html.<locals>.<listcomp>c                 S   s"   g | ]}| d dkr|d qS )ZsubTypewarningr[   )getr\   r)   r)   r*   r_      r`   c                 s   s   | ]}t |tV  qd S r   
isinstancestr)r]   rZ   r)   r)   r*   	<genexpr>   r`   z validate_html.<locals>.<genexpr>c                 s   s   | ]}t |tV  qd S r   rc   )r]   ra   r)   r)   r*   rf      r`   )errorswarnings)ranger   timesleepr9   requestsr   r   Zraise_for_statusr   printrG   rd   listall)r@   _r(   rrX   Zerrors_listZwarnings_listr)   r)   r*   validate_html{   s*    

$
rr   r>   c              	   C   s   t | dd}d|dd}ttD ]F}ztd tjt|dj	}W q$ t
yh   td| d	 Y q$0 q$td
|}|dusJ t|t|dS )u,   Renvoie le nombre d'erreurs CSS détectées.z/home/managerzhttps://iut.uca.netspace.frZcss3svgZsoap12)ZprofileurioutputrR   )paramsrV   rW   z%<m:errorcount>([0-9]+)</m:errorcount>N)re   replaceri   r   rj   rk   rl   rb   r   textr   rm   researchreprintgroup)r@   rs   Zpayloadrp   rw   matchr)   r)   r*   validate_css   s    
r~   )	html_filer2   c              
   C   s   z~t | }| }W d   n1 s(0    Y  t|D ]\}}| r: qbq:dd| j fW S d||< td| W dS  tjt	fy } zd|j
d fW  Y d}~S d}~0 0 dS )zTest if HTML file is also a valid XML file.

    `path` is the path of an HTML file.

    Return the result of the test (True/False) and a message.
    NFzEmpty file: uo   <!DOCTYPE html [<!ENTITY nbsp ' '> <!ENTITY commat '@'><!ENTITY gt '>'><!ENTITY lt '<'><!ENTITY eacute 'é'>]>
 )Tr   r   )r9   	readlines	enumeratestripnamer   Z
fromstringjoinZ
ParseErrorUnicodeErrorr#   )r   r(   linesilinerZ   r)   r)   r*   is_valid_xml   s    
&	r   c                 C   sJ   t dd| gtdj}t| dkr$dS |dd   }|dkrFdS |S )	z#Detect and return encoding of file.r;   z--mime-encoding)stdoutr   zutf-8   :rR   zus-ascii)r   r   r   r   splitdecoder   )r@   r   rB   r)   r)   r*   detect_encoding   s    r   )rT   	xlsx_filec                 C   s   t  }|j}t| ddD ].\}}t|ddD ]\}}||j||d_q,qtddd}g }	| D ]N}t|D ]@\}}|t|	k r|||	| kr|||	|< qj|	||g7 }	qjq^t|	dD ]\}}
|
|jt| _	q|
t| |  dS )z7Write a matrix (list of lists) to an XLSX (Excel) file.rR   )start)rowZcolumn)r2   c                 S   s    t | trt| d} tt| S )N   )rd   floatroundlenre   )valuer)   r)   r*   size   s    

zlist2xlsx.<locals>.sizeN)r   Zactiver   Zcellr   r{   r   Zcolumn_dimensionsr   widthZsavere   close)rT   r   wbwsr   r   jvalr   Zcolumn_widthsZcolumn_widthr)   r)   r*   	list2xlsx   s"    r   )urlr2   c                 C   s$   |   } td| d u o"| d S )Nz\w+:/)r   rx   r}   
startswith)r   r)   r)   r*   is_url_relative	  s    r   c              	   C   s  t   t jdtd ztj| dddd\}|j}|dksD|dkrbW d    W W d    d S |d	k W  d    W W  d    S 1 s0    Y  W nF tjjy   Y W d    dS  tjj	y   Y W d    d S 0 W d    n1  s0    Y  d S )
Nignore)categoryT   F)streamZtimeoutZverifyi  i  i  )
rh   catch_warningsfilterwarningsr   rl   rb   Zstatus_code
exceptionsr   ZReadTimeout)r   ZresponseZstatusr)   r)   r*   
url_exists  s    
:r   c                 C   s   t |   S r   )r   
expanduserr3   )r0   r)   r)   r*   rE     s    rE   r   )titler^   r2   c                 C   s0   t d| rdnd |  |rdnd d|  dS )zPrint a warning.z[43;1mWARNINGz - r   :z[0m N)rm   )r   r^   r)   r)   r*   warn#  s    r   )stringoldnewcountr2   c                 C   s   | | ||S )zHWorks like python builtin str.replace(), but replace from right to left.)r   rsplit)r   r   r   r   r)   r)   r*   right_replace(  s    r   c                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )LastOrderedSetaQ  Un ordered set minimalist implementation, based on a dict.

    Implemented methods:
    - add(element) : add element at the end of the set
    - pop() : remove first element of the set

    If an already present value is added to the ordered set, it will be moved to its end.

    (It is also iterable and have its length defined.)
    c                 G   s   t || _d S r   )dictfromkeys_dict)r"   r#   r)   r)   r*   __init__9  s    zLastOrderedSet.__init__c                 C   s    || j v r| j |= d | j |< d S r   )r   )r"   eltr)   r)   r*   add<  s    
zLastOrderedSet.addc                 C   s<   zt t| j}| j|= |W S  ty6   tdY n0 d S )Nzpop from an empty set)nextiterr   StopIterationKeyError)r"   Zelementr)   r)   r*   popA  s    zLastOrderedSet.popc                 C   s
   t | jS r   )r   r   r"   r)   r)   r*   __iter__I  s    zLastOrderedSet.__iter__c                 C   s
   t | jS r   )r   r   r   r)   r)   r*   __len__L  s    zLastOrderedSet.__len__c                 C   s   dd dd | D  dS )NzLastOrderSet(,c                 s   s   | ]}t |V  qd S r   )rz   )r]   r   r)   r)   r*   rf   P  r`   z*LastOrderedSet.__repr__.<locals>.<genexpr>))r   r   r)   r)   r*   __repr__O  s    zLastOrderedSet.__repr__N)
r   
__module____qualname____doc__r   r   r   r   r   r   r)   r)   r)   r*   r   -  s   r   )r   r   )r   )IrG   rx   rj   rh   	functoolsr   Zhashlibr   Zos.pathr   pathlibr   
subprocessr   r   typingr	   r
   r   r   r   r   r   r   Z	xml.etreer   rl   Zopenpyxlr   Zopenpyxl.utilsr   r   r   r   Zurllib3.connectionpoolr   $websites_test_framework.custom_typesr   r   websites_test_framework.paramr   r   r   r   ZCACHE_HTML_VALIDATIONZCACHE_CSS_VALIDATIONr9   Z_cache_htmlloadZJSON_HTML_VALIDATIONFileNotFoundErrorZ
_cache_cssZJSON_CSS_VALIDATIONr-   r/   boolr6   re   r<   rQ   rr   r{   r~   r   r   r   r   r   r   rE   r   r   r   r)   r)   r)   r*   <module>   s^   (

.

.
' #