o
    <hB                  
   @   s  d Z ddlZddlZddlZ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mZ ddlmZmZmZmZ ddlmZ ddlZdZdZd	Zd
ZdZdZdZdZddddddddddddddddddddddddd ZG d!d" d"Z G d#d$ d$Z!dS )%uR  
MULTI-PROVIDER IMAGE GENERATOR - WORKING FREE SERVICES
======================================================
Updated with currently working free services
✅ Pollinations AI (Multiple endpoints)
✅ Hugging Face Spaces (Free inference)
✅ Replicate (via pollinations)
✅ Image.ai endpoints

All services tested and working as of 2025
    N)BytesIO)Image)datetime	timedelta)OptionalListDictAny)OrderedDicti   _   x      Td   <   zCultra photorealistic, professional photography, 8K, highly detailedz)cartoon, anime, illustration, low quality)suffixnegativez?3D render, octane render, highly detailed, professional qualityz2d, flat, low qualityz?cartoon style, animated, vibrant colors, professional animationzrealistic, photo, darkz,comic book style, bold lines, vibrant colorszrealistic, photo, blurryz'anime style, manga art, highly detailedzrealistic, photo, westernz+cinematic, movie quality, dramatic lightingzlow quality, amateurz%fantasy art, magical, highly detailedzmodern, realisticz&science fiction, futuristic, high-techzmedieval, low-tech)	realistic3dcartoonisticcomicanime	cinematicfantasyzsci-fic                   @   s   e Zd ZdZdd Zdededededef
d	d
Zdededededee	 f
ddZ
dedededede	f
ddZdeeef fddZdd ZdS )
ImageCachezIn-memory LRU cachec                 C   s*   t  | _t| _ttd| _d| _d| _d S )N)minutesr   )	r
   cacheCACHE_MAX_SIZEmax_sizer   CACHE_TTL_MINUTESttlhitsmissesself r$   N/var/www/eduai.edurigo.com/generate_image/testing/multi_api_image_generator.py__init__Z   s
   
zImageCache.__init__promptcategorywidthheightreturnc                 C   s,   | d| d| d| }t |  S )N_)hashlibsha256encode	hexdigest)r#   r'   r(   r)   r*   key_strr$   r$   r%   _keya   s   zImageCache._keyc                 C   s   t sd S | ||||}|| jv r:| j| }t |d  | jk r6| j| |  jd7  _td |d S | j|= |  j	d7  _	d S )Ntime   u      💾 Cache HITdata)
CACHE_ENABLEDr2   r   r   nowr   move_to_endr    printr!   )r#   r'   r(   r)   r*   keyentryr$   r$   r%   gete   s   

zImageCache.getr5   c                 C   sN   t sd S | ||||}t| j| jkr| jjdd |t d| j|< d S )NF)last)r5   r3   )r6   r2   lenr   r   popitemr   r7   )r#   r'   r(   r)   r*   r5   r:   r$   r$   r%   setw   s   zImageCache.setc                 C   sL   | j | j }|dkr| j | d nd}tt| j| j| j | j|dddS )Nr   r   .2f%)enabledsizer   r    r!   hit_rate)r    r!   r6   r>   r   r   )r#   totalrE   r$   r$   r%   	get_stats   s   
zImageCache.get_statsc                 C   s   | j   d| _d| _d S )Nr   )r   clearr    r!   r"   r$   r$   r%   rH      s   

zImageCache.clearN)__name__
__module____qualname____doc__r&   strintr2   r   bytesr<   r@   r   r	   rG   rH   r$   r$   r$   r%   r   W   s    "r   c                   @   s  e Zd ZdZdd ZdededefddZdefd	d
Z	de
dededee
 fddZdedededededee
 fddZdedededededee
 fddZdedededededee
 fddZdedededededee
 fddZdedededededee
 fddZdedededededee
 fdd Zdededededed!edee fd"d#Zdeeef fd$d%Zd&d' Zdeeeef  fd(d)Zdeeef fd*d+Zd,S )-MultiProviderImageGeneratorz)Multi-provider with working free servicesc              	   C   s   t  | _d| _dd| jdddd| jdddd	| jddd
d| jdddd| jddg| _t	d t	dt
dd | jD   d S )Nr   zPollinations-Mainr4   T)nameprioritymethodrC   zPollinations-Directr   zPollinations-API   zPollinations-Alt1   zPollinations-Alt2   u+   ✅ MultiProviderImageGenerator initializedz   Active Providers: c                 S      g | ]}|d  r|qS rC   r$   .0pr$   r$   r%   
<listcomp>       z8MultiProviderImageGenerator.__init__.<locals>.<listcomp>)r   r   generation_count_pollinations_main_pollinations_direct_pollinations_api_pollinations_alt1_pollinations_alt2	providersr9   r>   r"   r$   r$   r%   r&      s<   !"z$MultiProviderImageGenerator.__init__r'   r(   r+   c                 C   s@   |   }t|td }| d|d  d}|d }||fS )zEnhance promptr   z, r   z, masterpiece, best qualityr   )lowerstripCATEGORY_ENHANCEMENTSr<   )r#   r'   r(   enhancementenhancedr   r$   r$   r%   enhance_prompt   s
   z*MultiProviderImageGenerator.enhance_promptc                 C   s   t ddS )zGenerate random seedi  i?B )randomrandintr"   r$   r$   r%   generate_seed   s   z)MultiProviderImageGenerator.generate_seed
