tbluhm commited on
Commit
7f0d652
·
verified ·
1 Parent(s): 791c769

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +182 -0
app.py ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import time
4
+ import fitz # PyMuPDF
5
+ from docx import Document
6
+ from docx.shared import Inches
7
+ from docx.oxml import OxmlElement
8
+ from docx.oxml.ns import qn
9
+ from tqdm import tqdm
10
+ from dotenv import load_dotenv
11
+ from modelo_clip import ValidatorVITImgTexto
12
+ from openai import OpenAI
13
+ import re
14
+ from threading import Thread
15
+ from queue import Queue
16
+ from gradio_pdf import PDF
17
+
18
+ # 🔹 Carregar variáveis de ambiente
19
+ load_dotenv()
20
+ secretk = os.environ.get("OPENAI_API_KEY")
21
+ cliente_openai = OpenAI(api_key=secretk)
22
+
23
+ # 🔹 Criar pastas para armazenar arquivos
24
+ os.makedirs("uploads", exist_ok=True)
25
+ os.makedirs("clippings", exist_ok=True)
26
+
27
+ # 🔹 Justificar parágrafos no Word
28
+ def justify_paragraph(paragraph):
29
+ p = paragraph._element
30
+ pPr = p.get_or_add_pPr()
31
+ jc = OxmlElement('w:jc')
32
+ jc.set(qn('w:val'), 'both')
33
+ pPr.append(jc)
34
+
35
+ # 🔹 Função para extrair texto do PDF
36
+ def extract_content(pdf_path):
37
+ doc = fitz.open(pdf_path)
38
+ extracted_data = []
39
+ for page_num, page in enumerate(doc, start=1):
40
+ page_data = {
41
+ "page_number": page_num,
42
+ "text": page.get_text("text"),
43
+ "link": f"{os.path.basename(pdf_path)}#page={page_num}"
44
+ }
45
+ extracted_data.append(page_data)
46
+ return extracted_data
47
+
48
+ # 🔹 Função para identificar palavras-chave no texto
49
+ def find_keywords(text, keywords):
50
+ detected = [kw for kw in keywords if kw.lower() in text.lower()]
51
+ return detected
52
+
53
+ # 🔹 Função para gerar resumos via OpenAI
54
+ def generate_summary(text):
55
+ prompt = f"Resuma o seguinte texto em poucas frases mantendo os pontos principais:\n\n{text}"
56
+ try:
57
+ response = cliente_openai.chat.completions.create(
58
+ model="gpt-4o",
59
+ messages=[{"role": "system", "content": "Você é um assistente que resume textos de forma objetiva."},
60
+ {"role": "user", "content": prompt}],
61
+ temperature=0.3,
62
+ max_tokens=150
63
+ )
64
+ return response.choices[0].message.content.strip()
65
+ except Exception as e:
66
+ return f"Erro ao gerar resumo: {e}"
67
+
68
+ # 🔹 Filtrar conteúdo com base nas palavras-chave e gerar resumos
69
+ def filter_content(extracted_data, keywords):
70
+ filtered_data = []
71
+ for page in extracted_data:
72
+ detected_keywords = find_keywords(page["text"], keywords)
73
+ if detected_keywords:
74
+ summary = generate_summary(page["text"])
75
+ filtered_data.append({
76
+ "page_number": page["page_number"],
77
+ "summary": summary,
78
+ "text": page["text"],
79
+ "keywords": ", ".join(detected_keywords),
80
+ "link": page["link"]
81
+ })
82
+ return filtered_data
83
+
84
+ # 🔹 Criar um documento Word com os resumos
85
+ def generate_word_from_summary(filtered_data, output_path):
86
+ doc = Document()
87
+ if not filtered_data:
88
+ doc.add_paragraph("Nenhum conteúdo relevante encontrado.")
89
+ else:
90
+ for page in filtered_data:
91
+ doc.add_heading(f"Resumo da Página {page['page_number']}", level=2)
92
+ doc.add_paragraph(f"**Palavras-chave encontradas:** {page['keywords']}")
93
+ doc.add_paragraph(f"**Resumo:** {page['summary']}")
94
+ doc.add_paragraph(f"📎 [Acesse a Página]({page['link']})")
95
+ doc.add_paragraph("-" * 50)
96
+ doc.save(output_path)
97
+
98
+ def generate_clickable_link(pdf_path, page_number):
99
+ """
100
+ Gera um link funcional para acessar uma página específica do PDF dentro do Gradio.
101
+ """
102
+ pdf_filename = os.path.basename(pdf_path) # Pega apenas o nome do arquivo
103
+ link = f'<a href="{pdf_filename}#page={page_number}" target="_blank">📄 Acesse a Página {page_number}</a>'
104
+ return link
105
+
106
+
107
+ # 🔹 Processamento do PDF no Gradio
108
+ def process_pdf(uploaded_pdf):
109
+ if not uploaded_pdf:
110
+ return "Nenhum arquivo enviado.", None
111
+
112
+ pdf_path = uploaded_pdf
113
+ output_docx = os.path.join("clippings", f"clipping_{int(time.time())}.docx")
114
+
115
+ keywords = ["Governo Federal", "Ceará", "infraestrutura", "saúde", "educação", "segurança pública"]
116
+
117
+ extracted_data = extract_content(pdf_path)
118
+ filtered_data = filter_content(extracted_data, keywords)
119
+ generate_word_from_summary(filtered_data, output_docx)
120
+
121
+ resumos = []
122
+ for page in extracted_data:
123
+ summary = generate_summary(page["text"])
124
+ resumos.append({
125
+ "page_number": page["page_number"],
126
+ "summary": summary
127
+ })
128
+
129
+ return resumos
130
+
131
+ # 🔹 Criar botões e resumos interativos em Markdown com HTML
132
+ def create_summary_buttons(resumos):
133
+ markdown_content = ""
134
+ for r in resumos:
135
+ page_num = r["page_number"]
136
+ summary = r["summary"]
137
+
138
+ markdown_content += f"""
139
+ <button style='padding:5px;margin:5px;' onclick='
140
+ const pages = document.querySelectorAll(".pdf-container .page");
141
+ if(pages && pages.length >= {page_num}){{
142
+ pages[{page_num}-1].scrollIntoView({{ behavior: "smooth" }});
143
+ }}
144
+ '>📄 Ir para Página {page_num}</button>
145
+ <strong>🔑 Resumo:</strong> {summary}<br><hr>
146
+ """
147
+
148
+ return markdown_content if markdown_content else "Nenhum resumo disponível."
149
+
150
+
151
+ # 🔹 Interface Gradio
152
+ with gr.Blocks() as demo:
153
+ gr.Markdown("### 📑 Clipapptor - IA para Resumo de PDFs")
154
+
155
+ with gr.Row():
156
+ with gr.Column(scale=1): # Lado esquerdo
157
+ uploaded_pdf = PDF(label="📤 Faça upload do PDF", interactive=True, height=650)
158
+ #page_input = gr.Number(value=1, label="Página", interactive=True)
159
+ #go_to_page_button = gr.Button("Ir para Página", elem_id="go-to-page-button")
160
+
161
+ with gr.Column(scale=1): # Lado direito
162
+ process_button = gr.Button("📄 Gerar Clippings do Jornal")
163
+ resumo_output = gr.Markdown("Aguardando resumos...", render=True, height=650)
164
+
165
+
166
+ # 🔹 Função para navegação no PDF
167
+ # def go_to_page(page_number):
168
+ # return page_number
169
+
170
+ def process_and_create_buttons(pdf):
171
+ resumos = process_pdf(pdf)
172
+ return create_summary_buttons(resumos)
173
+
174
+ process_button.click(
175
+ fn=process_and_create_buttons,
176
+ inputs=[uploaded_pdf],
177
+ outputs=[resumo_output]
178
+ )
179
+
180
+ # go_to_page_button.click(fn=go_to_page, inputs=[page_input], outputs=[page_input])
181
+
182
+ demo.launch(share=True)