U
    oh.$                    @   s  d Z ddlZddlZddlZddlZddlmZmZmZm	Z	 ddl
m
Z
m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ZddlZddlmZ ddlmZ ddlmZmZmZmZ ddl m!Z!m"Z"m#Z#m$Z$m%Z%m&Z& dd	l'm(Z( dd
l)m*Z*m+Z+m,Z, ddl-m.Z. ddl/m0Z0 e.  ej1dej2e3 ej4dddgd e5e6Z7e5d8ej2 e5d8ej2 e5d8ej2 G dd dZ9dd Z:e6dkre:  dS )uk   
Nano Banana Telegram Bot с генерацией изображений через Gemini 2.5 Flash Image
    N)ListDictAnyOptional)datetime	timedelta)AudioSegment)Image)UpdateMessageInlineKeyboardButtonInlineKeyboardMarkup)ApplicationCommandHandlerMessageHandlerContextTypesCallbackQueryHandlerfilters)	ParseMode)TelegramErrorNetworkErrorTimedOut)load_dotenv)ConfigzN%(asctime)s - %(name)s - %(levelname)s - %(funcName)s:%(lineno)d - %(message)sznano_banana_bot.logutf-8)encoding)formatlevelZhandlerstelegramZhttpxaiohttpc                   @   s  e Zd Zdd ZeejedddZeejdddZ	dAeeje
dd
dZdBeejedddZdCeejedddZdDeejdddZeejdddZe
e
dddZdd Ze
ee
ef dddZdEe
eej ee
ef dddZeejd	dd d!Zeejd	dd"d#Zeejd	dd$d%Zeejd	dd&d'Zejd	d(d)d*Zeeje
d	d+d,d-Zeejd	dd.d/Zeejd	dd0d1Z eeje
d	d2d3d4Z!eejd	dd5d6Z"ejd	d(d7d8Z#ee
 e
ee
ef d9d:d;Z$dFee%d<d=d>Z&d?d@ Z'd	S )GNanoBananaBotc              
   C   s,  t d t dtddd d  d t dtddd d  d d	| _d	| _i | _d
| _ddg| _	t
 st d tdt
j| _t
j| _t
j| _|   ztj| jd d | _W n8 tk
r } zt d|  d | _W 5 d }~X Y nX tjt
jdd i | _i | _i | _t d d S )Nu2   🤖 ИНИЦИАЛИЗАЦИЯ NANO BANANA BOT...u   🔑 Токен бота: TELEGRAM_BOT_TOKENu   НЕ НАЙДЕН   ...u   🔑 Gemini ключ: ZNANO_BANANA_KEYz@MagomedNaurbiev
   valeri_lookZ	naurbievmu*   ❌ Ошибка конфигурации!ub   Ошибка конфигурации. Проверьте переменные окружения.)Zapi_keyu/   ⚠️ Google Gemini API недоступен: T)exist_oku@   🤖 NanoBananaBot инициализирован успешно)loggerinfodebugosgetenvrequired_channelrequired_channel_iddaily_limitsmax_generations_per_dayexempt_usersr   Zvalidateerror
ValueErrorr!   	bot_tokenZNANO_BANANA_API_URLZnano_banana_urlZNANO_BANANA_API_KEYnano_banana_keysetup_proxygenaiZ	configureZmodel	ExceptionwarningmakedirsTEMP_PHOTOS_DIRlast_generationsuser_albumswaiting_for_modification)selfe r@   =/var/www/u0236315/data/www/consultsolution.ru/telegram_bot.py__init__<   s4    
""


zNanoBananaBot.__init__)user_idcontextreturnc              
      s   z||j |I dH }t|dd}dg}|rN| |krNtd| d W dS |j | j|I dH }|jdkrtW dS W dS W n> t	k
r } z t
d	| d
|  W Y dS d}~X Y nX dS )uc   Проверка подписки пользователя на обязательный каналNusernamer%      ✅ Пользователь @uE    в списке исключений - доступ разрешенT)memberZadministratorZcreatorFuS   ❌ Ошибка проверки подписки для пользователя : )botZget_chatgetattrlowerr'   r(   Zget_chat_memberr-   Zstatusr7   r1   )r>   rC   rD   userrF   r0   rH   r?   r@   r@   rA   check_subscriptionh   s    

z NanoBananaBot.check_subscription)rC   rD   c                    s^   t tdd| jdd  dgtdddgg}d	| j d
}|jj|||tjdI dH  dS )uV   Отправляет сообщение о необходимости подписки+   📢 Подписаться на каналhttps://t.me/   Nurl'   ✅ Проверить подпискуrN   callback_datau   🔒 **Доступ ограничен**

Для использования бота необходимо подписаться на канал:
👉 **u  **

После подписки нажмите кнопку "Проверить подписку" ниже.

