import gradio as gr import os import time import fitz # PyMuPDF from docx import Document from docx.shared import Inches from docx.oxml import OxmlElement from docx.oxml.ns import qn from tqdm import tqdm from dotenv import load_dotenv from modelo_clip import ValidatorVITImgTexto from openai import OpenAI import re from threading import Thread from queue import Queue from gradio_pdf import PDF # 🔹 Carregar variáveis de ambiente load_dotenv() secretk = os.environ.get("OPENAI_API_KEY") cliente_openai = OpenAI(api_key=secretk) # 🔹 Criar pastas para armazenar arquivos os.makedirs("uploads", exist_ok=True) os.makedirs("clippings", exist_ok=True) # 🔹 Justificar parágrafos no Word def justify_paragraph(paragraph): p = paragraph._element pPr = p.get_or_add_pPr() jc = OxmlElement('w:jc') jc.set(qn('w:val'), 'both') pPr.append(jc) # 🔹 Função para extrair texto do PDF def extract_content(pdf_path): doc = fitz.open(pdf_path) extracted_data = [] for page_num, page in enumerate(doc, start=1): page_data = { "page_number": page_num, "text": page.get_text("text"), "link": f"{os.path.basename(pdf_path)}#page={page_num}" } extracted_data.append(page_data) return extracted_data # 🔹 Função para identificar palavras-chave no texto def find_keywords(text, keywords): detected = [kw for kw in keywords if kw.lower() in text.lower()] return detected # 🔹 Função para gerar resumos via OpenAI def generate_summary(text): prompt = f"Resuma o seguinte texto em poucas frases mantendo os pontos principais:\n\n{text}" try: response = cliente_openai.chat.completions.create( model="gpt-4o", messages=[{"role": "system", "content": "Você é um assistente que resume textos de forma objetiva."}, {"role": "user", "content": prompt}], temperature=0.3, max_tokens=150 ) return response.choices[0].message.content.strip() except Exception as e: return f"Erro ao gerar resumo: {e}" # 🔹 Filtrar conteúdo com base nas palavras-chave e gerar resumos def filter_content(extracted_data, keywords): filtered_data = [] for page in extracted_data: detected_keywords = find_keywords(page["text"], keywords) if detected_keywords: summary = generate_summary(page["text"]) filtered_data.append({ "page_number": page["page_number"], "summary": summary, "text": page["text"], "keywords": ", ".join(detected_keywords), "link": page["link"] }) return filtered_data # 🔹 Criar um documento Word com os resumos def generate_word_from_summary(filtered_data, output_path): doc = Document() if not filtered_data: doc.add_paragraph("Nenhum conteúdo relevante encontrado.") else: for page in filtered_data: doc.add_heading(f"Resumo da Página {page['page_number']}", level=2) doc.add_paragraph(f"**Palavras-chave encontradas:** {page['keywords']}") doc.add_paragraph(f"**Resumo:** {page['summary']}") doc.add_paragraph(f"📎 [Acesse a Página]({page['link']})") doc.add_paragraph("-" * 50) doc.save(output_path) def generate_clickable_link(pdf_path, page_number): """ Gera um link funcional para acessar uma página específica do PDF dentro do Gradio. """ pdf_filename = os.path.basename(pdf_path) # Pega apenas o nome do arquivo link = f'📄 Acesse a Página {page_number}' return link # 🔹 Processamento do PDF no Gradio def process_pdf(uploaded_pdf): if not uploaded_pdf: return "Nenhum arquivo enviado.", None pdf_path = uploaded_pdf output_docx = os.path.join("clippings", f"clipping_{int(time.time())}.docx") keywords = ["Governo Federal", "Ceará", "infraestrutura", "saúde", "educação", "segurança pública"] extracted_data = extract_content(pdf_path) filtered_data = filter_content(extracted_data, keywords) generate_word_from_summary(filtered_data, output_docx) resumos = [] for page in extracted_data: summary = generate_summary(page["text"]) resumos.append({ "page_number": page["page_number"], "summary": summary }) return resumos # 🔹 Criar botões e resumos interativos em Markdown com HTML def create_summary_buttons(resumos): markdown_content = "" for r in resumos: page_num = r["page_number"] summary = r["summary"] markdown_content += f""" 🔑 Resumo: {summary}

""" return markdown_content if markdown_content else "Nenhum resumo disponível." # 🔹 Interface Gradio with gr.Blocks() as demo: gr.Markdown("### 📑 Clipapptor - IA para Resumo de PDFs") with gr.Row(): with gr.Column(scale=1): # Lado esquerdo uploaded_pdf = PDF(label="📤 Faça upload do PDF", interactive=True, height=650) #page_input = gr.Number(value=1, label="Página", interactive=True) #go_to_page_button = gr.Button("Ir para Página", elem_id="go-to-page-button") with gr.Column(scale=1): # Lado direito process_button = gr.Button("📄 Gerar Clippings do Jornal") resumo_output = gr.Markdown("Aguardando resumos...", render=True, height=650) # 🔹 Função para navegação no PDF # def go_to_page(page_number): # return page_number def process_and_create_buttons(pdf): resumos = process_pdf(pdf) return create_summary_buttons(resumos) process_button.click( fn=process_and_create_buttons, inputs=[uploaded_pdf], outputs=[resumo_output] ) # go_to_page_button.click(fn=go_to_page, inputs=[page_input], outputs=[page_input]) demo.launch(share=True)