Ë
    qýujB  ã                   óÚ   — d dl mZ d dlZd dlZd dlmZmZ d dlZd dlm	Z	m
Z
mZmZ d dlmZ d dlZ ej                   e«      Zdedefd„Zd	ed
edefd„Zddedededee   de
eef   f
d„Zy)é    )Úget_browserN)ÚurljoinÚurlparse)ÚListÚDictÚSetÚAny)ÚBeautifulSoupÚhtmlÚreturnc                 ó   — g }t        | d«      }|j                  dddi¬«      D ]³  }|j                  xs |j                  «       xs d}	 t	        j
                  |«      }t        |t        «      r|n|g}|D ]_  }t        |t        «      sŒt        |j                  d«      t        «      r|j                  d	„ |d   D «       «       ŒO|j                  |«       Œa Œµ |S # t        j                  t        f$ r t        j                  d«       Y Œèw xY w)
z½Every JSON-LD object on a page, with @graph wrappers flattened.

    Must run before the crawler decomposes <script> tags, which would otherwise
    delete exactly the data this reads.
    úhtml.parserÚscriptÚtypezapplication/ld+json©ÚattrsÚ z Skipping malformed JSON-LD blockz@graphc              3   óB   K  — | ]  }t        |t        «      sŒ|–— Œ y ­w©N)Ú
isinstanceÚdict)Ú.0Úgs     ú3/var/www/html/strategist-ai/app/services/website.pyú	<genexpr>z(extract_jsonld_blocks.<locals>.<genexpr>"   s   è ø€ ÒO A¼:ÀaÌÕ;NœaÑOùs   ‚˜)r
   Úfind_allÚstringÚget_textÚjsonÚloadsÚJSONDecodeErrorÚ	TypeErrorÚloggerÚdebugr   Úlistr   ÚgetÚextendÚappend)r   ÚblocksÚsoupÚtagÚrawÚparsedÚ
candidatesÚitems           r   Úextract_jsonld_blocksr0      sú   € ð €FÜ˜˜}Ó-€DØ�}‰}˜X¨fÐ6KÐ-Lˆ}ÓMò $ˆØ�j‰jÒ0˜CŸL™L›NÒ0¨bˆð	Ü—Z‘Z “_ˆFô  *¨&´$Ô7‘V¸f¸Xˆ
Øò 	$ˆDÜ˜d¤DÔ)ØÜ˜$Ÿ(™( 8Ó,¬dÔ3Ø—‘ÑO¨¨h©ÔOÕOà—‘˜dÕ#ñ	$ð$ð" €Møô ×$Ñ$¤iÐ0ò 	ä�L‰LÐ;Ô<Ùð	ús   Á
CÃ.DÄDÚbase_urlÚ
target_urlc                 óš  — 	 t        | «      }t        |«      }|j                  |j                  k7  ry|j                  j                  d«      r|j                  n|j                  dz   }|j                  j                  d«      r|j                  n|j                  dz   }|j                  dv ry|j	                  |«      S # t
        $ r Y yw xY w)z9
    Checks if target_url is a sub-path of base_url.
    Fú/)r   r4   T)r   ÚnetlocÚpathÚendswithÚ