🎨 **Что вас ждет после подписки:**
• Генерация изображений по тексту
• Создание изображений по фото-референсам  
• Модификация существующих изображений
• Работа с альбомами фотографий)chat_idtextreply_markup
parse_mode)r   r   r,   rJ   send_messager   MARKDOWN)r>   rC   rD   keyboardmessager@   r@   rA   "send_subscription_required_message   s    z0NanoBananaBot.send_subscription_required_messageNc                 C   s   zl|r t |dr |jr |jjW S t |drH|jrHt |jdrH|jjjW S t |drhd|jkrh|jd W S W dS    Y dS X dS )u2   Получает username пользователяeffective_userupdate	user_datarF   N)hasattrr`   rF   ra   rb   )r>   rC   rD   ra   r@   r@   rA   get_user_username   s    
zNanoBananaBot.get_user_usernamec              
   C   s   z^|  |||}|r:| | jkr:td| d W dS |dkrZtd| d W dS W dS  tk
r } z td| d	|  W Y dS d
}~X Y nX d
S )uY   Проверяет, является ли пользователь исключениемrG   u2    найден в списке исключенийTi[   ✅ Пользователь u:    найден в списке исключений по IDFuW   ❌ Ошибка проверки исключения для пользователя rI   N)rd   rL   r0   r'   r(   r7   r1   )r>   rC   rD   ra   rF   r?   r@   r@   rA   is_user_exempt   s    zNanoBananaBot.is_user_exemptc              
   C   s  z|  |||r(td| d W dS ddlm} | d}|| jkr\|dd| j|< | j| d |kr~|dd| j|< | j| d	 }|| jkrtd
| d| d| j  W dS W dS  tk
 r } z t	d| d|  W Y dS d}~X Y nX dS )u[   Проверяет, не превышен ли дневной лимит генерацийre   uP    в списке исключений - лимиты не применяютсяTr   r   %Y-%m-%ddatecountrj   rk      🚫 Пользователь u-    превысил дневной лимит: /FuO   ❌ Ошибка проверки лимита для пользователя rI   N)
rf   r'   r(   r   nowstrftimer.   r/   r7   r1   )r>   rC   rD   ra   r   todayZcurrent_countr?   r@   r@   rA   check_daily_limit   s$    

zNanoBananaBot.check_daily_limitc              
   C   s   z|  |||rW dS ddlm} | d}|| jkrJ|dd| j|< | j| d |krl|dd| j|< | j| d  d7  < td	| d
| j| d  d| j d W n8 tk
r } zt	d| d
|  W 5 d}~X Y nX dS )uX   Увеличивает счетчик генераций для пользователяNr   rg   rh   ri   rj   rk   rQ   u   📊 Пользователь rI   rm   u"    генераций сегодняuS   ❌ Ошибка обновления лимита для пользователя )
rf   r   rn   ro   r.   r'   r(   r/   r7   r1   )r>   rC   rD   ra   r   rp   r?   r@   r@   rA   increment_daily_limit   s    
.z#NanoBananaBot.increment_daily_limitc                    s2   d| j  d| j d}|jj||ddI dH  dS )uL   Отправляет сообщение о превышении лимитаu]   🚫 <b>Дневной лимит превышен</b>

Вы использовали все u    генераций на сегодня.

⏰ <b>Лимит обновится завтра</b>
🔄 <b>Попробуйте снова после 00:00</b>

💡 <b>Совет:</b> Подпишитесь на канал uY    для получения уведомлений о новых возможностях!HTMLrW   rX   rZ   N)r/   r,   rJ   r[   )r>   rC   rD   r^   r@   r@   rA   send_limit_exceeded_message   s    	z)NanoBananaBot.send_limit_exceeded_message)voice_file_pathrE   c           	   
      s.  zt d|  t }t|}|dd}|j|dd t|}|	|}W 5 Q R X |j
|dd}tj|rt| t d|  |W S  tjk
r   t d	 Y d
S  tjk
r } zt d|  W Y d
S d
}~X Y n: tk
r( } zt d|  W Y d
S d
}~X Y nX d
S )uJ   Преобразует голосовое сообщение в текстuO   🎤 Начинаем преобразование голоса в текст: .oggz.wavZwavr   zru-RU)ZlanguageuF   ✅ Голос успешно преобразован в текст: u5   ❌ Не удалось распознать речьNuE   ❌ Ошибка сервиса распознавания речи: uQ   ❌ Ошибка при преобразовании голоса в текст: )r'   r(   srZ
Recognizerr   Z	from_filereplaceZexportZ	AudioFilerecordZrecognize_googler*   pathexistsremoveZUnknownValueErrorr1   ZRequestErrorr7   )	r>   rv   Z
recognizerZaudioZwav_pathsourceZ
audio_datarX   r?   r@   r@   rA   convert_voice_to_text  s,    


