
    >i               	       "   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Zd dl	m
Z
mZmZ  ej                  e      Z G d de      Zddeded	ed
efdZded
efdZded
efdZdee   d
efdZded
efdZded
efdZded
efdZded
efdZy)    N)unescape)
HTMLParser)InvalidBrowserPathInvalidResponseNetworkErrorc                   T     e Zd ZdZ fdZd Zd Zd ZdefdZ	de
ded	e
fd
Z xZS )TextExtractorz
    HTML parser for text extraction.

    Extracts visible text content from an HTML string, excluding the contents of
    tags specified in _skip_tags.
    c                 P    t         |           g | _        d| _        h d| _        y )NF>   stylescripttemplate)super__init___parts_skip
_skip_tags)self	__class__s    Z/var/www/python/tenders/Scrapper/venv/lib/python3.12/site-packages/pydoll/utils/general.pyr   zTextExtractor.__init__   s#    
9    c                 0    || j                   v rd| _        yy)z
        Marks the parser to skip content inside tags specified in _skip_tags.

        Args:
            tag (str): The tag name.
            attrs (list): A list of (attribute, value) pairs.
        TNr   r   )r   tagattrss      r   handle_starttagzTextExtractor.handle_starttag   s     $//!DJ "r   c                 0    || j                   v rd| _        yy)zl
        Marks the parser the end of skip tags.

        Args:
            tag (str): The tag name.
        FNr   )r   r   s     r   handle_endtagzTextExtractor.handle_endtag(   s     $//!DJ "r   c                 f    | j                   s%| j                  j                  t        |             yy)z
        Handles text nodes. Adds them to the result unless they are within a skip tag.

        Args:
            data (str): The text data.
        N)r   r   appendr   )r   datas     r   handle_datazTextExtractor.handle_data2   s&     zzKKx~. r   stripc              #   Z   K   | j                   D ]  }|r|j                         n|  yw)z
        Yields all collected visible text fragments.

        Args:
            strip (bool): Whether to strip leading/trailing whitespace from each fragment.

        Yields:
            str: Visible text fragments.
        N)r   r"   )r   r"   texts      r   get_stringszTextExtractor.get_strings<   s+      KK 	2D"'$**,T1	2s   )+	separatorreturnc                 D    |j                  | j                  |            S )a  
        Returns all visible text.

        Args:
            separator (str): String inserted between extracted text fragments.
            strip (bool): Whether to strip whitespace from each fragment.

        Returns:
            str: The visible text.
        )r"   )joinr%   )r   r&   r"   s      r   get_textzTextExtractor.get_textI   s!     ~~d..U.;<<r   )__name__
__module____qualname____doc__r   r   r   r!   boolr%   strr*   __classcell__)r   s   @r   r	   r	      sB    :	/2 2=# =d =s =r   r	   htmlr&   r"   r'   c                 ^    t               }|j                  |        |j                  ||      S )a  
    Extracts visible text content from an HTML string.

    Args:
        html (str): The HTML string to extract text from.
        separator (str, optional): String inserted between extracted text fragments. Defaults to ''.
        strip (bool, optional): Whether to strip whitespace from text fragments. Defaults to False.

    Returns:
        str: The extracted visible text.
    )r&   r"   )r	   feedr*   )r2   r&   r"   parsers       r   extract_text_from_htmlr6   W   s*     _F
KK??Ye?<<r   imagec                 J    t        j                  | j                  d            S )z
    Decodes a base64 image string to bytes.

    Args:
        image (str): The base64 image string to decode.

    Returns:
        bytes: The decoded image as bytes.
    zutf-8)base64	b64decodeencode)r7   s    r   decode_base64_to_bytesr<   h   s     ELL122r   portc                 2  K   	 t        j                         4 d{   }|j                  d|  d      4 d{   }|j                          |j	                          d{   }|d   cddd      d{    cddd      d{    S 7 q7 U7 /7 7 # 1 d{  7  sw Y   nxY wddd      d{  7   y# 1 d{  7  sw Y   yxY w# t         j
                  $ r}t        d|       d}~wt        $ r}t        d|       d}~ww xY ww)a6  
    Fetches the WebSocket address for the browser instance.

    Returns:
        str: The WebSocket address for the browser.

    Raises:
        NetworkError: If the address cannot be fetched due to network errors
            or missing data.
        InvalidResponse: If the response is not valid JSON.
    Nzhttp://localhost:z/json/versionwebSocketDebuggerUrlz"Failed to get browser ws address: )	aiohttpClientSessiongetraise_for_statusjsonClientErrorr   KeyErrorr   )r=   sessionresponser    es        r   get_browser_ws_addressrJ   u   s    H((* 	4 	4g{{%6tfM#JK 4 4x))+%]]_,234 4 4	4 	4 	44,4	44 4 4	4 	4 	4 	4 	4  E?sCDD H B1#FGGHs   DC BC B?BB?$B"B#B+B?7B8B?<C B	C DC B?BB?C B*	B!B*	&B?-C 8B;9C >D?CCCC DC D'C55DDDDpathsc                     | D ]J  }t         j                  j                  |      s#t        j                  |t         j                        sH|c S  t        d|        )a  
    Validates potential browser executable paths and returns the first valid one.

    Checks a list of possible browser binary locations to find an existing,
    executable browser. This is used by browser-specific subclasses to locate
    the browser executable when no explicit binary path is provided.

    Args:
        paths: List of potential file paths to check for the browser executable.
            These should be absolute paths appropriate for the current OS.

    Returns:
        str: The first valid browser executable path found.

    Raises:
        InvalidBrowserPath: If the browser executable is not found at the path.
    z No valid browser path found in: )ospathisfileaccessX_OKr   )rK   rN   s     r   validate_browser_pathsrR      sN    $  77>>$BIIdBGG$<K ?wG