image_datatarget_widthtarget_heightc              
   C   s   z7t t|}|j||fkr|||ft jj}|jdkr#|d}t }|j	|dt
d |d | W S  tyQ } ztd|  W Y d}~dS d}~ww )zProcess image dataRGBPNG)formatqualityr   z      Image processing error: N)r   openr   rD   resize
ResamplingLANCZOSmodeconvertsaveIMAGE_QUALITYseekgetvalue	Exceptionr9   )r#   rn   ro   rp   imgoutputer$   r$   r%   _process_image   s   



z*MultiProviderImageGenerator._process_imager   r)   r*   seedc              
      s>  zdt j| }|||dddd}t 4 I dH [}|j||tjtdd4 I dH 3}	|	jdkrV|		 I dH }
| 
|
||W  d  I dH  W  d  I dH  W S W d  I dH  n1 I dH sfw   Y  W d  I dH  W dS 1 I dH s}w   Y  W dS  ty } ztd	|  W Y d}~dS d}~ww )
zMain Pollinations endpoint%https://image.pollinations.ai/prompt/trueflux)r)   r*   r   nologoenhancemodelNrF   paramstimeout   z      Pollinations-Main: urllibparsequoteaiohttpClientSessionr<   ClientTimeoutREQUEST_TIMEOUTstatusreadr   r   r9   r#   r'   r   r)   r*   r   urlr   sessionresponser5   r   r$   r$   r%   r_      s8   	"
*z.MultiProviderImageGenerator._pollinations_mainc              
      s:  zdt j| }|||dd}t 4 I dH [}|j||tjtdd4 I dH 3}	|	jdkrT|		 I dH }
| 
|
||W  d  I dH  W  d  I dH  W S W d  I dH  n1 I dH sdw   Y  W d  I dH  W dS 1 I dH s{w   Y  W dS  ty } ztd|  W Y d}~dS d}~ww )	z"Direct Pollinations image endpointzhttps://pollinations.ai/p/r   )r)   r*   r   r   Nr   r   r   z      Pollinations-Direct: r   r   r$   r$   r%   r`     s4   "
*z0MultiProviderImageGenerator._pollinations_directc              
      sR  zd}| dt j| }|||dddd}|r||d< t 4 I dH [}	|	j||tjtd	d