z#NanoBananaBot.convert_voice_to_textc              
   C   sd  z"t jrdt j dt j dt j dt j }|tjd< |tjd< t	 | _
||d| j
_| j
jddd	d
ddd d| _td zR| j
jddd}|jdkr| }td|dd  ntd|j  W n4 tk
r } ztd|  W 5 d}~X Y nX ntd d| _
W n: tk
r^ } ztd|  d| _
W 5 d}~X Y nX dS )u_   Настройка прокси для обхода блокировки Google в Россииzhttp://:@Z
HTTP_PROXYZHTTPS_PROXY)ZhttpZhttpszapplication/jsonz:Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0zen-US,en;q=0.9zhttps://aistudio.google.comzhttps://aistudio.google.com/z185.199.108.153)zContent-Typez
User-AgentzAccept-LanguageZOriginZRefererzX-Forwarded-Forz7https://generativelanguage.googleapis.com/v1beta/modelsuI   ✅ Прокси настроен успешно для Google Gemini APIzhttps://httpbin.org/ipr$   )timeout   u'   ✅ Прокси работает! IP: originu   неизвестноu8   ⚠️ Прокси тест вернул статус: uF   ⚠️ Не удалось протестировать прокси: Nu>   🔍 Прокси отключен в конфигурацииu2   ❌ Ошибка настройки прокси: )r   Z	USE_PROXYZPROXY_LOGINZ
PROXY_PASSZPROXY_SERVERZ
PROXY_PORTr*   environrequestsZSessiongemini_sessionZproxiesZheadersra   gemini_base_urlr'   r(   getstatus_codejsonr8   r7   r1   )r>   Z	proxy_urlZtest_responseZip_infoZproxy_test_errorr?   r@   r@   rA   r5   3  s@    $



	

$

zNanoBananaBot.setup_proxy)promptrE   c              
   C   sD  z| j stdtd|  dd| ig}d|igdddd	}| j d
| j }| j j||dd}|jdkr|| }td d|krp|d rp|d d }d|krpd|d krp|d d D ]}d|kr<|d 	dd
dr<|d 	d}	|	rbtdt|	 d d|	d| d|d  W S qd|krtd|d dd  d  qd!d"d#W S d!d"d#W S |j}
td$|j d%|
  |jd&krd!d'd#W S |jd(krd!d)d#W S |jd*krd!d+d#W S d!d,|j d#W S W nF tk
r> } z&td-|  d!t|d# W Y S d}~X Y nX dS ).uO   Генерация изображения через Gemini 2.5 Flash Image API5   HTTP клиент не инициализированuR   🎨 Генерация изображения через Gemini 2.5 Flash Image: rX   z*Create a detailed, high-quality image of: partsffffff?i   ZtemperatureZmaxOutputTokenscontentsZgenerationConfig,/gemini-2.5-flash-image:generateContent?key=x   r   r   r   A   🔍 Полный ответ от Gemini Image API получен
candidatesr   content
inlineDatamimeType image/datau;   ✅ Изображение получено! Размер:     символов base64TuQ   🎨 Изображение сгенерировано по запросу:
<b>«   »</b>success
image_datagenerated_textoriginal_prompt$   📝 Текстовый ответ: Nd   r#   F   Не удалось сгенерировать изображение. Попробуйте еще раз и запросите немного иначеr   r1   u#   ❌ Ошибка Gemini Image API: z - i  u9   Некорректный запрос к Gemini Image APIi  uS   Доступ к Gemini Image API запрещен (проверьте API ключ)i  u@   Превышен лимит запросов к Gemini Image APIu   Ошибка Gemini Image API: uN   ❌ Ошибка генерации изображения через Gemini: )r   r7   r'   r(   r   r4   postr   r   r   
startswithlenrX   r1   str)r>   r   r   request_datarS   responseresult	candidatepartr   Z
error_textr?   r@   r@   rA   generate_image_with_gemini`  st    	
"
 
z(NanoBananaBot.generate_image_with_gemini)r   imagesrE   c              
   C   s  zb| j stdd|ig}|rl|D ]F}t }|j|dd | }t|d}|	dd|di q$d	|igd
ddd}| j
 d| j }	| j j|	|dd}
|
jdkrF|
 }d|kr:|d r:|d d }d|kr:d	|d kr:g }|d d	 D ]}d|kr|	|d  q|r:dd|dW S dddW S dd|
j d|
j dW S W nF tk
r } z&td|  dt|d W Y S d}~X Y nX dS )uP   Прямой вызов Gemini API для анализа через проксиr   rX   ZJPEGrx   r   inline_data
image/jpegZ	mime_typer   r   r   i   r   r   z*/gemini-2.0-flash-exp:generateContent?key=<   r   r   r   r   r   T
)r   rX   Fu    Пустой ответ от APIr   HTTP rI   u9   ❌ Ошибка прямого вызова Gemini API: N)r   r7   ioBytesIOZsavegetvaluebase64	b64encodedecodeappendr   r4   r   r   r   joinrX   r'   r1   r   )r>   r   r   r   Zimagebufferr   image_base64r   rS   r   r   r   Z
text_partsr   r?   r@   r@   rA   call_gemini_api_direct  s^    
	
z$NanoBananaBot.call_gemini_api_direct)ra   rD   rE   c           	   
      sf  |j j}|j jpd}td| d| d | ||I dH }|sptd| d| j  | ||I dH  dS zd}tj	
|rt|d	$}|jj|td
ddI dH  W 5 Q R X td| d n.|jjtd
ddI dH  td| d W nf tk
r. } ztd|  W 5 d}~X Y n4 tk
r` } ztd|  W 5 d}~X Y nX dS )uQ   Обработчик команды /start с проверкой подпискиu   Пользователь   👤 Пользователь z (u   ) запустил ботаN   🔒 Пользователь '    не подписан на канал z7/var/www/u0236315/data/www/consultsolution.ru/logo.jpegrbwelcomers   )photocaptionrZ   re   uG    подписан - доступ разрешен с логотипом)rZ   uT    подписан - доступ разрешен (логотип не найден)uX   Ошибка при отправке приветственного сообщения: u6   Неожиданная ошибка в start_command: )r`   idZ
first_namer'   r(   rN   r,   r_   r*   r|   r}   openr^   Zreply_photor   get_message
reply_textr   r1   r7   )	r>   ra   rD   rC   Z	user_nameis_subscribedZ	logo_pathZ	logo_filer?   r@   r@   rA   start_command  s0     zNanoBananaBot.start_commandc           	   
      s  |j j}|jj }td| d|  | ||I dH }|sntd| d| j  | 	||I dH  dS | 