HHr   r   c                 ,   t        j                  dd| t         j                        }t        j                  dd|t         j                        }t        j                  dd|      }t        j                  dd|      }t        j                  d	d
|      }|S )a  
    Clean JavaScript code by removing comments and string literals.

    This helps avoid false positives when analyzing script structure.

    Args:
        script: JavaScript code to clean.

    Returns:
        str: Cleaned script with comments and strings removed.
    z//.*?$ )flagsz	/\*.*?\*/z"[^"]*"z""z'[^']*'z''z`[^`]*`z``)resub	MULTILINEDOTALL)r   cleaneds     r   clean_script_for_analysisr[      so     ffYF",,?Gff\2wbii@GffZw/GffZw/GffZw/GNr   c                     t        |       }d}d}t        t        j                  ||j	                               xs$ t        j                  ||j	                                     S )z
    Check if a JavaScript script is already wrapped in a function.

    Args:
        script: JavaScript code to analyze.

    Returns:
        bool: True if script is already a function, False otherwise.
    z^\s*function\s*\([^)]*\)\s*\{z^\s*\([^)]*\)\s*=>\s*\{)r[   r/   rV   matchr"   )r   cleaned_scriptfunction_patternarrow_function_patterns       r   is_script_already_functionra      s]     /v6N77
!>#7#7#9: 	D88*N,@,@,BC r   c                    t        |       }t        |      ryd}t        j                  ||      sy|j	                  d      }d}d}|D ]}  }t        j                  d|      st        j                  d|      rd}||j                  d      |j                  d	      z
  z  }t        j                  ||      r	|r|dk  r y|dk  s|d} y)
z
    Check if a JavaScript script has return statements outside of functions.

    Args:
        script: JavaScript code to analyze.

    Returns:
        bool: True if script has return outside function, False otherwise.
    Fz
\breturn\b
r   z\bfunction\bz=>T{})r[   ra   rV   searchsplitcount)r   r^   return_patternlinesbrace_countin_functionlines          r   has_return_outside_functionrn      s     /v6N ".1 #N99^^4   &EKK  99_d+ryy/EK 	tzz#C88 99^T*+"2 !K " r   selectorc                     | j                         }|j                  d      s| S d}|j                  |      }|dk(  r| S |t        |      z  }|j	                  d      }|dk(  s||k  r| S ||| S )a  
    Normalize synthetic XPath selector produced by the builder.

    Converts selectors of the form //*[@xpath="..."] back into the original
    XPath string between the quotes. Returns the input unchanged if the
    pattern is not present or cannot be parsed safely.

    Args:
        selector: The selector string that may contain the synthetic XPath format.

    Returns:
        str: The normalized original XPath or the input selector if no normalization applies.
    z//*[@xpath=z//*[@xpath="z"])r"   
startswithfindlenrfind)ro   sprefix	start_idxend_idxs        r   normalize_synthetic_xpathrz     sz     	A<<&FvIBVIggdmG"}9,Ywr   )rT   F)r9   loggingrM   rV   r2   r   html.parserr   r@   pydoll.exceptionsr   r   r   	getLoggerr+   loggerr	   r0   r/   r6   bytesr<   intrJ   listrR   r[   ra   rn   rz    r   r   <module>r      s      	 	  "  O O			8	$E=J E=P= = =$ =SV ="
3# 
3% 
3Hs Hs H4I$s) I I0c c 4s t *+ + +\     r   