Aplicação Desktop Mordomo
Interface gráfica (PyQt5) para automação centralizada de downloads e relatórios de múltiplos portais financeiros.
O Desafio
A necessidade de baixar relatórios de diversos portais web financeiros (Função, Credbase, Dig, Front) diariamente era um processo manual, demorado e propenso a erros. Cada portal possuía fluxos de login e navegação distintos, e o gerenciamento seguro de múltiplas credenciais era complexo e ineficiente.
Era crucial desenvolver uma solução centralizada que permitisse aos usuários configurar e executar essas automações de forma simples e segura, com feedback visual claro do progresso e capacidade de lidar com cenários como autenticação de dois fatores (2FA).
A Solução: Aplicação Desktop Mordomo
Desenvolvi a "Mordomo", uma aplicação desktop completa utilizando Python e a biblioteca PyQt5 para a interface gráfica. A aplicação foi projetada para oferecer uma experiência robusta e amigável:
- Interface Gráfica Intuitiva (PyQt5): Design limpo com modos "Tarefa Única" e "Power Mode" para execução sequencial de múltiplas tarefas, facilitando o uso por qualquer membro da equipe.
- Automação Web Robusta (Selenium): Utiliza Selenium e `webdriver-manager` para interagir com os portais (Função, Credbase, Dig, Front), garantindo compatibilidade entre navegadores/drivers e dispensando instalações manuais.
- Gerenciador de Logins Seguro (QSettings): Armazena credenciais por site de forma segura no sistema operacional (Registro/Windows, plist/macOS, ini/Linux), ofuscadas com Base64 para proteção adicional.
- Orquestração de Tarefas (QThread): Um `AutomationOrchestrator` gerencia a fila de execução e executa cada worker (automação específica do site) em uma thread separada, mantendo a interface responsiva.
- Suporte a 2FA (Credbase): Lida especificamente com o fluxo de autenticação de dois fatores do portal Credbase, pausando a automação e solicitando o código ao usuário através da interface.
- Feedback em Tempo Real: Um console de log na interface exibe o progresso detalhado, sucessos e eventuais erros de cada tarefa.
- Componentes Customizados (PyQt5): Widgets como `SearchableComboBox` (ComboBox com busca) melhoram significativamente a usabilidade na seleção de convênios em listas extensas.
Interface e Funcionalidades
Screenshots do gerenciador de logins e do modo "Power Mode" configurando múltiplas tarefas.
Código em Destaque
Trecho de um worker (ex: `FuncaoRelatorioPrincipalWorker`) mostrando a inicialização do Selenium em modo "headless" (sem interface gráfica visível do navegador) e o uso de `webdriver-manager` para baixar automaticamente o driver correto, garantindo a portabilidade da aplicação.
# (Trecho adaptado de funcao.py)
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from PyQt5.QtCore import QObject, pyqtSignal
class FuncaoRelatorioPrincipalWorker(QObject):
progress_updated = pyqtSignal(str)
finished = pyqtSignal()
# ... (outros atributos) ...
def __init__(self, usuario, senha, data_ini, data_fim, empregadores, task_index=0, total_tasks=1):
super().__init__()
# ... (atribuição de self.usuario, etc.) ...
self.is_running = True
# --- Ponto Chave: Configuração do WebDriver ---
try:
self.progress_updated.emit(">>> Inicializando WebDriver...")
# Baixa e instala o ChromeDriver automaticamente
service = Service(ChromeDriverManager().install())
# Configurações para rodar sem abrir janela do Chrome
options = webdriver.ChromeOptions()
options.add_argument("--headless")
options.add_argument("--window-size=1920,1080")
options.add_argument("--disable-gpu") # Necessário em alguns sistemas
options.add_argument("--no-sandbox") # Necessário em alguns sistemas Linux
options.add_argument("--disable-dev-shm-usage") # Necessário em alguns sistemas Linux
self.driver = webdriver.Chrome(service=service, options=options)
self.progress_updated.emit(">>> WebDriver inicializado com sucesso em modo Headless.")
except Exception as e:
self.progress_updated.emit(f"ERRO: Falha ao inicializar WebDriver: {e}")
self.is_running = False # Impede a execution se o driver falhar
# ... (método run, cleanup, etc.) ...