|||std| d | ||I dH  dS td|  td	| j|d
  || jkr| j| rtd| d | |||I dH  dS td|  |jj|ddI dH }td|j  z\td|  | |}td|dd
 d|dd  | |||||I dH  W nP tk
r } z0tjd| dd |d| dI dH  W 5 d}~X Y nX dS )uf   Обработчик текстовых сообщений - генерация изображенийu?   💬 ПОЛУЧЕН ЗАПРОС от пользователя rI   Nr   r   rl   >    превысил дневной лимит генерацийu'   📝 Полный объект update: uE   🔍 Проверяем состояние waiting_for_modification: F   🔄 Пользователь u'    в режиме модификацииu`   🎨 Начинаем генерацию изображения для пользователя `   🎨 Генерирую изображение...
⏳ Скоро пришлю результатrW   rX   uQ   📤 Отправлено сообщение о начале обработки: uF   🚀 Вызываем generate_image_with_gemini с промптом: 4   📊 Результат генерации: success=r   , error=r1   NoneuZ   ❌ КРИТИЧЕСКАЯ ОШИБКА при генерации изображения: Texc_infou<   ❌ Произошла критическая ошибка: ua   

Попробуйте еще раз или обратитесь к администратору.)r`   r   r^   rX   stripr'   r(   rN   r,   r_   rq   ru   r)   r=   r   handle_modification_promptrJ   r[   
message_idr   send_generation_resultr7   r1   	edit_text)	r>   ra   rD   rC   rX   r   processing_messager   r?   r@   r@   rA   handle_text_message!  s@    
&z!NanoBananaBot.handle_text_messagec              
      sb  |j j}|jj}td|  | ||I dH }|sdtd| d| j  | ||I dH  dS | 	|||std| d | 
||I dH  dS |jj|ddI dH   fd	d
}t|  zB|j|jI dH }d| dtt  d}||I dH  td|  | |I dH }	tj|rBt| |	s^ dI dH  W dS td|	  || jkr| j| rtd| d | |||	I dH  W dS  dI dH  | |	}
td|
dd d|
dd  | ||
 ||I dH  W nP t k
r\ } z0tj!d| dd  d| dI dH  W 5 d}~X Y nX dS )u   Обработчик голосовых сообщений - преобразование в текст и генерация изображенийuZ   🎤 ПОЛУЧЕНО ГОЛОСОВОЕ СООБЩЕНИЕ от пользователя Nr   r   rl   r   us   🎤 Обрабатываю голосовое сообщение...
⏳ Скоро пришлю результатr   c               
      sZ   t dI d H  z  I d H  W n2 tk
rT }  ztd|   W 5 d } ~ X Y nX d S )N   uJ   Не удалось удалить сообщение обработки: )asynciosleepdeleter7   r'   r)   )r?   r   r@   rA   delete_processing_messagen  s
    zENanoBananaBot.handle_voice_message.<locals>.delete_processing_messagez/tmp/voice__rw   u;   📥 Голосовое сообщение скачано: u   ❌ Не удалось распознать голосовое сообщение. Попробуйте еще раз или отправьте текстовое описание.u*   📝 Распознанный текст: r   u4    в режиме модификации (голос)r   r   r   Fr   r1   r   uk   ❌ КРИТИЧЕСКАЯ ОШИБКА при обработке голосового сообщения: Tr   uc   ❌ Произошла критическая ошибка при обработке голоса: uc   

Попробуйте еще раз или отправьте текстовое описание.)"r`   r   r^   voicer'   r(   rN   r,   r_   rq   ru   rJ   r[   r   Zcreate_taskget_filefile_idinttimedownload_to_driver   r*   r|   r}   r~   r   r=   r   r   r)   r   r   r7   r1   )r>   ra   rD   rC   r   r   r   Z
voice_fileZ
voice_pathrX   r   r?   r@   r   rA   handle_voice_messageS  sR    