startswithÚ	Exception)r1   r2   ÚbaseÚtargetÚb_pathÚt_paths         r   Ú
is_subpathr>   '   s­   € ðÜ˜Ó!ˆÜ˜*Ó%ˆà�;‰;˜&Ÿ-™-Ò'Øð #Ÿi™i×0Ñ0°Ô5�—’¸4¿9¹9Às¹?ˆØ &§¡× 4Ñ 4°SÔ 9�—’¸v¿{¹{ÈSÑ?Pˆð �9‰9˜	Ñ!Øà× Ñ  Ó(Ð(øÜò Ùðús   ‚/B> ²A:B> Â-B> Â>	C
Ã	C
ÚurlÚ	max_depthÚ	max_pagesÚvisitedc              ƒ   ó®  ‡ ‡‡‡‡‡‡	K  — ‰€
t        «       Št        ‰ «      j                  }dg g t        «       i g dœŠ	t        «       ƒ d{  –—† Šdt        dt
        fˆˆˆˆˆ	ˆ ˆfd„Š ‰‰ d«      ƒ d{  –—†  t        t        ‰	d   «      «      ‰	d<   t        ‰	d	   j                  «       «      dd
 D ��cg c]
  \  }}||dœ‘Œ c}}‰	d	<   ‰	S 7 Œ�7 ŒZc c}}w ­w)z¸
    Crawls the website starting from URL up to max_depth and max_pages using a headless browser.
    Returns a dictionary containing aggregated text, metadata, and color palette.
    Nr   )ÚtextÚpagesÚmetadataÚcolorsÚimagesÚurls_visitedÚcurrent_urlÚdepthc              “   óV	  •‡‡ K  — |‰#kD  s| ‰'v st        ‰'«      ‰$k\  ry ‰'j                  | «       t        j                  d| › d|› dt        ‰'«      › d�«       	 ‰!j	                  | «      ƒ d {  –—† \  }}}|st        j                  d| › �«       y t        |d«      }‰%d   j                  | «       | |j                  d«      xs$ |j                  r|j                  j                  nd	d	d
œ}|j                  dddi¬«      }|r|j                  dd	«      |d<   ‰%d   j                  |«       |j                  d«      }|D ]r  }	t        j                  d|	j                  xs d	«      }
‰%d   j                  |
«       t        j                  d|	j                  xs d	«      }‰%d   j                  |«       Œt t!        |«      } |g d¢«      D ]  }|j#                  «        Œ i }|j                  d«      }g d¢}|D ]ý  }|j                  d«      }|sŒt%        | |«      }|j'                  «       Š t)        ˆ fd„|D «       «      rŒH|j                  d«      xs |j                  d«      }|si|j+                  d«      d   j+                  d«      d   }|j-                  dd «      d   j/                  d!d"«      j/                  d#d"«      j1                  «       }|j3                  «       d d$ }|‰%d%   vr|‰%d%   |<   |||<   Œÿ |j5                  «       }d&„ |j7                  «       D «       }d'„ |D «       }d(j9                  d)„ |D «       «      }‰%d*   j                  | ||||j                  d«      xs$ |j                  r|j                  j                  nd	t;        |j=                  «       «      d d+ D ��cg c]
  \  }}||d,œ‘Œ c}}d-œ«       ‰%d.xx   d/| › d0|› d(�z  cc<   |‰#k  r“t        ‰'«      ‰$k  r„g }|D ]_  Št        ‰'«      ‰$k\  r nOt?        ‰«      }tA        ‰&‰«      sŒ+‰‰'vsŒ0t)        ˆfd1„d2D «       «      rŒE|j                   ‰"‰|d z   «      «       Œa |rtC        jD                  |Ž ƒ d {  –—†  y y y y 7 �Œÿc c}}w 7 Œ# tF        $ r'}t        jI                  d3| › d4|› �d5¬6«       Y d }~y d }~ww xY w­w)7NzCrawling URL (Headless): z (depth z, count ú)zNo content rendered for r   rI   Útitler   )r?   rN   ÚdescriptionÚmetaÚnamerO   r   ÚcontentrF   Ústylez#[0-9a-fA-F]{3,6}rG   z
rgb\(.*?\))r   rS   ÚnavÚfooterÚheaderÚasideÚimg)	ÚfacebookÚtwitterÚlinkedinÚ	instagramÚtiktokÚsocialÚiconÚarrowÚchevronÚsrcc              3   ó&   •K  — | ]  }|‰v –— Œ
 y ­wr   © )r   ÚkeyÚ	url_lowers     €r   r   z7extract_text_from_url.<locals>.crawl.<locals>.<genexpr>Ž   s   øè ø€ ÒE°˜3 )Ô+ÑEùs   ƒÚaltr4   éÿÿÿÿú?r   ú.é   Ú-Ú Ú_éd   rH   c              3   ó<   K  — | ]  }|j                  «       –— Œ y ­wr   )Ústrip)r   Úlines     r   r   z7extract_text_from_url.<locals>.crawl.<locals>.<genexpr>Ÿ   s   è ø€ ÒD d�T—Z‘Z—\ÑDùs   ‚c              3   óh   K  — | ]*  }|j                  d «      D ]  }|j                  «       –— Œ Œ, y­w)z  N)Úsplitrq   )r   rr   Úphrases      r   r   z7extract_text_from_url.<locals>.crawl.<locals>.<genexpr>    s,   è ø€ ÒV¨ÀTÇZÁZÐPTÓEUÒV¸6�f—l‘l—nÐV�nÑVùs   ‚02Ú