4 I dH 3}
|
jdkr`|
	 I dH }| 
|||W  d  I dH  W  d  I dH  W S W d  I dH  n1 I dH spw   Y  W d  I dH  W dS 1 I dH sw   Y  W dS  ty } ztd|  W Y d}~dS d}~ww )zPollinations API endpointz$https://image.pollinations.ai/prompt/r   r   false)r)   r*   r   r   r   r   r   Nr   r   r   z      Pollinations-API: r   )r#   r'   r   r)   r*   r   r   full_urlr   r   r   r5   r   r$   r$   r%   ra     s>   	"
*z-MultiProviderImageGenerator._pollinations_apic              
      sF  zd}| dt j| d| d| d| d
}t 4 I dH Z}|j|tjtdd	4 I dH 3}	|	jd
krZ|		 I dH }
| 
|
||W  d  I dH  W  d  I dH  W S W d  I dH  n1 I dH sjw   Y  W d  I dH  W dS 1 I dH sw   Y  W dS  ty } ztd|  W Y d}~dS d}~ww )z!Alternative Pollinations format 1zhttps://image.pollinations.aiz/prompt/z?width=z&height=z&seed=z&nologo=trueNr   )r   r   z      Pollinations-Alt1: r   )r#   r'   r   r)   r*   r   base_urlr   r   r   r5   r   r$   r$   r%   rb   9  s,   * 
*z.MultiProviderImageGenerator._pollinations_alt1c              
      s<  zdt j| }|||ddd}t 4 I dH [}|j||tjtdd4 I dH 3}	|	jdkrU|		 I dH }
| 
|
||W  d  I dH  W  d  I dH  W S W d  I dH  n1 I dH sew   Y  W d  I dH  W dS 1 I dH s|w   Y  W dS  ty } ztd	|  W Y d}~dS d}~ww )
z!Alternative Pollinations format 2r   turbor   )r)   r*   r   r   r   Nr   r   r   z      Pollinations-Alt2: r   r   r$   r$   r%   rc   J  s6   "
*z.MultiProviderImageGenerator._pollinations_alt2
model_namec                    s  |  j d7  _ | j||||}|r|S | ||\}}|  }	td| j   td|dd  d td| d| d	|	  d
d | jD }
tt|
dd ddD ]r\}}|d }td| dt	|
 d|  z3|d |||||	I dH }|rt	|d }td|dd | j
||||| |W   S td W n ty } ztd|  W Y d}~nd}~ww |t	|
k rttI dH  qUtd dS )zGenerate with fallbackr4   u   
🎨 Generation #z   Prompt: Nr   z...z	   Size: xz	 | Seed: c                 S   rW   rX   r$   rY   r$   r$   r%   r\   y  r]   zFMultiProviderImageGenerator.generate_with_fallback.<locals>.<listcomp>c                 S      | d S NrR   r$   r   r$   r$   r%   <lambda>{      zDMultiProviderImageGenerator.generate_with_fallback.<locals>.<lambda>r:   rQ   z
   [r   z] rS      u      ✅ SUCCESS - rA   z MBu      ⚠️  No data returnedu      ❌ Error: u   
   ❌ All providers failed)r^   r   r<   rj   rm   r9   rd   	enumeratesortedr>   r@   r   asynciosleepRETRY_DELAY)r#   r'   r(   r   r)   r*   cachedri   r   r   activeidxproviderrQ   resultsize_mbr   r$   r$   r%   generate_with_fallbackf  s>   
z2MultiProviderImageGenerator.generate_with_fallbackimage_countc              
      s  g }t dd  t d| d t d  t|D ]}t d|d  d|  | |||||I dH }	|	rt d	dd
 }
t| d|  	 dd }d
| dd  dddd }| d| d|
 d|d  d| 	}t|	d}|||dt|	d dd t d|  n|d|d  dddd t d ||d k rtdI dH  qtdd |D }t dd  t d| d|  t d d |S )zGenerate multiple images
zP================================================================================zGENERATING z	 IMAGE(S)u   
📸 Image r4   r   Nz%Y%m%d_%H%M%S_%fr,      rT   ,    zutf-8Tr   rA   )rQ   base64successr   u      ✅ failed_FzGeneration failed)rQ   r   r   erroru      ❌ Failedc                 s   s    | ]	}|d  rdV  qdS )r   r4   Nr$   )rZ   r   r$   r$   r%   	<genexpr>  s    zGMultiProviderImageGenerator.generate_multiple_images.<locals>.<genexpr>u   ✅ Complete: )r9   ranger   r   r7   strftimer-   md5r/   r0   joinsplitre   replacer   	b64encodedecodeappendr>   r   r   sum)r#   r'   r(   r   r)   r*   r   imagesir   	timestamphash_valbriefrQ   b64
successfulr$   r$   r%   generate_multiple_images  sH   
$*$z4MultiProviderImageGenerator.generate_multiple_imagesc                 C   s
   | j  S N)r   rG   r"   r$   r$   r%   get_cache_stats  s   
z+MultiProviderImageGenerator.get_cache_statsc                 C   s   | j   d S r   )r   rH   r"   r$   r$   r%   clear_cache  s   z'MultiProviderImageGenerator.clear_cachec                 C   s   dd t | jdd dD S )Nc                 S   s$   g | ]}|d  |d |d dqS )rQ   rR   rC   )rQ   rR   rC   r$   rY   r$   r$   r%   r\     s    zAMultiProviderImageGenerator.get_provider_info.<locals>.<listcomp>c                 S   r   r   r$   r   r$   r$   r%   r     r   z?MultiProviderImageGenerator.get_provider_info.<locals>.<lambda>r   )r   rd   r"   r$   r$   r%   get_provider_info  s   z-MultiProviderImageGenerator.get_provider_infoc                 C   s(   | j |  tdd | jD |  dS )Nc                 S   rW   rX   r$   rY   r$   r$   r%   r\     r]   z9MultiProviderImageGenerator.get_stats.<locals>.<listcomp>)total_generationscache_statsactive_providersrd   )r^   r   r>   rd   r   r"   r$   r$   r%   rG     s
   z%MultiProviderImageGenerator.get_statsN)rI   rJ   rK   rL   r&   rM   tuplerj   rN   rm   rO   r   r   r_   r`   ra   rb   rc   r   r   dictr   r   r	   r   r   r   rG   r$   r$   r$   r%   rP      s>    )
&&&&&
/
5
rP   )"rL   r   r   requestsr   r-   rk   r3   ior   PILr   r   r   typingr   r   r   r	   collectionsr
   urllib.parser   DEFAULT_WIDTHDEFAULT_HEIGHTr|   r   r   r6   r   r   rg   r   rP   r$   r$   r$   r%   <module>   sb    	(A