&z"NanoBananaBot.handle_voice_messagec              	      s  |j }| I dH  |jj}|j}|dkr| ||I dH }|rt|jdtd t	j
dI dH  td| d n`|jd| j d	ttd
d| jdd  dgtdddggt	j
dI dH  td| d dS |dr| ||I dH }|s| ||I dH  dS || jkrd| j|< |jj|dddI dH }|jj| jd||jdd| d|j d td| d n|jj|dd I dH  dS )!u5   Обработчик нажатий на кнопкиNrN   uD   ✅ **Отлично! Подписка подтверждена.**

r   )rX   rZ   re   u&    подтвердил подпискуu   ❌ **Подписка не найдена**

Пожалуйста, убедитесь, что вы подписались на канал:
👉 **up   **

После подписки нажмите кнопку "Проверить подписку" еще раз.rO   rP   rQ   rR   rT   rU   )rX   rY   rZ   u   ❌ Пользователь u.    не подписан при проверкеmodify_Tu   ⚡ <b>Режим изменения активирован</b>

📝 Напишите, как изменить изображение или отправьте новое фото с подписьюrs   rt      rW   r   Zdelete_system_msg_r   Zwhenr   namer   u;    запросил изменение изображенияu   ❌ Не найдено изображение для изменения. Сначала сгенерируйте изображение.r   )callback_queryZanswer	from_userr   r   rN   Zedit_message_textr   r   r   r\   r'   r(   r,   r   r   r   r_   r;   r=   rJ   r[   	job_queuerun_oncedelete_system_messager   )r>   ra   rD   ZqueryrC   rV   r   Zsystem_messager@   r@   rA   handle_button_callback  s^    

z$NanoBananaBot.handle_button_callback)rD   rE   c              
      sv   z>|j j}|jj|d |d dI dH  td|d   W n2 tk
rp } ztd|  W 5 d}~X Y nX dS )u4   Удаляет системное сообщениеrW   r   r   Nu]   🗑️ Системное сообщение удалено для пользователя uJ   Не удалось удалить системное сообщение: )jobr   rJ   Zdelete_messager'   r(   r7   r)   )r>   rD   job_datar?   r@   r@   rA   r     s    z#NanoBananaBot.delete_system_message)ra   rD   
new_promptrE   c              
      s  |j j}|| jkr2|jdI dH  d| j|< dS d| j|< | j| }|dd}|dd}|jdI dH }zddl}	d}
zt|}|	jdd
d}|| |j}
W 5 Q R X td|
  d| d| d| d| }td|  | |
g|I dH }|d r&d| |d< ||d< | |||||I dH  td| d|  W 5 |
rtj	
|
rt|
 td	|
  X W nD tk
r } z$td|  |dI dH  W 5 d}~X Y nX dS )ue   Обработчик нового промпта для модификации изображенияI   ❌ Не найдено изображение для изменения.NFr   r   r   \   🔄 Изменяю изображение...
⏳ Скоро пришлю результатr   2   🗑️ Временный файл удален: .jpgr   suffixuW   💾 Сохранено текущее изображение как референс: zTASK: MODIFY the provided reference image (do NOT create a new one)

REFERENCE IMAGE: This is the current image that needs to be modified
MODIFICATION REQUEST: z
ORIGINAL CONTEXT: z

INSTRUCTIONS:
1. Use the reference image as the BASE - keep the same people, objects, and overall scene
2. Apply ONLY the requested modification: a9  
3. Maintain the same style, lighting, and composition from the reference
4. Keep all people and objects in similar positions unless specifically asked to change them
5. Do NOT create a completely different image - MODIFY the existing one

The result should look like the original image with the specific change: u1   🔄 Промпт для модификации: r   uB   🔄 Изображение изменено по запросу: r   uL   ✅ Изображение изменено для пользователя rI   uG   ❌ Ошибка при модификации изображения: y   ❌ Произошла ошибка при изменении изображения. Попробуйте еще раз.)r`   r   r;   r^   r   r=   r   tempfiler*   r|   r}   r~   r'   r(   r   	b64decodeNamedTemporaryFilewriter   generate_image_from_referencer   r7   r1   r   )r>   ra   rD   r   rC   last_genr   current_image_datar   r  Ztemp_image_pathimage_bytes	temp_filemodification_promptr   r?   r@   r@   rA   r     sV    








