a
    .bs1                     @   s  d Z ddlmZ ddlmZ ddlmZmZmZmZ	m
Z
mZmZmZmZ ddlmZmZmZ ddlmZmZmZ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#m$Z$m%Z%m&Z& G d	d
 d
Z'G dd de'Z(G dd de'Z)ede'dZ*G dd dZ+ee( eee) dddZ,dS )zu
Website
=======

This module implement classes representing (static) websites:
- HTMLWebFile
- CSSWebFile
- Website
    )Counter)Path)	TupleListOptionalr   IteratorTypeTypeVarIterableDict)BeautifulSoupCommentTag)CssSimpleParserRuleCssErrorlooks_like_css_code)PathLikeHtmlValidationResult)detect_encodingvalidate_htmlvalidate_csscachedcached_propertyis_valid_xmlas_pathis_relative_tois_url_relativewarnLastOrderedSetc                   @   s   e Zd ZU dZeedf ed< deee dddZ	e
dd	 Zed
d ZeedddZeedddZeedddZeedddZeedddZedd Zdd Zdd Zdd ZdS ) WebFilezYGeneric base class for classes HTMLFile and CSSFile.

    You should not use it directly..valid_extensionsN)pathrootc                 C   sF   |j  }| j }vr*td|d| d|| _|d u r<|}|| _d S )NzInvalid file extension: z (expected: ))suffixr!   RuntimeErrorr"   r#   )selfr"   r#   ext
extensions r*   S/home/manager/.local/lib/python3.9/site-packages/websites_test_framework/website.py__init__5   s    zWebFile.__init__c                 C   s   t d S NNotImplementedErrorr'   r*   r*   r+   	structure=   s    zWebFile.structurec                 C   s   t t| jS r-   )r   strr"   r0   r*   r*   r+   encodingA   s    zWebFile.encodingreturnc                 C   s   | j  dddkS )N- utf8)r3   lowerreplacer0   r*   r*   r+   is_utf8E   s    zWebFile.is_utf8c                 C   s0   | j dkr td| j d dS | jj| j dS )NbinaryzCan't decode file z (binary file !)zBINARY FILE !r3   )r3   printr"   	read_textr0   r*   r*   r+   textI   s    
zWebFile.textc                 C   s
   t | jS r-   )lenr@   r0   r*   r*   r+   number_of_charactersP   s    zWebFile.number_of_charactersc                 C   sX   d}| j dkrTt| j| j d&}t|ddD ]\}}q,W d    n1 sJ0    Y  |S )Nr   r<   r=      )start)r3   openr"   	enumerate)r'   nfileliner*   r*   r+   number_of_linesV   s    
 zWebFile.number_of_linesc                 C   s   | j | jS r-   )r"   relative_tor#   r0   r*   r*   r+   relative_path_   s    zWebFile.relative_pathc                 C   s   | j jS r-   )r"   namer0   r*   r*   r+   rM   c   s    zWebFile.namec                 C   s   t | j| jfS r-   )hashr"   r#   r0   r*   r*   r+   __hash__g   s    zWebFile.__hash__c                 C   s"   t |to | j| jf|j|jfkS r-   )
isinstancer    r"   r#   )r'   otherr*   r*   r+   __eq__j   s    zWebFile.__eq__c                 C   s   | j j d| j dS )Nz('z'))	__class____name__rL   r0   r*   r*   r+   __str__m   s    zWebFile.__str__)N)rT   
__module____qualname____doc__r   r2   __annotations__r   r   r,   propertyr1   r   r3   boolr;   r@   intrB   rJ   rL   rM   rO   rR   rU   r*   r*   r*   r+   r    -   s,   



