← Voltar

instagram_handler.py

from telegram import Update
from telegram.ext import ContextTypes
from services.instagram import download_instagram_video
import shutil
import asyncio
from utils.ansi_stripper import strip_ansi_codes
import httpx # Importar httpx
import os # Importar os para os.path.getsize
import re # Importar re para expressões regulares
import logging # Importar logging
from handlers.commands import DOWNLOAD_COUNT # Importar DOWNLOAD_COUNT

logger = logging.getLogger(__name__) # Obter o logger

async def process_instagram(update: Update, context: ContextTypes.DEFAULT_TYPE):
    url = update.message.text
    progress_message = await update.message.reply_text("📸 Baixando do Instagram...")

    loop = asyncio.get_running_loop()
    last_update_time = 0

    async def update_progress_display(raw_progress_line):
        nonlocal last_update_time
        current_time = loop.time()
        if current_time - last_update_time > 2: # Atualiza a cada 2 segundos para evitar flood
            last_update_time = current_time
            
            logger.debug(f"Raw progress line: {raw_progress_line}")

            # Regex mais simples para extrair porcentagem e ETA
            # Ex: "[download]  57.6% of    1.20GiB at  4.20MiB/s ETA 00:04"
            match = re.search(r"\[download\]\s+(?P<percent>\d+\.\d+)%.*ETA\s+(?P<eta>\d{2}:\d{2})", raw_progress_line)
            
            progress_text = "Progresso: N/A"
            eta_text = "Tempo estimado: N/A"

            if match:
                percent = match.group("percent")
                eta = match.group("eta")
                progress_text = f"Progresso: {percent}%"
                eta_text = f"Tempo estimado: {eta}"
                logger.debug(f"Parsed progress: Percent={percent}, ETA={eta}")
            else:
                # Se não encontrar o padrão principal, tenta pegar outras informações úteis
                if "download" in raw_progress_line.lower():
                    progress_text = f"Progresso: {raw_progress_line}"
                logger.debug(f"No simple match, using raw line: {progress_text}")

            message_to_send = (
                f"📸 Baixando do Instagram...\n\n"
                f"{progress_text}\n"
                f"{eta_text}"
            )
            logger.debug(f"Message to send: {message_to_send}")

            try:
                await progress_message.edit_text(message_to_send)
            except Exception as e:
                logger.error(f"Erro ao editar mensagem de progresso: {e}")
                pass # Ignora erros de edição de mensagem (ex: mensagem inalterada)

    temp_dir = None
    try:
        file_path, title, temp_dir = await download_instagram_video(url, update_progress_display)

        await progress_message.edit_text("📤 Enviando mídia...")
        
        # Decide se envia como video ou documento
        size_mb = (await asyncio.to_thread(os.path.getsize, file_path) / 1024 / 1024)

        if file_path.endswith(".mp4"):
            if size_mb <= 50:
                await context.bot.send_video(
                    chat_id=update.effective_chat.id,
                    video=await asyncio.to_thread(open, file_path, 'rb'), # Envia o conteúdo como bytes
                    caption=f"📸 {title}"
                )
            else:
                await context.bot.send_document(
                    chat_id=update.effective_chat.id,
                    document=await asyncio.to_thread(open, file_path, 'rb'), # Envia o conteúdo como bytes
                    filename=f"{title}.mp4",
                    caption=f"📁 Arquivo grande enviado como documento ({int(size_mb)}MB).",
                )
        else: # Assume que é uma imagem
            await context.bot.send_photo(
                chat_id=update.effective_chat.id,
                photo=await asyncio.to_thread(open, file_path, 'rb'), # Envia o conteúdo como bytes
                caption=f"📸 {title}"
            )
        
        await progress_message.delete()
        global DOWNLOAD_COUNT
        DOWNLOAD_COUNT += 1 # Incrementa o contador de downloads


    except httpx.ReadError:
        await progress_message.edit_text(
            "❌ Erro: O arquivo de mídia pode ser muito grande para ser enviado ao Telegram. "
            "O limite para bots é de 50MB. Tente uma mídia mais curta."
        )
    except Exception as e: # Captura Exception genérica para erros do subprocesso
        error_text = str(e)
        if "Erro ao baixar do Instagram:" in error_text:
            instructions = (
                "📸 *Falha ao baixar do Instagram*\n\n"
                "Isso geralmente acontece porque o Instagram exige login para ver este post.\n\n"
                "**O que você pode tentar?**\n"
                "Às vezes, o 'link de compartilhar' (`/reel/...`) é mais restrito. Tente o seguinte:\n"
                "1. Abra o post diretamente no feed ou no perfil.\n"
                "2. Copie o link da barra de endereços do navegador (geralmente com `/p/...`).\n"
                "3. Envie esse novo link para mim.\n\n"
                "Se ainda assim não funcionar, o post provavelmente está protegido e não pode ser baixado."
            )
            await progress_message.edit_text(instructions, parse_mode="Markdown")
        elif "A operação de download do Instagram excedeu o tempo limite" in error_text:
            await progress_message.edit_text(f"❌ {error_text}")
        else:
            await progress_message.edit_text(f"❌ Erro inesperado ao baixar do Instagram: {error_text}")
    finally:
        if temp_dir:
            shutil.rmtree(temp_dir, ignore_errors=True)