z(NanoBananaBot.handle_modification_promptc                    s   |j j}|j}| ||I dH }|sRtd| d| j  | ||I dH  dS | |||std| d | 	||I dH  dS |j
rtd|j
  | ||I dH  ntd | ||I dH  dS )u   Универсальный обработчик фотографий - проверяет альбом или одиночное фотоNr   r   rl   r   u;   📸 Фото является частью альбома u1   📸 Получено одиночное фото)r`   r   r^   rN   r'   r(   r,   r_   rq   ru   media_group_idhandle_media_grouphandle_photo)r>   ra   rD   rC   r^   r   r@   r@   rA   handle_photo_with_album_check@  s     
z+NanoBananaBot.handle_photo_with_album_checkc              
      s  |j j}|j}|j}|r | s\|| jkrH| j| rH|dI dH  dS |dI dH  dS || jkr| j| r| ||| I dH  dS t	d| d |dI dH }z|j
d  I dH }tj d| d	t  d
}||I dH  t	d|  | |g| I dH }	| ||	|||I dH  zt| t	d|  W n: tk
r }
 ztd| d|
  W 5 d}
~
X Y nX W nD tk
r }
 z$td|
  |dI dH  W 5 d}
~
X Y nX dS )u   Обработчик одиночных фотографий - генерация изображений на основе референсовu  📝 Для изменения изображения на основе нового фото, добавьте подпись с описанием изменений.

**Пример:** Отправьте фото + "изменить позу как на этом фото"Nu  📝 Пожалуйста, добавьте подпись к фотографии с описанием того, что вы хотите сгенерировать.

🎨 **Пример:** Отправьте фото кота с подписью "красивый кот в космосе" - и бот сгенерирует новое изображение в этом стиле!uP   📸 Получено одиночное фото от пользователя u    для генерацииr   rm   _ref_r  u5   📸 Референсное фото скачано: r  u)   Ошибка удаления файла rI   uD   ❌ Ошибка при генерации по референсу: uy   ❌ Произошла ошибка при генерации изображения. Попробуйте еще раз.)r`   r   r^   r   r   r=   r   handle_photo_modificationr'   r(   r   r   r   r:   r   r   r
  r   r*   r~   r7   r1   r   )r>   ra   rD   rC   r^   r   r   
photo_file
photo_pathr   r?   r@   r@   rA   r  Z  s:    
,zNanoBananaBot.handle_photo)ra   rD   modification_textrE   c                    s  |j j}|j}|| jkr6|dI dH  d| j|< dS d| j|< | j| }|dd}|dI dH }z`|jd  I dH }	t	j
 d| d	t  d
}
|	|
I dH  td|
  ddl}d}zt|}|jdd
d}|| |j}W 5 Q R X td|  d| d| d}| ||
g|I dH }|d rTd| |d< ||d< | |||||I dH  td| d|  W 5 ||
fD ]4}|rtj|rt| td|  qX W nD tk
r } z$td|  |dI dH  W 5 d}~X Y nX dS )u   Обработчик модификации изображения с использованием нового фото как референсаr   NFr   r   r   r  rm   Z	_new_ref_r  u/   📸 Новый референс скачан: r   r  r  u?   💾 Сохранено текущее изображение: a!  TASK: Naturally modify the first image based on the description and inspiration from the second image.

CURRENT IMAGE: The first image shows the current scene that needs to be modified
REFERENCE PHOTO: The second image provides style inspiration and visual reference
MODIFICATION REQUEST: z

INSTRUCTIONS:
1. Keep the same people, objects, and overall composition from the first image
2. Apply the requested modification: ar  
3. Use the second image only as style/mood/lighting inspiration, NOT for copy-pasting elements
4. Make natural, realistic changes that flow with the original scene
5. Maintain visual consistency and natural lighting
6. The result should look like a natural evolution of the first image, not a collage

Create a harmonious, naturally modified version of the first image.r   uQ   🔄 Изображение изменено с новым референсом: r   r   uo   ✅ Изображение изменено с новым референсом для пользователя rI   uS   ❌ Ошибка при модификации с новым референсом: r  )r`   r   r^   r;   r   r=   r   r   r   r   r:   r   r   r'   r(   r  r*   r|   r}   r~   r   r  r  r	  r   r
  r   r7   r1   r   )r>   ra   rD   r  rC   r^   r  r  r   r  Znew_ref_pathr  Zcurrent_image_pathZ	temp_pathr  r  r  r   r?   r@   r@   rA   r    sV    