r    c                   @   s  e Zd ZdZdZeedddZee	dddZ
ee	ddd	Zeedd
dZeedddZeee dddZeee dddZeee dddZedd ZeedddZeee dddZeed dddZeeeef dddZd S )!HTMLWebFilez Class representing an HTML file.).htmlz.htmr4   c                 C   s   t t| jS r-   )r   r2   r"   r0   r*   r*   r+   get_w3c_validationv   s    zHTMLWebFile.get_w3c_validationc                 C   s   |   d S )Nerrorsr_   r0   r*   r*   r+   r`   z   s    zHTMLWebFile.errorsc                 C   s   |   d S )Nwarningsra   r0   r*   r*   r+   rb   ~   s    zHTMLWebFile.warningsc                 C   s   t d S r-   r.   r0   r*   r*   r+   is_valid_html5   s    zHTMLWebFile.is_valid_html5c                 C   s   t | jd S )Nr   )r   r"   r0   r*   r*   r+   r      s    zHTMLWebFile.is_valid_xmlc                 C   s$   | j  }tdd |D s J |S )Nc                 s   s   | ]}t |tV  qd S r-   )rP   r   .0tagr*   r*   r+   	<genexpr>       z#HTMLWebFile.tags.<locals>.<genexpr>)r1   find_allall)r'   tagsr*   r*   r+   rk      s    
zHTMLWebFile.tagsc                 C   s   t dd | jD S )Nc                 s   s   | ]}|j V  qd S r-   )rM   rd   r*   r*   r+   rg      rh   z)HTMLWebFile.tags_count.<locals>.<genexpr>)r   rk   r0   r*   r*   r+   
tags_count   s    zHTMLWebFile.tags_countc                 C   s   t d S r-   r.   r0   r*   r*   r+   
linked_css   s    zHTMLWebFile.linked_cssc                 C   s   | j jdd dS )Nc                 S   s
   t | tS r-   )rP   r   )sr*   r*   r+   <lambda>   rh   z&HTMLWebFile.comments.<locals>.<lambda>)r@   )r1   ri   r0   r*   r*   r+   comments   s    zHTMLWebFile.commentsc                 C   s>   t | jd}| }W d    n1 s*0    Y  t|dS )Nrblxml)rE   r"   readr   )r'   fZ	html_coder*   r*   r+   r1      s    &zHTMLWebFile.structurec                 C   sJ   g }| j jdddD ]0}|jd  }t|r|| jj|   q|S )Nlink
stylesheet)rM   relhref)	r1   ri   attrsstripr   appendr"   parentresolve)r'   pathsru   urlr*   r*   r+   !directly_linked_local_stylesheets   s    z-HTMLWebFile.directly_linked_local_stylesheets
CSSWebFilec                 C   s   t | g| jS r-   )_get_local_css_filesr#   r0   r*   r*   r+   local_css_files   s    zHTMLWebFile.local_css_files)selectorr5   c                 C   s&   i }| j D ]}||j| q
|S r-   )r   updater1   Zget_properties)r'   r   
propertiescss_filer*   r*   r+   get_css_property   s    
zHTMLWebFile.get_css_propertyN)rT   rV   rW   rX   r!   r   r   r_   r   listr`   rb   rZ   r[   rc   r   r   r   rk   CounterTyper2   rl   rm   rp   r   r1   r   r   r   r   r   r*   r*   r*   r+   r]   q   s6   
r]   c                   @   s   e Zd ZdZdZeedddZeedddZ	ee
e ddd	Zeedd
dZee
e dddZee
e dddZee
e dddZdS )r   zClass representing a CSS file.).cssr4   c                 C   s   t t| jS r-   )r   r2   r"   r0   r*   r*   r+   r_      s    zCSSWebFile.get_w3c_validationc                 C   s   |   S r-   ra   r0   r*   r*   r+   r`      s    zCSSWebFile.errorsc                 C   s   dd | j jD S )Nc                 S   s   g | ]}t |s|qS r*   )r   )re   commentr*   r*   r+   
<listcomp>   rh   z'CSSWebFile.comments.<locals>.<listcomp>)r1   rp   r0   r*   r*   r+   rp      s    zCSSWebFile.commentsc                 C   sJ   t  }z|| j W n. tyD   | jdkr@tdd| j Y n0 |S )Nr   zCSS parsing error:zDCSS can not be parsed but no error was reportedby W3C Validator for )r   parser@   r   r`   r   r"   )r'   r1   r*   r*   r+   r1      s    