c              3   ó&   K  — | ]	  }|sŒ|–— Œ y ­wr   rd   )r   Úchunks     r   r   z7extract_text_from_url.<locals>.crawl.<locals>.<genexpr>¡   s   è ø€ Ò$H¨uÂ%¤UÑ$Hùs   ‚ŠrE   é
   ©r?   Úlabel)r?   rD   Újsonldr   rN   rH   rD   z
--- Content from z ---
c              3   ó\   •K  — | ]#  }‰j                  «       j                  |«      –— Œ% y ­wr   )Úlowerr7   )r   ÚextÚnext_urls     €r   r   z7extract_text_from_url.<locals>.crawl.<locals>.<genexpr>¸   s#   øè ø€ Ò"vÀc 8§>¡>Ó#3×#<Ñ#<¸S×#AÑ"vùs   ƒ),)z.pdfz.jpgz.pngz.zipz.gifzFailed to crawl z with Playwright: T)Úexc_info)%ÚlenÚaddr#   ÚinfoÚget_rendered_contentÚwarningr
   r(   r&   rN   r   Úfindr   ÚreÚfindallÚupdater0   Ú	decomposer   r~   Úanyrt   ÚrsplitÚreplaceÚ
capitalizerq   r   Ú
splitlinesÚjoinr%   Úitemsr   r>   ÚasyncioÚgatherr9   Úerror)(rJ   rK   rR   ÚlinksÚpw_metar*   Ú	page_metaÚdesc_tagÚstylesrS   Ú
hex_colorsÚ
rgb_colorsÚpage_jsonldÚelementÚpage_imagesÚimg_tagsÚjunk_keywordsrX   Úimg_urlÚfull_img_urlr{   ÚfilenameÚraw_textÚlinesÚchunksÚcleaned_textÚuÚlÚtasksÚparsed_nextÚer€   rf   ÚbrowserÚcrawlr@   rA   Úresultsr?   rB   s(                                  @@€€€€€€€r   r¯   z$extract_text_from_url.<locals>.crawlS   s®  úè ø€ Ø�9Ò ¨wÑ 6¼#¸g»,È)Ò:SØà�‰�KÔ Ü�‰Ð/°¨}¸HÀUÀGÈ8ÔTWÐX_ÓT`ÐSaÐabÐcÔdðe	_à,3×,HÑ,HÈÓ,U×&UÑ#ˆG�U˜GáÜ—‘Ð!9¸+¸ÐGÔHØä  ¨-Ó8ˆDØ�NÑ#×*Ñ*¨;Ô7ð #Ø Ÿ™ WÓ-ÒZÀtÇzÂz°$·*±*×2CÒ2CÐWYØ!ñˆIð
 —y‘y °¸Ð/F�yÓGˆHÙØ+3¯<©<¸	À2Ó+F�	˜-Ñ(Ø�JÑ×&Ñ& yÔ1ð —]‘] 7Ó+ˆFØò 5�ÜŸZ™ZÐ(<¸e¿l¹lÒ>PÈbÓQ�
Ø˜Ñ!×(Ñ(¨Ô4ÜŸZ™Z¨°u·|±|Ò7IÀrÓJ�
Ø˜Ñ!×(Ñ(¨Õ4ð	5ô 0°Ó8ˆKñ  Ò WÓXò $�Ø×!Ñ!Õ#ð$ð ˆKØ—}‘} UÓ+ˆHò }ˆMàò 6�ØŸ'™' %›.�ÚÜ#*¨;¸Ó#@�Lð !-× 2Ñ 2Ó 4�IÜÓE°}ÔEÔEØ ð  ŸG™G E›NÒ>¨c¯g©g°gÓ.>�EÙ Ø#/×#5Ñ#5°cÓ#:¸2Ñ#>×#DÑ#DÀSÓ#IÈ!Ñ#L˜Ø (§¡°°QÓ 7¸Ñ :× BÑ BÀ3ÈÓ L× TÑ TÐUXÐZ]Ó ^× iÑ iÓ k˜à!ŸK™K›M¨$¨3Ð/�Eà#¨7°8Ñ+<Ñ<Ø:?˜ Ñ)¨,Ñ7Ø05�K Ò-ð)6ð. —}‘}“ˆHÙD¨h×.AÑ.AÓ.CÔDˆEÙV°ÔVˆFØŸ9™9Ñ$H¸Ô$HÓHˆLà�GÑ×#Ñ#Ø"Ø$Ø%ØØ Ÿ™ WÓ-ÒZÀtÇzÂz°$·*±*×2CÒ2CÐWYÜ>BÀ;×CTÑCTÓCVÓ>WÐX[ÐY[Ð>\×]±d°a¸ 1¨qÓ1Ó]ñ%ô ð �F‹OÐ!4°[°MÀÈÀ~ÐUWÐXÑX‹Oð �yÒ ¤S¨£\°IÒ%=Ø�Ø %ò E�HÜ˜7“| yÒ0Ùä"*¨8Ó"4�Kä! # xÕ0°XÀWÒ5LÜ"Ó"vÐMuÔ"vÕvØ!ŸL™L©¨x¸À¹Ó)CÕDðEñ Ü!Ÿ.™.¨%Ð0×0Ñ0ð ð &>Ð ðg 'VûóZ ^ð& 1ùäò 	_Ü�L‰LÐ+¨K¨=Ð8JÈ1È#ÐNÐY]ˆL×^Ñ^ûð	_üs‡   …AR)ÁQ6 Á,Q+Á-"Q6 ÂR)ÂE<Q6 ÈFQ6 Î%Q.Î4AQ6 ÐQ6 ÐQ6 Ð.4Q6 Ñ"Q4Ñ#Q6 Ñ'R)Ñ+Q6 Ñ.Q6 Ñ6	R&Ñ?R!ÒR)Ò!R&Ò&R)r   rG   rH   é   rz   )	Úsetr   r5   r   ÚstrÚintÚsortedr%   r’   )
r?   r@   rA   rB   Úbase_domainr©   rª   r®   r¯   r°   s
   ````   @@@r   Úextract_text_from_urlr·   >   sê   þè ø€ ð
 €Ü“%ˆä˜3“-×&Ñ&€KàØØÜ“%ØØñ€Gô  “M×!€Gðl_¤ð l_¬S÷ l_ó l_ñ\ ��Q‹-×Ðô œt G¨HÑ$5Ó6Ó7€GˆHÑÜ<@ÀÈÑAR×AXÑAXÓAZÓ<[Ð\_Ð]_Ð<`×a±D°A°q ¨QÓ/Óa€GˆHÑà€Nðm "øð` úó bùs7   ‰A CÁ	CÁ
(CÁ2CÁ3A CÂ3CÃ
CÃCÃC)rk   r±   N)Úapp.services.browserr   Úloggingr   Úurllib.parser   r   rˆ   Útypingr   r   r   r	   Úbs4r
   r“   Ú	getLoggerÚ__name__r#   r³   r%   r0   Úboolr>   r´   r·   rd   ó    r   ú<module>rÁ      s¡   ðÝ ,Û Û ß *Û 	ß 'Ó 'Ý Û à	ˆ×	Ñ	˜8Ó	$€ð ð ¨ó ð6˜ð ¨#ð °$ó ñ.I Sð I°Sð IÈð IÐ\_Ð`cÑ\dð IÐptÐuxÐz}Ðu}Ñp~ô IrÀ   