z'NanoBananaBot.handle_photo_modificationc              	      s  |j }|jj}|j}td| d|  t| ds:i | _|| jkrNi | j|< || j| krg dt	 dd| j| |< td| d|  | j| | }|j
r|j
d	 j|j
d	 jd
}|d | td|d   |jr|j|d< td|j  td| dt|d  d|d   |d sd| d| }|j|}	|	D ]}
|
  td qT|jj| jd||d|d td| d dS )uT   Обработчик альбомов фотографий для генерацииuQ   📸 Получено фото из альбома от пользователя z, media_group_id: r<   r   F)photosr   	timestamp	processedu*   🆕 Создан новый альбом !    для пользователя r  )r   file_unique_idr  u2   📸 Добавлено фото в альбом: r  r   u>   📝 Сохранена подпись для альбома: u6   📊 Текущее состояние альбома rI   u    фото, обработан: r  Zprocess_ref_album_r   u\   🗑️ Отменена предыдущая задача обработки альбомаr   )rC   r  r   uA   ⏰ Запланирована обработка альбома u    через 3 секундыN)r^   r   r   r  r'   r(   rc   r<   r   rn   r   r   r  r   r   r   r   Zget_jobs_by_nameZschedule_removalr   process_reference_album)r>   ra   rD   r^   rC   r  album
photo_infoZjob_nameZcurrent_jobsr   r@   r@   rA   r    sN    





(
z NanoBananaBot.handle_media_groupc                    s  |j j}|d }|d }td| d|  || jksF|| j| krbtd| d| d dS | j| | }tdt|d	  d
|d  d|d   |d rtd| d dS d|d< |d  s|jj	|ddI dH  | j| |= dS |jj	|ddI dH }z
zg }t|d	 D ]v\}	}
|j|
d I dH }tj d| d|	 dt  d}||I dH  || td|	d  d|  q | ||d I dH }| ||||tI dH  W nJ tk
r } z*td|  |jj	|ddI dH  W 5 d}~X Y nX W 5 dt
 kr(|ng D ]2}zt| td|  W n   Y nX q,|| jkr|| j| kr| j| |= X dS ) uO   Обработка альбома референсных изображенийrC   r  u8   🔄 Начинаем обработку альбома r  u   ❌ Альбом u    не найденNu(   📊 Состояние альбома: r  u    фото, подпись: 'r   u   ', обработан: r  u   ⏭️ Альбом u0    уже обработан, пропускаемTuT  📝 Пожалуйста, добавьте подпись к альбому с описанием того, что вы хотите сгенерировать.

🎨 **Пример:** Отправьте альбом с фотографиями и подписью "красивый пейзаж в стиле импрессионизма"r   r   photo_pathsr  r   rm   r  r   r  u%   📸 Референсное фото rQ   u    скачано: uF   ❌ Ошибка при обработке альбома referencer: u   ❌ Произошла ошибка при генерации изображения по референсам. Попробуйте еще раз.)r   r   r'   r(   r<   r8   r   r   rJ   r[   localsr*   r~   	enumerater   r   r:   r   r   r   r
  r   ra   r7   r1   )r>   rD   r   rC   r  r   r   r"  r|   ir!  fileZ	file_pathr   r?   r@   r@   rA   r    s`    ,"
"

z%NanoBananaBot.process_reference_album)r"  r   rE   c              
      s  zdt d|  t dt|  d|kp>d|kp>d|k}|rT|}t d n d| d| d	| }t d
 | jrXd|ig}|D ]F}t|d2}| }t|d}	|	dd|	di W 5 Q R X qd|igdddd}
| j
 d| j }| jj||
dd}|jdkr | }t d d|krV|d rV|d d }d|krVd|d krV|d d D ]}d|kr|d dd d!r|d d"}|rt d#t| d$ d%|d&t| d'| d(|d)  W S n(d|krnt d*|d d+d,  d- qnd.d/d0W S n6t d1|j d2|j  d.d3|j d2|j d0W S nd.d4d0W S W nF tk
r } z&t d5|  d.t|d0 W Y S d+}~X Y nX d+S )6ug   Генерация изображения на основе референсных фотографийuJ   🎨 Генерация изображения по референсам: u;   📸 Количество референсных фото: zTASK: MODIFYz#Modify the provided reference imagezTASK: Naturally modifyur   🔄 Режим модификации изображения - используем исходный промптz[Based on the provided reference images, create a new image with the following description: z

Use the visual style, colors, composition, and artistic elements from the reference images as inspiration, but create something new that matches the description: "z"

