
    H*j58                     6   S r SSKrSSKrSSKrSSKrSSKrSSKrSSKrSSKrSSK	r	SSK
Jr  SSKJrJrJrJr  SSKJr  SSKJrJr  \" \5      R/                  5       R0                  r\S-  r\R7                  SS	9  \S
-  r/ SQr1 Skr/ SQrSr \RB                  " \RD                  SSS9  \RF                  " S5      r$ " S S5      r%\%" 5       r& " S S5      r'S\(S\(S\\(   4S jr)S r*\+S:X  a,  \," S5        \)" SS5      r-\," S \-(       a  \." \-5      OS 35        gg)!a  
================================================================================
 STORIGO IMAGE GENERATOR v2.0 (Professional Rewrite)
================================================================================
 - Strict reliance on 'visualization_suggestion' (Usage of synonyms removed)
 - Global Deduplication (Persists across runs)
 - Multi-strategy Bing Scraping (Robust & Fast)
 - High Quality Filtering
================================================================================
    N)Path)OptionalListDictSet)BeautifulSoup)
quote_plusurlparsegenerated_images_for_storigoT)exist_okzimage_history_v2.json)zoMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36zuMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36zPMozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0>4   asshotsexxxxbdsmboobbutticonlogonsfwnudepornsexy123rfadultalamynakedpenisstockbikinibreasteroticescortfetishmaturenipplescantysketchvaginavectorcartoonclipartdrawingescortsgenitalnaughtyplayboysensualshuttertoplessalluringlingerie	nakedness	penthouse	revealing	unclothed	watermark
bottomless
dreamstime
suggestivedepositphotos
naked-body)z-nudez-nakedz-pornz-sexz-nsfwz-bikiniz	-lingeriez-xxxz-eroticz-adultz-boobz-assz-buttz-genitalz-sexy   z%%(asctime)s - [STORIGO] - %(message)sz%H:%M:%S)levelformatdatefmt
StorigoImgc                   n    \ rS rSrSrS rS rS rS\S\4S jr	SS\S	\S\
4S
 jjrS\S	\4S jrS rSrg)HistoryManagerF   zAManages persistent history of used image URLs and content hashes.c                 `    [        5       U l        [        5       U l        U R                  5         g N)set	used_urlsused_hashes_loadselfs    H/var/www/eduai.edurigo.com/storigo/production/storigo_image_generator.py__init__HistoryManager.__init__I   s    #&5%(U

    c                    [         R                  5       (       a   [        [         SSS9 n[        R                  " U5      n[        UR                  S/ 5      5      U l        [        UR                  S/ 5      5      U l        S S S 5        [        R                  S[        U R                  5       S[        U R                  5       S35        g g ! , (       d  f       NR= f! [         a"  n[        R                  S	U 35         S nAg S nAff = f)
Nrutf-8encodingurlshasheszLoaded History: z URLs, z HasheszFailed to load history: )HISTORY_FILEexistsopenjsonloadrK   getrL   rM   loggerinfolen	Exceptionerror)rP   fdataes       rQ   rN   HistoryManager._loadN   s      =,g>!99Q<D%(&")=%>DN'*488Hb+A'BD$ ? .s4>>/B.C73tO_O_K`Jaahij !>>
  =7s;<<=s0   C ACA
