File size: 5,489 Bytes
5b30b57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# handlers.py
import os
import asyncio
import logging
from typing import List

from hydrogram import Client, filters
from hydrogram.types import Message
from hydrogram.errors import FloodWait, RPCError
from hydrogram.handlers import MessageHandler # Explicit import for add_handler

from config import Config
from utils import is_admin
from processing import process_images_sync
from main import executor # Import executor from main.py

logger = logging.getLogger(__name__)

async def handle_photo_message_impl(client: Client, message: Message):
    user = message.from_user
    user_id = user.id
    user_info = f"user_id={user_id}" + (f", username={user.username}" if user.username else "")
    caption = message.caption if message.caption else ""
    message_id = message.id
    chat_id = message.chat.id

    logger.info(f"ADMIN ACTION (Bot): Received photo with caption from {user_info} (msg_id={message_id}).")

    temp_user_image_path = os.path.join(Config.OUTPUT_DIR, f"bot_user_{user_id}_{message_id}.jpg")
    file_downloaded = False
    processing_status_message = None

    try:
        if not message.photo: return
        download_start_time = asyncio.get_running_loop().time()
        logger.info(f"Attempting download photo (file_id: {message.photo.file_id})...")
        downloaded_path = await client.download_media(message.photo.file_id, file_name=temp_user_image_path)

        if downloaded_path and os.path.exists(downloaded_path):
             download_time = asyncio.get_running_loop().time() - download_start_time
             logger.info(f"Photo downloaded to '{downloaded_path}' in {download_time:.2f}s.")
             temp_user_image_path = downloaded_path
             file_downloaded = True
        else:
             logger.error(f"Download failed or file not found: '{temp_user_image_path}'. Path: {downloaded_path}")
             await message.reply_text("❌ Internal error after download attempt.")
             return
    except FloodWait as e:
        logger.warning(f"Flood wait: {e.value}s during download (msg_id={message_id}).")
        await asyncio.sleep(e.value + 2)
        await message.reply_text(f"⏳ Telegram limits hit. Wait {e.value}s & try again.")
        return
    except RPCError as e:
        logger.error(f"RPC error downloading photo (msg_id={message_id}): {e}", exc_info=True)
        await message.reply_text("❌ Telegram API error downloading image.")
        return
    except Exception as e:
        logger.error(f"Unexpected error downloading photo (msg_id={message_id}): {e}", exc_info=True)
        await message.reply_text("❌ Unexpected error downloading image.")
        return

    try:
        processing_status_message = await message.reply_text("⏳ Processing your image...", quote=True)
    except Exception as e: logger.warning(f"Could not send 'Processing...' message: {e}")

    message_to_delete_id = processing_status_message.id if processing_status_message else None
    loop = asyncio.get_running_loop()
    generated_images: List[str] = []
    processing_failed = False
    
    try:
        logger.info(f"Submitting image processing for '{os.path.basename(temp_user_image_path)}'")
        generated_images = await loop.run_in_executor(
            executor, process_images_sync, temp_user_image_path, caption
        )
    except Exception as e:
         processing_failed = True
         logger.error(f"Error during image processing executor call: {e}", exc_info=True)
         error_message = "❌ Unexpected error during processing."
         if message_to_delete_id:
             try: await client.edit_message_text(chat_id, message_to_delete_id, error_message)
             except Exception as edit_e: logger.warning(f"Could not edit status msg: {edit_e}")
             message_to_delete_id = None
         else: await message.reply_text(error_message)

    if message_to_delete_id:
        try: await client.delete_messages(chat_id, message_to_delete_id)
        except Exception as del_e: logger.warning(f"Could not delete status msg: {del_e}")

    if not processing_failed:
        if not generated_images:
            await message.reply_text("πŸ˜• No styled images generated. Check templates?")
        else:
            logger.info(f"Sending {len(generated_images)} images for message {message_id}.")
            for i, img_path in enumerate(generated_images):
                if not os.path.exists(img_path): continue
                caption_text = f"Style {i+1}" if len(generated_images) > 1 else "πŸ–ΌοΈ Styled image:"
                try:
                    await message.reply_photo(photo=img_path, caption=caption_text, quote=True)
                except Exception as e: logger.error(f"Error sending photo '{os.path.basename(img_path)}': {e}", exc_info=True)
                finally:
                     try:
                         if os.path.exists(img_path): os.remove(img_path)
                     except OSError as e: logger.error(f"Error deleting file '{img_path}': {e}")
    
    try:
        if file_downloaded and os.path.exists(temp_user_image_path):
            os.remove(temp_user_image_path)
    except OSError as e: logger.error(f"Error cleaning user image '{temp_user_image_path}': {e}")

def register_handlers(app: Client):
    admin_photo_filter = filters.photo & filters.caption & filters.private & is_admin
    app.add_handler(MessageHandler(handle_photo_message_impl, filters=admin_photo_filter))
    logger.info("Registered admin photo handler for bot.")