Key requirements:
- Maintain the visual style and aesthetic of the reference images
- Incorporate the color palette and artistic approach shown in the references
- Create a high-quality, detailed image
- Follow the specific description: uo   🎨 Режим генерации по референсам - создаем новое изображениеrX   r   r   r   r   r   r   g?i   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   uU   ✅ Изображение по референсам получено! Размер: r   TuI   🎨 Изображение сгенерировано на основе u$    фото по запросу:
<b>«r   r   r   Nr   r#   Fr   r   u   ❌ Ошибка HTTP rI   r   u'   HTTP клиент не настроенuF   ❌ Ошибка при генерации по референсам: )r'   r(   r   r   r   readr   r   r   r   r   r4   r   r   r   r   r   r1   rX   r7   r   )r>   r"  r   Zis_modificationZenhanced_promptr   r  fr   r   r   rS   r   r   r   r   r?   r@   r@   rA   r
  d  sz    	

	
"
"

z+NanoBananaBot.generate_image_from_reference)rW   r   c              
      s  zr|s| dI dH  W dS |dr6|dr6zt|d }t|}d|_ttdd| dgg}|j	j
|||d	d
|ddI dH }	|d |dd
|	jt d| j|< | ||| | I dH  td|  W nJ tk
r2 }
 z*td|
  | d|
 I dH  W 5 d}
~
X Y nX n<|rH|ddnd}| d| I dH  td|  W nV tk
r } z6td|  z| dI dH  W n   Y nX W 5 d}~X Y nX dS )u^   Универсальный метод отправки результата генерацииuO   ❌ Не удалось получить результат генерации.Nr   r   znano_banana_generated.jpgu,   🔄 Изменить изображениеr   rU   r   r   rs   )rW   r   r   rY   rZ   r   )r   r   r   r  uI   ✅ Изображение отправлено пользователю u:   ❌ Ошибка отправки изображения: un   ✅ Изображение сгенерировано, но произошла ошибка отправки: r1   u#   Неизвестная ошибкаu.   Результат генерации пустuK   ❌ Не удалось сгенерировать изображение: u%   ❌ Ошибка генерации: uC   ❌ Критическая ошибка в send_generation_result: uj   ❌ Произошла критическая ошибка при обработке результата.)r   r   r   r  r   r   r   r   r   rJ   Z
send_photor   r   r;   rr   r   r'   r(   r7   r1   )r>   rW   r   r   rD   ra   r  Z
image_filer]   Zsent_messageZ
send_errorZ	error_msgr?   r@   r@   rA   r     sN    



*z$NanoBananaBot.send_generation_resultc              
   C   s   zt  | j }|td| j |tt	j
t	j @ | j |tt	j| j |tt	jt	jj@ | j |t| j td |jdddgddd W n4 tk
r } ztd	|   W 5 d
}~X Y nX d
S )u   Запуск ботаstartuX   🚀 Запуск Nano Banana бота с генерацией изображений...Tr^   r      r   )Zdrop_pending_updatesZallowed_updatesr   Zbootstrap_retriesu1   ❌ Ошибка при запуске бота: N)r   ZbuilderZtokenr3   ZbuildZadd_handlerr   r   r   r   ZTEXTZCOMMANDr   ZVOICEr   ZPHOTOZ
UpdateTypeZMESSAGEr  r   r   r'   r(   Zrun_pollingr7   r1   )r>   Zapplicationr?   r@   r@   rA   run  s"    

zNanoBananaBot.run)N)N)N)N)N)N)(__name__
__module____qualname__rB   r   r   ZDEFAULT_TYPEboolrN   r_   r   rd   rf   rq   rr   ru   r   r5   r   r   r   r   r	   r   r
   r   r   r   r   r   r   r  r  r  r  r  r
  dictr   r+  r@   r@   r@   rA   r    ;   s4   ,'-W"F$2NGL3S;Id=r    c               
   C   sh   zt  } |   W nP tk
r0   td Y n4 tk
rb } ztd|   W 5 d}~X Y nX dS )u5   Главная функция запуска ботаu;   👋 Бот остановлен пользователемu*   💥 Критическая ошибка: N)r    r+  KeyboardInterruptr'   r(   r7   r1   )rJ   r?   r@   r@   rA   main"  s    r2  __main__);__doc__r*   Zloggingr   r   typingr   r   r   r   r   r   r   r   r   r   Zaiofilesr   Zgoogle.generativeaiZgenerativeair6   Zspeech_recognitionry   Zpydubr   ZPILr	   r   r
   r   r   r   Ztelegram.extr   r   r   r   r   r   Ztelegram.constantsr   Ztelegram.errorr   r   r   Zdotenvr   Zconfigr   ZbasicConfigZDEBUGZStreamHandlerZFileHandlerZ	getLoggerr,  r'   ZsetLevelr    r2  r@   r@   r@   rA   <module>   s`    
         p
