Inicia concerto do Proxy
This commit is contained in:
113
proxy_manager.py
113
proxy_manager.py
@@ -1,6 +1,6 @@
|
||||
from typing import Callable, Any, Optional
|
||||
from yt_dlp import YoutubeDL
|
||||
from database import get_latest_proxy, delete_proxy, format_proxy_url, mark_proxy_success
|
||||
from database import get_all_active_proxies, format_proxy_url, mark_proxy_success
|
||||
|
||||
class ProxyError(Exception):
|
||||
pass
|
||||
@@ -22,6 +22,16 @@ def is_proxy_error(error_msg: str) -> bool:
|
||||
'http error 407', # Proxy authentication required
|
||||
'tunnel connection failed',
|
||||
'connect to host',
|
||||
'bot', # YouTube bloqueando proxy como bot
|
||||
'sign in to confirm', # YouTube pedindo verificação
|
||||
'http error 429', # Too many requests
|
||||
'failed to extract', # Falha ao extrair dados (pode ser proxy ruim)
|
||||
'player response', # Problemas com resposta do player
|
||||
'http error 403', # Forbidden (pode ser proxy bloqueado)
|
||||
'http error 503', # Service unavailable (pode ser proxy)
|
||||
'ssl', # Erros SSL causados por proxy
|
||||
'certificate', # Erros de certificado causados por proxy
|
||||
'certificate_verify_failed', # Verificação de certificado SSL falhou
|
||||
]
|
||||
|
||||
non_proxy_error_keywords = [
|
||||
@@ -43,56 +53,81 @@ def is_proxy_error(error_msg: str) -> bool:
|
||||
def execute_with_proxy_retry(
|
||||
ydl_opts: dict,
|
||||
operation: Callable[[YoutubeDL], Any],
|
||||
max_retries: int = 10
|
||||
retry_per_proxy: int = 2
|
||||
) -> Any:
|
||||
attempts = 0
|
||||
"""
|
||||
Tenta executar operação com todos os proxies disponíveis.
|
||||
Cada proxy é tentado N vezes antes de passar para o próximo.
|
||||
Proxies NÃO são removidos do banco, apenas pulados.
|
||||
|
||||
Args:
|
||||
ydl_opts: Opções do YoutubeDL
|
||||
operation: Função a ser executada
|
||||
retry_per_proxy: Número de tentativas por proxy antes de pular para o próximo
|
||||
"""
|
||||
# Busca TODOS os proxies ativos
|
||||
all_proxies = get_all_active_proxies()
|
||||
total_proxies = len(all_proxies)
|
||||
|
||||
print(f"\n{'='*60}")
|
||||
print(f"Proxies disponíveis no banco: {total_proxies}")
|
||||
print(f"Tentativas por proxy: {retry_per_proxy}")
|
||||
print(f"{'='*60}\n")
|
||||
|
||||
last_error = None
|
||||
|
||||
while attempts < max_retries:
|
||||
attempts += 1
|
||||
proxy_data = None
|
||||
# Tenta cada proxy da lista
|
||||
for proxy_index, proxy_data in enumerate(all_proxies, 1):
|
||||
proxy_url = format_proxy_url(proxy_data)
|
||||
ydl_opts_with_proxy = {**ydl_opts, 'proxy': proxy_url}
|
||||
|
||||
try:
|
||||
proxy_data = get_latest_proxy()
|
||||
print(f"\n[Proxy {proxy_index}/{total_proxies}] {proxy_url} (ID: {proxy_data['id']})")
|
||||
|
||||
if proxy_data:
|
||||
proxy_url = format_proxy_url(proxy_data)
|
||||
ydl_opts_with_proxy = {**ydl_opts, 'proxy': proxy_url}
|
||||
print(f"Tentativa {attempts}: Usando proxy {proxy_url} (ID: {proxy_data['id']})")
|
||||
else:
|
||||
if attempts == 1:
|
||||
print(f"Tentativa {attempts}: Nenhum proxy disponível, tentando sem proxy")
|
||||
ydl_opts_with_proxy = ydl_opts
|
||||
else:
|
||||
raise ProxyError("Não há mais proxies disponíveis no banco de dados")
|
||||
# Tenta N vezes com o MESMO proxy
|
||||
for attempt in range(1, retry_per_proxy + 1):
|
||||
try:
|
||||
print(f" → Tentativa {attempt}/{retry_per_proxy}...", end=" ")
|
||||
|
||||
with YoutubeDL(ydl_opts_with_proxy) as ydl:
|
||||
result = operation(ydl)
|
||||
print(f"Operação concluída com sucesso na tentativa {attempts}")
|
||||
|
||||
if proxy_data:
|
||||
mark_proxy_success(proxy_data['id'])
|
||||
with YoutubeDL(ydl_opts_with_proxy) as ydl:
|
||||
result = operation(ydl)
|
||||
|
||||
print(f"✓ SUCESSO!")
|
||||
mark_proxy_success(proxy_data['id'])
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
error_msg = str(e)
|
||||
last_error = e
|
||||
except Exception as e:
|
||||
error_msg = str(e)
|
||||
last_error = e
|
||||
|
||||
print(f"Erro na tentativa {attempts}: {error_msg}")
|
||||
print(f"✗ Falhou")
|
||||
print(f" Erro: {error_msg[:80]}...")
|
||||
|
||||
if is_proxy_error(error_msg):
|
||||
if proxy_data:
|
||||
print(f"Erro identificado como erro de proxy. Removendo proxy ID {proxy_data['id']}")
|
||||
delete_proxy(proxy_data['id'])
|
||||
else:
|
||||
print("Erro de proxy mas nenhum proxy estava sendo usado")
|
||||
# Se não for erro de proxy, lança imediatamente
|
||||
if not is_proxy_error(error_msg):
|
||||
print(f" ⚠ Erro não relacionado a proxy, abortando")
|
||||
raise e
|
||||
|
||||
continue
|
||||
else:
|
||||
print(f"Erro não é relacionado a proxy, lançando exceção")
|
||||
raise e
|
||||
# Se chegou aqui, falhou todas as tentativas com este proxy
|
||||
print(f" ⨯ Proxy falhou {retry_per_proxy} vezes, pulando para o próximo...")
|
||||
|
||||
# Se chegou aqui, todos os proxies falharam, tenta SEM proxy
|
||||
print(f"\n{'='*60}")
|
||||
print(f"Todos os {total_proxies} proxies falharam")
|
||||
print(f"Tentando SEM proxy como último recurso...")
|
||||
print(f"{'='*60}\n")
|
||||
|
||||
try:
|
||||
print(f" → Tentativa sem proxy...", end=" ")
|
||||
with YoutubeDL(ydl_opts) as ydl:
|
||||
result = operation(ydl)
|
||||
print(f"✓ SUCESSO!")
|
||||
return result
|
||||
except Exception as e:
|
||||
print(f"✗ Falhou")
|
||||
print(f" Erro: {str(e)[:80]}...")
|
||||
last_error = e
|
||||
|
||||
raise ProxyError(
|
||||
f"Falha após {max_retries} tentativas. Último erro: {last_error}"
|
||||
f"Falha após tentar {total_proxies} proxies + tentativa sem proxy. Último erro: {last_error}"
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user