import requests import gradio as gr import os import uuid import PyPDF2 from PIL import Image import imageio import random from gtts import gTTS from reportlab.lib.pagesizes import letter from reportlab.platypus import SimpleDocTemplate, Paragraph from reportlab.lib.styles import getSampleStyleSheet # Configuração da API do Google Gemini API_KEYS = [ 'AIzaSyAgmf1ZvNrvzAmlNCQvQbyZDJJPdMwecqY', 'AIzaSyB18Z-Ct2-IKYGZ9vKaChcee-BDVS77Ksg', 'AIzaSyBB5Tp0xdXcemLMGDm8_cL6L37wTe_8sjg', 'AIzaSyCefvhXMsgHmAF_0KVkZ0UAeZ5nNC41v-A', ] def escolher_chave_api(): return random.choice(API_KEYS) GEMINI_API_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key={}" class AssistenteAcademico: def __init__(self): self.contexto_atual = {} self.ultima_imagem_path = None self.pasta_temp = 'assistente_temp' for pasta in [self.pasta_temp, 'audios_assistente', 'pdfs_respostas']: os.makedirs(pasta, exist_ok=True) def gerar_pdf_resposta(self, texto, nome_arquivo=None): try: nome_arquivo = nome_arquivo or f'resposta_{uuid.uuid4()}.pdf' caminho_pdf = os.path.join('pdfs_respostas', nome_arquivo) doc = SimpleDocTemplate(caminho_pdf, pagesize=letter) styles = getSampleStyleSheet() story = [Paragraph(texto.replace('\n', '
'), styles['Normal'])] doc.build(story) return caminho_pdf except Exception as e: return f"Erro ao criar PDF: {str(e)}" def texto_para_audio(self, texto, nome_arquivo=None): try: nome_arquivo = nome_arquivo or f'audio_{uuid.uuid4()}.mp3' caminho_audio = os.path.join('audios_assistente', nome_arquivo) tts = gTTS(texto, lang='pt-br') tts.save(caminho_audio) return caminho_audio except Exception as e: return f"Erro ao criar áudio: {str(e)}" def codificar_imagem(self, imagem_path): try: if not os.path.exists(imagem_path): raise ValueError("Arquivo de imagem não encontrado") extensao = os.path.splitext(imagem_path)[1].lower() formatos_suportados = {'.png', '.jpg', '.jpeg', '.bmp', '.gif', '.tiff', '.webp'} if extensao not in formatos_suportados: raise ValueError(f"Formato de imagem não suportado: {extensao}") imagem = imageio.imread(imagem_path) imagem_pil = Image.fromarray(imagem) imagem_pil.thumbnail((800, 800), Image.Resampling.LANCZOS) temp_path = os.path.join(self.pasta_temp, f'temp_image_{uuid.uuid4()}{extensao}') imagem_pil.convert('RGB').save(temp_path, quality=95) return temp_path except Exception as e: return f"Erro ao codificar imagem: {str(e)}" def extrair_texto_pdf(self, arquivo_pdf): try: if not arquivo_pdf or not os.path.exists(arquivo_pdf): return "Nenhum PDF válido fornecido" leitor_pdf = PyPDF2.PdfReader(arquivo_pdf) texto = "\n".join(pagina.extract_text() or "" for pagina in leitor_pdf.pages) return texto if texto.strip() else "Nenhum texto extraído do PDF" except Exception as e: return f"Erro ao extrair texto do PDF: {str(e)}" def processar_input(self, pergunta, pdf=None, imagem=None): try: if not pergunta: return "Por favor, forneça uma pergunta", None, None # Preparar o conteúdo para a API conteudo = [{"role": "user", "parts": [{"text": self.contexto_atual.get('pdf_texto', '')}]}] if pdf: texto_pdf = self.extrair_texto_pdf(pdf) self.contexto_atual['pdf_texto'] = texto_pdf conteudo[0]["parts"].append({"text": texto_pdf}) if imagem: if self.ultima_imagem_path and os.path.exists(self.ultima_imagem_path): os.remove(self.ultima_imagem_path) imagem_path = self.codificar_imagem(imagem) if isinstance(imagem_path, str) and os.path.exists(imagem_path): self.ultima_imagem_path = imagem_path with open(imagem_path, "rb") as img_file: conteudo[0]["parts"].append({ "inline_data": { "mime_type": f"image/{os.path.splitext(imagem_path)[1][1:]}", "data": base64.b64encode(img_file.read()).decode('utf-8') } }) prompt = f"""Como um assistente acadêmico avançado: - Seja objetivo e acadêmico - Forneça explicações claras - Use linguagem técnica quando apropriado - Cite referências se possível - Mantenha a explicação acessível Pergunta atual: {pergunta} """ conteudo[0]["parts"].append({"text": prompt}) # Fazer a requisição à API headers = {"Content-Type": "application/json"} api_key = escolher_chave_api() response = requests.post( GEMINI_API_URL.format(api_key), json={"contents": conteudo}, headers=headers ) if response.status_code != 200: return f"Erro na API: {response.status_code} - {response.text}", None, None resposta_json = response.json() texto_resposta = resposta_json["candidates"][0]["content"]["parts"][0]["text"] caminho_audio = self.texto_para_audio(texto_resposta) caminho_pdf = self.gerar_pdf_resposta(texto_resposta) return texto_resposta, caminho_audio, caminho_pdf except Exception as e: return f"Erro no processamento: {str(e)}", None, None def limpar_arquivos_temporarios(self): import time pastas = [self.pasta_temp, 'audios_assistente', 'pdfs_respostas'] for pasta in pastas: for arquivo in os.listdir(pasta): caminho = os.path.join(pasta, arquivo) if os.path.isfile(caminho) and time.time() - os.path.getctime(caminho) > 3600: try: os.remove(caminho) except: pass def chatbot_interface(self): with gr.Blocks(title="Assistente Acadêmico") as interface: gr.Markdown("# 🎓 Assistente Acadêmico\nFaça suas perguntas e carregue arquivos para análise.") chatbot = gr.Chatbot(label="Conversa") with gr.Row(): audio_output = gr.Audio(label="Resposta em Áudio") pdf_output = gr.File(label="Resposta em PDF") with gr.Row(): msg = gr.Textbox(label="Pergunta", placeholder="Digite sua pergunta...") pdf_input = gr.File(file_types=['.pdf'], label="Carregar PDF") img_input = gr.File(file_types=['.png', '.jpg', '.jpeg', '.bmp', '.gif', '.tiff', '.webp'], label="Carregar Imagem") submit_btn = gr.Button("Enviar") def responder(mensagem, historico, pdf=None, imagem=None): resposta, audio, pdf_file = self.processar_input(mensagem, pdf, imagem) historico.append((mensagem, resposta)) self.limpar_arquivos_temporarios() return "", historico, audio, pdf_file submit_btn.click( fn=responder, inputs=[msg, chatbot, pdf_input, img_input], outputs=[msg, chatbot, audio_output, pdf_output] ) return interface if __name__ == "__main__": assistente = AssistenteAcademico() interface = assistente.chatbot_interface() print("🚀 Assistente Acadêmico inicializado!") interface.launch(debug=True, share=True)