zCSSWebFile.structurec                 C   s   | j jS )z=Find recursively all the css rules and return them as a list.)r1   rulesr0   r*   r*   r+   r      s    zCSSWebFile.rulesc                 C   s   | j jS )zAFind recursively all the css selectors and return them as a list.)r1   	selectorsr0   r*   r*   r+   r      s    zCSSWebFile.selectorsc                 C   s   | j jS )zEFind recursively all the css @rules' names and return them as a list.)r1   at_rules_namesr0   r*   r*   r+   r      s    zCSSWebFile.at_rules_namesN)rT   rV   rW   rX   r!   r   r\   r_   r   r`   r   r2   rp   r   r1   r   r   r   r   r*   r*   r*   r+   r      s    r   T)boundc                   @   sf  e Zd ZdZd.eedddZee e	edf ddd	Z
eed
ddZee	edf dddZee	edf dddZeee dddZee	edf dddZeee dddZd/eee dddZd0eee dddZeeddd Zeee dd!d"Zeedd#d$Zeee dd%d&Zeedd'd(Z ed)d* Z!d+d, Z"d-S )1WebsitezClass representing a full website.

    Currently, provides simple access to HTML and CSS file,
    using its .html_files and .css_files attributes.
    /)r#   path_on_serverc                 C   sJ   t || _| j r(| jjdkr(|   | j s@td| || _d S )Nz.zipzNo such directory: )r   r#   is_filer%   _extract_from_zipis_dirFileNotFoundErrorr   )r'   r#   r   r*   r*   r+   r,      s    

zWebsite.__init__.)class_r5   c                    s    t  fddjdD S )Nc                 3   s.   | ]&}|  r|j jv r |jV  qd S r-   )r   r%   r!   r#   re   r"   r   r'   r*   r+   rg     s   z/Website._files_of_given_type.<locals>.<genexpr>*tupler#   rglob)r'   r   r*   r   r+   _files_of_given_type   s    
zWebsite._files_of_given_type)r   r5   c                 C   s4   | | jr0|t| jd  }| ds0d| }|S )Nr   )
startswithr   rA   )r'   r   r*   r*   r+   rewrite_absolute_url  s
    
zWebsite.rewrite_absolute_urlr4   c                 C   s
   |  tS r-   )r   r]   r0   r*   r*   r+   
html_files  s    zWebsite.html_filesc                 C   s
   |  tS r-   )r   r   r0   r*   r*   r+   	css_files  s    zWebsite.css_filesc                 C   s   t | j| jS )a  Return only the CSS files which are effectively used by the website.

        A CSS file is considered used if it meets one of the following:
        - it is linked to an HTML file using a <link> tag
        - it is imported in a used CSS file using an @import rule.
        )r   r   r#   r0   r*   r*   r+   used_css_files  s    zWebsite.used_css_filesc                 C   s   | j | j S )zReturn CSS and HTML files.)r   r   r0   r*   r*   r+   	web_files   s    zWebsite.web_files)r)   r5   c                    sF    r0t dd  D   fdd| jdD S dd | jdD S )zReturn path of all filesc                 s   s   | ]}|  V  qd S r-   )r9   )re   r(   r*   r*   r+   rg   (  rh   z3Website.iterate_over_files_paths.<locals>.<genexpr>c                 3   s(   | ] }|  r|j  v r|V  qd S r-   )r   r%   r9   r   r)   r*   r+   rg   )  s   r   c                 s   s   | ]}|  r|V  qd S r-   r   r   r*   r*   r+   rg   .  rh   r   )r'   r)   r*   r   r+   iterate_over_files_paths%  s    

