← Voltar

tiktok_handler.py

from telegram import Update
from telegram.ext import ContextTypes
from services.tiktok import download_tiktok_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
from handlers.commands import DOWNLOAD_COUNT # Importar DOWNLOAD_COUNT

async def process_tiktok(update: Update, context: ContextTypes.DEFAULT_TYPE):
    url = update.message.text
    progress_message = await update.message.reply_text("🎵 Baixando do TikTok...")

    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
            
            # Regex para extrair informações da linha de progresso do yt-dlp
            # Ex: "[download]  57.6% of    1.20GiB at  4.20MiB/s ETA 00:04"
            match = re.search(r"\[download\]\s+(?P<percent>\d+\.\d+)%\s+of\s+(?P<total_size>[\d\.]+\w+)\s+at\s+(?P<speed>[\d\.]+\w+/s)\s+ETA\s+(?P<eta>\d{2}:\d{2})", raw_progress_line)
            
            progress_text = "Progresso: N/A"
            speed_text = "Velocidade: N/A"
            eta_text = "Tempo estimado: N/A"

            if match:
                percent = match.group("percent")
                total_size = match.group("total_size")
                speed = match.group("speed")
                eta = match.group("eta")
                progress_text = f"Progresso: {percent}% de {total_size}"
                speed_text = f"Velocidade: {speed}"
                eta_text = f"Tempo estimado: {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}"

            try:
                await progress_message.edit_text(
                    f"🎵 Baixando do TikTok...\n\n"
                    f"{strip_ansi_codes(progress_text)}\n"
                    f"{strip_ansi_codes(speed_text)}\n"
                    f"{strip_ansi_codes(eta_text)}"
                )
            except Exception:
                pass # Ignora erros de edição de mensagem (ex: mensagem inalterada)

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

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

        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).",
            )
        
        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 vídeo pode ser muito grande para ser enviado ao Telegram. "
            "O limite para bots é de 50MB. Tente um vídeo mais curto."
        )
    except Exception as e: # Captura Exception genérica para erros do subprocesso
        error_text = str(e)
        if "Erro ao baixar do TikTok:" in error_text:
            await progress_message.edit_text(f"❌ {error_text}")
        elif "A operação de download do TikTok 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 TikTok: {error_text}")
    finally:
        if temp_dir:
            shutil.rmtree(temp_dir, ignore_errors=True)