C 
CC 
D
(DD
c                 ^    [        U R                  5      [        U R                  5      [        U R                  5      S.n[	        [
        SSS9 n[        R                  " XSS9  S S S 5        g ! , (       d  f       g = f! [         a"  n[        R                  SU 35         S nAg S nAff = f)N)rZ   r[   countwrW   rX      )indentzFailed to save history: )listrL   rM   rd   r^   r\   r_   dumpre   rb   rf   )rP   rh   rg   ri   s       rQ   saveHistoryManager.saveY   s    		9T^^,t//0T^^,D
 lC':a		$!, ;:: 	9LL3A3788	9s6   AB  A/&B  /
A=9B  =B   
B,
B''B,urlreturnc                     UR                  5       R                  5       nUR                  SS5      R                  SS5      nUR                  SS5      nUR                  S5      S   nUR	                  S5      $ !   Us $ = f)z5Robust normalization to catch variations of same URL.zhttps:// zhttp://zwww.?r   /)lowerstripreplacesplitrstrip)rP   rt   s     rQ   	normalizeHistoryManager.normalizee   st    	))+##%C++j"-55iDC++fb)C))C.#C::c?"	Js   A6A9 9A?content_hashc                     U R                  U5      nX0R                  ;   a  gXR                  ;   a  gU(       a  X R                  ;   a  gg)NTF)r   rL   rM   )rP   rt   r   
norm_inputs       rQ   is_usedHistoryManager.is_usedu   sB    ^^C(
 ' .. L,<,<<rT   c                     U R                   R                  U R                  U5      5        U R                   R                  U5        U(       a  U R                  R                  U5        U R	                  5         g rJ   )rL   addr   rM   rr   )rP   rt   r   s      rQ   	mark_usedHistoryManager.mark_used   sQ     	4>>#./3  .		rT   c                     U R                   R                  5         U R                  R                  5         [        R	                  5       (       a  [        R                  5         g g rJ   )rL   clearrM   r\   r]   unlinkrO   s    rQ   r   HistoryManager.clear   sD       ! !rT   )rM   rL   N)rw   )__name__
__module____qualname____firstlineno____doc__rR   rN   rr   strr   boolr   r   r   __static_attributes__ rT   rQ   rG   rG   F   sY    K
	=
9S S  3 c 4 *	S 	 	"rT   rG   c                   t    \ rS rSrSrS rS rSS\S\S\	\
   4S jjrS	\S\	\
   4S
 jrS\S\\   4S jrSrg)BingImageFinder   z(Robust Bing Image Search implementation.c                     [         R                  " 5       U l        U R                  R                  R	                  SSSSS.5        g )NzJtext/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8zen-US,en;q=0.5z
keep-alive1)AcceptzAccept-Language
ConnectionzUpgrade-Insecure-Requests)requestsSessionsessionheadersupdaterO   s    rQ   rR   BingImageFinder.__init__   s;    '')##b/&),	%
 	rT   c                 :    S[         R                  " [        5      0$ )Nz
User-Agent)randomchoiceUSER_AGENTSrO   s    rQ   _get_random_header"BingImageFinder._get_random_header   s    &--4
 	
rT   queryattemptru   c                 @   UR                  5       nSSR                  [        5      -   nSnS[        X-   5       SSUS-  -    3nUS-  nUS-  nXE-   n U R                  R
                  R                  U R                  5       5        U R                  R                  US	S
9nUR                  S:w  a$  [        R                  SUR                   35        / $ U R                  UR                  5      $ ! [         a$  n[        R                  SU 35        / s SnA$ SnAff = f)z!Performs a search on Bing Images. z"https://www.bing.com/images/searchz?q=z&first=      z&qft=+filterui:photo-photoz&adlt=strict
   timeout   zBing search failed: zSearch error: N)r{   joinNEGATIVE_KEYWORDSr	   r   r   r   r   ra   status_coderb   warning_parse_htmltextre   rf   )	rP   r   r   
negative_qbase_urlparamsfull_urlresponseri   s	            rQ   searchBingImageFinder.search   s     388$566
 8z%"456ga7R<>P=QR... $
	LL  ''(?(?(AB||''"'=H##s*!5h6J6J5KLM	##HMM22 	LL>!-.I	s%   B C/ C/ /
D9DDDhtmlc                    [        US5      n/ nUR                  SSS9 H  n [        R                  " UR	                  SS5      5      nUR	                  S5      nUR	                  S5      nUR	                  S	S
5      nU(       aK  UR                  UUU[        UR	                  SS5      5      [        UR	                  SS5      5      S.5        M  M     U$ !    M  = f)z)Extracts image candidates from Bing HTML.zhtml.parseraiusc)class_mz{}murlturltrw   mwr   mh)rt   thumbtitlewidthheight)r   find_allr_   loadsra   appendint)	rP   r   soup
candidatesr   r   r   r   r   s	            rQ   r   BingImageFinder._parse_html   s    T=1
 s62AJJquuS$/0uuV}uuV}c2%%#!%!&!$QUU4^!4"%aeeD!n"5'   3( s   B*CCrt   c                     U R                   R                  R                  U R                  5       5        U R                   R	                  USS9nUR
                  S:X  aY  UR                  n[        U5      [        S-  :  a7  UR                  S5      (       d  UR                  S5      (       d	  SUSS	 ;   a  U$ g!    g= f)
z&Downloads image bytes with validation.   r   r   i   s      PNG   WEBPN   )
r   r   r   r   ra   r   contentrd   MIN_FILE_SIZE_KB
startswith)rP   rt   respr   s       rQ   download_imageBingImageFinder.download_image   s    	LL  ''(?(?(AB<<##C#3D3&,,w<#3d#:;))+66':L:LZ:X:X\cgnorprgs\s '	s   B5B9 9B=)r   N)r   )r   r   r   r   r   rR   r   r   r   r   r   r   r   r   bytesr   r   r   rT   rQ   r   r      s\    2

$C $# $d4j $L T
 8# (5/ rT   r   	slide_keyvisualization_promptru   c                 h  ^^^ [         R                   " 5       n[        5       nUR                  SS5      R                  SS5      nUR                  5       n[        R                  SU  SU S35        SnSn[        S5       GH  nUR                  XGS9n[        R                  SU  S	U S
[        U5       S35        UR                  S SS9  U GH  n	U	R                  SS5      mU	R                  SS5      R                  5       m[        R                  T5      (       a  MR  TR                  5       m[        U4S j[         5       5      (       d  [        U4S j[         5       5      (       a   [        R!                  SU  STSS  35        M  / SQn
[        U4S jU
 5       5      (       a   [        R!                  SU  STSS  35        M  [        R                  SU  STSS  S35        UR#                  T5      nU(       d  GM6  [$        R&                  " U5      R)                  5       n[        R                  TU5      (       a  [        R                  SU  S35        GM  UnTn[        R+                  TU5          O   U(       d  GM    O   U(       a  SnUR-                  S5      (       a  SnOSUSS ;   a  S n[.        R0                  " U5      R3                  S!5      n[         R                   " 5       U-
  n[        R                  SU  S"US# S$35        S%U S&U 3$ [        R5                  SU  S'35        g)(z
Public API used by other files.

Args:
    slide_key: Unique identifier for the slide/request.
    visualization_prompt: The prompt describing the image.

Returns:
    Base64 Data URI string (data:image/xyz;base64,...) or None.
"rw   '[z] Searching for: 'Nrn   )r   z] Page z: Found z candidatesc                 L    U R                  SS5      U R                  SS5      -  $ )Nr   r   r   )ra   )xs    rQ   <lambda>'fetch_image_for_slide.<locals>.<lambda>.  s    quuWa'81551;M'MrT   T)keyreversert   r   c              3   ,   >#    U  H	  oT;   v   M     g 7frJ   r   ).0badr   s     rQ   	<genexpr>(fetch_image_for_slide.<locals>.<genexpr>:  s     :>C%<>   c              3   ,   >#    U  H	  oT;   v   M     g 7frJ   r   )r   r   	url_lowers     rQ   r   r   :  s     Am^lWZBR^lr   z!] Filtered inappropriate result: <   )r   r   r   r   r"   r   r   c              3   n   >#    U  H*  o[        T5      R                  R                  5       ;   v   M,     g 7frJ   )r
   netlocrz   )r   patternrt   s     rQ   r   r   @  s)     `J_whsm2288::J_s   25z] Filtered adult domain: z
] Trying: z...z$] Duplicate content found, skipping.z
image/jpegr   z	image/pngr   r   z
image/webprW   u   ] ✅ Image found in z.2fszdata:z;base64,u%   ] ❌ No image found after searching.)timer   r|   r{   rb   rc   ranger   rd   sortra   rz   HISTORYr   anyEXCLUDED_TERMSr   r   hashlibmd5	hexdigestr   r   base64	b64encodedecoderf   )r   r   
start_timefinderr   found_image_databest_candidate_urlpager   candADULT_DOMAIN_PATTERNS	img_bytesimg_hash	mime_typeb64_strdurationr   rt   r   s                   @@@rQ   fetch_image_for_slider  	  s    JF
 !((b199#rBE KKME
KK!I;0q9:  a]]5]7
a	{'$xJ7HTU
 	NX\]D((5"%CHHWb)//1E s## 		I:>:::cAm^lAm>m>m9+-NsSVTVxjYZ %_!`J_```9+-Fs3BxjQR KK!I;jSb
#>?--c2Iy";;y1;;=??311KK!I;.R ST $- %("!!#x0I L c h  	&&z22I("--<y""#34;;GD99;+a	{"7~QGHyk'33
LL1YKDEFrT   c                  ,    [         R                  5         g)zClears the history file.N)r   r   r   rT   rQ   clear_used_imagesr  g  s    MMOrT   __main__z%Testing Storigo Image Generator v2...test_1z3professional modern office workspace with computerszResult length: )/r   osr_   r   r   r   r  loggingr  repathlibr   typingr   r   r   r   bs4r   urllib.parser	   r
   __file__resolveparentBASE_DIRSTORAGE_DIRmkdirr\   r   r  r   r   basicConfigINFO	getLoggerrb   rG   r   r   r   r  r  r   printresrd   r   rT   rQ   <module>r+     sN  	 
        	  , ,  - >!!#**77   4   44      
,,2
 
		<	(S" S"n 
` `L\S \ \QT \| z	
12
*_
`C	OCH3
45	 rT   