z Website.iterate_over_files_pathsr7   )rL   r5   c                    s4   | j |    s t| d fdd| jD S )N is not a directoryc                    s   g | ]}t |j r|qS r*   r   r"   re   rH   	directoryr*   r+   r   4  rh   z4Website.get_directory_html_files.<locals>.<listcomp>)r#   r   r   r   r'   rL   r*   r   r+   get_directory_html_files0  s    
z Website.get_directory_html_filesc                    s4   | j |    s t| d fdd| jD S )Nr   c                    s   g | ]}t |j r|qS r*   r   r   r   r*   r+   r   :  rh   z3Website.get_directory_css_files.<locals>.<listcomp>)r#   r   r   r   r   r*   r   r+   get_directory_css_files6  s    
zWebsite.get_directory_css_filesc                 C   sv   | j t|  }|jdkr$| j}n"|jdkr6| j}ntd| d|D ]}|j|krJ|  S qJtd| dd S )Nr^   r   z"HTML or CSS file expected (file: 'z').zFile 'z' not found.)	r#   r   r}   r%   r   r   r/   r"   r   )r'   rL   r"   filesrH   r*   r*   r+   __getitem__<  s    



zWebsite.__getitem__c                 C   s    t  }| jD ]}||j7 }q|S )z6Return a dictionary {tag.name: number of occurrences}.)r   r   rl   )r'   rl   rH   r*   r*   r+   rl   I  s    
zWebsite.tags_countc                 C   s   t | j S )zReturn global tags' number.)sumrl   valuesr0   r*   r*   r+   tags_global_numberQ  s    zWebsite.tags_global_numberc                 C   s   dd | j D S )Nc                 S   s   g | ]}|j D ]}|qqS r*   )r   )re   r   r   r*   r*   r+   r   X  rh   z)Website.all_selectors.<locals>.<listcomp>)r   r0   r*   r*   r+   all_selectorsV  s    zWebsite.all_selectorsc                 C   s   t dd | jD S )z Return global css rules' number.c                 s   s   | ]}t |jV  qd S r-   )rA   r   )re   r   r*   r*   r+   rg   ]  rh   z2Website.css_rules_global_number.<locals>.<genexpr>)r   r   r0   r*   r*   r+   css_rules_global_numberZ  s    zWebsite.css_rules_global_numberc                 C   s   t dd | jdD S )Nc                 s   s   | ]}|  r|V  qd S r-   r   )re   pthr*   r*   r+   rg   a  rh   z*Website.all_files_paths.<locals>.<genexpr>z**/*)r   r#   globr0   r*   r*   r+   all_files_paths_  s    zWebsite.all_files_pathsc                 C   s   t d S r-   r.   r0   r*   r*   r+   r   c  s    zWebsite._extract_from_zipN)r   )r7   )r7   )#rT   rV   rW   rX   r   r2   r,   r   r   r   r   r   r   r]   r   r   r   r   r   r    r   r   r   r   r   r   r   r   rl   r\   r   r   r   r   r   r*   r*   r*   r+   r      s6   	
r   )r   r#   r5   c           	      C   s   t  }| D ]2}|jD ]&}| rt||r|t|| qq
t  }|r| }|| |j D ]B}|j	j
|  }| rdt||rdt||}||vrd|| qdqDt|S r-   )r   r   r   r   addr   popr1   Zlist_importsr"   r|   r}   r   )	r   r#   r   Z	html_filer"   Zprocessed_css_filesr   r   Znew_css_filer*   r*   r+   r   g  s     


r   N)-rX   collectionsr   pathlibr   typingr   r   r   r   r   r   r	   r
   r   Zbs4r   r   r   Z"websites_test_framework.css_parserr   r   r   r   Z$websites_test_framework.custom_typesr   r   Zwebsites_test_framework.toolsr   r   r   r   r   r   r   r   r   r   r   r    r]   r   r   r   r   r*   r*   r*   r+   <module>   s   	,4DH5v